A quick reference for every reqmd command and every schema.yaml option. Each command shows real output from the bundled spec/ or quickstart/ trees. Bookmark this page.

Command overview#

The main command. Recursively finds all schema.yaml files under the given directory and validates every .md file with requirement attr blocks.

reqmd check spec/                          # validate everything under spec/
reqmd check spec/ --json                   # JSON output for CI parsing
reqmd check spec/ --results ci-out/        # load verification results
reqmd check spec/ --results ci-out/ --results reviews/
reqmd check file.md -s schema.yaml         # single-file mode
reqmd check spec/ --relaxed-versions       # demote version-pin errors to warnings
reqmd check spec/ --filter '"Premium" in variant'   # only matching requirements
reqmd check spec/ --disjoint-check variant # error on cross-configuration trace links

Exit codes: 0 = all valid, 1 = validation errors, 2 = parse error.

Checks run: schema validation, broken references, circular dependencies, missing coverage (requires-trace-from), version-pin staleness, missing verdict, failing verdict, disjoint attributes (--disjoint-check).

Verification results: CTRF extra.x-reqmd supports id (bind directly to a measure), case (stable case identity), verifies (requirements a synthesized test case exercises) and description (case body). Verdicts roll up strictly over a measure’s own results plus its approved downstream test cases (any fail → fail, else inconclusive → inconclusive, else skipped → skipped, else pass); deferred/rejected measures are skipped. Uninstrumented tests are skipped silently; a test that declares x-reqmd but binds nothing warns as unbound-result (suppress with --ignore-unbound-results). Result-attributed findings appear in the Verification results section / JSON results array.

Filters: --filter "<expr>" scopes the check to requirements matching an expr-lang expression (see Filter expressions). Coverage is computed within the filtered subset, so a filtered-out requirement can neither require nor provide coverage. --disjoint-check <attr> verifies that every trace link has at least one overlapping value for the named array attribute (zero intersection → ERROR). With --json, the summary gains a "filter" field recording the active expression.

Example output (reqmd check quickstart/02-trace-your-spec/)
=
Schema : software-requirements — Software Requirements
File   : quickstart/02-trace-your-spec/software  (1 requirements)
=
  ✅  SW-001  all attributes valid

=
Schema : stakeholder-goals — Stakeholder Goals
File   : quickstart/02-trace-your-spec/stakeholder  (1 requirements)
=
  ✅  STK-GOAL-001  all attributes valid

=
Schema : system-requirements — System Requirements
File   : quickstart/02-trace-your-spec/system  (1 requirements)
=
  ⚠  SYS-001  attributes valid (see trace checks below)
  ⚠  SYS-001  no upstream trace: no approved requirement from "software" traces to this item (1 draft downstreams ignored)

=
Schema : test-specs — Test Specifications
File   : quickstart/02-trace-your-spec/tests  (2 requirements)
=
  ✅  TEST-001  all attributes valid
  ✅  TEST-002  all attributes valid

Summary: 5 total, 5 valid, 0 invalid, 0 parse errors, 1 warnings
Example JSON output (reqmd check --json quickstart/02-trace-your-spec/)
{
  "documents": [
    {
      "path": "quickstart/02-trace-your-spec/software",
      "schema_title": "software-requirements — Software Requirements",
      "requirements": [
        {
          "id": "SW-001",
          "valid": true
        }
      ],
      "req_count": 1
    },
    {
      "path": "quickstart/02-trace-your-spec/system",
      "schema_title": "system-requirements — System Requirements",
      "requirements": [
        {
          "id": "SYS-001",
          "checks": [
            {
              "level": "WARNING",
              "source": "quickstart/02-trace-your-spec/system/features.md",
              "message": "no upstream trace: no approved requirement from \"software\" traces to this item (1 draft downstreams ignored)"
            }
          ],
          "valid": true
        }
      ],
      "req_count": 1
    }
  ],
  "parse_errors": [],
  "summary": {
    "total": 5,
    "valid": 5,
    "invalid": 0,
    "parse_errors": 0,
    "warnings": 1
  },
  "version": 1,
  "exit_code": 0
}

reqmd ls — list all content#

Prints a table of every node in document order, with a leading Type column (req / container / info). Requirements show all schema attributes; containers and info items show their heading text.

