116: v0.13.1 — the release that stayed a patch

Where we left off

Task #73 (Autonomous Ops Lite, item 3) asked for one thing: run the manual autopilot-lite loop — dispatch, review, merge, reconcile — against a real synlynk goal instead of a synthetic one. The goal picked was goal-adb60ccc, scoped as "epic closure" across the Job-Truth and GH-Write epics from docs/superpowers/plans/2026-08-09-job-truth-and-gh-write-epics.md: Epic A3 (#740, cost-completeness for terminal jobs), Epic B2 (#577, Codex-sandbox invalid gh-token diagnosis), and Epic B3 (#659 and #714, dispatched-review-cancellation RCA). The working assumption going in was that closing these four stories would round out enough scope to cut a named v0.14.0 minor release.

What moved the goalpost

The loop run itself surfaced real friction — two consecutive Agy scratch-worktree infra crashes, a Grok review that landed on the wrong branch and posted a corrupted-template review, and a GitHub branch-protection block that looked like a missing review but was actually a pending CI check — all handled via the existing escalation clauses (self-review fallback, finishing-a-development-branch) rather than blocking the loop. That's exactly the kind of attribution/friction data task #75 exists to capture.

But looking at what was actually sitting in CHANGELOG.md's [Unreleased] section once the four stories landed, two of the largest line items didn't hold up to a "is this a real milestone" test: Agent vs Harness Terminology is explicitly Phase 0 of a 5-phase roadmap — the glossary and doctor table got renamed, but phases 1-4 (agent manifests, memory, capability registry, portability) don't exist yet. Quota-Aware Dispatch Reservation ships a real agent_reservations ledger and TPM hook surface, but no active agent currently exercises either — there's nothing production consuming what would be the release's headline feature.

Naming a v0.14.0 minor around content that's either incomplete or inert breaks the release policy's own rule: if you can't write the one-sentence pitch, the scope isn't coherent enough. Neither of those two features earns that sentence yet. So the release got rescoped down to what the Named Release Policy actually calls a patch: bug fixes and completed, load-bearing safety mechanisms, no new user-facing surface area with unfinished edges.

What this PR ships

v0.13.1, cut as release/v0.13.1 off main:

  • GOVERNS event-contract extension (#922) — job_terminal and review_submitted event types plus synlynk events tail [--type] [--limit], read-only against the existing events table.
  • Init/Migrate/Upgrade Rollback Mechanismrollback_checkpoint and rollback_checkpoint_upgrade wrap init()/migrate()/upgrade() in checkpoint-and-restore, plus synlynk rollback [--last|<op-id>|--clear] and --dry-run previews.
  • State Engine PR1roadmap.md/memory.md/costs.md are now write-through generated from state.db instead of hand-parsed markdown.
  • synlynk doctor TC-6 (#928, closes #577) — a new gh-auth check across all four dispatch harnesses that catches the false-green failure mode where gh auth status exits 0 but the token is actually invalid, closing the Codex-sandbox root cause diagnosed this session (no GitHub App token provisioned, network egress to api.github.com disabled by the sandbox).
  • Dispatched-review-cancellation RCA (#929, closes #714) — concluded Grok's cancelled stopReason is harness-side, distinct from synlynk's own 30-minute stall killer (_check_job_stall()) and HARNESS_TIMEOUT_PATTERNS; no code change warranted.
  • Three CVE/reliability fixes carried over from [Unreleased]: linkify-it and brace-expansion bumps (Dependabot #6/#7), and the base-branch resolution + Agy permission-warning fixes.

Agent vs Harness terminology and Quota-Aware Dispatch Reservation stay in [Unreleased] — both are real, tested, merged code, just not yet a milestone worth naming.

What this achieved

Every story in the goal-adb60ccc epic-closure goal is closed (A3 #740, B2 #577, B3 #659/#714), the fleet gained a doctor check that should catch the exact gh-token failure mode that cost three dispatch attempts on PR #928, and the release discipline held: a release got smaller rather than shipping partial work under a bigger version number because the version number was already mentally reserved.

The goal at the end of this PR

v0.13.1 ships. Task #75 — writing up the attribution/friction findings from this loop run (Agy scratch-worktree infra bug, Codex network restriction, recurring stale-job-status pattern, the branch-protection-vs-review confusion) — feeds directly into Week 2's TPM/session MVP design, which is also the natural trigger for Quota-Aware Dispatch Reservation to graduate out of [Unreleased]: once there's a TPM actually reading the reservation ledger, that's the milestone.