# PR #23624 proof audit, pass 2

AFTER `cfee52fc24f56169ed4c0ce48759ad1ff9a7f655` (~/wt/pr-23624 HEAD, verified). BEFORE `8d3b061121fe65669d5d43d011b48cd3027a4108` (run-before.log header; `git diff 8d3b061121 f054d1b8 -- apps/server/src/vcs` is empty). git 2.43.0, Linux 6.1.102.

## Integrity

- Local driver sha256 `95c72e8b…0f732c4`, matching the claim. The uploaded driver, downloaded to `audit2/driver.dl.ts`, has the same sha256. The uploaded captures.md is byte-identical to the local one.
- captures.md vs jsonl: 75 records (38 after, 37 before) against 76 table rows. Tree status, ms, index sha prefixes, unchanged flag, fresh read-tree and re-add counts, and path agree for every record. The extra table row is R20 old-mtime assume-unchanged BEFORE, which is listed as "no record: vitest 180 s timeout", consistent with the jsonl count. R12 assume-unchanged BEFORE is `ok:false` (main fails with "Cannot rebuild a checkpoint index for non-cone sparse checkout"), and the table reports that correctly. The real index is unchanged in all 75 records.

## Rows

| row | status | note |
|---|---|---|
| R1b skip-worktree | PRE-EXISTING-GAP | DIFF on both sides, identical (tree dcc278 = HEAD blob vs wt 366226) |
| R1b assume-unchanged | CONFIRMED | MATCH; AFTER reuses the index (re-add 1), BEFORE takes the fallback |
| R2a both | CONFIRMED | MATCH both sides; AFTER re-add 1 |
| R2b both | CONFIRMED | MATCH both sides |
| R4 both | CONFIRMED | MATCH both sides |
| R5 both | CONFIRMED | MATCH (working content captured, not the staged or HEAD blob) |
| R9 both | CONFIRMED | MATCH; sharedindex.* hashes unchanged |
| R11 skip-worktree | PRE-EXISTING-GAP | DIFF on both sides; independently rerun, see below |
| R11 assume-unchanged | CONFIRMED | MATCH (also in the rerun) |
| R12 skip-worktree | PRE-EXISTING-GAP | DIFF on both sides (non-cone, same mechanism) |
| R12 assume-unchanged | CONFIRMED | AFTER MATCH; BEFORE capture fails, so the PR improves this row |
| R13 both | CONFIRMED | fallback on AFTER as designed, MATCH |
| R14 both | CONFIRMED | MATCH, reuse path, 4 odd paths |
| R15 both | CONFIRMED | fallback on AFTER as designed, MATCH |
| R16 both | CONFIRMED | fallback on both sides, MATCH |
| R17 sparse / non-sparse | CONFIRMED | MATCH. Note that `s` on sparse took the reuse path, not the fallback the body lists, because the scratch read clears S on the present in-cone file and leaves `h`. |
| R19 non-sparse both | CONFIRMED | capture and restore MATCH |
| R19 cone-sparse skip-worktree | PRE-EXISTING-GAP | capture DIFF and restore writes the stale blob back, identical on main |
| R19 cone-sparse assume-unchanged | CONFIRMED | MATCH, restore MATCH |
| R20 (6 rows) | CONFIRMED | AFTER 294 to 630 ms; main's flagged rows take 138 to 171 s, rehash 25,001 files, and one exceeds 180 s. "2 rehashed" is one path read twice. |
| R21 both | CONFIRMED | MATCH |

## Rerun (R11 skip-worktree)

1. Plain git (`rerun-plain.log`): cone, `--no-sparse-index`, `sparse.expectFilesOutsideOfPatterns=true`, `update-index --skip-worktree in/a`, same-size edit with mtime pinned.
   - Real index: `S in/a`. A scratch copy read with the capture's `-c sparse.expectFilesOutsideOfPatterns=false`: `H in/a`. Read without that override: `S in/a`. **This confirms the claimed S-clearing.**
   - With default `core.trustctime=true`, `add -A` on the scratch copy **captures** the edit (366226), because ctime changed.
   - With `core.trustctime=false` (set by the driver's `initRepo` and by the PR's own INSP test), the tree keeps the HEAD blob dcc278: **DIFF reproduced**. The same happens even with S kept.
2. Real driver at cfee52fc24, sha256 verified, `-t R11` (`rerun-driver.log`, results in `cap/results-audit2rerun.jsonl`): skip-worktree `ok:true`, tree DIFF `"in/a": tree dcc27807b2 vs wt 366226fb97`, `tagsBefore [S in/a, S out/x]`, fresh read-tree 0, re-add 0, real index unchanged. assume-unchanged gives MATCH with re-add 1. The scratch file was deleted, and the worktree status is clean.

**Cause:** confirmed but incomplete. Git clears S on the present in-cone file in the scratch index, so the PR's scan never sees a flagged record. The entry keeps its real stat cache. The edit is then missed only when mtime, size **and ctime** all match: here that means `core.trustctime=false` plus a pinned mtime. With trusted ctime, a normal edit is caught.

## Judgement

- **Not a regression.** main 8d3b061121 shows the same DIFF with the same mechanism (reuse path, re-add 0) in R1b, R11, R12 and R19. The PR loses no change that main keeps. Every other uncovered row matches on AFTER, and R12 assume-unchanged goes from a capture failure to MATCH.
- **Realism:** low. It needs a present in-cone file manually marked skip-worktree, `sparse.expectFilesOutsideOfPatterns=true` (otherwise Git clears that S in the real index too), and an edit that leaves size, mtime and ctime cache-equal: `trustctime=false`, or a filesystem whose ctime is unreliable, as on the SMB report, combined with an mtime-preserving write. It is a real but narrow pre-existing gap.
- **Body claim is inaccurate as written.** "cone sparse checkouts, with and without a sparse index … the snapshot had the working-tree content" does not hold for an in-cone skip-worktree file that is present and edited same-size with mtime and ctime unchanged. It holds for assume-unchanged and for deleted in-cone skip-worktree files (SPARSE2). The author should narrow that bullet or document the gap. This needs a body edit, not a code change.
