Design: idea queue — Siri/Reminders + hub Ideas Discussions intake with obot triage

Requirement jwildfire/obot.roadmap#48 · 2026-07-24 · Implemented in obot.agent#42 — awaiting review
Queue front door: discussion #47 — Ideas inbox · Implementation: obot.agent#42 · Companion runbook: docs/remote-control.md (same PR).

1. Context and goals

Ideas and todos currently accumulate in the Apple Notes app until they are pasted into a Claude session by hand — fragile, lossy, and dependent on remembering the paste. The goal (@jwildfire, 2026-07-23): a capture path measured in seconds from anywhere, especially the phone, feeding a queue that obot triages into the roadmap automatically, with review happening inside the existing session framework.

Design stance: capture never touches an LLM. A persistent Claude "ideas" session was considered and rejected on context-management and cost grounds — instead the queue is plain GitHub data, and tokens are spent only in one bounded triage pass per session.

2. The pipeline at a glance

💡 CaptureSiri → Reminders, or a new Ideas discussion from GitHub mobile/web
QueueIdeas category, obot.roadmap Discussions — one idea per thread
Triageideas-triage Action within minutes; session-inbox at kickoff as backstop
Reviewbatch surfaces in the kickoff list; @jwildfire decides in-session or in-thread
Roadmappromoted to a Requirement issue; thread closed as resolved

Back-and-forth on any idea happens in its discussion thread — GitHub mobile notifications close the loop, giving the chat-like feel without a chat service.

3. Capture lanes

Lane A — direct. New discussion in the Ideas category from GitHub mobile or web. One idea per thread, any length, no polish. This is the canonical entry; everything else funnels here.
Lane B — Siri/Reminders. "Hey Siri, add ⟨idea⟩ to my obot list." The reminders-to-ideas script (no LLM) pulls uncompleted items from the Reminders list named obot and files each as an Ideas discussion posted by obotclaw[bot], with the capture timestamp. A reminder is marked complete only after its discussion posts successfully, so the script is safe to re-run; failures leave the reminder pending. Adapted from the proven OpenClaw-era ingest-reminders.sh.
Privacy lane. The hub is public. An item whose text starts with private: is appended to a local inbox file (.claude/private-inbox.md in the workspace) and never posted; the agent reads it at the same triage moment. Half-baked is fine on the public board — sensitive is not.

4. The queue: Ideas discussions

Discussions were enabled on the hub 2026-07-23; the explainer at #47 is the front door and is excluded from every sweep. Why Discussions rather than issues or a private file:

5. Triage: the session-inbox pass

Runs at session kickoff (step 2.5 of session-init) or on demand (/session-inbox). Sequence: ingest lane B → sweep the queue → triage → reply → surface → advance the watermark.

Idea looks likeTriage action
Quick todo / choreAdded to the session todo list; deadline items offered the priority flow
Requirement candidateDrafted via requirement-drafting — draft only; posting waits for @jwildfire
Update to existing workComment/edit drafted against the existing issue or PR
Design fragmentAttached to the relevant requirement's Design section or design doc
UnclearClarifying question posted in-thread; idea stays in the queue

The sweep is watermark-based (ideas-sweep, read-only): it lists threads new or updated since the last advance, so a reply from @jwildfire resurfaces its thread automatically. The watermark only advances (ideas-sweep --advance) after the pass's replies actually post — an aborted pass re-lists the same threads next time, and the re-read of each thread makes the pass idempotent.

6. Continuous triage: the ideas-triage Action

Added 2026-07-24 (@jwildfire: "don't really want ideas sitting idle until a session"). A GitHub Action on this repo (.github/workflows/ideas-triage.yml) fires on every new Ideas discussion or comment and runs Claude Code headless (claude -p, Sonnet 5, bounded toolset: gh only) on the runner — claude-code-action was the first implementation but rejects discussion events ("Unsupported event type", found live 2026-07-24). A workflow_dispatch trigger allows manual re-runs per discussion. Per run it reads the full thread, checks for an existing promotion, then takes exactly one action:

Guard rails: the agentic pipeline runs only for @jwildfire's posts and comments (added 2026-07-24) — any other human gets a one-time, LLM-free courtesy note from obotclaw[bot] saying the pipeline is not enabled for them and to ping @jwildfire for access; his reply on their thread re-triggers the pipeline with the full thread as context, which is the opt-in. The triage job additionally skips until the CLAUDE_CODE_OAUTH_TOKEN secret exists (one-time claude setup-token by @jwildfire); both jobs skip bot actors (the loop brake — obotclaw[bot]-authored posts can re-trigger workflows) and the pinned explainer #47; one comment per run; scoped to the triggering thread only; never deletes. The session-inbox pass (§5) stays as the in-session backstop, and its watermark sweep treats Action-handled (closed) threads as done. Session hygiene: whenever the roadmap is cleaned up or a wrapup runs, still-open Ideas threads are flagged as "captured but not yet promoted" so nothing idles invisibly.

GitHub agentic workflows (gh-aw), considered: GitHub's experimental agentic-workflow layer (markdown specs compiled to Actions) was evaluated for this lane. Deferred: it adds an extension + compile step and an engine abstraction we don't need, while headless Claude Code delivers the same watch → triage → file loop on the stack the program already runs (and on the existing Max subscription). Revisit if the triage prompt grows into multi-job orchestration.

7. Promotion lifecycle

When @jwildfire approves a candidate (in-session or in-thread), obot posts the Requirement issue through the standard hub lifecycle, replies in the thread with the issue link, and closes the discussion as resolved. Closing is the lifecycle end of a promoted idea; discussions are never deleted. All existing gates hold: in-thread replies and mechanical filing ride the standing hub grant, requirement posting follows the approval conventions, and nothing merges without explicit approval.

8. Cost and privacy model

9. Components

ComponentHomeRole
skills/session-inbox/SKILL.mdobot.agent (#42)The triage pass: procedure, classification table, reply and watermark rules
scripts/reminders-to-ideasobot.agent (#42)Lane B: Reminders → Ideas discussions (no LLM; complete-after-post; private: divert)
scripts/ideas-sweepobot.agent (#42)Watermark sweep of the Ideas category (read-only; --advance moves the mark)
session-init step 2.5obot.agent (#42)Runs the pass at every session kickoff
.github/workflows/ideas-triage.ymlobot.roadmapContinuous triage Action (claude-code-action prompt mode; gated on the CLAUDE_CODE_OAUTH_TOKEN secret)
Ideas category + #47obot.roadmapThe queue and its explainer (live since 2026-07-23)
.claude/ideas-watermark, .claude/private-inbox.mdobot2 workspace (local)Sweep state and the never-posted private lane

10. Rollout checklist