reqmd ls spec/                # table output
reqmd ls spec/ --json         # JSON output (rows array with a type field)
reqmd ls spec/ --filter '"Premium" in variant'   # only matching requirements (items always shown)
Example output
=== spec/02-system ===
Type       | ID                       | priority     | trace        | disposition  | disposition-reason | requires-trace-from | version      | status       |
-------------------------------------------------------------------------------------------------------------------------------------------------
req        | SYS-FMT-001: Markdown requirement format | Critical     | ["STK-GOAL-001","ASP-SR-001","ASP-SR-003","ASP-SR-020"] |              |              |              |              | approved     |
req        | SYS-FMT-002: Built-in attribute system | Critical     | ["STK-GOAL-002","ASP-SR-007","ASP-SR-013"] |              |              |              |              | approved     |
req        | SYS-FMT-003: Schema.yaml document configuration | Critical     | ["STK-GOAL-003","ASP-SR-002","ASP-SR-009","ASP-SR-015"] |              |              |              |              | approved     |
... (19 requirements total)

reqmd stats — attribute-value breakdown per document#

Shows how many requirements have each attribute value, grouped by document directory, plus item counts and a type breakdown.

reqmd stats spec/             # table output
reqmd stats spec/ --json      # JSON output
reqmd stats spec/ --filter 'priority == "Critical"'   # scope to matching requirements
Example output
Requirements: 19
Documents:    1

=== spec/02-system (19 reqs) ===
  priority:
    Critical             6
    High                 8
    Medium               5
  status:
    approved             19

reqmd init — scaffold a new project#

Creates a directory with schema.yaml and an example .md file.

reqmd init my-project/                              # generic template (default)
reqmd init my-project/ --preset aspice --id-prefix REQ  # ASPICE-oriented template with safety attributes
reqmd init my-project/ --preset results --id-prefix VR  # manual verification results template
reqmd init my-project/ --preset ./my-preset/        # custom preset directory
reqmd init my-project/ --id-prefix REQ --title "My Requirements"
reqmd init my-project/ --force                      # overwrite existing

Built-in presets: generic (default), aspice (ASPICE-oriented with safety attributes), results (manual verification results).

Example output
Initialized generic requirements in /tmp/my-project/
  /tmp/my-project/schema.yaml
  /tmp/my-project/requirements.md
Run: reqmd check /tmp/my-project/

Generated schema.yaml:

x-reqmd:
  level: "requirements"
  id-prefix: REQ
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "my-project"
title: "my-project Requirements"
type: object
properties:
  owner:
    type: string
    description: "Responsible person or team"
additionalProperties: false

Generated requirements.md (excerpt):

## REQ-001
```attr
status: draft
owner: Team Alpha
```
The system shall provide a login mechanism.

*Rationale: Authentication is required for secure access.*

Flags:

FlagDescription
--preset <name|dir>Built-in preset name or path to a custom preset directory
--id-prefix <prefix>ID prefix for requirements (e.g. SYS-, REQ-)
--id <id>Schema $id (default: directory basename)
--title <title>Schema title (default: <dir> Requirements)
--level <level>x-reqmd.level value (default: requirements)
--forceOverwrite existing files

reqmd serve — live-reloading HTML preview#

Watches the spec tree and serves a live HTML preview via HTTP. Re-parses, re-checks, and re-exports on every file change. The browser auto-reloads via Server-Sent Events.

reqmd serve spec/                           # default: localhost:8080
reqmd serve spec/ --addr :9090              # custom port
reqmd serve spec/ --no-open                 # don't auto-open browser
reqmd serve spec/ --headless                # terminal-only, no HTTP server
reqmd serve spec/ --results tests/ --results reviews/
reqmd serve spec/ --filter '"Sport" in variant'   # preview one configuration
Example output
reqmd serve spec/
  serving http://localhost:8080
  watching spec/ ...
  initial build: 281 reqs, 22 docs
  file changed: spec/02-system/features.md
  rebuilt: 281 reqs (48ms)
  file changed: spec/02-system/schema.yaml
  rebuilt: 281 reqs (52ms)
FlagDescription
--addr <addr>HTTP server address (default: localhost:8080)
--results <path>Load verification results (repeatable). Also watched for changes.
--no-openDon’t open a browser on start
--headlessTerminal-only mode (no HTTP server)
--debounce <dur>Debounce window for file events (default: 500ms)
--filter <expr>Serve only requirements matching an expr-lang expression

reqmd export csv — export to CSV#

One CSV file per document directory (<dirname>-requirements.csv).

