rcf-lite 0.28.2 → 0.29.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 (327) hide show
  1. package/CHANGELOG.md +317 -0
  2. package/bin/rcf.js +8 -0
  3. package/fixtures/canary-manifest.json +9 -9
  4. package/guidance/define-draft-shapes.md +89 -0
  5. package/guidance/define-intake.md +97 -0
  6. package/guidance/define-intent.md +107 -0
  7. package/guidance/discover-prototype.md +67 -0
  8. package/guidance/discovery-prototypes.md +69 -0
  9. package/guidance/harness-template.md +34 -0
  10. package/guidance/managed/agent-instructions-block.hash +1 -1
  11. package/guidance/managed/agent-instructions-block.md +34 -0
  12. package/guidance/manifest.json +9 -2
  13. package/package.json +1 -1
  14. package/rcf/adrs/adr-4120-canonical-json-hashing.json +30 -0
  15. package/rcf/adrs/adr-4121-define-sidecars.json +30 -0
  16. package/rcf/adrs/adr-4122-define-gates-blocking-and-optout.json +30 -0
  17. package/rcf/adrs/adr-4123-readiness-single-object.json +30 -0
  18. package/rcf/adrs/adr-4124-define-freeze-verb.json +30 -0
  19. package/rcf/adrs/adr-4126-persona-tagged-blockers-two-levels.json +40 -0
  20. package/rcf/adrs/adr-4127-readiness-tab-order-and-register.json +40 -0
  21. package/rcf/adrs/adr-4129-questions-harness-driven-loop.json +25 -0
  22. package/rcf/adrs/adr-4130-intake-harness-split-tool-scanned.json +20 -0
  23. package/rcf/adrs/adr-4132-prototypes-in-discovery-as-evidence.json +20 -0
  24. package/rcf/adrs/adr-4133-dag-dependency-depth-layout.json +40 -0
  25. package/rcf/adrs/adr-4134-index-json-route.json +35 -0
  26. package/rcf/adrs/adr-4135-readiness-po-register-and-adapter.json +35 -0
  27. package/rcf/adrs/adr-4136-embedding-host-fixture.json +35 -0
  28. package/rcf/code-nodes/cn-700.json +23 -0
  29. package/rcf/code-nodes/cn-701.json +14 -0
  30. package/rcf/code-nodes/cn-702.json +14 -0
  31. package/rcf/code-nodes/cn-703.json +16 -0
  32. package/rcf/code-nodes/cn-720.json +15 -0
  33. package/rcf/code-nodes/cn-721.json +15 -0
  34. package/rcf/code-nodes/cn-722.json +15 -0
  35. package/rcf/code-nodes/cn-723.json +18 -0
  36. package/rcf/code-nodes/cn-724.json +14 -0
  37. package/rcf/code-nodes/cn-725.json +37 -0
  38. package/rcf/code-nodes/cn-726.json +25 -0
  39. package/rcf/code-nodes/cn-727.json +23 -0
  40. package/rcf/code-nodes/cn-728.json +37 -0
  41. package/rcf/code-nodes/cn-729.json +26 -0
  42. package/rcf/code-nodes/cn-730.json +24 -0
  43. package/rcf/code-nodes/cn-731.json +20 -0
  44. package/rcf/code-nodes/cn-732.json +14 -0
  45. package/rcf/code-nodes/cn-733.json +14 -0
  46. package/rcf/code-nodes/cn-734.json +14 -0
  47. package/rcf/code-nodes/cn-735.json +20 -0
  48. package/rcf/code-nodes/cn-736.json +14 -0
  49. package/rcf/code-nodes/cn-737.json +14 -0
  50. package/rcf/code-nodes/cn-738.json +14 -0
  51. package/rcf/code-nodes/cn-739.json +18 -0
  52. package/rcf/code-nodes/cn-740.json +19 -0
  53. package/rcf/code-nodes/cn-741.json +16 -0
  54. package/rcf/code-nodes/cn-742.json +16 -0
  55. package/rcf/code-nodes/cn-743.json +15 -0
  56. package/rcf/code-nodes/cn-744.json +22 -0
  57. package/rcf/code-nodes/cn-745.json +16 -0
  58. package/rcf/code-nodes/cn-746.json +14 -0
  59. package/rcf/code-nodes/cn-747.json +18 -0
  60. package/rcf/code-nodes/cn-748.json +16 -0
  61. package/rcf/code-nodes/cn-749.json +16 -0
  62. package/rcf/code-nodes/cn-750.json +15 -0
  63. package/rcf/code-nodes/cn-751.json +18 -0
  64. package/rcf/code-nodes/cn-752.json +14 -0
  65. package/rcf/fbs/fbs-190.json +37 -0
  66. package/rcf/fbs/fbs-191.json +34 -0
  67. package/rcf/fbs/fbs-192.json +17 -0
  68. package/rcf/fbs/fbs-193.json +37 -0
  69. package/rcf/fbs/fbs-194.json +35 -0
  70. package/rcf/fbs/fbs-195.json +37 -0
  71. package/rcf/fbs/fbs-196.json +45 -0
  72. package/rcf/fbs/fbs-197.json +41 -0
  73. package/rcf/fbs/fbs-198.json +42 -0
  74. package/rcf/fbs/fbs-199.json +59 -0
  75. package/rcf/fbs/fbs-200.json +46 -0
  76. package/rcf/fbs/fbs-201.json +49 -0
  77. package/rcf/fbs/fbs-202.json +110 -0
  78. package/rcf/fbs/fbs-203.json +100 -0
  79. package/rcf/requirements/req-001.json +2 -1
  80. package/rcf/requirements/req-002.json +3 -2
  81. package/rcf/requirements/req-003.json +2 -1
  82. package/rcf/requirements/req-004.json +2 -1
  83. package/rcf/requirements/req-005.json +2 -1
  84. package/rcf/requirements/req-006.json +2 -1
  85. package/rcf/requirements/req-007.json +2 -1
  86. package/rcf/requirements/req-008.json +2 -1
  87. package/rcf/requirements/req-009.json +2 -1
  88. package/rcf/requirements/req-010.json +5 -2
  89. package/rcf/requirements/req-011.json +2 -1
  90. package/rcf/requirements/req-012.json +2 -1
  91. package/rcf/requirements/req-013.json +2 -1
  92. package/rcf/requirements/req-014.json +2 -1
  93. package/rcf/requirements/req-015.json +2 -1
  94. package/rcf/requirements/req-016.json +5 -2
  95. package/rcf/requirements/req-017.json +6 -2
  96. package/rcf/requirements/req-018.json +5 -2
  97. package/rcf/requirements/req-019.json +5 -2
  98. package/rcf/requirements/req-020.json +5 -2
  99. package/rcf/requirements/req-021.json +5 -2
  100. package/rcf/requirements/req-022.json +5 -2
  101. package/rcf/requirements/req-023.json +6 -4
  102. package/rcf/requirements/req-024.json +5 -2
  103. package/rcf/requirements/req-025.json +5 -2
  104. package/rcf/requirements/req-026.json +5 -2
  105. package/rcf/requirements/req-027.json +5 -2
  106. package/rcf/requirements/req-028.json +5 -2
  107. package/rcf/requirements/req-029.json +5 -2
  108. package/rcf/requirements/req-030.json +5 -2
  109. package/rcf/requirements/req-040.json +5 -2
  110. package/rcf/requirements/req-041.json +5 -2
  111. package/rcf/requirements/req-042.json +5 -2
  112. package/rcf/requirements/req-043.json +5 -2
  113. package/rcf/requirements/req-050.json +5 -2
  114. package/rcf/requirements/req-051.json +5 -2
  115. package/rcf/requirements/req-052.json +5 -2
  116. package/rcf/requirements/req-053.json +5 -2
  117. package/rcf/requirements/req-054.json +5 -2
  118. package/rcf/requirements/req-060.json +5 -2
  119. package/rcf/requirements/req-061.json +5 -2
  120. package/rcf/requirements/req-062.json +5 -2
  121. package/rcf/requirements/req-063.json +5 -2
  122. package/rcf/requirements/req-070.json +5 -2
  123. package/rcf/requirements/req-071.json +5 -2
  124. package/rcf/requirements/req-072.json +5 -2
  125. package/rcf/requirements/req-073.json +5 -2
  126. package/rcf/requirements/req-074.json +5 -2
  127. package/rcf/requirements/req-075.json +5 -2
  128. package/rcf/requirements/req-076.json +5 -2
  129. package/rcf/requirements/req-077.json +5 -2
  130. package/rcf/requirements/req-080.json +5 -2
  131. package/rcf/requirements/req-081.json +5 -2
  132. package/rcf/requirements/req-082.json +5 -2
  133. package/rcf/requirements/req-083.json +5 -2
  134. package/rcf/requirements/req-084.json +5 -2
  135. package/rcf/requirements/req-085.json +5 -2
  136. package/rcf/requirements/req-086.json +5 -2
  137. package/rcf/requirements/req-090.json +5 -2
  138. package/rcf/requirements/req-091.json +5 -2
  139. package/rcf/requirements/req-092.json +5 -2
  140. package/rcf/requirements/req-093.json +5 -2
  141. package/rcf/requirements/req-094.json +5 -2
  142. package/rcf/requirements/req-100.json +5 -2
  143. package/rcf/requirements/req-101.json +5 -2
  144. package/rcf/requirements/req-102.json +5 -2
  145. package/rcf/requirements/req-103.json +5 -2
  146. package/rcf/requirements/req-104.json +5 -2
  147. package/rcf/requirements/req-110.json +5 -2
  148. package/rcf/requirements/req-111.json +5 -2
  149. package/rcf/requirements/req-112.json +5 -2
  150. package/rcf/requirements/req-113.json +5 -2
  151. package/rcf/requirements/req-114.json +5 -2
  152. package/rcf/requirements/req-115.json +5 -2
  153. package/rcf/requirements/req-120.json +5 -2
  154. package/rcf/requirements/req-121.json +5 -2
  155. package/rcf/requirements/req-122.json +5 -2
  156. package/rcf/requirements/req-123.json +5 -2
  157. package/rcf/requirements/req-124.json +5 -2
  158. package/rcf/requirements/req-125.json +5 -2
  159. package/rcf/requirements/req-130.json +6 -2
  160. package/rcf/requirements/req-131.json +6 -2
  161. package/rcf/requirements/req-132.json +6 -2
  162. package/rcf/requirements/req-133.json +6 -2
  163. package/rcf/requirements/req-134.json +6 -2
  164. package/rcf/requirements/req-140.json +5 -2
  165. package/rcf/requirements/req-145.json +5 -2
  166. package/rcf/requirements/req-150.json +6 -2
  167. package/rcf/requirements/req-151.json +6 -2
  168. package/rcf/requirements/req-152.json +6 -2
  169. package/rcf/requirements/req-153.json +6 -2
  170. package/rcf/requirements/req-154.json +5 -2
  171. package/rcf/requirements/req-155.json +4 -1
  172. package/rcf/requirements/req-156.json +4 -1
  173. package/rcf/requirements/req-157.json +4 -1
  174. package/rcf/requirements/req-158.json +4 -1
  175. package/rcf/requirements/req-159.json +4 -1
  176. package/rcf/requirements/req-160.json +4 -1
  177. package/rcf/requirements/req-161.json +4 -1
  178. package/rcf/requirements/req-162.json +4 -1
  179. package/rcf/requirements/req-163.json +5 -2
  180. package/rcf/requirements/req-164.json +5 -2
  181. package/rcf/requirements/req-165.json +5 -2
  182. package/rcf/requirements/req-170.json +33 -0
  183. package/rcf/requirements/req-171.json +44 -0
  184. package/rcf/requirements/req-172.json +25 -0
  185. package/rcf/requirements/req-173.json +25 -0
  186. package/rcf/requirements/req-174.json +31 -0
  187. package/rcf/requirements/req-175.json +31 -0
  188. package/rcf/requirements/req-176.json +25 -0
  189. package/rcf/requirements/req-180.json +31 -0
  190. package/rcf/requirements/req-181.json +31 -0
  191. package/rcf/requirements/req-182.json +25 -0
  192. package/rcf/requirements/req-186.json +25 -0
  193. package/rcf/requirements/req-187.json +31 -0
  194. package/rcf/requirements/req-188.json +25 -0
  195. package/rcf/tacs/tac-4120-define-delta-and-freeze.json +21 -0
  196. package/rcf/tacs/tac-4121-define-ledgers.json +35 -0
  197. package/rcf/tacs/tac-4122-define-gates.json +61 -0
  198. package/rcf/tacs/tac-4123-define-readiness.json +61 -0
  199. package/rcf/tacs/tac-4124-define-freeze.json +28 -0
  200. package/rcf/tacs/tac-4127-readiness-view.json +49 -0
  201. package/rcf/tacs/tac-4128-define-guidance.json +53 -0
  202. package/rcf/tacs/tac-4129-define-questions.json +45 -0
  203. package/rcf/tacs/tac-4130-define-intake-brief.json +35 -0
  204. package/rcf/tacs/tac-4131-build-dag-view.json +39 -0
  205. package/rcf/tacs/tac-4132-id-lookup.json +42 -0
  206. package/rcf/tacs/tac-4133-readiness-po-layer.json +37 -0
  207. package/rcf/tacs/tac-4134-wespa-host-fixture.json +54 -0
  208. package/rcf/test-suites/ts-016.json +3 -3
  209. package/rcf/test-suites/ts-204.json +30 -0
  210. package/rcf/test-suites/ts-205.json +22 -0
  211. package/rcf/test-suites/ts-206.json +22 -0
  212. package/rcf/test-suites/ts-207.json +22 -0
  213. package/rcf/test-suites/ts-208.json +22 -0
  214. package/rcf/test-suites/ts-209.json +22 -0
  215. package/rcf/test-suites/ts-210.json +22 -0
  216. package/rcf/test-suites/ts-211.json +22 -0
  217. package/rcf/test-suites/ts-212.json +22 -0
  218. package/rcf/test-suites/ts-213.json +50 -0
  219. package/rcf/test-suites/ts-214.json +74 -0
  220. package/rcf/test-suites/ts-215.json +211 -0
  221. package/rcf/test-suites/ts-216.json +94 -0
  222. package/rcf/test-suites/ts-217.json +62 -0
  223. package/rcf/test-suites/ts-218.json +78 -0
  224. package/rcf/test-suites/ts-219.json +70 -0
  225. package/rcf/test-suites/ts-220.json +78 -0
  226. package/rcf/test-suites/ts-221.json +78 -0
  227. package/rcf/test-suites/ts-222.json +100 -0
  228. package/rcf/test-suites/ts-223.json +94 -0
  229. package/rcf/test-suites/ts-224.json +70 -0
  230. package/rcf/test-suites/ts-225.json +78 -0
  231. package/rcf/test-suites/ts-226.json +158 -0
  232. package/rcf/test-suites/ts-227.json +38 -0
  233. package/rcf/test-suites/ts-228.json +86 -0
  234. package/rcf/test-suites/ts-229.json +83 -0
  235. package/rcf/user-stories/us-15601.json +4 -4
  236. package/rcf/user-stories/us-17001.json +27 -0
  237. package/rcf/user-stories/us-17002.json +22 -0
  238. package/rcf/user-stories/us-17003.json +22 -0
  239. package/rcf/user-stories/us-17004.json +22 -0
  240. package/rcf/user-stories/us-17005.json +22 -0
  241. package/rcf/user-stories/us-17006.json +21 -0
  242. package/rcf/user-stories/us-17007.json +21 -0
  243. package/rcf/user-stories/us-17008.json +22 -0
  244. package/rcf/user-stories/us-17101.json +22 -0
  245. package/rcf/user-stories/us-17102.json +22 -0
  246. package/rcf/user-stories/us-17201.json +38 -0
  247. package/rcf/user-stories/us-17301.json +38 -0
  248. package/rcf/user-stories/us-17302.json +50 -0
  249. package/rcf/user-stories/us-17401.json +70 -0
  250. package/rcf/user-stories/us-17402.json +55 -0
  251. package/rcf/user-stories/us-17403.json +60 -0
  252. package/rcf/user-stories/us-17501.json +48 -0
  253. package/rcf/user-stories/us-17502.json +60 -0
  254. package/rcf/user-stories/us-17503.json +65 -0
  255. package/rcf/user-stories/us-17601.json +58 -0
  256. package/rcf/user-stories/us-18001.json +55 -0
  257. package/rcf/user-stories/us-18002.json +35 -0
  258. package/rcf/user-stories/us-18101.json +35 -0
  259. package/rcf/user-stories/us-18202.json +40 -0
  260. package/rcf/user-stories/us-18601.json +55 -0
  261. package/rcf/user-stories/us-18602.json +50 -0
  262. package/rcf/user-stories/us-18603.json +45 -0
  263. package/rcf/user-stories/us-18701.json +50 -0
  264. package/rcf/user-stories/us-18702.json +50 -0
  265. package/rcf/user-stories/us-18801.json +45 -0
  266. package/rcf/user-stories/us-204.json +59 -0
  267. package/rcf/user-stories/us-205.json +64 -0
  268. package/rcf/user-stories/us-206.json +54 -0
  269. package/releases/releases.yaml +31 -1
  270. package/src/cli/feedback.js +126 -10
  271. package/src/cli/freeze.js +730 -0
  272. package/src/cli/help.js +23 -0
  273. package/src/cli/ledger.js +615 -0
  274. package/src/cli/questions.js +288 -0
  275. package/src/cli/readiness.js +498 -0
  276. package/src/cli/view.js +29 -0
  277. package/src/core/store/writer.js +86 -6
  278. package/src/define/freeze-record.js +247 -0
  279. package/src/define/ledgers.js +712 -0
  280. package/src/feedback/redact.js +105 -19
  281. package/src/intake/index.js +1 -1
  282. package/src/intake/orchestrator.js +117 -0
  283. package/src/mcp/tools.js +354 -0
  284. package/src/query/delta.js +282 -0
  285. package/src/query/gates.js +1107 -0
  286. package/src/query/index.js +50 -0
  287. package/src/query/questions.js +438 -0
  288. package/src/query/readiness.js +574 -0
  289. package/src/server/index.js +60 -1
  290. package/src/server/routes.js +133 -4
  291. package/src/setup/identity-seed.js +17 -0
  292. package/src/view/build-dag.js +563 -0
  293. package/src/view/components/badge.js +41 -0
  294. package/src/view/components/diff.js +72 -0
  295. package/src/view/components/doc-row.js +62 -0
  296. package/src/view/components/empty-state.js +35 -0
  297. package/src/view/components/entity-selector.js +137 -0
  298. package/src/view/components/filter-bar.js +97 -0
  299. package/src/view/components/findings-list.js +49 -0
  300. package/src/view/components/index.js +12 -0
  301. package/src/view/components/pill.js +46 -0
  302. package/src/view/components/sub-tab-strip.js +43 -0
  303. package/src/view/components/toast.js +25 -0
  304. package/src/view/components-fixture.js +265 -0
  305. package/src/view/doc-renderers/architecture.js +304 -0
  306. package/src/view/doc-renderers/build.js +160 -0
  307. package/src/view/doc-renderers/helpers.js +2 -2
  308. package/src/view/doc-renderers/index.js +2 -0
  309. package/src/view/doc-renderers/prd.js +35 -6
  310. package/src/view/doc-renderers/req.js +10 -2
  311. package/src/view/doc-renderers/user-story.js +10 -5
  312. package/src/view/html-page.js +717 -300
  313. package/src/view/index.js +109 -3
  314. package/src/view/live-client.js +61 -8
  315. package/src/view/needs-work.js +79 -0
  316. package/src/view/page-init.js +2193 -0
  317. package/src/view/product-map.js +751 -0
  318. package/src/view/readiness/phrasebook.js +115 -0
  319. package/src/view/readiness/po-layer.js +288 -0
  320. package/src/view/readiness/question-adapter.js +329 -0
  321. package/src/view/readiness/stage-legend.js +71 -0
  322. package/src/view/readiness.js +505 -0
  323. package/src/view/style.css +2279 -266
  324. package/src/view/test-host/embed-client.js +121 -0
  325. package/src/view/test-host/fixture.js +183 -0
  326. package/src/view/test-host/lints.js +220 -0
  327. package/src/view/view-index.js +323 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": "TS-207",
