0.25.0
Cut on 2026-09-29. coxswain-graphs and coxswain-tools are tagged v0.25.0. coxswain-cartridges stays pinned at
v0.23.1 and coxswain-crew at v0.12.0. coxswain-tools is published to PyPI from its tag. Status: beta.
This release paces the fleet from the plan meter, fills every machine's lanes, and teaches the loop to guard its own
lands; it also lays the backend for coxtop, the terminal dashboard coming in 0.26. It carries four headlines.
Builds pace themselves. The chair loop and the launch gate read the Claude plan meter the status line records,
label every figure meter or est, and calibrate the fallback ceilings over the meter's own window, so a stale
reading no longer turns into a false usage stop. Every build task gets its own budget from the p75 cost of similar
landed tasks, clamped to $1 to $4; the per-thread stop at 1.5 times that budget was reverted in this release because a
build that hit it could wedge its run, and returns once that wait is fixed.
Lanes on any machine. Relaunches and retries go to any machine with a free lane, not only this one, while an
initiative's runs stay on its home machine until that machine drains, loses its login or loses its lane. Each
machine's lane capacity is set at run time with cox host capacity, cox runs move moves a run to another machine,
and the loop treats its own machine as local rather than as a remote lane host.
The loop guards itself. After every tools or graphs land the loop runs a smoke check (cox route context,
cox runs top, a dry-run tick); on a failure it holds launches, flags the land and opens a revert PR for it. A lane
with no node call for 30 minutes is flagged as stalled, and the epic driver dumps every thread's stack on SIGUSR1.
Lands got safer: a phase land merges main in first when its parent phase already landed, keys earlier runs' records
correctly, reads task states and records from the store in store mode, and refuses when an approved task's files are
missing from the squash; a fetched remote run counts as fetched, and an initiative decomposed into no tasks is
flagged.
coxtop's backend. cox dash --feed streams a versioned JSON snapshot of the fleet and cox dash --detail
serves drill-downs for a run, an initiative, a machine, spend, health and release. cox runs stop acts on a run on
any machine. cox runs pause and resume are in the CLI but fail in this release (see Known issues); the driver's
pause wait between nodes is in, but nothing can set a pause yet. The decompose can number tasks by ordinal (t1,
t2, ...) so no model writes a full task id.
Upgrading from 0.24.0. Upgrade every machine that reaches the shared store together: this release migrates the
store to schema version 10, and older code refuses a newer store. Restart the chair loop after upgrading cox; a
running loop keeps the planner it started with. The dashboards' charts now all match their datasets; rerun the
dashboards bootstrap after upgrading.
coxswain-tools
- The loop and the launch gate pace from the plan meter and label each figure's source (tools #1199, #1205); the meter's calibration measures dollars over the meter's own window and keeps a stale reading inside it (tools #1224, #1228), with the call sites fixed (tools #1225).
- Relaunches and retries fill any machine's free lanes and an initiative stays on its home machine (tools #1226, #1233, #1234, #1236); the loop's own host row is local (tools #1238).
- Lane capacity per machine is set at run time and a run can move machines:
cox host capacity,cox runs move(tools #1204, #1222, #1231). cox runs stopon any machine;cox runs pauseandresumeare added but fail until the harness command they call ships (tools #1201, #1211, #1215).cox dash --feedandcox dash --detail(tools #1203, #1210, #1219).- The post-land smoke check holds launches and opens a revert PR when it fails (tools #1230, #1232, #1235).
- A lane with no node call for 30 minutes is stalled (tools #1214, #1221, #1223).
- Phase lands: main merged in before squashing (tools #1198), earlier runs' records keyed by file name (tools #1212),
states and records read from the store in store mode, with
route importnever moving a state backward (tools #1220), and a refusal when an approved task's files are missing from the squash (tools #1216). - A fetched remote run counts as fetched (tools #1213); an initiative decomposed into no tasks is flagged (tools #1237).
coxswain-graphs
- Every build task gets a budget from landed history (graphs #613, #614), with the history matching build calls on run and task (graphs #620); the per-thread stop at 1.5 times the budget (graphs #615) is reverted (graphs #618).
- The machinery for a run to pause at its next node boundary: the store's pause flag and lease status, the runner's wait hook and the driver's wait (graphs #625, #627, #629). Nothing in this release sets the flag.
- The epic driver dumps every thread's stack on
SIGUSR1(graphs #626). - The decompose can number tasks by ordinal (graphs #630).
- store_read's import tests treat
sitecustomizeas interpreter machinery (graphs #633).
coxswain
- Every dashboard chart matches its dataset and no column is named
at(coxswain #199, #201); the table charts query their columns (coxswain #203).
Known issues
Corrected after the cut, on 2026-09-29.
- Every runner other than Claude Code fails on a style pass or a gate model-arm apply with
TypeError: run() got an unexpected keyword argument 'wait_if_paused': the Anthropic runner (the default when a profile names no runner), the OpenAI-compatible runner and System One. Profiles on the Claude Code runner are unaffected. Fixed in graphs #640, with a test that every runner accepts every keyword of the runner protocol. cox runs pauseandcox runs resumeexit withinvalid choice: 'pause': the harness store command they call has nopauseorresumeaction. Filed for 0.26.
Components
coxswain-tools carries the pacing, placement, loop guards and coxtop's backend, coxswain-graphs the build budgets,
the pause wait and the stack dump, and the umbrella the dashboards. coxswain-cartridges and coxswain-crew are
unchanged.