---
name: v013-publish-gate-p1c
description: v0.13.0 publish paused on the P1c controller-writer-reorder root-fix; pipeline state + P1b-innocence proof
metadata: 
  node_type: memory
  type: project
  originSessionId: 13f58dd9-2b2b-428d-bb80-9015bf14aff2
---

v0.13.0 ship (operator-priority — perri waits to build the spt-claude-code adapter against the published contract) is **paused on a root-fix**, as of 2026-06-20.

**Sequence that got here:** P1b bundle (ack-deadlock + ctrl+V→WT + scroll) gated GREEN + HITL-accepted + re-deployed (install binary @21bfd9a, daemon healthy). Scroll → Shift+scroll interim; adapter-manifest VT-mode follow-up logged in DEFERRED.md. Then drove toward the release: FF'd `v0.13.0-delivery-control` (PR #26 head) to fold P1b in → CI red.

**CI-green gate findings:** Windows fails were a stale-workspace EPERM (orphaned CI-workspace daemon holding `_work/.../target/debug/spt.exe`) — operator cleared it with an elevated `taskkill /PID 161556 /T /F` (I'm non-admin; the orphan was runner-session-owned). Linux fails = a pre-existing flaky resume-test cluster (`attach_survives_target_brain_restart_exactly_once`, `inject_control_wedge::g2`, `broker::spawn_env_reaches_child`).

**P1b is PROVEN INNOCENT** of the Linux flakes — mechanically (its diff touches only input-ack machinery, never output-resume seq) + empirically (the test passes post-P1b in isolation on kitsubito). The flakes are pre-existing; they only matter because the release contract needs green-both-runners before the tag.

**Root cause (operator chose "full fix + new hazard REQ"):** two `controller_writer` threads race one brain connection's socket on brain-restart re-serve — `handoff` subscribes `from_seq=1` (life1's cursor) spawning writer-A (seq 1) before `serve_attach` re-subscribes `from_seq=0` (writer-B seq 0,1), and `become_controller` drops the prior sink but never stops the prior writer. Full design in repo `V0.13.0-P1C-CONTROLLER-WRITER-REORDER-PLAN.md` @3749845. **Dispatched todlando** to build (handoff single-registration + become_controller stops superseded writer + seed session_cursors + mint REQ-HAZARD-CONTROLLER-WRITER-REORDER); doyle gates (20× green on kitsubito + deterministic two-become keystone + seam sweep).

