# reqmd — full content > Lightweight CLI for requirements-as-Markdown with trace checks. Git-native, text-first, no database. Validates 249 requirements in 16 ms; scales to 720k in 7 seconds. > Index available at: https://reqmd.xyz/llms.txt > 17 pages in this dump. ---## Step 0 — Installation URL: https://reqmd.xyz/quickstart/00-installation/ Description: Install reqmd in 30 seconds with go install, build from source, or download a prebuilt binary. Then verify the install against the bundled 249-requirement spec.Three ways to get reqmd on your machine. Pick one. Option 1 — go install (fastest) If you already have Go on your $PATH: go install github.com/dVoo/reqmd/cmd/reqmd@latestThe binary lands in $(go env GOBIN) (or $(go env GOPATH)/bin). Option 2 — Build from source git clone https://github.com/dVoo/reqmd cd mdreq go build -o reqmd ./cmd/reqmd ./reqmd --helpWorks on every platform Go supports — Linux, macOS, Windows, *BSD. Option 3 — Prebuilt binary Download a release from GitHub Releases. Extract the archive and put reqmd on your $PATH. Prerequisites Go 1.25 or newer — required for the source build. Cgo toolchain (gcc or clang) — only if you build the optional export graph subcommand with the ladybug build tag. With graph export (optional) reqmd export graph writes a LadybugDB database for Cypher queries. It pulls in Cgo and an extra dependency, so it’s gated behind a build tag: go build -tags ladybug -o reqmd ./cmd/reqmdWithout the tag, reqmd export graph is not built. The rest of the CLI works exactly the same. Verify the install reqmd --version # shows the version reqmd check spec/ # validate the bundled dogfooded spec (249 requirements)If the second command prints Summary: 249 total, 249 valid, 0 invalid, 0 parse errors, you’re good to go. What’s next Now write your first requirement — go to Step 1. ---## Step 1 — Get started URL: https://reqmd.xyz/quickstart/01-get-started/ Description: Scaffold a new requirements project and run your first validation.Scaffold a new requirements project and run your first validation. Scaffold reqmd init my-project/This creates: my-project/ schema.yaml # JSON Schema with x-reqmd config requirements.md # example file with two sample requirementsValidate reqmd check my-project/You should see both sample requirements pass validation: Schema : my-project — my-project Requirements File : my-project (2 requirements) ✅ REQ-001 all attributes valid ✅ REQ-002 all attributes valid Summary: 2 total, 2 valid, 0 invalid, 0 parse errorsTry the other presets reqmd init ships three built-in presets: # ASPICE-oriented template with safety attributes reqmd init my-aspice/ --preset aspice # Generic results template (review/inspection/analysis) reqmd init my-results/ --preset results --id-prefix VRWhat’s next You now have a single-document project. The real power of reqmd comes from multi-level traceability — go to Step 2. ---## Step 1a — CI integration URL: https://reqmd.xyz/quickstart/01a-ci-integration/ Description: Run reqmd in CI for validation gates and structured reports.Run reqmd in CI for validation gates and structured reports. JSON validation report reqmd check --json 02-trace-your-spec/Produces a structured JSON report with per-requirement pass/fail and trace check results: { "version": 1, "exit_code": 0, "summary": { "total": 5, "valid": 5, "invalid": 0, "parse_errors": 0, "warnings": 1 }, "documents": [...], "parse_errors": [] }The exit_code field mirrors the process exit code: 0 (all valid), 1 (validation errors), 2 (parse error). GitHub Actions example # .github/workflows/validate.yml name: Validate requirements on: [pull_request] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.25' - run: go build -o reqmd ./cmd/reqmd - run: ./reqmd check --json requirements/ > report.json - run: ./reqmd check requirements/ --results ci-artifacts/ - uses: actions/upload-artifact@v4 if: always() with: name: reqmd-report path: report.jsonExit codes for CI gating Code Meaning CI action 0 All valid ✅ Pass 1 Validation errors ❌ Fail 2 Parse error ❌ Fail Only ERROR-level checks affect the exit code. WARNINGs are informational. JSON list and stats reqmd ls --json 02-trace-your-spec/ # all requirements with attributes reqmd stats --json 02-trace-your-spec/ # attribute-value breakdown per docCheck suppression in CI Suppress per-requirement checks that are known/accepted: reqmd-suppress: - untraced - version-pinWhat’s next You can integrate reqmd into CI. Now build a traced spec tree — go to Step 2. ---## Step 2 — Trace your spec URL: https://reqmd.xyz/quickstart/02-trace-your-spec/ Description: Build a multi-level V-model spec tree with trace links between levels.Build a multi-level spec tree with trace links between levels. This is the heart of reqmd: a four-level V-model with bidirectional traceability, validated by the parser. 02-trace-your-spec/ stakeholder/ # Stakeholder needs (top of V) schema.yaml goals.md # STK-GOAL-001: Fast Boot system/ # System requirements schema.yaml # upstream: ../stakeholder/ features.md # SYS-001 traces to STK-GOAL-001 software/ # Software requirements schema.yaml # upstream: ../system/ components.md # SW-001 traces to SYS-001 tests/ # Test specifications (bottom of V) schema.yaml # upstream: ../software/ boot-test.md # TEST-001/002 trace to SW-001 and SYS-001How trace links work Each requirement has a trace attribute listing its upstream IDs. reqmd validates that every trace target exists: ## SYS-001: Boot Sequence ```attr status: approved requires-trace-from: [software, tests] trace: [stakeholder/STK-GOAL-001] The `requires-trace-from` attribute declares which downstream levels must trace back to this requirement. reqmd checks coverage both ways. ## Validate the full tree ```sh reqmd check 02-trace-your-spec/Expected output: Summary: 5 total, 5 valid, 0 invalid, 0 parse errorsList all requirements reqmd ls 02-trace-your-spec/Stats per document reqmd stats 02-trace-your-spec/What’s next The spec tree validates. Now export it for stakeholders — go to Step 3. ---## Use cases URL: https://reqmd.xyz/use-cases/ Description: Where reqmd fits — from writing your first requirement to CI-gated traceability and live review.reqmd is a tool for teams who need to write, link, and verify requirements. This page walks through the real workflows where reqmd adds value, then clearly states what is out of scope. What reqmd does reqmd reads a tree of Markdown files — each requirement is a heading, a YAML attr block, and some prose — and checks every cross-reference, every status, every version pin. It produces HTML, CSV, and graph exports, loads verification results from CI or manual reviews, and closes the loop from spec to code. You write requirements the way you already write documentation: in a text editor, in Git, in a pull request. reqmd adds the trace checks that a human reviewer would do — but mechanically, on every commit. Use cases Spec-first development Write the requirement, then the test, then the code. Traceability is enforced by the parser, not remembered by humans. The same pull request carries the spec change, the trace update, and the implementation — reviewed in one diff. Step 2 — Trace your spec → Requirements with status and lifecycle Every requirement is draft or approved, and carries a disposition: implemented, deferred, or rejected (with a mandatory reason). The schema enforces the lifecycle; the trace checks enforce that a draft requirement cannot satisfy an upstream coverage expectation. Step 2a — Status & disposition → Traceability in CI Drop reqmd check into GitHub Actions or GitLab CI. Exit code 0/1/2 maps to pass/fail/parse-error. --json output is shaped for parsing. Per-check suppression and a baseline diff for comparing two tagged releases. Five lines of YAML, done. Step 1a — CI integration → Version pinning and impact tracking A downstream requirement can pin the upstream version it was verified against (SYS-001~3). When the upstream version is bumped, the pin becomes stale and the downstream needs re-verification. This is the engineering work of tracking what a version bump actually breaks. Step 2b — Version pins → Verification result roll-up Load test results from CI (CTRF JSON) or manual reviews (Markdown). The --results flag runs missing-verdict and failing-verdict checks — an approved measure with no result, or a latest result that is fail. HTML export shows color-coded verdict badges on every measure. Step 5 — CTRF results → Live stakeholder review Run reqmd serve while editing. The browser refreshes on every save, with trace links resolved and verdict badges color-coded. Reviewers read the spec as a website — with search, filters, and a light/dark toggle. No server framework, no SPA build. Step 3a — Live preview → Submodule-based spec integration Compose specs from multiple git submodules. Use document-id/ID qualified references and baseline diff to see what changed between tags. Merge specs across teams without losing provenance. Step 3b — Baseline diff → Source-code traceability The companion reqmd-import tool walks Go and Python source with tree-sitter and writes per-package .md requirements into your spec tree. Every function and type gets an ID in the same namespace as your spec — the same reqmd check that catches broken upstream refs also catches broken implementation refs. reqmd-import → Custom schemas per document Each document directory carries its own schema.yaml. Define required fields, enums, ID prefixes, and per-directory metadata. Use reqmd init presets or build your own. The data model adapts to any V-model workflow. Step 4 — Custom templates → AI-assisted spec authoring An agent reads llms.txt, edits *.md in the same tool-call budget as code, runs reqmd check, parses the JSON verdict, and iterates. The check is 16 ms even on the bundled 249-req spec. Drop in a copy-pasteable AGENTS.md and you're done. AI & agents → What reqmd is good at These are the things reqmd does well, and that show up in every use case above: Bidirectional trace verification. Every requirement ID across every document, every trace link, every requires-trace-from expectation, every ~N version pin is checked mechanically. Broken references, circular dependencies, missing coverage — all caught on every commit. Status lifecycle and disposition. A requirement is either in progress (draft) or signed off (approved); either actively developed (disposition: implemented), or parked with a reason (deferred / rejected, both with mandatory reasons). The lifecycle is enforced by the schema and the trace checks. Documented rationale. Every requirement can carry a Rationale: paragraph alongside the body. The HTML export shows it. Reviewers see the why, not just the what — the engineering work of being able to answer “why is this requirement here?” six months from now. Version pinning. A downstream requirement can pin the upstream version it was verified against. When the upstream version is bumped, the pin becomes stale and the downstream needs re-verification. This is the engineering work of tracking what a version bump actually breaks. CI-gated quality. Stable exit codes, JSON output, per-check suppression. Every pull request that touches a spec, the agent (or the human) runs reqmd check and gets a pass/fail answer. No manual review of trace quality is required because the check is mechanical. Live HTML review. A traceable HTML export with bidirectional links, document chain, theme toggle, and search. Reviewers can read the spec as a website. The engineering work is making the spec legible to the people who didn’t write it. What is out of scope for reqmd reqmd is a requirements authoring and traceability tool. It is not a project management tool, a risk management tool, or a process compliance framework. The following categories of work are explicitly out of scope — reqmd will not grow features for them: Project management. Sprint planning, task assignment, effort estimation, milestone tracking, burndown charts. reqmd stores requirements, not tasks or schedules. Use a project tracker (Jira, Linear, GitHub Issues) for that. Risk management. Risk registers, risk assessment matrices, risk mitigation tracking. reqmd can store a requirement that says “mitigate risk X” — but it does not model risk as a first-class object, does not compute risk priorities, and does not track mitigation status. Use a dedicated risk tool or a spreadsheet. Process compliance and audit trails. Named approvers, sign-off records, electronic signatures, audit logs, regulatory submission packages. reqmd produces a validated artifact (the checked spec), not a compliance record. If your process requires named approvers and audit trails, use a tool designed for that. Supplier monitoring and procurement. Supplier scorecards, purchase-order tracking, supplier qualification records. Not a spec problem. Measurement and process improvement. KPI dashboards, process metrics, maturity assessments, CMMI levels. reqmd validates artifacts, not the organization that produced them. Notification and review threading. Active notification registries, affected-party tracking, review-thread tools, comment management. The HTML export is a passive publication — it shows the spec, it does not manage a conversation about it. Use a code review tool or a wiki. Configuration and build management. Version control of binaries, artifact repositories, build pipelines, release packaging. reqmd works with your VCS (it reads git tags for baseline diffs), but it is not a configuration management tool. If your team does this work, reqmd can store the requirements that result from it — e.g. “REQ-001: the build pipeline shall produce a signed artifact.” But reqmd does not do the work. No tool should pretend to conjure organizational process from a text file. See also Quickstart — try the workflow in 10 minutes. Benchmarks — performance on a real 249-requirement spec and on synthetic 35-doc corpora up to 720k reqs. reqmd-import — the source-code traceability tool that closes the gap from code to spec. Compare — how reqmd stacks up against other requirements tools. AI & agents — why reqmd’s plain-text format is the right substrate for AI-assisted spec workflows. ---## Cheat sheet URL: https://reqmd.xyz/cheat-sheet/ Description: Full reqmd command reference with example outputs and schema.yaml options — every command, every flag, every x-reqmd option.A quick reference for every reqmd command and every schema.yaml option. Each command shows real output from the bundled spec/ tree. 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 warningsExit 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. Example output Schema : reqmd-system-requirements — reqmd System Requirements File : spec/02-system (11 requirements) ✅ SYS-FMT-001 all attributes valid ✅ SYS-FMT-002 all attributes valid ✅ SYS-FMT-003 all attributes valid ✅ SYS-CLI-001 all attributes valid ✅ SYS-VAL-001 all attributes valid ⚠ SYS-FMT-001 broken reference: target "STK-GOAL-001" not found ⚠ SYS-FMT-001 broken reference: target "ASP-SR-001" not found ⚠ SYS-CLI-001 broken reference: target "STK-GOAL-004" not found Summary: 11 total, 11 valid, 0 invalid, 0 parse errors, 50 warnings Example JSON output (--json) { "version": 1, "exit_code": 0, "summary": { "total": 11, "valid": 11, "invalid": 0, "parse_errors": 0, "warnings": 50 }, "documents": [ { "path": "spec/02-system", "schema_title": "reqmd-system-requirements — reqmd System Requirements", "req_count": 11, "requirements": [ { "id": "SYS-FMT-001", "valid": true, "checks": [ { "level": "WARNING", "source": "spec/02-system/features.md", "message": "broken reference: target \"STK-GOAL-001\" not found" } ] } ] } ] } reqmd ls — list all requirements Prints a table of every requirement with all schema attributes. reqmd ls spec/ # table output reqmd ls spec/ --json # JSON output Example output === spec/02-system === ID | priority | trace | status | ------------------------------------------------------------------------------------------------------------------------- SYS-FMT-001: Markdown requirement format | Critical | ["STK-GOAL-001","ASP-SR-001"] | approved | SYS-FMT-002: Built-in attribute system | Critical | ["STK-GOAL-002","ASP-SR-007"] | approved | SYS-FMT-003: Schema.yaml document config | Critical | ["STK-GOAL-003","ASP-SR-002"] | approved | SYS-CLI-001: CLI subcommands | Critical | ["STK-GOAL-001","STK-GOAL-004"] | approved | SYS-VAL-001: Multi-pass validation | Critical | ["STK-GOAL-003","STK-GOAL-005"] | approved | reqmd stats — attribute-value breakdown per document Shows how many requirements have each attribute value, grouped by document directory. reqmd stats spec/ # table output reqmd stats spec/ --json # JSON output Example output Requirements: 11 Documents: 1 === spec/02-system (11 reqs) === priority: Critical 6 High 5 status: approved 11 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 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 Built-in preset name or path to a custom preset directory --id-prefix ID prefix for requirements (e.g. SYS-, REQ-) --id Schema $id (default: directory basename) --title Schema title (default: Requirements) --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/
Example output
reqmd serve spec/ serving http://localhost:8080 watching spec/ ... initial build: 249 reqs, 6 docs file changed: spec/02-system/features.md rebuilt: 249 reqs (48ms) file changed: spec/02-system/schema.yaml rebuilt: 249 reqs (52ms)
Flag Description
--addr HTTP server address (default: localhost:8080)
--results 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 Debounce window for file events (default: 500ms)

reqmd export csv — export to CSV

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

reqmd export csv spec/ -o csv-out/ reqmd export csv spec/ -o csv-out/ --results ci-out/

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

Example output
exporting spec/ → csv-out/ spec/02-system → csv-out/system-requirements.csv (11 rows) spec/03-software → csv-out/software-requirements.csv (17 rows) spec/04-tests → csv-out/tests-requirements.csv (7 rows) ... 6 documents, 249 requirements exported

Each CSV has columns: ID, Title, , Body, Rationale.

reqmd export html — export to HTML

Standalone HTML files with trace links, document chain, theme toggle, search.

reqmd export html spec/ -o html-out/ reqmd export html spec/ -o html-out/ --results ci-out/ --results reviews/

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 ... 6 documents exported

Each HTML file is standalone (no external JS), with card-based layout, trace links, document chain, search, and theme toggle.

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

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 249 nodes, 1240 edges 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

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

All commands at a glance

Command What it does Key flags
check Validate + trace checks --json, --results, --relaxed-versions, -s
ls List all requirements --json
stats Stats per document --json
init Scaffold a new project --preset, --id-prefix, --force
serve Live HTML preview --addr, --results, --headless
export csv CSV export -o, --results
export html HTML export -o, --results
export graph Graph export (ladybug tag) -o
baseline diff Compare two git tags --json
repin 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- upstream: level: stakeholder-needs sources: - ../01-stakeholder/ mandatory-disposition: true external: false

x-reqmd options

Option Type Description
level string The V-model level for this document (e.g. stakeholder-needs, system-requirements, software-requirements, test-specs). Used for the document chain in HTML export.
document-id string A short identifier for this document directory (e.g. system, stakeholder, tests). Used in qualified references (document-id/ID).
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.
upstream.sources array List of relative paths to upstream document directories. reqmd reads their schema.yaml to resolve trace targets.
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.

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.

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

The requirement format

Each requirement is a level-2 heading, a YAML attr block in a fenced code block, and free-form prose:

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

---## Step 2a — Status & disposition URL: https://reqmd.xyz/quickstart/02a-status-disposition/ Description: The status lifecycle and the disposition workflow for deferred and rejected requirements.Two built-in attributes control how requirements behave in trace coverage and how deferred work is tracked. Status lifecycle Every requirement has a status — either draft or approved (default when omitted). Only approved requirements count as upstream coverage providers. ## REQ-001: System boot ```attr status: approved trace: [STK-001] A `draft` requirement can be referenced by a `trace` but does **not** satisfy a `requires-trace-from:` expectation. This lets you stage work-in-progress without breaking coverage checks. Try it: in [Step 2](/quickstart/02-trace-your-spec/), the `SYS-001` requirement shows:⚠ SYS-001 no upstream trace: no approved requirement from “software” traces to this item (1 draft downstreams ignored) The `(1 draft downstreams ignored)` message means `SW-001` traces to `SYS-001` but `SW-001` is still `draft` — so the coverage chain is incomplete. ## Disposition workflow When a requirement can't be immediately implemented, use `disposition` + `disposition-reason` instead of leaving silent gaps: | Disposition | What it signals | Rationale needed? | |---|---|---| | `implemented` | Actively developed | No | | `deferred` | Accepted, postponed | **Yes** | | `rejected` | Not accepted | **Yes** | ```markdown ## STAKE-007 ```attr status: approved disposition: deferred disposition-reason: "Deferred to Phase 2 per steering committee 2025-03-14"The system shall support over-the-air firmware updates for all ECUs. Disposition is orthogonal to trace coverage. Use `requires-trace-from: []` to explicitly state that no downstream coverage is expected. ## Extending the status enum When `draft`/`approved` is too narrow, add custom values: ```yaml x-reqmd: additional-status-values: [review, in-progress]Opting out of the lifecycle For legacy imports or generated specs: x-reqmd: ignore-status: trueAll requirements count as coverage providers; the status filter is hidden in HTML export. What’s next Now export your spec tree — go to Step 3. ---## Benchmarks URL: https://reqmd.xyz/benchmarks/ Description: How fast is reqmd? Real numbers from a real run — from 249 requirements in 16 ms to 720,000 requirements in 7 seconds.reqmd is fast enough to run on every commit, every save, and every pull request — without anyone noticing the wait. This page shows the real numbers and explains what drives them. The headline The tool’s own spec — 249 requirements across 6 document directories — validates in 16 milliseconds. That’s faster than a page load. For context, a typical project spec is in the hundreds, not the thousands. How it scales at large sizes To find the ceiling, a synthetic spec tree was generated by replicating the real spec across 36 document directories at four sizes: 71k, 180k, 360k, and 720k requirements. The numbers below are wall-clock time (how long the command takes to finish), the median across 5 runs on an 8-core / 16-thread desktop CPU. 71,712 reqs 0.7 s 180,774 reqs 1.7 s 363,042 reqs 3.5 s 727,578 reqs 7.2 s The scaling is linear: double the requirements, double the time. There is no exponential blowup, no cliff, no surprise. The check time is predictable from the requirement count alone. For reference, the same benchmark on a 12-core laptop (Intel i5-1245U, 2 performance + 8 efficiency cores) runs ~2.7× slower — 1.9 s for 71k, 4.8 s for 180k, 9.4 s for 360k. The desktop numbers below are the ones to expect on typical CI or developer hardware. What this means in practice All times below are reqmd check on the 8-core / 16-thread desktop (AMD Ryzen 7 5800X): Your spec size reqmd check takes Good for CI? ~100 requirements ~5 ms instant ~1,000 requirements ~16 ms instant ~10,000 requirements ~100 ms instant ~71,712 requirements ~0.7 s yes ~180,774 requirements ~1.7 s yes ~363,042 requirements ~3.5 s yes ~727,578 requirements ~7.2 s yes Most project specs are in the hundreds to low thousands. Even a large, multi-team spec with 180,000 requirements finishes in under 2 seconds. The 720k case is an extreme stress test — more requirements than most teams will produce in a decade — and it still finishes in 7 seconds. Other commands The check command is the heaviest one. The other commands are faster because they skip the trace-graph pass: Command What it does 71k reqs 720k reqs reqmd check Validate + trace checks 0.7 s 7.2 s reqmd check --json Same, with JSON output 0.7 s 7.6 s reqmd ls List all requirements 0.4 s 3.4 s reqmd stats Stats per document 0.3 s 2.8 s reqmd export html Full HTML export 1.4 s 15.0 s The JSON output adds 5–10% overhead. The HTML export is the slowest because it renders every requirement as a standalone page with trace links — but even at 720k requirements it finishes in 15 seconds. Memory usage Memory grows linearly with the spec size, same as time. The 720k spec uses about 5.4 GB for check and 6.2 GB for ls. For typical specs (hundreds to low thousands of requirements), memory is negligible — under 100 MB. What makes it fast Three things, in plain terms: Parallel reading. reqmd reads all document directories at the same time, using every CPU core. On a 16-thread machine, up to 16 directories are parsed simultaneously. The more cores you have, the faster this goes — a server CPU with 32+ threads would parse proportionally faster. No database. The trace graph is built in memory on every run, then thrown away. There is no database to query, no cache to maintain, no incremental state to manage. Starting from scratch every time is faster than maintaining a complex cache — because the total time is so small. Single pass. Once the files are read, every trace check — broken references, cycles, missing coverage, version pins — runs in a single pass over the requirements. No multiple queries, no back-and-forth. How the numbers were measured The numbers come from a real run of two bundled tools: reqmd-bench-gen (generates a synthetic spec tree by replicating the real spec) and reqmd-bench-run (runs the benchmarks and reports the numbers). The spec tree was generated by copying the real 6-directory spec 6 times (36 directories total) and then replicating each document’s content to reach a target requirement count. The trace graph stays connected — every link is rewritten deterministically. The result looks like a multi-team spec repo where several teams independently authored requirements against the same template. To reproduce: # Build the bench tools go build -o reqmd-bench-gen ./cmd/reqmd-bench-gen go build -o reqmd-bench-run ./cmd/reqmd-bench-run # Run the full benchmark (baseline + 4 scales, 5 runs each) ./bench.sh # Or invoke the runner directly ./reqmd-bench-run -src spec/ \ -gen ./reqmd-bench-gen \ -reqmd ./reqmd \ -work /tmp/reqmd-bench \ -out /tmp/reqmd-bench-results.jsonThe full run takes about 6 minutes on the desktop at all four scales. Results are saved as JSON with hardware metadata (CPU model, core count, Go version, kernel) for reproducibility. Hardware: AMD Ryzen 7 5800X (8 cores / 16 threads), Linux 7.1.3, Go 1.26.5. This is a mainstream desktop CPU from 2020. A modern desktop or server CPU with more performance cores would be faster; the numbers on this page are a conservative baseline. For reference, the same benchmark on a 12-core laptop (Intel i5-1245U, 2 performance + 8 efficiency cores) runs ~2.7× slower. When it gets slow Past about 500,000 requirements, the parallel reader starts to lose efficiency and the markdown parser becomes the bottleneck. Two practical workarounds: Run reqmd check on a smaller subtree (e.g. only the documents that changed). Use --json output and cache the result keyed on the spec-tree hash. These are edge cases. Most teams will never hit them. See also Quickstart — try reqmd check on the bundled 249-requirement spec. Use cases — including CI integration patterns. reqmd-bench-gen source — the synthetic corpus generator. reqmd-bench-run source — the benchmark runner that produced these numbers. ---## Step 2b — Version pins URL: https://reqmd.xyz/quickstart/02b-version-pins/ Description: Pin trace references to a specific upstream version and detect when the upstream changes.Pin trace references to a specific upstream version and detect when the upstream changes. How version pins work A downstream requirement can pin the upstream version it was last verified against using the ~N suffix: ## UP-001 ```attr status: approved version: 3 ```markdown ## DN-001 ```attr status: approved trace: [UP-001~2] # verified against UP-001 v2, but UP-001 is now v3 When the upstream `version` is bumped, the pin becomes stale and reqmd flags the downstream as needing re-verification. ## Findings | Condition | Meaning | Level | Demote with | |-----------|---------|-------|-------------| | `pin < upstream.version` | Outdated — upstream bumped, downstream needs re-verify | **ERROR** | `--relaxed-versions` | | `pin > upstream.version` | Predated — downstream claims a non-existent version | **ERROR** | (never — data integrity) | | `pin == upstream.version` | Current | — | — | | No pin | No version check applies | — | — | ## Try it The spec tree in [Step 2](/quickstart/02-trace-your-spec/) doesn't use version pins, so no version-pin findings fire. To see it in action, add `version: 1` to an upstream requirement and `~1` to a downstream trace, then bump the upstream to `version: 2`: ```sh reqmd check 02-trace-your-spec/ # ❌ DN-001 version-pin: outdated — UP-001 is at version 2, pinned to ~1 # Demote to WARNING (CI-friendly: fails on predated, warns on outdated) reqmd check --relaxed-versions 02-trace-your-spec/ # ⚠ DN-001 version-pin: outdated — UP-001 is at version 2, pinned to ~1Suppression Suppress the check per-requirement: reqmd-suppress: - version-pinStale verdicts Version pins also apply to result→measure traces: pin a result with MEASURE-ID~3 against a measure now at version: 4 and the outdated finding fires. This is how stale-verdict is detected — no new check, just the existing version-pin check on a new edge type. See Step 5. Bulk-update pins When you’ve bumped a spec version and a wave of outdated findings appear, reqmd repin rewrites the affected pins in place. See Repin. What’s next Now export your spec tree — go to Step 3. ---## FAQ URL: https://reqmd.xyz/faq/ Description: Frequently asked questions about reqmd — what it's for, how it works, and how it fits into your workflow.Questions about reqmd, grouped by topic: what it is, how to use it, and how it fits your workflow. What is reqmd? What does reqmd do? reqmd is a command-line tool for writing, linking, and checking requirements and verification measures in plain Markdown. You write each requirement as a heading, a small YAML block, and some prose. reqmd checks every cross-reference — broken links, missing coverage, circular dependencies, stale version pins — and tells you what's wrong. It also exports to HTML, CSV, and graph formats. The key idea: your spec lives in text files, in Git, next to your code (or in its own repo). The validation runs in milliseconds. No database, no server, no lock-in. What can I use reqmd for? Any project where you need to write requirements and trace them to each other, to tests, and to reviews: Spec-first development — write the requirement, then the test, then the code, all in one pull request. Higher-level specification — stakeholder needs, system requirements, software design, and test specs traced across a V-model. The spec does not need to live next to the code; it can be a standalone repo for requirements and traceability at any level. Verification and validation tracking — load test results from CI (CTRF JSON) and manual review results (Markdown), and get verdict badges showing which measures pass, fail, or are still missing. CI-gated traceability — every pull request that touches a spec runs reqmd check and gets a pass/fail answer. Live review — reqmd serve gives you a live-reloading HTML preview while you edit. Does reqmd only handle requirements, or also verification measures? Both. reqmd treats verification measures — tests, reviews, inspections, analyses, demonstrations — as first-class objects. A test specification is a requirement with a verify attribute. A test result is loaded as a pseudo-requirement with an outcome (pass/fail/skipped/inconclusive) that traces back to the measure it verifies. This means the full traceability chain is: stakeholder need → system requirement → software requirement → test specification → test result. Every link is checked. If an approved measure has no result, reqmd warns (missing-verdict). If the latest result is a fail, reqmd errors (failing-verdict). Does the spec need to live next to the code? No. reqmd works on any directory of Markdown files. Many teams keep the spec in the same Git repository as the code so that spec changes and code changes land in the same pull request. But a standalone requirements repository works just as well — point reqmd check at whatever directory contains your spec tree. For higher-level requirement specification and traceability (stakeholder needs, system architecture, supplier specs), a separate repo is often the better choice. The spec is reviewed by people who don't work in the codebase — product managers, QA, safety engineers — and a dedicated repo with its own review cycle keeps things clean. How is reqmd different from a wiki or a Google Doc? A wiki stores text. reqmd stores text and checks it. In a wiki, a broken trace link is a human problem — someone has to notice it. In reqmd, a broken link is a CI failure — the tool catches it on every commit. You also get structured export (HTML with trace navigation, CSV, graph), version pinning, status lifecycle, and verification result tracking. None of that exists in a wiki. How is reqmd different from OpenFastTrace? Both are static-spec tools with a strong emphasis on bidirectional traceability. The differences: Data format. reqmd is Markdown-only with a YAML block; OFT uses its own .xml formats. Runtime. reqmd is a single Go binary; OFT is a Java project. Verification. reqmd has first-class CTRF ingestion and outcome-gated checks (missing-verdict, failing-verdict); OFT treats verification as separate artifacts. Fit. OFT is a stronger fit for traditional spec-by-spec coverage analysis; reqmd is a stronger fit for git-native, text-first, CI-driven workflows. Both are good tools. Pick by your team's existing workflow. How is reqmd different from Jama / Polarion / DOORS? Those are database-backed requirements-management suites. They've been the default in regulated industries for 20 years, and they solve a real problem — managed workflows, audit trails, role-based access. But they come with structural problems that get worse as your team gets more agile: Slow. Every interaction is a web UI round-trip. A spec review that takes 10 minutes in a Git diff takes an hour in DOORS. Disconnected from the code. The spec is in a database; the code is in Git. There is no native connection. When a developer renames a function, the spec doesn't know. No real branching. "Baselines" are snapshots, not branches. You can't git checkout -b, try a change, and merge it. Two teams working on the spec simultaneously means lock-then-edit. No submodules. A multi-team spec is one monolithic database. You can't split it into per-team repos and compose them. Not CI-native. Running "does the spec validate?" in CI requires a REST API call, authentication, and a custom script. With reqmd it's reqmd check spec/ — one binary, 16 ms, exit code 0/1/2. Not developer-friendly. Developers don't open DOORS. They open their editor. If the spec is in a database, the developer never reads it, and the spec drifts from the code. Vendor lock-in. Your spec is in a proprietary database schema. Exporting it is a project. With reqmd, your data is plain text — diffable, portable, yours. Pick reqmd when you want the spec to live where the developers work — in Git, next to the code, with branching, submodules, CI, and pull-request review as the natural workflow. Pick an RM suite when you specifically need named approvers with electronic signatures and a regulated audit trail that an auditor reads from the tool. Some teams use both: reqmd for the engineering spec, the RM suite as the system of record. See the compare page for the full side-by-side. How it works How does the GitHub review workflow work? reqmd is designed for Git-based review. The spec lives in a Git repository (either next to the code or in a dedicated repo). Every change to a requirement, a trace link, a schema, or a verification result is a commit. Here's the typical workflow: Author. Open a branch. Edit the .md files — add a requirement, update a trace link, change a status. Commit and push. Check locally. Run reqmd check spec/ before pushing. If it exits non-zero, fix the issues. Open a pull request. The diff shows exactly what changed: the requirement text, the trace link, the schema. Reviewers see the same diff they'd see for a code change. CI runs the check. A GitHub Action (or GitLab CI job) runs reqmd check --json spec/ on the PR. If it fails, the PR is blocked. The JSON output can be posted as a comment or an annotation. Review. Reviewers read the diff, check the trace links, run reqmd serve spec/ for a live preview if they want to see the rendered spec with links resolved. Merge. Once the check passes and the review is approved, merge. The spec is now consistent — no broken links, no missing coverage, no stale version pins. The key advantage over a database-backed RM tool: the review happens in the same pull request interface the team already uses for code. The diff is the review artifact. The check is the gate. No separate tool, no separate login, no separate review state to track. How does the trace check work? reqmd builds a trace graph from every trace: link in every requirement, then checks it in one pass: Broken references — a trace: pointing to an ID that doesn't exist anywhere. Missing coverage — a requirement with requires-trace-from that no downstream requirement traces to. Circular dependencies — a chain of traces that loops back to itself. Version pin staleness — a downstream pinned to SYS-001~3 but the upstream is now version 5. Missing verdicts — an approved measure with no verification result. Failing verdicts — the latest result for a measure is fail. Broken references, cycles, and failing verdicts are errors (exit code 1). Missing coverage and missing verdicts are warnings (exit code 0, but shown in the output). How does the status lifecycle work? Every requirement has a status: draft (work in progress) or approved (signed off). Only approved requirements count as coverage providers — a draft requirement can be referenced by a trace but does not satisfy a requires-trace-from expectation. Requirements can also carry a disposition: implemented (actively developed), deferred (parked, with a reason), or rejected (not doing it, with a reason). When a document directory sets mandatory-disposition: true, every requirement must have a disposition. How do I load verification results? Two formats, both loaded with the --results flag (repeatable): CTRF JSON — from automated test runs. The x-reqmd.id field in each test maps it to a requirement ID. reqmd reads the pass/fail/skipped verdict and the timestamp. Manual results (Markdown) — for reviews, inspections, analyses. Each result is a Markdown file with an attr block carrying outcome, verifier, verified-at, and a trace back to the measure it verifies. reqmd synthesizes one pseudo-requirement per result and runs two new checks: missing-verdict (approved measure, no result) and failing-verdict (latest result is fail). The HTML export shows color-coded verdict badges on every measure card. Is there a web UI? There is no separate web UI; the HTML export is the web UI. Run reqmd serve spec/ for a live-reloading preview, or reqmd export html spec/ -o docs/ and host the resulting docs/ directory as a static site. The HTML export includes card-based layout, upstream/downstream trace links, a document chain tab strip for V-model navigation, status filters, theme toggle, and (with --results) color-coded verdict badges on measure cards. Does reqmd work without Git? Yes, for everything except baseline diff. The spec tree is plain files; no Git required to validate, list, or export. baseline diff is the one command that calls git archive to read a tagged snapshot — every other command operates on whatever directory you point it at. How do I use git submodules for configuration management? Configuration management — the discipline of controlling, versioning, and composing a multi-team spec across component boundaries — is a core systems engineering practice. In reqmd, it's built on Git submodules. Each team owns their own requirements repo as a git submodule, and a top-level repo assembles them into a single tree that reqmd check validates as a whole. A typical layout: spec-monorepo/ stakeholder/ ← submodule: git@github.com:team/stakeholder-spec.git system/ ← submodule: git@github.com:team/system-spec.git software/ ← submodule: git@github.com:team/software-spec.git tests/ ← submodule: git@github.com:team/test-spec.git Each submodule is a normal reqmd document directory with its own schema.yaml. The top-level repo just holds the submodule references — no spec content of its own. When a team updates their spec, they push to their repo and the top-level repo bumps the submodule pin. Cross-repo trace links work out of the box. A requirement in system/ can trace to a requirement in stakeholder/ by ID — reqmd resolves it across the submodule boundary because all submodules are on disk under the top-level directory. Use qualified references (document-id/ID) if two submodules share ID prefixes. The baseline is the submodule pins. When you need to compare two baselines, reqmd baseline diff v1.0 v2.0 reads the submodule pins at each tag and reports what changed — added, removed, and modified requirements across all submodules, plus which submodule pins were updated. No separate configuration management tool needed; git is the tool. Review workflow works the same as a single repo. A PR that bumps a submodule pin shows the exact diff of the submodule's spec changes. Reviewers see what changed, CI runs reqmd check on the assembled tree, and the merge updates the baseline. How do I link requirements down to the actual code? Use the companion reqmd-import tool. It walks your Go or Python source code with a tree-sitter grammar and writes per-package .md requirements into your spec tree. Every function, type, and method gets a requirement ID in the same namespace as your spec. The extracted code requirements are marked external: true and live in an imported/ sub-tree. They don't need upstream traces (they're not authored by hand), but they do trace to the real implementation. The result: the same reqmd check that catches a broken spec reference also catches a broken implementation reference — if a function is renamed or deleted, the trace from the spec to that function becomes a broken reference. The full traceability chain becomes: stakeholder need → system requirement → software requirement → test specification → test result → code implementation. Every link is a plain-text reference that reqmd validates mechanically. reqmd-import is a separate Go module with its own release cadence. It supports Go and Python today; Rust and Zig are reserved for future work. Schema & data What does a schema.yaml file look like? Each document directory has a schema.yaml that defines the required attributes, their types, and reqmd-specific options. A minimal example: $schema: "https://json-schema.org/draft/2020-12/schema" $id: "my-requirements" title: "My Requirements" type: object required: - priority properties: priority: type: string enum: [Critical, High, Medium, Low] additionalProperties: false x-reqmd: level: system-requirements document-id: system id-prefix: SYS- upstream: level: stakeholder-needs sources: - ../01-stakeholder/ See the cheat sheet for the full list of x-reqmd options and all commands. Can I use JSON instead of YAML for the schema? No, the format is fixed to YAML. The schema.yaml filename and the YAML dialect are hard-coded. You can hand-author the file in JSON-compatible YAML and it will round-trip fine; extensions like x-reqmd work the same. Why YAML? The data is small (a few hundred lines per directory at most), human-authored, and benefits from comments. What about Excel or Word import? Not built in. The recommended path is reqmd init with a custom preset and a one-time script that produces the Markdown files. For ongoing imports, write a small script that walks the Excel/Word file and emits one Markdown file per requirement. The reqmd-import source-code extraction tool is the closest existing project — it extracts requirement IDs from Go and Python source via tree-sitter. Does reqmd work with my issue tracker (Jira, GitHub Issues, Linear)? No native integration. The common pattern is to put the issue-tracker key in a custom attribute (e.g. jira: PROJ-123) and search via reqmd ls --json or reqmd stats --json. The issue tracker is a downstream consumer of the spec, not a source. How does the trace check handle cycles? reqmd check reports a cycle as an error (with the cycle path) and exits non-zero. There is no auto-resolution; cycles are a modeling problem to fix in the source. What about ReqIF? Not supported yet. The data model is compatible; the importer is what's missing. A future reqmd-import reqif subcommand is the most likely path. CI & performance Can I run reqmd in CI without a database? Yes, no database, no daemon, no state. Each check is self-contained. Pin the version in CI. The recommended CI invocation: - run: go install github.com/dVoo/reqmd/cmd/reqmd@ - run: reqmd check --json requirements/ > report.json - run: reqmd check requirements/ --results ci-artifacts/Use --json for programmatic parsing, plain output for human review. Does reqmd scale to my 50,000-requirement spec? Yes. Based on the measured linear scaling (~50 req/ms on 12 cores), 50,000 requirements would take ~2.5 seconds for check. Even 720,000 requirements finish in under 10 seconds. The bottleneck is file I/O, not the graph. See the benchmarks page for the full numbers. What do the check / warning / error symbols mean? Three severity levels: ✅ — passes schema validation and all required trace checks. ⚠ — passes schema validation but has a warning (broken reference, untraced, missing verdict). Warnings do not affect the exit code. ❌ — fails schema validation or has an error (cycle, missing required attribute, failing verdict). Errors exit non-zero. Only errors affect the exit code. Warnings are informational. What's the deal with the ladybug build tag? reqmd export graph writes a LadybugDB database for Cypher queries. It pulls in a Cgo dependency, so it's gated behind a build tag: go build -tags ladybug -o reqmd ./cmd/reqmdWithout the tag, export graph is not built. The rest of the CLI works exactly the same. Still have questions? Read the Quickstart — most “how do I…” questions are answered there. Read the Cheat sheet — full command overview and schema reference. Read the Use cases page for what reqmd does and what it doesn’t. See the Compare page for how reqmd stacks up against other tools. Open an issue on GitHub. ---## Step 2c — Repin URL: https://reqmd.xyz/quickstart/02c-repin/ Description: Bulk-update version-pin (~N) trace references to match the upstream's current version with reqmd repin --yes.Bulk-update version-pin (~N) trace references to match the upstream’s current version. The reqmd repin command proposes or applies the changes for you. When to use After bumping a spec version (Version pins) you’ll see a wave of version-pin: outdated findings. repin rewrites the affected trace: lines in place so the pins catch up to the upstream — without you having to hand-edit every requirement. Dry-run by default # See what would change — no files are written reqmd repin 02-trace-your-spec/ # /path/to/dn.md DN-001 UP-001 → UP-001~3 # /path/to/dn.md DN-002 UP-002 → UP-002~7 # 2 outdated, 0 unpinned, 0 predated across 1 files.The default mode is dry-run. The output is one line per affected requirement (file REQ-ID bare-ref → ref~newPin) plus a one-line summary. Nothing is written to disk. Apply # Apply without prompting reqmd repin 02-trace-your-spec/ --yes # Or let repin prompt you on a TTY reqmd repin 02-trace-your-spec/ # /path/to/dn.md DN-001 UP-001 → UP-001~3 # 1 outdated, 0 unpinned, 0 predated across 1 files. # Apply 1 changes across 1 files? [y/N] y # applied 1 changes across 1 filesrepin rewrites only the ```attr blocks in the affected files; surrounding Markdown prose is preserved verbatim. The change is idempotent — a second repin run after the first reports no changes. Promote unpinned refs (opt-in) By default repin only fixes outdated pinned refs (~N lower than the upstream’s version). To also pin refs that have no ~N against a versioned upstream, pass --promote-unpinned: reqmd repin 02-trace-your-spec/ --yes --promote-unpinnedThis converts “no claim” into “claimed at current version”. It is opt-in because the semantics change: a previously-unpinned ref no longer means “verified against HEAD every time” — it now claims verification against a specific version. Predated findings Refs whose ~N is ahead of the upstream’s version (direction: "predated") are surfaced in the change list but never auto-fixed. They indicate a data integrity error (a downstream claiming verification against a version that does not yet exist on the upstream) and must be fixed manually — either by bumping the upstream or by correcting the pin. Machine-readable output reqmd repin 02-trace-your-spec/ --jsonThe JSON shape is stable: { "deltas": [ { "kind": "outdated", "req_id": "DN-001", "file": "spec/03-software/dn.md", "target_id": "UP-001", "source_ref": "UP-001~1", "old_pin": 1, "new_pin": 3, "new_version": 3 } ], "by_file": { "spec/03-software/dn.md": 1 }, "outdated": 1, "unpinned": 0, "predated": 0 }kind is one of outdated, unpinned, or predated. Combined with --yes, the JSON output also includes an apply block summarising the rewrite (files touched, deltas applied, deltas skipped). Suppression The per-requirement reqmd-suppress: [version-pin] opt-out is respected by repin — suppressed nodes never appear in the change list. What’s next Compare requirement baselines between git tags — go to Baseline diff. ---## Step 3 — Export URL: https://reqmd.xyz/quickstart/03-export/ Description: Export the spec tree to CSV, HTML, and graph formats.Export the spec tree from Step 2 to CSV, HTML, and graph formats. CSV export reqmd export csv 02-trace-your-spec/ -o csv-out/Produces one CSV per document directory (stakeholder-requirements.csv, system-requirements.csv, etc.) with columns: ID, Title, all schema attributes, Body, Rationale. HTML export reqmd export html 02-trace-your-spec/ -o html-out/Produces standalone HTML files with: Card-based layout with goldmark-rendered body text Upstream/downstream trace links between files Document chain tab strip (V-model navigation) Search and filter (Alpine.js) Light/dark theme toggle Open html-out/tests-requirements.html in a browser to see trace links. See it live. Don't want to run the export yourself? Here's a real HTML export from the reqmd project's own spec, showing card layout, trace links, the document chain, search, and theme toggle: Open the system requirements export → Other documents in the same export: Stakeholder needs, Software requirements, Test specifications. Try the trace links — they cross between documents. Graph export (requires LadybugDB build) go build -tags ladybug -o reqmd ./cmd/reqmd reqmd export graph 02-trace-your-spec/ -o graph-out/Creates a LadybugDB graph database with one node per requirement and TracesTo edges for every trace link. Query with: lbug graph-out/reqmd-graph.lbugExport with verification results All export formats accept --results (see Steps 5 and 6): reqmd export html 02-trace-your-spec/ \ --results 05-verification-results-ctrf/ \ --results 06-review-documentation/ \ -o html-out/HTML gets color-coded verdict badges on measure cards; CSV gets Verdict and Verdict Source columns; Graph gets RESULT: nodes with outcome properties. What’s next You can export the standard spec tree. Now define your own schema — go to Step 4. ---## Step 3a — Live preview URL: https://reqmd.xyz/quickstart/03a-live-preview/ Description: Serve a live-reloading HTML preview while you edit your spec tree.Serve a live-reloading HTML preview while you edit your spec tree. Start the server reqmd serve 02-trace-your-spec/This opens a browser at http://localhost:8080 showing the HTML export with live reload. Every time you save a .md or schema.yaml file, the browser auto-refreshes via SSE (Server-Sent Events). Flags Flag Default What it does --addr localhost:8080 Listen address --headless false Terminal-only mode (no HTTP server) --no-open false Don’t open a browser on start --debounce 500ms Debounce window for file-change events --results (none) Load verification results (CTRF .ctrf.json or manual-results dirs). Repeatable. Result file changes also trigger rebuild. Usage # Default — opens browser reqmd serve 02-trace-your-spec/ # Terminal-only (remote server, CI) reqmd serve 02-trace-your-spec/ --headless --addr 0.0.0.0:8080 # With verification results — verdict badges on measure cards reqmd serve 02-trace-your-spec/ --results 05-verification-results-ctrf/ reqmd serve 02-trace-your-spec/ --results 06-review-documentation/With verification results Pass --results (repeatable) to load CTRF or manual verification results. Verdict badges appear on measure cards (pass / fail / skipped / inconclusive). Result files are watched alongside spec files — editing a CTRF JSON or manual-results markdown triggers an immediate rebuild and browser refresh. reqmd serve 02-trace-your-spec/ --results 05-verification-results-ctrf/The failing-verdict graph check runs on every rebuild: a fail verdict on a measure produces an ERROR-level finding, turning the status line red. What’s next Now compare two baselines — go to Step 3b. ---## Step 3b — Baseline diff URL: https://reqmd.xyz/quickstart/03b-baseline-diff/ Description: Compare requirement baselines between two git tags — no checkout needed.Compare requirement baselines between two git tags — no checkout needed. How it works reqmd baseline diff extracts the repository at each tag via git archive | tar, parses both versions through the standard pipeline, and produces a semantic diff: Requirements: added (+), removed (-), modified (~) with attribute-level detail Schemas: new/removed properties, changed required fields Submodules: added/removed/updated submodule pins The command always exits 0 — the diff is informational, not validation. Try it For a Git-backed spec repo: # Compare two release tags reqmd baseline diff v1.0.0 v1.1.0Example output: Requirements + IVI-FUN-004 added in v1.1.0 - IVI-FUN-002 removed in v1.1.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"] -> ["priority","maturity","status","verify","owner"]JSON output for CI reqmd baseline diff v1.0.0 v1.1.0 --jsonProduces a structured report suitable for release-note generation or CI gating. Submodule changes When the repo has git submodules, the diff also reports submodule pin changes: --- Submodule Changes --- vendor/spec-a: a1b2c3d → e4f5g6h (updated) vendor/spec-b: f7g8h9i → (removed) vendor/spec-c: (added) → j0k1l2mThis section is hidden when no submodules exist. What’s next Now define your own schema — go to Step 4. ---## Step 4 — Custom templates URL: https://reqmd.xyz/quickstart/04-custom-templates/ Description: Define your own requirement schema with a custom reqmd init preset.Define your own requirement schema with a custom reqmd init preset. What’s in this folder 04-custom-templates/ preset/ # the custom preset directory schema.yaml.tmpl # Go template for schema.yaml example.md.tmpl # Go template for the example .md fileThis preset defines a custom requirements template with: priority (required) — low, medium, high, critical verification-method (required) — test, review, analysis, inspection, demonstration owner (optional) — responsible team Scaffold from the custom preset reqmd init my-safety/ --preset 04-custom-templates/preset/ --id-prefix SCThis produces: my-safety/ schema.yaml # rendered from schema.yaml.tmpl requirements.md # rendered from example.md.tmplValidate the scaffolded output reqmd check my-safety/Expected: two requirements (SC-001, SC-002) pass validation. Template variables Both .tmpl files use Go text/template syntax with: Variable Source Example {{ .ID }} --id flag or dir basename my-safety {{ .Title }} --title flag or Requirements my-safety Requirements {{ .Level }} --level flag (default requirements) requirements {{ .IDPrefix }} --id-prefix flag SC Create your own preset Create a directory with schema.yaml.tmpl + example.md.tmpl (or plain schema.yaml + any .md file — no template syntax needed) Use {{ .ID }}, {{ .Title }}, {{ .Level }}, {{ .IDPrefix }} variables Scaffold with reqmd init --preset / What’s next You can scaffold custom document types. Now load verification results — go to Step 5 for CTRF automated results or Step 6 for manual review results. ---## Step 5 — Verification results (CTRF) URL: https://reqmd.xyz/quickstart/05-verification-results-ctrf/ Description: Load automated test results in CTRF format and run outcome-gated checks against your spec tree.Load automated test results in CTRF format and run outcome-gated checks against your spec tree. What’s in this folder 05-verification-results-ctrf/ boot-tests.ctrf.json # CTRF report: TEST-001 passed coverage.json # NOT a CTRF file; auto-skipped silentlyHow CTRF maps to requirements CTRF test entries map to measures (requirements with a verify attribute) via the x-reqmd.id extra field: { "name": "Test_Boot_Time", "status": "passed", "extra": { "x-reqmd": { "id": "TEST-001" } } }CTRF status → reqmd outcome: CTRF status reqmd outcome passed pass failed fail skipped skipped pending / other inconclusive any + flaky: true inconclusive Run outcome-gated checks reqmd check 02-trace-your-spec/ --results 05-verification-results-ctrf/When results are loaded, reqmd runs two additional checks: Check Level When it fires missing-verdict WARNING An approved measure (verify: attr) has no result failing-verdict ERROR A measure’s latest result has outcome fail The coverage.json file in this folder is silently skipped — reqmd auto-detects it’s not a CTRF file (no results.tests[] object). Export with verdicts # HTML with color-coded verdict badges (green=pass, red=fail, etc.) reqmd export html 02-trace-your-spec/ --results 05-verification-results-ctrf/ -o html-out/ # CSV with Verdict and Verdict Source columns reqmd export csv 02-trace-your-spec/ --results 05-verification-results-ctrf/ -o csv-out/What’s next CTRF covers automated tests. Manual verification methods (review, inspection, analysis) are documented as markdown — go to Step 6. ---## Step 6 — Review documentation URL: https://reqmd.xyz/quickstart/06-review-documentation/ Description: Load manual verification results (review, inspection, analysis, demonstration) recorded as markdown with a user-supplied schema.Load manual verification results (review, inspection, analysis, demonstration) recorded as markdown with a user-supplied schema. What’s in this folder 06-review-documentation/ schema.yaml # schema for manual results design-review-results.md # VR-001: design review for TEST-002 (pass)Manual results format Manual results are markdown files with attr blocks, just like requirements — but the schema declares result-specific attributes: # schema.yaml x-reqmd: level: verify-results required: [outcome, verifier, verified-at] properties: outcome: type: string enum: [pass, fail, skipped, inconclusive] verifier: type: string evidence: type: string verified-at: type: stringEach result is a heading with an attr block: ## VR-001: Boot Sequence Design Review Result ```attr status: approved outcome: pass verifier: "A. Reviewer" evidence: minutes/2026-07-15-boot-review.md verified-at: "2026-07-15" trace: [TEST-002] The `trace` attribute links the result to the measure it verifies. ## Scaffold a results directory Use the built-in `results` preset: ```sh reqmd init my-reviews/ --preset results --id-prefix VRThis creates schema.yaml + results.md with one example result. Run checks with manual results reqmd check 02-trace-your-spec/ --results 06-review-documentation/Combine automated + manual results reqmd check 02-trace-your-spec/ \ --results 05-verification-results-ctrf/ \ --results 06-review-documentation/Both result sources are merged — if a measure has results from both CTRF and manual sources, the latest verified-at wins. Export with manual verdicts reqmd export html 02-trace-your-spec/ \ --results 06-review-documentation/ -o html-out/That’s it You’ve worked through the full reqmd workflow: Scaffold a project Build a traced spec tree Export to CSV/HTML/graph Define custom templates Load automated test results (CTRF) Load manual review results For the full spec, see the README and AGENTS.md. ---## Quickstart URL: https://reqmd.xyz/quickstart/ Description: Install reqmd and take a seven-step tour of the workflow — from your first requirement to a fully traced V-model spec tree, validated and exported.In the next 10 minutes you can go from a fresh reqmd install to a fully traced V-model spec tree, validated and exported. Work through the steps in order — lettered steps are optional detours. The seven steps Step Folder What you’ll learn 0 Installation go install, build from source, or prebuilt binary 1 Get started Scaffold a new project and run your first validation 1a CI integration JSON reports, exit codes, GitHub Actions 2 Trace your spec Build a four-level V-model with trace links 2a Status & disposition The draft/approved lifecycle and deferred/rejected workflow 2b Version pins Pin traces to a specific upstream version; detect when stale 2c Repin Bulk-update ~N version pins with reqmd repin --yes 3 Export CSV, HTML, and graph export formats 3a Live preview reqmd serve with live-reloading HTML 3b Baseline diff Compare requirements between two git tags 4 Custom templates Define your own schema with a custom reqmd init preset 5 Verification results (CTRF) Load automated test results and run outcome-gated checks 6 Review documentation Load manual review, inspection, and analysis results Suggested paths New users: 00 → 01 → 02 → 03 → 04 → 05 → 06 CI/automation focus: 00 → 01 → 01a → 02 → 03b → 05 Status & lifecycle focus: 00 → 01 → 02 → 02a → 02b → 05 → 06 Prerequisites Build the reqmd binary: go build -o reqmd ./cmd/reqmdEach step’s page shows the exact commands to run. Paths are relative to the project root. The full source for every step lives in the quickstart/ directory of the repo. Beyond the spec itself: the companion reqmd-import tool extracts requirement IDs from Go and Python source via tree-sitter. After you’ve written the spec for a feature, run reqmd-import extract and the implementation gets IDs in the same namespace — closing the loop from spec to code. ---## reqmd-import URL: https://reqmd.xyz/import/ Description: Source-code traceability — close the gap from code to spec by extracting requirement IDs from Go and Python source.A source-code extractor that reads your Go or Python code, walks each file with a tree-sitter grammar, and writes per-package .md files into your spec tree. Every function, type, and method becomes a reqmd requirement. The source is annotated as provenance, the symbol kind is preserved, and the doc comment becomes the requirement body. The result is a spec tree where the code and the spec share an ID space. This is what closes the traceability gap from code to spec. Without it, you have two artifacts that reference each other in different vocabularies. With it, the agent (and the human) can follow a trace from a stakeholder requirement to the system requirement to the software requirement to the function that implements it. What it does reqmd-import extract ./internal ./spec/03-software/importedThe extractor: Walks ./internal for files matching any registered language plugin. Parses each file with the language’s tree-sitter grammar. Extracts every symbol: package, function, method, type, constant, variable. Renders one .md file per package into ./spec/03-software/imported/, with one ## IMP-... heading per symbol. Writes a schema.yaml for the target dir (id-prefix IMP-, marks everything as status: approved and x-reqmd.imported: true). The reqmd CLI now validates the target with the rest of the spec — same trace checks, same CI gate. The output is a normal reqmd document. It can be checked, listed, exported, and diff’d like any other. The x-reqmd.imported: true flag and the HTML-comment marker tell readers and tooling that the file is auto-generated; the writer’s idempotent write-if-changed path won’t touch hand-authored content in the same target tree. Sample output Given internal/cli/check_test.go, the extractor emits a file like spec/03-software/imported/cli/package.md: # Package: cli This file is auto-generated by reqmd-import. Do not edit by hand. ## IMP-cli-BenchmarkRunValidationPipeline-80e6286: BenchmarkRunValidationPipeline ```attr status: approved x-reqmd.imported: true x-reqmd.source-file: internal/cli/check_test.go x-reqmd.source-line: 19 x-reqmd.symbol-kind: function trace: []BenchmarkRunValidationPipeline measures the cost of the full validation pipeline (Pass 1 schema compile + per-req validation, plus Pass 2 graph build + trace checks) against the spec/ fixture (6 documents, 249 requirements). The ID format is `IMP---<7charhash>`. The hash is computed over `(package, symbol name)` so IDs survive line-number shifts — a refactor that moves code around does not invalidate the trace. The attr block carries: - `status: approved` — generated items count as upstream coverage providers by default. - `x-reqmd.imported: true` — flag that tells the schema validator these came from the importer. - `x-reqmd.source-file` and `x-reqmd.source-line` — provenance back to the source. - `x-reqmd.symbol-kind` — `function`, `method`, `type`, `const`, `var`, etc. - `trace: []` — empty by default. Populated by `--heuristic-traces` (see below) or by hand. ## The trace gap Plain Markdown traceability has a directional problem. A software requirement can `trace: [system-requirements/SYS-001]` and reqmd validates that SYS-001 exists in the upstream document. But the *implementation* — the function in `internal/foo/bar.go` that actually implements the software requirement — has no native concept of a "reqmd ID". Without help, you have to either: - Manually maintain a mapping table somewhere (a spreadsheet, a comment, a separate `.md` file with hand-rolled `IMP-foo-FooBar-...` IDs that you have to keep in sync with the code). - Use a separate IDE plugin to jump from code to spec. - Give up and accept that the spec only goes down to the test layer. `reqmd-import` does the first option automatically. After a one-shot `reqmd-import extract`, the IDs exist in the spec tree. The agent and the human can grep for them, link to them, and the CI check enforces that they still resolve. When the function is renamed or moved, the next `reqmd-import extract` updates the file; if the ID prefix is unchanged (because it's a hash, not a position), the spec tree still references the same requirement. ## Usage ```sh # Build go build -o reqmd-import ./cmd/reqmd-import # One-shot extraction reqmd-import extract ./internal ./spec/03-software/imported # Restrict to one language reqmd-import extract --lang go ./internal ./spec/03-software/imported-go reqmd-import extract --lang python ./src ./spec/03-software/imported-py # Also extract bare requirement IDs from prose (not just explicit markers) reqmd-import extract --heuristic-traces ./internal ./spec/03-software/imported # Custom id-prefix (default: IMP-) reqmd-import extract --id-prefix MY- ./src ./spec/mine--heuristic-traces looks for bare IDs in the source code’s doc comments and prose (e.g. // implements SYS-001) and populates the trace: field automatically. This is how you wire the spec tree to the source without writing each trace by hand. After the extraction, validate like any other spec dir: reqmd check ./spec/The generated files participate in every check just like hand-authored ones. If you delete a function and re-run the extractor, the corresponding requirement disappears from the spec, and any upstream trace: [IMP-...] line becomes a broken-ref WARNING. Languages Language Status Tree-sitter grammar Notes Go Stable tree-sitter-go Functions, methods, types, constants, variables. Method receivers are part of the ID (Foo.Bar). Python Stable tree-sitter-python Functions, classes, methods, constants. Async functions are tagged in the symbol-kind. Rust Not implemented — The registry slot is reserved; contributions welcome. Zig Not implemented — Same. To add a new language: implement the lang.Language interface in a new package under internal/lang//, and self-register it via lang.Register(&impl{}) in an init() block. The blank import in cmd/reqmd-import/main.go pulls all plugins into the binary. Where it fits in the workflow A typical end-to-end loop: # 1. Author the spec by hand for stakeholder / system / software reqmd init my-feature/ $EDITOR my-feature/stakeholder/goals.md $EDITOR my-feature/system/features.md $EDITOR my-feature/software/components.md reqmd check my-feature/ # pass # 2. Write the code, referencing the spec $EDITOR src/foo/bar.go # ...function that implements [system-features/SYS-001]... # 3. Extract the spec from the code reqmd-import extract ./src ./my-feature/03-software/imported # 4. Re-validate reqmd check my-feature/ # still pass # 5. CI runs the same check on every PR # .github/workflows/reqmd-check.yml: # - run: reqmd check spec/ # 6. The agent can now follow a trace end-to-end # "Find the function that implements SYS-001" $ grep -r "IMP-foo-Bar" spec/ src/ spec/03-software/imported/foo/package.md:## IMP-foo-Bar-... src/foo/bar.go:func Bar() error { // implements SYS-001The agent — and the human — can now answer questions like: What functions implement SYS-001? — grep trace spec/03-software/imported/ | grep SYS-001 What spec IDs does foo/bar.go correspond to? — reqmd ls spec/03-software/imported/foo/ | grep -i "source-file:.*bar" What code is unstested? — load CTRF test results with reqmd check spec/ --results ctrf.json; the existing missing-verdict check fires on measures with no test. What it doesn’t do Three things, deliberately: It doesn’t guess traceability. The default is trace: [] for every generated item. You either annotate the source with // reqmd:trace: [SYS-001] markers, or run with --heuristic-traces, or hand-fill the trace: field in the generated .md. The tool surfaces the source; the trace is yours to declare. It doesn’t update the spec in place on every commit. You re-run the extractor when you want to refresh. This is a deliberate trade-off — incremental generation adds complexity (and the possibility of subtle drift) for a workflow that’s typically a once-per-PR or once-per-release concern. It doesn’t reach into binary artefacts. It reads source. It doesn’t introspect compiled binaries or runtime behaviour. If you need that, you’d add a separate runtime-instrumentation step. Architecture The extractor is structured as a small pipeline: walkdir (per-file) → language plugin (tree-sitter parse) → symbol list (functions, types, constants) → trace inference (explicit markers + heuristic) → writer (renders per-package .md, idempotent)Each stage is independently testable; the writer’s idempotency guarantee (byte-identical output for unchanged inputs) is what makes the import step safe to re-run in CI. The tree-sitter grammars are loaded once at startup; the per-file parse is dispatched to a worker pool sized to runtime.NumCPU(). See also Quickstart — the rest of the workflow, from reqmd init to verification roll-up. Use cases — where reqmd-import sits in the engineering workflow. Compare — how reqmd + reqmd-import compares to other tools. The reqmd-import source — see internal/cli/extract.go, internal/lang/, and internal/extractor/ for the implementation. ---## AI & agents URL: https://reqmd.xyz/ai/ Description: Why reqmd's plain-markdown + JSON format is the right substrate for AI-assisted spec workflows, and how an agent drives the loop.reqmd is designed for the agent era. Every artifact an agent needs — the spec, the schema, the trace graph, the validation result, the verdict — is a plain text file on disk or a JSON blob on stdout. There is no database to query, no REST API to authenticate against, no UI to drive. The agent can read, write, and validate specs as fast as it can read and write code. This page is written for two audiences. If you’re building an agent, you’ll find the loop, the AGENTS.md recipe, and the patterns below. If you’re evaluating reqmd against UI-based ALM tools, the comparison table at the end is the short version; the rest is the long version with receipts. The agent loop A spec-writing agent drives a tight four-step loop. Each step is fast enough to sit in the same tool call budget as reading a file: ┌─────────────────────────────────────────────────────┐ │ 1. READ cat spec/02-system/features.md │ │ 2. EDIT write the new SYS-007 heading + attr │ │ 3. CHECK reqmd check spec/ (16 ms, exits 0/1/2) │ │ 4. JSON reqmd check --json spec/ (parse verdict)│ └─────────────────────────────────────────────────────┘ ↓ iterate on ❌ findingsThe check is the contract. The agent doesn’t read the spec to “understand” it — it reads the JSON verdict, sees the failed checks, and fixes them. The same loop works for: Writing a new requirement (edit, check, fix id-prefix mismatch + missing upstream). Closing a trace gap (read requires-trace-from, write a downstream requirement, check again). Bumping a spec version (read all ~N pins against the upstream, run reqmd repin to fix the outdated findings, or use --relaxed-versions for the ones that don’t matter). Adding a verification result (read CTRF JSON or a manual-results file, run check --results, fix any failing-verdict or missing-verdict). All four exit with one of three codes: 0 clean, 1 validation errors, 2 parse error. The agent branches on the code, reads the JSON, and knows what to do. Why plain text beats a database UI-based ALM tools — Jama, Polarion, Siemens Teamcenter, IBM DOORS, codeBeamer — model requirements as rows in a relational schema. The agent doesn’t see those rows; it sees a REST API and a web UI. Three things go wrong: The prose is hidden. A requirement is id, title, description, priority, status, parent_id, and a foreign-key chain to a hundred other tables. The actual content of the requirement — the prose, the rationale, the body — is a single text column the agent has to fetch and re-format every time. The trace graph is opaque. “Where does SYS-007 trace to?” requires either a UI session or a paginated REST call that returns IDs but not context. The agent has to follow references by hand, across multiple round-trips, to recover what reqmd makes a single 16 ms read. Review is impossible. When the agent writes a new requirement through the API, the change shows up in the UI but the diff is unreadable. A reviewer looking at the agent’s PR sees a JSON blob in the audit log, not a Markdown paragraph they can mark up in GitHub. reqmd’s model is the opposite. A requirement is a level-2 heading, a YAML attr block, and free-form prose. The agent edits text. The diff is text. The review is text. The check is a binary that returns text. The whole pipeline is in text. The format is the API Every operation the agent needs maps to one CLI invocation. The full command surface: Need Command Output Validate a spec reqmd check spec/ text + exit code 0/1/2 Get structured findings reqmd check --json spec/ JSON Validate with V&V results reqmd check spec/ --results ci-out/ text + exit code Validate single file reqmd check file.md -s schema.yaml text + exit code Demote version-pin errors reqmd check spec/ --relaxed-versions text + exit code List all requirements reqmd ls spec/ table Same, structured reqmd ls --json spec/ JSON Coverage stats reqmd stats spec/ text Same, structured reqmd stats --json spec/ JSON Scaffold a new doc dir reqmd init my-feat/ --id-prefix SYS scaffolded dir Scaffold ASPICE template reqmd init my-feat/ --preset aspice scaffolded dir Scaffold results dir reqmd init my-results/ --preset results --id-prefix VR scaffolded dir Update version pins (dry-run) reqmd repin spec/ change list Apply version pins reqmd repin spec/ --yes applied changes Promote unpinned refs reqmd repin spec/ --yes --promote-unpinned applied changes Live HTML preview reqmd serve spec/ HTTP + SSE Export to HTML reqmd export html spec/ -o docs/ HTML files Export to CSV reqmd export csv spec/ -o csv/ CSV files Export to graph DB reqmd export graph spec/ -o g.lbug (needs -tags ladybug) LadybugDB Compare two git tags reqmd baseline diff v1.0 v2.0 text diff Same, structured reqmd baseline diff v1.0 v2.0 --json JSON That’s the entire surface. No API key, no auth, no rate limit, no SDK to install. The agent reads reqmd --help once and has the full vocabulary. See the cheat sheet for example outputs of every command. The schema is the contract Each document directory has a schema.yaml that defines the required attributes and the trace topology. The agent must read it before adding a new requirement — rejected schemas are config errors. The key fields: # Standard JSON Schema 2020-12 fields: $schema: "https://json-schema.org/draft/2020-12/schema" $id: "my-requirements" # relative URI, resolves against file path title: "My Requirements" # shown in HTML export and stats type: object # always object (attributes of a requirement) required: [priority] # attributes that must be present properties: priority: type: string enum: [Critical, High, Medium, Low] additionalProperties: false # reject attributes not in properties # reqmd-specific extension: x-reqmd: level: system-requirements # V-model level for this document document-id: system # short identifier for qualified refs id-prefix: SYS- # prefix for requirement IDs (SYS-001, SYS-002) upstream: # valid upstream sources for trace links level: stakeholder-needs sources: - ../01-stakeholder/ mandatory-disposition: true # every requirement needs a disposition external: false # external reference reqs (imported, not authored) additional-status-values: [review] # extend [draft, approved] with custom values ignore-status: false # all reqs count as coverage regardless of statusBuilt-in attributes (recognized automatically) Attribute Description trace Array of upstream IDs. Supports ~N version pins (e.g. SYS-001~3). requires-trace-from Declares expected downstream coverage. status draft or approved. Only approved counts as coverage. disposition implemented, deferred, or rejected. Required when mandatory-disposition: true. version Integer version. Used by version-pin staleness checks. verify Verification method: Test, Review, Inspection, Analysis, Demonstration. reqmd-suppress Array of check names to suppress (e.g. [version-pin, missing-verdict]). external If true, this is an external reference requirement. See the cheat sheet for the full schema reference and every x-reqmd option. A copy-pasteable AGENTS.md Drop this into the root of a spec repo. The agent reads it once per session and has everything it needs: # Spec workflow This repo is a [reqmd](https://reqmd.xyz) spec. The agent drives it as follows. ## What reqmd is Single-binary Go CLI. Validates a directory of `.md` files against per-directory JSON Schema (YAML) with bidirectional trace checks. Exit codes: 0 (clean), 1 (validation errors), 2 (parse error). See for a machine-readable index of the docs. ## Hard rules 1. **Read before write.** Never add a requirement without first reading the parent document and at least one downstream that traces to it. 2. **Edit, don't rewrite.** A change to a requirement is a heading-level edit, never a file rewrite. Preserve the prose, the rationale, the history. 3. **Run `reqmd check` after every edit.** It runs in 16 ms on this repo. If it exits non-zero, read the JSON output and fix the findings before continuing. Don't batch edits. 4. **Never touch `id` once it's set.** IDs are the trace target. If you need to change a requirement's identity, write a new one and deprecate the old with `disposition: rejected`. 5. **Use `requires-trace-from: []` to opt out of coverage**, not a missing `trace:`. A missing attribute is ambiguous; an explicit empty list is a contract. 6. **Check the schema before adding a new attribute.** Read `/schema.yaml` — if the attribute isn't in `properties`, it will be rejected (`additionalProperties: false`). ## The loop ``` read spec//.md # the current state edit write the change (heading + attr + prose) check reqmd check spec/ # ~16 ms, exits 0/1/2 json reqmd check --json spec/ # parse findings, fix ❌ ``` The check is the contract. Don't ship an edit that exits non-zero. ## All commands | Need | Command | |---|---| | Validate the whole tree | `reqmd check spec/` | | JSON for parsing | `reqmd check --json spec/` | | Validate with V&V results | `reqmd check spec/ --results ci-artifacts/` | | List all requirements | `reqmd ls spec/` | | Coverage stats | `reqmd stats spec/` | | Add a new doc dir | `reqmd init my-feat/ --id-prefix SYS` | | Update version pins | `reqmd repin spec/ --yes` | | Live HTML preview | `reqmd serve spec/` | | Export to HTML | `reqmd export html spec/ -o docs/` | | Export to CSV | `reqmd export csv spec/ -o csv/` | | Compare two tags | `reqmd baseline diff v1.0 v2.0` | | Find broken trace refs | `reqmd check spec/ \| grep "broken reference"` | ## Schema Each document dir has a `schema.yaml`. Key `x-reqmd` fields: - `id-prefix: SYS-` — prefix for requirement IDs - `upstream.sources: [../01-stakeholder/]` — where trace links can point - `mandatory-disposition: true` — every requirement needs a disposition - `external: true` — imported reference requirements, not authored Built-in attributes: `trace`, `requires-trace-from`, `status`, `disposition`, `version`, `verify`, `reqmd-suppress`, `external`. ## Status & disposition - `status: draft` — work in progress, doesn't satisfy coverage. - `status: approved` — signed off, counts as coverage provider. - `disposition: implemented` — actively developed. - `disposition: deferred` — accepted, postponed; needs `disposition-reason`. - `disposition: rejected` — not accepted; needs `disposition-reason`. ## Version pins If a requirement depends on a specific upstream version, pin the trace: `trace: [UP-001~3]`. When the upstream `version` is bumped, the `version-pin` check fires. Use `reqmd repin spec/ --yes` to bulk-update all outdated pins. Demote outdated pins with `--relaxed-versions` if the change is non-substantive. ## What NOT to do - Don't introduce a new field in `attr` without checking `/schema.yaml` first. Rejected schemas are config errors. - Don't drop the YAML fence language (`attr`) — it's how the parser finds the attribute block. - Don't add a `trace:` without confirming the target ID exists in some document. Use `reqmd ls spec/ | grep ID` to verify.The file is plain markdown, lives in the repo, and is read by humans and agents. One source of truth. Patterns Six patterns the agent can mix and match. 1. Spec-from-issue A user files an issue. The agent reads it, drafts a stakeholder-level requirement, writes it to the right document, checks, and posts a PR. The PR carries the new requirement, the trace to the parent goal, and the rationale — all in one diff. reqmd check spec/ # baseline: clean $EDITOR spec/01-stakeholder/ # write the new goal reqmd check spec/ # expect: 0 new findings reqmd check --json spec/ # post as a PR comment2. Coverage repair The CI check fails with a requires-trace-from warning. The agent reads the JSON, finds the requirement with no downstream coverage, and either adds a downstream (preferred) or annotates the upstream with requires-trace-from: [] (acceptable when there’s a real reason). 3. Spec validation in the agent loop The agent writes a spec for a feature it’s about to implement. The spec goes in a doc dir. The agent runs reqmd check after every edit. By the time the implementation lands, the spec already passes. $EDITOR spec/02-system/features.md # draft the feature reqmd check spec/ # find issues $EDITOR spec/02-system/features.md # fix reqmd check spec/ # clean4. Version-pin watch The agent is asked to bump the version of an upstream requirement. It runs reqmd repin to bulk-update all outdated pins: reqmd repin spec/ # dry-run: see what would change reqmd repin spec/ --yes # apply reqmd repin spec/ --json # machine-readable outputOr, to just report which downstreams will need re-verification without fixing: reqmd check spec/ --relaxed-versions | grep "version-pin"5. Verification roll-up The agent has a CTRF report from a CI run. It passes the path to reqmd check and the spec is checked with the latest verdicts: reqmd check spec/ --results ./ctrf.json # exits non-zero if any measure's latest result is "fail" reqmd check --json spec/ --results ./ctrf.json | jq '.documents[].requirements[] | select(.checks[]?.level == "ERROR")'The failing-verdict and missing-verdict checks behave like the trace checks: ERROR fails CI, WARNING is informational, and the JSON output is shaped for parsing. 6. Closing the spec → code loop with reqmd-import The agent has a function ready to ship but no ID in the spec for it. Run the source-code extractor to generate per-package IMP-... requirements, then re-check: reqmd-import extract ./internal ./spec/03-software/imported reqmd check spec/ # passEach generated requirement carries x-reqmd.source-file and x-reqmd.source-line provenance, so the agent can answer “where is this requirement implemented?” by reading the file. The companion reqmd-import page has the full reference; the takeaway is that the spec and the code now share an ID space, and the same reqmd check loop that catches broken upstream refs also catches broken implementation refs. Why this is better than UI-based ALM tools A spec row in a UI-based ALM is an object the agent can’t see. A spec paragraph in reqmd is a file the agent can read. That’s the whole difference, but the consequences compound: Concern UI-based ALM (Jama, Polarion, Teamcenter, DOORS) reqmd Spec format Rows in a relational schema, prose in a text column Plain Markdown + YAML Agent reads spec REST GET, paginated, returns IDs not context cat spec//.md Agent writes spec REST POST, returns a JSON audit log entry echo "## REQ-001" > spec//.md Trace graph REST GET, foreign keys, paginated joins reqmd ls spec/ (one read) Review of an agent’s change Replay the REST call in the UI; diff is invisible Standard Git diff, in the PR, in Markdown Spec + code in one PR No — spec and code live in different systems Yes — same repo, same PR, same CI Cost of a typo Server round-trip, possible transaction sed -i in your editor Cost of a schema change Migration script + admin review Edit schema.yaml, check, done Verification roll-up REST query, custom report, export to PDF reqmd check spec/ --results ctrf.json Baseline diff UI tool, “compare two baselines” wizard reqmd baseline diff v1 v2 Version pin staleness Report generator + email reqmd check spec/ (built-in check) Setup time Days (license, install, integrate, train) 30 seconds (go install) Lock-in Vendor-specific data model, hard to extract Plain text, you already have it The last row is the one that matters. A spec written in a UI-based ALM is, at the byte level, a vendor’s view of your requirements. A spec written in reqmd is, at the byte level, a Markdown file in a Git repo. The agent doesn’t have to choose between “use the tool” and “own your data.” It gets both. See also Quickstart — a 10-minute tour of the loop. Cheat sheet — full command reference with example outputs and schema.yaml options. Use cases — what reqmd is designed for, and what is out of scope. reqmd-import — the source-code traceability tool that closes the loop from code to spec. llms.txt — a machine-readable index of this site for agents. llms-full.txt — the full plain-text dump of every page. FAQ — the questions an integrator asks. ---## Compare URL: https://reqmd.xyz/compare/ Description: How reqmd compares to sphinx-needs, OpenFastTrace, IBM DOORS, Jama, and Polarion — and why git-native beats database-backed.reqmd is a different kind of requirements tool. Instead of a database and a web UI, it puts your spec in plain Markdown files inside a Git repository. That choice changes everything that follows — how fast it is, how it integrates with code, how branching works, how CI validates it, and how developers actually interact with it. This page compares reqmd against the other tools teams reach for. Three groups: git-native static tools (sphinx-needs, OpenFastTrace), database-backed RM suites (DOORS, Jama, Polarion, Siemens Teamcenter, codeBeamer), and issue-tracker-shaped ALM tools (Azure DevOps Boards). Quick decision If you need… Use Plain Markdown in git, no Python, no database, AI-agent-friendly reqmd Sphinx-rendered docs with .. req:: directives and Python tooling sphinx-needs XML-based spec coverage analysis, Java ecosystem OpenFastTrace Full RM suite: workflows, audit trails, role-based approvals, baselines Jama / Polarion / Siemens Teamcenter DOORS-class requirement management with deep links to engineering artifacts IBM DOORS Next Issue-tracker-shaped requirements with ALM features built in codeBeamer, Azure DevOps reqmd vs sphinx-needs Both are git-native, text-first, no-database tools for spec authoring with trace checks. The right pick depends on whether your spec lives inside a Sphinx docs site or a standalone repo. reqmd sphinx-needs Format Plain Markdown + YAML attr block reStructuredText with .. req:: directives Schema JSON Schema 2020-12 in YAML Sphinx-config-driven type system, per-type schema Storage Files on disk Sphinx doctree pickle (.doctree/) + JSON Runtime Single Go binary, no dependencies Python 3 + Sphinx + a dozen plugins Parse time 16 ms / 249 reqs (16 cores) Seconds at 8k reqs (single-threaded, includes Sphinx’s full pipeline) Web UI Static HTML export + reqmd serve for live preview needsbuild built-in (read-only viewer) Trace graph Built in memory on every check; ephemeral Stored in doctree; queryable via needflow and needtable directives Verification results check --results reads CTRF + manual-results markdown; 13 graph checks test_impact reads junit XML; older, less coverage of CTRF CI loop reqmd check exits 0/1/2; 16 ms sphinx-build -W exits non-zero on broken ref; seconds Type system JSON Schema enums (e.g. status: [draft, approved]) Sphinx type plugins (req, spec, test, story, …) — extensible in Python Custom types Edit schema.yaml, add an enum Write a Python Sphinx extension, register a directive AI agent readability One cat, plain text Sphinx doctree pickle is opaque; cat shows the RST but tracing requires a build Lock-in None Sphinx version, plugin set Learning curve One attr block syntax; 30 seconds to first check Sphinx + RST + the needs directive set; half a day Best fit Spec is a standalone repo, lives next to code, agent-driven Spec is a docs site (Sphinx-based) that needs rendering, search, theming Pick reqmd when the spec is a standalone repo next to the code, you want the agent to read/write/validate specs in the same tool call budget as code, and you don’t want a Python runtime in the loop. Pick sphinx-needs when the spec is part of a larger Sphinx docs site (the same source tree renders the user manual, the API reference, and the requirements), you need Sphinx’s theming and search, or you already have a Sphinx build pipeline and the cost of adding a third tool is higher than the cost of working inside Sphinx. The two are not mutually exclusive. A team can use sphinx-needs for the rendered, cross-linked docs site and use reqmd to validate trace changes in a pre-commit hook that runs in milliseconds, not seconds. The two formats don’t interop (RST vs Markdown) but you can have the source tree of the docs site live in a separate git submodule that doesn’t run through reqmd at all. reqmd vs OpenFastTrace OpenFastTrace (OFT) is the closest analog. Both tools are designed for “spec coverage analysis” — does every requirement have a trace to the implementing test, and vice versa? The differentiator is the format. reqmd OpenFastTrace Format Plain Markdown + YAML Custom XML (.xml) for spec items, plain text for code links Schema JSON Schema 2020-12 Implicit (covered-by/from link types only) Storage Files on disk Files on disk (XML) Runtime Single Go binary, no dependencies Java (Maven) or standalone JAR Type system Full JSON Schema Just “covered-by” and “covers” link types Trace direction Bidirectional, enforced via requires-trace-from Forward (covered-by) + reverse (covers), same idea Coverage report reqmd check shows missing coverage as a WARNING oft report produces a coverage matrix; CI-friendly exit code Version pin / staleness Yes, ~N syntax, with --relaxed-versions Yes, via the revision attribute on each spec item Verification results CTRF + manual-results markdown junit XML Spec coverage Inline within .md files (heading + attr + prose) Separate XML files per spec item Lock-in None (Markdown is universal) Low (XML is parseable, but you need the OFT convention) AI agent Same loop, 16 ms XML spec items; no prose context in the spec file Best fit Spec is documentation, the prose matters Spec is structured data, coverage matrix matters Pick reqmd when the spec is documentation — the prose is part of the deliverable, and reviewers read the requirements as paragraphs. Pick OFT when the spec is structured data — you want a coverage matrix output, and the prose lives in a separate doc that OFT links to. reqmd vs database-backed RM suites (DOORS, Jama, Polarion, Teamcenter, codeBeamer) These tools have been the default in regulated industries for 20 years. They solve a real problem — managed workflows, audit trails, role-based access — but they come with a set of structural problems that get worse as your team gets more agile and your code moves faster: Slow. Every interaction is a web UI round-trip. Opening a requirement, editing a field, checking a trace link, running a coverage report — each is a click, a page load, and a wait. A spec review that takes 10 minutes in a Git diff takes an hour in a web UI. reqmd check validates 249 requirements in 16 ms; a DOORS coverage report on the same tree takes minutes. Disconnected from the code. The spec lives in a database. The code lives in Git. There is no native connection. “Traceability to code” means a link field that someone manually maintains, or a third-party integration that syncs on a schedule. When a developer renames a function, the spec doesn’t know. With reqmd, the spec and the code live in the same Git repo (or linked submodules), and the companion reqmd-import tool extracts code symbols into the same ID space — so a rename becomes a broken trace link that CI catches. No real branching. DOORS and Jama have “baselines” — snapshots of the spec at a point in time. But you can’t branch a spec, try a change, and merge it the way you branch code. There’s no git checkout -b feature/new-requirement, no git merge, no git rebase, no pull request with a diff. If two teams need to work on the spec simultaneously, the workflow is lock-then-edit or a parallel branch that someone manually reconciles later. No developer-friendly configuration management. In DOORS and Jama, a multi-team spec is one big database with no native way to split it into per-team repos and compose them. The baseline concept is a server-side snapshot, not a Git tag. With reqmd, configuration management is built on Git submodules: each team owns their spec repo, a top-level repo assembles them, and baseline diff compares the assembled tree across tags. The submodule pins are the baseline. A configuration change is a PR that bumps a pin. This is git submodule add — developer-friendly, reviewable, and CI-gated. Not CI-native. Running “does the spec validate?” in a CI pipeline requires a REST API call, authentication, and a custom script. With reqmd, it’s reqmd check spec/ — one binary, one command, 16 ms, exit code 0/1/2. No API, no auth, no network. Not developer-friendly. Developers don’t open DOORS. They open their editor. If the spec is in a database, the developer never reads it, never edits it, and the spec drifts from the code. If the spec is in Markdown next to the code, the developer sees it in every pull request, reviews the diff, and keeps it honest. Vendor lock-in. Your spec is in a proprietary database schema. Exporting it means a vendor-provided tool, a custom script, or a CSV dump that loses the trace links. With reqmd, your data is plain text — openable in any editor, diffable with git diff, portable to any tool that reads Markdown. reqmd DOORS / Jama / Polarion / Teamcenter / codeBeamer Where the spec lives Git repo, plain files Proprietary database Speed 16 ms for 249 reqs Seconds to minutes per operation Branching Native Git branches, merges, rebase Baselines (snapshots, no merge) Configuration management Git submodules — per-team repos composed at top level; submodule pins are the baseline One monolithic database; baselines are server-side snapshots Connection to code Same repo or submodules; reqmd-import links to code symbols Manual link fields or scheduled sync CI integration reqmd check — one binary, 16 ms REST API + auth + custom script Developer workflow Edit in any editor, review in PR, merge in Git Log into web UI, click, wait Review Git diff in a pull request Web UI review threads Audit trail Git log (who changed what, when, why) First-class audit log in the database Access control Git permissions (repo-level) Per-object ACLs, role-based Named approvers / sign-off Via Git review (approve PR) Built-in workflow engine Cost Free, GPL-3.0 Per-seat licensing, often 6-figure annual cost Setup time 30 seconds (go install) Days to weeks (install, integrate, configure, train) Lock-in None — plain text Vendor-specific DB schema; export is a project AI agent fit cat files, reqmd check --json — designed for the loop REST API, OAuth, hundreds of endpoints — the prose is hidden behind the API Pick reqmd when you want the spec to live where the developers work — in Git, next to the code, with branching, submodules, CI, and pull-request review as the natural workflow. This is the right choice for agile teams, spec-first development, and any project where the spec and the code should move together. Pick a database-backed RM suite when you specifically need a process compliance surface — named approvers with electronic signatures, a regulated audit trail that an auditor reads from the tool, and role-based access at the per-object level. These are real requirements in some regulated environments, and reqmd doesn’t provide them. The complement pattern. Some teams in regulated environments use both: reqmd for the engineering spec (the one developers see, the one in the PR, the one that traces to code), and the RM suite as the system of record for the compliance version (the one that goes to the auditor). A one-way export from reqmd to the RM suite keeps them reconciled. This gives you developer agility and compliance documentation. reqmd vs issue-tracker-shaped ALM (Azure DevOps, Jira) A third category: tools that look like an issue tracker (Jira, Azure DevOps Boards) but add requirements-specific features on top. They share the same structural problems as the database-backed RM suites — the spec is in a database, not in Git, and the same limitations apply: reqmd Azure DevOps / Jira Spec format Markdown + YAML Work item (DB row) with a custom field schema Where it lives Git repo The ALM platform’s DB Branching Native Git branches Not supported — work items live in one project Configuration management Git submodules — per-team repos composed at top level Not possible — work items live in one project Connection to code Same repo or submodules; reqmd-import Manual link fields or git-branch references Speed 16 ms / 249 reqs Web UI round-trips; API calls CI integration reqmd check exits 0/1/2 Native to the ALM platform, but requires the platform Review Git PR diff Built-in review workflow with state transitions Lock-in None — plain text Vendor work-item schema Best fit Spec is documentation, developer-driven, CI-gated Spec is project-management-shaped, lives in the same tool as the tasks The trade-off is the same: if the spec is in a database, developers don’t touch it. If it’s in Git, they do. The full decision matrix A more compact version of the above, ordered by what you’ll feel first. If you need… Use reqmd? Use sphinx-needs? Use OFT? Use DOORS / Jama / Polarion? Spec lives in a git repo ✅ designed for this ⚠ works, friction ⚠ works, friction ❌ wrong shape Branching, merging, pull-request review ✅ native Git ❌ no branching ❌ no branching ❌ baselines only, no merge Configuration management via git submodules ✅ git submodules ❌ ❌ ❌ monolithic database Spec connected to code ✅ same repo or submodules + reqmd-import ⚠ separate repo ⚠ separate ❌ manual links Validation in CI, fast (16 ms) ✅ ❌ seconds ⚠ seconds ❌ server round-trip Developer-friendly (editor, not web UI) ✅ Markdown in any editor ⚠ RST in editor ⚠ XML in editor ❌ web UI only AI agent reads, edits, validates specs ✅ designed for this ❌ RST + opaque doctree ⚠ XML is verbose ❌ API is the only path Plain text, no vendor lock-in ✅ Markdown ⚠ RST, plugin-dependent ⚠ XML ❌ vendor schema Spec is a Sphinx docs site ❌ wrong shape ✅ designed for this ❌ wrong shape ❌ wrong shape Audit-ready, named approvers, sign-off records ❌ not its job ❌ not its job ❌ not its job ✅ Built-in compliance process workflows ❌ not its job ❌ not its job ❌ not its job ✅ Per-seat licensing is fine – – – ✅ Free, GPL-3.0, self-hosted ✅ ✅ ✅ ❌ What reqmd is not Two things reqmd is intentionally not, and a few that it could become: Not a process tool. reqmd doesn’t have a workflow engine, named approvers, or audit trails. If your auditor needs a sign-off record per requirement, you need a different tool (or a wrapper that produces one from the Git log). Not a UI tool. The HTML export is a view, not an editor. For authoring, you use a text editor. For review, you use GitHub. For presentation, you host the HTML. There’s no web-based “edit a requirement” experience in v1. Not a coverage matrix exporter. It emits the missing-coverage findings inline in the check output, not as a separate matrix artefact. (OFT does this; reqmd doesn’t yet.) Not a requirements database. The trace graph is built in memory on every check. If you want a persistent graph you can query, you need the export graph output to LadybugDB, or you use a commercial RM suite. See also FAQ — has the older “vs OpenFastTrace” entry with more detail. Use cases — what reqmd is designed for, in detail. Benchmarks — the performance numbers behind the claims in this page. AI & agents — why reqmd is the right shape for agent-driven workflows, in detail. ---## About URL: https://reqmd.xyz/about/ Description: reqmd's design principles, license, and the self-hosting story.reqmd is a Go CLI for writing, validating, and exporting requirement specs in plain Markdown. It’s GPL-3.0-licensed, developed in the open, and dogfoods its own format for its own spec. Design principles No lock-in. Your data is plain Markdown and YAML — openable in any editor, renderable on GitHub/GitLab, diffable with standard Git tools. No database. The trace graph is ephemeral, built in a temp directory on each invocation and discarded when done. The *.md files are the single source of truth — nothing is committed except text files. Per-directory schemas. Different subsystems (IVI, safety, system) can have different required fields and validation rules, all validated in one pass. Scale. Parses thousands of files in parallel using a runtime.NumCPU() worker pool. Dogfooding. The reqmd tool’s own requirements are defined in spec/ using the reqmd format and validate with reqmd check spec/. This ensures the format is always production-ready for the team’s own use. Self-hosted requirements | External | spec/00-aspice/ | 191 | Reference base practices (external: true) | | Stakeholder | spec/01-stakeholder/ | 5 | Stakeholder goals (top boundary, no upstream) | | Stakeholder mapping | spec/01a-aspice-stakeholder/ | 18 | Stakeholder requirements mapped to reference practices | | System | spec/02-system/ | 11 | Feature specifications | | Software | spec/03-software/ | 17 | Component-level design | | Tests | spec/04-tests/ | 7 | Test specifications (mandatory-disposition) | All 249 requirements validate cleanly: $ reqmd check spec/ # ... 249 total, 249 valid, 0 invalid, 0 parse errors $ reqmd serve spec/ # live-reloading HTML preview $ reqmd export html spec/ -o /tmp/out/Stakeholder goals (01-stakeholder) have no upstream traces (untraced warnings suppressed by boundary inference); the ASPICE base practices (00-aspice) carry external: true. The stakeholder mapping layer (01a-aspice-stakeholder) is the first fully-traced tier. License GPL-3.0 — see LICENSE on GitHub. The bundled Inter font is OFL-licensed; the chroma styles are MIT/BSD. Contributing Issues, PRs, and design discussions are all on GitHub. The codebase is small (~19 500 lines of Go across 10 packages plus cmd/) and the trace model is well-documented in AGENTS.md. For substantial changes, open an issue first to discuss. The spec/ tree is the design surface — every change to the model or the CLI is reflected there as a requirement update. ---