0.43.0
Cut on 2026-10-17. Status: beta. Lands can be frozen for a release cut with cox chair freeze-lands while the
lanes keep building. A quarantine caused by the ticket or the code is relaunched once by the loop instead of held for
the chair, and the relaunched run sends the task to triage before it builds again. cox chair watchdog checks the loop
from outside it, run from a five-minute timer. An initiative is marked done on the tick its last task closes, cox runs
triage prints a quarantined task's facts in one command, and cox route paths --move swaps a moved repository prefix
in the queue rows and work files. The home directory install is still not wired: a new install lays out under
--root, and the install into the home moves to 0.44.0, as the known gaps explain.
Freezing lands for a release cut. cox chair freeze-lands --for MINUTES --reason TEXT writes a land-freeze row
to the store's leases table that expires after MINUTES. While it stands, the chair plans no phase land and no task
land. Fetches, launches and holds are still planned, so the lanes keep building and approved work waits on its
branches. The status line gains a lands frozen until HH:MM (reason) part, with the time in UTC. With neither flag the
command prints whether lands are frozen, --off lifts the freeze, and a freeze that outlives its minutes lifts itself,
so a forgotten freeze never needs deleting. --for and --reason go together and never with --off, MINUTES is at
least 1, and any other mix prints the usage line and exits 1.
A ticket or code quarantine is relaunched once. A quarantine whose cause is the ticket or the code held its initiative for the chair. The loop now relaunches it once on the ticket's current body, and a second quarantine on that body reaches the chair with the first and the latest attempt's reasons, 300 characters each. In the relaunched run the epic harness caps a task whose newest attempt was caused by the ticket or the code at one attempt instead of two, so the task goes to triage before it builds again. When triage proposes a ticket amendment that only appends text to the body, the harness applies it at once, without waiting on the approval gate, provided the amendment is eligible and the cartridge names a model apply arm. It then checks that the ticket file holds the old body with text appended, and rebuilds the task on the new body in the same run with its attempt count reset. An apply that fails or writes anything else is undone: the ticket file is restored to the bytes read before, and the task is quarantined with the reason.
A watchdog outside the loop. cox chair watchdog [--idle-minutes N] [--stale-minutes N] [--dry-run] is a one-shot
check meant for a five-minute timer. It reads the chair lease and the recent status lines from the store. It pushes
Chair loop down when the lease has no row or no beat in --stale-minutes (default 10), or when no status line was
written in the last --idle-minutes (default 30). It pushes Lanes idle <minutes> min, naming the holds, when every
status line in that window shows no busy lane and at least one hold. It pushes through the profile's notify setting
with the loop's own sent-state file, --dry-run prints the alerts and pushes nothing, and it exits 1 only when the
store cannot be read. This command and the empty-decompose report below were already in the 0.42.0 packages, though the
0.42.0 notes left them out and called the watchdog planned.
An initiative closes on the tick its last task closes. In store mode, each tick the chair finds every initiative still in state todo whose task rows are all done or dropped, and moves it to done, or to dropped when none of its tasks is done. An initiative with no task rows is left alone, and the close is planned even while a limit has stopped launches.
cox runs triage TASK_ID [--json] prints a quarantined task's facts. It reads the store and git and makes no model
call. It prints the task's initiative, phase, state and newest run, each recorded attempt with its kind, cause and
reason, the review verdict and its objection, the last failed check with the last 20 lines of its output, the phase's
latest land refusal with its time, head and reason, and each surface as present, missing, or new when a surface marked
(new) is not on main yet. The store is the one the profile names, and surfaces are looked up on main, else
origin/main, of the git repository in the current directory. An unknown task id exits 1 with a line saying so.
cox route paths --move OLD NEW swaps a moved repository prefix. In store mode it rewrites each row's repo and
its absolute or tilde surfaces; otherwise it rewrites each work file's repo: line and surfaces. OLD and NEW are
taken to the tilde form first, a path moves only when it is OLD or lies under OLD/, and a relative surface never
moves. Like the rest of route paths it lists the changes and writes nothing without --apply. With --apply it reads
the rows or files again, prints how many values are still under OLD, and exits 1 when any are. It is the step cox
setup migrate --apply prints, but does not run, after it moves the checkouts.
cox setup migrate --apply migrates only this machine. In 0.42.0 --apply went on to each lane host after the
local steps. The host steps now run only with --apply --hosts, on the chair's machine; without --hosts the command
prints a line saying the hosts were not touched.
Smaller fixes. A needs-chair hold now pushes once while it stands. The one-hour repeat window had pushed a standing
hold again every hour, 19 notices in 46 minutes on 2026-10-17; its key is now kept while the hold stands and pruned an
hour after it clears. Holds the loop clears by itself (a land between its fetch and its record, a launch deferred behind
a running initiative that shares a file, a work file the export left alone) never push. A decomposed intake whose
decompose run ended with no stored tasks is reported as a hold with cox route requeue <initiative> as its remedy,
cox route requeue finds the intake through the intake: field of initiative.md when no store row links them, and
an initiative already done or dropped is never reported as an empty decompose. A launch on a lane host syncs the
harness and the repository at the checkout of the same name that the host's heartbeat recorded, migrated under
installs/ or not, and pushes the repository there. A decompose names its initiative from the intake's title, where it
had used the whole intake file, and the ticket lint no longer refuses a path under tests/ as corpus.
coxswain-graphs
- A task whose newest attempt was caused by the ticket or the code is capped at one attempt instead of two, so a relaunch sends it to triage before it builds again (graphs #800).
- An append-only ticket amendment from triage is applied at once when it is eligible and the cartridge names a model apply arm. The written file is checked for the old body with text appended, and the task is rebuilt on the new body in the same run with its attempt count reset. A failed or mismatched apply restores the file and quarantines the task with the reason (graphs #803).
- A decompose takes its initiative's title from the intake's
title:, else its first#heading, else its first line, as one line of at most 120 characters. The intake's frontmatter is dropped from thewhy, itsrepo:is used when the launch names no repository, and a title that spans more than one line is refused (graphs #802). - The ticket lint reads a path under
tests/as repository code, never corpus, so a ticket naming a folder such astests/fixtures/help/runs/is no longer refused at decompose (graphs #798). - Tests only: the store DDL tests pin only their own upgrade, and the decompose, tier, handoff and infrastructure tests stop pinning constants, private helpers and prompt wording. They remove 44 tests and add 5, and the suite goes from 2,406 test functions at v0.42.0 to 2,389. No DDL or migration changed (graphs #804, graphs #805, graphs #806, graphs #807).
coxswain-tools
cox chair freeze-lands [--for MINUTES] [--reason TEXT] [--off]sets, shows or lifts a land freeze kept as an expiringland-freezerow in theleasestable (tools #1738). The land planner plans no land while it stands (tools #1744), and the status line shows it (tools #1747).- A ticket or code quarantine with one attempt on its current body is relaunched, and the second attempt on that body reaches the chair with the first and latest reasons (tools #1742).
cox chair watchdogpushes when the loop is down or its lanes sit idle on a hold, as described above. It shipped in the 0.42.0 packages (tools #1735) on the rules and readers that 0.42.0 described as groundwork.- A decompose that wrote an initiative with no tasks is reported as a hold with the requeue command as its remedy, and
cox route requeuereads the intake frominitiative.mdwhen no store row links it. This also shipped in the 0.42.0 packages (tools #1736). An initiative already done or dropped is left out (tools #1739). - The chair reads each todo initiative with its task rows' states (tools #1745) and closes one whose tasks are all done or dropped, as done when any task is done and as dropped otherwise (tools #1761).
cox runs triage TASK_ID [--json]prints a task's attempts, review, failed check, land refusal and surfaces: the pure core shipped in the 0.42.0 packages (tools #1734), then came the store and git readers (tools #1740) and the command (tools #1754).cox route paths --move OLD NEWswaps a repository prefix in the store rows or work files (tools #1743) and reports what is still under OLD after--apply(tools #1748).- A notice is pushed once while its hold stands and pruned an hour after it clears, and the
no_run,steer_deferredandheld_fileholds never push (tools #1741). - A launch on a lane host syncs the harness and the repository at the host's recorded checkout of the same name, and maps the harness path to the host's home when it has none (tools #1746). The dry run of a launch on a host lists those sync steps when the host has recorded checkouts (tools #1752).
cox setup migrate --applyruns the host steps only with--hosts. The preflight refusals for a held lease, a live lane, the chair's lease and an active host row are written but not called yet (tools #1751).- Groundwork for installing into the home, wired to no command: the install plan can create the default workspace
<workspaces>/mainwith its folders and record the home, and a reader lists the installed plugin marketplaces (tools #1750). - A renderer and check for the README's commands block now live in this repository, as a module with tests; no command or test outside its own calls it yet (tools #1762).
- Tests only: six consolidation changes drop tests that pinned defaults, private plumbing and status-line wording, and the fake servers and the chair-run test rig stop waiting idle. They remove 95 tests and add 18, and the CLI dispatch test stops pinning the number of handlers (tools #1749, tools #1755, tools #1756, tools #1757, tools #1758, tools #1759, tools #1760). With the new features' tests, the suite goes from 6,962 test functions at v0.42.0 to 7,001.
coxswain
- The release rehearsal's fresh scenario installed into the default coxswain home with no
--root, and its upgrade scenario rancox setup migrate --applyafter the pin (coxswain #317). Both were reverted for this cut, sincecox installat 0.43.0 still requires--root(coxswain #318); they come back with the home install in 0.44.0.
Known gaps
The home directory install is still not wired. cox install and cox setup install require --root, so a new install
does not use the home until you run cox setup migrate --apply afterwards. The install plan's default workspace and
home record and the marketplace reader exist but no command calls them (tools #1750). Wiring them is 0.44.0, and so is
the rehearsal that installs fresh into the home. cox setup doctor still does not show the doctor rows for the home.
The cox setup migrate --apply preflight is partial. Only the --hosts split ships. The refusals that should stop
--apply while a lease holds a checkout, a lane runs on this machine, the chair holds its lease here, or this host's
row is active are written and tested but not called, so drain the host and stop the loop yourself before you migrate.
The empty-decompose hold always says that no refusal line was found in the decompose log, since nothing reads that log for it yet. Nothing records that the hold was reported either, so it is planned again on every tick until the intake is requeued. Since tools #1741 it pushes only once while it stands.
cox runs triage takes no --profile or --repo: it reads the store the routing profile names and looks surfaces up
in the repository of the current directory, so run it from the task's repository. cox chair watchdog is installed as
a command only; nothing sets up its timer, so add one yourself. Closing an initiative on its last task works in store
mode only.
The gate for 0.43.0 was the hosted rehearsal (run 39062083584), whose fresh, upgrade and migrate jobs passed, on tools
c1784d3, graphs edd8f74, dash b654297, cartridges 8584e34 and crew 80eb36a, with the umbrella at 281b845. A
clean-machine rehearsal in a throwaway Proxmox container passed the fresh install, the upgrade from 0.42.0 and
cox setup migrate on tools 2df7632, the commit before tools #1762, which adds a module nothing calls yet. An earlier
hosted run with the umbrella at 530285f failed its fresh job (run 39061438425) because that scenario installed with no
--root. A land freeze does not stop a land the loop planned before the freeze was set: tools #1762 landed that way
during this cut.
Migrations: none
Components
coxswain-graphs and coxswain-tools change and are released at 0.43.0. coxswain-dash has no commits since v0.42.0 and stays pinned there, coxswain-cartridges has none since v0.40.0 and stays pinned there, and coxswain-crew is unchanged since v0.38.0 and stays pinned there.
Upgrading from 0.42.0. The store schema is unchanged and nothing migrates on its own; the land freeze uses the
existing leases table. Update cox itself first, with uv tool upgrade coxswain-tools or brew upgrade cox, then
run cox upgrade. If you move an install under the home directory, cox setup migrate --apply now moves only this
machine: run cox setup migrate --apply --hosts on the chair's machine to move the lane hosts too. To use the
watchdog, call cox chair watchdog every five minutes from a timer of your own on a machine that can read the store.