**P1c GATE STATUS (2026-06-20, live):** first P1c impl @9b0025b (epoch-gate `Arc<AtomicU64>` initial-batch-only + handoff keeps eager subscribe [fix#1 reverted — standalone-resume callers brain_swap/handoff/idempotent need it] + session_cursors seed + attach-from_seq cursor-reset) — clippy/traceable/keystones/canaries ALL green, BUT the **20× kitsubito carrier GATE-FAILED**: 8-11 PASS / 4-9 FAIL, all at the OPERATOR-viewport forward-gap (attach.rs ~215/222), original brain-side gap (722) GONE. RACEDIAG (diag branch v0.13.0-p1c-reorder-diag @f5eef48, env `SPT_REORDER_DIAG`) PINNED the root: **NOT the two-writer socket reorder (epoch gate WORKS)** — it's a CONSUMER-side boundary race at seq=K in life2's serve_attach: the kept handoff eager-subscribe consumes epoch3-writer's seq K into life2, and the attach_as(0) reset + snap-above dedup drop seq K from the operator forward under the timing where epoch4's frames arrive first → operator (has seq0 from life1, needs K) jumps to K+1. todlando writing the targeted fix (operator-forward must not lose seq K to life2's internal consume cursor); doyle re-runs the 20× carrier. Real silent-content-loss-on-resume bug (rc.rs:1017 snap-aboves → would lose it silently) — correctly blocking ship.

**P1c FIX VERIFIED + CHAIN (2026-06-20 late):** the consumer-boundary race fix landed @0dc7018 (moved the resume-mode dedup-cursor reset from `Brain::attach` into `Brain::subscribe_with` so `attach_as(0)` re-delivers from 0; operator dedups the [0,K) overlap → seq K forwarded → gapless). doyle-verified: 20/20 kitsubito carrier (was 8-11/20), instrumented positive trace (seq K forwarded, no gap), prod-safe (serve brain = `cold_start` empty-map per dispatch.rs:239/attach.rs:135 → reset never fires in prod; resume.rs 3/3 green). Chain on v0.13.0-p1b-ack-deadlock: `0dc7018 fix(brain)` → `40b0072 ci(pre-checkout reap, doyle)` → `bdb51c2 test(keystone+guard, todlando)`. Two CI-gate blockers found + fixed: (1) the P1c int keystone wasn't forkpty-portable (ConPTY splits P1C_ONE/P1C_TWO to seq0/1; forkpty COALESCES to seq0 → precondition fail) → fixed read-between-writes; (2) Windows checkout EPERM recurred (cross-run orphan daemon locks workspace spt.exe) → added a PRE-checkout reap to ci.yml test+n1-gate jobs (runs as runner session-0 acct → can kill the orphan an interactive token can't). g2/spawn_env did NOT flake (carrier fix was the whole cluster). NEW deterministic guard `re_serve_resets_resume_cursor_after_a_pre_attached_consume` (RED-on-revert) added (REQ-HAZARD un-reintroducible bar). doyle verifying on kitsubito/forkpty (keystone green + guard green + revert-to-red), then fold bdb51c2→delivery-control + re-CI for green-both-runners → deployah cuts. Test names: keystone `controller_writer_reorder_consumer_view_stays_monotonic_and_session_live`, guard `re_serve_resets_resume_cursor_after_a_pre_attached_consume`. Revert-to-red = disable the `self.session_cursors.insert(session_id, from_seq)` in subscribe_with.

**KITSUBITO ACCESS GOTCHA:** kitsubito CANNOT auth to GitHub (gh helper is a no-op there; `git fetch origin` fails "could not read Username"). To get a new commit there: `git bundle create x.bundle refs/remotes/origin/<branch>` locally → scp → `git fetch x.bundle '<ref>:refs/...'` on kitsubito. CI-checked-out commits ARE present (CI uses its token). Carrier 20× harness: throwaway `git worktree add --detach /tmp/x <sha>` + `CARGO_TARGET_DIR=~/actions-runner/_work/spt-core/spt-core/target` (shared cache) + `timeout 90 cargo test -p spt-daemon --test attach <carrier> -- --test-threads=1`, `pkill -9 -f attach-` between iters.

**P1c FULLY VERIFIED + GUARD VALID (2026-06-20, GATE-PASS).** Final chain on v0.13.0-p1b-ack-deadlock = delivery-control (PR #26 head) @bdb51c2: `0dc7018 fix(brain subscribe_with reset)` → `40b0072 ci(pre-checkout reap, doyle)` → `bdb51c2 test(forkpty-portable keystone + deterministic guard, todlando)`. ALL forkpty-verified on kitsubito: carrier 20/20, keystone `controller_writer_reorder_consumer_view_stays_monotonic_and_session_live` 5/5, guard `re_serve_resets_resume_cursor_after_a_pre_attached_consume` (in tests/ATTACH.rs:1281, NOT broker.rs) green 5/5 + revert-to-RED 3/3 (disable the `self.session_cursors.insert(session_id, from_seq)` in subscribe_with → deterministic fail). Windows EPERM checkout = FIXED by the pre-checkout reap (n1-gate Windows passed). GOTCHA I hit: ran the guard with `--test broker` (wrong file) → 0 tests → vacuous "ok"; the guard lives in `--test attach`. Always verify the run isn't `filtered out`/0-passed.

**LAST BLOCKER → todlando (operator handed 2026-06-20): test-infra flaky cluster.** g4_translation_child_is_reaped (Win) + spawn_env_reaches_child (Linux) + g2/w5_a2 flake under CI = NOT P1c, NOT a product bug, NOT bind-collisions (unique_name = pid+counter, unique per nextest process). ROOT = LOAD/TIMING CONTENTION (heavy real-broker+PTY tests racing under high nextest parallelism; check .config/nextest.toml slow-timeout={60s,terminate-after 4}). FIX = a nextest TEST-GROUP capping concurrency for the heavy real-broker/PTY tests (broker/attach/inject_control_wedge/*_e2e). todlando builds (.config/nextest.toml [test-groups]+overrides), doyle gates (re-CI 2-3x to confirm RELIABLY green, not lucky). Then deployah cuts.

**Remaining pipeline after green-both-runners:** fold todlando's nextest-test-group commit → re-CI 2-3x (reliable green-both-runners) → deployah cuts v0.13.0 (MINOR, ~counter 27, bump+CHANGELOG+Cargo.lock+tag→sign→publish; tag fires docs-publish.yml but docs ALREADY published ahead) → ping perri to dogfood (she's built both seams, int deferred to binary). REQ-HAZARD-CONTROLLER-WRITER-REORDER + REQ-HAZARD-CONTROLLER-RETAKE-FLOOR (deferred seed) minted. perri F-014/F-015 still queued for post-ship REQs.

**(orig) Remaining pipeline after P1c green:** green PR #26 → deployah cuts v0.13.0 (MINOR, ~counter 27) → verify GH-Pages docs (both adapter seams @8b36b03) → ping perri.

**Docs published AHEAD of the binary (2026-06-20):** to unblock perri without waiting on P1c/the release, dispatched `docs-publish.yml --ref v0.13.0-delivery-control` (workflow_dispatch — its "docs-only refresh between releases" mode; publishes the dispatched ref's docs-site to spt-releases GH-Pages, independent of a release tag). The two v0.13.0 seams were version-SILENT → annotated "since v0.13.0" first (@35cad57) per the doc convention. Live + verified at `https://sabermage.github.io/spt-releases/harness-contract/manifest.html` (+ integration-checklist.html). perri pinged to start the adapter build against the contract NOW; runtime dogfood waits for the binary. P1c is internal — ZERO contract change — so the published docs are final.

**perri findings logged for post-v0.13.0** (F-014 gh_release update has no per-OS asset resolution → 404; F-015 Windows locked-binary partial-extract records new version despite stale binary = silent partial state). Both need REQs after ship; perri waiting on the ping. Kitsubito access: `ssh reavus@kitsubito`, cargo needs `bash -lc`, repo at `~/actions-runner/_work/spt-core/spt-core`, NEVER kill the live `~/.local/bin/spt` daemon. Related: [[don't-wait-proceed-autonomously]] [[no-machinewide-killon-shared-runner]] [[agent-roles]].
