Skillsspecify
S

specify

Interactive specification workflow - design vision, clarify capabilities, extract behaviors. Produces spec packets, capability maps, and ADRs for /plan consumption.

Dowwie
8 stars
1.2k downloads
Updated 1w ago

Readme

specify follows the SKILL.md standard. Use the install command to add it to your agent stack.

---
name: specify
description: Interactive specification workflow - design vision, clarify capabilities, extract behaviors. Produces spec packets, capability maps, and ADRs for /plan consumption.
---

# Specify Workflow

An **agent-driven interactive workflow** that transforms ideas into actionable specifications with extracted capabilities, ready for `/plan` to decompose into tasks.

## Core Principles

1. **Workflows and invariants before architecture** - Never discuss implementation until behavior is clear
2. **Decision-dense, not prose-dense** - Bullet points over paragraphs
3. **No guessing** — Uncertainty becomes Open Questions
4. **Minimal facilitation** — Decide only when required
5. **Specs are living; ADRs are historical**
6. **Less is more** — Avoid ceremony

## Artifacts

### Required Outputs (in TARGET project)
- **README** — `{TARGET}/README.md` (project overview - what it is, how to use it)
- **Spec Packet** — `{TARGET}/docs/specs/<slug>.md` (human-readable)
- **Capability Map** — `{TARGET}/docs/specs/<slug>.capabilities.json` (machine-readable, for `/plan`)
- **Behavior Model (FSM)** — `{TARGET}/docs/state-machines/<slug>/` (state machine artifacts, for `/plan` and `/execute`)
- **ADR files** — `{TARGET}/docs/adrs/ADR-####-<slug>.md` (0..N)

### Working Files (in target project's .tasker/)
- **Session state** — `$TARGET_DIR/.tasker/state.json` (persistent, primary resume source)
- **Spec draft** — `$TARGET_DIR/.tasker/spec-draft.md` (working draft, written incrementally)
- **Discovery file** — `$TARGET_DIR/.tasker/clarify-session.md` (append-only log)
- **Stock-takes** — `$TARGET_DIR/.tasker/stock-takes.md` (append-only log of vision evolution)
- **Decision registry** — `$TARGET_DIR/.tasker/decisions.json` (index of decisions/ADRs)
- **Spec Review** — `$TARGET_DIR/.tasker/spec-review.json` (weakness analysis)

### Archive
After completion, artifacts can be archived using `tasker archive` for post-hoc analysis.

---

## MANDATORY: Phase Order

```
Initialization → Scope → Clarification Loop (Discovery) → Synthesis → Architecture Sketch → Decisions/ADRs → Gate → Spec Review → Export
```

**NEVER skip or reorder these phases.**

---

# Phase 0 — Initialization

## Goal
Establish project context and session state before specification work begins.

## STEP 1: Auto-Detect Session State (MANDATORY FIRST)

**Before asking the user anything**, check for existing session state files.

### 1a. Determine Target Directory

Check in order:
1. If user provided a path in their message, use that
2. If CWD contains `.tasker/state.json`, use CWD
3. Otherwise, ask:

```
What is the target project directory?
```

### 1b. Check for Existing Session

```bash
TARGET_DIR="<determined-path>"
STATE_FILE="$TARGET_DIR/.tasker/state.json"

if [ -f "$STATE_FILE" ]; then
    # Read state to determine if session is in progress
    PHASE=$(jq -r '.phase.current' "$STATE_FILE")
    if [ "$PHASE" != "complete" ] && [ "$PHASE" != "null" ]; then
        echo "RESUME: Found active session at phase '$PHASE'"
        # AUTO-RESUME - skip to Step 1c
    else
        echo "NEW: Previous session completed. Starting fresh."
        # Proceed to Step 2 (new session)
    fi
else
    echo "NEW: No existing session found."
    # Proceed to Step 2 (new session)
fi
```

### 1c. Auto-Resume Protocol (if active session found)

**If `.tasker/state.json` exists and `phase.current != "complete"`:**

1. **Read state.json** to get current phase and step
2. **Inform user** (no question needed):
   ```
   Resuming specification session for "{spec_session.spec_slug}"
   Current phase: {phase.current}, step: {phase.step}
   ```
3. **Read required working files** for the current phase (see Resume Protocol section)
4. **Jump directly to the current phase** - do NOT re-run earlier phases

**This is automatic. Do not ask the user whether to resume.**

---

## STEP 2: New Session Setup (only if no active session)

### 2a. No Guessing on Reference Materials

**You MUST NOT:**
- Scan directories to infer what files exist
- Guess spec locations from directory structure
- Read files to detect existing specs
- Make any assumptions about what the user has

**The user tells you everything. You ask, they answer.**

### 2b. Ask About Reference Materials

Ask using AskUserQuestion:
```
Do you have existing specification reference materials (PRDs, requirements docs, design docs, etc.)?
```
Options:
- **No reference materials** — Starting from scratch
- **Yes, I have reference materials** — I'll provide the location(s)

### If "Yes, I have reference materials":
Ask for the location(s):
```
Where are your reference materials located? (Provide path(s) - can be files or directories)
```
Free-form text input. User provides path(s) (e.g., `docs/specs/`, `requirements.md`, `PRD.pdf`).

**Validate path exists:**
```bash
EXISTING_SPEC_PATH="<user-provided-path>"
if [ ! -e "$TARGET_DIR/$EXISTING_SPEC_PATH" ] && [ ! -e "$EXISTING_SPEC_PATH" ]; then
    echo "Warning: Path not found. Please verify the path."
fi
```

### 2c. Initialize Session State

Create `.tasker/` directory structure in target project:

```bash
TASKER_DIR="$TARGET_DIR/.tasker"
mkdir -p "$TASKER_DIR"/{inputs,artifacts,tasks,bundles,reports,fsm-draft,adrs-draft}
```

Create `$TARGET_DIR/.tasker/state.json`:

```json
{
  "version": "3.0",
  "target_dir": "<absolute-path>",
  "phase": {
    "current": "initialization",
    "completed": [],
    "step": null
  },
  "created_at": "<timestamp>",
  "updated_at": "<timestamp>",
  "spec_session": {
    "project_type": "new|existing",
    "existing_spec_path": "<path-from-step-2-or-null>",
    "spec_slug": "<slug>",
    "spec_path": "<target>/docs/specs/<slug>.md",
    "started_at": "<timestamp>",
    "resumed_from": null
  },
  "scope": null,
  "clarify": null,
  "synthesis": null,
  "architecture": null,
  "decisions": null,
  "review": null
}
```

**CRITICAL: Update state.json after EVERY significant action.** This enables resume from any point.

The phase-specific state objects are populated as each phase progresses (see phase definitions below).

**If user provided existing spec path in Step 2b**, store it in `spec_session.existing_spec_path` for reference during Scope phase.

## Output (New Session Only)

For **new sessions** (Step 2 path):
- `.tasker/` directory structure created in target project
- Session state initialized in `$TARGET_DIR/.tasker/state.json`
- Existing spec path captured (if provided)
- Proceed to Phase 1 (Scope)

For **resumed sessions** (Step 1c path):
- State already exists - no initialization needed
- Jump directly to `phase.current` phase
- Read working files as specified in Resume Protocol

---

# Phase 1 — Scope

## Goal
Establish bounds before discovery.

## Pre-Scope: Load Existing Spec (if provided)

If `spec_session.existing_spec_path` was set during initialization:

1. **Read the existing spec file** to understand prior context
2. **Extract initial answers** for the scope questions below (Goal, Non-goals, Done means)
3. **Present extracted context** to user for confirmation/refinement rather than asking from scratch

```bash
if [ -n "$EXISTING_SPEC_PATH" ]; then
    echo "Loading existing spec from: $EXISTING_SPEC_PATH"
    # Read and analyze existing spec
    # Pre-fill scope questions with extracted information
fi
```

## Required Questions (AskUserQuestion)

Ask these questions using AskUserQuestion tool with structured options.
**If existing spec was loaded**, present extracted answers for confirmation rather than blank questions:

### Question 1: Goal
```
What are we building?
```
Free-form text input.

### Question 2: Non-goals
```
What is explicitly OUT of scope?
```
Free-form text input (allow multiple items).

### Question 3: Done Means
```
What are the acceptance bullets? (When is this "done"?)
```
Free-form text input (allow multiple items).

### Question 4: Tech Stack
```
What tech stack should be used?
```
Free-form text input. Examples:
- "Python 3.12+ with FastAPI, PostgreSQL, Redis"
- "TypeScript, Next.js, Prisma, Supabase"
- "Go with Chi router, SQLite"
- "Whatever fits best" (let /specify recommend based on requirements)

**If user says "whatever fits best" or similar:**
- Note this for Phase 2 (Clarify) to recommend based on gathered requirements
- Ask clarifying questions: "Any language preferences?", "Cloud provider constraints?", "Team expertise?"

### Question 5: Entry Point (CRITICAL for W8/I6 compliance)
```
How will users invoke this? What makes it available?
```

Options to present:
- **CLI command** — User runs a command (specify command name)
- **API endpoint** — User calls an HTTP endpoint (specify URL pattern)
- **Claude Code skill** — User invokes /skillname (specify trigger)
- **Library/module** — No direct invocation, imported by other code
- **Other** — Custom activation mechanism

