agentleFS
team-attentionteam-attention/hoyeon/skills/specify/SKILL.md

specify

Skill173 starsChanged 8 months agoMITView on GitHub

"/specify", "specify", "요구사항 정의", "requirements", "스펙 잡기", "뭘 만들어야 하는지", "기획 정리", "인터뷰해서 스펙" Turn a goal into structured requirements through systematic interview. Three phases: Interview → Extract → Cross-check. Writes requirements.md in the cli format (consumed by /blueprint).

We split this skill into the rules it gives an agent

38 rules. 0 are common, 19 are distinctive, and 19 are very specific to this project.

  • 0

    Common

    Most of the 25 edited versions we read keep these.

  • 19

    Distinctive

    This author's own choices. Worth a look.

  • 19

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    All intermediate files (qa-log.md, reqs-business.md, reqs-interaction.md, reqs-tech.md) stay in <spec_dir>/ for traceability but are NOT …

    line 31
  2. Very specific:

    Use AskUserQuestion for the structured interview forms described below.

    line 37
  3. Very specific:

    Use Agent(subagent_type="...") for brownfield research and extractor subagents.

    line 38
  4. Distinctive:

    Keep the same interview protocol and output format, but use Codex-native structured input when available.

    line 45
  5. Very specific:

    Use Bash-first CLI setup through hoyeon-cli req init.

    line 48
  6. Very specific:

    Use logical Hoyeon subagent names in prompts, mapped to Codex adapters when installed.

    line 49
  7. Distinctive:

    Do not rely on hooks for session initialization or cleanup in Codex v1.

    line 52
  8. Distinctive:

    Before asking for goal/non-goals, present your understanding of the user's request using this template:

    line 60
  9. Very specific:

    Don't burn 4 cold-start questions on facts the codebase already answers.

    line 99
  10. Very specific:

    If brownfield, you may dispatch a quick code-explorer here — but a cheap ls + Read README.md + Glob is often enough for inference.

    line 122
  11. Distinctive:

    If ALL dimensions are medium/high confidence:

    line 148
  12. Distinctive:

    If ANY dimension is low confidence (typically AMBITION on truly new projects), skip the confirm-or-drill choice and ask only the …

    line 162
  13. Distinctive:

    Use these when the user picks "Override some" or when a dimension is low-confidence:

    line 166
  14. Very specific:

    Read the Q&A log template from ${baseDir}/templates/qa-log.md

    line 189
  15. Very specific:

    Write the derived calibration into qa-log.md frontmatter as depth_calibration: so Phase 1 and the gap-auditor can read it.

    line 220
  16. Very specific:

    Skip this phase entirely if where.situation == greenfield: Run it for brownfield-extension, brownfield-refactor, and hybrid.

    line 224
  17. Very specific:

    Write findings into qa-log.md under a new top-level heading ## Research (before the axis sections).

    line 250
  18. Distinctive:

    Only ask the user for decisions (what they want) and intent (why), not facts (what exists — we already found those)

    line 263
  19. Distinctive:

    When: After an axis ends, gap-auditor returns verdict=CONTINUE with an AMBIGUOUS list.

    line 367
  20. Distinctive:

    Only use free-text Q&A (no AskUserQuestion) when:

    line 379
  21. Distinctive:

    When the user's answer is "I don't know / not sure / up to you / whatever works" (either by Other free-text or by tone):

    line 388
  22. Distinctive:

    Don't re-ask the same question.

    line 398
  23. Very specific:

    Update qa-log.md after each exchange using the template format:

    line 412
  24. Distinctive:

    Do NOT call gap-auditor after every AskUserQuestion turn — that's wasteful.

    line 425
  25. Very specific:

    Write current Q&A state to qa-log.md first

    line 430
  26. Very specific:

    All 3 axes must receive SUFFICIENT verdict, AND the final audit must also return SUFFICIENT.

    line 441
  27. Very specific:

    Update qa-log.md frontmatter: status: complete with final coverage scores.

    line 442
  28. Distinctive:

    Run 3 agents in parallel:

    line 446
  29. Distinctive:

    Read all 3 reqs files

    line 460
  30. Very specific:

    Before writing the final requirements.md, surface everything to the user for explicit acceptance.

    line 472
  31. Distinctive:

    After all conflicts and assumptions are resolved, show the full requirements list before writing to disk:

    line 506
  32. Distinctive:

    If Edit: ask which requirements to change, apply edits, re-show preview.

    line 541
  33. Distinctive:

    If Re-interview: return to Phase 1 with the gap identified.

    line 542
  34. Distinctive:

    Only after user has explicitly approved the preview:

    line 546
  35. Very specific:

    Read ${baseDir}/templates/requirements.md template (cli format)

    line 548
  36. Distinctive:

    No axis grouping headings in the body (flat list).

    line 591
  37. Very specific:

    All outputs go to <spec_dir>/ (default .hoyeon/specs/{spec-name}/):

    line 599
  38. Very specific:

    No other cli commands are called by /specify.

    line 614

