fix: deadline on prompt dispatch — re-send once, then terminal error result#16
Merged
Conversation
…minal result Claude's status file reports idle a beat before the TUI input box accepts keystrokes. A prompt typed into that gap is silently eaten: busy never arrives, and the readiness watchdog is intentionally suppressed while a dispatch is in flight, so nothing ever timed out — an unbounded silent wedge with no terminal result. Hit live in the parity replay (permission-deny on haiku: idle at 1.6s, prompt dispatched, only the startup quota probe ever reached the API, killed by the harness at 240s with zero output). After sendPrompt, arm a 10s deadline. If no turn starts: re-send the same prompt once (the TUI is certainly accepting input by then — recovers the race invisibly), then fail via failWithTerminalError so stream-json consumers get a parseable error result instead of a hang. The deadline stands down when the turn starts, when a permission dialog appears (the dialog machinery owns the session; re-typing would corrupt it), and during interrupts/shutdown. Tests: race recovered by a single re-send with no error; terminal error result (exactly one, no duplicate from the exit path) when the retry also fails; no re-send on a prompt turn start; stand-down on permission dialogs.
dn00
added a commit
that referenced
this pull request
Jun 10, 2026
…pe, thinking signature Closes the consumed-field parity gaps confirmed by replay against the 2026-06-09 goldens (PARITY-GAPS #2/#3/#14/#15/#16), and adds the parity-policy tiers to PARITY-GAPS.md (contract / consumed fields / on-demand / won't-fix). - --max-turns now counts assistant API rounds (SSE message_start) like native, not user prompts — a single prompt chaining tools can exhaust it. On exceeding: interrupt, then report result.error_max_turns (is_error, NO result field, num_turns = rounds) and exit 1, even in stream-json mode, whether or not the interrupt beat the turn's natural completion. The old prompt-count check remains as a fallback for backends without SSE. - Ack initialize (truthful payload: commands from transcript init, output_style, pid) and set_permission_mode (echo mode) using native's nested control_response shape {type, response: {subtype, request_id, response}}; migrated the interrupt ack from clarp's old flat shape. - Turn-level backend API errors report subtype "success" with is_error: true (invalid-model golden), not subtype "error"; emitResult decouples is_error from subtype and can omit the result field (error_max_turns has none). - Assembler accumulates signature_delta; thinking blocks are {type, thinking, signature} like native. - Exit code now reflects the last result's is_error on stdin-drain shutdown (native exits 1 after an invalid-model turn even though the stream ends normally).
dn00
added a commit
that referenced
this pull request
Jun 10, 2026
…pe, thinking signature Closes the consumed-field parity gaps confirmed by replay against the 2026-06-09 goldens (PARITY-GAPS #2/#3/#14/#15/#16), and adds the parity-policy tiers to PARITY-GAPS.md (contract / consumed fields / on-demand / won't-fix). - --max-turns now counts assistant API rounds (SSE message_start) like native, not user prompts — a single prompt chaining tools can exhaust it. On exceeding: interrupt, then report result.error_max_turns (is_error, NO result field, num_turns = rounds) and exit 1, even in stream-json mode, whether or not the interrupt beat the turn's natural completion. The old prompt-count check remains as a fallback for backends without SSE. - Ack initialize (truthful payload: commands from transcript init, output_style, pid) and set_permission_mode (echo mode) using native's nested control_response shape {type, response: {subtype, request_id, response}}; migrated the interrupt ack from clarp's old flat shape. - Turn-level backend API errors report subtype "success" with is_error: true (invalid-model golden), not subtype "error"; emitResult decouples is_error from subtype and can omit the result field (error_max_turns has none). - Assembler accumulates signature_delta; thinking blocks are {type, thinking, signature} like native. - Exit code now reflects the last result's is_error on stdin-drain shutdown (native exits 1 after an invalid-model turn even though the stream ends normally).
dn00
added a commit
that referenced
this pull request
Jun 10, 2026
…pe, thinking signature Closes the consumed-field parity gaps confirmed by replay against the 2026-06-09 goldens (PARITY-GAPS #2/#3/#14/#15/#16), and adds the parity-policy tiers to PARITY-GAPS.md (contract / consumed fields / on-demand / won't-fix). - --max-turns now counts assistant API rounds (SSE message_start) like native, not user prompts — a single prompt chaining tools can exhaust it. On exceeding: interrupt, then report result.error_max_turns (is_error, NO result field, num_turns = rounds) and exit 1, even in stream-json mode, whether or not the interrupt beat the turn's natural completion. The old prompt-count check remains as a fallback for backends without SSE. - Ack initialize (truthful payload: commands from transcript init, output_style, pid) and set_permission_mode (echo mode) using native's nested control_response shape {type, response: {subtype, request_id, response}}; migrated the interrupt ack from clarp's old flat shape. - Turn-level backend API errors report subtype "success" with is_error: true (invalid-model golden), not subtype "error"; emitResult decouples is_error from subtype and can omit the result field (error_max_turns has none). - Assembler accumulates signature_delta; thinking blocks are {type, thinking, signature} like native. - Exit code now reflects the last result's is_error on stdin-drain shutdown (native exits 1 after an invalid-model turn even though the stream ends normally).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-files #13 against main (the original auto-closed when its stacked base branch was deleted by #12's merge; same single commit, rebased onto current main, 431 tests green locally).
See #13 for the full description and review context: 10s deadline after
sendPrompt— re-send once (self-heals the TUI input race seen live in the parity replay), then emit a terminal stream-jsonerrorresult viafailWithTerminalErrorinstead of wedging silently. Stands down on turn start, permission dialogs, interrupts, and shutdown.