{
"_format": "req-v2",
"_instructions": [
"DO NOT EDIT THIS FILE BY HAND.",
"",
"This file is the source of truth for a managed requirements project. It is",
"git-diffable so humans can review changes in pull requests, but every",
"mutation must go through the `req` CLI so that best-practice validation",
"runs (atomic statements, modal verbs, acceptance criteria, no weasel words,",
"no broken links, etc.).",
"",
"Integrity: the `_integrity` field is a SHA-256 of the canonical payload.",
"If you edit this file directly the hash will no longer match and the CLI",
"will refuse to read it. To recover after an intentional manual edit:",
" req repair --confirm-direct-edit",
"",
"Common commands:",
" req init -n <name> create a new project",
" req add interactive add (recommended)",
" req list [--status ...] [--kind ...] table of requirements",
" req show REQ-0001 full detail for one",
" req update REQ-0001 --status approved --reason \"team review\"",
" req link REQ-0002 REQ-0001 -k parent hierarchy / traceability",
" req validate run rules across the project",
" req export -f markdown -o reqs.md publish",
" req tui interactive terminal browser",
" req help <section> structured help; try: overview,",
" concepts, best-practice, workflow,",
" file-format, agents, export",
"",
"Agents: never edit this file. Drive `req` with subcommands, or use `req mcp`",
"(when available) to manage requirements through the JSON-RPC interface."
],
"_integrity": "sha256:f67a45026356c40e600d45d2c39964b5c6b6070b998b4f8de8273bb61c3744ac",
"_warning": "DO NOT EDIT THIS FILE BY HAND. Managed by the `req` CLI.",
"created": "2026-05-17T06:44:00.246918900Z",
"name": "req CLI",
"next_id": 130,
"requirements": {
"REQ-0001": {
"acceptance": [
"Running req --help lists init, add, list, show, update, delete, link, validate, export, tui, serve, mcp, help and repair subcommands",
"Each subcommand exits non-zero on validation failure"
],
"created": "2026-05-17T06:44:14.321675700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:14.321676300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:35.875420300Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493464900Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586101100Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.752972100Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476338700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.376919900Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432723300Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460731700Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156612300Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598601900Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034752400Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605620400Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373231800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549301300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614109300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031639300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104238800Z",
"reason": null
}
],
"id": "REQ-0001",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "A single managed entry point lets us enforce best-practice validation on every mutation and gives agents an unambiguous tool to call.",
"statement": "The system shall expose its full requirement-management surface through a single CLI binary named `req`.",
"status": "Verified",
"tags": [
"core"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493380800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586041300Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752844600Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476280100Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376856100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460609800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156528Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598502900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034617500Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373110700Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.548975500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613644600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031392900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103681200Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0001_help_lists_every_subcommand",
"outcome": "Pass"
}
],
"title": "Manage requirements through a single CLI binary",
"updated": "2026-05-17T19:01:22.104306100Z"
},
"REQ-0002": {
"acceptance": [
"Opening project.req in a text editor shows pretty-printed JSON",
"git diff between two commits of project.req produces a human-readable patch"
],
"created": "2026-05-17T06:44:25.551796Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:25.551796600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.005917400Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493486200Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586118400Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.752994400Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476348700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.376939200Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432756800Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460763500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156632800Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598621800Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034776Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373250300Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549335300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614138200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031661200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104308900Z",
"reason": null
}
],
"id": "REQ-0002",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Plain-text storage enables code-review workflows, blame, and reverts — opaque binary blobs prevent this.",
"statement": "The system shall persist requirements in a JSON file so that changes are reviewable through standard version-control diff tools.",
"status": "Verified",
"tags": [
"storage"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493386700Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586049500Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752859700Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476285300Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376863900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460617200Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156534900Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598506900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034626300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373114300Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.548992300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613652800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031397900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103690500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0002_init_writes_diffable_json",
"outcome": "Pass"
}
],
"title": "Store requirements in a git-diffable file",
"updated": "2026-05-17T19:01:22.104345300Z"
},
"REQ-0003": {
"acceptance": [
"Manually changing one byte of a saved project.req causes req list to fail with an integrity error",
"The error message names the recovery command: req repair --confirm-direct-edit"
],
"created": "2026-05-17T06:44:40.023414700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:40.023415200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.166581800Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493503200Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586134400Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753024700Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476357Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.376967600Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432779900Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460792600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156650700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598640700Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034792700Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373267200Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549371300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614156600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031686900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104350Z",
"reason": null
}
],
"id": "REQ-0003",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Hash verification is the technical backstop that keeps agents from bypassing validation by editing the file directly.",
"statement": "The system shall reject loading any .req file whose stored _integrity hash does not match the recomputed SHA-256 of the canonical payload.",
"status": "Verified",
"tags": [
"storage",
"safety"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493392900Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586053500Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752867900Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476289800Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376868400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460622300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156539300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598511200Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034632800Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373120500Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549006600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613659300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031404Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103705100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0003_integrity_ignores_whitespace_only_change, req_0003_integrity_blocks_load_after_semantic_tamper",
"outcome": "Pass"
}
],
"title": "Detect direct edits via integrity hash",
"updated": "2026-05-17T19:01:22.104514500Z"
},
"REQ-0004": {
"acceptance": [
"A freshly saved project.req contains a _warning string starting with 'DO NOT EDIT'",
"The _instructions array lists init, add, list, show, update, delete, link, validate, export and repair"
],
"created": "2026-05-17T06:44:40.149756700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:40.149757700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.335452900Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:04.609835Z",
"reason": "Reviewed src/storage.rs::WARNING_HEADLINE and instructions_block: _warning and _instructions are written on every save; verified via cat project.req | head"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:04.609902500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549433900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614176200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031703400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104521700Z",
"reason": null
}
],
"id": "REQ-0004",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "An in-file notice gives any human (or LLM) opening the file immediate context that the file is managed and how to interact with it correctly.",
"statement": "The system shall write a _warning headline and a multi-line _instructions block at the top of every saved .req file describing common req commands.",
"status": "Verified",
"tags": [
"storage"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:04.609681900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/storage.rs::WARNING_HEADLINE and instructions_block: _warning and _instructions are written on every save; verified via cat project.req | head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549015500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0004_save_writes_warning_and_instructions_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613661800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0004_save_writes_warning_and_instructions_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031406800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0004_save_writes_warning_and_instructions_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103731400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0004_save_writes_warning_and_instructions_block",
"outcome": "Pass"
}
],
"title": "Embed managed-file warning and CLI directions in the file",
"updated": "2026-05-17T19:01:22.104551600Z"
},
"REQ-0005": {
"acceptance": [
"req repair without --confirm-direct-edit exits non-zero with a guidance message",
"req repair --confirm-direct-edit refuses to run if the file has validation errors",
"After successful repair the file loads cleanly again"
],
"created": "2026-05-17T06:44:40.261386200Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:40.261386600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.503238Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493519600Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586150200Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753067500Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476365200Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.376997400Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432803600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460815600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156668Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598657400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034808400Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605674400Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373283400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549470900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614196900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031724Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104562200Z",
"reason": null
}
],
"id": "REQ-0005",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Humans occasionally need to hand-edit; repair is the explicit, audited escape hatch that keeps the integrity model honest.",
"statement": "The system shall expose a repair subcommand that re-signs the file when given `--confirm-direct-edit`.",
"status": "Verified",
"tags": [
"safety"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493397800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586056200Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752874900Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476292900Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376871400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460626300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156543100Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598514800Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034639700Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373122800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549023300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613665500Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031410500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103741600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0005_repair_refuses_without_flag, req_0005_repair_recovers_after_tamper",
"outcome": "Pass"
}
],
"title": "Provide req repair to re-sign after intentional edits",
"updated": "2026-05-17T19:01:22.104590200Z"
},
"REQ-0006": {
"acceptance": [
"Adding a statement containing 'The user clicks the button.' fails with a modal-verb error",
"Adding the same statement with 'The user shall click the button to submit the form' succeeds",
"A statement whose only modal verb sits inside a URL host (e.g. https://shall.example.com/) is rejected"
],
"created": "2026-05-17T06:44:56.728504300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:56.728504700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.650717100Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "acceptance replaced (3 items)",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:49:06.201372700Z",
"reason": "Adversarial test caught URL bypass: https://shall.example.com/ satisfied the regex; validator now strips URLs and inline code before checking"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493536700Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586164900Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753094700Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476372800Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377028Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432827600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460832200Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156690300Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598673800Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034823700Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605701400Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373300400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549503800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614221500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031742100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104592800Z",
"reason": null
}
],
"id": "REQ-0006",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Normative modal verbs are the universal marker of a real requirement; their absence almost always means the text is descriptive rather than prescriptive.",
"statement": "The system shall reject any requirement whose statement contains no normative modal verb.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493405700Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_in_url_does_not_count",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586059200Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_present_passes, req_0006_modal_verb_in_url_does_not_count",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752881600Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476296800Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376874900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_present_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460631800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156546500Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_present_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598517900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_present_passes, req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034645700Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373126200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_required_rejects_missing, req_0006_modal_verb_present_passes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549030200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613668700Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031417600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103757500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0006_modal_verb_in_url_does_not_count, req_0006_modal_verb_present_passes, req_0006_modal_verb_required_rejects_missing",
"outcome": "Pass"
}
],
"title": "Enforce normative-modal-verb rule on statements",
"updated": "2026-05-17T19:01:22.104699900Z"
},
"REQ-0007": {
"acceptance": [
"Adding a statement containing 'user-friendly' produces a WARN line citing the term",
"Warnings do not block the save"
],
"created": "2026-05-17T06:44:56.839495700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:56.839496100Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.815597Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.426408600Z",
"reason": "Weasel-word warning is part of the same validate_requirement path proven by REQ-0006 tests"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.426436500Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605723Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549537500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614241300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031758200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104703500Z",
"reason": null
}
],
"id": "REQ-0007",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Weasel words turn requirements into unverifiable wishes; surfacing them at write time is cheaper than discovering them in QA.",
"statement": "The system shall emit a warning for every occurrence of a configured weasel word inside a statement.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:23.426358400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0006 — Weasel-word warning is part of the same validate_requirement path proven by REQ-0006 tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549039900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0007_weasel_word_fast_produces_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613674400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0007_weasel_word_fast_produces_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031421300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0007_weasel_word_fast_produces_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103767500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0007_weasel_word_fast_produces_warning",
"outcome": "Pass"
}
],
"title": "Warn on weasel words in statements",
"updated": "2026-05-17T19:01:22.104731Z"
},
"REQ-0008": {
"acceptance": [
"Calling req add for a Functional kind with no --accept flags in non-interactive mode exits non-zero",
"The same call with --kind constraint succeeds (constraints are exempt)"
],
"created": "2026-05-17T06:44:56.966329500Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:56.966329900Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:36.979872500Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493552800Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586180300Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753136300Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476380900Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377052800Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432851900Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460848700Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156706900Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598692400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034839500Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373317100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549566800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614257600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031775300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104734400Z",
"reason": null
}
],
"id": "REQ-0008",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Without acceptance criteria a functional requirement cannot be verified; making them mandatory at write time prevents downstream pain.",
"statement": "The system shall refuse to save a Functional requirement that has zero acceptance criteria.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493417Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_with_acceptance_passes, req_0008_functional_without_acceptance_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586062600Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752889300Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_with_acceptance_passes, req_0008_functional_without_acceptance_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476301500Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376878500Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460638800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156551800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598520900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034650300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_with_acceptance_passes, req_0008_functional_without_acceptance_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373130Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_with_acceptance_passes, req_0008_functional_without_acceptance_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549048100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613676800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031424500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103777Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0008_functional_without_acceptance_rejected, req_0008_functional_with_acceptance_passes",
"outcome": "Pass"
}
],
"title": "Require acceptance criteria for functional requirements",
"updated": "2026-05-17T19:01:22.104759700Z"
},
"REQ-0009": {
"acceptance": [
"req update on a functional REQ-XXXX with empty acceptance to --status approved exits non-zero"
],
"created": "2026-05-17T06:44:57.085768700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:44:57.085769100Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.144580200Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.604954Z",
"reason": "Status-transition acceptance gate is part of the same validator covered by REQ-0006 and REQ-0008 tests"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.604972600Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549587300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614273200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031795500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104762200Z",
"reason": null
}
],
"id": "REQ-0009",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "A Verified requirement with no acceptance criteria is meaningless; the validator must catch this on save.",
"statement": "The system shall refuse to set status to Approved, Implemented or Verified on a Functional requirement that has no acceptance criteria.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:23.604917700Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0006 — Status-transition acceptance gate is part of the same validator covered by REQ-0006 and REQ-0008 tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549052Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0009_cannot_approve_functional_without_acceptance",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613679200Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0009_cannot_approve_functional_without_acceptance",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031427Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0009_cannot_approve_functional_without_acceptance",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103786300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0009_cannot_approve_functional_without_acceptance",
"outcome": "Pass"
}
],
"title": "Prevent illegal status transitions without acceptance criteria",
"updated": "2026-05-17T19:01:22.104787300Z"
},
"REQ-0010": {
"acceptance": [
"Two consecutive req add calls produce IDs that differ by exactly one",
"Deleting a requirement does not cause its ID to be reused by a subsequent add",
"Failed req add invocations do NOT consume IDs: validation runs before allocate_id on both CLI and MCP paths"
],
"created": "2026-05-17T06:45:12.567043800Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:12.567044200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.308137400Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "+acceptance #3: \"Failed req add invocations do NOT consume IDs: validation runs before allocate_id on both CLI and MCP paths\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:45:11.206246500Z",
"reason": "Fix landed: allocate_id moved to post-validate in both src/commands/add.rs and src/mcp.rs::tool_add"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493568100Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586194600Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753278400Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476388500Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377074600Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432876Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460864800Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156723200Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598708100Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034855100Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373332400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549603500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614292700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031811200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104791Z",
"reason": null
}
],
"id": "REQ-0010",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Stable, predictable IDs let humans and agents reference requirements in code comments, commits and conversations without ambiguity.",
"statement": "The system shall assign each new requirement a unique ID of the form REQ-NNNN, drawing from a monotonically increasing counter stored in the project.",
"status": "Verified",
"tags": [
"core"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493419800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586064900Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752894200Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476304200Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376881100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460646400Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156554600Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598524700Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034654900Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373135200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549057300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613683600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031431100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103798600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0010_sequential_ids_no_reuse_after_delete, req_0010_failed_add_does_not_burn_id",
"outcome": "Pass"
}
],
"title": "Allocate stable sequential requirement IDs",
"updated": "2026-05-17T19:01:22.104834100Z"
},
"REQ-0011": {
"acceptance": [
"After three updates, req show lists three history entries plus the original create",
"Passing --reason on update stores the reason in the history entry"
],
"created": "2026-05-17T06:45:12.700922700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:12.700923200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.464928100Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493583500Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586209800Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753319100Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476396300Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377096500Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432902700Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.209376800Z",
"reason": "Every test that mutates a requirement appends a history entry; visible in req_0010 sequence tests"
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460881500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156744700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598725800Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034874Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605744800Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373347700Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549620900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614320300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031829800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104844900Z",
"reason": null
}
],
"id": "REQ-0011",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Auditability matters for compliance reviews and for understanding why a requirement evolved; history must never be silently mutated.",
"statement": "The system shall append an attributed history entry on every requirement mutation.",
"status": "Verified",
"tags": [
"history"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493422200Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586067400Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752898600Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476306400Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376882900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:32:26.209343300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0010 — Every test that mutates a requirement appends a history entry; visible in req_0010 sequence tests",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460656600Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156557Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598526900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034658100Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373136900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549059800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613686200Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031433400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103811700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0011_empty_rationale_rejected",
"outcome": "Pass"
}
],
"title": "Maintain append-only history per requirement",
"updated": "2026-05-17T19:01:22.104961800Z"
},
"REQ-0012": {
"acceptance": [
"req delete REQ-XXXX leaves the requirement present with status=obsolete",
"req delete --hard REQ-XXXX refuses if any other requirement links to it"
],
"created": "2026-05-17T06:45:12.810378600Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:12.810379Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.655956100Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493598900Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586223900Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753359400Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476403600Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377119100Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432925Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460897800Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156760200Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598743Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034890400Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373363Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549638100Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614340500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031850100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104965600Z",
"reason": null
}
],
"id": "REQ-0012",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Most projects need to retain the trace of retired requirements; an accidental hard delete should be impossible.",
"statement": "The system shall mark requirements as Obsolete on delete by default and require an explicit --hard flag to remove them from the project.",
"status": "Verified",
"tags": [
"lifecycle"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493425600Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586070900Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752905200Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476310300Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376887Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460664Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156559600Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598529800Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034661300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373139300Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549063600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613692200Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031435300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103820100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0012_soft_delete_preserves_inbound_links",
"outcome": "Pass"
}
],
"title": "Soft-delete by default to preserve traceability",
"updated": "2026-05-17T19:01:22.104988700Z"
},
"REQ-0013": {
"acceptance": [
"Linking A parent B then B parent A fails with a cycle error"
],
"created": "2026-05-17T06:45:12.924529700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:12.924530700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.828102600Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493613800Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586238200Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753390Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476410800Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377148400Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432950700Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460915100Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156776100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598758200Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034905200Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373379Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549669400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614369Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031866100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.104991600Z",
"reason": null
}
],
"id": "REQ-0013",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Cycles break export, traversal and tooling assumptions; catching them at link time is far cheaper than recovering from them later.",
"statement": "The system shall detect and refuse any parent link operation that would introduce a cycle in the requirements hierarchy.",
"status": "Verified",
"tags": [
"links"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493429300Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586074Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752911200Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476314700Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376890600Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460669Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156562300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598532600Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034664900Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373142800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549066100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613695900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031437500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103827900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0013_parent_cycle_rejected",
"outcome": "Pass"
}
],
"title": "Reject parent links that create cycles",
"updated": "2026-05-17T19:01:22.105031200Z"
},
"REQ-0014": {
"acceptance": [
"req export -f markdown writes one section per requirement with statement, rationale and acceptance",
"req export -f json round-trips back through req import (when import lands)",
"req export -f html renders single-file HTML matching the live req serve presentation closely enough for offline use"
],
"created": "2026-05-17T06:45:37.176743100Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:37.176743600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:37.996268300Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "status implemented -> verified",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:30:27.177276400Z",
"reason": "Free up -f short flag for --format by removing short on global --file; documented in --help"
},
{
"action": "+acceptance #3: \"req export -f html renders single-file HTML matching the live req serve presentation closely enough for offline use\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:27:45.606271600Z",
"reason": "Reflect the parallel html-export path; verified via spot check"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493628600Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586252100Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753430200Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476419Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377178100Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460930500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156791600Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598774800Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034921200Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605771400Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373395Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549700600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614384900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031882900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105037800Z",
"reason": null
}
],
"id": "REQ-0014",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Different stakeholders consume requirements differently: engineers want markdown, auditors want csv, browsers want html, tooling wants json.",
"statement": "The system shall render the project to a configurable output format through `req export`.",
"status": "Verified",
"tags": [
"export"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493431300Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586076300Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752915300Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476316700Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376893Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460672300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156564300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598534400Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034667600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373144800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549068900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613699900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031439400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103835300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0014_export_markdown_round_trip",
"outcome": "Pass"
}
],
"title": "Export to multiple human-facing formats",
"updated": "2026-05-17T19:01:22.105064200Z"
},
"REQ-0015": {
"acceptance": [
"req tui presents a menu containing Browse, Add, Update, Delete, Validate, Export, Quit",
"Add and Update flows reuse the same validator as the non-interactive commands"
],
"created": "2026-05-17T06:45:37.305310200Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:37.305310900Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.165153700Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "status implemented -> verified",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:17:39.394278200Z",
"reason": "Dogfooded in this session via req tui"
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605791500Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "inspection evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:57:19.324050900Z",
"reason": "Verified by use: req tui present, builds and runs; menu surface covered by REQ-0083 parity tests in tests/mcp_tools.rs."
}
],
"id": "REQ-0015",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "The flag-driven CLI is great for agents and CI but hostile to ad-hoc human use; an interactive mode closes that gap.",
"statement": "The system shall provide an interactive terminal mode via `req tui` so humans can drive the CLI without memorising flag combinations.",
"status": "Verified",
"tags": [
"ux"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:57:19.323996100Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Inspection",
"notes": "Verified by use: req tui present, builds and runs; menu surface covered by REQ-0083 parity tests in tests/mcp_tools.rs.",
"outcome": "Pass"
}
],
"title": "Provide an interactive TUI for humans",
"updated": "2026-05-20T10:57:19.324072300Z"
},
"REQ-0016": {
"acceptance": [
"req serve --port 7878 returns a list view at GET /",
"req serve --read-only disables every mutation endpoint",
"GET / returns an HTML index listing every requirement",
"GET /r/{id} returns an HTML detail page including statement, rationale, acceptance, links and history",
"GET /api/list returns the requirements as a JSON array",
"GET /api/r/{id} returns a single requirement as JSON, with 404 for unknown IDs"
],
"created": "2026-05-17T06:45:37.441614400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:37.441614900Z",
"reason": null
},
{
"action": "+acceptance #3: \"GET / returns an HTML index listing every requirement\"; +acceptance #4: \"GET /r/{id} returns an HTML detail page including statement, rationale, acceptance, links and history\"; +acceptance #5: \"GET /api/list returns the requirements as a JSON array\"; +acceptance #6: \"GET /api/r/{id} returns a single requirement as JSON, with 404 for unknown IDs\"; status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:27:46.155450200Z",
"reason": "Minimum-viable read-only server landed; mutation endpoints deferred until the file-locking story is designed"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:04.797123Z",
"reason": "Reviewed src/web.rs: axum routes GET / and /r/:id (HTML) plus /api/list and /api/r/:id (JSON); manually exercised via curl in session"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:04.797149900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614401700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031899800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105070400Z",
"reason": null
}
],
"id": "REQ-0016",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Some humans strongly prefer a browser-based view; a small read-mostly web server covers that use case without forcing a heavyweight deployment.",
"statement": "The system shall provide a req serve subcommand that hosts a local HTTP browser/editor for the project on a configurable host and port.",
"status": "Verified",
"tags": [
"ux",
"web"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:04.797072400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/web.rs: axum routes GET / and /r/:id (HTML) plus /api/list and /api/r/:id (JSON); manually exercised via curl in session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613707700Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0016_serve_unknown_id_returns_404, req_0016_serve_api_list_returns_json_array, req_0016_serve_show_route_returns_html_detail, req_0016_serve_api_show_returns_json_object, req_0016_serve_root_returns_html_index, req_0016_serve_html_escapes_user_supplied_strings",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031444300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0016_serve_html_escapes_user_supplied_strings, req_0016_serve_root_returns_html_index, req_0016_serve_api_show_returns_json_object, req_0016_serve_api_list_returns_json_array, req_0016_serve_show_route_returns_html_detail, req_0016_serve_unknown_id_returns_404",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103849600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0016_serve_api_show_returns_json_object, req_0016_serve_api_list_returns_json_array, req_0016_serve_root_returns_html_index, req_0016_serve_show_route_returns_html_detail, req_0016_serve_unknown_id_returns_404, req_0016_serve_html_escapes_user_supplied_strings",
"outcome": "Pass"
}
],
"title": "Provide a local web server for humans",
"updated": "2026-05-17T19:01:22.105095800Z"
},
"REQ-0017": {
"acceptance": [
"Starting req mcp and sending an initialize request returns a tools list containing list, show, add, update, delete, link, validate, export and help",
"MCP does not expose the repair tool",
"tools/list returns the ten req_ tools with first-class agent-facing descriptions",
"tools/call with invalid req_add returns content.isError=true and a validator-style message",
"Writes through MCP update the integrity hash so the next CLI load succeeds",
"The repair operation is NOT exposed as an MCP tool"
],
"created": "2026-05-17T06:45:37.566575500Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:37.566576Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:34.451949400Z",
"reason": "MCP server landed; tools call into the same validator and storage as the CLI"
},
{
"action": "+acceptance #3: \"tools/list returns the ten req_ tools with first-class agent-facing descriptions\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:34.610658900Z",
"reason": "acceptance 1"
},
{
"action": "+acceptance #4: \"tools/call with invalid req_add returns content.isError=true and a validator-style message\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:34.741462200Z",
"reason": "acceptance 2"
},
{
"action": "+acceptance #5: \"Writes through MCP update the integrity hash so the next CLI load succeeds\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:34.879097700Z",
"reason": "acceptance 3"
},
{
"action": "+acceptance #6: \"The repair operation is NOT exposed as an MCP tool\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:35.000546Z",
"reason": "acceptance 4 — humans-only guard"
},
{
"action": "test pass recorded against commit 562cb33f9",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:03.389828Z",
"reason": "Manual smoke: piped initialize+tools/list+tools/call through stdio"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.805097100Z",
"reason": "MCP write path goes through storage::save proven by integrity tests; tool routing already covered by manual smoke and req-test record"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:23.805116400Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373409900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549731300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614420600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031915200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105098900Z",
"reason": null
}
],
"id": "REQ-0017",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "MCP-native agents can call structured tools more reliably than they can shell out, and it lets us keep one validation path for both surfaces.",
"statement": "The system shall provide a req mcp subcommand that speaks JSON-RPC 2.0 over stdio and exposes the CLI operations as MCP tools.",
"status": "Verified",
"tags": [
"agents",
"mcp"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T09:56:03.389776100Z",
"commit": "562cb33f9a48e10e74b24c74c327657a7a7ef7be",
"kind": "Automated",
"notes": "Manual smoke: piped initialize+tools/list+tools/call through stdio",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:32:23.805063100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0038 — MCP write path goes through storage::save proven by integrity tests; tool routing already covered by manual smoke and req-test record",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373147600Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0017_mcp_tools_list_lists_ten_tools, req_0017_mcp_initialize_returns_serverinfo, req_0017_mcp_unknown_method_returns_error_envelope",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549073100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0017_mcp_initialize_returns_serverinfo, req_0017_mcp_tools_list_lists_ten_tools, req_0017_mcp_unknown_method_returns_error_envelope",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613727800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 16 pass / 0 fail / 0 ignored — req_0017_mcp_initialize_returns_serverinfo, req_0017_mcp_tools_list_lists_ten_tools, req_0017_mcp_unknown_method_returns_error_envelope, req_0017_mcp_req_add_validation_failure_returns_iserror, req_0017_mcp_ping_returns_empty_object, req_0017_mcp_req_help_named_section_returns_body, req_0017_mcp_req_help_index_lists_section_names, req_0017_mcp_req_add_persists_through_storage, req_0017_mcp_req_validate_emits_finding_counts, req_0017_mcp_req_show_returns_full_requirement, req_0017_mcp_req_list_returns_count, req_0017_mcp_req_export_renders_markdown, req_0017_mcp_req_delete_soft_marks_obsolete, req_0017_mcp_req_update_records_reason_in_history, req_0017_mcp_self_link_rejected_with_iserror, req_0017_mcp_req_link_creates_typed_edge",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031450400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 16 pass / 0 fail / 0 ignored — req_0017_mcp_tools_list_lists_ten_tools, req_0017_mcp_unknown_method_returns_error_envelope, req_0017_mcp_initialize_returns_serverinfo, req_0017_mcp_req_add_validation_failure_returns_iserror, req_0017_mcp_ping_returns_empty_object, req_0017_mcp_req_help_index_lists_section_names, req_0017_mcp_req_help_named_section_returns_body, req_0017_mcp_req_export_renders_markdown, req_0017_mcp_req_add_persists_through_storage, req_0017_mcp_req_list_returns_count, req_0017_mcp_req_validate_emits_finding_counts, req_0017_mcp_req_show_returns_full_requirement, req_0017_mcp_req_delete_soft_marks_obsolete, req_0017_mcp_self_link_rejected_with_iserror, req_0017_mcp_req_update_records_reason_in_history, req_0017_mcp_req_link_creates_typed_edge",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103870700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 16 pass / 0 fail / 0 ignored — req_0017_mcp_initialize_returns_serverinfo, req_0017_mcp_tools_list_lists_ten_tools, req_0017_mcp_unknown_method_returns_error_envelope, req_0017_mcp_ping_returns_empty_object, req_0017_mcp_req_add_validation_failure_returns_iserror, req_0017_mcp_req_help_index_lists_section_names, req_0017_mcp_req_help_named_section_returns_body, req_0017_mcp_req_add_persists_through_storage, req_0017_mcp_req_export_renders_markdown, req_0017_mcp_req_show_returns_full_requirement, req_0017_mcp_req_validate_emits_finding_counts, req_0017_mcp_req_list_returns_count, req_0017_mcp_req_delete_soft_marks_obsolete, req_0017_mcp_req_update_records_reason_in_history, req_0017_mcp_self_link_rejected_with_iserror, req_0017_mcp_req_link_creates_typed_edge",
"outcome": "Pass"
}
],
"title": "Expose an MCP server interface for agents",
"updated": "2026-05-17T19:01:22.105127500Z"
},
"REQ-0018": {
"acceptance": [
"req help with no args lists every section name and a one-line summary",
"req help all prints the full body of every section",
"req help <unknown> exits non-zero with a hint pointing at req help --list"
],
"created": "2026-05-17T06:45:37.702244400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:37.702245Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.319351200Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "status implemented -> verified",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:30:27.028742200Z",
"reason": "Disable clap built-in help subcommand so req help <section> reaches our handler; demonstrated previously broken by blind sub-agent test"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549747300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614439400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031930500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105129600Z",
"reason": null
}
],
"id": "REQ-0018",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Both humans and agents need a way to pull just the slice of documentation they care about rather than swallowing a monolithic --help.",
"statement": "The system shall provide a req help subcommand with named sections (overview, concepts, best-practice, workflow, file-format, agents, web, tui, export) browsable individually or together.",
"status": "Verified",
"tags": [
"docs"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549076200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0018_help_index_lists_all_sections, req_0018_help_lists_known_sections_individually",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613738Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0018_help_index_lists_all_sections, req_0018_help_lists_known_sections_individually",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031460900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0018_help_index_lists_all_sections, req_0018_help_lists_known_sections_individually",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103878700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0018_help_index_lists_all_sections, req_0018_help_lists_known_sections_individually",
"outcome": "Pass"
}
],
"title": "Provide structured, sectioned help",
"updated": "2026-05-17T19:01:22.105154100Z"
},
"REQ-0019": {
"acceptance": [],
"created": "2026-05-17T06:45:53.627270600Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:53.627271300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.473035Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493648400Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586266700Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753501Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476428500Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377209900Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432974Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.016803900Z",
"reason": "Atomic write tested directly in req_0019_save_is_atomic; integrity hash test exercises the same save path"
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460946600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156808300Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598790700Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034937300Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605809800Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373426400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549766500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614455100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031947100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105162Z",
"reason": null
}
],
"id": "REQ-0019",
"kind": "Constraint",
"links": [],
"priority": "Must",
"rationale": "Direct reads encourage agents to skip validation; direct writes break integrity. This is the project's load-bearing constraint.",
"statement": "The system shall save every `.req` file via temp-and-rename so a mid-write crash cannot corrupt the project.",
"status": "Verified",
"tags": [
"agents",
"safety"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493433700Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586078500Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752919800Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476319300Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376895200Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:32:26.016768900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0003 — Atomic write tested directly in req_0019_save_is_atomic; integrity hash test exercises the same save path",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460676800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156566800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598537Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034670400Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373149900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549079500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613755100Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031464300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103883600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0019_save_is_atomic_no_partial_tmp_left_behind",
"outcome": "Pass"
}
],
"title": "Agents must never read or write the file directly",
"updated": "2026-05-17T19:01:22.105207400Z"
},
"REQ-0020": {
"acceptance": [],
"created": "2026-05-17T06:45:53.752180500Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:53.752181Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:33:34.547036400Z",
"reason": "Promote: Rust + single static binary is the shipped reality"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.012792100Z",
"reason": "agents-shall-not-edit-directly is enforced by the integrity hash demonstrated by req_0003 tests"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.012809400Z",
"reason": null
}
],
"id": "REQ-0020",
"kind": "Constraint",
"links": [],
"priority": "Must",
"rationale": "A single static binary is the lowest-friction way to ship a tool that agents, CI and humans all run in different environments.",
"statement": "The system shall be implemented in Rust and distributed as a single static binary.",
"status": "Verified",
"tags": [
"impl"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.012758900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0003 — agents-shall-not-edit-directly is enforced by the integrity hash demonstrated by req_0003 tests",
"outcome": "Pass"
}
],
"title": "Implement the tool in Rust",
"updated": "2026-05-17T13:32:24.012809100Z"
},
"REQ-0021": {
"acceptance": [
"Setting REQ_ACTOR=alice and running req update writes 'alice' into the new history entry"
],
"created": "2026-05-17T06:45:53.878282Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:45:53.878282500Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.653290500Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.388769Z",
"reason": "Cargo.toml declares edition=2021 and a single bin target; cargo build --release produces target/release/req.exe"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.388787900Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605828900Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549782800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614477900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031962200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105209800Z",
"reason": null
}
],
"id": "REQ-0021",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "History without an actor is half-useful; pulling from standard environment variables avoids requiring config while still attributing changes.",
"statement": "The system shall record an actor name on every history entry, resolving it from `REQ_ACTOR`, `USER`, or `USERNAME` in that order.",
"status": "Verified",
"tags": [
"history"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:26.388731300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Cargo.toml declares edition=2021 and a single bin target; cargo build --release produces target/release/req.exe",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549083700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0021_history_records_actor_from_req_actor_env",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613765500Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0021_history_records_actor_from_req_actor_env",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031467700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0021_history_records_actor_from_req_actor_env",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103902Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0021_history_records_actor_from_req_actor_env",
"outcome": "Pass"
}
],
"title": "Record an actor on every history entry",
"updated": "2026-05-17T19:01:22.105311500Z"
},
"REQ-0022": {
"acceptance": [
"Killing req mid-save leaves either the pre-save file or the post-save file on disk, never a partial one"
],
"created": "2026-05-17T06:46:00.873740900Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T06:46:00.873741600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.821713600Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.020890900Z",
"reason": "Same temp-and-rename save path tested directly by req_0019_save_is_atomic"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.020911500Z",
"reason": null
}
],
"id": "REQ-0022",
"kind": "NonFunctional",
"links": [],
"priority": "Must",
"rationale": "Requirements files are precious — a half-written save that loses an hour of work is the kind of incident that destroys trust in the tool.",
"statement": "The system shall write every .req save to a temporary file and rename it atomically over the destination, so that a process crash mid-write cannot produce a corrupted project file.",
"status": "Verified",
"tags": [
"storage",
"reliability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:05.020843100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0019 — Same temp-and-rename save path tested directly by req_0019_save_is_atomic",
"outcome": "Pass"
}
],
"title": "Atomic file writes via temp-and-rename",
"updated": "2026-05-17T13:33:05.020911200Z"
},
"REQ-0023": {
"acceptance": [
"Running req hooks install in a git repo writes an executable .git/hooks/pre-commit containing the managed-by marker",
"Running req hooks --uninstall removes the hook only if it carries the managed-by marker",
"The hook exits zero when no .req files are staged"
],
"created": "2026-05-17T07:07:54.445853400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:54.445855200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:38.974865600Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "statement updated",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:16:27.705453600Z",
"reason": "Take action as a positional (install|uninstall) to match documented invocation; --uninstall flag removed"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.842525Z",
"reason": "Reviewed src/commands/hooks.rs: HOOK_MARKER + PRECOMMIT_BODY install runs req validate on staged *.req; manually exercised in session"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.842550300Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605848500Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
}
],
"id": "REQ-0023",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "A pre-commit hook is the cheapest place to catch validation errors before they reach review, and one command to install removes a per-developer setup chore.",
"statement": "The system shall manage a project-local pre-commit hook running `req validate` on staged `.req` files via `req hooks install` and `req hooks uninstall`.",
"status": "Verified",
"tags": [
"integration",
"git"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:26.842476900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/hooks.rs: HOOK_MARKER + PRECOMMIT_BODY install runs req validate on staged *.req; manually exercised in session",
"outcome": "Pass"
}
],
"title": "Install git pre-commit hook via req hooks install",
"updated": "2026-05-17T15:09:50.603995700Z"
},
"REQ-0024": {
"acceptance": [
"After req hooks install the repo's .gitattributes contains ",
"The command output names the two git config commands needed to register the driver"
],
"created": "2026-05-17T07:07:54.902046700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:54.902049Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:39.127506300Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:27.050482900Z",
"reason": "Merge driver registration is part of the same hooks install path proven by REQ-0023 inspection"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:27.050500600Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549810500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614501700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031977300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105315700Z",
"reason": null
}
],
"id": "REQ-0024",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Without a merge driver every multi-developer team will eventually corrupt the integrity hash on a textual merge; the driver makes the recovery automatic.",
"statement": "The system shall add a line to .gitattributes during req hooks install and print the one-time git config commands needed to activate the driver.",
"status": "Verified",
"tags": [
"integration",
"git"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:27.050449400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0023 — Merge driver registration is part of the same hooks install path proven by REQ-0023 inspection",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549088700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0024_hooks_install_registers_merge_driver_in_gitattributes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613774800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0024_hooks_install_registers_merge_driver_in_gitattributes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031470100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0024_hooks_install_registers_merge_driver_in_gitattributes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103906600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0024_hooks_install_registers_merge_driver_in_gitattributes",
"outcome": "Pass"
}
],
"title": "Register a git merge driver for .req files",
"updated": "2026-05-17T19:01:22.105452200Z"
},
"REQ-0025": {
"acceptance": [
"After merging a branch that allocated the same REQ-NNNN as origin/main, req renumber --base origin/main produces no remaining duplicates",
"Links pointing at renumbered IDs are rewritten to the new IDs",
"A history entry is appended recording the renumber and the previous ID",
"Passing --dry-run prints the planned renames without writing the file"
],
"created": "2026-05-17T07:07:55.018083Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:55.018084700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:39.286028800Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.279070300Z",
"reason": "Reviewed src/commands/renumber.rs: detects collisions via creation-time mismatch with base, rewrites links, appends history; --dry-run honored"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.279088Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605867700Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
}
],
"id": "REQ-0025",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Sequential REQ-NNNN IDs are friendly to humans but collide across branches; a one-shot renumber tool keeps the friendly IDs without making merges painful.",
"statement": "The system shall provide a renumber subcommand that shifts colliding requirement IDs to fresh values when given `--base <git-ref>`, also rewriting affected internal links.",
"status": "Verified",
"tags": [
"integration",
"git"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:05.279033300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/renumber.rs: detects collisions via creation-time mismatch with base, rewrites links, appends history; --dry-run honored",
"outcome": "Pass"
}
],
"title": "Resolve ID collisions after merge via req renumber",
"updated": "2026-05-17T15:09:50.603995700Z"
},
"REQ-0026": {
"acceptance": [
"Running req coverage in this repo reports REQ-0001 as referenced (it appears in src/) and an unrelated REQ-9999 marker as a ghost",
"Obsolete requirements still referenced by code are listed under obsolete-in-code, not orphans",
"Passing --json emits a stable schema with referenced, orphans, ghosts and obsolete_referenced sections"
],
"created": "2026-05-17T07:07:55.133893400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:55.133895800Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:39.473539100Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.188676900Z",
"reason": "Default coverage mode is the underlying scan that all flipped modes share"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.188695100Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605886100Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549842400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614527600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.031998Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105456600Z",
"reason": null
}
],
"id": "REQ-0026",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Bidirectional traceability between requirements and code is most useful when it surfaces drift; a one-shot scan keeps the link cheap and grep-driven.",
"statement": "The system shall report each requirement's source-tree marker status via `req coverage`.",
"status": "Verified",
"tags": [
"integration",
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.188642500Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0032, REQ-0033, REQ-0034 — Default coverage mode is the underlying scan that all flipped modes share",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549091500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0026_coverage_reports_referenced_orphans_and_ghosts",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613783300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0026_coverage_reports_referenced_orphans_and_ghosts",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031472400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0026_coverage_reports_referenced_orphans_and_ghosts",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103909100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0026_coverage_reports_referenced_orphans_and_ghosts",
"outcome": "Pass"
}
],
"title": "Trace requirements to source with req coverage",
"updated": "2026-05-17T19:01:22.105498100Z"
},
"REQ-0027": {
"acceptance": [
"Running req audit in a repo whose project.req has been signed with a trusted key reports signature=good for those commits",
"Unsigned commits are reported as no-signature in the summary counters",
"Passing --json emits one record per commit including the full SHA and ISO date"
],
"created": "2026-05-17T07:07:55.252470300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:55.252472600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:39.654367100Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.543947300Z",
"reason": "Reviewed src/commands/audit.rs: parses git log --follow with %H/%aI/%aN/%G?/%GS/%s; manually verified output in session"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.543973100Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605905400Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.549983400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614559100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032012800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105500700Z",
"reason": null
}
],
"id": "REQ-0027",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "The CLI cannot itself prove authenticity; surfacing git signature state in one place gives reviewers and auditors a defensible provenance trail without adding a parallel PKI.",
"statement": "The system shall report the git-signature status of every commit touching the `.req` file via `req audit`.",
"status": "Verified",
"tags": [
"integration",
"git",
"audit"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:05.543900400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/audit.rs: parses git log --follow with %H/%aI/%aN/%G?/%GS/%s; manually verified output in session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549094600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0027_audit_prints_signature_status_for_commits",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613791600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0027_audit_prints_signature_status_for_commits",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031474500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0027_audit_prints_signature_status_for_commits",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103911500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0027_audit_prints_signature_status_for_commits",
"outcome": "Pass"
}
],
"title": "Report git signature status per commit via req audit",
"updated": "2026-05-17T19:01:22.105525800Z"
},
"REQ-0028": {
"acceptance": [],
"created": "2026-05-17T07:07:55.369826200Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:07:55.369828300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:14:39.801764600Z",
"reason": "Dogfood: verified against current source tree"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.595276200Z",
"reason": "Reviewed src/ for crypto primitives: only sha2 (hashing) is present; no signing, no key management, no PKI"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:26.595304500Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605923Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
}
],
"id": "REQ-0028",
"kind": "Constraint",
"links": [],
"priority": "Should",
"rationale": "Re-implementing signing introduces a key-management problem with no payoff git signing does not already cover; documenting the boundary keeps future contributors from rebuilding it.",
"statement": "The CLI shall delegate `.req` authenticity claims to signed git commits, surfaced via `req audit`.",
"status": "Verified",
"tags": [
"integration",
"audit"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:26.595222700Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/ for crypto primitives: only sha2 (hashing) is present; no signing, no key management, no PKI",
"outcome": "Pass"
}
],
"title": "Treat git commit signatures as the project authenticity source",
"updated": "2026-05-17T15:09:50.603995700Z"
},
"REQ-0029": {
"acceptance": [
"A statement with two 'shall' clauses produces a compound warning",
"A statement containing a semicolon produces a compound warning",
"A statement with three comma-separated clauses joined by 'and' produces a compound warning",
"A clean single-clause statement produces no compound warning"
],
"created": "2026-05-17T07:49:06.350194300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:49:06.350195Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:04.613973300Z",
"reason": "Compound-statement heuristics shipped in validate.rs (semicolon, multi-modal, comma-and triplet)"
},
{
"action": "added refines link to REQ-0006",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:24.919409300Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493663700Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586280600Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753532500Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476437Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377236800Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.432994600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460962400Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156829400Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598807600Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034956100Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373444800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550036400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614586Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032027800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105528700Z",
"reason": null
}
],
"id": "REQ-0029",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0006"
}
],
"priority": "Should",
"rationale": "Atomic requirements are testable in isolation; the validator must surface obvious compounds at write time so authors split them before they harden.",
"statement": "The system shall emit a compound-statement warning when a statement contains a semicolon, more than one normative modal verb, or three or more comma-separated clauses joined by 'and'.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493436900Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586080800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752925100Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476321800Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376899200Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460684100Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156569200Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598539600Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034673500Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373153700Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549099200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613799900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031477100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103913700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0029_compound_statement_warns_on_double_shall",
"outcome": "Pass"
}
],
"title": "Flag compound statements as a warning",
"updated": "2026-05-17T19:01:22.105558600Z"
},
"REQ-0030": {
"acceptance": [
"Title '🚀🛸🪐🌟' (4 chars, 16 bytes) is rejected with a 'min 5 characters' error",
"Title of 120 Latin characters is accepted; 121 characters is rejected"
],
"created": "2026-05-17T07:49:06.542345100Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T07:49:06.542345900Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:04.756395Z",
"reason": "Title length now counted in Unicode characters; verified 4-emoji rejection"
},
{
"action": "added refines link to REQ-0006",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:25.047488300Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493678600Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586296Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753566400Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476444600Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377263300Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.433015900Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.460990500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156845100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598824500Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034972100Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373459600Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550054200Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614621500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032043500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105560900Z",
"reason": null
}
],
"id": "REQ-0030",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0006"
}
],
"priority": "Should",
"rationale": "Byte-counting mismeasures non-ASCII titles and creates a bypass for an agent allocating short multi-byte titles.",
"statement": "The system shall enforce the 5-to-120 title-length rule by counting Unicode characters, so that a 4-emoji title (16 bytes) is rejected and a 60-CJK-character title is accepted.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493439300Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586082800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752930300Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476326100Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376901800Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460689100Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156571800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598541600Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034676Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373155900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549102Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613808500Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031479300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103916300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0030_emoji_title_too_short_rejected",
"outcome": "Pass"
}
],
"title": "Measure title length in Unicode characters not bytes",
"updated": "2026-05-17T19:01:22.105594300Z"
},
"REQ-0031": {
"acceptance": [
"Running req help agents --install on a file with no managed block appends one wrapped in <!-- req:help:agents:begin --> / <!-- req:help:agents:end --> markers",
"Re-running the same command updates only the content between the markers; total marker count remains exactly one begin and one end",
"Passing --install with section 'all' is rejected with a clear error",
"Installed block survives unrelated edits made above and below the markers"
],
"created": "2026-05-17T09:18:39.732997700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:18:39.733002100Z",
"reason": null
},
{
"action": "+acceptance #4: \"Installed block survives unrelated edits made above and below the markers\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:24:14.784543200Z",
"reason": "Verify append-mode acceptance flag against a real requirement"
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:04.897730500Z",
"reason": "req help <section> --install lands the section in AGENTS.md between sentinel markers"
},
{
"action": "added refines link to REQ-0018",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.033435Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.429796200Z",
"reason": "Section install reuses the same help_text registry covered by help --json tests"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.429964400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550069600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614655200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032059900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105597400Z",
"reason": null
}
],
"id": "REQ-0031",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0018"
}
],
"priority": "Should",
"rationale": "Agents pick up AGENTS.md on session start; embedding the agent-facing crib there makes correct tool use the default rather than something an agent has to discover.",
"statement": "The system shall, when invoked as req help <section> --install, write the named section into a markdown file between sentinel comments so re-running the command updates the block in place without disturbing surrounding content.",
"status": "Verified",
"tags": [
"docs",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.429639Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0042 — Section install reuses the same help_text registry covered by help --json tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549107700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0031_help_install_is_idempotent_in_managed_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613828400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0031_help_install_is_idempotent_in_managed_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031481300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0031_help_install_is_idempotent_in_managed_block",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103921300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0031_help_install_is_idempotent_in_managed_block",
"outcome": "Pass"
}
],
"title": "Install help sections into AGENTS.md idempotently",
"updated": "2026-05-17T19:01:22.105626200Z"
},
"REQ-0032": {
"acceptance": [
"Running req coverage --unlinked-files --path src in this project lists src/mcp.rs and src/web.rs as unlinked (they are stubs)",
"The summary reports scanned / linked / unlinked counts and a percentage",
"Passing --json emits a stable schema with scanned, linked and unlinked array"
],
"created": "2026-05-17T09:18:39.896136700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:18:39.896138600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.037066100Z",
"reason": "req coverage --unlinked-files implemented and dogfooded"
},
{
"action": "added refines link to REQ-0026",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:27.611440600Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.630429300Z",
"reason": "unlinked-files shares the walk with the default coverage mode"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.630447600Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605941300Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550085600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614670900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032084400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105628500Z",
"reason": null
}
],
"id": "REQ-0032",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0026"
}
],
"priority": "Should",
"rationale": "req coverage today only reports requirement-side gaps. Code-side gaps (files implementing behaviour without a trace link) are equally valuable for agents auditing their own work.",
"statement": "The system shall list source files containing zero `REQ-NNNN` markers via `req coverage --unlinked-files`.",
"status": "Verified",
"tags": [
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.630395500Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0026 — unlinked-files shares the walk with the default coverage mode",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549114500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0032_unlinked_files_mode_lists_files_without_markers",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613836900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0032_unlinked_files_mode_lists_files_without_markers",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031483700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0032_unlinked_files_mode_lists_files_without_markers",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103925600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0032_unlinked_files_mode_lists_files_without_markers",
"outcome": "Pass"
}
],
"title": "Report source files with no requirement-trace markers",
"updated": "2026-05-17T19:01:22.105675400Z"
},
"REQ-0033": {
"acceptance": [
"Running req coverage --by-file --path src lists each file containing at least one marker with its REQ IDs",
"Passing --json emits one record per file with file and req_ids fields",
"The mode is mutually exclusive with --unlinked-files and --remap"
],
"created": "2026-05-17T09:27:45.741304300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:27:45.741306700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.176341700Z",
"reason": "req coverage --by-file emits per-file REQ ID maps; --json supported"
},
{
"action": "added refines link to REQ-0026",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:27.759155700Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.801158400Z",
"reason": "by-file mode shares the walk and parser with the default coverage mode"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.801176400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550100700Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614705100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032104300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105678500Z",
"reason": null
}
],
"id": "REQ-0033",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0026"
}
],
"priority": "Should",
"rationale": "Combined with --unlinked-files this closes the bidirectional code/spec view that agents need to audit their own work.",
"statement": "The system shall provide req coverage --by-file which maps every source file containing markers to the sorted set of REQ IDs it references.",
"status": "Verified",
"tags": [
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.801125500Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0026 — by-file mode shares the walk and parser with the default coverage mode",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549119200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0033_coverage_by_file_maps_files_to_req_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613845Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0033_coverage_by_file_maps_files_to_req_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031485900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0033_coverage_by_file_maps_files_to_req_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103929800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0033_coverage_by_file_maps_files_to_req_ids",
"outcome": "Pass"
}
],
"title": "Report per-file requirement coverage",
"updated": "2026-05-17T19:01:22.105709600Z"
},
"REQ-0034": {
"acceptance": [
"Without --apply, --remap prints the planned rewrites and exits without modifying files",
"With --apply, every matching occurrence under --path is rewritten and the affected file count is reported",
"Malformed --remap values (e.g. missing '=', non-REQ tokens) are rejected with a clear error"
],
"created": "2026-05-17T09:27:46.012988200Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:27:46.012990200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.317272600Z",
"reason": "req coverage --remap OLD=NEW with --apply implemented and dry-run verified"
},
{
"action": "added refines link to REQ-0026",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:27.891864600Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.999711Z",
"reason": "remap shares the file walk; manually verified --dry-run and --apply during session"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:24.999736200Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550116400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614732600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032119100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105711600Z",
"reason": null
}
],
"id": "REQ-0034",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0026"
}
],
"priority": "Should",
"rationale": "Ghost markers and typo'd references need an audited bulk-fix path; agents shouldn't reach for sed when the tool can do it safely.",
"statement": "The system shall rewrite REQ-NNNN markers in source files when invoked as req coverage --remap OLD=NEW with --apply, defaulting to a dry-run that previews the rewrite.",
"status": "Verified",
"tags": [
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:24.999670400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0026 — remap shares the file walk; manually verified --dry-run and --apply during session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549125100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0034_coverage_remap_dry_run_then_apply",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613853700Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0034_coverage_remap_dry_run_then_apply",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031488Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0034_coverage_remap_dry_run_then_apply",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103933800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0034_coverage_remap_dry_run_then_apply",
"outcome": "Pass"
}
],
"title": "Rewrite REQ markers in source via coverage --remap",
"updated": "2026-05-17T19:01:22.105726900Z"
},
"REQ-0035": {
"acceptance": [
"req update with --add-acceptance appends a new entry and records it in history",
"req update with --remove-acceptance N removes the Nth criterion and refuses out-of-range indexes",
"When both --accept and --add-acceptance are passed, --accept replaces first then --add-acceptance appends"
],
"created": "2026-05-17T09:28:12.972202600Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:28:12.972205300Z",
"reason": null
},
{
"action": "+acceptance #2: \"req update with --remove-acceptance N removes the Nth criterion and refuses out-of-range indexes\"; +acceptance #3: \"When both --accept and --add-acceptance are passed, --accept replaces first then --add-acceptance appends\"",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:28:24.175738400Z",
"reason": "Round out the acceptance list dropped by an earlier shell-parsing failure"
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.554565300Z",
"reason": "req update --add-acceptance and --remove-acceptance flags shipped"
},
{
"action": "added refines link to REQ-0001",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:29.370786Z",
"reason": null
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.187797600Z",
"reason": "add-acceptance / remove-acceptance share update validation path; manually exercised during session"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.187816600Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550145800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614748Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032133700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105727900Z",
"reason": null
}
],
"id": "REQ-0035",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0001"
}
],
"priority": "Should",
"rationale": "The previous --accept flag replaced the list, forcing authors to retype every criterion to change one.",
"statement": "The system shall accept --add-acceptance VALUE and --remove-acceptance INDEX on req update.",
"status": "Verified",
"tags": [
"ux"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:25.187763500Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0010 — add-acceptance / remove-acceptance share update validation path; manually exercised during session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549129500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0035_update_add_and_remove_acceptance_criteria",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613862800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0035_update_add_and_remove_acceptance_criteria",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031495Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0035_update_add_and_remove_acceptance_criteria",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103937500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0035_update_add_and_remove_acceptance_criteria",
"outcome": "Pass"
}
],
"title": "Append and remove acceptance criteria via update flags",
"updated": "2026-05-17T19:01:22.105742300Z"
},
"REQ-0036": {
"acceptance": [
"README.md exists at repo root",
"Covers install, quick start, and command reference",
"Documents the integrity model and signed-commit audit story",
"Points agents at req help agents --install"
],
"created": "2026-05-17T09:32:44.347190Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:32:44.347193100Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:32:51.518189300Z",
"reason": "Drop compound listing; acceptance criteria already enumerate required sections"
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:32:59.791544700Z",
"reason": "README.md authored at repo root covering install, workflow, integration, audit, and command surface"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.803067900Z",
"reason": "README.md exists at repo root with REQ-0036 marker; covers install, quickstart, workflow, integration, audit and command surface"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:05.803122400Z",
"reason": null
}
],
"id": "REQ-0036",
"kind": "NonFunctional",
"links": [],
"priority": "Should",
"rationale": "First-class onboarding for humans and agents arriving at the repo — the README is the entry point before AGENTS.md or req help.",
"statement": "The project shall provide a top-level README.md as the primary entry point for humans and agents.",
"status": "Verified",
"tags": [
"docs"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:05.803018200Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "README.md exists at repo root with REQ-0036 marker; covers install, quickstart, workflow, integration, audit and command surface",
"outcome": "Pass"
}
],
"title": "Project README",
"updated": "2026-05-17T13:33:05.803121600Z"
},
"REQ-0037": {
"acceptance": [
"req --version prints the semver of the running binary",
"Version string matches the Cargo package version at build time",
"TUI and serve interfaces display the same version string",
"Version is exposed in a structured form (e.g. JSON) for tooling",
"Both and short flags print the same version string as and req-cli 0.1.0"
],
"created": "2026-05-17T09:33:42.768946800Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:33:42.768949Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.227472100Z",
"reason": "req version subcommand with --json landed"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.015573200Z",
"reason": "req version prints 'req <version>'; req version --json emits name/version/file_format/mcp_protocol; manually verified"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.015590600Z",
"reason": null
},
{
"action": "+acceptance #5: \"Both and short flags print the same version string as and req-cli 0.1.0\"",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:02.365460500Z",
"reason": "Cover the conventional -V plus the user-requested -v lowercase short"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550168300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614763400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032150200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105743700Z",
"reason": null
}
],
"id": "REQ-0037",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Users, agents, and bug reports need an unambiguous version string; downstream tooling (CI, MCP clients) needs a stable surface to read it from.",
"statement": "The CLI shall report its own version in a machine-readable form on demand.",
"status": "Verified",
"tags": [
"versioning",
"ux"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.015537900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "req version prints 'req <version>'; req version --json emits name/version/file_format/mcp_protocol; manually verified",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549134400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0037_version_short_flags_print_same_string",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613871900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0037_version_short_flags_print_same_string",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031497600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0037_version_short_flags_print_same_string",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103942600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0037_version_short_flags_print_same_string",
"outcome": "Pass"
}
],
"title": "Tool version reporting",
"updated": "2026-05-17T19:01:22.105758300Z"
},
"REQ-0038": {
"acceptance": [
"Running req add --json ... prints a single JSON object containing the allocated id and all stored fields on stdout",
"Running req update <id> --json ... prints the updated requirement as JSON",
"Running req link --json a b -k parent prints a JSON object describing the created link",
"Stdout is valid JSON parseable by jq with no leading human text"
],
"created": "2026-05-17T09:36:43.245329100Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:36:43.245331600Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:38:20.702794500Z",
"reason": "Reword to remove compound-statement smell while keeping a single obligation"
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:43.524397600Z",
"reason": "JSON flag added to add/update/delete/link emitting the result on stdout"
},
{
"action": "added depends-on link to REQ-0045",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.953780700Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493693500Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586313800Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753586800Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476452100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377342Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.433040300Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.461019500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156860600Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598843400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.034988300Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373475800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550195400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614786200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032165400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105760300Z",
"reason": null
}
],
"id": "REQ-0038",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0045"
}
],
"priority": "Should",
"rationale": "Agents currently must call req show after every mutation to confirm state; emitting JSON inline removes the extra round trip and reduces parsing of human-prose output.",
"statement": "The system shall accept a --json flag on every requirement mutation subcommand which causes the resulting requirement state to be printed as a JSON object on stdout.",
"status": "Verified",
"tags": [
"agents",
"json",
"ux"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493441500Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586084700Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752934500Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476328500Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376904400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460692500Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156573800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598543500Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034678300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373158500Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549139600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613879900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031499700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103946400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0038_add_json_emits_stdout_json",
"outcome": "Pass"
}
],
"title": "Emit JSON on mutation commands",
"updated": "2026-05-17T19:01:22.105777800Z"
},
"REQ-0039": {
"acceptance": [
"Every error path under --json prints a single JSON object with fields code, message and hint to stderr",
"Codes follow the pattern REQ-E-NNNN and are documented in req help errors",
"Validator failures under req validate --json return an array of objects with req_id, field, rule and severity",
"Integrity hash mismatch returns code REQ-E-INTEGRITY with a hint naming req repair --confirm-direct-edit"
],
"created": "2026-05-17T09:36:50.482792300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:36:50.482794600Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0017",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:38:27.053499400Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:27.923888700Z",
"reason": "Stable REQ-E-* codes routed via src/errors.rs; req help errors documents them"
},
{
"action": "removed depends-on link to REQ-0017",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:29.095790Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0045",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:29.238444600Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493708200Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586328Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753602600Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476460400Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377451200Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.433066500Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.461046200Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156876400Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598859400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035003100Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373492500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550217700Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614818700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032182100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105779800Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508151300Z",
"reason": "Rewrite to atomic, drops the embedded condition that tripped REQ-V-0010."
}
],
"id": "REQ-0039",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0045"
}
],
"priority": "Should",
"rationale": "Agents recover from failures more reliably when matching on stable codes than when parsing English prose; stable codes also make error handling testable.",
"statement": "On failure of a `--json` invocation, the system shall emit a stable error envelope with `code`, `message`, and `hint` fields.",
"status": "Verified",
"tags": [
"agents",
"errors",
"json"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493443500Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586086800Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752944600Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476330900Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376906600Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460695300Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156575400Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598546600Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034680600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373161400Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549143800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613888300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031502300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103961900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0039_json_error_envelope_on_failure",
"outcome": "Pass"
}
],
"title": "Emit structured JSON errors with stable codes",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0040": {
"acceptance": [
"req next --status approved returns one requirement whose depends-on targets are all status implemented or verified",
"req next --tag <topic> restricts the candidate set to that tag",
"req next --json prints the full requirement including acceptance criteria",
"When no requirement matches the filters the command exits non-zero with a clear message"
],
"created": "2026-05-17T09:36:53.736698200Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:36:53.736700200Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:38:23.915801200Z",
"reason": "Reword to remove compound-statement smell while keeping a single obligation"
},
{
"action": "statement updated",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:38:35.317335400Z",
"reason": "Drop enumeration of filter kinds that triggered compound-statement warning; acceptance criteria already enumerate the filters"
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.375400400Z",
"reason": "req next with dependency-aware filtering landed"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.209908300Z",
"reason": "Reviewed src/commands/next.rs: filters by status/kind/priority/tag, requires depends_on satisfied, sorts by priority then status; manually verified output"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.209932800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550248300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614846Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032198300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105818700Z",
"reason": null
}
],
"id": "REQ-0040",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Agents benefit from a single authoritative answer to 'what should I do next' rather than scraping list output and reasoning about depends-on prerequisites themselves.",
"statement": "The system shall provide a req next subcommand that returns a single requirement matching the supplied filters.",
"status": "Verified",
"tags": [
"agents",
"planning"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.209874200Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/next.rs: filters by status/kind/priority/tag, requires depends_on satisfied, sorts by priority then status; manually verified output",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549154900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0040_next_returns_highest_priority_unblocked_requirement",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613898400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0040_next_returns_highest_priority_unblocked_requirement",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031504800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0040_next_returns_highest_priority_unblocked_requirement",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103968500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0040_next_returns_highest_priority_unblocked_requirement",
"outcome": "Pass"
}
],
"title": "Suggest the next requirement to work on",
"updated": "2026-05-17T19:01:22.105844400Z"
},
"REQ-0041": {
"acceptance": [
"req check origin/main exits zero when no requirements changed since origin/main have validator errors",
"req check origin/main reports coverage findings only for source files changed since origin/main",
"req check --json origin/main prints the same findings as a JSON array",
"Running req check against an unknown ref exits non-zero with a message naming the ref"
],
"created": "2026-05-17T09:37:01.142466100Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:37:01.142468300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.507769300Z",
"reason": "req check ref scoped validation and coverage landed"
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.384006100Z",
"reason": "Reviewed src/commands/check.rs: loads base via git show, diffs reqs by content, runs validate on changed reqs, scopes coverage to git diff --name-only; manually verified HEAD~1 against current"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.384024Z",
"reason": null
}
],
"id": "REQ-0041",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Incremental validation gives agents and pre-commit hooks a tight feedback loop scoped to the change under review, instead of re-checking the whole project on every iteration.",
"statement": "The system shall provide a req check <ref> subcommand that runs the validator against requirements changed since the given git ref and reports coverage gaps for source files changed since that ref.",
"status": "Verified",
"tags": [
"validation",
"git",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.383970100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/check.rs: loads base via git show, diffs reqs by content, runs validate on changed reqs, scopes coverage to git diff --name-only; manually verified HEAD~1 against current",
"outcome": "Pass"
}
],
"title": "Validate only changes since a git ref",
"updated": "2026-05-17T13:33:06.384023400Z"
},
"REQ-0042": {
"acceptance": [
"req help agents --json prints a JSON object with sections triggers, commands and rules",
"Each trigger entry has fields situation and first_command",
"The JSON document round-trips through jq without error"
],
"created": "2026-05-17T09:37:09.605294800Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:37:09.605296900Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0017",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:38:27.196995100Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.649773600Z",
"reason": "help section JSON output plus structured agents crib landed"
},
{
"action": "added refines link to REQ-0018",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.217111Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.568135900Z",
"reason": "req help agents --json emits structured triggers/commands/rules/env; manually verified count: 11 triggers, 12 commands, 6 rules, 3 env"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.568155800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550276800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614873500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032213300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105846400Z",
"reason": null
}
],
"id": "REQ-0042",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0017"
},
{
"kind": "Refines",
"target": "REQ-0018"
}
],
"priority": "Could",
"rationale": "MCP clients and other automated consumers can ingest a structured crib without scraping markdown formatting.",
"statement": "The system shall support req help agents --json which prints the agent crib as a structured JSON document.",
"status": "Verified",
"tags": [
"agents",
"docs",
"json"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.568102Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "req help agents --json emits structured triggers/commands/rules/env; manually verified count: 11 triggers, 12 commands, 6 rules, 3 env",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549163Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0042_help_agents_json_emits_structured_crib",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613912Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0042_help_agents_json_emits_structured_crib",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031508600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0042_help_agents_json_emits_structured_crib",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103975300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0042_help_agents_json_emits_structured_crib",
"outcome": "Pass"
}
],
"title": "Expose agent guidance as JSON",
"updated": "2026-05-17T19:01:22.105872200Z"
},
"REQ-0043": {
"acceptance": [
"Each history entry stores an actor_kind field with one of the values human, agent or unknown",
"actor_kind is derived from a REQ_ACTOR_KIND environment variable when set and otherwise defaults to unknown",
"req audit --json includes actor_kind for every entry it emits",
"req help agents documents the REQ_ACTOR_KIND convention"
],
"created": "2026-05-17T09:37:14.164584400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:37:14.164586500Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.791396500Z",
"reason": "actor_kind field on HistoryEntry; REQ_ACTOR_KIND env; surfaced in req show"
},
{
"action": "added refines link to REQ-0011",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.814055900Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.762274600Z",
"reason": "Reviewed src/commands/mod.rs::current_actor_kind: reads REQ_ACTOR_KIND; show.rs displays (agent)/(human) tag; manually verified"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.762298Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550297600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614897100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032228400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105874500Z",
"reason": null
}
],
"id": "REQ-0043",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0011"
}
],
"priority": "Could",
"rationale": "Reviewers need to know which requirement changes were authored by a human versus an automated agent so that human-review-required policies can be enforced.",
"statement": "The system shall record a distinct actor classification on each history entry so that human edits can be separated from agent edits when auditing.",
"status": "Verified",
"tags": [
"agents",
"audit",
"provenance"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.762195600Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/mod.rs::current_actor_kind: reads REQ_ACTOR_KIND; show.rs displays (agent)/(human) tag; manually verified",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549173400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0043_actor_kind_env_tags_history_entry",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613920300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0043_actor_kind_env_tags_history_entry",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031519100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0043_actor_kind_env_tags_history_entry",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103980300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0043_actor_kind_env_tags_history_entry",
"outcome": "Pass"
}
],
"title": "Distinguish human and agent actors in history",
"updated": "2026-05-17T19:01:22.105898300Z"
},
"REQ-0044": {
"acceptance": [
"Running req hooks install --claude-code creates or updates .claude/settings.json with an allowlist permitting req subcommands",
"The same command writes a Stop hook entry that runs req validate",
"Re-running the command is idempotent and does not duplicate entries",
"The command prints the path it wrote to"
],
"created": "2026-05-17T09:37:19.490874700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:37:19.490877600Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T10:35:48.934112Z",
"reason": "hooks install claude-code writes permissions allowlist and Stop validate hook"
},
{
"action": "added refines link to REQ-0023",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.685338Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:27.283418100Z",
"reason": "Reviewed src/commands/hooks.rs::install_claude_code: merges with existing .claude/settings.json, allowlist + Stop hook; verified idempotent in session"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:27.283441300Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550323800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614926900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032243300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105900100Z",
"reason": null
}
],
"id": "REQ-0044",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0023"
}
],
"priority": "Could",
"rationale": "Pre-wired Claude Code settings remove per-clone setup friction and ensure validation runs on every agent session end without each user configuring it by hand.",
"statement": "The system shall provide a req hooks install --claude-code flag that writes a permissions allowlist and a stop hook running req validate into the project .claude/settings.json.",
"status": "Verified",
"tags": [
"integration",
"claude-code",
"hooks"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:27.283364300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/commands/hooks.rs::install_claude_code: merges with existing .claude/settings.json, allowlist + Stop hook; verified idempotent in session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549175400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0044_hooks_install_claude_code_writes_settings_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613928700Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0044_hooks_install_claude_code_writes_settings_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031521400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0044_hooks_install_claude_code_writes_settings_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103984300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0044_hooks_install_claude_code_writes_settings_json",
"outcome": "Pass"
}
],
"title": "Install Claude Code integration assets",
"updated": "2026-05-17T19:01:22.105926Z"
},
"REQ-0045": {
"acceptance": [
"Every Finding produced by the validator carries a rule_code field matching the pattern REQ-V-NNNN",
"req validate text output prints the rule code at the start of each finding line",
"req validate --json includes rule_code on every finding object",
"req help best-practice lists every rule code with its meaning"
],
"created": "2026-05-17T09:37:23.033326600Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:37:23.033329300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:27.358078600Z",
"reason": "Implemented in slice 1: rule codes / test records / show drift"
},
{
"action": "added refines link to REQ-0006",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:27.466929Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:39:57.493724300Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:11.586342700Z",
"reason": null
},
{
"action": "test pass recorded against commit 666cc1f8f via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:21:22.753618200Z",
"reason": null
},
{
"action": "test pass recorded against commit 51dcd0fb3 via req test run",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:22:21.476468400Z",
"reason": null
},
{
"action": "test pass recorded against commit f5bf83899 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.377480900Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:31:41.433093Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:28.461071200Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156892500Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598875200Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035019100Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373508800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550349Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614957Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032265Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105928600Z",
"reason": null
}
],
"id": "REQ-0045",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0006"
}
],
"priority": "Should",
"rationale": "Stable rule codes let agents and tooling react to specific findings without depending on the exact wording of human-readable messages.",
"statement": "The system shall prefix every validator finding message with a stable rule code of the form REQ-V-NNNN so that consumers can pattern-match without parsing prose.",
"status": "Verified",
"tags": [
"validation",
"errors",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:39:57.493447700Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T11:42:11.586092Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:21:22.752947900Z",
"commit": "666cc1f8f84ff2a75b1d0ce2534964502de5dedf",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:22:21.476333800Z",
"commit": "51dcd0fb3b3708a644665986d63d1186780fc3ac",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:31:41.376909700Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T13:46:28.460700Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156578100Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598550500Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034684100Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373164500Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549177500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613936700Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031523300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103988400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0045_validator_emits_stable_rule_codes",
"outcome": "Pass"
}
],
"title": "Prefix validator findings with stable rule codes",
"updated": "2026-05-17T19:01:22.105965100Z"
},
"REQ-0047": {
"acceptance": [
"req mcp --init-config writes a .mcp.json containing an mcpServers.req entry with command=req and args=[mcp]",
"Re-running without --force refuses to overwrite an existing file",
"The generated description names req_help as the first call agents should make"
],
"created": "2026-05-17T09:40:21.745821800Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:21.745823500Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.770422800Z",
"reason": "req mcp --init-config writes .mcp.json at repo root with managed shape"
},
{
"action": "added refines link to REQ-0017",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.390633300Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.468248400Z",
"reason": "Reviewed src/mcp.rs::write_config: writes pretty JSON with _readme and mcpServers.req; manually verified via req mcp --init-config"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.468266900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550380700Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.614985200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032282100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.105975800Z",
"reason": null
}
],
"id": "REQ-0047",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0017"
}
],
"priority": "Should",
"rationale": "Bootstrap config lets MCP clients launch the server with zero per-agent setup, which is the difference between agents discovering the tool and agents missing it.",
"statement": "The system shall, when invoked as req mcp --init-config, write a .mcp.json at the configured path that registers req as an mcpServers entry with a description aimed at agents on first contact.",
"status": "Verified",
"tags": [
"agents",
"mcp"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:25.468212400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed src/mcp.rs::write_config: writes pretty JSON with _readme and mcpServers.req; manually verified via req mcp --init-config",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549180400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0047_mcp_init_config_writes_managed_mcp_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613958Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0047_mcp_init_config_writes_managed_mcp_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031532100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0047_mcp_init_config_writes_managed_mcp_json",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.103997300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0047_mcp_init_config_writes_managed_mcp_json",
"outcome": "Pass"
}
],
"title": "Generate .mcp.json bootstrap for MCP-capable agent clients",
"updated": "2026-05-17T19:01:22.106003Z"
},
"REQ-0048": {
"acceptance": [
"Each tools/list entry has a description that starts with or contains an explicit trigger or call-ordering hint",
"req_list description marks it as the first tool to call when starting work",
"req_update description names reason as mandatory"
],
"created": "2026-05-17T09:40:21.883741800Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:40:21.883743900Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:05.942087500Z",
"reason": "Each MCP tool description starts with or contains an explicit trigger or call-ordering hint"
},
{
"action": "added refines link to REQ-0017",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:28.538242700Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.652094900Z",
"reason": "Reviewed each ToolDef description in src/mcp.rs: each contains a trigger or call-ordering hint (CALL FIRST, ALWAYS pass reason, etc)"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.652113100Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605959300Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550410500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615000600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032296800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106005400Z",
"reason": null
}
],
"id": "REQ-0048",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0017"
}
],
"priority": "Should",
"rationale": "Tool descriptions ARE the agent-facing guidance surface; an agent reading tools/list should be able to plan without further documentation lookups.",
"statement": "The system shall include a trigger sentence in every MCP tool description telling the agent when to call the tool.",
"status": "Verified",
"tags": [
"agents",
"mcp",
"docs"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:25.652058900Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Reviewed each ToolDef description in src/mcp.rs: each contains a trigger or call-ordering hint (CALL FIRST, ALWAYS pass reason, etc)",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549183Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0048_mcp_tool_descriptions_contain_trigger_hints",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613962300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0048_mcp_tool_descriptions_contain_trigger_hints",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031534300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0048_mcp_tool_descriptions_contain_trigger_hints",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104002Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0048_mcp_tool_descriptions_contain_trigger_hints",
"outcome": "Pass"
}
],
"title": "Tools expose first-class agent guidance in descriptions",
"updated": "2026-05-17T19:01:22.106032Z"
},
"REQ-0049": {
"acceptance": [
"req test record REQ-XXXX --result pass --notes \"...\" appends an entry containing the output of git rev-parse HEAD, the outcome, the notes, the actor and an ISO-8601 UTC timestamp",
"Running the command outside a git working tree exits non-zero with a clear message rather than recording a null SHA",
"A requirement may accumulate multiple test records; each is preserved in insertion order",
"Test records are stored inside project.req so they are git-diffable and round-trip through the integrity hash"
],
"created": "2026-05-17T09:43:07.810086Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:43:07.810090200Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:27.501522500Z",
"reason": "Implemented in slice 1: rule codes / test records / show drift"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.949011800Z",
"reason": "Test record machinery is exercised every time req test run executes; this very session has 17 automated records pinned to HEAD"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:06.949029700Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605977900Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550435800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615016Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032311900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106036400Z",
"reason": null
}
],
"id": "REQ-0049",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Without a recorded commit hash a passing test cannot be re-evaluated against later changes; storing the SHA plus outcome and notes gives a minimum evidence trail and lets future tooling decide if the result is still valid.",
"statement": "The system shall attach test records to any requirement via `req test record`.",
"status": "Verified",
"tags": [
"testing",
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:06.948977300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0055 — Test record machinery is exercised every time req test run executes; this very session has 17 automated records pinned to HEAD",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549185100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0049_test_record_attaches_outcome_and_head_sha",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613964900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0049_test_record_attaches_outcome_and_head_sha",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031540800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0049_test_record_attaches_outcome_and_head_sha",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104006600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0049_test_record_attaches_outcome_and_head_sha",
"outcome": "Pass"
}
],
"title": "Record test runs against requirements with git commit SHA",
"updated": "2026-05-17T19:01:22.106056600Z"
},
"REQ-0050": {
"acceptance": [
"req show REQ-XXXX lists every test record with its short SHA, outcome, actor, timestamp and notes",
"The latest record is annotated as either matching current HEAD or noting the SHA has drifted",
"A requirement with no test records renders an explicit \"no test records\" line rather than omitting the section"
],
"created": "2026-05-17T09:43:18.601686700Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:43:18.601690300Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:27.638696300Z",
"reason": "Implemented in slice 1: rule codes / test records / show drift"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:07.143546500Z",
"reason": "Show display of records with HEAD-drift marker is the same render path used by every req show; manually verified in this session"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:07.143566100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550561100Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615030900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032326700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106058600Z",
"reason": null
}
],
"id": "REQ-0050",
"kind": "Functional",
"links": [
{
"kind": "Parent",
"target": "REQ-0049"
}
],
"priority": "Should",
"rationale": "Recording a tested-against SHA only delivers value if users can see at a glance whether the codebase has moved since the last test; a simple same/differs marker is the cheapest useful signal.",
"statement": "The system shall display each requirement's test records in req show, indicating for the most recent record whether its commit SHA matches the current git HEAD.",
"status": "Verified",
"tags": [
"testing",
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:07.143508100Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0049 — Show display of records with HEAD-drift marker is the same render path used by every req show; manually verified in this session",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549187600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0050_show_marks_latest_record_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613967400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0050_show_marks_latest_record_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031542600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0050_show_marks_latest_record_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104011600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0050_show_marks_latest_record_against_head",
"outcome": "Pass"
}
],
"title": "Surface test records and commit drift in req show",
"updated": "2026-05-17T19:01:22.106080700Z"
},
"REQ-0051": {
"acceptance": [
"After three failed adds and one good add, the new ID equals previous next_id (no gaps)"
],
"created": "2026-05-17T09:44:29.608078400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:44:29.608078800Z",
"reason": null
},
{
"action": "test pass recorded against commit 33534464f",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:06.258575100Z",
"reason": "Verified in session 2026-05-17: three rejected adds before a successful one allocated the immediate next sequential ID (REQ-0051 itself)"
},
{
"action": "status draft -> verified",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:06.398742800Z",
"reason": "Test record captured against current HEAD; behaviour confirmed on both CLI and MCP paths"
},
{
"action": "added verifies link to REQ-0010",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:29.505908700Z",
"reason": null
}
],
"id": "REQ-0051",
"kind": "Functional",
"links": [
{
"kind": "Verifies",
"target": "REQ-0010"
}
],
"priority": "Should",
"rationale": "Pre-validation allocation burned IDs on every rejected attempt; this verifies the fix.",
"statement": "The system shall allocate REQ IDs only after a candidate requirement passes validation.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:05:06.258523600Z",
"commit": "33534464f0f0f8f90dd651cc353d486def94f4be",
"kind": "Automated",
"notes": "Verified in session 2026-05-17: three rejected adds before a successful one allocated the immediate next sequential ID (REQ-0051 itself)",
"outcome": "Pass"
}
],
"title": "Verify allocate_id is post-validation",
"updated": "2026-05-17T11:05:29.505930600Z"
},
"REQ-0052": {
"acceptance": [
"After validator rejection via CLI and MCP, the next successful add allocates the immediate next sequential ID"
],
"created": "2026-05-17T09:44:55.168697Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:44:55.168697600Z",
"reason": null
},
{
"action": "test pass recorded against commit 33534464f",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:06.565552Z",
"reason": "Verified 2026-05-17: validator-reject on CLI (no modal verb) and MCP (too-short statement) both preserved next_id"
},
{
"action": "status draft -> verified",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:06.695033900Z",
"reason": "Test record captured; covered both CLI and MCP validator-reject paths"
},
{
"action": "added verifies link to REQ-0010",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T11:05:29.648189900Z",
"reason": null
}
],
"id": "REQ-0052",
"kind": "Functional",
"links": [
{
"kind": "Verifies",
"target": "REQ-0010"
}
],
"priority": "Should",
"rationale": "Burned IDs across CLI and MCP would erode the contract documented in REQ-0010.",
"statement": "The system shall preserve the next ID counter when the validator rejects a candidate requirement on either the CLI or MCP path.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:05:06.565514500Z",
"commit": "33534464f0f0f8f90dd651cc353d486def94f4be",
"kind": "Automated",
"notes": "Verified 2026-05-17: validator-reject on CLI (no modal verb) and MCP (too-short statement) both preserved next_id",
"outcome": "Pass"
}
],
"title": "Verify validator-reject path preserves IDs",
"updated": "2026-05-17T11:05:29.648210700Z"
},
"REQ-0054": {
"acceptance": [
"req status prints counts for draft, proposed, approved, implemented, verified and obsolete with percentages of the total",
"req status reports a delivery-progress percentage equal to (implemented + verified) divided by non-obsolete",
"req status --json emits a stable shape with project, total, by_status, delivery_progress_pct, non_obsolete and done"
],
"created": "2026-05-17T09:56:28.064673300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T09:56:28.064675900Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:05:06.083649300Z",
"reason": "req status with bucket counts, percentages and delivery_progress_pct landed; --json shape stable"
},
{
"action": "composition evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.828344Z",
"reason": "Status counters share load_resolved with export; output shape verified manually"
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:32:25.828362Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.605995900Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550616100Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615054100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032349400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106082700Z",
"reason": null
}
],
"id": "REQ-0054",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Requested for at-a-glance progress signalling without scraping req list output.",
"statement": "The system shall report project-level implementation status via `req status`.",
"status": "Verified",
"tags": [
"ux",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:32:25.828310300Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Composition",
"notes": "cites: REQ-0014 — Status counters share load_resolved with export; output shape verified manually",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549189900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0054_status_emits_buckets_and_delivery_progress",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613975100Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0054_status_emits_buckets_and_delivery_progress",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031544800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0054_status_emits_buckets_and_delivery_progress",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104016Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0054_status_emits_buckets_and_delivery_progress",
"outcome": "Pass"
}
],
"title": "Project-level implementation status summary",
"updated": "2026-05-17T19:01:22.106107200Z"
},
"REQ-0055": {
"acceptance": [
"Running req test run --dry-run prints the planned records without modifying project.req",
"Running req test run records one TestRecord per REQ ID present in test names of the form req_NNNN_",
"Outcome is fail if any covered test failed, else pass; notes list the test names",
"REQ IDs that no longer exist in project.req are reported but not written"
],
"created": "2026-05-17T11:41:54.315016400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:41:54.315021700Z",
"reason": null
},
{
"action": "status draft -> implemented",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:34.585151400Z",
"reason": "req test run shipped; verified by recording 17 evidence points across REQ-0001..REQ-0045 in this session"
},
{
"action": "added refines link to REQ-0049",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:34.730208200Z",
"reason": null
},
{
"action": "test pass recorded against commit f0d490d1e",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:34.929250Z",
"reason": "Self-verification: req test run --dry-run lists 17 candidate requirements; req test run wrote 17 records on first invocation; the runner correctly distinguished known REQ IDs from unknowns"
},
{
"action": "status implemented -> verified",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T11:42:35.055421700Z",
"reason": "Self-attested test record captured"
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.606019100Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550641Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615068900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032365500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106109500Z",
"reason": null
}
],
"id": "REQ-0055",
"kind": "Functional",
"links": [
{
"kind": "Refines",
"target": "REQ-0049"
}
],
"priority": "Should",
"rationale": "Closes the loop between automated tests and the projects own coverage dashboard so test evidence reflects reality on every CI run.",
"statement": "The system shall provide `req test run` to attach per-requirement test records from a configurable test command's output.",
"status": "Verified",
"tags": [
"testing",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T11:42:34.929201200Z",
"commit": "f0d490d1e26ffb24c8f7c003b62552e1b01ad143",
"kind": "Automated",
"notes": "Self-verification: req test run --dry-run lists 17 candidate requirements; req test run wrote 17 records on first invocation; the runner correctly distinguished known REQ IDs from unknowns",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549192300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0055_test_run_dry_run_parses_req_named_tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613978400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0055_test_run_dry_run_parses_req_named_tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031546800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0055_test_run_dry_run_parses_req_named_tests",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104022900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0055_test_run_dry_run_parses_req_named_tests",
"outcome": "Pass"
}
],
"title": "Drive cargo test and attach per-requirement test records",
"updated": "2026-05-17T19:01:22.106129600Z"
},
"REQ-0056": {
"acceptance": [
"TestRecord carries an EvidenceKind discriminator of automated, composition or inspection",
"req verify ID --by composition|inspection --notes ... writes a record of the chosen kind with the current HEAD SHA",
"req test run --promote flips Implemented to Verified for every requirement with a fresh passing record of any kind",
"req show prints the kind in square brackets alongside outcome and commit"
],
"created": "2026-05-17T13:33:32.940876300Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:32.940878100Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5bf83899",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:33.143182Z",
"reason": "Self-attestation: this very batch promoted 33 reqs to Verified using --by composition/--by inspection with --promote; help section 'verification' documents the policy"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:33:33.143345800Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550765600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615092900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032380600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106131400Z",
"reason": null
}
],
"id": "REQ-0056",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Without an evidence policy, Verified is an optimism slider that lies after the next refactor.",
"statement": "The system shall back Verified status with at least one fresh evidence record (automated, composition or inspection) pinned to the current git HEAD.",
"status": "Verified",
"tags": [
"testing",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:33:33.143132400Z",
"commit": "f5bf83899e7c6d6f8a726930627ceff845ce2591",
"kind": "Inspection",
"notes": "Self-attestation: this very batch promoted 33 reqs to Verified using --by composition/--by inspection with --promote; help section 'verification' documents the policy",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549198800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0056_verify_inspection_promotes_to_verified",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613980400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0056_verify_inspection_promotes_to_verified",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031548700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0056_verify_inspection_promotes_to_verified",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104038500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0056_verify_inspection_promotes_to_verified",
"outcome": "Pass"
}
],
"title": "Verified status backed by automated or manual evidence",
"updated": "2026-05-17T19:01:22.106152500Z"
},
"REQ-0059": {
"acceptance": [
"Supported targets are x86_64-unknown-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin, and x86_64-pc-windows-msvc",
"Pushing a v* tag triggers .github/workflows/release.yml and the workflow run succeeds for every supported target",
"Each release archive contains the req binary plus README.md and LICENSE",
"Archive names follow the pattern req-<tag>-<target>.(tar.gz|zip)"
],
"created": "2026-05-17T13:38:48.594013700Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:38:48.594014500Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5a393f25",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.935377100Z",
"reason": "Reviewed .github/workflows/release.yml: triggers on v* tags, matrix builds for x86_64-unknown-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc; packages include req binary plus README.md and LICENSE; archive naming req-<tag>-<target>.(tar.gz|zip) per acceptance"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.935406700Z",
"reason": null
}
],
"id": "REQ-0059",
"kind": "NonFunctional",
"links": [],
"priority": "Should",
"rationale": "Users without a Rust toolchain need a one-step install. A tagged-release contract makes the distribution promise reproducible and auditable rather than ad-hoc.",
"statement": "The project shall attach a prebuilt binary archive for each supported target to a GitHub release on every push of a tag matching `v*`.",
"status": "Verified",
"tags": [
"distribution",
"release"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.935299200Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Inspection",
"notes": "Reviewed .github/workflows/release.yml: triggers on v* tags, matrix builds for x86_64-unknown-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc; packages include req binary plus README.md and LICENSE; archive naming req-<tag>-<target>.(tar.gz|zip) per acceptance",
"outcome": "Pass"
}
],
"title": "Publish prebuilt binaries on tagged releases",
"updated": "2026-05-17T14:43:13.935406Z"
},
"REQ-0060": {
"acceptance": [
"Cargo.toml package name is req-cli",
"Cargo.toml [[bin]] section defines a binary named req",
"`cargo install req-cli` from crates.io installs an executable named req",
"Cargo.toml declares license, description, repository, readme, keywords, and categories so the crates.io listing is complete"
],
"created": "2026-05-17T13:38:55.313099900Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:38:55.313100600Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0061",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:39:20.851867600Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5a393f25",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:14.195692500Z",
"reason": "Cargo.toml: name=req-cli, [[bin]] name=req, license=MIT, description, repository, readme, keywords, categories all populated for crates.io"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:14.195715200Z",
"reason": null
}
],
"id": "REQ-0060",
"kind": "NonFunctional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0061"
}
],
"priority": "Should",
"rationale": "The `req` crate name is already taken on crates.io. Using `req-cli` as the package name while keeping `req` as the binary name preserves the short CLI invocation users expect and matches the convention of tools like ripgrep (rg) and fd-find (fd).",
"statement": "The project shall be installable from crates.io via `cargo install req-cli`, producing a binary named `req`.",
"status": "Verified",
"tags": [
"distribution",
"release"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:14.195596500Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Inspection",
"notes": "Cargo.toml: name=req-cli, [[bin]] name=req, license=MIT, description, repository, readme, keywords, categories all populated for crates.io",
"outcome": "Pass"
}
],
"title": "Publish the crate to crates.io as req-cli",
"updated": "2026-05-17T14:43:14.195714400Z"
},
"REQ-0061": {
"acceptance": [
"A LICENSE file containing the MIT license text exists at the repository root",
"Cargo.toml [package] section sets license = \"MIT\"",
"README.md links to the LICENSE file in its license section"
],
"created": "2026-05-17T13:39:01.640242700Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:39:01.640243400Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156908600Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193182400Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598891100Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035033800Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373523500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550822700Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615109800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032396100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106154700Z",
"reason": null
}
],
"id": "REQ-0061",
"kind": "Constraint",
"links": [],
"priority": "Must",
"rationale": "An OSI-approved permissive license is required for the project to be legally reusable and for publication to crates.io. MIT is short, well understood, and consistent with the broader Rust ecosystem.",
"statement": "The project shall be distributed under the MIT license.",
"status": "Verified",
"tags": [
"legal",
"distribution"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156582700Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_cargo_declares_license, req_0061_license_file_is_mit, req_0061_readme_links_license",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598555500Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_cargo_declares_license, req_0061_license_file_is_mit, req_0061_readme_links_license",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034687800Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_readme_links_license, req_0061_license_file_is_mit, req_0061_cargo_declares_license",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373170Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_license_file_is_mit, req_0061_cargo_declares_license, req_0061_readme_links_license",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549208200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_cargo_declares_license, req_0061_license_file_is_mit, req_0061_readme_links_license",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613983300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_license_file_is_mit, req_0061_readme_links_license, req_0061_cargo_declares_license",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031551300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_cargo_declares_license, req_0061_readme_links_license, req_0061_license_file_is_mit",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104045Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0061_cargo_declares_license, req_0061_license_file_is_mit, req_0061_readme_links_license",
"outcome": "Pass"
}
],
"title": "Distribute under the MIT license",
"updated": "2026-05-17T19:01:22.106229800Z"
},
"REQ-0062": {
"acceptance": [
"Two concurrent req add invocations against the same project file both succeed, produce requirements with distinct IDs, and both end up in the final file",
"The lock is released automatically if the holding process is killed (OS-level advisory lock, not a stale sidecar file)",
"Lock acquisition has a bounded timeout and emits a clear error message naming the contending operation when the timeout is hit"
],
"created": "2026-05-17T13:43:00.167172400Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:43:00.167173400Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0022",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:43:06.530512900Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598906500Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648570600Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035048600Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373538400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550851800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615125200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032416600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106232500Z",
"reason": null
}
],
"id": "REQ-0062",
"kind": "NonFunctional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0022"
}
],
"priority": "Must",
"rationale": "Temp-and-rename (REQ-0022) guards against crash-corruption but not lost updates. Under MCP, two agents calling req_add concurrently can both load the same state, both allocate the same next ID, and then have the second writer silently overwrite the first. A held advisory lock across load+mutate+save closes this race.",
"statement": "The system shall acquire an exclusive advisory lock on the project file for the full load-modify-save cycle, so that two concurrent CLI or MCP invocations cannot lose each other's updates.",
"status": "Verified",
"tags": [
"storage",
"reliability",
"concurrency"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598571800Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_is_cleaned_up_after_release, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034704100Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_is_cleaned_up_after_release, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373173100Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_is_cleaned_up_after_release, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549211400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_persists_between_acquires, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613986300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_persists_between_acquires, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031554300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_persists_between_acquires, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104050300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0062_lock_sidecar_persists_between_acquires, req_0062_two_concurrent_adds_both_land_with_distinct_ids, req_0062_five_concurrent_adds_all_land_with_unique_ids",
"outcome": "Pass"
}
],
"title": "Serialize concurrent writes with an advisory file lock",
"updated": "2026-05-17T19:01:22.106257Z"
},
"REQ-0063": {
"acceptance": [
"req show prints [STALE — changed: <files>] on the latest record when linked files changed since the commit",
"req stale reports fresh / drifted / stale counts and lists offenders",
"req stale --only-stale exits non-zero if at least one requirement is stale"
],
"created": "2026-05-17T13:46:06.862642Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:06.862652200Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit ecb15948c",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:51.942511100Z",
"reason": "Self-verification: req stale just reported 12 STALE requirements with their changed linked files; req show on any stale req displays [STALE — changed: ...] tag; req stale --only-stale exits non-zero"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T13:46:51.942536100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550881400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615146500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032433200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106259200Z",
"reason": null
}
],
"id": "REQ-0063",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Commit-level drift fires on every push and trains reviewers to ignore the signal; content drift only fires when the code the requirement actually depends on has moved.",
"statement": "The system shall mark a test record as STALE when files containing the requirements REQ-NNNN marker have changed since the record commit.",
"status": "Verified",
"tags": [
"testing",
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T13:46:51.942446700Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Inspection",
"notes": "Self-verification: req stale just reported 12 STALE requirements with their changed linked files; req show on any stale req displays [STALE — changed: ...] tag; req stale --only-stale exits non-zero",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549213500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0063_stale_reports_records_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613988500Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0063_stale_reports_records_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031556700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0063_stale_reports_records_against_head",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104054600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0063_stale_reports_records_against_head",
"outcome": "Pass"
}
],
"title": "Surface content drift beyond commit drift in staleness reports",
"updated": "2026-05-17T19:01:22.106282100Z"
},
"REQ-0064": {
"acceptance": [
"`req doctor` reports whether the project-level pre-commit hook that invokes `req validate` is installed",
"`req doctor` reports whether the `req-merge` git merge driver is activated in the local git config",
"`req doctor` reports whether `commit.gpgsign` (or an equivalent SSH-signing config) is enabled for the repository",
"`req doctor` exits with a non-zero status when one or more checks fail, so it can be used as a CI gate",
"`req doctor --json` emits a machine-readable report for tooling"
],
"created": "2026-05-17T13:46:51.111161600Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:46:51.111165Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598921100Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648603900Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035062700Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373552400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550913600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615175Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032448100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106284600Z",
"reason": null
}
],
"id": "REQ-0064",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Pre-commit hook installation, git merge-driver activation, and commit signing are configured per-clone and easy to skip. When skipped they cause silent ID collisions, unsigned audit trails, and unvalidated commits that only surface as incidents. A single audit command lets users (and CI) catch missing setup before it bites.",
"statement": "The system shall provide a `req doctor` command that reports the status of per-clone setup steps required for safe collaborative use.",
"status": "Verified",
"tags": [
"setup",
"integration",
"ux"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598574200Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034707400Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373175800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549216200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613990900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031558900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104059100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0064_doctor_reports_missing_pre_commit, req_0064_doctor_passes_after_hooks_install",
"outcome": "Pass"
}
],
"title": "Provide req doctor to audit local repo setup",
"updated": "2026-05-17T19:01:22.106308600Z"
},
"REQ-0065": {
"acceptance": [
"`req coverage --strict` (or equivalent flag) exits with a non-zero status when at least one orphan or ghost is detected, and zero otherwise",
"Default `req coverage` behaviour remains informational (zero exit even with findings) so existing users are not broken",
"`req hooks install` installs (or updates) a pre-commit hook that runs `req coverage` in strict mode against the staged source tree",
"`req help integration` documents a minimal CI snippet (e.g. one-liner under a GitHub Actions step) using the strict-mode invocation"
],
"created": "2026-05-17T13:46:59.502858900Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:46:59.502859800Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156928200Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193224100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598939700Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035077200Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373566900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550949500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615202100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032468300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106311100Z",
"reason": null
}
],
"id": "REQ-0065",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "`req coverage` today is informational only — orphans and ghosts surface only if someone reads the output. Spec-code drift therefore accumulates silently. A strict-mode flag that turns findings into an exit-code failure lets the pre-commit hook and CI catch drift on the same invocation users already run locally.",
"statement": "The system shall provide a strict mode for `req coverage` that exits with a non-zero status when orphans or ghosts are detected, so that the same command can gate commits and CI runs.",
"status": "Verified",
"tags": [
"coverage",
"integration",
"ci"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156585800Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0065_coverage_strict_passes_when_clean, req_0065_coverage_default_remains_informational, req_0065_coverage_strict_exits_nonzero_with_orphans",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598577500Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0065_coverage_strict_passes_when_clean, req_0065_coverage_default_remains_informational, req_0065_coverage_strict_exits_nonzero_with_orphans",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034710300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0065_coverage_strict_passes_when_clean, req_0065_coverage_default_remains_informational, req_0065_coverage_strict_exits_nonzero_with_orphans",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373178800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 4 pass / 0 fail / 0 ignored — req_0065_strict_allow_lets_known_orphans_pass, req_0065_coverage_strict_passes_when_clean, req_0065_coverage_default_remains_informational, req_0065_coverage_strict_exits_nonzero_with_orphans",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549219600Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 4 pass / 0 fail / 0 ignored — req_0065_strict_allow_lets_known_orphans_pass, req_0065_coverage_strict_passes_when_clean, req_0065_coverage_strict_exits_nonzero_with_orphans, req_0065_coverage_default_remains_informational",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.613993800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 4 pass / 0 fail / 0 ignored — req_0065_strict_allow_lets_known_orphans_pass, req_0065_coverage_strict_passes_when_clean, req_0065_coverage_strict_exits_nonzero_with_orphans, req_0065_coverage_default_remains_informational",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031565100Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 4 pass / 0 fail / 0 ignored — req_0065_strict_allow_lets_known_orphans_pass, req_0065_coverage_strict_passes_when_clean, req_0065_coverage_strict_exits_nonzero_with_orphans, req_0065_coverage_default_remains_informational",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104064900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 4 pass / 0 fail / 0 ignored — req_0065_strict_allow_lets_known_orphans_pass, req_0065_coverage_strict_passes_when_clean, req_0065_coverage_strict_exits_nonzero_with_orphans, req_0065_coverage_default_remains_informational",
"outcome": "Pass"
}
],
"title": "Make req coverage usable as a gate in pre-commit and CI",
"updated": "2026-05-17T19:01:22.106334500Z"
},
"REQ-0066": {
"acceptance": [
"A batch with N valid mutations produces exactly one file write and N history entries (one per requirement touched).",
"A batch where any single mutation fails validation leaves project.req byte-identical to its pre-batch state and exits non-zero with a structured error identifying the failing mutation.",
"Supported mutation kinds at minimum: add, update, link, delete (mirroring the single-shot CLI surface).",
"Each mutation in the batch may carry its own --reason; a top-level reason applies as default."
],
"created": "2026-05-17T13:48:31.531327600Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:48:31.531329700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598954400Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648628300Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035091900Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373580900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.550974300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615219200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032484Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106336900Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508212Z",
"reason": "Atomic rewrite. Atomicity, validation rollback, and history-per-req detail captured by acceptance criteria."
}
],
"id": "REQ-0066",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Agents currently make one CLI round-trip per requirement when refactoring tags, retiring requirements en masse, or applying review feedback across many IDs. Each round-trip rewrites and re-hashes project.req, multiplies the chance of a partial-failure state, and produces noisy history. A single transactional entry point is the natural counterpart to the \"CLI is the only legitimate mutator\" design and removes the temptation to hand-edit for bulk changes.",
"statement": "The CLI shall apply a JSON document of mutations atomically through `req batch`.",
"status": "Verified",
"tags": [
"agents",
"ux",
"bulk"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598579900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034712600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373183200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 5 pass / 0 fail / 0 ignored — req_0066_batch_empty_mutations_array_is_a_noop, req_0066_batch_unknown_mutation_kind_is_rejected_atomically, req_0066_batch_link_to_self_is_rejected_and_rolls_back, req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549229900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 5 pass / 0 fail / 0 ignored — req_0066_batch_unknown_mutation_kind_is_rejected_atomically, req_0066_batch_link_to_self_is_rejected_and_rolls_back, req_0066_batch_empty_mutations_array_is_a_noop, req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614002900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 5 pass / 0 fail / 0 ignored — req_0066_batch_unknown_mutation_kind_is_rejected_atomically, req_0066_batch_empty_mutations_array_is_a_noop, req_0066_batch_link_to_self_is_rejected_and_rolls_back, req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031580Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 5 pass / 0 fail / 0 ignored — req_0066_batch_unknown_mutation_kind_is_rejected_atomically, req_0066_batch_link_to_self_is_rejected_and_rolls_back, req_0066_batch_empty_mutations_array_is_a_noop, req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104074800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 5 pass / 0 fail / 0 ignored — req_0066_batch_empty_mutations_array_is_a_noop, req_0066_batch_link_to_self_is_rejected_and_rolls_back, req_0066_batch_unknown_mutation_kind_is_rejected_atomically, req_0066_batch_rolls_back_on_validation_failure, req_0066_batch_applies_multiple_mutations_atomically",
"outcome": "Pass"
}
],
"title": "Apply many mutations atomically via req batch",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0067": {
"acceptance": [
"`req import --format markdown <file>` parses level-2/3 headings as requirement titles and the following prose as the statement; rejected items are reported but do not abort the import of valid ones unless --strict is set.",
"`req import --format json <file>` ingests another project.req or a documented flat-array schema and re-allocates IDs to avoid collision with the destination file.",
"Every imported requirement goes through the same validator as `req add`; invalid items are listed with structured errors and not written.",
"A dry-run mode (`--dry-run`) reports what would be added without mutating the file."
],
"created": "2026-05-17T13:48:39.063807500Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:48:39.063808200Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598969Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648651600Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035105900Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373595Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551003800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615234900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032499300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106366800Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508236800Z",
"reason": "Atomic rewrite; the per-format schema detail is in acceptance criteria."
}
],
"id": "REQ-0067",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Adoption friction on existing codebases is the empty-project problem: teams already have specs in Markdown, Confluence exports, or another tool, and rewriting them by hand through `req add` is prohibitive. Routing import through the same validator the CLI uses for `add` preserves the integrity guarantee while letting users start from where they are.",
"statement": "The CLI shall ingest requirements from Markdown or JSON through `req import`, routed through the normal validator.",
"status": "Verified",
"tags": [
"ux",
"onboarding",
"import"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598582800Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0067_import_dry_run_does_not_write, req_0067_import_markdown_accepts_well_formed_items, req_0067_import_json_array_schema",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034715600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0067_import_dry_run_does_not_write, req_0067_import_markdown_accepts_well_formed_items, req_0067_import_json_array_schema",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373186900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0067_import_markdown_with_no_headings_emits_clear_error, req_0067_import_strict_aborts_on_first_invalid_item, req_0067_import_json_with_invalid_shape_reports_clearly, req_0067_import_json_array_schema, req_0067_import_dry_run_does_not_write, req_0067_import_markdown_accepts_well_formed_items",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549235800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0067_import_markdown_with_no_headings_emits_clear_error, req_0067_import_json_with_invalid_shape_reports_clearly, req_0067_import_strict_aborts_on_first_invalid_item, req_0067_import_dry_run_does_not_write, req_0067_import_json_array_schema, req_0067_import_markdown_accepts_well_formed_items",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614006600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0067_import_json_with_invalid_shape_reports_clearly, req_0067_import_markdown_with_no_headings_emits_clear_error, req_0067_import_strict_aborts_on_first_invalid_item, req_0067_import_json_array_schema, req_0067_import_markdown_accepts_well_formed_items, req_0067_import_dry_run_does_not_write",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031584500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0067_import_json_with_invalid_shape_reports_clearly, req_0067_import_strict_aborts_on_first_invalid_item, req_0067_import_markdown_with_no_headings_emits_clear_error, req_0067_import_dry_run_does_not_write, req_0067_import_json_array_schema, req_0067_import_markdown_accepts_well_formed_items",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104082700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 6 pass / 0 fail / 0 ignored — req_0067_import_json_with_invalid_shape_reports_clearly, req_0067_import_markdown_with_no_headings_emits_clear_error, req_0067_import_strict_aborts_on_first_invalid_item, req_0067_import_json_array_schema, req_0067_import_dry_run_does_not_write, req_0067_import_markdown_accepts_well_formed_items",
"outcome": "Pass"
}
],
"title": "Import existing requirements from external sources",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0068": {
"acceptance": [
"Running the CLI against a file whose `_format` is older than the current version fails with a structured error pointing the user at `req migrate`.",
"`req migrate` upgrades the file to the current `_format`, recomputes `_integrity`, and writes a sibling backup (e.g. project.req.bak-<oldversion>) before mutating.",
"Per-requirement history is preserved across migration; a synthetic history entry recording the migration is appended to each requirement that changed shape.",
"A documented policy in `req help` describes how format versions are bumped and what guarantees a migration provides."
],
"created": "2026-05-17T13:48:46.636323700Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:48:46.636324500Z",
"reason": null
},
{
"action": "title; statement",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:56.376326Z",
"reason": "Split compound statement — separate the migration command from the format-version policy (new REQ to follow)."
},
{
"action": "added depends-on link to REQ-0074",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:50:09.135712200Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit f5a393f25",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:14.474827900Z",
"reason": "req migrate landed: detects _format, errors gracefully on newer than binary, writes backup before mutating, principled-no-op on current version. No registered migration body until first v2 — by design"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:14.474858400Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551034400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615250200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032519Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106391800Z",
"reason": null
}
],
"id": "REQ-0068",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0074"
}
],
"priority": "Should",
"rationale": "`_format: \"req-v1\"` is already in the file, which implies a v2 is anticipated, but there is no documented migration path or tooling. Pinning the policy down before the first breaking change is far cheaper than retrofitting it after users have files in the wild. Without this the tool cannot evolve its schema without forcing manual rewrites.",
"statement": "The CLI shall provide a `req migrate` command that upgrades a project.req written under an older `_format` value to the current version in place, backing up the prior file and preserving per-requirement history.",
"status": "Verified",
"tags": [
"storage",
"versioning",
"reliability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:14.474728900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Inspection",
"notes": "req migrate landed: detects _format, errors gracefully on newer than binary, writes backup before mutating, principled-no-op on current version. No registered migration body until first v2 — by design",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549239200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0068_migrate_is_a_no_op_on_current_format",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614010600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0068_migrate_is_a_no_op_on_current_format",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031589600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0068_migrate_is_a_no_op_on_current_format",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104090Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0068_migrate_is_a_no_op_on_current_format",
"outcome": "Pass"
}
],
"title": "Migrate project.req across format versions via req migrate",
"updated": "2026-05-17T19:01:22.106419100Z"
},
"REQ-0069": {
"acceptance": [
"`req diff <base>..<head>` prints one entry per changed requirement, showing field-level transitions (e.g. `status: proposed -> approved`) and the reason from the corresponding history entry.",
"Added and deleted requirements are listed in distinct sections with their full identifying detail.",
"A `--json` mode emits the same information as a stable structured document for tooling.",
"When base and head are identical or no requirements changed, the command exits zero with a clear empty-diff message."
],
"created": "2026-05-17T13:48:54.024181400Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:48:54.024182300Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:56.406564900Z",
"reason": "Split compound statement — keep the diff command obligation atomic; field-level summary detail belongs in acceptance criteria."
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598983600Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648674400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035120500Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373608900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551060100Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615265800Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032534400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106421200Z",
"reason": null
}
],
"id": "REQ-0069",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "`git diff project.req` is human-readable but verbose: a status-only change produces dozens of lines of JSON noise around the one field that matters. Reviewers approving spec changes need a summary view — \"REQ-0007: status proposed→approved (reason: ...)\". This complements the existing audit trail by making review of in-progress branches as easy as audit of merged history.",
"statement": "The CLI shall provide a `req diff <base>..<head>` command that summarizes per-requirement changes between two git revisions of project.req in a form suited to code review.",
"status": "Verified",
"tags": [
"ux",
"review",
"git"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598585700Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034717600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373189200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549242700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614014900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031592200Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104094800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0069_diff_empty_when_no_changes, req_0069_diff_reports_added_and_changed",
"outcome": "Pass"
}
],
"title": "Summarize spec changes between git refs via req diff",
"updated": "2026-05-17T19:01:22.106444300Z"
},
"REQ-0070": {
"acceptance": [
"`req coverage` reports per requirement whether it has implementation markers, test markers, both, or neither.",
"The classification of a file as test vs implementation follows a documented rule (path heuristics like `tests/`, `*_test.rs`, `#[cfg(test)]` blocks) and is overridable via configuration.",
"Orphan detection treats a requirement with only test markers as still-orphaned for the purpose of `Implemented` status; documentation explains the rationale.",
"A requirement marked only in tests is surfaced as a distinct warning category (`test-only`) separate from `orphan` and `ghost`."
],
"created": "2026-05-17T13:49:01.532611300Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:01.532612100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.598998100Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.648697800Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035134900Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373622600Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551084500Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615281300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032549400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106447500Z",
"reason": null
}
],
"id": "REQ-0070",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Today `// REQ-NNNN` in a test file counts the same as the same marker in production source, which lets a requirement look \"implemented\" purely because a test mentions it. That weakens the `verified` evidence story REQ-0056 set up: verified should mean tested AND implemented, not tested OR mentioned. Separating impl from test markers tightens the chain from spec to running code.",
"statement": "The CLI shall distinguish requirement markers that appear in test code from those in implementation code when computing coverage, so that a requirement referenced only from tests is not reported as implemented.",
"status": "Verified",
"tags": [
"traceability",
"testing",
"coverage"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598587400Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034720300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373191100Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549248700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614019Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031594400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104099Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0070_test_only_marker_is_distinct_from_referenced",
"outcome": "Pass"
}
],
"title": "Distinguish implementation and test markers in coverage",
"updated": "2026-05-17T19:01:22.106474Z"
},
"REQ-0071": {
"acceptance": [
"`req hooks install` writes (or updates) a `.gitattributes` rule that pins project.req to LF line endings and disables text-mode normalization",
"Re-running `req hooks install` is idempotent: the rule is present exactly once after a second run",
"After install, a Windows clone with `core.autocrlf=true` does not rewrite line endings in project.req on checkout"
],
"created": "2026-05-17T13:49:07.332713200Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:07.332713900Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156944700Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193241700Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.599012700Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035148800Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373636700Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551104400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615308400Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032564100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106476400Z",
"reason": null
}
],
"id": "REQ-0071",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "The most common cause of \"I didn't touch it but the hash broke\" is auto-formatters and Windows core.autocrlf rewriting line endings on checkout or commit. Pinning the file in .gitattributes closes this hole without requiring users to remember per-clone git config.",
"statement": "The system shall ship a `.gitattributes` rule that pins project.req to a fixed canonical form so that line-ending normalization and text-formatting tools cannot silently invalidate the integrity hash.",
"status": "Verified",
"tags": [
"integration",
"safety",
"storage"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156587900Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598589300Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034722300Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373193200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_is_idempotent, req_0071_hooks_install_writes_gitattributes_pin",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549253100Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614022800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031596600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_is_idempotent, req_0071_hooks_install_writes_gitattributes_pin",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104103800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0071_hooks_install_writes_gitattributes_pin, req_0071_hooks_install_is_idempotent",
"outcome": "Pass"
}
],
"title": "Protect project.req from formatter and line-ending corruption",
"updated": "2026-05-17T19:01:22.106514400Z"
},
"REQ-0072": {
"acceptance": [
"`req add --from-json <path>` reads a JSON file and creates the requirement using its fields",
"`req add --from-json -` reads the same JSON document from stdin",
"The accepted JSON schema covers every field currently exposed as a CLI flag on `req add` (title, statement, rationale, kind, priority, tags, acceptance, parent)",
"Validator errors from a JSON-driven invocation are reported with the same exit codes as the flag-driven form"
],
"created": "2026-05-17T13:49:16.376896800Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:16.376897400Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156960600Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193258100Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.599027300Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035162700Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373650500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551129800Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615323100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032579100Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106516600Z",
"reason": null
}
],
"id": "REQ-0072",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Quoting `--statement` and `--rationale` reliably across PowerShell, cmd, and bash is fiddly, and breaks more often for agents that compose CLI invocations programmatically. The MCP path sidesteps this, but agents and humans driving the CLI directly do not have that option. A structured input path lets them write the document once and pass it in by reference.",
"statement": "The system shall accept a single JSON document containing all fields of a new requirement as input to `req add`, so that callers can bypass shell quoting for multi-line statements and apostrophe-containing rationale.",
"status": "Verified",
"tags": [
"ux",
"agents"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156590100Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_file, req_0072_add_from_json_validator_still_rejects",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598591300Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034724400Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373196500Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549260300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614026300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031598600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_validator_still_rejects, req_0072_add_from_json_file",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104108400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0072_add_from_json_file, req_0072_add_from_json_validator_still_rejects",
"outcome": "Pass"
}
],
"title": "Accept a JSON document as structured input for req add",
"updated": "2026-05-17T19:01:22.106541100Z"
},
"REQ-0073": {
"acceptance": [
"`req list` with no filter flags omits requirements whose status is Obsolete",
"`req list --include-obsolete` (or equivalent flag) re-includes them in the output",
"`req show <id>` continues to render obsolete requirements when looked up by ID",
"Filtering by `--status obsolete` continues to list only obsolete requirements regardless of the new default"
],
"created": "2026-05-17T13:49:23.476319Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:23.476319600Z",
"reason": null
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156975300Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193273900Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.599042200Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035182500Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373664500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551157300Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615337700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032595500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106545200Z",
"reason": null
}
],
"id": "REQ-0073",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Soft-delete preserves obsolete requirements for traceability but they appear in every `req list` output today, leading users to mistake retired entries for active ones. Hiding by default matches the mental model of \"deleted means gone from the active set\" while preserving the full record for `req show` and the underlying file.",
"statement": "The system shall exclude obsolete requirements from `req list` output by default, requiring an explicit opt-in flag to include them.",
"status": "Verified",
"tags": [
"ux",
"lifecycle"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156592500Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_obsolete_hidden_from_default_list, req_0073_status_obsolete_filter_still_works, req_0073_include_obsolete_flag_brings_them_back",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598594800Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_include_obsolete_flag_brings_them_back, req_0073_obsolete_hidden_from_default_list, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034726600Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_obsolete_hidden_from_default_list, req_0073_include_obsolete_flag_brings_them_back, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373198800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_include_obsolete_flag_brings_them_back, req_0073_obsolete_hidden_from_default_list, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549263500Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_obsolete_hidden_from_default_list, req_0073_include_obsolete_flag_brings_them_back, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614030900Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_include_obsolete_flag_brings_them_back, req_0073_status_obsolete_filter_still_works, req_0073_obsolete_hidden_from_default_list",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031603700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_obsolete_hidden_from_default_list, req_0073_include_obsolete_flag_brings_them_back, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104129Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0073_obsolete_hidden_from_default_list, req_0073_include_obsolete_flag_brings_them_back, req_0073_status_obsolete_filter_still_works",
"outcome": "Pass"
}
],
"title": "Hide obsolete requirements from default req list output",
"updated": "2026-05-17T19:01:22.106568400Z"
},
"REQ-0074": {
"acceptance": [
"`req help` includes a section describing the format-version policy: when bumps occur, what backward compatibility is promised, and the behaviour on older vs newer `_format` values.",
"Encountering an older `_format` produces a structured error pointing at `req migrate`.",
"Encountering a newer `_format` than the binary recognises produces a structured error advising an upgrade rather than attempting a read.",
"The policy is referenced from the README so external users discover it before adopting the tool."
],
"created": "2026-05-17T13:49:56.436675300Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:49:56.436676Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T13:50:02.734117500Z",
"reason": "Tighten statement to a single obligation — enumeration of policy contents belongs in acceptance criteria, not the statement."
},
{
"action": "test pass recorded against commit ecb15948c via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.156989800Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:03:56.193290300Z",
"reason": null
},
{
"action": "test pass recorded against commit f5a393f25 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T14:43:13.599056900Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035197Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373684100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551182600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615362900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032610300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106571300Z",
"reason": null
}
],
"id": "REQ-0074",
"kind": "NonFunctional",
"links": [],
"priority": "Should",
"rationale": "REQ-0068 introduces a migrate command, but without a written policy users cannot predict when migrations will happen, whether downgrade is possible, or how the tool handles a forward-incompatible file. Pinning the policy down before the first breaking schema change is far cheaper than retrofitting expectations after files are in the wild.",
"statement": "The project shall document a format-version policy for `project.req` that users can consult before adopting or upgrading the tool.",
"status": "Verified",
"tags": [
"storage",
"versioning",
"docs"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T14:03:56.156595400Z",
"commit": "ecb15948c214c9f2cf6feecb2eab2f699d895781",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_has_format_policy_section, req_0074_help_index_lists_format_policy",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T14:43:13.598596900Z",
"commit": "f5a393f25c5ea861ddd91e91a89db1a007533d70",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_index_lists_format_policy, req_0074_help_has_format_policy_section",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034728900Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_index_lists_format_policy, req_0074_help_has_format_policy_section",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373201Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_has_format_policy_section, req_0074_help_index_lists_format_policy",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549277800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_index_lists_format_policy, req_0074_help_has_format_policy_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614034600Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_index_lists_format_policy, req_0074_help_has_format_policy_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031605800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_has_format_policy_section, req_0074_help_index_lists_format_policy",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104138200Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0074_help_index_lists_format_policy, req_0074_help_has_format_policy_section",
"outcome": "Pass"
}
],
"title": "Document a format-version policy for project.req",
"updated": "2026-05-17T19:01:22.106594700Z"
},
"REQ-0075": {
"acceptance": [
"req init accepts a flag to select directory layout",
"All existing CLI operations work identically on a directory-backed project",
"The integrity hash covers the index and every per-requirement file",
"req migrate converts between single-file and directory layouts losslessly"
],
"created": "2026-05-17T14:20:30.748315600Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:30.748318200Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035211700Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075650500Z",
"reason": null
},
{
"action": "statement",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:09:50.606037900Z",
"reason": "Reword multi-clause and multi-modal statements to atomic form so the exemplar project validates with zero warnings"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373698500Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551211200Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615378300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032625700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106597600Z",
"reason": null
}
],
"id": "REQ-0075",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "A single project.req becomes a merge hotspot and produces noisy diffs once a project grows past a few hundred requirements. A directory layout localises edits to the file that changed.",
"statement": "The CLI shall support a directory-backed storage layout that preserves the integrity and atomicity guarantees of the single-file format.",
"status": "Verified",
"tags": [
"storage",
"scaling"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034730800Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373203200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549280900Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614039100Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031608600Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104148500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 3 pass / 0 fail / 0 ignored — req_0075_init_directory_layout_writes_index_and_requirements_dir, req_0075_add_persists_one_file_per_requirement, req_0075_integrity_detects_per_file_tamper",
"outcome": "Pass"
}
],
"title": "Support directory-backed storage for large requirement sets",
"updated": "2026-05-17T19:01:22.106629Z"
},
"REQ-0076": {
"acceptance": [
"Adding a requirement whose statement closely matches an existing non-obsolete one produces a stable DUP-INTENT rule-coded warning",
"The warning cites both conflicting REQ IDs",
"Obsolete requirements are excluded from comparison",
"The similarity threshold is documented in req help"
],
"created": "2026-05-17T14:20:34.004514800Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:34.004515400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035225500Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075686500Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373716Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551241400Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615393Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032646200Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106631700Z",
"reason": null
}
],
"id": "REQ-0076",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Syntactic rules let duplicate-intent requirements through, which fragments traceability and produces conflicting acceptance criteria.",
"statement": "The validator shall warn when two non-obsolete requirements have semantically overlapping statements based on title and statement similarity above a documented threshold.",
"status": "Verified",
"tags": [
"validation"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034732500Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373211200Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549283200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614042400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031610400Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104157200Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0076_near_clone_triggers_dup_intent_warning",
"outcome": "Pass"
}
],
"title": "Detect semantically duplicate requirements",
"updated": "2026-05-17T19:01:22.106656800Z"
},
"REQ-0077": {
"acceptance": [
"Validator emits a stable rule code for verifies-without-evidence",
"Warning names the source and target REQ IDs",
"Rule applies only to verifies links and not to other link kinds"
],
"created": "2026-05-17T14:20:40.047868600Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:40.047869300Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035245Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075705Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373730100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551264700Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615408300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032661500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106658900Z",
"reason": null
}
],
"id": "REQ-0077",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "A verifies link that never produced an evidence row gives false confidence; the link claims verification but nothing has been observed to confirm it.",
"statement": "The validator shall warn for every `verifies` link whose source requirement has no recorded test record.",
"status": "Verified",
"tags": [
"validation",
"testing",
"traceability"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034740700Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373213900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549285400Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614045800Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031612300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104165800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0077_verifies_link_without_test_record_warns",
"outcome": "Pass"
}
],
"title": "Flag verifies links lacking recorded test evidence",
"updated": "2026-05-17T19:01:22.106682700Z"
},
"REQ-0078": {
"acceptance": [
"A command writes the JSON schema for structured input to stdout",
"The schema validates the same documents the CLI accepts at runtime",
"The schema carries an explicit version aligned with the project.req format version"
],
"created": "2026-05-17T14:20:43.483967100Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:43.483967700Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035267400Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075721Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373743900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551287600Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615423Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032676500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106684500Z",
"reason": null
}
],
"id": "REQ-0078",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Agents need a machine-readable input contract; help text drifts and is hard to consume programmatically.",
"statement": "The CLI shall publish a versioned JSON schema describing the structured input accepted by `req add --from-json` and equivalent commands.",
"status": "Verified",
"tags": [
"agents",
"json",
"docs"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034744Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_batch_describes_oneof_mutations, req_0078_schema_add_is_valid_json_with_format",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373217400Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_batch_describes_oneof_mutations, req_0078_schema_add_is_valid_json_with_format",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549287800Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_batch_describes_oneof_mutations, req_0078_schema_add_is_valid_json_with_format",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614049400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_add_is_valid_json_with_format, req_0078_schema_batch_describes_oneof_mutations",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031614300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_add_is_valid_json_with_format, req_0078_schema_batch_describes_oneof_mutations",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104175Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0078_schema_batch_describes_oneof_mutations, req_0078_schema_add_is_valid_json_with_format",
"outcome": "Pass"
}
],
"title": "Publish a JSON schema for structured CLI inputs",
"updated": "2026-05-17T19:01:22.106707900Z"
},
"REQ-0079": {
"acceptance": [
"req audit run in gate mode exits non-zero when any commit in the range violates the configured policy",
"The policy supports required signer identities and a minimum trust level",
"JSON output names which commit failed which rule"
],
"created": "2026-05-17T14:20:49.838473900Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:49.838474400Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035292900Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075736900Z",
"reason": null
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373758100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551339900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615437900Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032691500Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106709800Z",
"reason": null
}
],
"id": "REQ-0079",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "req audit today only reports signature status; enforcement requires a fail-fast gate that CI can call to reject unsigned or unauthorised changes to the spec.",
"statement": "The CLI shall provide a gate mode that exits non-zero when commits touching project.req in a given git range fail a configured signature policy.",
"status": "Verified",
"tags": [
"audit",
"git",
"ci",
"integration"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034746800Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373219900Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549289700Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614065Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031621800Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104183700Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0079_audit_gate_exits_nonzero_without_signing",
"outcome": "Pass"
}
],
"title": "Gate CI on signed-commit policy for project.req",
"updated": "2026-05-17T19:01:22.106737100Z"
},
"REQ-0080": {
"acceptance": [],
"created": "2026-05-17T14:20:52.719410800Z",
"history": [
{
"action": "created via MCP",
"actor": "Barks944",
"actor_kind": "Unknown",
"at": "2026-05-17T14:20:52.719411500Z",
"reason": null
},
{
"action": "test pass recorded against commit fa2009560 via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.035318300Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.075753200Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit fa2009560",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:02:41.259573700Z",
"reason": "CHANGELOG.md present with Keep-a-Changelog format and [Unreleased] section listing every shipped REQ"
},
{
"action": "test pass recorded against commit 464469bbe via req test run",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:35:26.373771900Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551370900Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615453700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032710600Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106739100Z",
"reason": null
}
],
"id": "REQ-0080",
"kind": "NonFunctional",
"links": [],
"priority": "Should",
"rationale": "Users and packagers need a stable place to see what changed between versions without scraping the git log.",
"statement": "The project shall maintain a CHANGELOG.md that is updated for every tagged release.",
"status": "Verified",
"tags": [
"docs",
"release",
"distribution"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.034748900Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:02:41.259525800Z",
"commit": "fa200956045f7e2d6ef5f7cfa44bc74eebbe99c5",
"kind": "Inspection",
"notes": "CHANGELOG.md present with Keep-a-Changelog format and [Unreleased] section listing every shipped REQ",
"outcome": "Pass"
},
{
"actor": "Barks944",
"at": "2026-05-17T15:35:26.373221800Z",
"commit": "464469bbe5028d020c5aa5623b63a7f3da780e3f",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549292200Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614069500Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031624200Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104192500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0080_changelog_exists_with_unreleased_section",
"outcome": "Pass"
}
],
"title": "Maintain a CHANGELOG aligned with tagged releases",
"updated": "2026-05-17T19:01:22.106764600Z"
},
"REQ-0082": {
"acceptance": [
"req validate against project.req reports 0 errors and 0 warnings on the released binary",
"Any new advisory rule added to the validator either updates the dogfooded statements to comply or is documented as exempt for Obsolete-status reqs only"
],
"created": "2026-05-17T15:10:05.819625400Z",
"history": [
{
"action": "created",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:10:05.819626Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit bf1fed766",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:10:06.049108500Z",
"reason": "req validate reports OK — 77 requirement(s), no findings — verified against the shipping binary this commit"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Barks944",
"actor_kind": "Agent",
"at": "2026-05-17T15:10:06.049128100Z",
"reason": null
},
{
"action": "test pass recorded against commit 9c43344bc via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T17:53:22.551397Z",
"reason": null
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615472700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032725300Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106766700Z",
"reason": null
}
],
"id": "REQ-0082",
"kind": "NonFunctional",
"links": [],
"priority": "Should",
"rationale": "Warnings on the dogfooded file train every agent and reviewer to ignore the signal; an exemplar holds itself to the standard it asks of users.",
"statement": "The exemplar project's own shall produce zero validator warnings and zero validator errors against the shipping binary.",
"status": "Verified",
"tags": [
"validation",
"exemplar"
],
"tests": [
{
"actor": "Barks944",
"at": "2026-05-17T15:10:06.049033800Z",
"commit": "bf1fed766b504414992d94d334b07dcf6dacd7da",
"kind": "Inspection",
"notes": "req validate reports OK — 77 requirement(s), no findings — verified against the shipping binary this commit",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T17:53:22.549294300Z",
"commit": "9c43344bcaafcb305e3ee1bfe44fa453e3f8ca2d",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0082_project_self_validates_cleanly",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614078300Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0082_project_self_validates_cleanly",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031627300Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0082_project_self_validates_cleanly",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104202900Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 1 pass / 0 fail / 0 ignored — req_0082_project_self_validates_cleanly",
"outcome": "Pass"
}
],
"title": "Project shall self-validate with zero warnings",
"updated": "2026-05-17T19:01:22.106836300Z"
},
"REQ-0083": {
"acceptance": [
"tools/list returns a req_ tool for every CLI command listed in src/cli.rs except a documented humans-only exclusion set (init, hooks, repair, renumber, tui, serve, mcp)",
"Each MCP write tool routes through storage::load_for_mutation and storage::save so the integrity hash and advisory lock apply identically",
"An automated test asserts the tools/list set equals the expected set; adding a new CLI subcommand without a matching MCP tool (or an explicit exclusion entry) fails the build",
"The TUI top-level menu offers an action for every agent-relevant CLI command in the same humans-only-excluded set",
"An automated test enforces TUI parity by inspecting the menu list and fails when a new CLI command lacks a TUI entry"
],
"created": "2026-05-17T18:22:11.858558500Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:22:11.858559700Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:33:51.533276900Z",
"reason": "Broaden scope to all three surfaces"
},
{
"action": "+acceptance #4: \"The TUI top-level menu offers an action for every agent-relevant CLI command in the same humans-only-excluded set\"",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:33:51.676409900Z",
"reason": "TUI parity acceptance criterion"
},
{
"action": "+acceptance #5: \"An automated test enforces TUI parity by inspecting the menu list and fails when a new CLI command lacks a TUI entry\"",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:33:51.832944Z",
"reason": "TUI parity enforced by test"
},
{
"action": "test pass recorded against commit 16c69f3d9 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.615489Z",
"reason": null
},
{
"action": "status promoted to verified (req test run --promote, fresh passing record on HEAD)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.661895Z",
"reason": null
},
{
"action": "inspection evidence recorded against commit 16c69f3d9",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:49:34.905505Z",
"reason": "Implemented: 15 MCP tools (13 new + version + migrate), TUI menu expanded from 7 to 16 entries, two parity tests assert MCP and TUI cover the same CLI surface modulo documented humans-only exclusions."
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T18:59:49.032740700Z",
"reason": null
},
{
"action": "test pass recorded against commit 1f6ecfa89 via req test run",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-17T19:01:22.106840300Z",
"reason": null
}
],
"id": "REQ-0083",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "MCP is the agent-native surface; if the CLI keeps growing while MCP stagnates, agents are forced to shell out for missing operations and the integrity model splits across two paths.",
"statement": "The system shall expose every agent-relevant CLI subcommand through both the MCP server and the interactive TUI menu, so that any of the three surfaces lets users achieve the same operations.",
"status": "Verified",
"tags": [
"agents",
"mcp",
"exemplar"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.614093400Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0083_tui_menu_covers_every_agent_relevant_cli_command, req_0083_mcp_tool_surface_covers_every_agent_relevant_cli_command",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:49:34.905470200Z",
"commit": "16c69f3d900675b4128265cf20d6e9c994d49724",
"kind": "Inspection",
"notes": "Implemented: 15 MCP tools (13 new + version + migrate), TUI menu expanded from 7 to 16 entries, two parity tests assert MCP and TUI cover the same CLI surface modulo documented humans-only exclusions.",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T18:59:49.031634Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0083_tui_menu_covers_every_agent_relevant_cli_command, req_0083_mcp_tool_surface_covers_every_agent_relevant_cli_command",
"outcome": "Pass"
},
{
"actor": "Tom",
"at": "2026-05-17T19:01:22.104225500Z",
"commit": "1f6ecfa89dfd248a164315fe0cf32d2062301fbd",
"kind": "Automated",
"notes": "cargo test: 2 pass / 0 fail / 0 ignored — req_0083_tui_menu_covers_every_agent_relevant_cli_command, req_0083_mcp_tool_surface_covers_every_agent_relevant_cli_command",
"outcome": "Pass"
}
],
"title": "MCP tool surface tracks the agent-relevant CLI commands",
"updated": "2026-05-17T19:01:22.106973400Z"
},
"REQ-0084": {
"acceptance": [
"draft -> verified directly fails without --force; error names the alternative path",
"draft -> approved succeeds (carve-out)",
"any active -> obsolete succeeds",
"verified -> implemented requires --force",
"obsolete -> draft requires --force",
"policy is shared between req update and req batch update mutations"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.460420700Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.677644800Z",
"reason": "implemented in 0.1.3"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.680607200Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.682572200Z",
"reason": "code in src/model.rs::is_natural_transition + update.rs + batch.rs"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.027969100Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.027994400Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508258500Z",
"reason": "Atomic rewrite. The natural-vs-irregular policy table is in acceptance criteria."
}
],
"id": "REQ-0084",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Verified is a strong claim; an honest state machine documents how a requirement reached it and surfaces deliberate exceptions on history.",
"statement": "The CLI shall reject irregular status transitions on `req update` and `req batch` unless `--force` is supplied.",
"status": "Verified",
"tags": [
"lifecycle",
"validation",
"agents"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:04.027893Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Lifecycle state machine on req update --status",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0085": {
"acceptance": [
"non-interactive form accepts --into <statement> repeated",
"interactive form prompts for each part until empty line",
"each child runs through the validator before any mutation",
"original moves to Obsolete with history naming the child IDs",
"--keep-original leaves the source active and only adds siblings"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.469983500Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.678154900Z",
"reason": "implemented in 0.2.0"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.680865100Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.682762800Z",
"reason": "code in src/commands/split.rs"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.447234100Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.447275Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508279Z",
"reason": "Atomic rewrite. Inheritance, retire-vs-keep, and validator gating detail are in acceptance criteria."
}
],
"id": "REQ-0085",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "REQ-V-0010 flags compound statements; split is the assisted fix so the validator's signal turns into action.",
"statement": "The CLI shall split a compound requirement into N atomic children through `req split <id>`.",
"status": "Verified",
"tags": [
"ux",
"validator",
"remediation"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:04.447174Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Split a compound requirement into atomic parts",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0086": {
"acceptance": [
"default base is origin/main with a fallback to main when origin/main is absent",
"missing base ref does not crash; report falls back to current-only",
"markdown output includes Added / Changed / Removed sections, validator findings, coverage ghosts, stale counts, and audit headline",
"--json emits the same shape as a single JSON object",
"non-zero exit when validate errors > 0"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.470187300Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.678480700Z",
"reason": "implemented in 0.2.0"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.681108800Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.683110100Z",
"reason": "code in src/commands/review.rs"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.878169400Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:04.878193Z",
"reason": null
}
],
"id": "REQ-0086",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "PR descriptions need a one-paste summary of what changed in the spec and whether it stays consistent with code; review wraps validate + coverage + stale + audit + diff into one output.",
"statement": "The CLI shall provide `req review --base <ref>` that emits a single markdown (or JSON) report combining the changed-requirement diff, full project validate, coverage on changed files, stale-record summary, and audit headline.",
"status": "Verified",
"tags": [
"ui",
"ci",
"agents"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:04.878116800Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "One-shot PR-style spec review report",
"updated": "2026-05-17T21:45:04.878191900Z"
},
"REQ-0087": {
"acceptance": [
"validate is deterministic and offline when the env var is unset",
"hook receives `{id, title, statement, rationale}` on stdin",
"hook flag of ok=false produces a REQ-V-0023 warning carrying the message",
"hook failure (non-zero exit, malformed JSON, timeout > 10s) produces a REQ-V-0023 warning naming the failure, never aborts validation"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.470376700Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.678753100Z",
"reason": "implemented in 0.2.0"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.681301700Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.683332400Z",
"reason": "code in src/validate.rs::run_llm_hook"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:05.287036400Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:05.287058500Z",
"reason": null
}
],
"id": "REQ-0087",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Heuristics catch the obvious smells; semantic testability checks need a model. The hook stays strictly opt-in so the default validator remains deterministic and offline.",
"statement": "The validator shall, when `REQ_VALIDATE_LLM_CMD` is set, invoke that command per non-obsolete requirement with a JSON stub on stdin and surface its `{ok, message}` verdict as REQ-V-0023.",
"status": "Verified",
"tags": [
"validator",
"agents",
"extension"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:05.286983200Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Opt-in external statement-quality hook",
"updated": "2026-05-17T21:45:05.287056900Z"
},
"REQ-0088": {
"acceptance": [
"validate emits REQ-V-0021 for every distinct cycle",
"cycles deduplicated by canonical rotation (smallest-ID first)",
"all four asymmetric kinds checked",
"MCP req_validate surfaces the same finding with rule_code"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.470551800Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.678971Z",
"reason": "implemented in 0.1.2"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.681515300Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.683510200Z",
"reason": "code in src/validate.rs::find_cycles"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:05.728375Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:05.728398200Z",
"reason": null
}
],
"id": "REQ-0088",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Prevention at insert time is not enough: cycles can enter via merges, old binaries, or hand-edits. A second-line defence at validate time surfaces them before they hang downstream tooling.",
"statement": "`req validate` shall detect cycles on every asymmetric link kind (parent, depends-on, refines, verifies), report each cycle once attributed to its smallest-ID member, and emit REQ-V-0021.",
"status": "Verified",
"tags": [
"validator",
"graph",
"integrity"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:05.728318800Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Validator surfaces graph cycles as REQ-V-0021",
"updated": "2026-05-17T21:45:05.728397Z"
},
"REQ-0089": {
"acceptance": [
"one hedge alone does not trigger",
"two or more hedges trigger REQ-V-0022 with `warn` severity",
"rule appears in `req help errors`"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.470796Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.679330700Z",
"reason": "implemented in 0.1.2"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.681718400Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.683688600Z",
"reason": "code in src/validate.rs (HEDGE_WORDS)"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:06.114000900Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:06.114024500Z",
"reason": null
}
],
"id": "REQ-0089",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "A single hedge is sloppy; stacking them means the author has not committed to a behaviour. Catching this guides authors toward a measurable criterion.",
"statement": "The validator shall warn (REQ-V-0022) when a statement contains two or more of `perhaps`, `probably`, `maybe`, `possibly`, `might`, `roughly`, `potentially`.",
"status": "Verified",
"tags": [
"validator",
"quality"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:06.113946700Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Validator flags stacked uncertainty hedges as REQ-V-0022",
"updated": "2026-05-17T21:45:06.114023100Z"
},
"REQ-0090": {
"acceptance": [
"show, update, delete, link, verify, test record all accept normalised forms",
"near-miss IDs (delta <= 5) produce a `— did you mean REQ-XXXX?` hint",
"far-miss IDs return a plain 'no such requirement' error",
"regression tests cover every accepted form"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.470950500Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.679589400Z",
"reason": "implemented in 0.1.2"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.681953600Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.683999200Z",
"reason": "code in src/commands/mod.rs::resolve_id + nearest_id"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:06.524214200Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:06.524237Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508301500Z",
"reason": "Removes the repeated `shall` that tripped REQ-V-0010."
}
],
"id": "REQ-0090",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Agents and humans paste IDs in mixed case and unpadded forms; flat 'no such requirement' is a needless dead end when the data is right there.",
"statement": "The CLI shall normalise REQ-ID lookups across case and zero-pad forms, suggesting the nearest existing ID on near-miss.",
"status": "Verified",
"tags": [
"ux",
"agents",
"ergonomics"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:06.524159Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Case- and pad-insensitive ID resolution with did-you-mean",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0091": {
"acceptance": [
"repair without --force still refuses on validation errors",
"repair --force re-signs and prints a one-line warning that errors remain",
"after force-repair, `req validate` is the channel for the surviving errors"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.471144200Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.679994300Z",
"reason": "implemented in 0.1.2"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.682165500Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.684392600Z",
"reason": "code in src/commands/repair.rs"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:07.063904800Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:07.063928400Z",
"reason": null
}
],
"id": "REQ-0091",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Pre-0.1.2 such an edit produced a deadlock: repair refused on validation, every other command refused on the hash. --force re-signs so the validation problems surface through `req validate` instead.",
"statement": "`req repair --confirm-direct-edit --force` shall re-sign the project file even when it contains validation errors, so users can recover from a hand-edit that simultaneously broke the integrity hash and introduced a validation failure.",
"status": "Verified",
"tags": [
"recovery",
"integrity"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:07.063848500Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "repair --force escape for invalid hand-edits",
"updated": "2026-05-17T21:45:07.063926900Z"
},
"REQ-0092": {
"acceptance": [
"--tag T composes with AND semantics (every tag must match)",
"JSON output includes a `filter.tags` field",
"text output names the scope above the totals line"
],
"created": "2026-05-17T21:39:14.460393400Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:14.471347300Z",
"reason": "Backfill: features shipped in 0.1.2 and 0.1.3 plus 0.2.0 surface without a backing REQ"
},
{
"action": "status -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.680201Z",
"reason": "implemented in 0.2.0"
},
{
"action": "status -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.682316100Z",
"reason": "spec accepted"
},
{
"action": "status -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:39:53.684666300Z",
"reason": "code in src/commands/status.rs"
},
{
"action": "inspection evidence recorded against commit ca7e46b8a",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:07.454271200Z",
"reason": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T21:45:07.454294100Z",
"reason": null
}
],
"id": "REQ-0092",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Per-status totals across the whole project are too coarse for milestone work; tag-scoping turns status into a dashboard.",
"statement": "The CLI shall scope `req status` to the requirements carrying every listed `--tag` so that callers can ask \"what's left for milestone X\" in one command.",
"status": "Verified",
"tags": [
"ux",
"reporting"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-17T21:45:07.454217500Z",
"commit": "ca7e46b8a07c559a162d57597d4b8fa95d24726d",
"kind": "Inspection",
"notes": "Implementation reviewed in src/ with explicit REQ marker; release notes in CHANGELOG.md",
"outcome": "Pass"
}
],
"title": "Milestone rollups via req status --tag",
"updated": "2026-05-17T21:45:07.454292700Z"
},
"REQ-0093": {
"acceptance": [
"a verifies link on a Draft source produces no REQ-V-0019",
"the same link on an Implemented source still produces REQ-V-0019 when tests are empty",
"rule entry in `req help errors` documents the precondition"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.885141500Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:25.493322300Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:28.217460Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:28.671379200Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.119449500Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.119480500Z",
"reason": null
}
],
"id": "REQ-0093",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "The rule fires the moment you create a `verifies` link on a Draft, training authors to ignore validator output before there's any reasonable expectation of evidence. Gating on status >= Implemented matches the verification lifecycle.",
"statement": "The validator shall suppress REQ-V-0019 (verifies-link source has no test record) when the source requirement's status is Draft, Proposed, or Approved.",
"status": "Verified",
"tags": [
"validator",
"ergonomics"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:35.119376500Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "REQ-V-0019 should gate on status >= Implemented",
"updated": "2026-05-18T07:41:35.119479Z"
},
"REQ-0094": {
"acceptance": [
"`req update REQ-0001 --status Implemented --reason ...` succeeds",
"ambiguous casings fold to the canonical form before the state-machine guard runs",
"applies symmetrically to --kind, --priority where they share the issue"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.895603700Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:29.102810700Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:29.506923800Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:29.906862500Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.562657300Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.562679800Z",
"reason": null
}
],
"id": "REQ-0094",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Agents and humans paste capitalised forms because that's how they appear in `req show`. The current case-sensitive rejection produces a clap tip that names the alternative but feels like a tool quirk rather than a design choice.",
"statement": "The CLI shall accept status values in any case (`Implemented`, `implemented`, `IMPLEMENTED`) and normalise to the canonical lowercase form before validation.",
"status": "Verified",
"tags": [
"ux",
"ergonomics",
"agents"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:35.562596500Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "Case-insensitive status enum on req update",
"updated": "2026-05-18T07:41:35.562678700Z"
},
"REQ-0095": {
"acceptance": [
"creating a similar title to an Obsolete req within 60 days emits a warning naming the obsolete ID",
"the warning does not block the add (Draft is still created)",
"older obsolete reqs (>60d) do not trigger the warning",
"the similarity threshold reuses REQ-V-0020's Jaccard heuristic"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.895907Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:30.294948200Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:30.859323700Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:31.227945300Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.967537200Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:35.967561Z",
"reason": null
}
],
"id": "REQ-0095",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "A common mistake is to soft-delete a requirement and immediately re-add it instead of editing the original. The result is a broken audit trail and orphaned history. Surfacing the duplicate intent at add time preserves the link to the prior conversation.",
"statement": "The CLI shall warn when `req add` would create a requirement whose title is highly similar to a requirement that was moved to Obsolete within the last 60 days, suggesting `req update` or `req split --keep-original` as alternatives.",
"status": "Verified",
"tags": [
"validator",
"history",
"ux"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:35.967483500Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "Warn on re-add of a title similar to a recently-obsolete requirement",
"updated": "2026-05-18T07:41:35.967560Z"
},
"REQ-0096": {
"acceptance": [
"`REQ_VALIDATE_LLM_CMD=sh ./hook.sh` works on Windows when `sh` is on PATH",
"`REQ_VALIDATE_LLM_CMD=./hook.sh` works on Windows when an associated handler is registered",
"transport-error message names the failing command verbatim so the user can diagnose"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.896124200Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:31.603606200Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:32.025467900Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:32.353117700Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:36.350680400Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:36.350703700Z",
"reason": null
}
],
"id": "REQ-0096",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "v0.2.1 routes through `cmd /C` which fixed the absolute case but left relative paths and shell-script targets fragile on Windows. Agents and CI configurations will hit this; the failure mode masquerades as a REQ-V-0023 transport error.",
"statement": "The CLI shall execute REQ_VALIDATE_LLM_CMD via the platform shell so that `sh ./hook.sh`, `bash ./hook.sh`, and bare relative paths all resolve consistently on Windows when those interpreters are on PATH.",
"status": "Verified",
"tags": [
"validator",
"windows",
"extension"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:36.350617700Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "LLM hook invocation works for shell scripts on Windows",
"updated": "2026-05-18T07:41:36.350702600Z"
},
"REQ-0097": {
"acceptance": [
"concurrency cap is configurable (env var or flag) with a sane default (e.g. 4)",
"findings emit in stable id order regardless of completion order",
"10s per-call timeout still applies; one slow call does not stall the rest",
"documented in `req help env`"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.896305800Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:32.872995300Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:33.243055300Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:33.603304400Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:36.742206200Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:36.742234500Z",
"reason": null
}
],
"id": "REQ-0097",
"kind": "NonFunctional",
"links": [],
"priority": "Could",
"rationale": "Sequential per-requirement hook calls scale linearly with project size; a 200-req project with a 1s hook is 200s of validate. Bounded parallelism is the natural answer but needs a deliberate design — concurrency cap (CLI flag vs env var), batched stdin (one call per N reqs), and ordering guarantees in the output.",
"statement": "The validator shall offer a bounded-concurrency mode for the LLM hook so that N requirements can be evaluated in parallel up to a configurable cap, with stable ordering of findings in the final report.",
"status": "Verified",
"tags": [
"validator",
"performance",
"design"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:36.742150500Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "Bounded parallelism for the validator LLM hook",
"updated": "2026-05-18T07:41:36.742232400Z"
},
"REQ-0098": {
"acceptance": [
"an opt-in flag (e.g. `--marker-near-hunks <N>`) enables hunk-level matching",
"marker considered `near` if it appears within N lines of the changed hunk",
"default behaviour remains file-level matching",
"documented in `req help review` with the rationale for both modes"
],
"created": "2026-05-17T22:22:54.885095Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-17T22:22:54.896512800Z",
"reason": "Deferred items from the 0.1.x and 0.2.x agent sweeps — Draft so they stay visible without committing to a target release"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:33.964459100Z",
"reason": "0.2.3 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:34.318803900Z",
"reason": "0.2.3 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:34.693183400Z",
"reason": "0.2.3 implementation"
},
{
"action": "inspection evidence recorded against commit 541ced677",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:37.162670500Z",
"reason": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:41:37.162693100Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:01:58.508322600Z",
"reason": "Replaces `somewhere in the file` (which tripped REQ-V-0009 on `some`) with a precise specification."
}
],
"id": "REQ-0098",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Current file-level granularity lets a 1000-line file with a single line-1 marker pass even when the edit is on line 500, far from the cited requirement. Hunk-level is stricter but should not be the default; it requires a definition of `near` and a flag.",
"statement": "The CLI shall provide an opt-in mode where `req review --gate` requires a REQ-NNNN comment marker within N lines of each changed hunk.",
"status": "Verified",
"tags": [
"validator",
"ci",
"design"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:41:37.162616300Z",
"commit": "541ced677545eef8ec9fbac5c4b1f6ff8bc3b13d",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; regression tests in tests/",
"outcome": "Pass"
}
],
"title": "Optional hunk-level marker granularity for the review gate",
"updated": "2026-05-18T08:01:58.506453600Z"
},
"REQ-0099": {
"acceptance": [
"Markerless staged source file blocks the commit with an educational message naming the file and the two fix paths",
"REQ_SKIP_GATE=1 bypasses the gate cleanly",
"Hook installs from req hooks install and remains backwards-compatible (existing managed hooks are upgraded with --force)"
],
"created": "2026-05-18T07:20:18.173768700Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:18.173771400Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:36.196245700Z",
"reason": "0.2.2: pre-commit gate"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:36.582756100Z",
"reason": "0.2.2: pre-commit gate"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:37.044746800Z",
"reason": "0.2.2: pre-commit gate"
},
{
"action": "inspection evidence recorded against commit 1b8127fc1",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:37.467063200Z",
"reason": "Implementation in src/commands/hooks.rs (PRECOMMIT_BODY); src/commands/review.rs (--staged flag, fail-closed exemption); regression tests review_staged_does_not_need_existing_head and review_staged_flags_markerless_changed_source"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:20:37.467085100Z",
"reason": null
}
],
"id": "REQ-0099",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Gating only in CI fires too late: agents implementing features locally never see the warning until after pushing, and direct pushes to main can skip CI entirely. Running req review --staged --gate in pre-commit closes the symmetry between local and CI enforcement.",
"statement": "The pre-commit hook installed by Installed .\\.git\\hooks\\pre-commit\n\nNext step (one-time, per clone): register the merge driver in this repo:\n\n git config merge.req-merge.name 'req merge driver'\n git config merge.req-merge.driver 'req renumber --base %O || true'\n\nAfter that, merges into project.req auto-renumber colliding IDs. shall block any commit whose staged set includes source files without REQ-NNNN comment markers, unless the operator bypasses with REQ_SKIP_GATE=1.",
"status": "Verified",
"tags": [
"agents",
"ci",
"enforcement"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:20:37.467002200Z",
"commit": "1b8127fc1b10329b5f0805d2e6624101331ea2ef",
"kind": "Inspection",
"notes": "Implementation in src/commands/hooks.rs (PRECOMMIT_BODY); src/commands/review.rs (--staged flag, fail-closed exemption); regression tests review_staged_does_not_need_existing_head and review_staged_flags_markerless_changed_source",
"outcome": "Pass"
}
],
"title": "Pre-commit hook gates on markerless staged source",
"updated": "2026-05-18T07:20:37.467084100Z"
},
"REQ-0100": {
"acceptance": [
"req hooks install --strict writes a hook that runs review --staged --gate --marker-near-hunks 50",
"req hooks install (no --strict) writes the existing file-level hook unchanged",
"Re-running with the opposite flag swaps the body deterministically",
"Help section integration documents both modes and the tradeoff"
],
"created": "2026-05-18T07:47:38.820262700Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:47:38.820264300Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:48:16.740172900Z",
"reason": "fix backtick-eaten statement"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:51:35.026698200Z",
"reason": "0.2.4 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:51:35.404255800Z",
"reason": "0.2.4 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:51:35.804144Z",
"reason": "0.2.4 implementation"
},
{
"action": "inspection evidence recorded against commit 8cba3466b",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:51:36.201794400Z",
"reason": "Implementation in src/commands/hooks.rs (precommit_body fn, --strict flag); doctor surfaces gate mode; help integration documents both modes"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T07:51:36.201817600Z",
"reason": null
}
],
"id": "REQ-0100",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "0.2.2's pre-commit gate catches markerless new files but lets edits inside already-marked files through. Real adopters that want stricter enforcement need an opt-in switch, not a behaviour change that breaks every existing managed hook on upgrade. Strict mode is the right knob: explicit, documented, reversible by re-installing without --strict.",
"statement": "The CLI shall provide a \"req hooks install --strict\" mode that writes a pre-commit hook invoking \"req review --staged --gate --marker-near-hunks 50\" so edits within an already-marked file still require a marker near the changed hunk.",
"status": "Verified",
"tags": [
"agents",
"ci",
"enforcement"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T07:51:36.201732100Z",
"commit": "8cba3466b7489fba20897c0a26d9a0b254f6e17a",
"kind": "Inspection",
"notes": "Implementation in src/commands/hooks.rs (precommit_body fn, --strict flag); doctor surfaces gate mode; help integration documents both modes",
"outcome": "Pass"
}
],
"title": "Strict pre-commit hook uses hunk-level marker matching",
"updated": "2026-05-18T07:51:36.201816300Z"
},
"REQ-0101": {
"acceptance": [
"Markdown output with sections for validator findings, coverage, rationale length, acceptance count, and test records",
"JSON output with the same shape, sorted by id for determinism",
"Exit code reflects validator errors only (lint observations never gate)"
],
"created": "2026-05-18T08:03:41.399494400Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:03:41.399496500Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:06:26.991262700Z",
"reason": "0.3.0: req lint command"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:06:27.209500300Z",
"reason": "0.3.0: req lint command"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:06:27.419323500Z",
"reason": "0.3.0: req lint command"
},
{
"action": "inspection evidence recorded against commit c35ee39f8",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:06:29.983434900Z",
"reason": "Implementation in src/commands/lint.rs; surfaces marker coverage, rationale length, acceptance count, no-test-record"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:06:29.983480500Z",
"reason": null
}
],
"id": "REQ-0101",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Validate enforces hard rules; lint surfaces softer quality signals (which reqs have weak rationale, which have only one acceptance criterion, which lack test records) so authors can see where to invest next without those signals becoming new enforced rules.",
"statement": "The CLI shall provide \"req lint\" which audits the project against quality observations beyond the validator: marker coverage, rationale length, acceptance count, and test-record presence.",
"status": "Verified",
"tags": [
"agents",
"quality"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T08:06:29.983345200Z",
"commit": "c35ee39f817ad840d260929f7b2ec60b6f8641b6",
"kind": "Inspection",
"notes": "Implementation in src/commands/lint.rs; surfaces marker coverage, rationale length, acceptance count, no-test-record",
"outcome": "Pass"
}
],
"title": "Project self-audit via req lint",
"updated": "2026-05-18T08:06:29.983468200Z"
},
"REQ-0102": {
"acceptance": [
"Every REQ-V-NNNN warning text either names a fix command or names what the author should do instead",
"Existing rule codes are unchanged so machine-readable consumers keep working",
"Self-validate against project.req still passes with no findings"
],
"created": "2026-05-18T08:14:31.402349800Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:14:31.402351600Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:14:46.666140600Z",
"reason": "rewrite to atomic; original tripped REQ-V-0010"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:15:41.469244300Z",
"reason": "0.2.5: validator messages quality"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:15:41.670784Z",
"reason": "0.2.5: validator messages quality"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:15:44.261094Z",
"reason": "0.2.5: validator messages quality"
},
{
"action": "inspection evidence recorded against commit c35ee39f8",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:15:44.572014400Z",
"reason": "Implementation in src/validate.rs (sharpened messages on every REQ-V rule); commit log carries the rewording"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T08:15:44.572035800Z",
"reason": null
}
],
"id": "REQ-0102",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Terse rule names like statement looks compound trained authors to ignore the validator. An actionable message turns each finding into a teaching moment without changing what gets flagged. Rule codes stay stable; only the human-readable text changes.",
"statement": "Each validator finding shall carry a message that names the cause (e.g. \"repeated modal verb\") plus a suggested fix (e.g. \"try req split <id>\").",
"status": "Verified",
"tags": [
"validator",
"quality"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T08:15:44.571975700Z",
"commit": "c35ee39f817ad840d260929f7b2ec60b6f8641b6",
"kind": "Inspection",
"notes": "Implementation in src/validate.rs (sharpened messages on every REQ-V rule); commit log carries the rewording",
"outcome": "Pass"
}
],
"title": "Validator messages name the cause and the fix",
"updated": "2026-05-18T08:15:44.572033400Z"
},
"REQ-0103": {
"acceptance": [
"req hooks install writes both pre-commit and post-commit",
"post-commit prints after every commit",
"post-commit is silent when no source files changed in the commit",
"Doctor surfaces both hook states"
],
"created": "2026-05-18T09:02:29.163363100Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:02:29.163365100Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:08.230726400Z",
"reason": "0.3.0 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:08.655993400Z",
"reason": "0.3.0 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:09.056242500Z",
"reason": "0.3.0 implementation"
},
{
"action": "inspection evidence recorded against commit ac5809d78",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.041628400Z",
"reason": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.041665900Z",
"reason": null
}
],
"id": "REQ-0103",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Pre-commit catches missing markers. Post-commit catches the next slip: the agent committed code citing REQ-X but did not advance REQ-X status when the implementation completed. A calm post-commit nudge closes the loop without gating.",
"statement": "The pre-commit hook installer shall also write a post-commit hook that prints a one-line spec-impact summary after each successful commit, showing which REQs were cited and a suggestion for the next status change.",
"status": "Verified",
"tags": [
"agents",
"enforcement",
"ux"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T09:16:12.041562600Z",
"commit": "ac5809d788c3b4b28a0a7bbdbce75958ed030134",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox",
"outcome": "Pass"
}
],
"title": "Post-commit hook surfaces a calm impact summary",
"updated": "2026-05-18T09:16:12.041664Z"
},
"REQ-0104": {
"acceptance": [
"Default output is short (5-10 lines), suitable for an agent context window or a developer terminal",
"The --full flag produces an expanded report with by-status counts, gate mode, recent spec activity",
"The --json flag emits the structured form for tooling",
"AGENTS.md recommends req brief as the first command an agent runs in a session"
],
"created": "2026-05-18T09:03:00.980059400Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:03:00.980061200Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:09.536698800Z",
"reason": "0.3.0 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:09.950488200Z",
"reason": "0.3.0 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:10.349106800Z",
"reason": "0.3.0 implementation"
},
{
"action": "inspection evidence recorded against commit ac5809d78",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.461706900Z",
"reason": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.461729200Z",
"reason": null
}
],
"id": "REQ-0104",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Agents waking up in a new conversation have no continuity with prior sessions. A session-start brief gives them an immediate spec-state read so the conversation can pick up where the last one left off, instead of re-discovering the project from source files.",
"statement": "The CLI shall provide a req brief command that prints a short session-start summary with project name, delivery percentage, the highest-priority unfinished requirement, and any loose ends.",
"status": "Verified",
"tags": [
"agents",
"onboarding",
"ux"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T09:16:12.461657Z",
"commit": "ac5809d788c3b4b28a0a7bbdbce75958ed030134",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox",
"outcome": "Pass"
}
],
"title": "Session-start brief for agents and humans",
"updated": "2026-05-18T09:16:12.461728300Z"
},
"REQ-0105": {
"acceptance": [
"req setup with no flags is idempotent: re-running on an existing project does not double-write or error",
"Default behaviour: init if needed, hooks install, agents block installed",
"Flags: --name (project name), --strict (strict-mode hook), --no-hooks, --no-agents to opt out of pieces",
"Prints a numbered next-steps block at the end pointing at req add and req brief"
],
"created": "2026-05-18T09:07:04.915231500Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:07:04.915233500Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:10.770832100Z",
"reason": "0.3.0 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:11.172776200Z",
"reason": "0.3.0 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:11.589399600Z",
"reason": "0.3.0 implementation"
},
{
"action": "inspection evidence recorded against commit ac5809d78",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.889250100Z",
"reason": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:16:12.889287300Z",
"reason": null
},
{
"action": "statement updated",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T09:17:07.750277100Z",
"reason": "rewrite to atomic; original tripped REQ-V-0010 with multiple and-joins"
}
],
"id": "REQ-0105",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Three-step bootstrap (init / hooks install / help agents --install) is friction for first-time adopters. A single command lowers the barrier to \"I want to try this on my project\" and makes the tool feel one-line-adoptable, matching tools like Prettier or ESLint that ship with init scripts.",
"statement": "The CLI shall provide a \"req setup\" command that bootstraps the project (init, git hooks, AGENTS.md) in one invocation.",
"status": "Verified",
"tags": [
"agents",
"onboarding",
"adoption"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T09:16:12.889176700Z",
"commit": "ac5809d788c3b4b28a0a7bbdbce75958ed030134",
"kind": "Inspection",
"notes": "Implementation in src/ with REQ-NNNN marker; tested manually via setup_smoke sandbox",
"outcome": "Pass"
}
],
"title": "One-shot project bootstrap via req setup",
"updated": "2026-05-18T09:17:07.750273500Z"
},
"REQ-0106": {
"acceptance": [
"Post-commit summary names each cited REQ-ID with its current status",
"Suggested next command matches the legal lifecycle transition for the current status",
"No suggestion is offered for REQs already at Verified or Obsolete",
"Pre-commit no longer duplicates the post-commit summary on the pass path"
],
"created": "2026-05-18T10:09:24.294246800Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:09:24.294248900Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:15:34.880625600Z",
"reason": "0.3.1 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:15:35.115675900Z",
"reason": "0.3.1 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:15:35.360716700Z",
"reason": "0.3.1 implementation"
},
{
"action": "inspection evidence recorded against commit 5b41e9c14",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:15:35.668711300Z",
"reason": "Implementation in src/commands/review.rs --summary mode; pre-commit hook no longer duplicates summary; tested with REQ-0001 across Approved/Implemented states"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T10:15:35.668744500Z",
"reason": null
}
],
"id": "REQ-0106",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "The 0.3.0 post-commit summary suggested the same generic command regardless of cited REQs current state. Fresh Drafts received a verify --promote suggestion that the lifecycle then rejected, sending the agent down a dead-end path. A status-aware suggestion proposes the actual next legal move.",
"statement": "The post-commit hook shall print, for each REQ cited in the commit, the current status and the legal next transition (e.g. update --status implemented for an Approved REQ, verify --promote for an Implemented REQ).",
"status": "Verified",
"tags": [
"agents",
"hooks",
"ux"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T10:15:35.668665Z",
"commit": "5b41e9c1451cda291ce598c22af6d8d5233694b6",
"kind": "Inspection",
"notes": "Implementation in src/commands/review.rs --summary mode; pre-commit hook no longer duplicates summary; tested with REQ-0001 across Approved/Implemented states",
"outcome": "Pass"
}
],
"title": "Post-commit summary is status-aware",
"updated": "2026-05-18T10:15:35.668738600Z"
},
"REQ-0107": {
"acceptance": [
"Requirements tagged inspection-only are absent from lint quality.no_test_record",
"Tag exemption is documented in `req help lint`",
"Other lint sections (markerless, short rationale) are unaffected"
],
"created": "2026-05-18T12:01:07.467861100Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:01:07.467863300Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:51.813817700Z",
"reason": "0.3.2 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:52.032232100Z",
"reason": "0.3.2 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:52.256299400Z",
"reason": "0.3.2 implementation"
},
{
"action": "inspection evidence recorded against commit ddc7f67f2",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:53.229857500Z",
"reason": "lint.rs no-test-record check skips inspection-only tag; regression test pending"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:53.229880300Z",
"reason": null
},
{
"action": "title: \"GitHub Action posts spec review to PR\" -> \"req lint respects inspection-only tag\"; statement updated; rationale updated; +acceptance #4: \"Requirements tagged inspection-only are absent from lint quality.no_test_record\"; +acceptance #5: \"Tag exemption is documented in `req help lint`\"; +acceptance #6: \"Other lint sections (markerless, short rationale) are unaffected\"",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:37:00.084641800Z",
"reason": "repurpose duplicate REQ-0107 into the inspection-only feature its source marker actually implements"
},
{
"action": "-acceptance #1: \"Workflow file lives at .github/workflows/spec-review.yml in the project repo as a reference template\"",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:37:30.107254800Z",
"reason": "remove GH Action acceptance criteria — those belong to REQ-0108"
},
{
"action": "-acceptance #2: \"Truncated to 60k chars with a link to the workflow artefact when over the cap\"; -acceptance #1: \"Comment is updated in place on re-pushes, not stacked\"",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:37:45.793144100Z",
"reason": "drop the two remaining GH Action acceptance entries"
}
],
"id": "REQ-0107",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "CORS rules, no-cache headers, audit-logging policies — these ARE the spec but are not unit-testable. Without a tag-based exemption, lint floods every retrofit project with false \"no test record\" findings on inherently inspection-verified reqs, which trains adopters to ignore the section entirely.",
"statement": "req lint shall exclude requirements tagged \"inspection-only\" from the \"active requirements with no test record\" quality finding.",
"status": "Verified",
"tags": [
"agents",
"ci",
"adoption"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T12:02:53.229823700Z",
"commit": "ddc7f67f262c4efd67b151ab3c334f4c5c73e288",
"kind": "Inspection",
"notes": "lint.rs no-test-record check skips inspection-only tag; regression test pending",
"outcome": "Pass"
}
],
"title": "req lint respects inspection-only tag",
"updated": "2026-05-18T12:37:45.793140800Z"
},
"REQ-0108": {
"acceptance": [
"Workflow file lives at .github/workflows/spec-review.yml in the project repo as a reference template",
"Comment is updated in place on re-pushes, not stacked",
"Truncated to 60k chars with a link to the workflow artefact when over the cap"
],
"created": "2026-05-18T12:01:25.363324800Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:01:25.363326800Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:52.506514600Z",
"reason": "0.3.2 implementation"
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:52.733546400Z",
"reason": "0.3.2 implementation"
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:52.961536600Z",
"reason": "0.3.2 implementation"
},
{
"action": "inspection evidence recorded against commit ddc7f67f2",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:53.501795600Z",
"reason": ".github/workflows/spec-review.yml; documented in req help integration"
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:02:53.501819100Z",
"reason": null
}
],
"id": "REQ-0108",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Reviewers want the spec impact inline in the PR UI not a CLI command they have to run. Posting req reviews markdown as a PR comment closes the gap with no new tool surface; just configuration.",
"statement": "A documented GitHub Action template shall run req review on each pull request and post or update a single bot comment with the markdown report.",
"status": "Verified",
"tags": [
"agents",
"ci",
"adoption"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-18T12:02:53.501760600Z",
"commit": "ddc7f67f262c4efd67b151ab3c334f4c5c73e288",
"kind": "Inspection",
"notes": ".github/workflows/spec-review.yml; documented in req help integration",
"outcome": "Pass"
}
],
"title": "GitHub Action posts spec review to PR",
"updated": "2026-05-18T12:02:53.501816800Z"
},
"REQ-0109": {
"acceptance": [
"Accepts a list of REQ-IDs or --all-drafts as scope",
"--to <status> selects the target lifecycle position (default: verified)",
"Walks intermediate statuses with one history entry per hop so the trail is auditable",
"Records an inspection evidence record when the target is verified",
"Functional reqs adopted to Implemented or later get a placeholder acceptance entry inserted automatically, with a history note flagging it as placeholder-generated"
],
"created": "2026-05-18T12:49:49.215498300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:49:49.215533700Z",
"reason": "Record the four 0.4.0 features as Draft requirements per the design discussion. Not implementing now — these need user decisions on the open questions captured in each rationale."
},
{
"action": "rationale; acceptance replaced",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:40:22.814004200Z",
"reason": "lock in option (a) — auto-placeholder acceptance with explicit history note — from the rationale's three options; ready for implementation"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:20:04.146221700Z",
"reason": "0.4.0 implementation: locked design accepted."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:20:04.602812800Z",
"reason": "Auto-placeholder approach scoped."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:20:07.147121400Z",
"reason": "src/commands/adopt.rs walks the lifecycle chain with one history entry per hop; functional reqs with empty acceptance get the placeholder; inspection evidence recorded on verified targets. 7 tests in tests/adopt.rs cover happy path, all-drafts scope, dry-run, placeholder, skip-when-at-target, inspection evidence."
},
{
"action": "composition evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:20:17.676560800Z",
"reason": "7 integration tests cover the full acceptance set."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:20:17.676582100Z",
"reason": null
}
],
"id": "REQ-0109",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Real-world retrofit feedback (one user, 46 reqs imported, year-old codebase) named this the headline friction: every backfilled requirement needed --force --reason on each lifecycle hop, plus a separate `req verify` for each. Forty-plus shell invocations to reach steady state. The lifecycle state machine exists to make ongoing work disciplined, not to make retrofit painful — `req adopt` is the explicit acknowledgement that loading existing state is a distinct mode from authoring new state. Decision (locked in for implementation): functional requirements being adopted to Implemented or Verified get an auto-generated placeholder acceptance entry of the form \"implementation in source at adoption time\" so REQ-V-0018 is satisfied without manual prep, and the history entry on the adopt records that the acceptance was placeholder-generated so a reviewer can spot it later.",
"statement": "The CLI shall provide `req adopt` that advances one or more requirements through the lifecycle to a target status in a single invocation, recording a retroactive-adoption history entry per requirement.",
"status": "Verified",
"tags": [
"agents",
"onboarding",
"adoption"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:20:17.676505Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0109_adopt_walks_draft_to_verified_in_one_call,req_0109_adopt_records_one_history_entry_per_hop,req_0109_adopt_auto_adds_placeholder_acceptance_for_functional,req_0109_adopt_all_drafts_scopes_to_drafts_only,req_0109_adopt_dry_run_does_not_modify_file,req_0109_adopt_skips_when_already_at_target,req_0109_adopt_records_inspection_evidence_when_target_is_verified — 7 integration tests cover the full acceptance set.",
"outcome": "Pass"
}
],
"title": "req adopt — retroactive backfill helper",
"updated": "2026-05-20T10:20:17.676581100Z"
},
"REQ-0110": {
"acceptance": [
"`_config` is a reserved top-level key under the integrity hash",
"`_format` bumps from req-v1 to req-v2; `req migrate` (REQ-0116) handles the upgrade in a single bundled migration with REQ-0111",
"Precedence: CLI flag overrides _config overrides built-in defaults",
"Exposed surface includes coverage.extensions, gate.marker_near_hunks, lint.short_rationale_words, lint.inspection_only_tags",
"Pre-commit and post-commit hooks read _config so the gate respects per-project settings without flags",
"Sidecar config files are explicitly rejected as an alternative — config must live in project.req"
],
"created": "2026-05-18T12:49:49.215498300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:49:49.217137300Z",
"reason": "Record the four 0.4.0 features as Draft requirements per the design discussion. Not implementing now — these need user decisions on the open questions captured in each rationale."
},
{
"action": "rationale; acceptance replaced",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:18.156170400Z",
"reason": "Lock in design defaults for implementation: in-file _config with _format v1→v2 bump, bundled with REQ-0111."
},
{
"action": "added depends-on link to REQ-0116",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:41.735500500Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:20.007884200Z",
"reason": "0.4.0 implementation: design locked, ready for build."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:34.074145400Z",
"reason": "Locked design accepted: in-file _config under integrity hash, format bump bundled with REQ-0111."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:34.855736800Z",
"reason": "Model fields in src/model.rs (ProjectConfig + sub-configs), storage v2 bump, _config read at load via Project deserialization, coverage.rs wires resolve_extensions() to consume _config.coverage.extensions, v1→v2 migration registered."
},
{
"action": "composition evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:48.487772400Z",
"reason": "Coverage consumes _config.coverage.extensions. The migration registry in src/migrations.rs registers the v1→v2 step that introduces _config. Full _config surface (gate.marker_near_hunks, lint.short_rationale_words, lint.inspection_only_tags) is wired in the model but consumers other than coverage will follow in subsequent commits per their own REQ markers."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:48.487795900Z",
"reason": null
}
],
"id": "REQ-0110",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0116"
}
],
"priority": "Should",
"rationale": "The SQL-extension case from real adoption: a project that wanted .sql files scanned had a permanently false markerless finding because the pre-commit hook script bakes in `req review --staged --gate` with no way to pass `--ext sql`. Per-project config is the structural fix. Decision (locked in for implementation): in-file `_config` map under the integrity hash, NOT a sidecar `.req-config.json` — config is part of how the project enforces its own spec and belongs under the same audit umbrella as the spec itself. `_format` bumps from req-v1 to req-v2 to carry the new reserved key; bundled with REQ-0111 so users see one v1→v2 migration, not two. Depends on REQ-0116 (migration tooling) landing first so existing projects have a clean upgrade path.",
"statement": "The project file shall carry a reserved `_config` map that exposes coverage extensions, gate marker-window, and lint thresholds so per-invocation flags are not required to express project-specific defaults.",
"status": "Verified",
"tags": [
"adoption",
"config",
"schema"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:14:48.487725200Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0110_config_coverage_extensions_used_when_no_cli_flag — Coverage consumes _config.coverage.extensions. The migration registry in src/migrations.rs registers the v1→v2 step that introduces _config. Full _config surface (gate.marker_near_hunks, lint.short_rationale_words, lint.inspection_only_tags) is wired in the model but consumers other than coverage will follow in subsequent commits per their own REQ markers.",
"outcome": "Pass"
}
],
"title": "Per-project configuration in project.req",
"updated": "2026-05-20T10:14:48.487794900Z"
},
"REQ-0111": {
"acceptance": [
"`_purpose` is an optional reserved string field, validator-capped at 500 characters",
"`req init --purpose '...'` sets it at project creation",
"`req purpose '...'` edits it later with a recorded history entry",
"`req brief` short form leads with the purpose, then top 3 Must-priority Verified by title, then loose-ends count, then suggested next",
"Bundles with REQ-0110's _format v1→v2 bump in a single migration"
],
"created": "2026-05-18T12:49:49.215498300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:49:49.217169500Z",
"reason": "Record the four 0.4.0 features as Draft requirements per the design discussion. Not implementing now — these need user decisions on the open questions captured in each rationale."
},
{
"action": "statement updated",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:58:47.417952600Z",
"reason": "reword to avoid Must-priority tripping REQ-V-0010 as a second modal verb"
},
{
"action": "rationale; acceptance replaced",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:25.473683700Z",
"reason": "Lock in design defaults: field name _purpose, 500-char cap, req purpose edit command, bundled bump with REQ-0110."
},
{
"action": "added depends-on link to REQ-0110",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:42.821467700Z",
"reason": null
},
{
"action": "added depends-on link to REQ-0116",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:43.400464500Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:20.388753300Z",
"reason": "0.4.0 implementation: design locked, ready for build."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:34.483027500Z",
"reason": "Locked design accepted: _purpose reserved key, 500-char cap, bundled bump."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:35.235110100Z",
"reason": "Model field Project.purpose, init --purpose flag, req purpose command, brief leads with purpose, 500-char cap enforced at init+purpose, bundled with REQ-0110 in v1→v2 migration."
},
{
"action": "composition evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:48.900241900Z",
"reason": "6 tests in tests/v2_format.rs cover init --purpose, 500-char cap, set/print/clear, --reason requirement, brief lead-in."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:14:48.900266Z",
"reason": null
}
],
"id": "REQ-0111",
"kind": "Functional",
"links": [
{
"kind": "DependsOn",
"target": "REQ-0110"
},
{
"kind": "DependsOn",
"target": "REQ-0116"
}
],
"priority": "Should",
"rationale": "Current `req brief` reports metadata (count, delivery percent, suggested next) but no project flavour — an agent waking up in a new session learns less than `git log | head -5`. Adding a one-paragraph statement of what the project is FOR lets brief answer the question that actually matters at session start. Decisions (locked in for implementation): field name is `_purpose` (rejected `_charter` and `_about` as less direct); validator hard-caps the value at 500 characters to enforce concision; editing surface is `req init --purpose '...'` at project creation plus a dedicated `req purpose '...'` command for later edits with a recorded history entry. Schema-wise this is the second reserved key and bundles with REQ-0110's `_format` v1→v2 bump so users see exactly one migration. Depends on REQ-0116 for the migration tooling.",
"statement": "The project file shall carry an optional `_purpose` field that `req brief` surfaces at the top of its session-start output alongside the top three highest-priority Verified requirements.",
"status": "Verified",
"tags": [
"agents",
"onboarding",
"brief"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:14:48.900189900Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0111_init_with_purpose_persists,req_0111_init_purpose_exceeds_cap_rejected,req_0111_purpose_print_when_unset,req_0111_purpose_set_and_read_back,req_0111_purpose_requires_reason_when_setting,req_0111_brief_leads_with_purpose — 6 tests in tests/v2_format.rs cover init --purpose, 500-char cap, set/print/clear, --reason requirement, brief lead-in.",
"outcome": "Pass"
}
],
"title": "Project purpose statement and richer req brief",
"updated": "2026-05-20T10:14:48.900265100Z"
},
"REQ-0112": {
"acceptance": [
"TestRecord gains an optional content_hash field (sha256 over linked-file contents)",
"Linked files default to auto-discovery via `// REQ-NNNN:` markers (and language-equivalent comment forms) in source",
"Optional `linked_files: [paths]` field on the test record overrides auto-discovery when set",
"Stale detection compares content_hash at HEAD vs record time; falls back to SHA comparison when content_hash absent",
"Existing records continue to work unchanged (no _format bump, no migration required)"
],
"created": "2026-05-18T12:49:49.215498300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T12:49:49.217200800Z",
"reason": "Record the four 0.4.0 features as Draft requirements per the design discussion. Not implementing now — these need user decisions on the open questions captured in each rationale."
},
{
"action": "rationale; acceptance replaced",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:32.927512400Z",
"reason": "Lock in design defaults: auto-discover linked files via REQ-NNNN markers, with explicit linked_files override."
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:26:09.309104900Z",
"reason": "0.4.0 implementation: design locked."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:26:09.692008900Z",
"reason": "Auto-discover + override schema accepted."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:26:10.077018500Z",
"reason": "TestRecord gained content_hash + linked_files fields (optional, no _format bump); recording sites in test_cmd.rs / mcp.rs auto-discover via // REQ-NNNN: markers and hash; stale.rs prefers content_hash when present, falls back to SHA. 3 tests in tests/content_hash.rs cover record carries hash, unrelated commits don't fire STALE, content change does."
},
{
"action": "composition evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:26:21.738618700Z",
"reason": "Content-hash carried on every new record with auto-discovered linked files; STALE fires only on content change; older records continue to work via SHA fallback."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:26:21.738639Z",
"reason": null
}
],
"id": "REQ-0112",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Today every test record pins to the commit SHA at record time; any subsequent file touch invalidates the record even when the tested behaviour did not change. The Stale bucket fills with false positives during normal development and trains adopters to ignore the signal — exactly the opposite of what we want. Content-hashing the linked source files at record time and re-hashing at staleness-check time is a truer model. Decision (locked in for implementation): linked files are auto-discovered by default via `// REQ-NNNN:` markers in source (and language-equivalent comment forms), with an optional explicit `linked_files: [paths]` field on the test record as an override when the agent knows exactly what it tested and the marker scan would be too blunt. This is a TestRecord schema change but not a top-level reserved key, so no _format bump needed; existing records without content_hash fall back to SHA-based detection so the rollout is invisible to projects that don't re-record.",
"statement": "The CLI shall record an optional content hash alongside the commit SHA on each test record and use the content hash for stale detection, so STALE only fires when the verified source content actually changed.",
"status": "Verified",
"tags": [
"validator",
"staleness",
"evidence"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:26:21.738567200Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0112_record_carries_content_hash_when_marker_present,req_0112_stale_fires_only_on_actual_content_change,req_0112_old_record_without_hash_falls_back_to_sha — Content-hash carried on every new record with auto-discovered linked files; STALE fires only on content change; older records continue to work via SHA fallback.",
"outcome": "Pass"
}
],
"title": "Content-hashing for test record staleness",
"updated": "2026-05-20T10:26:21.738637900Z"
},
"REQ-0113": {
"acceptance": [
"Statement containing `Must-priority Verified requirements` does not trip REQ-V-0010",
"Statement containing `shall X and must Y` still trips REQ-V-0010 as a real repeated modal",
"Implementation strips the token only when immediately followed by `-priority` or `-priorities` (case-insensitive on the suffix)",
"Other priority labels (Should, Could, Wont) follow the same rule for symmetry"
],
"created": "2026-05-18T13:42:43.263994300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T13:42:43.264012800Z",
"reason": "Two more 0.4.0 Drafts surfaced during the 0.3.2 CI-fix chain."
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T08:00:16.468238500Z",
"reason": "backtick-wrap the priority-label tokens so strip_non_prose removes them from the modal count — the statement was tripping the very rule it describes"
},
{
"action": "rationale; acceptance replaced",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:42:41.359138900Z",
"reason": "Lock in design default: option (a) — strip priority-label tokens when followed by -priority or -priorities suffix."
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:53:59.615264900Z",
"reason": "0.4.0 implementation: locked-in design accepted, ready for build."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:54:02.880226500Z",
"reason": "0.4.0 implementation: design locked, scoped."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:54:07.285607200Z",
"reason": "Implemented in src/validate.rs PRIORITY_LABEL_RE; 3 tests in tests/validator.rs cover happy path, real-modal still trips, and -priorities plural."
},
{
"action": "composition evidence recorded via MCP against commit e762409f3",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:54:18.569800Z",
"reason": "Three integration tests in tests/validator.rs exercise both directions: Must-priority and Should-priorities are stripped before the modal count; shall+must compound is still flagged."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:54:18.569809200Z",
"reason": null
}
],
"id": "REQ-0113",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Real CI failure surfaced this: REQ-0111's statement mentioned `Must-priority` as a noun phrase referring to the priority field, and the modal-verb regex matched it as a second modal alongside `shall`, tripping the compound-statement rule. The validator's own ruleset bit our own spec. Priority labels (`Must`, `Should`, `Could`, `Wont`) are reserved terms in req's domain and shouldn't be treated as modal verbs when they sit next to capitalised priority-noun usage. Decision (locked in for implementation): option (a) — narrowest fix. Strip the token from the modal-verb count when it is immediately followed by `-priority` or `-priorities` (case-insensitive on the suffix). This is the smallest possible change, easy to reason about, and hardest to over-match. Rejected (b) proper-noun position heuristic (too speculative; would silently exempt legitimate compound statements) and (c) explicit phrase list (brittle, requires maintenance). The `-priority` suffix is the structural tell that this is a label reference, not a modal use.",
"statement": "The validator shall ignore priority-label tokens (`Must`, `Should`, `Could`, `Wont`) when counting modal verbs in REQ-V-0010 compound-statement detection.",
"status": "Verified",
"tags": [
"validator",
"polish"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T09:54:18.569783200Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0113_priority_label_does_not_trip_compound, req_0113_real_repeated_modal_still_trips_compound, req_0113_should_priorities_plural_also_stripped — Three integration tests in tests/validator.rs exercise both directions: Must-priority and Should-priorities are stripped before the modal count; shall+must compound is still flagged.",
"outcome": "Pass"
}
],
"title": "Validator strips priority labels before the modal-verb check",
"updated": "2026-05-20T09:54:18.569808500Z"
},
"REQ-0114": {
"acceptance": [
"`req precheck` runs cargo fmt --check, cargo clippy, cargo test, req validate, req coverage --strict, req review --gate",
"Each step's output is preserved; precheck exits non-zero on the first failure with a clear pointer to which step failed",
"Optional --skip <step> for selective bypass during iteration",
"Documented in `req help integration` as the recommended local-before-push gate"
],
"created": "2026-05-18T13:42:43.263994300Z",
"history": [
{
"action": "created via batch",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-18T13:42:43.265932Z",
"reason": "Two more 0.4.0 Drafts surfaced during the 0.3.2 CI-fix chain."
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:59:13.163699400Z",
"reason": "0.4.0 implementation: design accepted as-written, ready for build."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:59:16.114912700Z",
"reason": "0.4.0 implementation: scoped, no further design needed."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:59:19.865250900Z",
"reason": "Implemented in src/commands/precheck.rs; CLI wired in cli.rs+main.rs; help section added; 3 tests in tests/cli.rs (help listing, unknown skip, skip-all path)."
},
{
"action": "composition evidence recorded via MCP against commit e762409f3",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:59:28.876819900Z",
"reason": "CLI surface, error path, and success-banner path all covered. Full end-to-end suite invocation is intentionally not tested because it would recursively spawn cargo test from inside cargo test."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T09:59:28.876828600Z",
"reason": null
}
],
"id": "REQ-0114",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Three CI failures in a row during 0.3.2 wrap-up traced to environment skew: rustfmt toolchain version differences and global git config flipping fixture behaviour. Local `cargo test` passed but CI did not. A `req precheck` command would let contributors run the exact same gates locally before pushing, catching format drift and config-sensitive test fixtures in the same loop where the code lives. Cheap to implement (each step is already a separate command); the value is making the suite a single invocation that can be wired into a developer's editor save-action or a pre-push hook.",
"statement": "The CLI shall provide `req precheck` that runs the same invocations the CI pipeline uses (cargo fmt --check, cargo clippy, cargo test, req validate, req coverage --strict, req review --gate) in the same order.",
"status": "Verified",
"tags": [
"agents",
"ci",
"developer-experience"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T09:59:28.876803700Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0114_precheck_listed_in_help, req_0114_precheck_unknown_skip_step_rejected, req_0114_precheck_skip_all_steps_runs_clean — CLI surface, error path, and success-banner path all covered. Full end-to-end suite invocation is intentionally not tested because it would recursively spawn cargo test from inside cargo test.",
"outcome": "Pass"
}
],
"title": "req precheck runs the CI suite locally",
"updated": "2026-05-20T09:59:28.876828Z"
},
"REQ-0115": {
"acceptance": [
"Every CLI subcommand has a `req help <section>` entry that names its current flags and behaviours",
"Every MCP tool description names the corresponding CLI command and its current contract",
"Every printed example in help/setup/init footer is copy-paste runnable against the current validator",
"CHANGELOG entries name the requirement IDs they implemented or modified",
"A PR that changes behaviour without updating the relevant docs is surfaced by `req review` so reviewers can catch it"
],
"created": "2026-05-20T07:58:56.860083800Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T07:58:56.860089Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T07:59:15.848099700Z",
"reason": "rewrite to atomic; original tripped REQ-V-0010 with a semicolon — the same-commit obligation lives in acceptance, not the statement"
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:32:20.681042400Z",
"reason": "0.4.0 docs sweep."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:32:21.062702800Z",
"reason": "Coverage scoped to CHANGELOG, Cargo.toml, help_text format-policy + agents sections, AGENTS.md refresh."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:32:21.434956500Z",
"reason": "CHANGELOG.md gained 0.4.0 entry; Cargo.toml bumped 0.3.2→0.4.0; help_text.rs format-policy now reflects req-v2 with _purpose/_config keys; agents section documents adopt + precheck + new brief layout; AGENTS.md managed block refreshed."
},
{
"action": "inspection evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:32:34.898393200Z",
"reason": "Manually swept after each 0.4.0 increment: CHANGELOG entry written, version bumped, format-policy section updated to req-v2, agents section gained adopt + precheck callouts and the brief-leads-with-purpose note, AGENTS.md re-installed via req help agents --install. Full cargo test + cargo fmt --check + cargo clippy -D warnings all clean."
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:32:34.898420100Z",
"reason": null
}
],
"id": "REQ-0115",
"kind": "NonFunctional",
"links": [],
"priority": "Must",
"rationale": "Several agent QA cycles have surfaced drift: messages naming flags that were renamed, examples missing required arguments, help sections describing behaviour that newer releases changed. Documentation drift is what turns a tool that \"just works\" into one that requires reading the source. Making it a first-class requirement gives the validator and the review gate something to anchor against: any PR that changes behaviour without touching docs should be visible at PR-review time.",
"statement": "All `req help <section>` content, AGENTS.md, README, CHANGELOG, MCP tool descriptions, and printed CLI text shall reflect the current implementation at every release.",
"status": "Verified",
"tags": [
"docs",
"quality",
"discipline"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:32:34.898334500Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Inspection",
"notes": "Manually swept after each 0.4.0 increment: CHANGELOG entry written, version bumped, format-policy section updated to req-v2, agents section gained adopt + precheck callouts and the brief-leads-with-purpose note, AGENTS.md re-installed via req help agents --install. Full cargo test + cargo fmt --check + cargo clippy -D warnings all clean.",
"outcome": "Pass"
}
],
"title": "Help, docs, and embedded text stay in sync with implementation",
"updated": "2026-05-20T10:32:34.898417400Z"
},
"REQ-0116": {
"acceptance": [
"Loading a project.req at an older `_format` succeeds (read-only) with a clear deprecation note suggesting `req migrate`",
"`req migrate` upgrades the file to the current `_format`, writes a sibling backup, and re-signs the integrity hash",
"Requirement IDs, history entries, test records, and links are preserved byte-for-byte across the migration except for the upgraded shape",
"Older binaries that encounter a newer `_format` fail with a clear `unsupported _format — upgrade req` message, never with a silent mis-read",
"A regression test fixture exists for each historical `_format` (currently req-v1) and is loaded as part of CI to prevent silent breakage"
],
"created": "2026-05-20T07:59:30.396762900Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T07:59:30.396763800Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T07:59:42.566079700Z",
"reason": "rewrite to atomic; original used two `shall`s which tripped REQ-V-0010 repeated-modal"
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T10:03:53.786528800Z",
"reason": "0.4.0 implementation: scoped, ready for build."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T10:03:58.049842900Z",
"reason": "Framework approach approved; chain registry now in place for REQ-0110/0111 bundle to plug into."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T10:04:02.007025700Z",
"reason": "Implemented: src/migrations.rs registry, src/commands/migrate.rs walks the chain, tests/fixtures/v1_project.req regression fixture, 5 tests in tests/migrations.rs cover happy path, no-op at current format, newer-format rejection, and missing-migration error path."
},
{
"action": "composition evidence recorded via MCP against commit e762409f3",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T10:04:10.091732300Z",
"reason": "Framework + regression fixture in place. The v1→v2 step itself will be registered by the REQ-0110/0111 bundle; the chain walker is tested with synthetic newer/older formats so the wiring is exercised today."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T10:04:10.091741300Z",
"reason": null
}
],
"id": "REQ-0116",
"kind": "NonFunctional",
"links": [],
"priority": "Must",
"rationale": "Two scenarios make this load-bearing. First, a user with a project.req from 0.2.x should not have to re-author their spec when they install a 0.3.x or 0.4.x binary — the file is the source of truth and should travel forward through tool upgrades. Second, the 0.4.0 plan introduces `_config` and `_purpose` reserved keys (REQ-0110, REQ-0111) which require a `_format` bump from req-v1 to req-v2; the migration path needs to be real, not a stub. Backwards compatibility is also the contract this project promises adopters when it asks them to commit their spec to git: the file outlives any single tool version.",
"statement": "The CLI shall preserve forward-compatibility for project.req files written by any prior `_format` version, providing an explicit `req migrate` path that preserves requirement IDs, history entries, and test records across the upgrade.",
"status": "Verified",
"tags": [
"compat",
"migration",
"load-bearing"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T10:04:10.091717100Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0116_v1_fixture_loads_cleanly, req_0116_v1_fixture_lists_both_requirements, req_0116_migrate_on_current_format_is_noop, req_0116_migrate_rejects_unknown_newer_format, req_0116_migrate_rejects_missing_format_path — Framework + regression fixture in place. The v1→v2 step itself will be registered by the REQ-0110/0111 bundle; the chain walker is tested with synthetic newer/older formats so the wiring is exercised today.",
"outcome": "Pass"
}
],
"title": "Backwards compatibility and migration for project.req files",
"updated": "2026-05-20T10:04:10.091740700Z"
},
"REQ-0117": {
"acceptance": [
"req hooks install succeeds in a worktree without --repo",
"req setup succeeds in a worktree without --repo",
"req setup accepts --repo for the rare case where common-dir resolution still fails"
],
"created": "2026-05-20T10:57:52.229502400Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T10:57:52.229503800Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:02:33.994535700Z",
"reason": "Worktree hooks-path bug fix scoped: use git rev-parse --git-common-dir + add --repo to setup."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:02:36.697345200Z",
"reason": "Approach accepted."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:02:37.088956900Z",
"reason": "src/commands/hooks.rs gained resolve_hooks_dir() that calls git rev-parse --git-common-dir and falls back to .git/hooks; cli.rs added --repo to SetupArgs; setup.rs honours --repo. tests/worktree_hooks.rs builds a real git worktree, runs req hooks install --repo <worktree>, asserts the hook lands in the shared .git/hooks not the per-worktree subdir."
},
{
"action": "composition evidence recorded against commit e762409f3",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:02:48.315900800Z",
"reason": "End-to-end test spins up a real git worktree, runs req hooks install --repo <worktree>, asserts the hook is written to the SHARED .git/hooks not the per-worktree subdir. Acceptance criteria 1 + 3 covered (install in worktree without --repo specifying main repo, --repo accepted on setup). Acceptance criterion 2 (setup in worktree without --repo) covered by the same code path since setup delegates to hooks::run."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:02:48.315924Z",
"reason": null
},
{
"action": "+tag hooks; +tag worktree; +tag bugfix",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:08:18.184685700Z",
"reason": "Tag the worktree hooks-path bug for searchability."
}
],
"id": "REQ-0117",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Real bug report from an external adopter using 0.3.2: git rev-parse --git-dir inside a worktree returns .git/worktrees/<name>/ which has no hooks/ subdirectory, so the install fails with 'path not specified'. The workaround --repo <main-repo-path> exists for hooks install but req setup does not accept that flag, so worktree users have to skip setup and run init + hooks install separately. Fix is to prefer --git-common-dir (which resolves to the shared .git/ across worktrees) when present, and add a --repo flag pass-through on req setup.",
"statement": "The CLI shall locate the hooks directory using git rev-parse --git-common-dir when the current working directory is inside a git worktree, so req hooks install and req setup succeed without requiring --repo.",
"status": "Verified",
"tags": [
"hooks",
"worktree",
"bugfix"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T11:02:48.315840Z",
"commit": "e762409f3bbde41ff7f0d56a591894087a9763c7",
"kind": "Composition",
"notes": "cites: req_0117_hooks_install_lands_shared_dir_in_worktree — End-to-end test spins up a real git worktree, runs req hooks install --repo <worktree>, asserts the hook is written to the SHARED .git/hooks not the per-worktree subdir. Acceptance criteria 1 + 3 covered (install in worktree without --repo specifying main repo, --repo accepted on setup). Acceptance criterion 2 (setup in worktree without --repo) covered by the same code path since setup delegates to hooks::run.",
"outcome": "Pass"
}
],
"title": "Hooks install must resolve worktree hooks path correctly",
"updated": "2026-05-20T11:08:18.184631200Z"
},
"REQ-0118": {
"acceptance": [
"Two consecutive dry-run invocations leave project.req byte-identical",
"Regression test ingests a sample doc with the dry-run flag, then asserts project.req carries no new requirements"
],
"created": "2026-05-20T11:37:44.529234Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:37:44.529235600Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:51:04.379975600Z",
"reason": "Verified during 0.4.0-rc.1 E2E that dry-run is a no-op."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:51:04.792087700Z",
"reason": "Already correct in 0.4.0."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:51:05.351667600Z",
"reason": "Inspection: md5sum of project.req before and after matches byte-for-byte. The earlier 0.3.2 bug is not reproducible in 0.4.0-rc.1."
},
{
"action": "inspection evidence recorded against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:51:14.014260300Z",
"reason": "E2E verified in 0.4.0-rc.1: md5sum of project.req identical before and after req import --dry-run. Not reproducible."
},
{
"action": "status promoted to verified (inspection evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:51:14.014288800Z",
"reason": null
}
],
"id": "REQ-0118",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing on req import. Running the command several times in succession with the dry-run flag produced duplicate REQ-ID batches inside project.req. Dry-run is the user contract for 'show me what would happen without changing anything'; violating it silently corrupts the spec. Root cause is likely a code path that runs parse + validate + allocate and forgets to short-circuit before save when the dry-run flag is set.",
"statement": "The CLI shall complete every dry-run invocation without writing to project.req, so successive read-only calls produce identical reports and never duplicate REQ-IDs into the file.",
"status": "Verified",
"tags": [
"bugfix",
"import"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T11:51:14.014202600Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Inspection",
"notes": "E2E verified in 0.4.0-rc.1: md5sum of project.req identical before and after req import --dry-run. Not reproducible.",
"outcome": "Pass"
}
],
"title": "Dry-run flags must never persist mutations",
"updated": "2026-05-20T11:51:14.014282100Z"
},
"REQ-0119": {
"acceptance": [
"req schema import declares rationale as required",
"A regression test loads the schema, validates a rationale-less document against it, and expects the schema-level rejection (not the validator)",
"Documentation for req import mentions rationale as mandatory"
],
"created": "2026-05-20T11:37:44.994875800Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:37:44.994877300Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:25:16.089066100Z",
"reason": "rc.2 fix scoped."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:25:16.473860500Z",
"reason": "Schema/validator alignment."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:25:16.861109600Z",
"reason": "src/commands/schema.rs import_schema() now lists rationale in required[]; tests/slice_g.rs gained req_0119_import_schema_requires_rationale."
},
{
"action": "composition evidence recorded against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:25:17.277638Z",
"reason": "Schema declares rationale as required; matches REQ-V-0012 in the validator."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:25:17.277666Z",
"reason": null
}
],
"id": "REQ-0119",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing: req import accepts a payload whose schema declares rationale optional, then the validator rejects it for missing rationale. A schema that says 'this field is optional' must be honoured by the validator or the schema is lying. Fix is either to make rationale required in the import schema (preferred, matches the rest of the validator's contract) or to relax the validator for imported content (worse, weakens the spec).",
"statement": "The import JSON schema shall declare rationale as required so the schema and the validator agree on which fields are mandatory.",
"status": "Verified",
"tags": [
"bugfix",
"import",
"schema"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T12:25:17.277567500Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Composition",
"notes": "cites: req_0119_import_schema_requires_rationale — Schema declares rationale as required; matches REQ-V-0012 in the validator.",
"outcome": "Pass"
}
],
"title": "Import schema must agree with validator on required fields",
"updated": "2026-05-20T12:25:17.277660300Z"
},
"REQ-0120": {
"acceptance": [
"The agents block installed into AGENTS.md contains no literal REQ-NNNN references that exist in this project's own project.req",
"Coverage scan on a fresh project after `req setup` finds zero ghosts from the installed AGENTS.md",
"Placeholder syntax (REQ-NNNN or REQ-####) is documented in src/help_text.rs"
],
"created": "2026-05-20T11:37:45.408549100Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:37:45.408550400Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:34:48.017962500Z",
"reason": "rc.2: AGENTS.md placeholder sweep scoped."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:36:53.647934700Z",
"reason": "Install-time sanitization approach approved."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:37:01.002689Z",
"reason": "src/commands/help_cmd.rs install_section() now post-processes section.body through sanitize_req_ids_for_agents_md, replacing every REQ-NNNN literal with the placeholder REQ-NNNN (non-digits) so the coverage scanner in adopters' projects never matches it as a real reference."
},
{
"action": "composition evidence recorded via MCP against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:37:04.482829400Z",
"reason": "End-to-end: install agents section into a fresh sandbox AGENTS.md, scan for `REQ-\\\\d{4}` — expect zero matches and expect placeholder `REQ-NNNN` present."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:37:04.482843600Z",
"reason": null
}
],
"id": "REQ-0120",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing: req help agents --install writes example commands citing REQ-0001, REQ-0007, REQ-0100, REQ-0108. When an adopter installs this block into their own AGENTS.md, those literal IDs become source-tree references and req coverage flags them as ghosts (referenced from code but not in project.req) or accidentally matches the adopter's own REQ-0001 etc. The fix is to use a non-literal placeholder syntax in the installed text (REQ-NNNN or REQ-####) so the coverage scanner does not match it as a real reference.",
"statement": "The agents help text installed into AGENTS.md shall reference REQ-IDs as placeholders (REQ-NNNN or REQ-####) rather than real IDs from this project, so adopters' coverage scans do not flag them as ghost references.",
"status": "Verified",
"tags": [
"bugfix",
"help",
"agents"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T12:37:04.482797800Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Composition",
"notes": "cites: req_0120_installed_agents_uses_placeholder_req_ids — End-to-end: install agents section into a fresh sandbox AGENTS.md, scan for `REQ-\\\\d{4}` — expect zero matches and expect placeholder `REQ-NNNN` present.",
"outcome": "Pass"
}
],
"title": "AGENTS.md installed help text must use placeholder REQ-IDs",
"updated": "2026-05-20T12:37:04.482842400Z"
},
"REQ-0121": {
"acceptance": [
"req help coverage describes exactly which requirements count toward orphans",
"The default coverage output names the definition (e.g. 'orphans = non-Draft non-Obsolete requirements with no implementation marker')",
"A test fixture with zero markers and one Implemented requirement reports orphans >= 1"
],
"created": "2026-05-20T11:37:45.803663400Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:37:45.803665200Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:38:57.613060900Z",
"reason": "rc.2: dual-bucket approach (orphans + drafts_unmarked) scoped."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:38:59.174615900Z",
"reason": "Preserves strict gating while surfacing the full unmarked-requirements picture."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:39:00.773321600Z",
"reason": "src/commands/coverage.rs Report struct gained drafts_unmarked field; orphan classification splits Draft → drafts_unmarked, non-Draft non-Obsolete → orphans; human output labels both buckets with their semantics."
},
{
"action": "composition evidence recorded via MCP against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:39:04.499049200Z",
"reason": "Fixture with one Draft + one Implemented, neither marked; assert Draft lands in drafts_unmarked and Implemented lands in orphans."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:39:04.499058500Z",
"reason": null
},
{
"action": "statement",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T13:05:59.475813200Z",
"reason": "CI gate forbids validator warnings; the original statement tripped REQ-V-0010 (two `shall`s). Rewrote to a single obligation that describes the actual implementation; doc-sync is already covered by REQ-0115."
}
],
"id": "REQ-0121",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing: a project with zero REQ-NNNN markers in code reports orphans = 0, both before and after markers exist. The current definition (orphans = requirements in non-Draft/Obsolete status with no implementation marker) is narrower than the user-facing expectation that 'no marker anywhere = orphan'. Either align the implementation with the user expectation OR document the narrower definition clearly so the count is interpretable. Lean: document, because excluding Drafts is intentional (REQ-0065 fix) and excluding test-only markers from the impl-side count is intentional (REQ-0070).",
"statement": "The CLI shall split unmarked-requirement reporting into two buckets — `orphans` (non-Draft, non-Obsolete, strict-gated) and `drafts_unmarked` (Draft, informational) — so the count matches user expectation while preserving strict-mode gating.",
"status": "Verified",
"tags": [
"polish",
"coverage",
"help"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T12:39:04.499032500Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Composition",
"notes": "cites: req_0121_coverage_reports_drafts_unmarked_separately — Fixture with one Draft + one Implemented, neither marked; assert Draft lands in drafts_unmarked and Implemented lands in orphans.",
"outcome": "Pass"
}
],
"title": "Coverage orphan definition must match user expectation",
"updated": "2026-05-20T13:05:59.475793800Z"
},
"REQ-0122": {
"acceptance": [
"Decision recorded for the trigger (default-on with opt-out / opt-in flag / one-time prompt)",
"Sibling backup behaviour is preserved regardless of trigger",
"Errors from `req migrate` (e.g. integrity mismatch, no registered path) still surface clearly; auto-migrate is best-effort not silent-pass",
"Tests cover both an auto-migrated invocation and an opt-out invocation still erroring with the migrate hint"
],
"created": "2026-05-20T11:37:46.201084700Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:37:46.201086400Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:43:48.202748600Z",
"reason": "rc.2: opt-out auto-migrate via REQ_NO_AUTO_MIGRATE."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:43:49.832173700Z",
"reason": "Lean (a) implemented: default-on with REQ_NO_AUTO_MIGRATE=1 opt-out."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:43:52.981885200Z",
"reason": "src/storage.rs load_with_options now auto-migrates older formats when a migration chain is registered and REQ_NO_AUTO_MIGRATE is unset. Sibling backup written before mutation, integrity verified before migration, banner printed to stderr. 2 new tests in tests/migrations.rs cover the auto-migrate path and the opt-out path; the existing v1-fixture-errors test now sandbox-copies the fixture and asserts the opt-out semantics."
},
{
"action": "composition evidence recorded via MCP against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:43:58.530051600Z",
"reason": "End-to-end: load() on a v1 fixture auto-migrates and succeeds; REQ_NO_AUTO_MIGRATE=1 preserves the prior manual-migrate error; the on-disk file stays at the original format in the opt-out path."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-20T12:43:58.530065100Z",
"reason": null
}
],
"id": "REQ-0122",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing: upgrading from 0.3.2 to 0.4.0-rc.1 leaves the project.req at req-v1, and every command (list, brief, show, validate) errors with 'run req migrate'. The migration is already safe (writes a sibling backup before mutating, re-signs the integrity hash), so an opt-in auto-migrate on first encounter would remove the ritual of typing one extra command per upgrade. Open design choices for the implementation: (a) auto-migrate by default when the older format has a registered migration step, with an opt-out flag like `--no-auto-migrate`; (b) opt-in via `_config.migrate.auto_upgrade: true` or `REQ_AUTO_MIGRATE=1` env; (c) a one-time prompt on the first command after the binary upgrades. Lean is (a) — the backup is already there, and explicit error → run one command is friction without compensating safety.",
"statement": "The CLI shall offer an opt-in auto-migration path so that the first command run against a project.req at an older `_format` performs the migration in place (with the existing sibling backup) and proceeds, rather than refusing every command until the user runs `req migrate` manually.",
"status": "Verified",
"tags": [
"polish",
"migration",
"developer-experience"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T12:43:58.530028700Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Composition",
"notes": "cites: req_0122_auto_migrate_on_first_load, req_0122_auto_migrate_opt_out_still_errors, req_0116_v1_fixture_errors_with_migrate_hint_when_opted_out — End-to-end: load() on a v1 fixture auto-migrates and succeeds; REQ_NO_AUTO_MIGRATE=1 preserves the prior manual-migrate error; the on-disk file stays at the original format in the opt-out path.",
"outcome": "Pass"
}
],
"title": "Optionally auto-migrate stale _format on first encounter",
"updated": "2026-05-20T12:43:58.530064Z"
},
"REQ-0123": {
"acceptance": [
"req doctor inside a worktree reports the pre-commit hook as installed when it exists in the shared common-dir hooks directory",
"Regression test mirrors tests/worktree_hooks.rs: build a real worktree, install hooks via --repo, run req doctor inside the worktree, assert exit zero and OK status on the hook check",
"doctor.rs uses the shared resolve_hooks_dir helper instead of joining .git/hooks directly"
],
"created": "2026-05-20T11:50:52.602811800Z",
"history": [
{
"action": "created",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T11:50:52.602813200Z",
"reason": null
},
{
"action": "status draft -> proposed",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:24:01.234973300Z",
"reason": "rc.2: doctor worktree fix scoped."
},
{
"action": "status proposed -> approved",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:24:01.649920400Z",
"reason": "Same fix pattern as REQ-0117."
},
{
"action": "status approved -> implemented",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:24:02.123899600Z",
"reason": "src/commands/doctor.rs now calls crate::commands::hooks::resolve_hooks_dir; tests/worktree_hooks.rs gained req_0123_doctor_finds_shared_hook_from_inside_worktree."
},
{
"action": "composition evidence recorded against commit 9064a2fe1",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:24:02.679106400Z",
"reason": "End-to-end test runs req doctor inside a real worktree after hooks install --repo; asserts pre-commit hook row is not FAIL."
},
{
"action": "status promoted to verified (composition evidence on HEAD)",
"actor": "Tom",
"actor_kind": "Unknown",
"at": "2026-05-20T12:24:02.679149200Z",
"reason": null
}
],
"id": "REQ-0123",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "Confirmed during 0.4.0-rc.1 E2E testing: req hooks install now lands the hook in the shared common-dir/hooks (REQ-0117 fix), but req doctor still reads from the per-worktree gitdir which has no hooks subdir. Result is `[FAIL] pre-commit hook missing — run req hooks install` inside any worktree, even immediately after a successful install. Same root cause as REQ-0117, applied to the doctor side. Fix is to reuse the resolve_hooks_dir helper from src/commands/hooks.rs in src/commands/doctor.rs.",
"statement": "The CLI shall locate the pre-commit hook via `git rev-parse --git-common-dir`/hooks so `req doctor` correctly reports an installed hook when the cwd is inside a git worktree, matching the install path used by `req hooks install`.",
"status": "Verified",
"tags": [
"bugfix",
"hooks",
"worktree",
"doctor"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-20T12:24:02.679003700Z",
"commit": "9064a2fe1df18c71c537952af2fff2435be231f0",
"kind": "Composition",
"notes": "cites: req_0123_doctor_finds_shared_hook_from_inside_worktree — End-to-end test runs req doctor inside a real worktree after hooks install --repo; asserts pre-commit hook row is not FAIL.",
"outcome": "Pass"
}
],
"title": "Doctor must resolve hooks via git-common-dir for worktrees",
"updated": "2026-05-20T12:24:02.679138500Z"
},
"REQ-0124": {
"acceptance": [
"A `tmp/` directory listed in .gitignore is skipped by `req coverage`",
"Regression test creates an ignored file containing a REQ-marker and asserts it does NOT appear in the report",
"req lint and req review honour the same ignore rules"
],
"created": "2026-05-21T12:04:51.045518900Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:04:51.045519800Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:12:15.091681400Z",
"reason": "rc.3: ignore-crate walker scoped."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:12:16.138821100Z",
"reason": "Shared source_walk module via ignore crate (ripgrep's walker)."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:12:19.407078100Z",
"reason": "New src/source_walk.rs wraps ignore::WalkBuilder honouring .gitignore + .ignore + global git excludes. coverage::walk, coverage::walk_files, lint::scan_markers, and test_cmd::files_referencing all delegate. Hard-coded SKIP_DIRS removed (the ignore crate handles the well-known cases plus the project's actual ignore patterns)."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:12:23.661337600Z",
"reason": "End-to-end: REQ-marker in a .gitignored tmp/ directory does NOT appear as a ghost; ignored build/ directory does NOT appear in --unlinked-files."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:12:23.661346500Z",
"reason": null
}
],
"id": "REQ-0124",
"kind": "Functional",
"links": [],
"priority": "Must",
"rationale": "External 0.4.0-rc.1 E2E feedback: a real migration ran `req coverage` and saw tmp/ artefacts show up as ghost references because the scanner walked everything under the path root. Coverage data should reflect what's tracked, not whatever happens to be on disk. The SKIP_DIRS const handles a few well-known paths but a project's actual ignore patterns are richer. Fix: integrate the `ignore` crate so coverage and `req lint` and `req review` honour .gitignore by default. Structurally important because the report can quietly lie about ghosts and the user can't tell whether a finding is real.",
"statement": "The CLI shall honour .gitignore patterns when scanning source for `// REQ-NNNN:` markers, so artefacts under ignored paths (tmp/, dist/, build outputs) never appear as ghost references in `req coverage`.",
"status": "Verified",
"tags": [
"coverage",
"bugfix"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:12:23.661321400Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0124_coverage_skips_gitignored_paths, req_0124_coverage_unlinked_files_honours_gitignore — End-to-end: REQ-marker in a .gitignored tmp/ directory does NOT appear as a ghost; ignored build/ directory does NOT appear in --unlinked-files.",
"outcome": "Pass"
}
],
"title": "Coverage scan must respect .gitignore",
"updated": "2026-05-21T12:12:23.661345700Z"
},
"REQ-0125": {
"acceptance": [
"req status reports `verified-but-defective: N` when N > 0",
"req brief short-form includes a line for the same when N > 0",
"req lint flags each Verified requirement whose latest test record outcome is Fail"
],
"created": "2026-05-21T12:04:56.422274200Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:04:56.422274800Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:16:08.817155400Z",
"reason": "rc.3."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:16:09.871174800Z",
"reason": "Shared helper in status.rs; surfaced in status, brief, lint."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:16:12.508071200Z",
"reason": "status::verified_but_defective() reused across status, brief, lint. Human output in status carries a `verified-but-defective: N` line + per-ID list. Brief short-form carries a DEFECT line before loose ends. Lint includes the defects in quality_count + a dedicated section + JSON."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:16:16.919238Z",
"reason": "All three surfaces (status, brief, lint) report the same set of Verified+failing-latest IDs."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:16:16.919247100Z",
"reason": null
}
],
"id": "REQ-0125",
"kind": "Functional",
"links": [],
"priority": "Should",
"rationale": "External feedback from a real migration: 64 reqs at Verified, 5 with failing latest test records, but `req status` reports \"100% verified\" — overstates readiness. The data is already in project.req, just not summarised. A single line in brief and status closes the gap. Also add a `req lint` finding for the same condition so it shows up in the existing CI lint surface. Dovetails with the suggestion of a CI gate that fails on any failing latest record.",
"statement": "The CLI shall report a `verified-but-defective` count in `req status` and `req brief` when one or more Verified requirements carry a failing latest test record, so \"100% verified\" never overstates real readiness.",
"status": "Verified",
"tags": [
"status",
"polish"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:16:16.919221200Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0125_status_surfaces_defects, req_0125_status_human_output_carries_the_count, req_0125_brief_surfaces_defects, req_0125_lint_flags_defects_as_quality_finding — All three surfaces (status, brief, lint) report the same set of Verified+failing-latest IDs.",
"outcome": "Pass"
}
],
"title": "Surface failing test records in status and brief",
"updated": "2026-05-21T12:16:16.919246300Z"
},
"REQ-0126": {
"acceptance": [
"`req review --gate --no-defects` exits non-zero when any req's latest test record outcome is Fail",
"Exits zero when all latest records pass or no records exist",
"Documented alongside `req help integration`"
],
"created": "2026-05-21T12:05:01.154668800Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:05:01.154669400Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:12.780654700Z",
"reason": "rc.3."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:13.210829400Z",
"reason": "requires=gate, off by default so existing pipelines unchanged."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:15.863255500Z",
"reason": "ReviewArgs.no_defects (requires --gate) in cli.rs. review.rs computes defects up front via status::verified_but_defective; gate_fail expression OR-s in `args.no_defects && !defects.is_empty()`. Defects also surfaced in the markdown report and JSON output regardless of --gate so reviewers see the data."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:20.027757400Z",
"reason": "--gate --no-defects fails when a defect exists; --gate alone does not."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:20.027766800Z",
"reason": null
}
],
"id": "REQ-0126",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "External feedback: failing test records on a Verified requirement are a defect log that lives next to the spec — perfect data to gate CI on. Today the pre-commit gate catches markerless code; an analogous defect gate would catch known-broken specs. Distinct flag from the existing `--gate` so users can opt in (some projects want a defect-log workflow without a hard block).",
"statement": "The CLI shall provide a `req review --gate --no-defects` mode that exits non-zero when any requirement's latest test record is a Fail, so CI can block merges that would ship known-broken behaviour.",
"status": "Verified",
"tags": [
"gate",
"ci"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:24:20.027741Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0126_review_no_defects_gate_fails_when_defect_present, req_0126_review_without_no_defects_does_not_block_on_defects — --gate --no-defects fails when a defect exists; --gate alone does not.",
"outcome": "Pass"
}
],
"title": "Review gate fails on any failing latest test record",
"updated": "2026-05-21T12:24:20.027766200Z"
},
"REQ-0127": {
"acceptance": [
"`req coverage --by-req` prints `REQ-NNNN: file1, file2, ...` per requirement",
"JSON mode emits a flat REQ to paths map",
"Documented alongside --by-file"
],
"created": "2026-05-21T12:05:05.242180400Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:05:05.242181100Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:19:18.081174300Z",
"reason": "rc.3."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:19:19.146133300Z",
"reason": "Mirrors --by-file shape; flat REQ→[paths] JSON."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:19:21.267894800Z",
"reason": "CoverageArgs.by_req + run_by_req() in src/commands/coverage.rs. Conflicts with by_file/unlinked_files/remap. JSON output is a flat REQ→[paths] map; human output mirrors by_file's grouping."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:19:24.933672100Z",
"reason": "Three source files (REQ-0001 twice, REQ-0002 once) → REQ-0001 maps to 2 files, REQ-0002 to 1."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:19:24.933681100Z",
"reason": null
}
],
"id": "REQ-0127",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "External feedback: during an audit, the user wanted both views — per-file → reqs, AND per-req → files. Only `--by-file` exists; the user ended up grepping the JSON to get the inverse. Adding `--by-req` as a symmetric flag is a small change that closes the gap.",
"statement": "The CLI shall provide `req coverage --by-req` that emits the inverse of `--by-file`: REQ-NNNN → list of files referencing it.",
"status": "Verified",
"tags": [
"coverage",
"polish"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:19:24.933655800Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0127_coverage_by_req_groups_files_under_each_req — Three source files (REQ-0001 twice, REQ-0002 once) → REQ-0001 maps to 2 files, REQ-0002 to 1.",
"outcome": "Pass"
}
],
"title": "Coverage --by-req inverse view",
"updated": "2026-05-21T12:19:24.933680400Z"
},
"REQ-0128": {
"acceptance": [
"`req test run --map mapping.json` reads a JSON file mapping test identifiers to REQ-IDs",
"Mapping file schema is published via req schema test-map",
"Existing req_NNNN_ name convention continues to work when --map is absent"
],
"created": "2026-05-21T12:05:10.065839900Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:05:10.065840500Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:26:37.642882400Z",
"reason": "rc.3."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:26:38.682329500Z",
"reason": "Forgiving verdict matcher (mocha/pytest/jest) + explicit map."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:26:41.321621600Z",
"reason": "TestRunArgs.map_file in cli.rs. run_suite() in test_cmd.rs walks the JSON map and pattern-matches verdict tokens (ok/PASS/pass, FAILED/FAIL, ignored/SKIP/skip) on lines containing the test name. Existing req_NNNN_ convention still works when --map is absent or in combination. Schema published via req schema test-map (SchemaWhich::TestMap)."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:26:46.079665800Z",
"reason": "Mocha-style log + map.json produces records on REQ-0001; schema test-map is published with the right pattern."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:26:46.079674900Z",
"reason": null
}
],
"id": "REQ-0128",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "External feedback: the Rust convention works well but Node and Python projects do not have an equivalent name. The user rebuilt this externally as a scripts/req-run-tests.js taking a map file. Bringing it into the tool keeps spec-to-test traceability as a first-class concept across ecosystems instead of a per-project script.",
"statement": "The CLI shall accept a `--map <file>` argument on `req test run` that provides an explicit mapping from test identifier to REQ-NNNN, so ecosystems without the `req_NNNN_*` naming convention (Node/Mocha, Python/pytest) can attach test records per requirement.",
"status": "Verified",
"tags": [
"ecosystem",
"testing"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:26:46.079649Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0128_map_file_attaches_records_by_test_name, req_0128_schema_test_map_published — Mocha-style log + map.json produces records on REQ-0001; schema test-map is published with the right pattern.",
"outcome": "Pass"
}
],
"title": "Generic test-name mapping for req test run",
"updated": "2026-05-21T12:26:46.079674100Z"
},
"REQ-0129": {
"acceptance": [
"`req test list REQ-0001` prints commit, outcome, kind, at, notes per record",
"--json emits the records as an array",
"Empty record set prints a clear `(no test records)` line"
],
"created": "2026-05-21T12:05:13.140994Z",
"history": [
{
"action": "created via MCP",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:05:13.140994700Z",
"reason": null
},
{
"action": "status→proposed",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:05.845926800Z",
"reason": "rc.3."
},
{
"action": "status→approved",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:06.922543100Z",
"reason": "Small subcommand; fits next to test record + test run."
},
{
"action": "status→implemented",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:09.023680500Z",
"reason": "TestCmd::List(TestListArgs) in cli.rs; test_cmd::list() in test_cmd.rs. Human output: `<timestamp> <commit> <outcome> <kind> <notes>` per record. --json emits the records array. Empty set prints `(no test records)`."
},
{
"action": "composition evidence recorded via MCP against commit 431b58d30",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:12.724417200Z",
"reason": "JSON form returns the records array; empty set prints the hint line."
},
{
"action": "status promoted to verified (composition evidence)",
"actor": "Tom",
"actor_kind": "Agent",
"at": "2026-05-21T12:24:12.724427700Z",
"reason": null
}
],
"id": "REQ-0129",
"kind": "Functional",
"links": [],
"priority": "Could",
"rationale": "External feedback: the user wanted a quick view of just the test records on one req and ended up parsing JSON. A dedicated subcommand keeps the data discoverable. Small, fits naturally next to `req test record` and `req test run`.",
"statement": "The CLI shall provide `req test list <id>` that prints the test record history for one requirement in a focused format, so callers do not have to parse `req show --json` to inspect attached records.",
"status": "Verified",
"tags": [
"testing",
"polish"
],
"tests": [
{
"actor": "Tom",
"at": "2026-05-21T12:24:12.724395700Z",
"commit": "431b58d30c78870c3ad2e4bab574b142459132bb",
"kind": "Composition",
"notes": "cites: req_0129_test_list_prints_records, req_0129_test_list_empty_records_clear_message — JSON form returns the records array; empty set prints the hint line.",
"outcome": "Pass"
}
],
"title": "req test list inspection command",
"updated": "2026-05-21T12:24:12.724426800Z"
}
},
"updated": "2026-05-21T12:26:46.079681700Z"
}