3
+ "usId": "US-17004",
4
+ "title": "Product Map trace coverage",
5
+ "purpose": "Cover AC-17004-1: each REQ bucketed by trace completeness with a plain-text \"what is missing\" line.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-17004-1"
9
+ ],
10
+ "testCases": [
11
+ {
12
+ "id": "TC-207-trace-coverage-buckets",
13
+ "acId": "AC-17004-1",
14
+ "description": "Trace coverage grouping buckets each REQ into the FIRST bucket whose rule it meets (missing-stories, missing-ac-scope, missing-component, missing-tests, complete); a synthetic fixture asserts the classification per REQ id, including the P1-4 dangling-TAC case landing in missing-component.",
15
+ "status": "passing",
16
+ "testPointer": "test/view/product-map.test.js::product-map trace coverage places each REQ in the FIRST bucket whose condition it meets, on a synthetic fixture (P2-3)"
17
+ }
18
+ ],
19
+ "status": "approved",
20
+ "createdAt": "2026-09-21T17:00:00.000Z",
21
+ "updatedAt": "2026-09-21T18:02:10.973Z"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": "TS-208",
3
+ "usId": "US-17005",
4
+ "title": "Product Map capability grouping",
5
+ "purpose": "Cover AC-17005-1: capability:<slug> tag consumption and Unclassified bucket.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-17005-1"
9
+ ],
10
+ "testCases": [
11
+ {
12
+ "id": "TC-208-capability-buckets",
13
+ "acId": "AC-17005-1",
14
+ "description": "Capability grouping enumerates one bucket per distinct capability:<slug> tag; multi-tag REQs appear in each bucket; untagged REQs go to Unclassified.",
15
+ "status": "passing",
16
+ "testPointer": "test/view/product-map.test.js::product-map capability grouping enumerates one bucket per capability slug with Unclassified for untagged REQs"
17
+ }
18
+ ],
19
+ "status": "approved",
20
+ "createdAt": "2026-09-21T17:00:00.000Z",
21
+ "updatedAt": "2026-09-21T17:00:00.000Z"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": "TS-209",
3
+ "usId": "US-17101",
4
+ "title": "Dogfood REQs carry capability tags",
5
+ "purpose": "Cover AC-17101-1: every REQ file carries at least one capability:<slug> tag drawn from the documented taxonomy.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-17101-1"
9
+ ],
10
+ "testCases": [
11
+ {
12
+ "id": "TC-209-every-req-has-capability-tag",
13
+ "acId": "AC-17101-1",
14
+ "description": "Every requirement file under packages/rcf-lite/rcf/requirements/ carries at least one capability:<slug> tag, and each slug is listed in docs/capability-tags.md.",
15
+ "status": "passing",
16
+ "testPointer": "test/view/capability-tags.test.js::every dogfood REQ carries at least one capability tag mapped to a documented slug"
17
+ }
18
+ ],
19
+ "status": "approved",
20
+ "createdAt": "2026-09-21T17:00:00.000Z",
21
+ "updatedAt": "2026-09-21T17:00:00.000Z"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": "TS-210",
3
+ "usId": "US-17102",
4
+ "title": "Capability taxonomy documented",
5
+ "purpose": "Cover AC-17102-1: docs/capability-tags.md exists and is linked from docs/README.md.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-17102-1"
9
+ ],
10
+ "testCases": [
11
+ {
12
+ "id": "TC-210-taxonomy-doc-present",
13
+ "acId": "AC-17102-1",
14
+ "description": "docs/capability-tags.md exists, lists every taxonomy slug with a one-line meaning, states the \"add a capability\" rule, and is linked from docs/README.md.",
15
+ "status": "passing",
16
+ "testPointer": "test/view/capability-tags.test.js::docs carry the capability taxonomy and link to it from the docs README"
17
+ }
18
+ ],
19
+ "status": "approved",
20
+ "createdAt": "2026-09-21T17:00:00.000Z",
21
+ "updatedAt": "2026-09-21T17:00:00.000Z"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "createdAt": "2026-09-21T18:46:16.398Z",
3
+ "updatedAt": "2026-09-21T18:46:16.604Z",
4
+ "purpose": "Cover the collapsed-by-default buckets, jump-nav rail, per-status mini counts, expand/collapse-all and open-bucket hash restore for AC-17006-1.",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-17006-1"
8
+ ],
9
+ "id": "TS-211",
10
+ "usId": "US-17006",
11
+ "title": "Product Map interaction model",
12
+ "testCases": [
13
+ {
14
+ "id": "TC-211-interaction-model-buckets",
15
+ "acId": "AC-17006-1",
16
+ "description": "Every bucket renders as a collapsed <details class=pm-bucket> with a per-status mini row and a jump-nav chip row per grouping.",
17
+ "status": "pending",
18
+ "testPointer": "test/view/product-map.test.js::product-map buckets are <details class=\"pm-bucket\"> collapsed by default with a per-status mini row (AC-17006-1)"
19
+ }
20
+ ],
21
+ "status": "draft"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "createdAt": "2026-09-21T18:46:16.821Z",
3
+ "updatedAt": "2026-09-21T18:46:17.106Z",
4
+ "purpose": "Cover the initial-render skeletons and raw-JSON suppression the lazy render depends on for AC-17007-1.",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-17007-1"
8
+ ],
9
+ "id": "TS-212",
10
+ "usId": "US-17007",
11
+ "title": "Product Map lazy first-load payload",
12
+ "testCases": [
13
+ {
14
+ "id": "TC-212-lazy-skeletons",
15
+ "acId": "AC-17007-1",
16
+ "description": "Initial contentHtml emits data-pm-lazy=true skeletons for every grouping and never inlines a raw-JSON disclosure inside a pm-req card.",
17
+ "status": "pending",
18
+ "testPointer": "test/view/product-map.test.js::product-map lazy render: initial contentHtml emits skeletons for every grouping (AC-17007-1)"
19
+ }
20
+ ],
21
+ "status": "draft"
22
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "createdAt": "2026-09-22T11:59:39Z",
3
+ "updatedAt": "2026-09-22T15:00:00Z",
4
+ "purpose": "Cover the blueprint badge on every REQ row and the by-blueprint grouping (bucket per applied blueprint plus Application bucket, capability second level, hash round-trip, /product-map/blueprint partial endpoint) for AC-17008-1.",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-17008-1"
8
+ ],
9
+ "id": "TS-213",
10
+ "usId": "US-17008",
11
+ "title": "Product Map by-blueprint grouping and blueprint badge",
12
+ "testCases": [
13
+ {
14
+ "id": "TC-213-badge",
15
+ "acId": "AC-17008-1",
16
+ "description": "In the shape grouping rendered over a fixture project that applies one blueprint contributing two REQs, both contributed REQ rows carry a pm-blueprint-badge in their summary while the non-blueprint (Application) REQ rows do not.",
17
+ "status": "pending",
18
+ "testPointer": "test/view/product-map.test.js::product-map: blueprint badge on every contributed REQ row across groupings (AC-17008-1)"
19
+ },
20
+ {
21
+ "id": "TC-213-buckets",
22
+ "acId": "AC-17008-1",
23
+ "description": "The by-blueprint grouping over a fixture with one applied blueprint (2 contributed REQs) and 2 non-blueprint REQs renders exactly two buckets: a blueprint bucket with count 2 and an Application bucket with count 2.",
24
+ "status": "pending",
25
+ "testPointer": "test/view/product-map.test.js::product-map: by-blueprint grouping yields one bucket per applied blueprint plus an Application bucket (AC-17008-1)"
26
+ },
27
+ {
28
+ "id": "TC-213-capability-second-level",
29
+ "acId": "AC-17008-1",
30
+ "description": "Inside each by-blueprint bucket the second level is capability (existing capability:<slug> tags), then requirement rows, then the usual drill-down.",
31
+ "status": "pending",
32
+ "testPointer": "test/view/product-map.test.js::product-map: by-blueprint bucket second level is capability then REQ (AC-17008-1)"
33
+ },
34
+ {
35
+ "id": "TC-213-hash-and-lazy-endpoint",
36
+ "acId": "AC-17008-1",
37
+ "description": "The inline script's PM_GROUPS constant lists 'blueprint', the lazy fetch endpoint /product-map/blueprint is exposed on the pre-rendered pmPartials, and renderProductMapGrouping(model, 'blueprint') returns a non-empty string.",
38
+ "status": "pending",
39
+ "testPointer": "test/view/product-map.test.js::product-map: by-blueprint grouping wired into PM_GROUPS, pmPartials and renderProductMapGrouping (AC-17008-1)"
40
+ },
41
+ {
42
+ "id": "TC-213-empty-blueprints",
43
+ "acId": "AC-17008-1",
44
+ "description": "A project with no applied blueprints (manifest.blueprints empty) renders the by-blueprint grouping with a single Application bucket and no error banner.",
45
+ "status": "pending",
46
+ "testPointer": "test/view/product-map.test.js::product-map: by-blueprint grouping on a project with no applied blueprints renders a single Application bucket (AC-17008-1)"
47
+ }
48
+ ],
49
+ "status": "draft"
50
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "createdAt": "2026-09-24T12:00:00Z",
3
+ "updatedAt": "2026-09-24T12:00:00Z",
4
+ "purpose": "Cover the delta-detection primitives (hashDocument, computeTreeHash, computeDelta) and the freeze record I/O (load, save, validate) against AC-17201-1..4 on US-17201.",
5
+ "testLevel": "unit",
6
+ "acIds": [
7
+ "AC-17201-1",
8
+ "AC-17201-2",
9
+ "AC-17201-3",
10
+ "AC-17201-4"
11
+ ],
12
+ "id": "TS-214",
13
+ "usId": "US-17201",
14
+ "title": "Delta detection and freeze record primitives",
15
+ "testCases": [
16
+ {
17
+ "id": "TC-214-delta-shape",
18
+ "acId": "AC-17201-1",
19
+ "description": "computeDelta returns the shape proposal section 2.2 pins: frozen / frozenAt / treeHash / currentTreeHash / changed / added / removed / briefSince / unchanged, and classifies changed / added / removed correctly against a divergent freeze record.",
20
+ "status": "pending",
21
+ "testPointer": "test/query/delta.test.js::delta: changed / added / removed classify against the freeze record"
22
+ },
23
+ {
24
+ "id": "TC-214-unchanged",
25
+ "acId": "AC-17201-1",
26
+ "description": "A tree that matches the freeze record produces empty changed / added / removed lists and unchanged equal to the docHashes count.",
27
+ "status": "pending",
28
+ "testPointer": "test/query/delta.test.js::delta: an unchanged tree against a matching freeze reports empty changed/added/removed"
29
+ },
30
+ {
31
+ "id": "TC-214-canonical",
32
+ "acId": "AC-17201-2",
33
+ "description": "hashDocument is invariant under a whitespace-only reformat: two documents that parse to the same object hash identically and produce zero changed entries in the delta.",
34
+ "status": "pending",
35
+ "testPointer": "test/query/delta.test.js::delta: a whitespace-only reformat of a document produces zero changed ids"
36
+ },
37
+ {
38
+ "id": "TC-214-hash-shape",
39
+ "acId": "AC-17201-2",
40
+ "description": "hashDocument returns a sha256:<64-hex> string over the canonical JSON form of the parsed document.",
41
+ "status": "pending",
42
+ "testPointer": "test/query/delta.test.js::delta: hashDocument returns a sha256:<64-hex> string over the canonical form"
43
+ },
44
+ {
45
+ "id": "TC-214-freeze-missing",
46
+ "acId": "AC-17201-3",
47
+ "description": "loadFreezeRecord returns null when rcf/define/freeze.json is absent; a malformed body raises FreezeRecordError with the parseFailure code.",
48
+ "status": "pending",
49
+ "testPointer": "test/define/freeze-record.test.js::freeze-record: a malformed JSON body raises FreezeRecordError with parseFailure code"
50
+ },
51
+ {
52
+ "id": "TC-214-freeze-schema",
53
+ "acId": "AC-17201-3",
54
+ "description": "A body with a non-sha256 docHashes value is refused with a FreezeRecordError naming the failing docHashes.<id> field.",
55
+ "status": "pending",
56
+ "testPointer": "test/define/freeze-record.test.js::freeze-record: docHashes with a non-sha256 value is refused"
57
+ },
58
+ {
59
+ "id": "TC-214-roundtrip",
60
+ "acId": "AC-17201-4",
61
+ "description": "saveFreezeRecord followed by loadFreezeRecord round-trips every field including unknown extension fields (counts, litmus, versions, note).",
62
+ "status": "pending",
63
+ "testPointer": "test/define/freeze-record.test.js::freeze-record: unknown top-level fields survive a save/load round trip"
64
+ },
65
+ {
66
+ "id": "TC-214-refuse-invalid-write",
67
+ "acId": "AC-17201-4",
68
+ "description": "saveFreezeRecord refuses an invalid record and writes nothing to disk.",
69
+ "status": "pending",
70
+ "testPointer": "test/define/freeze-record.test.js::freeze-record: saveFreezeRecord refuses to write an invalid record"
71
+ }
72
+ ],
73
+ "status": "draft"
74
+ }
@@ -0,0 +1,211 @@
1
+ {
2
+ "createdAt": "2026-09-24T12:00:00Z",
3
+ "updatedAt": "2026-10-02T16:40:00Z",
4
+ "purpose": "Cover the four sidecar ledgers, the rcf define ledger CLI (add / resolve / list with --json) and the walker-invisibility invariant on rcf/define/ (AC-17301-1..4 on US-17301), the update subverb and the closed resolvedBy pointer grammar (AC-17302-1..6 on US-17302), the statement-file markers (AC-18701-1..6 on US-18701) and the scan wiring (AC-18702-1..6 on US-18702).",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-17301-1",
8
+ "AC-17301-2",
9
+ "AC-17301-3",
10
+ "AC-17301-4",
11
+ "AC-17302-1",
12
+ "AC-17302-2",
13
+ "AC-17302-3",
14
+ "AC-17302-4",
15
+ "AC-17302-5",
16
+ "AC-17302-6",
17
+ "AC-18701-1",
18
+ "AC-18701-2",
19
+ "AC-18701-3",
20
+ "AC-18701-4",
21
+ "AC-18701-5",
22
+ "AC-18701-6",
23
+ "AC-18702-1",
24
+ "AC-18702-2",
25
+ "AC-18702-3",
26
+ "AC-18702-4",
27
+ "AC-18702-5",
28
+ "AC-18702-6"
29
+ ],
30
+ "id": "TS-215",
31
+ "usId": "US-17301",
32
+ "title": "Sidecar ledgers, rcf define ledger and walker invisibility (extended for update + intake markers + scans)",
33
+ "testCases": [
34
+ {
35
+ "id": "TC-215-brief-add-text",
36
+ "acId": "AC-17301-1",
37
+ "description": "rcf define ledger brief add --text mints id 1 with status open, kind capability by default, and writes rcf/define/brief-ledger.json.",
38
+ "status": "pending",
39
+ "testPointer": "test/cli/ledger.test.js::ledger CLI: brief add --text appends a numbered statement"
40
+ },
41
+ {
42
+ "id": "TC-215-brief-refuse-mixed",
43
+ "acId": "AC-17301-1",
44
+ "description": "rcf define ledger brief add refuses conflicting --text and --from with a usage-class error (exit 2).",
45
+ "status": "pending",
46
+ "testPointer": "test/cli/ledger.test.js::ledger CLI: brief add refuses conflicting --text and --from with a usage error"
47
+ },
48
+ {
49
+ "id": "TC-215-decisions-list-241",
50
+ "acId": "AC-17301-2",
51
+ "description": "rcf define ledger decisions list prints the numbered #241 format: question, options as 'letter) text', default and blocks labelled on their own lines.",
52
+ "status": "pending",
53
+ "testPointer": "test/cli/ledger.test.js::ledger CLI: decisions list prints the numbered #241 format"
54
+ },
55
+ {
56
+ "id": "TC-215-list-json",
57
+ "acId": "AC-17301-2",
58
+ "description": "rcf define ledger <name> list --json emits { ledger, <arrayKey>: [...] } with the same body loadLedger returns.",
59
+ "status": "pending",
60
+ "testPointer": "test/cli/ledger.test.js::ledger CLI: list --json emits the machine-readable envelope"
61
+ },
62
+ {
63
+ "id": "TC-215-brief-from-file",
64
+ "acId": "AC-17301-3",
65
+ "description": "rcf define ledger brief add --from <file> splits by non-empty lines, mints sequential ids and writes every statement with the resolved kind.",
66
+ "status": "pending",
67
+ "testPointer": "test/cli/ledger.test.js::ledger CLI: brief add --from <file> splits by non-empty line"
68
+ },
69
+ {
70
+ "id": "TC-215-parse-brief-bullets",
71
+ "acId": "AC-17301-3",
72
+ "description": "parseBriefFromFile strips leading '- ', '* ' and '<n>. ' bullets so drafts match the raw statement text.",
73
+ "status": "pending",
74
+ "testPointer": "test/define/ledgers.test.js::ledgers: parseBriefFromFile splits by non-empty lines and strips bullets"
75
+ },
76
+ {
77
+ "id": "TC-215-walker-invisible",
78
+ "acId": "AC-17301-4",
79
+ "description": "walkTree run over a project seeded with rcf/define/freeze.json, the four ledger files and a bug-bait req-999.json under rcf/define/ never surfaces any rcf/define/ path in errors or byId.",
80
+ "status": "pending",
81
+ "testPointer": "test/store/walker-invisible-define.test.js::walkTree never surfaces rcf/define/ files as documents in byId"
82
+ },
83
+ {
84
+ "id": "TC-215-brief-update-fields-and-preserve-id",
85
+ "acId": "AC-17302-1",
86
+ "description": "updateEntry patches brief fields (kind, resolvedBy) and preserves id and addedAt; the CLI brief update subverb returns 0 and the write lands on the ledger with the patched fields.",
87
+ "status": "pending",
88
+ "testPointer": "test/define/ledgers.test.js::updateEntry (AC-17302-1): patches brief fields and preserves id / addedAt"
89
+ },
90
+ {
91
+ "id": "TC-215-decisions-update-wellformed",
92
+ "acId": "AC-17302-2",
93
+ "description": "decisions update patches options and default so decisions:wellFormed shape passes (two options + a default).",
94
+ "status": "pending",
95
+ "testPointer": "test/define/ledgers.test.js::updateEntry (AC-17302-2): decisions update patches options and default and passes wellFormed shape"
96
+ },
97
+ {
98
+ "id": "TC-215-resolvedby-grammar-each-form",
99
+ "acId": "AC-17302-3",
100
+ "description": "Each resolvedBy pointer form (REQ-nnn, TAD.entity:<name>, PRD.user:<name>, TAD.system:<name>, TAC-nnnn, omitted:<reason>) resolves on the fixture and D2's skeleton:resolvedBy passes it.",
101
+ "status": "pending",
102
+ "testPointer": "test/query/gates.test.js::gates (REQ-173, AC-17302-3): each pointer form resolves on the fixture"
103
+ },
104
+ {
105
+ "id": "TC-215-update-refuses-nongrammar",
106
+ "acId": "AC-17302-4",
107
+ "description": "brief update --resolved-by with a free-text pointer exits 2 naming the grammar and the ledger is unchanged.",
108
+ "status": "pending",
109
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-17302-4): brief update --resolved-by outside the grammar exits 2 and writes nothing"
110
+ },
111
+ {
112
+ "id": "TC-215-d2-dangling-pointer-fails",
113
+ "acId": "AC-17302-5",
114
+ "description": "A statement with resolvedBy REQ-999 on a tree with no REQ-999 fails skeleton:resolvedBy with 'pointer does not resolve'.",
115
+ "status": "pending",
116
+ "testPointer": "test/query/gates.test.js::gates (REQ-173, AC-17302-5): REQ-999 fails with \"pointer does not resolve\""
117
+ },
118
+ {
119
+ "id": "TC-215-d2-title-hit-dropped",
120
+ "acId": "AC-17302-6",
121
+ "description": "In 0.30.0 skeleton:resolvedBy no longer passes a statement on a REQ-title text hit alone; a resolvedBy pointer is required.",
122
+ "status": "pending",
123
+ "testPointer": "test/query/gates.test.js::gates (REQ-173, AC-17302-6): a text-title hit alone does NOT pass in 0.30.0"
124
+ },
125
+ {
126
+ "id": "TC-215-markers-kind-and-source",
127
+ "acId": "AC-18701-1",
128
+ "description": "parseBriefFromFile parses a leading [kind] and a trailing (source: ...) marker; the CLI brief add --from mints a statement with that kind, text and source.",
129
+ "status": "pending",
130
+ "testPointer": "test/define/ledgers.test.js::parseBriefFromFile (AC-18701-1): leading [kind] and trailing (source: ...) markers mint one statement"
131
+ },
132
+ {
133
+ "id": "TC-215-defaults-from-flags",
134
+ "acId": "AC-18701-2",
135
+ "description": "A line without markers inherits --kind and --source from CLI flags.",
136
+ "status": "pending",
137
+ "testPointer": "test/define/ledgers.test.js::parseBriefFromFile (AC-18701-2): a line without markers inherits --kind and --source"
138
+ },
139
+ {
140
+ "id": "TC-215-question-heuristic",
141
+ "acId": "AC-18701-3",
142
+ "description": "A trailing '?' or a TBC/TBD/Open:/Question: prefix with no [kind] marker kinds the statement openQuestion.",
143
+ "status": "pending",
144
+ "testPointer": "test/define/ledgers.test.js::parseBriefFromFile (AC-18701-3): a question-mark trailing line is kinded openQuestion"
145
+ },
146
+ {
147
+ "id": "TC-215-029-line-per-statement-unchanged",
148
+ "acId": "AC-18701-4",
149
+ "description": "A 0.29.0 line-per-statement file (no markers) parses to the same drafts as the 0.29.0 code path produced.",
150
+ "status": "pending",
151
+ "testPointer": "test/define/ledgers.test.js::parseBriefFromFile (AC-18701-4): a 0.29.0 line-per-statement file parses unchanged"
152
+ },
153
+ {
154
+ "id": "TC-215-unknown-kind-exits-2",
155
+ "acId": "AC-18701-5",
156
+ "description": "A line with an unknown [kind] exits 2 naming the accepted kinds and writes nothing to the ledger.",
157
+ "status": "pending",
158
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18701-5): brief add --from with an unknown [kind] exits 2 before writing"
159
+ },
160
+ {
161
+ "id": "TC-215-dry-run-no-write",
162
+ "acId": "AC-18701-6",
163
+ "description": "brief add --from --dry-run never creates or modifies rcf/define/brief-ledger.json.",
164
+ "status": "pending",
165
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18701-6, --dry-run): writes nothing"
166
+ },
167
+ {
168
+ "id": "TC-215-scan-mints-openquestion",
169
+ "acId": "AC-18702-1",
170
+ "description": "A new statement that the contradiction scan flags against an existing statement adds one openQuestion statement with source scan:contradiction:<id>,<id>.",
171
+ "status": "pending",
172
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18702-1): mechanical scan on brief add mints an openQuestion with scan: source"
173
+ },
174
+ {
175
+ "id": "TC-215-findings-mints-openquestions",
176
+ "acId": "AC-18702-2",
177
+ "description": "--findings <path> accepts rcf discover intake --input shape and mints one openQuestion per finding with source scan:<name>.",
178
+ "status": "pending",
179
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18702-2): --findings file mints one openQuestion per finding with scan: source"
180
+ },
181
+ {
182
+ "id": "TC-215-scans-compare-every-existing",
183
+ "acId": "AC-18702-3",
184
+ "description": "runIntakeScansOnDelta compares every new statement against every existing statement (the frozen set is every statement).",
185
+ "status": "pending",
186
+ "testPointer": "test/intake/validate.test.js::runIntakeScansOnDelta (AC-18702-3): on a frozen set the comparison set is every existing statement"
187
+ },
188
+ {
189
+ "id": "TC-215-json-emits-added-and-findings",
190
+ "acId": "AC-18702-4",
191
+ "description": "brief add --json emits { added: [...], findings: [...] } on stdout.",
192
+ "status": "pending",
193
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18702-4, --json): emits { added, findings }"
194
+ },
195
+ {
196
+ "id": "TC-215-no-scan-plus-findings-exits-2",
197
+ "acId": "AC-18702-5",
198
+ "description": "--no-scan combined with --findings exits 2 naming the conflict.",
199
+ "status": "pending",
200
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18702-5): --no-scan with --findings exits 2"
201
+ },
202
+ {
203
+ "id": "TC-215-text-runs-no-scan",
204
+ "acId": "AC-18702-6",
205
+ "description": "brief add --text runs no scan and appends no openQuestion statement.",
206
+ "status": "pending",
207
+ "testPointer": "test/cli/ledger.test.js::ledger CLI (AC-18702-6): --text runs no scan and appends no openQuestion"
208
+ }
209
+ ],
210
+ "status": "draft"
211
+ }
@@ -0,0 +1,94 @@
1
+ {
2
+ "createdAt": "2026-09-24T14:30:00Z",
3
+ "updatedAt": "2026-10-01T13:12:16Z",
4
+ "purpose": "Cover the DEFINE stage-gate check functions D1..D8 (AC-17401-1..8) with unit tests over hand-built TreeModel and ledger fixtures.",
5
+ "testLevel": "unit",
6
+ "acIds": [
7
+ "AC-17401-1",
8
+ "AC-17401-2",
9
+ "AC-17401-3",
10
+ "AC-17401-4",
11
+ "AC-17401-5",
12
+ "AC-17401-6",
13
+ "AC-17401-7",
14
+ "AC-17401-8",
15
+ "AC-17401-9",
16
+ "AC-17401-10"
17
+ ],
18
+ "id": "TS-216",
19
+ "usId": "US-17401",
20
+ "title": "Stage gates D1..D8 check functions",
21
+ "testCases": [
22
+ {
23
+ "id": "TC-216-shape",
24
+ "acId": "AC-17401-1",
25
+ "description": "Every check function returns { stage, gate, state, checks[] } and every entry in checks[] is { name, ok, over: 'delta'|'tree', pass, total, failing }; failing is empty when ok is true.",
26
+ "status": "pending",
27
+ "testPointer": "test/query/gates.test.js::gates: every check function returns the section 2.4 shape"
28
+ },
29
+ {
30
+ "id": "TC-216-blocking-vs-warn",
31
+ "acId": "AC-17401-2",
32
+ "description": "Blocking stages fold to failing on any check.ok false; warn-with-ack stages (D3, D5, D6) also fold to failing on any check.ok false unless freeze.gates[<gate>].state === 'acknowledged' AND at.hash === currentTreeHash.",
33
+ "status": "pending",
34
+ "testPointer": "test/query/gates.test.js::gates: warn-with-ack fold honours freeze.gates acknowledgement at the current hash"
35
+ },
36
+ {
37
+ "id": "TC-216-not-applicable",
38
+ "acId": "AC-17401-3",
39
+ "description": "notApplicable is decided per stage per section 3.2: D2 with no statement of a resolving kind and no REQ/PRD/TAD in scope; D3 with no TAC and no shaped REQ in scope; D5 with no REQ in scope; D7 with no open decisions and profile.skipReviewFor 'singleDocument' and one-document delta.",
40
+ "status": "pending",
41
+ "testPointer": "test/query/gates.test.js::gates: notApplicable decision per stage"
42
+ },
43
+ {
44
+ "id": "TC-216-d4-floors",
45
+ "acId": "AC-17401-4",
46
+ "description": "checkD4Stories enforces every REQ has US, every US has testable AC + failure AC (parsed by [failure] prefix or opt-out with baselineKey 'defineD4:failure') + must-not AC (or opt-out with 'defineD4:mustNot'), tacIds non-empty and resolving, no TODO placeholder in AC.description.",
47
+ "status": "pending",
48
+ "testPointer": "test/query/gates.test.js::gates: D4 floors and per-class opt-outs"
49
+ },
50
+ {
51
+ "id": "TC-216-d3-shapes",
52
+ "acId": "AC-17401-5",
53
+ "description": "checkD3Shapes runs only the cheap data-backed checks: every TAC in scope has at least one interface, and every interface kind is in the closed vocabulary. Unknown kinds show up in failing[].",
54
+ "status": "pending",
55
+ "testPointer": "test/query/gates.test.js::gates: D3 interface presence and kind vocabulary"
56
+ },
57
+ {
58
+ "id": "TC-216-d5-crosscut",
59
+ "acId": "AC-17401-6",
60
+ "description": "checkD5Crosscut checks TAD.securityArchitecture presence when any REQ has shape 'auth' or 'httpApi'; TAD.operationalConcerns when any AC has '[deployed]' marker; no dangling 'open' concerns on in-scope REQs.",
61
+ "status": "pending",
62
+ "testPointer": "test/query/gates.test.js::gates: D5 crosscut cheap checks"
63
+ },
64
+ {
65
+ "id": "TC-216-d6-consistency",
66
+ "acId": "AC-17401-7",
67
+ "description": "checkD6Consistency asserts validateErrors is empty tree-wide and probeOpenCount is zero; the richer scans are named seams (0.30).",
68
+ "status": "pending",
69
+ "testPointer": "test/query/gates.test.js::gates: D6 consistency validate + probe count"
70
+ },
71
+ {
72
+ "id": "TC-216-d8-freeze",
73
+ "acId": "AC-17401-8",
74
+ "description": "checkD8Freeze asserts prior stages passed/acknowledged, every AC owned by exactly one FBS, computeQueue nextActionable not null, validateErrors empty.",
75
+ "status": "pending",
76
+ "testPointer": "test/query/gates.test.js::gates: D8 tree-wide freeze checks"
77
+ },
78
+ {
79
+ "id": "TC-216-d2-data-architecture",
80
+ "acId": "AC-17401-9",
81
+ "description": "checkD2Skeleton reads tad.dataArchitecture.{dataStores,coreEntities} per rcf-schemas 0.6.3; a tree with populated dataArchitecture passes skeleton:tadPersistence and empty/missing/wrong-top-level trees fail with the schema-anchored ids.",
82
+ "status": "pending",
83
+ "testPointer": "test/query/gates.test.js::gates: D2 skeleton:tadPersistence reads tad.dataArchitecture.* per schema 0.6.3"
84
+ },
85
+ {
86
+ "id": "TC-216-identity-seed-surface",
87
+ "acId": "AC-17401-10",
88
+ "description": "IDENTITY_TEMPLATE carries a '## Surface' section between '## Register' and '## Project-scoped notes' naming viewer/runningApp/prDiff and seeded to 'prDiff'; writeIdentityTemplate on a fresh dir seeds a profile that satisfies checkD1Brief surface markers; an existing profile.md is left byte-identical (slice-1 'kept' contract).",
89
+ "status": "pending",
90
+ "testPointer": "test/setup/identity-register.test.js::IDENTITY_TEMPLATE carries a ## Surface heading between ## Register and ## Project-scoped notes"
91
+ }
92
+ ],
93
+ "status": "draft"
94
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "createdAt": "2026-09-24T14:30:00Z",
3
+ "updatedAt": "2026-09-24T14:30:00Z",
4
+ "purpose": "Cover computeReadiness and the rcf define readiness CLI (AC-17501-1..6) with unit tests over fixture trees + a CLI spawn, plus a targeted test of the P3 loadAllLedgers fix.",
5
+ "testLevel": "unit",
6
+ "acIds": [
7
+ "AC-17501-1",
8
+ "AC-17501-2",
9
+ "AC-17501-3",
10
+ "AC-17501-4",
11
+ "AC-17501-5",
12
+ "AC-17501-6"
13
+ ],
14
+ "id": "TS-217",
15
+ "usId": "US-17501",
16
+ "title": "computeReadiness and rcf define readiness CLI",
17
+ "testCases": [
18
+ {
19
+ "id": "TC-217-shape",
20
+ "acId": "AC-17501-1",
21
+ "description": "computeReadiness returns { tree, delta, stages, nextAction, coverage, decisions, freezeable } and freezeable is true when every stage state is in { passed, acknowledged, notApplicable }.",
22
+ "status": "pending",
23
+ "testPointer": "test/query/readiness.test.js::readiness: returns the section 2.4 shape and freezeable folds correctly"
24
+ },
25
+ {
26
+ "id": "TC-217-fanout",
27
+ "acId": "AC-17501-2",
28
+ "description": "Fan-out: computeImpact runs once per id in changed union added; impacted is the deduplicated union; impactedFbs is the subset with kind 'fbs' AND actionNeeded 're-execute'.",
29
+ "status": "pending",
30
+ "testPointer": "test/query/readiness.test.js::readiness: fan-out impacted / impactedFbs (frozen delta)"
31
+ },
32
+ {
33
+ "id": "TC-217-coverage",
34
+ "acId": "AC-17501-3",
35
+ "description": "coverage.tree is a tree-wide CoverageResult; coverage.delta is one CoverageResult per unique REQ ancestor of the delta ids.",
36
+ "status": "pending",
37
+ "testPointer": "test/query/readiness.test.js::readiness: coverage tree-wide and per REQ ancestor"
38
+ },
39
+ {
40
+ "id": "TC-217-next-action",
41
+ "acId": "AC-17501-4",
42
+ "description": "nextAction picks the first failing stage in D1..D8 order and the first failing check inside it, listing ids and a rcf define readiness --check <short-name> command; null when no stage is failing.",
43
+ "status": "pending",
44
+ "testPointer": "test/query/readiness.test.js::readiness: nextAction picks first failing stage and check"
45
+ },
46
+ {
47
+ "id": "TC-217-cli",
48
+ "acId": "AC-17501-5",
49
+ "description": "The CLI prints text summary by default and JSON with --json; --check <stage> exits 4 on blocking failure, 0 with a [warn] on warn-with-ack unacknowledged failure, 0 otherwise; admissibility refusal exits 4.",
50
+ "status": "pending",
51
+ "testPointer": "test/cli/readiness.test.js::readiness cli: text output shape and --check exit codes"
52
+ },
53
+ {
54
+ "id": "TC-217-load-all-ledgers",
55
+ "acId": "AC-17501-6",
56
+ "description": "loadAllLedgers omits ledgers whose files are absent so computeDelta records no docHash for absent ledgers; a project with only brief-ledger.json sees exactly one ledger:brief docHash.",
57
+ "status": "pending",
58
+ "testPointer": "test/define/ledgers.test.js::ledgers: loadAllLedgers omits absent ledger files"
59
+ }
60
+ ],
61
+ "status": "draft"
62
+ }