Feedback capture handles oneshots


name: Capture handles one-shot intents (don't deflect to coordinator) description: When Justin asks the inbox capture bot for a one-shot action, capture must do it end-to-end. Don't reply "ping coordinator" — that's poor UX even if the implementation spans 2-3 internal API calls. Also: tools that depend on external data being present need done:false on iter 0 so the reply doesn't hallucinate success. type: feedback originSessionId: 68a1f854-0344-4662-bf25-627b9b55d423


The capture bot's tool surface is intentionally narrow ("inbox is for low-friction capture, downstream workers do heavy lifting"), but Justin's lived UX disagrees with the strictest version of that rule. If the user request is a single intent that resolves with one bot reply, capture must handle it — even if the tool internally hits 2-3 APIs.

Why: 2026-04-29, Justin asked the capture bot "add my eightsleep from last night to my google calendar". The bot replied "Saved. Ping coordinator bot to pull Eight Sleep data and log it to Calendar." That deflection is poor UX: he had to repeat himself to a different bot for a request that's mechanically a one-shot action (read Context API, write one calendar event).

How to apply: - A tool belongs in CAPTURE_TOOL_NAMES if a single user message can resolve it with a single tool call and a single confirmation reply, regardless of how many APIs the tool itself touches internally. - Keep capture out of: multi-step synthesis, project planning, weekly reviews, anything requiring spawn_worker, anything where the user expects iterative dialogue. - When adding a new tool, ask: "would Justin expect a one-line confirmation to suffice?" If yes, capture-tier. If no, coordinator-tier.

Iter-0 hallucination corollary: The capture brain composes its reply BEFORE the tool result is visible (single-shot prompt loop). For tools that always succeed (save_to_inbox, schedule_nudge), this is fine. For tools that depend on external data being present (log_sleep, log_habit, log_time_block, briefing), the LLM must set done:false on iter 0 so iter 1 can see the tool result and compose an HONEST reply. Otherwise the bot will say "Logged to Calendar" even when the tool returned "No data found." This rule is now codified in the capture system prompt at forge/scripts/forge_telegram_brain.py.

[Claude Code, bot-refiner-v2, 2026-04-29]