v0.18.0 — Dispatch Reliability & QA Merge-Gate Authority
Where we left off
Post #128 (v0.17.0) shipped ticket-driven approval auto-resume, closing the last named gap in the tpm sweep loop. That release tagged and published cleanly. What it didn't do — and what nothing since #1110 had done either — was give the several weeks of work that shipped alongside it a version number. QA's delegated merge-gate authority, the harness capability registry rewrite, the gh-write broker design, and a full Phase 1 identity-hardening closeout all landed on main between mid-August and v0.17.0's tag, each with its own PR and (mostly) its own blog post, but none of them got folded into a CHANGELOG entry or a release. They were shipped code with no release story.
A same-day sweep of the open-issue and open-PR backlog against docs/strategy/road-to-autonomous-ops.md's release gates surfaced this directly: the gate "No unreviewed autonomous merge or release" implicitly assumes releases happen at a reasonable cadence, and going four weeks with a growing pile of undocumented main commits works against that. It also surfaced two live defects along the way — a datetime-comparison crash in jobs --all (#1184) and a per-connection database backup storm (#1087) — both fixed in the same session that triggered this release.
What moved the goalpost
No architecture changed here. This release is bookkeeping made necessary by its own absence: cutting v0.18.0 is the correction, not a new capability. The one real finding was operational rather than technical — the sweep discovered the repo's own VERSION file had silently drifted to 0.16.0 while GitHub already showed v0.17.0 as the latest tagged release. synlynk doctor's _hc_version_current() check exists specifically to catch this class of drift, but it only runs when a human explicitly invokes synlynk doctor — nothing in the release-cut or dispatch hot path calls it. That gap is now tracked separately as #1188 rather than papered over by this release; bumping VERSION to 0.18.0 here fixes today's instance of the drift without fixing the mechanism that let it happen.
What this release shipped
QA delegated merge-gate authority, completion tracker, and merge-restricted classes (gh#1079/#1099/#1100/#1101, PRs #1082-#1104) — QA can now merge PRs that pass verification without every merge routing through PM/human action, with an explicit carve-out list (release branches, policy.json changes) that stays outside that delegation regardless of verification status. A Vizor panel surfaces verified-but-unmerged PRs so the delegation doesn't just move the bottleneck out of sight.
GitHub-write broker design (resolves #865 brainstorm, PR #1075) and gh-write identity hardening Phase 1 closeout (gh#423/#426, PR #1110) — consolidate GitHub App token resolution and write-permission checks behind one interface instead of scattered per-call-site logic, closing out the identity-hardening track that #1140/#1164/#1172/#1174/#1175/#1177/#1178/#1180 continued building on through this week.
Harness capability registry v2 (gh#786, PRs #1053-#1066) — replaces the old flat capability ledger with harness_models/harness_modes/capability_calibration_* tables, per-model and per-mode instead of per-harness, plus a Stage 0 explore bonus so thin-calibration-data models aren't starved of dispatch opportunities while they build a track record.
Agent-roles Phase 2 — memory-gated capability routing (PR #1030) — routing decisions can now consult accumulated per-role memory rather than treating every dispatch as a cold start.
A week of dispatch and gh-write reliability fixes (PRs #1140/#1164/#1166/#1172/#1174/#1175/#1177/#1180/#1182/#1183): a daemon-owned GitHub App token cache unblocks headless dispatch; worktree gh-write dispatch falls back to the main repo's github_apps when the worktree has none; PR-review task type is now inferred from task text; a missing review task_allocation policy entry is filled in; grok's review-type gh-write authorization is correctly downgraded; Codex sandbox network access is gated per #340; gh-write targets resolve from task text for #860; and a _maybe_open_worktree_pr bug in jobs.py is fixed.
PM competitive-intelligence sweep (PR #1159) — a weekly cron job maintaining a living comparison doc against competitor tooling, feeding a decide-round pipeline for roadmap input.
The two live fixes that triggered the cut
#1184 — jobs --all datetime-comparison crash (PR #1187). _parse_iso8601() in synlynk/gh_verify.py crashed with TypeError: can't compare offset-naive and offset-aware datetimes whenever a naive timestamp reached gh_write_verified(). Root cause was a pipx install four releases stale — the local CLI predated the v0.14.0 agent→harness DB rename entirely, which is what surfaced the real bug once the install was current. Fixed by normalizing a trailing Z and coercing naive timestamps to UTC-aware before every comparison. Independently verified with a full local test run outside the dispatch sandbox: 2267 passed, 2 pre-existing unrelated flakes, 0 regressions.
#1087 — _migrate_db() backup storm (PR #1189). _migrate_db() ran the harness-rename migration, full schema executescript, and seed step unconditionally on every connection open — the backup snapshot itself was already gated on schema version, but nothing after it was. Root-caused as the likely source of the intermittent database is locked failures seen during the #1187 verification run (test_cmd_agent_add_onboards_agent, test_cmd_probewrite_fencetrue_clobbers_sop_harness). Fixed with an early return once PRAGMA user_version is already current; regression test confirms a second connection against an already-migrated DB does zero migration work.
Process note: cleaning up dogfood exhaust
The same sweep closed eight stale [APPROVAL] GitHub issues (#1142-#1149) — artifacts of v0.17.0's Task 5 live dogfood run, which used a temporary task_dispatch_demo policy rule that was fully reverted before merge and never landed on main. Every one of those tickets cited a policy rule that no longer exists, meaning none of them could ever resolve through the normal auto-resume flow they were testing. Not a design flaw — the rule was deliberately throwaway — but leaving eight dead tickets sitting in the tracker works directly against the release gate "GitHub Issues in configured scope are linked, parked, or marked out of scope." Closed with provenance comments rather than silently.
Where this leaves the long-arc goal
road-to-autonomous-ops.md targets a public Autonomous Development Loop Preview by 2026-10-01, gated on (among other things) 100% of terminal jobs having cost data, no unreviewed autonomous merge, and GitHub Issues in scope being linked/parked/out-of-scope. This release doesn't advance the TPM/session MVP track directly — it's the release-hygiene correction that keeps four weeks of real shipped capability (QA merge-gate authority chief among them) from just sitting undocumented on main while that track continues. The open item it deliberately does not close is the ~90-issue backlog beyond the eight dogfood artifacts: that triage pass is running in parallel, in a separate session, and will get its own accounting once it's done.
New goalpost
Next: land the outstanding backlog triage, keep #1188 (version-drift) moving toward a durable fix rather than a one-off correction, and get back to the TPM/session MVP work road-to-autonomous-ops.md actually schedules for the 2026-08-17 to 2026-08-30 window.