# W3/W4 retake reproduction

The two real dev apps run from their own installed checkout: before 2359643cffa6ba9ee84d6f2694b935de54a8013e and after e3d7260bc6e260051d705492bf64c867bba4d976. No tracked files were edited. Every dev launch uses T3CODE_DEV_SEED=0. Never use the VM's live database.

1. Create the detached base worktree with the supplied command and run vp install there. Save the head checkout's previous synthetic .t3 aside. Start each app once with control.mjs; wait for its own migrations and startup authentication link, then stop its tracked process group.
2. Write 321dbe4b-8608-46c2-a0f4-d53c9d1c5980 to both isolated .t3/userdata/environment-id files. Run `node seed.mjs /home/ubuntu/wt/pr-28084 <scratch-directory> 321dbe4b-8608-46c2-a0f4-d53c9d1c5980`, with fixtures.json beside the driver. This is the reviewed prior seed, writing nine schema-checked events through the real EventSink. With both servers stopped, use SQLite backup to snapshot this isolated database and copy it to base's independently migrated database. No database is uploaded.
3. Start both with control.mjs, with live server clocks and timers. Open fresh incognito T3 preview tabs for their separate origins. Navigate each to its favicon-32x32.png first and clear origin storage with clear-client-cache.js before importing the saved composer draft; this prevents a prior cache sequence from surviving a database restore. Pair using each startup link. Set freeform 390x844 and light appearance. Apply settings-only.js and reload, then navigate to the environment/thread route in the fixture. Settings preserve the prior Inter/system font setup, 16px interface, 14px prompt, rich text off, zoom 1 and glass opacity 80.
4. On BASE, expand the composer and choose Replay (dev), search Multi turn, choose it and dismiss the model picker. Evaluate the reused web-driver.js. Paste `Please consider this quote:\n` + the generated long.marker + `\nEnd of note.` through proof.paste, which dispatches an actual composer paste. Wait for localStorage's t3code:composer-drafts:v1 to contain the exact prompt. Save only that draft and client settings to base-saved-draft.json. Reload base. Import those two saved localStorage values into the fresh head origin and reload head. No timeline/cache/sequence state is transferred.
5. Wait for the composer, loaded fonts, no pending resources, and no Syncing messages indicator. Hover the breadcrumb equally on both sides. Apply setup.js: the default Date constructor is fixed at 2026-11-03T01:00:00Z while Date.now stays live, so reconnect/sync timers continue. Server clocks remain live. The actual sends were synchronized and both display 3:01 AM. Carets are hidden equally; animations and glass styling are unchanged. Preview has no reduced-motion emulation.
6. Evaluate web-driver.js, then driver-b-retake.js on each tab. Start each preview recording, then schedule proof.runB1() without awaiting its promise. It opens the pencil at 10s, types a comment at 14s, saves at 17s, reopens at 21s, clears at 24s, saves at 27s and reloads at 31s. On base the unavailable controls are logged, leaving the raw draft unchanged. Wait for the new page's fonts and thread sync; reapply setup.js, hover the breadcrumb equally and capture W3. The no-comment draft bytes after head's clear/save/reload equal base's saved bytes exactly.
7. Re-evaluate the drivers after reload. Schedule proof.runB2() on both sides. It preserves the reloaded no-comment prompt, clears at 3s, selects the 631-character source at 5s, cites at 7s, attempts Cancel at 11s (head removes its new chip; base has no editor), clears/restores the preserved prompt through the composer at 14s, sends at 18s, blurs at 20s and opens the last sent no-comment chip at 30s. The actual user messages are persisted identically; persisted-final-send-proof.json includes their texts and SHA-256. The deterministic Replay response is outside the citation proof; no live Pi-provider run is claimed.
8. At each still, await fonts and all current animations, verify no sync indicator/pending resources, and take two full-surface preview screenshots 500ms apart. Compare decoded RGB pixels and accept only exact equality. W3 has timeline scrollTop 0 and composer scrollTop 0; W4 has timeline scrollTop 21 on both sides. W4's popover root had computed opacity 1 and zero active animations; its default glass background is retained. The PNGs are native 780x1688, not crops/resamples. W3 is around 44-47s of recording B and W4 around 79-80s.
9. Stop the preview recordings. Review both contact sheets, important full-resolution video frames, both PNGs and both diff images per row. generate-diffs-final.py computes maximum absolute RGB-channel differences: Diff0 marks every nonzero difference at full magenta; DiffT marks >16/255. Unchanged pixels retain the before image. Sheets label all four columns.
10. Upload with ghdrop upload -m. Stop only the tracked server process groups, close the two preview tabs, confirm all four ports closed, remove the detached base worktree and this step's scratch directory. Leave the lead's head worktree and parent scratch directory intact. Do not edit the PR body.

recording-final-events.json preserves the B1 and B2 checkpoints and monotonic action timestamps. In the continuous videos B2 starts at approximately 47.5 seconds. The recording includes the genuine reload splash and transient Send/provider state; the paired stills are taken only after those states settle.

The linked B-before.mp4/B-after.mp4 are 30 fps hold-preserving encodes of the preview tool’s sparse variable-frame-rate originals (B-final-before.mp4/B-final-after.mp4 in the evidence archive). No crop, overlay or timing edit was applied. Use normalize-recordings.sh to reproduce the encode.
