# Usage-limit recovery — corrected evidence index

Corrected evidence for the usage-limit recovery banner, captured 2026-10-22 in /home/ubuntu/wt/issue-21397, isolated .t3 only. No production source edits, commits, push or PR in this correction. No delegation. Prior evidence remains on disk and public; nothing was deleted.

Base [e54e71d725](https://git.cafe/pingdotgg/t3code/commit/e54e71d725), implementation [42a6c6fa99](https://git.cafe/pingdotgg/t3code/commit/42a6c6fa9922ca5b9a99f49308667a6c0bf48c23), captured head [21f167ed8c](https://git.cafe/pingdotgg/t3code/commit/21f167ed8c18d428343a8fd66461c667296867cb), branch fix/issue-21397. The production banner file is identical between implementation and current head; only the already committed synthetic fixture/seed follow-up differs.

This index supersedes B/C/E claims in the [prior index](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/88f90932caaf510d/evidence-index.md). A, D, all seven static pairs and their 21 pixel views, plus C's mounted-expiry recording are preserved unchanged. The old B-head, E-fault-head, E-resume-head and C-expired-mount recordings are superseded. The old BE-base recording remains a missing-action reference only: its final Saving frame does not prove a completed baseline toggle.

Result: B and E now show completed wake/reverse and resume/cancel states; C now shows the expired route mount. Full reload remains unverified and is not claimed. Route mount after expiry is the accepted correction to that proof step; both paths use the component's Date.now initializer. No production regression was found by the prior auditor or this evidence correction.

## Before/after matrix

| Matrix state | Before: real base | After: real head | Pixel proof | Status |
| --- | --- | --- | --- | --- |
| A 1440 light | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/35efdf0007eb09b3/A-base-1440-light.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/37a92d4f26add21e/A-head-1440-light.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5d3cb545ed297fe2/A-diff-zero-1440-light.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6ff444f43078c0ef/A-diff-8x-1440-light.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d2ccd6174a81645d/A-diff-threshold16-1440-light.png) | verified |
| A 1440 dark | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/393c95da9ed4307d/A-base-1440-dark.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ebd21a5fc75fe226/A-head-1440-dark.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8b7bb84fa3b3c016/A-diff-zero-1440-dark.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8d1fcb46a7ea0828/A-diff-8x-1440-dark.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f403935996a02a26/A-diff-threshold16-1440-dark.png) | verified |
| A 390 light | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/010099c8b578599f/A-base-390-light.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/24b64592a6e65877/A-head-390-light.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8a879ffa62da7c00/A-diff-zero-390-light.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/946181706a731dae/A-diff-8x-390-light.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9c8a15186f525cf9/A-diff-threshold16-390-light.png) | verified |
| A 390 dark | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/cbbd5941eec48ac3/A-base-390-dark.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/54c8073abb865a8a/A-head-390-dark.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/59c28f5d516da113/A-diff-zero-390-dark.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/962a9f5fbc9bf912/A-diff-8x-390-dark.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/264b7d4e56bc1c19/A-diff-threshold16-390-dark.png) | verified |
| B wake/reverse | [Base: missing banner action only](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3ec0065f29902851/BE-base.mp4) | [Wake](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a984551492140307/B-wake.mp4) / [keyboard reverse](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3f3e9ed2080e9317/B-reverse.mp4) | Shared A 390 dark initial-state comparison | completed endpoints verified |
| C expiry | [Base recording](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d49e7f1f914e9452/C-base.mp4); [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/17c5ec4ec2acdcc4/C-base.png) | [Preserved mounted deadline](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ac625e7f7c25dc80/C-head.mp4); [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/21990acd7183a3e6/C-head.png); [corrected expired route mount](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bbfef0f2bba3f334/C-expired-mount.mp4) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b2083dbeff158931/C-diff-zero.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fb713e43c2371e52/C-diff-8x.png) / [threshold16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6dc7a7e758fe2e59/C-diff-threshold16.png) | mounted expiry + expired route mount verified; full reload unverified |
| E rejection/sibling | Same base missing-action reference as B; baseline toggle completion is not claimed | [Rejection](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e422b2723b095523/E-fault.mp4) / [retry](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/759fd0b0c1977c04/E-retry.mp4) / [restore](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9ffa7d0386f7c221/E-restore.mp4); [arm](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bb7454ce578c5c2f/E-arm.mp4) / [wake while armed](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fbc9457c3c0370a6/E-wake-armed.mp4) / [restore while armed](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3da1e13e2fa12c6a/E-restore-armed.mp4) / [cancel](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9da5be30f84e4b55/E-cancel.mp4) | Shared A 390 dark initial-state comparison | completed endpoints + persisted autoResume verified |
| D absent snooze | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ba4712c0fc7e080e/D-absent-base.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/757a8d385e223c1e/D-absent-head.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3283f3e8a5f3cbe4/D-absent-diff-zero.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e972238794f7ffd3/D-absent-diff-8x.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9596e6d9f90d58d1/D-absent-diff-threshold16.png) | verified |
| D unrelated snooze | [Before](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b650cf2143887b01/D-unrelated-base.png) | [After](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f26a51bc8ca6e3f3/D-unrelated-head.png) | [raw](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b4fbc24fbc3f4c62/D-unrelated-diff-zero.png) / [8×](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/0d9faccf6dac408d/D-unrelated-diff-8x.png) / [threshold 16](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/ff8846f05e59f2f8/D-unrelated-diff-threshold16.png) | verified |
| --- | ---: | ---: | --- |
| A 1440 light | 808 | 649 | [865, 633, 1030, 642] |
| A 1440 dark | 803 | 657 | [865, 633, 1030, 642] |
| A 390 light | 3700 | 3320 | [44, 38, 688, 1565] |
| A 390 dark | 3602 | 3389 | [264, 1543, 688, 1565] |

