feat(usage-queue): dev-gated usage-limit simulation control for demos - #235
Conversation
Adds POST /api/usage-queue/_simulate?state=capped|cleared|off so the queue-send-on-clear feature can be demoed without hitting a real Claude usage limit. Sets an in-memory override that getRateLimits returns verbatim — so the dashboard usage panel AND the queue watcher both see the simulated value — then invalidates the cache and kicks an immediate queue tick (no 60s wait). Gated behind AUTONOMOS_ENABLE_USAGE_SIMULATION; the endpoint 404s in normal/prod runs and never touches the real usage path otherwise. Tests cover the scanner short-circuit + env gating + state validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UpGRD3fxgWmCKyp9nZtrQs
nox-0x
left a comment
There was a problem hiding this comment.
Approving — clean dev-gated demo control, well scoped and tested.
The design is tight: the override short-circuits getRateLimits before the cache so an in-flight real fetch refilling cached can't displace it, the route is double-gated (AUTONOMOS_ENABLE_USAGE_SIMULATION env + the existing /api/* requireAuth middleware), and tick()'s early-exit on armed.size === 0 keeps the immediate-kick a no-op when nothing is queued. Tests cover gate-off → 404, capped/cleared/off transitions, bogus state → 400, and the cache short-circuit (proven with a throwing fetcher).
Minor non-blocking note for a follow-up if it ever matters: !!process.env.AUTONOMOS_ENABLE_USAGE_SIMULATION treats =0/=false as enabled. Conventional gotcha but irrelevant here since the flag is set explicitly during demos.
Why
Follow-up so the queue-send-on-usage-clear feature (#232) can be seen working without waiting hours to actually hit a real limit. Requested by Terry: drive the real dashboard button + watch a real agent auto-submit, on demand.
What
POST /api/usage-queue/_simulate?state=capped|cleared|offsets an in-memory usage override thatgetRateLimits()returns verbatim — so the dashboard usage panel and the queue watcher both see the simulated value — then invalidates the usage cache and kicks an immediate queue evaluation (no 60s poll wait).capped→ 100% on the 5-hour window (button shows a ~2h ETA; armed panes latchseenBlocked)cleared→ a small non-zero below the queue's exit threshold (the high→low edge fires armed panes)off→ clears the override, resuming real usage readsSafety: gated behind
AUTONOMOS_ENABLE_USAGE_SIMULATION. The endpoint 404s and sets nothing in normal/prod runs, and the override code path is never reached unless the endpoint sets it.Demo runbook
The order matters: arm → capped → cleared (the pane must observe "blocked" before a clear can fire it — same as the real flow).
Testing
getRateLimits(a throwing fetcher proves no network), and clearing it resumes real reads.offclears; invalid state → 400.🤖 Generated with Claude Code
https://claude.ai/code/session_01UpGRD3fxgWmCKyp9nZtrQs