rcf-lite 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +86 -54
  2. package/README.md +8 -4
  3. package/bin/rcf.js +145 -57
  4. package/fixtures/canary-manifest.json +9 -9
  5. package/guidance/README.md +1 -1
  6. package/guidance/build-cycle-playbook.md +51 -51
  7. package/guidance/build-cycle.md +7 -7
  8. package/guidance/document-model.md +1 -1
  9. package/guidance/elicitation-playbook.md +29 -29
  10. package/guidance/harness-template.md +10 -10
  11. package/guidance/managed/README.md +1 -1
  12. package/guidance/managed/agent-instructions-block.hash +1 -1
  13. package/guidance/managed/agent-instructions-block.md +9 -9
  14. package/guidance/manifest.json +1 -1
  15. package/guidance/overview.md +4 -4
  16. package/package.json +4 -6
  17. package/rcf/adrs/adr-008.json +1 -1
  18. package/rcf/adrs/adr-009.json +4 -4
  19. package/rcf/code-nodes/cn-016.json +1 -1
  20. package/rcf/code-nodes/cn-019.json +1 -1
  21. package/rcf/code-nodes/cn-020.json +1 -1
  22. package/rcf/code-nodes/cn-021.json +1 -1
  23. package/rcf/code-nodes/cn-022.json +1 -1
  24. package/rcf/code-nodes/cn-049.json +1 -1
  25. package/rcf/code-nodes/cn-055.json +1 -1
  26. package/rcf/code-nodes/cn-057.json +5 -5
  27. package/rcf/code-nodes/cn-061.json +1 -1
  28. package/rcf/code-nodes/cn-066.json +1 -1
  29. package/rcf/code-nodes/cn-069.json +1 -1
  30. package/rcf/fbs/fbs-005.json +1 -1
  31. package/rcf/fbs/fbs-006.json +2 -2
  32. package/rcf/fbs/fbs-007.json +1 -1
  33. package/rcf/fbs/fbs-014.json +1 -1
  34. package/rcf/fbs/fbs-015.json +9 -8
  35. package/rcf/fbs/fbs-016.json +1 -1
  36. package/rcf/fbs/fbs-017.json +1 -1
  37. package/rcf/fbs/fbs-018.json +2 -2
  38. package/rcf/requirements/req-008.json +1 -1
  39. package/rcf/requirements/req-009.json +2 -2
  40. package/rcf/requirements/req-010.json +1 -1
  41. package/rcf/test-suites/PENDING.md +2 -2
  42. package/rcf/test-suites/ts-004.json +1 -1
  43. package/rcf/test-suites/ts-006.json +3 -3
  44. package/rcf/test-suites/ts-008.json +2 -2
  45. package/rcf/test-suites/ts-009.json +2 -2
  46. package/rcf/test-suites/ts-017.json +1 -1
  47. package/rcf/test-suites/ts-024.json +1 -1
  48. package/rcf/test-suites/ts-025.json +32 -18
  49. package/rcf/test-suites/ts-026.json +1 -1
  50. package/rcf/test-suites/ts-027.json +7 -7
  51. package/rcf/test-suites/ts-028.json +1 -1
  52. package/rcf/user-stories/us-1001.json +10 -10
  53. package/rcf/user-stories/us-1002.json +12 -12
  54. package/rcf/user-stories/us-1003.json +6 -6
  55. package/rcf/user-stories/us-805.json +2 -2
  56. package/rcf/user-stories/us-901.json +13 -13
  57. package/src/blueprint/conflicts.js +15 -15
  58. package/src/blueprint/supersede.js +6 -6
  59. package/src/build/bundle.js +3 -3
  60. package/src/build/formatters/markdown.js +9 -9
  61. package/src/build/mark.js +3 -3
  62. package/src/build/queue.js +1 -1
  63. package/src/cli/blueprint.js +3 -3
  64. package/src/cli/browser-verify.js +1 -1
  65. package/src/cli/build.js +139 -69
  66. package/src/cli/coverage.js +1 -1
  67. package/src/cli/create.js +3 -3
  68. package/src/cli/delete.js +2 -2
  69. package/src/cli/design.js +10 -10
  70. package/src/cli/fbs.js +1 -1
  71. package/src/cli/finalise.js +22 -20
  72. package/src/cli/help.js +267 -95
  73. package/src/cli/impact.js +1 -1
  74. package/src/cli/intake.js +3 -3
  75. package/src/cli/link.js +3 -3
  76. package/src/cli/preflight.js +2 -2
  77. package/src/cli/read.js +1 -1
  78. package/src/cli/req-baseline.js +2 -2
  79. package/src/cli/req-classify.js +3 -3
  80. package/src/cli/review.js +1 -1
  81. package/src/cli/standards.js +1 -1
  82. package/src/cli/test-suite.js +1 -1
  83. package/src/cli/trace.js +1 -1
  84. package/src/cli/ui-baseline.js +3 -3
  85. package/src/cli/ui-classify.js +4 -4
  86. package/src/cli/update.js +2 -2
  87. package/src/cli/validate.js +2 -2
  88. package/src/cli/view.js +12 -10
  89. package/src/core/store/writer.js +1 -1
  90. package/src/design/writer.js +3 -3
  91. package/src/finalise/detect.js +32 -38
  92. package/src/finalise/index.js +0 -1
  93. package/src/finalise/install.js +9 -8
  94. package/src/finalise/spawn.js +14 -10
  95. package/src/mcp/tools.js +1 -1
  96. package/src/req-baseline/gate.js +1 -1
  97. package/src/ui-baseline/manifest-writer.js +2 -2
  98. package/src/verify/cli/cleanup.js +1 -1
  99. package/src/verify/cli/mcp.js +1 -1
  100. package/src/verify/cli/provision.js +1 -1
  101. package/src/verify/cli/report.js +1 -1
  102. package/src/verify/cli/run.js +1 -1
  103. package/src/view-supervisor/manifest-writer.js +2 -2
  104. package/bin/rcf-verify.js +0 -122
  105. package/src/verify/cli/help.js +0 -56
@@ -22,7 +22,7 @@
22
22
  "estimatedSize": "medium",
23
23
  "estimatedHours": 6,
24
24
  "deliverables": [
25
- "rcf delete verb with reference-safe default",
25
+ "rcf define delete verb with reference-safe default",
26
26
  "Cascade flag with parent-reference cleanup"
27
27
  ],
28
28
  "riskLevel": "medium",
@@ -2,7 +2,7 @@
2
2
  "createdAt": "2026-07-20T17:05:46.941Z",
3
3
  "updatedAt": "2026-07-20T17:05:46.941Z",
4
4
  "summary": "Harden the build-cycle guidance so every build lands a documented local preview as its default outcome, every verification claim names the runtime it was checked against, and the method carries interim fresh-context self-review guidance. Edits the build-cycle playbook, the build-cycle contract and the harness fragment; no runtime subsystem.",
