Skip to content

/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.

  1. Say what you want, including constraints and things you do not want.
  2. 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.
  3. Read the approval summary (see Approval) and approve in your own words, for example “go ahead”. Silence or urgency alone is not approval.
  4. 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).

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.

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 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.

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 headings

proposal.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”.

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”.

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”.

Add complexity only when the work needs it:

  • multiple requirements with separate capability and operation values
  • dev document sections: summary, userFlow (Mermaid), failureMatrix, componentMap, apiContracts, dataModel, uiStates, configContract, jobContract, bugfix, or refactor. The harness infers workType from 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: why satisfies the summary (add summary only for more), and without an authored failureMatrix the scenarios with "kind": "failure" become its rows, with an optional scenario recovery for the recovery column. A task whose own tests sit outside its paths is a design warning
  • decisions for load-bearing choices, each with its consequences
  • Mermaid or referenced SVG/PNG diagrams
  • prototypeSelection pointing at an existing selection note
  • integrations with documentation source/version, linked requirements, and security/resilience/compatibility concerns; related scenarios explicitly use "kind": "success" and "kind": "failure"
  • repositories for multi-repository scope, with each task’s repository; 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.

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.

To change an agreed change before Build starts, revise the same change instead of abandoning it:

Terminal window
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.

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:

Terminal window
claude-foundation change amend <change> <amendment.json> --consume-amendment

It 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.