**If user selects CLI/API/Skill:**
Follow up: "What specific steps are needed to make this available to users?"

**If user selects Library/module:**
Note in spec: "Installation & Activation: N/A - library/module only"

**Why this matters:** Specs that describe invocation without activation mechanism cause W8 weakness and I6 invariant failure. Capturing this early prevents dead entry points.

## Output

### 1. Update State (MANDATORY)

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "scope",
    "completed": ["initialization"],
    "step": "complete"
  },
  "updated_at": "<timestamp>",
  "scope": {
    "goal": "<user-provided-goal>",
    "non_goals": ["<item1>", "<item2>"],
    "done_means": ["<criterion1>", "<criterion2>"],
    "tech_stack": "<tech-stack-or-TBD>",
    "entry_point": {
      "type": "cli|api|skill|library|other",
      "trigger": "<command-name or /skillname or endpoint>",
      "activation_steps": ["<step1>", "<step2>"]
    },
    "completed_at": "<timestamp>"
  }
}
```

### 2. Write Spec Draft (MANDATORY)

Write initial spec sections to `$TARGET_DIR/.tasker/spec-draft.md`:

```markdown
# Spec: {Title}

## Goal
{goal from scope}

## Non-goals
{non_goals from scope}

## Done means
{done_means from scope}

## Tech Stack
{tech_stack from scope}

## Installation & Activation
**Entry Point:** {entry_point.trigger from scope}
**Type:** {entry_point.type from scope}

**Activation Steps:**
{entry_point.activation_steps from scope, numbered list}

**Verification:**
<!-- To be filled in during Clarify or Synthesis -->

<!-- Remaining sections will be added by subsequent phases -->
```

**IMPORTANT:** All spec content is built in this file, NOT in conversation context. Read from this file when you need prior spec content.

---

# Phase 2 — Clarify (Ralph Iterative Discovery Loop)

## Purpose
Exhaustively gather requirements via structured questioning.

## Setup

### 1. Initialize Clarify State in state.json (MANDATORY)

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "clarify",
    "completed": ["initialization", "scope"],
    "step": "starting"
  },
  "updated_at": "<timestamp>",
  "clarify": {
    "current_category": "core_requirements",
    "current_round": 1,
    "categories": {
      "core_requirements": { "status": "not_started", "rounds": 0 },
      "users_context": { "status": "not_started", "rounds": 0 },
      "integrations": { "status": "not_started", "rounds": 0 },
      "edge_cases": { "status": "not_started", "rounds": 0 },
      "quality_attributes": { "status": "not_started", "rounds": 0 },
      "existing_patterns": { "status": "not_started", "rounds": 0 },
      "preferences": { "status": "not_started", "rounds": 0 }
    },
    "pending_followups": [],
    "requirements_count": 0,
    "stock_takes_count": 0,
    "started_at": "<timestamp>"
  }
}
```

### 2. Create Discovery File

Create `$TARGET_DIR/.tasker/clarify-session.md`:

```markdown
# Discovery: {TOPIC}
Started: {timestamp}

## Category Status

| Category | Status | Rounds | Notes |
|----------|--------|--------|-------|
| Core requirements | ○ Not Started | 0 | — |
| Users & context | ○ Not Started | 0 | — |
| Integrations | ○ Not Started | 0 | — |
| Edge cases | ○ Not Started | 0 | — |
| Quality attributes | ○ Not Started | 0 | — |
| Existing patterns | ○ Not Started | 0 | — |
| Preferences | ○ Not Started | 0 | — |

## Discovery Rounds

```

### 3. Create Stock-Takes File

Create `$TARGET_DIR/.tasker/stock-takes.md`:

```markdown
# Stock-Takes: {TOPIC}
Started: {timestamp}

This file tracks how the vision evolves as discovery progresses.

---

```

## CRITICAL: Resume Capability

**On resume (after compaction or restart):**
1. Read `$TARGET_DIR/.tasker/state.json` to get `clarify` state
2. Read `$TARGET_DIR/.tasker/clarify-session.md` to get discovery history
3. Resume from `clarify.current_category` and `clarify.current_round`
4. If `clarify.pending_followups` is non-empty, continue follow-up loop first

**DO NOT rely on conversation context for clarify progress. Always read from files.**

## Loop Rules

- **No iteration cap** - Continue until goals are met
- **Category Focus Mode** - Work on ONE category at a time until it's complete or explicitly deferred
- Each iteration:
  1. Read discovery file
  2. Select ONE incomplete category to focus on (priority: Core requirements → Users & context → Integrations → Edge cases → Quality attributes → Existing patterns → Preferences)
  3. Ask **2–4 questions** within that focused category
  4. Get user answers
  5. **Run Follow-up Sub-loop** (see below) - validate and drill down on answers
  6. Only after follow-ups are complete: update discovery file, extract requirements, update category status
  7. Repeat within same category until goal is met OR user says "move on from this category"

- **Clarity Before Progress** - If user response is anything except a direct answer (counter-question, confusion, pushback, tangential), provide clarification FIRST. Do NOT present new questions until prior questions have direct answers.

- **Stop ONLY when:**
  - ALL category goals are met (see checklist), OR
  - User says "enough", "stop", "move on", or similar

## Follow-up Sub-loop (MANDATORY)

After receiving answers to a question round, **DO NOT immediately move to the next round**. First, validate each answer:

### Answer Validation Triggers

For each answer, check if follow-up is required:

| Trigger | Example | Required Follow-up |
|---------|---------|-------------------|
| **Vague quantifier** | "several users", "a few endpoints" | "How many specifically?" |
| **Undefined scope** | "and so on", "etc.", "things like that" | "Can you list all items explicitly?" |
| **Weak commitment** | "probably", "maybe", "I think" | "Is this confirmed or uncertain?" |
| **Missing specifics** | "fast response", "secure" | "What's the specific target? (e.g., <100ms)" |
| **Deferred knowledge** | "I'm not sure", "don't know yet" | "Should we make a default assumption, or is this blocking?" |
| **Contradicts earlier answer** | Conflicts with prior round | "Earlier you said X, now Y. Which is correct?" |

### Sub-loop Process

```
For each answer in current round:
  1. Check against validation triggers
  2. If trigger found:
     a. Add to pending_followups in state.json
     b. Ask ONE follow-up question (not batched)
     c. Wait for response
     d. Remove from pending_followups, re-validate the new response
     e. Repeat until answer is concrete OR user explicitly defers
  3. Only after ALL answers validated → proceed to next round
```

### MANDATORY: Persist Follow-up State

Before asking a follow-up question, update `state.json`:
```json
{
  "clarify": {
    "pending_followups": [
      {
        "question_id": "Q3.2",
        "original_answer": "<user's vague answer>",
        "trigger": "vague_quantifier",
        "followup_question": "<the follow-up question being asked>"
      }
    ]
  }
}
```

After receiving follow-up response, remove from `pending_followups` and update the round in `clarify-session.md`.

### Follow-up Question Format

Use AskUserQuestion with context from the original answer:

```json
{
  "question": "You mentioned '{user_quote}'. {specific_follow_up_question}",
  "header": "Clarify",
  "options": [
    {"label": "Specify", "description": "I'll provide a specific answer"},
    {"label": "Not critical", "description": "This detail isn't important for the spec"},
    {"label": "Defer", "description": "I don't know yet, note as open question"}
  ]
}
```

### Handling Non-Direct Responses (MANDATORY)

If the user's response is **anything other than a direct answer**, assume clarification is required. Do NOT present new questions until the original question is resolved.

| Response Type | Example | Required Action |
|---------------|---------|-----------------|
| **Counter-question** | "What do you mean by X?" | Answer their question, then re-ask yours |
| **Confusion** | "I'm not sure what you're asking" | Rephrase the question with more context |
| **Pushback** | "Why do you need to know that?" | Explain why this matters for the spec |
| **Tangential** | Talks about something else | Acknowledge, then redirect to the question |
| **Partial answer** | Answers part, ignores rest | Note the partial, ask about the unanswered part |
| **Meta-comment** | "This is getting detailed" | Acknowledge, offer to simplify or defer |

**Process:**
```
1. Detect non-direct response
2. Address the user's concern/question FIRST
3. Only after clarity achieved → re-present the original question (or confirm it's now answered)
4. Do NOT batch new questions until all prior questions have direct answers
```

**Example:**
```
Agent: "What authentication method should users use?"
User: "What options are there?"

[NON-DIRECT: User asked a counter-question]

Agent: "Common options are: (1) Email/password, (2) OAuth (Google, GitHub),
       (3) Magic link, (4) SSO/SAML. Which fits your use case?"
User: "Email/password for now, maybe OAuth later."

[NOW DIRECT: Can proceed]
```

### When NOT to Follow Up

- User explicitly says "that's all I know" or "let's move on"
- The answer is already concrete and specific
- The detail is genuinely non-blocking (implementation detail, not spec-level)
- You've already asked 2 follow-ups on the same answer (avoid interrogation)

### Example Interaction

