/change
Audience: coding agents and integration operators. CLI commands and schemas below are system reference, not a user checklist. Users can follow Quickstart.
In plain words: Change turns what you want into a written agreement before
any code is written. You describe the outcome in your own words; the agent reads
the code and drafts the agreement (what will behave differently, how each promise
will be checked, which files may change); the harness validates it and creates
the change folder openspec/changes/<id>/. You get a proposal to read and
approve. Nothing is built until you do.
What you do
Section titled “What you do”- Say what you want, including constraints and things you do not want.
- Answer questions only you can answer. The agent asks at most three linked decisions at a time, and never asks about things it can read from the code.
- Read the approval summary (see Approval) and approve in your own words, for example “go ahead”. Silence or urgency alone is not approval.
- Change your mind early. Before Build, the agent revises the same change; an additive revision keeps your approval, and removing agreed behavior asks you again. After Build starts, new behavior goes through one amendment.
Next step: advance <change> --through build (the agent runs it).
What the agent compiles
Section titled “What the agent compiles”Everything below is for agents and integrators. You never write these files by hand.
/change <intent | existing-change> [--prototype-selection <path>]/change turns intent into the durable agreement that every later phase reads.
The agent interprets sources and writes one semantic draft; Change Loop derives
the required discovery dimensions, validates the decision frontier, generates
the bookkeeping, and installs the result transactionally.
Minimal draft
Section titled “Minimal draft”For an ordinary change, the agent writes only the intent, the work type, the
behavior, and the tasks. change start --template prints this form first as
minimalDraft, preceded by a save field: the agent writes a draft v5 folder,
.foundation/drafts/<id>/ (see below), with its Write tool, because the host
refuses a shell heredoc and .foundation/drafts/ is a pre-allowed path. Then it
runs claude-foundation change start .foundation/drafts/<id>. change.json
declares version: 5 and workType, which selects the required sections;
proposal.md holds the reason as prose:
{ "version": 5, "language": "en", "intent": "Reject empty note titles", "workType": ["bugfix"], "requirements": [{ "description": "The system SHALL reject a note whose title is empty", "scenarios": [{ "when": "a user submits an empty title", "then": "the note is not created" }] }], "tasks": [{ "outcome": "Validate note titles", "verify": "npm test", "paths": ["src/note.js"] }]}A one-file JSON draft without version, .foundation/drafts/<id>.json, still
starts as draft v4 with the same defaults.
The compiler fills in the version, requirement and task keys, capability (an
optional top-level capability names it; otherwise an existing openspec/specs
capability matched by requirement text or task paths; with no confident match
one EDIT lists the capabilities to choose from; when no specs exist, the
intent’s noun phrase in at most three words, such as kanban-board), operation
(modified when a canonical requirement matches, otherwise added), scenario
names, covers (inferred
only with one task or one requirement; several of both return one EDIT
naming each tasks[i].covers),
rapid defaults, and test evidence from verify. A derived requirement key is
whole words from the SHALL clause (at most five words and 40 characters, no
trailing word such as “and” or “to”), and the requirement heading is that
clause as a readable title, such as “Persist its cards in browser
localStorage”. A delta for a capability with no living spec states a
## Purpose (the capability overview, else the intent, with requirement titles
when the intent is short) that archive carries into the new spec; an existing
spec’s Purpose is never replaced. A derived scenario name is a
short whole-word title from when (at most 60 characters, no leading article or
dangling word); two that read the same are told apart by their given or
then, else a number. Add decisions: [{ "key", "choice", "reason"? }] for
each default you chose without asking (stack, storage): they are recorded as
decidedBy: agent, listed under Decisions in the proposal, and keep the rapid
lane. With no why, the proposal omits Why rather than repeat the intent.
One change start <draft>
inspects and starts it, and prints the packet files and tasks. A draft that
states version: 4 or version: 5, or declares risk, uses the full form below.
The full semantic draft
Section titled “The full semantic draft”The full core stays small:
{ "version": 4, "intent": "Prevent orphaned rows from blocking mutations", "impact": "medium", "coupling": "isolated", "requirements": [{ "key": "orphan-row-does-not-lock", "capability": "mutation-control", "operation": "added", "description": "The mutation guard SHALL ignore phase rows of inactive changes.", "outcome": "Unrelated mutations remain available", "scenarios": [{ "name": "Orphaned row", "kind": "success", "given": "a phase row belongs to an archived change", "when": "another change edits a product file", "then": "the edit is allowed" }] }], "tasks": [{ "key": "filter-orphan-rows", "outcome": "Exclude orphaned rows from active locks", "covers": ["orphan-row-does-not-lock"], "paths": ["src/**"], "verify": "npm test" }], "evidence": { "orphan-row-does-not-lock": { "capabilities": ["test"] } }, "discovery": { "coverage": [ { "dimension": "current-behavior", "status": "covered", "sources": ["src/mutations.js"] }, { "dimension": "compatibility", "status": "not-applicable", "rationale": "No public contract changes." } ], "decisions": [] }}The agent uses meaningful keys. Discovery coverage is optional for an ordinary
change: impact: high and typed risk declarations (riskSignals, security
triggers, integrations, external operations) add required dimensions, prose is
never scanned for keywords, and a risk-derived not-applicable row needs only
a rationale. A required dimension the draft already states needs no row: the
harness derives a covered row, marked derived in the proposal appendix, from
currentState, userStories, requirements, scenario kind (success,
failure, boundary), compatibility, nonGoals, tasks with verify and
evidence, failureMatrix, apiContracts, dataModel, uiStates,
jobContract, or documented integrations. Without such content the
dimension stays missing, and an authored row always wins, so a
needs-user-decision row is still asked. The harness refuses unresolved investigation or user-decision statuses, checks
decision prerequisite cycles, and exposes at most three dependency-ready
decisions at a time. The compiler creates stable claim/task IDs,
spec-to-claim-to-task-to-provider links, classification, and versioned defaults.
It reports every independent draft problem together, pointing back to the input
field. A failed compile leaves no partial change.
Specs are written for people. Each scenario is one case with a short name,
optional given preconditions, one when, one then, and optional and
results; a when or then that joins cases with ; is refused, as is a
requirement statement long enough to hide several requirements (list
constraints in details instead). capabilityOverviews gives each spec file a
human title and a short overview, and language records the document language:
prose follows it while SHALL, GIVEN, WHEN, THEN, and AND stay English
for the OpenSpec parser.
Print the current schema with change start --template, then run
change start <draft.json> (or change start <folder> for a draft v5 folder). A complete draft is inspected, compiled, and
started in one call, and the output lists the packet files and tasks.
Otherwise the harness returns agent-owned source investigation or repair, or at
most three linked user decisions, plus an exact resume route, and creates
nothing. --inspect inspects without starting; --consume-draft also removes
the draft after a successful start. Record the user’s spec approval with
advance <change> --approve-spec --decision-ref <ref>, or add
--approve-spec --decision-ref <ref> to the change start, change revise, or
change amend call that applies the approving answer. Open design questions are
printed with the approval packet. The first inspection also returns, as agent
repairs, a task verify naming a test file that neither exists nor falls in any
task’s paths, and an apiContracts error without a status or code. Versions 1 through 3 remain
supported for existing integrations.
Use typed riskSignals for access control, persisted data, integrations,
performance SLOs, UI, operational risk, external side effects, and financial
effects so required coverage does not depend on the language used in prose.
With access-control, tag at least one scenario access: allow and one
access: deny. Optional constraints render in the proposal, and optional
fixes names the archived changes this change corrects. The harness records
the source digest itself, so a correct draft reaches DONE on its first
inspect; design and reader-guide warnings are advisory.
Inspection stores one machine-owned snapshot bound to the draft and its local
source digests. Before inspection, bounded repository intelligence ranks specs,
tests, callers, integrations, persistence, and permission boundaries. Typed
risk and repository signals adapt the read budget without dropping required
dimensions. Source-answerable questions, duplicate alternatives, and
unsupported recommendations are rejected. A changed source returns
refresh-source-coverage; the snapshot records compact effectiveness metrics,
not a transcript.
Draft v5 folder
Section titled “Draft v5 folder”New work uses draft v5; v4 and v3 drafts remain compatible. A v5 draft is a
folder that change start <folder> accepts like a JSON draft:
.foundation/drafts/<id>/├── change.json # "version": 5 and every typed field├── proposal.md # authored prose under outline headings└── design.md # authored prose under outline headingsproposal.md and design.md use only ## headings from one versioned
outline, in outline order, in English or Thai. The harness writes the derived
sections itself (Change header, Capabilities, Acceptance traceability,
Definition of done, Work type, File map, Test map) and merges them with your
prose, kept byte for byte, in outline order. The proposal reads from why,
user stories, success criteria, and scope through impact and risk, decisions to
ratify, and how to verify, then appendices; the design reads from current state
and architecture through contracts, work-type sections, decisions, quality,
rollout, and tests. One EDIT names any unknown, derived, out-of-order, empty,
or TODO/TBD section. change start --template prints the accepted headings
as draftFolderV5. Status, approvers, evidence freshness, and the review
record never render before Land; read them with claude-foundation changes.
The full order and rules live in WORKFLOW.md under “Draft v5 folder and
outline”.
Work types
Section titled “Work types”workType (declared, or inferred from task paths) selects the design sections a
standard change must carry. A missing one is an agent EDIT naming the field’s
shape and an example, never a user question. Some examples:
| Work type | Required sections |
|---|---|
| feature | userFlow |
| bugfix | bugfix |
| api | apiContracts, boundaries |
| data | dataModel |
| migration | migrationPlan, rollout |
| ui | userFlow, uiStates, componentMap |
Docs, test, and chore work owes only a summary; user-visible work also owes a
releaseNote. Work types also select evidence capabilities. Agents choose
skills themselves from skill descriptions that name workType, riskSignals,
requirements, and scenarios.
The full catalog of 23 types is in WORKFLOW.md under “Work types and required
sections”; capabilities are in .claude/harness/EVIDENCE.md under “Work-type
capabilities”.
Decisions
Section titled “Decisions”A decision may carry status (proposed, accepted, superseded; absent
means accepted), drivers, options, and the requirements it explains. A proposed
decision appears only under the proposal’s Decisions to ratify, so you ratify
or change it with approval; design.md records accepted and superseded ones.
An accepted durable: true decision adds a Rationale line under each named
requirement, so the reason survives archive into the living spec. See
WORKFLOW.md under “Decisions”.
Typed extensions
Section titled “Typed extensions”Add complexity only when the work needs it:
- multiple requirements with separate
capabilityandoperationvalues - dev document sections:
summary,userFlow(Mermaid),failureMatrix,componentMap,apiContracts,dataModel,uiStates,configContract,jobContract,bugfix, orrefactor. The harness infersworkTypefrom task paths (declare it to override) and derives the folder tree, file map, and test map. A standard change must carry the sections its work type needs; a missing one is a draft repair for the agent, never a user question. Each fact is written once:whysatisfies the summary (addsummaryonly for more), and without an authoredfailureMatrixthe scenarios with"kind": "failure"become its rows, with an optional scenariorecoveryfor the recovery column. A task whose own tests sit outside itspathsis a design warning decisionsfor load-bearing choices, each with its consequences- Mermaid or referenced SVG/PNG
diagrams prototypeSelectionpointing at an existing selection noteintegrationswith documentation source/version, linked requirements, and security/resilience/compatibility concerns; related scenarios explicitly use"kind": "success"and"kind": "failure"repositoriesfor multi-repository scope, with each task’srepository; its paths and verify are relative to that repository’s root, where verify runs- external operations for permission-bound work
- Grounding v3 for non-derived material decisions
Prototype output is never proof. Missing or unversioned integration
documentation is a research/user-decision boundary, not permission to guess.
For MODIFIED, the compiler reads the canonical spec and merges its complete
scenario set before adding or changing scenarios; REMOVED requires a
migration consequence. A local diagram, prototype selection, or integration
document must resolve to a regular file inside the project; directories and
symlinks that escape it are refused. A remote integration source must use HTTPS
and a fixed version rather than latest or a branch.
Conditional artifacts and source of truth
Section titled “Conditional artifacts and source of truth”Rapid changes contain proposal.md, tasks.md, evidence.yaml, and a concise
delta specs/<capability>/spec.md rendered exactly as in standard; Land merges
it into openspec/specs. Only a legacy rapid packet or declared docs-only work
(workType: ["docs"] adding requirements) declares skip_specs and has no
delta, so README wording never becomes a living requirement. Every proposal opens with a rendered header (id, lane and why,
owner, created, status) and states scope, an acceptance traceability table
(requirement, scenario, task, evidence, test files), and a definition of done
generated from the enforced policy, with an optional one-line successMeasure.
Tasks live only in tasks.md; the derived folder tree (paths new at the base
marked +) sits in design.md’s file map. The rapid proposal is the compact
dev document: summary, user flow, failure matrix, and its decisions.
Existing changes keep their older layout and still read. Descriptive sections (fileMap,
testMap, componentMap, userFlow, configContract, refactor) render
there too and never move a low-risk change to standard. A standard v4 or v5 change
always adds design.md with the full dev document and states its work type,
noting when it was inferred. Flowchart node labels holding (, ), or "
must be quoted, as in A["mean(values)"]. Execution, repository,
handoff, and grounding files appear only for real overrides.
Two optional draft fields exist only for the approval page: scratch (four
plain lines: get, asIs, toBe, ifFail) and examples (typed blocks
with real values, such as api, examples, dataDiff, permission, or a
prototype file under .foundation/previews/<change>/). They never change the
lane or the packet, a malformed block is an intake EDIT, and change start
only advises (NOTE: scratch) when a medium or high change has none. See
Approval package, previews, and role lanes
for what approvers see; WORKFLOW.md lists all 29 example types.
At archive, Land appends the volatile records to the archived proposal.md
only: Appendix: Review record, Appendix: Compliance change record (only when
openspec/config.yaml sets compliance: change-record), and Appendix: Rollout
gates.
After compilation, openspec/changes/<id>/ is the source of truth. The draft is
temporary and .foundation/ is derived runtime state.
Revising before Build
Section titled “Revising before Build”To change an agreed change before Build starts, revise the same change instead of abandoning it:
claude-foundation change revise <change> <draft.json>The revised draft keeps the change id and passes the same intake gate as
change start in the same call: an incomplete intake prints its action and
changes nothing. With --merge the file holds only the keys and keyed entries
it changes, adds, or removes ("$remove": true). The whole packet is recompiled transactionally, the contract
revision increments, and any failure restores the prior packet and runtime
state. Once Build has a workspace, a receipt, or a completed task, the command
routes to change amend. The result lists the added, revised, and removed
requirements. An approved change keeps its approval for additive deltas; only
a delta that removes a requirement needs approval.
Revising during Build
Section titled “Revising during Build”If Build discovers a new or changed observable requirement, use one semantic
amendment. reviseRequirements replaces an existing requirement (an open task
must cover it) and removeRequirements drops one with a migration:
claude-foundation change amend <change> <amendment.json> --consume-amendmentIt preserves completed tasks, custom prose, diagrams, and unrelated sections;
adds stable links, increments the revision, validates, and rolls back on
failure. An existing task may gain claim coverage, but replacing its outcome
requires a new task; a completed task’s verify command changes only with
reopen: true, which unticks it so it must pass again. To fix the verify
command of an unfinished task, send only updateTasks: [{"key", "verify", "paths"?}]: no requirement, evidence, or intake is needed, and Prove reruns
that task’s evidence. change amend --template prints both forms. Legacy changes retain their
compatible manual path. A version-4 amendment must include discovery coverage
for its added requirements; the validated delta is appended to proposal.md.
Before mutation, the harness records the affected claims, tasks, and
dependency-closed provider set as bounded input for proof scheduling. It
preserves only passing unaffected receipts whose declared provider, claim, and
input fingerprints remain exact; affected or ambiguous bindings rerun through
the returned Prove route.
A successful /change is already validated and isolated. Continue with
claude-foundation advance <change> --through build.