Repository navigation
design: what a question's answer actually chose - #293
Merged
Merged
Conversation
§3 collapses an answered question to "Legacy keys · you chose Keep them under legacy". Today it keeps drawing the whole block -- header, question, and options nobody can press -- which is the largest thing in a finished transcript saying the least. The rule only; the view follows separately. Where the answer lives: the wire never states a choice, and AgentQuestion is exactly header/question/options/multiSelect on both sides. But an answered AskUserQuestion is a completed tool call, and conversation.ts attaches the tool_result to it with status "done" and result text. So the choice is recovered by matching the options' own labels against that result -- checked at the interface, the decoder and the attach site, because earlier tonight I concluded from a nested struct that tool timing was not on the wire and was wrong. Two things it must get right: a shorter label inside a longer one is not a second choice (options "Keep" and "Keep them under legacy" -- an answer naming the latter names one thing), so labels claim their span longest-first; and an answer matching nothing claims nothing, leaving the row as it is. Guessing at a person's decision is worse than not summarising it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE
stupart
added a commit
that referenced
this pull request
Sep 16, 2026
§3's collapse, wired onto #293's rule. An answered question was redrawing its header, the whole question, and every option greyed at 0.58 -- the largest block in a finished transcript, saying the least. It becomes one quiet line naming the decision. A running question is untouched: it is the row the session is blocked on and every option stays pressable. An answer naming no option collapses nothing, since the wire never states a choice and it is recovered by matching the options' labels against the finished call's result -- when nothing matches the block stays as it was, and that fallback is guarded. The line is not a button. There is nothing left to do to it, and leaving an answered question tappable is how an earlier choice gets sent in answer to a later prompt, which is why the existing code already disables those options. Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE Co-authored-by: Claude Opus 5 (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.
§3: "Questions: a single hairline block… Once answered it collapses to 'Legacy keys · you chose Keep them under legacy'." Today an answered question keeps drawing its whole block — header, question, and a list of options nobody can press any more. It is the largest thing in a finished transcript saying the least.
This is the rule only; the view wiring follows separately — the same order as
SessionGrouping,StageModeandToolFolding.Where the answer actually lives
The wire never states a choice.
AgentQuestionis exactlyheader,question,options,multiSelecton both sides, and nothing records a selection. But an answeredAskUserQuestionis a completed tool call:conversation.tsattaches thetool_resultto it withstatus: "done"andresult: claudeResultText(...). So the choice is recovered by matching the options' own labels against that result text.I checked that rather than assuming it — earlier tonight I concluded from a nested struct that tool timing wasn't on the wire, and was wrong. This time the interface, the decoder and the attach site were all read.
Two things the rule has to get right
Mutation battery
testAShorterLabelInsideALongerOneIsNotASecondChoicetestTheCollapsedLineIsTheOne3DescribestestMultipleChoicesComeBackInTheQuestionsOrderGate
swift test131/0 (from 125) ·bun testexit 0 ·tsc --noEmitexit 0 · MacxcodebuildBUILD SUCCEEDED · iOSxcodebuildBUILD SUCCEEDED (it links ConchDesign).🤖 Generated with Claude Code
https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE