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#
reqmd check — validate requirements and trace links#
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 linksExit 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 warningsExample 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 requirementsExample output
Requirements: 19
Documents: 1
=== spec/02-system (19 reqs) ===
priority:
Critical 6
High 8
Medium 5
status:
approved 19reqmd 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 existingBuilt-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: falseGenerated 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:
| Flag | Description |
|---|---|
--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) |
--force | Overwrite 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 configurationExample 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)| Flag | Description |
|---|---|
--addr <addr> | HTTP server address (default: localhost:8080) |
--results <path> | Load verification results (repeatable). Also watched for changes. |
--no-open | Don’t open a browser on start |
--headless | Terminal-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.htmlEvery 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 verdictin 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'| File | Row grain |
|---|---|
requirements.ndjson | one row per content node (req / container / info) |
traces.ndjson | one row per declared trace: reference |
results.ndjson | one row per measure verdict (only with --results) |
findings.ndjson | one 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.
| Flag | Description |
|---|---|
-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
doneQuery 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 commitWith --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 outputRewrites 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 filesNo changes needed:
no version-pin changes needed| Flag | Description |
|---|---|
--yes, -y | Apply changes without prompting |
--json | Output as JSON |
--promote-unpinned | Also pin trace refs that have no ~N against a versioned upstream |
--dry-run | Print 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.
| Expression | Matches |
|---|---|
"Premium" in variant | Requirements tagged Premium (array membership) |
variant == nil | Requirements with no variant attribute — “common to all” |
"Premium" in variant or variant == nil | The whole Premium configuration (Premium-specific plus common) |
status == "approved" | Approved requirements |
version > 3 | Requirements 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 variant | Multi-configuration requirements |
not "Sport" in variant | Everything 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.yamlis a compile-time ERROR (fails fast on typos, before any requirement is evaluated). Add--relaxed-filterto 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
niland is excluded unless the expression handles absence (e.g.variant == nil). - The
--jsonsummary 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#
| Command | What it does | Key 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: falsex-reqmd options#
| Option | Type | Description |
|---|---|---|
level | string | A 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-id | string | A 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-prefix | string | The ID prefix for requirements in this directory (e.g. SYS-, STK-GOAL-, TST-). Requirements get IDs like SYS-001, SYS-002. |
upstream | object | Declares which document directories are valid upstream sources for trace links. |
upstream.level | string | The x-reqmd.level of the expected upstream. Informational only — never read by the tool. The wiring that matters is upstream.sources. |
upstream.sources | array | List 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-disposition | boolean | If true, every requirement in this directory must carry a disposition attribute (implemented, deferred, or rejected). Used for test specs and verification measures. |
external | boolean | If 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-values | array | Extend the built-in status enum ([draft, approved]) with custom values (e.g. [review, withdrawn]). Lowercase only, no built-in collision, no duplicates. |
ignore-status | boolean | If true, all requirements in this directory are treated as coverage providers regardless of status. The status filter is hidden in HTML export. |
requires-trace-from | array | Document-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-check | string | array | Enables 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:
| Field | Description |
|---|---|
$schema | Always "https://json-schema.org/draft/2020-12/schema". |
$id | A relative URI identifying this schema. Resolves against the file’s base URI. |
title | Human-readable title. Shown in HTML export and stats output. |
type | Always object (each requirement is an object of attributes). |
required | Array of attribute names that must be present on every requirement. |
properties | Defines each attribute: its type, enum, description, etc. |
additionalProperties | Set 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: falseThe 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):
| Attribute | Description |
|---|---|
trace | Array of upstream IDs this requirement traces to. Supports ~N version pins (e.g. SYS-001~3). |
requires-trace-from | Declares 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. |
status | draft or approved. Only approved counts as coverage. |
disposition | implemented, deferred, or rejected. Required when mandatory-disposition: true. |
version | Integer version of the requirement. Used by version-pin staleness checks. |
verify | Verification method: Test, Review, Inspection, Analysis, or Demonstration. |
reqmd-suppress | Array of check names to suppress (e.g. [version-pin, missing-verdict]). |
external | If 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:
| Type | Definition | Shown in |
|---|---|---|
req | heading followed by an attr block | cards, ls/CSV rows, all checks |
container | heading without an attr block that has children | collapsible folder sections in HTML, container rows in ls/CSV, TOC folders |
info | heading without an attr block and no children, or prose before the first heading | plain 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#
- Quickstart — a hands-on tour of every command.
- Step 14 — Variant management — the
--filterworkflow end to end. - FAQ — answers to common questions.
- Use cases — what reqmd is for, and what it’s not.