Spec-Driven Development

SkillMedia

Spec-driven development workflow for turning feature ideas into structured PRDs, requirements, designs, tickets, and tasks. Uses a state machine approach with EXPLORE → REQUIREMENTS → DESIGN → TASKS → SYNC phases. Each phase has validation gates, checkpointing, and session transcript support for cross-sandbox resumption.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Spec-Driven Development skill

What this skill tells your AI

The instructions your AI receives, as published by kivo360/omoios in .claude/skills/spec-driven-dev/SKILL.md and read by ahel’s review.

A systematic workflow for turning feature ideas into actionable work items that AI agents can execute.

Architecture Note: This skill is designed to work with a state machine orchestrator that executes each phase as a separate Claude SDK session. Each phase saves checkpoints to the database and can resume from any point after failure. See docs/spec-execution-stability.md for the full architecture.


🔴 CRITICAL: Read This Skill Document Thoroughly

YOU MUST follow this skill document exactly. This is not optional guidance—it is the required workflow.

Before Creating ANY Spec Files:

  1. READ THIS ENTIRE SKILL DOCUMENT - Don't skim. Read every section to understand the required formats.
  2. CHECK EXISTING FILES - Run ls -la .omoi_os/ to see what already exists. Don't duplicate.
  3. REFERENCE THE TEMPLATES - Every file type has a specific format. Copy the exact structure.
  4. USE THE CLI TOOLS - Validate with python spec_cli.py validate before syncing.

During Spec Creation:

  1. REFER BACK TO THIS DOCUMENT OFTEN - When unsure about format, re-read the relevant section.
  2. COPY FRONTMATTER EXACTLY - Don't improvise. Use the exact field names shown in templates.
  3. CHECK YOUR WORK - After creating files, run validation to catch errors early.

Output Requirements:

  • ALL files MUST have YAML frontmatter - No exceptions
  • ALL frontmatter fields MUST match the templates - Use exact field names
  • ALL specs MUST be synced - Run python spec_cli.py sync push when done
  • ALL IDs MUST follow conventions - TKT-001, TSK-001, REQ-FEATURE-001, etc.

If You're Unsure:

  1. Re-read this skill document - The answer is here
  2. Look at the Concrete Example section - Full file contents are provided
  3. Run validation - python spec_cli.py validate will tell you what's wrong

🔄 State Machine Architecture

Overview

Spec generation runs as a state machine with discrete phases. Each phase:

  1. Receives context from previous phases
  2. Executes a focused, time-boxed Claude SDK session
  3. Validates output with evaluators
  4. Saves checkpoint to database and file system
  5. Stores session transcript for potential resumption
┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   EXPLORE   │───▶│ REQUIREMENTS│───▶│   DESIGN    │───▶│   TASKS     │───▶│    SYNC     │
│  (codebase) │    │  (EARS fmt) │    │ (arch+data) │    │  (atomic)   │    │  (to API)   │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘
       │                  │                  │                  │                  │
       ▼                  ▼                  ▼                  ▼                  ▼
   CHECKPOINT         CHECKPOINT         CHECKPOINT         CHECKPOINT         COMPLETE

Phase Definitions

