rcf-lite 0.9.0 → 0.11.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 +95 -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 +108 -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 +52 -10
- package/guidance/managed/README.md +1 -1
- package/guidance/managed/agent-instructions-block.hash +1 -1
- package/guidance/managed/agent-instructions-block.md +51 -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
package/bin/rcf.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Unified `rcf` binary.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Unified `rcf` binary. 0.10.0 CLI reorganisation around the five RCF
|
|
3
|
+
// tool groups (discover, define, build, verify, audit) plus a small
|
|
4
|
+
// deliberately-named core set (init, doctor, guidance, mcp, help). The
|
|
5
|
+
// old flat 32-verb surface is a clean break: no aliases, no shims, no
|
|
6
|
+
// hidden legacy dispatch. Old flat forms exit 2 with a pointer at the
|
|
7
|
+
// new grouped form.
|
|
5
8
|
//
|
|
6
|
-
// Argv layout:
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
9
|
+
// Argv layout:
|
|
10
|
+
// `rcf <core-verb> [args...]` for core verbs (init, doctor,
|
|
11
|
+
// guidance, mcp, help)
|
|
12
|
+
// `rcf <group> <verb> [args...]` for grouped verbs
|
|
13
|
+
// Global `--version` and `--help` short-circuit before dispatch.
|
|
10
14
|
|
|
11
15
|
import { realpathSync } from 'node:fs';
|
|
12
16
|
import { readFile } from 'node:fs/promises';
|
|
@@ -21,7 +25,7 @@ import { main as deleteMain } from '../src/cli/delete.js';
|
|
|
21
25
|
import { main as doctorMain } from '../src/cli/doctor.js';
|
|
22
26
|
import { main as finaliseMain } from '../src/cli/finalise.js';
|
|
23
27
|
import { main as guidanceMain } from '../src/cli/guidance.js';
|
|
24
|
-
import { main as helpMain, TOP_LEVEL_HELP } from '../src/cli/help.js';
|
|
28
|
+
import { main as helpMain, TOP_LEVEL_HELP, GROUP_HELP, HELP_MAP } from '../src/cli/help.js';
|
|
25
29
|
import { main as impactMain } from '../src/cli/impact.js';
|
|
26
30
|
import { main as initMain } from '../src/cli/init.js';
|
|
27
31
|
import { main as linkMain } from '../src/cli/link.js';
|
|
@@ -36,61 +40,115 @@ import { main as uiBaselineMain } from '../src/cli/ui-baseline.js';
|
|
|
36
40
|
import { main as uiClassifyMain } from '../src/cli/ui-classify.js';
|
|
37
41
|
import { main as designMain } from '../src/cli/design.js';
|
|
38
42
|
import { main as browserVerifyMain } from '../src/cli/browser-verify.js';
|
|
39
|
-
// Blueprint mechanism (Phase 1, w-2026-08-18-016).
|
|
40
43
|
import { main as blueprintMain } from '../src/cli/blueprint.js';
|
|
41
44
|
import { main as standardsMain } from '../src/cli/standards.js';
|
|
42
45
|
import { main as updateMain } from '../src/cli/update.js';
|
|
43
46
|
import { main as validateMain } from '../src/cli/validate.js';
|
|
44
47
|
import { main as viewMain } from '../src/cli/view.js';
|
|
45
|
-
// Track C+D (elicitation-and-playbook-hardening-0.7.0) verbs.
|
|
46
48
|
import { main as reqClassifyMain } from '../src/cli/req-classify.js';
|
|
47
49
|
import { main as reqBaselineMain } from '../src/cli/req-baseline.js';
|
|
48
50
|
import { main as intakeMain } from '../src/cli/intake.js';
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
import { main as
|
|
51
|
+
|
|
52
|
+
// Verify group members are handled by the verify-suite dispatch tree.
|
|
53
|
+
import { main as verifyRunMain } from '../src/verify/cli/run.js';
|
|
54
|
+
import { main as verifyReportMain } from '../src/verify/cli/report.js';
|
|
55
|
+
import { main as verifyProvisionMain } from '../src/verify/cli/provision.js';
|
|
56
|
+
import { main as verifyCleanupMain } from '../src/verify/cli/cleanup.js';
|
|
57
|
+
import { main as verifyMcpMain } from '../src/verify/cli/mcp.js';
|
|
53
58
|
|
|
54
59
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
// Core verbs dispatch at the top level. Deliberately named set (spec
|
|
62
|
+
// §Core); NOT an "other" or "misc" bucket.
|
|
63
|
+
export const CORE = {
|
|
57
64
|
init: initMain,
|
|
58
|
-
view: viewMain,
|
|
59
|
-
validate: validateMain,
|
|
60
|
-
create: createMain,
|
|
61
|
-
read: readMain,
|
|
62
|
-
update: updateMain,
|
|
63
|
-
delete: deleteMain,
|
|
64
|
-
link: (argv, deps) => linkMain(argv, { ...deps, remove: false }),
|
|
65
|
-
unlink: (argv, deps) => linkMain(argv, { ...deps, remove: true }),
|
|
66
|
-
coverage: coverageMain,
|
|
67
|
-
trace: traceMain,
|
|
68
|
-
impact: impactMain,
|
|
69
|
-
build: buildMain,
|
|
70
|
-
finalise: finaliseMain,
|
|
71
65
|
doctor: doctorMain,
|
|
72
66
|
guidance: guidanceMain,
|
|
73
67
|
mcp: mcpMain,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
68
|
+
// help handled inline below (needs group context)
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Grouped verbs: two-level map (group -> verb -> handler). Rendering
|
|
72
|
+
// order in help output is fixed by the GROUP_ORDER export in help.js.
|
|
73
|
+
export const GROUPS = {
|
|
74
|
+
discover: {
|
|
75
|
+
intake: intakeMain,
|
|
76
|
+
preflight: preflightMain,
|
|
77
|
+
'req-classify': reqClassifyMain,
|
|
78
|
+
'req-baseline': reqBaselineMain,
|
|
79
|
+
'ui-classify': uiClassifyMain,
|
|
80
|
+
'ui-baseline': uiBaselineMain,
|
|
81
|
+
},
|
|
82
|
+
define: {
|
|
83
|
+
create: createMain,
|
|
84
|
+
read: readMain,
|
|
85
|
+
update: updateMain,
|
|
86
|
+
delete: deleteMain,
|
|
87
|
+
link: (argv, deps) => linkMain(argv, { ...deps, remove: false }),
|
|
88
|
+
unlink: (argv, deps) => linkMain(argv, { ...deps, remove: true }),
|
|
89
|
+
validate: validateMain,
|
|
90
|
+
design: designMain,
|
|
91
|
+
blueprint: blueprintMain,
|
|
92
|
+
standards: standardsMain,
|
|
93
|
+
},
|
|
94
|
+
build: {
|
|
95
|
+
// build sub-verbs are dispatched by build.js internally (queue |
|
|
96
|
+
// bundle | mark). finalise, review, fbs, test-suite are their own
|
|
97
|
+
// handlers.
|
|
98
|
+
queue: (argv, deps) => buildMain(['queue', ...argv], deps),
|
|
99
|
+
bundle: (argv, deps) => buildMain(['bundle', ...argv], deps),
|
|
100
|
+
mark: (argv, deps) => buildMain(['mark', ...argv], deps),
|
|
101
|
+
finalise: finaliseMain,
|
|
102
|
+
review: reviewMain,
|
|
103
|
+
fbs: fbsMain,
|
|
104
|
+
'test-suite': testSuiteMain,
|
|
105
|
+
},
|
|
106
|
+
verify: {
|
|
107
|
+
run: verifyRunMain,
|
|
108
|
+
report: verifyReportMain,
|
|
109
|
+
provision: verifyProvisionMain,
|
|
110
|
+
cleanup: verifyCleanupMain,
|
|
111
|
+
mcp: verifyMcpMain,
|
|
112
|
+
browser: browserVerifyMain,
|
|
113
|
+
},
|
|
114
|
+
audit: {
|
|
115
|
+
view: viewMain,
|
|
116
|
+
coverage: coverageMain,
|
|
117
|
+
trace: traceMain,
|
|
118
|
+
impact: impactMain,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Old flat verb surface -> new grouped form. Consulted only when a
|
|
123
|
+
// bare unknown top-level token matches one of these keys, to emit a
|
|
124
|
+
// helpful stderr hint before exiting 2. This is NOT a back-compat
|
|
125
|
+
// fallback: the invocation still fails.
|
|
126
|
+
const OLD_FLAT_MAP = {
|
|
127
|
+
intake: 'discover intake',
|
|
128
|
+
preflight: 'discover preflight',
|
|
129
|
+
'req-classify': 'discover req-classify',
|
|
130
|
+
'req-baseline': 'discover req-baseline',
|
|
131
|
+
'ui-classify': 'discover ui-classify',
|
|
132
|
+
'ui-baseline': 'discover ui-baseline',
|
|
133
|
+
create: 'define create',
|
|
134
|
+
read: 'define read',
|
|
135
|
+
update: 'define update',
|
|
136
|
+
delete: 'define delete',
|
|
137
|
+
link: 'define link',
|
|
138
|
+
unlink: 'define unlink',
|
|
139
|
+
validate: 'define validate',
|
|
140
|
+
design: 'define design',
|
|
141
|
+
blueprint: 'define blueprint',
|
|
142
|
+
standards: 'define standards',
|
|
143
|
+
finalise: 'build finalise',
|
|
144
|
+
review: 'build review',
|
|
145
|
+
fbs: 'build fbs',
|
|
146
|
+
'test-suite': 'build test-suite',
|
|
147
|
+
'browser-verify': 'verify browser',
|
|
148
|
+
view: 'audit view',
|
|
149
|
+
coverage: 'audit coverage',
|
|
150
|
+
trace: 'audit trace',
|
|
151
|
+
impact: 'audit impact',
|
|
94
152
|
};
|
|
95
153
|
|
|
96
154
|
/**
|
|
@@ -119,13 +177,45 @@ export async function main(argv, deps = {}) {
|
|
|
119
177
|
stdout.write(TOP_LEVEL_HELP);
|
|
120
178
|
return 0;
|
|
121
179
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
180
|
+
|
|
181
|
+
// Core verbs dispatch directly.
|
|
182
|
+
if (first === 'help') {
|
|
183
|
+
return await helpMain(argv.slice(1), deps);
|
|
184
|
+
}
|
|
185
|
+
const coreHandler = CORE[first];
|
|
186
|
+
if (coreHandler) {
|
|
187
|
+
return await coreHandler(argv.slice(1), deps);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Group dispatch.
|
|
191
|
+
const group = GROUPS[first];
|
|
192
|
+
if (group) {
|
|
193
|
+
const verb = argv[1];
|
|
194
|
+
if (!verb || verb === '--help' || verb === '-h') {
|
|
195
|
+
stdout.write(GROUP_HELP[first]);
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
const verbHandler = group[verb];
|
|
199
|
+
if (!verbHandler) {
|
|
200
|
+
stderr.write(`[error] usage unknown verb '${verb}' in group '${first}'.\n`);
|
|
201
|
+
stderr.write(GROUP_HELP[first]);
|
|
202
|
+
return 2;
|
|
203
|
+
}
|
|
204
|
+
return await verbHandler(argv.slice(2), deps);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Unknown top-level token. If it matches an old flat verb, name the
|
|
208
|
+
// new form in the error message; otherwise the generic usage error.
|
|
209
|
+
const oldForm = OLD_FLAT_MAP[first];
|
|
210
|
+
if (oldForm) {
|
|
211
|
+
stderr.write(
|
|
212
|
+
`[error] usage unknown top-level command '${first}'. `
|
|
213
|
+
+ `Try 'rcf ${oldForm}' (see 'rcf help').\n`,
|
|
214
|
+
);
|
|
126
215
|
return 2;
|
|
127
216
|
}
|
|
128
|
-
|
|
217
|
+
stderr.write(`[error] usage unknown command '${first}'. Try 'rcf help'.\n`);
|
|
218
|
+
return 2;
|
|
129
219
|
}
|
|
130
220
|
|
|
131
221
|
async function readPackageVersion() {
|
|
@@ -155,7 +245,7 @@ export function isSameEntryPoint(metaUrl, argvPath) {
|
|
|
155
245
|
const metaPath = fileURLToPath(metaUrl);
|
|
156
246
|
return realpathSync(metaPath) === realpathSync(argvPath);
|
|
157
247
|
} catch {
|
|
158
|
-
// realpath failed on one side
|
|
248
|
+
// realpath failed on one side - fall back to the raw URL compare.
|
|
159
249
|
try {
|
|
160
250
|
return metaUrl === pathToFileURL(argvPath).href;
|
|
161
251
|
} catch {
|
|
@@ -164,7 +254,7 @@ export function isSameEntryPoint(metaUrl, argvPath) {
|
|
|
164
254
|
}
|
|
165
255
|
}
|
|
166
256
|
|
|
167
|
-
// isMain gate
|
|
257
|
+
// isMain gate - normalise both sides via realpath. Without this, macOS symlinks
|
|
168
258
|
// like `/tmp` -> `/private/tmp` and every `npm link` / `pnpm link` shim break
|
|
169
259
|
// the compare and main() silently never runs. See BUG-001.
|
|
170
260
|
const isMain = process.argv[1] && isSameEntryPoint(import.meta.url, process.argv[1]);
|
|
@@ -172,8 +262,6 @@ if (isMain) {
|
|
|
172
262
|
main(process.argv.slice(2))
|
|
173
263
|
.then((code) => process.exit(code))
|
|
174
264
|
.catch((err) => {
|
|
175
|
-
// Exit 1 is the "unexpected" escape hatch (§D15). Stack is not
|
|
176
|
-
// suppressed even under --quiet - operator needs the raw failure.
|
|
177
265
|
process.stderr.write(`[rcf] unexpected failure: ${err.message}\n${err.stack}\n`);
|
|
178
266
|
process.exit(1);
|
|
179
267
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"registerCanary": [
|
|
3
3
|
{
|
|
4
|
-
"id": "rc-2026-08-
|
|
5
|
-
"createdAt": "2026-08-
|
|
6
|
-
"buildVersion": "0.
|
|
4
|
+
"id": "rc-2026-08-27-001",
|
|
5
|
+
"createdAt": "2026-08-27T14:25:40.313Z",
|
|
6
|
+
"buildVersion": "0.11.0-mockdriver",
|
|
7
7
|
"fixturePromptId": "canary-prompt-01",
|
|
8
8
|
"responseWordCount": 55,
|
|
9
9
|
"grades": {
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"id": "rc-2026-08-
|
|
38
|
-
"createdAt": "2026-08-
|
|
39
|
-
"buildVersion": "0.
|
|
37
|
+
"id": "rc-2026-08-27-002",
|
|
38
|
+
"createdAt": "2026-08-27T14:25:40.313Z",
|
|
39
|
+
"buildVersion": "0.11.0-mockdriver",
|
|
40
40
|
"fixturePromptId": "canary-prompt-02",
|
|
41
41
|
"responseWordCount": 55,
|
|
42
42
|
"grades": {
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
"id": "rc-2026-08-
|
|
71
|
-
"createdAt": "2026-08-
|
|
72
|
-
"buildVersion": "0.
|
|
70
|
+
"id": "rc-2026-08-27-003",
|
|
71
|
+
"createdAt": "2026-08-27T14:25:40.314Z",
|
|
72
|
+
"buildVersion": "0.11.0-mockdriver",
|
|
73
73
|
"fixturePromptId": "canary-prompt-03",
|
|
74
74
|
"responseWordCount": 55,
|
|
75
75
|
"grades": {
|
package/guidance/README.md
CHANGED
|
@@ -20,6 +20,6 @@ The playbooks are prompts (instructions to a model); the reference docs are reso
|
|
|
20
20
|
|
|
21
21
|
1. Install the package so the `rcf` binary and this pack are on hand.
|
|
22
22
|
2. Run `rcf init` in your project BEFORE starting the agent session - it scaffolds the tree, registers the MCP server in `.mcp.json` and writes the fragment from [harness-template.md](harness-template.md) into your project's CLAUDE.md and AGENTS.md (both, on a fresh project; an existing instructions file is refreshed in place). Manual paste of the fragment is the fallback for non-standard harnesses.
|
|
23
|
-
3. Start your agent session and have the agent run `rcf build --next`, executing the runbook the bundle prints.
|
|
23
|
+
3. Start your agent session and have the agent run `rcf build bundle --next`, executing the runbook the bundle prints.
|
|
24
24
|
|
|
25
25
|
That is the whole loop. The playbooks add depth when the agent needs it; the bundle's built-in runbook is enough to start.
|