Skip to content

F7 · Budget governor for the autopilot

Done 2026-10-26 · commit b2687d8 · 10 unit tests, loop tested with a fake claude

What changed

  • tools/autopilot/statusline.py: a status line that writes plan usage to .autopilot/usage.json.
  • tools/autopilot/budget.py:

    • two modes: a number of points of a window (percentage points of the 7-day or the 5-hour plan window, counted from the start), or until the window is used up;
    • batch sizing;
    • waiting for the 5-hour reset;
    • limit detection from the stream, and from the StopFailure hook once Thomas adds it (autopilot §4);
    • calibration of percent per USD.
  • tools/autopilot/run.sh: now a governed loop of headless ticks.

  • Status line: the AUTOPILOT line shows the budget.
  • Docs: autopilot §6.

Why

Spectio is a side project. Thomas wants to give it a share of his weekly window at any time of the week, or let it use the rest of his quota. For example: start on Wednesday at 11:00 and stop when the window resets at 15:00.

Decision: decision log, 2026-10-26, budget governor.

Evidence

$ python3 -m unittest tools/autopilot/test_budget.py
Ran 10 tests in 1.988s
OK
$ bash tools/autopilot/run.sh --weekly 6 --max-ticks 6     # in a throwaway copy, fake claude first on PATH; each tick costs 1.5 points
budget=0.0/6pt 7d (live, window 40%)
tick 1  batch=[review,review,review,review,review,review,review,spike]  {"action": "go", "fits": 4, … "consumed": 0.0, "target": 6.0 …}
tick 2  batch=[…]  {"action": "go", "fits": 2, … "consumed": 1.5 …}
tick 3  batch=[…]  {"action": "go", "fits": 1, … "consumed": 3.0 …}
tick 4  batch=[…]  {"action": "stop", "fits": 0, "reason": "budget used", … "consumed": 4.5 …}
stop: budget used
AUTOPILOT  wave=W1  done=10/41  running=0  failed=0  blocked=0  waiting_human=0  budget=4.5/6pt 7d (live, window 44%)

Calibration of the percent-per-USD ratio is covered by the unit tests (test_estimate_from_calibrated_cost_when_no_live_reading); in this loop the live readings were always fresh, so no estimate was needed.

Figures and media

The same run, recorded with tools/media/cast.py (the JSON decisions are cut at the terminal width above):

The budget gauge in the tick:

One autopilot tick, with the budget gauge One autopilot tick, with the budget gauge

Findings and open questions

  • Status line only. Claude Code exposes plan usage only to the status line. Headless ticks are therefore estimated from total_cost_usd, using a calibrated ratio.
  • [to be validated] whether the status line runs in cloud sessions, and what claude -p emits when the plan limit is hit.