rcf-lite 0.8.0 → 0.10.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 +124 -51
- package/README.md +8 -4
- package/bin/rcf.js +147 -53
- package/fixtures/canary-manifest.json +9 -9
- package/guidance/README.md +1 -1
- package/guidance/build-cycle-playbook.md +51 -51
- package/guidance/build-cycle.md +7 -7
- package/guidance/document-model.md +1 -1
- package/guidance/elicitation-playbook.md +29 -29
- package/guidance/harness-template.md +21 -10
- package/guidance/managed/README.md +1 -1
- package/guidance/managed/agent-instructions-block.hash +1 -1
- package/guidance/managed/agent-instructions-block.md +20 -9
- package/guidance/manifest.json +1 -1
- package/guidance/overview.md +4 -4
- package/package.json +5 -7
- package/rcf/adrs/adr-008.json +1 -1
- package/rcf/adrs/adr-009.json +4 -4
- package/rcf/adrs/adr-010.json +30 -0
- package/rcf/code-nodes/cn-016.json +1 -1
- package/rcf/code-nodes/cn-019.json +1 -1
- package/rcf/code-nodes/cn-020.json +1 -1
- package/rcf/code-nodes/cn-021.json +1 -1
- package/rcf/code-nodes/cn-022.json +1 -1
- package/rcf/code-nodes/cn-049.json +1 -1
- package/rcf/code-nodes/cn-055.json +1 -1
- package/rcf/code-nodes/cn-057.json +5 -5
- package/rcf/code-nodes/cn-058.json +18 -0
- package/rcf/code-nodes/cn-059.json +14 -0
- package/rcf/code-nodes/cn-060.json +14 -0
- package/rcf/code-nodes/cn-061.json +14 -0
- package/rcf/code-nodes/cn-062.json +14 -0
- package/rcf/code-nodes/cn-063.json +15 -0
- package/rcf/code-nodes/cn-064.json +15 -0
- package/rcf/code-nodes/cn-065.json +16 -0
- package/rcf/code-nodes/cn-066.json +14 -0
- package/rcf/code-nodes/cn-067.json +15 -0
- package/rcf/code-nodes/cn-068.json +15 -0
- package/rcf/code-nodes/cn-069.json +16 -0
- package/rcf/fbs/fbs-005.json +1 -1
- package/rcf/fbs/fbs-006.json +2 -2
- package/rcf/fbs/fbs-007.json +1 -1
- package/rcf/fbs/fbs-014.json +1 -1
- package/rcf/fbs/fbs-015.json +9 -8
- package/rcf/fbs/fbs-016.json +39 -0
- package/rcf/fbs/fbs-017.json +40 -0
- package/rcf/fbs/fbs-018.json +34 -0
- package/rcf/fbs/fbs-019.json +33 -0
- package/rcf/requirements/req-008.json +1 -1
- package/rcf/requirements/req-009.json +2 -2
- package/rcf/requirements/req-010.json +20 -0
- package/rcf/test-suites/PENDING.md +2 -2
- package/rcf/test-suites/ts-004.json +1 -1
- package/rcf/test-suites/ts-006.json +3 -3
- package/rcf/test-suites/ts-008.json +2 -2
- package/rcf/test-suites/ts-009.json +2 -2
- package/rcf/test-suites/ts-017.json +1 -1
- package/rcf/test-suites/ts-024.json +1 -1
- package/rcf/test-suites/ts-025.json +32 -18
- package/rcf/test-suites/ts-026.json +54 -0
- package/rcf/test-suites/ts-027.json +115 -0
- package/rcf/test-suites/ts-028.json +46 -0
- package/rcf/test-suites/ts-029.json +46 -0
- package/rcf/user-stories/us-1001.json +56 -0
- package/rcf/user-stories/us-1002.json +96 -0
- package/rcf/user-stories/us-1003.json +48 -0
- package/rcf/user-stories/us-1004.json +48 -0
- package/rcf/user-stories/us-805.json +2 -2
- package/rcf/user-stories/us-901.json +13 -13
- package/src/blueprint/apply.js +464 -0
- package/src/blueprint/conflicts.js +351 -0
- package/src/blueprint/diff.js +82 -0
- package/src/blueprint/index.js +12 -0
- package/src/blueprint/list.js +21 -0
- package/src/blueprint/loader.js +163 -0
- package/src/blueprint/manifest-writer.js +49 -0
- package/src/blueprint/namespace.js +145 -0
- package/src/blueprint/remove.js +105 -0
- package/src/blueprint/resolutions.js +83 -0
- package/src/blueprint/standards.js +148 -0
- package/src/blueprint/supersede.js +318 -0
- package/src/browser-verify/invariants.js +33 -6
- package/src/build/bundle.js +37 -14
- package/src/build/formatters/markdown.js +9 -9
- package/src/build/mark.js +3 -3
- package/src/build/queue.js +1 -1
- package/src/build/standards-selector.js +52 -0
- package/src/cli/blueprint.js +325 -0
- package/src/cli/browser-verify.js +1 -1
- package/src/cli/build.js +139 -69
- package/src/cli/coverage.js +1 -1
- package/src/cli/create.js +48 -3
- package/src/cli/delete.js +2 -2
- package/src/cli/design.js +10 -10
- package/src/cli/fbs.js +1 -1
- package/src/cli/finalise.js +22 -20
- package/src/cli/help.js +269 -89
- package/src/cli/impact.js +1 -1
- package/src/cli/init.js +20 -5
- package/src/cli/intake.js +3 -3
- package/src/cli/link.js +3 -3
- package/src/cli/preflight.js +2 -2
- package/src/cli/read.js +1 -1
- package/src/cli/req-baseline.js +2 -2
- package/src/cli/req-classify.js +3 -3
- package/src/cli/review.js +1 -1
- package/src/cli/standards.js +127 -0
- package/src/cli/test-suite.js +1 -1
- package/src/cli/trace.js +1 -1
- package/src/cli/ui-baseline.js +3 -3
- package/src/cli/ui-classify.js +4 -4
- package/src/cli/update.js +2 -2
- package/src/cli/validate.js +2 -2
- package/src/cli/view.js +12 -10
- package/src/core/store/ids.js +168 -18
- package/src/core/store/loader.js +27 -16
- package/src/core/store/walker.js +27 -15
- package/src/core/store/writer.js +1 -1
- package/src/deployment/index.js +13 -0
- package/src/deployment/placeholder-detector.js +113 -0
- package/src/design/writer.js +3 -3
- package/src/finalise/detect.js +32 -38
- package/src/finalise/index.js +0 -1
- package/src/finalise/install.js +9 -8
- package/src/finalise/spawn.js +14 -10
- package/src/mcp/tools.js +1 -1
- package/src/query/formatters/table.js +7 -10
- package/src/query/trace.js +45 -4
- package/src/req-baseline/gate.js +1 -1
- package/src/ui-baseline/manifest-writer.js +2 -2
- package/src/verify/cli/cleanup.js +1 -1
- package/src/verify/cli/mcp.js +1 -1
- package/src/verify/cli/provision.js +1 -1
- package/src/verify/cli/report.js +1 -1
- package/src/verify/cli/run.js +1 -1
- package/src/view-supervisor/manifest-writer.js +2 -2
- package/bin/rcf-verify.js +0 -122
- package/src/verify/cli/help.js +0 -56
|
@@ -11,10 +11,10 @@ Every command output shown below is real, captured against this repository's own
|
|
|
11
11
|
## 2. The loop at a glance
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
rcf build --next -> spec bundle for the next actionable item
|
|
14
|
+
rcf build bundle --next -> spec bundle for the next actionable item
|
|
15
15
|
execute the five stages its runbook prints:
|
|
16
16
|
Define -> Build -> Review -> Test -> Finalise
|
|
17
|
-
rcf build <fbs-id>
|
|
17
|
+
rcf build mark <fbs-id> <status>
|
|
18
18
|
-> record each lifecycle transition, then repeat
|
|
19
19
|
```
|
|
20
20
|
|
|
@@ -30,7 +30,7 @@ What good looks like:
|
|
|
30
30
|
- Your plan maps every in-scope AC id to intended work. An AC with no planned work, or planned work with no AC, is a plan defect.
|
|
31
31
|
- Ambiguity is settled before code. If two readings of an AC survive the read-through, that is an escalation (section 8), not a coin flip.
|
|
32
32
|
|
|
33
|
-
Referee: the bundle itself is the definition, and `rcf validate` confirms the tree you are building against is clean before you start.
|
|
33
|
+
Referee: the bundle itself is the definition, and `rcf define validate` confirms the tree you are building against is clean before you start.
|
|
34
34
|
|
|
35
35
|
Failure modes:
|
|
36
36
|
|
|
@@ -40,15 +40,15 @@ Failure modes:
|
|
|
40
40
|
**Third-party service dependencies belong on the FBS at Define.** When the plan touches a service the pre-flight session recorded (`preFlightConfig` - see elicitation playbook §8.5), write the `dependsOnServices` binding on the FBS now, not later:
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
rcf fbs <fbs-id> depends-on --service <id> --mode <attestationMode> --acs <acIds> [--preflight <pfc-id>]
|
|
43
|
+
rcf build fbs <fbs-id> depends-on --service <id> --mode <attestationMode> --acs <acIds> [--preflight <pfc-id>]
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
This is not a build-time optimisation; it is the seam the whole verification-integrity surface hangs on. `coverage --strict` at Stage 4 refuses when a TC covers an AC whose FBS was named in a preflight `affectedFbsIds` list but has no matching entry here; verify's deployed-verdict gate reads the same binding to decide whether a live-attested AC needs a live probe or a `MOCK-ONLY-DECLARED` verdict is the honest answer. If the plan touches a service the pre-flight session did NOT record - a runtime dependency discovered mid-Build - `rcf build --next` will warn and point at `rcf preflight` for a re-run; add the entry to the preflight record, then to the FBS.
|
|
46
|
+
This is not a build-time optimisation; it is the seam the whole verification-integrity surface hangs on. `coverage --strict` at Stage 4 refuses when a TC covers an AC whose FBS was named in a preflight `affectedFbsIds` list but has no matching entry here; verify's deployed-verdict gate reads the same binding to decide whether a live-attested AC needs a live probe or a `MOCK-ONLY-DECLARED` verdict is the honest answer. If the plan touches a service the pre-flight session did NOT record - a runtime dependency discovered mid-Build - `rcf build bundle --next` will warn and point at `rcf discover preflight` for a re-run; add the entry to the preflight record, then to the FBS.
|
|
47
47
|
|
|
48
48
|
Stage end: mark pickup and commit any plan artefacts the driving workflow requires.
|
|
49
49
|
|
|
50
50
|
```
|
|
51
|
-
$ rcf build FBS-012
|
|
51
|
+
$ rcf build mark FBS-012 inProgress
|
|
52
52
|
marked FBS-012 notStarted -> inProgress
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -56,7 +56,7 @@ marked FBS-012 notStarted -> inProgress
|
|
|
56
56
|
|
|
57
57
|
Worked micro-example. The FBS-005 bundle ("CLI read verbs") scopes three ACs: AC-301-1 (reading a valid document returns it and reports it as valid), AC-301-2 (reading an id with no file returns a structured not-found error naming the id), AC-301-3 (reading an invalid document returns both the content and the validation errors). Restated as a three-line plan:
|
|
58
58
|
|
|
59
|
-
1. AC-301-1: wire `rcf read <id>` to the store load; render content plus a validity line; test the valid path.
|
|
59
|
+
1. AC-301-1: wire `rcf define read <id>` to the store load; render content plus a validity line; test the valid path.
|
|
60
60
|
2. AC-301-2: return the structured not-found error with the id in it; test against a missing id.
|
|
61
61
|
3. AC-301-3: on schema failure, render content and errors together rather than either alone; test with a deliberately broken document.
|
|
62
62
|
|
|
@@ -66,21 +66,21 @@ Three ACs, three lines, nothing extra. That is the whole Define output for a sma
|
|
|
66
66
|
|
|
67
67
|
What good looks like:
|
|
68
68
|
|
|
69
|
-
- The FBS classifier fired at Define and printed a `[info] build: ui-classifier verdict=ui reason=keyword-scan (N signal(s))` line ahead of the bundle. That is the trigger to think about design, not to skip it: even for a `notUi` verdict, if the FBS visibly renders pixels the operator overrides via `rcf update <fbs-id> --set uiBearing=true` (spec section 4.4). A false positive costs the operator one override; a false negative ships another dated UI.
|
|
70
|
-
- A `uiBaseline` record exists on the manifest. If it does not, run `rcf ui-baseline init` before opening any Design substage verb. The interactive session presents every ruled default on one summary screen; press ENTER to accept, type a field name to edit one, type `edit-all` to walk them sequentially, type `cancel` to leave without writing. Every opt-out lands with a plain-text reason of at least twenty characters. Silence is never an opt-out.
|
|
69
|
+
- The FBS classifier fired at Define and printed a `[info] build: ui-classifier verdict=ui reason=keyword-scan (N signal(s))` line ahead of the bundle. That is the trigger to think about design, not to skip it: even for a `notUi` verdict, if the FBS visibly renders pixels the operator overrides via `rcf define update <fbs-id> --set uiBearing=true` (spec section 4.4). A false positive costs the operator one override; a false negative ships another dated UI.
|
|
70
|
+
- A `uiBaseline` record exists on the manifest. If it does not, run `rcf discover ui-baseline init` before opening any Design substage verb. The interactive session presents every ruled default on one summary screen; press ENTER to accept, type a field name to edit one, type `edit-all` to walk them sequentially, type `cancel` to leave without writing. Every opt-out lands with a plain-text reason of at least twenty characters. Silence is never an opt-out.
|
|
71
71
|
- Three artefacts land on the FBS's `designStage` block before the design is called complete: a `journeys[]` list (at least one walk-through of a real actor + goal + two to eight steps), a `navModel` (shape from `shared-persistent` | `shared-per-section` | `none-single-page` | `operator-declared-other`, at least one route with a path + label + authRequired boolean, and a `signedInAsAffordance` boolean), and a `themeAndA11y` block (theme mode from `light-default-with-toggle` | `dark-default-with-toggle` | `single-theme-declared`, the tokens-module path, the contrast-test path, and the `contrastTestAuthoredBeforePalette` boolean attestation).
|
|
72
|
-
- Author via the verbs, not by hand-editing: `rcf design <fbs-id> journeys add --id <slug> --actor "..." --goal "..." --step "..." --step "..."`, `rcf design <fbs-id> nav set --shape <shape> --route <path=label:authRequired> ...`, `rcf design <fbs-id> theme-a11y set --mode <mode> --tokens <path> --contrast-test <path> --contrast-before-palette true|false`. When all three are in place, `rcf design <fbs-id> --mark-complete` sets `designStageComplete: true` on the FBS record. Alternatively, dispatch the Design worker via `rcf design <fbs-id>` (no sub-verb) and let the subagent author the three artefacts against the baseline plus a sibling-FBS `designStage` context, then mark complete.
|
|
72
|
+
- Author via the verbs, not by hand-editing: `rcf define design <fbs-id> journeys add --id <slug> --actor "..." --goal "..." --step "..." --step "..."`, `rcf define design <fbs-id> nav set --shape <shape> --route <path=label:authRequired> ...`, `rcf define design <fbs-id> theme-a11y set --mode <mode> --tokens <path> --contrast-test <path> --contrast-before-palette true|false`. When all three are in place, `rcf define design <fbs-id> --mark-complete` sets `designStageComplete: true` on the FBS record. Alternatively, dispatch the Design worker via `rcf define design <fbs-id>` (no sub-verb) and let the subagent author the three artefacts against the baseline plus a sibling-FBS `designStage` context, then mark complete.
|
|
73
73
|
- The playbook mandate 5 vocabulary (`Button`, `Input`, `Card`, `Badge`, `Table`, `Notice`, single badge shape) is guidance-only in v1. For string-templated projects (server-rendered HTML by concatenation, no framework) the operator can hand-check the six-component vocabulary with a `grep -oE 'class="[^"]+"'` sweep of view files; the audit does not enforce it mechanically in v1.
|
|
74
74
|
|
|
75
|
-
Warning at Stage 2 entry (`rcf build <fbs-id>
|
|
75
|
+
Warning at Stage 2 entry (`rcf build mark <fbs-id> inProgress`): if the FBS is uiBearing and no `designStage` has been authored, one `[warn]` line points at `rcf define design <fbs-id>`. Not a refusal - pickup and planning can happen before design when the operator wants to think about the AC scope first. The hard refusal fires at Stage 5.
|
|
76
76
|
|
|
77
|
-
Refusal at Stage 5 entry (`rcf build <fbs-id>
|
|
77
|
+
Refusal at Stage 5 entry (`rcf build mark <fbs-id> complete`) on a uiBearing FBS when any of: `designStageComplete` is not true; `designStage.themeAndA11y.contrastTestAuthoredBeforePalette` is false; the baseline disagrees with a `designStage` paired field and no `operatorOptOuts[]` entry excuses it; the browser-verification verdict is `block` or `warn` without operator ack (see section 7).
|
|
78
78
|
|
|
79
|
-
Escalation: when the operator disagrees with the classifier, ratify or override via `rcf update <fbs-id> --set uiBearing=true|false`. The override records `verdict: operatorOverride` on `uiClassification`, keeping the classifier's evidence in `signals[]` for provenance. When the operator disagrees with a baseline default, record it as an explicit opt-out via `rcf ui-baseline opt-out --field <path> --reason "..." ` (at least twenty characters).
|
|
79
|
+
Escalation: when the operator disagrees with the classifier, ratify or override via `rcf define update <fbs-id> --set uiBearing=true|false`. The override records `verdict: operatorOverride` on `uiClassification`, keeping the classifier's evidence in `signals[]` for provenance. When the operator disagrees with a baseline default, record it as an explicit opt-out via `rcf discover ui-baseline opt-out --field <path> --reason "..." ` (at least twenty characters).
|
|
80
80
|
|
|
81
81
|
Stage end: commit. The `designStage` and `designStageComplete` write are the artefacts of this stage.
|
|
82
82
|
|
|
83
|
-
Worked micro-example. FBS-016 ("Web UI dashboard") classifies as UI-bearing on `dashboard` and `page` signals in the summary. `rcf ui-baseline init` runs once for the project, accepting the ruled defaults on ENTER. Three journeys sketched: signed-in-owner checks status; new-monitor add flow; unauthenticated visitor lands on login. `navModel` records the four authenticated routes (dashboard, monitors, monitor-detail, settings) as `shared-persistent` with `signedInAsAffordance: true`. `themeAndA11y` records `light-default-with-toggle`, tokens at `src/ui/tokens.ts`, contrast test at `test/ui-accessibility.test.ts`, `contrastTestAuthoredBeforePalette: true`. `rcf design FBS-016 --mark-complete` sets the boolean; Stage 2 opens.
|
|
83
|
+
Worked micro-example. FBS-016 ("Web UI dashboard") classifies as UI-bearing on `dashboard` and `page` signals in the summary. `rcf discover ui-baseline init` runs once for the project, accepting the ruled defaults on ENTER. Three journeys sketched: signed-in-owner checks status; new-monitor add flow; unauthenticated visitor lands on login. `navModel` records the four authenticated routes (dashboard, monitors, monitor-detail, settings) as `shared-persistent` with `signedInAsAffordance: true`. `themeAndA11y` records `light-default-with-toggle`, tokens at `src/ui/tokens.ts`, contrast test at `test/ui-accessibility.test.ts`, `contrastTestAuthoredBeforePalette: true`. `rcf define design FBS-016 --mark-complete` sets the boolean; Stage 2 opens.
|
|
84
84
|
|
|
85
85
|
## 4. Stage 2 - Build
|
|
86
86
|
|
|
@@ -88,7 +88,7 @@ What good looks like:
|
|
|
88
88
|
|
|
89
89
|
- Implement to the section-4 ACs using the section-5 context. The TACs name the components and boundaries you are expected to respect; the ADRs name decisions already taken, which you follow rather than relitigate.
|
|
90
90
|
- The bundle is the spec. When the code teaches you the spec is wrong, stop and escalate; do not quietly ship your improved version.
|
|
91
|
-
- As each AC lands, author or update its Code Node: `rcf create cn --path <file>[#symbol] --acs <ac-ids>`. Do this now - the mapping from symbol to AC is exactly what you are holding in your head mid-implementation, and Stage 5 refuses completion without it (section 9).
|
|
91
|
+
- As each AC lands, author or update its Code Node: `rcf define create cn --path <file>[#symbol] --acs <ac-ids>`. Do this now - the mapping from symbol to AC is exactly what you are holding in your head mid-implementation, and Stage 5 refuses completion without it (section 9).
|
|
92
92
|
- Small commits inside the stage are fine; the stage-end commit is mandatory.
|
|
93
93
|
|
|
94
94
|
Referee: none new at this stage. The bundle stays open; you check yourself against it.
|
|
@@ -111,8 +111,8 @@ What good looks like:
|
|
|
111
111
|
Referee:
|
|
112
112
|
|
|
113
113
|
```
|
|
114
|
-
$ rcf validate
|
|
115
|
-
rcf validate: tree is clean.
|
|
114
|
+
$ rcf define validate
|
|
115
|
+
rcf define validate: tree is clean.
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
Exit 0 when clean; exit 3 with issue lines when not (section 9 shows the failure shape).
|
|
@@ -122,7 +122,7 @@ Failure modes:
|
|
|
122
122
|
- **Rubber-stamp review.** Symptom: review completes in the time it takes to scroll. Correction: the per-AC question above, answered per AC, in writing if the workflow keeps review notes.
|
|
123
123
|
- **Reviewing only what changed rather than what was promised.** Symptom: the review walks the diff top to bottom and never opens section 4. Correction: walk the AC list as the outer loop, the diff as the inner one. This is where AC-skipping is cheapest to catch.
|
|
124
124
|
|
|
125
|
-
**Second gate on Stage 3: `rcf review <fbs-id>`.** After `rcf validate` clears the tree, run the test-theatre audit. The audit asks the meta-question the diff review does not: are the tests themselves honest? Five finding categories run deterministically over the FBS's in-scope ACs and their covering TSes:
|
|
125
|
+
**Second gate on Stage 3: `rcf build review <fbs-id>`.** After `rcf define validate` clears the tree, run the test-theatre audit. The audit asks the meta-question the diff review does not: are the tests themselves honest? Five finding categories run deterministically over the FBS's in-scope ACs and their covering TSes:
|
|
126
126
|
|
|
127
127
|
- `mockOnlyIntegrationClaim` - an integration-level TS whose every TC records `runtimeProvenance.profile` in `{mock, stub, fixture}` while at least one bound AC's aggregated attestation is `live` or `sandboxed`. This is the exact failure the whole 0.7.0 verification-integrity surface exists to catch (d-2026-07-30-142). Severity: block.
|
|
128
128
|
- `testPointerBroken` - a TC's `testPointer` fails to resolve to a real test in the working tree. Severity: block.
|
|
@@ -146,7 +146,7 @@ What good looks like:
|
|
|
146
146
|
Referee:
|
|
147
147
|
|
|
148
148
|
```
|
|
149
|
-
$ rcf coverage --strict
|
|
149
|
+
$ rcf audit coverage --strict
|
|
150
150
|
Coverage mode: strict (per-AC)
|
|
151
151
|
Requirements: 8 covered: 8 covered-unresolved: 0 uncovered: 0
|
|
152
152
|
|
|
@@ -155,7 +155,7 @@ Requirement Covered AC AC covered Test cases
|
|
|
155
155
|
REQ-001 yes AC-101-1 yes TC-001-init-clean-tree-roots
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
(Captured against this repo's tree, first rows shown; exit 0. This tree binds all 76 of its ACs to named existing tests via resolving `testPointer`s. It did not start there: the audit that built this test axis opened with 14 honestly-registered gaps in `rcf/test-suites/PENDING.md`, the referee exited 4 for as long as any row remained, and the register emptied only when every AC got a test that genuinely asserts its outcome - including one whole feature the tree claimed and the code lacked. CI now runs `rcf validate` and `rcf coverage --strict` as required steps, so this exit 0 is locked in: a stub TC or a new uncovered AC fails the build.) Strict mode is per-AC: every AC in scope needs a TC whose pointer resolves, and any gap exits 4. The `covered-unresolved` column is the third state: TC rows exist but at least one pointer does not resolve to a real test - a stub or a stale pointer - and it fails the gate exactly as uncovered does, with the offending pointers listed under the table. Read the table by AC id: this stage ends when your in-scope ACs show `AC covered: yes` with test cases listed. Gaps elsewhere in the tree may legitimately remain and will keep the tree-wide command at exit 4; narrow the verdict with a scope id (`rcf coverage <scope-id> --strict`, PRD / REQ / US ids accepted) to read the subtree you are working in.
|
|
158
|
+
(Captured against this repo's tree, first rows shown; exit 0. This tree binds all 76 of its ACs to named existing tests via resolving `testPointer`s. It did not start there: the audit that built this test axis opened with 14 honestly-registered gaps in `rcf/test-suites/PENDING.md`, the referee exited 4 for as long as any row remained, and the register emptied only when every AC got a test that genuinely asserts its outcome - including one whole feature the tree claimed and the code lacked. CI now runs `rcf define validate` and `rcf audit coverage --strict` as required steps, so this exit 0 is locked in: a stub TC or a new uncovered AC fails the build.) Strict mode is per-AC: every AC in scope needs a TC whose pointer resolves, and any gap exits 4. The `covered-unresolved` column is the third state: TC rows exist but at least one pointer does not resolve to a real test - a stub or a stale pointer - and it fails the gate exactly as uncovered does, with the offending pointers listed under the table. Read the table by AC id: this stage ends when your in-scope ACs show `AC covered: yes` with test cases listed. Gaps elsewhere in the tree may legitimately remain and will keep the tree-wide command at exit 4; narrow the verdict with a scope id (`rcf audit coverage <scope-id> --strict`, PRD / REQ / US ids accepted) to read the subtree you are working in.
|
|
159
159
|
|
|
160
160
|
Failure modes:
|
|
161
161
|
|
|
@@ -165,13 +165,13 @@ Failure modes:
|
|
|
165
165
|
**Runtime provenance is authored, not remembered.** Every TC authored or updated in a build cycle carries `runtimeProvenance` on the same edit as `status`. The pattern:
|
|
166
166
|
|
|
167
167
|
```
|
|
168
|
-
rcf test-suite <ts-id> provenance --tc <tc-id> --profile <mock|stub|fixture|live|mixed> \
|
|
168
|
+
rcf build test-suite <ts-id> provenance --tc <tc-id> --profile <mock|stub|fixture|live|mixed> \
|
|
169
169
|
[--env-var VAR ...] [--host host ...] [--notes "..."]
|
|
170
170
|
```
|
|
171
171
|
|
|
172
172
|
`coverage --strict` refuses (exit 4) when a TC covers an AC that binds a `dependsOnServices` entry and lacks a provenance block, and enforces the section 3.5 attestation × profile matrix on every remaining TC. Belt and braces: the PR body still names the runtime it verified against (section 15), but the chain is now the source of truth and the PR is a rendering.
|
|
173
173
|
|
|
174
|
-
**TS approval is a Stage 4 outcome, not an authoring guess.** Once `coverage --strict` exits 0 and the underlying test run exits 0, promote each touched TS with `rcf test-suite <ts-id> approve`. Stage 4 does this automatically at end-of-stage; the operator only needs the verb for manual override (a rare re-approval after `needsRevision` cycles, via `--force`). CI can add the opt-in `rcf coverage --strict --require-approved` gate to fail the build on any TS still `draft` after Stage 4.
|
|
174
|
+
**TS approval is a Stage 4 outcome, not an authoring guess.** Once `coverage --strict` exits 0 and the underlying test run exits 0, promote each touched TS with `rcf build test-suite <ts-id> approve`. Stage 4 does this automatically at end-of-stage; the operator only needs the verb for manual override (a rare re-approval after `needsRevision` cycles, via `--force`). CI can add the opt-in `rcf audit coverage --strict --require-approved` gate to fail the build on any TS still `draft` after Stage 4.
|
|
175
175
|
|
|
176
176
|
Stage end: commit.
|
|
177
177
|
|
|
@@ -180,8 +180,8 @@ Stage end: commit.
|
|
|
180
180
|
What good looks like:
|
|
181
181
|
|
|
182
182
|
- CI green on the branch; PR raised and merged per the driving workflow's convention. The PR body is written for the reviewer, evidence first - author it per section 12, not as a diff walk.
|
|
183
|
-
- `rcf build <fbs-id>
|
|
184
|
-
- `rcf finalise <fbs-id> --url <deploy-url>` writes `verified` after post-merge verification: the merged artefact observed doing the right thing by an independent verify run, not just the pre-merge tests remembered fondly. `--mark` cannot write `verified` - it caps at `complete`; the finalise gate promotes `complete -> verified` only when the verify run passes with ship authority.
|
|
183
|
+
- `rcf build mark <fbs-id> complete` after the merge, never before it. This refuses (exit 3, `missingCodeNodes`) if any in-scope AC still carries no Code Node - a reliability chain with optional links is not a chain. Author the missing CNs and retry, or, for a genuinely no-code spec (docs-only, config-only), declare `rcf build mark <fbs-id> complete --no-code-nodes` once.
|
|
184
|
+
- `rcf build finalise <fbs-id> --url <deploy-url>` writes `verified` after post-merge verification: the merged artefact observed doing the right thing by an independent verify run, not just the pre-merge tests remembered fondly. `--mark` cannot write `verified` - it caps at `complete`; the finalise gate promotes `complete -> verified` only when the verify run passes with ship authority.
|
|
185
185
|
- A working, documented local preview is present as the default outcome (section 14), and every verification claim in the PR names the runtime it was checked against (section 15). These are part of done, not extras.
|
|
186
186
|
|
|
187
187
|
Referee: CI, the finalise gate, plus the mark commands' own refusals (section 9).
|
|
@@ -194,7 +194,7 @@ Failure modes:
|
|
|
194
194
|
|
|
195
195
|
**The finalise gate reads the attestation, not just the exit code.** A passing verify run whose report carries per-AC verdicts in `{MOCK-ONLY-DECLARED, BLOCKED-BY-DECLARATION}` will not promote to `verified`. The gate stays at `complete -> verified` promotion, but a mock-only-declared AC refuses the promotion unless the operator explicitly ships the FBS complete-without-verified via `--ship-without-verified`. The summary always discloses these verdicts (whether the FBS ships or not) so the honest picture reaches the reviewer. Older verify reports without the `perAcVerdicts` field are handled gracefully - verify's train car may land later; older reports flow through with the pre-0.7.0 gate behaviour.
|
|
196
196
|
|
|
197
|
-
**Browser-verification gate (Track B, UI-bearing FBS only).** Before `--mark complete` on a uiBearing FBS, run `rcf
|
|
197
|
+
**Browser-verification gate (Track B, UI-bearing FBS only).** Before `--mark complete` on a uiBearing FBS, run `rcf verify browser <fbs-id>` against the local preview or a deployed URL. The verb writes a `browserVerification[]` record on the manifest and aggregates a verdict (pass / warn / block). `--mark complete` refuses when the verdict is `block` (unless the operator uses `--accept-block --reason "..."` per the ship-without-verified escape hatch) or `warn` (unless `operatorAckAt` is populated via `rcf verify browser <fbs-id> --ack`). The `agentScreenshotCritique` mode drives an injectable browser driver over every enumerated route x theme, records the DOM against the versioned `UI_INVARIANTS_V1` set (shared-nav presence, active-nav marker, signed-in-as affordance, theme toggle, default theme, focus rings, structural layout compare), and (when the FBS binds an auth REQ) runs the auth-REQ smoke pack (`GET /login`, `POST /logout`, `GET /login/verify?token=`). The `operatorSession` mode records the operator's ack alone; the ack is the evidence. Screenshots and DOM dumps land under `.rcf/artefacts/<bv-id>/`, gitignored via the 0.6.0 managed block.
|
|
198
198
|
|
|
199
199
|
Stage end: the merge is the commit.
|
|
200
200
|
|
|
@@ -223,7 +223,7 @@ Render it in the operator's language (section 17): the item named by its title,
|
|
|
223
223
|
|
|
224
224
|
The commands and their output, read at a glance. Exit codes: 0 success, 1 unexpected runtime failure, 2 usage error, 3 validation or broken references, 4 refused.
|
|
225
225
|
|
|
226
|
-
**`rcf validate`** - exit 0 and `rcf validate: tree is clean.` when clean. On issues, exit 3 with one line per issue naming the document and the rule, then a summary count. Captured in a scratch copy with a required field removed by hand:
|
|
226
|
+
**`rcf define validate`** - exit 0 and `rcf define validate: tree is clean.` when clean. On issues, exit 3 with one line per issue naming the document and the rule, then a summary count. Captured in a scratch copy with a required field removed by hand:
|
|
227
227
|
|
|
228
228
|
```
|
|
229
229
|
[error] validation REQ-001: / must have required property 'title'
|
|
@@ -234,9 +234,9 @@ The commands and their output, read at a glance. Exit codes: 0 success, 1 unexpe
|
|
|
234
234
|
|
|
235
235
|
Note the fan-out: one broken document produced two broken references. Fix the named document first, then re-validate.
|
|
236
236
|
|
|
237
|
-
**`rcf coverage --strict`** - exit 0 when every AC in scope has a TC whose `testPointer` resolves to a real test; exit 4 on any gap, with the per-AC table shown in section 6 above. A TC whose pointer does not resolve counts as `covered-unresolved` - a gap, not coverage - and is listed under the table with the reason (file missing, test missing). The `Test cases` column is the evidence trail.
|
|
237
|
+
**`rcf audit coverage --strict`** - exit 0 when every AC in scope has a TC whose `testPointer` resolves to a real test; exit 4 on any gap, with the per-AC table shown in section 6 above. A TC whose pointer does not resolve counts as `covered-unresolved` - a gap, not coverage - and is listed under the table with the reason (file missing, test missing). The `Test cases` column is the evidence trail.
|
|
238
238
|
|
|
239
|
-
**`rcf build <fbs-id> --strict`** - exit 4 instead of a bundle when the item is blocked. Captured in a scratch copy with a dependency reset to `notStarted`:
|
|
239
|
+
**`rcf build bundle <fbs-id> --strict`** - exit 4 instead of a bundle when the item is blocked. Captured in a scratch copy with a dependency reset to `notStarted`:
|
|
240
240
|
|
|
241
241
|
```
|
|
242
242
|
[error] refused build: FBS-012 is blocked by FBS-010 (notStarted)
|
|
@@ -244,10 +244,10 @@ Note the fan-out: one broken document produced two broken references. Fix the na
|
|
|
244
244
|
|
|
245
245
|
Without `--strict` the bundle renders anyway, flagged as a read-ahead; `--next` never selects blocked items.
|
|
246
246
|
|
|
247
|
-
**`rcf build <fbs-id>
|
|
247
|
+
**`rcf build mark <fbs-id> <status>`** - exit 0 with a one-line confirmation (`marked FBS-012 notStarted -> inProgress`). The lifecycle is forward-only (`notStarted -> inProgress -> complete -> verified`; forward jumps legal), but `--mark` caps at `complete`: `--mark verified` is refused with exit 4 and points to `rcf build finalise` (only the finalise gate writes `verified`). A backward mark is likewise refused with exit 4 and names the escape hatch:
|
|
248
248
|
|
|
249
249
|
```
|
|
250
|
-
[error] refused build: refusing backward transition complete -> inProgress on FBS-005; for a deliberate correction use: rcf update FBS-005 --set executionStatus=inProgress
|
|
250
|
+
[error] refused build: refusing backward transition complete -> inProgress on FBS-005; for a deliberate correction use: rcf define update FBS-005 --set executionStatus=inProgress
|
|
251
251
|
```
|
|
252
252
|
|
|
253
253
|
The escape hatch is for operator-sanctioned corrections. If you are reaching for it, you are in section 8's fourth case.
|
|
@@ -297,7 +297,7 @@ Parallel-safe tiers (items in the same tier have no dependency between them and
|
|
|
297
297
|
Next actionable: FBS-013
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
Two actionable items, and the tier column says how they relate: FBS-013 and FBS-014 share tier 0, meaning no dependency path connects them - they are parallel-safe, so a harness with two write workers on separate clones could take one each. `rcf build --next` picks the lowest buildOrder and emits its bundle. The header orients you in one glance - what, where in the queue, how big, what it hangs off:
|
|
300
|
+
Two actionable items, and the tier column says how they relate: FBS-013 and FBS-014 share tier 0, meaning no dependency path connects them - they are parallel-safe, so a harness with two write workers on separate clones could take one each. `rcf build bundle --next` picks the lowest buildOrder and emits its bundle. The header orients you in one glance - what, where in the queue, how big, what it hangs off:
|
|
301
301
|
|
|
302
302
|
```
|
|
303
303
|
# Spec bundle: FBS-013 - Deploy-aware elicitation and hosting guidance
|
|
@@ -317,11 +317,11 @@ Two actionable items, and the tier column says how they relate: FBS-013 and FBS-
|
|
|
317
317
|
Mark pickup, and the cycle is running:
|
|
318
318
|
|
|
319
319
|
```
|
|
320
|
-
$ rcf build FBS-013
|
|
320
|
+
$ rcf build mark FBS-013 inProgress
|
|
321
321
|
marked FBS-013 notStarted -> inProgress
|
|
322
322
|
```
|
|
323
323
|
|
|
324
|
-
From here it is the five stages, a commit per stage, `--mark complete` after the merge, `rcf finalise` to promote to `verified` after post-merge verification, and back to `rcf build --next`.
|
|
324
|
+
From here it is the five stages, a commit per stage, `--mark complete` after the merge, `rcf build finalise` to promote to `verified` after post-merge verification, and back to `rcf build bundle --next`.
|
|
325
325
|
|
|
326
326
|
## 11. Driving the whole queue
|
|
327
327
|
|
|
@@ -332,15 +332,15 @@ Sections 3 to 7 deliver one item. This section is the loop around them: how a si
|
|
|
332
332
|
**The loop.**
|
|
333
333
|
|
|
334
334
|
```
|
|
335
|
-
rcf build
|
|
336
|
-
rcf build --next -> bundle for that item
|
|
335
|
+
rcf build queue -> queue state; a "Next actionable" id means there is work
|
|
336
|
+
rcf build bundle --next -> bundle for that item
|
|
337
337
|
run its five stages (sections 3-7), commit per stage
|
|
338
|
-
rcf build <fbs-id>
|
|
339
|
-
rcf finalise <fbs-id> --url <deploy-url> (independent verify -> verified)
|
|
340
|
-
then rcf build --next again
|
|
338
|
+
rcf build mark <fbs-id> complete (after merge)
|
|
339
|
+
rcf build finalise <fbs-id> --url <deploy-url> (independent verify -> verified)
|
|
340
|
+
then rcf build bundle --next again
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
-
You are done when `rcf build --next` stops handing back bundles and prints instead:
|
|
343
|
+
You are done when `rcf build bundle --next` stops handing back bundles and prints instead:
|
|
344
344
|
|
|
345
345
|
```
|
|
346
346
|
# Build queue: nothing actionable
|
|
@@ -352,7 +352,7 @@ That line - not "I built the first one" - is the end of the loop. If it instead
|
|
|
352
352
|
|
|
353
353
|
**Keep the driving context thin (why one session is enough).** The reason a sixteen-item queue "won't fit in one session" is that the agent kept every item's bundle, diff and test detail in a single growing thread. It does not have to. If your harness can spawn sub-agents, run each FBS in its own worker:
|
|
354
354
|
|
|
355
|
-
- The driver (you) holds only the queue, the trace and the running tally of what is done. You call `rcf build --next`, hand the bundle id to a worker, and wait for a short structured result.
|
|
355
|
+
- The driver (you) holds only the queue, the trace and the running tally of what is done. You call `rcf build bundle --next`, hand the bundle id to a worker, and wait for a short structured result.
|
|
356
356
|
- The worker holds one item's full working set - the bundle, the diff, the tests, the referee outputs - runs the five stages, opens its PR, and returns a few lines: item id, ACs satisfied, referee outputs, PR link, and any escalation. Then its context is discarded.
|
|
357
357
|
- The driver's context stays flat across all sixteen items because it never holds more than a summary of any one. That is the mechanism that makes a small app's whole queue a single-session job.
|
|
358
358
|
|
|
@@ -362,7 +362,7 @@ Brief each worker with the same four things the bundle names: the item id, the f
|
|
|
362
362
|
|
|
363
363
|
**The handover protocol.** A handover is state capture, not a memory dump. A fresh session must be able to resume from it without re-eliciting anything or re-deriving the queue.
|
|
364
364
|
|
|
365
|
-
1. Run `rcf build` and `rcf validate` first, so the handover records the tree's true state, not your remembered state.
|
|
365
|
+
1. Run `rcf build` and `rcf define validate` first, so the handover records the tree's true state, not your remembered state.
|
|
366
366
|
2. Write a next-session handover doc (e.g. `rcf/handover.md`, or wherever the harness keeps session notes). It captures: what is complete/verified, what is in progress and exactly where it stopped, the next actionable id, any open escalation awaiting a ruling, and any decision taken in conversation that is not yet written into the tree.
|
|
367
367
|
3. Point the agent-instructions files at it. Add one line to `CLAUDE.md` and `AGENTS.md` telling the next session to read the handover before anything else. A handover doc nobody is instructed to open is not a handover.
|
|
368
368
|
|
|
@@ -381,8 +381,8 @@ When Finalise raises a PR, the body is for the reviewer - human or agent - and i
|
|
|
381
381
|
**The body, in this order:**
|
|
382
382
|
|
|
383
383
|
1. **What and why, traced.** What changed, mapped to the FBS and its in-scope ACs. The AC ids are the "why" - they are the spec this diff exists to satisfy, so a reviewer can check the diff against the promise, not against your description of it.
|
|
384
|
-
2. **Verification actually performed.** Not "tests pass". State what you ran and what it reported: the test command and its result, `rcf coverage --with-code` (or a story-scoped `rcf coverage <us-id> --strict`) with the per-AC lines, `rcf validate` clean. Paste the outputs - they are the evidence, and pasted referee output is not something a reviewer has to take on trust. **Every claim in this section names the runtime it was checked against** (section 15): "verified against the local preview", "e2e against wrangler dev (localhost)", "smoke-tested against the deployed runtime". A verification line with no named runtime is incomplete, and a line that implies the deployed runtime when the check never touched it is a defect, not a wording nicety.
|
|
385
|
-
3. **Per-AC evidence trail.** For each in-scope AC: where it is satisfied (file and symbol) and the test that proves it. This is what `rcf coverage --with-code` and `rcf trace` already give you; lift it in rather than reprose it.
|
|
384
|
+
2. **Verification actually performed.** Not "tests pass". State what you ran and what it reported: the test command and its result, `rcf audit coverage --with-code` (or a story-scoped `rcf audit coverage <us-id> --strict`) with the per-AC lines, `rcf define validate` clean. Paste the outputs - they are the evidence, and pasted referee output is not something a reviewer has to take on trust. **Every claim in this section names the runtime it was checked against** (section 15): "verified against the local preview", "e2e against wrangler dev (localhost)", "smoke-tested against the deployed runtime". A verification line with no named runtime is incomplete, and a line that implies the deployed runtime when the check never touched it is a defect, not a wording nicety.
|
|
385
|
+
3. **Per-AC evidence trail.** For each in-scope AC: where it is satisfied (file and symbol) and the test that proves it. This is what `rcf audit coverage --with-code` and `rcf audit trace` already give you; lift it in rather than reprose it.
|
|
386
386
|
4. **Known limits and deviations, declared.** Anything you escalated and how it was ruled, any deliberate deviation from the bundle and its reason, any gap the operator accepted. A declared limit survives review; the same limit found later by the reviewer is a defect and a trust hit.
|
|
387
387
|
|
|
388
388
|
**What not to do:** a file-by-file walk of the diff (the reviewer can read the diff), "all tests pass" with no command or output behind it, or any verification claim you did not actually run. Zero unverifiable claims - every line in the body is something the reviewer can independently check.
|
|
@@ -398,8 +398,8 @@ FBS-012 - MCP server over the full surface. Satisfies AC-301-1, AC-301-2, AC-301
|
|
|
398
398
|
|
|
399
399
|
## Verification performed
|
|
400
400
|
- <test command>: <result, e.g. 807 passing> (full suite) - runtime: <e.g. Node 24 on CI (local-dev), NOT the deployed runtime>
|
|
401
|
-
- rcf coverage --with-code: in-scope ACs covered, per-AC lines below
|
|
402
|
-
- rcf validate: tree is clean
|
|
401
|
+
- rcf audit coverage --with-code: in-scope ACs covered, per-AC lines below
|
|
402
|
+
- rcf define validate: tree is clean
|
|
403
403
|
- local preview: <how it was started and what was driven, e.g. `npm run dev`, seeded data, exercised path X>
|
|
404
404
|
<paste the referee outputs here>
|
|
405
405
|
|
|
@@ -422,9 +422,9 @@ A bug that reached a build is a bug a test did not catch, which is a behaviour a
|
|
|
422
422
|
|
|
423
423
|
**The order - do not jump to the code:**
|
|
424
424
|
|
|
425
|
-
1. **Reproduce, then trace the bug to its governing AC.** Which AC should have made the correct behaviour required? Walk the tree with `rcf trace` from the story or the offending source path, and `rcf coverage --with-code` to see whether the behaviour was ever covered at all.
|
|
425
|
+
1. **Reproduce, then trace the bug to its governing AC.** Which AC should have made the correct behaviour required? Walk the tree with `rcf audit trace` from the story or the offending source path, and `rcf audit coverage --with-code` to see whether the behaviour was ever covered at all.
|
|
426
426
|
2. **Name the gap.** Either no AC covers this scenario - the common case, usually a missing edge or failure path - or an AC covers it but too weakly (a happy-path AC where the bug lives in the failure path). Both are elicitation-depth misses; the standard for an adequate AC set is section 5 of the elicitation playbook.
|
|
427
|
-
3. **Fix the spec.** Add or strengthen the AC so the scenario is required (`rcf create ac` / `rcf update`), then add its TS/TC so the chain checks it. Now the tree would catch this class of bug on the next run.
|
|
427
|
+
3. **Fix the spec.** Add or strengthen the AC so the scenario is required (`rcf define create ac` / `rcf define update`), then add its TS/TC so the chain checks it. Now the tree would catch this class of bug on the next run.
|
|
428
428
|
4. **Fix the code against the corrected spec,** and prove it with the new test - the one that would have failed before your change and passes after it.
|
|
429
429
|
|
|
430
430
|
**Escalation:** if strengthening the AC changes agreed behaviour rather than closing an obvious gap, that is a spec decision, not a silent redraw. Surface it (section 8) before you change it. Tightening "returns an empty list on no match" onto an existing search AC is closing a gap; changing what the feature is supposed to do is a decision for the operator.
|
|
@@ -469,16 +469,16 @@ Both name the runtime, both refuse to imply the deployed profile, and both say p
|
|
|
469
469
|
|
|
470
470
|
## 16. In-loop fresh-context self-review
|
|
471
471
|
|
|
472
|
-
Self-verification is only as truthful as the runtime it verifies against, and a green suite plus a confident claim can still ship a user-facing defect. The independent verification gate is the durable answer to that, and it ships: `rcf finalise` runs the independent verifier against the deployed app and is the only thing that promotes an FBS from `complete` to `verified` (section 7). Nothing in this section changes that.
|
|
472
|
+
Self-verification is only as truthful as the runtime it verifies against, and a green suite plus a confident claim can still ship a user-facing defect. The independent verification gate is the durable answer to that, and it ships: `rcf build finalise` runs the independent verifier against the deployed app and is the only thing that promotes an FBS from `complete` to `verified` (section 7). Nothing in this section changes that.
|
|
473
473
|
|
|
474
474
|
What this section adds is the cheap check that runs **in the loop, between builds** - long before you reach the gate. Its value is finding the defect at FBS 6 instead of at the ship gate. It is subordinate to the gate, never a substitute for it, and it never writes `verified`.
|
|
475
475
|
|
|
476
476
|
- **What it is: a fresh-context reviewer dispatch, periodic and at the end.** Run a manual-review subagent in a fresh context **every few FBS builds** and **once more at the end of the build**. Fresh context matters: a reviewer carrying the build's own assumptions re-confirms them; a reviewer starting cold does not.
|
|
477
477
|
- **It drives the app, it does not read the code.** The reviewer starts the running application (the local preview is right there) and **drives it against the acceptance criteria** - exercises the real behaviour a user would - rather than reading the diff. Reading code re-checks intent; driving the app checks what was actually built.
|
|
478
478
|
- **It targets the defect classes green suites miss.** Name them for the reviewer: **session-class bugs** (state that leaks or resets across requests/sessions), **false-promise UI** (buttons and screens that imply an action the code never performs), **runtime mismatch** (passes on localhost, fails on the deployed runtime), **dead auth paths** (login/signup flows that never actually work end to end), and **dead code** (paths shipped but never reachable). These are exactly the classes a passing unit suite reports nothing about.
|
|
479
|
-
- **It is honestly scoped, and it is not the gate.** State plainly, every time: this is **an in-loop check, not the independent verification gate** - the gate is `rcf finalise` (section 7) - and it is **guidance and prompt-level, not a new subsystem**. A same-agent, same-programme reviewer is better than nothing and weaker than an independent check: worth running before the gate, not worth overclaiming after it. Say both. A self-review pass is never evidence for a `verified` mark; only the finalise gate produces that.
|
|
480
|
-
- **For UI-bearing FBSes, cross-reference to `rcf browser
|
|
481
|
-
- **Keep the review surface up across the pass.** `rcf view` gains `start | status | stop | logs` verbs and defaults to `--detach` on an interactive session (the pre-0.7.0 foreground default survives non-interactive callers, so CI scripts do not change behaviour). Start it once at the top of the loop; the supervisor persists across session death and the manifest carries `reviewSurface.viewServer` so a subsequent session can pick up where the last one left off. Explicit `rcf view stop` when the loop closes.
|
|
479
|
+
- **It is honestly scoped, and it is not the gate.** State plainly, every time: this is **an in-loop check, not the independent verification gate** - the gate is `rcf build finalise` (section 7) - and it is **guidance and prompt-level, not a new subsystem**. A same-agent, same-programme reviewer is better than nothing and weaker than an independent check: worth running before the gate, not worth overclaiming after it. Say both. A self-review pass is never evidence for a `verified` mark; only the finalise gate produces that.
|
|
480
|
+
- **For UI-bearing FBSes, cross-reference to `rcf verify browser`.** The in-loop reviewer's "drive the app against ACs" behaviour is a superset of what `rcf verify browser <fbs-id>` does (open every enumerated route on every declared theme, record the DOM, run the versioned invariant set, run the auth smoke pack). Reach for `rcf verify browser` first for uiBearing FBS: it writes a persisted `browserVerification[]` record on the manifest that the Stage 5 gate reads, and it names the exact invariants a passing browser check must satisfy. The self-review pass then adds the qualitative rubric on top (component consistency, typography, interaction affordances, modern-versus-dated feel) - the same rubric the browser-verify agent-mode critique carries on its record's `notes` field.
|
|
481
|
+
- **Keep the review surface up across the pass.** `rcf audit view` gains `start | status | stop | logs` verbs and defaults to `--detach` on an interactive session (the pre-0.7.0 foreground default survives non-interactive callers, so CI scripts do not change behaviour). Start it once at the top of the loop; the supervisor persists across session death and the manifest carries `reviewSurface.viewServer` so a subsequent session can pick up where the last one left off. Explicit `rcf audit view stop` when the loop closes.
|
|
482
482
|
|
|
483
483
|
## 17. Speaking to the operator
|
|
484
484
|
|
package/guidance/build-cycle.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# The RCF 5-stage build cycle
|
|
2
2
|
|
|
3
|
-
The normative statement of the cycle. Every FBS item is delivered by one pass of five stages, in this order, under these contracts. The spec bundle that `rcf build --next` emits carries the same cycle as its closing runbook, parameterised for the item in hand; if this page and a bundle ever disagree, the bundle is authoritative.
|
|
3
|
+
The normative statement of the cycle. Every FBS item is delivered by one pass of five stages, in this order, under these contracts. The spec bundle that `rcf build bundle --next` emits carries the same cycle as its closing runbook, parameterised for the item in hand; if this page and a bundle ever disagree, the bundle is authoritative.
|
|
4
4
|
|
|
5
5
|
## The five stages
|
|
6
6
|
|
|
7
7
|
**1. Define.**
|
|
8
|
-
Entry: you hold the item's spec bundle. Exit: your plan is confirmed against every in-scope acceptance criterion in the bundle's section 4, and pickup is recorded with `rcf build <fbs-id>
|
|
8
|
+
Entry: you hold the item's spec bundle. Exit: your plan is confirmed against every in-scope acceptance criterion in the bundle's section 4, and pickup is recorded with `rcf build mark <fbs-id> inProgress`. Referee: the bundle itself, plus `rcf define validate` on a clean tree.
|
|
9
9
|
|
|
10
10
|
**2. Build.**
|
|
11
|
-
Entry: a confirmed plan. Exit: the acceptance criteria are implemented, using the bundle's architectural context, with nothing beyond them; deviation from the bundle is escalation, not improvisation. Author or update Code Nodes (`rcf create cn --path <file>[#symbol] --acs <ac-ids>`) for the source as you write it - comprehension of which symbols serve which ACs is cheapest to capture now, and Stage 5 refuses completion without it. Referee: none at this stage beyond the bundle as the spec.
|
|
11
|
+
Entry: a confirmed plan. Exit: the acceptance criteria are implemented, using the bundle's architectural context, with nothing beyond them; deviation from the bundle is escalation, not improvisation. Author or update Code Nodes (`rcf define create cn --path <file>[#symbol] --acs <ac-ids>`) for the source as you write it - comprehension of which symbols serve which ACs is cheapest to capture now, and Stage 5 refuses completion without it. Referee: none at this stage beyond the bundle as the spec.
|
|
12
12
|
|
|
13
13
|
**3. Review.**
|
|
14
|
-
Entry: the implementation is complete. Exit: `rcf validate` comes back clean and the diff has been re-read against every in-scope acceptance criterion, with deviations documented. Referee: `rcf validate`.
|
|
14
|
+
Entry: the implementation is complete. Exit: `rcf define validate` comes back clean and the diff has been re-read against every in-scope acceptance criterion, with deviations documented. Referee: `rcf define validate`.
|
|
15
15
|
|
|
16
16
|
**4. Test.**
|
|
17
|
-
Entry: a reviewed diff. Exit: TS / TC documents and the tests they point to exist for the in-scope acceptance criteria, and `rcf coverage --strict` covers them - the referee checks the pointer, not just the row: a test case counts only when its `testPointer` resolves to a real test in the tree, and one that does not is reported as `covered-unresolved`, which fails the strict gate. Every "verified" or "tested" claim made in this stage names the runtime it was checked against and never implies verification on a deployed runtime that was not exercised. Referee: `rcf coverage --strict`.
|
|
17
|
+
Entry: a reviewed diff. Exit: TS / TC documents and the tests they point to exist for the in-scope acceptance criteria, and `rcf audit coverage --strict` covers them - the referee checks the pointer, not just the row: a test case counts only when its `testPointer` resolves to a real test in the tree, and one that does not is reported as `covered-unresolved`, which fails the strict gate. Every "verified" or "tested" claim made in this stage names the runtime it was checked against and never implies verification on a deployed runtime that was not exercised. Referee: `rcf audit coverage --strict`.
|
|
18
18
|
|
|
19
19
|
**5. Finalise.**
|
|
20
|
-
Entry: covered, reviewed work. Exit: CI green and the work merged per the driving workflow's convention, then `rcf build <fbs-id>
|
|
20
|
+
Entry: covered, reviewed work. Exit: CI green and the work merged per the driving workflow's convention, then `rcf build mark <fbs-id> complete` after the merge, and `verified` written by the finalise gate (`rcf build finalise <fbs-id> --url <deploy-url>`) once an independent post-merge verify run passes with ship authority. `--mark` caps at `complete` - it cannot write `verified`. `--mark complete` refuses (exit 3, missingCodeNodes) if any in-scope acceptance criterion still carries no Code Node - go back to Stage 2, or declare `--no-code-nodes` for a genuinely no-code spec. The PR body's verification section carries a runtime label on every claim. Referee: CI, the finalise gate, plus the mark commands' own refusals.
|
|
21
21
|
|
|
22
22
|
## Definition of done includes a working local preview
|
|
23
23
|
|
|
@@ -29,7 +29,7 @@ Each stage ends in a commit. The commit is the stage boundary: it makes the cycl
|
|
|
29
29
|
|
|
30
30
|
## The lifecycle is forward-only
|
|
31
31
|
|
|
32
|
-
`notStarted -> inProgress -> complete -> verified`. Forward jumps are legal, but the `--mark` ladder caps at `complete`: `--mark verified` is refused with exit 4 and points to `rcf finalise`, because `verified` is written only by the finalise gate after an independent verify run. Backward transitions are refused with exit 4; the deliberate-correction / manual-override escape hatch is `rcf update <fbs-id> --set executionStatus=<status>`, and reaching for it should be rare enough to be remarkable.
|
|
32
|
+
`notStarted -> inProgress -> complete -> verified`. Forward jumps are legal, but the `--mark` ladder caps at `complete`: `--mark verified` is refused with exit 4 and points to `rcf build finalise`, because `verified` is written only by the finalise gate after an independent verify run. Backward transitions are refused with exit 4; the deliberate-correction / manual-override escape hatch is `rcf define update <fbs-id> --set executionStatus=<status>`, and reaching for it should be rare enough to be remarkable.
|
|
33
33
|
|
|
34
34
|
## Depth
|
|
35
35
|
|
|
@@ -26,7 +26,7 @@ One page per document type, the reference rule that keeps the tree drift-proof,
|
|
|
26
26
|
|
|
27
27
|
**TC (Test Case).** One test: which AC it verifies, where the executable test lives (its test pointer), and its status.
|
|
28
28
|
|
|
29
|
-
**CN (Code Node).** The spec-to-code bridge: a working-tree source path, optionally `#symbol`-suffixed, that implements one or more acceptance criteria (`implementsAcIds`, which may be empty - an orphan CN is a legitimate state for utilities and glue code). `rcf validate` checks every CN's path/symbol against the working tree, so a rename or deletion that leaves the pointer dangling is caught the same way a broken spec-side reference is. Author CNs during Stage 2 of the build cycle (see below), not after: `rcf build
|
|
29
|
+
**CN (Code Node).** The spec-to-code bridge: a working-tree source path, optionally `#symbol`-suffixed, that implements one or more acceptance criteria (`implementsAcIds`, which may be empty - an orphan CN is a legitimate state for utilities and glue code). `rcf define validate` checks every CN's path/symbol against the working tree, so a rename or deletion that leaves the pointer dangling is caught the same way a broken spec-side reference is. Author CNs during Stage 2 of the build cycle (see below), not after: `rcf build mark <fbs-id> complete` refuses when an in-scope acceptance criterion has none. Full detail, including the honest limits, is `docs/code-nodes.md` in the rcf-build-lite repo.
|
|
30
30
|
|
|
31
31
|
## Edges live on the child
|
|
32
32
|
|