```
Agent: "What integrations are required?"
User: "We need to connect to a few external services and maybe some APIs."

[FOLLOW-UP REQUIRED: "a few" is vague, "maybe" is weak commitment]

Agent: "You mentioned 'a few external services'. Can you list all the external systems this will integrate with?"
User: "Stripe for payments, SendGrid for email, and our internal user service."

[ANSWER NOW CONCRETE: specific services named]

Agent: "You said 'maybe some APIs'. Are there additional API integrations beyond Stripe, SendGrid, and the user service?"
User: "No, that's all."

[CATEGORY GOAL PROGRESS: Integrations now has concrete list]
```

## Category Checklist (Goal-Driven Coverage)

Each category has concrete "done" criteria. Track completion in the discovery file.

| Category | Goal (Done When) |
|----------|------------------|
| **Core requirements** | Primary workflows enumerated with inputs, outputs, and happy path steps |
| **Users & context** | User roles identified, expertise levels known, access patterns clear |
| **Integrations / boundaries** | All external systems named, data flows mapped, API contracts sketched |
| **Edge cases / failures** | Error handling defined for each workflow step, retry/fallback behavior specified |
| **Quality attributes** | Performance targets have numbers (or explicit "not critical"), security requirements stated |
| **Existing patterns** | Relevant prior art identified OR confirmed none exists, conventions to follow listed |
| **Preferences / constraints** | Tech stack decided, deployment target known, timeline/resource constraints stated |

### Tracking Format

Update discovery file with completion status:

```markdown
## Category Status

| Category | Status | Notes |
|----------|--------|-------|
| Core requirements | ✓ Complete | 3 workflows defined |
| Users & context | ✓ Complete | 2 roles: admin, user |
| Integrations | ⋯ In Progress | DB confirmed, auth TBD |
| Edge cases | ○ Not Started | — |
| Quality attributes | ○ Not Started | — |
| Existing patterns | ✓ Complete | Follow auth module pattern |
| Preferences | ⋯ In Progress | Python confirmed, framework TBD |
```

### Completion Criteria

A category is **complete** when:
1. The goal condition is satisfied (see table above)
2. User has confirmed or provided the information
3. **All answers have passed follow-up validation** (no vague quantifiers, no weak commitments, no undefined scope)
4. No obvious follow-up questions remain for that category
5. User has explicitly confirmed or the agent has verified understanding

**Do NOT mark complete** if:
- User said "I don't know" without a fallback decision
- Information is vague (e.g., "fast" instead of "<100ms")
- Dependencies on other categories are unresolved
- **Follow-up validation has not been run on all answers**
- **Any answer contains unresolved triggers** (vague quantifiers, weak commitments, etc.)

### Category Transition Rules

Before moving to a new category:
1. **Summarize** what was learned in the current category
2. **Confirm** with user: "I've captured X, Y, Z for [category]. Does that cover everything, or is there more?"
3. **Run Stock-Take** (see below)
4. **Only then** move to the next incomplete category

This prevents the feeling of being "rushed" through categories.

## Stock-Taking (Big Picture Synthesis)

### Purpose

As questions are answered and categories complete, periodically synthesize the "big picture" - what's emerging, the shape of the vision. This helps users see how their answers are building toward something coherent and provides calibration moments.

### Trigger

Stock-take is triggered **after each category completes** (before transitioning to the next category). This creates a natural rhythm of ~5-7 stock-takes during Phase 2.

### Content

A stock-take is NOT a list of answers. It's a **synthesis of meaning** - what's taking shape:

1. **What we're building** (1-2 sentences, evolving as understanding deepens)
2. **Key constraints/boundaries** that have emerged from answers
3. **The shape becoming visible** (patterns, tensions, tradeoffs surfacing)
4. **Direction check** - light confirmation the vision still feels right

### Format

```markdown
**Taking stock** (after {category_name}):

{1-3 sentence synthesis of what's emerging - not a summary of answers, but the picture forming}

{Any notable patterns, tensions, or tradeoffs becoming visible}

Does this still capture where we're heading?
```

### Example

After completing "Integrations" category:

> **Taking stock** (after Integrations):
>
> We're building a CLI skill system where specs drive task decomposition. The emphasis is on preventing incomplete handoffs - every behavior must trace back to stated requirements. The system is self-contained except for Git (for state persistence) and Claude Code (as the execution runtime).
>
> There's tension between thoroughness and workflow friction that keeps surfacing - users want comprehensive specs but not interrogation.
>
> Does this still capture where we're heading?

### Tone

- **Reflective**, not interrogative
- **Synthesizing**, not summarizing
- **Calibrating**, not gate-checking

The question at the end is light - "Does this still feel right?" not "Please confirm items 1-7."

### Process

After category completion:

1. **Read accumulated state** from `spec-draft.md` (scope), `clarify-session.md` (discovery so far)
2. **Synthesize** the emerging picture (not regurgitate answers)
3. **Present** the stock-take to user
4. **Listen** for any course correction or "that's not quite right"
5. **Append** to `$TARGET_DIR/.tasker/stock-takes.md`
6. **Update** `state.json` with `stock_takes_count`

### Stock-Takes File Format

Append each stock-take to `$TARGET_DIR/.tasker/stock-takes.md`:

```markdown
---

## Stock-Take {N} — After {Category Name}
*{timestamp}*

{The synthesis content}

**User response:** {confirmed | adjusted: brief note}

---
```

### State Update

After each stock-take, update `state.json`:
```json
{
  "clarify": {
    "stock_takes_count": N
  },
  "updated_at": "<timestamp>"
}
```

### When NOT to Stock-Take

- **Early exit**: If user says "move on" mid-category, skip stock-take for that category
- **Minor category**: If a category yielded very little new information, stock-take can be brief or combined with next
- **User impatience**: If user explicitly wants to skip calibration, respect that

## AskUserQuestion Format

### Primary Questions (Category-Focused)

Use AskUserQuestion with 2-4 questions per iteration, **all within the same category**:

```
questions:
  - question: "How should the system handle [specific scenario]?"
    header: "Edge case"  # Keep headers consistent within a round
    options:
      - label: "Option A"
        description: "Description of approach A"
      - label: "Option B"
        description: "Description of approach B"
    multiSelect: false
```

**IMPORTANT:** Do NOT mix categories in a single question batch. If you're asking about "Edge cases", all 2-4 questions should be about edge cases.

### Follow-up Questions (Single Question)

For follow-ups during the validation sub-loop, ask **ONE question at a time**:

```
questions:
  - question: "You mentioned '{user_quote}'. Can you be more specific about X?"
    header: "Clarify"
    options:
      - label: "Specify"
        description: "I'll provide details"
      - label: "Not critical"
        description: "This isn't spec-relevant"
      - label: "Defer"
        description: "Note as open question"
    multiSelect: false
```

### Open-ended Questions

For open-ended questions, use free-form with context:
```
questions:
  - question: "What integrations are required?"
    header: "Integrations"
    options:
      - label: "REST API"
        description: "Standard HTTP/JSON endpoints"
      - label: "Database direct"
        description: "Direct database access"
      - label: "Message queue"
        description: "Async via queue (Kafka, RabbitMQ, etc.)"
    multiSelect: true
```

## Updating Discovery File AND State (MANDATORY)

After each Q&A round AND its follow-ups are complete:

### 1. Append to Discovery File

Append to `$TARGET_DIR/.tasker/clarify-session.md`:

```markdown
### Round N — [Category Name]

**Questions:**
1. [Question text]
2. [Question text]

**Answers:**
1. [User's answer]
2. [User's answer]

**Follow-ups:**
- Q1 follow-up: "[follow-up question]" → "[user response]"
- Q2: No follow-up needed (answer was specific)

**Requirements Discovered:**
- REQ-NNN: [Req 1]
- REQ-NNN: [Req 2]

**Category Status:** [✓ Complete | ⋯ In Progress | User deferred]
```