5
- "approach": "In the build-cycle guidance, make a working, documented local preview loop (dev server, seeded data where needed, ideally one command) a required, hosting-independent part of a build's definition of done. Require every 'verified'/'tested' claim - in the Test and Finalise stages and in the PR body's verification section - to name the runtime it was checked against, forbid any claim implying deploy-runtime verification that did not happen, and add an explicit labelled-claim example. Add an interim self-review section describing a periodic and end-of-build fresh-context reviewer dispatch that drives the app against its ACs, targeting session-class bugs, false-promise UI, runtime mismatch, dead auth paths and dead code, scoped honestly as a stopgap until rcf-verify-lite and explicitly not the independent gate. Add matching harness-fragment rules and extend the guidance drift tests.",
5
+ "approach": "In the build-cycle guidance, make a working, documented local preview loop (dev server, seeded data where needed, ideally one command) a required, hosting-independent part of a build's definition of done. Require every 'verified'/'tested' claim - in the Test and Finalise stages and in the PR body's verification section - to name the runtime it was checked against, forbid any claim implying deploy-runtime verification that did not happen, and add an explicit labelled-claim example. Add an interim self-review section describing a periodic and end-of-build fresh-context reviewer dispatch that drives the app against its ACs, targeting session-class bugs, false-promise UI, runtime mismatch, dead auth paths and dead code, scoped honestly as a stopgap until rcf verify-lite and explicitly not the independent gate. Add matching harness-fragment rules and extend the guidance drift tests.",
6
6
  "deliverables": [
7
7
  "Build-cycle guidance: local preview loop as default, hosting-independent definition-of-done item",
8
8
  "Build-cycle and PR-authoring guidance: runtime-provenance labelling with a worked example",
@@ -4,19 +4,20 @@
4
4
  "bsId": "BS-001",
5
5
  "buildOrder": 15,
6
6
  "executionStatus": "complete",
7
- "title": "`rcf verify` subcommand routing (0.7.1 consolidation)",
8
- "summary": "Route the adversarial ship-gate verifier under the unified `rcf` CLI as `rcf verify <run|report|provision|cleanup|mcp>`. The pre-existing `rcf-verify` bin becomes a transition-grace alias that dispatches through the same handlers and emits a one-line stderr deprecation notice when invoked directly.",
9
- "approach": "One dispatcher, two entry points. bin/rcf.js imports the `main` export from bin/rcf-verify.js and registers it as the `verify` entry on the top-level SUBCOMMANDS map, so `rcf verify --help` and `rcf-verify --help` share the same code path by construction. The alias bin gains a deprecation notice guarded by RCF_QUIET for scripted callers. The unified CLI's help output lists `verify <verb>` alongside the other top-level commands, sourced from the same verify TOP_LEVEL_HELP the alias bin uses (single-source rule).",
7
+ "title": "`rcf verify` group routing (0.10.0 CLI reorganisation)",
8
+ "summary": "Route the adversarial ship-gate verifier under the unified `rcf` CLI as `rcf verify <run|report|provision|cleanup|mcp|browser>`. The legacy standalone `rcf-verify` bin (0.7.1 transition-grace alias) is deleted outright; consumers move to `rcf verify <verb>` in one hop.",
9
+ "approach": "bin/rcf.js declares a `verify` entry in the top-level GROUPS map whose sub-verbs (run, report, provision, cleanup, mcp, browser) resolve to the corresponding main() exports from src/verify/cli/*.js and src/cli/browser-verify.js. The unified CLI's help output lists the verify group with its sub-verbs, sourced from the per-verb HELP exports via HELP_MAP.verify (single-source rule). The dispatcher additionally recognises pre-0.10.0 flat verb tokens through OLD_FLAT_MAP: on match it writes a one-line stderr hint naming the new grouped form before exiting 2. This is a usage-error affordance, not a fallback; the invocation fails.",
10
10
  "deliverables": [
11
- "bin/rcf.js: `verify` on the top-level SUBCOMMANDS map, dispatching to the alias bin's exported main",
12
- "bin/rcf-verify.js: one-line stderr deprecation notice on direct invocation, suppressible via RCF_QUIET",
13
- "src/cli/help.js: `verify <verb>` listed in the top-level command table; `help verify` prints the alias bin's TOP_LEVEL_HELP block"
11
+ "bin/rcf.js: `verify` on the top-level GROUPS map, dispatching per sub-verb to the verify-suite handlers plus browser-verify",
12
+ "bin/rcf.js: OLD_FLAT_MAP recognises pre-0.10.0 flat verbs and emits a stderr hint at the new grouped form before exit 2",
13
+ "package.json: `bin` field carries only `rcf`; the historical `rcf-verify` entry and bin/rcf-verify.js file are deleted",
14
+ "src/cli/help.js: verify group header + sub-verb catalogue in TOP_LEVEL_HELP; `rcf help verify` prints the group help; `rcf help verify <verb>` prints per-verb help via HELP_MAP"
14
15
  ],
15
16
  "estimatedSize": "small",
16
17
  "estimatedHours": 1,
17
18
  "riskLevel": "low",
18
19
  "domain": "cli",
19
- "notes": "Ratified in the 2026-08-06 packaging-consolidation proposal (R3). Pure repackage relative to 0.7.0 verify behaviour; the invocation form gains a canonical route, existing scripts keep working via the alias.",
20
+ "notes": "Ratified in the 2026-08-26 CLI group-design ruling (clean break: no aliases, no shims, no back-compat fallbacks). Supersedes the 0.7.1 alias-bin transition-grace posture; the alias bin is deleted.",
20
21
  "contextRequirements": {
21
22
  "tacIds": [],
22
23
  "adrIds": []
@@ -28,5 +29,5 @@
28
29
  ],
29
30
  "dependsOnFbsIds": [],
30
31
  "createdAt": "2026-08-11T00:00:00Z",
31
- "updatedAt": "2026-08-11T00:00:00Z"
32
+ "updatedAt": "2026-08-26T00:00:00Z"
32
33
  }
@@ -5,7 +5,7 @@
5
5
  "buildOrder": 16,
6
6
  "executionStatus": "notStarted",
7
7
  "title": "Blueprint verb family (add, list, remove, upgrade) with manifest.blueprints[] writes",
8
- "summary": "Introduce the `rcf blueprint <verb>` verb family and its manifest-writing path. Adds `src/blueprint/` module (loader, applier, contribution-writer) and `src/cli/blueprint.js` (parseArgs, dispatch, HELP block). Adds `blueprint` to the top-level SUBCOMMANDS map on `bin/rcf.js` and to the `TOP_LEVEL` block on `src/cli/help.js` so `rcf --help` advertises it. Every apply writes an entry to `manifest.blueprints[]` per the 0.4.4 schema (slug, version, appliedAt, source, namespace, contributions[]). `add` is idempotent on a clean re-apply; `remove` refuses when any project-authored doc references a contribution id.",
8
+ "summary": "Introduce the `rcf define blueprint <verb>` verb family and its manifest-writing path. Adds `src/blueprint/` module (loader, applier, contribution-writer) and `src/cli/blueprint.js` (parseArgs, dispatch, HELP block). Adds `blueprint` to the top-level SUBCOMMANDS map on `bin/rcf.js` and to the `TOP_LEVEL` block on `src/cli/help.js` so `rcf --help` advertises it. Every apply writes an entry to `manifest.blueprints[]` per the 0.4.4 schema (slug, version, appliedAt, source, namespace, contributions[]). `add` is idempotent on a clean re-apply; `remove` refuses when any project-authored doc references a contribution id.",
9
9
  "approach": "One dispatcher, one loader, one applier, one writer. bin/rcf.js gains `blueprint: blueprintMain` on SUBCOMMANDS; src/cli/blueprint.js parses `add|list|remove|upgrade` and dispatches to src/blueprint/ handlers. Blueprint loading is a small package-metadata reader (slug, version, ADR contributions with optional scope, doc contributions manifest); Phase 1 keeps the resolver `file://` and `link:` only, with the registry/git-ref shape captured in the source string so the schema forward-compat holds. Contribution writing goes through the existing store writer paths so a blueprint apply produces the same doc files a hand-created doc would. Removal is a manifest patch + contribution-path unlink; the referring-doc check reuses the existing tree walker to enumerate every string field for id occurrences.",
