Render Duo clarifying questions as an interactive card in work item discussions
Summary
When the workplan flow needs a human decision it posts the question as a resolvable discussion on the work item. Today that renders as plain prose, so answering means reading it, working out what the options were, and typing a reply.
This renders the question as a card: the question, the options the agent considered, and which one it recommends. Choosing one posts the answer as a reply and resolves the thread.
Resolving is the part that matters. Discussions::ResolveService publishes WorkItems::DiscussionResolvedEvent, and once every question the run posted is resolved, ContinueWorkplanAfterDiscussionsResolvedWorker resumes that same paused workflow with the replies. The flow keeps its conversation history rather than starting over.
Implementation notes
- New EE component
ee/app/assets/javascripts/work_items/components/notes/duo_question_note.vue - CE no-op stub at the same path under
app/, imported throughee_else_ceso FOSS renders nothing - Mount in
app/assets/javascripts/work_items/components/notes/work_item_note.vue, gated onisFirstNote && !isDiscussionResolved - Answering posts a reply via the existing
createWorkItemNotemutation and resolves viatoggleWorkItemNoteResolveDiscussion, both already exist in CE - Hide the raw payload with
pre[data-lang-params='duo-question'] { display: none }inpage_bundles/work_items.scss, so it never flashes before hydration and stays hidden if the bundle never runs
Gated on two existing feature flags, both off by default: workplan (whether the Workplan widget exists at all) and duo_workplan_async_flow (whether generation runs as a background flow). No new flag is introduced. Nothing renders unless both are on and a note actually contains a question payload.
Proposed Designs
Complete prototypes available here
| Questions waiting for User Input | Questions with accepted answer | Custom Response | |
|---|---|---|---|
| Light | ![]() |
![]() |
![]() |
| Dark | ![]() |
![]() |
![]() |
Acceptance criteria
- Card renders the question, its options, and a
Recommendedbadge where the agent expressed a preference - Answering posts a reply and resolves the discussion
- Renders nothing in FOSS
- A malformed or absent payload results in no card, never an error
- Jest specs for rendering, answering, and the malformed case
Depends on
Blocked by the payload parser.
Reference
Working implementation on branch kp-sdd-hitl-poc: !248609 (closed)





