rcf-lite 0.17.0 → 0.19.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 (161) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/blueprints/application-api-rest/README.md +5 -1
  3. package/blueprints/application-api-rest/blueprint.json +12 -4
  4. package/blueprints/application-api-rest/contributions/adrs/adr-304-application-api-rest-logging.json +3 -3
  5. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +4 -4
  6. package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +9 -8
  7. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +3 -3
  8. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +27 -27
  9. package/blueprints/application-api-rest/docs/topics.md +6 -4
  10. package/blueprints/application-api-rest/guide/application-api-rest.md +5 -1
  11. package/blueprints/application-error-handling/README.md +42 -0
  12. package/blueprints/application-error-handling/assets/schemas/error-record.schema.json +17 -0
  13. package/blueprints/application-error-handling/blueprint.json +27 -0
  14. package/blueprints/application-error-handling/contributions/adrs/adr-1701-application-error-handling-record-shape.json +25 -0
  15. package/blueprints/application-error-handling/contributions/adrs/adr-1702-application-error-handling-classification-vocabulary.json +20 -0
  16. package/blueprints/application-error-handling/contributions/adrs/adr-1703-application-error-handling-transport-mapping.json +20 -0
  17. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-001.json +15 -0
  18. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-002.json +15 -0
  19. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-003.json +15 -0
  20. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-004.json +15 -0
  21. package/blueprints/application-error-handling/contributions/tacs/tac-1701-application-error-handling-boundary.json +45 -0
  22. package/blueprints/application-error-handling/contributions/tacs/tac-1702-application-error-handling-record-factory.json +40 -0
  23. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16101.json +25 -0
  24. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16102.json +25 -0
  25. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16103.json +34 -0
  26. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16104.json +25 -0
  27. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16105.json +25 -0
  28. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16106.json +25 -0
  29. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16107.json +25 -0
  30. package/blueprints/application-error-handling/docs/topics.md +24 -0
  31. package/blueprints/application-error-handling/guide/application-error-handling.md +35 -0
  32. package/blueprints/application-spa/blueprint.json +12 -2
  33. package/blueprints/application-spa/docs/topics.md +4 -2
  34. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -2
  35. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  36. package/blueprints/email-smtp-resend/docs/topics.md +2 -2
  37. package/blueprints/observability-essentials/README.md +6 -2
  38. package/blueprints/observability-essentials/blueprint.json +133 -33
  39. package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +4 -4
  40. package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +4 -4
  41. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +4 -4
  42. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +4 -4
  43. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +10 -9
  44. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +17 -11
  45. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +12 -3
  46. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +12 -3
  47. package/blueprints/observability-essentials/docs/topics.md +15 -8
  48. package/blueprints/observability-essentials/guide/observability-essentials.md +9 -3
  49. package/blueprints/observability-logging/README.md +44 -0
  50. package/blueprints/observability-logging/assets/samples/log-line.json +13 -0
  51. package/blueprints/observability-logging/blueprint.json +27 -0
  52. package/blueprints/observability-logging/contributions/adrs/adr-1601-observability-logging-line-shape.json +25 -0
  53. package/blueprints/observability-logging/contributions/adrs/adr-1602-observability-logging-correlation-id-header.json +25 -0
  54. package/blueprints/observability-logging/contributions/adrs/adr-1603-observability-logging-redaction-categories.json +25 -0
  55. package/blueprints/observability-logging/contributions/adrs/adr-1604-observability-logging-level-vocabulary.json +20 -0
  56. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-001.json +15 -0
  57. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-002.json +15 -0
  58. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-003.json +15 -0
  59. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-004.json +15 -0
  60. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-005.json +15 -0
  61. package/blueprints/observability-logging/contributions/tacs/tac-1601-observability-logging-logger-factory.json +46 -0
  62. package/blueprints/observability-logging/contributions/tacs/tac-1602-observability-logging-redaction-boundary.json +27 -0
  63. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15101.json +34 -0
  64. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15102.json +43 -0
  65. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15103.json +34 -0
  66. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15104.json +25 -0
  67. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15105.json +34 -0
  68. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15106.json +25 -0
  69. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15107.json +25 -0
  70. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15108.json +25 -0
  71. package/blueprints/observability-logging/docs/topics.md +21 -0
  72. package/blueprints/observability-logging/guide/observability-logging.md +36 -0
  73. package/blueprints/observability-probe-endpoints/README.md +5 -1
  74. package/blueprints/observability-probe-endpoints/blueprint.json +116 -24
  75. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +5 -5
  76. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +11 -2
  77. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +11 -2
  78. package/blueprints/observability-probe-endpoints/docs/topics.md +6 -6
  79. package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +10 -0
  80. package/blueprints/persistence-data-d1/docs/topics.md +2 -2
  81. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -2
  82. package/blueprints/security-auth-clerk/docs/topics.md +2 -2
  83. package/blueprints/security-auth-keycloak/docs/topics.md +2 -2
  84. package/blueprints/security-auth-magic-link/docs/topics.md +2 -2
  85. package/blueprints/security-auth-oauth2/docs/topics.md +2 -2
  86. package/blueprints/security-secrets-management/docs/topics.md +2 -2
  87. package/fixtures/canary-manifest.json +6 -6
  88. package/guidance/harness-template.md +8 -0
  89. package/guidance/managed/agent-instructions-block.hash +1 -1
  90. package/guidance/managed/agent-instructions-block.md +8 -0
  91. package/package.json +1 -1
  92. package/rcf/code-nodes/cn-074.json +19 -0
  93. package/rcf/code-nodes/cn-075.json +15 -0
  94. package/rcf/code-nodes/cn-076.json +14 -0
  95. package/rcf/code-nodes/cn-077.json +14 -0
  96. package/rcf/code-nodes/cn-078.json +15 -0
  97. package/rcf/code-nodes/cn-079.json +14 -0
  98. package/rcf/code-nodes/cn-080.json +15 -0
  99. package/rcf/code-nodes/cn-081.json +15 -0
  100. package/rcf/code-nodes/cn-082.json +15 -0
  101. package/rcf/code-nodes/cn-083.json +14 -0
  102. package/rcf/code-nodes/cn-084.json +15 -0
  103. package/rcf/code-nodes/cn-085.json +14 -0
  104. package/rcf/code-nodes/cn-086.json +16 -0
  105. package/rcf/code-nodes/cn-087.json +14 -0
  106. package/rcf/code-nodes/cn-088.json +14 -0
  107. package/rcf/code-nodes/cn-089.json +14 -0
  108. package/rcf/code-nodes/cn-090.json +14 -0
  109. package/rcf/code-nodes/cn-091.json +14 -0
  110. package/rcf/code-nodes/cn-092.json +15 -0
  111. package/rcf/code-nodes/cn-093.json +15 -0
  112. package/rcf/code-nodes/cn-094.json +14 -0
  113. package/rcf/code-nodes/cn-095.json +14 -0
  114. package/rcf/code-nodes/cn-096.json +14 -0
  115. package/rcf/code-nodes/cn-097.json +14 -0
  116. package/rcf/fbs/fbs-024.json +24 -0
  117. package/rcf/fbs/fbs-025.json +25 -0
  118. package/rcf/fbs/fbs-026.json +27 -0
  119. package/rcf/fbs/fbs-027.json +25 -0
  120. package/rcf/fbs/fbs-028.json +27 -0
  121. package/rcf/fbs/fbs-029.json +27 -0
  122. package/rcf/fbs/fbs-030.json +27 -0
  123. package/rcf/fbs/fbs-031.json +27 -0
  124. package/rcf/fbs/fbs-032.json +27 -0
  125. package/rcf/fbs/fbs-033.json +27 -0
  126. package/rcf/fbs/fbs-034.json +27 -0
  127. package/rcf/requirements/req-012.json +22 -0
  128. package/rcf/requirements/req-013.json +22 -0
  129. package/rcf/requirements/req-014.json +22 -0
  130. package/rcf/requirements/req-015.json +21 -0
  131. package/rcf/test-suites/ts-034.json +32 -0
  132. package/rcf/test-suites/ts-035.json +23 -0
  133. package/rcf/test-suites/ts-036.json +65 -0
  134. package/rcf/test-suites/ts-037.json +55 -0
  135. package/rcf/test-suites/ts-038.json +41 -0
  136. package/rcf/test-suites/ts-039.json +41 -0
  137. package/rcf/test-suites/ts-040.json +57 -0
  138. package/rcf/test-suites/ts-041.json +57 -0
  139. package/rcf/test-suites/ts-042.json +57 -0
  140. package/rcf/test-suites/ts-043.json +49 -0
  141. package/rcf/test-suites/ts-044.json +41 -0
  142. package/rcf/user-stories/us-1201.json +34 -0
  143. package/rcf/user-stories/us-1202.json +25 -0
  144. package/rcf/user-stories/us-1203.json +43 -0
  145. package/rcf/user-stories/us-1204.json +25 -0
  146. package/rcf/user-stories/us-1301.json +43 -0
  147. package/rcf/user-stories/us-1302.json +43 -0
  148. package/rcf/user-stories/us-1401.json +43 -0
  149. package/rcf/user-stories/us-1402.json +43 -0
  150. package/rcf/user-stories/us-1403.json +43 -0
  151. package/rcf/user-stories/us-1404.json +43 -0
  152. package/rcf/user-stories/us-1501.json +43 -0
  153. package/releases/releases.yaml +21 -1
  154. package/src/blueprint/apply.js +8 -0
  155. package/src/blueprint/companions.js +485 -0
  156. package/src/blueprint/index.js +17 -0
  157. package/src/blueprint/loader.js +243 -1
  158. package/src/blueprint/remove-resolution.js +104 -0
  159. package/src/cli/blueprint.js +350 -0
  160. package/src/cli/doctor.js +76 -1
  161. package/src/cli/validate.js +7 -0
