OpenSpec Explained: A Hands-On Guide for 2026

7 min read
Spec-Driven DevelopmentOpenSpecAIClaude CodeSoftware Engineering

OpenSpec is the spec-driven development framework I reach for when I'm working on a codebase that already has a lot of history. It doesn't pretend the repo is greenfield. It doesn't ask you to write a constitution before you can ship a small change. It just isolates the change, writes a spec, validates it, applies it, and archives it. That's the whole loop.

This post is a practical guide to OpenSpec on its own terms — not a comparison. If you want the head-to-head against GSD and Spec Kit, I wrote that comparison separately. Here I want to explain what OpenSpec actually does, how the four-phase state machine feels in practice, and what I'd change about it if I could.

What Is OpenSpec?

OpenSpec is an open-source spec-driven development tool from Fission AI (Y Combinator). The thesis is one line from the README: "Generating code is now cheap. Correctness is still expensive."

The framework sits between you and your AI coding agent — Claude Code, Cursor, Copilot, Gemini CLI, or any of the 24+ supported tools. You propose a change, OpenSpec scaffolds a change folder with a proposal, specs, design notes, and tasks, your agent executes against that scaffold, and the resulting spec gets archived into a permanent specifications directory.

The core unit is the change, not the feature. A change is a bounded, reviewable delta with its own folder. That framing matters more than it sounds — it's what makes OpenSpec feel different from Spec Kit.

The Four-Phase State Machine

Every OpenSpec change moves through the same states:

  1. Propose — You describe what's changing. OpenSpec generates proposal.md, seeds spec files, and drops task stubs.
  2. Validate — OpenSpec checks the proposal for structural completeness. Missing acceptance criteria, orphaned specs, or unbounded scope get flagged.
  3. Apply — Your agent reads the change folder and implements. OpenSpec doesn't orchestrate — it hands the context to the agent and gets out of the way.
  4. Archive — Once the change merges, /opsx:archive moves the specs from changes/<id>/specs/ into the permanent specs/ tree. The change folder gets zipped and preserved as an artifact.

The folder looks like this after a propose step:

openspec/
├── specs/                        # permanent, archived specs
│   └── auth/
│       └── session-management.md
└── changes/
    └── 2026-03-19-password-reset/
        ├── proposal.md
        ├── design.md
        ├── specs/
        │   └── auth/
        │       └── password-reset.md
        └── tasks/
            ├── 01-email-template.md
            └── 02-reset-endpoint.md

The naming convention (date-prefixed change ID) is a small detail that saved me hours. Chronological sort in a file tree = a usable history without any tooling.

Installing OpenSpec

Setup is deliberately boring. That's a feature.

npx @fission-ai/openspec@latest init

The init command creates the openspec/ directory, drops the default configuration, and registers slash commands with whichever AI agent you're using. For Claude Code that means adding the /opsx:* commands to your .claude/commands/ directory. For Cursor it drops rules into .cursor/rules/.

If you already have a codebase with undocumented logic — the usual case — run the onboarding command:

/opsx:onboard

This is the single feature that sold me on OpenSpec. It reverse-engineers your existing code into baseline specs. Not perfect specs — you'll edit them — but a starting point that most SDD tools assume doesn't exist. Spec Kit, by comparison, expects a clean slate.

Writing a Proposal

The proposal is the contract. Everything downstream — the generated specs, the task list, the agent's implementation — flows from whatever you put here.

A good proposal has three sections:

## Why
Users currently can't reset their password without contacting support.
Support tickets for this average 12 per week. We want to ship a
self-service reset flow that doesn't require engineering on every case.

## What Changes
- New `POST /auth/password-reset/request` endpoint
- New `POST /auth/password-reset/confirm` endpoint
- Transactional email template for the reset link
- Short-lived reset token stored in the sessions table

## Out of Scope
- Multi-factor auth on the reset flow
- Rate limiting (handled at the gateway)
- UI changes (separate change)

The Out of Scope section is where OpenSpec earns its keep. It's a structural reminder to scope aggressively. Every SDD framework preaches this. OpenSpec bakes it into the template so you can't skip it without noticing.

Validation: The Part Most Tools Skip

After the proposal is written, /opsx:validate walks the change folder and runs structural checks:

  • Every spec file has acceptance criteria
  • Every task references a spec it contributes to
  • No specs are orphaned (referenced by nothing)
  • The proposal's "What Changes" list matches the specs scaffolded

