perf(runtime-host): replace transcript snapshots with bounded pages - #2922
Conversation
bae495c to
4a42648
Compare
641d652 to
70e9da1
Compare
There was a problem hiding this comment.
Superseded by the later human-reviewed adjudication on the same exact head. The earlier automated findings were re-evaluated against #2445 ownership and the Session admission serialization model; its inline comments have been removed to avoid directing implementation toward incorrect owners or unsupported races. See the subsequent review for the final findings.
Astro-Han
left a comment
There was a problem hiding this comment.
Final review
I reviewed exact head 70e9da1702b9cf26b52dd8f7f913a5b21d5bc2db and re-adjudicated the earlier feedback against the actual ownership boundaries.
The core design is sound and should not be rewritten: fixed-watermark durable paging, a separate active overlay, bounded fragments, end-to-end chunk integrity, explicit overlay acknowledgement, and the epoch-19 wire break all serve real invariants.
Migration ownership is intentionally split. After integrating this PR, #2445 should own the Session metadata v22 → v23 transition, target-schema verification, registry publication, and rollback under its single BEGIN IMMEDIATE boundary. Existing inline transcript rows remain readable; #2922 should not introduce a second migration orchestrator or eagerly rewrite historical bodies.
Four issues remain at #2922's own boundaries: persisted access-grant compatibility, cumulative active-ledger scan work, idempotent overlay release during teardown, and unnecessarily late overlay release during full materialization. I recommend revising these before merge.
The previous automated review is superseded. Its legacy-inline migration request conflicted with #2445's chosen contract, and its pending-open revocation race was disproved by the per-Session admission serialization. This review is the final human-reviewed adjudication.
English
中文
|
Astro-Han
left a comment
There was a problem hiding this comment.
I re-reviewed the current head after the latest fixes. The four issues from the previous review are resolved at their owning boundaries: released grant decoding, cumulative immutable-event scan limits, idempotent overlay release, and prompt overlay materialization/release. The pending-open overlay retention is also necessary; release does not enter Session admission, so pendingConsumers correctly protects a generation while another open is awaiting durable bootstrap.
The paging architecture remains the right direction: SQLite is the sole durable transcript authority, the old snapshot/query path is removed, and the watermark, overlay generation, explicit acknowledgement, integrity digests, and epoch each represent distinct invariants. I do not recommend deleting or collapsing those states.
Three remaining edge cases are noted inline. The two P2 items both concern released legacy data paths that are still not bounded at the physical SQLite boundary; the P3 item is a near-capacity credential migration edge.
The required E2E check has failed twice in quote-selection.spec.ts. I do not currently attribute that failure to this PR: 70e9da1..199e621 changes no Renderer, quote-selection, or Desktop transcript-commit code, and the failure matches the previously tracked selection timing class in #2400. The client now releases overlay before durable hydration, but Desktop still commits only after the complete transcript Promise resolves. A trace showing selection collapse or DOM replacement would be needed to establish an indirect causal link. Regardless of attribution, the required check still needs to pass before merge.
Recommendation: revise the two boundedness gaps, address or conclusively rerun the E2E check, then re-review. The protocol replacement itself should remain one atomic epoch-19 slice; Session metadata v22→v23 migration ownership belongs with #2445.
Astro-Han
left a comment
There was a problem hiding this comment.
I approve the current head 199e621131e666a9b08261d6eeb3c3272730d769.
The core protocol replacement is sound: SQLite remains the sole durable transcript authority; the fixed watermark, overlay generation, explicit materialization acknowledgement, integrity digests, connection ownership, and compatibility epoch each enforce a distinct required invariant. The latest fixes correctly close the released-grant migration, cumulative immutable-event budget, idempotent release, overlay-first release, and pending-open retention gaps.
After severity calibration, the remaining inline observations are bounded legacy/capacity follow-ups rather than reasons to reject this protocol slice. They should remain tracked at their natural owners, particularly the Session metadata migration boundary in #2445.
The required quote-selection.spec.ts E2E failure still needs to be green before merge. I found no direct code-path evidence attributing it to this PR; branch protection should remain the independent merge gate.
Replace whole-transcript snapshots with fixed-watermark SQLite pages so session opening and transport work stay bounded as history grows. Keep full materialization as a shared client adapter while establishing the paging contract needed by Desktop's incremental replica. Generated-by: Codex
Move durable fragmentation into SQLite and publish transcript advancement from successful append commits. Bound open responses and active overlays at both per-generation and Host-wide levels, while streaming client reassembly keeps large transcripts from retaining every wire page.
Keep the remote-owner operation catalog aligned with the paged transcript contract after rebasing onto the latest access-control operations.
Bind overlay reconciliation and durable bootstrap pages to one inclusive SQLite watermark so late appends cannot be overwritten by stale active prefixes. Release cache ownership whenever no transcript subscriber remains or subscription opening does not complete, preserving Host-wide overlay capacity.
Invalidate the cached active overlay when the canonical Turn becomes terminal so later subscribers cannot inherit partial presentation state at an unchanged durable watermark. Preserve existing subscriber generations through their own references and avoid cloning the bounded projection before immediate serialization. Generated-by: Codex
Batch active-message reconciliation against the Storage lookup contract so large valid overlays remain attachable at one durable watermark.\n\nTreat transcript pages as the strict ordered stream the protocol guarantees, removing replay-oriented hashing and transcript-sized assembler metadata.
Move active-message reconciliation limits into SQLite so oversized rows are rejected before JSON materialization. Stream RuntimeEvent scans past control-only facts, add an explicit overlay completeness high-water, and retain bounded duplicate-page idempotency. Account the full overlay preparation working set against the Host aggregate budget.
Bound active RuntimeEvent scans before body materialization and retain only a fixed projection input budget. Serialize overlay preparation through a cancellable Host queue, and fail closed when transcript cursors stop advancing.
Acquire transcript preparation capacity before re-entering Session admission and revalidate state after the wait. This preserves global backpressure without freezing live events or terminal publication for the waiting Session.
Persist transcript byte lengths and fixed-size data-plane chunks beside canonical message JSON. Paging now reads only the chunks covering each requested fragment, while the v23 migration backfills existing messages in one linear pass and backup validation keeps both representations consistent.
Chunk only oversized durable records and verify every stored chunk before serving it, preserving inline storage for the common small-message path. Increase the bounded transcript page size within a proven transport envelope so long sessions require substantially fewer serial round trips without adding parallel cursor state.
Make chunked Session messages a single durable payload authority without rebuilding the parent message table during migration. Compact active partial segments before physical fragmentation becomes user-visible, and serialize large transcript pages per connection so valid concurrent reads cannot exhaust the outbound queue.
Avoid synchronous whole-history payload conversion during schema open by preserving legacy inline rows while chunking new large records. Replace cumulative partial snapshot rewrites with bounded tail segments and migrate legacy segment layouts once, keeping long model streams linear without weakening scan limits.
Repack legacy partial segments incrementally instead of materializing complete streams during startup migration. Keep the overlay queue for transient preparation contention, but fail immediately when long-lived retained generations make the requested reservation impossible.
Retry a capacity-rejected open once without a reservation so it can reuse a generation completed while queued, and skip active-overlay preparation for terminal Sessions. Batch legacy partial migration reads by both rows and bytes to retain bounded memory while avoiding per-segment SQLite crossings.
Retain active overlay bytes only while the signed bootstrap continuation still needs them, so long-lived subscriptions do not starve unrelated session opens. Keep legacy partial layouts readable through bounded streaming iteration instead of rewriting every workspace during startup.
Keep overlay page queries replayable until an explicit connection-bound materialization acknowledgement releases both their retained budget and buffer references. Carry the authoritative chunked-payload digest through durable paging so clients reject data-plane divergence after assembly.
A materialized overlay is not safe to retain when its release acknowledgement cannot be confirmed. Terminate the owning connection to guarantee Host-side cleanup, surface a recoverable subscription failure, and let Desktop or CLI rebuild from a fresh subscription.
The client has no transparent page replay path, while the Host already keeps query results replayable until overlay acknowledgement. Remove the synthetic identical-page tolerance and its per-page serialization cost.\n\nShare the duplicated transcript reader fixture and drop tests that only asserted private SQLite layout or mock callback counts, while retaining coverage for observable paging, integrity, recovery, and resource-lifecycle contracts.
Preserve released remote transcript grants while bounding active-ledger scan work before immutable event decoding. Make overlay acknowledgement prompt and idempotent, and keep shared generations alive until pending subscription opens install their references. Generated-by: Codex
199e621 to
69aa62b
Compare
|
Rebased onto the latest |
English
Summary
Replace the full in-memory transcript snapshot protocol with a bounded, sequence-based data plane shared by the Runtime Host and its Desktop/CLI/TUI clients.
subscription.open, then publish lightweight durable-watermark advancement.loadTranscript()API for current clients while assembling pages incrementally.session.transcript.query,TranscriptSnapshotStore, snapshot-expiry recovery, and the 16 MiB durable-history ceiling.The Runtime Host compatibility epoch advances to 19, so the Host and in-repository clients update together. The storage upgrade adds the large-record data plane without rewriting existing transcript bodies at startup.
Performance scope
The old path eagerly read and encoded the complete transcript into a Host snapshot before serving it. That snapshot was limited to 16 MiB, retained history in Host memory, expired while being consumed, and returned at most one message in each 24 KiB request. Long or remote sessions therefore failed outright or paid request latency proportional to message count.
This PR focuses on removing that scalability boundary. An append-only sequence watermark provides snapshot consistency without copying durable history; SQLite pages pack many small messages, fragment large records within fixed limits, and keep only the tail plus active overlay in the open response. This makes full hydration bounded and substantially reduces its request count, but current Desktop/CLI/TUI adapters intentionally continue to call
loadTranscript()and materialize the complete transcript.The user-visible tail-first fast path is a follow-up tracked by #2913: Desktop Main will consume the bootstrap tail directly, commit it without waiting for older history, and load/cache earlier ranges on demand. This PR supplies that follow-up's data-plane contract; it does not claim that Desktop already renders a long session after only the initial round trip.
Verification
中文
概述
将完整内存 transcript snapshot 协议替换为 Runtime Host 与 Desktop/CLI/TUI client 共用的、有界且基于 sequence 的数据平面。
subscription.open返回有界 tail 与 active overlay,后续只发布轻量 durable-watermark advancement。loadTranscript()API,内部增量组装 pages。session.transcript.query、TranscriptSnapshotStore、snapshot-expiry recovery 和 16 MiB durable-history ceiling。Runtime Host compatibility epoch 提升到 19,因此 Host 与仓库内 client 同步更新。Storage upgrade 增加大记录数据平面,但不会在启动时重写既有 transcript 正文。
性能范围
旧路径会先在 Host 中读取并编码完整 transcript,再通过内存 snapshot 提供给 client。该 snapshot 上限为 16 MiB,会在 Host 中保留完整历史,消费期间可能过期,并且每次 24 KiB 请求最多返回一条消息。因此长 session 或远程 session 要么直接失败,要么承担与消息数量成正比的请求延迟。
本 PR 聚焦消除这条扩展性边界。Append-only sequence watermark 在不复制 durable history 的情况下提供 snapshot 一致性;SQLite pages 可以打包多条小消息,将大记录限制在有界 fragments 内,并且 open response 只保留 tail 与 active overlay。这使完整 hydration 具备明确上界并显著减少请求数,但当前 Desktop/CLI/TUI adapter 仍会调用
loadTranscript(),有意保持完整 transcript materialization 行为。真正用户可见的 tail-first fast path 由 #2913 的 follow-up 完成:Desktop Main 将直接消费 bootstrap tail,不等待旧历史即可提交显示,并按需加载和缓存更早的 ranges。本 PR 提供该 follow-up 所需的数据平面契约;它不声称当前 Desktop 已经能在第一次 round trip 后立即渲染长 session。
验证
Refs #2913
Checklist
Does this PR entail a change in behavior?