PhasePurposeOutputTimeoutMax Turns
EXPLOREAnalyze codebase structure, patterns, conventionsexplore.json3 min25
REQUIREMENTSGenerate EARS-format requirementsrequirements.json + .omoi_os/requirements/*.md5 min20
DESIGNCreate architecture, data models, APIsdesign.json + .omoi_os/designs/*.md5 min25
TASKSBreak down into tickets and taskstasks.json + .omoi_os/tickets/*.md + .omoi_os/tasks/*.md3 min15
SYNCPush all artifacts to OmoiOS APIAPI sync complete2 min10

Phase Context Flow

Each phase receives accumulated context from all previous phases:

# REQUIREMENTS phase receives:
{
    "exploration_context": {
        "project_type": "Next.js + FastAPI",
        "existing_models": [...],
        "conventions": {...},
        "related_to_feature": [...]
    },
    "feature_request": "User's original request"
}

# DESIGN phase receives:
{
    "exploration_context": {...},
    "requirements": [...],  # From REQUIREMENTS phase
    "feature_name": "feature-name"
}

# TASKS phase receives:
{
    "exploration_context": {...},
    "requirements": [...],
    "design": {...},  # From DESIGN phase
    "feature_name": "feature-name"
}

Evaluator Criteria

Each phase output is validated before proceeding:

PhaseEvaluatorPass Criteria
EXPLOREExplorationEvaluatorHas project_type, structure, conventions, related_to_feature
REQUIREMENTSRequirementEvaluatorEARS format, 2+ acceptance criteria per requirement, testable
DESIGNDesignEvaluatorHas architecture, data_model, api_endpoints
TASKSTaskEvaluatorValid priorities, phases, no circular dependencies, no orphan tasks

Retry Logic

If validation fails:

  1. Evaluator returns failure reasons
  2. State machine retries the phase (max 3 attempts)
  3. Retry prompt includes previous attempt and failure reasons
  4. If all retries fail, phase is marked as failed with error details

Session Transcript Persistence

Session transcripts are stored for cross-sandbox resumption:

.omoi_os/
├── phase_data/
│   ├── explore.json           # EXPLORE phase output
│   ├── requirements.json      # REQUIREMENTS phase output
│   ├── design.json            # DESIGN phase output
│   └── tasks.json             # TASKS phase output
├── session_transcripts/
│   ├── explore.jsonl          # EXPLORE session transcript
│   ├── requirements.jsonl     # REQUIREMENTS session transcript
│   └── ...
└── checkpoints/
    └── state.json             # Current state checkpoint

Environment Variables

When running in a sandbox, these environment variables control execution:

VariablePurpose
SPEC_IDSpec being generated
SPEC_PHASECurrent phase (explore/requirements/design/tasks/sync)
PHASE_DATA_B64Base64-encoded previous phase outputs
RESUME_SESSION_IDSession ID to resume
SESSION_TRANSCRIPT_B64Transcript for cross-sandbox resumption
FORK_SESSION"true" to fork instead of modify

🚨 MANDATORY: YAML Frontmatter on ALL Files

EVERY file you create in .omoi_os/ MUST begin with YAML frontmatter. This is NON-NEGOTIABLE.

Why Frontmatter is Required

  1. Programmatic Parsing: The CLI tools, API sync, and orchestrator all parse frontmatter to understand file structure
  2. Traceability: Frontmatter enables linking requirements → designs → tickets → tasks
  3. Status Tracking: Status, priority, and dependencies are tracked via frontmatter fields
  4. API Integration: When syncing to backend, frontmatter provides the structured data

Required Frontmatter by File Type

PRDs (.omoi_os/docs/prd-*.md):

---
id: PRD-{FEATURE}-001
title: {Feature Name} PRD
feature: {feature-name}
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD}
status: draft  # draft | review | approved
author: Claude
---

Requirements (.omoi_os/requirements/*.md):

---
id: REQ-{FEATURE}-001
title: {Feature Name} Requirements
feature: {feature-name}
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD}
status: draft  # draft | review | approved
category: functional  # functional | non-functional | constraint
priority: HIGH  # CRITICAL | HIGH | MEDIUM | LOW
prd_ref: docs/prd-{feature-name}.md
design_ref: designs/{feature-name}.md
---

Designs (.omoi_os/designs/*.md):

---
id: DESIGN-{FEATURE}-001
title: {Feature Name} Design
feature: {feature-name}
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD}
status: draft  # draft | review | approved
requirements:
  - REQ-{FEATURE}-001
# API endpoints (synced to Design panel)
api_endpoints:
  - method: POST
    path: /api/v1/{resource}
    description: Create a new resource
    auth_required: true
    request_body: '{"field": "value"}'
    response: '{"id": "uuid", "field": "value"}'
  - method: GET
    path: /api/v1/{resource}/{id}
    description: Get resource by ID
    auth_required: true
    path_params: [id]
# Data models (synced to Design panel)
data_models:
  - name: ResourceModel
    description: Main resource entity
    table_name: resources
    typed_fields:
      - name: id
        type: uuid
        description: Unique identifier
        constraints: [primary_key]
      - name: name
        type: string
        description: Resource name
      - name: created_at
        type: timestamp
        default: now()
    relationships:
      - belongs_to User
      - has_many Items
---

Tickets (.omoi_os/tickets/TKT-*.md):

---
id: TKT-{NNN}
title: {Ticket Title}
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD}
status: backlog  # backlog | analyzing | building | testing | done | blocked
priority: HIGH  # CRITICAL | HIGH | MEDIUM | LOW
estimate: M  # S | M | L | XL
design_ref: designs/{feature-name}.md
requirements:
  - REQ-{FEATURE}-FUNC-001
dependencies:
  blocked_by: []
  blocks: []
---

Tasks (.omoi_os/tasks/TSK-*.md):

---
id: TSK-{NNN}
title: {Task Title}
created: {YYYY-MM-DD}
status: pending  # pending | in_progress | review | done | blocked
parent_ticket: TKT-{NNN}
estimate: S  # S | M | L
type: implementation  # implementation | refactor | test | documentation | research | bugfix
dependencies:
  depends_on: []
  blocks: []
---

❌ Files Without Frontmatter Will Fail

Files missing frontmatter will:

  • Not appear in spec_cli.py show commands
  • Not sync to the API
  • Not be tracked in traceability reports
  • Not be picked up by the orchestrator

✅ Always Start With Frontmatter

When creating ANY file in .omoi_os/, your FIRST action should be writing the YAML frontmatter block, THEN the content.


🚨 MANDATORY: Use Spec CLI to Sync to Server

After creating files in .omoi_os/, you MUST sync them to the OmoiOS server using the spec CLI. This is NON-NEGOTIABLE.

Why Sync is Required

  1. Visibility: Specs/tickets/tasks only appear in the dashboard after syncing
  2. Orchestration: The orchestrator only picks up tasks from the database, not from files
  3. Traceability: Server-side tracking enables dependency management and status updates
  4. Persistence: Local files can be lost; server data persists across sandbox restarts

Spec CLI Location

The spec CLI is located at:

/root/.claude/skills/spec-driven-dev/scripts/spec_cli.py

Required Workflow: Create → Validate → Sync

EVERY time you create or modify files in .omoi_os/, follow this workflow:

# Step 1: Navigate to the spec CLI scripts directory
cd /root/.claude/skills/spec-driven-dev/scripts

# Step 2: Validate your specs (check for errors BEFORE syncing)
python spec_cli.py validate

# Step 3: Preview what will be synced (dry run)
# Note: OMOIOS_PROJECT_ID and OMOIOS_API_URL are auto-injected - no need to specify!
python spec_cli.py sync-specs diff

# Step 4: Sync requirements and designs to create specs
python spec_cli.py sync-specs push

# Step 5: Preview ticket/task sync
python spec_cli.py sync diff

# Step 6: Sync tickets and tasks
python spec_cli.py sync push

# Step 7: Verify traceability
python spec_cli.py api-trace

Environment Variables (Auto-Injected by Sandbox)

When the sandbox is created, the orchestrator automatically injects environment variables so that CLI tools and scripts work without manual configuration. This design means:

  1. No manual URL configuration - The API client knows where to connect
  2. No credential passing - Authentication is pre-configured
  3. No project ID lookup - The context is already set

Auto-injected variables:

VariableDescriptionExample Value
OMOIOS_API_URLAPI endpoint URLhttps://api.omoios.dev
OMOIOS_API_KEYAuthentication keysk-...
OMOIOS_PROJECT_IDCurrent project IDproj-abc123
TASK_IDCurrent task being executedtask-xyz789
AGENT_IDAgent executing the taskagent-def456
EXECUTION_MODESkill loading modeimplementation or exploration

Fallback behavior: If running outside a sandbox (e.g., local development), the CLI falls back to https://api.omoios.dev as the default API URL. You can override any value by passing explicit arguments like --api-url or --project-id if needed.

Bottom line: Just run the commands - no configuration required inside sandboxes.

Quick Reference Commands

# Show all local specs
python spec_cli.py show all

# Show only tickets
python spec_cli.py show tickets

# Show only tasks with blocking status
python spec_cli.py show tasks

# Show dependency graph
python spec_cli.py show graph

# Show ready tasks (not blocked)
python spec_cli.py show ready

# List projects from server (uses OMOIOS_API_URL automatically)
python spec_cli.py projects

# View project details (uses OMOIOS_PROJECT_ID and OMOIOS_API_URL automatically)
python spec_cli.py project

❌ DO NOT Skip Syncing

If you only create local files without syncing:

  • Tasks won't be picked up by agents
  • Tickets won't appear in the dashboard
  • Dependencies won't be tracked
  • Status updates won't propagate

The Core Flow

The workflow maps to the state machine phases:

┌─────────────────────────────────────────────────────────────────────────────┐
│                        STATE MACHINE PHASES                                  │
│                                                                             │
│   EXPLORE ──────▶ REQUIREMENTS ──────▶ DESIGN ──────▶ TASKS ──────▶ SYNC   │
│     │                  │                 │              │            │      │
│   Analyze          Define WHAT       Define HOW     Break into    Push to  │
│   codebase         must happen       to build it    work items    API      │
│   context                                                                    │
│                                                                             │
│   explore.json   requirements/*.md  designs/*.md   tickets/*.md   API      │
│                                                    tasks/*.md     synced   │
└─────────────────────────────────────────────────────────────────────────────┘

Output Directory: All artifacts go in .omoi_os/ Sync Tool: Use spec_cli.py to push to the API State Machine: Each phase is a separate SDK session with checkpointing


Phase 1: EXPLORE (Most Important!)

State Machine Phase: EXPLORE - Timeout: 3 min, Max Turns: 25 Output: .omoi_os/phase_data/explore.json

Why This Phase Matters

The quality of everything downstream depends on deeply understanding the problem AND the existing codebase first. Never skip exploration. Rushing to create specs without understanding leads to wasted work and specs that don't align with existing patterns.

Step 1.1: Explore Existing Context

BEFORE asking questions, gather context:

# Check for existing documentation
Read docs/CLAUDE.md
Read docs/architecture/
ls .omoi_os/

# Search for related code
Grep for related service names, models, patterns
Read existing implementations this feature will integrate with

# Check for prior work
ls .omoi_os/requirements/
ls .omoi_os/tickets/
git log --oneline -20

Step 1.2: Ask Discovery Questions (5-15 Questions)

Structure your questions in categories:

Problem & Value (2-3 questions)
  • What specific problem does this solve? What pain exists today?
  • What happens if we DON'T build this?
  • How will we measure success? What metrics matter?
Users & Journeys (2-3 questions)
  • Who are the primary users? Secondary?
  • What's the happy path user journey?
  • What are the edge cases and error scenarios?
Scope & Boundaries (2-3 questions)
  • What is explicitly IN scope?
  • What is explicitly OUT of scope? (Very important!)
  • Are there existing features this overlaps with?
Technical Context (3-5 questions)
  • What existing systems/services will this integrate with?
  • What data does this need? Where does it come from?
  • Are there performance requirements (latency, throughput, scale)?
  • What security/privacy considerations apply?
  • Are there any hard technical constraints?
Trade-offs & Risks (2-3 questions)
  • Are there multiple valid approaches? Which should we explore?
  • What are the trade-offs between approaches?
  • What could go wrong? What are the risks?
  • What's the timeline/priority?

Step 1.3: Summarize Understanding

After questions are answered, write a summary:

## Feature Summary

**Name**: feature-name (kebab-case)
**One-liner**: Brief description of what this does

**Problem Statement**:
[2-3 sentences about the pain point this solves]

**User Stories**:
1. As a [user], I can [action] so that [benefit]
2. As a [user], I can [action] so that [benefit]
3. ...

**Scope**:
- IN: [list what's included]
- OUT: [list what's explicitly excluded]

**Technical Constraints**:
- [constraint 1]
- [constraint 2]

**Risks Identified**:
- [risk 1]
- [risk 2]

**Success Metrics**:
- [metric 1]
- [metric 2]

Get user confirmation before proceeding!

Step 1.4: Save Exploration Output (State Machine)

When running in the state machine, save the exploration context as JSON:

# .omoi_os/phase_data/explore.json
{
    "project_type": "Next.js 15 + FastAPI backend",
    "structure": {
        "frontend": "frontend/src/",
        "backend": "backend/omoi_os/",
        "api_routes": "backend/omoi_os/api/routes/",
        "models": "backend/omoi_os/models/",
        "services": "backend/omoi_os/services/"
    },
    "existing_models": [
        {"name": "Spec", "file": "backend/omoi_os/models/spec.py", "fields": ["id", "title", "description"]},
        {"name": "Ticket", "file": "backend/omoi_os/models/ticket.py", "fields": ["id", "title", "status"]}
    ],
    "conventions": {
        "naming": "snake_case for backend, camelCase for frontend",
        "testing": "pytest for backend, vitest for frontend",
        "patterns": ["Repository pattern", "Service layer", "Pydantic schemas"]
    },
    "related_to_feature": [
        {"name": "EventBusService", "file": "services/event_bus.py", "relevance": "Publish events for webhooks"},
        {"name": "TaskQueue", "file": "services/task_queue.py", "relevance": "Background processing"}
    ],
    "feature_summary": {
        "name": "webhook-notifications",
        "problem": "External systems cannot subscribe to OmoiOS events",
        "scope_in": ["Webhook subscriptions", "HMAC signing", "Retry logic"],
        "scope_out": ["UI management", "Rate limiting (future)"]
    }
}

Evaluator Criteria:

  • ✓ Has project_type (non-empty string)
  • ✓ Has structure (object with at least one key)
  • ✓ Has conventions (object with naming patterns)
  • ✓ Has related_to_feature (list, can be empty for greenfield)

Phase 2: PRD (Product Requirements Document)

Purpose

The PRD captures the "why" and "what" at a high level. It's the vision document that everything else traces back to.

Location

.omoi_os/docs/prd-{feature-name}.md

Template

---
id: PRD-{FEATURE}-001
title: {Feature Name} PRD
feature: {feature-name}
created: {date}
updated: {date}
status: draft
author: Claude
---

# {Feature Name}

## Executive Summary

[2-3 paragraph overview of the feature, the problem it solves, and why it matters]

## Problem Statement

### Current State
[Describe the pain point that exists today]

### Desired State
[Describe what the world looks like after this feature ships]

### Impact of Not Building
[What happens if we don't build this?]

## Goals & Success Metrics

### Primary Goals
1. [Goal 1]
2. [Goal 2]

### Success Metrics
| Metric | Current | Target | How Measured |
|--------|---------|--------|--------------|
| [Metric 1] | [baseline] | [target] | [method] |

## User Stories

### Primary User: {User Type}

1. **{Story Title}**
   As a {user}, I want to {action} so that {benefit}.

   Acceptance Criteria:
   - [ ] {criterion 1}
   - [ ] {criterion 2}

2. ...

## Scope

### In Scope
- [Feature/capability 1]
- [Feature/capability 2]

### Out of Scope
- [Explicitly excluded 1]
- [Explicitly excluded 2]

### Future Considerations
- [Things we might add later]

## Constraints

### Technical Constraints
- [Constraint 1]
- [Constraint 2]

### Business Constraints
- [Timeline, budget, etc.]

## Risks & Mitigations

| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| [Risk 1] | High/Med/Low | High/Med/Low | [How to mitigate] |

## Dependencies

- [Dependency 1 - what we need from other teams/systems]
- [Dependency 2]

## Open Questions

- [ ] [Question that still needs answering]
- [ ] [Another question]

Phase 3: REQUIREMENTS

State Machine Phase: REQUIREMENTS (Timeout: 5 min / 20 turns) Transition: EXPLOREREQUIREMENTS (requires ExplorationEvaluator pass) Next Phase: DESIGN (requires RequirementEvaluator pass)

Purpose

Requirements define the specific, testable behaviors the system must have. Use EARS format (Easy Approach to Requirements Syntax).

Location

.omoi_os/requirements/{feature-name}.md

EARS Format

WHEN [trigger/condition], THE SYSTEM SHALL [action/behavior].

Examples:

  • WHEN a user submits valid credentials, THE SYSTEM SHALL create an authenticated session within 2 seconds.
  • WHEN a notification is triggered, THE SYSTEM SHALL deliver it to the user within 5 seconds.
  • WHEN an API rate limit is exceeded, THE SYSTEM SHALL return a 429 status with retry-after header.

Template

---
id: REQ-{FEATURE}-001
title: {Feature Name} Requirements
feature: {feature-name}
created: {date}
updated: {date}
status: draft
category: functional
priority: HIGH
prd_ref: docs/prd-{feature-name}.md
design_ref: designs/{feature-name}.md
---

# {Feature Name} Requirements

## Overview

[Brief description of what these requirements cover]

## Functional Requirements

### REQ-{FEATURE}-FUNC-001: {Requirement Title}

**Priority**: HIGH | MEDIUM | LOW
**Category**: Functional

WHEN {trigger condition}, THE SYSTEM SHALL {required behavior}.

**Acceptance Criteria**:
- [ ] {Testable criterion 1}
- [ ] {Testable criterion 2}

**Notes**: {Any additional context}

---

### REQ-{FEATURE}-FUNC-002: {Requirement Title}

...

## Non-Functional Requirements

### REQ-{FEATURE}-PERF-001: {Performance Requirement}

**Priority**: HIGH
**Category**: Performance

THE SYSTEM SHALL {performance requirement with measurable target}.

**Metrics**:
- P50 latency: < X ms
- P99 latency: < Y ms
- Throughput: > Z requests/second

---

### REQ-{FEATURE}-SEC-001: {Security Requirement}

**Priority**: HIGH
**Category**: Security

THE SYSTEM SHALL {security requirement}.

## Traceability

| Requirement ID | PRD Section | Design Section | Ticket |
|----------------|-------------|----------------|--------|
| REQ-{FEATURE}-FUNC-001 | User Stories #1 | Component A | TKT-001 |

Step 3.1: Save Requirements Output (State Machine)

After completing requirements, save to .omoi_os/phase_data/requirements.json:

{
    "requirements": [
        {
            "id": "REQ-{FEATURE}-FUNC-001",
            "category": "functional",
            "priority": "HIGH",
            "condition": "WHEN user submits form",
            "action": "THE SYSTEM SHALL validate and persist data",
            "acceptance_criteria": ["Criterion 1", "Criterion 2"]
        }
    ],
    "total_count": 15,
    "categories": {
        "functional": 10,
        "performance": 3,
        "security": 2
    }
}

RequirementEvaluator Criteria

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
77
Forks
7
Last commit
Jun 2026
Advanced
Catalog kind
skill
Gateway key
spec-driven-dev
Source
github.com/kivo360/omoios