### 2. Update State (MANDATORY after every round)

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "step": "round_N_complete"
  },
  "updated_at": "<timestamp>",
  "clarify": {
    "current_category": "<category>",
    "current_round": N+1,
    "categories": {
      "<category>": { "status": "in_progress|complete", "rounds": N }
    },
    "pending_followups": [],
    "requirements_count": <total REQ count>
  }
}
```

### 3. Update Category Status Table

Also update the Category Status table at the top of `clarify-session.md` to reflect current state.

**NOTE:** Do NOT proceed to next round until both files are updated. This ensures resumability.

## Completion Signal

When ALL category goals are met:

1. Verify all categories show "✓ Complete" in the status table
2. Confirm no blocking questions remain
3. Update state.json:
```json
{
  "phase": {
    "current": "clarify",
    "completed": ["initialization", "scope"],
    "step": "complete"
  },
  "updated_at": "<timestamp>",
  "clarify": {
    "status": "complete",
    "completed_at": "<timestamp>",
    "categories": { /* all marked complete */ },
    "requirements_count": <final count>
  }
}
```
4. Output:
```
<promise>CLARIFIED</promise>
```

**If user requests early exit:** Accept it, mark incomplete categories in state.json with `status: "deferred"`, and note in discovery file for Phase 3 to flag as assumptions.

---

# Phase 3 — Synthesis (Derived, Not Asked)

## Purpose
Derive structured requirements AND capabilities from discovery. **No new information introduced here.**

This phase produces TWO outputs:
1. **Spec sections** (human-readable) - Workflows, invariants, interfaces
2. **Capability map** (machine-readable) - For `/plan` to consume

## CRITICAL: State-Driven, Not Context-Driven

**On entry to Phase 3:**
1. Read `$TARGET_DIR/.tasker/state.json` to confirm `clarify.status == "complete"`
2. Read `$TARGET_DIR/.tasker/clarify-session.md` for ALL discovery content
3. Read `$TARGET_DIR/.tasker/spec-draft.md` for existing spec sections (Goal, Non-goals, etc.)

**DO NOT rely on conversation context for discovery content. Read from files.**

## Initialize Synthesis State

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "synthesis",
    "completed": ["initialization", "scope", "clarify"],
    "step": "starting"
  },
  "updated_at": "<timestamp>",
  "synthesis": {
    "status": "in_progress",
    "spec_sections": {
      "workflows": false,
      "invariants": false,
      "interfaces": false,
      "open_questions": false
    },
    "capability_map": {
      "domains_count": 0,
      "capabilities_count": 0,
      "behaviors_count": 0,
      "steel_thread_identified": false
    },
    "fsm": {
      "machines_count": 0,
      "states_count": 0,
      "transitions_count": 0,
      "invariants_validated": false
    }
  }
}
```

## Process

1. Read `$TARGET_DIR/.tasker/clarify-session.md` completely
2. Extract and organize into spec sections (update spec-draft.md after each)
3. Decompose into capabilities using I.P.S.O.A. taxonomy
4. Everything must trace to a specific discovery answer

---

## Part A: Spec Sections

### Workflows
Numbered steps with variants and failures:
```markdown
## Workflows

### 1. [Primary Workflow Name]
1. User initiates X
2. System validates Y
3. System performs Z
4. System returns result

**Variants:**
- If [condition], then [alternative flow]

**Failures:**
- If [error], then [error handling]

**Postconditions:**
- [State after completion]
```

### Invariants
Bulleted rules that must ALWAYS hold:
```markdown
## Invariants
- [Rule that must never be violated]
- [Another invariant]
```

### Interfaces
Only if a boundary exists:
```markdown
## Interfaces
- [Interface description]

(or "No new/changed interfaces" if none)
```

### Open Questions
Classified by blocking status:
```markdown
## Open Questions

### Blocking
- [Question that affects workflows/invariants/interfaces]

### Non-blocking
- [Question about internal preferences only]
```

### Part A Output: Update Files (MANDATORY)

After synthesizing each spec section:

**1. Append section to `$TARGET_DIR/.tasker/spec-draft.md`:**
```markdown
## Workflows
[Synthesized workflows content]

## Invariants
[Synthesized invariants content]

## Interfaces
[Synthesized interfaces content]

## Open Questions
[Synthesized open questions content]
```

**2. Update state.json after EACH section:**
```json
{
  "synthesis": {
    "spec_sections": {
      "workflows": true,
      "invariants": true,
      "interfaces": false,
      "open_questions": false
    }
  },
  "updated_at": "<timestamp>"
}
```

---

## Part A.5: Behavior Model Compilation (FSM)

After synthesizing Workflows, Invariants, and Interfaces, compile the Behavior Model (state machine).

### Purpose

The FSM serves two purposes:
1. **QA during implementation** - Shapes acceptance criteria, enables transition/guard coverage verification
2. **Documentation** - Human-readable diagrams for ongoing system understanding

### CRITICAL INVARIANT: Canonical Truth

> **FSM JSON is canonical; Mermaid is generated. `/plan` and `/execute` must fail if required transitions and invariants lack coverage evidence.**

- **Canonical artifacts**: `*.states.json`, `*.transitions.json`, `index.json`
- **Derived artifacts**: `*.mmd` (Mermaid diagrams) - generated ONLY from canonical JSON
- **NEVER** manually edit `.mmd` files - regenerate from JSON using `fsm-mermaid.py`
- If Mermaid is ever edited manually, the system loses machine trust

### Compilation Steps

1. **Identify Steel Thread Flow**: The primary end-to-end workflow
2. **Derive States**: Convert workflow steps to business states
   - Initial state from workflow trigger
   - Normal states from step postconditions
   - Success terminal from workflow completion
   - Failure terminals from failure clauses
3. **Derive Transitions**: Convert step sequences, variants, and failures
   - Happy path: step N → step N+1
   - Variants: conditional branches with guards
   - Failures: error transitions to failure states
4. **Link Guards to Invariants**: Map spec invariants to transition guards
5. **Validate Completeness**: Run I1-I6 checks (see below)
6. **Resolve Ambiguity**: Use AskUserQuestion for any gaps

### Completeness Invariants

The FSM MUST satisfy these invariants:

| ID | Invariant | Check |
|----|-----------|-------|
| I1 | Steel Thread FSM mandatory | At least one machine for primary workflow |
| I2 | Behavior-first | No architecture dependencies required |
| I3 | Completeness | Initial state, terminals, no dead ends |
| I4 | Guard-Invariant linkage | Every guard links to an invariant ID |
| I5 | No silent ambiguity | Vague terms resolved or flagged as Open Questions |
| I6 | Precondition reachability | If initial transition requires external trigger (e.g., "user invokes X"), the preconditions for that trigger must be specified in the spec |

**I6 Detailed Check:**
If the first transition's trigger describes user invocation (e.g., "user runs /command", "user invokes skill"):
1. Check if spec has "Installation & Activation" section
2. Verify the activation mechanism makes the trigger possible
3. If missing, flag as W8 weakness (missing activation requirements)

Example I6 failure:
- FSM starts: `Idle --[user invokes /kx]--> Running`
- Spec has NO section explaining how `/kx` becomes available
- **I6 FAILS**: "Precondition for initial transition 'user invokes /kx' not reachable - no activation mechanism specified"

### Complexity Triggers (Splitting Rules)

Create additional machines based on **structural heuristics**, not just state count:

**State Count Triggers:**
- Steel Thread exceeds 12 states → split into domain-level sub-machines
- Any machine exceeds 20 states → mandatory split

**Structural Triggers (split even with fewer states):**
- **Divergent user journeys**: Two or more distinct journeys that share only an initial prefix, then branch into unrelated flows → separate machines for each journey
- **Unrelated failure clusters**: Multiple failure states that handle different categories of errors (e.g., validation errors vs. system errors vs. business rule violations) → group related failures into their own machines
- **Mixed abstraction levels**: Machine combines business lifecycle states (e.g., Order: Created → Paid → Shipped) with UI microstates (e.g., Modal: Open → Editing → Validating) → separate business lifecycle from UI state machines
- **Cross-boundary workflows**: Workflow that spans multiple bounded contexts or domains → domain-level machine for each context

**Hierarchy Guidelines:**
- `steel_thread` level: Primary end-to-end flow
- `domain` level: Sub-flows within a bounded context
- `entity` level: Lifecycle states for a specific entity

### Ambiguity Resolution

If the compiler detects ambiguous workflow language, use AskUserQuestion:

```json
{
  "question": "The workflow step '{step}' has ambiguous outcome. What business state results?",
  "header": "FSM State",
  "options": [
    {"label": "Define state", "description": "I'll provide the state name"},
    {"label": "Same as previous", "description": "Remains in current state"},
    {"label": "Terminal success", "description": "Workflow completes successfully"},
    {"label": "Terminal failure", "description": "Workflow fails with error"}
  ]
}
```

### FSM Working Files (Written Incrementally)

During synthesis, write FSM drafts to `$TARGET_DIR/.tasker/fsm-draft/`:
- `index.json` - Machine list, hierarchy, primary machine
- `steel-thread.states.json` - State definitions (S1, S2, ...)
- `steel-thread.transitions.json` - Transition definitions (TR1, TR2, ...)
- `steel-thread.notes.md` - Ambiguity resolutions and rationale

**Update state.json after each FSM file:**
```json
{
  "synthesis": {
    "fsm": {
      "machines_count": 1,
      "states_count": 8,
      "transitions_count": 12,
      "files_written": ["index.json", "steel-thread.states.json"],
      "invariants_validated": false
    }
  },
  "updated_at": "<timestamp>"
}
```

### FSM Final Output Structure

Final FSM artifacts are exported to `{TARGET}/docs/state-machines/<slug>/` in Phase 8:
- `index.json` - Machine list, hierarchy, primary machine
- `steel-thread.states.json` - State definitions (S1, S2, ...)
- `steel-thread.transitions.json` - Transition definitions (TR1, TR2, ...)
- `steel-thread.mmd` - Mermaid stateDiagram-v2 for visualization (DERIVED from JSON)
- `steel-thread.notes.md` - Ambiguity resolutions and rationale

### ID Conventions (FSM-specific)

- Machines: `M1`, `M2`, `M3`...
- States: `S1`, `S2`, `S3`...
- Transitions: `TR1`, `TR2`, `TR3`...

### Traceability (Spec Provenance - MANDATORY)

