@warpgogol/forge 5.3.3 → 6.0.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 (282) 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 +48 -16
  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 +39 -9
  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 +326 -0
  21. package/dist/os/compass/handlers/compass-docs-validate.js.map +1 -0
  22. package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
  23. package/dist/os/compass/handlers/compass-inventory.js +5 -2
  24. package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
  25. package/dist/os/compass/handlers/summary-record.d.ts +17 -3
  26. package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
  27. package/dist/os/compass/handlers/summary-record.js +107 -10
  28. package/dist/os/compass/handlers/summary-record.js.map +1 -1
  29. package/dist/os/compass/handlers/tests/forge-yaml-fixture.d.ts +18 -0
  30. package/dist/os/compass/handlers/tests/forge-yaml-fixture.d.ts.map +1 -0
  31. package/dist/os/compass/handlers/tests/forge-yaml-fixture.js +64 -0
  32. package/dist/os/compass/handlers/tests/forge-yaml-fixture.js.map +1 -0
  33. package/dist/os/compass/policy.d.ts +6 -1
  34. package/dist/os/compass/policy.d.ts.map +1 -1
  35. package/dist/os/compass/policy.js +8 -2
  36. package/dist/os/compass/policy.js.map +1 -1
  37. package/dist/os/core/core.module.d.ts.map +1 -1
  38. package/dist/os/core/core.module.js +124 -73
  39. package/dist/os/core/core.module.js.map +1 -1
  40. package/dist/os/exploration/exploration.module.d.ts.map +1 -1
  41. package/dist/os/exploration/exploration.module.js +3 -0
  42. package/dist/os/exploration/exploration.module.js.map +1 -1
  43. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  44. package/dist/os/mission/handlers/archive.js +1 -2
  45. package/dist/os/mission/handlers/archive.js.map +1 -1
  46. package/dist/os/naming/naming.module.d.ts.map +1 -1
  47. package/dist/os/naming/naming.module.js +9 -2
  48. package/dist/os/naming/naming.module.js.map +1 -1
  49. package/dist/os/notes/notes.module.d.ts.map +1 -1
  50. package/dist/os/notes/notes.module.js +17 -6
  51. package/dist/os/notes/notes.module.js.map +1 -1
  52. package/dist/os/plan/plan.module.d.ts.map +1 -1
  53. package/dist/os/plan/plan.module.js +2 -0
  54. package/dist/os/plan/plan.module.js.map +1 -1
  55. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  56. package/dist/os/plugin/plugin.module.js +9 -2
  57. package/dist/os/plugin/plugin.module.js.map +1 -1
  58. package/dist/os/program/program.module.d.ts.map +1 -1
  59. package/dist/os/program/program.module.js +19 -4
  60. package/dist/os/program/program.module.js.map +1 -1
  61. package/dist/os/queue/handlers/queue-validate.d.ts.map +1 -1
  62. package/dist/os/queue/handlers/queue-validate.js +154 -7
  63. package/dist/os/queue/handlers/queue-validate.js.map +1 -1
  64. package/dist/os/queue/manifest.d.ts +17 -1
  65. package/dist/os/queue/manifest.d.ts.map +1 -1
  66. package/dist/os/queue/manifest.js +127 -6
  67. package/dist/os/queue/manifest.js.map +1 -1
  68. package/dist/os/queue/queue.module.d.ts.map +1 -1
  69. package/dist/os/queue/queue.module.js +32 -4
  70. package/dist/os/queue/queue.module.js.map +1 -1
  71. package/dist/os/queue/types.d.ts +100 -1
  72. package/dist/os/queue/types.d.ts.map +1 -1
  73. package/dist/os/queue/types.js +44 -0
  74. package/dist/os/queue/types.js.map +1 -1
  75. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  76. package/dist/os/rfc/handlers/implement-stamp.js +28 -5
  77. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  78. package/dist/os/rfc/handlers/validate.js +1 -1
  79. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  80. package/dist/os/rfc/rfc.module.js +27 -3
  81. package/dist/os/rfc/rfc.module.js.map +1 -1
  82. package/dist/os/rfc/types.d.ts +11 -0
  83. package/dist/os/rfc/types.d.ts.map +1 -1
  84. package/dist/os/rfc/types.js +1 -0
  85. package/dist/os/rfc/types.js.map +1 -1
  86. package/dist/os/rfc/verification-evidence.d.ts +21 -0
  87. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  88. package/dist/os/rfc/verification-evidence.js +140 -23
  89. package/dist/os/rfc/verification-evidence.js.map +1 -1
  90. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  91. package/dist/os/rfc/verification-refresh.js +72 -37
  92. package/dist/os/rfc/verification-refresh.js.map +1 -1
  93. package/dist/os/session/handlers/save.d.ts.map +1 -1
  94. package/dist/os/session/handlers/save.js +46 -5
  95. package/dist/os/session/handlers/save.js.map +1 -1
  96. package/dist/os/session/session.module.d.ts.map +1 -1
  97. package/dist/os/session/session.module.js +5 -0
  98. package/dist/os/session/session.module.js.map +1 -1
  99. package/dist/os/spec/live-spec-merge.d.ts.map +1 -1
  100. package/dist/os/spec/live-spec-merge.js +55 -134
  101. package/dist/os/spec/live-spec-merge.js.map +1 -1
  102. package/dist/os/spec/live-spec-rebuild.d.ts +32 -0
  103. package/dist/os/spec/live-spec-rebuild.d.ts.map +1 -0
  104. package/dist/os/spec/live-spec-rebuild.js +272 -0
  105. package/dist/os/spec/live-spec-rebuild.js.map +1 -0
  106. package/dist/os/spec/live-spec-shared.d.ts +62 -0
  107. package/dist/os/spec/live-spec-shared.d.ts.map +1 -0
  108. package/dist/os/spec/live-spec-shared.js +315 -0
  109. package/dist/os/spec/live-spec-shared.js.map +1 -0
  110. package/dist/os/spec/live-spec-types.d.ts +17 -1
  111. package/dist/os/spec/live-spec-types.d.ts.map +1 -1
  112. package/dist/os/spec/live-spec-types.js +3 -0
  113. package/dist/os/spec/live-spec-types.js.map +1 -1
  114. package/dist/os/spec/live-spec-validate.d.ts.map +1 -1
  115. package/dist/os/spec/live-spec-validate.js +105 -2
  116. package/dist/os/spec/live-spec-validate.js.map +1 -1
  117. package/dist/os/spec/spec-materialize.d.ts +2 -0
  118. package/dist/os/spec/spec-materialize.d.ts.map +1 -1
  119. package/dist/os/spec/spec-materialize.js +45 -5
  120. package/dist/os/spec/spec-materialize.js.map +1 -1
  121. package/dist/os/spec/spec-schema.d.ts +19 -0
  122. package/dist/os/spec/spec-schema.d.ts.map +1 -1
  123. package/dist/os/spec/spec-schema.js +30 -0
  124. package/dist/os/spec/spec-schema.js.map +1 -1
  125. package/dist/os/spec/spec-status.d.ts +4 -0
  126. package/dist/os/spec/spec-status.d.ts.map +1 -1
  127. package/dist/os/spec/spec-status.js +19 -1
  128. package/dist/os/spec/spec-status.js.map +1 -1
  129. package/dist/os/spec/spec-validate.d.ts.map +1 -1
  130. package/dist/os/spec/spec-validate.js +55 -8
  131. package/dist/os/spec/spec-validate.js.map +1 -1
  132. package/dist/os/spec/spec.module.d.ts.map +1 -1
  133. package/dist/os/spec/spec.module.js +84 -8
  134. package/dist/os/spec/spec.module.js.map +1 -1
  135. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  136. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +10 -4
  137. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  138. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  139. package/dist/os/werkstatt/werkstatt.module.js +13 -4
  140. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  141. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  142. package/dist/os/workflow/workflow.module.js +13 -5
  143. package/dist/os/workflow/workflow.module.js.map +1 -1
  144. package/dist/src/cli-flags.d.ts.map +1 -1
  145. package/dist/src/cli-flags.js +25 -5
  146. package/dist/src/cli-flags.js.map +1 -1
  147. package/dist/src/config/forge-config.d.ts +24 -3
  148. package/dist/src/config/forge-config.d.ts.map +1 -1
  149. package/dist/src/config/forge-config.js +38 -7
  150. package/dist/src/config/forge-config.js.map +1 -1
  151. package/dist/src/onboarding/create.d.ts.map +1 -1
  152. package/dist/src/onboarding/create.js +26 -10
  153. package/dist/src/onboarding/create.js.map +1 -1
  154. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  155. package/dist/src/onboarding/doctor.js +49 -2
  156. package/dist/src/onboarding/doctor.js.map +1 -1
  157. package/dist/src/onboarding/init.d.ts.map +1 -1
  158. package/dist/src/onboarding/init.js +8 -3
  159. package/dist/src/onboarding/init.js.map +1 -1
  160. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  161. package/dist/src/onboarding/upgrade.js +24 -8
  162. package/dist/src/onboarding/upgrade.js.map +1 -1
  163. package/dist/src/pipeline-status.d.ts +14 -1
  164. package/dist/src/pipeline-status.d.ts.map +1 -1
  165. package/dist/src/pipeline-status.js +28 -8
  166. package/dist/src/pipeline-status.js.map +1 -1
  167. package/dist/src/types.d.ts +7 -1
  168. package/dist/src/types.d.ts.map +1 -1
  169. package/dist/src/types.js +6 -0
  170. package/dist/src/types.js.map +1 -1
  171. package/dist/src/utils/generated-marker.d.ts +8 -0
  172. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  173. package/dist/src/utils/generated-marker.js +25 -0
  174. package/dist/src/utils/generated-marker.js.map +1 -1
  175. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  176. package/dist/src/validators/skill-validate.js +42 -15
  177. package/dist/src/validators/skill-validate.js.map +1 -1
  178. package/os/adr/adr.module.ts +2 -0
  179. package/os/audit/audit.module.ts +2 -0
  180. package/os/compass/compass.module.ts +50 -16
  181. package/os/compass/handlers/compass-audit-handler.ts +50 -9
  182. package/os/compass/handlers/compass-docs-validate.ts +359 -0
  183. package/os/compass/handlers/compass-inventory.ts +6 -3
  184. package/os/compass/handlers/summary-record.ts +118 -10
  185. package/os/compass/handlers/tests/compass-audit-record.test.ts +2 -1
  186. package/os/compass/handlers/tests/compass-audit-validate.test.ts +92 -3
  187. package/os/compass/handlers/tests/compass-docs-validate.test.ts +203 -0
  188. package/os/compass/handlers/tests/compass-ledger-scope.test.ts +2 -1
  189. package/os/compass/handlers/tests/compass-policy.test.ts +15 -18
  190. package/os/compass/handlers/tests/compass-v2-contract.test.ts +38 -0
  191. package/os/compass/handlers/tests/forge-yaml-fixture.ts +69 -0
  192. package/os/compass/handlers/tests/summary-record.test.ts +152 -0
  193. package/os/compass/policy.ts +8 -2
  194. package/os/core/core.module.ts +147 -75
  195. package/os/core/docs-archive.test.ts +136 -0
  196. package/os/exploration/exploration.module.ts +3 -0
  197. package/os/mission/handlers/archive.ts +1 -2
  198. package/os/naming/naming.module.ts +9 -2
  199. package/os/notes/notes.module.ts +17 -6
  200. package/os/plan/plan-0000-template.md +150 -0
  201. package/os/plan/plan.module.ts +2 -0
  202. package/os/plugin/plugin.module.ts +9 -2
  203. package/os/program/program.module.ts +19 -4
  204. package/os/queue/decision-ledger.test.ts +163 -0
  205. package/os/queue/handlers/queue-validate.ts +190 -8
  206. package/os/queue/manifest.ts +201 -7
  207. package/os/queue/queue-validate.test.ts +303 -0
  208. package/os/queue/queue.module.ts +32 -4
  209. package/os/queue/types.ts +56 -1
  210. package/os/rfc/handlers/implement-stamp.ts +35 -5
  211. package/os/rfc/handlers/validate.ts +1 -1
  212. package/os/rfc/rfc.module.ts +29 -3
  213. package/os/rfc/types.ts +17 -1
  214. package/os/rfc/verification-emit.test.ts +305 -0
  215. package/os/rfc/verification-evidence.ts +155 -24
  216. package/os/rfc/verification-refresh.test.ts +222 -1
  217. package/os/rfc/verification-refresh.ts +80 -38
  218. package/os/session/handlers/save.ts +41 -5
  219. package/os/session/session.module.ts +5 -0
  220. package/os/spec/live-spec-idempotency.pbt.test.ts +222 -0
  221. package/os/spec/live-spec-list-show-validate.test.ts +10 -6
  222. package/os/spec/live-spec-merge.test.ts +187 -7
  223. package/os/spec/live-spec-merge.ts +71 -155
  224. package/os/spec/live-spec-rebuild.test.ts +317 -0
  225. package/os/spec/live-spec-rebuild.ts +356 -0
  226. package/os/spec/live-spec-shared.ts +378 -0
  227. package/os/spec/live-spec-types.ts +21 -1
  228. package/os/spec/live-spec-validate.test.ts +317 -0
  229. package/os/spec/live-spec-validate.ts +106 -2
  230. package/os/spec/spec-materialize.test.ts +192 -0
  231. package/os/spec/spec-materialize.ts +48 -4
  232. package/os/spec/spec-schema.ts +49 -0
  233. package/os/spec/spec-status.ts +24 -0
  234. package/os/spec/spec-validate.test.ts +66 -0
  235. package/os/spec/spec-validate.ts +62 -8
  236. package/os/spec/spec.module.ts +85 -8
  237. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +10 -4
  238. package/os/werkstatt/werkstatt.module.ts +13 -4
  239. package/os/workflow/workflow.module.ts +13 -5
  240. package/package.json +1 -1
  241. package/skills/_shared/fo-pipeline-conventions.md +126 -1
  242. package/skills/fo/fo-compass-annotate/SKILL.md +1 -1
  243. package/skills/fo/fo-doc-audit/SKILL.md +4 -4
  244. package/skills/fo/fo-explore/SKILL.md +2 -1
  245. package/skills/fo/fo-fix/SKILL.md +11 -3
  246. package/skills/fo/fo-handoff/SKILL.md +6 -8
  247. package/skills/fo/fo-idea-audit/SKILL.md +1 -1
  248. package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -2
  249. package/skills/fo/fo-idea-enhance/SKILL.md +23 -4
  250. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +86 -22
  251. package/skills/fo/fo-idea-implement/SKILL.md +57 -13
  252. package/skills/fo/fo-idea-plan/SKILL.md +28 -6
  253. package/skills/fo/fo-review/SKILL.md +69 -8
  254. package/skills/fo/fo-session-retro/SKILL.md +4 -3
  255. package/skills/fo/fo-session-save/SKILL.md +1 -1
  256. package/skills/fo/fo-step-commit/SKILL.md +2 -0
  257. package/skills/shared/grilling/SKILL.md +12 -0
  258. package/skills/shared/writing-great-skills/GLOSSARY.md +2 -0
  259. package/skills/shared/writing-great-skills/SKILL.md +2 -1
  260. package/src/cli-flags.ts +23 -5
  261. package/src/config/forge-config.ts +106 -57
  262. package/src/onboarding/create.ts +25 -9
  263. package/src/onboarding/doctor.ts +51 -2
  264. package/src/onboarding/init.ts +8 -3
  265. package/src/onboarding/upgrade.ts +36 -6
  266. package/src/pipeline-status.ts +32 -8
  267. package/src/tests/bindings-schema.test.ts +53 -1
  268. package/src/tests/cli-flags.test.ts +20 -0
  269. package/src/tests/cli-output.test.ts +13 -7
  270. package/src/tests/doctor-bindings.test.ts +7 -2
  271. package/src/tests/doctor-skills-unmanaged.test.ts +145 -0
  272. package/src/tests/fixtures/agents-generate-business-before.txt +7 -7
  273. package/src/tests/forge-config.test.ts +106 -2
  274. package/src/tests/implement-stamp.test.ts +38 -0
  275. package/src/tests/session-handlers.test.ts +33 -0
  276. package/src/tests/skill-validate.test.ts +180 -0
  277. package/src/tests/upgrade.test.ts +60 -0
  278. package/src/types.ts +13 -1
  279. package/src/utils/generated-marker.ts +28 -0
  280. package/src/validators/skill-validate.ts +43 -16
  281. package/skills/fo/fo-idea-implement/ADR-FLOW.md +0 -179
  282. package/skills/fo/fo-review/AXES.md +0 -70
