Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f8e5743
feat(skills): shorter workflow skills that let the CLI do the exact work
clay-good Oct 22, 2026
caf88cf
feat(skills): one openspec-beta router skill with a short skill per w…
clay-good Oct 22, 2026
1eb260e
feat(setup): install OpenSpec once per machine, with migration and re…
clay-good Oct 22, 2026
91ed452
test(skills): A/B eval harness with blind plan and readability judges
clay-good Oct 22, 2026
ccfe456
ci(setup): run openspec setup and --revert against the real Claude Co…
clay-good Oct 22, 2026
73c1ede
test(setup): check Codex and Gemini CLI discover and drop the beta sk…
clay-good Oct 22, 2026
8826285
fix(setup): upgrade cleanly between betas and across a namespace rename
clay-good Oct 22, 2026
9009223
chore(skills): hide maintainer skills from npx skills add; describe t…
clay-good Oct 22, 2026
b55ee25
docs(skills): beta tester page: try it, what you get, how to go back,…
clay-good Oct 22, 2026
268c099
test(setup): check Codex on Windows CI against the runner's real home
clay-good Oct 22, 2026
ca2c779
feat(skills): give the router a role, principles, and guides; sync be…
clay-good Oct 23, 2026
253ec32
docs(skills): describe the router's guides; drop the sync skill from …
clay-good Oct 23, 2026
fba68f9
docs(skills): say the spec-update task is the default schema's
clay-good Oct 23, 2026
308efe1
refactor(skills): lead the router with the skills table; principles p…
clay-good Oct 23, 2026
89641c3
docs(skills): list sync in the router as steps to ask for; restore th…
clay-good Oct 23, 2026
cc1039f
refactor(skills): tighter principles; split setup into short labeled …
clay-good Oct 23, 2026
4e807f8
feat(skills): name each guide in the step where its decision is made
clay-good Oct 23, 2026
7cc8fad
feat(skills): name the guides in continue, new, ff, and update; eval …
clay-good Oct 23, 2026
cf858f9
refactor(skills): principles close the router; keep the update guide …
clay-good Oct 23, 2026
e1c8ad9
Merge remote-tracking branch 'origin/main' into claude/openspec-skill…
clay-good Oct 23, 2026
cbbf491
Merge remote-tracking branch 'origin/main' into claude/openspec-skill…
clay-good Oct 26, 2026
c550fef
docs(skills): tell beta testers with the standalone binary which open…
clay-good Oct 26, 2026
6543928
refactor(skills): shorter propose and artifact loop; router handles s…
clay-good Oct 26, 2026
f4239ab
feat(skills): the router loads whenever work touches openspec/; a gui…
clay-good Oct 26, 2026
0e686ce
test(skills): real npx skills add and remove in CI; npx eval mode; sk…
clay-good Oct 26, 2026
f39faa7
refactor(skills): fold verify's check ladders, a priority table, shor…
clay-good Oct 26, 2026
3dc2779
feat(skills): plan only the gap, with nothing the request did not ask…
clay-good Oct 26, 2026
50ee86c
ci(skills): run the real-CLI tests one file at a time; on Windows the…
clay-good Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .agents/skills/draft-openspec-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
name: draft-openspec-docs
description: Collaborative page-drafting mode for the OpenSpec docs. Builds a scratch plan inside the target page (purpose, structure, numbered draft steps), iterates on it with the user, then drafts one section per approved step and cleans up after itself. Use when a page needs a from-scratch rewrite or a new page is being shaped with the user in the loop.
argument-hint: target page
# Repo-maintainer skill: hidden from `npx skills add` (skills CLI discovery).
metadata:
internal: true
---

# Draft OpenSpec docs (scratch-plan workflow)
Expand Down
3 changes: 3 additions & 0 deletions .agents/skills/release-openspec/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ description: >-
publishing, and polish GitHub release notes. Also use when asked whether an
open release PR is complete, what the next release step is, or to continue a
release paused for human approval.
# Repo-maintainer skill: hidden from `npx skills add` (skills CLI discovery).
metadata:
internal: true
---

