v2.1.0 — End-to-End Dogfood Blockers
The blockers that stopped an unattended devflow start run from reaching a completed Ship stage.
Phase 23 had proven the goal unreachable: its furthest attempt drove Define→Plan→Code unattended and then halted, and two of its three attempts needed a human to repair the base ref before devflow start would launch at all. This release closes those blockers individually rather than re-attempting the run and rediscovering them.
Fixed
compute_versionno longer invents version numbers. It derived a version fromCargo.toml's major, the raw count of git tags as the minor, and commits-since as the patch — which produced~1.11.359against a real1.8.1. It now takes the baseline from the highest semver tag reachable from HEAD and classifies the commits since with a conventional-commit parser. A baseline that exists in the repo but is not reachable from the release branch is refused outright rather than silently yielding a smaller version.- A major version bump can no longer ship unattended.
--yes-shippre-authorizes the Ship gate, which meant a major bump could ship with nobody seeing it. A major bump now opens its own gate that--yes-shipcannot auto-approve — the auto-response is a parameter of the gate call, never derived from state. devflow doctorno longer calls live, registered processes orphans, andgate sweep --reap-straysno longer SIGKILLs them. The/proccensus is structural by design — argv shape plus euid, no ownership test — yetdoctorasserted an orphan conclusion it never checked and named a destructive repair for it. On a machine running concurrent DevFlow phases, that listed every sibling run's monitor as a stray. Both surfaces now filter through one shared reachability set built from every registered root'smonitor_pidand lock holders. A process whose project root was deleted contributes nothing to that set, so the case the feature exists for still works.- A stale base ref can no longer launch a run, and repairing one can no longer corrupt it. The base branch is fetched and compared before launch; strictly-behind is fast-forwarded, anything else refuses loudly. The fast-forward is a compare-and-swap, so a ref that moved between check and write is refused rather than silently rolled back — and its "not checked out" precondition is evaluated across every worktree in the repository, not just the one you launched from.
- Build-staleness is adjudicated once per run. It ran on every stage launch, so a run that started against a current build could be blocked mid-flight by a later commit. It now runs once, at
start. - A test-suite race behind a ~50% CI failure rate is closed. A process's
/proccmdline is inherited from its parent betweenforkandexec, so a census taken inside that window could match the wrong process. A bounded barrier now covers every affected spawn site, and the reaper refuses to signal inside the window. Closed against an 11-observation streak, with the residual probability stated rather than claimed eliminated.
Added
devflow gate sweep --reap-strays— opt-in reaping of orphaned monitor processes with bounded TERM→KILL escalation and verified death, plus--dry-run. Identity is re-confirmed immediately before any signal, so a recycled PID cannot be hit.devflow doctorreports state-orphaned processes as their own finding class, describing only what was actually checked rather than asserting orphan-ness.
Changed
- The documented release procedure no longer drifts from what the code does. Tagging now shows the explicit key-selection form rather than a bare
git tag -s, which signs with whatever key happens to be configured — a real hazard when the release key and an agent's commit key share auser.emailand differ only by fingerprint. - The README says where the automation stops — the release cut itself is deliberately manual;
devflow release --checkruns the preflight but does not execute the release.
Full detail: CHANGELOG.md § 2.1.0.