@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,10 +6,18 @@
6
6
  </non-goals>
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
- <item>RFC-0394: initial forgeSpecModule registering spec.validate.</item>
10
- <item>RFC-0396: added spec.status and spec.materialize commands.</item>
11
- <item>RFC-0711: added spec.live.merge, spec.live.list, spec.live.show, spec.live.validate commands.</item>
9
+ <item>RFC-1230: added spec.live.rebuild command + --force flag on spec.live.merge (idempotent merge design).</item>
12
10
  <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>
11
+ <item>RFC-1230: review findings — scoped droppedSections to namespaced headings, warn on unreadable spec, fail-fast merge on corrupt frontmatter, CHANGE_SUMMARY dedupe</item>
12
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
13
+
14
+ Mechanical sweep: the field only ever gated --all argv acceptance; fan-out
15
+ follows the parsed selector. Guard renamed assertAllSitesAllowed ->
16
+ assertAllFlagAccepted, message updated. 417 declaration sites + type
17
+ surfaces (KernelCommandMetadata, ForgeCommandMetadata) in one atomic pass.</item>
18
+ <item>RFC-1234: spec.live.validate description lists V-LS-09 drift rule.</item>
19
+ <item>RFC-1240: --consumer flag on spec.validate/spec.status/spec.materialize; SPEC-12/13 rules in spec.validate description.</item>
20
+ <history>RFC-0394, RFC-0396, RFC-0711</history>
13
21
  </CHANGE_SUMMARY>
14
22
  */
15
23
 
@@ -23,6 +31,7 @@ const { runSpecValidate } = await import("./spec-validate.ts");
23
31
  const { runSpecLiveList } = await import("./live-spec-list.ts");
24
32
  const { runSpecLiveShow } = await import("./live-spec-show.ts");
25
33
  const { runSpecLiveValidate } = await import("./live-spec-validate.ts");
34
+ const { runSpecLiveRebuild } = await import("./live-spec-rebuild.ts");
26
35
  return {
27
36
  name: "forge-spec",
28
37
  version: "0.2.0",
@@ -33,11 +42,26 @@ const { runSpecValidate } = await import("./spec-validate.ts");
33
42
  name: "spec.validate",
34
43
  mutatesState: false,
35
44
  contract: "spec",
36
- rules: [],
45
+ rules: [
46
+ "SPEC-01",
47
+ "SPEC-02",
48
+ "SPEC-03",
49
+ "SPEC-04",
50
+ "SPEC-05",
51
+ "SPEC-06",
52
+ "SPEC-07",
53
+ "SPEC-08",
54
+ "SPEC-09",
55
+ "SPEC-10",
56
+ "SPEC-11",
57
+ "SPEC-12",
58
+ "SPEC-13",
59
+ ],
37
60
  description:
38
61
  "Validate vendored spec packages under docs/specs/. " +
39
62
  "Checks integrity (SHA-256), schema, dependency graph (acyclic), " +
40
- "reference resolution, wave coverage, duplicate ids, and materializedAs links. " +
63
+ "reference resolution, wave coverage, duplicate ids, materializedAs links, " +
64
+ "and consumer hygiene (SPEC-12 duplicates/empty, SPEC-13 identity warning). " +
41
65
  "Use --spec=<id> to validate a single spec.",
42
66
  scope: "workspace",
43
67
  flags: {
@@ -45,12 +69,17 @@ const { runSpecValidate } = await import("./spec-validate.ts");
45
69
  kind: "string",
46
70
  description: "Validate only the named spec.",
47
71
  },
72
+ consumer: {
73
+ kind: "string",
74
+ description: "Local consumer identity override (default: forge.yaml project.consumer).",
75
+ },
48
76
  },
49
77
  reads: ["docs/specs/**/*"],
50
78
  execute: runSpecValidate,
51
79
  },
52
80
  {
53
81
  name: "spec.status",
82
+ coverage: "operator" as const,
54
83
  mutatesState: false,
55
84
  description:
56
85
  "Show roadmap progress for vendored specs. " +
@@ -61,12 +90,17 @@ const { runSpecValidate } = await import("./spec-validate.ts");
61
90
  kind: "string",
62
91
  description: "Show status for a single spec.",
63
92
  },
93
+ consumer: {
94
+ kind: "string",
95
+ description: "Local consumer identity override (default: forge.yaml project.consumer).",
96
+ },
64
97
  },
65
98
  reads: ["docs/specs/**/*", "docs/rfcs/**/*.md"],
66
99
  execute: runSpecStatus,
67
100
  },
68
101
  {
69
102
  name: "spec.materialize",
103
+ coverage: "operator" as const,
70
104
  description:
71
105
  "Scaffold RFC files for the next N front nodes of a spec roadmap. " +
72
106
  "Requires --spec=<id>. Optional: --next=<N> (default 8, max 12), --nodes=<id,id> explicit selection.",
@@ -79,6 +113,7 @@ const { runSpecValidate } = await import("./spec-validate.ts");
79
113
  spec: { kind: "string", required: true, description: "Spec id to materialize from." },
80
114
  next: { kind: "string", description: "Number of front nodes to materialize (default 8, max 12)." },
81
115
  nodes: { kind: "string", description: "Comma-separated explicit node ids to materialize." },
116
+ consumer: { kind: "string", description: "Local consumer identity override (default: forge.yaml project.consumer)." },
82
117
  },
83
118
  execute: runSpecMaterialize,
84
119
  },
@@ -89,7 +124,8 @@ const { runSpecValidate } = await import("./spec-validate.ts");
89
124
  "under docs/specs/live/<domain>.md. Requires --id=<RFC-XXXX>. " +
