# Rebuild lossless sidebar drag evidence, round 2

Synthetic data only, on fs-26 (hostname freestyle), Linux x64. No product files changed, no real database copied, no PR mutation. Before [1da41f9499](https://git.cafe/pingdotgg/t3code/commit/1da41f949950bda57f45dc73effb7543037c844f), after [2a5accc1e2](https://git.cafe/pingdotgg/t3code/commit/2a5accc1e298cb27350a05e410e4ac936be467ce).

## Server and browser prerequisites

1. Create the detached before checkout with `git -C /home/ubuntu/t3code worktree add --detach /home/ubuntu/wt/pr-27691-before 1da41f949950bda57f45dc73effb7543037c844f`, then `vp install` there. The supplied after checkout is `/home/ubuntu/wt/pr-27691`.
2. Each checkout starts with a missing, isolated database. Run `T3CODE_DEV_SEED=0 vp run dev` in each, retaining its process session and reading ports from the dev-runner line. Never migrate/copy from the live T3 home. Capture servers used web6314/server14354 before and web5822/server13862 after. Ports may differ on rebuild.
3. Open each web origin with T3 preview. Pair using `node apps/server/src/bin.ts pair --base-dir <that-checkout>/.t3` from that checkout, navigate its returned URL, and reload if the pairing screen has not auto-submitted. Keep pairing credentials private. Resize to1280x800, DPR2, zoom100%, no device emulation. Browser was Chromium156. Preview has no reduced-motion emulation.
4. Set `window.evidenceCheckout` to that tab's checkout absolute path, evaluate trimmed `seed.js`, then `seed-data.js`. RPC stays same-origin. Archive any automatically created non-evidence empty thread. The synthetic project workspace is `/tmp/lead-27691-r1/evidence-capture/workspace` (create if absent).

## Exact F01 fresh rebuild, including previously missing prerequisites

Evaluate scripts from the scripts bundle in this order, independently on each side:

1. `seed.js`, `seed-data.js` as above, then **`shortcut.js` before F01**. The shortcut registers the `holdingReplay` provider instance using devReplay's command path and `holding-replay.ts`, archives the automatic draft row, deletes41/42, creates settled61/62, chooses dark appearance, and navigates to13. Registration is required even before Working fixtures: the configured instance roster changes provider badge rendering. Keep Holding Replay registered thereafter. Its fixture imports use the after checkout and are shared by both revisions; it is the free Replay agent held immediately before a request, through the real adapter/orchestrator.
2. Wait for route13's empty conversation prompt, with no loading/sync message. Then evaluate `driver.js`, `scenarios.js`, `exact-fixture-variants.js`, `freeze.js`, `gate.js`. `driver.js` freezes Date at2026-11-04T12:00:00Z but leaves performance.now/timers live.
3. Wait until row ages read **1d**, not a cached age from before Date was frozen. The client minute clock may need its next wall-minute tick (up to60s). Do not capture during that transition.
4. Warm the list's content-visibility caches: scroll its viewport in350px increments from0 toscrollHeight, waiting120ms per step; reset0 and wait800ms. Collapsed lists must have rendered their actual60px rows rather than estimated58px intrinsic sizes. Repeat after major fixture/layout changes. This prevents initial/max-scroll drift. Do not override product CSS.
5. Use **preview_act hover at x1000,y40**, outside the sidebar, before `prepare('F01')`. Synthetic PointerEvents do not move the real browser hover cursor. `begin` blurs the active element. Verify the **Toggle main sidebar** button is neither hovered nor focused. The old round's748px difference was this button's hover background, not a provider/update badge. Its rectangle was x13..40,y12..39; the old max channel difference was25.
6. Set functions stores `before`/`after` to owned tab IDs, `run` to a new timestamped directory, and `gate` to gate.js text. Load captureSource.js into the functions orchestration context, then `await lossless('F01','after')` (and before). This helper is tool-side JS, not page JS. It uses page screenshots via preview_snapshot(save:true), never decoded video frames.
7. A fresh second after server used `T3CODE_DEV_SEED=0 vp run dev --home-dir /tmp/lead-27691-r1/evidence-capture-2/rebuild-home --port 15362` (web5823), a new database and new preview tab. Following the above produced **0 changed pixels, max delta0** versus the delivered F01-after initial PNG, including HUD. See rebuild-result.json and rebuild-F01-after-pre.png. Its two500ms-separated initial stills also matched0.

## Remaining fixtures and selected takes

Use the same scripts/coordinates on both sides. Freeze Date only after route content has loaded; wait for cached ages, warm rows, park real hover outside the sidebar and blur focus before each initial pair. Cancel unmatched synthetic pointer99 from toggleShelf before navigation or preparing another scenario. Use an actual preview click on the route row if a programmatic click is swallowed; verify the route before capture.

- F01/F10:40 baseline rows,01–12 pinned,61/62 Settled, collapsed. `scenarios.js`. F01 PNGs from run0530; F10 PNG+MP4 from run0540. F10 snapshots are at the hold after exiting the edge, not while scrolling.
- F03/F04/F12: `exactTwentySettled()` creates71–88,20 Settled total; expand. F03 PNG+MP4 from0540; F04/F12 PNGs from0530. F12 PNG is the outside hold; its inside-edge result is in the retained MP4.
- F02: `exactEmptySettled()` deletes61/62,71–88; no settled rows. PNGs0530.
- F11/F13: `exactWorking()` creates91/92 Settled, snoozes38/39 until2099, creates93 on holdingReplay and starts it. Install exact-shelf-gestures.js. Stop/restart Working93 on both sides within the same UTC minute using restart-working.js so frozen duration text matches. F11 PNG+MP4 from0540, snapshot after edge exit. F13 PNG0530, held Working source (not sortable). Stop93 afterward.
- F09: stop93 and archive all except01/02, both pinned. Actual click route01; light/font16. Install short-gesture.js; capture at Active y285. PNGs0548, after the cached clock was settled. Retained MP4 includes Active→Settled→drop Active→reverse Pinned/cancel.
- F14: restore03–40, unsnooze38/39, repin02, restore two Settled entries, light/font20,390x844. Database deletion tombstones prevent reusing61/62: round2 used101/102 with visible titles61/62. Install responsive-gesture.js and open the real Sheet through its app toggle. PNGs0533 at first held pickup; retained MP4 also shows edge entry/exit. Responsive driver cancels pointer instead of Escape to keep Sheet open.
- F08:1280x800 dark/font16; full-sidebar-harness.js plus full-sidebar-gesture.js. Actual Sidebar with public client atom static snapshot limited to01–06 and300px viewport. Route row stays in collapsed Settled. No server projection edits. PNGs0533.
- F05–07:640x480 dark/font16; marker-harness.js mounts actual SidebarSectionPlaceholder with existing deterministic test geometries,300px scroller, dnd auto-scroll off, visible harness label. PNGs0533. F06 resting bottom370.59375 vs viewport371.59375: **1px inside**, then forced+80 follows80. F05 reveals19, F07 reveals26.
- For a later fresh long-list pass after deletions, restore the same visible data with101/102 titled61/62 and171–188 titled71–88, archiving the Working fixtures. Those aliases do not change row rendering. Warm caches after restoration. Keep ordinary captures on route13, responsive/short on01.

## Lossless snapshot protocol and raw data

`freeze.js` wraps subsequently scheduled intervals and rAF callbacks. `gate.js` wraps the driver's wait. At the scripted stationary hold it updates HUD, samples geometry/pointer, pauses those callbacks, and resolves snapshotReady. captureSource.js then takes a **lossless full-page PNG**, resumes and cancels the gesture. This prevents screenshot transport latency from adding autoscroll frames. No geometry, styles, projections or product handlers are patched. Selected point is end of first1.8s hold for ordinary/harness rows; F09 Active1.3s, F12 outside2s, F13 Working3s, F10/F11 exit holds1s/1.2s. Both sides hit the same driver barrier. `snapshotAt` and telemetry record the sampled values.

fullCaptureSource.js removes the deliberate abort at that barrier, records the complete gesture and resumes after its PNG; used for new F03/F10/F11 videos. All other MP4 URLs remain from round1. New recordings include a brief still while the lossless screenshot is saved. Encoded frames are used only to inspect chapter timestamps, never for pixel diffs.

build-lossless.py selects source runs, copies two initial screenshots500ms apart plus held PNGs, asserts each within-side initial pair and every cross-side initial pair equal at **any nonzero channel delta**, builds initial+held sheets and before/after held comparisons. Diff0 amplifies maxRGB delta>0 as magenta, DiffT uses>16/255. There is no normalization, video resampling or lossy decoding in these diffs. Desktop page PNGs1280x800; H1280x960 and N780x1688 are native screenshot pixel sizes. Each PNG/diff was opened for visual inspection before upload, including unchanged pairs.

All14 initial pairs have0 changed pixels. Held pairs F05–F09,F12,F13 also have0. Other differences lie within sidebar scroller/rows/drag target and the capture HUD. Outside those regions there are0 changed pixels, including composer. F14's full-width Sheet mask is x<389,y112..794 CSS and HUD y15..50; desktop mask x<256 plus HUD x980..1280,y62..139. See manifest and measured-mask check in rebuild script. This is a measured comparison at the selected hold, not a claim that complete videos match pixel-for-pixel.

## Chapter timing

retime.py uses round1 pointer-onset calibration (20fps,50ms resolution) and actual recorded pointer events. retime-new.py writes chapters-new/chapters.json and calibrates replacement videos the same way. build-delivery.py selects the corrected held times and links all artifacts. Every published chapter time was extracted and visually checked inside a stationary hold. F08 is5.60/9.40s on both sides; F09 Active4.40/Settled5.90s (completed drop7.80, reverse hold9.50); F12 outside9.40s both, inside before12.20/after13.10; F14 first3.70/edge8.70/exit9.80s. Normal drag labels follow the pointer and can cover source rows; these frames precede cancellation and leave the claimed HUD, targets or marker readable. F12 after13.10 has expected drag/source text overlap at the bottom; its scroll614 HUD is unobscured. No cancellation frame is labelled held.

## Cleanup and scope

All three owned preview tabs and all three tracked dev sessions stopped; ports closed. Temporary before worktree removed. After checkout's newly created `.t3` removed by literal path; git status empty. Scratch is retained. No commits/pushes/comments/PR edits. Physical touch, macOS trackpad, Electron and native mobile remain unverified. F05–08 are explicitly harnesses; F13 uses a held Replay fixture.
