diff --git a/TODO.md b/TODO.md index 1dde347..8c1d1ae 100644 --- a/TODO.md +++ b/TODO.md @@ -34,6 +34,46 @@ Pick anything from here when relevant. Cross-cutting design notes live in the harness. Pairs well with the unprivileged-container work — would let the operator drop into the container without `nixos-container root-login`. +## Manager → operator question channel + +- **`mcp__hyperhive__ask_operator(question, options?)` tool** on the manager + MCP surface. The manager turn pauses; the question gets surfaced as a + prominent prompt on the dashboard (its own section, or interleaved with + the operator inbox); the operator's typed answer comes back as the tool + result. Modelled after Claude Code's `AskUserQuestion` tool. + + Design open questions: + + - **Storage.** New sqlite table `operator_questions(id, asker, question, + options_json, asked_at, answered_at, answer)` — or piggyback on the + existing message broker with a new envelope kind. Probably a new + table because the lifecycle (pending → answered) is different from + fire-and-forget messages. + + - **Waiting semantics.** The MCP tool call needs to block until + answered. Two options: + 1. Long-poll from inside the tool handler (broker-style — broadcast + on insert, await via `tokio::sync::broadcast`). Simple but the + claude turn stays alive for the whole wait, eating context-window + budget. + 2. Tool returns a `question_id` immediately; manager re-enters its + inbox loop and a `HelperEvent::OperatorAnswered { id, answer }` + wakes it. Cheaper context-wise but two-step. + + - **Dashboard UX.** New "◆ M1ND H4S QU3STI0NS ◆" section at the top + when any question is pending. Inline `