Every state and transition MUST have a `spec_ref` pointing to the specific workflow step, variant, or failure that defined it. This prevents "FSM hallucination" where states/transitions are invented without spec basis.

**Required for each state:**
- `spec_ref.quote` - Verbatim text from the spec that defines this state
- `spec_ref.location` - Section reference (e.g., "Workflow 1, Step 3")

**Required for each transition:**
- `spec_ref.quote` - Verbatim text from the spec that defines this transition
- `spec_ref.location` - Section reference (e.g., "Workflow 1, Variant 2")

**If no spec text exists for an element:**
1. The element should NOT be created (likely FSM hallucination)
2. Or, use AskUserQuestion to get clarification and document the decision

---

## Part B: Capability Extraction

Extract capabilities from the synthesized workflows using **I.P.S.O.A. decomposition**.

### I.P.S.O.A. Behavior Taxonomy

For each capability, identify behaviors by type:

| Type | Description | Examples |
|------|-------------|----------|
| **Input** | Validation, parsing, authentication | Validate email format, parse JSON body |
| **Process** | Calculations, decisions, transformations | Calculate total, apply discount rules |
| **State** | Database reads/writes, cache operations | Save order, fetch user profile |
| **Output** | Responses, events, notifications | Return JSON, emit event, send email |
| **Activation** | Registration, installation, deployment | Register skill, deploy endpoint, write config |

### Activation Behaviors

If the spec describes user invocation (e.g., "user runs /command"), extract activation behaviors:
- **Registration**: Skill/plugin registration with runtime
- **Installation**: CLI or package installation steps
- **Deployment**: API endpoint or service deployment
- **Configuration**: Config files or environment setup

**Missing activation = coverage gap.** If spec says "user invokes X" but doesn't specify how X becomes available, add to `coverage.gaps`.

### Domain Grouping

Group related capabilities into domains:
- **Authentication** - Login, logout, session management
- **User Management** - Profile, preferences, settings
- **Core Feature** - The primary business capability
- etc.

### Steel Thread Identification

Identify the **steel thread** - the minimal end-to-end flow that proves the system works:
- Mark one flow as `is_steel_thread: true`
- This becomes the critical path for Phase 1 implementation

### Capability Map Working File

During synthesis, write capability map draft to `$TARGET_DIR/.tasker/capability-map-draft.json`.

**Update state.json as you build the map:**
```json
{
  "synthesis": {
    "capability_map": {
      "domains_count": 3,
      "capabilities_count": 8,
      "behaviors_count": 24,
      "steel_thread_identified": true,
      "draft_written": true
    }
  },
  "updated_at": "<timestamp>"
}
```

### Capability Map Final Output

In Phase 8, write final to `{TARGET}/docs/specs/<slug>.capabilities.json`:

```json
{
  "version": "1.0",
  "spec_checksum": "<first 16 chars of SHA256 of spec>",

  "domains": [
    {
      "id": "D1",
      "name": "Authentication",
      "description": "User identity and access",
      "capabilities": [
        {
          "id": "C1",
          "name": "User Login",
          "discovery_ref": "Round 3, Q2: User confirmed email/password auth",
          "behaviors": [
            {"id": "B1", "name": "ValidateCredentials", "type": "input", "description": "Check email/password format"},
            {"id": "B2", "name": "VerifyPassword", "type": "process", "description": "Compare hash"},
            {"id": "B3", "name": "CreateSession", "type": "state", "description": "Store session"},
            {"id": "B4", "name": "ReturnToken", "type": "output", "description": "JWT response"}
          ]
        }
      ]
    }
  ],

  "flows": [
    {
      "id": "F1",
      "name": "Login Flow",
      "is_steel_thread": true,
      "steps": [
        {"order": 1, "behavior_id": "B1", "description": "Validate input"},
        {"order": 2, "behavior_id": "B2", "description": "Check password"},
        {"order": 3, "behavior_id": "B3", "description": "Create session"},
        {"order": 4, "behavior_id": "B4", "description": "Return JWT"}
      ]
    }
  ],

  "invariants": [
    {"id": "I1", "description": "Passwords must never be logged", "discovery_ref": "Round 5, Q1"}
  ],

  "coverage": {
    "total_requirements": 15,
    "covered_requirements": 15,
    "gaps": []
  }
}
```

### ID Conventions

- Domains: `D1`, `D2`, `D3`...
- Capabilities: `C1`, `C2`, `C3`...
- Behaviors: `B1`, `B2`, `B3`...
- Flows: `F1`, `F2`, `F3`...
- Invariants: `I1`, `I2`, `I3`...

### Traceability

Every capability and invariant MUST have a `discovery_ref` pointing to the specific round and question in `$TARGET_DIR/.tasker/clarify-session.md` that established it.

## Synthesis Complete: Update State

After all synthesis outputs are complete, update state.json:
```json
{
  "phase": {
    "current": "synthesis",
    "completed": ["initialization", "scope", "clarify"],
    "step": "complete"
  },
  "updated_at": "<timestamp>",
  "synthesis": {
    "status": "complete",
    "completed_at": "<timestamp>",
    "spec_sections": { "workflows": true, "invariants": true, "interfaces": true, "open_questions": true },
    "capability_map": { "domains_count": N, "capabilities_count": N, "behaviors_count": N, "steel_thread_identified": true, "draft_written": true },
    "fsm": { "machines_count": N, "states_count": N, "transitions_count": N, "invariants_validated": true }
  }
}
```

## CRITICAL: Resume From Synthesis

**On resume (after compaction or restart):**
1. Read `$TARGET_DIR/.tasker/state.json` to get `synthesis` state
2. If `synthesis.spec_sections` shows incomplete sections, read `spec-draft.md` and continue
3. If `synthesis.capability_map.draft_written` is false, continue building from `capability-map-draft.json`
4. If `synthesis.fsm.invariants_validated` is false, continue FSM work from `fsm-draft/`

---

# Phase 4 — Architecture Sketch

## Rule
Architecture MUST come **AFTER** workflows, invariants, interfaces.

## Initialize Architecture State

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "architecture",
    "completed": ["initialization", "scope", "clarify", "synthesis"],
    "step": "starting"
  },
  "updated_at": "<timestamp>",
  "architecture": {
    "status": "in_progress",
    "user_provided": false,
    "agent_proposed": false
  }
}
```

## CRITICAL: Read Prior State

**On entry:**
1. Read `$TARGET_DIR/.tasker/spec-draft.md` to understand synthesized workflows
2. Architecture sketch should align with the workflows defined

## Process

Use AskUserQuestion to either:

**Option A: Ask for sketch**
```
questions:
  - question: "Can you provide a brief architecture sketch for this feature?"
    header: "Architecture"
    options:
      - label: "I'll describe it"
        description: "User provides architecture overview"
      - label: "Propose one"
        description: "Agent proposes architecture for review"
```

**Option B: Propose and confirm**
Present a brief sketch and ask for confirmation/edits.

## Output

### 1. Update spec-draft.md

Append **Architecture sketch** section to `$TARGET_DIR/.tasker/spec-draft.md`:
```markdown
## Architecture sketch
- **Components touched:** [list]
- **Responsibilities:** [brief description]
- **Failure handling:** [brief description]
```

**Keep this SHORT. No essays.**

### 2. Update State

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "step": "complete"
  },
  "updated_at": "<timestamp>",
  "architecture": {
    "status": "complete",
    "completed_at": "<timestamp>",
    "user_provided": true|false,
    "agent_proposed": true|false
  }
}
```

---

# Phase 5 — Decisions & ADRs

## Initialize Decisions State

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "decisions",
    "completed": ["initialization", "scope", "clarify", "synthesis", "architecture"],
    "step": "starting"
  },
  "updated_at": "<timestamp>",
  "decisions": {
    "status": "in_progress",
    "count": 0,
    "pending": 0
  }
}
```

## CRITICAL: Read Prior State

**On entry:**
1. Read `$TARGET_DIR/.tasker/spec-draft.md` to identify decision points from workflows/invariants
2. Read `$TARGET_DIR/.tasker/clarify-session.md` for context on requirements

## ADR Trigger

**Create ADR if ANY of these are true:**
- Hard to reverse
- Reusable standard
- Tradeoff-heavy
- Cross-cutting
- NFR-impacting

**If none apply → record decision in spec only.**

## Decision Facilitation Rules

### FACILITATE a decision ONLY IF ALL are true:
1. ADR-worthy (meets trigger above)
2. Not already decided (no existing ADR, no explicit user preference)
3. Blocking workflows, invariants, or interfaces

### DO NOT FACILITATE if ANY are true:
- Already decided
- Local / reversible / implementation detail
- Non-blocking
- User not ready to decide
- Too many options (>3)
- Premature (behavior not defined yet)

## Facilitation Format

If facilitation is allowed:

```
questions:
  - question: "How should we approach [decision topic]?"
    header: "Decision"
    options:
      - label: "Option A: [Name]"
        description: "Consequences: [1], [2]"
      - label: "Option B: [Name]"
        description: "Consequences: [1], [2]"
      - label: "Need more info"
        description: "Defer decision, add to Open Questions"
