Claude Usage Monitor 1.0.0 — replay the last good snapshot while the endpoint is busy #5

Merged
ClaudiuSchuster merged 5 commits from oss-oo/replay-last-snapshot into main 2026-10-27 02:48:28 +00:00
Owner

Summary

  • A busy or unreachable usage endpoint no longer leaves a freshly reloaded applet empty. The helper saves every endpoint snapshot to $XDG_STATE_HOME/cinnamon-claude-usage/last-snapshot.json. That file is mode 0600, holds no history and is keyed to a truncated fingerprint of the access token. When the endpoint fails (429, 5xx, network, cut-off responses), the helper replays the file as source.stale with source.error:
    • only while the snapshot is at most two hours old, twice the longest refresh interval;
    • without windows whose reset already passed;
    • only for the same access token. A rejected token's snapshot is deleted.
  • The applet adopts a replay only while it shows no snapshot of its own (after a reload or a sign-in prompt):
    • it keeps the original "Updated" time and the error line, and skips the green confirmation;
    • a running applet keeps its own snapshot, so the weekly reset detection still compares against the previous windows;
    • a replay records no history sample.
  • Version 1.0.0: first stable release, on top of the 0.1 line.
  • The release skill now follows the station rules: a dedicated worktree, the station token via askpass, and a draft-then-publish release.

Validation

  • make verify passes:
    • 83 Python tests and 14 CJS suites;
    • the translation template, icons, rights inventory, ShellCheck and social preview checks;
    • ruff and Prettier are clean.
  • Clock shifts of +1 h, +4 d, +30 d and +1 y leave the suite green. The 4ac693b fixture failed at +1 h.
  • Mutation check: all 11 mutants against the replay and review-fix code fail the tests.
  • Live: the pre-release build is installed and reloaded on the owner's desktop.
    • last-snapshot.json is 0600 and holds no token material.
    • The live file replays in process for the same login and not for another token.
  • Independent review, round 1 (66e1850..4ac693b):
    • found 1 blocker (a clock-dependent fixture), 3 minor findings and nits;
    • all fixed in 46e7f79 except nit 5, which is kept by design: an adopted replay behaves like a running applet's own snapshot, which the weekly reset detection needs.
  • Independent review, round 2 (4ac693b..46e7f79): in progress.
  • CI: runs 1922 (4ac693b) and 1924 (46e7f79) succeeded.

🤖 Generated with Claude Code

## Summary - A busy or unreachable usage endpoint no longer leaves a freshly reloaded applet empty. The helper saves every endpoint snapshot to `$XDG_STATE_HOME/cinnamon-claude-usage/last-snapshot.json`. That file is mode 0600, holds no history and is keyed to a truncated fingerprint of the access token. When the endpoint fails (429, 5xx, network, cut-off responses), the helper replays the file as `source.stale` with `source.error`: - only while the snapshot is at most two hours old, twice the longest refresh interval; - without windows whose reset already passed; - only for the same access token. A rejected token's snapshot is deleted. - The applet adopts a replay only while it shows no snapshot of its own (after a reload or a sign-in prompt): - it keeps the original "Updated" time and the error line, and skips the green confirmation; - a running applet keeps its own snapshot, so the weekly reset detection still compares against the previous windows; - a replay records no history sample. - Version 1.0.0: first stable release, on top of the 0.1 line. - The release skill now follows the station rules: a dedicated worktree, the station token via askpass, and a draft-then-publish release. ## Validation - `make verify` passes: - 83 Python tests and 14 CJS suites; - the translation template, icons, rights inventory, ShellCheck and social preview checks; - ruff and Prettier are clean. - Clock shifts of +1 h, +4 d, +30 d and +1 y leave the suite green. The 4ac693b fixture failed at +1 h. - Mutation check: all 11 mutants against the replay and review-fix code fail the tests. - Live: the pre-release build is installed and reloaded on the owner's desktop. - `last-snapshot.json` is 0600 and holds no token material. - The live file replays in process for the same login and not for another token. - Independent review, round 1 (66e1850..4ac693b): - found 1 blocker (a clock-dependent fixture), 3 minor findings and nits; - all fixed in 46e7f79 except nit 5, which is kept by design: an adopted replay behaves like a running applet's own snapshot, which the weekly reset detection needs. - Independent review, round 2 (4ac693b..46e7f79): in progress. - CI: runs 1922 (4ac693b) and 1924 (46e7f79) succeeded. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A busy or unreachable usage endpoint (429, 5xx, network) left a freshly
reloaded applet empty. The helper now saves every endpoint snapshot
(last-snapshot.json, 0600, no history, truncated token fingerprint) and
replays it for up to 30 minutes on a transient error — original
"Updated" time, windows past their reset dropped, same sign-in only,
marked source.stale with source.error. The applet shows the data, keeps
the error line and skips the green confirmation; a replay does not end a
sign-in watch.

Tests: unit replay rules, a real HTTP round trip with a 429 after a
success, and the applet's stale handling (78 Python tests, 14 CJS suites).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A replay drops windows past their reset. Adopting it in a running applet
would hide those windows early and make the weekly reset detection miss
the reset it compares against, so only an empty (freshly reloaded) applet
takes it; a running one keeps its own snapshot and shows the error, as for
any failed refresh. The helper also stops rewriting the history sample at
the replay's time, which would have lost the dropped windows' points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Call it 1.0.0: first stable release
All checks were successful
Checks / Functional checks (pull_request) Successful in 31s
4ac693b59a
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review fixes: clock-free fixture, forget rejected snapshots, cut-off responses
All checks were successful
Checks / Functional checks (pull_request) Successful in 35s
46e7f797e8
- The end-to-end fixture's reset times are relative to the real clock: with
  fixed dates the replay assertions started failing once the 5-hour reset
  passed (a test time bomb for CI from 2026-10-27 03:00 UTC).
- A rejected (401/403) token deletes its saved snapshot, so a later 429 for
  the same token cannot bring back old usage over the sign-in prompt.
- Cut-off bodies and garbled status lines (http.client.HTTPException) count
  as endpoint failures and replay, and no longer fail a run through the
  profile read.
- The replay window is two hours, twice the longest refresh interval, so a
  reload always finds the previous refresh's snapshot; a test ties it to the
  settings schema.
- Tests for windows without a reset time, snapshots from the future and a
  replay over an own snapshot running no reset or notification checks.
- Docs say what is stored and when it replays; the release skill follows
  the station rules (worktree, station token via askpass, draft release).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep the status of a cut-off error reply
All checks were successful
Checks / Functional checks (pull_request) Successful in 35s
bc3947735f
`_error_detail` reads the error body inside the HTTPError handler; an
IncompleteRead there escaped every handler, so a cut-off 429/503 gave no
replay and a cut-off 401 no sign-in prompt. It now returns no detail and the
status keeps its meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ClaudiuSchuster deleted branch oss-oo/replay-last-snapshot 2026-10-27 02:48:28 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OSS-Singularity/cinnamon-claude-usage!5
No description provided.