## Corrected recording endpoints and timestamps

Narration is timestamped text in a footer, without audio. Each clip begins with its action at 00:00. For B/E, the second caption starts at 00:03 after the projected state has visibly settled. For C it starts at 00:01.5 (footer displays00:01). Raw footage is neither padded nor looped. Every completed label was inspected in the extracted raw final frame and at 2.1 seconds before the end BEFORE captioning; the captioned final decoded frame was inspected afterward. The proof bundle retains both samples and raw footage.

| Clip | Actual final visible action labels | Duration | Proof |
| --- | --- | ---: | --- |
| [B-wake](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a984551492140307/B-wake.mp4) | Resume at reset / Snooze until reset | 8.09s | persisted snoozedAt=null, snoozedUntil=null; autoResume=false |
| [B-reverse](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3f3e9ed2080e9317/B-reverse.mp4) | Resume at reset / Wake now | 4.99s | keyboard Enter on focused Snooze until reset; persisted matching snooze restored; [Final frame](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bfe27801a7cd82dd/B-reverse-last.png) |
| [E-arm](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bb7454ce578c5c2f/E-arm.mp4) | Cancel auto-resume / Wake now | 5.07s | persisted autoResume=true, snooze=true; [Final frame](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e9bccdd32512bbcb/E-arm-last.png) |
| [E-wake-armed](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/fbc9457c3c0370a6/E-wake-armed.mp4) | Cancel auto-resume / Snooze until reset | 5.15s | persisted autoResume=true while snoozedAt/snoozedUntil clear; [Final frame](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/afc6c07231e8a6d8/E-wake-armed-last.png) |
| [E-restore-armed](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/3da1e13e2fa12c6a/E-restore-armed.mp4) | Cancel auto-resume / Wake now | 5.29s | persisted autoResume=true and matching snooze restored |
| [E-cancel](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9da5be30f84e4b55/E-cancel.mp4) | Resume at reset / Wake now | 5.02s | persisted autoResume=false; matching snooze remains; [Final frame](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8b1a441b23d1e4c2/E-cancel-last.png) |
| [E-fault](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e422b2723b095523/E-fault.mp4) | Resume at reset / Wake now, plus Could not snooze thread toast | 5.14s | browser suppresses one intended wake request, injects typed failure after 2s; persisted state unchanged |
| [E-retry](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/759fd0b0c1977c04/E-retry.mp4) | Resume at reset / Snooze until reset | 5.08s | real wake accepted; both Saving buttons disabled; four programmatic click attempts add zero requests |
| [E-restore](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/9ffa7d0386f7c221/E-restore.mp4) | Resume at reset / Wake now | 5.03s | real reverse accepted, matching snooze restored |
| [C-expired-mount](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bbfef0f2bba3f334/C-expired-mount.mp4) | Resume at reset enabled / Snooze until reset disabled | 4.88s | expired clock established before route mount; visible fixture banner; [Final frame](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/e3ae48b4bb5ca57e/C-expired-mount-last.png) |

