Skip to content

Frontmatter reference

The exhaustive field contract of every document kind: which properties are allowed, which are required, and what values they accept.

Artifacts defines what each artifact type means and why it exists; this chapter defines the fields. Where the two appear to disagree, the JSON Schemas under schemas/ win — the tables below are generated from them (pnpm docs:frontmatter) and a conformance test fails the build if they drift.

Every kind is a closed object: an unknown property is a PRODUCT002 error, not a warning and not silently ignored. There is no extension point. If you need to record something the schema does not allow, put it in the Markdown body.

Conforming implementations SHOULD expose this contract programmatically (for example as a schema query command), so it can be inspected without a repository.

ColumnMeaning
FieldThe YAML key. a.b is a nested key; a[] is an array element, and a[].b a key of an element object.
RequiredWhether the key must be present. For a nested key, whether it is required when its parent is present.
Typestring, const (one permitted value), enum, array, object.
Allowed valuesThe permitted values, or the regular expression a string must match.
NotesConstraints and guidance carried by the schema itself.

Four fields are common to every Markdown-authored kind: id (stable and immutable, see Identifiers), type, title and status. Artifact status is draft | active | deprecated | retired; Product Changes and Delivery Slices have their own lifecycles.

provenance is an optional object accepted by all nine artifact kinds. It records the evidence behind recovered knowledge: where a claim came from and how strongly the evidence supports it.

Set it on recovered (brownfield) artifacts. Leave it unset on greenfield artifacts authored from intent — there is no evidence to cite, and an empty claim of provenance is worse than none.

Provenance is deliberately not authorship metadata. Artifacts forbids author, owner, date, version and review fields because Git history already records who changed what and when. Provenance answers a different question: how far to trust this artifact’s content.

A draft artifact whose provenance.confidence is low produces a PRODUCT111 warning, so the queue of candidates needing human validation is derivable from validation output rather than tracked by hand.

FieldRequiredAllowed valuesMeaning
sourceyesfree textA file path, a URL, a ticket reference, or interview: <person>.
confidenceyeshigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
recovered-fromnoobservation, inference, interview, documentationHow the knowledge was recovered. Optional, because real evidence is often more than one of these.
provenance:
source: src/orders/validation.ts (limit check), tests/orders/limits.spec.ts
confidence: high
recovered-from: observation

provenance itself is closed: an unrecognised sub-field such as recovered-by is a PRODUCT002 error, and omitting confidence while providing source is too.


The nine artifact types of the current product model.

ACT-. Who or what interacts with the product to achieve a meaningful outcome. See Artifacts → Actor.

FieldRequiredTypeAllowed valuesNotes
idyesstring^ACT-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstactor
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
actor-kindyesenumhuman, external-system, scheduled-process, product
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

JRN-. An end-to-end outcome pursued by an actor. steps defines the main ordered path only; branches and exceptional paths belong in the body. See Artifacts → Journey.

FieldRequiredTypeAllowed valuesNotes
idyesstring^JRN-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstjourney
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
primary-actoryesstring^ACT-[A-Z0-9]+(-[A-Z0-9]+)*$
stepsyesarray of objectThe main ordered journey. Branches and exceptional paths belong in the body. At least one entry.
steps[].use-caseyesstring^UC-[A-Z0-9]+(-[A-Z0-9]+)*$
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

UC-. A concrete interaction through which an actor obtains a product outcome. See Artifacts → Use Case.

FieldRequiredTypeAllowed valuesNotes
idyesstring^UC-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstuse-case
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
primary-actoryesstring^ACT-[A-Z0-9]+(-[A-Z0-9]+)*$
supporting-actorsnoarray of string
supporting-actors[]yesstring^ACT-[A-Z0-9]+(-[A-Z0-9]+)*$
bounded-contextnostring^BC-[A-Z0-9]+(-[A-Z0-9]+)*$
governed-bynoarray of string
governed-by[]yesstring^BR-[A-Z0-9]+(-[A-Z0-9]+)*$
uses-termsnoarray of string
uses-terms[]yesstring^TERM-[A-Z0-9]+(-[A-Z0-9]+)*$
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