90
125
  "Domain is auto-derived from packagesImpacted[0] when liveSpec: true, or uses " +
91
126
  "the string value when liveSpec: <domain>. " +
92
- "All-or-nothing: aborts on any heading conflict without writing. " +
127
+ "Idempotent: an RFC already in spec history[] is skipped as already-merged; " +
128
+ "use --force to re-merge (replaces that RFC's namespaced sections). " +
93
129
  "Use --dry-run to preview deltas without writing.",
94
130
  scope: "workspace",
95
131
  mutatesState: true,
@@ -98,12 +134,14 @@ const { runSpecValidate } = await import("./spec-validate.ts");
98
134
  reads: ["docs/rfcs/**/*.md", "docs/specs/live/*.md"],
99
135
  flags: {
100
136
  id: { kind: "string", required: true, description: "RFC id to merge (e.g. RFC-0711)." },
137
+ force: { kind: "boolean", description: "Re-merge an already-merged RFC — strips its (RFC-XXXX) sections and old history entries first." },
101
138
  "dry-run": { kind: "boolean", description: "Preview deltas without writing files." },
102
139
  },
103
140
  execute: runSpecLiveMerge,
104
141
  },
105
142
  {
106
143
  name: "spec.live.list",
144
+ coverage: "operator" as const,
107
145
  mutatesState: false,
108
146
  description:
109
147
  "List all living feature specs in docs/specs/live/. " +
@@ -115,6 +153,7 @@ const { runSpecValidate } = await import("./spec-validate.ts");
115
153
  },
116
154
  {
117
155
  name: "spec.live.show",
156
+ coverage: "operator" as const,
118
157
  mutatesState: false,
119
158
  description:
120
159
  "Show a single living feature spec by domain. " +
@@ -128,18 +167,56 @@ const { runSpecValidate } = await import("./spec-validate.ts");
128
167
  },
129
168
  {
130
169
  name: "spec.live.validate",
170
+ coverage: "operator" as const,
171
+ coverageNote: "spec.live drift audit — current debt repaired via spec.live.rebuild",
131
172
  mutatesState: false,
132
173
  contract: "spec",
133
- rules: [],
174
+ rules: [
175
+ "V-LS-01",
176
+ "V-LS-02",
177
+ "V-LS-03",
178
+ "V-LS-04",
179
+ "V-LS-05",
180
+ "V-LS-06",
181
+ "V-LS-07",
182
+ "V-LS-08",
183
+ "V-LS-09",
184
+ ],
134
185
  description:
135
186
  "Validate all living feature specs in docs/specs/live/. " +
136
187
  "Checks V-LS-01 (frontmatter), V-LS-02 (domain/filename match), " +
137
188
  "V-LS-03 (lastMergedRfc is archived), V-LS-04 (history entries are archived), " +
138
- "V-LS-05 (no duplicate domains).",
189
+ "V-LS-05 (no duplicate domains), V-LS-06 (no duplicate RFC-namespaced headings), " +
190
+ "V-LS-07 (no duplicate history RFCs), V-LS-08 (merged-history coverage is complete), " +
191
+ "V-LS-09 (spec content matches the deterministic replay of its history). " +
192
+ "Repair path: spec.live.rebuild.",
139
193
  scope: "workspace",
140
194
  flags: {},
141
195
  reads: ["docs/specs/live/*.md", "docs/rfcs/**/*.md"],
142
196
  execute: runSpecLiveValidate,
197
+ },
198
+ {
199
+ name: "spec.live.rebuild",
200
+ coverage: "operator" as const,
201
+ acceptsAllFlag: true,
202
+ description:
203
+ "Rebuild a living feature spec by replaying its deduplicated history[] — " +
204
+ "the repair path for duplicated (RFC-XXXX) sections and duplicate history entries " +
205
+ "reported by spec.live.validate (V-LS-06/V-LS-07). " +
206
+ "Each unique RFC's current ## Design is re-applied in first-occurrence order; " +
207
+ "unreadable or unimplemented RFCs are skipped with a warning. " +
208
+ "With no --domain (or --all) every spec is rebuilt. Use --dry-run to preview.",
209
+ scope: "workspace",
210
+ mutatesState: true,
211
+ writes: ["docs/specs/live/*.md"],
212
+ generates: [],
213
+ reads: ["docs/specs/live/*.md", "docs/rfcs/**/*.md"],
214
+ flags: {
215
+ domain: { kind: "string", description: "Rebuild a single living spec by domain (filename without .md)." },
216
+ all: { kind: "boolean", description: "Rebuild every living spec in docs/specs/live/ (default when --domain is omitted)." },
217
+ "dry-run": { kind: "boolean", description: "Preview rebuild without writing files." },
218
+ },
219
+ execute: runSpecLiveRebuild,
143
220
  }
144
221
  ],
