Chapter 1 — What is OpenSpec?
Get a working mental model of OpenSpec, set it up in your existing lab workspace, and run a smoke test before the guided walkthrough in Chapter 2.
- Reading time: 20 minutes
- Practical time: 15 minutes
1. The problem
In Chapter 7 of the Introductive Lab you drove an AI agent through a large feature from a single natural-language prompt. It worked — but you probably noticed some rough edges:
- The agent made architectural decisions silently (which table? which endpoint? which component?).
- Halfway through, you realised a constraint you forgot to mention, so you re-prompted and the agent partially rewrote work it had just finished.
- The final diff was large and opaque; reviewing it felt like reviewing a completed painting rather than a blueprint.
- If a teammate asked "why did the API contract change?", the answer lived only in your chat history.
This is the drift problem: without a shared, reviewable spec, the agent optimises for "code that compiles" rather than "code that matches what we actually wanted". The longer the task, the more the two diverge.
The same issue appears even on smaller tasks when multiple people are involved: two developers prompt the same agent differently, get different results, and spend more time reconciling than coding.
2. What OpenSpec is
OpenSpec is a Markdown-first change-proposal workflow that sits between "here is my idea" and "write the code". Instead of handing your idea straight to the agent, you ask the agent to first produce a structured proposal — a small folder of Markdown files that captures why the change is needed, what it will do, and how it will be implemented.
Everything lives under an openspec/ folder in your repository:
openspec/
└── changes/
├── <change-name>/
│ ├── proposal.md # rationale and scope
│ ├── specs/ # requirements and acceptance scenarios
│ ├── design.md # technical approach
│ └── tasks.md # implementation checklist
└── archive/ # completed changes (timestamped)Because these files are plain Markdown checked into Git, they are:
- Auditable —
git log openspec/shows every decision and revision. - Diff-able — pull-request reviews show exactly what changed in the spec before any code moves.
- Mergeable — multiple proposals can coexist; conflicts surface in spec files, not in business logic.
The agent writes the spec first. You review it. Only then does the agent write the code.
3. The loop
OpenSpec structures every change as four stages:
| Stage | What you do | What the agent produces |
|---|---|---|
| Propose | Give the agent a feature idea via /opsx:propose | proposal.md, specs/, design.md, tasks.md |
| Review | Read the generated files; request changes in plain English | Revised spec files (loop back to Propose if needed) |
| Apply | Approve the spec; run /opsx:apply | Actual code changes, following tasks.md exactly |
| Archive | Run /opsx:archive | Change folder moved to openspec/changes/archive/ |
The key insight: you review a spec, not a diff. Catching a wrong assumption in proposal.md costs one sentence of feedback; catching it after the agent has written 400 lines of Spring code costs a revert and a re-run.
Beyond the four-stage loop
Propose / Apply / Archive is the spine of the workflow, but OpenSpec ships several auxiliary commands you can mix in. Because the install step in section 5 selects the expanded profile, all of them are available in your workspace:
| Command | When to use it |
|---|---|
/opsx:explore | Investigate the codebase or compare approaches before committing to a change. No artifacts are created. |
/opsx:new | Scaffold an empty change folder when you want to drive artifact creation yourself instead of letting propose do it in one shot. |
/opsx:continue | Generate the next artifact in the dependency chain, one at a time. Pairs with /opsx:new. |
/opsx:ff | Fast-forward: generate all planning artifacts at once. Equivalent surface area to /opsx:propose once a change exists. |
/opsx:verify | Check that the implementation actually matches proposal.md, specs/, and design.md before archiving. |
/opsx:sync | Merge delta specs from a change into the main openspec/specs/ directory without archiving. Archive prompts for this automatically, so manual use is rare. |
/opsx:bulk-archive | Archive several completed changes together and resolve spec conflicts across them. |
/opsx:onboard | Guided tutorial that walks you through the full loop on your own codebase — useful for teammates joining later. |
Full syntax, arguments, and examples live in the upstream OpenSpec commands reference. For Chapter 2 we only need /opsx:propose, /opsx:apply, and /opsx:archive; the rest are there when you outgrow the basic loop.
4. OpenSpec vs ad-hoc planning
You may already drop a PLAN.md or TODO.md into your repo before starting a big task. OpenSpec formalises and automates that habit:
| Aspect | Free-form PLAN.md | OpenSpec |
|---|---|---|
| Structure | Whatever you write | Consistent schema (proposal / specs / design / tasks) |
| Author | You, manually | Agent generates the first draft from your idea |
| Review | Informal, easy to skip | Explicit stage — code cannot start until you approve |
| History | One file, overwritten | Each change is its own versioned folder |
| Archival | Often forgotten | archive/ is a first-class step in the workflow |
| Agent grounding | Agent re-reads the whole file each time | Agent works from tasks.md — a focused, current checklist |
For small, single-session changes a PLAN.md is fine. OpenSpec pays off when the change spans multiple sessions, involves more than one person, or needs a clear "what did we decide and why?" trail.
5. Install & verify
These steps run in the same ~/lab-workspace/fullstack-onlineshop workspace you set up in the Introductive Lab.
Install the CLI
npm install -g @fission-ai/openspec@latestRequires Node.js ≥ 20.19.0 (the same version used for the frontend).
Initialise OpenSpec in the workspace
cd ~/lab-workspace/fullstack-onlineshop
openspec initThis creates the openspec/ folder and a .openspec/ config directory. The CLI also injects OpenSpec instructions into your AI assistant's context — no manual file editing required.
Select the expanded profile
openspec config profile
# Select "expanded" at the prompt to unlock the full command set
openspec update
# Refreshes the assistant instructions after the config changeSmoke test
First, verify the CLI is installed:
openspec --versionThis should print a version number. If you get "command not found", re-run the install step above.
To verify that the AI agent integration is also working, start a new AI agent session (Copilot CLI or Claude Code) inside the fullstack-onlineshop directory and run:
/opsx:propose add a hello world bannerIf OpenSpec is wired up correctly the agent creates files under openspec/changes/. Once it finishes, check the folder name and delete it — leaving it in place will cause /opsx:apply in Chapter 2 to find multiple proposals and prompt you to choose.
ls openspec/changes/
# note the folder name the agent created, then delete it:
rm -rf openspec/changes/<the folder you see>The agent slugifies the prompt into a folder name. Common results for "add a hello world banner" include
add-a-hello-world-banneroradd-hello-world-banner— always uselsto confirm rather than guessing the name.
Telemetry opt-out (optional)
export OPENSPEC_TELEMETRY=0
# or: export DO_NOT_TRACK=1For the full CLI reference, see the OpenSpec README.
6. Working with Git - Best Practices
The spec is only an audit trail if you commit it deliberately. The rules below align Git checkpoints with the four stages from section 3, keeping the archive folder a faithful record of what was approved and when.
Start by committing the openspec/ folder you created in section 5:
git add openspec/
git commit -m "chore: initialise openspec"From here, every feature follows the same Git pattern, one stage at a time.
Before /opsx:propose — start from a clean tree
Run git status before invoking propose. The working tree must be clean — no uncommitted code, no stray spec files from a previous run. The agent reads the working tree to ground its proposal, so uncommitted edits leak into the spec as if they were intentional design decisions.
git status # expect: "nothing to commit, working tree clean"If you have in-progress work, commit or stash it under its own branch before starting the new spec.
After /opsx:propose — commit the proposal
Once the agent finishes generating proposal.md, specs/, design.md, and tasks.md, commit them as a single unit before you start refining. This gives every refinement round a clear diff against the original draft.
git add openspec/changes/<change-folder>/
git commit -m "spec: propose <change-folder>"During Review — commit each refinement round
Treat each round of dialogue with the agent as a discrete revision. After the agent updates the spec files, read the diff (git diff openspec/), then commit it.
git add openspec/changes/<change-folder>/
git commit -m "spec: refine <change-folder> — <one-line summary>"This is what makes the audit trail useful. Six months later, git log openspec/changes/archive/<date>-<change-folder>/ shows the negotiation, not just the final spec.
After /opsx:apply — commit code separately from spec
The apply stage writes TypeScript/HTML/CSS based on tasks.md. Commit the code as its own commit, separate from any spec edits. Mixed commits make reverts surgical instead of mechanical.
git add <implementation-files>
git commit -m "feat: implement <change-folder>"If /opsx:apply fails mid-task, do not amend. Reset with git reset --hard HEAD — the code is regenerable from tasks.md — then fix the spec and re-run apply.
After /opsx:archive — commit the move
Archive moves the change folder from openspec/changes/<name>/ to openspec/changes/archive/<date>-<name>/. Commit this move on its own so the boundary between active and archived work is easy to spot later.
git add openspec/
git commit -m "chore: archive <change-folder>"Summary
| Stage | Git action |
|---|---|
Before /opsx:propose | Confirm clean tree (git status) |
After /opsx:propose | Commit the proposal folder |
| During Review | Commit each refinement round |
After /opsx:apply | Commit implementation (separate from spec) |
After /opsx:archive | Commit the archive move |
Next
You have OpenSpec installed and verified. Head to Chapter 2 — Walkthrough: Recently Viewed Products to use the full propose → review → apply → archive loop on a real feature.