# Openspec Workflow

> Autonomous spec-driven development with OpenSpec + Fabro. You orchestrate spec artifacts (proposal, design, specs, tasks), then Fabro handles implementation with its multi-model planning, review, and verification pipeline. Use when: (1) building a new app from scratch, (2) making any code change in a repo that uses OpenSpec, (3) creating or modifying proposals, designs, specs, or task breakdowns, (4) shipping PRs that need spec artifacts. Covers the full lifecycle: spec → Fabro build → verify → ship. Requires: openspec CLI, fabro CLI, gh CLI, git.

- Skill: `natea/openspec-workflow` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add natea/openspec-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/natea/openspec-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: natea (https://skillmd.com/u/natea)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/natea/openspec-workflow

---


# OpenSpec Workflow

Ship spec-driven apps with OpenSpec for specification and Fabro for implementation.

## Architecture

| Role | Tool | What |
|------|------|------|
| **Spec Author** | You + OpenSpec CLI | Create change, draft artifacts (proposal, design, specs, tasks), review loop |
| **Builder** | Fabro | Multi-model planning, implementation, code review, verification (lint, test, typecheck, build), polish |
| **Reviewer** | Claude Code subagents | Challenge spec artifacts before implementation |

**Why this split:** OpenSpec defines *what* to build. Fabro orchestrates *how* to build it — with dual-model planning, automated verification loops, and retry-on-failure. You bridge the two by creating specs and configuring the Fabro run.

## When to Use This Skill

**Use OpenSpec when** the change affects what the product *does*:
- New features or capabilities
- Refactors that change behavior
- Breaking changes or migrations
- Anything that modifies or creates specs

**Skip OpenSpec, just ship a PR when** the change is supplementary:
- Examples, tutorials, sample projects
- Typo fixes, README updates, comment tweaks
- CI/CD config (GitHub Actions, linting)
- Dependency bumps

## Prerequisites

- `openspec` CLI installed (`npm install -g @fission-ai/openspec`)
- `fabro` CLI installed
- `gh` CLI authenticated with repo access
- Git repo with `openspec/` directory initialized

## Convention: App Directory Structure

Each app lives in its own directory under `apps/` and shares its name with the OpenSpec change:

```
apps/
└── <name>/              # Same name as openspec/changes/<name>
    ├── openspec/        # App's own openspec (copied from parent or initialized)
    ├── fabro/           # App's own fabro workflow
    ├── src/             # Generated source code
    ├── package.json     # (or pyproject.toml, etc.)
    └── ...
```

The `<name>` is always kebab-case and must match between `openspec/changes/<name>` and `apps/<name>`.

## Quick Start

```
1. openspec new change "<name>"
2. For each artifact: draft → review loop → write
3. Set up app directory and run fabro
4. Commit, push, open PR
```

## Workflow

### Step 0. Set up the app directory

```bash
# Create the app directory (name matches the OpenSpec change)
NAME="<name>"
mkdir -p ../apps/$NAME
cd ../apps/$NAME

# Initialize git repo
git init

# Initialize openspec in the app
openspec init --tools claude --force

# Copy OpenSpec and Fabro skills into the skills Directory
cp -r ../../fabro-repo/skills/fabro-create-workflow .claude/skills
cp -r ../../openclaw-skills/skills/bobbyradford/openspec-workflow .claude/skills
```

### Step 1: Create the Change

```bash
openspec new change "<kebab-case-name>"
openspec status --change "<name>"
```

### Step 2: Artifact Loop

For each artifact in order (typically: proposal → design → specs → tasks):

```bash
openspec instructions <artifact-id> --change "<name>"
```

Read the template and dependencies. Draft the artifact content.

**Then decide: review or skip?**

- **Skip review** if the artifact is genuinely trivial (one-liner, obvious config, mechanical rename). Log: `Skipped review — trivial: <reason>`.
- **Send to review** for anything with real design decisions, trade-offs, or ambiguity.

Spawn reviewers as subagents with the **repo path** so they can explore the codebase independently — read files, grep for patterns, verify "no code changes" claims. Don't just paste the artifact; give them the tools to challenge it. See `references/review-loop.md` for the full protocol and prompt template.

After writing the artifact, confirm progress:

```bash
openspec status --change "<name>"
```

Continue to the next artifact until all 4 are complete (proposal, design, specs, tasks).

### Step 3: Implement via Fabro

Once all OpenSpec artifacts are complete, set up the app directory and run Fabro to build it.


```bash
# Copy the openspec change artifacts into the app's openspec
cp -r ../../openspec/changes/$NAME openspec/changes/
cp -r ../../openspec/specs/* openspec/specs/ 2>/dev/null || true
```

#### 3b. Set up the Fabro workflow

```bash
# Copy the generic-build workflow into the app
cp -r ../../fabro/workflows/generic-build fabro/workflows/generic-build

# Create a run config for this app
cat > fabro/workflows/generic-build/runs/$NAME.toml << 'EOF'
version = 1
graph = "../workflow.fabro"

[vars]
app_dir = "."
spec_dir = "openspec"
workflow_dir = ".workflow"
EOF
```

#### 3c. Validate and run

```bash
# Validate the workflow parses correctly
fabro validate fabro/workflows/generic-build/runs/$NAME.toml

# Preflight check (dry run)
fabro run fabro/workflows/generic-build/runs/$NAME.toml --preflight

# Run the full build pipeline with auto-approve
fabro run fabro/workflows/generic-build/runs/$NAME.toml --auto-approve
```

Fabro will:
1. **Bootstrap** — verify toolchain (bun/tsc/python/etc.)
2. **Plan** — two models independently create implementation plans, then synthesize
3. **Implement** — write all code per the OpenSpec specs
4. **Review** — code review against specs
5. **Verify** — install deps → lint → test → typecheck → build → structure check (with retry loops)
6. **Format** — auto-format code
7. **Polish** — final UI/UX pass

For trivial changes (pure doc edits, one-line fixes), you may implement directly instead of running Fabro. Log: `Implemented directly — trivial: <reason>`.

### Step 4: Ship

**Before committing**, verify the change name matches the actual directory:

```bash
# Get the exact change directory name
CHANGE=$(ls openspec/changes/ | grep -v archive | head -1)
echo "Change name: $CHANGE"
```

Use this exact name everywhere — commit message AND PR body:

```bash
git add -A
git commit -m "<type>(scope): <description> (#<issue>)

OpenSpec change: $CHANGE"
git push origin <branch>
gh pr create --repo <owner/repo> --base main --head <branch> \
  --title "<type>: <description>" \
  --body "Closes #<issue>

OpenSpec change: $CHANGE"
```

**Critical:** The `OpenSpec change: <name>` in the PR body must **exactly match** the directory name under `openspec/changes/`. The auto-archive GitHub Action uses this to locate the change. A mismatch means the archive silently skips. Always verify with `ls openspec/changes/` before writing the PR body.

### Step 5: Address PR Review Comments

After opening the PR, code review agents may leave comments. Monitor and respond:

```bash
# Check for review comments
gh pr view <number> --repo <owner/repo> --json reviews,comments
gh api repos/<owner>/<repo>/pulls/<number>/comments
```

For each review comment:

1. **Evaluate** — Is it significant? Does it catch a real bug, missing edge case, or design issue?
2. **If significant:** Fix it in the worktree, commit, push. The PR updates automatically.
   ```bash
   # Fix, then:
   git add -A && git commit -m "fix: address review — <what changed>"
   git push origin <branch>
   ```
3. **If not significant:** Reply inline with your justification.
   ```bash
   gh api repos/<owner>/<repo>/pulls/<number>/comments/<comment-id>/replies \
     -f body="<your justification>"
   ```

Apply the same judgment rules as the artifact review loop: accept valid concerns, reject with reasoning, partially accept where appropriate. Don't blindly apply every suggestion — you're the decision-maker.

### Step 6: Document & Report

Post the workflow log to the GitHub issue:

```bash
gh issue comment <number> --repo <owner/repo> --body '<workflow log>'
```

Include: each artifact's draft, review challenges, revisions, skip decisions with reasoning, and final implementation notes.

**Always end by linking the user to the issue and PR:**
- Issue: `https://github.com/<owner>/<repo>/issues/<number>`
- PR: `https://github.com/<owner>/<repo>/pull/<number>`

## Artifact Guidelines

### proposal.md
- **Why** (1-2 sentences), **What Changes** (bullet list), **Capabilities** (new + modified specs), **Impact**
- List every spec that will be created or modified in Capabilities — this drives the specs artifact

### design.md
- **Context**, **Goals / Non-Goals**, **Decisions** (with alternatives considered), **Risks / Trade-offs**
- Skip for trivial changes (pure doc fixes, one-line config changes)

### specs/\<capability\>/spec.md
- Delta format: `## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`
- Every requirement needs `### Requirement: <name>` + at least one `#### Scenario:`
- MODIFIED must include the full updated requirement text (not just the diff)
- Use existing spec names from `openspec/specs/` for modified capabilities

### tasks.md
- Numbered groups with checkboxes: `- [ ] 1.1 Task description`
- Small enough to complete in one session
- Ordered by dependency

## GitHub Action: Auto-Archive on Merge

For repos that want automatic spec sync and archiving, add this workflow. See `references/archive-action.md` for the complete GitHub Action YAML.

The action:
1. Triggers on PR merge
2. Extracts change name from `OpenSpec change: <name>` in PR body
3. Runs `openspec archive --yes` on a new branch
4. Opens a PR with the archive and spec sync changes
5. Deletes the original merged branch