# Release OpenSpec
Expand Down
3 changes: 3 additions & 0 deletions .agents/skills/verify-openspec-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
name: verify-openspec-docs
description: Fact-checks OpenSpec user documentation with a fresh-context subagent that re-runs commands and checks claims against source. Manually triggered; not part of the drafting loop. Use when the user asks to verify, fact-check, or accuracy-check a docs page, section, or set of changed claims.
argument-hint: page or section
# Repo-maintainer skill: hidden from `npx skills add` (skills CLI discovery).
metadata:
internal: true
---

# Verify OpenSpec docs
Expand Down
3 changes: 3 additions & 0 deletions .agents/skills/write-openspec-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
name: write-openspec-docs
description: Switches into OpenSpec docs-writing mode; loads the house style guide and drafts or revises pages in its voice (action-first, no preamble, scannable). Use when writing or editing pages in the OpenSpec docs tree.
argument-hint: page or section
# Repo-maintainer skill: hidden from `npx skills add` (skills CLI discovery).
metadata:
internal: true
---

# Write OpenSpec docs
Expand Down
5 changes: 5 additions & 0 deletions .changeset/lean-skills-references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fission-ai/openspec": minor
---

New, opt-in `openspec-beta` skills, installed once per machine with `openspec setup`. One `openspec-beta` router skill says what OpenSpec is, the principles every skill follows, and when to read each skill's steps (`references/<skill>.md`) or a short guide (sizing a change, naming capabilities, decisions to raise, how specs change); a short `openspec-beta-<skill>` skill keeps autocomplete (`/openspec-beta-propose`, or `/openspec-beta:propose` in Claude Code). Sync is no longer its own skill: apply's last task and archive merge the specs. Setup installs a Claude Code plugin and `~/.agents/skills` for Codex, Cursor, Gemini CLI, OpenCode, and others, moves older OpenSpec skills and `/opsx` command files into a backup, and `openspec setup --revert` puts everything back. Explore keeps a living draft; propose plans from the settled scope, checks what the code already does, and ends `tasks.md` with a spec update. Archive lets `openspec archive` merge and validate. `openspec context --json` now includes `project_context`. `openspec init --tools` still installs per-project skills under today's names, with the same shorter steps, so existing projects get the clearer text on their next `openspec update`.
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,49 @@ jobs:
path: coverage/
retention-days: 7

skills_setup_real_claude:
# `openspec setup` and `--revert` against the real Claude Code, Codex, and
# Gemini CLIs on every OS. Not a required check: it depends on external packages.
name: Skills setup (${{ matrix.os }}, real agent CLIs)
runs-on: ${{ matrix.os }}
timeout-minutes: 15
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup pnpm
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# Claude Code needs Node 22 or newer.
node-version: '22'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build project
run: pnpm run build

- name: Install Claude Code, Codex, and Gemini CLI
run: npm install -g @anthropic-ai/claude-code@2.1.306 @openai/codex@0.163.0 @google/gemini-cli@0.65.0

- name: Run setup, revert, and npx skills add end to end
env:
OPENSPEC_REAL_CLAUDE: '1'
OPENSPEC_REQUIRE_AGENTS: 'claude,codex,gemini'
DISABLE_AUTOUPDATER: '1'
run: pnpm exec vitest run --no-file-parallelism test/cli-e2e/setup-real-claude.test.ts test/cli-e2e/setup-revert-journey.test.ts test/cli-e2e/npx-skills-real.test.ts

test_pr_required:
name: Test
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ opencode.json

# Cursor
.cursor/
scripts/skill-eval/results/

# Standalone binaries (scripts/binary/build.mjs); Bun can leave .bun-build temp files
dist-bin/
Expand Down
21 changes: 20 additions & 1 deletion docs-lab/reference/schemas/spec-driven/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Create the proposal document that establishes WHY this change is needed.

