Use when starting any large or multi-file task, when working in a long session, or when told the task has many steps — before writing a single line of code or editing a single file.
Large batch tasks exhaust rate limits mid-run, leaving codebases in broken partial states. Natural agent instinct is to dive in immediately — especially under deadline pressure. This skill forces a pre-flight that decomposes work, routes cheap units to Haiku, and pauses safely before the budget runs out.
Core principle: Urgency makes pre-flight MORE important, not less.
You are about to violate this skill if you think:
All of these mean: run pre-flight first.
Confirm the paths and files the task refers to actually exist before decomposing. A plan built on phantom files wastes the entire budget.
Record the project root as an absolute path — this will be stored in the queue so future sessions can resume without asking the user where the code lives.
cat ~/.claude/rate-budget-session.json 2>/dev/null || echo '{"used_pct": 0, "total_tokens": 0}'
Missing file = 0% used (not an error — accumulator resets daily). If used_pct >= 75: do NOT start. Tell the user and offer to schedule resumption via cron (see Pause & Resume).
used_pct tracks all tokens in the session regardless of model. Haiku and Sonnet share the same daily budget counter.
Check if ~/.claude/rate-queue.json already exists — if it does, read it first. If it belongs to a different task, archive it to ~/.claude/rate-queue-prev.json before overwriting.
Break the task into atomic units — one unit = one file, one function, one self-contained change. Write the queue before touching any files:
{
"task": "<original task description>",
"project_path": "<absolute path to project root, e.g. /Users/alice/code/myapp>",
"created_at": "<ISO timestamp>",
"threshold_pct": 75,
"units": [
{"id": 1, "description": "<what to do>", "model": "haiku", "status": "pending"},
{"id": 2, "description": "<what to do>", "model": "sonnet", "status": "pending"}
],
"resume_prompt": "Resume rate-budget task. Read ~/.claude/rate-queue.json, find project_path, validate it exists, skip done units, continue from first pending unit."
}
Ask 2–3 clarifying questions before decomposing if the task scope is ambiguous.
For each unit, decide: Haiku or Sonnet?
| Use Haiku | Use Sonnet |
|---|---|
| Mechanical repetition (same change across N files) | Multi-file reasoning required |
| Boilerplate generation | Architectural decisions |
| Simple search/replace with known pattern | Ambiguous requirements |
| File is < 100 lines, single responsibility | Debugging / root cause analysis |
Default to Haiku for mechanical work. You save ~10x tokens per unit.
For each pending unit in order:
done in ~/.claude/rate-queue.jsoncat ~/.claude/rate-budget-session.json) where N = check_every_n_units from ~/.config/rate-budget/config.json (default: 5)used_pct >= 75: stop immediately → Pause & ResumeNever skip the budget check. Urgency does not override it. For tasks with large units (e.g. reading 10+ files per unit), set N=1 in config.
When budget threshold is reached:
rate-queue.json)touch ~/.claude/.rate-resume-pending
(crontab -l 2>/dev/null; echo "5 0 * * * claude -p \"$(cat ~/.claude/rate-queue.json | python3 -c 'import sys,json; print(json.load(sys.stdin)[\"resume_prompt\"])')\"") | crontab -
~/.claude/rate-queue.json."On session start, if ~/.claude/.rate-resume-pending exists, remind the user to run /rate-budget resume.
When invoked as /rate-budget resume or via cron:
~/.claude/rate-queue.jsonproject_path exists on disk — if missing, ask the user before proceedingstatus == "pending"~/.claude/.rate-resume-pending and ~/.claude/rate-queue.json| Mistake | Fix |
|---|---|
| Starting work before pre-flight | Always check budget + decompose first |
| Treating all units as Sonnet-worthy | Classify explicitly — most mechanical work is Haiku |
| Skipping budget checks mid-run | Check every 5 units, no exceptions |
| Urgency overriding pre-flight | Reframe: urgent tasks need checkpoints more, not less |
| Partial codebase left broken on rate limit | This is what the skill prevents — pause cleanly |
Queue has no project_path | Resume session can't find the code — always record the absolute path at queue creation |