@warpgogol/forge 5.3.4 → 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 (235) 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 +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/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 +93 -5
  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/exploration/exploration.module.d.ts.map +1 -1
  30. package/dist/os/exploration/exploration.module.js +3 -0
  31. package/dist/os/exploration/exploration.module.js.map +1 -1
  32. package/dist/os/naming/naming.module.d.ts.map +1 -1
  33. package/dist/os/naming/naming.module.js +9 -2
  34. package/dist/os/naming/naming.module.js.map +1 -1
  35. package/dist/os/notes/notes.module.d.ts.map +1 -1
  36. package/dist/os/notes/notes.module.js +17 -6
  37. package/dist/os/notes/notes.module.js.map +1 -1
  38. package/dist/os/plan/plan.module.d.ts.map +1 -1
  39. package/dist/os/plan/plan.module.js +2 -0
  40. package/dist/os/plan/plan.module.js.map +1 -1
  41. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  42. package/dist/os/plugin/plugin.module.js +9 -2
  43. package/dist/os/plugin/plugin.module.js.map +1 -1
  44. package/dist/os/program/program.module.d.ts.map +1 -1
  45. package/dist/os/program/program.module.js +19 -4
  46. package/dist/os/program/program.module.js.map +1 -1
  47. package/dist/os/queue/handlers/queue-validate.d.ts.map +1 -1
  48. package/dist/os/queue/handlers/queue-validate.js +154 -7
  49. package/dist/os/queue/handlers/queue-validate.js.map +1 -1
  50. package/dist/os/queue/manifest.d.ts +17 -1
  51. package/dist/os/queue/manifest.d.ts.map +1 -1
  52. package/dist/os/queue/manifest.js +127 -6
  53. package/dist/os/queue/manifest.js.map +1 -1
  54. package/dist/os/queue/queue.module.d.ts.map +1 -1
  55. package/dist/os/queue/queue.module.js +32 -4
  56. package/dist/os/queue/queue.module.js.map +1 -1
  57. package/dist/os/queue/types.d.ts +100 -1
  58. package/dist/os/queue/types.d.ts.map +1 -1
  59. package/dist/os/queue/types.js +44 -0
  60. package/dist/os/queue/types.js.map +1 -1
  61. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  62. package/dist/os/rfc/handlers/implement-stamp.js +28 -5
  63. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  64. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  65. package/dist/os/rfc/rfc.module.js +27 -3
  66. package/dist/os/rfc/rfc.module.js.map +1 -1
  67. package/dist/os/rfc/types.d.ts +11 -0
  68. package/dist/os/rfc/types.d.ts.map +1 -1
  69. package/dist/os/rfc/types.js +1 -0
  70. package/dist/os/rfc/types.js.map +1 -1
  71. package/dist/os/rfc/verification-evidence.d.ts +21 -0
  72. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  73. package/dist/os/rfc/verification-evidence.js +140 -23
  74. package/dist/os/rfc/verification-evidence.js.map +1 -1
  75. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  76. package/dist/os/rfc/verification-refresh.js +72 -37
  77. package/dist/os/rfc/verification-refresh.js.map +1 -1
  78. package/dist/os/session/handlers/save.d.ts.map +1 -1
  79. package/dist/os/session/handlers/save.js +46 -5
  80. package/dist/os/session/handlers/save.js.map +1 -1
  81. package/dist/os/session/session.module.d.ts.map +1 -1
  82. package/dist/os/session/session.module.js +5 -0
  83. package/dist/os/session/session.module.js.map +1 -1
  84. package/dist/os/spec/live-spec-merge.d.ts.map +1 -1
  85. package/dist/os/spec/live-spec-merge.js +55 -134
  86. package/dist/os/spec/live-spec-merge.js.map +1 -1
  87. package/dist/os/spec/live-spec-rebuild.d.ts +32 -0
  88. package/dist/os/spec/live-spec-rebuild.d.ts.map +1 -0
  89. package/dist/os/spec/live-spec-rebuild.js +272 -0
  90. package/dist/os/spec/live-spec-rebuild.js.map +1 -0
  91. package/dist/os/spec/live-spec-shared.d.ts +62 -0
  92. package/dist/os/spec/live-spec-shared.d.ts.map +1 -0
  93. package/dist/os/spec/live-spec-shared.js +315 -0
  94. package/dist/os/spec/live-spec-shared.js.map +1 -0
  95. package/dist/os/spec/live-spec-types.d.ts +17 -1
  96. package/dist/os/spec/live-spec-types.d.ts.map +1 -1
  97. package/dist/os/spec/live-spec-types.js +3 -0
  98. package/dist/os/spec/live-spec-types.js.map +1 -1
  99. package/dist/os/spec/live-spec-validate.d.ts.map +1 -1
  100. package/dist/os/spec/live-spec-validate.js +105 -2
  101. package/dist/os/spec/live-spec-validate.js.map +1 -1
  102. package/dist/os/spec/spec-materialize.d.ts +2 -0
  103. package/dist/os/spec/spec-materialize.d.ts.map +1 -1
  104. package/dist/os/spec/spec-materialize.js +45 -5
  105. package/dist/os/spec/spec-materialize.js.map +1 -1
  106. package/dist/os/spec/spec-schema.d.ts +19 -0
  107. package/dist/os/spec/spec-schema.d.ts.map +1 -1
  108. package/dist/os/spec/spec-schema.js +30 -0
  109. package/dist/os/spec/spec-schema.js.map +1 -1
  110. package/dist/os/spec/spec-status.d.ts +4 -0
  111. package/dist/os/spec/spec-status.d.ts.map +1 -1
  112. package/dist/os/spec/spec-status.js +19 -1
  113. package/dist/os/spec/spec-status.js.map +1 -1
  114. package/dist/os/spec/spec-validate.d.ts.map +1 -1
  115. package/dist/os/spec/spec-validate.js +55 -8
  116. package/dist/os/spec/spec-validate.js.map +1 -1
  117. package/dist/os/spec/spec.module.d.ts.map +1 -1
  118. package/dist/os/spec/spec.module.js +84 -8
  119. package/dist/os/spec/spec.module.js.map +1 -1
  120. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  121. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +10 -4
  122. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  123. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  124. package/dist/os/werkstatt/werkstatt.module.js +13 -4
  125. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  126. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  127. package/dist/os/workflow/workflow.module.js +13 -5
  128. package/dist/os/workflow/workflow.module.js.map +1 -1
  129. package/dist/src/cli-flags.d.ts.map +1 -1
  130. package/dist/src/cli-flags.js +25 -5
  131. package/dist/src/cli-flags.js.map +1 -1
  132. package/dist/src/config/forge-config.d.ts +3 -0
  133. package/dist/src/config/forge-config.d.ts.map +1 -1
  134. package/dist/src/config/forge-config.js +2 -0
  135. package/dist/src/config/forge-config.js.map +1 -1
  136. package/dist/src/onboarding/init.d.ts.map +1 -1
  137. package/dist/src/onboarding/init.js +8 -3
  138. package/dist/src/onboarding/init.js.map +1 -1
  139. package/dist/src/pipeline-status.d.ts +14 -1
  140. package/dist/src/pipeline-status.d.ts.map +1 -1
  141. package/dist/src/pipeline-status.js +28 -8
  142. package/dist/src/pipeline-status.js.map +1 -1
  143. package/dist/src/types.d.ts +7 -1
  144. package/dist/src/types.d.ts.map +1 -1
  145. package/dist/src/types.js +6 -0
  146. package/dist/src/types.js.map +1 -1
  147. package/dist/src/utils/generated-marker.d.ts +8 -0
  148. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  149. package/dist/src/utils/generated-marker.js +25 -0
  150. package/dist/src/utils/generated-marker.js.map +1 -1
  151. package/os/adr/adr.module.ts +2 -0
  152. package/os/audit/audit.module.ts +2 -0
  153. package/os/compass/compass.module.ts +49 -15
  154. package/os/compass/handlers/compass-audit-handler.ts +50 -9
  155. package/os/compass/handlers/compass-docs-validate.ts +359 -0
  156. package/os/compass/handlers/summary-record.ts +104 -5
  157. package/os/compass/handlers/tests/compass-audit-record.test.ts +2 -1
  158. package/os/compass/handlers/tests/compass-audit-validate.test.ts +92 -3
  159. package/os/compass/handlers/tests/compass-docs-validate.test.ts +203 -0
  160. package/os/compass/handlers/tests/compass-ledger-scope.test.ts +2 -1
  161. package/os/compass/handlers/tests/summary-record.test.ts +127 -0
  162. package/os/core/core.module.ts +147 -75
  163. package/os/core/docs-archive.test.ts +136 -0
  164. package/os/exploration/exploration.module.ts +3 -0
  165. package/os/naming/naming.module.ts +9 -2
  166. package/os/notes/notes.module.ts +17 -6
  167. package/os/plan/plan-0000-template.md +150 -0
  168. package/os/plan/plan.module.ts +2 -0
  169. package/os/plugin/plugin.module.ts +9 -2
  170. package/os/program/program.module.ts +19 -4
  171. package/os/queue/decision-ledger.test.ts +163 -0
  172. package/os/queue/handlers/queue-validate.ts +190 -8
  173. package/os/queue/manifest.ts +201 -7
  174. package/os/queue/queue-validate.test.ts +303 -0
  175. package/os/queue/queue.module.ts +32 -4
  176. package/os/queue/types.ts +56 -1
  177. package/os/rfc/handlers/implement-stamp.ts +35 -5
  178. package/os/rfc/rfc.module.ts +29 -3
  179. package/os/rfc/types.ts +17 -1
  180. package/os/rfc/verification-emit.test.ts +305 -0
  181. package/os/rfc/verification-evidence.ts +155 -24
  182. package/os/rfc/verification-refresh.test.ts +222 -1
  183. package/os/rfc/verification-refresh.ts +80 -38
  184. package/os/session/handlers/save.ts +41 -5
  185. package/os/session/session.module.ts +5 -0
  186. package/os/spec/live-spec-idempotency.pbt.test.ts +222 -0
  187. package/os/spec/live-spec-list-show-validate.test.ts +10 -6
  188. package/os/spec/live-spec-merge.test.ts +187 -7
  189. package/os/spec/live-spec-merge.ts +71 -155
  190. package/os/spec/live-spec-rebuild.test.ts +317 -0
  191. package/os/spec/live-spec-rebuild.ts +356 -0
  192. package/os/spec/live-spec-shared.ts +378 -0
  193. package/os/spec/live-spec-types.ts +21 -1
  194. package/os/spec/live-spec-validate.test.ts +317 -0
  195. package/os/spec/live-spec-validate.ts +106 -2
  196. package/os/spec/spec-materialize.test.ts +192 -0
  197. package/os/spec/spec-materialize.ts +48 -4
  198. package/os/spec/spec-schema.ts +49 -0
  199. package/os/spec/spec-status.ts +24 -0
  200. package/os/spec/spec-validate.test.ts +66 -0
  201. package/os/spec/spec-validate.ts +62 -8
  202. package/os/spec/spec.module.ts +85 -8
  203. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +10 -4
  204. package/os/werkstatt/werkstatt.module.ts +13 -4
  205. package/os/workflow/workflow.module.ts +13 -5
  206. package/package.json +1 -1
  207. package/skills/_shared/fo-pipeline-conventions.md +126 -1
  208. package/skills/fo/fo-doc-audit/SKILL.md +4 -4
  209. package/skills/fo/fo-explore/SKILL.md +2 -1
  210. package/skills/fo/fo-fix/SKILL.md +11 -3
  211. package/skills/fo/fo-handoff/SKILL.md +4 -6
  212. package/skills/fo/fo-idea-create-rfc/SKILL.md +2 -1
  213. package/skills/fo/fo-idea-enhance/SKILL.md +23 -4
  214. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +86 -22
  215. package/skills/fo/fo-idea-implement/SKILL.md +53 -10
  216. package/skills/fo/fo-idea-plan/SKILL.md +28 -6
  217. package/skills/fo/fo-review/SKILL.md +69 -8
  218. package/skills/fo/fo-session-retro/SKILL.md +3 -2
  219. package/skills/fo/fo-step-commit/SKILL.md +2 -0
  220. package/skills/shared/grilling/SKILL.md +12 -0
  221. package/skills/shared/writing-great-skills/GLOSSARY.md +2 -0
  222. package/skills/shared/writing-great-skills/SKILL.md +2 -1
  223. package/src/cli-flags.ts +23 -5
  224. package/src/config/forge-config.ts +4 -0
  225. package/src/onboarding/init.ts +8 -3
  226. package/src/pipeline-status.ts +32 -8
  227. package/src/tests/cli-flags.test.ts +20 -0
  228. package/src/tests/cli-output.test.ts +13 -7
  229. package/src/tests/fixtures/agents-generate-business-before.txt +7 -7
  230. package/src/tests/implement-stamp.test.ts +38 -0
  231. package/src/tests/session-handlers.test.ts +33 -0
  232. package/src/types.ts +13 -1
  233. package/src/utils/generated-marker.ts +28 -0
  234. package/skills/fo/fo-idea-implement/ADR-FLOW.md +0 -179
  235. package/skills/fo/fo-review/AXES.md +0 -70