145
222
  pipelines: [
@@ -12,6 +12,7 @@ helper module (RFC-0362 §6).</purpose>
12
12
  <CHANGE_SUMMARY>
13
13
  <item>RFC-0362: initial operation.validate command handler.</item>
14
14
  <item>RFC-0556: moved from @warpgogol/site-kernel-checks to @warpgogol/forge for autonomous mode. Uses node:fs/promises directly instead of context.io.</item>
15
+ <item>RFC-1248: VITE-CLIENT-DEP-02 lazy-import gate + SCAN-02 validator reads-root existence check (RFC-1248)</item>
15
16
  </CHANGE_SUMMARY>
16
17
  */
17
18
 
@@ -25,8 +26,8 @@ import type {
25
26
  ForgeRuntimeContext,
26
27
  } from "../../../src/types.ts";
27
28
 
28
- const SCAN_DIR = "packages/os/site-kernel-handoff/src";
29
- const ALLOWLIST_DIR = "packages/os/site-kernel-handoff/src/werkstatt";
29
+ const SCAN_DIR = "packages/werkstatt-engine/src/handoff";
30
+ const ALLOWLIST_DIR = "packages/werkstatt-engine/src/werkstatt";
30
31
 
31
32
  const DIRECT_WRITE_PATTERNS: Array<{ regex: RegExp; label: string }> = [
32
33
  { regex: /\bwriteFile\s*\(/g, label: "writeFile" },
@@ -56,10 +57,15 @@ export async function runWerkstattOperationValidate(
56
57
 
57
58
  const violations: Array<{ file: string; line: number; pattern: string }> = [];
58
59
 
59
- const PRE_EXISTING_ALLOWLIST = new Set(["handoff-pack.ts", "materialize.ts", "bundle-io.ts"]);
60
+ const PRE_EXISTING_ALLOWLIST = new Set([
61
+ "handoff-pack.ts",
62
+ "materialize.ts",
63
+ "bundle-io.ts",
64
+ "platform-consistency.ts",
65
+ ]);
60
66
 
61
67
  for (const filePath of files) {
62
- if (filePath.startsWith(allowlistPath) || filePath.includes("werkstatt")) continue;
68
+ if (filePath.startsWith(allowlistPath)) continue;
63
69
 
64
70
  const fileName = basename(filePath);
65
71
  if (fileName.endsWith(".test.ts") || fileName.endsWith(".spec.ts")) continue;
@@ -9,6 +9,13 @@
9
9
  <item>RFC-0374: initial forgeWerkstattModule registering 3 werkstatt commands.</item>
10
10
  <item>RFC-0556: removed dynamic imports of @warpgogol/site-kernel-handoff and @warpgogol/site-kernel-checks, all handlers now inlined in forge/os/werkstatt/handlers/.</item>
11
11
  <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>
12
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
13
+
14
+ Mechanical sweep: the field only ever gated --all argv acceptance; fan-out
15
+ follows the parsed selector. Guard renamed assertAllSitesAllowed ->
16
+ assertAllFlagAccepted, message updated. 417 declaration sites + type
17
+ surfaces (KernelCommandMetadata, ForgeCommandMetadata) in one atomic pass.</item>
18
+ <item>RFC-1248: VITE-CLIENT-DEP-02 lazy-import gate + SCAN-02 validator reads-root existence check (RFC-1248)</item>
12
19
  </CHANGE_SUMMARY>
13
20
  */
14
21
 
@@ -25,20 +32,22 @@ export const forgeWerkstattModule: ForgeModule = {
25
32
  commands: [
26
33
  {
27
34
  name: "werkstatt.lock.status",
35
+ coverage: "operator" as const,
28
36
  mutatesState: false,
29
37
  description: "Report all Werkstatt locks, their age, owner, and staleness (RFC-0362).",
30
38
  scope: "workspace",
31
- supportsAllSites: false,
39
+ acceptsAllFlag: false,
32
40
  flags: {},
33
41
  reads: [".werkstatt/locks/**"],
34
42
  execute: runWerkstattLockStatus,
35
43
  },
36
44
  {
37
45
  name: "werkstatt.lock.recover",
46
+ coverage: "operator" as const,
38
47
  description:
39
48
  "Classify and clean stale locks and staging artifacts (RFC-0362). Flags: --scope, --purge.",
40
49
  scope: "workspace",
41
- supportsAllSites: false,
50
+ acceptsAllFlag: false,
42
51
  mutatesState: true,
43
52
  flags: {
44
53
  scope: { kind: "string", description: "Recover only a single lock scope." },
@@ -61,9 +70,9 @@ export const forgeWerkstattModule: ForgeModule = {
61
70
  description:
62
71
  "Validate that mutating Werkstatt commands use shared lock/idempotency/atomic-write helpers (RFC-0362).",
63
72
  scope: "workspace",
64
- supportsAllSites: false,
73
+ acceptsAllFlag: false,
65
74
  flags: {},
66
- reads: ["packages/os/site-kernel-handoff/src/**/*.ts"],
75
+ reads: ["packages/werkstatt-engine/src/handoff/**/*.ts"],
67
76
  execute: runWerkstattOperationValidate,
68
77
  },
69
78
  ],
@@ -9,6 +9,13 @@
9
9
  <item>RFC-0075: Add workflow command module.</item>
10
10
  <item>RFC-0374: Migrated from packages/os/site-kernel/src/workflow/ to packages/forge/os/workflow/.</item>
11
11
  <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>
12
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
13
+
14
+ Mechanical sweep: the field only ever gated --all argv acceptance; fan-out
15
+ follows the parsed selector. Guard renamed assertAllSitesAllowed ->
16
+ assertAllFlagAccepted, message updated. 417 declaration sites + type
17
+ surfaces (KernelCommandMetadata, ForgeCommandMetadata) in one atomic pass.</item>
18
+ <item>RFC-1248: VITE-CLIENT-DEP-02 lazy-import gate + SCAN-02 validator reads-root existence check (RFC-1248)</item>
12
19
  </CHANGE_SUMMARY>
13
20
  */
14
21
 
@@ -32,19 +39,20 @@ export async function createForgeWorkflowModule(): Promise<ForgeModule> {
32
39
  "and per-chain phase links (RFC-0075 + RFC-0136).",
33
40
  scope: "workspace",
34
41
  flags: {},
35
- supportsAllSites: true,
36
- reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"],
42
+ acceptsAllFlag: true,
43
+ reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"], // scan-coverage: optional tool dirs — workshops declare workflows under either
37
44
  execute: runWorkflowLint,
38
45
  },
39
46
  {
40
47
  name: "workflow.list",
48
+ coverage: "operator" as const,
41
49
  mutatesState: false,
42
50
  description:
43
51
  "List .agents/workflows entries with phase, IO summary, and next workflow (RFC-0075).",
44
52
  scope: "workspace",
45
53
  flags: {},
46
- supportsAllSites: true,
47
- reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"],
54
+ acceptsAllFlag: true,
55
+ reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"], // scan-coverage: optional tool dirs — workshops declare workflows under either
48
56
  execute: runWorkflowList,
49
57
  },
50
58
  {
@@ -54,7 +62,7 @@ export async function createForgeWorkflowModule(): Promise<ForgeModule> {
54
62
  "List .agents/workflows-amend entries with phase, IO summary, and next workflow (RFC-0136).",
55
63
  scope: "workspace",
56
64
  flags: {},
57
- supportsAllSites: true,
65
+ acceptsAllFlag: true,
58
66
  reads: [".agents/workflows-amend/**/*.md"],
59
67
  execute: runWorkflowAmendList,
60
68
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warpgogol/forge",
3
- "version": "5.3.4",
3
+ "version": "6.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -27,6 +27,27 @@ Stage only the files this skill produces or modifies. Another agent may be worki
27
27
  - **RFC pipeline**: create → audit → enhance → plan → implement (includes review → fix)
28
28
  - **ADR pipeline**: create → implement (includes review → fix)
29
29
 
30
+ ## Review triggers (T1/T2/T3)
31
+
32
+ Reviews fire on mandatory triggers across the pipeline lifecycle, not only at delivery.
33
+
34
+ | Trigger | Point | Covered by |
35
+ | --- | --- | --- |
36
+ | T1 — plan review | Before implementation starts | `fo-idea-audit` + `fo-idea-enhance` + `fo-idea-plan` grilling (existing — declared, unchanged) |
37
+ | T2 — checkpoint review | A step checkpoint that records an approach change vs. the plan, or a plan step that consumed >2 fix iterations | `fo-review` invocation scoped to the step diff, `independent` mode preferred |
38
+ | T3 — pre-delivery review | End of `fo-idea-implement` | Existing; `independent` mode by default in the full pipeline |
39
+
40
+ ## Review blocking semantics
41
+
42
+ `fo-review` verdicts carry `blockLevel` (`pass | warning | soft-block | hard-block`), mapped to `verdict` for backward compatibility (`fo-fix` consumes `verdict` unchanged).
43
+
44
+ - **`hard-block` (`rejected`)** — the item must be corrected and then undergo a **full** re-review (not a delta on the flagged point) before it may proceed to stamping. At most two fix→re-review cycles inside one pipeline run; a third failure escalates to the operator regardless of mode. In queue mode the item stops before stamping and is recorded as blocked in the batch report; the batch continues.
45
+ - **`soft-block` (`needs-revision` + `escalation: operator`)** — interactive mode: the pipeline pauses and escalates to the operator via a structured question (`acknowledge and continue` / `redirect` / `abort`), presenting stop/redirect as first-class options to counter the continue-bias. Queue mode: the item is paused, recorded in the batch summary as `awaiting operator arbitration`, the arbitration question is appended to the queue's decision ledger (§Decision ledger), and the batch continues with the next item.
46
+ - **`warning` (`needs-revision`)** — findings are recorded as tracked observations; unresolved warnings at T3 escalate to `soft-block`.
47
+ - **`pass` (`approved`)** — no fracture signals; zero findings.
48
+
49
+ **Queue-mode resume:** a parked item resumes by re-invoking the orchestrator with the same manifest — `queue.validate` derives the continuation point from document status (the queue resume contract). Parking never leaves an item stranded without a defined re-entry path. `blocked` remains report language only — never persisted into RFC frontmatter or queue manifests.
50
+
30
51
  ## Minimality ladder
31
52
 
32
53
  Before writing implementation code, climb the minimality ladder. Stop at the first rung that holds — that is your implementation. The ladder runs after you understand the problem (read the code, trace the flow), not instead of it.
@@ -229,6 +250,7 @@ When the orchestrator skill processes multiple documents (>=2), perform a contex
229
250
  - `commits`: list of commit SHAs produced for this document
230
251
  - `lessons`: 1-3 short freeform sentences capturing key errors, root causes, patterns discovered, or validator quirks encountered during this document's pipeline run
231
252
  - `dependencies`: cross-RFC dependency notes (e.g., "RFC-YYYY depends on RFC-XXXX for schema field Z") — empty if none
253
+ - `unclosed`: list of `{ item, state: closed | unclosed | undecidable }` — mandatory when the item carried a checklist structure (§Tri-state closure marking); required in particular when `status` is `failed` or the item was parked
232
254
  - `next`: id of the next document to process, or `null` if this was the last
233
255
  2. **Release context** — explicitly treat all detailed context from the completed document as no longer actionable: file contents, search results, edit operations, intermediate reasoning. Retain only the checkpoint block. Release means treat as no longer actionable for reasoning, not delete or undo.
234
256
  3. **Fresh start** — begin the next document with a fresh read phase: re-read the RFC file and all related documents (amends, supersedes, related RFCs, DNA invariants, AGENTS.md sections).
@@ -248,6 +270,7 @@ When the orchestrator skill implements a single RFC with >=5 plan steps, perform
248
270
  - `commit`: SHA of the commit produced by this step
249
271
  - `decisions`: 1-3 short freeform sentences capturing key micro-decisions made during this step (e.g., "used flag instead of new command", "skipped validator X because it's in package Y, not in scope")
250
272
  - `errors`: list of errors encountered and fixed during this step — empty if none
273
+ - `unclosed`: list of `{ item, state: closed | unclosed | undecidable }` for every multi-item checklist the step carried — mandatory when a checklist exists (§Tri-state closure marking); three or more `undecidable` entries escalate to the operator
251
274
  - `nextStep`: number of the next plan step, or `null` if this was the last
252
275
  2. **Release step context** — treat all detailed context from the completed step as no longer actionable: codebase search results, file reads, edit operations, validation output. Retain only the step-checkpoint block and the RFC's plan file.
253
276
  3. **Fresh start** — begin the next plan step with a fresh read of the plan file and the specific files the next step touches.
@@ -270,12 +293,46 @@ The beacon text must use `aiLanguage` per the language policy.
270
293
 
271
294
  When a pipeline step fails and cannot be auto-fixed within 2 attempts (per §Command execution timeout discipline), emit a structured error checkpoint block in conversation output:
272
295
 
273
- 1. **Emit error checkpoint** — output a YAML block with: rfc, step, planStep (if within implement phase), error (command, exitCode, summary, attempts), partialState (filesModified, commits, rfcStatus), resumePoint.
296
+ 1. **Emit error checkpoint** — output a YAML block with: rfc, step, planStep (if within implement phase), error (command, exitCode, summary, attempts), partialState (filesModified, commits, rfcStatus), resumePoint, unclosed (tri-state list per §Tri-state closure marking — mandatory here because a failing step always carries an implicit checklist of attempted sub-items).
274
297
  2. **Stop the pipeline** — do not continue to the next pipeline step. The error is not auto-fixable; continuing would compound the problem. This is an **explicit exception** to the orchestrator's "no pauses between pipeline steps" constraint. The "no pauses" directive assumes the pipeline can proceed; when an error is unfixable after 2 attempts, continuing is impossible and the exception is justified. The pause is for error reporting, not for optional operator input.
275
298
  3. **Report to operator** — present the error checkpoint in `aiLanguage` and ask the operator how to proceed: fix manually, skip the step, or abort the RFC.
276
299
 
277
300
  The error checkpoint doubles as a resume marker: when resuming an interrupted session, scan for the last error checkpoint. If found, resume from the failed step using the partialState and resumePoint fields.
278
301
 
302
+ ## Falsified-routes ledger
303
+
304
+ Plan files (`docs/plans/plan-*.md`) MAY carry a `## Falsified routes` section — the negative-knowledge ledger for the work item:
305
+
306
+ ```markdown
307
+ ## Falsified routes
308
+
309
+ | Route | Root cause | Falsified at | Forbidden retry |
310
+ | --- | --- | --- | --- |
311
+ | <approach tried> | <why it cannot work — the evidence, not the vibe> | <commit-sha or date> | yes \| no |
312
+ ```
313
+
314
+ Rules for `fo-idea-implement` and `fo-fix`:
315
+
316
+ - **Append on abandon** — when an approach is abandoned after a real attempt (not merely considered and skipped), append a row with the route, the root cause discovered, and falsified-at evidence (commit SHA or date). Never write prose instead of rows.
317
+ - **Consult before proposing** — before proposing an alternative route, read the plan's `## Falsified routes` section. A `Forbidden retry: yes` row rejects a matching proposal unless the proposal states a new fact that invalidates the recorded root cause. A plan-prescribed route that matches a forbidden row counts as an approach change for this rule — consult applies even when the route was chosen by a previous session.
318
+ - **Rows are never deleted** — a superseded route gets a `revivedAt` annotation: annotate the row's Route cell as `<route> (revived <date>: <new fact that invalidates the root cause>)`, matching criterion-versioning discipline. An empty or absent section is legal: the ledger is required only when an approach was actually abandoned.
319
+ - `blocked` and `falsified` are report and ledger vocabulary — never persist them into RFC frontmatter or queue manifests.
320
+
321
+ ### Blind-spot pass
322
+
323
+ After **two failed attempts on the same approach** within one work item — whether during step execution or the fix loop — and before the next retry or pivot, dispatch a clean-context re-examination using the same artifacts-only contract as `fo-review` `independent` mode: the problem statement, the falsified-routes table, the raw failing-run evidence, and the settled conclusion phrased as a question — never the executor's session narrative or self-assessment. The pass answers one question: _is the settled conclusion ("dead end", "impossible", "only option left") actually supported by evidence?_ Where no subagent primitive exists, degrade to an `isolated-inline` re-derive-from-artifacts pass and record that mode. The record lands in the session output and in the next step checkpoint's `decisions` field.
324
+
325
+ The pass runs once per approach — it never chains recursively. It answers a different question than the T2 checkpoint review (conclusion validity vs. implementation quality), so neither de-duplicates against the other.
326
+
327
+ ## Tri-state closure marking
328
+
329
+ Checkpoint blocks and handoff documents declare their open items with a tri-state value — `closed | unclosed | undecidable` — so that "silently forgotten" is distinguishable from "done".
330
+
331
+ - **Mandatory-if-any:** wherever a checkpoint or handoff carries a multi-item checklist or unclosed-items structure, the `unclosed` list is mandatory and must state every item: `unclosed: [{ item, state: closed | unclosed | undecidable }]`. Where the anchor is a simple declare/verify with no checklist structure, `unclosed` may be absent entirely — the mandate binds the structure, not every anchor.
332
+ - **Absence is never success:** an item absent from `unclosed` after the checkpoint executes is treated as `undecidable`.
333
+ - **`undecidable` is explicit and legal:** an executor that cannot determine closure records `undecidable` — never silence.
334
+ - **Escalation:** a checkpoint carrying three or more `undecidable` items escalates to the operator instead of continuing — the tri-state exists to surface uncertainty, not to warehouse it.
335
+
279
336
  ## Pipeline continuation
280
337
 
281
338
  When a pipeline step completes (audit, enhance, plan), the agent MUST proactively suggest the next step and offer to proceed. This is NOT automatic chaining — the agent asks the operator first. This applies when the operator is manually driving the pipeline step by step.
@@ -322,3 +379,71 @@ When the orchestrator skill processes multiple documents (>=2), emit a batch pla
322
379
  The preview is informational — it does not pause for operator approval unless the operator explicitly requests confirmation. The operator's invocation of the orchestrator is the instruction to proceed.
323
380
 
324
381
  The preview text must use `aiLanguage` per the language policy.
382
+
383
+ ## Decision ledger
384
+
385
+ Every orchestrator run materializes a queue manifest (single-document runs are a one-item queue) and owns a **decision ledger** sibling: `docs/queues/<id>.decisions.yaml`. The ledger is the durable record of "what requires operator judgment" for that queue — committed, append-only, survives sessions, isolated per manifest so parallel batches in different sessions never share mutable decision state.
386
+
387
+ The ledger's `id` field equals the filename stem `<manifest-id>.decisions`, and its `queue` field equals the manifest `id` — `queue.validate` enforces both bindings (QUEUE-02) plus `Q-N` uniqueness (QUEUE-05), so a misplaced or copy-pasted ledger can never apply foreign decisions to this queue. `answered` and `auto-resolved` entries MUST carry `answer`, and every entry's `doc` MUST be a manifest item — violations surface as non-blocking QUEUE-08 warnings. Schema lives in `packages/forge/os/queue/types.ts` (`decisionLedgerSchema`).
388
+
389
+ Status vocabulary for `items[]` entries:
390
+
391
+ - `open` — awaiting the decision window; blocks execution (QUEUE-07) unless the entry is `parked`.
392
+ - `answered` — decided by the operator at the window; carries `answer` + `answeredAt`.
393
+ - `auto-resolved` — the agent applied its recommended option and logged it. Covers both resolved-by-inference rows emitted during maturation (shown at the window for dispute) and emergent questions auto-resolved during execution; carries `answer` + `answeredAt`.
394
+ - `deferred` — the operator deferred; the item is parked for this run.
395
+
396
+ Parking vocabulary: `parked: true` on an `open` entry means the _system_ parked the item pending arbitration — written only by the enumerated parking paths (execution hard-stop per §Auto-resolve and log, soft-block review arbitration). `deferred` means the _operator_ parked it at a window. Both make the item non-executable this run; `queue.validate`'s `next` skips them, and an item whose `dependsOn` target is parked is itself parked (cascade). QUEUE-07 is an error: an item derivable to the implement stage (RFC `pipelineStep: implement`, or a non-terminal ADR) that is NOT parked and carries ≥1 un-parked `open` entry blocks `queue.validate`. A parked entry never fires QUEUE-07 — the park is already the containment; it surfaces in the briefing's parked section and waits for the next window's arbitration. An un-parked `open` on an implementable item means "collected but never resolved" — its presence routes the run into the decision window rather than halting it, and the only suppression is resolving the entries.
397
+
398
+ The rendered human view is `docs/queues/<id>.briefing.md` — generated from the ledger, never the source of truth.
399
+
400
+ **Pending-decision markers.** Documents carry `> PENDING DECISION: Q-N — <one-line question>` blockquote markers at the point where an answer matters (RFC section, plan step). A document with open markers cannot transition to `accepted`, and an implementable document with open markers trips QUEUE-07. Markers lift during the resolution phase when the answer lands.
401
+
402
+ The ledger is append-only: changing an `answered` entry is forbidden. A disputed or superseded decision gets a new entry referencing the old `Q-N` — never an in-place edit. `blocked`, `parked`, and `deferred` are report/ledger vocabulary — never persisted into RFC frontmatter or queue manifests.
403
+
404
+ ## Collect and finalize contract
405
+
406
+ Pipeline steps that produce operator-facing questions run in one of two modes:
407
+
408
+ - **`interview`** (standalone skill invocations — the operator is at the keyboard): ask inline, one question at a time, as today.
409
+ - **`collect`** (orchestrator-driven runs with a queue manifest): never call `ask_user_question` for pipeline questions. Emit each unresolved question as a ledger entry with `status: open`, a `resolutionPath`, and recommended options; apply all autonomous work; leave `PENDING DECISION` markers where an answer is required.
410
+ - **`finalize`** (the resolution phase after the window): consume `answered` entries, integrate them into the document, lift markers, complete the stage's stamps and commits. Finalize per document is atomic — a crash mid-document leaves markers intact and the next run re-finalizes idempotently.
411
+
412
+ Mode trigger: collect/finalize activate only under an orchestrator run carrying a manifest + ledger path. Everything else is `interview`.
413
+
414
+ ## Decision window
415
+
416
+ The decision window is the single scheduled operator interaction of a queue run — placed after maturation, before execution. It doubles as the batch acceptance act: `draft → accepted` transitions happen in the resolution phase that follows the window, so the operator signs off having seen every trade-off at once.
417
+
418
+ Window mechanics:
419
+
420
+ - The orchestrator renders the ledger into `docs/queues/<id>.briefing.md`: batch header, batch policies, per-document decision blocks (question, `resolutionPath`, options with `recommended`, consequences), the resolved-by-inference list (disputable at a glance), and the parked-items section.
421
+ - The operator answers in free text — codes like `Q-03: B`, `all — per recommendations`, `Q-07: defer`. `ask_user_question` is legal only for ≤4 highest-risk decisions (it cannot carry open-ended answers).
422
+ - Batch `policies[]` collapse identical questions across documents — answer once, items inherit unless overridden.
423
+ - One bounded follow-up round is permitted only when an answer invalidates a drafted plan and surfaces a genuinely new trade-off; then the batch proceeds.
424
+
425
+ ## Self-resolution ladder
426
+
427
+ Before any question reaches the ledger, the emitting skill MUST exhaust these rungs in order — a fact is looked up, never asked:
428
+
429
+ 1. **codebase** — the answer is a fact in the repository; find it.
430
+ 2. **convention** — derivable from DNA invariants, AGENTS.md rules, established patterns; record as inference.
431
+ 3. **profile** — covered by `PREFERENCES.md`, `.agents/operator-profile.md`, or grilling `learned-principles.md` (`status: active`).
432
+ 4. **policy** — already answered by a batch-level `policies[]` entry or an identical earlier question.
433
+ 5. **none** — a genuine trade-off only the operator can settle → ledger entry.
434
+
435
+ Every ledger entry records which rung produced it (`resolutionPath`) — this disciplines the agent and gives the operator audit context. Inferences land in the ledger too (as briefing-visible "resolved-by-inference" rows) — the operator reviews them at the window but answers only genuine `none`-rung trade-offs.
436
+
437
+ ## Auto-resolve and log
438
+
439
+ Questions discovered during execution (emergent questions) do not interrupt the operator. The agent applies its recommended option and appends a ledger entry with `status: auto-resolved` — append-only evidence, disputable post-factum via a follow-up document, never silently decided.
440
+
441
+ Only the **hard-stop** class parks an item instead of auto-resolving:
442
+
443
+ 1. DNA-invariant changes or conflicts.
444
+ 2. Security or privacy impact.
445
+ 3. External-contract changes (Verbund, third-party APIs, published interfaces).
446
+ 4. Irreversible or data-destructive operations.
447
+ 5. Hard-block review verdicts surviving two fix→re-review cycles.
448
+
449
+ A hard-stopped question lands in the ledger as `status: open` + `parked: true`; the item parks, `dependsOn` dependents cascade-park, and the batch continues. These items surface for arbitration in the final batch report — or at the start of the next session with the same manifest.
@@ -49,7 +49,7 @@ The ecosystem has seven documentation surfaces. Each has a different audience an
49
49
  | **architecture-dna.md** | `ref(forge.yaml bindings.paths.invariantsFile)` | AI agents + humans | New DNA invariant, invariant amendment, or invariant retirement |
50
50
  | **Templates** | `packages/werkstatt-site/src/onboarding/templates/`, `packages/werkstatt-site/src/codegen/templates/` | Future apps/packages (scaffold time) | Change to what a new app or package should look like at creation time |
51
51
  | **Generated artifacts** | `docs/ecosystem.generated.json`, `docs/command-manifest.generated.yaml`, `fleet/*.generated.yaml`, `*.generated.css` | AI agents (read-only projection) | **Never edit directly** — update the generator or registry, then regenerate |
52
- | **COMMANDS / PACKAGE_GRAPH** | `docs/COMMANDS.md`, `docs/PACKAGE_GRAPH.md` | Humans + AI agents | New command, removed command, package graph change |
52
+ | **Command / ecosystem docs** | `docs/COMMANDS.md`, `docs/ecosystem.generated.yaml` | Humans + AI agents | New command, removed command, package graph change — regenerate via `docs.commands.generate` / `ecosystem.manifest.generate`, never hand-edit |
53
53
 
54
54
  ## Process
55
55
 
@@ -147,12 +147,12 @@ ref(forge.yaml bindings.commands.produce) --workspace=command.manifest.generate
147
147
 
148
148
  Note: if the regeneration command is expensive or unavailable in the current session, document the need to regenerate in the session summary and move on.
149
149
 
150
- #### 2g. COMMANDS.md / PACKAGE_GRAPH.md
150
+ #### 2g. Command / ecosystem doc surfaces
151
151
 
152
152
  - Were **commands** added, removed, or renamed?
153
153
  - Did the **package graph** change (new package, removed package, new dependency)?
154
154
 
155
- If yes, update `docs/COMMANDS.md` and/or `docs/PACKAGE_GRAPH.md`. If these are generated, update the generator instead (see 2f).
155
+ If yes, regenerate the owned projections — `docs.commands.generate` refreshes `docs/command-manifest.generated.yaml` + `docs/COMMANDS.md`; `ecosystem.manifest.generate` refreshes `docs/ecosystem.generated.yaml` (the successor of the retired `docs/PACKAGE_GRAPH.md`). Never hand-edit generated files — update the generator or registry (see 2f).
156
156
 
157
157
  ### 3. Present analysis to the operator
158
158
 
@@ -264,7 +264,7 @@ Skills that delegate to `fo-doc-audit`:
264
264
  - **`fo-fix`** step 5 ("Documentation audit") — invokes `fo-doc-audit`.
265
265
  - **`fo-fix`** merge conflict resolution step 4 ("Documentation audit") — invokes `fo-doc-audit`.
266
266
  - **`fo-idea-implement`** step 4.9 ("Documentation audit") — invokes `fo-doc-audit`.
267
- - **`fo-idea-implement`** ADR-FLOW step 5.6 ("Documentation audit") — invokes `fo-doc-audit`.
267
+ - **`fo-idea-implement`** step 5.6 ("Documentation audit", ADR path) — invokes `fo-doc-audit`.
268
268
 
269
269
  ## Constraints
270
270
 
@@ -9,7 +9,7 @@ languagePolicy: ref(PREFERENCES.md)
9
9
  bindings:
10
10
  requires: [paths.invariantsFile]
11
11
  optional: []
12
- triggerPhrases: ["explore this idea", "let me think about this", "what are the options for", "what if we"]
12
+ triggerPhrases: ["нам надо закрыть открытые вопросы", "explore this idea", "let me think about this", "what are the options for", "what if we"]
13
13
  ---
14
14
 
15
15
  <!--
@@ -23,6 +23,7 @@ triggerPhrases: ["explore this idea", "let me think about this", "what are the o
23
23
  <item>RFC-1097: sweep — SKILL.md headers + classification fixes
24
24
 
25
25
  Sweep batch 1: add Compass v2 headers to 45 SKILL.md files (purpose derived from frontmatter description). Fix non-skill-markdown exclusion to check filename not workspace-relative path (packages/AGENTS.md escaped it). Add .coverage to ignoredDirs.</item>
26
+ <item>RFC-1247: triggerPhrases vocabulary sync — mined operator phrasing applied to this skill's trigger set.</item>
26
27
  </CHANGE_SUMMARY>
27
28
  -->
28
29
 
@@ -9,7 +9,7 @@ languagePolicy: ref(PREFERENCES.md)
9
9
  bindings:
10
10
  requires: [commands.typecheck]
11
11
  optional: [commands.test, paths.invariantsFile]
12
- triggerPhrases: ["fix issues from review", "apply review findings and fix", "iterative fix workflow for code"]
12
+ triggerPhrases: ["исправим", "примени findings", "fix all", "fix issues from review", "apply review findings and fix"]
13
13
  ---
14
14
 
15
15
  <!--
@@ -20,9 +20,13 @@ triggerPhrases: ["fix issues from review", "apply review findings and fix", "ite
20
20
  </non-goals>
21
21
  </MODULE_CONTRACT>
22
22
  <CHANGE_SUMMARY>
23
+ <item>RFC-1250: orchestrated-run contract — ambiguous findings auto-resolve
24
+ with auto-resolved ledger entries; hard-stop class parks the item instead of
25
+ asking.</item>
23
26
  <item>RFC-1097: sweep — SKILL.md headers + classification fixes
24
27
 
25
28
  Sweep batch 1: add Compass v2 headers to 45 SKILL.md files (purpose derived from frontmatter description). Fix non-skill-markdown exclusion to check filename not workspace-relative path (packages/AGENTS.md escaped it). Add .coverage to ignoredDirs.</item>
29
+ <item>RFC-1247: triggerPhrases vocabulary sync — mined operator phrasing applied to this skill's trigger set.</item>
26
30
  </CHANGE_SUMMARY>
27
31
  -->
28
32
 
@@ -87,10 +91,14 @@ If the review used the legacy format (`[Critical errors]`, `[Warnings]`, `[Concr
87
91
  For each finding:
88
92
 
89
93
  - If it includes a concrete line range or code snippet, apply the change directly.
90
- - If it is ambiguous, ask the user before changing.
94
+ - If it is ambiguous, ask the user before changing — **except under an orchestrated queue run**: never call `ask_user_question` there. Auto-resolve the ambiguity with the recommended option and append a ledger entry `status: auto-resolved`; if the ambiguity falls in the hard-stop class (§Auto-resolve and log), append `status: open` + `parked: true` and park the item instead.
91
95
  - Do not delete or weaken existing tests without explicit direction.
92
96
  - Prefer minimal upstream fixes over downstream workarounds.
93
97
 
98
+ **Falsified-routes ledger** — before choosing a fix approach for a finding, read the plan's `## Falsified routes` section when the work item carries a plan file: a `Forbidden retry: yes` row rejects the approach unless you can state a new fact that invalidates its root cause. When a fix approach is abandoned after a real attempt, append a row (route, root cause, falsified-at evidence) before moving on — when no plan file exists, record the falsified route in the session output instead. See `_shared/fo-pipeline-conventions.md` §Falsified-routes ledger.
99
+
100
+ **Blind-spot pass after two failures on one approach** — after two failed attempts on the same fix approach, and before the next retry or pivot, run the clean-context blind-spot pass defined in `_shared/fo-pipeline-conventions.md` §Blind-spot pass.
101
+
94
102
  After applying fixes, update any tests that should cover the change, then run the relevant package tests before the full build when that saves time.
95
103
 
96
104
  ### 3. Run scoped typecheck verification
@@ -155,7 +163,7 @@ If no source files were touched, skip this step.
155
163
 
156
164
  This step is **always** performed — it is not optional and must not be skipped.
157
165
 
158
- Invoke `fo-doc-audit` via the `skill` tool. It analyzes the session's changes, checks all documentation surfaces (AGENTS.md, README, Compass XML, `ref(forge.yaml bindings.paths.invariantsFile)`, templates, generated artifacts, COMMANDS.md/PACKAGE_GRAPH.md), applies needed updates, and commits them separately. Wait for it to complete.
166
+ Invoke `fo-doc-audit` via the `skill` tool. It analyzes the session's changes, checks all documentation surfaces (AGENTS.md, README, Compass XML, `ref(forge.yaml bindings.paths.invariantsFile)`, templates, generated artifacts, generated command docs (COMMANDS.md, ecosystem.generated.yaml)), applies needed updates, and commits them separately. Wait for it to complete.
159
167
 
160
168
  If `fo-doc-audit` reports that no updates are needed, state this explicitly and move on — the check itself is the mandatory part, not the outcome.
161
169