@warpgogol/forge 5.3.4 → 6.2.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 (253) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/bin/cli.ts +7 -2
  3. package/dist/bin/cli.js +7 -2
  4. package/dist/bin/cli.js.map +1 -1
  5. package/dist/os/adr/adr.module.d.ts.map +1 -1
  6. package/dist/os/adr/adr.module.js +2 -0
  7. package/dist/os/adr/adr.module.js.map +1 -1
  8. package/dist/os/audit/audit.module.d.ts.map +1 -1
  9. package/dist/os/audit/audit.module.js +2 -0
  10. package/dist/os/audit/audit.module.js.map +1 -1
  11. package/dist/os/compass/compass.module.d.ts.map +1 -1
  12. package/dist/os/compass/compass.module.js +47 -15
  13. package/dist/os/compass/compass.module.js.map +1 -1
  14. package/dist/os/compass/handlers/compass-audit-handler.d.ts +2 -0
  15. package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
  16. package/dist/os/compass/handlers/compass-audit-handler.js +40 -10
  17. package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
  18. package/dist/os/compass/handlers/compass-docs-validate.d.ts +13 -0
  19. package/dist/os/compass/handlers/compass-docs-validate.d.ts.map +1 -0
  20. package/dist/os/compass/handlers/compass-docs-validate.js +328 -0
  21. package/dist/os/compass/handlers/compass-docs-validate.js.map +1 -0
  22. package/dist/os/compass/handlers/summary-record.d.ts +11 -2
  23. package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
  24. package/dist/os/compass/handlers/summary-record.js +95 -15
  25. package/dist/os/compass/handlers/summary-record.js.map +1 -1
  26. package/dist/os/core/core.module.d.ts.map +1 -1
  27. package/dist/os/core/core.module.js +124 -73
  28. package/dist/os/core/core.module.js.map +1 -1
  29. package/dist/os/core/handlers/file-size-lint.d.ts.map +1 -1
  30. package/dist/os/core/handlers/file-size-lint.js +2 -0
  31. package/dist/os/core/handlers/file-size-lint.js.map +1 -1
  32. package/dist/os/exploration/exploration.module.d.ts.map +1 -1
  33. package/dist/os/exploration/exploration.module.js +3 -0
  34. package/dist/os/exploration/exploration.module.js.map +1 -1
  35. package/dist/os/naming/naming-convention.d.ts.map +1 -1
  36. package/dist/os/naming/naming-convention.js +11 -1
  37. package/dist/os/naming/naming-convention.js.map +1 -1
  38. package/dist/os/naming/naming.module.d.ts.map +1 -1
  39. package/dist/os/naming/naming.module.js +9 -2
  40. package/dist/os/naming/naming.module.js.map +1 -1
  41. package/dist/os/notes/notes.module.d.ts.map +1 -1
  42. package/dist/os/notes/notes.module.js +17 -6
  43. package/dist/os/notes/notes.module.js.map +1 -1
  44. package/dist/os/plan/plan.module.d.ts.map +1 -1
  45. package/dist/os/plan/plan.module.js +2 -0
  46. package/dist/os/plan/plan.module.js.map +1 -1
  47. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  48. package/dist/os/plugin/plugin.module.js +9 -2
  49. package/dist/os/plugin/plugin.module.js.map +1 -1
  50. package/dist/os/program/program.module.d.ts.map +1 -1
  51. package/dist/os/program/program.module.js +19 -4
  52. package/dist/os/program/program.module.js.map +1 -1
  53. package/dist/os/queue/handlers/queue-validate.d.ts.map +1 -1
  54. package/dist/os/queue/handlers/queue-validate.js +154 -7
  55. package/dist/os/queue/handlers/queue-validate.js.map +1 -1
  56. package/dist/os/queue/manifest.d.ts +17 -1
  57. package/dist/os/queue/manifest.d.ts.map +1 -1
  58. package/dist/os/queue/manifest.js +127 -6
  59. package/dist/os/queue/manifest.js.map +1 -1
  60. package/dist/os/queue/queue.module.d.ts.map +1 -1
  61. package/dist/os/queue/queue.module.js +32 -4
  62. package/dist/os/queue/queue.module.js.map +1 -1
  63. package/dist/os/queue/types.d.ts +100 -1
  64. package/dist/os/queue/types.d.ts.map +1 -1
  65. package/dist/os/queue/types.js +44 -0
  66. package/dist/os/queue/types.js.map +1 -1
  67. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  68. package/dist/os/rfc/handlers/implement-stamp.js +30 -8
  69. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  70. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  71. package/dist/os/rfc/rfc.module.js +25 -6
  72. package/dist/os/rfc/rfc.module.js.map +1 -1
  73. package/dist/os/rfc/types.d.ts +12 -2
  74. package/dist/os/rfc/types.d.ts.map +1 -1
  75. package/dist/os/rfc/types.js +2 -2
  76. package/dist/os/rfc/types.js.map +1 -1
  77. package/dist/os/rfc/verification-evidence.d.ts +21 -0
  78. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  79. package/dist/os/rfc/verification-evidence.js +134 -23
  80. package/dist/os/rfc/verification-evidence.js.map +1 -1
  81. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  82. package/dist/os/rfc/verification-refresh.js +66 -37
  83. package/dist/os/rfc/verification-refresh.js.map +1 -1
  84. package/dist/os/session/handlers/save.d.ts.map +1 -1
  85. package/dist/os/session/handlers/save.js +42 -5
  86. package/dist/os/session/handlers/save.js.map +1 -1
  87. package/dist/os/session/session.module.d.ts.map +1 -1
  88. package/dist/os/session/session.module.js +5 -0
  89. package/dist/os/session/session.module.js.map +1 -1
  90. package/dist/os/spec/live-spec-merge.d.ts.map +1 -1
  91. package/dist/os/spec/live-spec-merge.js +55 -134
  92. package/dist/os/spec/live-spec-merge.js.map +1 -1
  93. package/dist/os/spec/live-spec-rebuild.d.ts +32 -0
  94. package/dist/os/spec/live-spec-rebuild.d.ts.map +1 -0
  95. package/dist/os/spec/live-spec-rebuild.js +272 -0
  96. package/dist/os/spec/live-spec-rebuild.js.map +1 -0
  97. package/dist/os/spec/live-spec-shared.d.ts +62 -0
  98. package/dist/os/spec/live-spec-shared.d.ts.map +1 -0
  99. package/dist/os/spec/live-spec-shared.js +315 -0
  100. package/dist/os/spec/live-spec-shared.js.map +1 -0
  101. package/dist/os/spec/live-spec-types.d.ts +17 -1
  102. package/dist/os/spec/live-spec-types.d.ts.map +1 -1
  103. package/dist/os/spec/live-spec-types.js +3 -0
  104. package/dist/os/spec/live-spec-types.js.map +1 -1
  105. package/dist/os/spec/live-spec-validate.d.ts.map +1 -1
  106. package/dist/os/spec/live-spec-validate.js +105 -2
  107. package/dist/os/spec/live-spec-validate.js.map +1 -1
  108. package/dist/os/spec/spec-materialize.d.ts +2 -0
  109. package/dist/os/spec/spec-materialize.d.ts.map +1 -1
  110. package/dist/os/spec/spec-materialize.js +45 -5
  111. package/dist/os/spec/spec-materialize.js.map +1 -1
  112. package/dist/os/spec/spec-schema.d.ts +19 -0
  113. package/dist/os/spec/spec-schema.d.ts.map +1 -1
  114. package/dist/os/spec/spec-schema.js +30 -0
  115. package/dist/os/spec/spec-schema.js.map +1 -1
  116. package/dist/os/spec/spec-status.d.ts +4 -0
  117. package/dist/os/spec/spec-status.d.ts.map +1 -1
  118. package/dist/os/spec/spec-status.js +19 -1
  119. package/dist/os/spec/spec-status.js.map +1 -1
  120. package/dist/os/spec/spec-validate.d.ts.map +1 -1
  121. package/dist/os/spec/spec-validate.js +55 -8
  122. package/dist/os/spec/spec-validate.js.map +1 -1
  123. package/dist/os/spec/spec.module.d.ts.map +1 -1
  124. package/dist/os/spec/spec.module.js +84 -8
  125. package/dist/os/spec/spec.module.js.map +1 -1
  126. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  127. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +10 -4
  128. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  129. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  130. package/dist/os/werkstatt/werkstatt.module.js +13 -4
  131. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  132. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  133. package/dist/os/workflow/workflow.module.js +13 -5
  134. package/dist/os/workflow/workflow.module.js.map +1 -1
  135. package/dist/src/cli-flags.d.ts.map +1 -1
  136. package/dist/src/cli-flags.js +25 -5
  137. package/dist/src/cli-flags.js.map +1 -1
  138. package/dist/src/config/forge-config.d.ts +3 -0
  139. package/dist/src/config/forge-config.d.ts.map +1 -1
  140. package/dist/src/config/forge-config.js +2 -0
  141. package/dist/src/config/forge-config.js.map +1 -1
  142. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  143. package/dist/src/onboarding/doctor.js +2 -3
  144. package/dist/src/onboarding/doctor.js.map +1 -1
  145. package/dist/src/onboarding/init.d.ts.map +1 -1
  146. package/dist/src/onboarding/init.js +8 -3
  147. package/dist/src/onboarding/init.js.map +1 -1
  148. package/dist/src/pipeline-status.d.ts +14 -1
  149. package/dist/src/pipeline-status.d.ts.map +1 -1
  150. package/dist/src/pipeline-status.js +28 -8
  151. package/dist/src/pipeline-status.js.map +1 -1
  152. package/dist/src/types.d.ts +7 -1
  153. package/dist/src/types.d.ts.map +1 -1
  154. package/dist/src/types.js +6 -0
  155. package/dist/src/types.js.map +1 -1
  156. package/dist/src/utils/generated-marker.d.ts +8 -0
  157. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  158. package/dist/src/utils/generated-marker.js +25 -0
  159. package/dist/src/utils/generated-marker.js.map +1 -1
  160. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  161. package/dist/src/validators/skill-validate.js +2 -4
  162. package/dist/src/validators/skill-validate.js.map +1 -1
  163. package/os/adr/adr.module.ts +2 -0
  164. package/os/audit/audit.module.ts +2 -0
  165. package/os/compass/compass.module.ts +49 -15
  166. package/os/compass/handlers/compass-audit-handler.ts +51 -10
  167. package/os/compass/handlers/compass-docs-validate.ts +361 -0
  168. package/os/compass/handlers/summary-record.ts +106 -15
  169. package/os/compass/handlers/tests/compass-audit-record.test.ts +2 -1
  170. package/os/compass/handlers/tests/compass-audit-validate.test.ts +92 -3
  171. package/os/compass/handlers/tests/compass-docs-validate.test.ts +203 -0
  172. package/os/compass/handlers/tests/compass-ledger-scope.test.ts +2 -1
  173. package/os/compass/handlers/tests/compass-policy.test.ts +7 -1
  174. package/os/compass/handlers/tests/summary-record.test.ts +127 -0
  175. package/os/core/core.module.ts +147 -75
  176. package/os/core/docs-archive.test.ts +136 -0
  177. package/os/core/handlers/file-size-lint.ts +2 -0
  178. package/os/exploration/exploration.module.ts +3 -0
  179. package/os/naming/naming-convention.ts +11 -1
  180. package/os/naming/naming.module.ts +9 -2
  181. package/os/notes/notes.module.ts +17 -6
  182. package/os/plan/plan-0000-template.md +150 -0
  183. package/os/plan/plan.module.ts +2 -0
  184. package/os/plugin/plugin.module.ts +9 -2
  185. package/os/program/program.module.ts +19 -4
  186. package/os/queue/decision-ledger.test.ts +163 -0
  187. package/os/queue/handlers/queue-validate.ts +190 -8
  188. package/os/queue/manifest.ts +201 -7
  189. package/os/queue/queue-validate.test.ts +303 -0
  190. package/os/queue/queue.module.ts +32 -4
  191. package/os/queue/types.ts +56 -1
  192. package/os/rfc/handlers/implement-stamp.ts +37 -8
  193. package/os/rfc/rfc-read-only-no-side-effects.test.ts +1 -0
  194. package/os/rfc/rfc.module.ts +27 -6
  195. package/os/rfc/types.ts +18 -3
  196. package/os/rfc/verification-emit.test.ts +305 -0
  197. package/os/rfc/verification-evidence.ts +149 -24
  198. package/os/rfc/verification-refresh.test.ts +222 -1
  199. package/os/rfc/verification-refresh.ts +74 -38
  200. package/os/session/handlers/save.ts +37 -5
  201. package/os/session/session.module.ts +5 -0
  202. package/os/spec/live-spec-idempotency.pbt.test.ts +222 -0
  203. package/os/spec/live-spec-list-show-validate.test.ts +10 -6
  204. package/os/spec/live-spec-merge.test.ts +187 -7
  205. package/os/spec/live-spec-merge.ts +71 -155
  206. package/os/spec/live-spec-rebuild.test.ts +317 -0
  207. package/os/spec/live-spec-rebuild.ts +356 -0
  208. package/os/spec/live-spec-shared.ts +378 -0
  209. package/os/spec/live-spec-types.ts +21 -1
  210. package/os/spec/live-spec-validate.test.ts +317 -0
  211. package/os/spec/live-spec-validate.ts +106 -2
  212. package/os/spec/spec-materialize.test.ts +192 -0
  213. package/os/spec/spec-materialize.ts +48 -4
  214. package/os/spec/spec-schema.ts +49 -0
  215. package/os/spec/spec-status.ts +24 -0
  216. package/os/spec/spec-validate.test.ts +66 -0
  217. package/os/spec/spec-validate.ts +62 -8
  218. package/os/spec/spec.module.ts +85 -8
  219. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +10 -4
  220. package/os/werkstatt/werkstatt.module.ts +13 -4
  221. package/os/workflow/workflow.module.ts +13 -5
  222. package/package.json +1 -1
  223. package/skills/_shared/fo-pipeline-conventions.md +126 -1
  224. package/skills/fo/fo-doc-audit/SKILL.md +4 -4
  225. package/skills/fo/fo-explore/SKILL.md +2 -1
  226. package/skills/fo/fo-fix/SKILL.md +11 -3
  227. package/skills/fo/fo-handoff/SKILL.md +4 -6
  228. package/skills/fo/fo-idea-create-rfc/SKILL.md +2 -1
  229. package/skills/fo/fo-idea-enhance/SKILL.md +23 -4
  230. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +86 -22
  231. package/skills/fo/fo-idea-implement/SKILL.md +53 -10
  232. package/skills/fo/fo-idea-plan/SKILL.md +28 -6
  233. package/skills/fo/fo-review/SKILL.md +69 -8
  234. package/skills/fo/fo-session-retro/SKILL.md +3 -2
  235. package/skills/fo/fo-step-commit/SKILL.md +2 -0
  236. package/skills/shared/grilling/SKILL.md +12 -0
  237. package/skills/shared/writing-great-skills/GLOSSARY.md +2 -0
  238. package/skills/shared/writing-great-skills/SKILL.md +2 -1
  239. package/src/cli-flags.ts +23 -5
  240. package/src/config/forge-config.ts +4 -0
  241. package/src/onboarding/doctor.ts +2 -3
  242. package/src/onboarding/init.ts +8 -3
  243. package/src/pipeline-status.ts +32 -8
  244. package/src/tests/cli-flags.test.ts +20 -0
  245. package/src/tests/cli-output.test.ts +13 -7
  246. package/src/tests/fixtures/agents-generate-business-before.txt +7 -7
  247. package/src/tests/implement-stamp.test.ts +38 -0
  248. package/src/tests/session-handlers.test.ts +33 -0
  249. package/src/types.ts +13 -1
  250. package/src/utils/generated-marker.ts +28 -0
  251. package/src/validators/skill-validate.ts +2 -4
  252. package/skills/fo/fo-idea-implement/ADR-FLOW.md +0 -179
  253. package/skills/fo/fo-review/AXES.md +0 -70
