0.23.0
Cut on 2026-09-28. coxswain-graphs and coxswain-tools are tagged v0.23.0. coxswain-cartridges had no changes
and stays pinned at v0.21.0; coxswain-crew stays pinned at v0.12.0. coxswain-tools is published to PyPI from
its tag. Status: beta. This release lets the fleet run itself, and it carries four headlines.
The store is the board. Work items live in the store (graphs harness.store_queue, migration 0009), intake
states agree between the ticket files and the store, and cox route drift compares intake rows as well as tasks. A
machine whose profile names a shared Postgres storage_url now reads its board from the store when the store answers,
and says work state: files (store unreachable) when it does not; a local SQLite store keeps the ticket files, so
local-first stays the default.
A lane host can come and go. A lane whose host has gone quiet and whose own lease heartbeat has stopped is marked lost and relaunched elsewhere; hosts can be drained, and placement weighs hosts and their capabilities. The loop checks each lane host's Claude login every 30 minutes over ssh, records it with the host's beat, and gives a host with a lapsed login no new lanes. A remote run's approvals reach the chair's ticket files when it is fetched, and so do its phase branches.
The chair is resident and has a console. cox chair service --install --host <name> prints or runs the steps
that put the chair loop on a lane host as a user service, and --status --host reports it. cox console is one
terminal screen of drafts, hosts, lanes, the chair and needs-chair items, whose keys run cox commands after a y/n.
Stale work becomes a draft for a person to approve or decline.
One merge to main per phase. The loop lands a completed phase as one squash of its branch onto a fresh main,
from its own pr/ branch, and marks every task in it done; a partial phase's branch is carried forward on relaunch
with main merged into it, and an approved task of a partial phase waits for its phase instead of landing alone.
Upgrading from 0.22.0. Run the graphs migration (0009) against the store. A lane host needs the tools' postgres
extra. To make a machine a resident chair, run cox chair service --install --host <name>, then the two steps it
prints for a person (loginctl enable-linger and systemctl --user enable --now).
coxswain-tools
- Lost lanes: the contract, the drained display, marking a run lost, the recovery rule and the signal reader (tools #1061, #1063, #1065, #1067, #1069); placement facts and weighted, capability-aware fill (tools #1090, #1092). A lane counts as lost only when its own lease heartbeat is quiet too (tools 95616b6).
- Login watchdog: types, the watch rule, the executor, the facts and the plan (tools #1097, #1099, #1101, #1103, #1105); the loop reads the hosts table for it and the ssh check times out after 60 seconds (tools 249cca8).
- One merge to main per phase: the carry rule, no lone lands for a partial phase, the land_phase action and its
executor, the stranded wiring and the carry merge (tools #1078, #1080, #1082, #1109, #1113, #1115). Phase lands
accept approved tasks, squash the phase onto a fresh main from a
pr/branch, close each task's work item, and a remote fetch brings back phase branches (tools #1140, #1142, #1150, #1152). The planner switch (tools #1117) was reverted until a phase land could merge (tools 168c789) and then re-applied (tools #1154); the first phase land under it is tools #1156. - Stale work becomes a draft: the executor, the planner, the signal reader and the facts (tools #1074, #1084, #1086,
#1095); a ticket with no commit reads its file's modification time, so a fresh ticket is never stale (tools
91a4010); a stale draft names
proposed_byandproposed_at(tools 5e736a7). - The store as queue:
cox route filewrites the store first (tools #1088); intake states agree, and drift and import compare intake rows (tools #1136, #1146, #1148); the work-state default reads a shared Postgres store (tools #1156). cox console(tools #1121, #1125, #1127), with drafts, one needs-chair line per item and host login shown (tools 21a6b57).- Resident chair: the install steps,
--install --hostand--status --host(tools #1130, #1138, #1144). - Remote runs: every unfetched remote run is found, not only the newest, and a run with no directory is fetched once (tools #1132, #1134); a fetched run's approvals reach the ticket files (tools 936aa2e).
- The loop: it takes its lease under its own host (tools 6abe8d1), recovery launches stop at the machine's free lanes (tools 2d26c92), and a loop tick under a takeover still moves the record heartbeat (tools #1123).
coxswain-graphs
harness.store_queue: migration 0009 adds the work-item queue columns, and the queue verbs read, upsert, claim and release rows (graphs #594, #596); an upsert without a stamp gets the write time andstore_queueas author (graphs 980225b).
coxswain
- Fleet and Chair dashboards: the fleet datasets, the charts and dashboards, the installer creating every listed dashboard, and their docs (coxswain #172, #175, #179, #181).
- The release branches the tap PR from the fetched remote default, not the local tap checkout (coxswain #177).
- The 0.22.0 notes name the real pins (coxswain 7a3e274).
Components
coxswain-tools carries most of the release, coxswain-graphs the store queue, and the umbrella the dashboards and
the release fix. coxswain-cartridges and coxswain-crew are unchanged.