fix(rpc): every queue clear closes drained input as cleared

Merged
CO
8d ago
+154-16

Fixes #3412

Problem

Queued input dropped by clear_queue, or by unload_session { clearQueue: true }, was closed with a plain completed receipt. get_effect_status then reported it as if it had been delivered. abort { clearQueue } (#3345) used its own cleared_by_abort outcome, so one kind of event had two answers depending on the path.

Change

  • One outcome, cleared (with reason, detail and action), for every path that drains the queue: clear_queue, unload_session { clearQueue: true } and abort { clearQueue }. The receipt is projected as failed, because the input never ran.
  • ClientAdmissions.clearQueued() writes the receipts before the drain. ClientAdmissions.clearQueuedFor(session) does so only when a ledger for that session already exists; it never creates one, since creating one would restore queued input.
  • cleared_by_abort is renamed to cleared. It was never released (it lands with #3345).
  • A session release is deliberately not a clear: its queued deliveries stay unwritten, so the sender redelivers them to the next owner.
  • Updated docs/rpc.md, both changes.md trackers and the CHANGELOG.

Tests

  • RED (d3871bc65): rpc-unload-session.test.ts unloads with clearQueue, and the cleared input comes back as completed.
  • GREEN: that test expects cleared. A new clear_queue test expects a failed receipt with outcome cleared, and the #3345 abort test now expects cleared.

Stack

Base: #3345 (feat/3156-abort-quiesce). It retargets to main once #3345 merges.

Evidence at 5504677e71 (boat:bx_eycscmer, bun 1.4.2)

  • bun install --frozen-lockfile, bun run build and bun run check all exit 0.
  • bun run test on rpc-unload-session, rpc-abort-quiesce, rpc-effect-ledger-host, rpc-effect-held-switch, rpc-effect-outcome-copy and rpc-queued-open-record: 50 passed, 0 failed.

Summary by cubic

Fixes #3412 by giving every path that drains the queue the same cleared outcome, so clear_queue, unload_session { clearQueue: true }, and abort { clearQueue: true } no longer report dropped input as delivered.

Bug Fixes

  • Drained input now gets a failed receipt with outcome cleared (with reason, detail, action) instead of a plain completed receipt.
  • Receipts written as cleared_by_abort by 2026.10.16-2 are still read and reported as stored, so that input is never restored on reopen; clients matching outcome.kind should accept both values.
  • A session release is not a clear: its queued deliveries stay unwritten so the sender redelivers them.
  • ClientAdmissions.clearQueuedFor(session) marks receipts only on an existing session ledger, never creating one (which would restore queued input).
  • Updated docs/rpc.md, both changes.md trackers, and the CHANGELOG.