Repository navigation
fix(conductor): stop AskUserQuestion silently vanishing; force corral-question - #409
Merged
Merged
Conversation
TestCaptureSendRecordsAndPassesThrough asserted delivered==6, but the capturer legitimately injects a one-shot conv_meta frame (carrying the conv id/uuid to the UI) when it first creates the conversation row, so 7 frames reach the browser. The test predates that frame. Assert the 6 sent frames + exactly one conv_meta. Pre-existing failure — CI only runs Playwright e2e, never go test, so it went unnoticed on main. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-question
The global-chat conductor is a headless `claude -p` process. It had two
ways to ask the user a question: the native AskUserQuestion tool and the
`corral-question` fenced convention. The old guidance only *suggested*
the convention ("you MAY"), so the model often reached for the native
tool instead — which is auto-DISMISSED in headless mode (no interactive
channel to answer over the stream). The question then silently vanished:
the user saw nothing and the model got an empty "dismissed" result. It
was intermittent because the model sometimes picked the answerable
convention (which worked) and sometimes the native tool (which didn't).
Fix, both halves needed (verified empirically against claude 2.1.186):
- Deny the native AskUserQuestion for the conductor via --disallowedTools,
removing the silent-vanish path.
- Rewrite chatQuestionGuidance from permissive to imperative: "you do NOT
have an interactive question tool; the ONLY way to ask is a
corral-question block" — so the model routes to the answerable path
instead of dead-ending on the denied tool.
buildClaudeArgs gains a `disallowed` param; only the conductor (global
chat) passes AskUserQuestion. Project/worker chats are unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Symptom
The global-chat conductor's questions to the user were intermittent — "sometimes it works, sometimes nothing comes through."
Root cause
The conductor is a headless
claude -pprocess. It had two ways to ask a question:AskUserQuestiontool — auto-dismissed in headless mode (there's no interactive channel to answer it over the stream). The call returns an empty "dismissed" result and the user sees nothing.corral-questionfenced convention — plain text the UI renders as one-click chips. This is answerable and works.The old guidance only suggested the convention ("you MAY ask with a fenced block"), so the model frequently reached for the native tool instead → question silently vanished. In conv 160 the conductor called
AskUserQuestiontwice (seq 388, 428); both were dismissed and it wrote "It looks like the question prompt was dismissed." When it happened to pickcorral-question, the chips appeared — hence the intermittency.Fix (both halves required — verified against claude 2.1.186)
AskUserQuestionfor the conductor via--disallowedTools, removing the silent-vanish path. (Only the global-chat conductor; project/worker chats unaffected.)chatQuestionGuidancefrom permissive to imperative: "you do NOT have an interactive question tool; the ONLY way to ask is acorral-questionblock." Denial alone isn't enough — without this the model can dead-end on the blocked tool instead of falling back. I tested this exact config (denied tool + imperative guidance) and the model produced a cleancorral-questionblock,is_error: False.buildClaudeArgsgains adisallowed []stringparam; callers updated.Also in this PR
A separate, pre-existing test fix:
TestCaptureSendRecordsAndPassesThroughasserteddelivered==6but the capturer legitimately injects a one-shotconv_metaframe (conv id/uuid → UI), so 7 frames reach the browser. The test predated that frame. Now asserts 6 sent + exactly oneconv_meta. (CI runs only Playwright e2e, nevergo test, so it went unnoticed on main.)Full
internal/dashboardpackage passes.🤖 Generated with Claude Code