Repository navigation
Keep pending chat decisions available outside loaded history - #29121
Conversation
Current status: review complete, real-agent QA passedFinal head 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. Pending approvals and questions now remain answerable independently of the loaded conversation history. 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 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 Real signed-in agent QA — 2026-10-16Passed on exact head The initial child-question attempt could not use AskUserQuestion because that tool was absent from the real child’s tool contract; that question flow is unverified. The actual child approval flow above passed. Claude recovered from one temporary HTTP502 retry. Codex remains blocked by credential isolation; no SSH, phone, or older-peer pass is claimed. Real Claude/Codex hook-file SHA256 values stayed unchanged. Real signed-in agent QA — integrated headPASS on Backward scrolling loaded and rendered the oldest messages. The child and its notification turn finished before the restart snapshot. Restart preserved all 771 saved items with identical hash This sequential check reused the disposable chat profile from successor QA; it is not an independent empty-profile comparison. Codex remained blocked by authentication isolation, and the real child tool contract did not expose grouped questions. Native phone UI, SSH transport, older binaries and the full synthetic withdrawal/large-payload matrix were not rerun. Source review completion and readiness remain the review owner's responsibility. Launch gates passed (initial load 5.61, memory 83% free; restart load 4.46, memory 83%; zero typechecks). Real Claude settings and Codex hook hashes stayed unchanged. Owned app and agent processes were stopped using recorded identities, and disposable homes were removed; the clean private checkout was removed. Real signed-in agent QA (M4Air), head a4f3467Passed 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
Hooks stayed on. SHA-256 before and after:
Pending approval: Original prompt after scrollback: Settled child after restart: |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
e28ee281-2e1a-4841-bbd1-512a8fe8f0e9
⛔ Files ignored due to path filters: 1
src/shared/rpc-contract/rpc-params-catalog.generated.tsis excluded by!**/*.generated.*
📒 Files selected for processing: 59
mobile/src/session/mobile-structured-actionable-prompt.tsmobile/src/session/mobile-structured-agent-session-cancel.tsmobile/src/session/mobile-structured-transcript-read.test.tsmobile/src/session/mobile-structured-transcript-read.tsmobile/src/session/mobile-structured-transcript-subscription.tsmobile/src/session/use-mobile-structured-agent-session.tsmobile/src/session/use-mobile-structured-agent-state.tsmobile/src/session/use-mobile-structured-send-with-outcome.tsmobile/src/transport/mobile-runtime-client-capabilities.tsmobile/src/transport/rpc-subscription-inventory.tssrc/main/claude/claude-background-stop-records.test.tssrc/main/ipc/desktop-renderer-runtime-capabilities.tssrc/main/native-chat/agent-session-wire/agent-session-bounded-frames.tssrc/main/native-chat/agent-session-wire/agent-session-current-requests.test.tssrc/main/native-chat/agent-session-wire/agent-session-current-requests.tssrc/main/native-chat/agent-session-wire/agent-session-published-work.tssrc/main/native-chat/agent-session-wire/agent-session-stop-note-refresh.test.tssrc/main/native-chat/agent-session-wire/agent-session-stop-note-refresh.tssrc/main/native-chat/agent-session-wire/agent-session-subscriber-catch-up.tssrc/main/native-chat/agent-session-wire/agent-session-subscriber-frame-fields.tssrc/main/native-chat/agent-session-wire/structured-agent-session-background-task-channel.tssrc/main/native-chat/agent-session-wire/structured-agent-session-current-requests.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-current-work.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host.tssrc/main/native-chat/agent-session-wire/structured-agent-session-queued-message-rig-provider.test-fixture.tssrc/main/native-chat/agent-session-wire/structured-agent-session-subscribers.tssrc/main/native-chat/agent-session-wire/structured-conversation-command-admission.test.tssrc/main/runtime/mobile-rpc-allowlist.test.tssrc/main/runtime/rpc/methods/structured-agent-session-current-requests.tssrc/main/runtime/rpc/methods/structured-agent-session.test.tssrc/main/runtime/rpc/methods/structured-agent-session.tssrc/main/runtime/runtime-rpc/runtime-rpc-mobile-agent-session-methods.tssrc/renderer/src/components/native-chat/structured-agent-session-message-projection.tssrc/renderer/src/components/native-chat/structured-agent-session-prompt-response.tssrc/renderer/src/components/native-chat/structured-agent-session-read-owner-contract.tssrc/renderer/src/components/native-chat/structured-agent-session-read-owner.tssrc/renderer/src/components/native-chat/structured-agent-session-read-transport.tssrc/renderer/src/components/native-chat/structured-agent-session-reconnect.tssrc/renderer/src/components/native-chat/use-structured-agent-session-transport-state.tssrc/renderer/src/components/native-chat/use-structured-agent-session.tssrc/renderer/src/web/web-runtime-client-capabilities.tssrc/renderer/src/web/web-runtime-client.test.tssrc/shared/agent-session-current-requests-capability.tssrc/shared/agent-session-current-requests-reader.tssrc/shared/agent-session-current-requests-wire.tssrc/shared/agent-session-current-requests.tssrc/shared/agent-session-frame-fields.tssrc/shared/agent-session-handoff-status.tssrc/shared/agent-session-wire.tssrc/shared/electron-remote-runtime-client-capabilities.tssrc/shared/protocol-version.tssrc/shared/rpc-contract/agent-session-current-requests-params.tssrc/shared/structured-agent-session-coalescer.tssrc/shared/structured-agent-session-history-state.tssrc/shared/structured-agent-session-reducer.tstests/e2e/cross-version-wire/structured-agent-session-host-fixture.tstests/e2e/cross-version-wire/structured-agent-session-surface-calls.tstests/e2e/cross-version-wire/structured-agent-session-surface-execution.tstests/e2e/cross-version-wire/structured-agent-session-surface-manifest.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
…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
Resolve against main's current-request reads (#29121): the shared live read now owns the current-request reader (desktop's reopen-once-per-failed-version rule) and the reconnect scheduler moves to src/shared, so desktop and phone still run one reopen loop. The phone's separate transcript read from #29121 is replaced by the shared read; its subscribe-after-hold adapter keeps main's file name.
Derive pending questions from delivered history so cards remain available outside the loaded message window. Extend the current-request transport from stablyai#29121 with opt-in async rows and adapt rollout reconstruction and regressions from stablyai#25448.
|
Follow-up in #30062: Codex async questions now use the current-request transport introduced here, so their cards can remain available outside loaded history on desktop and mobile. The extension keeps the existing chunked reads and host ownership. Hosts advertise async support, clients opt in, and older clients retain the previous response shape. New clients connected to older hosts keep their inline-card fallback. No new RPC method or persisted question store is added. The PR also adapts the async-question reconstruction from #25448 for terminal-backed chat. It has 384 passing focused tests and a passing build; full CI and physical-device/live SSH verification remain pending. |








ELI5
An approval or question can disappear while its agent is still waiting for an answer. Chat controls currently come from whichever conversation rows are loaded, so opening a long chat, replacing its newest page or unloading old history can remove a request that still needs the person.
What Changed
Pending approvals and questions come from the host’s complete view of current work, independently of conversation pages. The existing controls keep the full request identity, revision, choices and question fields; answering still uses the existing saved-request validation. Resolved requests and requests from positively replaced owners are removed by that same host projection.
The subscription announces when current requests change. The client reads their full contents one small piece at a time and replaces the collection only when the complete answer belongs to the current host and execution. Unrelated conversation output does not restart the read. Older hosts retain the existing loaded-history behavior, and older clients receive no full request transfer. Desktop catch-up can require the new consumer capability separately.
Why
Current decisions must remain answerable when conversation history is paged. Keeping history pinned or avoiding snapshots around particular prompts would leave that dependency in place. Reusing the existing host owner separates current requests from historical rows without another saved state. Small reads provide delivery flow control through existing request replies; sending the entire collection through a subscription can overfill a phone’s receive window even when each individual frame fits.
This is an independent prerequisite for #28951, stacked on #28993. It also applies to ordinary initial reads and phone history windows. Requested by @BrennanKB5 during review.
Linked Issue
Native-chat performance review requested by @BrennanKB5; blocker R1-01 tracked in #28951. No separate issue.
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.
After (this PR): the complete approval stays available outside the loaded history page.
The grouped question also stays answerable through the existing card.
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
Current head: 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 passedaggregate succeeded on this exact head, including all five unit shards, static analysis/typecheck, generated catalog checks, wire compatibility, mobile verification, packages and relay integration. The full host current-request flow passed after correcting its provider test fixture. The exact-head helper benchmark passed, including complete pending-request adoption and full history reconstruction; rendered Electron and actual paired bridge evidence are complete. CI run.Review
The architectural decider ruled to keep complete current requests independent of paged history and adopt separate bounded reads refreshed by stream changes. One fresh plan check required bounded phone read-failure recovery; that correction is committed. Final source implementation review and readiness completed with no new proven high-severity regression; the remaining transport evidence is now complete with the limits below. Source review includes local and paired desktops, web, phone consumers, SSH host ownership and mixed versions. No new user-facing notice or prompt surface is added.
Agent skill upstream boundary
Notes
Intended differences from the common pattern: reuse the existing execution-host saved conversation owner instead of adding a second request database; read small pieces to support independently updated phones and remote hosts; retain complete question payloads and existing controls. Temporary, tracked follow-up: pre-decode journal replay byte admission.
Complete pending-request memory scales with the work awaiting a response; each transport part is bounded. This does not change journal retention or preflight raw journal replay bytes. Pre-existing Cancel limitations when a child prompt outlives its parent turn are recorded separately on desktop and phone; answering remains supported.
Checklist
Measurement evidence
Measured this exact head and #29125 on the same original Linux host and Node 26.1.0, with 300 older messages, 200/2,000/20,000 missed rows, 5 warmups and 31 samples. The original history-only control and 18 production-helper cases per head passed. Complete child approvals and required grouped questions adopted outside the loaded page; exact final content/cursor and full backward reconstruction passed, with no request refetch on unrelated output. The comparative timings and setup limits are in #29125. This helper run excludes outer RPC/network/phone bridge behavior and rendered UI, which are verified separately.
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.