@@ -6,16 +6,17 @@
6
6
  </non-goals>
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
- <item>RFC-1089: rename forge.file-size.lint to file.size.lint (domain validator, no forge. prefix).</item>
10
- <item>RFC-1097: step 6 — compass.migrate codemod run
9
+ <item>RFC-1230: docs.archive post-loop merges only RFCs moved this run (collectLiveMergeTargets on rfc.archive moved[] instead of a full-tree rescan); declared docs/specs/live/*.md in writes/reads.</item>
10
+ <item>RFC-1230: review findings — scoped droppedSections to namespaced headings, warn on unreadable spec, fail-fast merge on corrupt frontmatter, CHANGE_SUMMARY dedupe</item>
11
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
11
12
 
12
- Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order.</item>
13
- <item>RFC-1097: sweep — packages/forge + services clean
14
-
15
- Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PURPOSE-02), headers on mission/index + gen-upstreams, sanitizeItemText in summary.record (literal Compass tags corrupted history), excludedPaths for wrangler types, test-fixtures testPattern. forge+services now 0 diagnostics under --mode error.</item>
16
- <item>RFC-1173: declare mutatesState on all kernel commands — collectDeclarationDiagnostics emits error-severity MUTATES-STATE-DECLARED, command.manifest.validate is the blocking consumer in packages.check, sweep declares the flag on every command definition (factories hardcode false for read-only check specs)</item>
17
- <item>RFC-1173: fixup: flip mutatesState to true on 19 commands that declare writes/generates — the codemod's name-suffix rules misclassified leitstand.dev-deploy, leitstand.certify, coverage.report and peers as read-only; declared writes imply mutation</item>
18
- <history>ADR-0021, RFC-0374, RFC-0521, RFC-0539, RFC-0542, RFC-0543, RFC-0544, RFC-0546, RFC-0640, RFC-0662, RFC-0674, RFC-0678, RFC-0679, RFC-0680, RFC-0711, RFC-0733, RFC-0877, RFC-0940, RFC-1080, RFC-1088</history>
13
+ Mechanical sweep: the field only ever gated --all argv acceptance; fan-out
14
+ follows the parsed selector. Guard renamed assertAllSitesAllowed ->
15
+ assertAllFlagAccepted, message updated. 417 declaration sites + type
16
+ surfaces (KernelCommandMetadata, ForgeCommandMetadata) in one atomic pass.</item>
17
+ <item>RFC-1235: docs.archive post-loop records merge outcomes by exit code — exit-nonzero merges (incl. RFC-1230 fail-fast with populated data) land in failed[] with the merge summary as error, thrown errors record via liveMergeFailureEntry, and the spec.live.merge result block emits whenever anything was attempted; top-level result gains liveSpecFailures.</item>
18
+ <item>RFC-1248: VITE-CLIENT-DEP-02 lazy-import gate + SCAN-02 validator reads-root existence check (RFC-1248)</item>
19
+ <history>ADR-0021, RFC-0374, RFC-0521, RFC-0539, RFC-0542, RFC-0543, RFC-0544, RFC-0546, RFC-0640, RFC-0662, RFC-0674, RFC-0678, RFC-0679, RFC-0680, RFC-0711, RFC-0733, RFC-0877, RFC-0940, RFC-1080, RFC-1088, RFC-1089, RFC-1097, RFC-1173</history>
19
20
  </CHANGE_SUMMARY>
20
21
  */
21
22
 
@@ -218,7 +219,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
218
219
  generates: [],
219
220
  description: "Diagnose forge state in an existing project.",
220
221
  scope: "workspace",
221
- supportsAllSites: false,
222
+ acceptsAllFlag: false,
222
223
  flags: {
223
224
  strict: {
224
225
  kind: "boolean",
@@ -234,10 +235,11 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
234
235
  },
235
236
  {
236
237
  name: "forge.port.scaffold",
238
+ coverage: "operator" as const,
237
239
  mutatesState: true,
238
240
  description: "Generate a skeleton for a new forge skill or command.",
239
241
  scope: "workspace",
240
- supportsAllSites: false,
242
+ acceptsAllFlag: false,
241
243
  flags: {
242
244
  name: { kind: "string", description: "Skill or command name (kebab-case)." },
243
245
  type: { kind: "string", description: "Type: 'skill' or 'command' (default: skill)." },
@@ -253,30 +255,33 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
253
255
  description:
254
256
  "Validate all forge skills against frontmatter contract and invariants SKILL-01..SKILL-20.",
255
257
  scope: "workspace",
256
- supportsAllSites: false,
258
+ acceptsAllFlag: false,
257
259
  flags: {},
258
260
  reads: ["packages/forge/src/**/*.ts", "packages/forge/os/**/*.ts"],
259
261
  execute: skillValidateWrapper,
260
262
  },
261
263
  {
262
264
  name: "forge.skill.list",
265
+ coverage: "operator" as const,
263
266
  mutatesState: false,
264
267
  description: "List all registered forge skills.",
265
268
  scope: "workspace",
266
- supportsAllSites: false,
269
+ acceptsAllFlag: false,
267
270
  flags: {},
268
271
  reads: ["packages/forge/src/registry.ts"],
269
272
  execute: skillListWrapper,
270
273
  },
271
274
  {
272
275
  name: "forge.port.validate",
276
+ coverage: "operator" as const,
277
+ coverageNote: "requires --name",
273
278
  mutatesState: false,
274
279
  contract: "forge",
275
280
  rules: [],
276
281
  description:
277
282
  "Validate a single ported skill or command for compliance with forge contracts.",
278
283
  scope: "workspace",
279
- supportsAllSites: false,
284
+ acceptsAllFlag: false,
280
285
  flags: {
281
286
  name: { kind: "string", description: "Skill or command name to validate." },
282
287
  },
@@ -285,11 +290,12 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
285
290
  },
286
291
  {
287
292
  name: "forge.agents.generate",
293
+ coverage: "operator" as const,
288
294
  mutatesState: true,
289
295
  description:
290
296
  "Regenerate AGENTS.md deterministically from forge.yaml and the skill registry.",
291
297
  scope: "workspace",
292
- supportsAllSites: false,
298
+ acceptsAllFlag: false,
293
299
  flags: {},
294
300
  writes: ["AGENTS.md", "**/AGENTS.md"],
295
301
  generates: [],
@@ -298,11 +304,13 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
298
304
  },
299
305
  {
300
306
  name: "memory.compact",
307
+ coverage: "operator" as const,
308
+ coverageNote: "agent memory compaction",
301
309
  mutatesState: true,
302
310
  description:
303
311
  "Enforce the MEMORY.md character budget by removing oldest Environment notes bullets (RFC-1151).",
304
312
  scope: "workspace",
305
- supportsAllSites: false,
313
+ acceptsAllFlag: false,
306
314
  flags: {},
307
315
  cacheable: false,
308
316
  execute: runMemoryCompact,
@@ -313,7 +321,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
313
321
  description:
314
322
  "Additive sync for npm consumers: refresh .agents/skills/ from installed forge, add missing binding defaults, update forge.syncedVersion, run doctor.",
315
323
  scope: "workspace",
316
- supportsAllSites: false,
324
+ acceptsAllFlag: false,
317
325
  flags: {
318
326
  "dry-run": {
319
327
  kind: "boolean",
@@ -333,11 +341,12 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
333
341
  },
334
342
  {
335
343
  name: "forge.scaffold",
344
+ coverage: "operator" as const,
336
345
  mutatesState: true,
337
346
  description:
338
347
  "Create a working pnpm + Turborepo monorepo from a stack profile in an empty directory. Required flags: `--profile`, `--name`.",
339
348
  scope: "workspace",
340
- supportsAllSites: false,
349
+ acceptsAllFlag: false,
341
350
  flags: {
342
351
  profile: {
343
352
  kind: "string",
@@ -360,7 +369,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
360
369
  description:
361
370
  "Create a forge project in-place: scaffold + init + binding defaults. The target directory must be empty (only .git/ tolerated). Usage: forge create --in-place --profile <profile-id> [--name <name>] [--package-manager pnpm]",
362
371
  scope: "workspace",
363
- supportsAllSites: false,
372
+ acceptsAllFlag: false,
364
373
  flags: {
365
374
  "in-place": {
366
375
  kind: "boolean",
@@ -396,7 +405,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
396
405
  description:
397
406
  "Deploy forge into a project: create forge.yaml, PREFERENCES.md, copy skills, create docs dirs. Hidden recovery command — normally called by forge.create.",
398
407
  scope: "workspace",
399
- supportsAllSites: false,
408
+ acceptsAllFlag: false,
400
409
  hidden: true,
401
410
  flags: {
402
411
  "ai-language": {
@@ -420,7 +429,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
420
429
  description:
421
430
  "Validate profile YAML files under packages/forge/profiles/ against the stack-profile schema (RFC-0640).",
422
431
  scope: "workspace",
423
- supportsAllSites: false,
432
+ acceptsAllFlag: false,
424
433
  flags: {
425
434
  id: {
426
435
  kind: "string",
@@ -433,11 +442,12 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
433
442
  },
434
443
  {
435
444
  name: "forge.dev",
445
+ coverage: "operator" as const,
436
446
  mutatesState: true,
437
447
  description:
438
448
  "Start the dev/preview server declared in the active stack profile. Use --dry-run to print the resolved command without executing.",
439
449
  scope: "workspace",
440
- supportsAllSites: false,
450
+ acceptsAllFlag: false,
441
451
  longRunning: true,
442
452
  flags: {
443
453
  "dry-run": {
@@ -455,11 +465,12 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
455
465
  },
456
466
  {
457
467
  name: "forge.build",
468
+ coverage: "operator" as const,
458
469
  mutatesState: true,
459
470
  description:
460
471
  "Execute produce commands for all artifacts declared in the active stack profile. Use --dry-run to print resolved commands.",
461
472
  scope: "workspace",
462
- supportsAllSites: false,
473
+ acceptsAllFlag: false,
463
474
  flags: {
464
475
  "dry-run": {
465
476
  kind: "boolean",
@@ -476,13 +487,15 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
476
487
  },
477
488
  {
478
489
  name: "forge.validate",
490
+ coverage: "operator" as const,
491
+ coverageNote: "artifact validator — typescript profile declares no artifacts by design",
479
492
  mutatesState: false,
480
493
  contract: "forge",
481
494
  rules: [],
482
495
  description:
483
496
  "Execute validate commands for all artifacts declared in the active stack profile. Use --dry-run to print resolved commands. Use --artifact to validate a single artifact.",
484
497
  scope: "workspace",
485
- supportsAllSites: false,
498
+ acceptsAllFlag: false,
486
499
  flags: {
487
500
  "dry-run": {
488
501
  kind: "boolean",
@@ -503,13 +516,15 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
503
516
  },
504
517
  {
505
518
  name: "forge.determinism.check",
519
+ coverage: "operator" as const,
520
+ coverageNote: "forge determinism audit",
506
521
  mutatesState: true,
507
522
  contract: "forge",
508
523
  rules: [],
509
524
  description:
510
525
  "Verify artifact determinism by building twice and comparing output hashes. Reads determinism.inputs glob patterns from the active stack profile. Use --dry-run to print resolved inputs, --artifact to check a single artifact.",
511
526
  scope: "workspace",
512
- supportsAllSites: false,
527
+ acceptsAllFlag: false,
513
528
  flags: {
514
529
  "dry-run": {
515
530
  kind: "boolean",
@@ -524,19 +539,21 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
524
539
  description: "Check only the specified artifact id.",
525
540
  },
526
541
  },
527
- reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "dist/.determinism-cache.json"],
528
- writes: ["dist/.determinism-cache.json"],
542
+ reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "dist/.determinism-cache.json"], // scan-coverage: post-build artifact — dist/ exists only after forge build
543
+ writes: ["dist/.determinism-cache.json"], // scan-coverage: post-build artifact — dist/ exists only after forge build
529
544
  generates: [],
530
545
  cacheable: false,
531
546
  execute: runDeterminismCheck,
532
547
  },
533
548
  {
534
549
  name: "forge.assets.list",
550
+ coverage: "operator" as const,
551
+ coverageNote: "asset listing for asset-declaring forge profiles",
535
552
  mutatesState: false,
536
553
  description:
537
554
  "List all assets declared in the active stack profile, grouped by type. Use --dry-run to skip hashing, --type to filter by asset type.",
538
555
  scope: "workspace",
539
- supportsAllSites: false,
556
+ acceptsAllFlag: false,
540
557
  flags: {
541
558
  "dry-run": {
542
559
  kind: "boolean",
@@ -551,19 +568,21 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
551
568
  description: "Filter assets by type id (e.g. video, audio, image).",
552
569
  },
553
570
  },
554
- reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "assets/**"],
571
+ reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "assets/**"], // scan-coverage: consumer-workshop root — assets/ declared by stack profiles
555
572
  cacheable: false,
556
573
  execute: runAssetsList,
557
574
  },
558
575
  {
559
576
  name: "forge.assets.check",
577
+ coverage: "operator" as const,
578
+ coverageNote: "asset check for asset-declaring forge profiles",
560
579
  mutatesState: false,
561
580
  contract: "forge",
562
581
  rules: [],
563
582
  description:
564
583
  "Check for missing, orphaned, and unreferenced assets. Use --strict to fail on orphaned assets, --dry-run to skip hashing.",
565
584
  scope: "workspace",
566
- supportsAllSites: false,
585
+ acceptsAllFlag: false,
567
586
  flags: {
568
587
  "dry-run": {
569
588
  kind: "boolean",
@@ -578,17 +597,19 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
578
597
  description: "Override the active profile id.",
579
598
  },
580
599
  },
581
- reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "assets/**"],
600
+ reads: ["forge.yaml", "packages/forge/profiles/*.yaml", "assets/**"], // scan-coverage: consumer-workshop root — assets/ declared by stack profiles
582
601
  cacheable: false,
583
602
  execute: runAssetsCheck,
584
603
  },
585
604
  {
586
605
  name: "forge.release.prepare",
606
+ coverage: "operator" as const,
607
+ coverageNote: "forge release front door",
587
608
  mutatesState: true,
588
609
  description:
589
610
  "Bundle built artifacts into a release package with a manifest. Use --dry-run to preview without writing.",
590
611
  scope: "workspace",
591
- supportsAllSites: false,
612
+ acceptsAllFlag: false,
592
613
  flags: {
593
614
  "dry-run": {
594
615
  kind: "boolean",
@@ -607,11 +628,13 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
607
628
  },
608
629
  {
609
630
  name: "forge.release.publish",
631
+ coverage: "operator" as const,
632
+ coverageNote: "forge release publish step",
610
633
  mutatesState: true,
611
634
  description:
612
635
  "Publish a prepared release to the declared target (local, R2, S3). Use --dry-run to preview without uploading.",
613
636
  scope: "workspace",
614
- supportsAllSites: false,
637
+ acceptsAllFlag: false,
615
638
  flags: {
616
639
  "dry-run": {
617
640
  kind: "boolean",
@@ -630,12 +653,13 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
630
653
  },
631
654
  {
632
655
  name: "forge.skill.knowledge.compact",
656
+ coverage: "operator" as const,
633
657
  mutatesState: true,
634
658
  description:
635
659
  "Compact skill knowledge files: archive expired/superseded/aged L0 entries, mark stale L2 principles. " +
636
660
  "Usage: forge.skill.knowledge.compact --all-skills [--dry-run] [--json] | --skill <name> [--dry-run] [--json]",
637
661
  scope: "workspace",
638
- supportsAllSites: false,
662
+ acceptsAllFlag: false,
639
663
  flags: {
640
664
  skill: {
641
665
  kind: "string",
@@ -677,6 +701,8 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
677
701
  },
678
702
  {
679
703
  name: "pinned.validate",
704
+ coverage: "operator" as const,
705
+ coverageNote: "pin-file hygiene",
680
706
  mutatesState: true,
681
707
  contract: "pinned",
682
708
  rules: [],
@@ -711,6 +737,8 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
711
737
  },
712
738
  {
713
739
  name: "pinned.init",
740
+ coverage: "operator" as const,
741
+ coverageNote: "pin-file bootstrap for mission pinning",
714
742
  description:
715
743
  "Initialize .forge/pinned.yaml with default foundation entries, " +
716
744
  "install pre-commit hook, and add audit log to .gitignore. " +
@@ -743,7 +771,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
743
771
  "and devDependencies completeness (no hoisted tool deps). " +
744
772
  "Exits non-zero on errors. Use --json for machine-readable output.",
745
773
  scope: "workspace",
746
- supportsAllSites: false,
774
+ acceptsAllFlag: false,
747
775
  reads: [
748
776
  "packages/*/package.json",
749
777
  "packages/*/.github/workflows/ci.yml",
@@ -768,7 +796,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
768
796
  "Enforces FORGE-AUTONOMY-01 (RFC-0940, DNA-64). @warpgogol/werkstatt-shared is exempt. " +
769
797
  "Type-only imports (import type) are exempt.",
770
798
  scope: "workspace",
771
- supportsAllSites: false,
799
+ acceptsAllFlag: false,
772
800
  reads: ["packages/forge/os/**/*.ts"],
773
801
  cacheable: false,
774
802
  flags: {},
@@ -784,7 +812,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
784
812
  contract: "forge",
785
813
  rules: ["SURFACE-01", "SURFACE-02", "SURFACE-03", "SURFACE-04", "SURFACE-05"],
786
814
  scope: "workspace",
787
- supportsAllSites: false,
815
+ acceptsAllFlag: false,
788
816
  reads: ["README.md", "package.json", "docs/**"],
789
817
  cacheable: false,
790
818
  flags: {},
@@ -798,7 +826,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
798
826
  description:
799
827
  "SIZE-01: flags a packages/** .ts/.tsx source file exceeding a 600-line threshold (warning 601-1200, error 1200+), against a shrink-only ratchet baseline. Pass --write-baseline to regenerate the baseline. Pass --baseline-path to override the default baseline location (RFC-1088).",
800
828
  scope: "workspace",
801
- supportsAllSites: false,
829
+ acceptsAllFlag: false,
802
830
  reads: ["packages/*/src/**/*.ts", "packages/*/src/**/*.tsx"],
803
831
  writes: ["file-size-lint.baseline.yaml"],
804
832
  generates: [],
@@ -818,6 +846,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
818
846
  },
819
847
  {
820
848
  name: "docs.archive",
849
+ coverage: "operator" as const,
821
850
  description:
822
851
  "Umbrella command that runs rfc.archive, adr.archive, plan.archive, " +
823
852
  "audit.archive, session.archive, and mission.archive in sequence. " +
@@ -839,6 +868,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
839
868
  "docs/sessions/archive/**",
840
869
  "missions/*",
841
870
  "missions/archive/**",
871
+ "docs/specs/live/*.md",
842
872
  ],
843
873
  generates: [],
844
874
  reads: [
@@ -847,6 +877,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
847
877
  "docs/plans/**/*.md",
848
878
  "docs/audits/**/*.md",
849
879
  "docs/sessions/**/*.md",
880
+ "docs/specs/live/*.md",
850
881
  "missions/**",
851
882
  ],
852
883
  cacheable: false,
@@ -902,39 +933,78 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
902
933
  }
903
934
  }
904
935
 
905
- // ── RFC-0711: post-loop spec.live.merge for implemented RFCs with liveSpec ──
906
- const { listRfcFiles, readAndParseRfc } = await import("../rfc/frontmatter-io.ts");
936
+ // ── RFC-0711 + RFC-1230: post-loop spec.live.merge — only RFCs moved
937
+ // into archive/implemented/ this run. Re-scanning the whole tree on
938
+ // every invocation is what produced duplicate sections/history.
939
+ // Merge failure stays non-fatal; V-LS-08 detects any coverage gap. ──
940
+ const { readAndParseRfc } = await import("../rfc/frontmatter-io.ts");
907
941
  const { RFC_DIR } = await import("../rfc/types.ts");
908
942
  const { runSpecLiveMerge } = await import("../spec/live-spec-merge.ts");
943
+ const {
944
+ collectLiveMergeTargets,
945
+ classifyLiveMergeOutcome,
946
+ liveMergeFailureEntry,
947
+ formatLiveMergeFailure,
948
+ buildLiveMergeBlock,
949
+ } = await import("../spec/live-spec-shared.ts");
909
950
  const rfcDirPath = path.join(context.workspaceRoot, RFC_DIR);
910
- const statusFilter = input.flags["status"] as string | undefined;
911
- const allRfcFiles = await listRfcFiles(rfcDirPath);
951
+ const rfcArchiveData = results["rfc.archive"] as
952
+ | {
953
+ moved?: Array<{
954
+ id: string;
955
+ status: string;
956
+ direction: string;
957
+ from: string;
958
+ to: string;
959
+ }>;
960
+ }
961
+ | undefined;
962
+ const thisRunMoved = Array.isArray(rfcArchiveData?.moved) ? rfcArchiveData.moved : [];
963
+ const movedById = new Map(thisRunMoved.map((m) => [m.id, m]));
964
+ const selection = collectLiveMergeTargets(thisRunMoved);
912
965
  const liveMergeResults: Array<{
913
966
  id: string;
914
967
  domain: string;
915
968
  operation: string;
916
969
  conflicts: number;
917
970
  }> = [];
971
+ // RFC-1235: exit-nonzero merges land in failed[] — merged[] must mean
972
+ // "the spec was written". Thrown and exit-1-with-data paths both record.
973
+ const liveMergeFailures: Array<{
974
+ id: string;
975
+ exitCode?: number;
976
+ error: string;
977
+ }> = [];
918
978
  let liveMergeSkipped = 0;
919
979
 
920
- for (const rfcFile of allRfcFiles) {
921
- const parsed = await readAndParseRfc(rfcDirPath, rfcFile);
922
- if (!parsed || "error" in parsed) continue;
923
- const fm = parsed.parsed.frontmatter;
924
- const rfcStatus = String(fm["status"] ?? "").trim();
925
- const liveSpec = fm["liveSpec"];
926
- const rfcId = String(fm["id"] ?? "");
980
+ const parseMovedRfc = async (id: string) => {
981
+ const move = movedById.get(id);
982
+ if (!move) return undefined;
983
+ const rel = (p: string) =>
984
+ p.startsWith(`${RFC_DIR}/`) ? p.slice(RFC_DIR.length + 1) : p;
985
+ // Under --dry-run the file was not renamed — `to` does not exist yet,
986
+ // so fall back to `from` (the still-current location).
987
+ for (const candidate of [rel(move.to), rel(move.from)]) {
988
+ const parsed = await readAndParseRfc(rfcDirPath, candidate);
989
+ if (parsed && "parsed" in parsed) return parsed;
990
+ }
991
+ return undefined;
992
+ };
927
993
 
928
- if (!liveSpec || rfcStatus !== "implemented") {
929
- if (liveSpec && rfcStatus === "rejected") {
930
- liveMergeSkipped++;
931
- if (outputFormat === "pretty") {
932
- logger.info(` spec.live.merge: skipping ${rfcId} (status: rejected)`);
933
- }
994
+ for (const rfcId of selection.rejected) {
995
+ const parsed = await parseMovedRfc(rfcId);
996
+ if (parsed?.parsed.frontmatter["liveSpec"]) {
997
+ liveMergeSkipped++;
998
+ if (outputFormat === "pretty") {
999
+ logger.info(` spec.live.merge: skipping ${rfcId} (status: rejected)`);
934
1000
  }
935
- continue;
936
1001
  }
937
- if (statusFilter && rfcStatus !== statusFilter) continue;
1002
+ }
1003
+
1004
+ for (const rfcId of selection.candidates) {
1005
+ const parsed = await parseMovedRfc(rfcId);
1006
+ if (!parsed) continue;
1007
+ if (!parsed.parsed.frontmatter["liveSpec"]) continue;
938
1008
 
939
1009
  try {
940
1010
  const mergeInput: ForgeCommandInput = {
@@ -942,31 +1012,32 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
942
1012
  flags: { id: rfcId, "dry-run": dryRun },
943
1013
  };
944
1014
  const mergeResult = await runSpecLiveMerge(mergeInput, context);
945
- const mergeData = mergeResult.data as
946
- { domain?: string; operation?: string; conflicts?: unknown[] } | undefined;
947
- if (mergeData) {
948
- liveMergeResults.push({
949
- id: rfcId,
950
- domain: String(mergeData.domain ?? ""),
951
- operation: String(mergeData.operation ?? ""),
952
- conflicts: Array.isArray(mergeData.conflicts) ? mergeData.conflicts.length : 0,
953
- });
1015
+ const outcome = classifyLiveMergeOutcome(rfcId, mergeResult);
1016
+ if (outcome.kind === "merged") {
1017
+ liveMergeResults.push(outcome.entry);
1018
+ } else {
1019
+ liveMergeFailures.push(outcome.entry);
1020
+ if (outputFormat === "pretty") {
1021
+ logger.error(` ${formatLiveMergeFailure(outcome.entry)}`);
1022
+ }
954
1023
  }
955
1024
  } catch (err) {
1025
+ const failure = liveMergeFailureEntry(rfcId, err);
1026
+ liveMergeFailures.push(failure);
956
1027
  if (outputFormat === "pretty") {
957
- logger.error(
958
- ` spec.live.merge: failed for ${rfcId}: ${String((err as Error).message)}`,
959
- );
1028
+ logger.error(` ${formatLiveMergeFailure(failure)}`);
960
1029
  }
961
1030
  }
962
1031
  }
963
1032
 
964
- if (liveMergeResults.length > 0 || liveMergeSkipped > 0) {
965
- results["spec.live.merge"] = {
966
- merged: liveMergeResults,
967
- skipped: liveMergeSkipped,
968
- dryRun,
969
- };
1033
+ const liveMergeBlock = buildLiveMergeBlock(
1034
+ liveMergeResults,
1035
+ liveMergeFailures,
1036
+ liveMergeSkipped,
1037
+ dryRun,
1038
+ );
1039
+ if (liveMergeBlock) {
1040
+ results["spec.live.merge"] = liveMergeBlock;
970
1041
  if (outputFormat === "pretty") {
971
1042
  for (const r of liveMergeResults) {
972
1043
  logger.info(
@@ -1032,6 +1103,7 @@ export async function createForgeCoreModule(): Promise<ForgeModule> {
1032
1103
  dryRun,
1033
1104
  liveSpecMerges: liveMergeResults.length,
1034
1105
  liveSpecSkipped: liveMergeSkipped,
1106
+ liveSpecFailures: liveMergeFailures.length,
1035
1107
  },
1036
1108
  summary: dryRun
1037
1109
  ? `[dry-run] Would move ${totalMoved} file(s), skip ${totalSkipped}`