# PR 25267 — final-head evidence matrix

PR: [#25267](https://git.cafe/pingdotgg/t3code/pulls/25267), [GitHub mirror #25267](https://github.com/pingdotgg/t3code/pull/25267).
Original contribution: bompus:fix/pr-sync-sweep-retention, [e0a39360](https://github.com/bompus/t3code/commit/e0a39360d55d4533b4b06d00fe8a1c44500d54b0).

Captured checkout: /home/ubuntu/wt/pr-25267, takeover/pr-25267, final HEAD daf6e30653a135e15e7c3f7d8cda1a5f8369ddb5; base f88b33a16de988f86782343b348631d11432ddf2.
Final regression SHA-256: 7f643cb44feb2c2d9860afc0ec5e6cab2c0207fdba809d438dc19100b7a35d66. Node v26.12.1, Linux x86_64, machine fs-17.
This replaces the earlier matrix's inspected-head attribution. The earlier 4bcb54d5 audit did not certify this final head. Evidence below was freshly captured against the identified final test and head on 2026-10-26 UTC.

Rows captured: 7/7. Runtime capture checkpoints: 4/4. Successful synthetic requested sweeps: 5/5.
Absolute zero retained completed groups: NOT achieved; counts warm-up/1/3/5 = 0/1/1/1. No active sweeps at any checkpoint. One surviving map must remain visible in the result.

| Path / constraint | Captured evidence | Qualification |
|---|---|---|
| readCache.get caller retention | Same final test: base implementation fails, actual=5 expected=0, exit 1; patched passes all 8 tests, exit 0. Same final test hash in both. | Base source substituted in memory by Vite pre-load plugin; no shared source edits. Public base/patch logs supplied. |
| invalidate and behavior guards | Seven existing behavior guards pass in BOTH controls, and patched retention regression passes. Runtime: 5 actual cache invalidations plus 10 actual get calls. | No host writes. No new behavior tests. |
| Real reactor/service/filesystem runtime | Five links with initial null snapshots, five successful requested sweeps, five summary and five stack transport reads (null stack), each persisted snapshot event then reactor.drain. Actual groups Maps counted via WeakRefs at 0/1/3/5; local snapshots corroborate survivor and its path. 10 PR entry files + revisions; final heap query finds 10 strongly reachable distinct hashed PR read-request keys. | Deterministic forge transport, not real forge auth. Retained counts 0/1/1/1. Final heap path: Database -> prepareCache -> EntryImpl.fiber -> cache.stackFrame -> lazy stack closures -> groups. It is a SQLite prepare-cache path; this is not an exhaustive proof excluding all other paths. |
| detachStackFrame helper | Helper unchanged in final diff; read and invalidate are the changed boundaries. Focused file tests validate behavior. | No independent helper mutation or timing claim. |
| Other service callers | Focused cache suite covers shared invalidation boundary. | No runtime merge/comment/review, refreshAfterTurn, or files-viewed mutation performed; source-derived sharing only. |
| Surfaces and connection modes | Diff contains only server cache and focused server test. No contract/client/provider-adapter diff. | No UI capture requested or needed. No browser/mobile/relay/tunnel E2E claim. |
| Persistence / fallback / longevity | Real filesystem cache at /tmp/ev-25267/caches/pull-requests, normal SQLite state; 294-second instrumented session, 5 distinct PRs and 5 synthetic threads. Tests cover failed reads, store fallback, restart, cancellation, revision persistence, scope isolation and coalescing. | Not multi-hour plateau, capacity, pruning, or a fix for the observed SQLite prepare-cache retention. RSS is diagnostic only and inflated by snapshots. |

## Original minimum capture protocol


1. Coordinate with the test agent; do not edit its file or reset/check out the shared worktree. Capture current HEAD, base SHA, regression file hash, Node version, exact regression command, base failure and patched success. From apps/server run `vp test run src/pullRequest/PullRequestReadCache.test.ts`. For the failing control use the test agent's isolated base-implementation run with the SAME final regression, not a different test and not a reset of this checkout. Include assertion values and process exit status. A green original-PR CI run is not proof of the evolving local test.
2. Use a NEW /tmp/ev-25267. If that path already exists, stop and coordinate with its owner; do not erase or reuse an unknown server's state. From /home/ubuntu/wt/pr-25267 run `T3CODE_DEV_SEED=0 vp run dev:server --no-seed --home-dir /tmp/ev-25267 --host 127.0.0.1` and capture the spawn PID and log outside the worktree. Do not run migrate-dev-db, seed, copy secrets/settings, or access ~/.t3/userdata. Do not start web or a browser. Record the actual port/baseDir from [dev-runner].
3. Bootstrap only synthetic project/thread records through the isolated server's typed RPC/service fixture, rooted at this checkout. Add five distinct accessible, existing read-only PR references in that project, one per round, initially with snapshot:null. No host PR writes. Use ordinary existing forge CLI auth if needed; do not copy T3 live state. Auth failures or host-rate-limit pauses invalidate a round; report them rather than counting an empty sweep. A deterministic fixture replacing only the forge transport is acceptable if explicitly labeled; keep the REAL reactor, PullRequestService and filesystem PullRequestReadCache.
4. For each round i=1..5, link the next distinct PR through thread.pull-request.link and await that PR's persisted thread.pull-request-link-updated snapshot update. Initial null-snapshot links automatically enqueue requested sweeps. To request explicitly use typed RPC `pullRequests.invalidate` with `{reference:{projectId,host,repository,number}}`, omit filesViewedOnly. Its handler invalidates and calls requestSync; RPC return only confirms queueing, NOT sweep completion. Within an in-process fixture await reactor.drain after the command/event is applied. With an external capturer confirm sweep return using an inspector breakpoint/function-return observation; an unchanged snapshot need not produce another persisted sync event. Do not claim an event proves the entire worker drained.
5. Never reread earlier keys during the five rounds; run the requested sequence promptly, before the minute timer or five-minute quiet cadence adds uncontrolled reads. Record extra timer sweeps if any. Five PRs stay well below the 512-entry bound. Every requested sweep exercises scope invalidation and summary read; record whether the conditional stack read actually ran. Do not demand stack UI or a real stack mutation.
6. At warm-up and after completed rounds 1, 3, 5, take a server heap snapshot. The unchanged server installs SIGUSR2 -> v8.writeHeapSnapshot; use `kill -USR2 <confirmed-server-pid>` and await its 'Wrote heap snapshot.' log. The spawn PID may be a runner: if necessary find the owner of the recorded port with `ss -H -ltnp`, confirm /proc/<pid>/cwd is this checkout's apps/server (or checkout), and confirm it is the isolated server before signaling. Never signal a PID selected by name/path pattern. Snapshot path is printed in the isolated server log under its configured logsDir. Use a local-only inspector/CDP HeapProfiler.collectGarbage before snapshot if the capture tool requires explicit GC, enabled only on this owned process; do not expose an inspector port remotely.
7. Count unique actual sweep groups Maps by retaining paths through PullRequestSyncReactor per-sweep closures and Effect CurrentStackFrame/cache lookup fibers, not all Maps and not cache files or RSS. Save the counting script/query and snapshot basename with the transcript so the count is reproducible. Separate completed-sweep maps from any in-progress sweep. At quiescent capture the intended result is no cache-retained completed-sweep groups; if one remains, show its retaining path rather than silently excluding it. An active sweep may legitimately retain its current map. Regressions must distinguish released callers while the cache service remains alive. If an inspector WeakRef probe is used instead, keep only WeakRefs, cross a JS job boundary before GC, avoid debugger strong references, and label instrumentation and the exact completion signal.
8. Minimal transcript fields: revision/test hash; isolated command/port/home/server PID; fixture kind and project/thread/link counts; successful summary/stack read counts and invalidations; completed sweep count; at warm-up/1/3/5: active_sweeps, retained_completed_sweep_groups, snapshot basename/count method; base regression failure and patched success; cleanup of only the server processes captured at spawn/confirmed port ownership. Upload only sanitized transcript/matrix, not raw auth logs or heap dumps. A five-sweep synthetic result is short-run proof, not a multi-hour production claim.



## Capture qualifications and friction

FRICTION: First driver used source='linked', rejected by the real event-store schema; no link or successful sweep was counted. Correct source='manual' is in the uploaded driver.
FRICTION: Driver initially asserted absolute zero and stopped after round 1. Heap inspection found the SQLite prepare-cache survivor. The assertion was removed without excluding that map, then the same owned server resumed at round 2. No source implementation changed.
FRICTION: Five timer sweeps were recorded alongside five requested sweeps by checkpoint 5. They caused no extra summary or stack transport reads. Snapshot capture/investigation crossed minute boundaries; original keys were never reread. Entries have 60-second TTL, so older values expired during the investigation; cache eviction is lazy and residency is separately inspected in the final heap query.
FRICTION: This is an evidence-only handoff; it does not certify zero groups retention throughout the real server, or claim production memory stability. Both supplied reviewers were MERGE, but no new reviewer result or merge authorization is inferred.

All seven owned process PIDs stopped and disappeared; port 14813 closed. Worktree remained clean and at the captured head. No pushes, PR comments, watches, merges, browser use, live userdata access, or published raw logs/heaps.
