Description
do_prompt (crates/zeph-acp/src/agent/turn.rs) acquires output_rx via acquire_prompt_channels but only restores it on the success path (turn.rs:318-320). The input_tx.send(...) failure early-return (turn.rs:294-303), and any drop of the future before completion, leak the channel — permanently wedging the session with "prompt already in progress" on every subsequent session/prompt request.
Found during review of #6656 (ACP permission gate dispatch-loop deadlock fix) — pre-existing, not introduced by that PR. Not fixed there to keep that PR scoped to the deadlock.
Why it matters more now
Before #6656, the ACP SDK's dispatch loop serialized session/prompt dispatch, so "prompt already in progress" was unreachable from ACP — a client could never observe this wedge because a second prompt could never even be dispatched while the first was in flight. #6656 spawns the turn instead of awaiting it inline, which frees the dispatch loop and makes a pipelined second prompt (or a retry after a failed first prompt) reachable — making this leak observable for the first time via a real client interaction.
Reproduction Steps
- Trigger an
input_tx.send(...) failure inside do_prompt (e.g. by closing the receiving side of the turn channel before the send, or via a targeted unit test that drops the receiver).
- Observe the early return does not restore
output_rx.
- Send a subsequent
session/prompt on the same session.
- Observe:
"prompt already in progress" is returned even though no prompt is actually in flight.
Expected Behavior
output_rx is restored (or the session's in-progress state is otherwise cleared) on every exit path from do_prompt, not just the success path, so a failed prompt does not permanently wedge the session.
Actual Behavior
Session is permanently wedged after a single input_tx.send failure (or an aborted/dropped prompt future) — every subsequent prompt on that session fails with "prompt already in progress".
Environment
Logs / Evidence
Found during independent adversarial critique and code review of PR #6660 (fix for #6656). See PR #6660 discussion for the full audit trail.
Description
do_prompt(crates/zeph-acp/src/agent/turn.rs) acquiresoutput_rxviaacquire_prompt_channelsbut only restores it on the success path (turn.rs:318-320). Theinput_tx.send(...)failure early-return (turn.rs:294-303), and any drop of the future before completion, leak the channel — permanently wedging the session with"prompt already in progress"on every subsequentsession/promptrequest.Found during review of #6656 (ACP permission gate dispatch-loop deadlock fix) — pre-existing, not introduced by that PR. Not fixed there to keep that PR scoped to the deadlock.
Why it matters more now
Before #6656, the ACP SDK's dispatch loop serialized
session/promptdispatch, so"prompt already in progress"was unreachable from ACP — a client could never observe this wedge because a second prompt could never even be dispatched while the first was in flight. #6656 spawns the turn instead of awaiting it inline, which frees the dispatch loop and makes a pipelined second prompt (or a retry after a failed first prompt) reachable — making this leak observable for the first time via a real client interaction.Reproduction Steps
input_tx.send(...)failure insidedo_prompt(e.g. by closing the receiving side of the turn channel before the send, or via a targeted unit test that drops the receiver).output_rx.session/prompton the same session."prompt already in progress"is returned even though no prompt is actually in flight.Expected Behavior
output_rxis restored (or the session's in-progress state is otherwise cleared) on every exit path fromdo_prompt, not just the success path, so a failed prompt does not permanently wedge the session.Actual Behavior
Session is permanently wedged after a single
input_tx.sendfailure (or an aborted/dropped prompt future) — every subsequent prompt on that session fails with"prompt already in progress".Environment
crates/zeph-acp/src/agent/turn.rs(lines ~294-303, ~318-320)Logs / Evidence
Found during independent adversarial critique and code review of PR #6660 (fix for #6656). See PR #6660 discussion for the full audit trail.