@@ -9,7 +9,6 @@
9
9
  </non-goals>
10
10
  </MODULE_CONTRACT>
11
11
  <CHANGE_SUMMARY>
12
- <item>RFC-0643: pass profileId to runInit so forge.yaml gets a `profile` field.</item>
13
12
  <item>RFC-0664: scaffold memory layer (.agents/memory/) after init.</item>
14
13
  <item>RFC-0877: in-place mode only — --in-place flag required, no subdirectory creation, name derived from folder, strict empty-directory check (only .git/ tolerated).</item>
15
14
  <item>RFC-1097: step 6 — compass.migrate codemod run
@@ -18,7 +17,8 @@ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten
18
17
  <item>RFC-1097: sweep — packages/forge + services clean
19
18
 
20
19
  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>
21
- <history>RFC-0544, RFC-0548, RFC-0550, RFC-0640</history>
20
+ <item>RFC-1224: preserve operator forge.yaml content on upgrade, promote adrImplementStamp binding</item>
21
+ <history>RFC-0544, RFC-0548, RFC-0550, RFC-0640, RFC-0643, RFC-1224</history>
22
22
  </CHANGE_SUMMARY>
23
23
  */
24
24
 
@@ -32,6 +32,7 @@ import { scaffoldMemoryLayer } from "./memory-scaffold.ts";
32
32
  import {
33
33
  loadForgeConfig,
34
34
  serializeForgeConfig,
35
+ applyForgeYamlPatches,
35
36
  resolveForgeRoot,
36
37
  resolvePackageManager,
37
38
  applyCliBindingDefaults,
@@ -346,15 +347,30 @@ export async function runCreate(
346
347
  const forgeYamlPath = path.join(targetDir, "forge.yaml");
347
348
  if (await fio.exists(forgeYamlPath)) {
348
349
  try {
349
- const config = loadForgeConfig(targetDir);
350
350
  const pm = resolvePackageManager(packageManager);
351
- config.project.packageManager = pm;
352
- if (config.bindings) {
353
- config.bindings.commands = applyCliBindingDefaults(pm);
351
+ const commandDefaults = applyCliBindingDefaults(pm);
352
+ // RFC-1224: patch the document init just wrote instead of re-serializing —
353
+ // preserves comments/formatting and any schema-unknown sections.
354
+ const raw = await fio.readFile(forgeYamlPath);
355
+ const patched = applyForgeYamlPatches(raw, [
356
+ { path: ["project", "packageManager"], value: pm },
357
+ ...Object.entries(commandDefaults).map(([key, value]) => ({
358
+ path: ["bindings", "commands", key],
359
+ value,
360
+ })),
361
+ ]);
362
+ if (patched !== null) {
363
+ await fio.writeFile(forgeYamlPath, patched);
364
+ } else {
365
+ const config = loadForgeConfig(targetDir);
366
+ config.project.packageManager = pm;
367
+ if (config.bindings) {
368
+ config.bindings.commands = commandDefaults;
369
+ }
370
+ // RFC-1118: serializeForgeConfig writes the declared profile id verbatim —
371
+ // never the resolved StackProfile object, never drops an unresolvable id.
372
+ await fio.writeFile(forgeYamlPath, stringifyYaml(serializeForgeConfig(config)));
354
373
  }
355
- // RFC-1118: serializeForgeConfig writes the declared profile id verbatim —
356
- // never the resolved StackProfile object, never drops an unresolvable id.
357
- await fio.writeFile(forgeYamlPath, stringifyYaml(serializeForgeConfig(config)));
358
374
  } catch {
359
375
  // Post-processing is best-effort — init already wrote a valid config
360
376
  }
@@ -8,7 +8,6 @@ Checks for forge.yaml, AGENTS.md, PREFERENCES.md, .agents/skills/, docs/rfcs/,
8
8
  </non-goals>
9
9
  </MODULE_CONTRACT>
10
10
  <CHANGE_SUMMARY>
11
- <item>RFC-0664: added memory-layer health check (budget usage, gitignore coverage, daily-file leak risk).</item>
12
11
  <item>RFC-0704: added independent-version-packages check — validates that paths in independentVersionPackages exist and contain package.json.</item>
13
12
  <item>RFC-0941: added pack-manifests advisory check — validates forge.plugin.yaml existence and schema for each declared skill pack.</item>
14
13
  <item>RFC-1097: step 6 — compass.migrate codemod run
@@ -17,7 +16,9 @@ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten
17
16
  <item>RFC-1097: sweep — packages/forge + services clean
18
17
 
19
18
  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>
20
- <history>RFC-0391, RFC-0393, RFC-0524, RFC-0539, RFC-0540, RFC-0611, RFC-0640, RFC-0660, RFC-0661, RFC-0663, RFC-0675</history>
19
+ <item>RFC-1224: preserve operator forge.yaml content on upgrade, promote adrImplementStamp binding</item>
20
+ <item>RFC-1226: skills-unmanaged check — warn on SKILL.md-bearing dirs without .forge-managed marker</item>
21
+ <history>RFC-0391, RFC-0393, RFC-0524, RFC-0539, RFC-0540, RFC-0611, RFC-0640, RFC-0660, RFC-0661, RFC-0663, RFC-0664, RFC-0675, RFC-1224</history>
21
22
  </CHANGE_SUMMARY>
22
23
  */
23
24
 
@@ -54,6 +55,7 @@ import { compactMemoryMd } from "./memory-compact.ts";
54
55
  import { checkInvariants } from "./invariant-engine.ts";
55
56
  import type { InvariantViolation } from "./invariant-engine.ts";
56
57
  import { checkNpmToken, workshopNeedsWarpgogolToken } from "./npm-token-check.ts";
58
+ import { SKILL_MARKER_FILE } from "./skill-markers.ts";
57
59
  import { execSync } from "../utils/sync-fs.ts";
58
60
  import * as fs from "../utils/sync-fs.ts";
59
61
  import type { ProfilePrerequisite } from "../profiles/profile-schema.ts";
@@ -142,6 +144,7 @@ const BINDING_COMMAND_KEYS = [
142
144
  "commands.validateRfc",
143
145
  "commands.validateAdr",
144
146
  "commands.implementStamp",
147
+ "commands.adrImplementStamp",
145
148
  "commands.typecheck",
146
149
  "commands.test",
147
150
  "commands.scopedBuild",
@@ -762,6 +765,49 @@ async function checkPackSkills(workspaceRoot: string, io: WorkspaceIO): Promise<
762
765
  };
763
766
  }
764
767
 
768
+ // ---------------------------------------------------------------------------
769
+ // Unmanaged skill directories (RFC-1226)
770
+ // ---------------------------------------------------------------------------
771
+
772
+ // Visibility only: a dir bearing SKILL.md without .forge-managed is
773
+ // consumer-owned per RFC-1154 — report it, never prune or block.
774
+ async function checkUnmanagedSkillDirs(workspaceRoot: string, io: WorkspaceIO): Promise<DoctorCheck> {
775
+ let config;
776
+ try {
777
+ config = loadForgeConfig(workspaceRoot);
778
+ } catch {
779
+ return { name: "skills-unmanaged", status: "pass", message: "No forge.yaml — unmanaged skill dir check skipped" };
780
+ }
781
+
782
+ const skillsDir = join(workspaceRoot, config.paths.skillsDir);
783
+ let entries;
784
+ try {
785
+ entries = await io.readdir(skillsDir);
786
+ } catch {
787
+ return { name: "skills-unmanaged", status: "pass", message: "skillsDir absent — nothing to scan" };
788
+ }
789
+
790
+ const unmanaged: string[] = [];
791
+ for (const entry of entries) {
792
+ if (!entry.isDirectory) continue;
793
+ const dir = join(skillsDir, entry.name);
794
+ // Support dirs (_shared/, knowledge-only dirs) are not skills — skip.
795
+ if (!(await io.exists(join(dir, "SKILL.md")))) continue;
796
+ if (await io.exists(join(dir, SKILL_MARKER_FILE))) continue;
797
+ unmanaged.push(entry.name);
798
+ }
799
+
800
+ if (unmanaged.length === 0) {
801
+ return { name: "skills-unmanaged", status: "pass", message: "all skill dirs forge-managed" };
802
+ }
803
+
804
+ return {
805
+ name: "skills-unmanaged",
806
+ status: "warn",
807
+ message: `${unmanaged.length} unmanaged skill dir(s): ${unmanaged.join(", ")} — consumer-owned (no ${SKILL_MARKER_FILE} marker). Port into a declared skillPacks pack to make them forge-managed, or leave as-is.`,
808
+ };
809
+ }
810
+
765
811
  // ---------------------------------------------------------------------------
766
812
  // Pack manifest diagnostics (RFC-0941)
767
813
  // ---------------------------------------------------------------------------
@@ -1455,6 +1501,9 @@ export async function runDoctor(
1455
1501
  const packManifestCheck = await checkPackManifests(workspaceRoot, fio);
1456
1502
  checks.push(packManifestCheck);
1457
1503
 
1504
+ // RFC-1226: List unmanaged skill dirs under skillsDir (visibility only)
1505
+ checks.push(await checkUnmanagedSkillDirs(workspaceRoot, fio));
1506
+
1458
1507
  // RFC-0704: Check independent version packages — paths must exist and contain package.json
1459
1508
  const independentCheck = await checkIndependentVersionPackages(workspaceRoot, fio);
1460
1509
  checks.push(independentCheck);
@@ -461,9 +461,9 @@ export function runInit(
461
461
  }
462
462
  }
463
463
 
464
- // 5. Copy neutral RFC and ADR templates into the project's docs directories.
465
- // Templates are copied from the forge package so new projects can create
466
- // RFCs and ADRs without falling back to the forge package's internal copy.
464
+ // 5. Copy neutral RFC, ADR, and plan templates into the project's docs
465
+ // directories. Templates are copied from the forge package so new projects
466
+ // can create documents without falling back to the package's internal copy.
467
467
  // Existing templates are never overwritten.
468
468
  const templatesToCopy = [
469
469
  {
@@ -476,6 +476,11 @@ export function runInit(
476
476
  destRel: `${config.paths.adrsDir}/adr-0000-template.md`,
477
477
  label: "docs/adrs/adr-0000-template.md",
478
478
  },
479
+ {
480
+ src: path.join(forgeRoot, "os", "plan", "plan-0000-template.md"),
481
+ destRel: `${config.paths.plansDir}/plan-0000-template.md`,
482
+ label: "docs/plans/plan-0000-template.md",
483
+ },
479
484
  ];
480
485
  for (const { src, destRel, label } of templatesToCopy) {
481
486
  const destPath = path.join(workspaceRoot, destRel);
@@ -11,7 +11,6 @@ With --update-npm, also updates @warpgogol/forge from npm before syncing (skippe
11
11
  </non-goals>
12
12
  </MODULE_CONTRACT>
13
13
  <CHANGE_SUMMARY>
14
- <item>RFC-0611: added nested AGENTS.md generation after skill sync.</item>
15
14
  <item>RFC-0663: added syncSharedKnowledge step to sync shared knowledge layer to .agents/skills/shared-knowledge/.</item>
16
15
  <item>RFC-0664: added scaffoldMemoryLayer step to scaffold .agents/memory/ and .gitignore block.</item>
17
16
  <item>RFC-1097: step 6 — compass.migrate codemod run
@@ -20,7 +19,8 @@ Mechanical v1 to v2 header migration across the workspace: 942 files rewritten
20
19
  <item>RFC-1097: sweep — werkstatt-engine clean
21
20
 
22
21
  Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics.</item>
23
- <history>RFC-0543</history>
22
+ <item>RFC-1224: preserve operator forge.yaml content on upgrade, promote adrImplementStamp binding</item>
23
+ <history>RFC-0543, RFC-0611, RFC-1224</history>
24
24
  </CHANGE_SUMMARY>
25
25
  */
26
26
 
@@ -35,10 +35,12 @@ import {
35
35
  resolveForgeRoot,
36
36
  loadForgeConfig,
37
37
  serializeForgeConfig,
38
+ applyForgeYamlPatches,
38
39
  resolvePmRunner,
39
40
  resolvePmInstall,
40
41
  type ForgeConfig,
41
42
  type ForgeBindings,
43
+ type ForgeYamlPatch,
42
44
  } from "../config/forge-config.ts";
43
45
  import { FORGE_SKILLS, discoverPackSkills } from "../registry.ts";
44
46
  import { syncKnowledgeFile } from "../knowledge/index.ts";
@@ -452,18 +454,38 @@ async function updateSyncedVersion(
452
454
  workspaceRoot: string,
453
455
  config: ForgeConfig,
454
456
  version: string,
457
+ bindingsAdded: { key: string; value: string }[],
455
458
  dryRun: boolean,
456
459
  io: WorkspaceIO,
460
+ warn: (msg: string) => void,
457
461
  ): Promise<void> {
458
462
  if (dryRun) return;
459
463
 
460
- // Set the syncedVersion on the in-memory config (bindings already updated)
464
+ // Keep the in-memory config truthful for downstream steps (doctor).
461
465
  config.forge = { syncedVersion: version };
462
466
 
463
- // Write the full config back to forge.yaml
467
+ // RFC-1224: patch the existing document — syncedVersion plus newly added
468
+ // binding defaults — instead of re-serializing, so consumer-owned keys,
469
+ // sections, comments and ordering survive the rewrite.
470
+ const patches: ForgeYamlPatch[] = [
471
+ { path: ["forge", "syncedVersion"], value: version },
472
+ ...bindingsAdded.map((b) => ({
473
+ path: ["bindings", ...b.key.split(".")],
474
+ value: b.value,
475
+ })),
476
+ ];
477
+ const forgeYamlPath = path.join(workspaceRoot, "forge.yaml");
478
+ const raw = await io.readFile(forgeYamlPath).catch(() => null);
479
+ const patched = raw === null ? null : applyForgeYamlPatches(raw, patches);
480
+ if (patched !== null) {
481
+ await io.writeFile(forgeYamlPath, patched);
482
+ return;
483
+ }
484
+ warn(
485
+ "forge.upgrade: forge.yaml patch failed — falling back to full serialization (schema-unknown keys may be dropped)",
486
+ );
464
487
  // RFC-1118: serializeForgeConfig writes the declared profile id verbatim —
465
488
  // never the resolved StackProfile object, never drops an unresolvable id.
466
- const forgeYamlPath = path.join(workspaceRoot, "forge.yaml");
467
489
  await io.writeFile(forgeYamlPath, stringifyYaml(serializeForgeConfig(config)));
468
490
  }
469
491
 
@@ -689,7 +711,15 @@ export async function runUpgrade(
689
711
 
690
712
  // Step 5: Update forge.syncedVersion
691
713
  if (!isDryRun) {
692
- await updateSyncedVersion(workspaceRoot, config, toVersion, false, fio);
714
+ await updateSyncedVersion(
715
+ workspaceRoot,
716
+ config,
717
+ toVersion,
718
+ bindingsAdded,
719
+ false,
720
+ fio,
721
+ (msg) => context.logger.warn(msg),
722
+ );
693
723
  }
694
724
 
695
725
  // Step 5b: Generate nested AGENTS.md (RFC-0611). RFC-1153: the write path
@@ -19,9 +19,24 @@ os/ or kernel imports.</purpose>
19
19
  <item>RFC-1140: steps 1-4 — shared resolver, queue module, registration
20
20
 
21
21
  Extract pipeline-status derivation into packages/forge/src/pipeline-status.ts, refactor rfc.pipeline.status onto it, add os/queue module with queue.validate command, register in WORKSHOP_MODULE_MAP.forge + bin/cli.ts + package.json exports.</item>
22
+ <item>RFC-1250: decision-aware queue report — QueueItemReport gains kind +
23
+ decisions counts; `next` exclusion of parked/blocked items is computed by
24
+ the queue.validate caller (the resolver stays ledger-agnostic).</item>
22
25
  <item>RFC-1140: step 6 — cover shared resolver and queue.validate
23
26
 
24
27
  Add pipeline-status.test.ts (derivation matrix, order, next selection, ADR, skipped) and queue-validate.test.ts (schema errors, unknown/dup ids, id-filename mismatch, empty items, dependsOn warning, JSON shape). Fix queue derivation: pipelineStep is the stage after the last completed stage, not first incomplete — handles non-contiguous artifacts.</item>
28
+ <item>RFC-1250: review wave — QUEUE-07 gates un-parked opens only, ledger binding checks, fail-closed loader
29
+
30
+ REVIEW-RFC-1250-01 findings: QUEUE-07 no longer fires on parked entries
31
+ (the park is the containment — a parked queue stays resumable and the
32
+ decision window arbitrates it); loader fails open only on ENOENT —
33
+ other read errors are QUEUE-01; ledger gains queue/id-stem binding
34
+ (QUEUE-02), Q-N uniqueness (QUEUE-05), and QUEUE-08 hygiene warnings
35
+ (missing answers, foreign doc ids); next excludes QUEUE-07-blocked
36
+ items; top-level decision totals added. Orchestrator pre-flight treats
37
+ QUEUE-07 as the window agenda — structural errors still stop the batch;
38
+ maturation skips parked/deferred items; uncovered imperative ask sites
39
+ gain collect riders (ADR code-trace, NC markers, audit-verdict guard).</item>
25
40
  </CHANGE_SUMMARY>
26
41
  */
27
42
 
@@ -244,6 +259,10 @@ export interface QueueItemReport {
244
259
  status: QueueItemStatus;
245
260
  /** First incomplete pipeline stage — present only when in-progress. */
246
261
  pipelineStep?: PipelineStage;
262
+ /** Document kind — needed by queue.validate for QUEUE-07 (any non-terminal ADR is implementable). */
263
+ kind?: QueueDocumentKind;
264
+ /** Decision-ledger counts (RFC-1250) — present when the queue carries a sibling ledger. */
265
+ decisions?: { open: number; deferred: number; autoResolved: number };
247
266
  }
248
267
 
249
268
  /**
@@ -266,20 +285,20 @@ export async function deriveQueueItemStatus(
266
285
  const implementedAt = fm["implementedAt"] ? String(fm["implementedAt"]) : undefined;
267
286
 
268
287
  if (status === "implemented" || implementedAt) {
269
- return { id: doc.id, status: "implemented" };
288
+ return { id: doc.id, status: "implemented", kind: doc.kind };
270
289
  }
271
290
  if (status === "rejected" || status === "superseded") {
272
- return { id: doc.id, status: "skipped" };
291
+ return { id: doc.id, status: "skipped", kind: doc.kind };
273
292
  }
274
293
 
275
294
  // ADR pipeline is create → implement — no intermediate artifacts exist.
276
295
  if (doc.kind === "adr") {
277
- return { id: doc.id, status: "pending" };
296
+ return { id: doc.id, status: "pending", kind: doc.kind };
278
297
  }
279
298
 
280
299
  // RFC accepted means the plan step is done by definition.
281
300
  if (status === "accepted") {
282
- return { id: doc.id, status: "in-progress", pipelineStep: "implement" };
301
+ return { id: doc.id, status: "in-progress", pipelineStep: "implement", kind: doc.kind };
283
302
  }
284
303
 
285
304
  const enhancedAt = fm["enhancedAt"] ? String(fm["enhancedAt"]) : undefined;
@@ -302,13 +321,13 @@ export async function deriveQueueItemStatus(
302
321
  if (stages[i]!.done) lastDone = i;
303
322
  }
304
323
  if (lastDone === -1) {
305
- return { id: doc.id, status: "pending" };
324
+ return { id: doc.id, status: "pending", kind: doc.kind };
306
325
  }
307
326
  const nextStage = stages[lastDone + 1];
308
327
  if (!nextStage) {
309
- return { id: doc.id, status: "pending" };
328
+ return { id: doc.id, status: "pending", kind: doc.kind };
310
329
  }
311
- return { id: doc.id, status: "in-progress", pipelineStep: nextStage.stage };
330
+ return { id: doc.id, status: "in-progress", pipelineStep: nextStage.stage, kind: doc.kind };
312
331
  }
313
332
 
314
333
  export interface QueueReport {
@@ -317,7 +336,12 @@ export interface QueueReport {
317
336
  next: string | null;
318
337
  }
319
338
 
320
- /** Derive the full queue report, preserving manifest order. */
339
+ /**
340
+ * Derive the full queue report, preserving manifest order. `next` selects
341
+ * the first pending/in-progress item; callers that need ledger-aware
342
+ * exclusion (RFC-1250 parked/QUEUE-07-blocked items) re-filter the returned
343
+ * items — the resolver itself stays ledger-agnostic.
344
+ */
321
345
  export async function deriveQueueReport(
322
346
  workspaceRoot: string,
323
347
  itemIds: string[],
@@ -7,6 +7,8 @@
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
9
  <item>RFC-0639: initial test suite for semantic command keys, terminology resolution, and applyCliBindingDefaults.</item>
10
+ <item>RFC-1224: adrImplementStamp schema/default coverage; consumer-defined command key passthrough.</item>
11
+ <item>RFC-1224: preserve operator forge.yaml content on upgrade, promote adrImplementStamp binding</item>
10
12
  </CHANGE_SUMMARY>
11
13
  */
12
14
 
@@ -174,12 +176,14 @@ describe("RFC-0639: Terminology schema change", () => {
174
176
  });
175
177
 
176
178
  describe("RFC-0639: applyCliBindingDefaults", () => {
177
- test("returns 13 keys with semantic keys as null", () => {
179
+ test("returns 14 keys with semantic keys as null", () => {
178
180
  const commands = applyCliBindingDefaults("pnpm");
179
181
  // CLI-backed keys are non-null
180
182
  expect(commands.validateRfc).not.toBeNull();
181
183
  expect(commands.validateAdr).not.toBeNull();
182
184
  expect(commands.implementStamp).not.toBeNull();
185
+ // RFC-1224: adr.implement.stamp promoted to a first-class default binding
186
+ expect(commands.adrImplementStamp).not.toBeNull();
183
187
  expect(commands.specValidate).not.toBeNull();
184
188
  expect(commands.sessionSave).not.toBeNull();
185
189
  // Software-domain keys are null
@@ -312,3 +316,51 @@ describe("RFC-0639: resolveTerminology", () => {
312
316
  expect(resolveTerminology(config, undefined, "source")).toBe("source file");
313
317
  });
314
318
  });
319
+
320
+ describe("RFC-1224: promoted + consumer-defined command keys", () => {
321
+ test("forgeBindingsSchema accepts adrImplementStamp", () => {
322
+ const result = forgeBindingsSchema.safeParse({
323
+ schema: "forge/bindings@1",
324
+ commands: {
325
+ adrImplementStamp:
326
+ "pnpm exec forge adr.implement.stamp --id {id} --implementation-commit {commit}",
327
+ },
328
+ paths: {
329
+ invariantsFile: null,
330
+ compassDocs: [],
331
+ reviewsDir: null,
332
+ handoffsDir: null,
333
+ sessionsDir: null,
334
+ },
335
+ });
336
+ expect(result.success).toBe(true);
337
+ if (result.success) {
338
+ expect(result.data.commands.adrImplementStamp).toBe(
339
+ "pnpm exec forge adr.implement.stamp --id {id} --implementation-commit {commit}",
340
+ );
341
+ }
342
+ });
343
+
344
+ test("forgeBindingsSchema retains consumer-defined command keys", () => {
345
+ const result = forgeBindingsSchema.safeParse({
346
+ schema: "forge/bindings@1",
347
+ commands: {
348
+ validateRfc: null,
349
+ createRfc: "pnpm exec forge rfc.create",
350
+ },
351
+ paths: {
352
+ invariantsFile: null,
353
+ compassDocs: [],
354
+ reviewsDir: null,
355
+ handoffsDir: null,
356
+ sessionsDir: null,
357
+ },
358
+ });
359
+ expect(result.success).toBe(true);
360
+ if (result.success) {
361
+ expect((result.data.commands as Record<string, unknown>)["createRfc"]).toBe(
362
+ "pnpm exec forge rfc.create",
363
+ );
364
+ }
365
+ });
366
+ });
@@ -143,6 +143,26 @@ describe("resolveCliFlags — strict (schema-carrying) path", () => {
143
143
  expect(flags["files"]).toEqual(["a", "b"]);
144
144
  expect(errorRuleIds(diagnostics)).toEqual([]);
145
145
  });
146
+
147
+ test("string[] flag consumes consecutive bare tokens as a value list", () => {
148
+ const cmd = command({
149
+ files: { kind: "string[]", description: "Files." },
150
+ id: { kind: "string", description: "Id." },
151
+ });
152
+ const { flags, diagnostics } = resolveCliFlags(["--files", "a", "b", "c", "--id", "x"], cmd);
153
+ expect(flags["files"]).toEqual(["a", "b", "c"]);
154
+ expect(flags["id"]).toBe("x");
155
+ expect(errorRuleIds(diagnostics)).toEqual([]);
156
+ });
157
+
158
+ test("string[] flag with no value still emits KERNEL-FLAG-02", () => {
159
+ const cmd = command({
160
+ files: { kind: "string[]", description: "Files." },
161
+ json2: { kind: "boolean", description: "Switch." },
162
+ });
163
+ const { diagnostics } = resolveCliFlags(["--files", "--json2"], cmd);
164
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
165
+ });
146
166
  });
147
167
 
148
168
  describe("resolveCliFlags — legacy (schema-less) path", () => {
@@ -8,6 +8,12 @@ renderNextSteps, renderIdeRecommendation, generateHelp.</purpose>
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
10
  <item>RFC-0542: initial CLI output rendering tests.</item>
11
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
12
+
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>
11
17
  </CHANGE_SUMMARY>
12
18
  */
13
19
 
@@ -41,7 +47,7 @@ class MockRegistry implements CommandRegistry, ForgeModuleRegistry {
41
47
  provider: "workspace" as const,
42
48
  mutatesState: c.mutatesState,
43
49
  requiresNetwork: c.requiresNetwork,
44
- supportsAllSites: c.supportsAllSites,
50
+ acceptsAllFlag: c.acceptsAllFlag,
45
51
  timeoutMs: c.timeoutMs,
46
52
  expectedDurationMs: c.expectedDurationMs,
47
53
  longRunning: c.longRunning,
@@ -112,7 +118,7 @@ describe("generateHelp", () => {
112
118
  name: "forge.init",
113
119
  description: "Deploy forge into a project.",
114
120
  scope: "workspace",
115
- supportsAllSites: false,
121
+ acceptsAllFlag: false,
116
122
  flags: {},
117
123
  cacheable: false,
118
124
  execute: async () => ({ exitCode: 0 }),
@@ -121,7 +127,7 @@ describe("generateHelp", () => {
121
127
  name: "forge.doctor",
122
128
  description: "Diagnose forge state in an existing project.",
123
129
  scope: "workspace",
124
- supportsAllSites: false,
130
+ acceptsAllFlag: false,
125
131
  flags: {},
126
132
  cacheable: false,
127
133
  execute: async () => ({ exitCode: 0 }),
@@ -138,7 +144,7 @@ describe("generateHelp", () => {
138
144
  name: "forge.doctor",
139
145
  description: "Diagnose forge state.",
140
146
  scope: "workspace",
141
- supportsAllSites: false,
147
+ acceptsAllFlag: false,
142
148
  flags: {},
143
149
  cacheable: false,
144
150
  execute: async () => ({ exitCode: 0 }),
@@ -147,7 +153,7 @@ describe("generateHelp", () => {
147
153
  name: "forge.init",
148
154
  description: "Deploy forge.",
149
155
  scope: "workspace",
150
- supportsAllSites: false,
156
+ acceptsAllFlag: false,
151
157
  flags: {},
152
158
  cacheable: false,
153
159
  execute: async () => ({ exitCode: 0 }),
@@ -167,7 +173,7 @@ describe("generateHelp", () => {
167
173
  name: "forge.init",
168
174
  description: "Deploy forge.",
169
175
  scope: "workspace",
170
- supportsAllSites: false,
176
+ acceptsAllFlag: false,
171
177
  flags: {},
172
178
  cacheable: false,
173
179
  execute: async () => ({ exitCode: 0 }),
@@ -184,7 +190,7 @@ describe("generateHelp", () => {
184
190
  name: "forge.init",
185
191
  description: "Deploy forge.",
186
192
  scope: "workspace",
187
- supportsAllSites: false,
193
+ acceptsAllFlag: false,
188
194
  flags: {},
189
195
  cacheable: false,
190
196
  execute: async () => ({ exitCode: 0 }),
@@ -4,6 +4,8 @@
4
4
  </MODULE_CONTRACT>
5
5
  <CHANGE_SUMMARY>
6
6
  <item>RFC-0540: initial doctor binding notices tests.</item>
7
+ <item>RFC-1224: adrImplementStamp added to notice inventory and fixtures.</item>
8
+ <item>RFC-1224: preserve operator forge.yaml content on upgrade, promote adrImplementStamp binding</item>
7
9
  </CHANGE_SUMMARY>
8
10
  */
9
11
 
@@ -58,7 +60,7 @@ async function setupMinimalProject(dir: string): Promise<void> {
58
60
  await writeFile(join(dir, "PREFERENCES.md"), "# Test", "utf8");
59
61
  }
60
62
 
61
- test("doctor emits defaultable-binding-null notices for all 5 forge-CLI bindings when null", async () => {
63
+ test("doctor emits defaultable-binding-null notices for all 6 forge-CLI bindings when null", async () => {
62
64
  await setupMinimalProject(tempDir);
63
65
  await writeForgeYaml(
64
66
  tempDir,
@@ -96,11 +98,12 @@ bindings:
96
98
 
97
99
  const result = await runDoctor({ argv: [], flags: {} }, mockContext(tempDir));
98
100
  const notices = result.data?.bindings?.notices ?? [];
99
- expect(notices).toHaveLength(5);
101
+ expect(notices).toHaveLength(6);
100
102
  const keys = notices.map((n) => n.key);
101
103
  expect(keys).toContain("commands.validateRfc");
102
104
  expect(keys).toContain("commands.validateAdr");
103
105
  expect(keys).toContain("commands.implementStamp");
106
+ expect(keys).toContain("commands.adrImplementStamp");
104
107
  expect(keys).toContain("commands.specValidate");
105
108
  expect(keys).toContain("commands.sessionSave");
106
109
  for (const notice of notices) {
@@ -131,6 +134,7 @@ bindings:
131
134
  validateRfc: "custom rfc validate command"
132
135
  validateAdr: "custom adr validate command"
133
136
  implementStamp: "custom stamp command"
137
+ adrImplementStamp: "custom adr stamp command"
134
138
  typecheck: null
135
139
  test: null
136
140
  scopedBuild: null
@@ -172,6 +176,7 @@ bindings:
172
176
  validateRfc: "npx forge rfc.validate --id {id} --json"
173
177
  validateAdr: "npx forge adr.validate --id {id} --json"
174
178
  implementStamp: "npx forge rfc.implement.stamp --id {id} --implementation-commit {commit}"
179
+ adrImplementStamp: "npx forge adr.implement.stamp --id {id} --implementation-commit {commit}"
175
180
  typecheck: null
176
181
  test: null
177
182
  scopedBuild: null