10
10
  "deliverables": [
11
11
  "src/cli/blueprint.js: parseArgs + HELP + main() dispatching add/list/remove/upgrade",
@@ -5,7 +5,7 @@
5
5
  "buildOrder": 17,
6
6
  "executionStatus": "notStarted",
7
7
  "title": "Namespaced blueprint ids and scope:global ADR conflict surfacing",
8
- "summary": "Blueprint-contributed docs are namespaced by the blueprint's slug: REQ/US/PRD/BS/TAD/TS via the 0.4.4 slug PREFIX (e.g. `spa-REQ-001`), and ADR/TAC/FBS/CN via the 0.4.3 kebab SUFFIX (e.g. `ADR-005-rest-versioning`). `rcf blueprint add` runs a conflict-detection pass BEFORE writing anything: two blueprints both contributing an ADR tagged `scope: global` on the same topic exit non-zero with both sides printed and four honest resolution paths named (adopt-incoming, keep-existing, supersede via project ADR, declare-on-add via `--resolve`). Non-global TACs, ADRs, REQs, USs and FBSes namespace cleanly and cannot topic-conflict; cross-blueprint id claims (an incoming id already recorded on another applied blueprint) are refused via the authoritative manifest record, not string grammar.",
8
+ "summary": "Blueprint-contributed docs are namespaced by the blueprint's slug: REQ/US/PRD/BS/TAD/TS via the 0.4.4 slug PREFIX (e.g. `spa-REQ-001`), and ADR/TAC/FBS/CN via the 0.4.3 kebab SUFFIX (e.g. `ADR-005-rest-versioning`). `rcf define blueprint add` runs a conflict-detection pass BEFORE writing anything: two blueprints both contributing an ADR tagged `scope: global` on the same topic exit non-zero with both sides printed and four honest resolution paths named (adopt-incoming, keep-existing, supersede via project ADR, declare-on-add via `--resolve`). Non-global TACs, ADRs, REQs, USs and FBSes namespace cleanly and cannot topic-conflict; cross-blueprint id claims (an incoming id already recorded on another applied blueprint) are refused via the authoritative manifest record, not string grammar.",
9
9
  "approach": "Namespacing is enforced at the loader: contribution ids are stamped with the blueprint slug at load time; a contribution whose declared id already carries a namespace is trusted verbatim (author declaration is the truth for what that blueprint owns; the earlier grammar-veto of legitimate slug-tail ids like `ADR-201-spa-theme` under blueprint `spa` was retired in w-2026-08-19-005). Ownership of a written contribution is answered by the manifest's `appliedBlueprintRecord.contributions[]` list — the authoritative record — not by re-parsing the id string. Conflict detection reads the applied `blueprints[]` and the applying blueprint's contributions, and scores collisions along two axes: `scope: global` ADR topic collision (two applied ADRs both tagged `scope: global` with a matching `topic` field), and cross-blueprint ownership (an incoming id whose manifest record is on a DIFFERENT applied blueprint's contribution list — the class the record consultation catches once grammar stopped being a trust surface). Presentation: per-conflict block leads with both ADR titles and their one-sentence decisions, ids and paths as a footer, and four honest resolution paths with actual blueprint slugs filled in — no placeholders. A `--json` output shape is available for agent-driven composition. Phase 3.5 (w-2026-08-19-008) added the `supersede` and `diff` verbs plus the `--resolve` add-time flag, backed by `manifest.resolutions[]` on the 0.4.5 schema; both blueprint ADRs may now co-reside on disk as superseded history alongside a project-level ADR that supersedes them.",
10
10
  "deliverables": [
11
11
  "src/blueprint/namespace.js: pure functions that stamp/verify contribution namespacing for all doc kinds",
@@ -4,8 +4,8 @@
4
4
  "bsId": "BS-001",
5
5
  "buildOrder": 18,
6
6
  "executionStatus": "notStarted",
7
- "title": "Standards ingestion: rcf standards add + reference-by-default",
8
- "summary": "Introduce a `rcf standards <verb>` verb family (`add`, `list`) that registers standards packs on the project manifest. Reference-by-default when the source lives inside the project root; copy into `rcf/standards/<slug>/` only when the source lives outside. Manifest registration is authoritative; every add writes a `manifest.standards[]` entry per the 0.4.4 `standardsPackRecord` schema.",
7
+ "title": "Standards ingestion: rcf define standards add + reference-by-default",
8
+ "summary": "Introduce a `rcf define standards <verb>` verb family (`add`, `list`) that registers standards packs on the project manifest. Reference-by-default when the source lives inside the project root; copy into `rcf/standards/<slug>/` only when the source lives outside. Manifest registration is authoritative; every add writes a `manifest.standards[]` entry per the 0.4.4 `standardsPackRecord` schema.",
9
9
  "approach": "One dispatcher, one applier. src/cli/standards.js parses `add|list`; src/blueprint/standards.js resolves whether the source is inside or outside the project root (via node:path.relative + startsWith), copies when needed, and writes the manifest entry. Copy path is fs.cp recursive with a per-run overwrite guard (idempotent re-adds refuse to re-copy unless `--refresh` is passed; Phase 1 keeps to add-only + idempotent read, `refresh` verb deferred to Phase 3).",
10
10
  "deliverables": [
11
11
  "src/cli/standards.js: parseArgs + HELP + main() for add/list",
@@ -4,7 +4,7 @@
4
4
  "category": "functional",
5
5
  "priority": "must",
6
6
  "description": "The agent guidance pack teaches a build method that keeps the deployment runtime present in the loop from elicitation to verification, so that a non-coding owner who cannot self-verify is not led into an undeployable stack or a false 'verified' claim. It requires four properties of the method the tool ships: (1) every build lands a working, documented local preview loop as its default outcome; (2) elicitation establishes where the app will run early and constrains the stack to that answer, with a jargon-free hosting-choice walkthrough when the owner does not know; (3) every 'verified' or 'tested' claim names the runtime it was checked against and never implies deploy-runtime verification that did not happen; (4) the method carries guidance for a periodic and end-of-build fresh-context self-review that drives the app against its acceptance criteria, subordinate to the independent verification gate rather than a substitute for it. This requirement governs the shipped guidance/prompt surface, not a new runtime subsystem.",
7
- "rationale": "The five-run rcf-persona-testing programme (concluded 2026-07-20) found the tool builds excellently at every level but its own loop missed a ship-blocking or user-facing defect in three of five runs, with a single root cause: the deploy runtime is absent from the loop. It is absent from elicitation (runs 03/04 chose Cloudflare-incompatible stacks a CF-only holder cannot host, run 03 silently) and absent from verification (run 05 shipped a production auth 500 while 89/89 tests were green and the tool claimed a live-Worker verification its E2E never ran). The target user cannot diagnose 'wrong stack for your host' or 'verified against the wrong runtime', so the method itself must foreclose both. These are Tier-1 hardening fixes to make the base offering usable now, while the productised independent verification gate (rcf-verify-lite) is built separately.",
7
+ "rationale": "The five-run rcf-persona-testing programme (concluded 2026-07-20) found the tool builds excellently at every level but its own loop missed a ship-blocking or user-facing defect in three of five runs, with a single root cause: the deploy runtime is absent from the loop. It is absent from elicitation (runs 03/04 chose Cloudflare-incompatible stacks a CF-only holder cannot host, run 03 silently) and absent from verification (run 05 shipped a production auth 500 while 89/89 tests were green and the tool claimed a live-Worker verification its E2E never ran). The target user cannot diagnose 'wrong stack for your host' or 'verified against the wrong runtime', so the method itself must foreclose both. These are Tier-1 hardening fixes to make the base offering usable now, while the productised independent verification gate (rcf verify-lite) is built separately.",
8
8
  "reqId": "REQ-008",
9
9
  "prdId": "PRD-001",
10
10
  "title": "Deploy-aware, runtime-honest build guidance",
@@ -2,11 +2,11 @@
2
2
  "reqId": "REQ-009",
3
3
  "prdId": "PRD-001",
4
4
  "title": "Umbrella CLI: verify as a first-class subcommand",
5
- "description": "Post 0.7.1 packaging consolidation the RCF Lite suite ships as one npm package with one unified `rcf` CLI. The adversarial ship-gate verifier that used to live behind its own `rcf-verify` bin is mounted as `rcf verify <run|report|provision|cleanup|mcp>` on that unified CLI. The pre-existing `rcf-verify` bin remains as a transition-grace alias that dispatches through the same handlers, deprecated in favour of `rcf verify`. Behaviour of each verify verb is unchanged; only the invocation form gains a canonical route.",
5
+ "description": "Post 0.7.1 packaging consolidation the RCF Lite suite ships as one npm package with one unified `rcf` CLI. The adversarial ship-gate verifier that used to live behind its own `rcf verify` bin is mounted as `rcf verify <run|report|provision|cleanup|mcp>` on that unified CLI. The pre-existing `rcf verify` bin remains as a transition-grace alias that dispatches through the same handlers, deprecated in favour of `rcf verify`. Behaviour of each verify verb is unchanged; only the invocation form gains a canonical route.",
6
6
  "category": "functional",
7
7
  "domain": "cli",
8
8
  "priority": "must",
9
- "rationale": "The packaging consolidation ruling (docs/2026-08-06_packaging-consolidation-proposal.md, ratified 2026-08-11) picks one install (`rcf-lite`) with one CLI verb space (`rcf`). Verify is a first-class part of the RCF chain (define, build, verify) and must sit inside that verb space, not beside it. Keeping `rcf-verify` as an alias avoids a hard break for existing scripts across a transition window.",
9
+ "rationale": "The packaging consolidation ruling (docs/2026-08-06_packaging-consolidation-proposal.md, ratified 2026-08-11) picks one install (`rcf-lite`) with one CLI verb space (`rcf`). Verify is a first-class part of the RCF chain (define, build, verify) and must sit inside that verb space, not beside it. Keeping `rcf verify` as an alias avoids a hard break for existing scripts across a transition window.",
10
10
  "tags": [
11
11
  "packaging",
12
12
  "cli",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "createdAt": "2026-08-18T22:54:27.031Z",
3
3
  "updatedAt": "2026-08-18T22:57:45.660Z",
4
- "description": "The framework provides a Blueprint mechanism the operator uses to compose blueprint packages (specifications + assets, not code) onto a project tree at any point in its life. Composition is many blueprints per project. Blueprint-contributed docs are namespaced by the blueprint's slug so multiple blueprints cannot collide on ids. Standards packs register at rcf init (or later via rcf standards add), reference-by-default, copied to rcf/standards/<slug>/ only when the source lives outside the project root. Manifest registration is authoritative. Selective retrieval populates fbs.contextRequirements.standardIds at bundle-assembly time by analysing the FBS work text against the standards tag vocabulary; operator override is supported by authoring the array on the FBS. scope:global ADR contributions surface as blocking conflicts at rcf blueprint add time.",
4
+ "description": "The framework provides a Blueprint mechanism the operator uses to compose blueprint packages (specifications + assets, not code) onto a project tree at any point in its life. Composition is many blueprints per project. Blueprint-contributed docs are namespaced by the blueprint's slug so multiple blueprints cannot collide on ids. Standards packs register at rcf init (or later via rcf define standards add), reference-by-default, copied to rcf/standards/<slug>/ only when the source lives outside the project root. Manifest registration is authoritative. Selective retrieval populates fbs.contextRequirements.standardIds at bundle-assembly time by analysing the FBS work text against the standards tag vocabulary; operator override is supported by authoring the array on the FBS. scope:global ADR contributions surface as blocking conflicts at rcf define blueprint add time.",
5
5
  "reqId": "REQ-010",
6
6
  "prdId": "PRD-001",
7
7
  "title": "Blueprint library mechanism (composition, standards, selective retrieval)",
@@ -15,8 +15,8 @@ a genuine feature gap - was closed by porting the parallel-safe tier
15
15
  computation from the full RCF platform into the build queue and binding
16
16
  TC-014-independent-items-share-tier to it.
17
17
 
18
- Status: **76 bound / 0 pending** of 76 ACs. `rcf coverage --strict`
19
- exits 0, and CI runs `rcf validate` and `rcf coverage --strict` as
18
+ Status: **76 bound / 0 pending** of 76 ACs. `rcf audit coverage --strict`
19
+ exits 0, and CI runs `rcf define validate` and `rcf audit coverage --strict` as
20
20
  required steps, so a new uncovered AC or a non-resolving testPointer
21
21
  fails the build. A future genuine gap gets a row here (AC id, US, kind,
22
22
  what a sufficient test must assert, nearest existing test) until its
@@ -37,7 +37,7 @@
37
37
  "acId": "AC-202-1",
38
38
  "description": "the view serves from a local server process and never writes files to disk",
39
39
  "status": "pending",
40
- "testPointer": "test/view/cli.test.js::rcf view never writes any files to disk (regression against static mode)"
40
+ "testPointer": "test/view/cli.test.js::rcf audit view never writes any files to disk (regression against static mode)"
41
41
  }
42
42
  ],
43
43
  "status": "draft"
@@ -15,21 +15,21 @@
15
15
  "acId": "AC-301-2",
16
16
  "description": "reading an unknown id exits 2 with a structured not-found usage error",
17
17
  "status": "pending",
18
- "testPointer": "test/cli/read.test.js::rcf read UNKNOWN-999 exits 2 (usage, unknown id)"
18
+ "testPointer": "test/cli/read.test.js::rcf define read UNKNOWN-999 exits 2 (usage, unknown id)"
19
19
  },
20
20
  {
21
21
  "id": "TC-006-read-reports-valid",
22
22
  "acId": "AC-301-1",
23
23
  "description": "read returns the body on stdout and reports the document valid against its schema on stderr",
24
24
  "status": "pending",
25
- "testPointer": "test/cli/read.test.js::rcf read REQ-001 returns the body and reports it valid against its schema (AC-301-1)"
25
+ "testPointer": "test/cli/read.test.js::rcf define read REQ-001 returns the body and reports it valid against its schema (AC-301-1)"
26
26
  },
27
27
  {
28
28
  "id": "TC-006-read-invalid-content-plus-errors",
29
29
  "acId": "AC-301-3",
30
30
  "description": "read on an invalid-but-present document returns the content together with the validation errors",
31
31
  "status": "pending",
32
- "testPointer": "test/cli/read.test.js::rcf read on an invalid-but-present document returns the content together with the validation errors (AC-301-3)"
32
+ "testPointer": "test/cli/read.test.js::rcf define read on an invalid-but-present document returns the content together with the validation errors (AC-301-3)"
33
33
  }
34
34
  ],
