Files
OpenSpec/docs-lab/start/quickstart.md
T
Clay GoodandClaude Opus 5 5f5914e7f7 fix(skills): match natural "openspec <verb>" phrasing to its workflow (#1852)
* feat(skills): match natural "openspec <verb>" phrasing to its workflow

Users and agents say "openspec propose" / "openspec apply", but no workflow
skill description contained that phrasing, so an agent hearing it had nothing
to match and routinely hand-built the artifacts with the CLI instead of
running the workflow.

Each workflow skill's description now names the phrasings that should route
to it. `openspec update` is deliberately left unclaimed: it is a real CLI
command that refreshes generated files, unrelated to the update-change
workflow, so that skill claims "openspec update change" instead.

Descriptions are emitted as unquoted YAML plain scalars, so the new tests also
pin that the generated frontmatter still parses and the description round-trips.

Closes #1221

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(skills): derive the CLI-collision guard instead of hardcoding it

Review found the guard codified the one exception rather than the rule, so it
could never catch the next collision. It now reads every command name the CLI
registers and fails on any claimed phrase that shadows one, unless the phrase
is listed in DELIBERATE_CLI_PHRASE_CLAIMS with a reason.

Two routing fixes fall out of stating the rule:

- bulk-archive also claims "openspec archive all", so an exact-phrase match on
  "openspec archive" no longer pulls a multi-change request to the
  single-change skill.
- update-change now disclaims the openspec update CLI command in prose, not
  only by avoiding the string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(skills): drop the trailing clause and close the plural-archive hole

Review found the "- follow this skill rather than doing the work by hand"
trailer was decoration that contradicted two of the skills it was appended to:
sync-specs opens "This is an agent-driven operation - you will read delta specs
and directly edit main specs", and explore says "This is a stance, not a
workflow. There are no fixed steps." A description is read at selection time,
so the clause could not reach the hand-building it targeted anyway; the bodies
already carry that guidance. Removing it from all 12 also drops ~800 chars of
identical boilerplate that made update-change's CLI redirect read as filler.

Routing fixes:

- bulk-archive claims the plural phrasings that do not contain "all", so
  "openspec archive these three changes" no longer loses to the single-change
  skill on the bare literal.
- update-change redirects to the CLI command positively instead of negating
  ("run that command instead"), which routers honor far better than "not for".
- apply also claims "openspec implement", the natural English verb for it,
  which shadows no CLI command.

Corrects the recorded reason for claiming "openspec archive": the CLI command
does merge delta specs (docs/cli.md:631, src/core/archive.ts:1402). The real
reason is that the workflow confirms and verifies the merge before anything
moves, where the bare command does it in one shot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(quickstart): name the verb phrasing that now routes to a workflow

Also rewrites the changeset to house style: links the issue, names the
commands-only scope limit, and tells a reader they need `openspec update`
to pick it up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(skills): walk the real command tree instead of scanning the entrypoint

Mutation testing found the collision guard was a strict subset of reality,
not the superset its comment claimed. It scanned src/cli/index.ts for
`.command('…')`, but seven groups — spec, config, schema, store, doctor,
context, workset — are registered from their own modules, so 23 real command
names were invisible. A description claiming "openspec doctor" or
"openspec spec" passed 18/18 green.

It now walks the commander tree from the exported `program` (importing it does
not parse argv; runCli does that), and a sanity test pins the seven delegated
groups so the blind spot cannot come back.

Three more holes the same pass found, all confirmed by re-running the
mutations that previously slipped through:

- phrase extraction was case-sensitive and double-quote-only, so
  "Openspec update" and `openspec update` in backticks both evaded every
  guard. Matching is now case-insensitive and accepts either delimiter.
  Unquoted prose stays excluded on purpose: the update-change redirect names
  the CLI command in prose, and prose is not a routing trigger.
- prefix shadowing was unguarded, which is the exact shape of the
  archive/bulk-archive tension. A shorter phrase contained in another skill's
  longer phrase must now be declared in DELIBERATE_PHRASE_SHADOWING.
- both allowlists accepted an empty reason and never flagged stale entries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(skills): let the CLI-collision guard ignore hidden workflow-verb hints

PR #1776 registers the workflow verbs (explore, propose, apply, ...) as
hidden CLI commands that only point the user at the workflow. Walking the
commander tree then saw "openspec explore" as a real command and failed
the collision guard for every skill trigger.

Skip a subcommand only when it is hidden AND named after a workflow.
Visible commands and hidden non-workflow commands are still guarded,
pinned by a synthetic commander tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(changeset): drop em dashes from the release note

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(skills): drop the generic by-hand clause from the explore description

The other eleven descriptions dropped it; explore is a stance, not a
workflow, so telling the agent to follow it instead of doing the work
contradicts it. Adds a regression over every workflow description.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 23:34:57 +00:00

7.4 KiB

Quickstart

Your first change on your existing repo, from idea to archived.

Before you start, you need the CLI on your machine (Installation) and OpenSpec initialized in your project (Set up your project).

The loop at a glance

Every change moves through the same five steps: you think the idea through with your agent, it drafts a plan, you correct the plan before any code exists, the agent builds from it, and archiving updates your specs with what shipped.

flowchart LR
    explore["1 · Explore<br/>think it through together"] --> propose["2 · Propose<br/>agent drafts the plan"]
    propose --> review["3 · Review<br/>you correct the plan"]
    review --> apply["4 · Apply<br/>agent builds, task by task"]
    apply --> archive["5 · Archive<br/>specs absorb the change"]
    archive -. "next change" .-> explore

Every prompt below goes in your AI chat, the same place you ask for code. Each invokes an OpenSpec skill by name, the same spelling in every tool. A plain ask works too ("propose a change to add rate limiting"), and so does naming the step directly - "openspec propose", "opsx apply" - which runs the workflow instead of hand-building the files. (openspec update is a real CLI command that refreshes generated files, so say "openspec update change" for that workflow.) Some tools add shorter command aliases (/opsx:propose in Claude Code, other tools vary).

Step 1: Explore

Think the idea through with your agent before you ask for a plan. In your AI chat:

/openspec-explore how rate limiting should work in this app

Explore is a thinking mode. The agent investigates your codebase, asks the questions that matter, sketches options, and challenges assumptions. It never writes code. It writes nothing else unless you ask it to capture what you decided, or say yes when it offers. The output is a sharper idea.

Stay here as long as the problem needs. When the shape feels right, hand it off:

/openspec-propose

That line starts propose for you, carrying everything you settled. Skip the first prompt in step 2.

Step 2: Propose

Propose turns the idea into a reviewable plan. Coming from explore, it's already running. Starting cold, when the change is clear in your head, ask directly. In your AI chat:

/openspec-propose add rate limiting

The agent asks what it needs to, then writes a change folder:

openspec/changes/add-rate-limiting/
├── proposal.md    why, and what changes
├── specs/         what "done" means, as testable requirements
├── design.md      technical decisions (only when the change needs one)
└── tasks.md       the implementation checklist

No code yet. Propose stops at the plan.

Step 3: Review and correct the plan

Fix the plan while it's still words and nothing is built yet. Read in this order:

  • proposal.md: is this the right problem, at the right size?
  • specs/: the highest-value read. Would you accept these requirements as done?
  • tasks.md: do the tasks cover the specs, and nothing more?

To fix something, either works:

  • Edit the file yourself. The artifacts are plain markdown, and the files are the plan.
  • Tell your agent what's wrong ("the spec is missing the unauthenticated case"). It revises the artifacts.

Step 4: Apply

Apply turns the plan into code. Start a fresh chat session, since implementation goes better on a clean context window. In your AI chat:

/openspec-apply-change add-rate-limiting

The agent reads the change folder, then works through tasks.md, checking off each task as it lands.

  • Interrupted, or out of context? Open a new session and ask it to apply again. It resumes at the first unchecked task.
  • Plan turned out wrong? Fix the artifacts (either way from step 3), then continue applying.
  • Progress lives in the tasks.md checkboxes. There is no hidden state.

Step 5: Archive

Archiving does two things: it updates your main specs with the change's requirements, and it moves the change folder into the archive folder (in /openspec/changes/archive/*).

When every box in tasks.md is checked, in your AI chat:

/openspec-archive-change add-rate-limiting

Step through what archiving does:

## The finished change
> Implementation is done. The delta spec (what this change adds) still sits inside the change folder; specs/ doesn't know about rate limiting yet.
  openspec/
  ├── specs/                                   (no rate-limiting spec yet)
  └── changes/
      └── add-rate-limiting/
          ├── proposal.md
          ├── tasks.md                         every box checked
          └── specs/
              └── rate-limiting/
                  └── spec.md                  the delta: ADDED requirements

## Requirements land in specs/
> Each requirement in the delta lands in the main spec: added ones append, modified ones replace their old version. A new capability gets a new spec file.
  openspec/
  ├── specs/
+ │   └── rate-limiting/
+ │       └── spec.md                          gains "Requirement: Rate limiting"
  └── changes/
      └── add-rate-limiting/
          └── specs/
              └── rate-limiting/
                  └── spec.md                  the delta, source of the merge

## The folder moves to archive/
> The whole change folder, delta included, moves into the archive under a date prefix. Nothing is deleted.
  openspec/
  ├── specs/
  │   └── rate-limiting/
  │       └── spec.md
  └── changes/
-     └── add-rate-limiting/
+     └── archive/
+         └── 2026-08-08-add-rate-limiting/
+             ├── proposal.md
+             ├── tasks.md
+             └── specs/rate-limiting/spec.md

## Specs describe the system as built
> changes/ is clear for the next change. specs/ is the source of truth for what the system does; archive/ is the history of how it got there.
  openspec/
  ├── specs/
  │   └── rate-limiting/
  │       └── spec.md                          the spec as built
  └── changes/
      └── archive/
          └── 2026-08-08-add-rate-limiting/

Git is a separate concern. Commit the change folder with the code, and nothing else about your workflow changes. When to archive relative to a PR is a team convention; the Teams guide has the tradeoff.

Going further

  • Concepts: what the two artifacts are, and how a delta describes a change.
  • Explore: getting more out of explore mode.
  • Apply: pacing, context windows, resuming long changes.
  • Review the plan: what to look for in specs before you build.
  • Profiles: optional workflows beyond the core set (verify before archive, incremental planning).

Advanced guides

Not written yet; guides we plan to add:

  • Prototype first: spike the code before any spec, then backfill the proposal from what the prototype taught you.
  • Building iteratively: a sequence of small changes instead of one big proposal.
  • Revising an implemented change: the plan needs to move again after apply, but the change hasn't merged or archived yet.