@@ -2,156 +2,31 @@
2
2
  <MODULE_CONTRACT>
3
3
  <purpose>spec.live.merge handler — extracts deltas from an RFC's ## Design section,
4
4
  classifies them as ADDED/MODIFIED/REMOVED, applies to a living spec with RFC-namespaced
5
- headings, and writes atomically (RFC-0711).</purpose>
5
+ headings, and writes atomically (RFC-0711). Idempotent since RFC-1230: an RFC already
6
+ present in spec history[] is skipped as already-merged unless --force re-merges it.</purpose>
6
7
  <non-goals>
7
8
  <item>Do not handle docs.archive integration — that is in core.module.ts.</item>
8
9
  <item>Do not validate living specs — that is spec.live.validate.</item>
10
+ <item>Do not repair corrupted specs — that is spec.live.rebuild.</item>
9
11
  </non-goals>
10
- </MODULE_CONTRACT>
11
12
  <CHANGE_SUMMARY>
12
13
  <item>RFC-0711: initial spec.live.merge handler with delta extraction, classification, and atomic writes.</item>
13
14
  <item>RFC-0957: namespace headings by RFC ID, remove conflict detection (structurally impossible with namespacing).</item>
15
+ <item>RFC-1230: idempotent merge — already-merged gate keyed on spec history[], --force surgical re-merge via removeNamespacedSections, fail-fast on spec file with unparseable frontmatter; pure helpers moved to live-spec-shared.ts.</item>
16
+ <item>RFC-1230: review findings — scoped droppedSections to namespaced headings, warn on unreadable spec, fail-fast merge on corrupt frontmatter, CHANGE_SUMMARY dedupe</item>
14
17
  </CHANGE_SUMMARY>