B/E browser-local outbound delay is 2000ms, restricted to the synthetic thread. The E fault is a synthetic browser response failure, not a server rejection or accepted mutation. Retry and all other mutations reach the real server. Wake requests carry runId/resetAt/snooze:false, reverse carries snooze:true; resume/cancel carry only runId/resetAt/autoResume:true or false. The complete stopped failed run count remains 1; no provider turn starts.

The [proof bundle](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/43974c77b06d475d/issue-21397-correction-proof.zip) contains raw and captioned clips, SRT narration, raw final/hold frames, captioned final decoded frames, seven read-only projection checkpoints, filtered browser request observations, canonical persisted metadata events, source/fixture hashes, rendering provenance and SHA256SUMS. Eight accepted metadata command IDs each match exactly one persisted thread.metadata-updated event; the suppressed fault command matches none. B's historical persisted wake/reverse states are in persisted-command-events.json; E's armed, armed-wake, restoration and cancellation also have individual projection checkpoint JSON files. No database, pairing token or credentials are included.

## Rendering environment and reproducible fixture

Linux x86_64, Chromium 154.0.0.0, product Browser panel, own automation tab; DPR 2, visualViewport.scale 1, root font 16px, banner font 12px, default system font stack. Narrow web is 390×900 CSS, not native mobile; raw recordings 780×1800. Wide web is 1440×900 CSS; raw recordings 2880×1800. Browser screenshot export resamples wide PNGs to 1280×800; narrow PNGs remain 780×1800. New captioned narrow clips are 780×2020; wide clip 2880×1950. The new footer does not crop or cover the app.

Preserved A pairs use the same fixture/view/theme on base and implementation in light/dark. Corrected B/E use the default dark palette selected through app appearance preferences; browser Date frozen at 2026-10-22T19:00:00.000Z. Reset remains 2026-10-23T08:50:00.000Z. Corrected C uses default light, sidebar 256 CSS px, details closed, expanded composer. Prior static C uses sidebar 208px; its comparison is preserved and not recomputed against the new recording. New B/E begin with the existing collapsed composer; prior A stills show the expanded composer.

For C, first leave the fixture for the New thread route, set browser Date to 2026-10-23T08:50:02.000Z, then click the fixture through the sidebar. Wait until its actual visible recovery banner appears, inspect disabled/enabled buttons, and hold at least 2 seconds. Only subscribeThread was observed for this thread during mount; no metadata dispatch occurred. The real server stays before reset, preserving matching recovery/snoozedUntil, autoResume=false and the same stopped failed run. This establishes route mount after expiry, not a full reload. The preserved C-head recording separately proves the mounted timer crossing reset.

