Skip to main content

@rqml/cli (the rqml command)

The command-line interface, and the universal substrate every integration can invoke. It is published as @rqml/cli; the installed command is rqml.

npm install -g @rqml/cli      # then: rqml <command>
# or, no install:
npx @rqml/cli <command>

It bundles @rqml/core, so it runs fully offline and its verdicts match the engine and the @rqml/mcp server.

Commands

rqml <command> [spec.rqml] [options]

init [path] Scaffold a starter spec and an AGENTS.md project marker
validate [path] XML well-formedness, XSD, and referential integrity
status [path] Spec summary: requirement count, coverage, lint findings
check [path] Deterministic enforcement gate (validation + coverage + drift)
link <id> <uri> Record an implements/verifiedBy trace edge and its drift baseline
(--update repoints an existing edge; --refresh <edge-id>
re-records only the baseline for an intentional change)
show <id> One artifact: statement, acceptance criteria, trace neighborhood
impact <id> What is affected, transitively, if this artifact changes
overview [path] Readable spec projection (whole, or --section/--id scoped)
matrix [path] Traceability matrix: status, goals, code, tests, coverage gaps
approve <id> Transition a requirement's status (--status, default approved)
gate [paths...] Block implementation of non-approved requirements (exit 2)
skeleton <kind> Print a schema-valid snippet (req | edge | testCase | stateMachine)

When no path is given, the lone *.rqml document in the working directory is used (preferring requirements.rqml).

Options

FlagMeaning
--jsonEmit machine-readable JSON (for status, check, validate, link, show, impact, matrix) — for control loops and editor hooks
--strictness <level>relaxed · standard (default) · strict · certified — how aggressively check gates
--base-dir <dir>Directory to resolve the spec and implements code links against
--spec <path>Explicit spec file for link, show, and impact (whose positional argument is an artifact id, not a path)
--type <type>Link type: implements (default) · verifiedBy
--id <id>Explicit edge id for link, or the root id for skeleton
--kind, --titleOptional locator hints recorded on the edge by link (preserved on --update unless re-stated)
--updateFor link: replace the external locator of the existing edge — matched by --id or the derived id — instead of appending, and re-record its baseline entry
--refresh <edge-id>For link: re-record the drift baseline for one intentionally changed artifact; the spec file is not touched

The agent loop

validate and check guard the ends of a spec-first task. The loop commands serve the middle — choosing work, reading one artifact, and recording what was done — so an agent (or a human) never has to hold the whole document in view or hand-edit trace XML. This is the Code and Verify half of the five-stage development process:

rqml show REQ-PAY-001                                  # read the requirement: statement,
# acceptance criteria, trace neighborhood
rqml impact REQ-PAY-001 # blast radius before touching anything
# … implement …
rqml link REQ-PAY-001 src/payments/capture.ts#capture # record the implements edge
rqml link REQ-PAY-001 test/capture.test.ts --type verifiedBy
rqml check # the gate — must exit 0

link is the workhorse:

  • It appends a schema-valid edge textually, before </trace> — XML comments and hand formatting in the spec survive untouched.
  • It writes the file only if the edited document still validates; otherwise nothing changes.
  • It derives a deterministic edge id (REQ-PAY-001E-IMPL-PAY-001); pass --id to override.
  • For implements links it records a drift baseline: a content hash of the linked artifact, stored in .rqml/baseline.json (commit it — see below).
  • It also maintains links as they age: --update repoints the existing edge in place — same id, same orientation, only the locator changes — and --refresh <edge-id> re-blesses one artifact's baseline without re-stating the URI (see Drift baselines).

skeleton exists so nobody hand-rolls invalid structure:

rqml skeleton req --id REQ-PAY-002    # a ready-to-fill <req> with acceptance criteria

matrix is the spec-health view: one row per requirement with its status, the goals it satisfies, the code that implements it, the tests that verify it, and any coverage warnings — derived from the same coverage pass as check, as a markdown table or --json, and filterable by --status / --type / --warning:

rqml matrix --warning unverified      # requirements still lacking a test

The check gate

rqml check is the deterministic enforcement gate. It composes XSD + integrity validation, trace coverage, and implementation drift into a single pass/fail verdict, and exits non-zero only when the document is invalid or has blocking drift/coverage. Coverage findings block at strict and certified — including the lifecycle-aware ones: approved requirements with no implements link, and implements edges that point at a requirement that is not yet approved (premature implementation).

Integrity validation also covers state machines: an unresolved initial state, a dangling transition endpoint, or an outgoing transition from a final state fails validation at every strictness level.

Because it invokes no language model, the verdict is reproducible — which is what makes it safe to wire into a save hook, a pre-commit hook, or CI.

rqml check --strictness strict
echo $? # 0 = pass

Drift baselines

rqml link records a sha256 hash of each linked artifact in .rqml/baseline.json. When that file exists, check reports a linked artifact as changed — its content no longer matches the hash recorded at link time — in addition to missing. Commit the baseline so CI catches both:

rqml link REQ-PAY-001 src/payments/capture.ts   # writes the edge + the baseline entry
git add requirements.rqml .rqml/baseline.json
# later, someone edits capture.ts without touching the spec…
rqml check # ✗ changed-implementation, exit 2

When the failure is unintentional drift, fix the code or the spec. When the change is intentional — the implementation was legitimately revised, or it moved — bless it explicitly instead of hand-editing the trace XML or the baseline file:

rqml link --refresh E-IMPL-PAY-001                       # content changed: re-record this edge's hash
rqml link REQ-PAY-001 src/payments/charge.ts --update # artifact moved: repoint the edge + baseline
rqml check # ✓ exit 0

Both forms are deliberately edge-scoped: nothing else is re-hashed, so unrelated drift is never silently blessed along the way.

Without a baseline, drift detection falls back to existence checks only.

Exit codes

Stable and documented, so scripts can branch on them:

CodeMeaning
0success
1validation failure (not well-formed, schema-invalid, or integrity error)
2check-gate failure (blocking drift or coverage)
64usage error

Examples

rqml init                       # scaffold requirements.rqml + AGENTS.md
rqml validate # is the spec structurally valid?
rqml status --json | jq . # coverage/lint summary as JSON
rqml show REQ-PAY-001 # one requirement as markdown (add --json for data)
rqml impact GOAL-CHECKOUT # everything that traces to/from this goal, transitively
rqml link REQ-PAY-001 src/payments/capture.ts#capture
rqml link --refresh E-IMPL-PAY-001 # bless an intentional change to linked code
rqml skeleton stateMachine # a valid lifecycle snippet to fill in
rqml check --strictness strict # CI gate