15
18
  */
16
19
  import { ambientIo as fs } from "../../src/utils/io.js";
17
20
  import { existsSync } from "../../src/utils/sync-fs.js";
18
21
  import path from "node:path";
19
- import YAML from "yaml";
20
22
  import { writeFileIfChanged, buildGeneratedHeader } from "../../src/utils/index.js";
21
- import { parseRfcFile, listRfcFiles } from "../rfc/frontmatter-io.js";
23
+ import { parseRfcFile } from "../rfc/frontmatter-io.js";
22
24
  import { RFC_DIR } from "../rfc/types.js";
23
- const LIVE_SPECS_DIR = "docs/specs/live";
24
- function extractDesignSection(rfcBody) {
25
- const designMatch = rfcBody.match(/^##\s+Design\s*$/m);
26
- if (!designMatch)
27
- return "";
28
- const startIndex = designMatch.index + designMatch[0].length;
29
- const nextH2Match = rfcBody.slice(startIndex).match(/^##\s+/m);
30
- if (!nextH2Match) {
31
- return rfcBody.slice(startIndex).trim();
32
- }
33
- return rfcBody.slice(startIndex, startIndex + nextH2Match.index).trim();
34
- }
35
- function parseHeadings(content) {
36
- const lines = content.split("\n");
37
- const headings = [];
38
- let currentHeading = null;
39
- let currentBody = [];
40
- for (const line of lines) {
41
- const headingMatch = line.match(/^(#{3,})\s+(.+)$/);
42
- if (headingMatch) {
43
- if (currentHeading) {
44
- currentHeading.body = currentBody.join("\n").trim();
45
- headings.push(currentHeading);
46
- }
47
- currentHeading = {
48
- level: headingMatch[1].length,
49
- text: headingMatch[2].trim(),
50
- body: "",
51
- };
52
- currentBody = [];
53
- }
54
- else if (currentHeading) {
55
- currentBody.push(line);
56
- }
57
- }
58
- if (currentHeading) {
59
- currentHeading.body = currentBody.join("\n").trim();
60
- headings.push(currentHeading);
61
- }
62
- return headings;
63
- }
64
- function deriveDomain(frontmatter) {
65
- const liveSpec = frontmatter["liveSpec"];
66
- if (typeof liveSpec === "string" && liveSpec.length > 0) {
67
- return liveSpec;
68
- }
69
- if (liveSpec === true) {
70
- const packagesImpacted = frontmatter["packagesImpacted"];
71
- if (Array.isArray(packagesImpacted) && packagesImpacted.length > 0) {
72
- const firstPkg = String(packagesImpacted[0]);
73
- return firstPkg.replace(/^packages\//, "").replace(/^@[^/]+\//, "");
74
- }
75
- return null;
76
- }
77
- return null;
78
- }
79
- function parseLivingSpec(content) {
80
- const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
81
- if (!match)
82
- return null;
83
- const fm = (YAML.parse(match[1]) ?? {});
84
- return {
85
- domain: String(fm["domain"] ?? ""),
86
- title: String(fm["title"] ?? ""),
87
- lastMergedRfc: String(fm["lastMergedRfc"] ?? ""),
88
- updatedAt: String(fm["updatedAt"] ?? ""),
89
- createdAt: String(fm["createdAt"] ?? ""),
90
- history: (Array.isArray(fm["history"]) ? fm["history"] : []),
91
- body: match[2] ?? "",
92
- };
93
- }
94
- function serializeLivingSpec(spec) {
95
- const fm = {
96
- domain: spec.domain,
97
- title: spec.title,
98
- lastMergedRfc: spec.lastMergedRfc,
99
- updatedAt: spec.updatedAt,
100
- createdAt: spec.createdAt,
101
- history: spec.history,
102
- };
103
- const fmStr = YAML.stringify(fm).trimEnd();
104
- return `---\n${fmStr}\n---\n\n${spec.body}`;
105
- }
106
- function findHeadingInSpec(spec, headingText) {
107
- const headings = parseHeadings(spec.body);
108
- return headings.find((h) => h.text === headingText) ?? null;
109
- }
110
- function applyDeltasToSpecBody(specBody, deltas, operations) {
111
- let body = specBody;
112
- for (const delta of deltas) {
113
- const op = operations.find((o) => o.heading === delta.text);
114
- if (!op)
115
- continue;
116
- if (op.type === "added") {
117
- body = `${body}\n\n${"#".repeat(delta.level)} ${delta.text}\n\n${delta.body}`;
118
- }
119
- else if (op.type === "modified") {
120
- const headingRegex = new RegExp(`(${"#".repeat(delta.level)}\\s+${escapeRegex(delta.text)}\\s*\\n)([\\s\\S]*?)(?=#{3,}|$)`);
121
- body = body.replace(headingRegex, `$1\n${delta.body}\n`);
122
- }
123
- else if (op.type === "removed") {
124
- const headingRegex = new RegExp(`\\n*${"#".repeat(delta.level)}\\s+${escapeRegex(delta.text)}\\s*\\n[\\s\\S]*?(?=#{3,}|$)`);
125
- body = body.replace(headingRegex, "\n");
126
- }
127
- }
128
- return body.trim();
129
- }
130
- function escapeRegex(str) {
131
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
132
- }
133
- function namespaceHeadings(content, rfcId) {
134
- return content.replace(/^(#{3,})\s+(.+)$/gm, (_match, hashes, text) => {
135
- if (/\(RFC-\d{4}\)$/.test(text))
136
- return `${hashes} ${text}`;
137
- return `${hashes} ${text} (${rfcId})`;
138
- });
139
- }
140
- function findRfcFile(rfcDir, rfcId) {
141
- return (async () => {
142
- const files = await listRfcFiles(rfcDir);
143
- for (const file of files) {
144
- const basename = path.basename(file);
145
- if (basename.toLowerCase().startsWith(rfcId.toLowerCase())) {
146
- return file;
147
- }
148
- }
149
- return null;
150
- })();
151
- }
25
+ import { LIVE_SPECS_DIR, extractDesignSection, parseHeadings, deriveDomain, parseLivingSpec, serializeLivingSpec, findHeadingInSpec, applyDeltasToSpecBody, namespaceHeadings, removeNamespacedSections, findRfcFile, seedSpecPrefix, } from "./live-spec-shared.js";
152
26
  export async function runSpecLiveMerge(input, context) {
153
27
  const { workspaceRoot, logger, outputFormat } = context;
154
28
  const rfcId = String(input.flags["id"] ?? "");
29
+ const force = input.flags["force"] === true;
155
30
  const dryRun = context.dryRun || input.flags["dry-run"] === true;
156
31
  if (!rfcId) {
157
32
  return {
@@ -239,6 +114,52 @@ export async function runSpecLiveMerge(input, context) {
239
114
  if (existsSync(specFilePath)) {
240
115
  const specContent = await fs.readFile(specFilePath);
241
116
  existingSpec = parseLivingSpec(specContent);
117
+ // A spec file whose frontmatter cannot be parsed must not be silently
118
+ // overwritten by the creation path — that would discard its history[].
119
+ if (!existingSpec) {
120
+ return {
121
+ data: {
122
+ command: "spec.live.merge",
123
+ domain,
124
+ operation: "modified",
125
+ deltas: [],
126
+ conflicts: [],
127
+ dryRun,
128
+ },
129
+ exitCode: 1,
130
+ summary: `spec.live.merge: ${domain}.md exists but has no valid frontmatter — inspect or repair via spec.live.rebuild`,
131
+ };
132
+ }
133
+ }
134
+ // RFC-1230: idempotency gate — an RFC already in history[] is a no-op unless
135
+ // --force surgically re-merges (strips its namespaced sections + old entries).
136
+ if (existingSpec) {
137
+ const alreadyMerged = existingSpec.history.some((h) => h.rfc === rfcId);
138
+ if (alreadyMerged && !force) {
139
+ const result = {
140
+ command: "spec.live.merge",
141
+ domain,
142
+ operation: "already-merged",
143
+ deltas: [],
144
+ conflicts: [],
145
+ dryRun,
146
+ };
147
+ if (outputFormat === "pretty") {
148
+ logger.info(`spec.live.merge: ${rfcId} already merged into "${domain}" — skipping (use --force to re-merge)`);
149
+ }
150
+ return {
151
+ data: result,
152
+ exitCode: 0,
153
+ summary: `spec.live.merge: ${rfcId} already merged into ${domain}`,
154
+ };
155
+ }
156
+ if (force) {
157
+ existingSpec = {
158
+ ...existingSpec,
159
+ body: removeNamespacedSections(existingSpec.body, rfcId),
160
+ history: existingSpec.history.filter((h) => h.rfc !== rfcId),
161
+ };
162
+ }
242
163
  }
243
164
  const operations = [];
244
165
  const today = new Date().toISOString().slice(0, 10);
@@ -258,7 +179,7 @@ export async function runSpecLiveMerge(input, context) {
258
179
  updatedAt: today,
259
180
  createdAt: today,
260
181
  history: [{ rfc: rfcId, mergedAt: today, operation: "created" }],
261
- body: `${header}# Living Spec: ${domain}\n\n## Overview\n\n${designSection}`,
182
+ body: `${seedSpecPrefix(domain, header)}${designSection}`,
262
183
  };
263
184
  if (!dryRun) {
264
185
  await fs.mkdir(liveSpecsDir);
@@ -1 +1 @@
1
- {"version":3,"file":"live-spec-merge.js","sourceRoot":"","sources":["../../../os/spec/live-spec-merge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"live-spec-merge.js","sourceRoot":"","sources":["../../../os/spec/live-spec-merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { ForgeCommandInput, ForgeCommandResult, ForgeRuntimeContext } from "../../src/types.ts";
2
+ import type { LivingSpec, SpecLiveRebuildResult } from "./live-spec-types.ts";
3
+ interface RebuildSummary {
4
+ command: "spec.live.rebuild";
5
+ domains: SpecLiveRebuildResult[];
6
+ dryRun: boolean;
7
+ }
8
+ /** Pure projection core (RFC-1234): reads the spec and replays its history
9
+ * into the canonical regenerated bytes — no writes, no logging. The
10
+ * `projection` field is serialized with the spec's own `updatedAt`, so
11
+ * byte-equality with the committed file means "no drift". Consumed by
12
+ * rebuild (write path) and by spec.live.validate V-LS-09 (compare only). */
13
+ export type LiveSpecProjection = {
14
+ kind: "unreadable";
15
+ } | {
16
+ kind: "invalid-frontmatter";
17
+ } | {
18
+ kind: "empty-history";
19
+ } | {
20
+ kind: "projected";
21
+ spec: LivingSpec;
22
+ content: string;
23
+ projection: string;
24
+ regenerated: LivingSpec;
25
+ uniqueIds: string[];
26
+ unreadableRfcs: string[];
27
+ droppedSections: number;
28
+ };
29
+ export declare function projectLiveSpec(specFilePath: string, domain: string, rfcFiles: readonly string[], rfcDirPath: string): Promise<LiveSpecProjection>;
30
+ export declare function runSpecLiveRebuild(input: ForgeCommandInput, context: ForgeRuntimeContext): Promise<ForgeCommandResult<RebuildSummary | SpecLiveRebuildResult>>;
31
+ export {};
32
+ //# sourceMappingURL=live-spec-rebuild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-spec-rebuild.d.ts","sourceRoot":"","sources":["../../../os/spec/live-spec-rebuild.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAEV,UAAU,EAEV,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAY9B,UAAU,cAAc;IACtB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;4EAI4E;AAC5E,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AAyFD,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,cAAc,GAAG,qBAAqB,CAAC,CAAC,CAgGrE"}
@@ -0,0 +1,272 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>spec.live.rebuild handler — regenerates a living spec by deterministic
4
+ replay of its deduplicated history[] (RFC-1230). The repair path for duplicated
5
+ namespaced sections and duplicate history entries produced before spec.live.merge
6
+ became idempotent. Replaying each unique RFC's current ## Design in first-occurrence
7
+ order yields the canonical spec; hand-applied edits are dropped by design.</purpose>
8
+ <non-goals>
9
+ <item>Do not merge new RFCs — that is spec.live.merge.</item>
10
+ <item>Do not validate — spec.live.validate reports what rebuild must repair.</item>
11
+ <item>Do not delete spec files — empty-history or missing specs are skipped, never removed.</item>
12
+ </non-goals>
13
+ <CHANGE_SUMMARY>
14
+ <item>RFC-1230: initial spec.live.rebuild handler — dedupe history, single RFC scan, replay via shared section mechanics, unchanged-detection modulo updatedAt.</item>
15
+ <item>RFC-1230: review findings — scoped droppedSections to namespaced headings, warn on unreadable spec, fail-fast merge on corrupt frontmatter, CHANGE_SUMMARY dedupe</item>
16
+ <item>RFC-1231: step 1 — rename supportsAllSites to acceptsAllFlag
17
+
18
+ Mechanical sweep: the field only ever gated --all argv acceptance; fan-out
19
+ follows the parsed selector. Guard renamed assertAllSitesAllowed ->
20
+ assertAllFlagAccepted, message updated. 417 declaration sites + type
21
+ surfaces (KernelCommandMetadata, ForgeCommandMetadata) in one atomic pass.</item>
22
+ <item>RFC-1234: extracted projectLiveSpec — the pure projection core (dedupe history, replay Design sections, serialize modulo updatedAt) — consumable without writes or logging; spec.live.validate V-LS-09 reuses it so the validator sees exactly what rebuild would write.</item>
23
+ </CHANGE_SUMMARY>
24
+ */
25
+ import { ambientIo as fs } from "../../src/utils/io.js";
26
+ import { existsSync } from "../../src/utils/sync-fs.js";
27
+ import path from "node:path";
28
+ import { writeFileIfChanged, buildGeneratedHeader } from "../../src/utils/index.js";
29
+ import { listRfcFiles, readAndParseRfc, rfcFileMatchesId } from "../rfc/frontmatter-io.js";
30
+ import { RFC_DIR } from "../rfc/types.js";
31
+ import { LIVE_SPECS_DIR, extractDesignSection, parseHeadings, parseLivingSpec, serializeLivingSpec, applyDeltasToSpecBody, namespaceHeadings, seedSpecPrefix, } from "./live-spec-shared.js";
32
+ export async function projectLiveSpec(specFilePath, domain, rfcFiles, rfcDirPath) {
33
+ const content = await fs.readFile(specFilePath).catch(() => null);
34
+ if (content === null)
35
+ return { kind: "unreadable" };
36
+ const spec = parseLivingSpec(content);
37
+ if (!spec)
38
+ return { kind: "invalid-frontmatter" };
39
+ if (spec.history.length === 0)
40
+ return { kind: "empty-history" };
41
+ const uniqueIds = [];
42
+ const normalizedHistory = [];
43
+ for (const entry of spec.history) {
44
+ if (!entry?.rfc || uniqueIds.includes(entry.rfc))
45
+ continue;
46
+ uniqueIds.push(entry.rfc);
47
+ normalizedHistory.push(entry);
48
+ }
49
+ // Count only namespaced duplicates — the metric is "duplicate (RFC-XXXX)
50
+ // sections removed"; non-namespaced heading repeats are out of contract.
51
+ const existingHeadings = parseHeadings(spec.body);
52
+ const seenTexts = new Set();
53
+ let droppedSections = 0;
54
+ for (const h of existingHeadings) {
55
+ if (!/\(RFC-\d{4}\)$/.test(h.text))
56
+ continue;
57
+ if (seenTexts.has(h.text))
58
+ droppedSections++;
59
+ else
60
+ seenTexts.add(h.text);
61
+ }
62
+ const header = buildGeneratedHeader({
63
+ filePath: specFilePath,
64
+ ownerCommand: "spec.live.merge",
65
+ commandPrefix: "pnpm exec werkstatt run",
66
+ });
67
+ // trimEnd so applyDeltas' own "\n\n" separator reproduces the creation path's
68
+ // `seed + designSection` layout exactly — otherwise rebuild inserts an extra
69
+ // blank line after "## Overview" and unchanged-detection never fires.
70
+ let body = seedSpecPrefix(domain, header).trimEnd();
71
+ const unreadableRfcs = [];
72
+ for (const rfcId of uniqueIds) {
73
+ const file = rfcFiles.find((f) => rfcFileMatchesId(f, rfcId));
74
+ const parsedResult = file
75
+ ? await readAndParseRfc(rfcDirPath, file)
76
+ : undefined;
77
+ const fm = parsedResult && "parsed" in parsedResult ? parsedResult.parsed.frontmatter : undefined;
78
+ const status = fm ? String(fm["status"] ?? "").trim() : "";
79
+ const design = parsedResult && "parsed" in parsedResult
80
+ ? extractDesignSection(parsedResult.parsed.body)
81
+ : "";
82
+ if (!fm || status !== "implemented" || !design) {
83
+ unreadableRfcs.push(rfcId);
84
+ continue;
85
+ }
86
+ const namespaced = namespaceHeadings(design, rfcId);
87
+ const headings = parseHeadings(namespaced);
88
+ const ops = headings.map((h) => ({
89
+ type: "added",
90
+ heading: h.text,
91
+ rfc: rfcId,
92
+ }));
93
+ body = applyDeltasToSpecBody(body, headings, ops);
94
+ }
95
+ const regenerated = {
96
+ ...spec,
97
+ lastMergedRfc: uniqueIds[uniqueIds.length - 1],
98
+ history: normalizedHistory,
99
+ body: body.trim(),
100
+ };
101
+ // Compare modulo updatedAt — a clean spec rebuilt on another day must still
102
+ // report unchanged, otherwise every rebuild produces a one-line date diff.
103
+ const projection = serializeLivingSpec({ ...regenerated, updatedAt: spec.updatedAt });
104
+ return {
105
+ kind: "projected",
106
+ spec,
107
+ content,
108
+ projection,
109
+ regenerated,
110
+ uniqueIds,
111
+ unreadableRfcs,
112
+ droppedSections,
113
+ };
114
+ }
115
+ async function rebuildOneSpec(specFilePath, domain, rfcFiles, rfcDirPath, today, dryRun, context) {
116
+ const { logger } = context;
117
+ const base = {
118
+ command: "spec.live.rebuild",
119
+ domain,
120
+ operation: "skipped",
121
+ uniqueRfcs: 0,
122
+ droppedHistoryEntries: 0,
123
+ droppedSections: 0,
124
+ unreadableRfcs: [],
125
+ dryRun,
126
+ };
127
+ const proj = await projectLiveSpec(specFilePath, domain, rfcFiles, rfcDirPath);
128
+ if (proj.kind === "unreadable") {
129
+ logger.warn(`spec.live.rebuild: ${domain} unreadable at ${specFilePath} — skipping`);
130
+ return { result: base, exitCode: 1 };
131
+ }
132
+ if (proj.kind === "invalid-frontmatter") {
133
+ logger.warn(`spec.live.rebuild: ${domain} has no valid frontmatter — skipping`);
134
+ return { result: base, exitCode: 1 };
135
+ }
136
+ if (proj.kind === "empty-history") {
137
+ return { result: base, exitCode: 0 };
138
+ }
139
+ for (const rfcId of proj.unreadableRfcs) {
140
+ logger.warn(`spec.live.rebuild: ${rfcId} unreadable, not implemented, or lacks ## Design — skipping`);
141
+ }
142
+ const replayed = proj.uniqueIds.length - proj.unreadableRfcs.length;
143
+ if (replayed === 0) {
144
+ return {
145
+ result: {
146
+ ...base,
147
+ operation: "skipped",
148
+ uniqueRfcs: proj.uniqueIds.length,
149
+ unreadableRfcs: proj.unreadableRfcs,
150
+ },
151
+ exitCode: 2,
152
+ };
153
+ }
154
+ const droppedHistoryEntries = proj.spec.history.length - proj.regenerated.history.length;
155
+ if (proj.projection === proj.content) {
156
+ return {
157
+ result: {
158
+ ...base,
159
+ operation: "unchanged",
160
+ uniqueRfcs: proj.uniqueIds.length,
161
+ droppedHistoryEntries,
162
+ droppedSections: proj.droppedSections,
163
+ unreadableRfcs: proj.unreadableRfcs,
164
+ },
165
+ exitCode: 0,
166
+ };
167
+ }
168
+ const finalSpec = serializeLivingSpec({ ...proj.regenerated, updatedAt: today });
169
+ if (!dryRun) {
170
+ await writeFileIfChanged(specFilePath, finalSpec);
171
+ }
172
+ return {
173
+ result: {
174
+ ...base,
175
+ operation: "rebuilt",
176
+ uniqueRfcs: proj.uniqueIds.length,
177
+ droppedHistoryEntries,
178
+ droppedSections: proj.droppedSections,
179
+ unreadableRfcs: proj.unreadableRfcs,
180
+ },
181
+ exitCode: 0,
182
+ };
183
+ }
184
+ export async function runSpecLiveRebuild(input, context) {
185
+ const { workspaceRoot, logger, outputFormat } = context;
186
+ const domain = String(input.flags["domain"] ?? "");
187
+ const dryRun = context.dryRun || input.flags["dry-run"] === true;
188
+ // The kernel consumes `--all` as its own site-selector before argv reaches
189
+ // the command (acceptsAllFlag: true lets it through). Under `werkstatt run`
190
+ // the flag never lands in input.flags — so "no --domain" IS the kernel-level
191
+ // --all signal. The explicit flag still works via the standalone forge CLI.
192
+ const explicitAll = input.flags["all"] === true;
193
+ if (domain && explicitAll) {
194
+ return {
195
+ data: {
196
+ command: "spec.live.rebuild",
197
+ domains: [],
198
+ dryRun,
199
+ },
200
+ exitCode: 1,
201
+ summary: "spec.live.rebuild: --domain and --all are mutually exclusive",
202
+ };
203
+ }
204
+ const all = explicitAll || !domain;
205
+ const liveSpecsDir = path.join(workspaceRoot, LIVE_SPECS_DIR);
206
+ const rfcDirPath = path.join(workspaceRoot, RFC_DIR);
207
+ const today = new Date().toISOString().slice(0, 10);
208
+ const specPaths = [];
209
+ if (all) {
210
+ if (existsSync(liveSpecsDir)) {
211
+ const files = (await fs.readdir(liveSpecsDir)).map((e) => e.name);
212
+ for (const f of files.filter((f) => f.endsWith(".md") && f !== "README.md").sort()) {
213
+ specPaths.push({ domain: f.slice(0, -3), filePath: path.join(liveSpecsDir, f) });
214
+ }
215
+ }
216
+ }
217
+ else {
218
+ const filePath = path.join(liveSpecsDir, `${domain}.md`);
219
+ if (!existsSync(filePath)) {
220
+ return {
221
+ data: {
222
+ command: "spec.live.rebuild",
223
+ domains: [],
224
+ dryRun,
225
+ },
226
+ exitCode: 1,
227
+ summary: `spec.live.rebuild: living spec not found for domain "${domain}" (${LIVE_SPECS_DIR}/${domain}.md)`,
228
+ };
229
+ }
230
+ specPaths.push({ domain, filePath });
231
+ }
232
+ if (specPaths.length === 0) {
233
+ return {
234
+ data: { command: "spec.live.rebuild", domains: [], dryRun },
235
+ exitCode: 0,
236
+ summary: "spec.live.rebuild: no living specs found",
237
+ };
238
+ }
239
+ // Single recursive RFC scan reused for every spec — a corrupted spec can carry
240
+ // ~170 history entries, and a per-id listRfcFiles rescan is O(n²).
241
+ const rfcFiles = await listRfcFiles(rfcDirPath);
242
+ const results = [];
243
+ let worstExit = 0;
244
+ for (const { domain: d, filePath } of specPaths) {
245
+ const { result, exitCode } = await rebuildOneSpec(filePath, d, rfcFiles, rfcDirPath, today, dryRun, context);
246
+ results.push(result);
247
+ if (exitCode > worstExit)
248
+ worstExit = exitCode;
249
+ if (outputFormat === "pretty") {
250
+ const suffix = dryRun ? " [dry-run]" : "";
251
+ if (result.operation === "rebuilt") {
252
+ logger.success(`spec.live.rebuild: ${d} rebuilt — ${result.uniqueRfcs} unique RFC(s), dropped ${result.droppedHistoryEntries} history entr(ies), ${result.droppedSections} duplicate section(s)${suffix}`);
253
+ }
254
+ else {
255
+ logger.info(`spec.live.rebuild: ${d} — ${result.operation}${suffix}`);
256
+ }
257
+ }
258
+ }
259
+ if (!all) {
260
+ return {
261
+ data: results[0],
262
+ exitCode: worstExit,
263
+ summary: `spec.live.rebuild: ${domain} — ${results[0].operation}`,
264
+ };
265
+ }
266
+ return {
267
+ data: { command: "spec.live.rebuild", domains: results, dryRun },
268
+ exitCode: worstExit,
269
+ summary: `spec.live.rebuild: ${results.length} spec(s) processed${dryRun ? " [dry-run]" : ""}`,
270
+ };
271
+ }
272
+ //# sourceMappingURL=live-spec-rebuild.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-spec-rebuild.js","sourceRoot":"","sources":["../../../os/spec/live-spec-rebuild.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { LivingSpec, DeltaOperation } from "./live-spec-types.ts";
2
+ export declare const LIVE_SPECS_DIR = "docs/specs/live";
3
+ export interface ParsedHeading {
4
+ level: number;
5
+ text: string;
6
+ body: string;
7
+ }
8
+ export declare function extractDesignSection(rfcBody: string): string;
9
+ export declare function parseHeadings(content: string): ParsedHeading[];
10
+ export declare function deriveDomain(frontmatter: Record<string, unknown>): string | null;
11
+ export declare function parseLivingSpec(content: string): LivingSpec | null;
12
+ export declare function serializeLivingSpec(spec: LivingSpec): string;
13
+ export declare function findHeadingInSpec(spec: LivingSpec, headingText: string): ParsedHeading | null;
14
+ export declare function applyDeltasToSpecBody(specBody: string, deltas: ParsedHeading[], operations: DeltaOperation[]): string;
15
+ export declare function escapeRegex(str: string): string;
16
+ export declare function namespaceHeadings(content: string, rfcId: string): string;
17
+ export declare function removeNamespacedSections(body: string, rfcId: string): string;
18
+ export declare function findRfcFile(rfcDir: string, rfcId: string): Promise<string | null>;
19
+ export declare function seedSpecPrefix(domain: string, generatedHeader: string): string;
20
+ export interface LiveMergeTargetSelection {
21
+ candidates: string[];
22
+ rejected: string[];
23
+ }
24
+ export declare function collectLiveMergeTargets(moved: ReadonlyArray<{
25
+ id: string;
26
+ status: string;
27
+ direction: string;
28
+ }>): LiveMergeTargetSelection;
29
+ export interface LiveMergeEntry {
30
+ id: string;
31
+ domain: string;
32
+ operation: string;
33
+ conflicts: number;
34
+ }
35
+ export interface LiveMergeFailure {
36
+ id: string;
37
+ exitCode?: number;
38
+ error: string;
39
+ }
40
+ export type LiveMergeOutcome = {
41
+ kind: "merged";
42
+ entry: LiveMergeEntry;
43
+ } | {
44
+ kind: "failed";
45
+ entry: LiveMergeFailure;
46
+ };
47
+ export declare function classifyLiveMergeOutcome(rfcId: string, result: {
48
+ exitCode?: number;
49
+ data?: unknown;
50
+ summary?: string;
51
+ }): LiveMergeOutcome;
52
+ export declare function liveMergeFailureEntry(rfcId: string, error: unknown): LiveMergeFailure;
53
+ export declare function formatLiveMergeFailure(entry: LiveMergeFailure): string;
54
+ /** Emission gate + block assembly for results["spec.live.merge"] — undefined
55
+ * when nothing was attempted, so an all-failed run still surfaces. */
56
+ export declare function buildLiveMergeBlock(merged: LiveMergeEntry[], failed: LiveMergeFailure[], skipped: number, dryRun: boolean): {
57
+ merged: LiveMergeEntry[];
58
+ failed: LiveMergeFailure[];
59
+ skipped: number;
60
+ dryRun: boolean;
61
+ } | undefined;
62
+ //# sourceMappingURL=live-spec-shared.d.ts.map