Sections:
- **Why**: 1-2 sentences on the problem or opportunity. What problem does this solve? Why now?
- **What Changes**: Bullet list of changes. Be specific about new capabilities, modifications, or removals. Mark breaking changes with **BREAKING**.
- **What Changes**: Bullet list of changes. Be specific about new capabilities, modifications, or removals. Mark breaking changes with **BREAKING**. Prefer the change that keeps existing behavior, data shapes, and tests working; when one must break, mark it **BREAKING** and say why it is needed.
- **Capabilities**: Identify which specs will be created or modified:
- **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<capability-path>/spec.md`. Name each capability for a durable system behavior (for example, `user-auth`), not the work in this change (for example, `add-login-endpoint`). Choose a cohesive boundary that can own related requirements as the system evolves; avoid broad catch-all capabilities. Use kebab-case for path segments you introduce (e.g., `user-auth` or `identity/user-auth`) and follow the project's existing spec organization.
- **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Use the exact existing path under `openspec/specs/`. Leave empty if no requirement changes.
Expand Down Expand Up @@ -159,6 +159,10 @@ The template the agent receives as the output format ([templates/spec.md](https:
#### Scenario: <!-- scenario name -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->

#### Scenario: <!-- a failure or edge case, when the behavior can fail -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->
```

### Instructions
Expand Down Expand Up @@ -219,6 +223,9 @@ Format requirements:
- Each scenario: `#### Scenario: <name>` with WHEN/THEN format
- **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
- Every requirement MUST have at least one scenario.
- State one behavior per requirement: a single SHALL or MUST obligation, with no "and also". If a requirement bundles several obligations, split it into separate `### Requirement:` blocks.
- Cover the main success path, then add a scenario for each way the behavior can fail or surprise a reader (invalid input, a missing item, a refused action, a boundary value). A tester should be able to write one test per scenario, so use concrete example values (a specific date, an exact message) rather than placeholders like "a valid value". Describe how the requested behavior fails; do not add validation, errors, or limits the request did not ask for.
- Describe what a user or caller observes, not how the code does it: no internal function or class names, file paths, or private APIs in requirement text, unless they are themselves the public contract (for example, a documented CLI flag or API endpoint).
- Keep each requirement's description (the text between `### Requirement:` and its first scenario) to 500 characters or fewer. `openspec validate` flags longer descriptions in ADDED requirements and in the main spec. This is a warning: normal validation still passes, but `openspec validate --strict` fails on it. When writing a new requirement, state one behavior per requirement: move examples and edge cases into scenarios, and split a requirement that covers several behaviors into separate `### Requirement:` blocks, each with its own scenarios. Under MODIFIED, keep the existing requirement block whole; never split, trim or rewrite existing text just to meet the length. Split an existing long requirement only when the user asks for it, in a change made for that purpose: under MODIFIED, keep its header and every scenario and cut its description down to one behavior without changing its meaning, then add each behavior you removed as its own ADDED requirement with its own scenarios.

New capabilities only: the delta spec's first section is `## Purpose` -
Expand Down Expand Up @@ -263,6 +270,10 @@ The system SHALL allow users to export their data in CSV format.
- **WHEN** user clicks "Export" button
- **THEN** system downloads a CSV file with all user data

#### Scenario: Nothing to export
- **WHEN** user with no data clicks "Export" button
- **THEN** system explains there is nothing to export and downloads no file

## REMOVED Requirements

### Requirement: Legacy export
Expand Down Expand Up @@ -383,6 +394,10 @@ Guidelines:
- Each tracked task MUST be a checkbox: `- [ ] X.Y Task description`
- Tasks should be small enough to complete in one session
- Order tasks by dependency (what must be done first?)
- End with a tracked `## N. Update the specs` group: one task to sync this
change's delta specs into the main specs and verify `openspec validate
--specs` passes. It finishes before archive, so the main specs are
current as soon as the work is.
- Track implementation and verification work that can be completed before
archive. If the requested workflow includes archive or work that requires
this change to be archived, preserve those steps as plain bullets in an
Expand Down Expand Up @@ -415,6 +430,10 @@ Example:
- [ ] 2.1 Implement data export function and verify the export test passes
- [ ] 2.2 Add CSV formatting utilities and verify unit tests cover quoting and delimiters
- [ ] 2.3 Document the export API in docs/export.md and verify the documented command runs as written

## 3. Update the specs

- [ ] 3.1 Sync this change's delta specs into the main specs and verify `openspec validate --specs` passes
```

