Proof audit, pass 1, for [#32744](https://git.cafe/pingdotgg/t3code/pull/32744), pinned local head [de4008a9e9](https://git.cafe/pingdotgg/t3code/commit/de4008a9e948a6b20ff3deec6304b3e94b0a3e09), branch `fix/issue-32736`, against `main`.

No blocking proof gaps for supported inputs. The committed regression test proves a retained link keeps its URL and loses its active watch. It does not prove complete history preservation, mixed arrays, or multiple watched threads. Those properties are covered by the PR's additional synthetic CLI evidence: I independently checked the uploaded raw before/after payloads, rather than relying on its summary. All six threads and 17 links survive, nine active watch keys become absent, three controls retain byte-identical payload strings, and source captures/file hashes remain unchanged.

The original single-thread CLI/startup transcript remains applicable. The requested `git diff 9f04b777d8 de4008a9e9 -- apps/server/scripts scripts/dev-runner.ts` changes only unrelated ACP mock-agent and speech-catalog files. Its narrower diff for `migrate-dev-db.ts`, its test, and `scripts/dev-runner.ts` is empty. The newer CLI evidence on [f219ff96d1](https://git.cafe/pingdotgg/t3code/commit/f219ff96d124b536fd79bf09e64d8dd71e10dee5) also has an empty diff to the pinned head for those files. The reactor did change since the original capture, but only watch comparison fields and comment pagination accounting; watch-target selection is unchanged. No existing transcript needs recapture for this head. The startup transcript establishes the removed host-read path, not a successful live provider wake, and no live wake is required to prove this seed fix.

Implementation basis: [the new UPDATE](https://git.cafe/pingdotgg/t3code/blob/de4008a9e948a6b20ff3deec6304b3e94b0a3e09/apps/server/scripts/migrate-dev-db.ts#L384), [the committed test](https://git.cafe/pingdotgg/t3code/blob/de4008a9e948a6b20ff3deec6304b3e94b0a3e09/apps/server/scripts/migrate-dev-db.test.ts#L133), [automatic first-start seeding](https://git.cafe/pingdotgg/t3code/blob/de4008a9e948a6b20ff3deec6304b3e94b0a3e09/scripts/dev-runner.ts#L615), and [the link schema](https://git.cafe/pingdotgg/t3code/blob/de4008a9e948a6b20ff3deec6304b3e94b0a3e09/packages/contracts/src/threadPullRequest.ts#L110).

Evidence labels: **U** = committed test inspected, not rerun in this read-only audit; **T1** = PR-body single-thread before/after CLI plus seeded `dev:server` startup transcript; **T2** = [mixed-links/control CLI transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6405d10c65f36f3b/transcript.md), [raw before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/80b09308a1e5b667/raw-before.json), [raw after](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/31bdf9b278e2eb7b/raw-after.json), [driver](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/4656e8ed604cd94f/driver.mjs), and [assertions](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/21e4017101169da8/assertions.mjs); **P** = this audit's synthetic in-memory SQLite probes using the exact UPDATE read from the pinned source.

| Row | Input or entry point and expected behavior | Diff effect / required proof | Committed unit-test coverage | Transcript or other proof | Status |
| --- | --- | --- | --- | --- | --- |
| R1: active watch | One retained stopped thread with one object-valued watch: remove the watch, retain its link. | Changed payload; regression test proof. | U directly asserts surviving URL and SQL-null extracted watch. It does not distinguish absent key from JSON null. | T1 shows before/after CLI; T2 independently proves key absence through raw payloads and `json_type`/own-property assertions. | COVERED |
| R2: untouched controls | No `pullRequests` key; empty array; links without watch, including `endedWatch` history. All must remain byte-identical. | New WHERE evaluates these rows but matches none; test/assertion proof of no collateral rewrite. | U retains no-key fork/settled threads and completes, but never asserts their payload equality; empty/unwatched controls absent. | T1 does not cover them. T2 directly asserts all three controls byte-for-byte before and after. P also confirms predicate behavior. | COVERED by T2 |
| R3: mixed links and history | A 13-link array mixes watched/unwatched entries; remove every watch while preserving order, count, URL, snapshot, stack, endedWatch, and unrelated fields. | Changed array rebuild; data-level test/assertion proof, no UI capture. | U has only one watched link with null snapshot/stack; insufficient alone. | T1 has one link. T2 compares complete resulting payloads with source-minus-watch, uses deliberately nonnumeric link order, and retains all populated history. | COVERED by T2 |
| R4: multiple retained threads | Independently sanitize stopped root, retained fork, and settled root; do not cross-correlate links between rows. | Changed UPDATE applies to every kept row; data-level test/assertion proof. | U retains three threads, but only the stopped root has a watch. | T1 has one thread. T2 retains six threads, removes watches from all three watched threads, and preserves all six completed runs. | COVERED by T2 |
| R5: null watch | `watch: null` alone makes `json_extract` SQL-null, so the row is untouched. With an object-valued watch elsewhere in the same array, rebuilding removes both watch keys. | Predicate is reached; mixed-null payload can change. Null is outside `Schema.optional(ThreadPullRequestWatch)`, so no supported-input runtime requirement. | No input null-watch case; U's expected SQL null is an output assertion, not coverage of this input. | Neither transcript includes null-watch input. P verifies both null-only and mixed-null behavior. | OUT OF CONTRACT; behavior checked, no recapture required |
| R6: malformed payload JSON | Invalid `payload_json` is rejected by existing `copySourceSlice` lineage/visibility JSON extraction before pruning; it does not reach the added UPDATE through either entry point. | No new reachable behavior; no new runtime proof requirement. Direct invocation of the UPDATE would also reject invalid JSON. | No malformed-payload case. | Neither transcript covers it. Existing path inspected; P confirms malformed JSON rejection by the preceding extraction. | PRE-EXISTING rejection; no recapture required |
| R7: manual CLI | `vp run migrate-dev-db` maps to the real script, whose CLI calls `runMigrateDevDb` then `pruneSnapshot`. | Shared sanitizer reached through CLI; short real runtime transcript required. | U calls `runMigrateDevDb` directly, so does not prove CLI argument/launch wiring. | T1 runs real CLI on both sides; T2 repeats it with explicit source/base-dir and successful exit codes. | COVERED |
| R8: automatic seed and startup | First server-capable dev-runner start in a worktree without V1/V2 destination data and with an eligible source invokes the same CLI before starting the server. The seeded watch cannot become a reactor target. | Shared sanitizer reached through automatic seed; real first-start runtime transcript required. | U does not execute dev-runner or the reactor. | T1 shows first-start seeding, Listening, before host-read failure, and after no watch-check failure; retained link remains. Source tracing confirms identical sanitizer and unchanged target selection. `dev:web`, disabled seed, existing data, missing source and oversize source bypass the new SQL and are unaffected. | COVERED; no recapture required |
| R9: evidence freshness | Earlier runtime captures must still describe pinned head's seed behavior. | Source comparison, no new runtime scenario. | U file unchanged from both evidence heads. | Required broad diff inspected; seed script and dev-runner unchanged. T2-to-head seed diff also empty; reactor-target selection unchanged. | VALID for pinned head |

Read-only limits: no source edits, pushes, PR comments, new servers, live database access, or new worktrees. Only synthetic scratch downloads, in-memory probes and the requested public matrix upload were used. This is a proof audit, not a certification of all CI or merge readiness. GitCafe currently reports PR head [f219ff96d1](https://git.cafe/pingdotgg/t3code/commit/f219ff96d124b536fd79bf09e64d8dd71e10dee5); the local checkout was verified clean at the explicitly requested [de4008a9e9](https://git.cafe/pingdotgg/t3code/commit/de4008a9e948a6b20ff3deec6304b3e94b0a3e09). The freshness conclusion concerns that pinned local revision. No runtime model identifiers or non-synthetic data are included.

FRICTION:
forge | GitCafe PR metadata still reports the earlier head while the requested local checkout has the newer merge head; pinned local revision audited explicitly | Refresh PR metadata after the merge head is published/synchronized.
VERDICT: SUFFICIENT