This sounds small. It isn't. Two hours into a change, when you're tired and about to hand it to the agent, this is the step that catches the missing piece. I've had validate flag that I scaffolded a reset-token spec but never wrote a task for the token cleanup job. Would the agent have caught it? Maybe. But I shouldn't need the agent to be the safety net for my own planning.

Strict mode is worth turning on from day one:

# openspec.config.yaml
validation:
  strict: true
  required_sections:
    - why
    - what-changes
    - out-of-scope

Apply: Where the Agent Takes Over

Apply is where OpenSpec is philosophically different from GSD. GSD orchestrates — it spawns fresh subagents per task, prunes context, and manages git operations deterministically. OpenSpec hands the change folder to whatever agent you connected and trusts it to execute.

That's a trade-off. You lose the context isolation and parallel execution GSD provides. You gain agent portability — the same change folder can be applied by Claude Code today and by Cursor tomorrow without modification.

In practice the apply step for Claude Code looks like:

/opsx:apply 2026-03-19-password-reset

Claude Code then reads the proposal, specs, and tasks, and executes. The task files act as a checklist the agent can tick off. No orchestration layer, no verification ladder — just a structured context and a motivated agent.

For small-to-medium changes this works well. For changes with more than ~8 tasks, context rot starts to bite. I've watched Claude Code forget what task 2 did by the time it reached task 7. OpenSpec doesn't solve this. GSD does, via anchor-message context pruning.

Archive: Specs as Living Documentation

When a change merges, archive moves the specs into the permanent tree:

/opsx:archive 2026-03-19-password-reset

This is where OpenSpec's philosophy about specs as documentation shows up. The specs that survive to openspec/specs/ are the ones that describe the system as it is, not as it was proposed. Future changes that touch the same area load these specs as context. You're incrementally building a specification of your running system, one change at a time.

It's the closest thing I've seen to living documentation that actually stays current, because the update happens at merge time, not as a separate chore.

Where OpenSpec Wins

  • Brownfield onboarding is unmatched. /opsx:onboard is the only reverse-engineering story in the SDD space that actually works. Point it at a legacy Rails app and get back a starting set of specs that describe reality, not aspiration.
  • Change isolation. Every change lives in its own folder until archive. No cross-change contamination. Easy to pause a change, work on another, and come back.
  • Lightweight output. A typical OpenSpec change is ~250 lines of markdown across proposal, specs, and tasks. Spec Kit features are 3–4x that. Less noise, less review burden, more likely to actually get read.
  • Broadest agent support. 24+ tools. You're not locked into one vendor's agent.
  • Low ceremony. Four commands. No constitution to write. No seven-phase pipeline. If you're shipping a small change, OpenSpec stays out of your way.

Where OpenSpec Falls Short

  • No execution orchestration. Apply hands the change to the agent and hopes for the best. On longer changes, context rot degrades quality. You can split a change into multiple smaller changes, but that's a workaround, not a solution.
  • Specs are static during apply. If the agent discovers a spec assumption is wrong mid-implementation, the spec doesn't auto-update. You fix it manually after the fact. Augment's Intent and GSD's goal-backward verification both do more here.
  • Manual archive discipline. If you forget to archive, specs and reality diverge. I've walked into OpenSpec repos where half the "pending" changes had shipped months ago. This is a human problem OpenSpec doesn't automate around.
  • No automatic git branching. You manage branches yourself. For solo work that's fine. In teams it's a surprise.
  • Validation occasionally false-positives. A handful of GitHub issues describe validation errors on legitimately-structured specs. Usually fixed by a version bump, but worth knowing.

When I Reach for OpenSpec

I use GSD as my default on greenfield projects — the orchestration and context isolation matter too much to give up. But when a client hands me a 3-year-old NestJS codebase with undocumented business logic, OpenSpec's onboarding command is the first thing I run. Thirty minutes later I have a starting spec set, and from there the four-phase loop is light enough that I can ship small, reviewable changes without the ceremony tax.

Rule of thumb:

  • Greenfield, solo, Claude Code primary → GSD
  • Brownfield, fast iteration, any agent → OpenSpec
  • Team environment, cross-agent, governance needs → Spec Kit

For the full decision tree, see the SDD tools comparison.

Give It 30 Minutes

If you've been curious about spec-driven development but put off by the ceremony, OpenSpec is the lowest-commitment way in. Pick the smallest change on your current project. Run /opsx:onboard on the affected module, /opsx:propose the change, and walk through the four phases once. You'll have a feel for whether the workflow earns its keep on your codebase within an hour.

Check out my tools and stack for the full development setup I pair with OpenSpec on client work.


Shipping with OpenSpec or evaluating SDD tools? Reach out — I'm always trading notes on what works.