BR-. Durable product knowledge that governs behaviour. See Artifacts → Business Rule.

FieldRequiredTypeAllowed valuesNotes
idyesstring^BR-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstbusiness-rule
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
applies-tonoarray of string
applies-to[]yesstring^(JRN|UC|BC)-[A-Z0-9]+(-[A-Z0-9]+)*$A journey, use case or bounded context.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

TERM-. Shared meaning within a bounded context. Ownership is authored here, on the term, and never on the context. See Artifacts → Domain Term.

FieldRequiredTypeAllowed valuesNotes
idyesstring^TERM-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstdomain-term
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
defined-inyesstring^BC-[A-Z0-9]+(-[A-Z0-9]+)*$Canonical direction of term ownership. Bounded contexts never author owns-terms.
synonymsnoarray of string
synonyms[]yesstringMust not be empty.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

BC-. A product-language boundary. Note the absence of owns-terms: term ownership is derived from Domain Term.defined-in and MUST NOT be authored here (see Relationships). See Artifacts → Bounded Context.

FieldRequiredTypeAllowed valuesNotes
idyesstring^BC-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstbounded-context
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

FR-. A derived product obligation stating what the product must do. derived-from is what keeps it traceable to the knowledge it came from. See Artifacts → Functional Requirement.

FieldRequiredTypeAllowed valuesNotes
idyesstring^FR-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstfunctional-requirement
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
derived-fromyesarray of stringTraceability to the use cases, business rules or constraints this requirement originates from. At least one entry.
derived-from[]yesstring^(UC|BR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$
verificationyesarray of objectAt least one entry.
verification[].scenarioyesstringMust not be empty.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

QR-. A measurable quality obligation. See Artifacts → Quality Requirement.

FieldRequiredTypeAllowed valuesNotes
idyesstring^QR-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstquality-requirement
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
quality-attributeyesstringMust not be empty.
applies-toyesarray of stringAt least one entry.
applies-to[]yesstring^(JRN|UC|BC)-[A-Z0-9]+(-[A-Z0-9]+)*$A journey, use case or bounded context.
verificationyesarray of objectAt least one entry.
verification[].scenarioyesstringMust not be empty.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

CON-. An externally imposed or deliberately fixed boundary. When applies-to is absent the constraint applies to the entire product. See Artifacts → Constraint.

FieldRequiredTypeAllowed valuesNotes
idyesstring^CON-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstconstraint
titleyesstringMust not be empty.
statusyesenumdraft, active, deprecated, retiredLifecycle of a product artifact.
applies-tonoarray of string
applies-to[]yesstring^(JRN|UC|BC)-[A-Z0-9]+(-[A-Z0-9]+)*$A journey, use case or bounded context.
provenancenoobjectEvidence behind recovered knowledge. Set on recovered (brownfield) artifacts only.
provenance.sourceyesstringWhere the knowledge came from: a file path, a URL, a ticket reference, or ‘interview: ’. Must not be empty.
provenance.confidenceyesenumhigh, medium, lowhigh: read directly from a specification scenario or a test. medium: inferred from structured prose. low: inferred from indirect evidence such as a variable name.
provenance.recovered-fromnoenumobservation, inference, interview, documentationHow the knowledge was recovered from the evidence.

CHG-. The Markdown-authored definition of a proposed change to the baseline. Authored by hand and validated through the same schema path as the artifacts. Semantics, lifecycle and overlay rules are in Product Changes.

Note that provenance is not accepted here. A recovery change carries provenance on its proposed artifacts, which are ordinary artifact documents, not on the change itself.

FieldRequiredTypeAllowed valuesNotes
idyesstring^CHG-[A-Z0-9]+(-[A-Z0-9]+)*$
typeyesconstproduct-change
titleyesstringMust not be empty.
statusyesenumdraft, proposed, approved, in-progress, implemented, rejected, supersededLifecycle of a product change.
base-revisionyesstring^[0-9a-f]{7,40}$The baseline Git revision this change was created against.
operationsyesobject
operations.addyesarray of string
operations.add[]yesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.
operations.modifyyesarray of string
operations.modify[]yesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.
operations.removeyesarray of string
operations.remove[]yesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.

Three YAML document kinds complete the change and handoff flow. Their normative semantics live in Delivery Slices and the Handoff Contract; the tables below are the field index.

SLI-. Authored by hand (or proposed by the slicing skill) under a change’s slices/ directory. implements declares coverage per requirement; scope becomes required when coverage is partial. See Delivery Slices.

FieldRequiredTypeAllowed valuesNotes
schemayesconstproduct-definition-as-code/delivery-slice/v1alpha1
idyesstring^SLI-[A-Z0-9]+(-[A-Z0-9]+)*$
titleyesstringMust not be empty.
statusyesenumdraft, proposed, approved, in-progress, completed, cancelledLifecycle of a delivery slice.
product-changeyesstring^CHG-[A-Z0-9]+(-[A-Z0-9]+)*$
outcomeyesstringMust not be empty.
implementsyesarray of objectAt least one entry.
implements[].requirementyesstring^(FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$A functional requirement, quality requirement or constraint.
implements[].coverageyesenumfull, partial
implements[].scopenostringRequired when coverage is partial: the precise part of the requirement this slice covers. Must not be empty.
affectsnoarray of string
affects[]yesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.
depends-onnoarray of string
depends-on[]yesstring^SLI-[A-Z0-9]+(-[A-Z0-9]+)*$
verificationyesarray of stringAt least one entry.
verification[]yesstringMust not be empty.
out-of-scopenoarray of string
out-of-scope[]yesstringMust not be empty.

HOF-. Generated, never authored by hand. A conforming implementation produces it and reports its staleness. Documented here so the contract is inspectable. See Handoff Contract.

FieldRequiredTypeAllowed valuesNotes
schemayesconstproduct-definition-as-code/handoff/v1alpha1
idyesstring^HOF-[A-Z0-9]+(-[A-Z0-9]+)*$
generated-atyesstring
work-itemyesobject
work-item.provideryesstringMust not be empty.
work-item.repositoryyesstringMust not be empty.
work-item.idyesstringMust not be empty.
work-item.titleyesstringMust not be empty.
sourceyesobject
source.repositoryyesstringMust not be empty.
source.revisionyesstring^[0-9a-f]{7,40}$
source.product-changeyesstring^CHG-[A-Z0-9]+(-[A-Z0-9]+)*$
source.delivery-sliceyesstring^SLI-[A-Z0-9]+(-[A-Z0-9]+)*$
implementsyesarray of stringAt least one entry.
implements[]yesstring^(FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$A functional requirement, quality requirement or constraint.
affectsyesarray of string
affects[]yesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.
artifactsyesarray of objectAt least one entry.
artifacts[].idyesstring^(ACT|JRN|UC|BR|TERM|BC|FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$Any artifact of the current product model.
artifacts[].typeyesenumactor, journey, use-case, business-rule, domain-term, bounded-context, functional-requirement, quality-requirement, constraint
artifacts[].pathyesstringMust not be empty.
artifacts[].digestyesstring^sha256:[0-9a-f]{64}$SHA-256 over UTF-8 content with line endings normalized to LF.
contextyesobject
context.pathyesstringMust not be empty.
context.digestyesstring^sha256:[0-9a-f]{64}$SHA-256 over UTF-8 content with line endings normalized to LF.

Adapter-owned. Written alongside an SDD change to evidence that a slice’s requirements were implemented, and checked before archive. See Adopting in an existing OpenSpec repository.

FieldRequiredTypeAllowed valuesNotes
schemayesconstproduct-definition-as-code/coverage/v1alpha1
handoffyesstring^HOF-[A-Z0-9]+(-[A-Z0-9]+)*$
requirementsyesobjectKeys match ^(FR|QR|CON)-[A-Z0-9]+(-[A-Z0-9]+)*$. At least one key.
requirements.<key>noobject
requirements.<key>.statusyesenumcovered, partial, uncovered
requirements.<key>.specificationnoarray of stringRequired when status is covered or partial. At least one entry.
requirements.<key>.specification[]yesstringMust not be empty.
requirements.<key>.verificationnoarray of stringRequired when status is covered or partial. At least one entry.
requirements.<key>.verification[]yesstringMust not be empty.