“Common” is measured: kept by at least 6 in 10 of the 25 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

specify: Goal → Requirements via Systematic Interview

Overview

Transform a vague goal into structured, traceable requirements through: 0. WHERE Grounding — establish project type, situation, ambition, and risk modifiers 0.5. Context Research (brownfield only) — scan existing codebase before asking the user

  1. Interview — systematic Q&A across Business/Interaction/Tech axes (depth-calibrated by WHERE)
  2. Extract — parallel requirements extraction by domain experts
  3. Cross-check — conflict/gap/duplicate detection
  4. Confirmation — user accepts assumptions + final requirements.md committed in cli format

Handoff contract

The final deliverable is <spec_dir>/requirements.md in the format that /blueprint consumes:

  • Frontmatter: type (greenfield|feature|refactor|bugfix), goal, non_goals[]
  • Body: flat list of ## R-X<num>: parent requirements, each with nested #### R-X<num>.Y: sub-requirements carrying given/when/then
  • X in the ID is axis code: B=Business, U=Interaction (user), T=Tech
  • Optional ## Open Decisions section with ### OD-N: blocks

All intermediate files (qa-log.md, reqs-business.md, reqs-interaction.md, reqs-tech.md) stay in <spec_dir>/ for traceability but are NOT read by /blueprint.

Runtime Surface

Claude Code

  • Use AskUserQuestion for the structured interview forms described below.
  • Use Agent(subagent_type="...") for brownfield research and extractor subagents.
  • Claude hooks may initialize skill session state, but the durable output remains <spec_dir>/requirements.md.

Codex

  • Keep the same interview protocol and output format, but use Codex-native structured input when available; otherwise ask one concise plain-text question at a time.
  • Use Bash-first CLI setup through hoyeon-cli req init.
  • Use logical Hoyeon subagent names in prompts, mapped to Codex adapters when installed. If adapters are not loaded in the current session, perform the smallest direct research pass needed to complete requirements.md.
  • Do not rely on hooks for session initialization or cleanup in Codex v1.

Phase 0: WHERE Grounding

The WHERE is the combination of current situation and intended scope. It calibrates how deep the interview goes on each axis — without it, every project gets the same heavyweight treatment, which over-engineers toys and under-specs production systems.

Step 0.1: Mirror (prove understanding before asking)

Before asking for goal/non-goals, present your understanding of the user's request using this template:

**Mirror — Here's what I understood**

**Understanding:**
<1–2 sentences paraphrasing the user's request in your own words. Not a verbatim echo.>

**Goal:**
- <bullet 1: concrete outcome>

**Non-Goal (explicitly out of scope):**
- <bullet 1: exclusion — at least one must be inferred by you, not stated by user>

**Ambiguous (scope-level unknowns):**
- <ambiguity about what "done" means, what's included, or who the user is>

Then confirm via AskUserQuestion:

AskUserQuestion(
  question: "Does this match your intent?",
  options: [
    { label: "Approve", description: "Proceed to WHERE grounding" },
    { label: "Revise", description: "Fix goal/non-goal/scope" }
  ]
)

Rules:

  • At least one Non-Goal and one Ambiguous item must be inferred by you — a pure echo is a violation
  • Ambiguous items are scope-level only ("what are we building / for whom / done when?"), NOT tech choices
  • Max 2 revision rounds. If still unclear, proceed and record residual ambiguities for Phase 1
  • On Approve: extract goal and non_goals from the mirror (no need to re-ask in free-text)

