Featured image of post OpenSpec: Make AI Coding Assistants Follow a Spec, Not Just Guess

OpenSpec: Make AI Coding Assistants Follow a Spec, Not Just Guess

OpenSpec is a spec-driven development framework. Before AI writes code, align on requirements first. Propose generates spec documents, apply implements by spec, archive records completed changes. Supports Claude Code, Cursor, Copilot, and 30+ tools.

The most common problem with AI coding assistants isn’t that they can’t write code β€” it’s that they write something different from what you had in mind.

You say “add dark mode” and it rewrites CSS variables, adds a toggle button, and refactors the layout β€” when all you wanted was to change color tokens. Next conversation, context is gone, and it guesses your intent from scratch.

OpenSpec solves this: before AI starts writing code, it produces a spec document. Both sides align on “what to do” and “how to do it”, then implement according to the spec.

Core Architecture

OpenSpec splits your project knowledge into two parts:

1
2
3
4
5
6
7
8
9
openspec/
β”œβ”€β”€ specs/              ← source of truth (current behavior)
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   └── spec.md
β”‚   └── payments/
β”‚       └── spec.md
└── changes/            ← in-progress modifications (one folder per change)
    β”œβ”€β”€ add-dark-mode/
    └── archive/        ← completed changes archived here

Specs describe the system’s current behavior. Changes are proposed modifications. Managed separately, multiple changes can proceed in parallel without conflict.

Install

Requires Node.js 20.19.0+:

1
2
3
npm install -g @fission-ai/openspec@latest
cd your-project
openspec init

Supports npm, pnpm, yarn, bun, nix.

Basic Workflow: propose β†’ apply β†’ archive

1. Propose: Describe the Change

1
/opsx:propose add-dark-mode

AI produces four artifacts at once:

1
2
3
4
5
6
7
openspec/changes/add-dark-mode/
β”œβ”€β”€ proposal.md       # why, scope (in/out of scope)
β”œβ”€β”€ specs/            # delta spec: what behavior is added/changed/removed
β”‚   └── ui/
β”‚       └── spec.md
β”œβ”€β”€ design.md         # technical approach, architecture decisions
└── tasks.md          # implementation checklist (checkboxes)

Each artifact has a clear responsibility:

ArtifactQuestion It Answers
proposal.mdWhy are we doing this? What’s the scope?
specs/What system behavior changed? (Delta)
design.mdHow do we implement it technically? What architecture?
tasks.mdWhat are the implementation steps? What’s done?

2. Apply: Implement by Spec

1
/opsx:apply

AI follows tasks.md item by item, checking off each one:

1
2
3
4
5
Working on 1.1: Create ThemeContext...
βœ“ 1.1 Complete

Working on 1.2: Add CSS custom properties...
βœ“ 1.2 Complete

It won’t go off-script. If interrupted, it picks up where it left off next time.

3. Archive: Record Completion

1
/opsx:archive

Archive does two things:

  1. Merges delta specs into openspec/specs/ (updates source of truth)
  2. Moves the change folder to openspec/changes/archive/2026-03-08-add-dark-mode/

Specs grow incrementally with each archive, forming a complete system behavior document over time.

Spec Format

Specs are behavior contracts, not implementation details. Described using requirements + scenarios:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Auth Specification

## Purpose
Authentication and session management.

## Requirements

### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.

#### Scenario: Valid credentials
- GIVEN a user with valid credentials
- WHEN the user submits login form
- THEN a JWT token is returned
- AND the user is redirected to dashboard

#### Scenario: Invalid credentials
- GIVEN invalid credentials
- WHEN the user submits login form
- THEN an error message is displayed
- AND no token is issued

Given/When/Then for scenarios, each one testable. RFC 2119 keywords (MUST/SHALL/SHOULD/MAY) express requirement strength.

Delta Spec: Describing “What Changed”

This is OpenSpec’s most important concept. Modifications don’t rewrite the entire spec β€” they describe the diff:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Delta for Auth

## ADDED Requirements

### Requirement: Two-Factor Authentication
The system MUST support TOTP-based two-factor authentication.

#### Scenario: 2FA login
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented

## MODIFIED Requirements

### Requirement: Session Expiration
The system MUST expire sessions after 15 minutes of inactivity.
(Previously: 30 minutes)

## REMOVED Requirements

### Requirement: Remember Me
(Deprecated in favor of 2FA.)

Three sections, each with a clear meaning:

SectionMeaningArchive Action
ADDEDNew behaviorAdded to main spec
MODIFIEDChanged existing behaviorReplaces original requirement
REMOVEDRemoved behaviorDeleted from main spec

Why delta instead of rewriting the entire spec? Because two parallel changes can each modify different requirements of the same spec without conflict.

Explore Mode: When You’re Not Sure What to Do