@@ -0,0 +1,57 @@
1
+ {
2
+ "id": "TS-041",
3
+ "usId": "US-1402",
4
+ "title": "rcf define blueprint add prints resolved companion suggestions and honours --companion / --no-companion-suggestions with persistence to rcf/companions.json",
5
+ "purpose": "Cover the three ACs on US-1402: apply-time suggestion block and its suppression, --companion selectors and refusal for non-providers, companions.json shape and pin overwrite behaviour.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-1402-1",
9
+ "AC-1402-2",
10
+ "AC-1402-3"
11
+ ],
12
+ "testCases": [
13
+ {
14
+ "id": "TC-041-suggestion-block",
15
+ "acId": "AC-1402-1",
16
+ "description": "rcf define blueprint add application-api-rest into a fresh fixture prints the header line and one line per suggested role with the origin annotation; the apply does not adopt any companion.",
17
+ "testPointer": "test/cli/blueprint-companions.test.js::apply prints resolved companion suggestion block after success (TC-041-suggestion-block)",
18
+ "status": "pending",
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "TC-041-no-suggestions-flag",
23
+ "acId": "AC-1402-1",
24
+ "description": "rcf define blueprint add application-api-rest --no-companion-suggestions succeeds and produces no suggestion block on stdout.",
25
+ "testPointer": "test/cli/blueprint-companions.test.js::--no-companion-suggestions suppresses the block (TC-041-no-suggestions-flag)",
26
+ "status": "pending",
27
+ "scope": "library"
28
+ },
29
+ {
30
+ "id": "TC-041-companion-flag-writes-pin",
31
+ "acId": "AC-1402-2",
32
+ "description": "rcf define blueprint add application-api-rest --companion logging=observability-logging --companion errorHandling=application-error-handling writes rcf/companions.json with both pins carrying pinnedAt.",
33
+ "testPointer": "test/cli/blueprint-companions.test.js::--companion selectors write rcf/companions.json pins with pinnedAt (TC-041-companion-flag-writes-pin)",
34
+ "status": "pending",
35
+ "scope": "library"
36
+ },
37
+ {
38
+ "id": "TC-041-companion-flag-non-provider",
39
+ "acId": "AC-1402-2",
40
+ "description": "rcf define blueprint add --companion logging=observability-essentials (which does not declare providesRoles containing logging) refuses exit 2 with the specified message shape.",
41
+ "testPointer": "test/cli/blueprint-companions.test.js::--companion naming a non-provider refuses exit 2 with no side effects (TC-041-companion-flag-non-provider)",
42
+ "status": "pending",
43
+ "scope": "library"
44
+ },
45
+ {
46
+ "id": "TC-041-pin-file-shape-and-overwrite",
47
+ "acId": "AC-1402-3",
48
+ "description": "rcf/companions.json is created lazily with schemaVersion 1 and current-pin-only shape; a re-run with a different --companion value overwrites the pin and prints the pin-transition stderr line.",
49
+ "testPointer": "test/cli/blueprint-companions.test.js::rcf/companions.json shape and pin overwrite prints transition line (TC-041-pin-file-shape-and-overwrite)",
50
+ "status": "pending",
51
+ "scope": "library"
52
+ }
53
+ ],
54
+ "status": "draft",
55
+ "createdAt": "2026-09-04T12:20:00Z",
56
+ "updatedAt": "2026-09-04T12:20:00Z"
57
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "id": "TS-042",
3
+ "usId": "US-1403",
4
+ "title": "rcf define blueprint companions <slug>|set|unset verb: text output, --json envelope, exit codes",
5
+ "purpose": "Cover the three ACs on US-1403: <slug> resolution printing with origin annotations, set/unset pin round-trip and refusals, --json envelope on all three sub-verbs.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-1403-1",
9
+ "AC-1403-2",
10
+ "AC-1403-3"
11
+ ],
12
+ "testCases": [
13
+ {
14
+ "id": "TC-042-companions-slug-text",
15
+ "acId": "AC-1403-1",
16
+ "description": "rcf define blueprint companions application-api-rest with application-api-rest applied prints the header and one line per role with the origin annotations already-applied / shelf-fallback / registered-library.",
17
+ "testPointer": "test/cli/blueprint-companions.test.js::rcf define blueprint companions <slug> prints resolved companions with origin (TC-042-companions-slug-text)",
18
+ "status": "pending",
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "TC-042-companions-slug-not-applied",
23
+ "acId": "AC-1403-1",
24
+ "description": "rcf define blueprint companions <slug> refuses exit 2 when the named slug is not applied on the project.",
25
+ "testPointer": "test/cli/blueprint-companions.test.js::rcf define blueprint companions refuses when slug is not applied (TC-042-companions-slug-not-applied)",
26
+ "status": "pending",
27
+ "scope": "library"
28
+ },
29
+ {
30
+ "id": "TC-042-companions-set-unset-round-trip",
31
+ "acId": "AC-1403-2",
32
+ "description": "rcf define blueprint companions set logging observability-logging writes companions.json; rcf define blueprint companions unset logging removes the entry; an unset without a pin refuses exit 2.",
33
+ "testPointer": "test/cli/blueprint-companions.test.js::companions set writes pin and unset removes it; unset without pin refuses (TC-042-companions-set-unset-round-trip)",
34
+ "status": "pending",
35
+ "scope": "library"
36
+ },
37
+ {
38
+ "id": "TC-042-companions-set-refuses-non-provider",
39
+ "acId": "AC-1403-2",
40
+ "description": "rcf define blueprint companions set logging observability-essentials refuses exit 2 because observability-essentials does not declare providesRoles containing logging.",
41
+ "testPointer": "test/cli/blueprint-companions.test.js::companions set refuses non-provider slug (TC-042-companions-set-refuses-non-provider)",
42
+ "status": "pending",
43
+ "scope": "library"
44
+ },
45
+ {
46
+ "id": "TC-042-companions-json-envelope",
47
+ "acId": "AC-1403-3",
48
+ "description": "rcf define blueprint companions application-api-rest --json emits {slug, suggestions: [{role, provider, origin, notes}]} preserving the order of suggestedCompanions[].",
49
+ "testPointer": "test/cli/blueprint-companions.test.js::--json emits machine-readable envelope preserving suggestedCompanions order (TC-042-companions-json-envelope)",
50
+ "status": "pending",
51
+ "scope": "library"
52
+ }
53
+ ],
54
+ "status": "draft",
55
+ "createdAt": "2026-09-04T12:20:00Z",
56
+ "updatedAt": "2026-09-04T12:20:00Z"
57
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": "TS-043",
3
+ "usId": "US-1404",
4
+ "title": "Resolution rule tier ladder, two-libraries refusal exit 3, and validate refusal for unresolvable pin",
5
+ "purpose": "Cover the three ACs on US-1404: deterministic tier ladder (applied > registered library > core shelf) with pin override, two-libraries-one-role refusal message shape on both add and companions verb, validate refusal for a pin naming no known provider.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-1404-1",
9
+ "AC-1404-2",
10
+ "AC-1404-3"
11
+ ],
12
+ "testCases": [
13
+ {
14
+ "id": "TC-043-resolver-tier-ladder",
15
+ "acId": "AC-1404-1",
16
+ "description": "The resolveCompanions function returns origin already-applied when a provider is applied, registered-library-<prefix> when one library provides it, shelf-fallback when only the core shelf provides it, and pinned when rcf/companions.json overrides.",
17
+ "testPointer": "test/blueprint/companions-resolver.test.js::resolver returns shelf-fallback when only the core shelf provides the role",
18
+ "status": "pending",
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "TC-043-two-libraries-refuse-exit-3",
23
+ "acId": "AC-1404-2",
24
+ "description": "With two registered libraries both providing role logging and no pin, rcf define blueprint add on a service blueprint refuses exit 3 with the ambiguous-role message naming both library slugs and the three resolution paths verbatim.",
25
+ "testPointer": "test/cli/blueprint-companions.test.js::two libraries providing one role refuse exit 3 with three-path resolution message (TC-043-two-libraries-refuse-exit-3)",
26
+ "status": "pending",
27
+ "scope": "library"
28
+ },
29
+ {
30
+ "id": "TC-043-two-libraries-on-companions-verb",
31
+ "acId": "AC-1404-2",
32
+ "description": "The same two-libraries-one-role case on rcf define blueprint companions <slug> refuses exit 3 with the same three-path resolution message.",
33
+ "testPointer": "test/cli/blueprint-companions.test.js::rcf define blueprint companions refuses exit 3 when two libraries provide same role (TC-043-two-libraries-on-companions-verb)",
34
+ "status": "pending",
35
+ "scope": "library"
36
+ },
37
+ {
38
+ "id": "TC-043-validate-refuses-unresolvable-pin",
39
+ "acId": "AC-1404-3",
40
+ "description": "rcf define validate refuses exit 3 when rcf/companions.json pins a role to a slug that no applied blueprint, no registered library, and no shelf blueprint provides; message shape names the exact role and slug.",
41
+ "testPointer": "test/cli/validate-companions-pin.test.js::validate refuses exit 3 when a companions.json pin names an unresolvable provider (TC-043-validate-refuses-unresolvable-pin)",
42
+ "status": "pending",
43
+ "scope": "library"
44
+ }
45
+ ],
46
+ "status": "draft",
47
+ "createdAt": "2026-09-04T12:20:00Z",
48
+ "updatedAt": "2026-09-04T12:20:00Z"
49
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "id": "TS-044",
3
+ "usId": "US-1501",
4
+ "title": "Loader validates standardsTrace with the standardsTraceClause discipline; refuses missing clause without cross-checking severity",
5
+ "purpose": "Cover the three ACs on US-1501: loader acceptance of standardsTrace/recommendedDefault/elicited/standardsTraceClause, refusal message shape when standardsTrace is declared and any ADR lacks a standardsTraceClause, and no-cross-check on MUST-to-kind mapping.",
6
+ "testLevel": "unit",
7
+ "acIds": [
8
+ "AC-1501-1",
9
+ "AC-1501-2",
10
+ "AC-1501-3"
11
+ ],
12
+ "testCases": [
13
+ {
14
+ "id": "TC-044-loader-accepts-standards-fields",
15
+ "acId": "AC-1501-1",
16
+ "description": "loadBlueprint on a fixture with standardsTrace [{id: WSD-001, version: 2026-05}] and one ADR contribution carrying recommendedDefault true and standardsTraceClause 'WSD-001 clause 3.1' returns the fields on the LoadedBlueprint object; no rcfError.",
17
+ "testPointer": "test/blueprint/loader-standards-trace.test.js::loader accepts standardsTrace and recommendedDefault/elicited/standardsTraceClause (AC-1501-1)",
18
+ "status": "pending",
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "TC-044-loader-refuses-missing-clause",
23
+ "acId": "AC-1501-2",
24
+ "description": "loadBlueprint refuses a fixture declaring standardsTrace but with one ADR contribution missing standardsTraceClause; rcfError kind validation with the exact refusal message shape.",
25
+ "testPointer": "test/blueprint/loader-standards-trace.test.js::loader refuses missing standardsTraceClause when standardsTrace is declared (AC-1501-2)",
26
+ "status": "pending",
27
+ "scope": "library"
28
+ },
29
+ {
30
+ "id": "TC-044-no-cross-check-and-sentinel",
31
+ "acId": "AC-1501-3",
32
+ "description": "The two new core companion blueprints (observability-logging, application-error-handling), which declare NO standardsTrace, load clean regardless of standardsTraceClause presence; a fixture with standardsTrace declared and every ADR carrying 'generic enterprise practice' loads clean; the loader does not refuse a MUST-marked ADR (no cross-check of clause severity to kind, per amendment A2).",
33
+ "testPointer": "test/blueprint/loader-standards-trace.test.js::no cross-check on severity; sentinel and no-standardsTrace baseline both load clean (AC-1501-3)",
34
+ "status": "pending",
35
+ "scope": "library"
36
+ }
37
+ ],
38
+ "status": "draft",
39
+ "createdAt": "2026-09-04T12:20:00Z",
40
+ "updatedAt": "2026-09-04T12:20:00Z"
41
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "usId": "US-1201",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-012",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "observability-essentials + observability-probe-endpoints + application-api-rest compose cleanly in every ordering with no globalAdrTopic conflict on healthProbes or readinessSemantics",
8
+ "asA": "operator applying the three post-alignment observability + api-rest blueprints on one project in any order",
9
+ "iWant": "the three amended blueprints (essentials v2.0.0, probe-endpoints v1.1.0, api-rest v2.0.0) to apply cleanly in every ordering, with observability-probe-endpoints as the sole scope:global claimant of healthProbes and readinessSemantics in the resulting manifest",
10
+ "soThat": "a project that reaches for all three shipped blueprints inherits a single-owner probe-path surface without an operator-side supersede ADR or a manifest-editing follow-up",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1201-1",
14
+ "description": "Applying the three blueprints in every ordering (six permutations) into a freshly initialised project tree succeeds with no `globalAdrTopic` conflict on `healthProbes` or `readinessSemantics`; the resulting `rcf/manifest.json` carries all three blueprint records.",
15
+ "given": "a freshly initialised rcf-lite project tree and the three shipped blueprints at essentials v2.0.0, probe-endpoints v1.1.0, api-rest v2.0.0",
16
+ "when": "for each of the six permutations of the three blueprints, applyBlueprint runs three times in that order against a fresh project tree",
17
+ "then": "no ordering returns a `globalAdrTopic` conflict on healthProbes or readinessSemantics, and every ordering ends with manifest.blueprints containing observability-essentials, observability-probe-endpoints, and application-api-rest",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1201-2",
23
+ "description": "In the applied manifest, exactly one blueprint declares `scope: global` with `topic: healthProbes` (observability-probe-endpoints ADR-1501) and exactly one declares `scope: global` with `topic: readinessSemantics` (observability-probe-endpoints ADR-1502); zero from essentials, zero from api-rest.",
24
+ "given": "a project with all three amended blueprints applied",
25
+ "when": "manifest.blueprints[].contributions[] is walked for scope:global ADRs on the two topics",
26
+ "then": "the claimant list for healthProbes equals [\"observability-probe-endpoints\"] and the claimant list for readinessSemantics equals [\"observability-probe-endpoints\"]",
27
+ "testable": true,
28
+ "scope": "library"
29
+ }
30
+ ],
31
+ "tacIds": [],
32
+ "createdAt": "2026-09-04T00:00:00Z",
33
+ "updatedAt": "2026-09-04T00:00:00Z"
34
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "usId": "US-1202",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-012",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "The applied tree carries no literal probe path (/healthz, /readyz, /healthz/*) outside observability-probe-endpoints prose",
8
+ "asA": "operator or reviewer grepping an applied project tree for literal probe paths after re-applying the three amended blueprints",
9
+ "iWant": "zero matches for /healthz, /readyz, /healthz/live, /healthz/ready or /healthz/startup in the applied `rcf/` tree, so the shelf ships one probe-path opinion (the resolved one) and no rogue literals",
10
+ "soThat": "a project that composes the three shipped blueprints never inherits a stale literal path binding that disagrees with the resolved probe path set",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1202-1",
14
+ "description": "Grepping the applied `rcf/` tree of a project that has re-applied observability-essentials v2.0.0 + observability-probe-endpoints v1.1.0 + application-api-rest v2.0.0 for the strings `/healthz/live`, `/healthz/ready`, `/healthz/startup`, `/healthz`, and `/readyz` returns zero matches across all contribution JSON files.",
15
+ "given": "a project with all three amended blueprints applied",
16
+ "when": "the applied `rcf/` tree is grepped for the five literal probe-path strings above",
17
+ "then": "the match count is zero (matches remain only in the source blueprint READMEs and guides for observability-probe-endpoints, never in the applied contribution JSON)",
18
+ "testable": true,
19
+ "scope": "library"
20
+ }
21
+ ],
22
+ "tacIds": [],
23
+ "createdAt": "2026-09-04T00:00:00Z",
24
+ "updatedAt": "2026-09-04T00:00:00Z"
25
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1203",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-012",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Each amended blueprint carries the ratified alignment facts: probe-endpoints optional startup + composing section; essentials path-neutral REQs/TACs and PROBE_INTERFACE_PATHS_MISSING; api-rest defers all probe paths",
8
+ "asA": "reviewer walking the three amended blueprint source directories after the alignment lands",
9
+ "iWant": "each blueprint to carry the shape the spec ratified: observability-probe-endpoints v1.1.0 adds the optional startup path and a composing section; observability-essentials v2.0.0 restates REQ-001/002 and TAC-801/802 path-neutral and names the PROBE_INTERFACE_PATHS_MISSING boot refusal; application-api-rest v2.0.0 defers probe paths to the resolved set with a matching AC on the auth-exempt list and a startup AC that consumes the optional path",
10
+ "soThat": "a downstream project (or a gate reviewer walking the shelf) reads the ratified alignment off the source blueprints directly, without needing to reconstruct the intent from the spec",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1203-1",
14
+ "description": "observability-probe-endpoints/blueprint.json declares version 1.1.0. US-14102 carries a new AC-14102-4 naming the three-path resolution (/live, /ready, /startup) and the startup handler when `probeInterface.options.kubernetes.startup.enabled: true`. US-14107 carries a new AC-14107-4 naming the three-entry auth-exempt list when startup is enabled. ADR-1503 decision text names the startup.enabled flag, the same body shape, and the fused topology by default. `guide/observability-probe-endpoints.md` carries a \"Composing with observability-essentials and application-api-rest\" section naming the deferral pattern and the compose test at `packages/rcf-lite/test/blueprint/probe-path-alignment.test.js` as the ratified truth.",
15
+ "given": "the shipped observability-probe-endpoints blueprint source directory at HEAD",
16
+ "when": "blueprint.json, US-14102, US-14107, ADR-1503, and the guide are read",
17
+ "then": "blueprint.json version equals 1.1.0; AC-14102-4 and AC-14107-4 exist and name the startup path; ADR-1503 decision names startup.enabled; the guide carries the composing section naming the compose test path",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1203-2",
23
+ "description": "observability-essentials/blueprint.json declares version 2.0.0; the ADR-801 and ADR-802 contribution entries no longer carry `scope: \"global\"` or `topic`. REQ-001 and REQ-002 restate path-neutral and name `probeInterface.paths.liveness` / `probeInterface.paths.readiness` as the required configuration key. TAC-801 and TAC-802 mark the path as REQUIRED with no shipped default and name the `PROBE_INTERFACE_PATHS_MISSING` stable-coded boot refusal on the responsibilities list. US-7101 gains AC-7101-4 and US-7102 gains AC-7102-4 covering the boot-refusal-on-missing-config semantics. `docs/topics.md` shrinks the global-topics table to `statusPageContract` alone and records `healthProbes` and `readinessSemantics` in a \"Historical global topics (dropped in v2.0.0)\" section.",
24
+ "given": "the shipped observability-essentials blueprint source directory at HEAD",
25
+ "when": "blueprint.json, ADR-801, ADR-802, REQ-001, REQ-002, TAC-801, TAC-802, US-7101, US-7102, and docs/topics.md are read",
26
+ "then": "blueprint.json version equals 2.0.0; ADR-801/802 contribution entries carry no scope or topic field; REQ-001/002 name probeInterface.paths and refuses-boot; TAC-801/802 mark path as REQUIRED and name PROBE_INTERFACE_PATHS_MISSING; AC-7101-4 and AC-7102-4 exist; topics.md carries the Historical global topics section",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1203-3",
32
+ "description": "application-api-rest/blueprint.json declares version 2.0.0. REQ-006 restates path-neutral naming observability-probe-endpoints as the probe-path owner and probeInterface.paths as the essentials-alone fallback. US-2108 all eight ACs bind to \"the resolved liveness path\", \"the resolved readiness path\", or \"the resolved startup path\"; AC-2108-5 binds the auth-exempt assertion to the resolved probe path set (naming `getExemptPathSet` from TAC-1501). TAC-306 responsibilities restate the three probe surfaces at their resolved paths, drop the literal path strings, and name the auth-exempt consumption of the resolved set. US-2103 versioning-exemption AC no longer carries the literal `/healthz/*` and names the resolved probe paths instead.",
33
+ "given": "the shipped application-api-rest blueprint source directory at HEAD",
34
+ "when": "blueprint.json, REQ-006, US-2108 (all eight ACs), TAC-306, and US-2103 are read",
35
+ "then": "blueprint.json version equals 2.0.0; REQ-006 names probe-endpoints and probeInterface.paths as the two path-resolution sources; every US-2108 AC contains \"resolved\" and none contains a literal /healthz/* prefix; TAC-306 responsibilities name the resolved probe path set and getExemptPathSet or probeInterface.paths; US-2103 no longer contains /healthz/*",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T00:00:00Z",
42
+ "updatedAt": "2026-09-04T00:00:00Z"
43
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "usId": "US-1204",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-012",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator running `rcf define blueprint remove-resolution <adr-id>` drops a redundant historical resolutions[] entry cleanly (spec section 9 remedy)",
8
+ "asA": "operator running `rcf doctor --check probe-path-owner` on a project that upgraded to observability-essentials v2.0.0 + observability-probe-endpoints v1.1.0 and now sees a redundant-<topic>-resolution drift line",
9
+ "iWant": "the `rcf define blueprint remove-resolution <adr-id>` verb the drift line and section 9 name to actually exist, drop the named manifest.resolutions[] entry (and nothing else), refuse exit 2 when the id is not a resolution entry, and be idempotent on a second run",
10
+ "soThat": "the section 9 migration remedy printed by the doctor is executable verbatim, and re-running the same command after a successful pass is a no-op rather than a refusal",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1204-1",
14
+ "description": "The `rcf define blueprint remove-resolution <adr-id>` verb exists on the blueprint CLI (advertised in `rcf help define blueprint`), matches the `<adr-id>` argument against `manifest.resolutions[].resolvedByAdrId`, and exhibits three ratified behaviours: (a) when an entry matches, drop that entry and only that entry from `manifest.resolutions[]` (every other manifest section byte-identical, and the project-level ADR file at `rcf/adrs/<adr-id>.json` untouched), print one result line naming the id, the topic, and the dropped resolution id, and exit 0; (b) when the `<adr-id>` is a well-formed ADR id that still names an ADR present on the project tree but is no longer on any `resolutions[]` entry, print `[blueprint] nothing to remove: '<adr-id>' is not on manifest.resolutions[]` and exit 0 (idempotent on re-run of the same operation); (c) when the `<adr-id>` is malformed against the ADR id grammar, or is well-formed but names no ADR on the tree and no resolutions[] entry, print `[error] blueprint remove-resolution: ...` on stderr and exit 2.",
15
+ "given": "a project whose manifest.resolutions[] carries one globalAdrTopic entry on healthProbes with resolvedByAdrId = 'ADR-011-health-probes' and the ADR file present at rcf/adrs/adr-011-health-probes.json",
16
+ "when": "the operator runs `rcf define blueprint remove-resolution ADR-011-health-probes` once, then a second time, then with 'not-an-adr' and with 'ADR-999-nowhere'",
17
+ "then": "the first run exits 0 with the removal line and drops the single resolutions[] entry (project-ADR file untouched, every other manifest section byte-identical); the second run exits 0 with the 'nothing to remove' line and does not write; 'not-an-adr' exits 2 with 'is not a well-formed ADR id'; 'ADR-999-nowhere' exits 2 with 'is not a resolution entry on this manifest'; and `rcf help define blueprint` output contains the `remove-resolution <adr-id>` verb block",
18
+ "testable": true,
19
+ "scope": "library"
20
+ }
21
+ ],
22
+ "tacIds": [],
23
+ "createdAt": "2026-09-04T00:00:00Z",
24
+ "updatedAt": "2026-09-04T00:00:00Z"
25
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1301",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-013",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Core shelf ships observability-logging v1.0.0 with providesRoles logging and the shelf-canonical logging global topic",
8
+ "asA": "operator running rcf define blueprint add on a fresh project that needs a general-enterprise-practice logging contract",
9
+ "iWant": "the shipped core shelf to carry an observability-logging blueprint (v1.0.0) that provides the logging role, mints the logging global topic on ADR-1601, and applies cleanly into a fixture project alongside every other shipped shelf blueprint",
10
+ "soThat": "a project falls back to a sensible logging contract without registering any library, the mechanism in REQ-014 has a shelf provider to resolve to, and the logging global topic has one owner on the shelf",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1301-1",
14
+ "description": "`blueprints/observability-logging/blueprint.json` exists with `slug: \"observability-logging\"`, `version: \"1.0.0\"`, `category: \"observability\"`, `providesRoles: [\"logging\"]`, and a contributions list carrying five REQs (`observability-logging-REQ-001` through `-REQ-005`), user stories in the 15101-15899 band (at least `-US-15101` through `-US-15108`), TACs `TAC-1601-observability-logging-logger-factory` and `TAC-1602-observability-logging-redaction-boundary`, and ADRs `ADR-1601` through `ADR-1604` including `ADR-1601-observability-logging-line-shape` with `scope: \"global\", topic: \"logging\"`.",
15
+ "given": "the shipped core shelf at packages/rcf-lite/blueprints/observability-logging (staged from the top-level blueprints/ directory)",
16
+ "when": "the loader reads blueprint.json and enumerates contributions[]",
17
+ "then": "the fields resolve to the values above and jq queries against blueprint.json return them verbatim",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1301-2",
23
+ "description": "`rcf define blueprint add <path>/blueprints/observability-logging` applied into a fresh fixture project with no prior applied blueprints succeeds (exit 0), writes `manifest.blueprints[]` with slug `observability-logging`, and copies the namespaced contribution files under `rcf/req/`, `rcf/userStory/`, `rcf/tac/` and `rcf/adr/`.",
24
+ "given": "a fresh fixture project initialised via `rcf init` with no applied blueprints",
25
+ "when": "the operator runs `rcf define blueprint add <path-to>/blueprints/observability-logging`",
26
+ "then": "the exit code is 0, `manifest.blueprints[]` lists observability-logging at version 1.0.0, and `rcf/adr/adr-1601-observability-logging-line-shape.json` exists on disk",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1301-3",
32
+ "description": "The blueprint anatomy is complete: `README.md`, `guide/observability-logging.md`, `docs/topics.md` and `assets/` are present at the blueprint root; the README carries an `Apply` block and a `Known mechanism-reach gaps` section; `docs/topics.md` names the `logging` global topic string with the shelf band 15101-15899 and 16xx suffix block recorded.",
33
+ "given": "the blueprint source directory on disk",
34
+ "when": "the reviewer walks the anatomy",
35
+ "then": "every named file exists, the docs/topics.md table includes the observability-logging row, and the README carries the two required sections",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T12:20:00Z",
42
+ "updatedAt": "2026-09-04T12:20:00Z"
43
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1302",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-013",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Core shelf ships application-error-handling v1.0.0 with providesRoles errorHandling and mints the errorHandling global topic",
8
+ "asA": "operator running rcf define blueprint add on a fresh project that needs a transport-agnostic error-handling contract",
9
+ "iWant": "the shipped core shelf to carry an application-error-handling blueprint (v1.0.0) that provides the errorHandling role, mints the errorHandling global topic on ADR-1701 (distinct from errorEnvelope), and applies cleanly into a fixture project",
10
+ "soThat": "a project falls back to a sensible error-handling contract without registering any library, and the internal error record shape sits one project decision above any transport-specific error-envelope decision",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1302-1",
14
+ "description": "`blueprints/application-error-handling/blueprint.json` exists with `slug: \"application-error-handling\"`, `version: \"1.0.0\"`, `category: \"application\"`, `providesRoles: [\"errorHandling\"]`, and a contributions list carrying four REQs (`application-error-handling-REQ-001` through `-REQ-004`), user stories in the 16101-16899 band (at least `-US-16101` through `-US-16107`), TACs `TAC-1701-application-error-handling-boundary` and `TAC-1702-application-error-handling-record-factory`, and ADRs `ADR-1701` through `ADR-1703` including `ADR-1701-application-error-handling-record-shape` with `scope: \"global\", topic: \"errorHandling\"`.",
15
+ "given": "the shipped core shelf at packages/rcf-lite/blueprints/application-error-handling (staged from the top-level blueprints/ directory)",
16
+ "when": "the loader reads blueprint.json and enumerates contributions[]",
17
+ "then": "the fields resolve to the values above and jq queries return them verbatim",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1302-2",
23
+ "description": "`rcf define blueprint add <path>/blueprints/application-error-handling` applied into a fresh fixture project with no prior applied blueprints succeeds (exit 0), writes `manifest.blueprints[]` with slug `application-error-handling`, and copies the namespaced contribution files.",
24
+ "given": "a fresh fixture project initialised via `rcf init` with no applied blueprints",
25
+ "when": "the operator runs `rcf define blueprint add <path-to>/blueprints/application-error-handling`",
26
+ "then": "the exit code is 0, `manifest.blueprints[]` lists application-error-handling at version 1.0.0, and `rcf/adr/adr-1701-application-error-handling-record-shape.json` exists on disk",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1302-3",
32
+ "description": "The `errorHandling` topic is DISTINCT from `errorEnvelope`; the blueprint's docs/topics.md names both, distinguishes them (errorHandling is the internal record shape and uncaught-exception boundary; errorEnvelope stays with application-api-rest as the REST wire shape), and reserves the 16101-16899 band and 17xx suffix block for the shelf-wide registry.",
33
+ "given": "the blueprint's docs/topics.md file",
34
+ "when": "the reviewer reads the topic table",
35
+ "then": "the errorHandling and errorEnvelope rows are both present, distinct, and the band registry row is recorded",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T12:20:00Z",
42
+ "updatedAt": "2026-09-04T12:20:00Z"
43
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1401",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-014",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Loader accepts and validates providesRoles[] and suggestedCompanions[] on blueprint.json (shape + camelCase + paired-ADR + reason-string)",
8
+ "asA": "blueprint author declaring a companion suggestion or a role provided on a shipped blueprint",
9
+ "iWant": "the loader to accept two additive top-level fields on blueprint.json, validate their shape at load time, and refuse a mis-authored file before the tree is touched",
10
+ "soThat": "a service blueprint can name the roles it recommends and a provider blueprint can name the roles it provides, and mis-shaped or unpaired declarations never reach apply",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1401-1",
14
+ "description": "The loader accepts optional top-level `providesRoles` (non-empty array of lower camelCase strings on the pattern `^[a-z][a-zA-Z0-9]*$`) and optional top-level `suggestedCompanions` (non-empty array of `{role, reason}` objects; `role` is a lower camelCase string; `reason` is a non-empty string with no em-dashes and no emojis). Both fields are independent (a blueprint may provide a role AND suggest another; a blueprint may declare neither). Existing shelf blueprints (application-spa v1.4.0 baseline, observability-essentials v2.0.0, etc.) that declare neither still load clean.",
15
+ "given": "a blueprint.json declaring `providesRoles: [\"logging\"]` and `suggestedCompanions: [{role: \"logging\", reason: \"...\"}]`",
16
+ "when": "the loader parses the file",
17
+ "then": "the LoadedBlueprint object carries both fields verbatim and returns no rcfError; a blueprint declaring neither loads clean",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1401-2",
23
+ "description": "The loader refuses (rcfError kind `validation`, exit 2 at the CLI edge) each of: a `providesRoles` value that fails the lower camelCase pattern (message names the offending index and value); a `suggestedCompanions` entry with a non-string or empty `role`; a `suggestedCompanions` entry with a missing, empty, or whitespace-only `reason`; a `suggestedCompanions` entry whose `reason` contains an em-dash (U+2014) or an emoji.",
24
+ "given": "four separate mis-authored blueprint.json fixtures, one per refusal shape",
25
+ "when": "the loader parses each",
26
+ "then": "each returns an rcfError of kind `validation` with a message naming the offending field and (for arrays) the index",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1401-3",
32
+ "description": "A blueprint that declares a role in `providesRoles[]` MUST also carry a `scope: \"global\"` ADR contribution whose `topic` string equals the role name; the loader refuses otherwise with `providesRoles[] names '<role>' but no scope:global ADR carries topic '<role>'.` and exits 2 at the CLI edge.",
33
+ "given": "a fixture blueprint with `providesRoles: [\"logging\"]` and no ADR contribution carrying `scope: \"global\", topic: \"logging\"`",
34
+ "when": "the loader parses the file",
35
+ "then": "the loader returns an rcfError of kind `validation` with the paired-ADR message exactly as specified",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T12:20:00Z",
42
+ "updatedAt": "2026-09-04T12:20:00Z"
43
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1402",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-014",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "`rcf define blueprint add` prints resolved companion suggestions and accepts --companion selectors that persist to rcf/companions.json",
8
+ "asA": "operator running rcf define blueprint add on a service blueprint that declares suggestedCompanions[]",
9
+ "iWant": "the apply to print the resolved companion set as a suggestion block after a successful apply, and to accept `--companion <role>=<slug>` selectors that record my choice to rcf/companions.json for future runs",
10
+ "soThat": "the mechanism surfaces the suggestion at the moment of the apply, my explicit selection at apply time survives to future re-runs without repeating the flag, and the apply itself never adopts a companion on my behalf",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1402-1",
14
+ "description": "After `rcf define blueprint add <service-slug>` succeeds and the service blueprint declares `suggestedCompanions[]`, stdout carries a block: a header line `Suggested companions this blueprint recommends alongside it:` followed by one line per suggested role in the shape ` <role> -> <resolved-provider> (<origin>)`, where origin reads `registered library '<prefix>'` or `shelf fallback` or `already applied`, and a footer line `Apply either with: rcf define blueprint add <slug>`. The apply itself does not adopt any companion (`manifest.blueprints[]` contains only the service blueprint and any prior applies). `--no-companion-suggestions` suppresses the block entirely and every other apply behaviour is unchanged.",
15
+ "given": "a fixture project with application-api-rest v2.1.0 (or later) applied cleanly and no core companions applied",
16
+ "when": "the operator runs `rcf define blueprint add <path-to>/blueprints/application-api-rest`",
17
+ "then": "the suggestion block prints for `logging` and `errorHandling` roles, manifest.blueprints[] carries only application-api-rest, and passing `--no-companion-suggestions` on the same command produces no suggestion block",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1402-2",
23
+ "description": "`rcf define blueprint add <service-slug> --companion <role>=<slug>` (repeatable) accepts `<libraryPrefix>:<slug>` for a library provider or a bare kebab slug for a shelf provider, validates that the named provider blueprint's `providesRoles[]` contains the role, refuses with exit 2 (`--companion <role>=<slug>: blueprint '<slug>' does not declare providesRoles containing '<role>'.`) when it does not, and writes the accepted choices to `rcf/companions.json` under `roles.<role>.provider` with a `pinnedAt` ISO-8601 timestamp.",
24
+ "given": "a fixture project with application-api-rest applying and the shelf observability-logging blueprint available",
25
+ "when": "the operator runs `rcf define blueprint add <path-to>/blueprints/application-api-rest --companion logging=observability-logging --companion errorHandling=application-error-handling`",
26
+ "then": "the exit code is 0, `rcf/companions.json` exists with `roles.logging.provider = \"observability-logging\"` and `roles.errorHandling.provider = \"application-error-handling\"`, and `--companion logging=observability-essentials` (a non-provider) refuses exit 2 with the specified message",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1402-3",
32
+ "description": "`rcf/companions.json` is created lazily on the first pin (no file when no pins exist), rides git, is human-readable JSON with `schemaVersion: 1`, and carries only the current pin per role (no per-apply history per amendment A1). A re-run of the same `rcf define blueprint add ... --companion ...` command overwrites the pin's `pinnedAt` timestamp but keeps the same provider; a `--companion` naming a different provider than the current pin overwrites the pin and prints one stderr line `[blueprint] companion pin for role '<role>' updated: '<old>' -> '<new>'`.",
33
+ "given": "a fixture project with an existing companions.json pin",
34
+ "when": "the operator re-runs the apply with the same or a different --companion selector",
35
+ "then": "the pin file schema stays valid, the shape matches the spec section 2.4 example (schemaVersion + roles + pinnedAt), and the pin overwrite prints the transition line",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T12:20:00Z",
42
+ "updatedAt": "2026-09-04T12:20:00Z"
43
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "usId": "US-1403",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-014",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "`rcf define blueprint companions` verb: three sub-verbs (print resolution, set pin, unset pin) with --json on all three",
8
+ "asA": "operator inspecting or pinning companion suggestions on an applied service blueprint outside the apply flow",
9
+ "iWant": "a `rcf define blueprint companions <slug>` sub-verb that prints the resolved companion set for one applied service blueprint, `rcf define blueprint companions set <role> <slug>` that writes a project-level pin to rcf/companions.json, and `rcf define blueprint companions unset <role>` that removes a pin",
10
+ "soThat": "I can read the current resolution without re-applying, pin a decision the operator makes outside the apply, and lift a pin cleanly",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-1403-1",
14
+ "description": "`rcf define blueprint companions <slug>` (three positionals: `blueprint`, `companions`, `<slug>`) with `<slug>` naming an applied service blueprint that declares `suggestedCompanions[]` prints on stdout: header `<slug> suggests companions:` and one line per role in the shape ` <role> -> <resolved-provider> (<origin-note>)`, where the origin note reads `already applied` / `pinned via rcf/companions.json` / `registered library '<prefix>' (overrides shelf provider <shelf-slug>)` / `shelf fallback (no registered library provides this role)`. Exit 0. Refuses with exit 2 when `<slug>` names no applied blueprint or the applied blueprint declares no `suggestedCompanions[]`.",
15
+ "given": "a fixture project with application-api-rest v2.1.0 applied and observability-logging applied",
16
+ "when": "the operator runs `rcf define blueprint companions application-api-rest`",
17
+ "then": "stdout carries the header and one line per role with `already applied` on `logging` and `shelf fallback` (or similar) on `errorHandling`; a slug that is not applied refuses exit 2",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-1403-2",
23
+ "description": "`rcf define blueprint companions set <role> <slug>` writes `rcf/companions.json` under `roles.<role>.provider` with `pinnedAt` ISO-8601 (or updates it if present); refuses exit 2 when `<slug>` names no blueprint or the named blueprint does not declare `providesRoles` containing `<role>`. `rcf define blueprint companions unset <role>` removes the `roles.<role>` entry (leaves the rest of the file intact); refuses exit 2 when no pin exists for `<role>`. Both sub-verbs honour `--json` (emit `{ok: true, role, provider, pinnedAt}` on success; `{ok: false, error: {...}}` on refusal).",
24
+ "given": "a fixture project with no existing pin",
25
+ "when": "the operator runs `rcf define blueprint companions set logging observability-logging`, then `rcf define blueprint companions unset logging`",
26
+ "then": "the first run writes companions.json with the pin (exit 0); the second run removes the pin and prints `[blueprint] companion pin for role 'logging' removed` on stdout (exit 0); an unset on a role without a pin refuses exit 2",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-1403-3",
32
+ "description": "`--json` on `rcf define blueprint companions <slug>` emits a machine-readable object: `{slug, suggestions: [{role, provider, origin, notes}]}`, exit 0. The suggestions array preserves the order of the applied blueprint's `suggestedCompanions[]`.",
33
+ "given": "a fixture project with application-api-rest applied and both companions applied",
34
+ "when": "the operator runs `rcf define blueprint companions application-api-rest --json`",
35
+ "then": "stdout carries a JSON object of the shape above and jq queries against it return the resolved provider per role",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "tacIds": [],
41
+ "createdAt": "2026-09-04T12:20:00Z",
42
+ "updatedAt": "2026-09-04T12:20:00Z"
43
+ }