Step 0.2: WHERE Inference (infer-first, ask-only-on-uncertainty)

Default behavior: infer from the working directory and the user's goal. Only ask the user about dimensions you genuinely cannot determine from evidence.

Don't burn 4 cold-start questions on facts the codebase already answers. Most of PROJECT_TYPE, SITUATION, and risk factors are visible to you. Only AMBITION is reliably user-intent-driven.

Step 0.2.a: Gather signals (read-only)

Inspect the repo. Use evidence — file paths, not vibes:

  • PROJECT_TYPE signals:
    • package.json + frontend deps (react, vue, svelte, vite) / app/, src/components/ → user-facing
    • package.json + backend deps (express, fastify, nest) / routes/, api/, controllers/ → api-service
    • bin/, cli.ts, pyproject.toml with [project.scripts], single-binary Cargo project → dev-tool
    • terraform/, k8s/, helm/, Dockerfile + no app code → infrastructure
  • SITUATION signals:
    • Empty repo or only scaffolding (single README, no src) → greenfield
    • Existing src tree, many files, established conventions → brownfield (extension or refactor depends on user's goal verb)
    • User's goal mentions a new module/feature inside existing project → hybrid
  • RISK signals:
    • auth/, session, passport, oauth, cookie, jwt references → sensitive-data candidate
    • prisma/schema.prisma / migrations/ with PII columns (email, phone, ssn) → sensitive-data
    • Payment SDKs (stripe, toss, iamport, paypal) → sensitive-data + external-exposure
    • Public route definitions (no auth middleware), webhooks, /api/public → external-exposure
    • migrations/, destructive scripts, public SDK exports → irreversible
    • Load balancers, queues (kafka, sqs, redis streams), CDN config → high-scale

If brownfield, you may dispatch a quick code-explorer here — but a cheap ls + Read README.md + Glob is often enough for inference. Don't over-spend on Phase 0.

Step 0.2.b: Construct tentative WHERE and present

Build a single block in the Mirror (extend Step 0.1's mirror, or send as follow-up):

**Inferred Context** (confirm or override)

- **PROJECT_TYPE**: <inferred value>
  - Evidence: <file:line or path that supports this>
- **SITUATION**: <inferred value>
  - Evidence: <...>
- **AMBITION**: <best guess, mark confidence>
  - Confidence: low/medium/high — <why>
- **RISK factors**: [<inferred list, or "none detected">]
  - Evidence: <...>

Mark each dimension with confidence:

  • high: evidence is unambiguous (e.g., package.json with react = user-facing)
  • medium: evidence is suggestive but could be wrong
  • low: little to no signal — needs user input

Step 0.2.c: Confirm or drill (single AskUserQuestion)

If ALL dimensions are medium/high confidence:

AskUserQuestion(
  question: "Confirm inferred context?",
  options: [
    { label: "Approve all", description: "Use inferred WHERE as-is" },
    { label: "Override some", description: "Correct one or more dimensions" }
  ]
)

On Override: ask follow-up only for the dimensions the user flags. Use the original option lists below as the menu for those targeted questions.

If ANY dimension is low confidence (typically AMBITION on truly new projects), skip the confirm-or-drill choice and ask only the low-confidence dimensions directly, batched in one AskUserQuestion. Do not re-ask high-confidence dimensions.

Option menus (for targeted drills)

Use these when the user picks "Override some" or when a dimension is low-confidence:

  • PROJECT_TYPE: User-facing app / API or Service / Dev tool or Library / Infrastructure
  • SITUATION: Greenfield / Brownfield extension / Brownfield refactor / Hybrid
  • AMBITION: Toy or Experiment / Feature or MVP / Product
  • RISK factors (multiSelect): Sensitive data / External exposure / Irreversible ops / High scale

Definitions match the originals: Toy = days, failure ok; Feature/MVP = 1-2 weeks, core only; Product = long-term, reliability + security matter. Risk factors escalate specific nodes to deep in Step 0.4.

Step 0.3: Spec Name & Output Setup

  • Determine spec name (kebab-case, e.g., user-dashboard)
  • Decide spec_dir: default .hoyeon/specs/{spec-name}/
  • Bootstrap via cli — creates the directory AND writes a requirements.md stub with the correct frontmatter so /blueprint can read it later:
    hoyeon-cli req init <spec_dir> --type <greenfield|feature|refactor|bugfix> --goal "<one-line goal>"
    Map WHERE.SITUATION → --type:
    • greenfield → greenfield
    • brownfield-extension → feature
    • brownfield-refactor → refactor
    • hybrid → feature (or refactor if structural churn dominates) The stub is overwritten at Phase 4.3 once the interview is complete. If <spec_dir>/requirements.md already exists from a prior run, skip req init and proceed (the user is re-running specify on the same spec).
  • Read the Q&A log template from ${baseDir}/templates/qa-log.md
  • Initialize <spec_dir>/qa-log.md with spec name, goal, non-goals, and the WHERE context filled in

Step 0.4: Derive Axis Depth Calibration

Combine SITUATION × AMBITION × RISK_MODIFIERS to assign each taxonomy node a depth level (light, standard, or deep). Apply rules in order — later rules escalate, never downgrade.

Step A — SITUATION base:

  • Greenfield → TECH.ARCH/DATA standard
  • Brownfield extension → TECH.ARCH deep, TECH.COMPAT deep; BUSINESS.WHO light
  • Brownfield refactor → TECH.ARCH deep, TECH.COMPAT deep, TECH.DATA deep
  • Hybrid → blend Greenfield + Extension rules

Step B — AMBITION modulation:

  • Toy → TECH.SECURITY light, BUSINESS.RISK light, INTERACTION.ACCESS light. Keep INTERACTION.JOURNEY/HAPPY standard.
  • Feature/MVP → default standard; only honor deeps from Step A.
  • Product → TECH.SECURITY deep, INTERACTION.ACCESS deep, BUSINESS.RISK deep, TECH.COMPAT deep.

Step C — RISK_MODIFIERS escalation (override Step B downgrades):

  • sensitive-data → TECH.SECURITY deep, TECH.DATA deep
  • external-exposure → TECH.SECURITY deep, INTERACTION.ACCESS deep
  • irreversible → BUSINESS.RISK deep, TECH.COMPAT deep
  • high-scale → TECH.INFRA deep, TECH.ARCH deep

Examples:

  • User-facing + Greenfield + Toy + no modifiers → light SECURITY/RISK/ACCESS, standard elsewhere
  • User-facing + Greenfield + Toy + sensitive-data → SECURITY/DATA escalated to deep (small-but-dangerous)
  • API-service + Brownfield-refactor + Product + external-exposure → virtually everything deep

Project-type notes — PROJECT_TYPE doesn't change calibration numbers, but it changes what each INTERACTION node means (the interaction-extractor reads project_type for lens selection).

Write the derived calibration into qa-log.md frontmatter as depth_calibration: so Phase 1 and the gap-auditor can read it.

Phase 0.5: Context Research (brownfield only)

Skip this phase entirely if where.situation == greenfield. Run it for brownfield-extension, brownfield-refactor, and hybrid.

Why: brownfield work depends on existing code that the user may not fully remember. Asking the user "what's the architecture?" when the codebase is right there is wasteful and unreliable. Scan the code first, then interview them on decisions — not facts.

Dispatch subagents in parallel

Task(subagent_type="code-explorer",
     prompt="Goal: {goal}. Find: existing patterns, modules, or files relevant to this change. Report as file:line format with brief summary.")

Task(subagent_type="code-explorer",
     prompt="Find project structure and toolchain: package manifests, build/test/lint commands, entry points, deployment config. Report as file:line format.")

Task(subagent_type="docs-researcher",
     prompt="Goal: {goal}. Search ADRs, READMEs, docs/, CLAUDE.md, config files for conventions, architecture decisions, and constraints relevant to this work. Report as file:line format.")

For brownfield-refactor specifically, add:

Task(subagent_type="code-explorer",
     prompt="Find all call sites and dependents of {the area being refactored}. Report impact surface as file:line format.")

Consolidate into qa-log.md → research: section

Write findings into qa-log.md under a new top-level heading ## Research (before the axis sections). Include:

  • Existing architecture summary (1-3 sentences)
  • Relevant files/modules (with file:line anchors)
  • Toolchain (build/test/lint)
  • Existing constraints or conventions discovered
  • Potential impact surface (for refactors)

Also add research_done: true to the where: frontmatter block so later phases can rely on it.

Interview uses research as baseline

During Phase 1, when asking Tech axis questions:

  • Reference the research findings ("I see you use Vite + TypeScript — is that still the target?" instead of "what's your build tool?")
  • Only ask the user for decisions (what they want) and intent (why), not facts (what exists — we already found those)

Phase 1: Interview

Interview Protocol

You are the interviewer. Ask questions one axis at a time, following this taxonomy:

Axis 1: BUSINESS    — WHO, WHY, WHAT, SUCCESS, SCOPE, RISK
Axis 2: INTERACTION — JOURNEY, HAPPY, EDGE, STATE, FEEDBACK, ACCESS
Axis 3: TECH        — ARCH, DATA, INFRA, DEPEND, COMPAT, SECURITY

The INTERACTION axis is consumer-generic. Reinterpret nodes based on where.project_type:

project_typeJOURNEYHAPPYFEEDBACKACCESS
user-facingUser entry → outcomeCore UI flowVisual/audio reactionsPermissions, a11y
api-serviceConsumer integration flowCanonical API callHTTP responses, errorsAuth, rate limits
dev-toolInstall → invoke → result--help / canonical usestdout+exit codesInstall, platform
infrastructureOperator procedureGreen deploy pathDashboards, alertsRBAC, IAM

EDGE/STATE are universal: failures & conditional behavior apply everywhere.

Question Rules

PRIMARY: Use AskUserQuestion tool for all interview questions. Free-text prompting should only be a fallback when options genuinely cannot be enumerated.

Why AskUserQuestion

  • Directly implements Recognition over Recall — user picks from concrete options
  • Options with description field show consequences/trade-offs per choice
  • "Other" is auto-added — user can always override with custom answer
  • Supports batching (1-4 questions per call) — pair related questions together
  • multiSelect: true for non-exclusive choices

Batching Guidance

Batch when:

  • Questions are within the same axis node and mutually informative (e.g., WHO + WHAT)
  • Questions are orthogonal and won't confuse the user (e.g., STATE + FEEDBACK)
  • User has already given broad context and is ready for several specifics

Do NOT batch when:

  • A later question's options depend on the answer to an earlier one (ask sequentially)
  • The first question is a depth drill that may trigger more drills (go one-at-a-time)
  • User seems uncertain — a single focused question is less overwhelming

Max 4 per call (tool limit). Default: batch 2-3 related questions per turn.

Question Construction

Each AskUserQuestion option must have:

  • label: 1-5 words (what the user picks)
  • description: the consequence/implication of this choice
  • First option gets "(Recommended)" suffix only when you genuinely have a recommendation

Example (batched):

questions: [
  {
    question: "Who is the primary user?",
    header: "Primary user",
    options: [
      { label: "Senior developers", description: "Power users; expect depth + customization" },
      { label: "Junior developers", description: "Learning users; expect guidance + safe defaults" },
      { label: "Both equally", description: "Dual-mode UX; complexity to serve both" }
    ]
  },
  {
    question: "What's the success signal?",
    header: "Success metric",
    options: [
      { label: "Team-wide adoption", description: "Qualitative; hard to measure" },
      { label: "Daily active use", description: "Quantitative DAU; needs tracking" },
      { label: "Time saved per task", description: "Efficiency metric; baseline needed" }
    ]
  }
]

Depth Drill: Two Mechanisms

Drills happen at two distinct moments, with different judges. Both are required.

Type A: Inline Drill (You judge, in real time)

When: Immediately after an AskUserQuestion answer arrives.

How: Scan the selected option + any "Other" free-text for these signals. If present, the NEXT AskUserQuestion is a drill on the same node.

SignalExample answerDrill question
Vague qualifier"fast", "easy", "simple", "good UX"AskUserQuestion with concrete thresholds as options (e.g., "<1s", "<3s", "<10s")
Hidden assumption"obviously X", "of course Y"AskUserQuestion surfacing the assumption ("does X always hold? What if not?")
Multiple interpretationsA term that could mean 2+ things (e.g., "admin")AskUserQuestion listing each interpretation as an option
New stakeholderMentions a role not yet coveredAdd a new node under the current axis, AskUserQuestion about their perspective

Inline drills are fast and subjective — you catch the obvious ones on the spot.

Type B: Post-Audit Drill (gap-auditor judges, end of axis)

When: After an axis ends, gap-auditor returns verdict=CONTINUE with an AMBIGUOUS list.

How: The auditor's AMBIGUOUS list tells you exactly which nodes still need drilling. Convert each AMBIGUOUS item into an AskUserQuestion targeting that specific ambiguity, then continue until gap-auditor returns SUFFICIENT.

Post-audit drills are systematic — they catch what inline judgment missed.

Why Both

Type A is a fast first-pass filter; Type B is the safety net. Relying on only Type A means subjective blind spots slip through. Relying on only Type B means needlessly long axis rounds because trivially fixable ambiguities aren't caught early.

When Free-Text Is Acceptable

Only use free-text Q&A (no AskUserQuestion) when:

  • The answer is genuinely open-ended (e.g., "describe your current workflow")
  • You cannot construct 2+ distinct options honestly
  • The question is exploratory to find option candidates for the next round

Handling "I Don't Know" — Tentative Judgment + Open Decision

Users will sometimes not know the answer (especially on Tech axis, or when the PM doesn't know implementation details). Don't let the interview stall.

When the user's answer is "I don't know / not sure / up to you / whatever works" (either by Other free-text or by tone):

  1. Make a tentative judgment: Pick the reasonable default based on the WHERE context, existing research findings, and what experienced engineers would typically choose.
  2. Log it as an assumption: Record in qa-log.md with status: assumption and include the reasoning in > blockquote.
  3. Add to Open Decisions: Append an entry to ## Open Items in qa-log.md with:
    • The undecided question
    • Your tentative judgment
    • Why this decision can be deferred (or why it might need revisiting)
  4. Tell the user: "I'll go with {X} for now, logged as an open decision. You can revisit it later."

Don't re-ask the same question. Move on. The Phase 4 Confirmation will let the user review and override any tentative judgment.

Example:

Q: What authentication method?
User: "Dunno, whatever works"
→ Tentative: "Given brownfield-extension + sensitive-data, I'll assume existing SSO integration"
→ Log as assumption with status: assumption
→ Add to Open Items: "OD: auth method (tentative: SSO based on existing system)"
→ Continue to next question

Recording Answers

Update qa-log.md after each exchange using the template format:

  • #### Q: for the question, > blockquote for the answer (include the selected option label + any free-text)
  • ##### Drill: for depth follow-ups
  • Mark each with status: resolved | ambiguous | assumption

Gap Audit Triggers

Dispatch the gap-auditor agent at these specific moments:

  1. End of axis (required) — after you believe an axis is complete, before moving to the next
  2. Stuck on axis (early check) — after 3 consecutive AskUserQuestion turns on the same axis without moving forward
  3. Final audit (required) — after all 3 axes look done, before transitioning to Phase 2

Do NOT call gap-auditor after every AskUserQuestion turn — that's wasteful. Call it at boundaries.

Gap Audit Flow

Each call:

  1. Write current Q&A state to qa-log.md first
  2. Dispatch gap-auditor with:
    • Full qa-log.md content
    • Which axis just completed (or "final" for the full audit)
  3. Read the verdict:
    • CONTINUE → ask the agent's suggested questions (use AskUserQuestion)
    • SUFFICIENT → move on
  4. You do NOT decide completion yourself — only gap-auditor can say SUFFICIENT

Interview Completion

All 3 axes must receive SUFFICIENT verdict, AND the final audit must also return SUFFICIENT. Update qa-log.md frontmatter: status: complete with final coverage scores.

Phase 2: Requirements Extraction

Run 3 agents in parallel:

  1. Read ${baseDir}/templates/reqs-axis.md template
  2. Dispatch simultaneously:
    • business-extractor agent with: qa-log.md content + template
    • interaction-extractor agent with: qa-log.md content + template
    • tech-extractor agent with: qa-log.md content + template
  3. Write outputs to:
    • .hoyeon/specs/{spec-name}/reqs-business.md
    • .hoyeon/specs/{spec-name}/reqs-interaction.md
    • .hoyeon/specs/{spec-name}/reqs-tech.md

Phase 3: Cross-Check

  1. Read all 3 reqs files
  2. Detect issues across axes:
    • CONFLICT: requirements that contradict each other across axes
    • GAP: something mentioned in one axis but missing in others
    • DUPLICATE: same requirement expressed differently
  3. Build a Cross-Check Report (in memory, not yet written to disk):
    • List each issue with the requirement IDs involved
    • Collect all confidence: low and open_questions items from extractor outputs
    • Collect all assumptions the extractors made (items inferred but not directly sourced from Q&A)

Phase 4: User Confirmation & Finalization

Before writing the final requirements.md, surface everything to the user for explicit acceptance. This prevents assumptions from silently becoming "requirements."

Step 4.1: Present Cross-Check Summary

Show the user a concise summary grouped into:

## Final Confirmation

### Confirmed Requirements
{count by axis: Business N, Interaction N, Tech N}

### Conflicts to Resolve ({count})
- {ID pair}: {conflict description}
  → Options to resolve

### Open Questions ({count})
- {ID}: {question} (axis: {axis})

### Assumptions to Accept ({count})
- {ID}: {assumption the extractor made} — accept / reject / replace

### Out of Scope (Non-Goals)
- {items from where.non_goals}

Step 4.2: Resolve via AskUserQuestion

For each CONFLICT and ASSUMPTION, use AskUserQuestion with options (typically: accept / reject / modify / defer).

For OPEN QUESTIONS: either answer them now (free-text or AskUserQuestion) or explicitly defer them to the open_decisions list.

Step 4.3: Preview final requirements

After all conflicts and assumptions are resolved, show the full requirements list before writing to disk:

[specify] Final Requirements Preview

Type: greenfield | Goal: "<goal>"
Non-goals: <list>

## R-B1: <title>
  - R-B1.1: <sub title>
    given: ... | when: ... | then: ...
  - R-B1.2: ...

## R-U1: <title>
  - R-U1.1: ...

## R-T1: <title>
  - R-T1.1: ...

Summary: {N} parent reqs, {M} sub-reqs (B:{b} U:{u} T:{t})
Open Decisions: {count or "none"}

Then ask:

AskUserQuestion(
  question: "Finalize these requirements?",
  options: [
    { label: "Approve", description: "Write requirements.md and finish" },
    { label: "Edit", description: "Modify specific requirements before writing" },
    { label: "Re-interview", description: "Go back to interview for missing coverage" }
  ]
)

If Edit: ask which requirements to change, apply edits, re-show preview. Max 3 rounds. If Re-interview: return to Phase 1 with the gap identified.

Step 4.4: Write Final requirements.md

Only after user has explicitly approved the preview:

  1. Read ${baseDir}/templates/requirements.md template (cli format)
  2. Overwrite <spec_dir>/requirements.md (replacing the stub created by hoyeon-cli req init at Phase 0.3). Final shape:
    ---
    type: greenfield | feature | refactor | bugfix
    goal: "<one-line goal>"
    non_goals:
      - "<item>"
    ---
    
    # Requirements
    
    ## R-B1: <parent title>
    - behavior: <one-sentence system behavior>
    
    #### R-B1.1: <sub title>
    - given: <precondition>
    - when: <trigger>
    - then: <expected outcome>
    
    #### R-B1.2: ...
    
    ## R-U1: <Interaction requirement parent>
    ...
    
    ## R-T1: <Tech requirement parent>
    ...
    
    ## Pre-work
    
    - [ ] <action> (blocking)
    - [ ] <action> (non-blocking)
    
    ## Open Decisions
    
    ### OD-1: <title>
    - context: <why undecided>
    - options: [<A>, <B>]
    - impact: <what is blocked>
  3. ID rules (must match /blueprint's expectations):
    • Parent: ## R-X<num>: at H2, where X is axis code (B=Business, U=Interaction, T=Tech)
    • Sub: #### R-X<num>.Y: at H4 with given/when/then lines
    • No axis grouping headings in the body (flat list); axis is encoded in the ID letter
  4. Frontmatter carries only type, goal, non_goals[]. Do NOT add extra keys like spec, phase, date, total_requirements — those broke with cli's frontmatter format.
  5. Pre-work is optional — include only when the interview surfaced actions the user must complete before execution (e.g., "get API key", "run migration"). Mark each item (blocking) or (non-blocking). execute will gate on blocking items.
  6. Open Decisions is optional — omit the section if no unresolved decisions
  7. Confirm completion with the user, showing final file path + next step: /blueprint <spec_dir>/

Output Files

All outputs go to <spec_dir>/ (default .hoyeon/specs/{spec-name}/):

FilePhaseDescriptionConsumed by
requirements.md0.3 (stub) / 4.3 (final)Requirements in cli format (frontmatter + flat ## R-X / #### R-X.Y with GWT)/blueprint
qa-log.md1Full interview transcriptaudit/traceability only
reqs-business.md2Axis extraction scratchmerged into requirements.md
reqs-interaction.md2Axis extraction scratchmerged into requirements.md
reqs-tech.md2Axis extraction scratchmerged into requirements.md

Only requirements.md is load-bearing for downstream skills. The other files are internal scratch/audit — /blueprint does not read them.

CLI Dependency

  • hoyeon-cli req init <spec_dir> --type <t> --goal "<g>" (Phase 0.3) — creates dir + requirements.md stub
  • No other cli commands are called by /specify. Phase 4.3 overwrites requirements.md directly via Write tool.

Agents Used

AgentPhasePurpose
gap-auditor1Interview coverage validation
business-extractor2Business req extraction
interaction-extractor2Interaction req extraction (project-type-aware)
tech-extractor2Tech req extraction

Download now (ZIP)

  • Other versions28 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 28

    1. ZaxbyHub/opencode-swarm★ 517same name
    2. zaxbysauce/opencode-swarm★ 503same name
    3. genkovich/sdd★ 187same name
    4. ArvorCo/Relentless★ 98same name
    5. jantichy/claude★ 45same name
    6. mehrad-dm/mastermind★ 23same name
    7. agent-ix/quoin★ 20same name
    8. danielcherubini/skills★ 14same name
    9. ariadoss/superskills★ 12same name
    10. stormlightlabs/thunderus★ 4same name

    18 more not listed

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • Used alongsideProjects with it also use spec-review, init and 7 more.

    Other files people use alongside this one.

    Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
    • MicrosoftSkill

      spec-review

      Independent, multi-model review of a design or spec **before** any code is written, for the microsoft/winappcli repo. Activate when a contributor asks to "review this spec", "review my design", "review this design doc", "validate this approach", "should we build this", "spec review", "design review", or "feature review". Fans out parallel sub-agents — each doing its OWN research against the real codebase and ecosystem rather than trusting the spec — covering necessity & scope, approach & alternatives, feasibility vs reality, risks & unknowns, DX & user impact, and a different-model-family cross-check. Emits a decision-oriented recommendation (proceed / proceed-with-changes / reconsider) to stdout. This is the PRE-CODE companion to the pr-review skill (which reviews code already written); use spec-review at the design/spec stage, not on an implemented diff. Does NOT write code or edit the spec.

      Also in 3 projects that use this

    • MicrosoftSkill

      init

      Also in 5 projects that use this

    • Itsokay-coSkill

      discover

      Automated pattern discovery — finds what correlates with your best and worst sleep nights. Scans workouts, meals, caffeine, tags, gut scores, and timing patterns. Use when the user wants to know what actually affects their sleep.

      Also in 3 projects that use this

    • Microsoft AzureSkill

      design

      Design rules and conventions for the API Center Portal. Use when editing detail pages, card components, badges, layout, navigation, sidebars, or headers. Covers badge styling, metadata placement, page navigation patterns, and layout alignment.

      Also in 5 projects that use this

    • AWSSkill

      ship

      Finalize dev work on an issue branch — update docs, push, and open a PR.

      Also in 5 projects that use this

    • nicodianskSkill

      brainstorm

      Use when starting creative work - creating features, building components, adding functionality, or modifying behavior. Explores requirements through Socratic dialogue before any implementation.

      Also in 4 projects that use this

  • In this repository27 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.