reqmd export csv spec/ -o csv-out/
reqmd export csv spec/ -o csv-out/ --results ci-out/
reqmd export csv spec/ -o csv-out/ --filter '"Premium" in variant'

With --results, adds Verdict and Verdict Source columns.

Example output
Wrote csv-out/00-aspice-requirements.csv
Wrote csv-out/01-stakeholder-requirements.csv
Wrote csv-out/01a-aspice-stakeholder-requirements.csv
Wrote csv-out/02-system-requirements.csv
...
Wrote csv-out/03-software-requirements.csv
Wrote csv-out/04-tests-requirements.csv

22 CSV files, one per document (the bundled spec/ tree: 1337 requirements,
including the generated code-proxy documents)

Each CSV has columns: Type, ID, Title, <schema attributes>, Body, Rationale. Rows are emitted in document order for every node — requirements and containers/info items alike.

reqmd export html — export to HTML#

A project home (index.html) plus one standalone HTML file per document, with a server-rendered Document view plus on-demand Table, Trace, and Coverage views, a compact sticky app bar, trace links, and a ⌘K command palette.

reqmd export html spec/ -o html-out/
reqmd export html spec/ -o html-out/ --results ci-out/ --results reviews/
reqmd export html spec/ -o html-out/ --filter '"Sport" in variant'

With --results, renders color-coded verdict badges (pass/fail/skipped/inconclusive) on measure cards.

Example output
exporting spec/ → html-out/
  spec/02-system  → html-out/system-requirements.html
  spec/03-software → html-out/software-requirements.html
  spec/04-tests   → html-out/tests-requirements.html
  ...
  22 documents exported
  html-out/index.html

Every page is fully standalone — the stylesheet and client controller are embedded, so there is no network access and no CDN — with a server-rendered Document view that stays readable without JavaScript:

  • Document — requirement cards with status/coverage/verdict chips, a collapsible detail block (attributes, rationale, evidence, traces), collapsible container sections and info blocks, and the document chain.
  • Table — a dense sortable grid with a column chooser, type-aware sorting, and expandable rows that reuse the server-rendered card content.
  • Trace — a selected-requirement explorer with upstream and downstream neighbourhoods (click any node to recenter) and a size-bounded full matrix.
  • Coverage — expected versus actual coverage, the verification rollup with no verdict in the denominator, link health, and exception lists that filter the other views.

index.html adds a document catalog, project-wide health, and cross-document search. A ⌘K command palette, keyboard shortcuts (/ search, g d/g t/g r/g c views, t theme, f density, ? help), a density toggle, and URL-synced state (?q=&f=attr:value&view=&density=) make a filtered view bookmarked or shared.

The toolbar’s attribute menus are built from every attribute present on a requirement, so attributes declared in no schema.yaml are filterable too (and show up in the cards and table marked as undeclared).

See a live HTML export → (from the reqmd project’s own spec) · project home →

reqmd export json — export NDJSON tables for reporting platforms#

Writes the whole tree as four flat NDJSON (newline-delimited JSON) files, one JSON object per line, for warehouses and reporting platforms (Databricks, Snowflake, BigQuery) to ingest directly. No connector, no SDK, no credentials.

The output is a pure function of the tree plus any --results, so two exports of the same tree are byte-identical.

reqmd export json spec/ -o json-out/
reqmd export json spec/ -o json-out/ --results ci-out/ --results reviews/
reqmd export json spec/ -o json-out/ --filter '"Premium" in variant'
FileRow grain
requirements.ndjsonone row per content node (req / container / info)
traces.ndjsonone row per declared trace: reference
results.ndjsonone row per measure verdict (only with --results)
findings.ndjsonone row per check finding (ERROR and WARNING)
Example rows
{"doc_path":"spec/02-system","doc_title":"System Features","level":"system-requirements","id":"SYS-001","title":"Boot Sequence","type":"req","status":"approved","trace":["stakeholder/STK-GOAL-001"],"attrs":{"priority":"High"}}
{"from":"SYS-001","to":"STK-GOAL-001","doc_id":"stakeholder","ref":"stakeholder/STK-GOAL-001","file":"spec/02-system/features.md","pin":null,"resolved":true}
{"measure_id":"TEST-002","outcome":"pass","source":"reviews/VR-001.md","verify":"Review"}
{"level":"WARNING","req_id":"SYS-001","code":"missing-verdict","file":"spec/02-system/features.md","message":"missing verdict: ..."}

