Skip to content

Plan mode: "open questions / risks" banner fires but the questions are never shown #477

@esengine

Description

@esengine

Symptom

When submit_plan returns a plan whose markdown contains an Open Questions / Risks / Unknowns / Assumptions section, PlanConfirm shows a yellow banner:

▲ the plan flags open questions or risks — pick refine to write concrete answers before the model moves on.

But the actual questions are not surfaced to the user:

  1. If the plan came back with structured steps, PlanConfirm.tsx renders PlanStepList and skips the markdown body entirely — the questions exist only in the un-rendered text.
  2. Even without steps, the body preview is capped at 24 lines; the open-questions block can be in the truncated tail.
  3. Picking refine opens PlanRefineInput titled refining — what should the model change? with no echo of the questions the model raised — just a blank prompt.
  4. If the user submits blank, the synthetic feedback in App.tsx literally tells the model: "the user didn't give specifics. Ask them one or two concrete questions … then wait for their answer" — i.e. we hand the question back to the model to re-derive, costing an extra round-trip.

Net effect: the user is told there are open questions, isn't shown them, and the only way to see them is to enter refine, type a placeholder, and wait for the model to repeat its own questions in the next turn.

Where

  • Banner detection (regex only; no extraction): src/cli/ui/PlanConfirm.tsx:38-56
  • Body hidden when steps are present: src/cli/ui/PlanConfirm.tsx:58-73
  • Refine input with no question context: src/cli/ui/PlanRefineInput.tsx:32-39
  • Synthetic blank-refine fallback that pushes the question back to the model: src/cli/ui/App.tsx:2920-2923

The PlanStep type in src/tools/plan-types.ts has no field for plan-level open questions, so even when steps are returned there is nowhere structured to put them.

Related signal

Discussion #22 has independent feedback that plan mode feels weak / has low presence — the agent reads as a direct executor rather than a planner. The open-questions UX is one concrete cause: when the model does flag something to clarify, the UI swallows it, so plan mode looks like it has nothing to add over normal execution. Fixing this is a small lever on that broader perception.

Localization gap (in scope)

The plan-mode surface is hardcoded English. None of PlanConfirm.tsx, PlanRefineInput.tsx, PlanStepList.tsx, PlanCheckpointConfirm.tsx import useI18n — header (Approve plan), warning banner, picker labels (accept / refine / revise), hints, footers, scrollback note, and all five MODES blocks in PlanRefineInput (title / hint / blankHint for approve / refine / reject / checkpoint-revise / choice-custom) live as inline string literals. Compare to App.tsx / Wizard.tsx / WelcomeBanner.tsx / SlashSuggestions.tsx, which all wire through the i18n module — the plan flow was simply skipped when those landed.

Fold both the existing strings and any new strings introduced by the fix below through src/i18n/EN.ts + src/i18n/zh-CN.ts rather than extending the inline pattern.

Fix direction

  • Extract the Open Questions / Risks block from the plan markdown when the regex hits, and render it under the banner in PlanConfirm regardless of whether steps are present and regardless of the 24-line body cap.
  • When the user picks refine, pass the extracted questions into PlanRefineInput and show them above the input as numbered prompts the user can answer in place.
  • Move all plan-flow strings (existing + new) into the i18n catalogs in the same PR.
  • Longer-term: add an optional openQuestions: string[] field to the submit_plan schema so the model can surface them as structured data instead of relying on header parsing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions