manager: don't trust agents on config asks; sketch ask_operator tool in TODO

This commit is contained in:
müde 2026-05-15 18:06:01 +02:00
parent ac4a978846
commit 6e75d8e6db
3 changed files with 54 additions and 1 deletions

40
TODO.md
View file

@ -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 `<form>` with a textarea (or
select if `options` were provided), POST `/api/answer-question`.
State refresh + the live SSE stream notify the manager harness.
- **Sub-agent path.** Sub-agents don't get the tool — they message the
manager and the manager decides whether to relay the question to the
operator. The manager's system prompt already covers this.
- **Timeout / cancel.** Questions that sit pending too long: do they
expire? Manager probably wants to know if the operator hasn't
answered after some interval so it can fall back. Maybe a per-
question `ttl_seconds`.
## Loop substance
- **Notes compaction.** `/state/` is bind-mounted persistently and agents