rcf-lite 0.9.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 +86 -54
- package/README.md +8 -4
- package/bin/rcf.js +145 -57
- 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 +10 -10
- package/guidance/managed/README.md +1 -1
- package/guidance/managed/agent-instructions-block.hash +1 -1
- package/guidance/managed/agent-instructions-block.md +9 -9
- package/guidance/manifest.json +1 -1
- package/guidance/overview.md +4 -4
- package/package.json +4 -6
- package/rcf/adrs/adr-008.json +1 -1
- package/rcf/adrs/adr-009.json +4 -4
- 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-061.json +1 -1
- package/rcf/code-nodes/cn-066.json +1 -1
- package/rcf/code-nodes/cn-069.json +1 -1
- 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 +1 -1
- package/rcf/fbs/fbs-017.json +1 -1
- package/rcf/fbs/fbs-018.json +2 -2
- package/rcf/requirements/req-008.json +1 -1
- package/rcf/requirements/req-009.json +2 -2
- package/rcf/requirements/req-010.json +1 -1
- 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 +1 -1
- package/rcf/test-suites/ts-027.json +7 -7
- package/rcf/test-suites/ts-028.json +1 -1
- package/rcf/user-stories/us-1001.json +10 -10
- package/rcf/user-stories/us-1002.json +12 -12
- package/rcf/user-stories/us-1003.json +6 -6
- package/rcf/user-stories/us-805.json +2 -2
- package/rcf/user-stories/us-901.json +13 -13
- package/src/blueprint/conflicts.js +15 -15
- package/src/blueprint/supersede.js +6 -6
- package/src/build/bundle.js +3 -3
- package/src/build/formatters/markdown.js +9 -9
- package/src/build/mark.js +3 -3
- package/src/build/queue.js +1 -1
- package/src/cli/blueprint.js +3 -3
- 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 +3 -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 +267 -95
- package/src/cli/impact.js +1 -1
- 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 +1 -1
- 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/writer.js +1 -1
- 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/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
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
"version": "0.1.0",
|
|
6
6
|
"status": "draft",
|
|
7
7
|
"title": "Standards ingestion: reference by default, copy only when out of root",
|
|
8
|
-
"description": "Standards packs are per operator or organisation and register at `rcf init` (or later via `rcf standards add`). Manifest registration is authoritative. In-repo sources are referenced in place. Out-of-root sources are copied into `rcf/standards/<slug>/` so the tree remains portable. Provenance (personal vs corporate) is recorded per pack.",
|
|
8
|
+
"description": "Standards packs are per operator or organisation and register at `rcf init` (or later via `rcf define standards add`). Manifest registration is authoritative. In-repo sources are referenced in place. Out-of-root sources are copied into `rcf/standards/<slug>/` so the tree remains portable. Provenance (personal vs corporate) is recorded per pack.",
|
|
9
9
|
"asA": "operator on an RCF project",
|
|
10
10
|
"iWant": "to register standards packs against my project tree, referencing in place when the source is already inside the repo and copying into `rcf/standards/<slug>/` only when the source lives outside the project root",
|
|
11
11
|
"soThat": "duplication inside the repo is not accepted, portability across machines is preserved for external sources, and the manifest is the single source of truth for what standards apply",
|
|
12
12
|
"acceptanceCriteria": [
|
|
13
13
|
{
|
|
14
14
|
"id": "AC-1003-1",
|
|
15
|
-
"description": "`rcf standards add <path>` writes a manifest entry with the pack's id, slug, sourcePath, tag vocabulary, testsProvidedBy and provenance",
|
|
15
|
+
"description": "`rcf define standards add <path>` writes a manifest entry with the pack's id, slug, sourcePath, tag vocabulary, testsProvidedBy and provenance",
|
|
16
16
|
"given": "a project with no standards registered and a valid standards folder anywhere on disk",
|
|
17
|
-
"when": "`rcf standards add <path> --slug wsd-naming --tags naming,conventions --tests-provided-by agent --provenance corporate` runs",
|
|
17
|
+
"when": "`rcf define standards add <path> --slug wsd-naming --tags naming,conventions --tests-provided-by agent --provenance corporate` runs",
|
|
18
18
|
"then": "the manifest gains one `standards[]` entry with all named fields populated and validates against the schema",
|
|
19
19
|
"testable": true
|
|
20
20
|
},
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"id": "AC-1003-2",
|
|
23
23
|
"description": "In-repo sources are referenced in place; no copy is written",
|
|
24
24
|
"given": "a standards folder path inside the project root (e.g. `docs/standards/wsd-naming`)",
|
|
25
|
-
"when": "`rcf standards add` runs against it",
|
|
25
|
+
"when": "`rcf define standards add` runs against it",
|
|
26
26
|
"then": "the `sourcePath` records the in-repo path, `copyPath` is absent, and no file is written under `rcf/standards/`",
|
|
27
27
|
"testable": true
|
|
28
28
|
},
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"id": "AC-1003-3",
|
|
31
31
|
"description": "Out-of-root sources are mirrored into `rcf/standards/<slug>/` and `copyPath` records the mirror",
|
|
32
32
|
"given": "a standards folder path outside the project root (an absolute path pointing outside the repo)",
|
|
33
|
-
"when": "`rcf standards add` runs against it",
|
|
33
|
+
"when": "`rcf define standards add` runs against it",
|
|
34
34
|
"then": "the source is copied into `rcf/standards/<slug>/`, the manifest entry records the original `sourcePath` and the in-tree `copyPath`, and re-running the verb is idempotent (no double copy)",
|
|
35
35
|
"testable": true
|
|
36
36
|
},
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"id": "AC-1003-4",
|
|
39
39
|
"description": "The manifest.standards[] entry validates against the shipped schema (@stravica-ai/rcf-schemas standardsPackRecord)",
|
|
40
40
|
"given": "a manifest with one or more standards[] entries",
|
|
41
|
-
"when": "`rcf validate` runs",
|
|
41
|
+
"when": "`rcf define validate` runs",
|
|
42
42
|
"then": "the manifest validates without errors under the shipped schema",
|
|
43
43
|
"testable": true
|
|
44
44
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"createdAt": "2026-07-20T17:04:24.904Z",
|
|
3
3
|
"updatedAt": "2026-07-28T16:39:51.461Z",
|
|
4
|
-
"description": "The method carries guidance for a periodic and end-of-build fresh-context self-review that drives the app against its acceptance criteria to catch the defect classes green test suites miss, honestly scoped as an in-loop check subordinate to the independent verification gate that rcf finalise runs.",
|
|
4
|
+
"description": "The method carries guidance for a periodic and end-of-build fresh-context self-review that drives the app against its acceptance criteria to catch the defect classes green test suites miss, honestly scoped as an in-loop check subordinate to the independent verification gate that rcf build finalise runs.",
|
|
5
5
|
"asA": "non-coding product owner",
|
|
6
6
|
"iWant": "the build to include a periodic fresh look that actually drives the app against what it is supposed to do",
|
|
7
7
|
"soThat": "defects my passing tests miss are caught before I rely on the result",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"description": "The guidance scopes the self-review honestly as an in-loop check and not the independent gate",
|
|
42
42
|
"given": "the self-review guidance",
|
|
43
43
|
"when": "it frames the review",
|
|
44
|
-
"then": "it states plainly that this is an in-loop check and not the independent verification gate, names rcf finalise (section 7) as the gate, and says it is guidance and not a new subsystem",
|
|
44
|
+
"then": "it states plainly that this is an in-loop check and not the independent verification gate, names rcf build finalise (section 7) as the gate, and says it is guidance and not a new subsystem",
|
|
45
45
|
"testable": true
|
|
46
46
|
}
|
|
47
47
|
],
|
|
@@ -2,39 +2,39 @@
|
|
|
2
2
|
"usId": "US-901",
|
|
3
3
|
"prdId": "PRD-001",
|
|
4
4
|
"reqId": "REQ-009",
|
|
5
|
-
"title": "Route `rcf verify`
|
|
6
|
-
"description": "A consumer running the unified `rcf` CLI
|
|
5
|
+
"title": "Route the verify suite under the `rcf verify` group and delete the legacy alias bin",
|
|
6
|
+
"description": "A consumer running the unified `rcf` CLI reaches the adversarial ship-gate verifier as `rcf verify <verb>` (run | report | provision | cleanup | mcp | browser). The pre-0.10.0 standalone `rcf-verify` bin is deleted outright; the historical 0.7.1 transition-grace alias is gone. The old flat `rcf-verify <verb>` invocation form is not available at all; consumers scripting against it must move to `rcf verify <verb>`.",
|
|
7
7
|
"asA": "consumer of the RCF Lite CLI",
|
|
8
8
|
"iWant": "to invoke the verify suite as `rcf verify <verb>` inside the unified CLI",
|
|
9
9
|
"soThat": "verify sits inside the same verb space as the rest of the RCF chain and I only have to install one package",
|
|
10
10
|
"acceptanceCriteria": [
|
|
11
11
|
{
|
|
12
12
|
"id": "AC-901-1",
|
|
13
|
-
"description": "The `rcf` bin exposes `verify` as a top-level
|
|
13
|
+
"description": "The `rcf` bin exposes `verify` as a top-level group whose sub-verbs run | report | provision | cleanup | mcp | browser dispatch to the verify-suite handlers",
|
|
14
14
|
"given": "the unified `rcf` binary imported from bin/rcf.js",
|
|
15
|
-
"when": "`verify` is looked up on the top-level
|
|
16
|
-
"then": "the
|
|
15
|
+
"when": "`verify` is looked up on the top-level GROUPS map",
|
|
16
|
+
"then": "the sub-verb resolves to the corresponding main() from src/verify/cli/{run,report,provision,cleanup,mcp}.js or src/cli/browser-verify.js",
|
|
17
17
|
"testable": true
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
"id": "AC-901-2",
|
|
21
|
-
"description": "The top-level `rcf
|
|
21
|
+
"description": "The top-level `rcf help` output advertises the `verify` group with its sub-verbs",
|
|
22
22
|
"given": "the unified `rcf` binary",
|
|
23
23
|
"when": "`--help` or `help` runs",
|
|
24
|
-
"then": "the printed usage lists
|
|
24
|
+
"then": "the printed usage lists the verify group header with the sub-verb catalogue (run, report, provision, cleanup, mcp, browser)",
|
|
25
25
|
"testable": true
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"id": "AC-901-3",
|
|
29
|
-
"description": "The `rcf-verify`
|
|
30
|
-
"given": "
|
|
31
|
-
"when": "the
|
|
32
|
-
"then": "
|
|
29
|
+
"description": "The legacy standalone `rcf-verify` bin is deleted; invoking `rcf-verify <verb>` is not possible from an rcf-lite install, and calling any old flat top-level token via the umbrella `rcf` bin exits 2 with a stderr hint naming the new grouped form",
|
|
30
|
+
"given": "an installed rcf-lite@0.10.0",
|
|
31
|
+
"when": "the operator invokes `rcf <old-flat-verb>` where old-flat-verb is a pre-0.10.0 name (validate, coverage, browser-verify, ...)",
|
|
32
|
+
"then": "package.json:bin carries no `rcf-verify` entry, bin/rcf-verify.js does not exist in the package, and bin/rcf.js writes '[error] usage unknown top-level command <verb>. Try rcf <group> <verb>' to stderr and exits 2 (not a back-compat fallback)",
|
|
33
33
|
"testable": true
|
|
34
34
|
}
|
|
35
35
|
],
|
|
36
|
-
"version": "0.
|
|
36
|
+
"version": "0.2.0",
|
|
37
37
|
"status": "draft",
|
|
38
38
|
"createdAt": "2026-08-11T00:00:00Z",
|
|
39
|
-
"updatedAt": "2026-08-
|
|
39
|
+
"updatedAt": "2026-08-26T00:00:00Z"
|
|
40
40
|
}
|
|
@@ -45,8 +45,8 @@ import { matchingResolution } from './resolutions.js';
|
|
|
45
45
|
* )} Conflict
|
|
46
46
|
*
|
|
47
47
|
* `incoming.source` on the globalAdrTopic shape is the CLI-supplied
|
|
48
|
-
* source label the operator typed on `rcf blueprint add SRC`; the
|
|
49
|
-
* renderer inlines it into option 3 (`rcf blueprint supersede <topic>
|
|
48
|
+
* source label the operator typed on `rcf define blueprint add SRC`; the
|
|
49
|
+
* renderer inlines it into option 3 (`rcf define blueprint supersede <topic>
|
|
50
50
|
* --incoming <source>`) so the printed command is copy-paste-runnable
|
|
51
51
|
* verbatim from the refused-add state. Absent when the caller did not
|
|
52
52
|
* thread a source label (unit-test paths).
|
|
@@ -58,7 +58,7 @@ import { matchingResolution } from './resolutions.js';
|
|
|
58
58
|
* Optional `manifest` argument: when supplied and the manifest carries a
|
|
59
59
|
* matching entry in `manifest.resolutions[]`, the conflict is honoured
|
|
60
60
|
* (dropped from the returned list). Callers that want the raw shape
|
|
61
|
-
* (`rcf blueprint diff <topic>` needs to inspect both ADRs even when a
|
|
61
|
+
* (`rcf define blueprint diff <topic>` needs to inspect both ADRs even when a
|
|
62
62
|
* resolution exists) can pass `manifest: null` to bypass the honour step.
|
|
63
63
|
*
|
|
64
64
|
* @param {Array<{
|
|
@@ -203,7 +203,7 @@ export function renderConflictReport(conflicts) {
|
|
|
203
203
|
// Round-3 (Baz ruling): option 3 must be executable VERBATIM
|
|
204
204
|
// from this refused-add state. supersede accepts `--incoming
|
|
205
205
|
// <source>` and carries the SAME source path the operator just
|
|
206
|
-
// typed on `rcf blueprint add SRC`, so the printed command is
|
|
206
|
+
// typed on `rcf define blueprint add SRC`, so the printed command is
|
|
207
207
|
// copy-paste-runnable. Fall back to `<source>` only when the
|
|
208
208
|
// caller did not thread the source label onto the conflict
|
|
209
209
|
// (unit-test paths that call renderConflictReport directly).
|
|
@@ -212,15 +212,15 @@ export function renderConflictReport(conflicts) {
|
|
|
212
212
|
: '<source>';
|
|
213
213
|
lines.push(' resolutions (pick one, honest options only):');
|
|
214
214
|
lines.push(` 1. Adopt the incoming blueprint. Run:`);
|
|
215
|
-
lines.push(` rcf blueprint remove ${c.existing.slug}`);
|
|
216
|
-
lines.push(` then re-run \`rcf blueprint add ${sourceLabel}\`.`);
|
|
215
|
+
lines.push(` rcf define blueprint remove ${c.existing.slug}`);
|
|
216
|
+
lines.push(` then re-run \`rcf define blueprint add ${sourceLabel}\`.`);
|
|
217
217
|
lines.push(` 2. Keep the existing blueprint. Do not add ${c.incoming.slug} on this project.`);
|
|
218
218
|
lines.push(` 3. Author a project-level ADR that supersedes both. Run:`);
|
|
219
|
-
lines.push(` rcf blueprint supersede ${c.topic} --incoming ${sourceLabel}`);
|
|
219
|
+
lines.push(` rcf define blueprint supersede ${c.topic} --incoming ${sourceLabel}`);
|
|
220
220
|
lines.push(` which scaffolds the project ADR (both blueprint ADRs listed as superseded)`);
|
|
221
|
-
lines.push(` and registers the resolution in the manifest, then re-run \`rcf blueprint add ${sourceLabel}\`.`);
|
|
221
|
+
lines.push(` and registers the resolution in the manifest, then re-run \`rcf define blueprint add ${sourceLabel}\`.`);
|
|
222
222
|
lines.push(` 4. Declare the resolution on the add itself:`);
|
|
223
|
-
lines.push(` rcf blueprint add ${sourceLabel} --resolve ${c.topic}=project:<ADR-id>`);
|
|
223
|
+
lines.push(` rcf define blueprint add ${sourceLabel} --resolve ${c.topic}=project:<ADR-id>`);
|
|
224
224
|
lines.push(` which records the resolution and skips the remove/re-add ceremony.`);
|
|
225
225
|
} else if (c.kind === 'crossBlueprintOwnership') {
|
|
226
226
|
lines.push(`conflict on id ${c.id}:`);
|
|
@@ -229,7 +229,7 @@ export function renderConflictReport(conflicts) {
|
|
|
229
229
|
lines.push('');
|
|
230
230
|
lines.push(' resolutions (pick one, honest options only):');
|
|
231
231
|
lines.push(` 1. Adopt the incoming blueprint. Run:`);
|
|
232
|
-
lines.push(` rcf blueprint remove ${c.existing.slug}`);
|
|
232
|
+
lines.push(` rcf define blueprint remove ${c.existing.slug}`);
|
|
233
233
|
lines.push(` then re-run the incoming add.`);
|
|
234
234
|
lines.push(` 2. Keep the existing blueprint. Do not add ${c.incoming.slug} on this project.`);
|
|
235
235
|
lines.push(` 3. Fix the incoming blueprint's contribution ids (author-side change);`);
|
|
@@ -280,7 +280,7 @@ export function conflictReportJson(conflicts) {
|
|
|
280
280
|
{
|
|
281
281
|
id: 'adoptIncoming',
|
|
282
282
|
description: `Adopt the incoming blueprint (${c.incoming.slug}); remove the existing (${c.existing.slug}).`,
|
|
283
|
-
commands: [`rcf blueprint remove ${c.existing.slug}`, `rcf blueprint add ${sourceLabel}`],
|
|
283
|
+
commands: [`rcf define blueprint remove ${c.existing.slug}`, `rcf define blueprint add ${sourceLabel}`],
|
|
284
284
|
},
|
|
285
285
|
{
|
|
286
286
|
id: 'keepExisting',
|
|
@@ -290,12 +290,12 @@ export function conflictReportJson(conflicts) {
|
|
|
290
290
|
{
|
|
291
291
|
id: 'supersede',
|
|
292
292
|
description: `Author a project-level ADR that supersedes both blueprint ADRs on topic '${c.topic}'.`,
|
|
293
|
-
commands: [`rcf blueprint supersede ${c.topic} --incoming ${sourceLabel}`, `rcf blueprint add ${sourceLabel}`],
|
|
293
|
+
commands: [`rcf define blueprint supersede ${c.topic} --incoming ${sourceLabel}`, `rcf define blueprint add ${sourceLabel}`],
|
|
294
294
|
},
|
|
295
295
|
{
|
|
296
296
|
id: 'declareOnAdd',
|
|
297
297
|
description: `Declare the resolution on the incoming add itself.`,
|
|
298
|
-
commands: [`rcf blueprint add ${sourceLabel} --resolve ${c.topic}=project:<ADR-id>`],
|
|
298
|
+
commands: [`rcf define blueprint add ${sourceLabel} --resolve ${c.topic}=project:<ADR-id>`],
|
|
299
299
|
},
|
|
300
300
|
],
|
|
301
301
|
};
|
|
@@ -310,7 +310,7 @@ export function conflictReportJson(conflicts) {
|
|
|
310
310
|
{
|
|
311
311
|
id: 'adoptIncoming',
|
|
312
312
|
description: `Adopt the incoming blueprint (${c.incoming.slug}); remove the existing (${c.existing.slug}).`,
|
|
313
|
-
commands: [`rcf blueprint remove ${c.existing.slug}`],
|
|
313
|
+
commands: [`rcf define blueprint remove ${c.existing.slug}`],
|
|
314
314
|
},
|
|
315
315
|
{
|
|
316
316
|
id: 'keepExisting',
|
|
@@ -343,7 +343,7 @@ function pruneAdrRef(side) {
|
|
|
343
343
|
if (typeof side.title === 'string' && side.title.length > 0) out.title = side.title;
|
|
344
344
|
if (typeof side.decision === 'string' && side.decision.length > 0) out.decision = side.decision;
|
|
345
345
|
// Round-3: the incoming side may also carry `source` (the CLI arg
|
|
346
|
-
// to `rcf blueprint add SRC`); surface it on --json so agent-driven
|
|
346
|
+
// to `rcf define blueprint add SRC`); surface it on --json so agent-driven
|
|
347
347
|
// composition has the same copy-paste-runnable command the terminal
|
|
348
348
|
// renderer produces.
|
|
349
349
|
if (typeof side.source === 'string' && side.source.length > 0) out.source = side.source;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `rcf blueprint supersede <topic> [--incoming <source>]` implementation.
|
|
1
|
+
// `rcf define blueprint supersede <topic> [--incoming <source>]` implementation.
|
|
2
2
|
//
|
|
3
3
|
// Scaffolds a project-level ADR at `rcf/adrs/adr-NNN-<kebab-topic>.json`
|
|
4
4
|
// that supersedes the CONFLICT PAIR on the topic (one currently-applied
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
// blueprint's scope:global ADR — Baz ruling, w-2026-08-19-008 round 3),
|
|
7
7
|
// and appends a matching `manifest.resolutions[]` record so the conflict
|
|
8
8
|
// detector honours the resolution when the operator re-runs
|
|
9
|
-
// `rcf blueprint add <incoming source>`.
|
|
9
|
+
// `rcf define blueprint add <incoming source>`.
|
|
10
10
|
//
|
|
11
11
|
// The `incomingSource` argument (mapped to `--incoming <source>` on the
|
|
12
12
|
// CLI) is REQUIRED when the applied-blueprints count on the topic is
|
|
13
13
|
// < 2, and silently accepted (informational) when it is already >= 2.
|
|
14
14
|
// This is what makes option 3 as printed by the reshaped conflict
|
|
15
15
|
// message executable VERBATIM from the refused-add state: the operator
|
|
16
|
-
// runs `rcf blueprint supersede <topic> --incoming <source>` immediately
|
|
16
|
+
// runs `rcf define blueprint supersede <topic> --incoming <source>` immediately
|
|
17
17
|
// after the refused add, with zero prep; the verb loads the incoming
|
|
18
18
|
// blueprint from disk, finds its scope:global ADR on <topic>, stamps
|
|
19
19
|
// the id into the incoming blueprint's namespace, and uses that
|
|
@@ -85,7 +85,7 @@ export async function supersedeBlueprintTopic({ projectRoot, tree, topic, incomi
|
|
|
85
85
|
if (typeof topic !== 'string' || topic.trim().length === 0) {
|
|
86
86
|
// Schema minLength:1 accepts whitespace-only; the writer refuses
|
|
87
87
|
// it up-front so a whitespace-only topic never lands on disk.
|
|
88
|
-
return rcfError({ kind: 'usage', message: `topic is required (e.g. rcf blueprint supersede errorEnvelope --incoming ./blueprints/rest)` });
|
|
88
|
+
return rcfError({ kind: 'usage', message: `topic is required (e.g. rcf define blueprint supersede errorEnvelope --incoming ./blueprints/rest)` });
|
|
89
89
|
}
|
|
90
90
|
// Topic is a LOOKUP KEY into applied ADR topics, not a slug (ADR-010).
|
|
91
91
|
// Schema is minLength:1 with no character constraint and the schema
|
|
@@ -161,7 +161,7 @@ export async function supersedeBlueprintTopic({ projectRoot, tree, topic, incomi
|
|
|
161
161
|
if (supersedes.length < 2) {
|
|
162
162
|
return rcfError({
|
|
163
163
|
kind: 'usage',
|
|
164
|
-
message: `topic '${topic}' has ${supersedes.length} scope:global ADR(s) across applied+incoming; at least two are required for a supersession record. If the incoming blueprint has not been named, add \`--incoming <source>\` (the same source you passed to \`rcf blueprint add\`).`,
|
|
164
|
+
message: `topic '${topic}' has ${supersedes.length} scope:global ADR(s) across applied+incoming; at least two are required for a supersession record. If the incoming blueprint has not been named, add \`--incoming <source>\` (the same source you passed to \`rcf define blueprint add\`).`,
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -198,7 +198,7 @@ export async function supersedeBlueprintTopic({ projectRoot, tree, topic, incomi
|
|
|
198
198
|
title: `Project ruling on ${topic} (supersedes ${supersedes.length} blueprint ADR${supersedes.length === 1 ? '' : 's'})`,
|
|
199
199
|
context: `Two or more applied blueprints each contributed a scope:global ADR on the '${topic}' topic: ${superseededSlugs}. Composition of these blueprints on one project needs a single project-level decision on ${topic}; the blueprint ADRs are retained on disk as superseded history.`,
|
|
200
200
|
decision: `Adopt a project-level ruling on ${topic}. This ADR is the live decision; the blueprint ADRs listed under relatedAdrs are superseded and their content stands as historical context only.`,
|
|
201
|
-
consequences: `The blueprint conflict on topic '${topic}' is honoured via manifest.resolutions[]. Any future blueprint added with a scope:global ADR on '${topic}' must be listed on the resolution (or a fresh resolution must be recorded) before rcf blueprint add proceeds.`,
|
|
201
|
+
consequences: `The blueprint conflict on topic '${topic}' is honoured via manifest.resolutions[]. Any future blueprint added with a scope:global ADR on '${topic}' must be listed on the resolution (or a fresh resolution must be recorded) before rcf define blueprint add proceeds.`,
|
|
202
202
|
...(relatedAdrs.length > 0 ? { relatedAdrs } : {}),
|
|
203
203
|
createdAt: isoNow,
|
|
204
204
|
updatedAt: isoNow,
|
package/src/build/bundle.js
CHANGED
|
@@ -195,9 +195,9 @@ export function assembleBundle(tree, { fbsId }) {
|
|
|
195
195
|
|
|
196
196
|
// Section 7 - completion contract (static, parameterised by fbsId).
|
|
197
197
|
const completionContract = {
|
|
198
|
-
markInProgress: `rcf build ${fbsId}
|
|
199
|
-
markComplete: `rcf build ${fbsId}
|
|
200
|
-
finalise: `rcf finalise ${fbsId} --url <deploy-url>`,
|
|
198
|
+
markInProgress: `rcf build mark ${fbsId} inProgress`,
|
|
199
|
+
markComplete: `rcf build mark ${fbsId} complete`,
|
|
200
|
+
finalise: `rcf build finalise ${fbsId} --url <deploy-url>`,
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
const result = {
|
|
@@ -326,7 +326,7 @@ function pushArchitecturalContext(lines, bundle) {
|
|
|
326
326
|
|
|
327
327
|
function pushTestSurface(lines, bundle) {
|
|
328
328
|
lines.push(`## ${SECTION_NUMBERS.testSurface}. Existing test surface`, '');
|
|
329
|
-
lines.push('Presence reporting off the tree, not a coverage verdict (`rcf coverage` is the coverage surface).', '');
|
|
329
|
+
lines.push('Presence reporting off the tree, not a coverage verdict (`rcf audit coverage` is the coverage surface).', '');
|
|
330
330
|
for (const entry of bundle.tests) {
|
|
331
331
|
if (!entry.covered && entry.suites.length === 0) {
|
|
332
332
|
lines.push(`- ${entry.acId}: no existing tests - test suite to be written for this AC`);
|
|
@@ -366,7 +366,7 @@ function pushRunbook(lines, bundle) {
|
|
|
366
366
|
lines.push('architectural context above ARE the definition. Confirm your plan against');
|
|
367
367
|
lines.push(`every in-scope acceptance criterion (${acIds}) in section 4 before writing`);
|
|
368
368
|
lines.push('code, then mark pickup:', '');
|
|
369
|
-
lines.push(` rcf build ${fbsId}
|
|
369
|
+
lines.push(` rcf build mark ${fbsId} inProgress`, '');
|
|
370
370
|
lines.push('Commit any plan artefacts the driving workflow requires.', '');
|
|
371
371
|
|
|
372
372
|
lines.push('### Stage 2 - Build', '');
|
|
@@ -374,14 +374,14 @@ function pushRunbook(lines, bundle) {
|
|
|
374
374
|
lines.push('context in section 5. The bundle is the spec: deviation is escalation to');
|
|
375
375
|
lines.push('the operator of the loop, not improvisation. As you implement, author or');
|
|
376
376
|
lines.push('update Code Nodes for the source you write:', '');
|
|
377
|
-
lines.push(' rcf create cn --path <file>[#symbol] --acs <ac-ids>', '');
|
|
377
|
+
lines.push(' rcf define create cn --path <file>[#symbol] --acs <ac-ids>', '');
|
|
378
378
|
lines.push('Do this now, not as an afterthought: comprehension of which symbols serve');
|
|
379
379
|
lines.push('which acceptance criteria is cheapest to capture while you are writing the');
|
|
380
380
|
lines.push('code, and Stage 5 refuses completion without it. Commit at stage end.', '');
|
|
381
381
|
|
|
382
382
|
lines.push('### Stage 3 - Review', '');
|
|
383
383
|
lines.push('Mechanical referee pass:', '');
|
|
384
|
-
lines.push(' rcf validate', '');
|
|
384
|
+
lines.push(' rcf define validate', '');
|
|
385
385
|
lines.push('must come back clean; then re-read the diff against every in-scope');
|
|
386
386
|
lines.push('acceptance criterion and document any deviations. Commit.', '');
|
|
387
387
|
|
|
@@ -389,18 +389,18 @@ function pushRunbook(lines, bundle) {
|
|
|
389
389
|
lines.push('Exercise every in-scope acceptance criterion: write or extend the TS / TC');
|
|
390
390
|
lines.push('documents (section 6 lists the existing surface and the flagged gaps) and');
|
|
391
391
|
lines.push('the tests they point to, until:', '');
|
|
392
|
-
lines.push(' rcf coverage --strict', '');
|
|
392
|
+
lines.push(' rcf audit coverage --strict', '');
|
|
393
393
|
lines.push('covers the in-scope acceptance criteria. Commit.', '');
|
|
394
394
|
|
|
395
395
|
lines.push('### Stage 5 - Finalise', '');
|
|
396
396
|
lines.push('CI green; PR raised and merged per the driving workflow\'s convention.');
|
|
397
397
|
lines.push('After the merge:', '');
|
|
398
|
-
lines.push(` rcf build ${fbsId}
|
|
398
|
+
lines.push(` rcf build mark ${fbsId} complete`, '');
|
|
399
399
|
lines.push('This refuses (exit 3, missingCodeNodes) if any in-scope acceptance');
|
|
400
400
|
lines.push('criterion still carries no Code Node - go back to Stage 2 and author it,');
|
|
401
401
|
lines.push('or, for a genuinely no-code spec (docs-only, config-only), declare:', '');
|
|
402
|
-
lines.push(` rcf build ${fbsId}
|
|
403
|
-
lines.push('Then ship-gate the deployed app - an independent
|
|
402
|
+
lines.push(` rcf build mark ${fbsId} complete --no-code-nodes`, '');
|
|
403
|
+
lines.push('Then ship-gate the deployed app - an independent verify run that');
|
|
404
404
|
lines.push('passes with ship authority promotes complete -> verified:', '');
|
|
405
|
-
lines.push(` rcf finalise ${fbsId} --url <deploy-url>`);
|
|
405
|
+
lines.push(` rcf build finalise ${fbsId} --url <deploy-url>`);
|
|
406
406
|
}
|
package/src/build/mark.js
CHANGED
|
@@ -85,8 +85,8 @@ export function planMark(tree, { fbsId, status }) {
|
|
|
85
85
|
noOp: false,
|
|
86
86
|
refused: true,
|
|
87
87
|
message: `build: refusing --mark verified on ${fbsId}; 'verified' is written only by the `
|
|
88
|
-
+ `independent verify gate, not by --mark. Promote it with: rcf finalise ${fbsId} --url <deploy-url>. `
|
|
89
|
-
+ `For a deliberate manual override (no verify run) use: rcf update ${fbsId} --set executionStatus=verified`,
|
|
88
|
+
+ `independent verify gate, not by --mark. Promote it with: rcf build finalise ${fbsId} --url <deploy-url>. `
|
|
89
|
+
+ `For a deliberate manual override (no verify run) use: rcf define update ${fbsId} --set executionStatus=verified`,
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
const fromIndex = LIFECYCLE.indexOf(from);
|
|
@@ -102,7 +102,7 @@ export function planMark(tree, { fbsId, status }) {
|
|
|
102
102
|
noOp: false,
|
|
103
103
|
refused: true,
|
|
104
104
|
message: `build: refusing backward transition ${from} -> ${status} on ${fbsId}; `
|
|
105
|
-
+ `for a deliberate correction use: rcf update ${fbsId} --set executionStatus=${status}`,
|
|
105
|
+
+ `for a deliberate correction use: rcf define update ${fbsId} --set executionStatus=${status}`,
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
return { fbsId, from, to: status, noOp: false };
|
package/src/build/queue.js
CHANGED
|
@@ -134,7 +134,7 @@ function findCycleMembers(fbsById) {
|
|
|
134
134
|
* any item whose chain reaches one, gets tier null (no defined chain
|
|
135
135
|
* length) - the walk short-circuits there, so a cyclic graph can never
|
|
136
136
|
* loop it. A dependency id that resolves to no FBS contributes chain
|
|
137
|
-
* length 0 (same as the platform port; `rcf validate` is the
|
|
137
|
+
* length 0 (same as the platform port; `rcf define validate` is the
|
|
138
138
|
* broken-reference surface).
|
|
139
139
|
*
|
|
140
140
|
* @param {Map<string, object>} fbsById
|
package/src/cli/blueprint.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from '../blueprint/index.js';
|
|
24
24
|
import { conflictReportJson, renderConflictReport } from '../blueprint/conflicts.js';
|
|
25
25
|
|
|
26
|
-
export const HELP = `Usage: rcf blueprint <verb> [options]
|
|
26
|
+
export const HELP = `Usage: rcf define blueprint <verb> [options]
|
|
27
27
|
|
|
28
28
|
Verbs:
|
|
29
29
|
add <source> Apply a blueprint from a source directory
|
|
@@ -43,7 +43,7 @@ Verbs:
|
|
|
43
43
|
--incoming <source>), and record a
|
|
44
44
|
manifest.resolutions[] entry so the conflict
|
|
45
45
|
detector honours the resolution when the
|
|
46
|
-
operator re-runs \`rcf blueprint add <source>\`.
|
|
46
|
+
operator re-runs \`rcf define blueprint add <source>\`.
|
|
47
47
|
--incoming is required when the topic has fewer
|
|
48
48
|
than two applied scope:global ADRs (the
|
|
49
49
|
refused-add state) and is silently accepted
|
|
@@ -82,7 +82,7 @@ Composition and namespacing:
|
|
|
82
82
|
REQ / US / PRD / BS / TAD / TS: slug PREFIX (spa-REQ-001).
|
|
83
83
|
ADR / TAC / FBS / CN: slug SUFFIX (ADR-005-spa).
|
|
84
84
|
Two blueprints both contributing a scope:global ADR on the same topic
|
|
85
|
-
is a genuine conflict: rcf blueprint add refuses and prints both
|
|
85
|
+
is a genuine conflict: rcf define blueprint add refuses and prints both
|
|
86
86
|
sides, plus four resolution paths (adopt incoming, keep existing,
|
|
87
87
|
supersede via project ADR, or declare on the add itself via
|
|
88
88
|
--resolve).
|
|
@@ -43,7 +43,7 @@ const OPTION_SPEC = {
|
|
|
43
43
|
help: { type: 'boolean' },
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
export const HELP = `Usage: rcf
|
|
46
|
+
export const HELP = `Usage: rcf verify browser <fbs-id> [options]
|
|
47
47
|
|
|
48
48
|
Stage 5 browser-verification gate for a UI-bearing FBS. Writes a
|
|
49
49
|
browserVerification record on the manifest; the finalise gate reads it.
|