Usage guard
Work a task autonomously and continuously, checking usage-window consumption (the 5-hour block by default, or the 7-day/weekly cap with `--window 7d`) at each checkpoint, and stop when usage hits a threshold (default 99%) instead of getting rate-limited mid-action. Use when the user runs `/usage-guard <task>`, `/usage-guard --queue <task>`, `/usage-guard --window 7d <task>`, says "keep going until I'm almost out of usage", "grind on this until the 5-hour limit", "use up my block on this", "stop when I'm near my weekly/7-day limit", or "work until 99% then stop / then queue the rest".From its SKILL.md
npx -y skills add nikhilsitaram/claude-caliper --skill usage-guardAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
9.1 KB, as published. Nobody here has run it
/usage-guard — work until the 5-hour usage window is nearly spent
Run a task as a continuous autonomous work session, self-checking how much of the current 5-hour usage window has been consumed, and stop cleanly at a threshold (default 99%) — leaving 1% headroom so the stop/report (or queue) actions don't trip a real rate limit mid-action.
/usage-guard [--queue] [--at <pct>] <task>
Parse the invocation
--queue— at the threshold, don't just stop: queue the remaining work to auto-resume in the next 5-hour block (see "At the threshold" below).--at <pct>— override the threshold (e.g.--at 95). Default 99.- Everything else is the TASK. If no task is given, treat the current in-progress work / the conversation's active objective as the task; if that's unclear, ask what to grind on before starting.
How usage is read
./skills/usage-guard/scripts/check-usage.sh [--window 5h|7d] [threshold]
(invoke directly — executable, no bash prefix) reads ~/.claude/queue/state.json,
kept fresh by the queue skill's statusline wrapper. It prints WINDOW=, USED_PCT=,
VERDICT= (UNDER/OVER), CAPTURED_AGE_SEC=, STALE= (yes/no), RESETS_AT_HUMAN=,
RESETS_IN_MIN= and exits 0 = under, 10 = at/over, 1/2 = data unavailable.
--windowselects the rolling window (default5h). Pass--window 7dto guard the weekly cap instead — e.g. "stop when I'm near my 7-day limit". The work loop is otherwise identical; just thread the same--windowvalue through every check this run so cadence and the threshold branch track one window.- This depends on the queue skill's statusline wrapper being wired in. If
check-usage exits 1/2, relay its stderr and stop — usage can't be read. One
exception: exit 2 with a past
resets_atstderr is a transient cross-session glitch (a stale blob from another session, overwritten within ~10s). Re-run once after ~5s before stopping; only stop if it repeats. STALE=yes(the same >90s cutoffcompute-fire.shuses) means the statusline hasn't rendered recently — terminal idle/unfocused — soUSED_PCTlags reality. Note it; the number may be behind.
The work loop
- Set up a ledger. Use the task list (TaskCreate/TaskUpdate) to break the
TASK into trackable sub-tasks and keep it current. This ledger IS your
"what's done / what's still open" for the stop report and the queue payload.
In
--queuemode, also write the rate-limit backstop marker once now (see "Rate-limit backstop"), and — at the very start of any run — check for a leftover breadcrumb from a previously interrupted run. - Do a chunk of the work (a sub-task, or a small batch of steps).
- Update the ledger (mark finished items done) — do this before the usage check so the check/branch always sees a current ledger.
- Check usage by running check-usage.sh:
- Exit 0 (UNDER) → continue to the next chunk.
- Exit 10 (OVER) → go to "At the threshold".
- Exit 1/2 → relay and stop.
- Cadence AND chunk size — the overshoot guard. Checking often isn't enough
if a single chunk between checks can itself burn several percent:
- Check after each sub-task while usage is low; past ~90%
USED_PCT, check after every step. - Past ~90%, also keep chunks small — do NOT start a single long-running action (big build, wide subagent fan-out, large batch) that could plausibly consume more than the remaining headroom. If the next step might, check/stop before it, not after.
- If
STALE=yesnear the ceiling, the reading lags reality — treatUSED_PCTas a floor and stop early rather than trusting a sub-threshold number.
- Check after each sub-task while usage is low; past ~90%
- If the task completes before the threshold → stop and report it done; do NOT queue, and clear the backstop marker. (A finished task ends the chain.)
Work continuously without pausing to ask between chunks — that's the point of the guard. Only stop for the threshold, task completion, a hard error, or a genuine decision that's the user's to make.
At the threshold (VERDICT=OVER)
First, make the ledger accurate (mark what's done; the open items are what remains). Then:
Default (no --queue): stop now and report:
USED_PCTreached and that the window resets atRESETS_AT_HUMAN,- what got done this run,
- what's still open (the remaining ledger items),
- how to resume (a one-line "say continue / re-run with --queue" pointer).
With --queue: queue the remainder to resume in the next block.
- First, the termination guard: if no open ledger items remain, the task is effectively done — report it done and do NOT queue. Only queue when real work remains.
- Compose a CONTINUATION PAYLOAD — a self-contained resume prompt, because
the resumed session is cold (no task list, no file context, no memory of
this run except this string). It MUST include all of:
- (i) the original task statement, verbatim — so block N hasn't drifted;
- (ii) done so far (the completed ledger items);
- (iii) still open (the remaining ledger items, in order);
- (iv) environment — working directory, git branch/worktree, and key file paths / IDs / URLs needed to resume;
- (v) decisions & constraints already settled this run.
- Get the fire time:
./skills/queue/scripts/compute-fire.sh(reset mode — fires ~90s after the window resets). Relay stderr and stop if it errors; if it printsSTALE=yes, refresh the statusline first. CronCreatewith:cron= itsCRONvalue,recurring: false,durable: true(a multi-block chain almost always outlives this terminal, so persist it — unlike a plain/queue, which defaults session-only), andprompt:Your queued usage-guarded work is due — the 5-hour window has reset. First
<CONTINUATION PAYLOAD>cdto the working directory named below. Then resume by invoking/usage-guard --queueon the following remaining work, so it keeps guarding usage and re-queues anything still open at the next threshold:- Clear the backstop marker — the work is durably queued now, so the
StopFailure hook must not double-queue it:
./skills/usage-guard/scripts/guard-marker.sh clear - Report: what got done, that the rest is queued for
FIRE_HUMAN(job ID), and the caveats below. Because the continuation re-invokes/usage-guard --queue, a task bigger than one block chains block-to-block until the open list is empty (the termination guard above is what ends it).
(Default-mode stop also clears the marker — there's no queued continuation to protect.)
Rate-limit backstop (--queue, opt-in hook)
usage-guard's job is to stop before the limit; this is just a light safety net
for the overshoot case (one oversized action trips a real rate limit before the
next check). An opt-in StopFailure hook (matcher rate_limit) records — it does
NOT auto-resume — so an interrupted --queue run isn't silently lost.
- At
--queuerun start, write the marker once with the original task + the environment needed to resume (working dir, branch/worktree, key paths/IDs):printf '%s' "<task + env>" | ./skills/usage-guard/scripts/guard-marker.sh set - Clear it the moment the run ends — task completion, a clean stop, or right
after the CronCreate above (steps 4/6):
guard-marker.sh clear.
If a rate limit hits while the marker is live, the hook copies it to
~/.claude/queue/pending-resume.json (a breadcrumb). At the start of any
/usage-guard run, check for that file; if present, fold its task/env into this
run and delete it so it isn't picked up twice. The hook is opt-in (a plugin
can't edit settings.json) — wiring + caveats in the README.
Caveats (state these when stopping)
- Checkpoint-granular, not a hard interrupt — the stop lands at the first check at/after the threshold, so actual usage may be a hair above it. That's what the 1% headroom is for.
--queuechains aredurable: true— they persist to disk and survive a restart (a 5h+ chain won't keep one terminal open). But a durable job still only fires while some Claude session is running and idle — if nothing is running at reset time it fires late, when you next open Claude. It is not a headless/background runner.CronList/CronDelete <id>to inspect or cancel.- The continuation resumes cold in whatever session fires it — its quality is only as good as the CONTINUATION PAYLOAD (hence the required fields above).