35
35
  "status": "draft"
@@ -16,7 +16,7 @@
16
16
  "acId": "AC-303-1",
17
17
  "description": "a valid update persists the change and advances updatedAt on disk",
18
18
  "status": "pending",
19
- "testPointer": "test/cli/update.test.js::rcf update REQ-001 --set title=X changes the title and bumps updatedAt"
19
+ "testPointer": "test/cli/update.test.js::rcf define update REQ-001 --set title=X changes the title and bumps updatedAt"
20
20
  },
21
21
  {
22
22
  "id": "TC-008-invalid-update-refused",
@@ -30,7 +30,7 @@
30
30
  "acId": "AC-303-3",
31
31
  "description": "update on a nonexistent id returns a structured not-found error naming the id and writes nothing",
32
32
  "status": "pending",
33
- "testPointer": "test/cli/update.test.js::rcf update REQ-999 returns a structured not-found error and writes nothing (AC-303-3)"
33
+ "testPointer": "test/cli/update.test.js::rcf define update REQ-999 returns a structured not-found error and writes nothing (AC-303-3)"
34
34
  }
35
35
  ],
36
36
  "status": "draft"
@@ -17,7 +17,7 @@
17
17
  "acId": "AC-304-1",
18
18
  "description": "delete without cascade refuses with exit 4 naming dependents",
19
19
  "status": "pending",
