Files
OpenSpec/docs
e0a2f00f95 fix(metadata): stop reporting x- extension keys in .openspec.yaml as unknown (#2063)
* feat(metadata): x- extension keys in .openspec.yaml are not reported as unknown

Teams that keep tool data beside a change (a tracker id, a goal id, an owner) had no
place for it: since 1.14.0 every unrecognized top-level key is a validation warning,
so validate --strict fails. Keys that start with x- are now extension metadata, as in
OpenAPI: never read, never written, never reported. Every other unknown key is still
reported, and the warning now names the x- prefix as the way to keep such data.

Refs #657

* fix(metadata): accept any x- name, and say so when a key just misses

The extension grammar was narrower than the contract above it. The doc
comment said "the prefix is the whole contract, as in OpenAPI's x-
extensions", but the pattern was `/^x-[a-z0-9][a-z0-9_-]*$/`, so the
spellings teams actually write were still reported:

  x-jiraKey    warned     x-a-       accepted
  x-trackerID  warned     x-foo_bar  accepted
  x-Owner      warned

`x-jiraKey` is the obvious key for the tracker case in #657, and it failed
`validate --strict` while a trailing-hyphen name passed. Worse, the new
remediation sentence told that user to "prefix a key with x-" - which they
had done - so the warning became a dead end with no way out from the
message alone. That is a worse experience than the warning this PR removes.

The name after the prefix is now the owner's business: `/^x-\S+$/`. Empty
and whitespace-carrying names stay rejected, the latter because whitespace
would let a key forge a second line in the warning output.

The prefix itself stays lowercase, keeping this PR's deliberate
`X-goal -> false`. That is the one near-miss a user cannot diagnose from
the old message, so the message now names both conditions it does not
cover, and only when a reported key actually starts with the prefix.

Also pinned the round-trip, which was the risk worth checking: archive
moves `.openspec.yaml` rather than rewriting it, and `writeChangeMetadata`
only ever writes a new file, so extension keys survive today. But
`ChangeMetadataSchema` is not passthrough and strips them, so the first
read-modify-write caller would silently delete data a team put there.
A test pins the stripping and the writer's doc comment now says to merge
`x-` keys back from the raw YAML.

Documented the namespace in docs/cli.md next to the other metadata keys,
since `x-* (yours)` in a directory-tree comment could not carry the rule,
and flipped the changeset to `patch` to match the `fix` retitle and the
#2020/#2028 precedent.

Verified end to end: a change with `x-jiraKey` and `x-Owner` passes
`validate --strict`, while `X-Tracker` beside a `taskss` typo reports both
and explains the prefix. 6413 tests pass; lint clean.

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

* refactor(metadata): merge the stacked writeChangeMetadata JSDoc and trim extension-key comments

- writeChangeMetadata had two consecutive /** */ blocks, orphaning the first;
  merge them into one that keeps the params and the x- key stripping caveat.
- Trim the EXTENSION_KEY_PATTERN comment to the contract, dropping the
  history of the earlier grammar and the inaccurate claim that whitespace
  could forge a warning line (reported keys are already sanitized).
- Tighten the changeset to the user-facing behavior.

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

* test(archive): keep x- extension keys byte-for-byte through archive

Archive is the only path that touches an existing .openspec.yaml; it moves
the file rather than rewriting it. Pin that, and that archive --json emits no
unknown-key warning for x- keys.

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

* docs(metadata): document x- extension keys in the docs-lab reference

The canonical change-metadata reference still said every unknown top-level
key is reported and fails --strict. Add an Extension keys section (name
rule, ignored value, top-level scope, strict result, archive) and point
the Validation bullets at it.

Pin each documented claim where it is enforced, not only in the helper:
the validator passes --strict on x- keys with any YAML value, still fails
on X-Tracker, a bare x- and "x- tracker", and loadChangeContext (status,
instructions) returns no warning. All three tests fail on main's code.

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

---------

Co-authored-by: beast-infra <hi@fbeeg.io>
Co-authored-by: Clay Good <hi@claygood.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-14 23:27:55 +00:00
..

OpenSpec Documentation

Warning

These pages are legacy and some are out of date. The current docs are at openspec.dev/docs (source: docs-lab/).

Welcome. This is the home for everything OpenSpec.

OpenSpec helps you and your AI coding assistant agree on what to build before any code is written. You describe the change, the AI drafts a short spec and a task list, you both look at the same plan, and then the work happens. No more discovering halfway through that the AI built the wrong thing.

If you read nothing else, read these two pages:

  1. Getting Started: install, initialize, and ship your first change.
  2. How Commands Work: where you actually type /opsx:propose (hint: in your AI chat, not the terminal). This trips up almost everyone once.

That second one matters more than it looks. OpenSpec has two halves: a command line tool you run in your terminal, and slash commands you give to your AI assistant. Knowing which is which saves you the most common moment of confusion.

The best habit to build first: when you're not sure what to build, start with /opsx:explore. It's a no-stakes thinking partner that reads your code, weighs options, and sharpens a fuzzy idea into a concrete plan before any code gets written. The Explore First guide makes the case.

Pick your path

I'm brand new. Start with Getting Started, then skim the Core Concepts at a Glance. When something feels mysterious, the FAQ and Glossary are nearby.

I have a problem but not a plan. This is the common case, and it has a dedicated answer: Explore First. Use /opsx:explore to think it through with the AI before committing to anything.

I have a big existing codebase. You don't document all of it. Using OpenSpec in an Existing Project shows how to start on real, brownfield code without boiling the ocean.

I just want to get it working. Install, run openspec init, then read How Commands Work so your first slash command lands in the right place. Or hand the setup to your assistant with the AI-assisted install prompt.

I learn by example. The Examples & Recipes page walks through real changes start to finish: a small feature, a bug fix, a refactor, an exploration.

The AI just drafted a plan — now what? Read it. Reviewing a Change shows the two-minute pass that catches a wrong turn while it's still cheap, and Writing Good Specs covers what a plan worth approving is made of.

I work on a team. OpenSpec on a Team shows how a change maps onto a branch and a pull request, and how teammates review a plan before the code.

I'm coming from the old workflow. The Migration Guide explains what changed and why, and promises your existing work is safe.

I want to bend it to my team's process. Customization covers project config, custom schemas, and shared context.

Something's broken. Troubleshooting collects the failures people actually hit, with fixes.

The whole map

Start here

Doc What it gives you
Getting Started Install, initialize, and run your first change end to end
Explore First Use /opsx:explore to think through an idea before you commit
How Commands Work Where slash commands run, what "interactive mode" means, terminal vs chat
Core Concepts at a Glance The whole mental model on one page: specs, changes, deltas, archive
Installation npm, pnpm, yarn, bun, Nix, a prompt that hands setup to your AI assistant, and how to verify it worked

Use it day to day

Doc What it gives you
Workflows Common patterns and when to reach for each command
Examples & Recipes Full walkthroughs of real changes, copy-pasteable
Writing Good Specs What a strong requirement and scenario look like, and how to right-size a change
Reviewing a Change The two-minute pass on a drafted plan before any code is written
OpenSpec on a Team How changes fit branches, pull requests, and review
Using OpenSpec in an Existing Project Adopting OpenSpec on a large brownfield codebase
Editing & Iterating on a Change Update artifacts, go back, reconcile manual edits
Commands Reference for every /opsx:* slash command
CLI Reference for every openspec terminal command

Understand it deeply

Doc What it gives you
Concepts The long-form explanation of specs, changes, artifacts, schemas, and archive
OPSX Workflow Why the workflow is fluid instead of phase-locked, plus an architecture deep dive
Glossary Every term defined in one place

Make it yours

Doc What it gives you
Customization Project config, custom schemas, shared context
Multi-Language Generate artifacts in languages other than English
Supported Tools The 30+ AI tools OpenSpec integrates with, and where files land
Community Showcase Projects and resources built with and for OpenSpec

When you need help

Doc What it gives you
FAQ Quick answers to the questions people ask most
Troubleshooting Concrete fixes for concrete failures
Migration Guide Moving from the legacy workflow to OPSX

Coordinate across repos (beta)

Doc What it gives you
Stores: User Guide Plan in its own repo when your work spans repos or teams
Agent Contract The machine-readable CLI surfaces agents drive

The thirty-second version

1. Install        npm install -g @fission-ai/openspec@latest
2. Initialize     cd your-project && openspec init
3. Explore        (in your AI chat)  /opsx:explore           ← optional, but a great habit
4. Propose        (in your AI chat)  /opsx:propose add-dark-mode
5. Build          (in your AI chat)  /opsx:apply
6. Archive        (in your AI chat)  /opsx:archive

Steps 1 and 2 happen in your terminal. The rest happen in your AI assistant's chat. That split is the one thing worth memorizing, and How Commands Work explains exactly why. Step 3 is optional, but starting with /opsx:explore when you're unsure is the habit most worth forming.

Where else to get help

Found something in these docs that's wrong, stale, or confusing? That's a bug. Open an issue or a PR. Documentation improvements are some of the most valuable contributions you can make.