Built-in attributes (trace, requires-trace-from, status, disposition, version, verify) are promoted to top-level keys for direct SQL; the remaining declared attributes stay in the attrs envelope with their native JSON types (arrays stay arrays). Every fixed key is present in every row (null when unset), so warehouse schema inference sees the full column set regardless of which row it samples. A dangling trace ref is written to traces.ndjson with "resolved":false and to findings.ndjson, so a warehouse can count or filter it on its own terms.

FlagDescription
-o, --output <dir>Output directory (default: the exported tree root)
--results <path>Load verification results for results.ndjson (repeatable)
--filter <expr>Limit requirements.ndjson to matching requirements
--disjoint-check <attr>Also reported in findings.ndjson (repeatable)

reqmd export graph — export to LadybugDB graph#

Creates a graph database with one node per requirement and TracesTo edges. Requires the ladybug build tag.

go build -tags ladybug -o reqmd ./cmd/reqmd
reqmd export graph spec/ -o graph-out/
Example output
exporting spec/ → graph-out/reqmd-graph.lbug
  281 nodes, one TracesTo edge per trace link
  done

Query with the lbug CLI: lbug graph-out/reqmd-graph.lbug

reqmd baseline diff — compare two git tags#

Extracts the spec tree at each tag (no checkout), parses both, and produces a semantic diff.

reqmd baseline diff v1.0 v2.0
reqmd baseline diff v1.0 v2.0 --json
reqmd baseline diff HEAD~10 HEAD
reqmd baseline diff v1.0 v2.0 --filter '"Base" in variant'   # one configuration across two tags
reqmd baseline diff --filter-a 'variant == nil or "Base" in variant' \
                    --filter-b '"Premium" in variant' HEAD    # two views of one commit

With --filter, both snapshots are scoped to matching requirements before diffing. With --filter-a/--filter-b (used together, mutually exclusive with --filter), a single snapshot at the given ref (default HEAD) is compared two ways — the “what does Premium add over Base” report from one commit. --filter-a and --filter-b are required together.

Reports added, removed, and modified requirements (with attribute-level detail), schema changes, and submodule pin changes. Always exits 0.

Example output
Requirements
  + IVI-FUN-004  added in v2.0
  - IVI-FUN-002  removed in v2.0
  ~ IVI-FUN-001
      priority: medium -> high
      trace: ["SYS-001"] -> ["SYS-001","SAFE-003"]

Schemas
  ~ ivi-requirements
      + property: owner
      - property: priority
      required: ["priority","maturity","status","verify"] -> ["maturity","status","verify","owner"]

--- Submodule Changes ---
  vendor/spec-a: a1b2c3d -> e4f5g6h (updated)

reqmd repin — update version pins#

Updates ~N version pins in trace references to match the upstream’s current version. Dry-run by default; pass --yes to apply.

reqmd repin spec/                                    # dry-run: list proposed changes
reqmd repin spec/ --yes                              # apply changes
reqmd repin spec/ --yes --promote-unpinned           # also pin refs with no ~N
reqmd repin spec/ --json                             # machine-readable output

Rewrites only the attr blocks; surrounding Markdown is preserved. Idempotent — a second run after the first reports no changes. Predated pins (pin > upstream version) are surfaced but never auto-fixed.

Example output

Dry-run (default):

spec/03-software/dn.md  DN-001  UP-001 → UP-001~3
spec/03-software/dn.md  DN-002  UP-002 → UP-002~7
2 outdated, 0 unpinned, 0 predated across 1 files.

Apply:

spec/03-software/dn.md  DN-001  UP-001 → UP-001~3
spec/03-software/dn.md  DN-002  UP-002 → UP-002~7
2 outdated, 0 unpinned, 0 predated across 1 files.
Apply 2 changes across 1 files? [y/N] y
applied 2 changes across 1 files

No changes needed:

no version-pin changes needed
FlagDescription
--yes, -yApply changes without prompting
--jsonOutput as JSON
--promote-unpinnedAlso pin trace refs that have no ~N against a versioned upstream
--dry-runPrint the change list without applying (default; implicit when --yes is absent)

Filter expressions#

--filter "<expr>" is available on check, ls, stats, export csv, export html, export json, serve, and baseline diff. The expression is evaluated against each requirement’s attributes (plus the built-ins id, title, status, disposition, trace, version), and the command runs only on matching requirements. It’s the generic primitive behind variant management — the same flag slices by variant, platform, region, priority, or any other attribute.

