Source code is one implementation of an idea.
SPEC.md is the transferable expression of the idea itself.
SPEC.md Core is the minimal self-contained standard for creating and maintaining a conforming SPEC.md.
A SPEC.md captures implementation-independent behavior, rules, constraints, and design semantics that must survive across implementations.
A human or LLM should be able to implement the design from SPEC.md without the original codebase, hidden project history, or this Core document.
Use SPEC.md Optional only when extra rigor materially improves clarity, portability, implementation, or verification.
SPEC.md captures design decisions; it does not complete the design.
Do not turn assumptions, common practice, or likely future needs into requirements.
A SPEC.md SHOULD begin with a short contract containing these rules:
TBD or Open Issue, not guessed.Use TBD or an Open Issue when the current design depends on an unresolved decision.
Do not create future Open Issues merely because a decision may become relevant later.
A conforming SPEC.md uses:
Define, as applicable:
Define only terms whose meaning matters for correct implementation. Use one canonical term per concept in normative text. Prefer standard representations where ambiguity could arise:
. separator, no grouping separator;null, absent, empty string, empty collection, zero, and false are distinct unless explicitly stated otherwise.Describe behaviorally significant structure and behavior. As applicable, include:
Requirements SHOULD be:
FUN-001, DATA-001, AUTH-001, SEC-001, INT-001.
IDs SHOULD remain stable when requirements move. Retired IDs SHOULD NOT be reused.
Section numbers express location; requirement IDs express identity.Note: Stable IDs may also identify non-requirement elements such as behavioral flows. An ID alone does not make an element normative. When traceability is used, TRACE coverage follows normative obligations, not every label in the document.
A specification MUST be internally consistent as a whole. Requirements, invariants, models, contracts, and acceptance criteria MUST NOT prescribe incompatible behavior. References to requirements, flows, states, entities, or contracts MUST be accurate. Informative diagrams and examples SHOULD remain consistent with normative prose. Distinguish:
For important external systems, specify enough for independent interoperability:
A non-goal says what the spec does not require. It does not forbid an implementation from doing more unless that is explicitly required. State important constraints and intentional exclusions explicitly. A deliberate non-feature belongs here rather than being left to inference. Avoid implementation constraints unless the implementation choice itself is part of the required design.
Important requirements SHOULD have a clear way to verify them. When requirement IDs are used, verification SHOULD reference the IDs it checks. Verification MAY use Test, Analysis, Inspection, or Demonstration. Given / When / Then MAY be used for readable acceptance criteria and need not be executable Gherkin. When multiple requirements jointly determine an observable outcome, verification SHOULD test the combined behavior, not only each requirement in isolation.
This section is informative by default and MAY contain rationale, history, alternatives, limitations, future considerations, or implementation guidance. Do not hide requirements inside rationale.
Use MAJOR.MINOR.PATCH.
spec_version are independent.SPEC.md MAY begin nearly empty and grow with the design. If missing, create frontmatter, a Specification Contract, and the eight Core sections. Whenever behavior is implemented, changed, or decided, update SPEC.md in the same change. Do not defer behavior documentation until the end. If material behavior is genuinely undecided:
TBD / Open Issue;A small design SHOULD remain one file when practical.
A larger design MAY use a root SPEC.md plus directly referenced normative modules.
The root remains the canonical entry point, MUST identify every normative module, and owns the set version unless stated otherwise.
A module MAY refine a rule within its scope but MUST NOT silently contradict a global requirement.
Any normative module change participates in the root spec_version bump.
Give SPEC.md to a competent unfamiliar human or LLM with only:
Implement the system/design defined in SPEC.md. They should proceed without asking how the original implementation works. If not, the specification is incomplete, ambiguous, or too implementation-dependent.
SPEC.md MAY contain comments intended only for human maintainers.
Use:
<!-- SPECMD-HUMAN-ONLY
Human drafting or review note.
SPECMD-END-HUMAN-ONLY -->
Human-only comments are not part of the specification, MUST NOT influence implementation or conformance, and MUST NOT contain required implementation or verification information. Tooling SHOULD remove them before supplying SPEC.md to an LLM.
Use SPEC.md Optional only when useful.
Possible extensions include EARS, ERDs/diagrams, advanced modularization, integration detail, monitoring/audit/operations, DESIGN.md, TASKS.md, TRACE.md, implementation guidance, and tooling.
Use an optional feature when it reduces ambiguity, improves portability, or makes the design easier to implement or verify. Omit it when it adds ceremony without improving the design.
A good SPEC.md is:
---
specmd: "0.4.3"
spec_version: "0.1.0"
status: draft
name: "<design name>"
last_updated: "YYYY-MM-DD"
---
Add metadata only when it materially helps.