Files
buzz/crates
Duncan 5c8ec7a2ec fix(acp): scope permission-card retirement to terminating turn; fix fan-out false-ack
P1 (fan-out false-ack, lib.rs): The prior fix correctly gated nonce
recording and 'sent' status on all_tx_accepted (every tx-equipped loop
accepted). Adds the required regression test: saturate the owner queue
while leaving a sibling queue open, deliver a decision -> status must be
'channel_full' not 'sent', nonce not recorded; drain owner queue, retransmit
-> status 'sent', nonce recorded, owner loop receives the message.

P2 (channel-wide card retirement, agentSessionTranscript.ts): Replace
retireAllLivePermissionCards with retireLivePermissionCardsForTurn at both
turn_completed and turn_error/agent_panic call sites. With concurrent
thread-scoped turns, channel-wide retirement on turn B completing would
retire thread A's still-pending cards and delete their nonce indexes, making
a later A decision drop on an unknown nonce. Turn-scoped retirement confines
the backstop to cards whose turnId matches the terminating turn; falls back
to channel-wide only when no turn identity is present (legacy archive frames).

retireLivePermissionCardsForTurn added to agentSessionTranscriptPermissions.ts
with the same copy-on-write semantics as retireAllLivePermissionCards, scoping
both the itemsById scan (item.turnId === turnId) and the pendingPermissions
cleanup (ch:session:turn:id key format, parts[2] matches turnId).

Regression tests added (agentSessionTranscript.test.mjs):
- buildTranscript_turn_scoped_retirement_does_not_retire_sibling_thread_cards:
  thread A pending -> thread B turn_completed -> A still actionable -> A
  decision resolves correctly, including archive replay.
- buildTranscript_turn_error_scoped_retirement_does_not_retire_sibling_thread_cards:
  same invariant for the turn_error terminal path.

Mutation table:
- P1: restore any_sent semantics -> mixed-result test fails at 'sent'!=
  'channel_full' assertion.
- P2: restore retireAllLivePermissionCards -> both sibling-isolation tests
  fail because A's card is retired by B's terminal event.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-09-01 19:23:57 -04:00
..