When applicable, append workflow follow-up as plain bullets, for example:
Expand Down
51 changes: 49 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The OpenSpec CLI (`openspec`) provides terminal commands for project setup, vali

| Category | Commands | Purpose |
|----------|----------|---------|
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
| **Setup** | `setup`, `init`, `update` | Install OpenSpec for your agents, and initialize and update it in your project |
| **Stores (standalone OpenSpec repos)** | `store setup`, `store register`, `store unregister`, `store remove`, `store list`, `store doctor` | Manage stores — standalone OpenSpec repos you've registered |
| **Health** | `doctor` | Report relationship health for the resolved root |
| **Working context** | `context` | Assemble the working set (root + referenced stores) |
Expand Down Expand Up @@ -78,6 +78,53 @@ These options work with all commands:

## Setup Commands

### `openspec setup`

Install OpenSpec's skills once for every coding agent on this machine, so no project needs skill files of its own. Beta.

```
openspec setup [--dry-run] [--revert] [--json]
```

It installs an `openspec-beta` router skill and one short skill per workflow. The router's `SKILL.md` names the workflows and holds the rules they all share; each workflow's steps are in `openspec-beta/references/<workflow>.md`. The `openspec-beta` names never clash with the `openspec-*` skills earlier versions installed. Each workflow skill only points there, so workflows autocomplete while every rule lives in one place. Setup finds your agents from the folders they create in your home directory:

| Agent | What you get | Start a workflow |
|-------|--------------|-----|
| Claude Code | An `openspec-beta` plugin holding the skills | `/openspec-beta:propose` |
| Codex, Gemini CLI, OpenCode, Cursor, GitHub Copilot, Amp, Qwen Code, Crush, Goose, Cline, Kilo Code | `openspec-beta` and `openspec-beta-<workflow>` in `~/.agents/skills`, the folder these agents share | `/openspec-beta-propose` (`$openspec-beta-propose` in Codex) |

```text
OpenSpec is set up on this machine.

Claude Code plugin "openspec-beta": /openspec-beta:propose
Codex ~/.agents/skills: $openspec-beta-propose

Moved 18 older OpenSpec files to a backup:
.agents/skills (6)
.claude/skills (6)
.claude/commands/opsx (6)

The "openspec-beta" skill explains OpenSpec and picks the right skill; 5 skills start one directly: explore, propose, update, apply, archive.

Undo all of this with `openspec setup --revert`.
```

Setup moves what an earlier OpenSpec wrote into a dated backup in OpenSpec's data directory (`~/.local/share/openspec/backups/`): its skills in `~/.agents/skills` and `~/.claude/skills` and, when you run it inside an OpenSpec project, that project's skills and `/opsx` command files. `openspec setup --revert` unregisters and removes the plugin, removes the skills setup wrote, and moves every backed-up file back. Files OpenSpec did not write are never touched, and a second run leaves the new skills alone.

The skills follow your profile (`openspec config profile`). Claude Code loads the plugin in place from `~/.local/share/openspec/claude-plugin`, so `openspec update` refreshes it, and `~/.agents/skills`, from any directory. If the `claude` command is not on your `PATH`, setup writes the plugin and prints the two commands that register it. Interactive `openspec init` offers this install instead of adding skill files to the project; `openspec init --tools <tool>` still installs into the project.

Skills installed with `npx skills add` are not setup's to remove. Remove them by name:

```bash
npx skills remove -g -y openspec-beta openspec-beta-apply openspec-beta-archive openspec-beta-bulk-archive openspec-beta-continue openspec-beta-explore openspec-beta-ff openspec-beta-new openspec-beta-onboard openspec-beta-propose openspec-beta-update openspec-beta-verify
```

| Option | Description |
|--------|-------------|
| `--dry-run` | Show what would be installed without writing anything |
| `--revert` | Remove what setup installed and restore the skills it replaced |
| `--json` | Output as JSON |

### `openspec init`

Initialize OpenSpec in your project. Creates the folder structure and configures AI tool integrations.
Expand Down Expand Up @@ -432,7 +479,7 @@ Everything this work relates to through OpenSpec declarations, in one working se
openspec context [--store <id>] [--json] [--code-workspace <path> [--force]]
```

The JSON brief is agent-consumable (each available referenced store carries its fetch recipe; unresolved members carry the same fixes instructions and doctor show). `--code-workspace` additionally writes a VS Code workspace file containing the root plus the available referenced stores (`ref:<id>` folders) — the one write this command performs, refused without `--force` if the file exists. Unavailable members are reported, never guessed at.
The JSON brief is agent-consumable (each available referenced store carries its fetch recipe; unresolved members carry the same fixes instructions and doctor show). It also carries `project_context`: the root's `context:` config field, validated the same way `openspec instructions` loads it, or `null` when there is none. `--code-workspace` additionally writes a VS Code workspace file containing the root plus the available referenced stores (`ref:<id>` folders) — the one write this command performs, refused without `--force` if the file exists. Unavailable members are reported, never guessed at.

"Working context" is the assembled set; the `context:` field in `openspec/config.yaml` is project background injected into instructions — two different things. `openspec doctor` answers whether the set is healthy; `openspec context` answers what the set is.

Expand Down
30 changes: 11 additions & 19 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,9 @@ Archive a completed change. Finalizes the change and moves it to the archive fol
| `change-name` | No | Which change to archive (inferred from context if not provided) |

**What it does:**
- Checks artifact completion status
- Checks task completion (warns if incomplete)
- Offers to sync delta specs if not already synced
- Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
- Runs `openspec archive --json`. When nothing needs your go-ahead, that archives the change directly; otherwise it reports what needs approval and moves nothing
- Shows you any warnings (incomplete tasks or artifacts, main specs that will change) and asks before going on
- Runs `openspec archive --yes`, which merges the delta specs into the main specs, validates them, and moves the change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`; if anything fails, the CLI refuses and nothing changes
- Preserves all artifacts for audit trail

**Example:**
Expand All @@ -537,26 +536,19 @@ You: /opsx:archive

AI: Archiving add-dark-mode...

Artifact status:
✓ proposal.md exists
✓ specs/ exists
✓ design.md exists
✓ tasks.md exists (8/8 tasks complete)

Delta specs: Not yet synced
→ Sync now? (recommended)
All 8 tasks are complete. Archiving will update 1 main spec
(specs/ui/spec.md: 1 requirement added).
→ Archive and update the main specs? (recommended)

You: Yes

AI: ✓ Synced specs to openspec/specs/ui/spec.md
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/

Change archived successfully.
AI: ✓ Archived as openspec/changes/archive/2025-01-24-add-dark-mode/
✓ Main specs updated and validated (1 added)
```

**Tips:**
- Archive won't block on incomplete tasks, but will warn
- Delta specs can be synced during archive or beforehand
- Archive won't block on incomplete tasks, but will warn and ask
- Delta specs can be synced during archive or beforehand; archiving a change whose specs are already synced adds nothing twice
- Archived changes are preserved for history
- Use `/opsx:verify` first to catch issues

Expand All @@ -581,7 +573,7 @@ Archive multiple completed changes at once. Handles spec conflicts between chang
- Validates each change before archiving
- Detects spec conflicts across changes
- Resolves conflicts by checking what's actually implemented
- Archives in chronological order
- Archives each change with `openspec archive`, in chronological order when changes conflict

**Example:**
```
Expand Down
Loading
Loading