```

## Outcomes

- **User chooses option** → Write decision to spec-draft.md + create ADR (Accepted)
- **User says "need more info"** → Add as Blocking Open Question (no ADR yet)

**Update state.json after each decision:**
```json
{
  "decisions": {
    "count": 2,
    "pending": 1
  },
  "updated_at": "<timestamp>"
}
```

### Decision Registry

Write decision index to `$TARGET_DIR/.tasker/decisions.json`:
```json
{
  "decisions": [
    { "id": "DEC-001", "title": "Authentication method", "adr": "ADR-0001-auth-method.md" },
    { "id": "DEC-002", "title": "Database choice", "adr": "ADR-0002-database-choice.md" },
    { "id": "DEC-003", "title": "Error handling strategy", "adr": null }
  ]
}
```

- `adr` is the filename if ADR-worthy, `null` if inline decision only
- ADR files contain full decision context and rationale

**Usage pattern:** Always consult `decisions.json` first to find relevant decisions by title. Only read a specific ADR file when you need the full details. Never scan `adrs-draft/` directory to discover what decisions exist.

### ADR Working Files

Write ADR drafts to `$TARGET_DIR/.tasker/adrs-draft/`:
- `ADR-0001-auth-method.md`
- `ADR-0002-database-choice.md`

Final ADRs are exported to `{TARGET}/docs/adrs/` in Phase 8.

## ADR Template

Write ADRs to `{TARGET}/docs/adrs/ADR-####-<slug>.md`:

```markdown
# ADR-####: {Title}

**Status:** Accepted
**Date:** {YYYY-MM-DD}

## Applies To
- [Spec: Feature A](../specs/feature-a.md)
- [Spec: Feature B](../specs/feature-b.md)

## Context
[Why this decision was needed - reference specific discovery round if applicable]

## Decision
[What was decided]

## Alternatives Considered
| Alternative | Pros | Cons | Why Not Chosen |
|-------------|------|------|----------------|
| [Alt 1] | ... | ... | ... |
| [Alt 2] | ... | ... | ... |

## Consequences
- [Consequence 1]
- [Consequence 2]

## Related
- Supersedes: (none | ADR-XXXX)
- Related ADRs: (none | ADR-XXXX, ADR-YYYY)
```

**ADR Rules:**
- ADRs are **immutable** once Accepted
- Changes require a **new ADR** that supersedes the old
- ADRs can apply to multiple specs (many-to-many relationship)
- When creating a new spec that uses an existing ADR, update the ADR's "Applies To" section

## Decisions Complete: Update State

After all decisions are resolved, update state.json:
```json
{
  "phase": {
    "step": "complete"
  },
  "updated_at": "<timestamp>",
  "decisions": {
    "status": "complete",
    "completed_at": "<timestamp>",
    "count": 3,
    "pending": 0
  }
}
```

Also append Decisions section to `$TARGET_DIR/.tasker/spec-draft.md`.

---

# Phase 6 — Handoff-Ready Gate

## CRITICAL: State-Driven Gate Check

**On entry to Phase 6:**
1. Read `$TARGET_DIR/.tasker/state.json` to verify all prior phases complete
2. Read `$TARGET_DIR/.tasker/spec-draft.md` to verify all sections exist
3. Read `$TARGET_DIR/.tasker/fsm-draft/` to verify FSM compiled
4. Read `$TARGET_DIR/.tasker/capability-map-draft.json` to verify capability map exists

**DO NOT rely on conversation context. All gate checks use persisted files.**

Update state.json:
```json
{
  "phase": {
    "current": "gate",
    "completed": ["initialization", "scope", "clarify", "synthesis", "architecture", "decisions"],
    "step": "checking"
  },
  "updated_at": "<timestamp>"
}
```

## Preliminary Check (ALL must pass)

| Check | Requirement | Verify By |
|-------|-------------|-----------|
| Phases complete | All phases 1-5 completed in order | `state.json` phase.completed array |
| No blocking questions | Zero Blocking Open Questions | `spec-draft.md` Open Questions section |
| Interfaces present | Interfaces section exists (even if "none") | `spec-draft.md` |
| Decisions present | Decisions section exists | `spec-draft.md` |
| Workflows defined | At least one workflow with variants/failures | `spec-draft.md` |
| Invariants stated | At least one invariant | `spec-draft.md` |
| FSM compiled | Steel Thread FSM compiled with I1-I6 passing | `fsm-draft/index.json` |

## Spec Completeness Check (Checklist C1-C11)

Run the checklist verification against the current spec draft:

```bash
tasker spec checklist /tmp/claude/spec-draft.md
```

This verifies the spec contains all expected sections:

| Category | Critical Items (must pass) |
|----------|---------------------------|
| C2: Data Model | Tables defined, fields typed, constraints stated |
| C3: API | Endpoints listed, request/response schemas, auth requirements |
| C4: Behavior | Observable behaviors, business rules |
| C7: Security | Authentication mechanism, authorization rules |

### Handling Checklist Gaps

For **critical missing items** (marked with *):

1. If the spec SHOULD have this content → return to Phase 2 (Clarify) to gather requirements
2. If the spec legitimately doesn't need this → document as N/A with rationale

Example checklist failure:
```
## Gate FAILED - Incomplete Spec

Checklist verification found critical gaps:

- [✗] C2.4*: Constraints stated (UNIQUE, CHECK, FK)?
  → Data model section exists but no constraints defined

- [✗] C3.2*: Request schemas defined?
  → API endpoints listed but request bodies not specified

Action: Return to Phase 2 to clarify data constraints and API request formats.
```

## Gate Result: Update State

### If Gate PASSES:
```json
{
  "phase": {
    "current": "gate",
    "step": "passed"
  },
  "updated_at": "<timestamp>"
}
```

### If Gate FAILS:

Update state.json with blockers:
```json
{
  "phase": {
    "current": "gate",
    "step": "failed"
  },
  "updated_at": "<timestamp>",
  "gate_blockers": [
    { "type": "blocking_question", "detail": "Rate limiting across tenants" },
    { "type": "missing_section", "detail": "Interfaces" },
    { "type": "checklist_gap", "detail": "C2.4: No database constraints" }
  ]
}
```

1. List exact blockers
2. **STOP** - do not proceed to spec review
3. Tell user what must be resolved

Example:
```
## Gate FAILED

Cannot proceed. The following must be resolved:

1. **Blocking Open Questions:**
   - How should rate limiting work across tenants?
   - What is the retry policy for failed webhooks?

2. **Missing Sections:**
   - Interfaces section not present

3. **Checklist Gaps (Critical):**
   - C2.4: No database constraints defined
   - C3.2: API request schemas missing
```

---

# Phase 7 — Spec Review (MANDATORY)

## Purpose
Run automated weakness detection to catch issues before export. This is the final quality gate.

