Skip to content

Limit transcript bodies to visible chat panels - #970

Draft
yongkangc wants to merge 6 commits into
net/warm-chat-activationfrom
net/chat-transcript-interest
Draft

yongkangc wants to merge 6 commits into
net/warm-chat-activationfrom
net/chat-transcript-interest

Conversation

@yongkangc

@yongkangc yongkangc commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Every browser currently receives full transcript bodies for every running chat. Sockets now declare the chats displayed in their panels, including split panes, and receive bodies only for those chats. Background chats receive activity summaries that keep previews, unread state, plan mode, and lifecycle updates current. Plan-approval payloads and global control events still reach every socket.

Opening a background chat resumes its cached ledger cursor through #967. Interest is scoped to one socket and re-declared before reconnect replay; summaries racing an activation trigger catch-up without discarding its valid cached prefix. Panel registration is separated from registry coordination to keep both responsibilities bounded.

WebSocket migration: browsers send the complete chat-transcript-interest set; unselected chats receive chat-transcript-advanced summaries. Declarations accept at most 64 raw entries, including duplicates, with canonical 16-digit chat IDs. Invalid declarations preserve the socket's previous set. New sockets start with no body subscriptions. HTTP, CLI, and executor-link contracts are unchanged.

Desktop interface

Mobile interface

…et/chat-transcript-interest

# Conflicts:
#	docs/transcript-ledger-v5-design.md
#	web/src/lib/chat/conversation/conversation-panel-registry.svelte.ts
#	web/src/lib/components/workspace/__tests__/WorkspaceRoot.test.ts
#	web/src/lib/ws/__tests__/reconnect-coordinator.test.ts
#	web/src/lib/ws/reconnect-coordinator.svelte.ts
@yongkangc

yongkangc commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator Author

Implementation head: 3bb8edb, stacked on #967.

The full lint/type check, 8,900 web tests, focused backend/shared regressions, transcript inventory, startup check, and both Chromium warm-switch/gap cases pass. All four delivery scenarios pass on Local and remote controller-dials. All four worker-dials scenarios also pass. The split-panel case needed a longer local startup allowance after two attempts stopped at controller startup; assertions and committed timeouts remain unchanged. The root suite stopped at the existing five-second script timeout; its isolated rerun passed.

Measured decoded JSON for the same synthetic large turn: 129,076 bytes to a viewing socket and 1,542 bytes to a background socket. The browser received nine offscreen summaries totaling 2,707 bytes and no transcript bodies; switching back used one delta request without history HTTP. These are synthetic payload measurements, not compressed wire traffic or a general speed claim.

Desktop and mobile captures are preserved. Litterbox returned HTTP 500 on repeated upload attempts, so the required public screenshot embeds remain blocked. Hosted checks are still running.

CI follow-up in 3bb8edb: the server architecture budget and multi-client Chromium row suite pass. Transcript publication now stays in the interest registry, and the existing browser test checks summaries while hidden, full rendering on activation, and exact-once reconnect replay. The final lint/type check and isolated startup pass. The latest root run stopped at the unchanged five-second search-schema test timeout; all 22 cases pass in its longer-timeout isolated recheck.

@cfal

cfal commented Oct 30, 2026

Copy link
Copy Markdown
Owner

Medium

  • Transcript-interest declarations can retain unbounded identifier data per socket. The parser checks only the deduplicated Set size, without bounding the raw array or validating canonical 16-digit chat IDs (ws-requests.ts). An authenticated or auth-disabled client can therefore submit a 16 MB frame containing millions of duplicate IDs, or 64 multi-hundred-kilobyte unique strings. Parsing blocks the controller event loop, and the latter payload remains retained for the socket. With the default 128-client limit, this can exhaust memory. Reject arrays longer than 64 before iterating and validate every entry with the canonical chat-ID parser; add cases for 65 duplicates and oversized/noncanonical IDs.

No other actionable defects were found in the reviewed change.

Reviewed commit: 3bb8edb248bade4a9b11e4d3b77ebd3be4171464

@yongkangc

yongkangc commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator Author

Addressed the declaration-bound finding in ba67e43.

  • The parser rejects raw arrays longer than 64 before visiting entries. Every entry must have exactly 16 characters and pass the canonical chat-ID parser; duplicates collapse only after validation. Invalid declarations preserve the previous socket subscription.
  • Added regressions for 65 duplicate IDs, a 256 KiB identifier, noncanonical/unsafe IDs, and the accepted 64-entry boundary. Nine rejection cases fail before the fix and pass afterward. Handler tests also prove malformed declarations cannot replace the existing set.
  • Fixed the two Chromium assumptions exposed by selective delivery: the preamble test now reads authoritative history when opening a background chat, and the New Chat test verifies committed source through HTTP rather than waiting for bodies on an uninterested observer socket. Existing focus, scroll, responsive rendering, and content assertions remain.

Validation on this head: 69 shared/backend checks, 35 focused web checks, all five affected Chromium cases, the 429-case transcript inventory, full lint/type check, frontend build, and isolated server startup pass. The root test command stopped at the five-second integration-assertions script timeout; all three cases pass in an isolated rerun with a longer local timeout. Committed timeouts are unchanged. All 29 hosted checks pass on ba67e43; release-only jobs are skipped.

Desktop and mobile screenshots now render in all four PR descriptions, with freshly verified 72-hour image links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants