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.
Files changed (105) hide show
  1. package/CHANGELOG.md +95 -54
  2. package/README.md +8 -4
  3. package/bin/rcf.js +145 -57
  4. package/fixtures/canary-manifest.json +9 -9
  5. package/guidance/README.md +1 -1
  6. package/guidance/build-cycle-playbook.md +108 -51
  7. package/guidance/build-cycle.md +7 -7
  8. package/guidance/document-model.md +1 -1
  9. package/guidance/elicitation-playbook.md +29 -29
  10. package/guidance/harness-template.md +52 -10
  11. package/guidance/managed/README.md +1 -1
  12. package/guidance/managed/agent-instructions-block.hash +1 -1
  13. package/guidance/managed/agent-instructions-block.md +51 -9
  14. package/guidance/manifest.json +1 -1
  15. package/guidance/overview.md +4 -4
  16. package/package.json +4 -6
  17. package/rcf/adrs/adr-008.json +1 -1
  18. package/rcf/adrs/adr-009.json +4 -4
  19. package/rcf/code-nodes/cn-016.json +1 -1
  20. package/rcf/code-nodes/cn-019.json +1 -1
  21. package/rcf/code-nodes/cn-020.json +1 -1
  22. package/rcf/code-nodes/cn-021.json +1 -1
  23. package/rcf/code-nodes/cn-022.json +1 -1
  24. package/rcf/code-nodes/cn-049.json +1 -1
  25. package/rcf/code-nodes/cn-055.json +1 -1
  26. package/rcf/code-nodes/cn-057.json +5 -5
  27. package/rcf/code-nodes/cn-061.json +1 -1
  28. package/rcf/code-nodes/cn-066.json +1 -1
  29. package/rcf/code-nodes/cn-069.json +1 -1
  30. package/rcf/fbs/fbs-005.json +1 -1
  31. package/rcf/fbs/fbs-006.json +2 -2
  32. package/rcf/fbs/fbs-007.json +1 -1
  33. package/rcf/fbs/fbs-014.json +1 -1
  34. package/rcf/fbs/fbs-015.json +9 -8
  35. package/rcf/fbs/fbs-016.json +1 -1
  36. package/rcf/fbs/fbs-017.json +1 -1
  37. package/rcf/fbs/fbs-018.json +2 -2
  38. package/rcf/requirements/req-008.json +1 -1
  39. package/rcf/requirements/req-009.json +2 -2
  40. package/rcf/requirements/req-010.json +1 -1
  41. package/rcf/test-suites/PENDING.md +2 -2
  42. package/rcf/test-suites/ts-004.json +1 -1
  43. package/rcf/test-suites/ts-006.json +3 -3
  44. package/rcf/test-suites/ts-008.json +2 -2
  45. package/rcf/test-suites/ts-009.json +2 -2
  46. package/rcf/test-suites/ts-017.json +1 -1
  47. package/rcf/test-suites/ts-024.json +1 -1
  48. package/rcf/test-suites/ts-025.json +32 -18
  49. package/rcf/test-suites/ts-026.json +1 -1
  50. package/rcf/test-suites/ts-027.json +7 -7
  51. package/rcf/test-suites/ts-028.json +1 -1
  52. package/rcf/user-stories/us-1001.json +10 -10
  53. package/rcf/user-stories/us-1002.json +12 -12
  54. package/rcf/user-stories/us-1003.json +6 -6
  55. package/rcf/user-stories/us-805.json +2 -2
  56. package/rcf/user-stories/us-901.json +13 -13
  57. package/src/blueprint/conflicts.js +15 -15
  58. package/src/blueprint/supersede.js +6 -6
  59. package/src/build/bundle.js +3 -3
  60. package/src/build/formatters/markdown.js +9 -9
  61. package/src/build/mark.js +3 -3
  62. package/src/build/queue.js +1 -1
  63. package/src/cli/blueprint.js +3 -3
  64. package/src/cli/browser-verify.js +1 -1
  65. package/src/cli/build.js +139 -69
  66. package/src/cli/coverage.js +1 -1
  67. package/src/cli/create.js +3 -3
  68. package/src/cli/delete.js +2 -2
  69. package/src/cli/design.js +10 -10
  70. package/src/cli/fbs.js +1 -1
  71. package/src/cli/finalise.js +22 -20
  72. package/src/cli/help.js +267 -95
  73. package/src/cli/impact.js +1 -1
  74. package/src/cli/intake.js +3 -3
  75. package/src/cli/link.js +3 -3
  76. package/src/cli/preflight.js +2 -2
  77. package/src/cli/read.js +1 -1
  78. package/src/cli/req-baseline.js +2 -2
  79. package/src/cli/req-classify.js +3 -3
  80. package/src/cli/review.js +1 -1
  81. package/src/cli/standards.js +1 -1
  82. package/src/cli/test-suite.js +1 -1
  83. package/src/cli/trace.js +1 -1
  84. package/src/cli/ui-baseline.js +3 -3
  85. package/src/cli/ui-classify.js +4 -4
  86. package/src/cli/update.js +2 -2
  87. package/src/cli/validate.js +2 -2
  88. package/src/cli/view.js +12 -10
  89. package/src/core/store/writer.js +1 -1
  90. package/src/design/writer.js +3 -3
  91. package/src/finalise/detect.js +32 -38
  92. package/src/finalise/index.js +0 -1
  93. package/src/finalise/install.js +9 -8
  94. package/src/finalise/spawn.js +14 -10
  95. package/src/mcp/tools.js +1 -1
  96. package/src/req-baseline/gate.js +1 -1
  97. package/src/ui-baseline/manifest-writer.js +2 -2
  98. package/src/verify/cli/cleanup.js +1 -1
  99. package/src/verify/cli/mcp.js +1 -1
  100. package/src/verify/cli/provision.js +1 -1
  101. package/src/verify/cli/report.js +1 -1
  102. package/src/verify/cli/run.js +1 -1
  103. package/src/view-supervisor/manifest-writer.js +2 -2
  104. package/bin/rcf-verify.js +0 -122
  105. 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. Phase 4 §D1 / §D23: replaces the standalone
3
- // `bin/rcf-view.js` and adds init / validate / create / read / update /
4
- // delete / link / unlink / help subcommands. Zero external deps.
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: `rcf <subcommand> [args...]`. The first positional is
7
- // the subcommand; everything after is handed to that subcommand's
8
- // handler (`src/cli/<subcommand>.js`). Global `--version` and `--help`
9
- // short-circuit before dispatch.
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
- // 0.7.1 packaging consolidation: `rcf verify <verb>` routes through the
50
- // same dispatcher the `rcf-verify` alias bin exposes. One place to wire
51
- // the verify subcommands; two entry points.
52
- import { main as verifyMain } from './rcf-verify.js';
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
- export const SUBCOMMANDS = {
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
- preflight: preflightMain,
75
- review: reviewMain,
76
- fbs: fbsMain,
77
- 'test-suite': testSuiteMain,
78
- 'ui-classify': uiClassifyMain,
79
- 'ui-baseline': uiBaselineMain,
80
- design: designMain,
81
- 'browser-verify': browserVerifyMain,
82
- // Blueprint mechanism (Phase 1, w-2026-08-18-016).
83
- blueprint: blueprintMain,
84
- standards: standardsMain,
85
- // Track C+D (elicitation-and-playbook-hardening-0.7.0) verbs.
86
- 'req-classify': reqClassifyMain,
87
- 'req-baseline': reqBaselineMain,
88
- intake: intakeMain,
89
- // 0.7.1 packaging consolidation (R3, ratified 2026-08-06): the verify
90
- // suite lives under `rcf verify <run|report|provision|cleanup|mcp>`.
91
- // Dispatches to the same handlers as the `rcf-verify` alias bin.
92
- verify: verifyMain,
93
- help: helpMain,
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
- const handler = SUBCOMMANDS[first];
123
- if (!handler) {
124
- stderr.write(`[error] usage unknown subcommand: ${first}\n`);
125
- stderr.write(TOP_LEVEL_HELP);
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
- return await handler(argv.slice(1), deps);
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 fall back to the raw URL compare.
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 normalise both sides via realpath. Without this, macOS symlinks
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-25-001",
5
- "createdAt": "2026-08-25T14:47:32.185Z",
6
- "buildVersion": "0.9.0-mockdriver",
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-25-002",
38
- "createdAt": "2026-08-25T14:47:32.185Z",
39
- "buildVersion": "0.9.0-mockdriver",
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-25-003",
71
- "createdAt": "2026-08-25T14:47:32.185Z",
72
- "buildVersion": "0.9.0-mockdriver",
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": {
@@ -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.