## Initialize Review State

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "review",
    "completed": ["initialization", "scope", "clarify", "synthesis", "architecture", "decisions", "gate"],
    "step": "starting"
  },
  "updated_at": "<timestamp>",
  "review": {
    "status": "in_progress",
    "weaknesses_found": 0,
    "weaknesses_resolved": 0,
    "critical_remaining": 0
  }
}
```

## CRITICAL: Read From Files

**On entry to Phase 7:**
1. The spec draft is already in `$TARGET_DIR/.tasker/spec-draft.md` - use this file
2. Do NOT build spec from conversation context

## Process

### Step 1: Copy Spec Draft for Analysis

The spec draft already exists at `$TARGET_DIR/.tasker/spec-draft.md`. Copy to temp for analysis:

```bash
cp "$TARGET_DIR/.tasker/spec-draft.md" /tmp/claude/spec-draft.md
```

### Step 2: Run Weakness Detection

```bash
tasker spec review /tmp/claude/spec-draft.md
```

This detects:
- **W1: Non-behavioral requirements** - DDL/schema not stated as behavior
- **W2: Implicit requirements** - Constraints assumed but not explicit
- **W3: Cross-cutting concerns** - Config, observability, lifecycle
- **W4: Missing acceptance criteria** - Qualitative terms without metrics
- **W5: Fragmented requirements** - Cross-references needing consolidation
- **W6: Contradictions** - Conflicting statements
- **W7: Ambiguity** - Vague quantifiers, undefined scope, weak requirements, passive voice
- **W8: Missing activation requirements** - Spec describes invocation without specifying how to make it invocable (e.g., "user runs /command" without defining how the command becomes available)
- **CK-*: Checklist gaps** - Critical missing content from C1-C11 categories

W7 Ambiguity patterns include:
- Vague quantifiers ("some", "many", "several")
- Undefined scope ("etc.", "and so on")
- Vague conditionals ("if applicable", "when appropriate")
- Weak requirements ("may", "might", "could")
- Passive voice hiding actor ("is handled", "will be processed")
- Vague timing ("quickly", "soon", "eventually")
- Subjective qualifiers ("reasonable", "appropriate")
- Unquantified limits ("large", "fast", "slow")

### Step 3: Handle Critical Weaknesses

For **CRITICAL** weaknesses (W1, W6, W7 with weak requirements), engage user:

#### W1: Non-Behavioral Requirements

```json
{
  "question": "The spec contains DDL/schema that isn't stated as behavioral requirement: '{spec_quote}'. How should this be treated?",
  "header": "DDL Mandate",
  "options": [
    {"label": "DB-level required", "description": "MUST be implemented as database-level constraint"},
    {"label": "App-layer OK", "description": "Application-layer validation is sufficient"},
    {"label": "Documentation only", "description": "This is reference documentation, not a requirement"}
  ]
}
```

#### W6: Contradictions

```json
{
  "question": "Conflicting statements found: {description}. Which is authoritative?",
  "header": "Conflict",
  "options": [
    {"label": "First statement", "description": "{first_quote}"},
    {"label": "Second statement", "description": "{second_quote}"},
    {"label": "Clarify", "description": "I'll provide clarification"}
  ]
}
```

#### W7: Ambiguity

Each W7 weakness includes a clarifying question. Use AskUserQuestion with the auto-generated question:

```json
{
  "question": "{weakness.question or weakness.suggested_resolution}",
  "header": "Clarify",
  "options": [
    {"label": "Specify value", "description": "I'll provide a specific value/definition"},
    {"label": "Not required", "description": "This is not a hard requirement"},
    {"label": "Use default", "description": "Use a sensible default"}
  ]
}
```

Example clarifying questions by ambiguity type:
- Vague quantifier: "How many specifically? Provide a number or range."
- Weak requirement: "Is this required or optional? If optional, under what conditions?"
- Vague timing: "What is the specific timing? (e.g., <100ms, every 5 minutes)"
- Passive voice: "What component/system performs this action?"

#### W8: Missing Activation Requirements

Detected when the spec describes invocation (e.g., "user runs /command", "user invokes the skill") without specifying how that invocation becomes possible.

```json
{
  "question": "The spec describes '{invocation_description}' but doesn't specify how this becomes invocable. What makes this available to users?",
  "header": "Activation",
  "options": [
    {"label": "Registration required", "description": "I'll specify what registration/installation is needed"},
    {"label": "Built-in", "description": "This is provided by the runtime environment (document which)"},
    {"label": "Documentation only", "description": "Activation is out of scope - add to Non-goals"}
  ]
}
```

W8 patterns to detect:
- "User invokes X" or "User runs X" without installation/registration steps
- Entry points described without activation mechanism
- Commands or APIs referenced without deployment/registration
- Skills or plugins described without installation instructions

If user selects "Registration required", follow up:
```json
{
  "question": "What specific steps or files are needed to make '{invocation}' available?",
  "header": "Activation Steps",
  "options": [
    {"label": "Config file", "description": "A configuration file registers this (specify format/location)"},
    {"label": "CLI install", "description": "A CLI command installs this (specify command)"},
    {"label": "Auto-discovery", "description": "The runtime auto-discovers this (specify convention)"},
    {"label": "Manual setup", "description": "Manual steps are required (I'll document them)"}
  ]
}
```

#### CK-*: Checklist Gaps

For critical checklist gaps that weren't caught in Phase 6 Gate:

```json
{
  "question": "The spec is missing {checklist_item}. Should this be added?",
  "header": "Missing Content",
  "options": [
    {"label": "Add it", "description": "I'll provide the missing information"},
    {"label": "N/A", "description": "This spec doesn't need this (document why)"},
    {"label": "Defer", "description": "Address in a follow-up spec"}
  ]
}
```

### Step 4: Record and Apply Resolutions

For each resolved weakness:

1. **Record the resolution** for downstream consumers (logic-architect):
```bash
tasker spec add-resolution {weakness_id} {resolution_type} \
    --response "{user_response}" \
    --notes "{context}"
```

Resolution types:
- `mandatory` - MUST be implemented as specified (W1 DDL requirements, W8 activation requirements)
- `clarified` - User provided specific value/definition (W7 ambiguity, W8 activation mechanism)
- `not_applicable` - Doesn't apply to this spec (checklist gaps)
- `defer` - Address in follow-up work

2. **Update the spec content** to address the issue:
   - If W1 resolved as "mandatory", add explicit behavioral statement
   - If W6 resolved, remove contradictory statement
   - If W7 resolved, replace ambiguous language with specific terms
   - If W8 resolved as "mandatory" or "clarified", add Installation & Activation section to spec
   - If CK-* resolved as "not_applicable", document rationale

### Step 5: Re-run Until Clean

```bash
# Re-run analysis
tasker spec review /tmp/claude/spec-draft.md
```

**Update state.json after each resolution:**
```json
{
  "review": {
    "weaknesses_found": 6,
    "weaknesses_resolved": 4,
    "critical_remaining": 2
  },
  "updated_at": "<timestamp>"
}
```

**Continue until:**
- Zero critical weaknesses remain, OR
- All critical weaknesses have been explicitly accepted by user

### Step 6: Save Review Results

Save the final review results:

```bash
tasker spec review /tmp/claude/spec-draft.md > $TARGET_DIR/.tasker/spec-review.json
```

Update state.json:
```json
{
  "phase": {
    "step": "complete"
  },
  "review": {
    "status": "complete",
    "completed_at": "<timestamp>",
    "weaknesses_found": 6,
    "weaknesses_resolved": 6,
    "critical_remaining": 0
  },
  "updated_at": "<timestamp>"
}
```

## Spec Review Gate

| Check | Requirement |
|-------|-------------|
| No critical weaknesses | All W1, W6, critical W7, CK-* resolved or accepted |
| Resolutions recorded | `spec-resolutions.json` contains all resolution decisions |
| Review file saved | `$TARGET_DIR/.tasker/spec-review.json` exists |

Check resolution status:
```bash
tasker spec unresolved
```

If critical weaknesses remain unresolved, **STOP** and ask user to resolve.

---

# Phase 8 — Export

## CRITICAL: Export From Working Files

**On entry to Phase 8:**
All content comes from working files, NOT conversation context:
- Spec content: `$TARGET_DIR/.tasker/spec-draft.md`
- Capability map: `$TARGET_DIR/.tasker/capability-map-draft.json`
- FSM artifacts: `$TARGET_DIR/.tasker/fsm-draft/`
- Decision registry: `$TARGET_DIR/.tasker/decisions.json`
- ADR drafts: `$TARGET_DIR/.tasker/adrs-draft/`

Update state.json:
```json
{
  "phase": {
    "current": "export",
    "completed": ["initialization", "scope", "clarify", "synthesis", "architecture", "decisions", "gate", "review"],
    "step": "starting"
  },
  "updated_at": "<timestamp>"
}
```

## Write Files

Only after spec review passes. All permanent artifacts go to the **TARGET project**.

### 1. Ensure Target Directory Structure

```bash
mkdir -p {TARGET}/docs/specs {TARGET}/docs/adrs {TARGET}/docs/state-machines/<slug>
```

### 2. Spec Packet
Copy and finalize `$TARGET_DIR/.tasker/spec-draft.md` to `{TARGET}/docs/specs/<slug>.md`:

```markdown
# Spec: {Title}

## Related ADRs
- [ADR-0001: Decision Title](../adrs/ADR-0001-decision-title.md)
- [ADR-0002: Another Decision](../adrs/ADR-0002-another-decision.md)

## Goal
[From Phase 1]

## Non-goals
[From Phase 1]

## Done means
[From Phase 1]

## Tech Stack
[From Phase 1 - summarized]

**Language & Runtime:**
- [e.g., Python 3.12+, Node.js 20+, Go 1.22+]

**Frameworks:**
- [e.g., FastAPI, Next.js, Chi]

**Data:**
- [e.g., PostgreSQL, Redis, SQLite]

**Infrastructure:**
- [e.g., Docker, AWS Lambda, Kubernetes]

**Testing:**
- [e.g., pytest, Jest, go test]

