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
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,323 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
## [0.29.0] - 2026-10-03
|
|
11
|
+
|
|
12
|
+
0.29.0 lands the viewer UI refresh train (nine PRs that rebuild the shell, add shared components, redesign the Requirements, Architecture, Build and Readiness tabs, ship a Build DAG sub-tab, add fast ID lookup, and prove the embedding contract with a same-origin test-host fixture), the DEFINE readiness persona split (two readiness levels, `--level` and `--persona` on `rcf define readiness`, a Readiness tab as tab 1), and the first three DEFINE step 3 PRs (document intake into the brief ledger with the closed `resolvedBy` grammar, a `rcf define questions` verb with three new MCP tools and two argument-free prompts for the harness loop, and the `[draft]` shapes gate across TAC purpose, interface and core-entity homes with a DISCOVERY prototypes doctrine). The brief said 0.29.0 was never tagged; it is tagged here, and the spec sections that referred to those D2 behaviours as "0.30.0" now read 0.29.0.
|
|
13
|
+
|
|
14
|
+
Scope note: DEFINE step 3 PR 5 (D3 bite) is still on the cloud at cut time and is NOT included; it rides a later minor. Spec amendment note: `projects/rcf-lite-wsd/specs/2026-10-01_define-step3-po-elicitation-spec.md` section 16 and every "0.30.0" reference to the D2 `skeleton:resolvedBy` tightening, the `rcf define ledger <name> update <id>` subverb and the `resolvedBy` closed grammar should read "0.29.0" at the next amendment pass.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Viewer UI refresh PR 1 of 9: shell, brand tokens, theme contract, embed contract, Router and relative asset refs (`#263` + `#265`; w-2026-10-02-dave-017).** AppShell with a compact header (icon mark, product block, sticky tabstrip, tools well) and a one-line footer carrying version, GitHub, docs links and the live-update pill. Full `--sv-*` Stravica brand token set under `:root[data-theme="light"]` and `:root[data-theme="dark"]` with a `prefers-color-scheme` fallback; pre-PR-1 `--colour-*` names kept as aliases so doc-renderer, Mermaid and Product Map rules get dark theme for free. `theme=light|dark|auto` and `embed=1` on `/`; live theme switch via same-origin `postMessage({ type: "rcf-view-theme", theme })` (origin checked). Router (`#tab=&sub=&entity=`) with bare-id compatibility and query-string preservation on every hash write. Relative asset and stream refs for embedding: `./style.css`, `./mermaid.min.js`, `./page-init.js`, `./live-client.js`, `./events`, `./scope.json`, `./product-map/<group>`. Inline-script-free shell: the former inline IIFE lives in `src/view/page-init.js` served by a new relative route (see "For embedders" below).
|
|
19
|
+
- **Viewer UI refresh PR 2 of 9: shared components layer and shell polish (#266; w-2026-10-02-dave-010).** Six shared component helpers under `src/view/components/` land for the per-tab cutover PRs: `DocRow`, `FilterBar`, `Badge`, `EmptyState`, `Toast`, `SubTabStrip`, with matching `.rcf-*` CSS. Toast container mounted once in the shell outside `#rcf-live-content` so the SSE innerHTML swap cannot blow it away. `/_fixtures/components` route renders every shared component in isolation with sample data. Shell polish per decision 17: `resolveProductHeader()` returns the project name only; no technology chip under any register.
|
|
20
|
+
- **Viewer UI refresh PR 3 of 9: Requirements tab and PRD EntitySelector (#268; w-2026-10-02-dave-025).** Requirements tab under `#tab=requirements` ships a FilterBar (text, Area, Priority, Status, Needs-work toggle), Expand/Collapse all and a live count; FilterBar state mirrors into the hash. DocRow per REQ carries `data-domain`, `data-priority`, `data-status`, `data-needswork`, `data-text`; row body has nested per-US DocRows with the full renderUserStory body, slice diagram and raw-JSON disclosure as collapsed `<details>` so first-paint stays cheap. `#entity=US-304` resolves to REQ-003 and US-304; bare `#entity=<id>` works. Needs-work set sourced from `model.readiness.levels.intentComplete.blockedBy` filtered to the engineer-plain reasons (viewer never re-runs gates). PRD tab (`#tab=overview` for hash backwards compatibility) collapses the five lists into `<details>` with count badges, drops the 109 inline requirement links, and mounts a shared EntitySelector below the article (bold total line, type-ahead jump input, 21 area chips deep-linking into `#tab=requirements&domain=<area>`). Component payload data rides on `data-*` attributes, never inline `<script>` bodies.
|
|
21
|
+
- **Viewer UI refresh PR 4 of 9: Architecture tab with TAD sections and TAC/ADR filters (#269; w-2026-10-02-dave-026).** Six TAD sections (`systemOverview`, `architecturePrinciples`, `integrationArchitecture`, `operationalConcerns`, `dataArchitecture`, `securityArchitecture`) render as shared `DocRow` with a one-line preview, closed by default. Absent sections keep their heading, read "Nothing written yet" with an `empty` badge, and name the exact authoring command `rcf define update TAD-001 --set <section>.<field>="..."`. Components (TAC) and Decisions (ADR) panels each use shared `FilterBar` plus `DocRow` list; TAC rows carry interface and dependency count badges, ADR rows carry a status pill sized against the dogfood vocabulary. Hash scheme extends: `#tab=architecture[&cq=...][&cstatus=...][&dq=...][&dstatus=...][&open=<tad-section-keys>]`. Raw TAD JSON kept as a muted collapsed disclosure at the foot of the tab.
|
|
22
|
+
- **Viewer UI refresh PR 5 of 9: Build tab with Specs and sub-tab strip (#271; w-2026-10-02-dave-027).** SubTabStrip "Specs | DAG" inside the Build tab (DAG is a placeholder empty state at PR 5; PR 6 wires it). BuildStats card with six totals read from `computeQueue({ fbsItems })` (items, verified, complete, in progress, not started, buildable now = `queue.totals.actionable`). Specs FilterBar (text, status, area, size, Buildable-now toggle) over a shared DocRow list. Expanded Spec body: summary, approach, AC and dep links, deliverables, context links (TACs, ADRs, TAD sections), "Show in the DAG" pointer, raw JSON disclosure. Hash scheme extends: `#tab=build[&sub=specs|dag][&q=][&status=][&domain=][&size=][&buildable=1]`.
|
|
23
|
+
- **Viewer UI refresh PR 6 of 9: Build/DAG sub-tab (#272; w-2026-10-02-dave-031).** Lands DagCanvas, DagInspector, DagToolbar and the unconnected lane: depth-by-`dependsOnFbsIds` columns, buildOrder rows, node-count critical path (longest chain), hidden unconnected lane with a visible count. Click-to-highlight closure (upstream outlined in link colour, downstream in warning, rest dimmed); inspector lists direct needs and waits-on with Open-in-Specs; `#tab=build&sub=dag&entity=FBS-<n>` deep-links. Inspector payload rides on a `data-rcf-dag-inspector-data` attribute, never an inline `<script>` body. Chain: REQ-002 amended, US-204 new (seven ACs), TAC-4131, ADR-4133.
|
|
24
|
+
- **Viewer UI refresh PR 7 of 9: ID lookup over `./index.json` (#275; REQ-002 / US-205; TAC-4132; ADR-4134).** The viewer serves a new relative route `./index.json` built from `BuiltTreeModel` on every rewalk, one row per document id plus one per AC, carrying `{ id, kind, title, snippet, parent, tab }` (`src/view/view-index.js` + `src/server/routes.js` + `src/server/index.js`). A SearchButton renders to the right of the tabstrip and a LookupModal mounts outside `#rcf-live-content` so the SSE innerHTML swap cannot blow it away; Cmd/Ctrl+F opens the modal from any tab (Cmd/Ctrl+Shift+F stays the browser's in-page find). Type-ahead ranks id matches first (exact > prefix > contains); then every query word must match title or snippet, title above snippet; a single character searches ids only; 20 results; matches marked. The index is fetched lazily on first open and refreshed when the next SSE `tree-update` event lands (`__rcfLookupDirty` is set in `src/view/live-client.js`). A pick writes `#tab=<tab>&entity=<id>` through the existing writeHash so `?embed=` and `?theme=` survive every navigation. Keyboard: up/down/Enter/Esc; the modal is a `role="dialog"` with `aria-modal`, labelled live-region status, and the SearchButton is `aria-label`-ed as `Find any document or AC (Cmd/Ctrl+F)`. The new relative viewer route is `./index.json` (released alongside PR 1's `./page-init.js`; wespa's reverse-proxy allow-list is extended before the version pin bump).
|
|
25
|
+
- **Viewer UI refresh PR 8 of 9: Readiness tab Product Owner redesign (#277; REQ-180 / US-18002 / TAC-4133 / ADR-4135; w-2026-10-02-dave-033).** PO layer with two equal-height VerdictCards (muted chain term on both), QuestionCards grouped by source span, Requirements-that-still-need-work table, and a "For engineers" DocRow at the foot that collapses the pre-PR-8 engineer rendering (never removed from the DOM in any register, per AC-18002-3). Readiness phrasebook ships now. Feature-detected adapter seam consumes DEFINE step 3 PR 2's `computeQuestions` output on the real path and falls back to the blockers path with phrasebook asks when it is absent. `src/view/index.js` folds `computeQuestions(readiness, { tree, ledgers, profileText, persona: 'productOwner' })` onto `readiness.{questions,questionGroups,questionOptional,questionEngineer}` before the view reads it, so the two sources render identical labels on the dogfood tree.
|
|
26
|
+
- **Viewer UI refresh PR 9 of 9: embedding proof via a same-origin test-host fixture (#279; REQ-002 / US-206; TAC-4134; ADR-4136; w-2026-10-02-dave-034).** `src/view/test-host/` (`fixture.js`, `embed-client.js`, `lints.js`) and routes `GET /test-host.html` and `GET /test-host.js` served ONLY behind `--test-host` (CLI) or `RCF_VIEW_TEST_HOST=1` (env), 404 by default so wespa's reverse-proxy allow-list is unaffected. The fixture ships a 56 px header, a resizable sidebar (64 to 400 px) and a toggle posting `rcf-view-theme`. Three in-suite guards pin the embedding contract: framing headers absent (no `X-Frame-Options`, no CSP), zero `target="_top"` across all served responses, and every `src/view` storage key under the `rcf-view:v1:` namespace.
|
|
27
|
+
- **DEFINE viewer: Readiness tab as tab 1 and Overview-to-PRD rename (#262; REQ-180 / REQ-181 / US-18001 / US-18101; TAC-4127; ADR-4127; w-2026-10-01-dave-003 PR C).** `src/view/readiness.js` lands and `src/view/html-page.js` wires it as the first tab of the HTML review surface. The former Overview tab is renamed PRD (label-only; the `data-tab="overview"` identifier and `id="tab-overview"` are preserved so every existing `#tab-overview` hash link still resolves). The tab renders the `computeReadiness` object top-to-bottom in the layout spec section 5 pins: tree line, two verdict pills with `formatVerdictLines` strings as labels, two per-persona next-action lines, D1 to D8 state chips, blockers grouped by persona (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, per-stage check detail, coverage tree-versus-delta, decisions outstanding, a Freeze now control enabled iff `levels.readyToBuild.ok`, and the loaded freeze record. The renderer is pure: it never recomputes readiness or hits disk. Three shared view components (`src/view/components/{pill,findings-list,diff}.js`) land as additive modules.
|
|
28
|
+
- **DEFINE readiness CLI: `--level` and `--persona` flags, persona-grouped text report (#261; ADR-4126; REQ-175 / US-17503; TAC-4123; w-2026-10-01-dave-003 PR B).** `rcf define readiness` gains `--level intent|build` and `--persona productOwner|engineer`. `--level intent` exits 4 iff `levels.intentComplete.ok === false`, `--level build` exits 4 iff `levels.readyToBuild.ok === false` (stricter than `--check all` on unacknowledged warn-with-ack failures; the `[warn]` line still prints). When both `--check` and `--level` are given, the invocation exits 4 if either policy says 4. With neither flag the exit code stays 0. `--persona` is a display filter only: it never affects the exit code or `--json` content, and is ignored under `--json`. Unknown values exit 2 with a usage line naming the accepted set. The text report prints both verdict lines at the top, then groups blockers into a `Product owner: N question(s)` section and an `Engineer: N check(s) blocking` section ordered by the `profile.md` register (PO first when `register: productOwner` or when the marker is `unstated`/absent; engineer first when `register: engineer`). The JSON gains `_meta.level` reflecting the invocation (`"intent"`, `"build"` or `null`).
|
|
29
|
+
- **DEFINE readiness: persona tags on every gate check, two readiness levels (#260; ADR-4126; REQ-174 / US-17402 / US-17403 and REQ-175 / US-17502; TAC-4122 and TAC-4123; w-2026-10-01-dave-003 PR A).** Every entry in `stages[].checks[]` carries `persona` (`productOwner` | `engineer`) and a one-sentence `question` heading, declared in `CHECK_PERSONA` / `CHECK_QUESTION` maps in `src/query/gates.js`. The `notApplicable` placeholder (`stage:<D>:scope`) carries the `STAGE_FALLBACK_PERSONA` for its stage so the per-check vocabulary is total. `skeleton:reqFields` splits into `skeleton:reqIntent` (productOwner: description without TODO + domain) and `skeleton:reqShape` (engineer: shapeClassification.shapes), each evaluating every REQ independently. `decisions:allAnswered` splits into `decisions:wellFormed` (productOwner) and `decisions:allAnswered` (engineer). A new D3 check `shapes:draftSettled` fails any interface whose `description` starts with `[draft]` (leading whitespace tolerated). `computeReadiness` folds `levels.intentComplete`, `levels.readyToBuild`, `personas.productOwner.blockers` and `personas.engineer.blockers` on every read. `deriveNextAction(stages, persona?)` gains an optional persona filter. New shared helper `formatVerdictLines(result)` builds the two verdict strings. All additions are strictly additive; `rcf define freeze` is untouched and remains L2-only.
|
|
30
|
+
- **DEFINE step 3 PR 1: document intake into the brief ledger, `rcf define ledger <name> update <id>` subverb, closed `resolvedBy` grammar (#270; REQ-187 / US-18701 / US-18702; REQ-173 amended / US-17302; TAC-4121 amended, TAC-4130 new).** `rcf define ledger brief add` grows `--from <statement-file>`, `--scan` / `--no-scan`, `--findings <path>`, `--dry-run` and `--json`; the parser recognises `[kind]` and `(source: ...)` text markers (with `--kind` and `--source` defaults) and promotes `?` / `TBC` / `TBD` / `Open:` / `Question:` to `openQuestion`; unknown `[kind]` exits 2 before any write. The mechanical intake scans run over new statements against existing ones and append `openQuestion` statements per finding (`--no-scan` with `--findings` exits 2). A new `rcf define ledger <name> update <id>` subverb lands on every ledger with the add-side validation; `brief --resolved-by` validates the closed pointer grammar before any write. The D2 `skeleton:resolvedBy` check now parses the pointer against the closed grammar (`REQ-nnn`, `TAD.entity:<name>`, `PRD.user:<name>`, `TAD.system:<name>`, `TAC-nnnn`, `omitted:<reason>`); see Changed for the dropped title-hit fallback. Chain: FBS-202 new (holds the new ACs with `executionStatus: notStarted`; the CN axis is deferred); `docs/capability-tags.md` grows a `define-intake` slug.
|
|
31
|
+
- **DEFINE step 3 PR 2: `rcf define questions` verb, three MCP tools and two argument-free prompts (#274; REQ-186 / US-18601 / US-18602 / US-18603; TAC-4128, TAC-4129; ADR-4129, ADR-4130).** `rcf define questions` turns every failing product-owner check into one plain question carrying its exact write-back (real three-step `create req; define update <REQ-id> --set description=... --set domain=...; ledger brief update ... --resolved-by <REQ-id>` for new REQ; real `create us --parent --title`, `define update <US-id> --json --set story='{...}'` and `create ac --parent --description "[happy] ..."` sequence for new US; `decisions add ...; ledger brief resolve <N> --answer "decision <id>"` for `brief:openQuestions`). Three new MCP tools expose the same compute: `rcf_define_questions`, `rcf_define_readiness`, `rcf_define_ledger`; two argument-free prompts (`rcf_define_intent`, `rcf_define_intake`) steer the harness through the loop. The question extractor reads the full `readiness.stages[].checks[].failing[]` so a check with 25 failing items yields 25 questions (not 20). Termination under `--stage` is `result.ok` alone (not `result.ok || result.remaining === 0`). Stable sort of questions by `(stageIndex, sourceSpan, originalIndex)`.
|
|
32
|
+
- **DEFINE step 3 PR 3: `[draft]` shapes across TAC purpose, interface and core-entity homes; DISCOVERY prototypes doctrine; two new argument-free prompts (#278; REQ-188 / US-18801; REQ-182 / US-18202; ADR-4132).** `parseInterfaceDraft` becomes a thin wrapper over a shared `hasDraftMarker` string test; two sibling readers `parseTacPurposeDraft` and `parseCoreEntityDraft` cover the new homes. `checkD3Shapes` enumerates all three draft homes and emits `shapes:draftSettled` findings with ids `<tacId>:<name>`, `<tacId>` and `TAD.entity:<name>`. D3 `notApplicable` widens to include any tree-wide `[draft]` core entity so a draft-only tree reports under D3 rather than being skipped. `guidance/discovery-prototypes.md` (slug `discovery-prototypes`, `rcf://docs/discovery-prototypes`) lands the doctrine (prototype as elicitation instrument; outputs as `prototype:<name>:<observation>` statements; code burned by a single `constraint`; salvage by re-derivation only). `guidance/discover-prototype.md` wraps it as the argument-free `rcf_discover_prototype` prompt. `guidance/define-draft-shapes.md` lands the argument-free `rcf_define_draft_shapes` prompt. `guidance/manifest.json` registers the slug and the two prompts; the managed block gains the "Prototypes in DISCOVERY (ADR-4132)" rule beside the existing "Prototype rule". `docs/capability-tags.md` grows a `define-drafts` slug.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **DEFINE D2 `skeleton:resolvedBy` tightens to the closed pointer grammar (PR #270, breaking under the pre-1.0 convention; spec amendment: this behaviour was previously named "0.30.0" in the DEFINE step 3 spec section 16 and now ships at 0.29.0).** The 0.28.4 title-hit fallback (a brief statement with `resolvedBy` left as free-form title text was quietly accepted if the title matched any downstream document) is dropped. A pointer that does not parse against the closed grammar (`REQ-nnn`, `TAD.entity:<name>`, `PRD.user:<name>`, `TAD.system:<name>`, `TAC-nnnn`, `omitted:<reason>`) now fails `skeleton:resolvedBy` on D2. Operators with brief ledgers written against 0.28.4 must rewrite non-conforming `resolvedBy` values to the closed grammar; `rcf define ledger brief update <id> --resolved-by <pointer>` validates before write.
|
|
37
|
+
- **Managed agent-instructions block regenerated: adds the "Prototypes in DISCOVERY (ADR-4132)" rule and registers the four argument-free DEFINE/DISCOVERY prompts (PRs #274 and #278).** `scripts/gen-managed-artefacts.mjs` reran on PR 2 and PR 3 of DEFINE step 3; the block hash changed. Agents update their copy of the managed block by rerunning `rcf init` (`minAgentAction: rerun-init`).
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
|
|
41
|
+
- **Viewer Build tab: the "FBS slots" ordered list and the "Test suites" section are gone (PR #271).** The Build tab's "Specs" sub-tab replaces both. Suites stay reachable via AC links and PR 7's ID lookup (Cmd/Ctrl+F). Consumers that embedded a deep link into the old Build-tab FBS-slots list need to update to `#tab=build&sub=specs&entity=FBS-<n>` or to the DAG sub-tab `#tab=build&sub=dag&entity=FBS-<n>`.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **DEFINE D2 skeleton gate reads TAD at the schema-authorised path (#259; w-2026-09-25-dave-004 defect A, REQ-174 / US-17401 / TAC-4122).** `checkD2Skeleton` in `src/query/gates.js` now reads `tad.dataArchitecture.dataStores` and `tad.dataArchitecture.coreEntities` instead of the top-level `tad.dataStores` / `tad.coreEntities` that slice-2 drifted onto. The authority is rcf-schemas 0.6.3 (`tad.schema.json` requires both arrays under `dataArchitecture`), so the previous top-level reads failed `skeleton:tadPersistence` on every valid tree carrying a persistence REQ. The `failing` entry ids tracked the move to `TAD.dataArchitecture.dataStores` and `TAD.dataArchitecture.coreEntities`.
|
|
46
|
+
- **DEFINE D1 brief gate: a fresh `rcf init` tree now satisfies the review-surface marker without operator edits (#259; w-2026-09-25-dave-004 defect B, REQ-174 / US-17401 / TAC-4122).** `src/setup/identity-seed.js` IDENTITY_TEMPLATE now carries a `## Surface` section between `## Register` and `## Project-scoped notes`, mirroring the Register section's shape: a short italicised explanation, one bullet each for `viewer` / `runningApp` / `prDiff`, and a bare `prDiff` line as the default. `checkD1Brief`'s `profile:surface` check now passes on a clean post-init tree. The slice-1 idempotency contract (an existing profile.md is left byte-identical) is preserved.
|
|
47
|
+
|
|
48
|
+
### For embedders (wespa reverse-proxy)
|
|
49
|
+
|
|
50
|
+
- **New relative routes shipped since 0.28.4.** `GET /page-init.js` (PR 1), `GET ./index.json` (PR 7). Both must be allow-listed on the wespa reverse-proxy for `/rcf-viewer/*` before the version pin bump, or the proxy returns 404 for `/rcf-viewer/page-init.js` (losing tab wiring, Mermaid lazy render, product-map interactivity, theme boot, embed stamp, origin-checked `postMessage` listener and the hash router) and `/rcf-viewer/index.json` (losing the Cmd/Ctrl+F ID lookup).
|
|
51
|
+
- **No new allow-list routes from PR 9.** `GET /test-host.html` and `GET /test-host.js` are served ONLY when `--test-host` (CLI) or `RCF_VIEW_TEST_HOST=1` (env) is set, and return 404 otherwise. Production wespa does not set the flag, so the allow-list is unchanged by PR 9.
|
|
52
|
+
- **Removed inline script in the viewer shell (PR 1).** CSP hash pin for the inline shell IIFE is no longer needed; the IIFE lives in `src/view/page-init.js` (served by `GET /page-init.js`). Wespa's CSP for `/rcf-viewer/*` should allow the external script in place of the previous inline hash pin.
|
|
53
|
+
- **Live update pill in the footer (PR 1).** Carries connection state (connecting, open, retrying, closed); styled through the `--sv-*` tokens so it tracks the theme.
|
|
54
|
+
- **`embed=1` and `theme=light|dark|auto` query params (PR 1).** `embed=1` stamps `data-embed="1"` on `<html>`, suppresses the title block and footer, and left-aligns the tabstrip; the icon mark and project name remain. `theme` on `/` either stamps `data-theme` (explicit value), clears it (`auto`), or leaves the default light (absent).
|
|
55
|
+
- **Live theme switch via `postMessage({ type: "rcf-view-theme", theme })` (PR 1).** Same-origin only; the viewer's listener checks `event.origin`.
|
|
56
|
+
- **Hash contract (PR 1, extended by PRs 3 to 9).** `#tab=<name>&sub=<name>&entity=<id>` is the canonical hash form; bare `#<id>` and `#entity=<id>` keep working. `?embed=` and `?theme=` and unknown query params survive every in-viewer navigation.
|
|
57
|
+
- **`./index.json` (PR 7).** Lazy JSON index served from the viewer root; refreshed on every SSE `tree-update`.
|
|
58
|
+
|
|
59
|
+
## [0.28.4] - 2026-09-30
|
|
60
|
+
|
|
61
|
+
Note: 0.28.3 (2026-09-22 below) was never tagged or published; its entries ship in 0.28.4 together with the ones here.
|
|
62
|
+
### Added
|
|
63
|
+
|
|
64
|
+
- **DEFINE workflow: `rcf define freeze` CLI verb (REQ-176, first slice of the 0.29.0 train; slices 1 and 2 shipped in 0.28.4 on 2026-09-30).** New module `src/cli/freeze.js` is the only
|
|
65
|
+
writer of `rcf/define/freeze.json` in the shipped product. It runs
|
|
66
|
+
`computeReadiness` once (REQ-175) over the live tree, freeze record
|
|
67
|
+
and four ledgers; refuses (exit 4) on any stage state `failing`
|
|
68
|
+
after applying any `--ack` acknowledgements; and, on success, writes
|
|
69
|
+
the freeze record via `saveFreezeRecord` (REQ-172) plus the
|
|
70
|
+
proposal 2026-09-22 v3 §2.5 summary line the operator signs off.
|
|
71
|
+
`--ack <gate> --reason <text>` is accepted only for the three
|
|
72
|
+
warn-with-ack gates (`define.shapes` / D3 / shapes,
|
|
73
|
+
`define.crosscut` / D5 / crosscut, `define.consistency` / D6 /
|
|
74
|
+
consistency); `--ack` on any other gate is a usage refusal
|
|
75
|
+
(exit 2) with a stderr message naming the accepted set. Ack pairs
|
|
76
|
+
are folded in-memory at the current tree hash and the readiness
|
|
77
|
+
compute runs with a synthesised freeze context so D8's
|
|
78
|
+
`priorGates` check sees the acked stages as `acknowledged`. On
|
|
79
|
+
success the record carries `frozenAt` (ISO UTC now), `treeHash`
|
|
80
|
+
(from `computeDelta`), `docHashes`, `briefStatements`,
|
|
81
|
+
`gates` (per-stage envelope including acked entries),
|
|
82
|
+
`counts` (`req` / `us` / `ac` / `acByClass` / `tac` /
|
|
83
|
+
`interfaces` by kind / `adr` / `fbs`), `litmus`
|
|
84
|
+
(`{ attestedAt: [], readers: 0 }` default; `--litmus-attested
|
|
85
|
+
D3,D6` records the agent's attestation per proposal §9 decision
|
|
86
|
+
7), `versions` (`rcfLite` / `ruleset` / `schemas` read from
|
|
87
|
+
package.json, `src/ruleset/ruleset.json` and the installed
|
|
88
|
+
`@stravica-ai/rcf-schemas`), `note` and `override: null`. The
|
|
89
|
+
producer is wrapped with `runWithAdmissibilityGate` per ADR-4124;
|
|
90
|
+
refused admissibility is informational (a stderr `[warn]` line)
|
|
91
|
+
and never a freeze refusal (ADR-4123 carried). `--status` prints
|
|
92
|
+
the current record and the live delta summary without running any
|
|
93
|
+
gates and without writing; `--status --json` emits
|
|
94
|
+
`{ record, delta }`. `--json` on a freeze success emits
|
|
95
|
+
`{ record, summary, delta }`. The `--litmus <n>` real-dispatch
|
|
96
|
+
runner is a named 0.30 seam.
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- **Freeze record `override` is now a required-nullable field
|
|
101
|
+
(slice 3, resolves the slice-1 P3).** `validateFreezeRecord` in
|
|
102
|
+
`src/define/freeze-record.js` throws `FreezeRecordError` with
|
|
103
|
+
`field: 'override'` when the key is missing; `saveFreezeRecord`
|
|
104
|
+
refuses to write a body that omits override. `loadFreezeRecord`
|
|
105
|
+
defaults a missing key to `null` on read so pre-slice-3
|
|
106
|
+
freeze.json records survive without a migration step. Every
|
|
107
|
+
fresh freeze written by the new CLI stamps `override: null`, so
|
|
108
|
+
the on-disk shape converges on the current schema the next time
|
|
109
|
+
a project freezes.
|
|
110
|
+
|
|
111
|
+
### Fixed
|
|
112
|
+
|
|
113
|
+
- **DEFINE hygiene: the ` -- ` double-dash is gone from the
|
|
114
|
+
readiness CLI stage header and the CHANGELOG's TODO-regex line
|
|
115
|
+
(slice 3).** The readiness `rcf define readiness` stage block
|
|
116
|
+
now uses `: ` between the stage id / gate and the state label
|
|
117
|
+
(`D1 (define.brief): failing`); the CHANGELOG's `The regex is
|
|
118
|
+
now /\bTODO:/` line likewise uses a colon.
|
|
119
|
+
|
|
120
|
+
- **Product Map tab on the review surface (#238).** Merged on `main` at
|
|
121
|
+
`ab35dd7d`; grouped by shape, component, trace coverage, capability,
|
|
122
|
+
blueprint. This entry backfills the changelog now that the following
|
|
123
|
+
DEFINE-train slice rides on top of it.
|
|
124
|
+
- **DEFINE workflow: delta detection foundation (REQ-172, slice 1 of
|
|
125
|
+
the 0.29.0 train).** New pure module `src/query/delta.js` exports
|
|
126
|
+
`hashDocument`, `computeTreeHash` and `computeDelta`. `hashDocument`
|
|
127
|
+
is SHA-256 over the canonical JSON of the parsed document (keys
|
|
128
|
+
sorted recursively, no whitespace), so a hand reformat is not a
|
|
129
|
+
change; the tree hash is over the sorted `(id, docHash)` pairs.
|
|
130
|
+
`computeDelta(tree, freeze, ledgers)` returns the exact
|
|
131
|
+
`frozen / frozenAt / treeHash / currentTreeHash / changed / added /
|
|
132
|
+
removed / briefSince / unchanged` shape proposal 2026-09-22 v3
|
|
133
|
+
section 2.2 pins. Before the first freeze the delta is the whole
|
|
134
|
+
tree (`frozen: false`, everything in `added`). Reused unchanged:
|
|
135
|
+
`computeImpact`, `computeTrace`, `computeCoverage`.
|
|
136
|
+
- **DEFINE workflow: freeze record I/O (REQ-172, slice 1).** New
|
|
137
|
+
module `src/define/freeze-record.js` owns `rcf/define/freeze.json`
|
|
138
|
+
with a small local schema (until schemas 0.7 promotes it to
|
|
139
|
+
`manifest.freeze` per ADR-4121). `loadFreezeRecord` returns `null`
|
|
140
|
+
on a missing file; a malformed body raises `FreezeRecordError` with
|
|
141
|
+
a coded reason (`parseFailure | schemaFailure | ioFailure`) and a
|
|
142
|
+
named field. `saveFreezeRecord` validates first, so a bad
|
|
143
|
+
in-memory record never lands on disk; extension fields survive a
|
|
144
|
+
save / load round trip. The `rcf define freeze` verb is a
|
|
145
|
+
later-slice consumer; this slice ships the writer so the verb can
|
|
146
|
+
be built without a second refactor.
|
|
147
|
+
- **DEFINE workflow: four sidecar ledgers and `rcf define ledger`
|
|
148
|
+
(REQ-173, slice 1).** Four ledgers live under `rcf/define/`, one
|
|
149
|
+
JSON file each, each with one numbered sequence per project:
|
|
150
|
+
`brief-ledger.json` (D1 statements, kinded from the closed set
|
|
151
|
+
`capability | constraint | actor | entity | externalSystem |
|
|
152
|
+
surface | outOfScope | openQuestion | amendment`),
|
|
153
|
+
`decisions-ledger.json` (D7, printed in the numbered #241 format),
|
|
154
|
+
`concern-ledger.json` (D5, `applied | waived`),
|
|
155
|
+
`probe-ledger.json` (D6, `low | medium | high`).
|
|
156
|
+
`rcf define ledger <name> <verb>` covers `add`, `resolve` and
|
|
157
|
+
`list`; `brief add --from <file>` splits statements one per
|
|
158
|
+
non-empty line and mints sequential ids (the
|
|
159
|
+
intake-scan-against-frozen-statements hook is a named seam this
|
|
160
|
+
slice leaves for slice 2). `decisions list` prints the #241
|
|
161
|
+
numbered format. `list --json` emits `{ ledger, <arrayKey>: [...] }`.
|
|
162
|
+
A dedicated test proves the walker never surfaces any `rcf/define/`
|
|
163
|
+
path in `walkTree` errors or `tree.byId`.
|
|
164
|
+
- **DEFINE workflow: stage gates D1..D8 (REQ-174, slice 2 of the
|
|
165
|
+
0.29.0 train).** New pure module `src/query/gates.js` exports one
|
|
166
|
+
check function per stage (`checkD1Brief`..`checkD8Freeze`) plus
|
|
167
|
+
the `STAGE_ORDER`, `STAGE_GATES`, `STAGE_SHORT_NAMES` and
|
|
168
|
+
`INTERFACE_KINDS` constants. Every function returns the exact
|
|
169
|
+
`{ stage, gate, state, checks[] }` shape proposal 2026-09-22 v3
|
|
170
|
+
section 2.4 specifies, with `checks[i]` in the `{ name, ok, over,
|
|
171
|
+
pass, total, failing }` form. Blocking in 0.29.0: D1 (define.brief),
|
|
172
|
+
D2 (define.skeleton), D4 floors (define.stories), D7
|
|
173
|
+
(define.decisions), D8 (define.freeze). Warn-with-ack in 0.29.0:
|
|
174
|
+
D3 (define.shapes), D5 (define.crosscut), D6 (define.consistency)
|
|
175
|
+
\- the state folds to `acknowledged` when the freeze record's
|
|
176
|
+
`gates[<gate>]` entry names `acknowledged` at the current tree
|
|
177
|
+
hash (ADR-4122). D4 per-class opt-outs reuse the existing
|
|
178
|
+
`manifest.baselineAcOptOuts[]` array with a baselineKey of
|
|
179
|
+
`'defineD4:failure'` or `'defineD4:mustNot'`; no new sidecar is
|
|
180
|
+
introduced. The template parser, entity join, D5 catalogue, D6
|
|
181
|
+
contradiction / unsatisfiable scans and probe runner remain as
|
|
182
|
+
named seams for 0.30.
|
|
183
|
+
- **DEFINE workflow: readiness compute and `rcf define readiness`
|
|
184
|
+
CLI (REQ-175, slice 2).** New pure module `src/query/readiness.js`
|
|
185
|
+
exports `computeReadiness(tree, { freeze, ledgers, profile,
|
|
186
|
+
testPointers })` returning the section 2.4 object exactly:
|
|
187
|
+
`{ tree, delta, stages, nextAction, coverage, decisions,
|
|
188
|
+
freezeable }`. The composer runs `computeDelta` once, calls
|
|
189
|
+
`computeImpact` per id in the union of changed and added (skipping
|
|
190
|
+
the fan-out on the unfrozen whole-tree case where the delta IS the
|
|
191
|
+
tree), runs the eight gate check functions over
|
|
192
|
+
`scope = changed union added union impacted`, calls
|
|
193
|
+
`computeCoverage` tree-wide plus once per REQ ancestor of the
|
|
194
|
+
delta, lists open decisions, and folds to `freezeable` and
|
|
195
|
+
`nextAction`. New verb `rcf define readiness [--json] [--check
|
|
196
|
+
<stage>|all]` (stage accepts D1..D8 or the short names
|
|
197
|
+
`brief | skeleton | shapes | stories | crosscut | consistency |
|
|
198
|
+
decisions | freeze`); text output = tree line, next action, chip
|
|
199
|
+
line, delta list, failing items; `--check` exits 4 on a
|
|
200
|
+
blocking-stage failure, exits 0 with a visible `[warn]` line on an
|
|
201
|
+
unacknowledged warn-with-ack failure. The producer is wrapped with
|
|
202
|
+
`runWithAdmissibilityGate` per the NV-BL-SR-03 addendum; on
|
|
203
|
+
admissibility refusal the CLI prints a `[warn]` note and still
|
|
204
|
+
runs the compute, because readiness is a diagnostic and refusing
|
|
205
|
+
to render is the opposite of what it exists to say (ADR-4123).
|
|
206
|
+
Slice 3's `rcf define freeze` will read `freezeable` and refuse
|
|
207
|
+
on any failing stage.
|
|
208
|
+
|
|
209
|
+
### Fixed
|
|
210
|
+
|
|
211
|
+
- **US auto-mint extends flat legacy sequences instead of jumping to
|
|
212
|
+
the encoded slot (#256).** `nextIdForKind(tree, 'userStory', ...)`
|
|
213
|
+
in `src/core/store/writer.js` assumed every US id encodes
|
|
214
|
+
`US-<reqNum><localTwoDigit>`. On a legacy tree whose USes carry
|
|
215
|
+
flat sequential ids (`US-1`, ..., `US-163`, migrated in from a
|
|
216
|
+
WESPA v1 project) that decode failed and the allocator fell back
|
|
217
|
+
to `US-<reqNumLabel>01`, minting shapes like `US-5301` under
|
|
218
|
+
`REQ-053` next to the existing `US-163`. Classification now runs
|
|
219
|
+
before allocation: every US id is labelled ENCODED (id decomposes
|
|
220
|
+
as `<declaredReqNum><local in 01..99>`) or FLAT. An all-flat tree
|
|
221
|
+
extends past the tree-wide high-water mark (`US-164`), an
|
|
222
|
+
all-encoded tree preserves the historical rule, and a mixed tree
|
|
223
|
+
refuses with a message that names both example ids and asks the
|
|
224
|
+
operator to normalise one shape before retrying. AC auto-mint is
|
|
225
|
+
unchanged.
|
|
226
|
+
- **Slice-1 P3: `loadAllLedgers` omits absent ledger files
|
|
227
|
+
(AC-17501-6).** The `LedgerBundle` typedef on `computeDelta` said
|
|
228
|
+
"if a project has not authored any decisions, the caller passes
|
|
229
|
+
no `decisions` key and the delta records no `ledger:decisions`
|
|
230
|
+
docHash"; the previous implementation always returned the four
|
|
231
|
+
empty bodies. `loadAllLedgers` now `stat`s each ledger file first
|
|
232
|
+
and omits the key on ENOENT, so a project with no ledgers gets
|
|
233
|
+
zero `ledger:<name>` docHashes in the delta and a project with
|
|
234
|
+
only a brief ledger gets exactly one. `loadLedger` still returns
|
|
235
|
+
an empty ledger on ENOENT so single-ledger callers keep the
|
|
236
|
+
ergonomic default.
|
|
237
|
+
- **Slice-2 P3: D2 / D4 scaffold-TODO matcher narrowed to the literal
|
|
238
|
+
`TODO:` placeholder.** `src/query/gates.js`'s `TODO_RE` used to be
|
|
239
|
+
the whole-word `/\btodo\b/i`, which false-positived on prose
|
|
240
|
+
mentioning the word ("no AC description contains the scaffold TODO
|
|
241
|
+
placeholder" on US-17401 / AC-17401-4 tripped D4 against itself).
|
|
242
|
+
The regex is now `/\bTODO:/`: case-sensitive uppercase `TODO`
|
|
243
|
+
followed by a colon, matching every scaffold string
|
|
244
|
+
`src/core/store/init.js` and `src/core/store/writer.js` write for a
|
|
245
|
+
fresh `rcf init` / `rcf define create`. `src/cli/validate.js` keeps
|
|
246
|
+
its broader `\btodo\b/i` matcher for the informational tree-wide
|
|
247
|
+
notice, so incidental prose still surfaces there without failing
|
|
248
|
+
the D2 / D4 gates.
|
|
249
|
+
|
|
250
|
+
## [0.28.3] - 2026-09-22
|
|
251
|
+
|
|
252
|
+
Batched fix release for the residuals Dex's 0.28.2 round-trip surfaced
|
|
253
|
+
and one HQ-side viewer bug caught the same day. Ships one chain
|
|
254
|
+
amendment (three design amendments on the same redactor AC) and four
|
|
255
|
+
build diffs behind it, plus one viewer-side snapshot fix.
|
|
256
|
+
|
|
257
|
+
### Fixed
|
|
258
|
+
|
|
259
|
+
- **Feedback redactor no longer folds the git protocol sentinel
|
|
260
|
+
`git@<host>` inside git+ssh, ssh or git URLs as an email (#243).**
|
|
261
|
+
A `--evidence` pointer copied verbatim from a git remote or a clone
|
|
262
|
+
URL survives verbatim, so the operator can re-run the exact command
|
|
263
|
+
they hit. The bare-remote shape `git@<host>:<owner>/<repo>` is
|
|
264
|
+
covered by the same guard. Real emails in surrounding prose still
|
|
265
|
+
fold to `<email>`. The URL rule 4 also now handles git+ssh, ssh and
|
|
266
|
+
git schemes with optional userinfo, so a non-allowlisted host inside
|
|
267
|
+
a clone URL still folds to `<host>` while the sentinel is preserved.
|
|
268
|
+
- **Feedback redactor now treats single-letter trailing labels as
|
|
269
|
+
filename fragments, not hostnames (#247, Codex P1-5 deferred from
|
|
270
|
+
PR #242).** Tokens like `a.b.c` survive verbatim. Single-letter TLDs
|
|
271
|
+
are not registrable domains in normal prose; folding them yields
|
|
272
|
+
more false positives on short identifiers and abbreviated references
|
|
273
|
+
than legitimate redactions.
|
|
274
|
+
- **Feedback redactor emits a visible stderr warning when identity
|
|
275
|
+
folding is disabled (#246).** When `rcf/.identity/profile.md` is
|
|
276
|
+
missing, has no `## Name` heading, has a blank or placeholder Name
|
|
277
|
+
line, or the Name contains only reserved-noun tokens, one line on
|
|
278
|
+
stderr names the file and states that folding is disabled. The
|
|
279
|
+
operator is no longer left thinking their identity is in force when
|
|
280
|
+
it silently is not. Folding still skips per AC-15601-5.
|
|
281
|
+
- **`rcf feedback status --json` and text now expose the destination
|
|
282
|
+
resolution `source` field, matching preview (#244).** Programmatic
|
|
283
|
+
verifiers can now assert which resolver path picked the destination
|
|
284
|
+
(`library-manifest`, `package-bugs-url`, `derived`,
|
|
285
|
+
`sourceRef-derivation`, `library-slug-inference`) without parsing
|
|
286
|
+
preview text. The field is null when the resolver did not attach
|
|
287
|
+
one, e.g. for an unresolved library.
|
|
288
|
+
- **`rcf feedback add --evidence` pointers now render with the label
|
|
289
|
+
matching their shape, not always `(command)` (#245).** The help
|
|
290
|
+
text promises three labels (`command / path:line / id`); the
|
|
291
|
+
classifier now recognises `path:line` and bare paths ending in a
|
|
292
|
+
known file extension as `file`, canonical RCF ids
|
|
293
|
+
(`AC-15601-6`, `REQ-155`, `FBS-181`, `US-15701`) as `id`, and
|
|
294
|
+
everything else as `command`. Whitespace anywhere in the pointer
|
|
295
|
+
is a hard signal for `command`.
|
|
296
|
+
- **`rcf audit view` snapshots its shipped static assets at server
|
|
297
|
+
startup (#248).** The live-view server rendered the HTML body from
|
|
298
|
+
a tree walk captured at startup, but `/style.css`, `/mermaid.min.js`
|
|
299
|
+
and `/live-client.js` were `readFile`-d per request against the
|
|
300
|
+
on-disk file. A checkout branch switch during the server's lifetime
|
|
301
|
+
silently changed what got served; the 2026-09-22 Product Map
|
|
302
|
+
preview rendered unstyled for exactly this reason. All three
|
|
303
|
+
assets are now read once at startup into memory and served from
|
|
304
|
+
there. The tree walker remains the only path that re-reads disk on
|
|
305
|
+
`rcf/` change.
|
|
306
|
+
|
|
307
|
+
### Chain
|
|
308
|
+
|
|
309
|
+
- AC-15601-6 amended with design amendments R5e (single-letter TLDs
|
|
310
|
+
are filename fragments), R5f (git protocol sentinel protection on
|
|
311
|
+
rule 3, extended URL rule 4 for git+ssh/ssh/git schemes) and R5g
|
|
312
|
+
(visible stderr warning when identity folding is disabled). All
|
|
313
|
+
three land on the same story so operators see one AC that names
|
|
314
|
+
the redactor's full posture.
|
|
315
|
+
- `rcf define validate`: clean. `rcf audit coverage --strict`: clean
|
|
316
|
+
(103 requirements, 0 uncovered).
|
|
317
|
+
|
|
318
|
+
### Release mechanics
|
|
319
|
+
|
|
320
|
+
- Version bumped: `packages/rcf-lite/package.json` 0.28.2 -> 0.28.3.
|
|
321
|
+
- Changelog entry under `## [0.28.3]` (this section).
|
|
322
|
+
- Feed entry added under `releases/releases.yaml`; `latest` set to
|
|
323
|
+
0.28.3.
|
|
324
|
+
- Tag / publish: Dave (not this PR).
|
|
325
|
+
|
|
9
326
|
## [0.28.2] - 2026-09-22
|
|
10
327
|
|
|
11
328
|
Batched fix release for the seven defects Barry's WSD-lens dogfood on
|
package/bin/rcf.js
CHANGED
|
@@ -51,6 +51,10 @@ import { main as reqClassifyMain } from '../src/cli/req-classify.js';
|
|
|
51
51
|
import { main as reqBaselineMain } from '../src/cli/req-baseline.js';
|
|
52
52
|
import { main as intakeMain } from '../src/cli/intake.js';
|
|
53
53
|
import { main as evalMain } from '../src/cli/eval.js';
|
|
54
|
+
import { main as ledgerMain } from '../src/cli/ledger.js';
|
|
55
|
+
import { main as readinessMain } from '../src/cli/readiness.js';
|
|
56
|
+
import { main as questionsMain } from '../src/cli/questions.js';
|
|
57
|
+
import { main as freezeMain } from '../src/cli/freeze.js';
|
|
54
58
|
|
|
55
59
|
// Verify group members are handled by the verify-suite dispatch tree.
|
|
56
60
|
import { main as verifyRunMain } from '../src/verify/cli/run.js';
|
|
@@ -95,6 +99,10 @@ export const GROUPS = {
|
|
|
95
99
|
design: designMain,
|
|
96
100
|
blueprint: blueprintMain,
|
|
97
101
|
standards: standardsMain,
|
|
102
|
+
ledger: ledgerMain,
|
|
103
|
+
readiness: readinessMain,
|
|
104
|
+
questions: questionsMain,
|
|
105
|
+
freeze: freezeMain,
|
|
98
106
|
},
|
|
99
107
|
build: {
|
|
100
108
|
// build sub-verbs are dispatched by build.js internally (queue |
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"registerCanary": [
|
|
3
3
|
{
|
|
4
|
-
"id": "rc-2026-
|
|
5
|
-
"createdAt": "2026-
|
|
6
|
-
"buildVersion": "0.
|
|
4
|
+
"id": "rc-2026-10-03-001",
|
|
5
|
+
"createdAt": "2026-10-03T12:16:10.630Z",
|
|
6
|
+
"buildVersion": "0.29.0-mockdriver",
|
|
7
7
|
"fixturePromptId": "canary-prompt-01",
|
|
8
8
|
"responseWordCount": 55,
|
|
9
9
|
"grades": {
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"id": "rc-2026-
|
|
38
|
-
"createdAt": "2026-
|
|
39
|
-
"buildVersion": "0.
|
|
37
|
+
"id": "rc-2026-10-03-002",
|
|
38
|
+
"createdAt": "2026-10-03T12:16:10.631Z",
|
|
39
|
+
"buildVersion": "0.29.0-mockdriver",
|
|
40
40
|
"fixturePromptId": "canary-prompt-02",
|
|
41
41
|
"responseWordCount": 55,
|
|
42
42
|
"grades": {
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
"id": "rc-2026-
|
|
71
|
-
"createdAt": "2026-
|
|
72
|
-
"buildVersion": "0.
|
|
70
|
+
"id": "rc-2026-10-03-003",
|
|
71
|
+
"createdAt": "2026-10-03T12:16:10.631Z",
|
|
72
|
+
"buildVersion": "0.29.0-mockdriver",
|
|
73
73
|
"fixturePromptId": "canary-prompt-03",
|
|
74
74
|
"responseWordCount": 55,
|
|
75
75
|
"grades": {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Drafting the engineer's entry shapes
|
|
2
|
+
|
|
3
|
+
This document is the content of the `rcf_define_draft_shapes` MCP
|
|
4
|
+
prompt served argument-free by the server. The agent reads it once
|
|
5
|
+
per session and runs the draft pass after L1 is green. The product
|
|
6
|
+
owner is not in the room; the agent populates `[draft]`-marked
|
|
7
|
+
entities, components and interfaces so the engineer walks into a tree
|
|
8
|
+
whose shape is honest about what is still owed.
|
|
9
|
+
|
|
10
|
+
## When to run
|
|
11
|
+
|
|
12
|
+
Run this pass once `rcf define readiness --level intent` prints
|
|
13
|
+
`levels.intentComplete.ok === true` and the product owner has stepped
|
|
14
|
+
back. Not before. The draft pass reads only the brief ledger, the
|
|
15
|
+
decisions ledger and the current tree; it writes only `[draft]`-marked
|
|
16
|
+
content. `shapes:draftSettled` then lists exactly what the engineer
|
|
17
|
+
has yet to own.
|
|
18
|
+
|
|
19
|
+
Nothing in the draft pass can fail a product-owner check. That is the
|
|
20
|
+
property that keeps L1 and the draft pass independent. If an edit
|
|
21
|
+
would fail any check in the `productOwner` persona, stop and raise it
|
|
22
|
+
back to the intent loop (it was not an engineer-only question).
|
|
23
|
+
|
|
24
|
+
## The three homes
|
|
25
|
+
|
|
26
|
+
The `[draft]` marker lives on three homes in 0.30.0. The agent writes
|
|
27
|
+
to all three; `shapes:draftSettled` reads back from all three.
|
|
28
|
+
|
|
29
|
+
- `TAD.dataArchitecture.coreEntities[].description` begins `[draft]`
|
|
30
|
+
for every entity minted from an `entity` statement. The marker
|
|
31
|
+
reports under id `TAD.entity:<name>`.
|
|
32
|
+
- `TAC.purpose` begins `[draft]` for every TAC stub minted from a
|
|
33
|
+
`surface` or `externalSystem` cluster. The marker reports under id
|
|
34
|
+
`<tacId>`.
|
|
35
|
+
- `TAC.interfaces[].description` begins `[draft]` for every interface
|
|
36
|
+
pre-populated inside a draft stub. The marker reports under id
|
|
37
|
+
`<tacId>:<name>`.
|
|
38
|
+
|
|
39
|
+
Each marker is `[draft]` followed by a space and the one-sentence
|
|
40
|
+
seed body. Leading whitespace is tolerated by the reader; keep the
|
|
41
|
+
marker at the start of the string regardless.
|
|
42
|
+
|
|
43
|
+
## The four writes
|
|
44
|
+
|
|
45
|
+
Walk the brief in this order; each step writes `[draft]` content only.
|
|
46
|
+
|
|
47
|
+
1. One `TAD.dataArchitecture.coreEntities[]` entry per `entity`
|
|
48
|
+
statement. `description` begins `[draft]` and quotes the
|
|
49
|
+
statement's source so the engineer can trace it. Use the statement
|
|
50
|
+
text to pick a name in UpperCamel; the engineer renames when the
|
|
51
|
+
entity is owned.
|
|
52
|
+
2. One TAC stub per `surface` or `externalSystem` cluster when no
|
|
53
|
+
TAC exists for it. `purpose` begins `[draft]`; `responsibilities`
|
|
54
|
+
lists the statements the surface or external system serves (one
|
|
55
|
+
bullet per statement, in the brief's words). Pick a `tacId` of the
|
|
56
|
+
next free number and a descriptive slug; the engineer renames when
|
|
57
|
+
the TAC is owned.
|
|
58
|
+
3. On each draft TAC, `[draft]` interfaces with real kinds from the
|
|
59
|
+
closed vocabulary (`recordShape`, `httpRoute`, `event`,
|
|
60
|
+
`cliCommand`, `uiRoute`, `port`, `fileFormat`, `fixture`,
|
|
61
|
+
`other`). Draft one of each kind the surface uses:
|
|
62
|
+
- a `recordShape` per entity the surface owns, with `fields:`
|
|
63
|
+
guessed from the brief;
|
|
64
|
+
- a `uiRoute` per surface;
|
|
65
|
+
- an `httpRoute` per exchange with an external system.
|
|
66
|
+
`description` begins `[draft]` with the one-line what-this-is.
|
|
67
|
+
4. `rcf discover req-classify` over every REQ created in the loop, so
|
|
68
|
+
`skeleton:reqShape` passes where the classifier is confident and
|
|
69
|
+
the engineer sees only the rest. The classifier is already
|
|
70
|
+
available under `src/review/` or `src/discover/`; this prompt only
|
|
71
|
+
invokes it.
|
|
72
|
+
|
|
73
|
+
## The read-back
|
|
74
|
+
|
|
75
|
+
After the pass, run `rcf define readiness --json` and read
|
|
76
|
+
`stages[].checks[]`. `shapes:draftSettled` is the engineer's entry
|
|
77
|
+
list: every id it names is a shape the agent pre-populated and the
|
|
78
|
+
engineer still has to settle. `shapes:tacHasInterface` and
|
|
79
|
+
`shapes:kindVocabulary` have already applied to drafts, so an empty
|
|
80
|
+
`shapes:tacHasInterface` finding means every stub carries at least
|
|
81
|
+
one interface and an empty `shapes:kindVocabulary` finding means
|
|
82
|
+
every interface's kind is in the closed vocabulary. The template
|
|
83
|
+
marker check and the entity join arrive in a later PR; the draft
|
|
84
|
+
pass does not need them to be honest about what is drafted.
|
|
85
|
+
|
|
86
|
+
Hand over by naming the three id forms the engineer will see
|
|
87
|
+
(`<tacId>:<name>`, `<tacId>`, `TAD.entity:<name>`) and the one verb
|
|
88
|
+
they will run to walk them (`rcf define readiness`). Nothing further
|
|
89
|
+
is said; the engineer owns the ladder from here.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Document intake into the brief ledger
|
|
2
|
+
|
|
3
|
+
This document is the content of the `rcf_define_intake` MCP prompt
|
|
4
|
+
served argument-free by the server. It walks the harness through
|
|
5
|
+
intake and lands every finding as an open-question statement the
|
|
6
|
+
intent loop then asks.
|
|
7
|
+
|
|
8
|
+
## What intake is
|
|
9
|
+
|
|
10
|
+
The owner hands over a folder. One file is the brief (short, prose,
|
|
11
|
+
the "what we are building" document); the rest are supporting
|
|
12
|
+
documents (ADRs, spec sketches, old READMEs, OpenAPI YAML, meeting
|
|
13
|
+
notes). The split that reaches the brief ledger is the harness's
|
|
14
|
+
work; the mechanical scans and the follow-up questions are
|
|
15
|
+
rcf-lite's.
|
|
16
|
+
|
|
17
|
+
Intake is harness-split and tool-scanned. The harness writes
|
|
18
|
+
`<source>.statements.md` beside each source; rcf-lite mints the
|
|
19
|
+
statements, runs the three mechanical scans against the existing
|
|
20
|
+
body, and appends one `openQuestion` statement per finding. The loop
|
|
21
|
+
then reads one check (`brief:openQuestions`) and the owner answers
|
|
22
|
+
in one place (ADR-4130).
|
|
23
|
+
|
|
24
|
+
## The walk
|
|
25
|
+
|
|
26
|
+
Walk the folder brief-first. For each source, in this order:
|
|
27
|
+
|
|
28
|
+
1. Open the source.
|
|
29
|
+
2. Split it into one statement per line. A statement is a sentence
|
|
30
|
+
that stands on its own: a capability (something the product must
|
|
31
|
+
do), a constraint (a rule it must obey), an actor (a person or
|
|
32
|
+
role), an entity (a thing it keeps track of), an externalSystem
|
|
33
|
+
(another system), a surface (a screen or channel), outOfScope
|
|
34
|
+
(something explicitly not in), an openQuestion (a question still
|
|
35
|
+
to answer), or an amendment (a correction to an earlier
|
|
36
|
+
statement).
|
|
37
|
+
3. Write `<source>.statements.md` next to the source. Each line is
|
|
38
|
+
one statement with a leading `[kind]` marker and a trailing
|
|
39
|
+
`(source: <path>:<line-span>)` marker.
|
|
40
|
+
4. Show the file to the owner in one message. Correct based on their
|
|
41
|
+
reply.
|
|
42
|
+
5. Run `rcf define ledger brief add --from <path>` (or the
|
|
43
|
+
`rcf_define_ledger` MCP tool with `verb: add`, `from: <path>`).
|
|
44
|
+
The mechanical scans run by default; findings are appended as
|
|
45
|
+
openQuestion statements. Report the scan findings as plain
|
|
46
|
+
questions.
|
|
47
|
+
6. Move to the next source.
|
|
48
|
+
|
|
49
|
+
Never add two sources through one `brief add --from`. Each `add`
|
|
50
|
+
scans the new ids against the existing body, and the scan source
|
|
51
|
+
marker `scan:<name>:<ids>` names the ids from both sides.
|
|
52
|
+
|
|
53
|
+
## The line grammar
|
|
54
|
+
|
|
55
|
+
Each line of a statement file is a statement. The grammar:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
[<kind>] <text> (source: <path>:<line-span>)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- `[<kind>]` is one of the nine kinds above. When absent, the kind
|
|
62
|
+
defaults to the harness's `--kind` flag (default `capability`), or
|
|
63
|
+
to `openQuestion` when the line ends with `?` or begins with
|
|
64
|
+
`TBC`, `TBD`, `Open:` or `Question:`.
|
|
65
|
+
- `(source: ...)` names the file and the line range in the source.
|
|
66
|
+
When absent, the harness's `--source` flag or the file path itself
|
|
67
|
+
is used.
|
|
68
|
+
- Everything between the two markers is the statement text,
|
|
69
|
+
verbatim.
|
|
70
|
+
|
|
71
|
+
## What the owner sees
|
|
72
|
+
|
|
73
|
+
A statement file is operator prose. The owner reads it; the harness
|
|
74
|
+
corrects based on their reply. Example:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
[capability] Officers can put a loan on hold for up to 30 days. (source: briefs/loans.md:12-14)
|
|
78
|
+
[constraint] A loan on hold must not accrue late fees. (source: briefs/loans.md:15)
|
|
79
|
+
[openQuestion] Who approves a hold longer than 30 days? (source: briefs/loans.md:16)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
After `brief add --from` runs, the loop will ask about each of these
|
|
83
|
+
through `rcf define questions --persona productOwner`.
|
|
84
|
+
|
|
85
|
+
## After intake
|
|
86
|
+
|
|
87
|
+
Run `rcf define questions --persona productOwner`. The next set is
|
|
88
|
+
the `resolvedBy` questions for every capability, constraint, entity,
|
|
89
|
+
actor, externalSystem and surface statement, suggesting existing
|
|
90
|
+
REQ titles that share two or more words of 4+ characters. The owner
|
|
91
|
+
decides which become new REQs, which point at existing REQs, and
|
|
92
|
+
which are omitted.
|
|
93
|
+
|
|
94
|
+
At L1 (`levels.intentComplete.ok === true`) the agent pre-populates
|
|
95
|
+
`[draft]` entities, components and interfaces as engineer entry
|
|
96
|
+
material. These are drafts the engineer refines; they are never a
|
|
97
|
+
product-owner blocker.
|