rcf-lite 0.28.1 → 0.28.4
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 +310 -0
- package/bin/rcf.js +4 -0
- package/fixtures/canary-manifest.json +9 -9
- 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/code-nodes/cn-602.json +3 -2
- 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 +21 -0
- package/rcf/code-nodes/cn-726.json +17 -0
- package/rcf/code-nodes/cn-727.json +14 -0
- package/rcf/code-nodes/cn-728.json +21 -0
- package/rcf/code-nodes/cn-729.json +18 -0
- package/rcf/code-nodes/cn-730.json +14 -0
- package/rcf/fbs/fbs-181.json +3 -2
- 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 +37 -0
- package/rcf/fbs/fbs-197.json +41 -0
- package/rcf/requirements/req-001.json +2 -1
- package/rcf/requirements/req-002.json +2 -1
- 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 +25 -0
- package/rcf/requirements/req-175.json +25 -0
- package/rcf/tacs/tac-4103-feedback-redact.json +2 -2
- package/rcf/tacs/tac-4120-define-delta-and-freeze.json +21 -0
- package/rcf/tacs/tac-4121-define-ledgers.json +23 -0
- package/rcf/tacs/tac-4122-define-gates.json +25 -0
- package/rcf/tacs/tac-4123-define-readiness.json +25 -0
- package/rcf/test-suites/ts-188.json +10 -2
- package/rcf/test-suites/ts-191.json +19 -5
- 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 +67 -0
- package/rcf/test-suites/ts-216.json +78 -0
- package/rcf/test-suites/ts-217.json +62 -0
- package/rcf/user-stories/us-15601.json +10 -1
- package/rcf/user-stories/us-15701.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-17401.json +58 -0
- package/rcf/user-stories/us-17501.json +48 -0
- package/releases/releases.yaml +31 -1
- package/src/browser-verify/manifest-writer.js +9 -5
- package/src/cli/browser-verify.js +9 -1
- package/src/cli/feedback.js +316 -32
- package/src/cli/help.js +11 -0
- package/src/cli/intake.js +25 -4
- package/src/cli/ledger.js +399 -0
- package/src/cli/preflight.js +24 -3
- package/src/cli/readiness.js +280 -0
- package/src/cli/review.js +9 -1
- package/src/cli/ui-baseline.js +14 -1
- package/src/core/store/index.js +5 -0
- package/src/core/store/validate-composed-record.js +95 -0
- package/src/core/store/writer.js +86 -6
- package/src/define/freeze-record.js +232 -0
- package/src/define/ledgers.js +513 -0
- package/src/feedback/gh.js +27 -1
- package/src/feedback/redact-allowlist.json +7 -0
- package/src/feedback/redact.js +126 -11
- package/src/feedback/render.js +34 -12
- package/src/intake/manifest-writer.js +6 -3
- package/src/intake/orchestrator.js +44 -7
- package/src/preflight/manifest-writer.js +11 -11
- package/src/query/delta.js +276 -0
- package/src/query/gates.js +832 -0
- package/src/query/index.js +36 -0
- package/src/query/readiness.js +333 -0
- package/src/req-baseline/sweep.js +34 -5
- package/src/server/index.js +37 -0
- package/src/server/routes.js +65 -3
- package/src/ui-baseline/manifest-writer.js +11 -10
- package/src/view/doc-renderers/helpers.js +39 -2
- package/src/view/doc-renderers/req.js +10 -2
- package/src/view/doc-renderers/tad.js +67 -6
- package/src/view/doc-renderers/user-story.js +10 -5
- package/src/view/html-page.js +347 -28
- package/src/view/index.js +14 -1
- package/src/view/live-client.js +22 -2
- package/src/view/product-map.js +751 -0
- package/src/view/style.css +383 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-17301",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-173",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "rcf define ledger reads and writes the four sidecars under rcf/define/",
|
|
8
|
+
"description": "User story under REQ-173. The operator-facing CLI for the four sidecar ledgers lands with add / resolve / list on every ledger name.",
|
|
9
|
+
"asA": "an operator staging or reviewing a DEFINE change",
|
|
10
|
+
"iWant": "rcf define ledger to author brief statements, decisions, concern dispositions and probe findings under rcf/define/ with numbered ids stable for the life of the project, and to leave every ledger invisible to the walker",
|
|
11
|
+
"soThat": "the freeze record's high-water mark, the D7 decisions list, D5 concern coverage and D6 probe findings all have a written record and every later DEFINE slice reads the same seam without discovering a second source of truth",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-17301-1",
|
|
15
|
+
"description": "rcf define ledger brief add --kind <k> --text <t> appends a numbered statement to rcf/define/brief-ledger.json, mints the next id (highest current + 1), stamps status open and addedAt (ISO-8601), refuses an unknown kind with a usage-class error, and refuses --text combined with --from with a usage-class error.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-17301-2",
|
|
20
|
+
"description": "rcf define ledger decisions list prints the numbered #241 format: one decision per item (id. question), options rendered as 'letter) text', the default letter labelled 'default:', and what it blocks labelled 'blocks:'. rcf define ledger <name> list --json emits the machine-readable envelope { ledger, <arrayKey>: [...] }.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-17301-3",
|
|
25
|
+
"description": "rcf define ledger brief add --from <file> reads the file, splits it into one statement per non-empty line (stripping leading '- ', '* ' or '<n>. ' bullets), mints sequential ids for every statement, refuses if the file produced zero non-empty lines, and stamps the file path as source unless --source overrides it. The intake-scan-against-frozen-statements hook is a named seam in the writer, not called in this slice.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-17301-4",
|
|
30
|
+
"description": "walkTree run over a project that carries rcf/define/freeze.json, all four ledger files, and a bug-bait file named req-999.json under rcf/define/ never surfaces any rcf/define/ file as a tree.byId document and reports no walker error naming a rcf/define/ path. The sidecar directory is invisible to every consumer of walkTree.",
|
|
31
|
+
"testable": true
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"tacIds": ["TAC-4121-define-ledgers"],
|
|
35
|
+
"tags": [],
|
|
36
|
+
"createdAt": "2026-09-24T12:00:00Z",
|
|
37
|
+
"updatedAt": "2026-09-24T12:00:00Z"
|
|
38
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-17401",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-174",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Stage gates land as pure check functions with per-stage state",
|
|
8
|
+
"description": "User story under REQ-174. Eight stage-gate check functions land in src/query/gates.js with a stable per-stage return shape that computeReadiness and every later slice can consume unchanged.",
|
|
9
|
+
"asA": "a downstream consumer of DEFINE gates (readiness, freeze, viewer)",
|
|
10
|
+
"iWant": "gates.js to expose one pure check function per stage D1..D8, each returning a { stage, gate, state, checks[] } object with checks in the { name, ok, over: 'delta'|'tree', pass, total, failing: [{ id, why }] } shape",
|
|
11
|
+
"soThat": "computeReadiness composes the eight checks, the freeze verb refuses on any failing state, and the viewer's Readiness tab prints the same rows the CLI does with no schema translation",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-17401-1",
|
|
15
|
+
"description": "src/query/gates.js exports one check function per stage D1..D8 (checkD1Brief, checkD2Skeleton, checkD3Shapes, checkD4Stories, checkD5Crosscut, checkD6Consistency, checkD7Decisions, checkD8Freeze), each taking (tree, { ledgers, profile, scope, freeze, delta, validateErrors, probeOpenCount, coverageTree }) and returning { stage, gate, state, checks[] }; every entry in checks is { name, ok, over: 'delta'|'tree', pass, total, failing: [{ id, why }] } (failing empty on ok).",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-17401-2",
|
|
20
|
+
"description": "Blocking stages in 0.29.0 (D1, D2, D4, D7, D8) report state 'passed' when every check ok is true, 'failing' when any check ok is false; warn-with-ack stages (D3, D5, D6) report 'passed' when every check ok is true, 'failing' when any check ok is false and the freeze record does NOT acknowledge that gate at the current tree hash, and 'acknowledged' when the freeze.gates[<gate>] entry names state 'acknowledged' and at.hash === currentTreeHash and any check ok is false.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-17401-3",
|
|
25
|
+
"description": "notApplicable is decided per stage per proposal section 3.2: D2 notApplicable when no statement of a resolving kind (capability, constraint, entity, actor, externalSystem, surface) is in the delta AND no REQ, PRD or TAD is in scope; D3 notApplicable when no TAC and no shaped REQ (httpApi/persistence/auth) is in scope; D5 notApplicable when no REQ is in scope; D7 notApplicable when no open decisions exist AND the profile sets skipReviewFor: singleDocument AND the delta holds exactly one document; D4 and D6 use their own rules; D1 and D8 never notApplicable.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-17401-4",
|
|
30
|
+
"description": "checkD4Stories enforces the D4 floors: every REQ in scope has a US (fail: 'no owning user story'), every US in scope has a testable AC ('missing testable AC'), a failure AC (parsed by the bracketed [failure] prefix on AC description) or a reasoned opt-out per class (manifest.baselineAcOptOuts[] entry with baselineKey 'defineD4:failure' and matching scope), a must-not AC (parsed by [must-not] prefix) or a reasoned opt-out per class (baselineKey 'defineD4:mustNot'), tacIds non-empty and every named tac resolving to a real TAC, and no AC description contains the scaffold TODO placeholder.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-17401-5",
|
|
35
|
+
"description": "checkD3Shapes runs only cheap data-backed checks in 0.29.0: every TAC in scope has at least one interface (fail: 'no interfaces authored'), and every interface's kind is in the closed vocabulary { recordShape, httpRoute, event, cliCommand, uiRoute, port, fileFormat, fixture, other } (fail: 'unknown interface kind <k>'). The template parser, entity-name join, ownerRef and path resolution are named seams (not called this slice) and D3 stays warn-with-ack.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-17401-6",
|
|
40
|
+
"description": "checkD5Crosscut runs only cheap data-backed checks in 0.29.0: TAD.securityArchitecture non-empty when the tree carries any REQ whose shapeClassification.shapes includes 'auth' or 'httpApi'; TAD.operationalConcerns non-empty when any AC description carries the '[deployed]' marker (a cheap presence signal proposal section 3.2 D5 lists as 'deployed-scope AC'); concern-ledger entries in scope disposed as 'applied' or 'waived' (no dangling 'open' concerns on REQs in scope). The full catalogue and per-pair enumeration are named seams for 0.30.",
|
|
41
|
+
"testable": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "AC-17401-7",
|
|
45
|
+
"description": "checkD6Consistency runs only cheap data-backed checks in 0.29.0: validate is clean tree-wide (validateErrors is empty; the caller passes the walker + validator's error list), and probe-ledger holds zero 'open' probe entries. Contradiction-lite, unsatisfiable-lite, duplicates and orphan-interface scans, plus the probe runner, are named seams for 0.30.",
|
|
46
|
+
"testable": true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "AC-17401-8",
|
|
50
|
+
"description": "checkD8Freeze enforces the tree-wide gate: every prior stage state (D1..D7 as computeReadiness composes them) is passed or acknowledged at the current hash; every AC id in the tree is bound by exactly one FBS (walker's fbsByAcId map has length 1); the queue head (computeQueue.nextActionable) is not null; validateErrors is empty. The stage is never notApplicable.",
|
|
51
|
+
"testable": true
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"tacIds": ["TAC-4122-define-gates"],
|
|
55
|
+
"tags": [],
|
|
56
|
+
"createdAt": "2026-09-24T14:30:00Z",
|
|
57
|
+
"updatedAt": "2026-09-24T14:30:00Z"
|
|
58
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-17501",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-175",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "computeReadiness and rcf define readiness render the same object",
|
|
8
|
+
"description": "User story under REQ-175. computeReadiness lands as a pure module and rcf define readiness as its CLI twin. The viewer's Readiness tab (slice 5) will render the same object with no schema translation.",
|
|
9
|
+
"asA": "an operator asking 'can I build, and if not what is in the way'",
|
|
10
|
+
"iWant": "one pure compute that composes delta, fan-out, gates, coverage and decisions into a single object, and one CLI that prints it in a compact form or emits it as JSON",
|
|
11
|
+
"soThat": "the tree line, next action, stage chips, delta list and failing items are the same wherever they are shown, and slice 3's rcf define freeze refuses on the same freezeable flag the CLI reports",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-17501-1",
|
|
15
|
+
"description": "computeReadiness(tree, { freeze, ledgers, profile, testPointers }) returns the exact section 2.4 shape: tree { frozen, frozenAt, treeHash, currentTreeHash, buildAt, fbsTotal }, delta { changed, added, removed, briefSince, impacted, impactedFbs }, stages [{ stage, gate, state, checks }], nextAction { stage, check, ids, command } or null, coverage { tree, delta }, decisions [...open in #241 format], freezeable boolean. freezeable is true when every stage state is 'passed', 'acknowledged' or 'notApplicable'.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-17501-2",
|
|
20
|
+
"description": "Fan-out is computed by calling computeImpact once per id in the union of changed and added; impacted is the union of every impact node id excluding the pivots; impactedFbs is the subset whose kind is 'fbs' and actionNeeded is 're-execute'. Gates run over scope = changed union added union impacted (with duplicates removed).",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-17501-3",
|
|
25
|
+
"description": "Coverage is tree-wide plus per REQ ancestor of the delta: coverage.tree is computeCoverage(tree, { testPointers, strict: true }) once over the whole tree; coverage.delta is an array with one CoverageResult per unique REQ id reachable by walking back from every delta id (changed union added) through parentByChild until the reqId is found, using scopeId per invocation. testPointers is the map the CLI produced with resolveTestPointers.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-17501-4",
|
|
30
|
+
"description": "nextAction picks the first stage in D1..D8 order whose state is 'failing', then the first failing check in that stage's checks[] (or the check with the largest failing.length when tie); it names the stage id, the check name, the failing ids (deduped), and a command string like 'rcf define readiness --check <stage-short-name> after editing'. nextAction is null when every stage is passed / acknowledged / notApplicable.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-17501-5",
|
|
35
|
+
"description": "rcf define readiness prints a text summary: the tree line ('Frozen at <shortHash> on <frozenAt>. N documents changed since, M impacted. Build at <fbsId> of <total>; K FBS impacted.' or 'Unfrozen. N documents; the whole tree is the delta.'), the next action line, a chip line 'D1:passed D2:failing D3:acknowledged D4:notApplicable ...', and the failing-items list per stage. --json emits the full computeReadiness object under `${JSON.stringify(result, null, 2)}\\n`. --check <stage> (D1..D8 or short name brief|skeleton|shapes|stories|crosscut|consistency|decisions|freeze) prints only that stage and exits 0 when its state is 'passed' or 'acknowledged' or 'notApplicable', exit 4 on 'failing' for blocking stages (D1, D2, D4, D7, D8), exit 0 with a visible '[warn]' line on 'failing' for warn-with-ack stages (D3, D5, D6). The verb wraps its producer with runWithAdmissibilityGate and, on admissibility refusal, prints the refusal on stderr and exits 4.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-17501-6",
|
|
40
|
+
"description": "loadAllLedgers({ projectRoot }) returns a LedgerBundle that OMITS a ledger key when the sidecar file does not exist (ENOENT), so computeDelta records no docHash for absent ledgers; the docstring on computeDelta (LedgerBundle typedef) and the loader implementation agree. A project that has authored a brief ledger and no others sees exactly one 'ledger:brief' entry in the delta docHashes; a project that has authored no ledgers sees zero 'ledger:*' entries.",
|
|
41
|
+
"testable": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"tacIds": ["TAC-4123-define-readiness"],
|
|
45
|
+
"tags": [],
|
|
46
|
+
"createdAt": "2026-09-24T14:30:00Z",
|
|
47
|
+
"updatedAt": "2026-09-24T14:30:00Z"
|
|
48
|
+
}
|
package/releases/releases.yaml
CHANGED
|
@@ -40,8 +40,38 @@
|
|
|
40
40
|
# `npm install rcf-lite`.
|
|
41
41
|
|
|
42
42
|
feedVersion: 1
|
|
43
|
-
latest: "0.28.
|
|
43
|
+
latest: "0.28.4"
|
|
44
44
|
releases:
|
|
45
|
+
- version: "0.28.4"
|
|
46
|
+
date: "2026-09-30"
|
|
47
|
+
breaking: false
|
|
48
|
+
headlines:
|
|
49
|
+
- "rcf-lite 0.28.4 fixes user story minting on legacy trees that carry flat sequential ids. On a tree migrated in from a v1 project, minting a new user story under a requirement now extends the flat sequence (US-163 to US-164) instead of jumping to an encoded slot such as US-5301; a tree that mixes both id shapes is refused with a message naming one example of each so the operator can normalise it first. Acceptance criteria minting is unchanged."
|
|
50
|
+
- "The 0.28.3 fixes ship in this release, because 0.28.3 was written up on 22 September but never tagged or published. Those are the feedback redactor no longer folding git protocol sentinels as emails, a visible warning when identity folding is disabled, and the live-view server snapshotting its static assets at startup."
|
|
51
|
+
- "The DEFINE workflow foundations arrive ahead of the 0.29.0 train: delta detection, freeze records, four sidecar ledgers with rcf define ledger, stage gates D1 to D8, and rcf define readiness, plus the Product Map tab on the review surface."
|
|
52
|
+
minAgentAction: null
|
|
53
|
+
notesUrl: "https://stravica.ai/docs/rcf/changelog/"
|
|
54
|
+
|
|
55
|
+
- version: "0.28.3"
|
|
56
|
+
date: "2026-09-22"
|
|
57
|
+
breaking: false
|
|
58
|
+
headlines:
|
|
59
|
+
- "rcf-lite 0.28.3 is a small batched fix release for the residuals Dex's 0.28.2 round-trip surfaced and one HQ-side viewer bug caught the same day. The feedback redactor no longer folds the git protocol sentinel git@<host> inside git+ssh, ssh or git URLs as an email, so an evidence pointer copied verbatim from a git remote or clone URL survives as evidence. Bare git remotes and single-letter trailing labels like a.b.c are also protected as URI userinfo and filename fragments; real emails in surrounding prose still fold."
|
|
60
|
+
- "The redactor emits a visible stderr warning when identity folding is disabled, so an operator whose rcf/.identity/profile.md is missing, empty, a placeholder, or contains only reserved nouns is no longer left thinking their identity is in force when it silently is not. Feedback status --json now exposes the destination source field the preview surface already prints, and --evidence pointers now render with the label matching their shape (command / path:line / id) rather than always (command)."
|
|
61
|
+
- "The live-view server snapshots its shipped static assets (style.css, mermaid.min.js, live-client.js) at startup instead of reading them from disk per request, so a checkout branch switch during the server's lifetime can no longer silently change the served CSS."
|
|
62
|
+
minAgentAction: null
|
|
63
|
+
notesUrl: "https://stravica.ai/docs/rcf/changelog/"
|
|
64
|
+
|
|
65
|
+
- version: "0.28.2"
|
|
66
|
+
date: "2026-09-22"
|
|
67
|
+
breaking: false
|
|
68
|
+
headlines:
|
|
69
|
+
- "rcf-lite 0.28.2 is a batched fix release for the seven defects Barry's WSD-lens dogfood on 0.28.1 surfaced, plus three unreported dry-run gaps folded into the same release. Feedback submit no longer folds unrelated findings into one issue and no longer replaces the report with a +1 stub. Submit re-reads every candidate issue body and folds only on a verified fingerprint match, refusing to fold across differing anchor or target; every fold comment now carries the full report. The redactor also stops rewriting .md filenames as hostnames: a candidate whose trailing dot-label is on a bundled extensions shortlist in redact-allowlist.json is left intact."
|
|
70
|
+
- "The five discover verbs share one schema pass across --dry-run and the write path (intake, preflight, review, ui-baseline init, browser-verify). A preview now reports the same validation error the real run would refuse on, so intake --dry-run --input catches a fidelity enum miss and preflight --dry-run --input catches a kebab-case service id. intake and preflight --help advertise their allowed values."
|
|
71
|
+
- "Three more build defects ride along: discover intake dedupes findings before writing the record so a shared branch that fires on two artefacts lands as one finding, req-baseline sweep --yes now allocates distinct AC ids across a batch on one user story, and the TAD review surface renders dataStores, coreEntities and externalSystems as tables instead of raw JSON.stringify blobs."
|
|
72
|
+
minAgentAction: null
|
|
73
|
+
notesUrl: "https://stravica.ai/docs/rcf/changelog/"
|
|
74
|
+
|
|
45
75
|
- version: "0.28.1"
|
|
46
76
|
date: "2026-09-17"
|
|
47
77
|
breaking: false
|
|
@@ -5,7 +5,7 @@ import { mkdir, rename, unlink, writeFile } from 'node:fs/promises';
|
|
|
5
5
|
import { dirname, join } from 'node:path';
|
|
6
6
|
|
|
7
7
|
import { rcfError } from '#core/errors';
|
|
8
|
-
import { validateDocument } from '#core/store';
|
|
8
|
+
import { buildNextManifest, validateDocument } from '#core/store';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Compute the next `bv-<fbsId>-<n>` id: monotonic per FBS.
|
|
@@ -181,10 +181,14 @@ function stripSeverity(check) {
|
|
|
181
181
|
* @returns {Promise<{ record: object } | import('#core/errors').RcfError>}
|
|
182
182
|
*/
|
|
183
183
|
export async function writeBrowserVerificationRecord({ projectRoot, tree, record, options = {} }) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
nextManifest
|
|
184
|
+
// 0.28.2 (Codex review follow-up on the shared helper): compose via
|
|
185
|
+
// the shared `buildNextManifest` helper so write and dry-run
|
|
186
|
+
// produce the same shape and the same schema pass runs on both.
|
|
187
|
+
const nextManifest = buildNextManifest({
|
|
188
|
+
manifest: tree.manifest ?? {},
|
|
189
|
+
record,
|
|
190
|
+
verb: 'browserVerify',
|
|
191
|
+
});
|
|
188
192
|
|
|
189
193
|
const relPath = 'rcf/manifest.json';
|
|
190
194
|
const validation = validateDocument({ doc: nextManifest, kind: 'manifest', filePath: relPath });
|
|
@@ -20,7 +20,7 @@ import { parseArgs } from 'node:util';
|
|
|
20
20
|
import process from 'node:process';
|
|
21
21
|
import { isAbsolute, resolve } from 'node:path';
|
|
22
22
|
|
|
23
|
-
import { walkTree } from '#core/store';
|
|
23
|
+
import { walkTree, validateComposedRecord } from '#core/store';
|
|
24
24
|
import { writeUnexpectedFailure, rcfError } from '#core/errors';
|
|
25
25
|
|
|
26
26
|
import { findProjectRoot } from '../view/index.js';
|
|
@@ -270,6 +270,14 @@ export async function main(argv, deps = {}) {
|
|
|
270
270
|
if (flags.json) stdout.write(`${JSON.stringify(record, null, 2)}\n`);
|
|
271
271
|
|
|
272
272
|
if (flags['dry-run']) {
|
|
273
|
+
// 0.28.2 (folded into #230): dry-run runs the same schema pass
|
|
274
|
+
// the writer runs so a preview reports the same validation error
|
|
275
|
+
// the write path would refuse.
|
|
276
|
+
const dryValidation = validateComposedRecord({ tree, record, verb: 'browserVerify' });
|
|
277
|
+
if (dryValidation) {
|
|
278
|
+
stderr.write(`[error] ${dryValidation.kind} ${dryValidation.message}\n`);
|
|
279
|
+
return 3;
|
|
280
|
+
}
|
|
273
281
|
if (!flags.quiet) {
|
|
274
282
|
renderSummary({ stdout, record });
|
|
275
283
|
}
|