DocsSupervision (zirv ctx)
Usage pacing
Long autonomous runs die if a subscription window (5 hour rolling, 7 day) runs
dry mid-task. zirv ctx loop and zirv ctx exec consult a pacing gate before
every spawn and every restart, and wait instead of exiting when a window is at
or above pace.max_percent (default 99).
Three data layers, best available wins:
-
Collector, server-authoritative. Claude Code's statusline input carries
rate_limits.five_hourandrate_limits.seven_dayfor Pro and Max sessions after the first response. Wire your statusline through the tee and every live session keeps machine-wide state fresh:{ "statusLine": { "type": "command", "command": "zirv ctx usage tee -- bash ~/.claude/statusline-command.sh" } }The tee records the fields, then runs your original command unchanged. It always exits 0 and always prints a statusline, so a failure here can never leave you looking at a blank one.
zirv ctx statusline [-- <your command>](issue #833) composes with it: it runs your command (or the built-in fallback line when none is given), keeps its output and appendsagents n/cap · supervisor off · jev N · $spendto the last line, for example"command": "zirv ctx statusline -- zirv ctx usage tee -- bash ~/.claude/statusline-command.sh".ncounts live sessions in the reported directory,capisdash.max_panes,jevis the 24 hour call count (offwithout a gate and credential, or past a 2 MiB log), and the spend is Claude Code's owncost.total_cost_usd. It makes no network call; the segment is dropped if it takes over 40 ms, and any error leaves your line exactly as it was.subagentStatusLineis not wired. -
Estimator, an approximation. When no fresh collector reading exists, zirv sums token usage across local transcripts (including subagent files) over the trailing window. It is off until you set a budget, because a plan's real token allowance is undocumented and a made-up default would read as data:
[pace] five_hour_budget_tokens = 0 # set to enable the 5h estimate seven_day_budget_tokens = 0 # set to enable the 7d estimate count_cache_reads = false # cache reads are discounted, so excluded -
Circuit breaker, authoritative on trip. If the agent prints a documented limit-hit notice, that is treated as 100% no matter what the other layers say: the run is parked until the window resets and then relaunched, without consuming the restart budget.
Full pacing configuration:
[pace]
enabled = true
max_percent = 99.0
collector_max_age_secs = 900
estimator = true
jitter_secs = 30
fallback_delay_secs = 900 # used when a window's reset time is unknown
wait_slack_secs = 3600 # head room added to the window's own length
# max_wait_secs = 7200 # optional absolute override, see belowHow long a pause can last#
The wait is bounded per window, not by one global clock: at most the window's own
length plus wait_slack_secs, so a five-hour trip is bounded near six hours and
a seven-day trip is allowed to wait out the week. That distinction matters,
because resuming a seven-day window every few hours would spend tokens against a
window that has not reset, which is exactly what pacing exists to prevent.
When a window's reset time is known and lands inside that bound, the pause ends
at the reset (plus jitter) and not before. Set max_wait_secs only if you would
rather a supervisor give up waiting and proceed after a fixed time; it replaces
the per-window bound entirely and is unset by default.
A pause is announced once, not once per check, and appears in the decision log as
a single pace-wait entry. Parks and relaunches are logged too. Check the
current picture, including how fresh each reading is, with zirv ctx usage.