Skip to content

Catch up desktop chats from the newest page - #29125

Merged
brennanb2025 merged 39 commits into
mainfrom
brennanb2025/nc-perf-catchup-current-requests
Oct 17, 2026
Merged

brennanb2025 merged 39 commits into
mainfrom
brennanb2025/nc-perf-catchup-current-requests

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​97 $\color{#cf222e}{\Huge{\mathbf{−}}}$​52 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​45
Prod 8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​27 $\color{#cf222e}{\Huge{\mathbf{−}}}$​5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​22

ELI5

Returning to a chat after a long reply can pause while the desktop replays every saved revision it missed. The desktop only needs the newest conversation page to catch up; older text can load when the person scrolls.

What Changed

A supported desktop replaces a gap larger than one page with the newest bounded page. Short gaps still replay exactly. Pending approvals and questions remain available through the independent current-request contract in #29121, and accepted sends settle through #28993. A desktop must support both contracts before receiving history-replacing catch-up. Older desktops retain exact replay; existing phone behavior stays compatible.

Why

This uses the existing paged history and host subscription rather than replaying work proportional to every missed revision. Current decisions stay independent of whichever history page is loaded. It avoids pinning old rows or treating approvals as a special catch-up case.

This is the reviewed replacement for #28951, preserving that PR's reviewed history without a force-push. Stack: #28993, then #29121, then this PR. Requested by @BrennanKB5.

Linked Issue

Native-chat performance review requested by @BrennanKB5; original change tracked in #28951.

Visual Proof

Actual hidden Electron on isolated GitHub Linux runners, built from the reviewed source commits. A deterministic command-line provider exercised the real host, read owner and rendered controls in a folder workspace; no renderer request collection was injected. Runtime run.

Before (#28993): a child approval has fallen outside 607 newer messages and its control is absent.

Before: pending child approval missing

After (this PR): the complete approval stays available outside the loaded history page.

After: approval remains answerable

The grouped question also stays answerable through the existing card.

Grouped question

Rendered answers and removal, backward wheel paging, hidden-send settlement, owner-end removal and quit/relaunch ran. Ordinary short replay also passed on both heads; a separate fresh-window prerequisite run retained all loaded messages (run). A strict retention check after backward paging trimmed nine old rows on both the prerequisite and its base, an existing retention boundary. The separate paired bridge transport run below now certifies huge payloads and explicit required-text metadata; screenshots remain evidence of rendered controls.

Testing

Head 4c2a7d7 adds the catch-up policy and capability compatibility case to prerequisite 422766b. Round 3 correctness and dedicated transport/performance source review found no new proven issue. Final source readiness and the end-round architectural decider completed. The full PR workflow and its PR checks passed aggregate succeeded on this exact head, including all five unit shards, static analysis/typecheck, wire compatibility, mobile verification, packages and relay integration. The host current-request flow and bounded catch-up contracts passed. CI run. The final-stack Linux benchmark passed on this exact head and the direct prerequisite. Rendered backward scrolling, off-page approval/question responses, send settlement, owner end and restart passed in the isolated run. Ordinary short replay passed on both heads, including a fresh-window prerequisite control. The paired bridge transport checks below also passed. No checks, installs, builds or apps run on the development Mac.

  • Final hidden Electron comparison, full-window screenshots and response proof
  • Targeted catch-up/current-request contracts pass
  • Exact prerequisite and final stack measured with the same workload and runtime

Review

Independent architecture review required complete current requests before enabling desktop snapshots. That contract is a separate prerequisite. Fresh round 3 correctness and transport/performance review of both source heads found no new proven issue; final source readiness completed with no new proven high-severity regression; the remaining transport evidence is now complete with the limits below.

Agent skill upstream boundary

  • Not applicable; no upstream skill implementation copied.

Notes

Intended differences from the common pattern: keep the existing 200-row and projected-byte page policy, use the execution host's saved conversation facts, and negotiate independently updated consumers. Temporary difference, tracked follow-up: pre-decode journal replay byte admission; the initial raw row read is not byte-preflighted. Complete current-request memory still scales with actual pending work.

Historical numbers on #28951 remain separate from the measurements below. The original history-only control and complete current-request helper measurements were run separately; neither measures browser painting or network latency.

Checklist

  • Focused on bounded desktop catch-up and its required consumer admission
  • Problem, user-facing before/after, mechanism and alternatives explained
  • Exact-source before/after Electron screenshots attached
  • Final source correctness, performance, compatibility and readiness reviews complete
  • Cross-platform, SSH, phone and mixed-version behavior considered
  • Full PR CI green on exact final head

Pre-existing desktop and phone Cancel limitations for a child prompt after its parent turn ends are deferred; this change preserves the answer path and does not certify prompt-only Cancel.

Final-stack measurements

Same Linux host (Intel i3-12100F), Node 26.1.0; direct prerequisite 422766b923c versus this head 4c2a7d717b8. Each case has 300 older messages, 5 warmups and 31 measured samples. These times include history subscription, JSON decoding/reduction and complete independent pending-request adoption through production helpers. The child approval and required grouped question start outside the loaded page.

Missed output Prerequisite p50 / p95 This PR p50 / p95 Journal rows / frames, before → after
20,000 revisions of a reply growing to 32 KiB 262.936 / 296.338 ms 1.154 / 1.561 ms 20,099 / 100 → 201 / 1
20,000 distinct 4 KiB messages 350.373 / 422.345 ms 9.986 / 11.516 ms 20,099 / 100 → 201 / 1

Both heads preserved exact final content/cursor, complete request payloads and full backward reconstruction. Unrelated output caused no request refetches. Short 200-row gaps retained exact replay and identical frame/byte counts. Retained conversation items are still scanned for current-work publication; this is no claim of constant total cost or constant memory.

The same isolated Node-only launcher and pinned minimal dependencies were used on both heads. Production source stayed at the exact commits; a package-manager bootstrap-only lockfile edit during setup was preserved as evidence and restored. This setup differs from the historical launcher, and shared-host load was not isolated. The helper excludes outer host/RPC dispatch, capability negotiation, real bridge/network behavior and React painting; rendered Electron evidence is attached; completed transport checks are reported separately below.

Existing question-card behavior observed during QA: a blank required last question displays Skip, but clicking it leaves the card unanswered; entering text and choosing Submit works. The card code is unchanged from the base and this is deferred with the existing child-only Cancel limitations.

Paired transport validation

Paired bridge run passed on the exact successor; nine relevant request/reader/transport source blobs are identical on the prerequisite. Production bridge modules and an actual encrypted connection delivered 5,774,314 bytes in 235 sequential reads, including a 1,048,911-byte request body. The largest bridge frame was 51,270 bytes, with one read in flight. The assembled JSON matched the host exactly, including all four generic approval options and explicit required-text metadata. Twelve subscription events (67,078 bytes) remained unacknowledged during the transfer; this did not fill the event window. Capability simulation correctly rejected an unsupported read, omitted the marker, replayed eight rows exactly, recovered after terminating the owned socket and stopped delivery after disposal. This exercises a scripted page endpoint, not a native phone WebView. The earlier run passed the main transfer and failed only because the compatibility probe supplied an invalid UUID; that harness input was corrected.

Native phone UI, an actual older binary, SSH transport and a late RPC reply after disposal were not exercised by this run. Owner replacement, unsupported openings and late-completion rejection passed the automated exact-head contracts.

@brennanb2025

brennanb2025 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Current status: review complete, real-agent QA passed

Final head 285256df2b6b3c50db65785c1fd173397bad8f0b. #29121 has merged into main (squash 8c1ade9); this PR now targets main, and the head merges current main, including the line-limit fix #29869. Its diff against main is only this PR's change (15 files). The CodeRabbit fix described in the next paragraphs (7776abf, reopen once per failing current-request version) shipped with #29121. The full PR workflow and its aggregate passed on this head, and real signed-in Claude QA passed on this exact head (see the last section): an off-page child approval answered with one Allow, scrollback, a hidden send with no Sending bubble, zero subscription reopens over 60 s, and a restart with all 241 items unchanged. Native phone UI, SSH transport, an older binary and Codex were not exercised by real QA. Earlier heads named below are history.

A pending child approval or question could disappear when its history row left the loaded page. The reviewed stack separates current decisions from paged history through the execution host’s existing owner and bounded independent reads. Returning after a long hidden reply now loads the newest page while keeping pending decisions available; short gaps and older desktops still replay exactly.

Three source rounds completed. The architecture review required the independent-request prerequisite; round 2 replaced an unpaced stream transfer with sequential cursor reads, and round 3 found no new proven defect. The final decider ruled KEEP. Catalog, type and wire-test corrections are included in the exact head 4c2a7d717b85c80606c0accff351552f1419384d; the full PR workflow and its aggregate passed.

Actual hidden Electron comparison on isolated Linux runners reproduced missing controls on the base and verified both reviewed heads: off-page approval/grouped question, rendered answers and removal, backward wheel paging, hidden-send settlement, owner completion plus withdrawals, restart and ordinary short replay. Whole-window screenshots are attached in the PR body. A strict retention check after paging retired nine oldest rows on both base and prerequisite; the fresh prerequisite replay retained every loaded text message. Runtime matrix, fresh replay.

Final-stack measurements on the same original Linux host passed exact content/cursor/request payload and backward reconstruction checks. For 20,000 missed revisions, helper p50/p95 fell from 262.936/296.338 to 1.154/1.561 ms; distinct messages fell from 350.373/422.345 to 9.986/11.516 ms. These exclude network and painting; retained host scans and total request memory still scale with useful data.

Paired bridge run passed on the exact successor; nine relevant request/reader/transport source blobs are identical on the prerequisite. Production bridge modules and an actual encrypted connection delivered 5,774,314 bytes in 235 sequential reads, including a 1,048,911-byte request body. The largest bridge frame was 51,270 bytes, with one read in flight. The assembled JSON matched the host exactly, including all four generic approval options and explicit required-text metadata. Twelve subscription events (67,078 bytes) remained unacknowledged during the transfer; this did not fill the event window. Capability simulation correctly rejected an unsupported read, omitted the marker, replayed eight rows exactly, recovered after terminating the owned socket and stopped delivery after disposal. This exercises a scripted page endpoint, not a native phone WebView. The earlier run passed the main transfer and failed only because the compatibility probe supplied an invalid UUID; that harness input was corrected.

Deferred existing limitations: journal rows are decoded before byte admission; Cancel may do nothing for a child request after its parent ends; a blank required final question can display Skip but send no answer. Nonblank answers work. Intended differences from the common pattern are the existing execution-host owner, complete question payloads and bounded reads for independently updated remote consumers. Pre-decode byte admission remains a named temporary follow-up. Native phone UI, a real older binary and SSH transport were not exercised; capability simulation must not be read as those tests.

#28951 was closed separately by brennanb2025 at 22:07 UTC on October 15. This review worker did not merge or close any PR.

Real signed-in agent QA — integrated head

PASS on cfaa40af2ba0ae8c3f4ebaec47ca0f7dba24fd3a, using real signed-in Claude Opus 5.5 (1M context), high effort, in a hidden Electron window on the explicitly authorized Mac. A real background child waited for Write approval while the parent made 225 Read calls and streamed a long reply with the chat tab hidden. The pending approval was at sequence 640, outside the newest 200 rows (oldest 688). Reopening showed one Allow control; clicking it once removed the control, recorded the answer and let the child create the expected file.

Backward scrolling rendered older history. After the child and its notification turn finished, restarting preserved all 529 saved items with exactly the same hash, 06f350fa07e54e69dc2e3cbf2ed05a58201af3ad7956d9c723ebee1c2d289da3. The child success remained visible and the settled approval stayed gone. An additional real short reply sent while hidden appeared after reopening, with no Sending bubble or approval control.

This is a sequential saved-chat check, reusing the disposable profile from prerequisite QA. Codex was blocked by authentication isolation; grouped child questions were not available in the real provider's child tool contract. Native phone UI, an older binary, SSH transport, synthetic large-payload measurements and the full withdrawal matrix were not rerun here; the earlier source/CI evidence remains separate.

Launch gates passed (initial load 7.36, memory 82% free; restart load 6.56, memory 82%; zero typechecks). Real Claude settings and Codex hook hashes remained unchanged. Runtime processes were stopped by recorded identity; final shared cleanup is recorded in the worker report. Final review completion and readiness remain the review owner's responsibility.

Real child approval after returning to the chat
Older history remains available
Restart keeps the child result and settled request

Real signed-in agent QA (M4Air), head b56a336

Passed with M4Air's real signed-in Claude, Opus (picker description Opus 5.5), High, Ask for approval, and auto-naming off through the UI. Grok drove the hidden isolated app over CDP; the folder workspace's group had its real parentPath set.

  • The parent completed 225 Read calls over all 225 distinct fixtures and a 100-paragraph streamed reply while hidden. The child's pending Write approval was absent from the host's newest 200-item history page (235 saved items at that point).
  • Reopening showed exactly one Allow. One click produced exactly ORCA_M4AIR_29125_CHILD_APPROVED plus one newline (32 bytes). Scrollback rendered the original prompt.
  • A short follow-up was initiated through the real native-chat send RPC while Terminal 1 was already active and the chat was hidden; the real reply appeared after reopening with no Sending bubble. A UI Send followed by an immediate tab switch also passed.
  • Actual agentSession.subscribe opens after attach: 0 over 60 seconds in each of two settled observation windows, with the healthy chat open.
  • Same-profile restart on this head: 245/245 item IDs and body SHA-256 hashes matched, and all 522 journal rows were unchanged. The UI rendered the settled child and hidden-send reply with no pending control or Sending bubble. No Claude 429 occurred.
  • Initial launch load (1/5/15 min): 5.31 / 4.15 / 3.99, 63% memory free. Hidden-send launch: 4.88 / 3.36 / 3.62, 67% free. Final restart: 3.46 / 3.53 / 3.56, 65% free.

Hooks stayed on. SHA-256 before and after:

  • ~/.claude/settings.json: before 7847561ee31422545b5f29fc9154aeb4b73733c46e0457b719d1b633920a45c0; after 7847561ee31422545b5f29fc9154aeb4b73733c46e0457b719d1b633920a45c0.
  • ~/.codex/hooks.json: before edb2d1cab54568e86a32aa813939d8a8892f1184a0d13bddbd08e9059a723eee; after edb2d1cab54568e86a32aa813939d8a8892f1184a0d13bddbd08e9059a723eee.

Pending approval:

pending-approval.png

Original prompt after scrollback:

original-prompt.png

Settled child and hidden-send reply after restart:

restart-literal-hidden-settled.png

Real signed-in agent QA, head 285256d

Exercised on M4Air with its real signed-in Claude, Opus (Opus 5.5), High effort, Ask for approval and automatic chat naming off, selected through the UI. Grok drove the hidden isolated test copy through Chrome DevTools Protocol; hooks stayed on. The folder group had a non-null parent path and a real folder workspace.

  • Sent a parent prompt that started a background child Write request, completed 225 distinct Reads and streamed 100 numbered paragraphs. Switched to Terminal 1 after 209 ms. The saved-history audit proved the pending child approval was outside the actual newest 200 history items. Reopening showed exactly one Allow control; one click completed the child write with exactly ORCA_FINAL_29125_CHILD_APPROVED\n. Scrolling back rendered the original prompt.
  • Initiated a short follow-up while Terminal 1 was already active and the chat was hidden. The real reply appeared after reopening, with zero Sending bubbles and zero pending approval or question controls. An initial QA request used an invalid operation ID and was refused before submission; the corrected call used the app's operation-ID generator and was accepted once.
  • Counted actual agentSession.subscribe opens in the main process, with the healthy settled chat open: 0 over 60 seconds after attach.
  • Restarted the same isolated profile on this head: 241/241 saved item IDs and body SHA-256 hashes matched, and all 513 journal rows were unchanged. The restarted UI showed the settled child result and exact hidden-send reply, with zero pending controls or Sending bubbles; the final screenshot is unobstructed.
  • Final-head launch load (1/5/15 minutes): 2.39 / 5.89 / 6.31, with 63% system memory free. Restart: 11.85 / 17.57 / 11.41, 58% free. No Claude 429 occurred.

Real hook configuration SHA-256 before and after:

  • ~/.claude/settings.json: before 7847561ee31422545b5f29fc9154aeb4b73733c46e0457b719d1b633920a45c0; after 7847561ee31422545b5f29fc9154aeb4b73733c46e0457b719d1b633920a45c0.
  • ~/.codex/hooks.json: before edb2d1cab54568e86a32aa813939d8a8892f1184a0d13bddbd08e9059a723eee; after edb2d1cab54568e86a32aa813939d8a8892f1184a0d13bddbd08e9059a723eee.

Pending child approval after reopening:

pending-approval.png

Original prompt after scrollback:

original-prompt.png

Settled child and hidden-send reply after restart:

restart-unobstructed.png

@brennanb2025
brennanb2025 marked this pull request as ready for review October 15, 2026 21:49
@brennanb2025
brennanb2025 marked this pull request as draft October 15, 2026 22:04
@brennanb2025
brennanb2025 marked this pull request as ready for review October 16, 2026 04:24
…d keeps failing

A deterministic read failure reopened the subscription, whose first frame re-read the same version and reset the backoff, so the pane resubscribed every 750 ms forever.
…nt-requests

# Conflicts:
#	src/shared/electron-remote-runtime-client-capabilities.ts
…' into brennanb2025/nc-perf-catchup-current-requests
…' into brennanb2025/nc-perf-catchup-current-requests
…' into brennanb2025/nc-perf-catchup-current-requests
@brennanb2025
brennanb2025 changed the base branch from brennanb2025/nc-current-requests to main October 16, 2026 23:02
…catchup-current-requests

# Conflicts:
#	src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
#	src/main/runtime/rpc/methods/structured-agent-session.ts
#	src/shared/electron-remote-runtime-client-capabilities.ts
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 07858b92-a950-4d56-bdaa-c972e5389825
📥 Commits

Reviewing files that changed from the base of the PR and between a99f4ec and 285256d.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6cab214f-806e-432e-8b28-f0402abdc0f8
📥 Commits

Reviewing files that changed from the base of the PR and between 8c1ade9 and a99f4ec.

📒 Files selected for processing: 15
  • src/main/ipc/desktop-renderer-runtime-capabilities.ts
  • src/main/native-chat/agent-session-wire/agent-session-history-forward-read-budget.test.ts
  • src/main/native-chat/agent-session-wire/agent-session-subscriber-catch-up.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-subscribers.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-wire-admission.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-rpc.test-fixture.ts
  • src/main/runtime/rpc/methods/structured-agent-session-wire-contracts.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session.ts
  • src/renderer/src/web/web-runtime-client-capabilities.ts
  • src/renderer/src/web/web-runtime-client.test.ts
  • src/shared/electron-remote-runtime-client-capabilities.ts
  • src/shared/runtime-capability-constants.ts
  • tests/e2e/cross-version-wire/cross-version-stop-note-scenarios.ts
  • tests/e2e/cross-version-wire/cross-version-stop-note-test-rig.ts
  • tests/e2e/structured-agent-session-read-owner.unit.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

📝 Walkthrough

The change adds a snapshot catch-up capability and advertises it from desktop and web clients. The subscription RPC selects snapshot catch-up based on client kind and advertised capabilities. Subscribers can emit a snapshot instead of replaying newer rows page by page. Updated tests cover capability negotiation, bounded reads, admitted snapshots, and follow-up paging.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to a99f4

Desktop chat catch-up now uses the newest bounded page for large gaps, with exact replay kept for short gaps and older desktops. No actionable merge-blocking risk was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 15 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the main change: supported desktop chats catch up from the newest history page.
Description check Passed The description is complete and well aligned with the template. It explains the user impact, implementation, rationale, linked work, visual proof, testing, compatibility considerations, limitations, a…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is complete and well aligned with the template. It explains the user impact, implementation, rationale, linked work, visual proof, testing, compatibility considerations, limitations, and checklist status. The Linked Issue section references #28951 and related prerequisite work, although it does not use a formal Fixes reference.

✨ Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@brennanb2025
brennanb2025 merged commit dd3bbf6 into main Oct 17, 2026
33 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/nc-perf-catchup-current-requests branch October 17, 2026 00:47
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.

1 participant