(Remove sections that don't apply)

## Installation & Activation
[If spec describes user invocation, this section is REQUIRED]

**Entry Point:** [e.g., `/myskill`, `mycommand`, `POST /api/start`]

**Activation Mechanism:**
- [e.g., "Skill registration in .claude/settings.local.json"]
- [e.g., "CLI installation via pip install"]
- [e.g., "API deployment to AWS Lambda"]

**Activation Steps:**
1. [Step to make the entry point available]
2. [Step to verify it works]

**Verification Command:**
```bash
[Command to verify the system is properly activated and invocable]
```

(If no user invocation is described, this section can be "N/A - library/module only")

## Workflows
[From Phase 3]

## Invariants
[From Phase 3]

## Interfaces
[From Phase 3]

## Architecture sketch
[From Phase 4]

## Decisions
Summary of key decisions made during specification:

| Decision | Rationale | ADR |
|----------|-----------|-----|
| [Decision 1] | [Why] | [ADR-0001](../adrs/ADR-0001-slug.md) |
| [Decision 2] | [Why] | (inline - not ADR-worthy) |

## Open Questions

### Blocking
(none - gate passed)

### Non-blocking
- [Any remaining non-blocking questions]

## Agent Handoff
- **What to build:** [Summary]
- **Must preserve:** [Key constraints]
- **Blocking conditions:** None

## Artifacts
- **Capability Map:** [<slug>.capabilities.json](./<slug>.capabilities.json)
- **Behavior Model (FSM):** [state-machines/<slug>/](../state-machines/<slug>/)
- **Discovery Log:** Archived in tasker project
```

### 3. Capability Map
Copy and validate `$TARGET_DIR/.tasker/capability-map-draft.json` to `{TARGET}/docs/specs/<slug>.capabilities.json`.

Validate against schema:
```bash
tasker state validate capability_map --file {TARGET}/docs/specs/<slug>.capabilities.json
```

### 4. Behavior Model (FSM)

Copy FSM drafts from `$TARGET_DIR/.tasker/fsm-draft/` to `{TARGET}/docs/state-machines/<slug>/`:

```bash
# Copy FSM drafts to final location
cp -r "$TARGET_DIR/.tasker/fsm-draft/"* "{TARGET}/docs/state-machines/<slug>/"

# Generate Mermaid diagrams from canonical JSON
tasker fsm mermaid {TARGET}/docs/state-machines/<slug>

# Validate FSM artifacts (I1-I6 invariants)
tasker fsm validate {TARGET}/docs/state-machines/<slug>
```

Validate against schemas:
```bash
tasker fsm validate {TARGET}/docs/state-machines/<slug>
```

### 6. ADR Files (0..N)
Copy ADR drafts from `$TARGET_DIR/.tasker/adrs-draft/` to `{TARGET}/docs/adrs/`:

```bash
cp "$TARGET_DIR/.tasker/adrs-draft/"*.md "{TARGET}/docs/adrs/"
```

### 7. Spec Review Results
Verify `$TARGET_DIR/.tasker/spec-review.json` is saved.

### 8. Generate README.md

**Purpose:** Ensure anyone encountering the project immediately understands what it is and how to use it.

Generate `{TARGET}/README.md` with:

```markdown
# {Project Title}

{One-sentence description of what this system does}

## What It Does

{2-3 bullet points explaining the core functionality}

## Installation

{From Installation & Activation section of spec}

## Usage

{Primary entry point and basic usage example}

## How It Works

{Brief explanation of the architecture/workflow - 3-5 bullet points}

## Project Structure

```
{key directories and files with one-line descriptions}
```

## License

{License from spec or "TBD"}
```

**Content Sources:**
- Title/description: From spec Goal section
- Installation: From spec Installation & Activation section
- Usage: From spec Entry Point and Workflows
- How It Works: From spec Architecture Sketch
- Project Structure: From capability map domains/files

**IMPORTANT:** The README is the first thing anyone sees. It must clearly answer:
1. What is this? (one sentence)
2. What problem does it solve?
3. How do I use it?

## Final State Update

Update `$TARGET_DIR/.tasker/state.json`:
```json
{
  "phase": {
    "current": "complete",
    "completed": ["initialization", "scope", "clarify", "synthesis", "architecture", "decisions", "gate", "review", "export"],
    "step": "done"
  },
  "updated_at": "<timestamp>",
  "completed_at": "<timestamp>"
}
```

## Completion Message

```markdown
## Specification Complete

### What Was Designed

**{Project Title}** — {One-sentence description}

{2-3 sentences explaining what this system does, who it's for, and the key value it provides}

**Entry Point:** {e.g., `/kx`, `mycommand`, `POST /api/start`}

---

**Exported to {TARGET}/:**
- `README.md` (project overview - start here)

**Exported to {TARGET}/docs/:**
- `specs/<slug>.md` (human-readable spec)
- `specs/<slug>.capabilities.json` (machine-readable for /plan)
- `state-machines/<slug>/` (behavior model - state machine)
  - `index.json`, `steel-thread.states.json`, `steel-thread.transitions.json`
  - `steel-thread.mmd` (Mermaid diagram)
- `adrs/ADR-####-*.md` (N ADRs)

**Working files (in $TARGET_DIR/.tasker/):**
- `clarify-session.md` (discovery log)
- `spec-review.json` (weakness analysis)
- `state.json` (session state)

**Capabilities Extracted:**
- Domains: N
- Capabilities: N
- Behaviors: N
- Steel Thread: F1 (name)

**Behavior Model (FSM) Summary:**
- Machines: N (primary: M1 Steel Thread)
- States: N
- Transitions: N
- Guards linked to invariants: N

**Spec Review Summary:**
- Total weaknesses detected: X
- Critical resolved: Y
- Warnings noted: Z

**Next steps:**
- Review exported spec, capability map, and FSM diagrams
- Run `/plan {TARGET}/docs/specs/<slug>.md` to begin task decomposition
```

---

# Non-Goals (Skill-Level)

- No Git automation (user commits manually)
- No project management (no Jira/Linear integration)
- No runtime ops/runbooks
- No over-facilitation (don't ask unnecessary questions)
- No architectural debates before behavior is defined
- No file/task mapping (that's `/plan`'s job)

---

# Commands

| Command | Action |
|---------|--------|
| `/specify` | Start or resume specification workflow (auto-detects from state files) |
| `/specify status` | Show current phase and progress |
| `/specify reset` | Discard current session and start fresh |

---

# Context Engineering: Persistence Over Memory

## Design Principle

This skill is designed to **survive context compaction**. All significant state is persisted to files, not held in conversation memory.

## Working Files Summary

| File | Purpose | Lifecycle |
|------|---------|-----------|
| `state.json` | Phase progress, granular step tracking | Updated after every significant action |
| `spec-draft.md` | Accumulated spec sections | Appended after each phase |
| `clarify-session.md` | Discovery Q&A log | Append-only during Phase 2 |
| `stock-takes.md` | Vision evolution log | Append-only during Phase 2 (after each category) |
| `capability-map-draft.json` | Capability extraction working copy | Written during Phase 3 |
| `fsm-draft/` | FSM working files | Written during Phase 3 |
| `decisions.json` | Decision registry (index of ADRs) | Updated during Phase 5 |
| `adrs-draft/` | ADR working files (full decision details) | Written during Phase 5 |
| `spec-review.json` | Weakness analysis results | Written during Phase 7 |

## Resume Protocol

**On any `/specify` invocation (including after compaction):**

The skill automatically detects and resumes active sessions. This is NOT optional.

### Detection (Phase 0, Step 1)
1. Check for `$TARGET_DIR/.tasker/state.json`
2. If exists and `phase.current != "complete"` → **auto-resume**
3. If not exists or `phase.current == "complete"` → **new session**

### Resume Steps (when auto-resume triggered)
1. **Read `state.json`** to get current phase and step
2. **Inform user** of resume (no confirmation needed)
3. **Read the appropriate working files** for that phase's context:

| Phase | Files to Read |
|-------|---------------|
| scope | `state.json` only |
| clarify | `clarify-session.md`, `stock-takes.md`, `state.json` (category status, pending followups, stock_takes_count) |
| synthesis | `clarify-session.md`, `stock-takes.md`, `spec-draft.md`, `capability-map-draft.json`, `fsm-draft/` |
| architecture | `spec-draft.md` |
| decisions | `spec-draft.md`, `decisions.json` |
| gate | `spec-draft.md`, `capability-map-draft.json`, `fsm-draft/` |
| review | `spec-draft.md`, `spec-review.json` |
| export | All working files |

4. **Jump to the current phase** - do NOT re-run earlier phases
5. **Resume from `phase.step`** within that phase

## Anti-Patterns (AVOID)

- **DO NOT** accumulate requirements in conversation context during Phase 2 - write to `clarify-session.md`
- **DO NOT** build spec text in conversation - write sections to `spec-draft.md` immediately
- **DO NOT** assume prior phase content is in context - always read from files
- **DO NOT** batch state updates - update `state.json` after every significant action
- **DO NOT** scan `adrs-draft/` to find decisions - use `decisions.json` as the index, then read specific ADR files only when full details are needed

## State Update Frequency

Update `state.json` after:
- Completing any user question round
- Completing any follow-up sub-loop
- Changing categories in Phase 2
- Completing any stock-take in Phase 2
- Completing any spec section in Phase 3
- Each decision outcome in Phase 5
- Each weakness resolution in Phase 7
- Completing any phase

This ensures the skill can resume from any point with minimal context loss.

---

# Integration with /plan

After `/specify` completes, user runs:
```
/plan {TARGET}/docs/specs/<slug>.md
```

Because `/specify` already produced a capability map and FSM, `/plan` can **skip** these phases:
- Spec Review (already done)
- Capability Extraction (already done)

`/plan` starts directly at **Physical Mapping** (mapping capabilities to files).

Additionally, `/plan` will:
- Load FSM artifacts from `{TARGET}/docs/state-machines/<slug>/`
- Validate transition coverage (every FSM transition → ≥1 task)
- Generate FSM-aware acceptance criteria for tasks

# Integration with /execute

When executing tasks, `/execute` will:
- Load FSM artifacts for adherence verification
- For each task with FSM context:
  - Verify transitions are implemented
  - Verify guards are enforced
  - Verify states are reachable
- Include FSM verification results in task completion

Install

Requires askill CLI v1.0+

Metadata

LicenseUnknown
Version-
Updated1w ago
PublisherDowwie

Tags

apici-cddatabasedockergithubgithub-actionsjavascriptkubernetesllmmlobservabilitypostgrespythonredisrustsecuritytestingtypescript