# Proof audit pass 2 re-audit: PR #22930 corrected captures index

PR [#22930](https://github.com/pingdotgg/t3code/pull/22930), mirror [#22927](https://git.cafe/pingdotgg/t3code/pulls/22927). I re-audited the [corrected index](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3dd1c62e09350813/captures-index.md) against the [matrix](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/61a82c853f284a55/matrix.md) and the [prior audit](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/126c16c1660cd4ca/proof-audit-pass2.md). This pass was read-only: no forge writes, no `gh`, no servers started or stopped, no browser tabs opened, and no state or settings writes.

## Reuse statement

**No media byte changed between the audited index and this one.** Every image and video URL in the corrected index has the same drop ID as in the previously audited index ([04a15c6f](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/04a15c6f5dee9464/captures-index.md)). The only URL changes are three files: `captures.json` was replaced, and `provenance.json` and the pass-2 audit link were added. I re-downloaded all 47 linked artifacts and compared them byte for byte with `/tmp/pr22930-evidence`: **47/47 identical**. The 8 video sha256 values in `provenance.json` match the local files.

I therefore **reuse** these prior results without re-running them:
- the full-frame decode and destination checks in [settled-checks.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/41ac1f1e2e14fe1a/settled-checks.json)
- the exact pixel-delta reproduction
- the authorized narrow-light rebuild: 2,203 px = **0.167%** changed at >16/255, header only (live relative time and the absent "All commits" selector), diff body pixel-identical

No new rebuild was performed.

## Corrections verified

| Prior finding | Correction claimed | Verified |
|---|---|---|
| Video lags the event clock by 0.25–0.76s | `captures.json` per-clip median lag; the index adds approximate video seek times | **Yes.** The revised `captures.json` differs from the old one *only* by added fields, with no existing value altered. `auditedMedianVideoLagSeconds` equals `settled-checks.json` `lag` for all 8 clips (0.76/0.74/0.31/0.25/0.30/0.25/0.60/0.62). All **80/80** narrated pairs (10 per clip) satisfy event = (elapsedMs − record start)/1000 and video = event + clip lag, within ±0.05s rounding. |
| "destination visible" / "Code visible" are 500 ms dwells, not assertions | Dwell interpretation added | **Yes.** In every clip, all 12 dwell events carry `interpretation: "500 ms dwell only; result true is not a visibility assertion…"`. The Script section of the index states the same. |
| Absdiff is not linear ×4 | Wording fixed | **Yes.** All four pair sections say "PIL contrast enhancement factor 4 (not linear ×4)". `prepare.py:28` is `ImageEnhance.Contrast(d).enhance(4)`. The threshold is >16 (`prepare.py:31`), as the index states. |
| Freestyle vs fs-17 provenance | Both recorded | **Yes**, in the index header. `~/.agents/MACHINE` = `freestyle`, and kernel 6.1.102 and Node v24.21.0 match the per-pair environment lines. `provenance.json` records only `machineMarker: freestyle`; `fs-17` appears only in the index. Minor. |
| Per-pair environment | Added | Present in all 4 sections, with the correct SHAs and clean flags. The worktrees are still at [448b8a9186](https://github.com/pingdotgg/t3code/commit/448b8a918694e84137f850c6526d75aacfb2292d) / [0a986b24eb](https://github.com/pingdotgg/t3code/commit/0a986b24ebe66ef3c28d2c2301832bbd95fd0e33), with 0 dirty files. |

**New check (frames at the corrected seek times).** I decoded each clip at each narrated video seek time + 0.15s and compared the frame with the settled start-still frame. At every "trip metrics N …" time, the frame is the Code view at the same diff lines: 1.5–3.3% differing pixels at 1440×900 and 3.5–6.7% at 390×844. I inspected one case visually (after 1440×900 light, trip 1): lines 65–98 are identical, and the residue is the hover ring on the tab plus whole-frame encoder noise. The after final frames match the start (1.6–7.7%). The before final frames diverge more (5.5–20.9%), consistent with the empty state. So the corrected seek times land on the narrated states.

**Clarity nit.** The narration label "trip metrics 1 Summary" is a metric taken *after returning to Code*. A reader seeking there sees Code, not Summary. The Summary and Timeline destination moments themselves (click + lag) have no timestamps in the narration; only `captures.json` and the prior decode cover them. This does not invalidate anything, but "after Summary round-trip" would read better.

**Index defects (new, minor):**
1. The FRICTION table has a 3-column header but a 2-column delimiter row (`|---|---|`, line 180). GFM will not render it as a table.
2. Each pair section says "Rendering environment is the line above", but the environment line comes *below* it.

**What else changed.** It still matches the source: `git diff --stat 448b8a9186 0a986b24eb` shows exactly 7 files under `apps/web/src/components/pullRequest/` (+971/−70). There are no contracts, server, desktop, or mobile changes.

## Bounded claims: still valid?

Yes. The media is unchanged and the reused decode and rebuild results stand, so the row 01/09 partial claims hold as previously verified:
- **Row 01:** explicit Refresh at all 4 viewport/theme combinations. The before build ends with 0 files and no scroller; the after build ends with 7 files at 470 px, within a 10s window.
- **Row 09:** six tab returns at 470 px in both builds. This shows no regression; it does not reproduce a baseline bug.

The index's own disposition (0/34 complete, 01/09 partial, the rest unverified) is accurate and does not overclaim.

## Corrected narration vs matrix sufficiency

- **Corrected narration: sufficient.** Every narrated claim is now backed by a capture, and the three wording defects are fixed. The two remaining issues are cosmetic markup problems.
- **Full matrix: insufficient, unchanged.** None of the corrections add fixture coverage. These are still absent: S/L stub fixtures, split layout, the thread surface, Guide, F-WATCH/F-UPDATE, editor, pagination and errors, selection, desktop, and remote. The live forge clock and the transient commit selector still prevent byte-exact rebuilds.

## FRICTION

| category | what happened | what would have avoided it |
|---|---|---|
| reference frame | My first seek check used the initial-metrics frame as reference. It is only ~0.1s after "settle header then set 470", so header motion inflated the diffs to ~5%. | Use the start-still moment (settled) as the reference frame |
| narration labels | "trip metrics N Summary" reads as the Summary state but is measured on Code | Label it "after Summary round-trip", or narrate the destination click times as well |
| markup | FRICTION table delimiter row has 2 columns for a 3-column header | Lint the generated markdown (`build-index.py`) |
| provenance | `fs-17` is in the index prose only, not in `provenance.json` | Add `environmentLabel` to `provenance.json` |
| scope | 32 rows still need fixtures that do not exist | Build stub-forge S/L/F-* fixtures before the next capture run |

Audit: Claude Opus 5.5 via Claude Code (T3 Code), proof audit pass 2 re-audit.

VERDICT: INSUFFICIENT 01 (partial) 02 03 04 05 06 07 08 09 (partial) 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