ExpressionMatches
"Premium" in variantRequirements tagged Premium (array membership)
variant == nilRequirements with no variant attribute — “common to all”
"Premium" in variant or variant == nilThe whole Premium configuration (Premium-specific plus common)
status == "approved"Approved requirements
version > 3Requirements with version greater than 3
id startsWith "SYS-"Requirements whose ID starts with SYS-
title contains "boot"Requirements whose title contains “boot”
"Base" in variant and "Premium" in variantMulti-configuration requirements
not "Sport" in variantEverything except Sport-tagged

Rules:

  • The engine is expr-lang; supported operators include ==, !=, <, >, <=, >=, in, and, or, not, contains, startsWith, endsWith.
  • A filter referencing an attribute not declared in any schema.yaml is a compile-time ERROR (fails fast on typos, before any requirement is evaluated). Add --relaxed-filter to downgrade that to a warning; it also allows any attribute actually present on a requirement.
  • A filter with invalid syntax is a compile-time ERROR, reported once.
  • A requirement lacking a referenced attribute evaluates that variable to nil and is excluded unless the expression handles absence (e.g. variant == nil).
  • The --json summary includes the active expression in a "filter" field.

Filter-aware coverage: with --filter, coverage (requires-trace-from) is computed within the filtered subset — a filtered-out requirement can neither require nor provide coverage, so per-configuration checks don’t produce false “missing coverage” failures.

Disjoint-attribute check: --disjoint-check <attr> verifies that every trace link has at least one overlapping value for the named array attribute. Zero intersection → ERROR; empty/absent value = “applies to all” (exempt). Enable via CLI flag (repeatable) or x-reqmd.disjoint-check in schema.yaml.

All commands at a glance#

CommandWhat it doesKey flags
check <dir>Validate + trace checks--json, --results, --relaxed-versions, --filter, --disjoint-check, --ignore-unbound-results, -s
ls <dir>List all requirements--json, --filter
stats <dir>Stats per document--json, --filter
init <dir>Scaffold a new project--preset, --id-prefix, --force
serve <dir>Live HTML preview--addr, --results, --headless, --filter
export csv <dir>CSV export-o, --results, --filter
export html <dir>HTML export-o, --results, --filter
export json <dir>NDJSON tables for reporting platforms-o, --results, --filter, --disjoint-check
export graph <dir>Graph export (ladybug tag)-o
baseline diff <t1> <t2>Compare two git tags--json, --filter, --filter-a, --filter-b
repin <dir>Update version pins to upstream’s current version--yes, --json, --promote-unpinned

The schema.yaml file#

Every document directory has a schema.yaml that defines what attributes a requirement must have. It’s a standard JSON Schema 2020-12 file in YAML, plus a x-reqmd extension block for reqmd-specific options.

Full example#

$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "my-system-requirements"
title: "System Requirements"
type: object
required:
  - priority
  - verify
properties:
  priority:
    type: string
    enum: [Critical, High, Medium, Low]
  verify:
    type: string
    enum: [Test, Review, Inspection, Analysis, Demonstration]
  status:
    type: string
    enum: [draft, approved]
  trace:
    type: array
    items:
      type: string
  version:
    type: integer
additionalProperties: false

x-reqmd:
  level: system-requirements
  document-id: system
  id-prefix: SYS-
  requires-trace-from: [software-requirements]
  upstream:
    level: stakeholder-needs
    sources:
      - ../01-stakeholder/
  mandatory-disposition: true
  external: false

x-reqmd options#

