fix(acpmux): keep capped remote turn openers across restart
A cold capped remote chat lost its turn's prompt in the persisted peer copy, so a completed turn could first draw expanded and fold only after attach. Keep the opener in the existing bounded snapshot and forward it in peerCopyTail before the peer handshake. Preserve #33155's stale/generation provenance and the render changes owned by #33460.
Leo, November 3: "the text shows up right on click but the actual thing loads a second later" and "you should be able to simply see the text rendered instantly wherever it is"; "even for remote things it should be fast".
The Rust store keeps one prompt before its retained run, carries it through restart, and replaces it when a newer prompt is evicted. A tighter read cap selects the matching prompt from retained records first. Steers, other sessions, obsolete generations and malformed openers are excluded. The opener shares the existing head and memory limits and must fit the response byte budget; an oversized opener is omitted without losing the tail. Old snapshots still open (the field defaults absent), and older binaries ignore the added field. Sign-out erasure still removes this same store. No synchronization or new store is introduced.
Background newest-page reads opt into the same turn-opener lookup already used by attach, so their persisted copies have context too. Ordinary history reads keep their existing cost and wire shape. Older peers ignore the optional field; they acquire an opener once a supported attach or a prompt in captured records supplies it. There are no new timers, retries or observers, and no Swift changes.
Design: leo-workspace design/chat-transcript.md, disk-backed instant transcript opening and its settled/replaced record (leo-workspace#2727). Scene: agent-pane.peer-copy/cold-long-chat-connecting. This change supplies existing rendering data; it adds no visual control. The cached capped completed-turn regression exercises the previously missing opener before any handshake. Related diagnostic: cmuxterm-hq#6338, instant switch.
Prior art read and acknowledged: #33207 (sign-out erasure), #28626 (bounded background peer read-ahead), #27991 (allocation-free size accounting), #25474, #25473, #25449, #25447, #25446, #25505, #25445, #25448 (snapshot adapter/store/protocol). #33155 is preserved, and #33460 owns cached render preparation. No duplicate tail reader or render path. The added read-ahead request paths were checked manually against #29632 (prompt index), #28750 (read-aware reports), #27614 (superseded output) and #28626; the supplemental prior-art tool reported NOT CHECKED because its broker GraphQL route was unavailable. None of those existing paths is replaced.
Performance:
| Metric | Before | After | Delta | Harness/run |
|---|---|---|---|---|
| Tiny cold persisted snapshot RPC read, median of 3 | 0.274 ms, opener absent | 0.289 ms, opener present | +0.015 ms | Same fixture/toolchain; run 41619801892, performance.json |
| Turn prompt available before handshake | Missing on capped persisted copy | Present; focused regression passes | Fixed missing context | Web red/green evidence, run 41622864017 |
Current head d6bbefa3890c52621e0fa738ee8f37049b9785ca is the bot merge of base 4bfbe033b119ae433d8a53892e4703756145d3f4 into reviewed head 6b277cb8. The PR patch against its respective base is identical before/after (nine files, +347/-9; stable patch ID eb83b676b43607d32fbc195bbec6e68529ecfc7f). The review carry is requested and new-head routed checks are in flight. The runs below remain evidence for their named product head, not claims about the new-head checks.
These microbenchmarks measure a six-record fixture read after a fresh store instance, with OS caches warm, not click-to-frame latency or a GCP peer. No native final-frame claim is made.
Verification at reviewed product head 6b277cb8a8c15610e073ef6f02b1df59c406156d (before the bot base merge): the first runs passed all 69 snapshot tests, the attach/read-ahead integration test and 70 focused web tests, then failed while preparing the red comparison because the CI snapshot has no ancestor history. Corrected Rust run 41619801892 and web run 41620261890 embed the inverse product patch and preserve the same tests and toolchain. The corrected Rust run passed 69 snapshot tests plus the attach/read-ahead integration test; reversing the product patch caused the capped reload and read-ahead assertions to fail as expected. The corrected web run passed all 70 focused tests; with the adapter removed, both opener assertions failed. Its overall job failed on seven Event-type errors in the existing streaming-flicker test and a harness assertion-output matcher; the corrected explicit base comparison run 41622864017 is green, proving the same seven type diagnostics with and without the product changes. The earlier harness failure is not counted as red proof. The same capped-reload, attach/read-ahead and shared-web opener regressions run with the product changes removed to establish red/green. The rejected/oversized-opener test is a safety guard that also passes on base; it is not counted as red/green evidence. Independent Opus 5.5 medium SHIP is posted at that reviewed product head; the finished webview workflow 41617402355 is green at that head. Clippy matches base push 3534e7b7bcf149c79d7e17e5af8b73595b03f485, run 41615680726: the same unused notify::Watcher import and all three ratchet failures (acpmux indexing 693/686 and string slice 95/94; cmux-host indexing 1/0). Gallery health shards 0ā5 name the exact cross-PR flaky states already filed in #33516: Settings font picker, git-actions include-new/keyboard, and RTL path picker. This diff does not render those controls. Nonblocking review follow-ups: #33642 (normalize/revalidate reload opener), #33643 (skip unchanged page header remeasurement), #33644 (classify safety guards separately from red/green proof). The owner has prepared the first two fixes and a durable test comment for a separate follow-up PR. Risk: matching the wrong prompt would change a completed turn's initial grouping; tests cover read caps, eviction, restart, invalid prompts and session recreation.
š¤ Generated with Codex
Agent session: agent session