The synthetic fixture and recipe remain committed: [fixture](https://git.cafe/pingdotgg/t3code/blob/21f167ed8c18d428343a8fd66461c667296867cb/scripts/fixtures/issue-21397.json), [seed script](https://git.cafe/pingdotgg/t3code/blob/21f167ed8c18d428343a8fd66461c667296867cb/scripts/seed-issue-21397.py). With dev stopped, run python3 scripts/seed-issue-21397.py matching, then vp run dev --no-seed. Ports in this worktree were 6692/14732. The recipe is a projection fixture, not a coherent event history; backend behavior claims come from real commands and persisted observations. It targets only the checkout's regular non-symlinked .t3 database, clears unrelated projected conversations and cancels sandbox pending work. No live state or other worktree was touched.

## Every visible difference

- A wide light/dark: Wake now appears; Resume at reset shifts left. Banner title/description/composer otherwise retain layout.
- A narrow light/dark: Wake now appears on the second action line, Resume shifts left; labels remain unclipped. Existing info control owns the reset description. Light pair has the declared sidebar-toggle antialias/hover noise at exported x44–72,y38–66.
- C preserved static pair: disabled Snooze until reset appears; Resume shifts left. Sidebar New thread relative time changes 2m→3m because that utility captured its clock before override. It remains unmasked in the diff.
- D absent and unrelated: no visible difference; each pair is pixel-identical.
- B/E interactions: pointer/hover and keyboard focus ring; both buttons read Saving... and disable; header snooze notice disappears after wake and returns after reverse; action labels swap; auto-resume changes Resume at reset↔Cancel auto-resume. Longer labels can wrap onto another action line and move the banner top, especially Cancel auto-resume beside Snooze until reset. E fault adds the exact existing Could not snooze thread toast with synthetic evidence-capture wake rejection text; it disappears before retry's stable endpoint.
- Existing composer expansion/collapse is visible in prior interaction recordings: the long placeholder/model name disappear or return, composer height and banner position change. This is existing focus/interaction/capture behavior, not attributed to the production banner diff. New narrow clips consistently retain the collapsed composer; C route mount expands it.
- Corrected C mount intentionally navigates from a draft to the fixture: breadcrumb, conversation body, sidebar selection and composer change. Expired client time moves the snoozed sidebar item into the active list; header becomes Woke from snooze; relative error/time text becomes Retry after 8:50 AM / yesterday at 7:00 PM. The sidebar remains 256px and details closed throughout this new clip. This recording is not a static base/head delta.
- Prior C mounted-time recording changes relative recovery text as the clock passes reset and swaps Wake now for disabled Snooze until reset. Captions and cursor are recording additions; app pixels were not retouched.

## Preserved pixel method and results

Unmasked whole-surface RGB absolute difference. Raw = no amplification. Amplified = channel difference ×8, clipped at 255. Threshold mask = white iff maximum absolute RGB-channel difference >16/255, otherwise black. Counts are changed pixels, not changed channels. No screenshot masks or edited UI pixels.

| State | Raw nonzero pixels | Threshold >16 pixels | Bounding box in exported pixels |
| --- | ---: | ---: | --- |
| A 1440 light | 808 | 649 | [865, 633, 1030, 642] |
| A 1440 dark | 803 | 657 | [865, 633, 1030, 642] |
| A 390 light | 3700 | 3320 | [44, 38, 688, 1565] |
| A 390 dark | 3602 | 3389 | [264, 1543, 688, 1565] |
| C | 986 | 763 | [198, 102, 1051, 642] |
| D-absent | 0 | 0 | None |
| D-unrelated | 0 | 0 | None |

## Verification, scope and FRICTION

Verification: final raw and captioned frames inspected, ≥2 seconds of completed state in each new clip, visible-state waits before stopping, read-only projection checkpoints and persisted command-event assertions passed. Banner source hash c96d5e4c15f6bdafba4170af1ad1bbd09a52ac50230111f86450790e7f52ca95 matches the unchanged head source. Working tree clean and git diff --check passed. No broad test suite was run for this evidence-only correction.

Scope: web wide and narrow. Electron shares this component but was not launched; native mobile is separate. Settings/palette/provider adapters/contracts/transports unchanged. Existing null-reset, stoppedAt and identity guards plus recovery-aware header wake were inspected in the prior audit. This correction does not claim additional coverage for them.

FRICTION: auth wait landed on pairing; one reload submitted the pairing hash before clock override. A first focus selector hit notice details; that clip was discarded and keyboard activation recaptured after checking the focused button text. An unsupported chained wait locator was replaced with visible-state waits and explicit disabled-state checks. Captioned last 100ms sometimes contained no decoded frame; actual final decoded frames were extracted by updating the PNG through the final second. Canonical events live in orchestration_events; the legacy V2 events table was empty. Sandbox migration warnings for unknown recorded ids 68–70 remained, while the fixture and real metadata commands worked. No alternative browser was used.

Teardown complete: clock/socket instrumentation restored, own tab closed, retained dev session stopped with Ctrl-C, ports 6692/14732 verified unbound after exit. No prior evidence deleted; no production source changes, PR, push, comments or merge.
