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.
- package/CHANGELOG.md +317 -0
- package/bin/rcf.js +8 -0
- package/fixtures/canary-manifest.json +9 -9
- package/guidance/define-draft-shapes.md +89 -0
- package/guidance/define-intake.md +97 -0
- package/guidance/define-intent.md +107 -0
- package/guidance/discover-prototype.md +67 -0
- package/guidance/discovery-prototypes.md +69 -0
- package/guidance/harness-template.md +34 -0
- package/guidance/managed/agent-instructions-block.hash +1 -1
- package/guidance/managed/agent-instructions-block.md +34 -0
- package/guidance/manifest.json +9 -2
- package/package.json +1 -1
- package/rcf/adrs/adr-4120-canonical-json-hashing.json +30 -0
- package/rcf/adrs/adr-4121-define-sidecars.json +30 -0
- package/rcf/adrs/adr-4122-define-gates-blocking-and-optout.json +30 -0
- package/rcf/adrs/adr-4123-readiness-single-object.json +30 -0
- package/rcf/adrs/adr-4124-define-freeze-verb.json +30 -0
- package/rcf/adrs/adr-4126-persona-tagged-blockers-two-levels.json +40 -0
- package/rcf/adrs/adr-4127-readiness-tab-order-and-register.json +40 -0
- package/rcf/adrs/adr-4129-questions-harness-driven-loop.json +25 -0
- package/rcf/adrs/adr-4130-intake-harness-split-tool-scanned.json +20 -0
- package/rcf/adrs/adr-4132-prototypes-in-discovery-as-evidence.json +20 -0
- package/rcf/adrs/adr-4133-dag-dependency-depth-layout.json +40 -0
- package/rcf/adrs/adr-4134-index-json-route.json +35 -0
- package/rcf/adrs/adr-4135-readiness-po-register-and-adapter.json +35 -0
- package/rcf/adrs/adr-4136-embedding-host-fixture.json +35 -0
- package/rcf/code-nodes/cn-700.json +23 -0
- package/rcf/code-nodes/cn-701.json +14 -0
- package/rcf/code-nodes/cn-702.json +14 -0
- package/rcf/code-nodes/cn-703.json +16 -0
- package/rcf/code-nodes/cn-720.json +15 -0
- package/rcf/code-nodes/cn-721.json +15 -0
- package/rcf/code-nodes/cn-722.json +15 -0
- package/rcf/code-nodes/cn-723.json +18 -0
- package/rcf/code-nodes/cn-724.json +14 -0
- package/rcf/code-nodes/cn-725.json +37 -0
- package/rcf/code-nodes/cn-726.json +25 -0
- package/rcf/code-nodes/cn-727.json +23 -0
- package/rcf/code-nodes/cn-728.json +37 -0
- package/rcf/code-nodes/cn-729.json +26 -0
- package/rcf/code-nodes/cn-730.json +24 -0
- package/rcf/code-nodes/cn-731.json +20 -0
- package/rcf/code-nodes/cn-732.json +14 -0
- package/rcf/code-nodes/cn-733.json +14 -0
- package/rcf/code-nodes/cn-734.json +14 -0
- package/rcf/code-nodes/cn-735.json +20 -0
- package/rcf/code-nodes/cn-736.json +14 -0
- package/rcf/code-nodes/cn-737.json +14 -0
- package/rcf/code-nodes/cn-738.json +14 -0
- package/rcf/code-nodes/cn-739.json +18 -0
- package/rcf/code-nodes/cn-740.json +19 -0
- package/rcf/code-nodes/cn-741.json +16 -0
- package/rcf/code-nodes/cn-742.json +16 -0
- package/rcf/code-nodes/cn-743.json +15 -0
- package/rcf/code-nodes/cn-744.json +22 -0
- package/rcf/code-nodes/cn-745.json +16 -0
- package/rcf/code-nodes/cn-746.json +14 -0
- package/rcf/code-nodes/cn-747.json +18 -0
- package/rcf/code-nodes/cn-748.json +16 -0
- package/rcf/code-nodes/cn-749.json +16 -0
- package/rcf/code-nodes/cn-750.json +15 -0
- package/rcf/code-nodes/cn-751.json +18 -0
- package/rcf/code-nodes/cn-752.json +14 -0
- package/rcf/fbs/fbs-190.json +37 -0
- package/rcf/fbs/fbs-191.json +34 -0
- package/rcf/fbs/fbs-192.json +17 -0
- package/rcf/fbs/fbs-193.json +37 -0
- package/rcf/fbs/fbs-194.json +35 -0
- package/rcf/fbs/fbs-195.json +37 -0
- package/rcf/fbs/fbs-196.json +45 -0
- package/rcf/fbs/fbs-197.json +41 -0
- package/rcf/fbs/fbs-198.json +42 -0
- package/rcf/fbs/fbs-199.json +59 -0
- package/rcf/fbs/fbs-200.json +46 -0
- package/rcf/fbs/fbs-201.json +49 -0
- package/rcf/fbs/fbs-202.json +110 -0
- package/rcf/fbs/fbs-203.json +100 -0
- package/rcf/requirements/req-001.json +2 -1
- package/rcf/requirements/req-002.json +3 -2
- package/rcf/requirements/req-003.json +2 -1
- package/rcf/requirements/req-004.json +2 -1
- package/rcf/requirements/req-005.json +2 -1
- package/rcf/requirements/req-006.json +2 -1
- package/rcf/requirements/req-007.json +2 -1
- package/rcf/requirements/req-008.json +2 -1
- package/rcf/requirements/req-009.json +2 -1
- package/rcf/requirements/req-010.json +5 -2
- package/rcf/requirements/req-011.json +2 -1
- package/rcf/requirements/req-012.json +2 -1
- package/rcf/requirements/req-013.json +2 -1
- package/rcf/requirements/req-014.json +2 -1
- package/rcf/requirements/req-015.json +2 -1
- package/rcf/requirements/req-016.json +5 -2
- package/rcf/requirements/req-017.json +6 -2
- package/rcf/requirements/req-018.json +5 -2
- package/rcf/requirements/req-019.json +5 -2
- package/rcf/requirements/req-020.json +5 -2
- package/rcf/requirements/req-021.json +5 -2
- package/rcf/requirements/req-022.json +5 -2
- package/rcf/requirements/req-023.json +6 -4
- package/rcf/requirements/req-024.json +5 -2
- package/rcf/requirements/req-025.json +5 -2
- package/rcf/requirements/req-026.json +5 -2
- package/rcf/requirements/req-027.json +5 -2
- package/rcf/requirements/req-028.json +5 -2
- package/rcf/requirements/req-029.json +5 -2
- package/rcf/requirements/req-030.json +5 -2
- package/rcf/requirements/req-040.json +5 -2
- package/rcf/requirements/req-041.json +5 -2
- package/rcf/requirements/req-042.json +5 -2
- package/rcf/requirements/req-043.json +5 -2
- package/rcf/requirements/req-050.json +5 -2
- package/rcf/requirements/req-051.json +5 -2
- package/rcf/requirements/req-052.json +5 -2
- package/rcf/requirements/req-053.json +5 -2
- package/rcf/requirements/req-054.json +5 -2
- package/rcf/requirements/req-060.json +5 -2
- package/rcf/requirements/req-061.json +5 -2
- package/rcf/requirements/req-062.json +5 -2
- package/rcf/requirements/req-063.json +5 -2
- package/rcf/requirements/req-070.json +5 -2
- package/rcf/requirements/req-071.json +5 -2
- package/rcf/requirements/req-072.json +5 -2
- package/rcf/requirements/req-073.json +5 -2
- package/rcf/requirements/req-074.json +5 -2
- package/rcf/requirements/req-075.json +5 -2
- package/rcf/requirements/req-076.json +5 -2
- package/rcf/requirements/req-077.json +5 -2
- package/rcf/requirements/req-080.json +5 -2
- package/rcf/requirements/req-081.json +5 -2
- package/rcf/requirements/req-082.json +5 -2
- package/rcf/requirements/req-083.json +5 -2
- package/rcf/requirements/req-084.json +5 -2
- package/rcf/requirements/req-085.json +5 -2
- package/rcf/requirements/req-086.json +5 -2
- package/rcf/requirements/req-090.json +5 -2
- package/rcf/requirements/req-091.json +5 -2
- package/rcf/requirements/req-092.json +5 -2
- package/rcf/requirements/req-093.json +5 -2
- package/rcf/requirements/req-094.json +5 -2
- package/rcf/requirements/req-100.json +5 -2
- package/rcf/requirements/req-101.json +5 -2
- package/rcf/requirements/req-102.json +5 -2
- package/rcf/requirements/req-103.json +5 -2
- package/rcf/requirements/req-104.json +5 -2
- package/rcf/requirements/req-110.json +5 -2
- package/rcf/requirements/req-111.json +5 -2
- package/rcf/requirements/req-112.json +5 -2
- package/rcf/requirements/req-113.json +5 -2
- package/rcf/requirements/req-114.json +5 -2
- package/rcf/requirements/req-115.json +5 -2
- package/rcf/requirements/req-120.json +5 -2
- package/rcf/requirements/req-121.json +5 -2
- package/rcf/requirements/req-122.json +5 -2
- package/rcf/requirements/req-123.json +5 -2
- package/rcf/requirements/req-124.json +5 -2
- package/rcf/requirements/req-125.json +5 -2
- package/rcf/requirements/req-130.json +6 -2
- package/rcf/requirements/req-131.json +6 -2
- package/rcf/requirements/req-132.json +6 -2
- package/rcf/requirements/req-133.json +6 -2
- package/rcf/requirements/req-134.json +6 -2
- package/rcf/requirements/req-140.json +5 -2
- package/rcf/requirements/req-145.json +5 -2
- package/rcf/requirements/req-150.json +6 -2
- package/rcf/requirements/req-151.json +6 -2
- package/rcf/requirements/req-152.json +6 -2
- package/rcf/requirements/req-153.json +6 -2
- package/rcf/requirements/req-154.json +5 -2
- package/rcf/requirements/req-155.json +4 -1
- package/rcf/requirements/req-156.json +4 -1
- package/rcf/requirements/req-157.json +4 -1
- package/rcf/requirements/req-158.json +4 -1
- package/rcf/requirements/req-159.json +4 -1
- package/rcf/requirements/req-160.json +4 -1
- package/rcf/requirements/req-161.json +4 -1
- package/rcf/requirements/req-162.json +4 -1
- package/rcf/requirements/req-163.json +5 -2
- package/rcf/requirements/req-164.json +5 -2
- package/rcf/requirements/req-165.json +5 -2
- package/rcf/requirements/req-170.json +33 -0
- package/rcf/requirements/req-171.json +44 -0
- package/rcf/requirements/req-172.json +25 -0
- package/rcf/requirements/req-173.json +25 -0
- package/rcf/requirements/req-174.json +31 -0
- package/rcf/requirements/req-175.json +31 -0
- package/rcf/requirements/req-176.json +25 -0
- package/rcf/requirements/req-180.json +31 -0
- package/rcf/requirements/req-181.json +31 -0
- package/rcf/requirements/req-182.json +25 -0
- package/rcf/requirements/req-186.json +25 -0
- package/rcf/requirements/req-187.json +31 -0
- package/rcf/requirements/req-188.json +25 -0
- package/rcf/tacs/tac-4120-define-delta-and-freeze.json +21 -0
- package/rcf/tacs/tac-4121-define-ledgers.json +35 -0
- package/rcf/tacs/tac-4122-define-gates.json +61 -0
- package/rcf/tacs/tac-4123-define-readiness.json +61 -0
- package/rcf/tacs/tac-4124-define-freeze.json +28 -0
- package/rcf/tacs/tac-4127-readiness-view.json +49 -0
- package/rcf/tacs/tac-4128-define-guidance.json +53 -0
- package/rcf/tacs/tac-4129-define-questions.json +45 -0
- package/rcf/tacs/tac-4130-define-intake-brief.json +35 -0
- package/rcf/tacs/tac-4131-build-dag-view.json +39 -0
- package/rcf/tacs/tac-4132-id-lookup.json +42 -0
- package/rcf/tacs/tac-4133-readiness-po-layer.json +37 -0
- package/rcf/tacs/tac-4134-wespa-host-fixture.json +54 -0
- package/rcf/test-suites/ts-016.json +3 -3
- package/rcf/test-suites/ts-204.json +30 -0
- package/rcf/test-suites/ts-205.json +22 -0
- package/rcf/test-suites/ts-206.json +22 -0
- package/rcf/test-suites/ts-207.json +22 -0
- package/rcf/test-suites/ts-208.json +22 -0
- package/rcf/test-suites/ts-209.json +22 -0
- package/rcf/test-suites/ts-210.json +22 -0
- package/rcf/test-suites/ts-211.json +22 -0
- package/rcf/test-suites/ts-212.json +22 -0
- package/rcf/test-suites/ts-213.json +50 -0
- package/rcf/test-suites/ts-214.json +74 -0
- package/rcf/test-suites/ts-215.json +211 -0
- package/rcf/test-suites/ts-216.json +94 -0
- package/rcf/test-suites/ts-217.json +62 -0
- package/rcf/test-suites/ts-218.json +78 -0
- package/rcf/test-suites/ts-219.json +70 -0
- package/rcf/test-suites/ts-220.json +78 -0
- package/rcf/test-suites/ts-221.json +78 -0
- package/rcf/test-suites/ts-222.json +100 -0
- package/rcf/test-suites/ts-223.json +94 -0
- package/rcf/test-suites/ts-224.json +70 -0
- package/rcf/test-suites/ts-225.json +78 -0
- package/rcf/test-suites/ts-226.json +158 -0
- package/rcf/test-suites/ts-227.json +38 -0
- package/rcf/test-suites/ts-228.json +86 -0
- package/rcf/test-suites/ts-229.json +83 -0
- package/rcf/user-stories/us-15601.json +4 -4
- package/rcf/user-stories/us-17001.json +27 -0
- package/rcf/user-stories/us-17002.json +22 -0
- package/rcf/user-stories/us-17003.json +22 -0
- package/rcf/user-stories/us-17004.json +22 -0
- package/rcf/user-stories/us-17005.json +22 -0
- package/rcf/user-stories/us-17006.json +21 -0
- package/rcf/user-stories/us-17007.json +21 -0
- package/rcf/user-stories/us-17008.json +22 -0
- package/rcf/user-stories/us-17101.json +22 -0
- package/rcf/user-stories/us-17102.json +22 -0
- package/rcf/user-stories/us-17201.json +38 -0
- package/rcf/user-stories/us-17301.json +38 -0
- package/rcf/user-stories/us-17302.json +50 -0
- package/rcf/user-stories/us-17401.json +70 -0
- package/rcf/user-stories/us-17402.json +55 -0
- package/rcf/user-stories/us-17403.json +60 -0
- package/rcf/user-stories/us-17501.json +48 -0
- package/rcf/user-stories/us-17502.json +60 -0
- package/rcf/user-stories/us-17503.json +65 -0
- package/rcf/user-stories/us-17601.json +58 -0
- package/rcf/user-stories/us-18001.json +55 -0
- package/rcf/user-stories/us-18002.json +35 -0
- package/rcf/user-stories/us-18101.json +35 -0
- package/rcf/user-stories/us-18202.json +40 -0
- package/rcf/user-stories/us-18601.json +55 -0
- package/rcf/user-stories/us-18602.json +50 -0
- package/rcf/user-stories/us-18603.json +45 -0
- package/rcf/user-stories/us-18701.json +50 -0
- package/rcf/user-stories/us-18702.json +50 -0
- package/rcf/user-stories/us-18801.json +45 -0
- package/rcf/user-stories/us-204.json +59 -0
- package/rcf/user-stories/us-205.json +64 -0
- package/rcf/user-stories/us-206.json +54 -0
- package/releases/releases.yaml +31 -1
- package/src/cli/feedback.js +126 -10
- package/src/cli/freeze.js +730 -0
- package/src/cli/help.js +23 -0
- package/src/cli/ledger.js +615 -0
- package/src/cli/questions.js +288 -0
- package/src/cli/readiness.js +498 -0
- package/src/cli/view.js +29 -0
- package/src/core/store/writer.js +86 -6
- package/src/define/freeze-record.js +247 -0
- package/src/define/ledgers.js +712 -0
- package/src/feedback/redact.js +105 -19
- package/src/intake/index.js +1 -1
- package/src/intake/orchestrator.js +117 -0
- package/src/mcp/tools.js +354 -0
- package/src/query/delta.js +282 -0
- package/src/query/gates.js +1107 -0
- package/src/query/index.js +50 -0
- package/src/query/questions.js +438 -0
- package/src/query/readiness.js +574 -0
- package/src/server/index.js +60 -1
- package/src/server/routes.js +133 -4
- package/src/setup/identity-seed.js +17 -0
- package/src/view/build-dag.js +563 -0
- package/src/view/components/badge.js +41 -0
- package/src/view/components/diff.js +72 -0
- package/src/view/components/doc-row.js +62 -0
- package/src/view/components/empty-state.js +35 -0
- package/src/view/components/entity-selector.js +137 -0
- package/src/view/components/filter-bar.js +97 -0
- package/src/view/components/findings-list.js +49 -0
- package/src/view/components/index.js +12 -0
- package/src/view/components/pill.js +46 -0
- package/src/view/components/sub-tab-strip.js +43 -0
- package/src/view/components/toast.js +25 -0
- package/src/view/components-fixture.js +265 -0
- package/src/view/doc-renderers/architecture.js +304 -0
- package/src/view/doc-renderers/build.js +160 -0
- package/src/view/doc-renderers/helpers.js +2 -2
- package/src/view/doc-renderers/index.js +2 -0
- package/src/view/doc-renderers/prd.js +35 -6
- package/src/view/doc-renderers/req.js +10 -2
- package/src/view/doc-renderers/user-story.js +10 -5
- package/src/view/html-page.js +717 -300
- package/src/view/index.js +109 -3
- package/src/view/live-client.js +61 -8
- package/src/view/needs-work.js +79 -0
- package/src/view/page-init.js +2193 -0
- package/src/view/product-map.js +751 -0
- package/src/view/readiness/phrasebook.js +115 -0
- package/src/view/readiness/po-layer.js +288 -0
- package/src/view/readiness/question-adapter.js +329 -0
- package/src/view/readiness/stage-legend.js +71 -0
- package/src/view/readiness.js +505 -0
- package/src/view/style.css +2279 -266
- package/src/view/test-host/embed-client.js +121 -0
- package/src/view/test-host/fixture.js +183 -0
- package/src/view/test-host/lints.js +220 -0
- package/src/view/view-index.js +323 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-21T16:52:32.174Z",
|
|
3
|
+
"updatedAt": "2026-09-21T17:00:00.000Z",
|
|
4
|
+
"description": "The RCF review surface offers a Product Map tab in addition to Overview, Requirements, Architecture and Build sequence. The tab lets a product reader group requirements by shape, status, component (TAC), trace coverage or capability. Every grouping drills group -> requirement (with a status pill) -> its user stories -> acceptance criteria. Groupings and the status filter are hash-addressable so a URL of the form #tab=product-map&group=capability&status=approved is deep-linkable and shareable.",
|
|
5
|
+
"reqId": "REQ-170",
|
|
6
|
+
"prdId": "PRD-001",
|
|
7
|
+
"title": "Product Map tab on the review surface",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "reviewSurface",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"webUi"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-09-21T16:52:32.226Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "webUi",
|
|
23
|
+
"match": "component"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "The Requirements tab is a flat REQ list ordered by id. A product reader (operator or reviewer) does not think in that shape - they think in surfaces, capabilities, states, and what has and has not been built yet. The Product Map tab re-buckets the same in-memory tree by the axes the data actually populates (shape 65%, status 100%) and by two derived axes (component-first via TAC, and trace coverage), plus a convention-driven capability grouping. No schema change; all work is a re-bucketing of the tree-model the view already builds.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:review-surface",
|
|
30
|
+
"product-map",
|
|
31
|
+
"view"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-21T16:52:37.436Z",
|
|
3
|
+
"updatedAt": "2026-09-21T17:00:00.000Z",
|
|
4
|
+
"description": "Requirements carry one or more capability slugs on their existing free-form tags array using the convention capability:<kebab-slug>. A capability taxonomy for the rcf-lite product itself is documented in the rcf-lite docs, alongside the rule for adding a new capability. This is a convention that rides on the shipped schema; no schema change. The Product Map by-capability grouping is the consumer that proves the convention works on real data.",
|
|
5
|
+
"reqId": "REQ-171",
|
|
6
|
+
"prdId": "PRD-001",
|
|
7
|
+
"title": "Capability tag convention on requirements",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "requirementsAuthoring",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"webUi",
|
|
16
|
+
"persistence"
|
|
17
|
+
],
|
|
18
|
+
"reason": "keyword-scan",
|
|
19
|
+
"classifiedAt": "2026-09-21T16:52:37.488Z",
|
|
20
|
+
"signals": [
|
|
21
|
+
{
|
|
22
|
+
"source": "description",
|
|
23
|
+
"shape": "webUi",
|
|
24
|
+
"match": "form"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"source": "description",
|
|
28
|
+
"shape": "persistence",
|
|
29
|
+
"match": "schema"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"source": "description",
|
|
33
|
+
"shape": "persistence",
|
|
34
|
+
"match": "schema"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"rationale": "Analysis d-019 established that the shipped schema has no capability or feature level between PRD and REQ. The trial answers whether a lightweight convention on the existing tags array carries a usable product taxonomy without a schema change. If the tags and the by-capability view earn their keep, the capability level is promoted to a proper schema field later; if not, nothing was spent.",
|
|
39
|
+
"tags": [
|
|
40
|
+
"capability:requirements-authoring",
|
|
41
|
+
"capability:review-surface",
|
|
42
|
+
"capability-tags-trial"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T12:00:00Z",
|
|
3
|
+
"updatedAt": "2026-09-24T12:00:00Z",
|
|
4
|
+
"reqId": "REQ-172",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "DEFINE delta detection and freeze record foundation",
|
|
7
|
+
"description": "rcf-lite gains three pure primitives and one durable record. hashDocument returns a sha256:<hex> hash over the canonical JSON of a parsed document (keys sorted recursively, no whitespace). computeTreeHash hashes the sorted (id, docHash) pairs. computeDelta(tree, freeze, ledgers) returns the whole change model of the proposal (2026-09-22 v3) section 2.2: frozen, frozenAt, treeHash, currentTreeHash, changed, added, removed, briefSince, unchanged. docHashes cover every standalone document the walker exposes on tree.byId (PRD, TAD, BS, REQ, US, TAC, ADR, FBS, TS, CN, EVAL) plus one ledger:<name> entry per sidecar the caller passes in. Before the first freeze the delta is the whole tree (frozen false, everything in added). The freeze record itself sits at rcf/define/freeze.json (owned by rcf-lite, outside the shared rcf-schemas package until 0.7) with a small local schema and a reader/writer module: reading a missing file returns null, a malformed file raises a clear error. No rcf define freeze verb yet; the writer the verb will call is exposed for slice 3.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": ["persistence"],
|
|
15
|
+
"reason": "keyword-scan",
|
|
16
|
+
"classifiedAt": "2026-09-24T12:00:00Z",
|
|
17
|
+
"signals": [
|
|
18
|
+
{ "source": "description", "shape": "persistence", "match": "record" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"rationale": "Barry's backstory dogfood found DEFINE generated too fast with no gates. Baz ruled 2026-09-22 that the fix is detection over configured change records: the freeze remembers what the tree looked like; anything that differs is the change. The delta.js primitives are what every later slice (gates, readiness, freeze verb, bundle read, viewer tab) consumes, so their return shape is a contract worth pinning early. Canonical-JSON hashing (over raw bytes) is the difference between a real change and a hand reformat; document granularity (over criterion granularity) keeps the model cheap while git supplies the criterion-level diff.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-detection"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T12:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-02T16:40:00Z",
|
|
4
|
+
"reqId": "REQ-173",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "Sidecar ledgers under rcf/define/ and the rcf define ledger verb",
|
|
7
|
+
"description": "Four sidecars live under rcf/define/, each one JSON file, each with one numbered sequence for the life of the project (proposal 2026-09-22 v3 section 2.5, 3.2, 8.2). Names and shapes: brief-ledger.json (statements[] kinded from a closed set), decisions-ledger.json (decisions[] in the numbered #241 format), concern-ledger.json (concerns[] with disposition applied or waived), probe-ledger.json (probes[] with severity low, medium, high). A local schema in rcf-lite validates every write until schemas 0.7. Reading a missing ledger file returns an empty ledger so callers can compose without a per-file null check; a malformed file raises a clear error. The rcf define ledger name verb pattern (brief, decisions, concerns, probes; add, resolve, list) is the operator surface. brief add --from <file> splits statements one per non-empty line, mints sequential ids and writes; the intake-scan-against-frozen-statements hook is a named seam this slice leaves for a later one. decisions list prints the #241 numbered format (one decision per item, options with letters, the default, what it blocks). The walker never reads under rcf/define/ so the sidecars stay invisible to every existing tree consumer. Every ledger supports `update <id>` with field patches validated as `add` validates; `resolvedBy` on a brief statement is a closed pointer grammar (REQ-nnn, TAD.entity:<name>, PRD.user:<name>, TAD.system:<name>, TAC-nnnn, omitted:<reason>) validated by D2.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineLedgers",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": ["persistence"],
|
|
15
|
+
"reason": "keyword-scan",
|
|
16
|
+
"classifiedAt": "2026-09-24T12:00:00Z",
|
|
17
|
+
"signals": [
|
|
18
|
+
{ "source": "description", "shape": "persistence", "match": "record" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"rationale": "The proposal (2026-09-22 v3, section 8.2) makes ledgers the seam every later DEFINE stage draws from: D1 reads the brief ledger, D5 the concern ledger, D6 the probe ledger, D7 the decisions ledger, and D2's greenfield resolution walks the brief statements. Building the sidecars and the CLI now, before any gate reads them, keeps slice 2 free of write-side surprises. Baz's ruling of 2026-09-22 (decision 5) fixed the ownership: sidecars in rcf-lite until schemas 0.7 promotes them to manifest records. Precedent: .rcf/preflight-secrets.local.json is an rcf-lite-owned file outside the shared schema; rcf/define/ follows the same shape.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-ledgers"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T14:30:00Z",
|
|
3
|
+
"updatedAt": "2026-10-01T14:13:27Z",
|
|
4
|
+
"reqId": "REQ-174",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "DEFINE stage gates D1..D8 as pure check functions",
|
|
7
|
+
"description": "rcf-lite gains src/query/gates.js with one check function per stage D1..D8. Each function takes (tree, ledgers, profile, scope) and returns { stage, gate, state, checks[] } where every check is { name, ok, over: 'delta'|'tree', pass, total, failing: [{ id, why }] }. Stage state is 'passed' | 'failing' | 'acknowledged' (only for D3, D5, D6 and only when the freeze record acknowledges that gate at the current hash) | 'notApplicable' (the stage decides that itself from the scope per the proposal 2026-09-22 v3 section 3.2 rules and the summary table in section 2.7). Blocking in 0.29.0: D1 brief, D2 skeleton, D4 floors (every REQ in scope has a US; every US in scope has a testable AC, a failure AC and a must-not AC, or a reasoned opt-out per class; tacIds non-empty and resolving; no scaffold placeholder), D7 decisions, D8 freeze (prior gates passed or acknowledged at the current hash, every AC owned by exactly one FBS, queue head actionable and not a placeholder, validate clean; preflight and ui-baseline presence as the section 3.2 rules specify). Warn-with-ack in 0.29.0: D3, D5, D6 build only the cheap data-backed checks (D3: every TAC in scope has at least one interface and each interface kind is in the closed vocabulary of section 5.2; D5: TAD securityArchitecture present when any auth or httpApi REQ exists, operationalConcerns present when deployed-scope ACs exist, concern-ledger entries applied or waived where they exist; D6: validate clean tree-wide plus open probe-ledger count). The D3 template parser, entity join, D5 catalogue, D6 contradiction and unsatisfiable scans, and the probe runner are 0.30 and left as named seams. AC class is a bracketed prefix on AC description ('[failure] ...', '[must-not] ...', '[happy]', '[edge]', '[non-functional]', decision 6); opt-out per class reuses the existing manifest.baselineAcOptOuts[] array with a baselineKey of the shape 'defineD4:failure' or 'defineD4:mustNot' (recorded in ADR-4122). No storage state, no 'stale' state. ADR-4126 (0.29.0) amendment: every gate check declares an owning persona, `productOwner` or `engineer`, and a one-sentence `question` in that persona’s register. A check that would need both personas is split so every check is homogeneous: `skeleton:reqFields` becomes `skeleton:reqIntent` (productOwner: description + domain) + `skeleton:reqShape` (engineer: shapeClassification.shapes); `decisions:allAnswered` becomes `decisions:wellFormed` (productOwner: enumerated per #241 format) + `decisions:allAnswered` (engineer: zero open). A new D3 check `shapes:draftSettled` fails every interface whose description still carries the leading `[draft]` marker so an L1-pre-populated interface stays distinguishable from one the engineer has settled.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"persistence"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-09-24T14:30:00Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "persistence",
|
|
23
|
+
"match": "record"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "Baz ruled on 2026-09-22 (proposal section 9, decision 2) that gates block where the data exists and warn-with-ack for D3, D5 and D6 until 0.31 (Baz ruled 2026-09-24 that 0.31 renumbers to 0.30, so this train ships D3/D5/D6 as warn-with-ack in 0.29.0). One check function per stage is the seam every later consumer reads: the readiness view (REQ-175) composes them, the freeze verb (slice 3) refuses on any failing stage, the viewer's Readiness tab (slice 5) prints the same checks[]. Building the check functions now, with cheap data-backed checks only, keeps 0.29.0 shippable while leaving named seams for 0.30's template parser, entity join, catalogue walk, probe runner and consistency scans.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:define-detection"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T14:30:00Z",
|
|
3
|
+
"updatedAt": "2026-10-01T14:13:27Z",
|
|
4
|
+
"reqId": "REQ-175",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "computeReadiness and the rcf define readiness CLI verb",
|
|
7
|
+
"description": "rcf-lite gains src/query/readiness.js with computeReadiness(tree, { freeze, ledgers, profile, testPointers }) returning the exact section 2.4 shape { tree, delta, stages, nextAction, coverage, decisions, freezeable }. computeReadiness composes computeDelta (slice 1), calls computeImpact once per id in changed union added (the union is the fan-out; impacted names every id, impactedFbs names the re-execute subset), runs the gates D1..D8 over scope = changed union added union impacted ids, calls computeCoverage tree-wide plus per REQ ancestor of the delta (using the testPointers map the CLI produces exactly as src/cli/coverage.js builds it), lists open decisions (in the #241 numbered format from the decisions ledger), derives a nextAction { stage, check, ids, command } from the first failing gate, and reports freezeable when every stage state is passed, acknowledged or notApplicable. rcf-lite also gains src/cli/readiness.js implementing rcf define readiness [--json] [--check <stage>|all] (stage accepts D1..D8 or the gate short name: brief, skeleton, shapes, stories, crosscut, consistency, decisions, freeze). Text output: tree line, next action, stage chips, delta list, failing items. --check exits 0 green, 4 red (matching coverage refusal exit); warn-with-ack stages failing but unacknowledged exit 0 with a visible warning. The producer is wrapped with runWithAdmissibilityGate as the ruleset toolScope requires. loadAllLedgers (src/define/ledgers.js) is corrected so a project that never authored a ledger does not get ledger:<name> hashes in the docHashes map (slice-1 P3 resolution: code and JSDoc agree that absent ledger files contribute no docHash). ADR-4126 (0.29.0) amendment: the readiness object carries two computed levels on the one ladder. `levels.intentComplete.ok` is true when every `productOwner` check is ok across every stage (stage state ignored); `levels.readyToBuild.ok` equals `freezeable`. Neither is recorded. `personas.productOwner.blockers` deep-equals `levels.intentComplete.blockedBy`; `personas.engineer.blockers` is the failing engineer checks in failing stages. `deriveNextAction(stages, persona?)` gains an optional persona filter; the productOwner next-action command carries `--level intent`. `formatVerdictLines(result)` builds the two verdict strings the CLI (PR B) and the Readiness tab (PR C) share so they cannot disagree.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"persistence"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-09-24T14:30:00Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "persistence",
|
|
23
|
+
"match": "record"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "Baz ruled on 2026-09-22 (proposal section 2.4, section 6, section 9 decision 4) that Readiness is one object rendered by two consumers (the CLI and the viewer tab) so the two cannot disagree. The Product Map precedent (PR #238) established the shape: one pure compute, one JSON envelope, two renderers. computeReadiness is the object; rcf define readiness is the CLI twin the viewer tab (REQ-180, slice 5) will render unchanged. Slice 3 (rcf define freeze) reads freezeable and the per-stage state and refuses on any failing stage; slice 4's bundle --next reads the same object; slice 6's guidance points at the CLI as the one 'am I ready to build' surface. Fixing the slice-1 P3 in the same slice as the reader that consumes it keeps the ledger docHash contract single-sourced before it stabilises across the fleet.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:define-detection"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T16:33:15Z",
|
|
3
|
+
"updatedAt": "2026-09-24T16:33:15Z",
|
|
4
|
+
"reqId": "REQ-176",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "rcf define freeze verb writes freeze.json and closes the change",
|
|
7
|
+
"description": "rcf-lite gains src/cli/freeze.js implementing 'rcf define freeze [--ack <gate> --reason <text>]... [--litmus-attested <D3,D6>] [--note <text>] [--status] [--json]'. The verb runs computeReadiness (REQ-175) once over the live tree, freeze record and four ledgers; refuses with exit 4 when any stage state is 'failing' after applying any --ack argument, printing the failing gates and their first failing ids; and, on success, writes rcf/define/freeze.json via saveFreezeRecord (REQ-172) with { frozenAt, treeHash, docHashes, briefStatements, gates, counts, litmus, versions, note, override } and prints the proposal section 2.5 one-line summary derived from the pre-freeze delta ('frozen at <short treeHash>: <n> REQ, <n> stories, <n> criteria, <n> interfaces added; <ids> amended; ...'; first freeze reports 'first freeze: <whole-tree counts>'). --ack is accepted only for the three warn-with-ack gates (define.shapes, define.crosscut, define.consistency; short names shapes / crosscut / consistency; readiness's stage aliases); ack on any other gate is a usage refusal (exit 2), ack without --reason is a usage refusal. An acked gate lands in freeze.gates as { state: 'acknowledged', at: { hash: <currentTreeHash>, reason: <text> }, failing: [<id>, ...] }. --litmus-attested records the operator's per-decision attestation (Baz decision 7: default { attestedAt: [], readers: 0 }); the numbered --litmus <n> dispatch is NOT built (slice-6 seam). counts derives req/us/ac/tac/adr/fbs from tree.byId groupings, acByClass by parsing bracketed class markers on AC.description, and interfaces by kind from every TAC's interfaces[]. versions reads rcfLite from package.json, ruleset from src/ruleset/ruleset.json, and schemas from the installed @stravica-ai/rcf-schemas. --status prints the current freeze record (short hash, frozenAt, note, counts, acknowledged gates + reasons, litmus, versions, override) plus the live delta summary; --status --json emits the record and computeDelta object. The producer is wrapped with runWithAdmissibilityGate (ADR-4123: refusal is informational, the freeze still runs). Same slice: (a) src/define/freeze-record.js is corrected so the local schema requires override as a nullable field and every writer stamps override: null on a fresh freeze; loadFreezeRecord tolerates older records that lack the key by defaulting to null on load; (b) the ' -- ' double-dash in the readiness CLI stage header and the CHANGELOG regex line is replaced with a colon.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": ["persistence"],
|
|
15
|
+
"reason": "keyword-scan",
|
|
16
|
+
"classifiedAt": "2026-09-24T16:33:15Z",
|
|
17
|
+
"signals": [
|
|
18
|
+
{ "source": "description", "shape": "persistence", "match": "record" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"rationale": "Baz ruled on 2026-09-22 (proposal section 2.5) that closing a change is freezing again: the freeze verb is the only close verb, nothing is minted, and the one-line summary is what the operator signs off. Slice 3 is the smallest coherent seam between the pieces slices 1 and 2 built (delta, freeze-record writer, gates, computeReadiness) and the readers slices 4 and 5 will add (bundle --next, viewer Readiness tab). Warn-with-ack ack is accepted only on D3 / D5 / D6 per proposal section 9 decision 2 (Baz 2026-09-24) so the escape hatch matches the fold rule in gates.js. The freeze verb is also the only writer of freeze.gates and freeze.litmus, so writing them in the same slice that ships the writer keeps the record's schema surface single-sourced before slice 4 reads it. Bundling the slice-1 override-nullable P3 and the double-dash hygiene here is the same reasoning: the freeze verb is now the only writer of the record, so making override always-written is a one-touch change; the readiness CLI header's ' -- ' pattern is a small blast radius carried across the slice boundary.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-detection"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-01T18:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-02T19:30:00Z",
|
|
4
|
+
"reqId": "REQ-180",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "Readiness tab as tab 1 and the Overview-to-PRD rename",
|
|
7
|
+
"description": "src/view/readiness.js lands and html-page.js wires it as the first tab. The former Overview tab becomes PRD (same panel content; the rename is label-only). The Readiness panel renders the computeReadiness object top-to-bottom in the layout the DEFINE step 2 spec section 5 pins: tree line (formatTreeLine), two verdict pills with formatVerdictLines strings as the labels and blockedBy.length as the count, two per-persona next-action lines anchored into the stage detail, D1..D8 state chips with reason/acknowledgement text on hover, blockers grouped by persona (profile register orders the pair; the non-register group collapses with its count visible, never omitted), delta list grouped by REQ ancestor with a document-level diff on changed items (criterion-level diff deferred to the UX review per ADR-4127), per-stage check detail with persona pill and findings list when not ok, coverage tree-versus-delta with re-verify and re-execute counts, decisions outstanding in the #241 numbered format, a Freeze now control enabled iff levels.readyToBuild.ok (showing the `rcf define freeze` command and what it will record; disabled it names the failing gates from levels.readyToBuild.blockedBy; no intent-complete button), and the loaded freeze record (hash, when, note, counts, acknowledged gates with reasons). The view is pure: it never recomputes readiness, so the tab and `rcf define readiness --json` cannot disagree on the same tree hash. question cards grouped by source span rendering the questions object, per the viewer UI refresh design section 8.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"webUi"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-10-01T18:00:00Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "webUi",
|
|
23
|
+
"match": "tab"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "Baz ruling 2026-09-22 (DEFINE step 2 spec section 2.4, decision 2): one object, two renderers. The CLI (REQ-175, PR B) and the tab (REQ-180, PR C) read the same computeReadiness result so they cannot disagree. Readiness is where an operator starts, so it must be tab 1. The Overview panel is just the PRD body today (phase 3.6 dropped the diagram) so the rename is honest; keeping the hash-anchor `#tab-overview` preserves every existing link into the surface. The L1 pre-population posture (ADR-4126) requires the tab to visibly distinguish [draft] shapes from settled ones, which the shapes:draftSettled check row makes legible.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:define-detection"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-01T18:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-01T18:00:00Z",
|
|
4
|
+
"reqId": "REQ-181",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "Shared pill, findings-list and diff view components",
|
|
7
|
+
"description": "src/view/components/{pill,findings-list,diff}.js land as three stable modules every tab can call. pill({ value, variant, title?, href? }) returns a span (or anchor when href is set) with the vocabulary class `rcf-pill--<variant>` for the vocabulary family (gate state green/amber/red; level verdict yes/no; persona po/eng; AC class) and `rcf-pill--<normalisedValue>` for the specific value, so one call site renders one markup shape across every family. findingsList({ heading, count, items }) returns a heading plus an ordered id list, each item an anchor into the document tabs with a one-line `why` string, ids capped at 20 and a `... N more suppressed` tail beyond. diff(before, after) returns a two-column rendering of two document bodies for the delta list. Readiness is the first consumer in 0.29.0; Product Map and Requirements are re-pointed only where the swap is mechanical in this PR (otherwise their markup stays and the swap is a follow-up), so no existing Product Map or Requirements test expectation changes.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "defineDetection",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"webUi"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-10-01T18:00:00Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "webUi",
|
|
23
|
+
"match": "render"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "Three tabs today each ship their own markup for the same visual roles (status pill, items list, before-after). The hand-rolled copies drift so a gate state on one tab reads differently from the same gate state on another. Factoring to three shared components makes gate state, persona, level verdict and AC class read the same everywhere and is the smallest surface the Readiness tab needs. The spec is explicit (section 5): one module each, same markup shape across callers; existing tab tests change only where the PR explicitly re-points.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:define-detection"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-03T00:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-03T00:00:00Z",
|
|
4
|
+
"reqId": "REQ-182",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "DEFINE-stage guidance pack",
|
|
7
|
+
"description": "The DEFINE-stage guidance pack is served through `rcf guidance <slug>`, the `rcf://docs/<slug>` resources and the argument-free MCP prompts registered in guidance/manifest.json: define-intent and discovery-prototypes guidance, the elicitation-playbook restructure, two managed-block rules.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "define",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"none"
|
|
16
|
+
],
|
|
17
|
+
"reason": "operatorOverride",
|
|
18
|
+
"classifiedAt": "2026-10-03T00:00:00Z",
|
|
19
|
+
"signals": []
|
|
20
|
+
},
|
|
21
|
+
"rationale": "Spec 2026-10-01 (DEFINE step 3) section 6 pins the DEFINE-stage guidance surface: argument-free prompts (served from markdown in guidance/), resource URIs under `rcf://docs/`, and two managed-block rules the harness picks up through `rcf doctor`. REQ-182 was reserved by the PR 2 chain for this pack but did not land on origin/main; this PR authors it minimally with the amended description from spec section 11.8 (that shift is recorded at the top of report.md) so US-18202 has an owning REQ and the pack has a single home across DEFINE step 3 PRs. The amendment keeps room for later PRs to append: step 3 PR 7 will add `rcf_define_litmus` under the same REQ.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-intent"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-02T18:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-02T18:00:00Z",
|
|
4
|
+
"reqId": "REQ-186",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "guided product-owner elicitation",
|
|
7
|
+
"description": "rcf-lite computes, from the readiness object, the ordered set of questions one persona can answer, each with the write-back that answers it, so that a harness can conduct the intent-complete loop without an engineer. Nothing is stored; the loop ends when `levels.intentComplete.ok` is true.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "define",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"none"
|
|
16
|
+
],
|
|
17
|
+
"reason": "operatorOverride",
|
|
18
|
+
"classifiedAt": "2026-10-02T18:00:00Z",
|
|
19
|
+
"signals": []
|
|
20
|
+
},
|
|
21
|
+
"rationale": "Spec 2026-10-01 (DEFINE step 3) section 1 pins the loop as harness-driven. rcf-lite supplies the questions, the write-backs and the verdict; the harness holds the conversation. One new read verb `rcf define questions` turns every failing product-owner check into a per-item plain-sentence question carrying its exact write-back; `levels.intentComplete.ok === true` terminates the loop. The engineer register rides the same mechanism with `--persona engineer`.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-intent"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-02T16:40:00Z",
|
|
3
|
+
"updatedAt": "2026-10-02T16:40:00Z",
|
|
4
|
+
"reqId": "REQ-187",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "document intake into brief statements",
|
|
7
|
+
"description": "A submitted document reaches the brief ledger as kinded statements with source spans through `brief add --from`, the intake scans run over the new statements against the existing ones, and every finding becomes an open question the loop asks.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "define",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"persistence"
|
|
16
|
+
],
|
|
17
|
+
"reason": "keyword-scan",
|
|
18
|
+
"classifiedAt": "2026-10-02T16:40:00Z",
|
|
19
|
+
"signals": [
|
|
20
|
+
{
|
|
21
|
+
"source": "description",
|
|
22
|
+
"shape": "persistence",
|
|
23
|
+
"match": "ledger"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"rationale": "Spec 2026-10-01 (DEFINE step 3) section 2.1 splits intake into two halves. The harness writes a statement file beside each source and the operator corrects it. rcf-lite mints the statements, runs the intake scans over the new statements against the existing ones, and appends one openQuestion statement per finding. This is the seam decision 4 pins down: scan findings become brief statements so the loop reads one check (brief:openQuestions) and the owner answers in one place.",
|
|
28
|
+
"tags": [
|
|
29
|
+
"capability:define-intake"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-10-03T00:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-03T00:00:00Z",
|
|
4
|
+
"reqId": "REQ-188",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"title": "draft shapes for the engineer",
|
|
7
|
+
"description": "After intent-complete the agent pre-populates `[draft]` entities, components and interfaces as engineer entry material; `shapes:draftSettled` lists every draft home.",
|
|
8
|
+
"category": "functional",
|
|
9
|
+
"domain": "define",
|
|
10
|
+
"priority": "must",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"status": "draft",
|
|
13
|
+
"shapeClassification": {
|
|
14
|
+
"shapes": [
|
|
15
|
+
"none"
|
|
16
|
+
],
|
|
17
|
+
"reason": "operatorOverride",
|
|
18
|
+
"classifiedAt": "2026-10-03T00:00:00Z",
|
|
19
|
+
"signals": []
|
|
20
|
+
},
|
|
21
|
+
"rationale": "Spec 2026-10-01 (DEFINE step 3) section 3 and decision 8: once L1 is green, the agent populates one `[draft]` core entity per `entity` statement, one `[draft]` TAC stub per surface or external-system cluster, and `[draft]` interfaces with real kinds inside each stub, so the engineer walks into a tree whose shape is honest about what is still owed. `shapes:draftSettled` already fails `[draft]` on `TAC.interfaces[].description` in 0.29.0 (the current main; the 0.29.0 tag has not been cut). This REQ extends the marker to `TAC.purpose` and `coreEntities[].description` and extends the check to list all three id forms (`<tacId>:<name>`, `<tacId>`, `TAD.entity:<name>`). `tacHasInterface`, `kindVocabulary`, the new template-marker check and the entity join apply to drafts unchanged; nothing in the draft pass can fail a product-owner check, which is the property that keeps L1 and the draft pass independent.",
|
|
22
|
+
"tags": [
|
|
23
|
+
"capability:define-drafts"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T12:00:00Z",
|
|
3
|
+
"updatedAt": "2026-09-24T12:00:00Z",
|
|
4
|
+
"tacId": "TAC-4120-define-delta-and-freeze",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"tadId": "TAD-001",
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"status": "draft",
|
|
9
|
+
"name": "define delta compute and freeze record",
|
|
10
|
+
"purpose": "The detection-model primitives (hashDocument, computeTreeHash, computeDelta) live in a new pure module src/query/delta.js, exported from src/query/index.js alongside computeTrace, computeImpact and computeCoverage. The freeze record I/O sits in a new module src/define/freeze-record.js with a small local schema (until schemas 0.7 promotes it to manifest.freeze per ADR-4121). Both modules are pure per call: no filesystem I/O beyond the freeze reader / writer, no state, no time. Canonical JSON is defined on the parsed body, not the raw bytes: keys sorted recursively, no whitespace, JSON.stringify escaping. A whitespace-only reformat of a document produces the same hash; two objects that parse to the same value produce the same hash. Delta granularity is the standalone document: every id in tree.byId (PRD, TAD, BS, REQ, US, TAC, ADR, FBS, TS, CN, EVAL) contributes one docHash; inline AC / TC ride inside the parent's hash; the criterion-level diff is git's job (proposal section 2.2). Ledger docHashes are added under a ledger:<name> id per sidecar the caller passes in.",
|
|
11
|
+
"responsibilities": [
|
|
12
|
+
"src/query/delta.js: canonicaliseJson, hashDocument, computeTreeHash and computeDelta pure functions; JSDoc on computeDelta names the exact return shape AC-17201-1 pins.",
|
|
13
|
+
"src/query/index.js: re-export canonicaliseJson, hashDocument, computeTreeHash and computeDelta so every consumer imports through one seam.",
|
|
14
|
+
"src/define/freeze-record.js: FREEZE_RECORD_REL_PATH (rcf/define/freeze.json), FreezeRecordError, validateFreezeRecord, loadFreezeRecord (returns null on ENOENT, throws FreezeRecordError on parse or schema failure), saveFreezeRecord (validates then writes pretty JSON with trailing newline; creates rcf/define/ on demand).",
|
|
15
|
+
"Every hash is a 'sha256:<64-hex>' string; the record's docHashes values and treeHash are validated against that shape and rejected with a named field otherwise.",
|
|
16
|
+
"Extension fields (counts, litmus, versions, note, override, gates) survive a save / load round trip; the writer refuses to persist an invalid record so a bad in-memory value never lands on disk."
|
|
17
|
+
],
|
|
18
|
+
"internalStructure": "canonicaliseJson recurses over parsed values: object keys sorted lexicographically, arrays kept in source order, JSON.stringify handles string / number / boolean escaping (non-finite numbers coerce to 'null' as JSON does), undefined is omitted from objects and arrays (matches JSON.stringify semantics). computeTreeHash normalises the input (Map or plain object) into sorted (id, docHash) pairs, canonically encodes the pair array, and hashes the resulting string; the tree hash is thereby order-independent by construction. computeDelta walks tree.byId once, hashes each doc, adds one ledger:<name> entry per non-nullish ledger the caller passes, then either returns the whole-tree 'added' shape (freeze absent) or classifies every id against freeze.docHashes; briefSince walks the brief ledger's statements[] and reports ids above freeze.briefStatements.",
|
|
19
|
+
"interfaces": [],
|
|
20
|
+
"notes": "Slice-2 hook: the readiness module will call computeDelta once per render, pass the result through computeImpact per changed id, and hand the union of changed + added + fan-out to every gate check. Slice 3 (the freeze verb) is the only caller of saveFreezeRecord in the shipped path; this slice ships the writer so the verb can be built without a second refactor."
|
|
21
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T12:00:00Z",
|
|
3
|
+
"updatedAt": "2026-10-02T16:40:00Z",
|
|
4
|
+
"tacId": "TAC-4121-define-ledgers",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"tadId": "TAD-001",
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"status": "draft",
|
|
9
|
+
"name": "define ledgers module and rcf define ledger CLI",
|
|
10
|
+
"purpose": "The four sidecar ledgers land under rcf/define/ as one JSON file each, with one numbered sequence per ledger for the life of the project. The pure module src/define/ledgers.js exposes LEDGER_NAMES (the four allowed values), BRIEF_KINDS, LedgerError, emptyLedger, ledgerRelPath, ledgerPath, loadLedger, saveLedger, validateLedger, addEntry, resolveEntry, nextIdFor, parseBriefFromFile and loadAllLedgers (returns a LedgerBundle for computeDelta). The CLI verb src/cli/ledger.js wraps the module with parseArgs, wires under bin/rcf.js's define group as GROUPS.define.ledger, and prints usage text also mounted in src/cli/help.js's HELP_MAP.define.ledger so `rcf help define ledger` and `rcf define ledger --help` render the same block by construction.",
|
|
11
|
+
"responsibilities": [
|
|
12
|
+
"src/define/ledgers.js: LEDGER_NAMES = ['brief','decisions','concerns','probes']; per-ledger config maps a name to its filename (brief-ledger.json, decisions-ledger.json, concern-ledger.json, probe-ledger.json) and its body array key (statements | decisions | concerns | probes).",
|
|
13
|
+
"loadLedger returns emptyLedger(name) on ENOENT; a malformed file raises LedgerError with a code ('parseFailure' | 'schemaFailure' | 'ioFailure' | 'usage') and a named field.",
|
|
14
|
+
"addEntry mints the next id (highest current + 1), stamps addedAt and defaults status open, validates the resulting body before returning it, refuses unknown BRIEF_KINDS at validation.",
|
|
15
|
+
"resolveEntry flips status to resolved, stamps resolvedAt, throws LedgerError code 'usage' when the id is unknown, is idempotent-ish (resolving twice refreshes resolvedAt).",
|
|
16
|
+
"parseBriefFromFile splits by non-empty lines, strips leading '- ', '* ' or '<n>. ' bullets, defaults kind to 'capability', and threads --source through to every draft.",
|
|
17
|
+
"src/cli/ledger.js: `rcf define ledger <name> <verb>` argv parsing; verbs add / resolve / list; ledger-specific flags for each; renderDecisionsList formats the #241 numbered layout; list --json emits { ledger, <arrayKey>: [...] }.",
|
|
18
|
+
"bin/rcf.js: register GROUPS.define.ledger; src/cli/help.js: import LEDGER_HELP and wire into HELP_MAP.define.ledger + DEFINE_HELP + top-level DEFINE listing so per-verb help stays single-sourced.",
|
|
19
|
+
"`update <id>` subverb patches named fields and re-runs full-body validation; `resolvedBy` is a closed pointer grammar (REQ-nnn, TAD.entity:<name>, PRD.user:<name>, TAD.system:<name>, TAC-nnnn, omitted:<reason>) validated by D2."
|
|
20
|
+
],
|
|
21
|
+
"internalStructure": "The walker never reads under rcf/define/: subdirFor in src/core/store/loader.js returns null for anything that is not a known child kind (requirements, user-stories, tacs, adrs, fbs, test-suites, code-nodes, evals), so a ledger file sitting under rcf/define/ is never enumerated for schema validation. The walker-invisibility invariant is proved by a dedicated test that seeds the four ledger files plus a bug-bait req-shaped file under rcf/define/ and asserts zero walker error paths starting with rcf/define/ and no matching id in tree.byId. Validation is JSON-schema-shaped inline (no ajv, no @stravica-ai/rcf-schemas dependency) because the sidecars ride outside the shared schema until schemas 0.7 (ADR-4121).",
|
|
22
|
+
"interfaces": [
|
|
23
|
+
{
|
|
24
|
+
"name": "rcf define ledger <name> update <id>",
|
|
25
|
+
"kind": "cliCommand",
|
|
26
|
+
"description": "Patch named fields on an existing ledger entry (brief, decisions, concerns or probes); full-body validation runs as `add` validates. On brief, `--resolved-by` must match the closed pointer grammar."
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "parseResolvedBy",
|
|
30
|
+
"kind": "other",
|
|
31
|
+
"description": "Parse a resolvedBy pointer against the tree; returns { ok, kind, target } on a resolved form (REQ-nnn, TAD.entity:<name>, PRD.user:<name>, TAD.system:<name>, TAC-nnnn, omitted:<reason>) and { ok: false, why } otherwise."
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"notes": "The intake-scan-against-frozen-statements hook on brief add --from is a named seam this slice leaves for a later one: 'rcf discover intake' is the intended caller in slice 2's D1 gate check, and this slice ensures the CLI has one place to inject that seam without a second refactor. `list --json` is a keep-alive for slice 5's viewer, which will render the same object over http."
|
|
35
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-09-24T14:30:00Z",
|
|
3
|
+
"updatedAt": "2026-10-03T00:00:00Z",
|
|
4
|
+
"tacId": "TAC-4122-define-gates",
|
|
5
|
+
"prdId": "PRD-001",
|
|
6
|
+
"tadId": "TAD-001",
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"status": "draft",
|
|
9
|
+
"name": "define stage gates D1..D8",
|
|
10
|
+
"purpose": "src/query/gates.js lands as a new pure module beside delta.js. Every stage has one exported check function that takes (tree, context) and returns the { stage, gate, state, checks[] } shape section 2.4 pins. computeReadiness (TAC-4123) is the composer; every gate function is otherwise consumable in isolation for tests and for future viewers that render one stage. No I/O, no state, no time: the caller supplies ledgers, profile, freeze, delta, validate errors, probe count and coverage rollups.",
|
|
11
|
+
"responsibilities": [
|
|
12
|
+
"src/query/gates.js: STAGE_ORDER = ['D1','D2','D3','D4','D5','D6','D7','D8']; STAGE_GATES map (D1 -> 'define.brief' etc.); INTERFACE_KINDS closed set matching proposal section 5.2; STAGE_SHORT_NAMES map (D1 -> 'brief' etc.).",
|
|
13
|
+
"checkD1Brief: intake acknowledged (brief-ledger has at least one statement since the freeze high-water mark), every statement kinded from BRIEF_KINDS, every openQuestion statement resolved or promoted to a decisions-ledger entry, profile.md carries surface (viewer | runningApp | prDiff) and register (productOwner | engineer | unstated) markers.",
|
|
14
|
+
"checkD2Skeleton: every 'capability' and 'constraint' statement in scope resolves to a REQ (via a REQ id in the statement's resolvedBy field OR by name-match against a REQ title, cheap check); every REQ in scope has non-TODO description, shapeClassification and domain; TAD.dataArchitecture.dataStores and TAD.dataArchitecture.coreEntities non-empty when any persistence REQ exists (per rcf-schemas 0.6.3 tad.schema.json; the top-level path was a slice-2 drift corrected under w-2026-09-25-dave-004); exactly one deploy or deferral ADR tree-wide (title prefix 'Deploy target:' or 'Deploy deferral:').",
|
|
15
|
+
"checkD3Shapes: every TAC in scope has at least one interface; every interface's kind is in INTERFACE_KINDS. Template markers, entity join, ownerRef resolution and path resolution are seams (0.30).",
|
|
16
|
+
"checkD4Stories: every REQ in scope has at least one US (fbsByAcId inversion via reqByUs is enough); every US in scope has a testable AC (ac.testable !== false and description non-empty), a failure AC or a project-scoped or req-scoped opt-out with baselineKey 'defineD4:failure', a must-not AC or an opt-out with baselineKey 'defineD4:mustNot', tacIds non-empty and every id resolving to a walker-known TAC, and no AC description containing the scaffold TODO placeholder pattern (case-sensitive uppercase 'TODO:' with a colon -- the literal shape src/core/store/init.js writes; incidental prose mentioning 'todo' does NOT trip the gate, and the validate CLI's broader whole-word notice stays separate).",
|
|
17
|
+
"checkD5Crosscut: TAD.securityArchitecture non-empty when tree carries any REQ with shape 'auth' or 'httpApi'; TAD.operationalConcerns non-empty when any AC description carries the '[deployed]' marker; every concern-ledger entry on a REQ in scope has disposition applied or waived (no status 'open').",
|
|
18
|
+
"checkD6Consistency: caller-supplied validateErrors is empty (tree-wide); caller-supplied probeOpenCount is zero.",
|
|
19
|
+
"checkD7Decisions: no decisions-ledger entry with status 'open'.",
|
|
20
|
+
"checkD8Freeze: prior stages passed | acknowledged at the current tree hash; every AC id owned by exactly one FBS (walker.fbsByAcId length 1); computeQueue.nextActionable is not null (queue head actionable) and the head's title is not 'TODO' or empty; validateErrors empty.",
|
|
21
|
+
"src/setup/identity-seed.js IDENTITY_TEMPLATE seeds a '## Surface' section carrying one of 'viewer' | 'runningApp' | 'prDiff' (default 'prDiff') so a fresh 'rcf init' project satisfies checkD1Brief's profile:surface marker without the operator editing profile.md first.",
|
|
22
|
+
"ADR-4126 (0.29.0): own the per-check persona and question map; export `CHECK_PERSONA`, `CHECK_QUESTION`, `STAGE_FALLBACK_PERSONA`, `checkPersona(name)`, `checkQuestion(name)` and `parseInterfaceDraft(iface)`. Every entry in `stages[].checks[]` carries `persona` (productOwner | engineer) and a non-empty `question`; the `stage:<D>:scope` placeholder uses `STAGE_FALLBACK_PERSONA`.",
|
|
23
|
+
"ADR-4126 (0.29.0): split `skeleton:reqFields` into `skeleton:reqIntent` (productOwner: description without TODO and domain, evaluated per REQ independently) and `skeleton:reqShape` (engineer: shapeClassification.shapes). Split `decisions:allAnswered` into `decisions:wellFormed` (productOwner: non-empty question + two or more options + a default naming one of them) and `decisions:allAnswered` (engineer: zero open).",
|
|
24
|
+
"ADR-4126 (0.29.0): new D3 check `shapes:draftSettled` fails any interface whose `description` starts with `[draft]` (whitespace tolerated), id `<tacId>:<name>`, over delta, total = interfaces on TACs in scope; `tacHasInterface` counts a draft as present; `kindVocabulary` applies to drafts.",
|
|
25
|
+
"`shapes:draftSettled` reports `[draft]` on `TAC.purpose`, `coreEntities[].description` and `TAC.interfaces[].description` with ids `<tacId>`, `TAD.entity:<name>` and `<tacId>:<name>` respectively (REQ-188, 0.30.0): `parseInterfaceDraft` reads the marker on all three homes with the same whitespace-tolerant rule; the draft pass enumerates across the three homes; nothing in the draft pass can fail a product-owner check."
|
|
26
|
+
],
|
|
27
|
+
"internalStructure": "Every stage function follows the same shape: 1) decide notApplicable per section 3.2 and return { state: 'notApplicable' } with a single-check summary; 2) build checks[] as a list of { name, ok, over, pass, total, failing: [{ id, why }] }; 3) fold to state: 'passed' if every ok is true; 'failing' otherwise, unless the stage is D3/D5/D6 AND freeze.gates[<gate>].state === 'acknowledged' AND freeze.gates[<gate>].at.hash === currentTreeHash, in which case state is 'acknowledged'. Blocking-vs-warn is a property of the stage, not of the state: D3/D5/D6 use the acknowledged fold, D1/D2/D4/D7/D8 do not. The caller (readiness) folds the array of stage results into freezeable and nextAction.",
|
|
28
|
+
"interfaces": [
|
|
29
|
+
{
|
|
30
|
+
"name": "CHECK_PERSONA",
|
|
31
|
+
"kind": "other",
|
|
32
|
+
"description": "[draft] Owning persona map (productOwner | engineer) for every stage-gate check in 0.29.0 (ADR-4126)."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "CHECK_QUESTION",
|
|
36
|
+
"kind": "other",
|
|
37
|
+
"description": "[draft] Per-check heading question in the owning persona's register; the report and the Readiness tab print it as the heading of each check's findings list."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "STAGE_FALLBACK_PERSONA",
|
|
41
|
+
"kind": "other",
|
|
42
|
+
"description": "[draft] Per-stage fallback persona for the `stage:<D>:scope` placeholder check that `notApplicable` envelopes carry."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "checkPersona",
|
|
46
|
+
"kind": "other",
|
|
47
|
+
"description": "[draft] Look up the owning persona for a check name; returns 'productOwner' | 'engineer' | null."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "checkQuestion",
|
|
51
|
+
"kind": "other",
|
|
52
|
+
"description": "[draft] Look up the question heading for a check name; returns the empty string when no question is registered."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "parseInterfaceDraft",
|
|
56
|
+
"kind": "other",
|
|
57
|
+
"description": "[draft] True when an interface's `description` carries the leading `[draft]` marker (whitespace tolerated)."
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"notes": "Slice-3 hook (rcf define freeze): reads state to refuse on any 'failing'; --ack <gate> --reason <text> writes freeze.gates[<gate>] = { state: 'acknowledged', at: { hash: <currentTreeHash>, reason: <text>, by: <id> } } and re-runs computeReadiness to check freezeable. Slice-5 hook (viewer): reads the same object end-to-end."
|
|
61
|
+
}
|