OptionTypeDescription
levelstringA label naming this document’s V-model layer (e.g. stakeholder-needs, system-requirements, software-requirements, test-specs). Free-form string. Only functional use: a requires-trace-from token may name a level instead of a document-id; reqmd resolves it to every directory declaring that level. Not used for HTML chain navigation or boundary inference (those use upstream.sources). See the FAQ.
document-idstringA short identifier for this document directory (e.g. system, stakeholder, tests). Used in qualified references (document-id/ID) and as a requires-trace-from token.
id-prefixstringThe ID prefix for requirements in this directory (e.g. SYS-, STK-GOAL-, TST-). Requirements get IDs like SYS-001, SYS-002.
upstreamobjectDeclares which document directories are valid upstream sources for trace links.
upstream.levelstringThe x-reqmd.level of the expected upstream. Informational only — never read by the tool. The wiring that matters is upstream.sources.
upstream.sourcesarrayList of relative paths to upstream document directories. reqmd reads their schema.yaml to resolve trace targets. This drives HTML document-chain navigation and path-based boundary inference.
mandatory-dispositionbooleanIf true, every requirement in this directory must carry a disposition attribute (implemented, deferred, or rejected). Used for test specs and verification measures.
externalbooleanIf true, requirements in this directory are external reference requirements (imported, not authored). They can be traced to but don’t need upstream traces.
additional-status-valuesarrayExtend the built-in status enum ([draft, approved]) with custom values (e.g. [review, withdrawn]). Lowercase only, no built-in collision, no duplicates.
ignore-statusbooleanIf true, all requirements in this directory are treated as coverage providers regardless of status. The status filter is hidden in HTML export.
requires-trace-fromarrayDocument-wide default coverage expectation (same document-id/level tokens as the built-in attribute). Requirements that don’t declare their own requires-trace-from inherit it; an explicit requires-trace-from: [] on a requirement overrides it; an empty default opts every requirement in the document out.
disjoint-checkstring | arrayEnables the disjoint-attribute check for the named array-typed attribute(s) (e.g. variant) on every reqmd check. Same effect as the --disjoint-check <attr> CLI flag.

Standard JSON Schema fields#

These are the JSON Schema 2020-12 fields you’ll use most:

FieldDescription
$schemaAlways "https://json-schema.org/draft/2020-12/schema".
$idA relative URI identifying this schema. Resolves against the file’s base URI.
titleHuman-readable title. Shown in HTML export and stats output.
typeAlways object (each requirement is an object of attributes).
requiredArray of attribute names that must be present on every requirement.
propertiesDefines each attribute: its type, enum, description, etc.
additionalPropertiesSet to false to reject attributes not listed in properties. Recommended.

A custom classification attribute (the basis for variant management) is a plain JSON Schema property — an array with an enum:

properties:
  variant:
    type: array
    items:
      type: string
      enum: [Base, Premium, Sport]
additionalProperties: false

The enum gives free validation (a typo like variant: [Premuim] fails reqmd check), and "Premium" in variant works as a --filter expression without any reqmd-specific declaration. To also reject trace links between incompatible variants, add x-reqmd.disjoint-check: variant. See Step 14 — Variant management.

Built-in attributes#

reqmd recognizes these attribute names automatically (they don’t need to be in your properties, but they can be):

AttributeDescription
traceArray of upstream IDs this requirement traces to. Supports ~N version pins (e.g. SYS-001~3).
requires-trace-fromDeclares that this requirement expects downstream coverage. Used for coverage checks. Omitted on a requirement → inherits the document’s x-reqmd.requires-trace-from default when one is set; [] opts out.
statusdraft or approved. Only approved counts as coverage.
dispositionimplemented, deferred, or rejected. Required when mandatory-disposition: true.
versionInteger version of the requirement. Used by version-pin staleness checks.
verifyVerification method: Test, Review, Inspection, Analysis, or Demonstration.
reqmd-suppressArray of check names to suppress (e.g. [version-pin, missing-verdict]).
externalIf true, this is an external reference requirement (imported, not authored in this tree).

Content model — nothing is dropped#

Every heading in a document is a node in a content tree:

TypeDefinitionShown in
reqheading followed by an attr blockcards, ls/CSV rows, all checks
containerheading without an attr block that has childrencollapsible folder sections in HTML, container rows in ls/CSV, TOC folders
infoheading without an attr block and no children, or prose before the first headingplain blocks in HTML, info rows in ls/CSV

Containers and info items carry no attributes and skip validation, trace checks, coverage, and --filter pruning — they exist so exported documents stay faithful to the source. check is requirement-scoped.

The requirement format#

Each requirement is a heading, a YAML attr block in a fenced code block, and free-form prose. Any heading level works — the first requirement heading anchors the hierarchy, and deeper requirement headings nest under the nearest shallower requirement as sub-requirements:

## SYS-001  Temperature warning

```attr
priority: High
status: approved
trace:
  - STK-003~2
verify: Test
version: 1
```

The system shall display a warning when cabin temperature
exceeds 80°C for more than 5 seconds of continuous operation.

*Rationale:* Driver distraction from sudden thermal events
is a safety concern.

The heading text is the requirement ID plus a title. The attr block holds the structured attributes. The prose is the requirement body. The Rationale: paragraph is optional but shown in the HTML export.

See also#