Skip to content

fix(rpc): recover stalled Roost input receipts - #1699

Draft
Lampese wants to merge 2 commits into
mainfrom
codex/roost-input-receipt-recovery
Draft

Lampese wants to merge 2 commits into
mainfrom
codex/roost-input-receipt-recovery

Conversation

@Lampese

@Lampese Lampese commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Related issue

Problem / pressure

A Roost message can remain unconfirmed while the shared RPC response read stays connected but stops delivering replies. Recovery previously depended on unrelated RPC timeouts, so an input could wait much longer than its successful append.

Summary

Renew the shared response read once when an appended accept_input or accept_input_and_dispatch has no reply after two seconds. Resume from the saved offset using long polling, retaining the original request identity and deadline. Overlapping inputs share renewal; pins, cancellation, timeout and shutdown retain their contracts. Only a validated owner receipt confirms delivery: no input replay or inferred acknowledgement.

This browser-side change is compatible with the current remote CLI and can ship without upgrading it. Slow owner processing can also trigger renewal; two seconds bounds the recovery trigger, not end-to-end delivery. The original remote 26.8-second wait has not been attributed or remeasured after deployment.

Visual explanation

flowchart TD
  A[Input append succeeds] --> B[Original RPC call pending]
  B -->|Owner reply arrives|C[Validate receipt and confirm delivery]
  B -->|Two seconds, once per appended input|D[Renew shared read from saved offset using long polling]
  D --> E[Same request and deadline remain pending]
  E -->|Owner reply arrives|C
  E -->|Original deadline expires|F[Report timeout]
Loading

Before / after

Before After
A quiet response connection could wait for unrelated response timeouts. An outstanding appended input triggers one shared-read renewal after two seconds.
Intentional read aborts could take the read-error backoff. Recovery reconnects immediately while retaining offset and pending calls.
A synced Roost control cursor cannot establish delivery. Delivery still requires the real encrypted receipt; no change to that authority.

Test plan

  • pnpm check — passed on the combined local stack, including CLI 4,397, components 5,605, shared 1,577 and RPC 153 tests
  • pnpm format and git diff --check.
  • Fake-clock coverage for stalled SSE/long-poll, delayed append/owner, overlapping inputs, unrelated/duplicate replies, diagnostic failures, pins, cancellation, deadlines and stop.
  • Real pinned Streams SDK + renderer bridge + encrypted synthetic receipt: one write, recovery from offset 42, no history readback. Healthy SSE remains connected; disabling recovery makes its regression fail.
  • Controlled before/after probe: healthy SSE delivers at virtual time zero in both; withheld SSE stays pending until the baseline's deliberate release at 10 seconds, while renewal receives the existing receipt at two seconds. This is a fake-clock fault control, not a network latency benchmark.
  • pnpm run docs check retains six baseline broken links to absent isolated ACP sources; no protected-topic changes.

Context handoff

Same-repository branch. The owning note records the authority boundary, recovery lifecycle, evidence and rollout limits.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant