The OpenSpec workflow
Development on archmax automation is spec-driven. A substantive change flows through
OpenSpec artifacts under openspec/ before and
while it is implemented, and the specs under openspec/specs/ say what the platform does now.
Anatomy of a change
Section titled “Anatomy of a change”Each open change lives at openspec/changes/<change-name>/:
| Artifact | Purpose |
|---|---|
proposal.md |
Why the change exists, what changes, which specs it adds or modifies, its impact |
design.md |
Context, goals and non-goals, decisions with the alternatives considered, risks, rollout |
specs/<spec>/spec.md |
Delta specs: added, modified or removed requirements, each with scenarios |
tasks.md |
The implementation checklist, each task with how it is verified |
A requirement says what the platform SHALL do (the validator reads the first line of a
requirement’s body for SHALL or MUST), and each has at least one #### Scenario: with
WHEN and THEN bullets. A modified requirement is restated in full, keeping every
scenario title it already has.
Lifecycle
Section titled “Lifecycle”- Propose: describe the change and generate the proposal, the design, the delta specs and the tasks.
- Apply: implement the tasks and check them off as they land. When the work shows the design was wrong, the artifacts change with it.
- Archive: merge the delta specs into
openspec/specs/and move the change underopenspec/changes/archive/. Thengit addthe archive: the spec gate refuses an untracked one.
The openspec CLI drives this:
openspec list # open changesopenspec status --change <name> # which artifacts are doneopenspec validate <name> # the change's artifacts and deltasopenspec archive <name> --yes # merge the deltas and archiveAgent-assisted work has matching slash commands in .claude/commands/: /opsx:propose,
/opsx:apply, /opsx:sync and /opsx:archive.
The vocabulary
Section titled “The vocabulary”The vocabulary table in openspec/config.yaml is normative: one word per concept, shared with
the SDK, used in code identifiers, collection and route names, UI strings, specs and these
pages. Its “not called” column lists the spellings that must not appear. When a concept has no
word yet, the row is added to the table first. The glossary is that
table, rendered when this site is built.
The spec gate
Section titled “The spec gate”pnpm check:specs (tools/check-specs.ts) runs in CI beside the typecheck and before every
push. It fails on:
- a spec without exactly one
## Purpose, or one that starts with TBD; - a requirement without SHALL or MUST, without a scenario, or a scenario without WHEN and THEN;
- a requirement title used twice anywhere under
openspec/specs/; - a “not called” spelling in a spec or on a page of this site (fenced code blocks are skipped);
- a spec directory missing from
openspec/spec-map.yaml, or a mapped path that does not exist; - an archived change left untracked under
openspec/changes/archive/; - the product’s former codename on any line of the repository outside the archive.
openspec/spec-map.yaml maps each spec to the modules that implement it, under the keys
core, api, frontend, docs (this site) and ci (the workflows, scripts and image). A new
spec’s entry is added when the change is archived, because the map is checked against
openspec/specs/.
Documentation ships with the change
Section titled “Documentation ships with the change”openspec/config.yaml injects two rules into artifact generation: a proposal for a change
owners, authors or operators see or configure names the pages of this site that change, and
its tasks include updating them. Write a page about the behaviour as it is, from the spec it
describes, and link the harness docs for the SDK’s own concepts
instead of restating them.