req-cli 0.2.2

Managed requirements CLI for LLM agents and humans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
// Implements REQ-0018 (structured, sectioned help browsable by name).
pub struct Section {
    pub name: &'static str,
    pub summary: &'static str,
    pub body: &'static str,
}

pub fn sections() -> &'static [Section] {
    SECTIONS
}

pub fn section(name: &str) -> Option<&'static Section> {
    SECTIONS.iter().find(|s| s.name.eq_ignore_ascii_case(name))
}

const SECTIONS: &[Section] = &[
    Section {
        name: "overview",
        summary: "What `req` is and why it exists.",
        body: "`req` is a managed requirements tool. Requirements live in a
git-tracked `project.req` file: pretty-printed JSON so diffs are
reviewable, but every mutation goes through this CLI, which enforces
best-practice rules. A SHA-256 `_integrity` field over the canonical
payload catches hand edits — the CLI refuses to load a tampered file
and tells the user to run `req repair --confirm-direct-edit`.

Humans get a `tui` browser, a local web server (`serve`), and exports
to Markdown/JSON/CSV/HTML. Agents get a `mcp` mode that speaks JSON-RPC
over stdio, exposing the same managed operations as MCP tools.

See `req help file-format` for the on-disk layout and `req help agents`
for the agent trigger table.",
    },
    Section {
        name: "concepts",
        summary: "Requirement, kind, priority, status, links.",
        body: "A REQUIREMENT has: id (REQ-NNNN), title, statement, rationale,
acceptance criteria, kind, priority, status, tags, and links.

KIND — Functional, NonFunctional, Constraint, Interface, Business.
PRIORITY — Must / Should / Could / Wont (MoSCoW).
STATUS  — Draft → Proposed → Approved → Implemented → Verified.
          Obsolete is a terminal state for retired requirements.
LINKS   — Parent, DependsOn, Conflicts, Refines, Verifies.

Functional requirements MUST have at least one acceptance criterion.
Approved/Implemented/Verified functional reqs cannot lack acceptance.",
    },
    Section {
        name: "best-practice",
        summary: "Rules the validator enforces.",
        body: "Enforced (errors block save):
  * title 5-120 characters (counted as Unicode chars, not bytes), non-empty
  * statement >= 5 words, contains shall/must/should/will, not a question
  * URLs and `inline code` are stripped before the modal-verb check, so
    `https://shall.example.com/` does NOT satisfy the rule
  * rationale non-empty
  * functional requirements need acceptance criteria
  * link targets must exist; no self-links; parent links cannot cycle
  * approved/implemented/verified functional reqs need acceptance

Warned (saved but flagged):
  * weasel words: etc, and/or, user-friendly, fast, robust, TBD, ...
  * compound statements — flagged when ANY of these hold:
      - the statement contains a semicolon
      - the statement contains more than one normative modal verb
      - the statement has 3+ comma-separated clauses joined by ' and '
  * statements longer than 80 words (likely non-atomic)
  * trailing period on the title
  * very short rationale / vague acceptance criteria

BACKTICK ESCAPE (use sparingly)

  The compound, weasel-word, and modal-verb checks all run against
  the statement AFTER stripping URLs and `inline code` spans. This
  lets you cite forbidden terms when documenting a rule
  ('the validator shall warn on `etc`, `TBD`, ...') and embed
  enumerations of identifiers, CLI flags, or REQ-IDs without
  tripping the heuristics. Use it for descriptive code citations,
  NOT to launder genuinely compound obligations into a single
  statement — that would game the validator and weaken the spec.",
    },
    Section {
        name: "workflow",
        summary: "Typical lifecycle for a requirement.",
        body: "1. `req init -n MyProject`               create project.req
2. `req add`                              guided interactive add
3. `req list`                             review the table
4. `req show REQ-0001`                    inspect one
5. `req update REQ-0001 --status proposed --reason \"team review\"`
6. `req link REQ-0002 REQ-0001 -k parent` build hierarchy
7. `req validate`                         pre-flight check
8. `req export -f markdown -o reqs.md`    publish",
    },
    Section {
        name: "file-format",
        summary: "What's in a .req file and how integrity is checked.",
        body: "On-disk format is pretty-printed JSON so the file is git-diffable.
Four reserved top-level fields sit above the project payload:

  _warning      DO NOT EDIT THIS FILE BY HAND. (one-line headline)
  _instructions multi-line array of CLI directions for whoever opens it
  _format       schema tag, currently \"req-v1\"
  _integrity    sha256:<hex> of the canonical payload

The integrity hash covers every other top-level field in canonical
form (sorted keys, no whitespace). Whitespace-only edits do not change
the hash. Semantic edits — even one priority changed from Must to
Should — do, and the CLI refuses to load until you run:

  req repair --confirm-direct-edit

This is the core safety property: structured edits only. Agents must
go through `req`; the file is plain JSON for diffability, not for
direct editing.",
    },
    Section {
        name: "agents",
        summary: "How LLM agents should drive this tool — read this first.",
        body: "This project uses the `req` CLI for managed requirements. As an
agent working on this project you MUST drive every requirements change
through `req` — never read or edit project.req directly.

WHEN TO REACH FOR `req`

  trigger                                              first command
  ---------------------------------------------------  --------------------------
  user describes new behaviour the system should have  req add ...
  starting work on a feature                           req list / req show <id>
  about to commit                                      req validate
  changed behaviour covered by a requirement           req update <id> --reason
  refactor; unsure what's load-bearing                 req coverage --path src
  finding code with no requirement link                req coverage --unlinked-files
  requirement is no longer relevant                    req delete <id> --reason
  file won't load (integrity error)                    req repair --confirm-direct-edit
  merge brought in colliding IDs                       req renumber --base origin/main

QUICK COMMAND CRIB

  req list                              # what exists
  req show REQ-0007                     # full detail with history
  req add --title ... --statement ...   # see `req add --help`
  req update <id> --status implemented --reason \"...\"
  req link <from> <to> -k parent
  req validate                          # must be clean before ship
  req coverage --path src               # spec ↔ code
  req help <section>                    # docs (overview, concepts,
                                        # best-practice, workflow,
                                        # integration, audit)

RULES

  * Statements need a normative modal verb (shall / must / should / will)
    and one obligation per requirement. The validator rejects bad input
    and warns on smells — let it. Don't argue with the validator; rewrite.
  * Pass --reason on every update / delete so history attributes the why.
  * Drop // REQ-NNNN markers in source where you implement a requirement;
    `req coverage` connects spec to code via those markers.
  * Never `cat` / `read_file` project.req. The integrity hash will block
    the next operation if you edit it by hand.

INSTALL THIS GUIDANCE INTO AGENTS.md

  req help agents --install              # idempotent; updates a managed
                                         # block between sentinel markers.
                                         # Use --path PATH for non-default
                                         # locations.

MCP (Model Context Protocol)

  An MCP server is built in. Two ways to use it:

  * Run it: `req mcp` — speaks JSON-RPC 2.0 over stdio. Pair with an MCP
    client (Claude Code, etc.).
  * Bootstrap: `req mcp --init-config` — writes a .mcp.json at the repo
    root so MCP-capable clients can launch the server automatically.

  Once connected, call tool `req_help` with {section: 'agents'} for the
  trigger table. See `req help mcp` for the full transport detail.",
    },
    Section {
        name: "web",
        summary: "Running the local web server for humans.",
        body: "`req serve --host 127.0.0.1 --port 7878` starts a minimal HTML
browser/editor. Pass `--read-only` to disable mutation endpoints.

Endpoints:
  GET  /                list view (HTML)
  GET  /r/{id}          single requirement (HTML)
  GET  /api/list        JSON list
  GET  /api/r/{id}      JSON single
  POST /api/update/{id} JSON patch (disabled if --read-only)
  POST /api/add         JSON body (disabled if --read-only)",
    },
    Section {
        name: "tui",
        summary: "The interactive terminal UI.",
        body: "`req tui` opens an interactive menu that mirrors the agent-relevant
CLI commands so a human can drive the tool without memorising flags.
The current menu covers: browse, status, next, add, update, link,
delete, validate, coverage, stale, doctor, diff, audit, export,
version, quit. REQ-0083 obliges the menu to stay one-to-one with the
CLI's agent-relevant subset; a parity test fails the build if a new
command lands without a menu entry.

Built on dialoguer — works on any terminal, no full-screen TUI.",
    },
    Section {
        name: "integration",
        summary: "Wiring `req` into a real project, including CI.",
        body: "Put `project.req` at the repo root. Keep `AGENTS.md` next to it so
agents pick up the workflow on first read.

PER-CLONE SETUP

  req hooks install                  # pre-commit + .gitattributes
  req hooks install --claude-code    # also writes .claude/settings.json
                                     # (allowlist + Stop hook)

`req hooks install` writes `.git/hooks/pre-commit` that runs
`req validate` on every staged `.req` file, and adds these
`.gitattributes` lines:

  *.req merge=req-merge        # merge driver for ID collisions
  project.req -text eol=lf     # line-ending pin (Windows autocrlf
  *.req       -text eol=lf       cannot break the integrity hash)

Activate the merge driver once per clone:

  git config merge.req-merge.name 'req merge driver'
  git config merge.req-merge.driver 'req renumber --base %O || true'

Confirm the setup any time:

  req doctor                          # exits non-zero if anything missing

CI / BUILD INTEGRATION

  Three commands belong in any CI pipeline; this project wires
  exactly these in .github/workflows/ci.yml:

  # GATING — fail the build on any of these
  req validate                                     # zero errors required
  req coverage --strict \\
    --allow REQ-XXXX --allow REQ-YYYY              # orphan/ghost gate;
                                                   # whitelist verification-only
                                                   # or policy-only requirements

  # ADVISORY — print but don't fail
  req doctor                                       # per-clone health
  req stale --path .                               # records vs current HEAD

  Optionally enforce signed commits on the spec file in CI:

  req audit --gate --require-good-signature        # exits non-zero if any
                                                   # commit touching project.req
                                                   # lacks a verifiable signature

CROSS-LINKING CODE TO REQUIREMENTS

  Drop `// REQ-NNNN` comments in your source. Then:

  req coverage                # orphans / ghosts / test-only / obsolete-in-code
  req coverage --by-file      # per-file -> REQ IDs
  req coverage --unlinked-files   # code files lacking any marker
  req coverage --remap REQ-OLD=REQ-NEW --apply    # rewrite markers in source

CODE REVIEW

  req diff origin/main..HEAD  # per-requirement changes since the base ref
  req check origin/main       # incremental validate + coverage scoped to
                              # files changed since the ref",
    },
    Section {
        name: "version-control",
        summary: "Diffs, merges, ID collisions.",
        body: "The .req file is pretty-printed JSON specifically so it diffs
cleanly in code review. The merge story has three moving parts:

  1. _integrity hash. A text merge produces a file whose hash no longer
     matches. The merge driver runs `req renumber --base %O` which
     force-loads, fixes ID collisions, and re-signs the file. If you
     resolved conflicts by hand, run `req repair --confirm-direct-edit`.

  2. ID collisions. Two branches that both ran `req add` while diverged
     allocate the same REQ-NNNN. After merging, run:

        req renumber --base origin/main

     This loads the base from git, finds requirements on your branch
     whose IDs are taken upstream, and shifts them to fresh IDs.
     Internal links are rewritten and a history entry records the move.

  3. Content conflicts (same requirement edited on both sides). These
     are real conflicts — resolve in your editor, then run
     `req repair --confirm-direct-edit` to re-sign.",
    },
    Section {
        name: "audit",
        summary: "Who changed which requirement, and was it signed?",
        body: "`req audit` walks `git log --follow` on the .req file and reports
each commit alongside its GPG/SSH signature status and signer name. Use
this in regulated environments to prove provenance:

  req audit                   # last 50 commits
  req audit -n 200 --json     # machine-readable

Signature codes mirror git's %G?:
  good           verified signature, key trusted
  good-unknown   verified, key not in your trust store
  bad            signature does not match
  expired        key expired
  revoked        key revoked
  cannot-check   key unavailable
  no-signature   commit was not signed

The _integrity hash inside the file is for *integrity* (the CLI wrote
it last) not *authenticity* (a trusted human approved it). Lean on
signed commits for the latter.",
    },
    Section {
        name: "format-policy",
        summary: "How `_format` versions evolve and what guarantees the CLI makes.",
        body: "`project.req` carries a `_format` tag at the top of the file
(currently `req-v1`). This section pins down what changes that tag
and what to expect when it does.

CURRENT VERSION

  req-v1 — the only released format. All shipping binaries read and
  write it. The schema is:
    _warning / _instructions   informational, ignored by the loader
    _format                    schema tag (required)
    _integrity                 sha256 of canonical payload (required)
    name / created / updated   project metadata
    next_id                    monotonic ID counter
    requirements               map of REQ-NNNN to Requirement objects

WHEN THE TAG BUMPS

  We bump `_format` only for changes that cannot be expressed as
  backwards-compatible additions. Backwards-compatible additions —
  new optional fields with a serde default, new enum variants used
  only in newer files — DO NOT bump the tag. Examples of changes
  that WOULD bump:
    * removing or renaming an existing field
    * changing the canonical-hash rule
    * changing how `next_id` is interpreted

ENCOUNTERING AN OLDER FORMAT

  The CLI refuses to load a file whose `_format` is older than the
  one it understands, and tells you to run:

    req migrate

  `req migrate` writes a sibling backup (project.req.bak-<oldver>),
  upgrades the file in place, recomputes `_integrity`, and appends
  a synthetic history entry to each requirement whose shape changed.

ENCOUNTERING A NEWER FORMAT

  The CLI refuses to load a file whose `_format` is NEWER than its
  own. The error advises upgrading the binary rather than silently
  attempting to read it — silent reads of unknown-shape files are
  the bug class this policy exists to prevent.

DOWNGRADE

  The CLI does not provide a downgrade path. Once a file is migrated
  to a newer format, the prior `.bak` is the only way back; restoring
  it requires no special tooling (it's just JSON on disk).

PROMISE

  No `_format` bump will silently change semantic behaviour of an
  already-stored requirement. Migrations preserve per-requirement
  history; new fields synthesize a single history entry recording
  the migration.

OBLIGATION ON FUTURE SCHEMA CHANGES

  The first commit that bumps `_format` to `req-v2` (or later) MUST
  also register a migration body in `src/commands/migrate.rs` —
  shipping a new format without a path forward from `req-v1` is a
  release-blocking bug. The current binary intentionally errors out
  if it encounters an older format it has no migration for, rather
  than silently passing the data through.",
    },
    Section {
        name: "env",
        summary: "Environment variables read by the tool.",
        body: "REQ_FILE         Override the default .req file path. Equivalent
                 to passing --file PATH.

REQ_ACTOR        Override the actor name recorded on history entries.
                 Falls back to USER / USERNAME.

REQ_ACTOR_KIND   Tag history entries (and downstream audit output) with
                 'human' or 'agent'. Defaults to 'unknown' if unset.
                 Agents driving req over MCP or CLI should set this to
                 'agent' so reviewers can separate human vs automated
                 edits when auditing.

REQ_VALIDATE_LLM_CMD
                 OPTIONAL statement-quality hook. When set, `req
                 validate` invokes this command once per non-obsolete
                 requirement and surfaces the verdict as REQ-V-0023.
                 The command is run via the platform shell (`sh -c`
                 on Unix, `cmd /C` on Windows).

                 Contract:
                   - stdin: JSON object {id, title, statement, rationale}
                     followed by EOF (we close the pipe immediately so
                     a `read_to_end()` hook returns at once).
                   - stdout: JSON {ok: bool, message: string}.
                   - exit 0 expected; non-zero surfaces as a transport
                     warning (not a validate error).
                   - 10s hard timeout per requirement; timeouts surface
                     as transport warnings, validate continues.
                   - ok: true is silent; ok: false produces a
                     REQ-V-0023 warning carrying `message`.

                 Example (sh): echo '{\"ok\":false,\"message\":\"too vague\"}'

                 Notes:
                   - Calls are sequential, so a 1s hook × 100 reqs is
                     ~100s. Cache verdicts by sha256(statement) in your
                     hook if you call a paid model.
                   - Default validator stays deterministic and offline
                     when this var is unset.",
    },
    Section {
        name: "verification",
        summary: "What it takes to mark a requirement as Verified.",
        body: "Verified means there is a HEAD-current evidence record on file.
Evidence comes in three kinds, all stored on the same TestRecord
shape with a `kind` discriminator:

  automated     captured by `req test run` from a cargo test suite
  composition   verified by citing another requirement's passing tests
                (e.g. REQ-0020 'agents shall not edit directly' is
                discharged by REQ-0003's integrity-hash test)
  inspection    verified by human review of the code at the recorded
                commit (use when the requirement is a negative
                assertion or pure policy not testable in code)

Every record pins the current git HEAD SHA. A record is FRESH if its
commit matches current HEAD. `req show REQ-XXXX` annotates the latest
record with [matches HEAD] or [drifted — HEAD now ...] so reviewers
see staleness at a glance.

RECORDING

  # automated — usually via the runner
  req test run --promote                     # runs cargo test + flips
                                             # status to Verified for any
                                             # req with a fresh pass

  # composition — cite tests/reqs that imply this one
  req verify REQ-0020 --by composition \\
    --cites REQ-0003 --cites req_0003_integrity_blocks_load_after_semantic_tamper \\
    --notes \"agents-shall-not-edit-directly is enforced by integrity hash\" \\
    --promote

  # inspection — human review at HEAD
  req verify REQ-0028 --by inspection \\
    --notes \"reviewed src/ for crypto deps; only sha2 used for hashing\" \\
    --promote

POLICY

  * Verified requires fresh evidence on the current HEAD.
  * Composition records should name the cited test or REQ in --cites.
  * Inspection records should describe what was reviewed; if the
    code at the cited commit has drifted, re-inspect or re-verify.
  * `req test run --promote` is safe to wire into CI: it only
    flips Implemented -> Verified, never the other way.

STALENESS HAS TWO LEVELS

  fresh        record commit equals current HEAD
  drifted      HEAD moved but none of the requirement's linked source
               files (files containing its REQ-NNNN marker) changed
  STALE        at least one linked file changed since the record commit

`req show` annotates the latest record with the strongest applicable
tag. `req stale` reports the same three states across the whole
project; `req stale --only-stale` exits non-zero if anything is
actually stale (CI-friendly).

When HEAD moves, drifted/STALE records remain visible in `req show`
and `req stale` but do NOT automatically demote status. Re-running
`req test run --promote` lands fresh records; STALE entries become
fresh when their evidence is re-affirmed.",
    },
    Section {
        name: "testing",
        summary: "How to wire cargo tests into requirement test records.",
        body: "Convention: name every #[test] function `req_NNNN_description` where
NNNN is the 4-digit ID of the requirement it exercises. Multiple tests
may share an ID — they are aggregated into one record per run.

  #[test]
  fn req_0006_modal_verb_required_rejects_missing() { ... }
  #[test]
  fn req_0006_modal_verb_present_passes() { ... }

Then drive the suite through `req test run`:

  req test run                          # default: cargo test --release
  req test run --dry-run                # preview without writing
  req test run --json                   # machine-readable result map
  req test run --cmd \"cargo test\"       # custom command

The runner shells out, parses stdout for `^test req_NNNN_* ... (ok|FAILED|ignored)`,
groups by REQ-NNNN, and attaches one TestRecord per requirement:
outcome = fail if any covered test failed, else pass. Each record
captures the current git HEAD SHA, the actor (REQ_ACTOR), the test
name list, and a UTC timestamp.

Effect on the project:
  * `req show REQ-NNNN` displays the run with a [matches HEAD] /
    [drifted] marker, so reviewers can see at a glance whether the
    evidence is current.
  * Test records round-trip through the integrity hash.

The runner ignores test names that don't match the convention and
skips records for REQ-IDs that no longer exist in project.req
(orphan markers in code).",
    },
    Section {
        name: "errors",
        summary: "Stable error and rule codes for agents and tooling.",
        body: "Every CLI subcommand that supports --json emits errors on stderr
as a single JSON object with three fields:

  { \"code\": \"REQ-E-...\", \"message\": \"...\", \"hint\": \"...\" }

ERROR CODES (stable)

  REQ-E-INTEGRITY       File integrity hash mismatch. Hint names
                        `req repair --confirm-direct-edit`.
  REQ-E-NOT-FOUND       Referenced requirement / file / ref does not exist.
  REQ-E-VALIDATION      Validator rejected the input.
  REQ-E-CYCLE           A parent link would create a cycle.
  REQ-E-DUPLICATE       Link already exists, or another uniqueness clash.
  REQ-E-INVALID-INPUT   Malformed arguments or unknown enum value.
  REQ-E-IO              File or process error (read/write/exec).

VALIDATOR RULE CODES (stable)

  REQ-V-0001  title is required
  REQ-V-0002  title is too short (min 5 characters)
  REQ-V-0003  title is too long (max 120 characters)
  REQ-V-0004  title ends with a period (warn)
  REQ-V-0005  statement is required
  REQ-V-0006  statement must be a complete sentence (>=5 words)
  REQ-V-0007  statement is too long (>80 words, warn)
  REQ-V-0008  statement must contain a normative modal verb
  REQ-V-0009  statement contains a weasel word (warn)
  REQ-V-0010  statement looks compound (warn)
  REQ-V-0011  statement must not be a question
  REQ-V-0012  rationale is required
  REQ-V-0013  rationale is very short (warn)
  REQ-V-0014  functional requirement is missing acceptance criteria
  REQ-V-0015  acceptance criterion is too vague (warn)
  REQ-V-0016  link target does not exist
  REQ-V-0017  self-link not allowed
  REQ-V-0018  status requires acceptance for functional requirement

Codes are append-only — adding a code is backwards compatible; renumbering
existing codes is NOT. Agents may match on codes and treat messages as
informational text.",
    },
    Section {
        name: "mcp",
        summary: "Run `req` as an MCP server for LLM agents.",
        body: "`req mcp` speaks the Model Context Protocol over stdio: each line
is a JSON-RPC 2.0 message (newline-delimited, no Content-Length header).
Pair it with any MCP-capable client.

BOOTSTRAP — once per project

  req mcp --init-config           # writes .mcp.json at the repo root
  req mcp --init-config --path .somewhere/req.json --force

The generated .mcp.json registers a server named `req` with a
description aimed at agents on first contact. Edit it freely OUTSIDE
the values you want to keep.

TOOLS EXPOSED

  req_list       List requirements with filters. Call FIRST.
  req_show       Full detail for one ID (statement, rationale, ACs, history).
  req_add        Create. Validator rejects bad input — rewrite, don't bypass.
  req_update     Modify; `reason` mandatory. Prefer add_acceptance over
                 acceptance (append vs replace).
  req_delete     Soft by default (status→Obsolete). hard=true refuses if
                 inbound links exist.
  req_link       parent / depends_on / refines / conflicts / verifies.
                 Parent links cycle-checked.
  req_validate   Run rules across the whole project.
  req_coverage   default / unlinked_files=true / by_file=true modes.
  req_export     markdown / json (csv & html via CLI only for now).
  req_help       Fetch any documentation section by name.

NOT EXPOSED

  `repair` is human-only. The integrity-recovery escape hatch is
  deliberately not on the agent surface so an agent cannot accept an
  integrity violation and continue.

SCHEMAS

  Every tool has a JSON Schema in its description that names required
  vs optional fields, enumerated values for kind/priority/status, and
  short per-field descriptions. Honour the schema; the server validates.

DEBUGGING

  Pipe JSON-RPC into the binary directly:

    printf '%s\\n%s\\n' \\
      '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}' \\
      '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}' \\
      | req mcp

  Each response is a single JSON line on stdout. Notifications (no `id`)
  produce no response.",
    },
    Section {
        name: "export",
        summary: "Export formats.",
        body: "  markdown   human-friendly, default
  json       full project including history
  csv        spreadsheet-friendly summary
  html       single-file HTML

Use `-o -` to write to stdout (default), or `-o reqs.md` to a file.",
    },
];