20
- "testPointer": "test/cli/delete.test.js::rcf delete REQ-001 without --cascade refuses with exit 4"
20
+ "testPointer": "test/cli/delete.test.js::rcf define delete REQ-001 without --cascade refuses with exit 4"
21
21
  },
22
22
  {
23
23
  "id": "TC-009-cascade-removes-subtree",
@@ -31,7 +31,7 @@
31
31
  "acId": "AC-304-3",
32
32
  "description": "deleting an unreferenced leaf removes the file with exit 0 on a still-valid tree",
33
33
  "status": "pending",
34
- "testPointer": "test/cli/delete.test.js::rcf delete leaf ADR-001 removes the file (exit 0)"
34
+ "testPointer": "test/cli/delete.test.js::rcf define delete leaf ADR-001 removes the file (exit 0)"
35
35
  }
36
36
  ],
37
37
  "status": "draft"
@@ -24,7 +24,7 @@
24
24
  "acId": "AC-602-2",
25
25
  "description": "rcf_build returns the assembled bundle deep-equal to the CLI output for the named FBS",
26
26
  "status": "pending",
27
- "testPointer": "test/mcp/parity.test.js::parity: rcf_build FBS-001 structuredContent deep-equals live `rcf build FBS-001 --format json`"
27
+ "testPointer": "test/mcp/parity.test.js::parity: rcf_build FBS-001 structuredContent deep-equals live `rcf build bundle FBS-001 --format json`"
28
28
  },
