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,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-17601",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-176",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "rcf define freeze runs readiness, refuses on failing, writes freeze.json and prints the section 2.5 summary",
|
|
8
|
+
"description": "User story under REQ-176. The freeze verb is the only close verb: no change-object is minted, nothing else changes state. It reads the live tree via computeReadiness, refuses on any failing stage (accepting acks only on the three warn-with-ack gates), and writes the freeze record slice 4's bundle --next and slice 5's viewer will read.",
|
|
9
|
+
"asA": "an operator wrapping up a change on the tree",
|
|
10
|
+
"iWant": "one command that says 'yes freezeable and I have written the record' or 'no here is the gate that blocks and its first failing ids', accepts --ack on the three warn-first gates with a mandatory reason, and prints a summary line I can paste into a commit message",
|
|
11
|
+
"soThat": "the freeze record is authoritative for slice 4's bundle --next and slice 5's viewer, and the same rules that gate readiness also gate the freeze",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-17601-1",
|
|
15
|
+
"description": "[happy] rcf define freeze runs computeReadiness once over walkTree(projectRoot) plus loadFreezeRecord and loadAllLedgers. When result.freezeable is true, it writes rcf/define/freeze.json via saveFreezeRecord with these fields: frozenAt (ISO UTC now), treeHash (result.tree.currentTreeHash), docHashes (delta.js currentHashes over the live tree plus 'ledger:<name>' for each ledger present), briefStatements (the count of statements in the brief ledger, ledgers.brief.statements.length or 0), gates (one entry per stage-gate with { state, at: { hash, at, reason?, by? } | null, failing: [{ id, why }] } from the live readiness plus any --ack entries), counts { req, us, ac, acByClass: { happy, edge, failure, mustNot, nonFunctional, unclassified }, tac, interfaces: { <kind>: n, ... }, adr, fbs }, litmus { attestedAt, readers: 0 }, versions { rcfLite, ruleset, schemas } read from package.json, src/ruleset/ruleset.json and node_modules/@stravica-ai/rcf-schemas/package.json, note (--note argument or null), override (always null on a fresh freeze). The verb exits 0. Immediately after the write, calling computeDelta over the live tree + the new freeze reports every list empty (changed / added / removed / briefSince).",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-17601-2",
|
|
20
|
+
"description": "[failure] When result.freezeable is false and no --ack argument covers the failing stage, the verb exits 4 without writing the freeze record. It prints the failing gates (one per line: '<stage> (<gate>): failing (<first check name>); failing ids: <id1>, <id2>, ...' capped at 20 ids per gate) to stderr, followed by the exact rcf define readiness --check <shortName> command that will re-print the same block for each failing stage. The file at rcf/define/freeze.json is not created or modified (a pre-existing file is byte-identical after the refusal).",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-17601-3",
|
|
25
|
+
"description": "[failure] --ack <gate> --reason <text> is accepted only for the three warn-with-ack gates: define.shapes / D3 / shapes, define.crosscut / D5 / crosscut, define.consistency / D6 / consistency (the same STAGE_ALIASES readiness accepts). --ack on any other gate name is a usage refusal (exit 2) with a stderr message naming the accepted set. --ack without a matching --reason argument is a usage refusal (exit 2). Multiple --ack / --reason pairs may be passed together (parseArgs multiple: true) as long as the count matches; a mismatch is a usage refusal. An acked gate lands in the written freeze.gates entry as { state: 'acknowledged', at: { hash: <currentTreeHash>, at: <frozenAt>, reason: <text>, by: <freezerId or null> }, failing: [<id>, ...] } and its acknowledgement carries into the next computeReadiness run (which reports the stage state as 'acknowledged').",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-17601-4",
|
|
30
|
+
"description": "[happy] The stdout summary derived from the delta BEFORE the freeze matches proposal section 2.5: 'frozen at <shortHash>: <n> REQ, <n> stories, <n> criteria, <n> interfaces added; <ids> amended; <impactedFbs> re-execute.' Counts of added come from delta.added grouped by tree.kindById; amended is delta.changed (US ids in the amended list per the proposal's example wording); impactedFbs is delta.impactedFbs. On the first freeze (freeze record absent before the run), the summary is 'first freeze at <shortHash>: <req> REQ, <us> stories, <ac> criteria, <interfaces> interfaces, <tac> TAC, <adr> ADR, <fbs> FBS.' --json emits { record, summary, delta } where record is the just-written freeze record body and delta is the pre-freeze DeltaResult.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-17601-5",
|
|
35
|
+
"description": "[happy] --status prints the current record and the live delta summary, exit 0. Text: 'Frozen at <short> on <frozenAt>. Note: <note|(none)>. Counts: <req> REQ / <us> US / <ac> AC / <tac> TAC / <adr> ADR / <fbs> FBS. Acknowledged: <gate1> (\"<reason>\"); <gate2> ...(none). Litmus: attestedAt [<D3>, <D6>], readers <n>. Versions: rcfLite <v> / ruleset <v> / schemas <v>. Override: <null|<reason by at>>.' followed by the live delta summary line: '<changed> changed, <added> added, <removed> removed, <impacted> impacted, <impactedFbs> FBS re-execute.' --status --json emits { record: <freeze body>, delta: <computeDelta output> }. --status when no record exists prints 'never frozen' and exits 0 (--json: { record: null, delta: <computeDelta output over unfrozen tree> }). --status never runs the gates and never writes anything.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-17601-6",
|
|
40
|
+
"description": "[happy] The freeze producer is wrapped with runWithAdmissibilityGate the same way readiness is (ADR-4124 carrying ADR-4123): the wrap runs first so the ruleset toolScope guard is honoured, and on a refused-admissibility verdict the CLI prints the refusal envelope to stderr as a [warn] line and the freeze compute still runs and writes if freezeable. The verb never exits 4 solely because of a refused-admissibility verdict.",
|
|
41
|
+
"testable": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "AC-17601-7",
|
|
45
|
+
"description": "[must-not] src/define/freeze-record.js is updated so validateFreezeRecord REQUIRES the override key (nullable): a body without override throws FreezeRecordError with field 'override'. loadFreezeRecord tolerates older records that lack the key by defaulting to null (never fails on ENOKEY). saveFreezeRecord validates first and refuses to write a body that omits override. Every existing test fixture that omits override still loads (either the loader default fills it in, or a targeted fixture update writes override: null; no legacy fixture becomes unreadable).",
|
|
46
|
+
"testable": true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "AC-17601-8",
|
|
50
|
+
"description": "[non-functional] The src/cli/readiness.js stage header line no longer contains a double-dash: it uses a colon between the stage id and the state label ('D1 (define.brief): failing'). The CHANGELOG.md line 'The regex is now `/\\bTODO:/` -- case-sensitive uppercase `TODO`' is likewise rewritten to a colon. Any golden fixture that captured the old header text is updated. `grep -R ' -- ' src/ test/ CHANGELOG.md` returns no matches under text this slice added or edited (the grep is scoped to added lines; unrelated pre-existing occurrences elsewhere in the tree stay out of scope of the AC).",
|
|
51
|
+
"testable": true
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"tacIds": ["TAC-4124-define-freeze"],
|
|
55
|
+
"tags": [],
|
|
56
|
+
"createdAt": "2026-09-24T16:33:15Z",
|
|
57
|
+
"updatedAt": "2026-09-24T16:33:15Z"
|
|
58
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-180",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Readiness as the first tab in the viewer",
|
|
8
|
+
"description": "User story under REQ-180. Opening the viewer puts Readiness first (default active tab), the former Overview tab is renamed PRD with its content preserved, the two level verdict pills carry the formatVerdictLines strings as labels, blockers group by persona ordered by the profile.md register (the non-register group collapses with its count visible, never omitted), and the Freeze now control is enabled iff levels.readyToBuild.ok. See the DEFINE step 2 spec dated 2026-10-01 (section 5) for the layout.",
|
|
9
|
+
"asA": "an operator opening the viewer",
|
|
10
|
+
"iWant": "Readiness as the first tab with the two verdict pills and persona-grouped blockers",
|
|
11
|
+
"soThat": "the first thing I see is whether I can build and whose questions stand in the way",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18001-1",
|
|
15
|
+
"description": "[happy] Given any project, when the viewer renders, then the first tab is Readiness and the second is PRD with the former Overview content unchanged.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18001-2",
|
|
20
|
+
"description": "[happy] Given a failing tree, when the Readiness tab renders, then it shows two verdict pills whose labels equal the formatVerdictLines strings for the same tree.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18001-3",
|
|
25
|
+
"description": "[happy] Given personas.productOwner.blockers non-empty, when the tab renders, then each blocker is a findings list headed by its question with its ids as anchor links into the document tabs.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18001-4",
|
|
30
|
+
"description": "[happy] Given a profile register of productOwner, when the tab renders, then the product-owner group is expanded first and the engineer group is collapsed with its count visible.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18001-5",
|
|
35
|
+
"description": "[must-not] Given any profile register, when the tab renders, then no blocker id of either persona is omitted from the DOM.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-18001-6",
|
|
40
|
+
"description": "[failure] Given a tree where levels.readyToBuild.ok is false, when the tab renders, then the Freeze now control is disabled and names the failing gates from levels.readyToBuild.blockedBy.",
|
|
41
|
+
"testable": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "AC-18001-7",
|
|
45
|
+
"description": "[happy] Given the tab and the CLI --json output for the same tree hash, when compared, then every id rendered on the tab appears in the JSON for that hash.",
|
|
46
|
+
"testable": true
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"tacIds": [
|
|
50
|
+
"TAC-4127-readiness-view"
|
|
51
|
+
],
|
|
52
|
+
"tags": [],
|
|
53
|
+
"createdAt": "2026-10-01T18:00:00Z",
|
|
54
|
+
"updatedAt": "2026-10-01T18:00:00Z"
|
|
55
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-180",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the Readiness tab renders question cards grouped by source span",
|
|
8
|
+
"description": "User story under REQ-180, reserved by DEFINE step 3 spec section 11.8 and authored here by the viewer UI refresh PR 8. The Readiness tab leads with the product owner's three questions in plain words: two VerdictCards from `levels` (Ready for engineers, Ready to build, each with its chain term `intent-complete` or `ready-to-build` muted beside the plain label; both cards rendered at equal height), QuestionCards grouped by source span (one group per blocker; one card per failing item, phrasebook-sourced today, swapping to `readiness.questions[]` when DEFINE step 3 PR 2 ships `computeQuestions`), a what-happens-next paragraph, and a Requirements that still need work table. Every engineer-level finding stays on the page one level down in one collapsed `For engineers` DocRow (closed in the productOwner register, open in engineer; never removed from the DOM). The adapter seam `toQuestions(readiness)` is a pure module reading blockers today and feature-detecting `readiness.questions` tomorrow.",
|
|
9
|
+
"asA": "a product owner opening the Readiness tab",
|
|
10
|
+
"iWant": "the questions waiting on me in plain words, grouped by their source span, without ids or stage codes",
|
|
11
|
+
"soThat": "I can answer them in my own session and see the hand-over state update as I go",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18002-1",
|
|
15
|
+
"description": "[happy] given questions[] non-empty, when the tab renders, then the block lists each group with its asks and every id is in the JSON.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18002-2",
|
|
20
|
+
"description": "[failure] given questions[] empty, when the tab renders, then the block shows the intent-complete verdict line.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18002-3",
|
|
25
|
+
"description": "[must-not] given any register, when the tab renders, then the engineer blockers are not removed from the DOM.",
|
|
26
|
+
"testable": true
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"tacIds": [
|
|
30
|
+
"TAC-4133-readiness-po-layer"
|
|
31
|
+
],
|
|
32
|
+
"tags": [],
|
|
33
|
+
"createdAt": "2026-10-02T19:30:00Z",
|
|
34
|
+
"updatedAt": "2026-10-02T19:30:00Z"
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18101",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-181",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Shared pill, findings-list and diff components",
|
|
8
|
+
"description": "User story under REQ-181. Three view modules land under src/view/components/: pill, findings-list, diff. Readiness is their first consumer; existing Product Map and Requirements rendering keeps its markup where the swap is not mechanical, and no existing test expectation changes in that case. See the DEFINE step 2 spec dated 2026-10-01 (section 5) for the component contract.",
|
|
9
|
+
"asA": "a maintainer of the viewer",
|
|
10
|
+
"iWant": "one pill, one findings list and one diff component",
|
|
11
|
+
"soThat": "gate state, persona, level verdict and AC class read the same on every tab",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18101-1",
|
|
15
|
+
"description": "[happy] Given the pill component, when rendered with a gate state, a level verdict, a persona or an AC class, then it emits the same markup shape with a vocabulary class per value.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18101-2",
|
|
20
|
+
"description": "[happy] Given the findings-list component, when called with the same inputs from the Readiness and Product Map callers, then the two call sites produce byte-identical markup.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18101-3",
|
|
25
|
+
"description": "[must-not] Given the shared components, when introduced, then no existing Product Map or Requirements test changes its expected output except where this PR explicitly re-points that tab.",
|
|
26
|
+
"testable": true
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"tacIds": [
|
|
30
|
+
"TAC-4127-readiness-view"
|
|
31
|
+
],
|
|
32
|
+
"tags": [],
|
|
33
|
+
"createdAt": "2026-10-01T18:00:00Z",
|
|
34
|
+
"updatedAt": "2026-10-01T18:00:00Z"
|
|
35
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18202",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-182",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the DEFINE-stage guidance pack",
|
|
8
|
+
"description": "User story under REQ-182. The guidance pack prints its slugs through `rcf guidance`, the MCP server advertises every argument-free DEFINE prompt, the register scan protects every new file from em-dashes, and the managed block regeneration never removes an existing rule.",
|
|
9
|
+
"asA": "harness",
|
|
10
|
+
"iWant": "the DEFINE-stage guidance pack served through one surface",
|
|
11
|
+
"soThat": "the loop reads one slug per topic and the register scans and managed-block rules apply everywhere",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18202-1",
|
|
15
|
+
"description": "[happy] given the pack, when rcf guidance define-intent and rcf guidance discovery-prototypes run, then each prints its file.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18202-2",
|
|
20
|
+
"description": "[happy] given the manifest, when the MCP server lists prompts, then rcf_define_intent, rcf_define_intake, rcf_define_draft_shapes, rcf_define_litmus and rcf_discover_prototype are present and argument-free.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18202-3",
|
|
25
|
+
"description": "[failure] given a new guidance file containing an em-dash, when the register scan runs, then it fails.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18202-4",
|
|
30
|
+
"description": "[must-not] given the managed block, when regenerated, then no existing rule is removed.",
|
|
31
|
+
"testable": true
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"tacIds": [
|
|
35
|
+
"TAC-4128-define-guidance"
|
|
36
|
+
],
|
|
37
|
+
"tags": [],
|
|
38
|
+
"createdAt": "2026-10-03T00:00:00Z",
|
|
39
|
+
"updatedAt": "2026-10-03T00:00:00Z"
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18601",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-186",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the question set",
|
|
8
|
+
"description": "User story under REQ-186. computeQuestions turns every failing product-owner item into one plain question with its write-back, so the harness can ask without reading gate internals.",
|
|
9
|
+
"asA": "harness serving a product owner",
|
|
10
|
+
"iWant": "computeQuestions to turn every failing product-owner item into one plain question with its write-back",
|
|
11
|
+
"soThat": "I can ask without reading gate internals",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18601-1",
|
|
15
|
+
"description": "[happy] given a tree where brief:openQuestions, skeleton:resolvedBy and stories:reqHasUs each fail at least one item, when computeQuestions runs with persona productOwner, then questions[] holds exactly one entry per failing item with id, stage, check, itemId, heading, ask, answerKinds, writeBack and blocks intent.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18601-2",
|
|
20
|
+
"description": "[happy] given the same tree, when computeQuestions runs twice, then the two questions[] arrays are deep-equal and ordered D1, D2, D4, D7 then by source span.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18601-3",
|
|
25
|
+
"description": "[happy] given an open decision with two options and a default, when computeQuestions runs, then it appears in optional[] with blocks build and not in questions[].",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18601-4",
|
|
30
|
+
"description": "[happy] given a tree where levels.intentComplete.ok is true, when computeQuestions runs with persona productOwner, then questions[] is empty and ok is true.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18601-5",
|
|
35
|
+
"description": "[happy] given persona engineer, when computeQuestions runs, then questions[] holds one entry per failing engineer item in failing stages and blocks is build.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-18601-6",
|
|
40
|
+
"description": "[failure] given a persona value outside productOwner and engineer, when computeQuestions runs, then it throws a usage error naming the accepted values.",
|
|
41
|
+
"testable": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "AC-18601-7",
|
|
45
|
+
"description": "[must-not] given any tree, when computeQuestions runs, then no file under rcf/ is created or modified and no question carries a writeBack command whose verb is not registered in the CLI help.",
|
|
46
|
+
"testable": true
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"tacIds": [
|
|
50
|
+
"TAC-4129-define-questions"
|
|
51
|
+
],
|
|
52
|
+
"tags": [],
|
|
53
|
+
"createdAt": "2026-10-02T18:00:00Z",
|
|
54
|
+
"updatedAt": "2026-10-02T18:00:00Z"
|
|
55
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18602",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-186",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the verb and the tools",
|
|
8
|
+
"description": "User story under REQ-186. `rcf define questions` and `rcf_define_questions` return the same object, so the CLI loop and the MCP loop cannot disagree.",
|
|
9
|
+
"asA": "operator or harness",
|
|
10
|
+
"iWant": "the verb and the MCP tool to return the same object",
|
|
11
|
+
"soThat": "the two loops cannot disagree",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18602-1",
|
|
15
|
+
"description": "[happy] given a failing tree, when rcf define questions --json runs, then stdout is the computeQuestions object and the exit code is 0.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18602-2",
|
|
20
|
+
"description": "[happy] given no --persona, when the verb runs on a profile whose register is engineer, then persona is engineer; with no profile it is productOwner.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18602-3",
|
|
25
|
+
"description": "[happy] given --stage skeleton and --limit 2, when the verb runs, then questions[] holds at most two D2 entries and remaining counts every D2 item.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18602-4",
|
|
30
|
+
"description": "[happy] given the MCP tool rcf_define_questions with the same arguments, when it is called, then structuredContent deep-equals the verb's --json output.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18602-5",
|
|
35
|
+
"description": "[failure] given --persona architect, when the verb runs, then it exits 2 with the usage line naming productOwner and engineer.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-18602-6",
|
|
40
|
+
"description": "[must-not] given any invocation of rcf define questions, when it completes, then no file under rcf/ has been created or modified.",
|
|
41
|
+
"testable": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"tacIds": [
|
|
45
|
+
"TAC-4129-define-questions"
|
|
46
|
+
],
|
|
47
|
+
"tags": [],
|
|
48
|
+
"createdAt": "2026-10-02T18:00:00Z",
|
|
49
|
+
"updatedAt": "2026-10-02T18:00:00Z"
|
|
50
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18603",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-186",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "write-back and termination",
|
|
8
|
+
"description": "User story under REQ-186. Every answer lands through a verb and the loop ends at the computed verdict, so nothing about intent lives only in a chat.",
|
|
9
|
+
"asA": "product owner",
|
|
10
|
+
"iWant": "every answer to land through a verb and the loop to end at the computed verdict",
|
|
11
|
+
"soThat": "nothing about my intent lives only in a chat",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18603-1",
|
|
15
|
+
"description": "[happy] given the scripted loop fixture, when every writeBack the question set returns is applied and readiness recomputed each turn, then the question count strictly decreases every turn and reaches zero.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18603-2",
|
|
20
|
+
"description": "[happy] given a statement resolved to a newly created REQ carrying description and domain, when readiness recomputes, then skeleton:reqIntent passes that REQ and stories:reqHasUs asks for it once.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18603-3",
|
|
25
|
+
"description": "[happy] given a tree at L1, when [draft] entities, TAC stubs and interfaces are added, then levels.intentComplete.ok stays true and the product-owner question set stays empty.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18603-4",
|
|
30
|
+
"description": "[failure] given an openQuestion promoted to a decision with one option and no default, when readiness recomputes, then decisions:wellFormed asks once and brief:openQuestions does not.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18603-5",
|
|
35
|
+
"description": "[must-not] given any product-owner check, when readiness recomputes after an engineer-only edit, then no product-owner check changes from ok to failing.",
|
|
36
|
+
"testable": true
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"tacIds": [
|
|
40
|
+
"TAC-4129-define-questions"
|
|
41
|
+
],
|
|
42
|
+
"tags": [],
|
|
43
|
+
"createdAt": "2026-10-02T18:00:00Z",
|
|
44
|
+
"updatedAt": "2026-10-02T18:00:00Z"
|
|
45
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18701",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-187",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the statement file",
|
|
8
|
+
"description": "User story under REQ-187. The harness writes a statement file beside each source with a leading bracketed kind and a trailing (source: ...) marker; `brief add --from` parses the markers and mints the statements.",
|
|
9
|
+
"asA": "harness",
|
|
10
|
+
"iWant": "a line grammar for kind and source",
|
|
11
|
+
"soThat": "the split I propose to the owner is what gets minted",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18701-1",
|
|
15
|
+
"description": "[happy] given a line \"- [constraint] A loan on hold must not accrue late fees. (source: briefs/x.md:15)\", when brief add --from runs, then one statement is minted with kind constraint, that text and that source.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18701-2",
|
|
20
|
+
"description": "[happy] given a line with no markers under --kind actor --source doc.md, when brief add --from runs, then the statement has kind actor and source doc.md.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18701-3",
|
|
25
|
+
"description": "[happy] given a line ending with \"?\" and no kind marker, when brief add --from runs, then the statement has kind openQuestion.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18701-4",
|
|
30
|
+
"description": "[happy] given a 0.29.0 line-per-statement file, when brief add --from runs, then the minted statements equal the 0.29.0 output.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18701-5",
|
|
35
|
+
"description": "[failure] given a line \"[gadget] text\", when brief add --from runs, then it exits 2 naming the accepted kinds and writes nothing.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-18701-6",
|
|
40
|
+
"description": "[must-not] given --dry-run, when brief add --from runs, then rcf/define/brief-ledger.json is not created or modified.",
|
|
41
|
+
"testable": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"tacIds": [
|
|
45
|
+
"TAC-4130-define-intake-brief"
|
|
46
|
+
],
|
|
47
|
+
"tags": [],
|
|
48
|
+
"createdAt": "2026-10-02T16:40:00Z",
|
|
49
|
+
"updatedAt": "2026-10-02T16:40:00Z"
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18702",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-187",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "scans into open questions",
|
|
8
|
+
"description": "User story under REQ-187. The intake scans run inside `brief add --from` over the new statements against every existing statement, and every finding becomes an openQuestion statement with source `scan:<name>:<ids>`.",
|
|
9
|
+
"asA": "product owner",
|
|
10
|
+
"iWant": "contradictions and gaps the tool can see to reach me as questions",
|
|
11
|
+
"soThat": "the first readiness run tells me what is still mine",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18702-1",
|
|
15
|
+
"description": "[happy] given two new statements the contradiction scan flags, when brief add --from runs with scans on, then one openQuestion statement is appended with source scan:contradiction:<id>,<id> and brief:openQuestions fails it.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18702-2",
|
|
20
|
+
"description": "[happy] given a --findings file with two findings, when brief add --from runs, then two openQuestion statements are appended with source scan:<name>.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18702-3",
|
|
25
|
+
"description": "[happy] given a frozen tree, when brief add --from runs, then the scans compare the new statements against every existing statement.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18702-4",
|
|
30
|
+
"description": "[happy] given --json, when brief add --from runs, then stdout holds added[] and findings[].",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18702-5",
|
|
35
|
+
"description": "[failure] given --no-scan together with --findings, when brief add runs, then it exits 2.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-18702-6",
|
|
40
|
+
"description": "[must-not] given --text, when brief add runs, then no scan runs and no openQuestion statement is appended.",
|
|
41
|
+
"testable": true
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"tacIds": [
|
|
45
|
+
"TAC-4130-define-intake-brief"
|
|
46
|
+
],
|
|
47
|
+
"tags": [],
|
|
48
|
+
"createdAt": "2026-10-02T16:40:00Z",
|
|
49
|
+
"updatedAt": "2026-10-02T16:40:00Z"
|
|
50
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-18801",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-188",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "the draft homes",
|
|
8
|
+
"description": "User story under REQ-188. Every pre-populated shape across the three draft homes (`TAC.purpose`, `coreEntities[].description`, `TAC.interfaces[].description`) carries the `[draft]` marker; `shapes:draftSettled` reports all three id forms so nothing drafted reads as settled.",
|
|
9
|
+
"asA": "engineer picking up an intent-complete tree",
|
|
10
|
+
"iWant": "every pre-populated shape marked",
|
|
11
|
+
"soThat": "nothing drafted reads as settled",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-18801-1",
|
|
15
|
+
"description": "[happy] given a coreEntities entry whose description starts with [draft], when D3 runs, then shapes:draftSettled fails TAD.entity:<name>.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-18801-2",
|
|
20
|
+
"description": "[happy] given a TAC whose purpose starts with [draft], when D3 runs, then shapes:draftSettled fails <tacId> and shapes:tacHasInterface treats the TAC as present.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-18801-3",
|
|
25
|
+
"description": "[happy] given the three marker homes cleared, when D3 runs, then shapes:draftSettled passes.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-18801-4",
|
|
30
|
+
"description": "[failure] given a [draft] recordShape without fields:, when D3 runs, then shapes:templateMarkers fails it exactly as a settled one.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-18801-5",
|
|
35
|
+
"description": "[must-not] given any [draft] content, when readiness runs, then no productOwner check reads it.",
|
|
36
|
+
"testable": true
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"tacIds": [
|
|
40
|
+
"TAC-4122-define-gates"
|
|
41
|
+
],
|
|
42
|
+
"tags": [],
|
|
43
|
+
"createdAt": "2026-10-03T00:00:00Z",
|
|
44
|
+
"updatedAt": "2026-10-03T00:00:00Z"
|
|
45
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-204",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-002",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "An engineer sees the FBS DAG",
|
|
8
|
+
"description": "The Build tab's DAG sub-tab lays FBS out by dependency depth from `dependsOnFbsIds` with click-to-highlight closure, a dependency inspector, status/area/Buildable-now/Critical-path/Show-unconnected filters, a hidden unconnected lane with a count, and `#tab=build&sub=dag&entity=<id>` deep links so a node is a link. The canvas scrolls inside its own box and the viewer never scrolls horizontally. See viewer UI refresh design doc section 7.",
|
|
9
|
+
"asA": "an engineer looking at the build sequence",
|
|
10
|
+
"iWant": "a dependency DAG of the FBS with click-to-highlight closure, an inspector and filters",
|
|
11
|
+
"soThat": "I can see what feeds what, pick the next buildable work and spot the critical path without reading JSON",
|
|
12
|
+
"acceptanceCriteria": [
|
|
13
|
+
{
|
|
14
|
+
"id": "AC-204-1",
|
|
15
|
+
"description": "[happy] Given the Build tab's DAG sub-tab, when it renders, then every connected FBS sits in a column whose index equals its longest dependency depth from `dependsOnFbsIds` (0 for no dependency) and rows inside a column are ordered by `buildOrder` ascending.",
|
|
16
|
+
"testable": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-204-2",
|
|
20
|
+
"description": "[happy] Given the DAG canvas, when a node is clicked, then it is selected, its upstream closure outlines in the link colour and its downstream closure outlines in the warning colour; a second click on the same node clears the selection.",
|
|
21
|
+
"testable": true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "AC-204-3",
|
|
25
|
+
"description": "[happy] Given a selected FBS, when the inspector renders, then it lists status, area, AC count, size, build order, a buildable-now flag, direct and transitive needs, direct and transitive waits-on and an \"Open in Specs\" link that moves to `#tab=build&sub=specs&entity=<id>`.",
|
|
26
|
+
"testable": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "AC-204-4",
|
|
30
|
+
"description": "[happy] Given a selection, when it is set or cleared, then the hash becomes `#tab=build&sub=dag&entity=<id>` (or drops the entity key when cleared) and a reload with that hash restores the selection and scrolls the node into view.",
|
|
31
|
+
"testable": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "AC-204-5",
|
|
35
|
+
"description": "[happy] Given the DAG toolbar, when the Status, Area, Buildable-now, Critical-path or Show-unconnected filter changes, then the visible nodes update and the current selection is kept.",
|
|
36
|
+
"testable": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "AC-204-6",
|
|
40
|
+
"description": "[failure] Given a `dependsOnFbsIds` cycle on disk, when the DAG renders, then the cycle is reported as a finding in the toolbar area and the remaining non-cycle FBS still render.",
|
|
41
|
+
"testable": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "AC-204-7",
|
|
45
|
+
"description": "[must-not] Given the DAG canvas, when a node is clicked, filtered or inspected, then no `postMessage` is sent to the parent window and no outbound network request is made.",
|
|
46
|
+
"testable": true
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"tacIds": [
|
|
50
|
+
"TAC-4131-build-dag-view"
|
|
51
|
+
],
|
|
52
|
+
"tags": [
|
|
53
|
+
"view",
|
|
54
|
+
"build",
|
|
55
|
+
"dag"
|
|
56
|
+
],
|
|
57
|
+
"createdAt": "2026-10-02T18:00:00Z",
|
|
58
|
+
"updatedAt": "2026-10-02T18:00:00Z"
|
|
59
|
+
}
|