0.15.0
Cut on 2026-09-25. coxswain-cartridges, coxswain-graphs and coxswain-tools are tagged v0.15.0 in
lockstep; coxswain-crew is unchanged and stays pinned at v0.12.0; coxswain-tools is published to PyPI
from its tag. Status: beta; nothing here breaks a 0.14.0 install. This is the first release cut by the
umbrella's own devtools, now that the release commands have left the published cox CLI (coxswain #76).
The release index keeps the manifest's order and is committed with the manifest bump, so a cut no longer
leaves the umbrella dirty (coxswain #82). The devtools messages and the README marker name devtools
(coxswain #83, #84). System one
defaults to shadow with the local backend: it answers beside the handoff node, never instead of it, records
every answer next to the node's own, and turns itself off quietly on a machine that cannot run it. A report
says when a role has earned on, as a proposal for the maintainer. Run records gain a SQLite store that
graphs owns, written alongside the files the tools still read. The chair's own cost and the harness's are
now measured side by side.
coxswain-cartridges
- Provider profiles write their per-role defaults as capability classes, with every role on the same model
as before (cartridges #149); the graphs runners and
coxread class names since graphs #309 and tools #461. - System one defaults to shadow with the local backend in the Claude Code and local profiles: a kNN
decider over the handoff role at threshold 0.9, reading
~/.local/state/coxswain/system_one/handoff.jsonl(cartridges #152). Shadow answers beside the node and never replaces it. Nothing leaves the machine. The hosted-API profile carries no block. - The release-sync skill names the umbrella's
devtoolsrelease commands (cartridges #151).
coxswain-graphs
- System one records and degrades. Every call's usage row carries its decision, with the fast path's
backend, mode, answer, confidence, threshold and whether it agreed with the node (graphs #329). A backend
that cannot serve (a missing key, a missing or empty examples file, an optional package not installed)
turns system one off for the run with one
system-one: off (<reason>)line instead of failing it; a malformed block still fails (graphs #332). The local backend expands~in its examples path (graphs #334). - Capability classes, shadow phase. The runner protocol accepts a router decision through a
DecisionSource(graphs #312); both runners record a supplied decision beside their own and never compute one (graphs #305, #306); the lifecycle, phase-validation, decompose and triage call sites pass one on every call (graphs #324, #325). The Claude Code runner enforces a profile's CLI version pin or floor and records a violation (graphs #313). The runners accept class names wherever they accepted tiers (graphs #309). - A single graph run can write its result as JSON for its caller with
--result-out(graphs #343). - A
state_moveproposal namesapproved, neverdone. The work-state arm writes what the proposal names, so every approved task used to readdonebeforecox runs landmerged it (graphs #344). - SQLite run records. Graphs owns the schema. One connection URL selects SQLite or Postgres with portable
placeholders (graphs #308); numbered migrations apply on open (graphs #311); migration 0001 holds the
run-record tables, ledger, gate decisions and lease (graphs #317) and 0002 the graph registry (graphs #319);
trace events go to per-run day files compressed with zstandard (graphs #315); a leader lease carries a
monotonic fencing epoch (graphs #321); a loaded graph registers its definition and content hash once
(graphs #327); and idempotent writers cover every run-record table (graphs #331). Given a store, the runners
record every call and its decision (graphs #336), and the epic driver records phases, tasks, attempts, gate
decisions and ledger rows, fencing each leader-only write with the lease epoch (graphs #338). Every graph run
now opens the store at start: the profile's
storage_url, orcox.dbin the runs directory. It registers the graph and writes the run row, and a run whose record cannot be kept does not start (graphs #340). One connection serves the runner's thread pool, with a lock that keeps another thread's statement out of an open transaction (graphs #341). The record files are still written exactly as before; the store is written beside them. A read module answers run summaries, cost by model, calls, attempts, ledger rows, gate decisions, the current lease and a run's graph (graphs #346). Two backfills import the existing record files and loose traces. Each reports row counts and archives its sources only when asked and only when the counts balance; neither deletes anything (graphs #348, #350).docs/STORAGE.mdin graphs covers the tables, the lease and its fencing epoch, the read path, the Postgres step and the chair's backfill runbook (graphs #352).
coxswain-tools
- Chair measures.
cox runs landappends every land toruns/land.jsonlwith the steps it reached (tools #470);chair.jsonrecords the chair's Claude session, and the chair's cost is priced from its transcripts (tools #471); a quarantined attempt carries a cause, andcox runs causeand the quarantine spend split by cause (tools #474);cox stats chairreports harness PRs and spend, chair spend per PR, hand-finished lands and quarantine spend by cause (tools #476). cox route syncputs the run and each task's cost on its card and makes an initiative the parent issue of its tasks (tools #464).cox devis gone from the published CLI; it prints where the release tooling moved and exits 2 (tools #442).cox stats examples --role handoff|review_charterwrites the local system-one backend's examples file from the task records, with the same state text the system-one layer builds at run time (tools #477).cox stats system-onereports, per role, the shadow rows since the last model or Claude Code version change, their coverage, agreement and the costly-direction disagreements, and a READY or NOT YET verdict against 100 rows, 95% agreement and at most 1% costly.--proposewrites a graduation proposal for the maintainer, with the calls it would save and the risk it takes, and never edits a profile (tools #479).cox route pull [--source github] [--dry-run]files an intake ticket for each new item a source lists, once per link. It refuses a repository the profile'srepo_mapdoes not map, and marks the source item with the intake path. The profile gainssourcesandrepo_map(tools #481). A pull also sends each open pull request labelledreviewtocox runs review, then relabels itreview:takenso the next pull skips it (tools #488).cox runs review --pr <url>runs the review graph on a contributor's pull request, in a fresh worktree of the local checkout the profile'srepo_mapnames, and posts the verdict as a review with inline comments. It refuses a repository with no checks interpreter, ascox runs landdoes, and never merges (tools #486).- The README Commands block lists the new commands (tools #480, #487).
- The tools repository pins Python 3.12, the CI version, so the byte-exact help fixtures are written the way CI reads them (tools #478).
Known gaps
The SQLite cutover, where graphs stops writing the record files, waits until the tools read the store and
the backfill counts are verified on a real workspace. Until then the files remain the record the tools
read. The graph registry stays empty in practice: no graph declares a loaded graph object yet, so a run
row's graph id is unset. Shadow runs only where the graphs system-one-local extra (sentence-transformers)
is installed and cox stats examples has written the examples file. Without either, it stays off and
prints its one-line reason. Only the handoff role has a default; the review prescreen needs its own
examples file. The Jira and Asana intake adapters are built but held, because the tools repository names
no vendor.
Components
coxswain-graphs carries the run-record store, system one's recording and degrade path, and the
capability-class shadow phase. coxswain-tools carries the chair measures, the system-one examples and
graduation report, cox route pull and cox runs review. coxswain-cartridges carries the shadow default
and the class-named defaults. coxswain-crew is unchanged and stays pinned at v0.12.0.