02 — Requirements: Pre-Feature Deep Brainstorming Workflow
Plan slug: i-want-to-ea3316Stage: 2 of 7 — requirements Date: 2026-05-21 Source: 01-brainstorming.md
Scope: requirements for the brainstorming feature itself, not for agents-fleet as a whole. Every requirement is testable against the actual
src/codebase.
Functional Requirements
/brainstorm slash command (standalone)
FR-1 —
/brainstorm "<topic>"registers as a new slash command in theWorkflowscategory ofsrc/commands/registry.ts, withtype: 'fleet'and aliasesbrain,bs. Usage line:/brainstorm [--rounds <n>] [--resume <slug>] "<topic>".FR-2 — Invoking
/brainstorm "<topic>"with no--resumecreates a new plan dir.plans/<slug>/using the same slug-generation pattern as/feature(descriptive prefix + 6-char hash). The slug is printed once at startup so the user can copy it for later--resumeor/feature --from-brainstorm.FR-3 —
/brainstorm --resume <slug>continues an in-progress brainstorm if its artifact pair has not yet been written. If the artifacts already exist, the command prints the artifact paths and exits without re-running (idempotent).FR-4 —
/brainstorm "<topic>"spawns exactly 3 parallel inquisitor workers on round 1 viaspawn_worker:inquisitor-ux(role filesrc/skills/bundled/roles/inquisitor-ux.role.md, agent_typeexplorer)inquisitor-technical(role fileinquisitor-technical.role.md, agent_typeexplorer)inquisitor-edge-cases(role fileinquisitor-edge-cases.role.md, agent_typeexplorer)
Each inquisitor receives: the topic, the active project context (
.fleet/context/*.md), and a role-specific system prompt that constrains its angle. Each MUST return between 3 and 8 questions viareport_to_coordinatorwithreport_type: 'partial_result', then exit without writing files.FR-5 — After round 1 inquisitor workers complete, the coordinator collects all question payloads from the message bus, deduplicates them (case-insensitive substring + cosine-similar enough heuristics), and prioritizes them so that no more than 8 questions are surfaced per round.
FR-6 — Prioritized questions are asked one at a time via
context.coordinator.askUser({ question })— the deterministic T-153 grilling path. The full Q/A pairs are accumulated in a transcript buffer inFleetStateStore(or a command-scoped in-memory list).FR-7 — After each completed round, the coordinator decides whether to continue or summarize:
- If
roundsSoFar < N_min(defaultN_min = 2, overridable via--rounds <n>), automatically start the next round (re-spawn inquisitors OR generate follow-ups from the coordinator itself; see FR-12). - If
roundsSoFar >= N_min, ask the user viaaskUser({ question: 'Should I keep grilling or summarize?', choices: ['keep grilling', 'summarize'] }). Onsummarize, exit the loop. Onkeep grilling, run another round.
- If
FR-8 — On loop exit, the coordinator writes two artifacts to
.plans/<slug>/:00-brainstorming.md— human-readable narrative (Vision / Where it Fits / Constraints / Per-Inquisitor Findings / Full Q&A Transcript / Assumptions / Open Questions). Renders cleanly in Markdown viewers.00-brainstorming.context.md— structured machine-readable file with YAML frontmatterschema_version: 1and downstream-consumable fields (see FR-14).
FR-9 — The artifact pair MUST be written atomically (use
atomicWritefromsrc/utils/index.ts) so a crashed/brainstormleaves either both files or neither.FR-10 —
/brainstormMUST print a single-line success summary on exit:✓ Brainstorm complete: <N> questions across <M> rounds → .plans/<slug>/00-brainstorming.md.FR-11 —
/brainstorm --unattendedMUST refuse to run with an actionable error (/brainstorm is interactive by design; --unattended is not supported. Omit the flag or use /feature --unattended for non-interactive planning.). This is enforced even when invoked from inside/loop --unattendedor/loop-target --unattended.FR-12 — Round 2+ question generation MUST use coordinator-only follow-ups (not re-spawn inquisitors) by default, to control cost. A
--full-inquisitors-each-roundflag (or equivalent) re-spawns the 3 inquisitors every round if the user wants maximum coverage. Default = coordinator-only follow-ups after round 1.FR-13 — The
--rounds <n>flag overridesN_min. Valid range: 1 ≤ n ≤ 10. Out-of-range values are rejected with an actionable error.FR-14 —
00-brainstorming.context.mdschema (v1):yaml--- schema_version: 1 slug: <plan-slug> topic: <verbatim topic from /brainstorm> created_at: <ISO-8601 UTC> rounds_completed: <number> questions_asked: <number> qa_pairs: - round: 1 angle: ux | technical | edge-cases | coordinator-followup question: "..." answer: "..." asked_at: <ISO-8601> assumptions: - id: A-1 text: "..." reason: "..." confidence: certain | likely | guess # see FR-15 open_questions: - id: OQ-1 text: "..." blocking: true | false carry_forward_hints: - phase: requirements | research | design | validation | dod | tasks hint: "..." ---FR-15 — Each
qa_pairsentry MAY carry an optionalconfidencefield (certain | likely | guess). The coordinator asks the user this only when their answer was very short (< 10 chars) or contained hedging words ("maybe", "probably", "I think"). Otherwise the field is omitted and downstream phases treat absence ascertain. (This resolves Phase 1 OQ-5.)
/feature integration
- FR-16 —
/feature --from-brainstorm <slug>loads.plans/<slug>/00-brainstorming.context.md, validatesschema_version <= 1, and uses itsqa_pairs+assumptions+carry_forward_hintsas seed input for Phase 2 (requirements). Phase 1 (brainstorm) is skipped entirely — no01-brainstorming.mdis written by/featurein this mode; instead/featurecreates a reference file01-brainstorming.mdcontaining only a> Brainstorm imported from .plans/<source-slug>/00-brainstorming.mdpointer. - FR-17 —
/feature --from-brainstorm <missing-slug>MUST error with an actionable message listing available brainstorms (Available brainstorms in .plans/: <list>). If no brainstorms exist, the error suggests/brainstorm "<topic>"first. - FR-18 —
/feature --from-brainstorm <slug>when00-brainstorming.context.mdexists but has a higherschema_versionthan the current loader supports MUST error withBrainstorm artifact schema_version <N> is newer than this CLI supports (max <M>). Upgrade agents-fleet or regenerate the brainstorm. - FR-19 —
/feature --deep-brainstorm "<topic>"runs the/brainstormworkflow inline as Phase 1 of/feature. The brainstorm artifacts are written inside the feature's plan dir (same slug, not a separate slug). Downstream phases consume them like any other Phase 1 output. - FR-20 — Plain
/feature "<topic>"(no flags) continues to work exactly as today — the 3 fixedpreQuestionslight grilling. Backward compatibility is preserved (see IR-1, NFR-3).
Integration Requirements
- IR-1 — Existing
/featurebehavior MUST be preserved when invoked without--from-brainstormand without--deep-brainstorm. Test: the currentfeature-pipeline.workflow.mdparsing (7 stages, 4 with preQuestions) must continue to produce the same 7 artifacts in the same order. No regression insrc/commands/featureCommand.test.ts. - IR-2 —
/brainstormMUST use the sameaskUserpath that/featurePhase 1 grilling uses (context.coordinator.askUser({ question })→CoordinatorEngine.askUser→eventHandler.onUserInput→ InkUserInputDialog). No new user-input plumbing. The T-153 explorer mapped this path; reuse verbatim. - IR-3 —
/brainstormMUST use the same workflow definition format (*.workflow.mdwith YAML frontmatter + sibling<workflow-name>/<stage>.prompt.mdfiles) as/feature. New file:src/skills/bundled/workflows/brainstorm.workflow.md+src/skills/bundled/workflows/brainstorm/*.prompt.md. The parser fix from T-153 (nested string lists under empty-value keys) MUST cover anypreQuestions:blocks in the new workflow. - IR-4 — Inquisitor roles MUST live under
src/skills/bundled/roles/and follow the existing*.role.mdformat (YAML frontmatter withname,description,agent_type,version; body as system prompt). They MUST be discoverable bySkillRegistry.getRole(name)after the next bundled-asset cache rebuild. - IR-5 —
/brainstormMUST register throughsrc/commands/registry.ts(createBrainstormCommand()insrc/commands/brainstormCommand.ts) so it appears in/helpunderWorkflowsand is discoverable byfindCommand(). - IR-6 — The loop semantics (round-by-round until summarize) MUST be implemented in
brainstormCommand.ts, not as a declarative construct in the workflow runner. The workflow file holds the per-round stage list (spawn-inquisitors → collect-and-prioritize → grill-round → decide); the command handler drives iteration. No changes torunWorkflowStagescore. (Resolves Brainstorming Risk #1.) - IR-7 —
/brainstormMUST declare and enforcetopology: hubfor the duration of the brainstorm session (workers report only to coordinator, no peer-to-peer). If the active topology ismeshorsilent, the command MUST temporarily flip tohuband restore the prior topology on exit (try/finally). (Resolves Brainstorming Risk #7.) - IR-8 — The artifact pair written by
/brainstormMUST live in.plans/<slug>/with prefix00-(not01-), signaling Phase 0 / pre-feature./featureartifacts retain the01-–07-numbering. This convention is documented indocs/commands-manual.md. - IR-9 —
/brainstormMUST integrate with the existing graceful-shutdown flow (GracefulShutdowninsrc/utils/errors.ts): if the user/exits mid-brainstorm, any in-progress round MUST be aborted cleanly and the partial Q&A transcript MUST be discarded (do not write half-baked artifacts). Resuming via/brainstorm --resume <slug>starts a fresh round 1 against the same topic, not a partial recovery (v1 simplicity). - IR-10 — All worker output capture for inquisitors MUST go through the existing
report_to_coordinator→MessageBuspath. No new bus types or event variants.
Non-Functional Requirements
Performance
- NFR-1 — Round 1 spawn-to-first-question latency MUST be under 15 seconds on a warm cache (3 explorer workers in parallel; explorers don't require git worktree creation). Acceptable on cold cache: < 30 seconds.
- NFR-2 — A typical 2-round, 8-question brainstorm MUST complete (excluding user think-time on answering questions) in under 3 minutes of fleet activity. Outliers acceptable when the inquisitors do heavy investigation.
- NFR-3 — Plain
/feature "<topic>"(no flags) latency MUST NOT regress by more than 5% compared to today's baseline. Test: a benchmark of/featurebrainstorm phase against a fixed topic, before/after, on the same machine. - NFR-4 —
00-brainstorming.context.mdMUST be loadable in under 100ms (typical < 50ms) by/feature --from-brainstorm. The schema parser uses the existing custom YAML parser; no js-yaml dep added.
Backward compatibility
- NFR-5 — No changes to the existing
WorkflowStagetype that would break out-of-tree consumers. Any new field MUST be optional with default-undefined semantics. - NFR-6 —
feature-pipeline.workflow.mdMUST remain parseable by existing tests after this feature ships. The Phase 1preQuestionsblock stays as a fallback for plain/feature. - NFR-7 — Session schema MUST NOT change. The brainstorm transcript is in-memory only during the run, then committed to the artifact pair on exit. No persistence in the session JSON.
Security
- NFR-8 — Inquisitor workers are
exploreragent_type (read-only). They MUST NOT receive write or shell permissions, even under--provider claude(the permissionGate insrc/providers/claude/permissionGate.tsenforces this for non-bypassed types). - NFR-9 — The topic string passed to
/brainstorm "<topic>"MUST be sanitized withescapeXml/neutralizePromptInputbefore injection into inquisitor system prompts. Same defense the existing slash commands use. - NFR-10 —
00-brainstorming.mdand00-brainstorming.context.mdMUST be written with mode0o644(consistent with other plan artifacts)..plans/dir mode unchanged. - NFR-11 — No new MCP servers, no new external network calls, no new subprocesses outside the existing worker spawn path.
Testing
- NFR-12 — New unit tests in
src/commands/brainstormCommand.test.tscovering:- Argument parsing (
--rounds,--resume,--unattendedrefusal, missing topic). - Single-round flow with mocked askUser and mocked coordinator.askUser returning predetermined answers.
- N_min loop termination (continues until
N_min, then asks summarize). - "summarize" choice exits the loop and writes both artifacts.
- "keep grilling" choice runs another round.
- Artifact schema v1 contents and YAML parseability.
- Argument parsing (
- NFR-13 — New unit tests in
src/commands/featureCommand.test.tscovering:--from-brainstorm <slug>loads context file and skips Phase 1.--from-brainstorm <missing>errors with available-brainstorms list.--from-brainstormwith newer schema_version errors actionably.--deep-brainstorm "<topic>"runs the brainstorm workflow inline as Phase 1.
- NFR-14 — New parser test (extension of T-153's
parser.preQuestions.test.tsor sibling file): parsesbrainstorm.workflow.mdend-to-end and validates stage count, preQuestions (if any), artifact field, dependency declarations. - NFR-15 — Full vitest suite + parity tests MUST pass before the feature ships. Same gate as T-153.
- NFR-16 — Coverage thresholds (statements 80, branches 67, functions 75, lines 81) MUST NOT regress. New code in
brainstormCommand.tsaims for ≥ 85% line coverage (loops are tricky; mock the askUser path heavily).
Documentation
- NFR-17 —
docs/commands-manual.mdgains a/brainstormsection and updates the/featuresection with--from-brainstormand--deep-brainstormexamples. - NFR-18 —
README.mdgains a one-line mention of/brainstormin the feature list. - NFR-19 — A new
.fleet/context/architecture.md(orFLEET.md) entry mentions the brainstorm workflow alongside the existing/featuredescription.
Out of Scope
The following are explicitly NOT part of this feature. They MAY be done as follow-ups but MUST NOT block shipping:
- OOS-1 — Declarative loop semantics in
runWorkflowStages(e.g.,repeat: until-user-says-stopstage attribute). The loop lives inbrainstormCommand.tsfor v1. - OOS-2 — Fix for the
CoordinatorEngine.askUser()latent bug where--unattendedmode doesn't short-circuit (the T-153 explorer's recommendation #3)./brainstormrefuses--unattendedoutright as a workaround. The fix is a separate task. - OOS-3 — Auto-detection of "complex enough domain to use multi-agent vs simple enough for single-agent" (the adaptive option D rejected during brainstorming). Always uses multi-agent on round 1.
- OOS-4 — LLM-driven topic extraction (e.g., parse a long paste into a topic + sub-topics). Topic is the literal user-supplied string.
- OOS-5 — Multi-user / multi-session collaboration on a single brainstorm. Each
/brainstormis a single-user session. - OOS-6 — Backfilling existing
.plans/<slug>/plans with a00-brainstorming.context.mdderived from their01-brainstorming.md. New artifacts only. - OOS-7 — A
/brainstorm listsubcommand or REPL UI for browsing prior brainstorms. Usersls .plans/for now. Could be added later if demand surfaces. - OOS-8 — A "merge two brainstorms" capability (
/brainstorm merge <slug-a> <slug-b>). - OOS-9 — Hot-reload of inquisitor roles during a brainstorm. Roles are loaded at command start; mid-run edits don't apply.
- OOS-10 — Cost telemetry per brainstorm (input/output tokens budgeted separately from the rest of the session). Token usage rolls up into the session totals as usual.
- OOS-11 — Schema migration tooling for
00-brainstorming.context.mdwhen schema_version bumps. v1 is the only schema for now; bump handling is a follow-up if/when v2 lands. - OOS-12 — Integration with
/research(a sibling workflow). The two are conceptually similar but separate; cross-pollination is a future design choice.
Assumptions
- ⚠️ ASSUMPTION: Slug naming uses the same
slugify()fromplanDir.tsas/feature(descriptive prefix + 6-char hash) — REASON: consistency, plus this function is already battle-tested. No need for a brainstorm-specific naming convention. (Resolves Phase 1 OQ-2.) - ⚠️ ASSUMPTION:
/feature --deep-brainstormwrites brainstorm artifacts inside the feature's plan dir (same slug) — REASON: the brainstorm IS Phase 1 in this mode; keeping artifacts together makes the plan dir self-contained. The00-prefix still distinguishes brainstorm artifacts from the01-–07-feature artifacts. (Resolves Phase 1 OQ-3.) - ⚠️ ASSUMPTION: The askUser
--unattendedshort-circuit fix is a STRICT pre-requisite for/feature --deep-brainstorm --unattendedbut NOT for standalone/brainstorm(which refuses--unattendedoutright). REASON:/brainstormis interactive by design;/featuremay run unattended and the deep-brainstorm flag should respect that. We can ship/brainstorm+ plain/feature --from-brainstormfirst;--deep-brainstorm --unattendedwaits on the askUser fix. (Resolves Phase 1 OQ-4.) - ⚠️ ASSUMPTION: Round 2+ defaults to coordinator-only follow-up questions (no re-spawn of inquisitors) — REASON: cost control. Re-spawning 3 explorers per round burns tokens and time; coordinator-driven follow-ups are sufficient for most cases.
--full-inquisitors-each-roundis the opt-in. (Resolves Brainstorming Risk #2.) - ⚠️ ASSUMPTION: Confidence scoring per Q/A is opt-in via heuristic, not always-asked — REASON: asking "how confident are you?" after every answer is fatiguing. Only ask when the answer is short or hedged. (Resolves Phase 1 OQ-5.)
- ⚠️ ASSUMPTION: The custom YAML parser handles the schema v1 frontmatter shape (nested arrays of objects under
qa_pairs,assumptions, etc.) — REASON: post-T-153, the parser correctly handles nested string lists under empty-value keys; nested objects-in-arrays was already supported. TO VERIFY in design phase by running a real schema instance throughparseFrontmatter(). If not supported, we extend the parser similarly to T-153. - ⚠️ ASSUMPTION: Inquisitors are spawned via
spawn_workerwith explicitrole: 'inquisitor-<angle>'— REASON: the existing crew system supports role-based spawning. We don't need a brainstorm-specific crew; the active crew (if any) is bypassed for these workers via the explicit role. - ⚠️ ASSUMPTION: A brainstorm aborted by
/exitor Ctrl+C is discarded entirely (no partial artifacts) — REASON: a partial brainstorm misleads downstream/feature --from-brainstormconsumers. Simpler v1; recovery is just "run /brainstorm again".
Open Questions for Phase 3 (Research)
- ⚠️ OPEN QUESTION (RES-1): What's the exact deduplication algorithm for collected questions across the 3 inquisitor outputs? (Lowercase + token overlap? Embedding similarity? Manual exclusion list?)
- ⚠️ OPEN QUESTION (RES-2): How does the prioritization heuristic rank questions when more than 8 are returned? Need to understand the per-angle vs cross-cutting tradeoff.
- ⚠️ OPEN QUESTION (RES-3): What's the exact prompt template structure for each inquisitor role that maximizes question quality without over-fitting to a particular project type?
- ⚠️ OPEN QUESTION (RES-4): How are coordinator-driven follow-up questions (round 2+) generated — directly by the coordinator LLM, or by a small short-lived inquisitor spawn? Cost vs context-window tradeoff.
- ⚠️ OPEN QUESTION (RES-5): How should the user signal "skip this question, it's irrelevant" mid-round? A special answer like
skipparsed by the coordinator? A separateaskUserchoice? - ⚠️ OPEN QUESTION (RES-6): For
/feature --from-brainstorm, what's the format of the "Phase 2 seed input" actually injected into the requirements prompt? Verbatim Q&A pairs, a synthesized summary, or both?
Pre-stage user answer
Q: Do these requirements look right? Anything to add or change? A: yes (answered before requirements existed; effectively "proceed". User-confirmation of these specific requirements happens implicitly via the next phase advancing — if requirements were off-base, user will catch in Phase 3.)
Phase 2 complete. Ready for Phase 3 (research).