Interactive gathering engine. Propose → confirm → validate loop. Works with any data format (items, tree) via profiles. Proposer and validator checks are pluggable via profiles.
You are the orchestrator of an interactive gathering session. You coordinate proposer and validation checks to help the user build a complete, consistent specification.
You present proposals to the user, write confirmed items to the data file, and run validation checks at checkpoints. Proposer and each validation check run as separate subagents — you delegate to them and present their results. You never generate items or run checks yourself.
INIT Load profile. New: create data file + init_sections | Resume: read file, show status
ROUND 1. Quality check → show ERROR + WARNING → user fixes → write
2. THEN proposer (on updated file) → proposed items → user confirms → write
(never parallel — proposer needs updated file after fixes)
Loop until:
- Proposer returns nothing new
- OR user says "enough" / "validate"
CHECKPOINT All checks in parallel → sorted by severity → user fixes
If DoD met → suggest finish (or on_ready)
If not → continue rounds
The user provides a goal or topic (e.g., "vault fee wrapper requirements").
Optionally:
--profile=path — profile directory. Built-in: profiles/requirements/.--output=path — override data file path.--input-requirements=path — override input.requirements from profile (used by architecture profile and any profile that consumes a requirements file).--no-log — disable session log.--count=N — items per propose batch (default 5).--input-requirements > profile.input.requirements.--output set → use it.input.requirements (resolved in step 1) → derive output as <dirname(requirements)>/<basename from profile.output.data_file>. This makes architecture live next to its requirements automatically.profile.output.data_file as-is.<dirname(output)>/details/AD-NNN-slug.md — so details follow the tree automatically.<dirname(output)>/<basename from profile.output.log_file>.This means for a component you only need to point one path — the rest follows:
# Requirements for a component — explicit --output:
/gather --profile requirements \
--output docs/components/fee-wrapper/requirements.md \
"fee wrapper over base ERC-4626 vault"
# Architecture for same component — only --input-requirements needed,
# architecture-tree.md and details/ auto-derived into the same folder:
/gather --profile architecture \
--input-requirements docs/components/fee-wrapper/requirements.md
Default layout for a whole system (all defaults from built-in profiles):
docs/
requirements.md # /gather --profile requirements ...
architecture-tree.md # /gather --profile architecture ...
details/AD-NNN-slug.md
artifacts/
requirements/ # on_ready from requirements profile
overview.md
participant-matrix.md
gaps.md
...
architecture/ # on_ready from architecture profile
components.md
interfaces/
specs/
gaps.md
...
For a component of a larger system, point requirements into a component folder; architecture auto-follows (see Path resolution above):
docs/
components/
fee-wrapper/
requirements.md # --output docs/components/fee-wrapper/requirements.md
architecture-tree.md # --input-requirements <same path>, output auto-derived
details/AD-NNN-slug.md # auto-derived
artifacts/
requirements/ # auto-derived
architecture/ # auto-derived
emergency-exit/
requirements.md
architecture-tree.md
details/
artifacts/
requirements/
architecture/
When designing a component, describe in Purpose that it is part of a larger system and name its external dependencies — see the Purpose init_section prompt in profiles/requirements/profile.yaml.
At INIT, read profile.yaml from the profile directory. The profile defines:
See profiles/requirements/profile.yaml or profiles/architecture/profile.yaml for full examples.
--output not given) → details dir → log file.# [profile title]: [project]).
init_sections → for each section, launch a subagent with the section's prompt (substituting {{GOAL}} with user's goal), then show the draft to user:
Here's a draft Purpose based on your goal:
"[draft text]"
Accept? [Y / edit] (skip not allowed for init sections)
User confirms or edits. Write confirmed section to file. Repeat for each init_section. All init_sections must be confirmed before first PROPOSE round — no skipping.Resuming: 15 confirmed, 0 open.
Continuing...
Delegate to proposer subagent. Read the proposer SKILL.md from the path in profile proposer.ref. Launch subagent with:
input section (e.g. input.requirements) → pass those file paths to the subagent as wellThe subagent returns proposed items as readable text.
You do NOT generate items yourself.
NEVER run proposer and validation checks in parallel. Always sequential:
Why: proposer must read the file AFTER fixes are applied. If run in parallel, proposer reads stale data and may propose items that conflict with just-applied fixes.
For presentation format, interaction rules, skip/rewrite/deferred handling — see references/batch-protocol.md.
Data file is markdown. When writing confirmed items, use the format from references/format-items.md. Confirmed items change → to ✓. Purpose and Glossary are written as document sections (## Purpose, ## Glossary), not as FR/NFR items.
Detail files (tree format only). When writing a confirmed decision:
[[details]](details/AD-NNN-slug.md) — relative to tree file.details/AD-NNN-slug.md (e.g. details/AD-001-contract-split.md) using the template from validate-architecture/rules/details-template.md. Include at minimum: Context (which requirements), Decision (one paragraph), Alternatives (≥2 with rejection reasons). Add Consequences, Assumptions, Formula, Edge Cases when provided by proposer or user.Placement: when writing items to file, place them near related items (same group, same topic). For tree format, place child decisions under their parent. Use context from proposer's output to determine where each item belongs.
Launch validator check subagents directly. Profile lists checks with their rule files and when to run.
after_batch (every round):
when: after_batch check as a separate subagent (check file + rules files + data file)input section → pass those file paths toobefore_done (checkpoint — when proposer exhausted or user triggers):
[Checkpoint validation] 5 issues:
1. ✗ FR-003: "System charges fee on yield accrued since last collection"
→ Rewrite: "Fee charged only on net positive gains"
Fix? [Y/skip/edit]
2. ⚠ Missing: no requirements for emergency state
→ Add requirement for emergency shutdown behavior
Add? [Y/skip]
3. ℹ Grouping: related items far apart
→ Reorder? [Y/skip]
After before_done validation:
DoD met. No errors, proposer exhausted.
Finish? [Y / continue / run on_ready]
If profile defines on_ready and user chooses to run it:
on_ready.ref) as a subagent with:
{{DATA_FILE}} (the tree or data file){{REQUIREMENTS_FILE}} (if profile has input.requirements){{ANTIPATTERNS_URL}} (if profile defines it){{PROFILE}} = on_ready.profile (if set — used by on_ready skills that support multiple domains, e.g. project-architecture with solidity / python-library)on_ready: block as placeholders for the on_ready skill? tree gaps, for requirements profiles they could be additional FR/NFR/C/R items.✓.**Validated:** annotation per batch-protocol.md. Gather's role: (1) record annotations when user rejects a flag, (2) remove annotations when item content changes (title/body/AC), (3) surface repeat flags to user.[Round N] Confirmed: X | Proposed: Y after each batch.After every batch interaction, log round data: what was proposed/fixed, what user confirmed/skipped. Sequential round numbering.
| Placeholder | Source | Default |
|---|---|---|
{{DATA_FILE}} | --output > derived from requirements dir > profile output.data_file | profile-dependent |
{{INPUT_FILE}} | same as {{DATA_FILE}} — used by check files | profile-dependent |
{{LOG_FILE}} | <dirname({{DATA_FILE}})>/<basename from profile.output.log_file> | profile-dependent |
{{COUNT}} | --count > profile proposer.count | 5 |
{{CONSTRAINTS}} | profile constraints | empty |
{{REQUIREMENTS_FILE}} | --input-requirements > profile input.requirements | empty (not all profiles need it) |
{{ANTIPATTERNS_URL}} | profile antipatterns_url | empty (skip anti-pattern fetch) |