1
/opsx:explore

Discuss with AI first β€” it analyzes the codebase, compares approaches, draws architecture diagrams. No artifacts produced. Once you’ve thought it through, run /opsx:propose.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
You: /opsx:explore
AI:  What would you like to explore?

You: How should we handle authentication for the mobile app?
AI:  Let me investigate your current auth setup...
     I see you're using session-based auth for the web app.
     For mobile, we have three options:
     1. JWT tokens (stateless, works offline)
     2. OAuth2 (third-party login)
     3. Extend current sessions (simpler)

You: Let's go with JWT.
AI:  Ready. Run /opsx:propose add-jwt-auth to begin.

Advanced Commands

Expanded Workflow (requires profile switch)

1
2
openspec config profile   # choose expanded workflow
openspec update           # refresh AI instructions
CommandPurpose
/opsx:newCreate folder only, no artifacts (manual pacing)
/opsx:continueProduce next artifact in dependency order
/opsx:ffFast-forward, produce all artifacts at once
/opsx:verifyVerify implementation matches spec
/opsx:syncManually merge delta spec (without archiving)
/opsx:bulk-archiveArchive multiple changes at once
/opsx:onboardGuided tutorial using your own codebase

continue vs ff

/opsx:continue produces one artifact at a time, letting you review step by step:

1
proposal β†’ (review) β†’ specs β†’ (review) β†’ design β†’ (review) β†’ tasks

/opsx:ff produces everything at once β€” for when you already know exactly what you want.

verify: Three Dimensions of Validation

1
/opsx:verify
DimensionWhat It Checks
CompletenessAll tasks done? All requirements have corresponding implementation?
CorrectnessImplementation matches spec intent? Edge cases handled?
CoherenceCode consistent with design.md decisions? Naming conventions uniform?

Reports come in three levels: CRITICAL, WARNING, SUGGESTION. Won’t block archiving, but lets you know what needs attention.

Schema: Customize the Artifact Flow

The default spec-driven schema flow is:

1
2
3
proposal β†’ specs β†’ design β†’ tasks β†’ implement
         β†˜              β†—
          (design only depends on proposal, can run parallel with specs)

You can define custom schemas, e.g. adding a research phase:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
  - id: research
    generates: research.md
    requires: []

  - id: proposal
    generates: proposal.md
    requires: [research]

  - id: tasks
    generates: tasks.md
    requires: [proposal]
1
openspec schema init research-first

Supported Tools

OpenSpec isn’t locked to a specific AI tool. It supports 30+ coding assistants:

ToolCommand Format
Claude Code/opsx:propose, /opsx:apply
Cursor/opsx-propose, /opsx-apply
Windsurf/opsx-propose, /opsx-apply
GitHub Copilot (IDE)/opsx-propose, /opsx-apply
Codex / Gemini CLI / Amazon QEach has its own integration

Basically any AI tool that can read files and handle slash commands works.

Compared to Alternatives

OpenSpecSpec Kit (GitHub)Kiro (AWS)
PhilosophyLightweight, fluidComplete but heavyweightPowerful but IDE-locked
Phase controlNo phase gatesStrict phase gatesLocked to specific models
BrownfieldNative support (delta spec)Requires full rewriteLimited
Tool lock-in30+ toolsGitHub ecosystemKiro IDE only
FormatMarkdown + GitMarkdown + PythonBuilt-in format

What It Actually Feels Like

The biggest difference after using it: AI stops going off on tangents.

Before, every new conversation required re-explaining “what this project looks like, what decisions were made before.” Now AI reads openspec/specs/ and already knows.

The scope distinction in proposal.md (in scope / out of scope) is especially useful. Write down “what we’re NOT doing” and AI won’t “helpfully” do things you didn’t ask for.

design.md is also valuable β€” it forces you to think through the technical approach before writing code. Many times, the design phase reveals “this approach won’t work, let’s try another one” β€” saving the time of discovering that after implementation.

The only cost is one extra step: you can’t just tell AI “add dark mode” and wait for results. You propose, review, then apply. But the payoff is predictability and traceability, which is worth it for anything beyond trivial changes.

Not suitable for: changing one line of CSS, fixing a typo β€” just do it directly, no need for the propose flow.

Summary

OpenSpec doesn’t replace AI coding assistants β€” it adds a spec layer in front of them.

Core concepts:

  • Specs β€” source of truth for system behavior
  • Changes β€” describe modifications with delta specs, don’t rewrite the whole spec
  • Artifacts β€” proposal (why) β†’ specs (what changes) β†’ design (how) β†’ tasks (what to do)
  • Archive β€” merge deltas into main spec after completion, forming the system’s evolution record

v1.2.0 (February 2026), 28k+ GitHub stars, MIT license.

References