29
29
  {
30
30
  "id": "TC-017-mcp-invalid-write-refused",
@@ -37,7 +37,7 @@
37
37
  {
38
38
  "id": "TC-024-in-loop-not-the-gate",
39
39
  "acId": "AC-805-4",
40
- "description": "the self-review is scoped as an in-loop check naming rcf finalise as the gate",
40
+ "description": "the self-review is scoped as an in-loop check naming rcf build finalise as the gate",
41
41
  "status": "pending",
42
42
  "testPointer": "test/guidance/tier1-hardening.test.js::AC-805-4: the self-review is honestly scoped as an in-loop check subordinate to the independent gate"
43
43
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "id": "TS-025",
3
3
  "usId": "US-901",
4
- "title": "`rcf verify` subcommand routing (0.7.1 consolidation)",
5
- "purpose": "Verify the umbrella CLI mounts `rcf verify` as a first-class subcommand that dispatches to the same handlers the transition-grace `rcf-verify` alias bin exposes, that the top-level help advertises it, and that the alias bin emits a one-line stderr deprecation notice (suppressible via RCF_QUIET) when run directly.",
4
+ "title": "`rcf verify` group routing (0.10.0 CLI reorganisation)",
5
+ "purpose": "Verify the umbrella CLI mounts the `verify` group with the six sub-verbs (run, report, provision, cleanup, mcp, browser), that the top-level help advertises the group with its catalogue, and that the legacy standalone `rcf-verify` bin is deleted at 0.10.0 (with old flat verb tokens on the umbrella `rcf` bin refused with a stderr hint at the new grouped form).",
6
6
  "testLevel": "unit",
7
7
  "acIds": [
8
8
  "AC-901-1",
@@ -11,42 +11,56 @@
11
11
  ],
12
12
  "testCases": [
13
13
  {
14
- "id": "TC-025-verify-routes-to-alias-dispatcher",
14
+ "id": "TC-025-verify-group-routes-per-subverb",
15
15
  "acId": "AC-901-1",
16
- "description": "the `verify` entry on the top-level SUBCOMMANDS map is the same `main` function the alias bin exports",
16
+ "description": "`verify` on the top-level GROUPS map wires each sub-verb (run / report / provision / cleanup / mcp / browser) to its corresponding verify-suite main() (browser routes to src/cli/browser-verify.js main)",
17
17
  "status": "pending",
18
- "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-1: `verify` on the top-level SUBCOMMANDS map is the alias bin's dispatcher"
18
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-1: `verify` group on GROUPS wires each sub-verb to the verify-suite handler"
19
19
  },
20
20
  {
21
- "id": "TC-025-verify-help-parity",
21
+ "id": "TC-025-verify-help-routes-to-group-help",
22
22
  "acId": "AC-901-1",
23
- "description": "`rcf verify --help` and `rcf-verify --help` print byte-identical help",
23
+ "description": "`rcf verify --help` prints the verify group help (Usage: rcf verify <verb>) including the browser sub-verb",
24
24
  "status": "pending",
25
- "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-1 (routing surface): `rcf verify --help` dispatches to the same help block as `rcf-verify --help`"
25
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-1 (routing surface): `rcf verify --help` prints the verify group help"
26
26
  },
27
27
  {
28
- "id": "TC-025-top-level-help-lists-verify",
28
+ "id": "TC-025-top-level-help-lists-verify-group",
29
29
  "acId": "AC-901-2",
30
- "description": "the top-level rcf --help output lists `verify <verb>` alongside the other commands",
30
+ "description": "the top-level `rcf --help` output carries the verify group header with its sub-verb catalogue (run, report, provision, cleanup, mcp, browser)",
31
31
  "status": "pending",
32
- "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-2: `rcf --help` advertises the verify subcommand"
32
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-2: `rcf --help` carries the verify group header and sub-verb catalogue"
33
33
  },
34
34
  {
35
- "id": "TC-025-alias-emits-deprecation-notice",
35
+ "id": "TC-025-alias-bin-deleted-file",
36
36
  "acId": "AC-901-3",
37
- "description": "`rcf-verify` alias bin emits exactly one stderr line pointing at `rcf verify` when invoked directly",
37
+ "description": "the pre-0.10.0 alias bin file is deleted: bin/rcf-verify.js does not exist in the published package",
38
38
  "status": "pending",
39
- "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3: `rcf-verify` alias emits a one-line stderr deprecation notice on direct invocation"
39
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3: bin/rcf-verify.js is deleted from the package"
40
40
  },
41
41
  {
42
- "id": "TC-025-alias-honours-quiet-env",
42
+ "id": "TC-025-alias-bin-deleted-package-json",
43
43
  "acId": "AC-901-3",
44
- "description": "RCF_QUIET=1 silences the deprecation notice for scripted callers",
44
+ "description": "package.json bin field carries only `rcf`; the historical `rcf-verify` entry is gone",
45
45
  "status": "pending",
46
- "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3 (silencing): `rcf-verify` with RCF_QUIET=1 does not emit the deprecation notice"
46
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3: package.json:bin carries no `rcf-verify` entry"
47
+ },
48
+ {
49
+ "id": "TC-025-old-flat-validate-refused",
50
+ "acId": "AC-901-3",
51
+ "description": "calling `rcf <old-flat-validate>` via the umbrella bin exits 2 with a stderr hint at `rcf define validate` as the new grouped form",
52
+ "status": "pending",
53
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3: `rcf <old-flat-validate>` exits 2 with a stderr hint at `rcf define validate`"
54
+ },
55
+ {
56
+ "id": "TC-025-old-flat-browser-verify-refused",
57
+ "acId": "AC-901-3",
58
+ "description": "calling `rcf <old-flat-browser-verify>` via the umbrella bin exits 2 with a stderr hint at `rcf verify browser` as the new grouped form",
59
+ "status": "pending",
60
+ "testPointer": "test/cli/rcf-verify-subcommand.test.js::AC-901-3: `rcf <old-flat-browser-verify>` exits 2 with a hint at `rcf verify browser`"
47
61
  }
48
62
  ],
49
63
  "status": "draft",
50
64
  "createdAt": "2026-08-11T00:00:00Z",
51
- "updatedAt": "2026-08-11T00:00:00Z"
65
+ "updatedAt": "2026-08-26T00:00:00Z"
52
66
  }
@@ -2,7 +2,7 @@
2
2
  "id": "TS-026",
3
3
  "usId": "US-1001",
4
4
  "title": "Blueprint verb family",
5
- "purpose": "Cover rcf blueprint add/list/remove verb family behaviour and the manifest.blueprints[] write path.",
5
+ "purpose": "Cover rcf define blueprint add/list/remove verb family behaviour and the manifest.blueprints[] write path.",
6
6
  "testLevel": "unit",
7
7
  "acIds": [
8
8
  "AC-1001-1",
@@ -55,36 +55,36 @@
55
55
  {
56
56
  "id": "TC-027-shipped-blueprints-option-3-executable",
57
57
  "acId": "AC-1002-5",
58
- "description": "shipped SPA + REST option-3 verbatim-from-refused-state money probe: fresh scaffold; add spa; add rest (refused with the reshaped message); follow option 3 EXACTLY as printed (`rcf blueprint supersede errorEnvelope --incoming <rest>` and `rcf blueprint supersede authModel --incoming <rest>`) with ZERO prep; then re-run `rcf blueprint add <rest>` and verify co-residence + honour",
58
+ "description": "shipped SPA + REST option-3 verbatim-from-refused-state money probe: fresh scaffold; add spa; add rest (refused with the reshaped message); follow option 3 EXACTLY as printed (`rcf define blueprint supersede errorEnvelope --incoming <rest>` and `rcf define blueprint supersede authModel --incoming <rest>`) with ZERO prep; then re-run `rcf define blueprint add <rest>` and verify co-residence + honour",
59
59
  "testPointer": "test/blueprint/cli.test.js::shipped SPA + REST: option 3 executes VERBATIM from the refused-add state (rev-3 P1-1, Baz ruling on the conflict-pair supersede precondition)",
60
60
  "status": "pending"
61
61
  },
62
62
  {
63
63
  "id": "TC-027-add-reason-persists",
64
64
  "acId": "AC-1002-6",
65
- "description": "rcf blueprint add --reason attaches the ruling text to every resolutions[] record on that add",
66
- "testPointer": "test/blueprint/cli.test.js::rcf blueprint add --reason: reason lands on every resolution record (rev-2 P1-2)",
65
+ "description": "rcf define blueprint add --reason attaches the ruling text to every resolutions[] record on that add",
66
+ "testPointer": "test/blueprint/cli.test.js::rcf define blueprint add --reason: reason lands on every resolution record (rev-2 P1-2)",
67
67
  "status": "pending"
68
68
  },
69
69
  {
70
70
  "id": "TC-027-add-reason-whitespace-refused",
71
71
  "acId": "AC-1002-6",
72
72
  "description": "whitespace-only --reason on add refused at the writer edge (exit 2, no record written)",
73
- "testPointer": "test/blueprint/cli.test.js::rcf blueprint add --reason: whitespace-only reason is refused at the writer edge (rev-2 P1-2)",
73
+ "testPointer": "test/blueprint/cli.test.js::rcf define blueprint add --reason: whitespace-only reason is refused at the writer edge (rev-2 P1-2)",
74
74
  "status": "pending"
75
75
  },
76
76
  {
77
77
  "id": "TC-027-add-resolve-dedupes-with-warn",
78
78
  "acId": "AC-1002-7",
79
79
  "description": "duplicate --resolve for the same topic keeps the first declaration, drops the rest, and warns on stderr",
80
- "testPointer": "test/blueprint/cli.test.js::rcf blueprint add --resolve: duplicate topic dedupes with a stderr warning; only one record persists (rev-2 P3-b)",
80
+ "testPointer": "test/blueprint/cli.test.js::rcf define blueprint add --resolve: duplicate topic dedupes with a stderr warning; only one record persists (rev-2 P3-b)",
81
81
  "status": "pending"
82
82
  },
83
83
  {
84
84
  "id": "TC-027-add-resolve-error-no-double-prefix",
85
85
  "acId": "AC-1002-7",
86
86
  "description": "--resolve validation error carries the CLI's single '[error] blueprint add: ' prefix — the underlying rcfError message MUST NOT prepend its own 'blueprint add: '",
87
- "testPointer": "test/blueprint/cli.test.js::rcf blueprint add --resolve: validation error carries no doubled prefix (rev-2 P3-a)",
87
+ "testPointer": "test/blueprint/cli.test.js::rcf define blueprint add --resolve: validation error carries no doubled prefix (rev-2 P3-a)",
88
88
  "status": "pending"
89
89
  },
90
90
  {
@@ -105,7 +105,7 @@
105
105
  "id": "TC-027-supersede-no-double-prefix",
106
106
  "acId": "AC-1002-10",
107
107
  "description": "every error path in supersede.js exits at the CLI with exactly one `[error] blueprint supersede: ` prefix; the doubled `blueprint supersede: blueprint supersede:` string never appears",
108
- "testPointer": "test/blueprint/cli.test.js::rcf blueprint supersede: every rcfError message lands with exactly one `[error] blueprint supersede:` prefix (rev-3 mechanical P1)",
108
+ "testPointer": "test/blueprint/cli.test.js::rcf define blueprint supersede: every rcfError message lands with exactly one `[error] blueprint supersede:` prefix (rev-3 mechanical P1)",
109
109
  "status": "pending"
110
110
  }
111
111
  ],
@@ -2,7 +2,7 @@
2
2
  "id": "TS-028",
3
3
  "usId": "US-1003",
4
4
  "title": "Standards ingestion",
5
- "purpose": "Cover rcf standards add reference-by-default and out-of-root copy paths.",
5
+ "purpose": "Cover rcf define standards add reference-by-default and out-of-root copy paths.",
6
6
  "testLevel": "unit",
7
7
  "acIds": [
8
8
  "AC-1003-1",
@@ -5,40 +5,40 @@
5
5
  "version": "0.1.0",
6
6
  "status": "draft",
7
7
  "title": "Blueprint verb family: add, list, remove, upgrade",
8
- "description": "A `rcf blueprint` verb family provides the primary operator seat for composing blueprints onto a project. Every verb runs against the current tree, is idempotent where the semantics allow, and writes to the manifest's `blueprints[]` registry so the applied set is greppable and mechanical.",
8
+ "description": "A `rcf define blueprint` verb family provides the primary operator seat for composing blueprints onto a project. Every verb runs against the current tree, is idempotent where the semantics allow, and writes to the manifest's `blueprints[]` registry so the applied set is greppable and mechanical.",
9
9
  "asA": "operator on an RCF project",
10
- "iWant": "to add, list, remove and upgrade blueprints against my project tree from a single `rcf blueprint` verb family",
10
+ "iWant": "to add, list, remove and upgrade blueprints against my project tree from a single `rcf define blueprint` verb family",
11
11
  "soThat": "composition is a first-class action instead of a one-shot init flag, and I can layer several blueprints across the life of a project without hand-editing the manifest",
12
12
  "acceptanceCriteria": [
13
13
  {
14
14
  "id": "AC-1001-1",
15
- "description": "`rcf blueprint add <slug>` on a project with no blueprints applied writes an entry into `manifest.blueprints[]` and prints the applied slug and version",
15
+ "description": "`rcf define blueprint add <slug>` on a project with no blueprints applied writes an entry into `manifest.blueprints[]` and prints the applied slug and version",
16
16
  "given": "a validated project tree with no existing `blueprints[]` entries and a resolvable blueprint slug",
17
- "when": "`rcf blueprint add <slug>` runs",
17
+ "when": "`rcf define blueprint add <slug>` runs",
18
18
  "then": "the manifest gains one `blueprints[]` entry (slug, version, appliedAt, source, and any contributions[] the blueprint wrote), and stdout names the slug and applied version",
19
19
  "testable": true
20
20
  },
21
21
  {
22
22
  "id": "AC-1001-2",
23
- "description": "`rcf blueprint list` prints every applied blueprint (slug, version, appliedAt) in apply order",
23
+ "description": "`rcf define blueprint list` prints every applied blueprint (slug, version, appliedAt) in apply order",
24
24
  "given": "a project with one or more blueprints already applied",
25
- "when": "`rcf blueprint list` runs",
25
+ "when": "`rcf define blueprint list` runs",
26
26
  "then": "every applied blueprint prints, one per line, ordered by `appliedAt`, with slug, version and apply timestamp columns",
27
27
  "testable": true
28
28
  },
29
29
  {
30
30
  "id": "AC-1001-3",
31
- "description": "`rcf blueprint remove <slug>` removes the manifest entry and refuses when any project-authored doc references a contributed id",
31
+ "description": "`rcf define blueprint remove <slug>` removes the manifest entry and refuses when any project-authored doc references a contributed id",
32
32
  "given": "a project with the blueprint applied and no project-authored doc referencing any of the contributions[] ids",
33
- "when": "`rcf blueprint remove <slug>` runs",
33
+ "when": "`rcf define blueprint remove <slug>` runs",
34
34
  "then": "the `blueprints[]` entry is dropped from the manifest; when a project-authored doc DOES reference a contribution, the verb exits non-zero and prints the referencing id + path without mutating the manifest",
35
35
  "testable": true
36
36
  },
37
37
  {
38
38
  "id": "AC-1001-4",
39
- "description": "`rcf blueprint add <slug>` is idempotent: repeating on an already-applied clean slug is a no-op with a friendly message",
39
+ "description": "`rcf define blueprint add <slug>` is idempotent: repeating on an already-applied clean slug is a no-op with a friendly message",
40
40
  "given": "a project with `<slug>` already in `blueprints[]`",
41
- "when": "`rcf blueprint add <slug>` runs again with no conflicts to surface",
41
+ "when": "`rcf define blueprint add <slug>` runs again with no conflicts to surface",
42
42
  "then": "the manifest is not rewritten, exit code is 0, and stdout names the slug as already applied at the applied version",
43
43
  "testable": true
44
44
  },
@@ -5,7 +5,7 @@
5
5
  "version": "0.1.0",
6
6
  "status": "draft",
7
7
  "title": "Composition, namespaced ids and scope:global ADR conflict surfacing",
8
- "description": "Multiple blueprints may be applied to a single project. Blueprint-contributed docs are namespaced by the blueprint's slug so ids cannot collide across blueprints. A blueprint's ADR contributions may be tagged `scope: global`; two applied blueprints each contributing a `scope: global` ADR are a genuine conflict and `rcf blueprint add` surfaces both entries and refuses to write. Conflict-presentation ergonomics are prototype-unknown #1 (design brief); this US covers the first pass.",
8
+ "description": "Multiple blueprints may be applied to a single project. Blueprint-contributed docs are namespaced by the blueprint's slug so ids cannot collide across blueprints. A blueprint's ADR contributions may be tagged `scope: global`; two applied blueprints each contributing a `scope: global` ADR are a genuine conflict and `rcf define blueprint add` surfaces both entries and refuses to write. Conflict-presentation ergonomics are prototype-unknown #1 (design brief); this US covers the first pass.",
9
9
  "asA": "operator on an RCF project",
10
10
  "iWant": "blueprint contributions to compose without id collisions, and for `scope: global` ADR conflicts to be surfaced with both sides visible before anything is written",
11
11
  "soThat": "composition never silently merges incompatible whole-project decisions",
@@ -14,15 +14,15 @@
14
14
  "id": "AC-1002-1",
15
15
  "description": "Blueprint-contributed doc ids are namespaced with the blueprint's slug so composition cannot collide on ids at the id layer",
16
16
  "given": "two blueprints `spa` and `rest` that both contribute a REQ, a US and an ADR",
17
- "when": "both are applied to the same project via `rcf blueprint add`",
17
+ "when": "both are applied to the same project via `rcf define blueprint add`",
18
18
  "then": "every contributed id carries the blueprint slug as its prefix (REQ/US: `spa-REQ-001`, `rest-REQ-001`) or as its kebab-suffix (ADR: `ADR-004-spa-theme`, `ADR-005-rest-versioning`); no two contributed ids across the two blueprints match",
19
19
  "testable": true
20
20
  },
21
21
  {
22
22
  "id": "AC-1002-2",
23
- "description": "`rcf blueprint add <slug>` refuses when the new blueprint contributes a `scope: global` ADR on a topic already contributed by an applied blueprint",
23
+ "description": "`rcf define blueprint add <slug>` refuses when the new blueprint contributes a `scope: global` ADR on a topic already contributed by an applied blueprint",
24
24
  "given": "a project with blueprint `alpha` already applied contributing an ADR tagged `scope: global` on topic `versioning`",
25
- "when": "`rcf blueprint add beta` runs and blueprint `beta` also contributes a `scope: global` ADR on `versioning`",
25
+ "when": "`rcf define blueprint add beta` runs and blueprint `beta` also contributes a `scope: global` ADR on `versioning`",
26
26
  "then": "the verb exits non-zero, prints both ADR ids and their file paths, and the manifest is unchanged",
27
27
  "testable": true
28
28
  },
@@ -31,7 +31,7 @@
31
31
  "description": "Conflict output leads with per-side headers (ADR title + one-sentence decision) and names four honest resolution paths with actual blueprint slugs filled in (Phase 3.5 reshape)",
32
32
  "given": "the conflict case above",
33
33
  "when": "the verb prints the conflict",
34
- "then": "the output opens with `conflict on topic (<topic>)` and one line per side carrying `blueprint <slug>: <title> — <decision>` (or `<id> at <path>` when the tree did not carry the ADR body), a `refs:` footer with both ids + paths, and four honest resolutions numbered 1-4: adopt-incoming (`rcf blueprint remove <existing-slug>`), keep-existing (do not add the incoming), supersede via a project-level ADR (`rcf blueprint supersede <topic>`), and declare-on-add (`rcf blueprint add <source> --resolve <topic>=project:<ADR-id>`) — all with the actual conflicting blueprint slugs already substituted, no `<slug>` placeholders",
34
+ "then": "the output opens with `conflict on topic (<topic>)` and one line per side carrying `blueprint <slug>: <title> — <decision>` (or `<id> at <path>` when the tree did not carry the ADR body), a `refs:` footer with both ids + paths, and four honest resolutions numbered 1-4: adopt-incoming (`rcf define blueprint remove <existing-slug>`), keep-existing (do not add the incoming), supersede via a project-level ADR (`rcf define blueprint supersede <topic>`), and declare-on-add (`rcf define blueprint add <source> --resolve <topic>=project:<ADR-id>`) — all with the actual conflicting blueprint slugs already substituted, no `<slug>` placeholders",
35
35
  "testable": true
36
36
  },
37
37
  {
@@ -44,15 +44,15 @@
44
44
  },
45
45
  {
46
46
  "id": "AC-1002-5",
47
- "description": "The supersession record's two sides are the CONFLICT PAIR — one currently-applied blueprint's scope:global ADR on the topic PLUS one incoming (would-be-applied) blueprint's scope:global ADR on the same topic — and the `rcf blueprint supersede` verb accepts the incoming blueprint as the second side. Operator ruling (Baz, w-2026-08-19-008 round 3): option 3 as printed in the reshaped conflict message MUST be executable EXACTLY as printed from the refused-add state, with zero prep. Mechanism (builder judgement against the chain): the reshaped conflict message names option 3 as `rcf blueprint supersede <topic> --incoming <source>`, carrying the very same `<source>` argument the refused add was invoked with; `supersede` loads the incoming blueprint from `--incoming <source>`, finds its scope:global ADR on `<topic>`, stamps its id into the incoming blueprint's namespace, and uses `{slug, adrId}` for the incoming blueprint as the second side of `manifest.resolutions[].supersedes[]`. The scaffolded project ADR file lists both blueprint ADR ids (applied + incoming stamped) under `relatedAdrs[]`; after supersede returns, re-running `rcf blueprint add <source>` succeeds because the detector honours the freshly-recorded resolution. `--incoming <source>` is required when applied count on the topic is < 2 and is silently accepted (informational) when applied count is already >= 2.",
47
+ "description": "The supersession record's two sides are the CONFLICT PAIR — one currently-applied blueprint's scope:global ADR on the topic PLUS one incoming (would-be-applied) blueprint's scope:global ADR on the same topic — and the `rcf define blueprint supersede` verb accepts the incoming blueprint as the second side. Operator ruling (Baz, w-2026-08-19-008 round 3): option 3 as printed in the reshaped conflict message MUST be executable EXACTLY as printed from the refused-add state, with zero prep. Mechanism (builder judgement against the chain): the reshaped conflict message names option 3 as `rcf define blueprint supersede <topic> --incoming <source>`, carrying the very same `<source>` argument the refused add was invoked with; `supersede` loads the incoming blueprint from `--incoming <source>`, finds its scope:global ADR on `<topic>`, stamps its id into the incoming blueprint's namespace, and uses `{slug, adrId}` for the incoming blueprint as the second side of `manifest.resolutions[].supersedes[]`. The scaffolded project ADR file lists both blueprint ADR ids (applied + incoming stamped) under `relatedAdrs[]`; after supersede returns, re-running `rcf define blueprint add <source>` succeeds because the detector honours the freshly-recorded resolution. `--incoming <source>` is required when applied count on the topic is < 2 and is silently accepted (informational) when applied count is already >= 2.",
48
48
  "given": "a fresh project with ZERO applied blueprints and the shipped SPA + REST blueprints on disk (both carry scope:global ADRs on camelCase topics `errorEnvelope` and `authModel`)",
49
- "when": "the operator runs the flow verbatim as printed: `rcf blueprint add <spa>`; `rcf blueprint add <rest>` (refused with the reshaped four-honest-paths message); then follows option 3 EXACTLY as printed: `rcf blueprint supersede errorEnvelope --incoming <rest>` and `rcf blueprint supersede authModel --incoming <rest>`; then re-runs `rcf blueprint add <rest>`",
50
- "then": "each supersede exits 0, scaffolds a project ADR at `rcf/adrs/adr-NNN-<kebab-topic>.json` (topic string verbatim on `manifest.resolutions[].topic`; ADR id tail kebab-ified per ADR-010), and appends a `manifest.resolutions[]` record listing both blueprint ADR ids in `supersedes[]`; the subsequent `rcf blueprint add <rest>` exits 0 (detector honours the resolution) and both blueprint ADR files co-reside on disk with the project supersedes-ADR alongside them",
49
+ "when": "the operator runs the flow verbatim as printed: `rcf define blueprint add <spa>`; `rcf define blueprint add <rest>` (refused with the reshaped four-honest-paths message); then follows option 3 EXACTLY as printed: `rcf define blueprint supersede errorEnvelope --incoming <rest>` and `rcf define blueprint supersede authModel --incoming <rest>`; then re-runs `rcf define blueprint add <rest>`",
50
+ "then": "each supersede exits 0, scaffolds a project ADR at `rcf/adrs/adr-NNN-<kebab-topic>.json` (topic string verbatim on `manifest.resolutions[].topic`; ADR id tail kebab-ified per ADR-010), and appends a `manifest.resolutions[]` record listing both blueprint ADR ids in `supersedes[]`; the subsequent `rcf define blueprint add <rest>` exits 0 (detector honours the resolution) and both blueprint ADR files co-reside on disk with the project supersedes-ADR alongside them",
51
51
  "testable": true
52
52
  },
53
53
  {
54
54
  "id": "AC-1002-6",
55
- "description": "`rcf blueprint add --reason <text>` attaches the operator's ruling text to every `manifest.resolutions[]` record minted on that add. Whitespace-only reasons are refused at the writer edge (schema does not enforce a minimum floor on the field itself; the writer's floor is emptiness, not length).",
55
+ "description": "`rcf define blueprint add --reason <text>` attaches the operator's ruling text to every `manifest.resolutions[]` record minted on that add. Whitespace-only reasons are refused at the writer edge (schema does not enforce a minimum floor on the field itself; the writer's floor is emptiness, not length).",
56
56
  "given": "an incoming blueprint whose apply would collide on one or more topics, resolved via one or more --resolve declarations",
57
57
  "when": "the operator adds `--reason \"...\"` alongside the --resolve flags",
58
58
  "then": "every newly-minted resolutions[] record carries the reason string verbatim; a whitespace-only --reason exits 2 with an error naming the topic and no record is written",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  {
62
62
  "id": "AC-1002-7",
63
- "description": "Duplicate `--resolve` declarations for the same topic within a single `rcf blueprint add` are deduped: the first declaration is kept, subsequent declarations on the same topic are dropped, and a `[warn]` line names each dropped topic on stderr. The add still exits 0 on success; the manifest carries exactly one resolutions[] record per topic.",
63
+ "description": "Duplicate `--resolve` declarations for the same topic within a single `rcf define blueprint add` are deduped: the first declaration is kept, subsequent declarations on the same topic are dropped, and a `[warn]` line names each dropped topic on stderr. The add still exits 0 on success; the manifest carries exactly one resolutions[] record per topic.",
64
64
  "given": "an incoming blueprint whose apply would collide on topic X",
65
65
  "when": "the operator passes `--resolve X=project:ADR-A --resolve X=project:ADR-B` on the same command",
66
66
  "then": "the manifest carries exactly one resolutions[] record on topic X with `resolvedByAdrId: ADR-A` (first-wins), and stderr carries a warn line naming X as a duplicate --resolve topic",
@@ -70,7 +70,7 @@
70
70
  "id": "AC-1002-8",
71
71
  "description": "Conflict enrichment is symmetric: the CLI's conflict report and `--json` output both carry `title` + one-sentence `decision` on BOTH sides of a globalAdrTopic conflict — the existing side read from the walker's tree, the incoming side read from the blueprint's ADR file on disk. Round-1 only enriched the existing side, which read asymmetrically against shipped blueprints.",
72
72
  "given": "an incoming blueprint that would collide with an applied blueprint on a scope:global ADR topic, both ADRs carrying a title and a decision",
73
- "when": "`rcf blueprint add <source>` refuses with the reshaped message (with or without --json)",
73
+ "when": "`rcf define blueprint add <source>` refuses with the reshaped message (with or without --json)",
74
74
  "then": "both `incoming` and `existing` sides render `blueprint <slug>: <title> — <decision>` in the terminal output, and `conflicts[].incoming` and `conflicts[].existing` both carry `title` and `decision` in the --json output",
75
75
  "testable": true
76
76
  },
@@ -86,7 +86,7 @@
86
86
  "id": "AC-1002-10",
87
87
  "description": "Error-message prefix discipline on supersede: rcfError messages returned from `src/blueprint/supersede.js` MUST NOT prepend their own `blueprint supersede: ` prefix — the CLI edge already writes `[error] blueprint supersede: ` on every rcfError from the supersede verb. Round-2 caught the same bug on the `add` path; round-3 catches it on the supersede path (six sites: supersede.js:54, :70, :85, :107, :145, :160).",
88
88
  "given": "any error path in `src/blueprint/supersede.js` (missing topic, --reason whitespace-only, sub-2 applied ADRs, missing prd/tad, overwrite guard tripped, ADR write ioFailure)",
89
- "when": "`rcf blueprint supersede ...` runs into that error path at the CLI",
89
+ "when": "`rcf define blueprint supersede ...` runs into that error path at the CLI",
90
90
  "then": "the printed stderr line matches `^\\[error\\] blueprint supersede: <message>$` with exactly one `blueprint supersede: ` prefix; the string `blueprint supersede: blueprint supersede:` does not appear anywhere in the output",
91
91
  "testable": true
92
92
  }