@accelerator-mzq/forge 1.4.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 (663) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE-THIRD-PARTY.md +50 -0
  3. package/README.md +159 -0
  4. package/dist/cli/commands/ack.d.ts +7 -0
  5. package/dist/cli/commands/ack.d.ts.map +1 -0
  6. package/dist/cli/commands/ack.js +223 -0
  7. package/dist/cli/commands/ack.js.map +1 -0
  8. package/dist/cli/commands/archive.d.ts +44 -0
  9. package/dist/cli/commands/archive.d.ts.map +1 -0
  10. package/dist/cli/commands/archive.js +689 -0
  11. package/dist/cli/commands/archive.js.map +1 -0
  12. package/dist/cli/commands/backlog.d.ts +3 -0
  13. package/dist/cli/commands/backlog.d.ts.map +1 -0
  14. package/dist/cli/commands/backlog.js +55 -0
  15. package/dist/cli/commands/backlog.js.map +1 -0
  16. package/dist/cli/commands/config.d.ts +3 -0
  17. package/dist/cli/commands/config.d.ts.map +1 -0
  18. package/dist/cli/commands/config.js +107 -0
  19. package/dist/cli/commands/config.js.map +1 -0
  20. package/dist/cli/commands/evidence.d.ts +7 -0
  21. package/dist/cli/commands/evidence.d.ts.map +1 -0
  22. package/dist/cli/commands/evidence.js +662 -0
  23. package/dist/cli/commands/evidence.js.map +1 -0
  24. package/dist/cli/commands/finding.d.ts +3 -0
  25. package/dist/cli/commands/finding.d.ts.map +1 -0
  26. package/dist/cli/commands/finding.js +93 -0
  27. package/dist/cli/commands/finding.js.map +1 -0
  28. package/dist/cli/commands/init.d.ts +3 -0
  29. package/dist/cli/commands/init.d.ts.map +1 -0
  30. package/dist/cli/commands/init.js +126 -0
  31. package/dist/cli/commands/init.js.map +1 -0
  32. package/dist/cli/commands/legacy-bridge.d.ts +11 -0
  33. package/dist/cli/commands/legacy-bridge.d.ts.map +1 -0
  34. package/dist/cli/commands/legacy-bridge.js +586 -0
  35. package/dist/cli/commands/legacy-bridge.js.map +1 -0
  36. package/dist/cli/commands/migrate.d.ts +3 -0
  37. package/dist/cli/commands/migrate.d.ts.map +1 -0
  38. package/dist/cli/commands/migrate.js +34 -0
  39. package/dist/cli/commands/migrate.js.map +1 -0
  40. package/dist/cli/commands/monitor.d.ts +3 -0
  41. package/dist/cli/commands/monitor.d.ts.map +1 -0
  42. package/dist/cli/commands/monitor.js +113 -0
  43. package/dist/cli/commands/monitor.js.map +1 -0
  44. package/dist/cli/commands/preflight.d.ts +7 -0
  45. package/dist/cli/commands/preflight.d.ts.map +1 -0
  46. package/dist/cli/commands/preflight.js +63 -0
  47. package/dist/cli/commands/preflight.js.map +1 -0
  48. package/dist/cli/commands/scope.d.ts +3 -0
  49. package/dist/cli/commands/scope.d.ts.map +1 -0
  50. package/dist/cli/commands/scope.js +32 -0
  51. package/dist/cli/commands/scope.js.map +1 -0
  52. package/dist/cli/commands/stage-extensions.d.ts +45 -0
  53. package/dist/cli/commands/stage-extensions.d.ts.map +1 -0
  54. package/dist/cli/commands/stage-extensions.js +590 -0
  55. package/dist/cli/commands/stage-extensions.js.map +1 -0
  56. package/dist/cli/commands/update.d.ts +3 -0
  57. package/dist/cli/commands/update.d.ts.map +1 -0
  58. package/dist/cli/commands/update.js +98 -0
  59. package/dist/cli/commands/update.js.map +1 -0
  60. package/dist/cli/commands/upgrade.d.ts +3 -0
  61. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  62. package/dist/cli/commands/upgrade.js +277 -0
  63. package/dist/cli/commands/upgrade.js.map +1 -0
  64. package/dist/cli/commands/validate.d.ts +3 -0
  65. package/dist/cli/commands/validate.d.ts.map +1 -0
  66. package/dist/cli/commands/validate.js +66 -0
  67. package/dist/cli/commands/validate.js.map +1 -0
  68. package/dist/cli/index.d.ts +3 -0
  69. package/dist/cli/index.d.ts.map +1 -0
  70. package/dist/cli/index.js +69 -0
  71. package/dist/cli/index.js.map +1 -0
  72. package/dist/core/ack-log.d.ts +107 -0
  73. package/dist/core/ack-log.d.ts.map +1 -0
  74. package/dist/core/ack-log.js +197 -0
  75. package/dist/core/ack-log.js.map +1 -0
  76. package/dist/core/archive/ack-log-consistency.d.ts +15 -0
  77. package/dist/core/archive/ack-log-consistency.d.ts.map +1 -0
  78. package/dist/core/archive/ack-log-consistency.js +164 -0
  79. package/dist/core/archive/ack-log-consistency.js.map +1 -0
  80. package/dist/core/archive/fence.d.ts +66 -0
  81. package/dist/core/archive/fence.d.ts.map +1 -0
  82. package/dist/core/archive/fence.js +218 -0
  83. package/dist/core/archive/fence.js.map +1 -0
  84. package/dist/core/archive/index.d.ts +4 -0
  85. package/dist/core/archive/index.d.ts.map +1 -0
  86. package/dist/core/archive/index.js +6 -0
  87. package/dist/core/archive/index.js.map +1 -0
  88. package/dist/core/archive/legacy-exemption.d.ts +14 -0
  89. package/dist/core/archive/legacy-exemption.d.ts.map +1 -0
  90. package/dist/core/archive/legacy-exemption.js +82 -0
  91. package/dist/core/archive/legacy-exemption.js.map +1 -0
  92. package/dist/core/archive/lock.d.ts +46 -0
  93. package/dist/core/archive/lock.d.ts.map +1 -0
  94. package/dist/core/archive/lock.js +98 -0
  95. package/dist/core/archive/lock.js.map +1 -0
  96. package/dist/core/archive/pause-decisions-fence.d.ts +13 -0
  97. package/dist/core/archive/pause-decisions-fence.d.ts.map +1 -0
  98. package/dist/core/archive/pause-decisions-fence.js +384 -0
  99. package/dist/core/archive/pause-decisions-fence.js.map +1 -0
  100. package/dist/core/archive/process-evidence-fence.d.ts +110 -0
  101. package/dist/core/archive/process-evidence-fence.d.ts.map +1 -0
  102. package/dist/core/archive/process-evidence-fence.js +449 -0
  103. package/dist/core/archive/process-evidence-fence.js.map +1 -0
  104. package/dist/core/archive/process-evidence-rerun.d.ts +9 -0
  105. package/dist/core/archive/process-evidence-rerun.d.ts.map +1 -0
  106. package/dist/core/archive/process-evidence-rerun.js +238 -0
  107. package/dist/core/archive/process-evidence-rerun.js.map +1 -0
  108. package/dist/core/archive/recover-prompt.d.ts +10 -0
  109. package/dist/core/archive/recover-prompt.d.ts.map +1 -0
  110. package/dist/core/archive/recover-prompt.js +29 -0
  111. package/dist/core/archive/recover-prompt.js.map +1 -0
  112. package/dist/core/archive/recover.d.ts +83 -0
  113. package/dist/core/archive/recover.d.ts.map +1 -0
  114. package/dist/core/archive/recover.js +219 -0
  115. package/dist/core/archive/recover.js.map +1 -0
  116. package/dist/core/archive/resume-summary.d.ts +22 -0
  117. package/dist/core/archive/resume-summary.d.ts.map +1 -0
  118. package/dist/core/archive/resume-summary.js +82 -0
  119. package/dist/core/archive/resume-summary.js.map +1 -0
  120. package/dist/core/archive/summary-builder.d.ts +28 -0
  121. package/dist/core/archive/summary-builder.d.ts.map +1 -0
  122. package/dist/core/archive/summary-builder.js +287 -0
  123. package/dist/core/archive/summary-builder.js.map +1 -0
  124. package/dist/core/archive/summary-render.d.ts +8 -0
  125. package/dist/core/archive/summary-render.d.ts.map +1 -0
  126. package/dist/core/archive/summary-render.js +64 -0
  127. package/dist/core/archive/summary-render.js.map +1 -0
  128. package/dist/core/archive/three-level-fence.d.ts +10 -0
  129. package/dist/core/archive/three-level-fence.d.ts.map +1 -0
  130. package/dist/core/archive/three-level-fence.js +93 -0
  131. package/dist/core/archive/three-level-fence.js.map +1 -0
  132. package/dist/core/archive/transaction.d.ts +41 -0
  133. package/dist/core/archive/transaction.d.ts.map +1 -0
  134. package/dist/core/archive/transaction.js +184 -0
  135. package/dist/core/archive/transaction.js.map +1 -0
  136. package/dist/core/archive/verify-findings-fence.d.ts +11 -0
  137. package/dist/core/archive/verify-findings-fence.d.ts.map +1 -0
  138. package/dist/core/archive/verify-findings-fence.js +80 -0
  139. package/dist/core/archive/verify-findings-fence.js.map +1 -0
  140. package/dist/core/archive/version-retrograde-fence.d.ts +10 -0
  141. package/dist/core/archive/version-retrograde-fence.d.ts.map +1 -0
  142. package/dist/core/archive/version-retrograde-fence.js +103 -0
  143. package/dist/core/archive/version-retrograde-fence.js.map +1 -0
  144. package/dist/core/artifact-graph/builder.d.ts +16 -0
  145. package/dist/core/artifact-graph/builder.d.ts.map +1 -0
  146. package/dist/core/artifact-graph/builder.js +32 -0
  147. package/dist/core/artifact-graph/builder.js.map +1 -0
  148. package/dist/core/artifact-graph/index.d.ts +3 -0
  149. package/dist/core/artifact-graph/index.d.ts.map +1 -0
  150. package/dist/core/artifact-graph/index.js +4 -0
  151. package/dist/core/artifact-graph/index.js.map +1 -0
  152. package/dist/core/artifact-graph/types.d.ts +14 -0
  153. package/dist/core/artifact-graph/types.d.ts.map +1 -0
  154. package/dist/core/artifact-graph/types.js +2 -0
  155. package/dist/core/artifact-graph/types.js.map +1 -0
  156. package/dist/core/backlog/assets/backlog-readme.md +11 -0
  157. package/dist/core/backlog/index.d.ts +20 -0
  158. package/dist/core/backlog/index.d.ts.map +1 -0
  159. package/dist/core/backlog/index.js +60 -0
  160. package/dist/core/backlog/index.js.map +1 -0
  161. package/dist/core/backlog/render.d.ts +51 -0
  162. package/dist/core/backlog/render.d.ts.map +1 -0
  163. package/dist/core/backlog/render.js +196 -0
  164. package/dist/core/backlog/render.js.map +1 -0
  165. package/dist/core/bootstrap/index.d.ts +2 -0
  166. package/dist/core/bootstrap/index.d.ts.map +1 -0
  167. package/dist/core/bootstrap/index.js +5 -0
  168. package/dist/core/bootstrap/index.js.map +1 -0
  169. package/dist/core/canonical-json.d.ts +11 -0
  170. package/dist/core/canonical-json.d.ts.map +1 -0
  171. package/dist/core/canonical-json.js +43 -0
  172. package/dist/core/canonical-json.js.map +1 -0
  173. package/dist/core/git/utils.d.ts +27 -0
  174. package/dist/core/git/utils.d.ts.map +1 -0
  175. package/dist/core/git/utils.js +53 -0
  176. package/dist/core/git/utils.js.map +1 -0
  177. package/dist/core/harness-adapters/claude.d.ts +13 -0
  178. package/dist/core/harness-adapters/claude.d.ts.map +1 -0
  179. package/dist/core/harness-adapters/claude.js +53 -0
  180. package/dist/core/harness-adapters/claude.js.map +1 -0
  181. package/dist/core/harness-adapters/codex.d.ts +14 -0
  182. package/dist/core/harness-adapters/codex.d.ts.map +1 -0
  183. package/dist/core/harness-adapters/codex.js +60 -0
  184. package/dist/core/harness-adapters/codex.js.map +1 -0
  185. package/dist/core/harness-adapters/detector.d.ts +15 -0
  186. package/dist/core/harness-adapters/detector.d.ts.map +1 -0
  187. package/dist/core/harness-adapters/detector.js +45 -0
  188. package/dist/core/harness-adapters/detector.js.map +1 -0
  189. package/dist/core/harness-adapters/hash-compare.d.ts +21 -0
  190. package/dist/core/harness-adapters/hash-compare.d.ts.map +1 -0
  191. package/dist/core/harness-adapters/hash-compare.js +49 -0
  192. package/dist/core/harness-adapters/hash-compare.js.map +1 -0
  193. package/dist/core/harness-adapters/index.d.ts +8 -0
  194. package/dist/core/harness-adapters/index.d.ts.map +1 -0
  195. package/dist/core/harness-adapters/index.js +8 -0
  196. package/dist/core/harness-adapters/index.js.map +1 -0
  197. package/dist/core/harness-adapters/interface.d.ts +52 -0
  198. package/dist/core/harness-adapters/interface.d.ts.map +1 -0
  199. package/dist/core/harness-adapters/interface.js +3 -0
  200. package/dist/core/harness-adapters/interface.js.map +1 -0
  201. package/dist/core/harness-adapters/legacy-detector.d.ts +14 -0
  202. package/dist/core/harness-adapters/legacy-detector.d.ts.map +1 -0
  203. package/dist/core/harness-adapters/legacy-detector.js +83 -0
  204. package/dist/core/harness-adapters/legacy-detector.js.map +1 -0
  205. package/dist/core/harness-adapters/transaction.d.ts +12 -0
  206. package/dist/core/harness-adapters/transaction.d.ts.map +1 -0
  207. package/dist/core/harness-adapters/transaction.js +113 -0
  208. package/dist/core/harness-adapters/transaction.js.map +1 -0
  209. package/dist/core/harness-adapters/types.d.ts +45 -0
  210. package/dist/core/harness-adapters/types.d.ts.map +1 -0
  211. package/dist/core/harness-adapters/types.js +3 -0
  212. package/dist/core/harness-adapters/types.js.map +1 -0
  213. package/dist/core/hash/content.d.ts +10 -0
  214. package/dist/core/hash/content.d.ts.map +1 -0
  215. package/dist/core/hash/content.js +131 -0
  216. package/dist/core/hash/content.js.map +1 -0
  217. package/dist/core/hash/diff.d.ts +26 -0
  218. package/dist/core/hash/diff.d.ts.map +1 -0
  219. package/dist/core/hash/diff.js +40 -0
  220. package/dist/core/hash/diff.js.map +1 -0
  221. package/dist/core/hash/index.d.ts +6 -0
  222. package/dist/core/hash/index.d.ts.map +1 -0
  223. package/dist/core/hash/index.js +7 -0
  224. package/dist/core/hash/index.js.map +1 -0
  225. package/dist/core/hash/log.d.ts +7 -0
  226. package/dist/core/hash/log.d.ts.map +1 -0
  227. package/dist/core/hash/log.js +14 -0
  228. package/dist/core/hash/log.js.map +1 -0
  229. package/dist/core/hash/tasks.d.ts +9 -0
  230. package/dist/core/hash/tasks.d.ts.map +1 -0
  231. package/dist/core/hash/tasks.js +20 -0
  232. package/dist/core/hash/tasks.js.map +1 -0
  233. package/dist/core/legacy-bridge/ack.d.ts +30 -0
  234. package/dist/core/legacy-bridge/ack.d.ts.map +1 -0
  235. package/dist/core/legacy-bridge/ack.js +133 -0
  236. package/dist/core/legacy-bridge/ack.js.map +1 -0
  237. package/dist/core/legacy-bridge/anchors.d.ts +15 -0
  238. package/dist/core/legacy-bridge/anchors.d.ts.map +1 -0
  239. package/dist/core/legacy-bridge/anchors.js +119 -0
  240. package/dist/core/legacy-bridge/anchors.js.map +1 -0
  241. package/dist/core/legacy-bridge/budget.d.ts +39 -0
  242. package/dist/core/legacy-bridge/budget.d.ts.map +1 -0
  243. package/dist/core/legacy-bridge/budget.js +83 -0
  244. package/dist/core/legacy-bridge/budget.js.map +1 -0
  245. package/dist/core/legacy-bridge/conflict.d.ts +44 -0
  246. package/dist/core/legacy-bridge/conflict.d.ts.map +1 -0
  247. package/dist/core/legacy-bridge/conflict.js +105 -0
  248. package/dist/core/legacy-bridge/conflict.js.map +1 -0
  249. package/dist/core/legacy-bridge/diff-report.d.ts +14 -0
  250. package/dist/core/legacy-bridge/diff-report.d.ts.map +1 -0
  251. package/dist/core/legacy-bridge/diff-report.js +105 -0
  252. package/dist/core/legacy-bridge/diff-report.js.map +1 -0
  253. package/dist/core/legacy-bridge/encoding.d.ts +42 -0
  254. package/dist/core/legacy-bridge/encoding.d.ts.map +1 -0
  255. package/dist/core/legacy-bridge/encoding.js +104 -0
  256. package/dist/core/legacy-bridge/encoding.js.map +1 -0
  257. package/dist/core/legacy-bridge/excel.d.ts +32 -0
  258. package/dist/core/legacy-bridge/excel.d.ts.map +1 -0
  259. package/dist/core/legacy-bridge/excel.js +124 -0
  260. package/dist/core/legacy-bridge/excel.js.map +1 -0
  261. package/dist/core/legacy-bridge/hash-anchor.d.ts +23 -0
  262. package/dist/core/legacy-bridge/hash-anchor.d.ts.map +1 -0
  263. package/dist/core/legacy-bridge/hash-anchor.js +55 -0
  264. package/dist/core/legacy-bridge/hash-anchor.js.map +1 -0
  265. package/dist/core/legacy-bridge/indexer.d.ts +28 -0
  266. package/dist/core/legacy-bridge/indexer.d.ts.map +1 -0
  267. package/dist/core/legacy-bridge/indexer.js +145 -0
  268. package/dist/core/legacy-bridge/indexer.js.map +1 -0
  269. package/dist/core/legacy-bridge/mapper.d.ts +40 -0
  270. package/dist/core/legacy-bridge/mapper.d.ts.map +1 -0
  271. package/dist/core/legacy-bridge/mapper.js +241 -0
  272. package/dist/core/legacy-bridge/mapper.js.map +1 -0
  273. package/dist/core/legacy-bridge/quality-judge.d.ts +65 -0
  274. package/dist/core/legacy-bridge/quality-judge.d.ts.map +1 -0
  275. package/dist/core/legacy-bridge/quality-judge.js +277 -0
  276. package/dist/core/legacy-bridge/quality-judge.js.map +1 -0
  277. package/dist/core/legacy-bridge/redact.d.ts +28 -0
  278. package/dist/core/legacy-bridge/redact.d.ts.map +1 -0
  279. package/dist/core/legacy-bridge/redact.js +121 -0
  280. package/dist/core/legacy-bridge/redact.js.map +1 -0
  281. package/dist/core/legacy-bridge/regenerator.d.ts +50 -0
  282. package/dist/core/legacy-bridge/regenerator.d.ts.map +1 -0
  283. package/dist/core/legacy-bridge/regenerator.js +193 -0
  284. package/dist/core/legacy-bridge/regenerator.js.map +1 -0
  285. package/dist/core/legacy-bridge/resolve.d.ts +28 -0
  286. package/dist/core/legacy-bridge/resolve.d.ts.map +1 -0
  287. package/dist/core/legacy-bridge/resolve.js +75 -0
  288. package/dist/core/legacy-bridge/resolve.js.map +1 -0
  289. package/dist/core/legacy-bridge/sync-check.d.ts +47 -0
  290. package/dist/core/legacy-bridge/sync-check.d.ts.map +1 -0
  291. package/dist/core/legacy-bridge/sync-check.js +198 -0
  292. package/dist/core/legacy-bridge/sync-check.js.map +1 -0
  293. package/dist/core/legacy-bridge/types.d.ts +114 -0
  294. package/dist/core/legacy-bridge/types.d.ts.map +1 -0
  295. package/dist/core/legacy-bridge/types.js +4 -0
  296. package/dist/core/legacy-bridge/types.js.map +1 -0
  297. package/dist/core/markers/index.d.ts +3 -0
  298. package/dist/core/markers/index.d.ts.map +1 -0
  299. package/dist/core/markers/index.js +3 -0
  300. package/dist/core/markers/index.js.map +1 -0
  301. package/dist/core/markers/parse.d.ts +12 -0
  302. package/dist/core/markers/parse.d.ts.map +1 -0
  303. package/dist/core/markers/parse.js +31 -0
  304. package/dist/core/markers/parse.js.map +1 -0
  305. package/dist/core/markers/types.d.ts +142 -0
  306. package/dist/core/markers/types.d.ts.map +1 -0
  307. package/dist/core/markers/types.js +3 -0
  308. package/dist/core/markers/types.js.map +1 -0
  309. package/dist/core/migrate/ack.d.ts +13 -0
  310. package/dist/core/migrate/ack.d.ts.map +1 -0
  311. package/dist/core/migrate/ack.js +62 -0
  312. package/dist/core/migrate/ack.js.map +1 -0
  313. package/dist/core/migrate/archive-detect.d.ts +19 -0
  314. package/dist/core/migrate/archive-detect.d.ts.map +1 -0
  315. package/dist/core/migrate/archive-detect.js +89 -0
  316. package/dist/core/migrate/archive-detect.js.map +1 -0
  317. package/dist/core/migrate/budget.d.ts +7 -0
  318. package/dist/core/migrate/budget.d.ts.map +1 -0
  319. package/dist/core/migrate/budget.js +25 -0
  320. package/dist/core/migrate/budget.js.map +1 -0
  321. package/dist/core/migrate/conflict.d.ts +49 -0
  322. package/dist/core/migrate/conflict.d.ts.map +1 -0
  323. package/dist/core/migrate/conflict.js +99 -0
  324. package/dist/core/migrate/conflict.js.map +1 -0
  325. package/dist/core/migrate/index.d.ts +7 -0
  326. package/dist/core/migrate/index.d.ts.map +1 -0
  327. package/dist/core/migrate/index.js +389 -0
  328. package/dist/core/migrate/index.js.map +1 -0
  329. package/dist/core/migrate/markdown-aware.d.ts +27 -0
  330. package/dist/core/migrate/markdown-aware.d.ts.map +1 -0
  331. package/dist/core/migrate/markdown-aware.js +112 -0
  332. package/dist/core/migrate/markdown-aware.js.map +1 -0
  333. package/dist/core/migrate/quality.d.ts +66 -0
  334. package/dist/core/migrate/quality.d.ts.map +1 -0
  335. package/dist/core/migrate/quality.js +302 -0
  336. package/dist/core/migrate/quality.js.map +1 -0
  337. package/dist/core/migrate/regenerate.d.ts +24 -0
  338. package/dist/core/migrate/regenerate.d.ts.map +1 -0
  339. package/dist/core/migrate/regenerate.js +145 -0
  340. package/dist/core/migrate/regenerate.js.map +1 -0
  341. package/dist/core/migrate/report.d.ts +36 -0
  342. package/dist/core/migrate/report.d.ts.map +1 -0
  343. package/dist/core/migrate/report.js +154 -0
  344. package/dist/core/migrate/report.js.map +1 -0
  345. package/dist/core/migrate/sources/index.d.ts +4 -0
  346. package/dist/core/migrate/sources/index.d.ts.map +1 -0
  347. package/dist/core/migrate/sources/index.js +17 -0
  348. package/dist/core/migrate/sources/index.js.map +1 -0
  349. package/dist/core/migrate/sources/openspec.d.ts +14 -0
  350. package/dist/core/migrate/sources/openspec.d.ts.map +1 -0
  351. package/dist/core/migrate/sources/openspec.js +453 -0
  352. package/dist/core/migrate/sources/openspec.js.map +1 -0
  353. package/dist/core/migrate/sources/superpowers.d.ts +12 -0
  354. package/dist/core/migrate/sources/superpowers.d.ts.map +1 -0
  355. package/dist/core/migrate/sources/superpowers.js +310 -0
  356. package/dist/core/migrate/sources/superpowers.js.map +1 -0
  357. package/dist/core/migrate/types.d.ts +183 -0
  358. package/dist/core/migrate/types.d.ts.map +1 -0
  359. package/dist/core/migrate/types.js +5 -0
  360. package/dist/core/migrate/types.js.map +1 -0
  361. package/dist/core/migrate/utils.d.ts +2 -0
  362. package/dist/core/migrate/utils.d.ts.map +1 -0
  363. package/dist/core/migrate/utils.js +28 -0
  364. package/dist/core/migrate/utils.js.map +1 -0
  365. package/dist/core/monitor/artifact-observer.d.ts +9 -0
  366. package/dist/core/monitor/artifact-observer.d.ts.map +1 -0
  367. package/dist/core/monitor/artifact-observer.js +180 -0
  368. package/dist/core/monitor/artifact-observer.js.map +1 -0
  369. package/dist/core/monitor/config.d.ts +16 -0
  370. package/dist/core/monitor/config.d.ts.map +1 -0
  371. package/dist/core/monitor/config.js +48 -0
  372. package/dist/core/monitor/config.js.map +1 -0
  373. package/dist/core/monitor/divergence-map.d.ts +5 -0
  374. package/dist/core/monitor/divergence-map.d.ts.map +1 -0
  375. package/dist/core/monitor/divergence-map.js +92 -0
  376. package/dist/core/monitor/divergence-map.js.map +1 -0
  377. package/dist/core/monitor/exit-handler.d.ts +6 -0
  378. package/dist/core/monitor/exit-handler.d.ts.map +1 -0
  379. package/dist/core/monitor/exit-handler.js +27 -0
  380. package/dist/core/monitor/exit-handler.js.map +1 -0
  381. package/dist/core/monitor/health-verdict.d.ts +9 -0
  382. package/dist/core/monitor/health-verdict.d.ts.map +1 -0
  383. package/dist/core/monitor/health-verdict.js +55 -0
  384. package/dist/core/monitor/health-verdict.js.map +1 -0
  385. package/dist/core/monitor/report-renderer.d.ts +4 -0
  386. package/dist/core/monitor/report-renderer.d.ts.map +1 -0
  387. package/dist/core/monitor/report-renderer.js +82 -0
  388. package/dist/core/monitor/report-renderer.js.map +1 -0
  389. package/dist/core/monitor/trace-store.d.ts +39 -0
  390. package/dist/core/monitor/trace-store.d.ts.map +1 -0
  391. package/dist/core/monitor/trace-store.js +130 -0
  392. package/dist/core/monitor/trace-store.js.map +1 -0
  393. package/dist/core/monitor/types.d.ts +63 -0
  394. package/dist/core/monitor/types.d.ts.map +1 -0
  395. package/dist/core/monitor/types.js +26 -0
  396. package/dist/core/monitor/types.js.map +1 -0
  397. package/dist/core/parse/design.d.ts +14 -0
  398. package/dist/core/parse/design.d.ts.map +1 -0
  399. package/dist/core/parse/design.js +17 -0
  400. package/dist/core/parse/design.js.map +1 -0
  401. package/dist/core/parse/fenced-yaml.d.ts +18 -0
  402. package/dist/core/parse/fenced-yaml.d.ts.map +1 -0
  403. package/dist/core/parse/fenced-yaml.js +45 -0
  404. package/dist/core/parse/fenced-yaml.js.map +1 -0
  405. package/dist/core/parse/index.d.ts +7 -0
  406. package/dist/core/parse/index.d.ts.map +1 -0
  407. package/dist/core/parse/index.js +8 -0
  408. package/dist/core/parse/index.js.map +1 -0
  409. package/dist/core/parse/markdown.d.ts +30 -0
  410. package/dist/core/parse/markdown.d.ts.map +1 -0
  411. package/dist/core/parse/markdown.js +66 -0
  412. package/dist/core/parse/markdown.js.map +1 -0
  413. package/dist/core/parse/proposal.d.ts +18 -0
  414. package/dist/core/parse/proposal.d.ts.map +1 -0
  415. package/dist/core/parse/proposal.js +22 -0
  416. package/dist/core/parse/proposal.js.map +1 -0
  417. package/dist/core/parse/specs.d.ts +25 -0
  418. package/dist/core/parse/specs.d.ts.map +1 -0
  419. package/dist/core/parse/specs.js +58 -0
  420. package/dist/core/parse/specs.js.map +1 -0
  421. package/dist/core/parse/tasks.d.ts +33 -0
  422. package/dist/core/parse/tasks.d.ts.map +1 -0
  423. package/dist/core/parse/tasks.js +82 -0
  424. package/dist/core/parse/tasks.js.map +1 -0
  425. package/dist/core/parse/yaml.d.ts +13 -0
  426. package/dist/core/parse/yaml.d.ts.map +1 -0
  427. package/dist/core/parse/yaml.js +39 -0
  428. package/dist/core/parse/yaml.js.map +1 -0
  429. package/dist/core/process-evidence-freeze-warnings.d.ts +24 -0
  430. package/dist/core/process-evidence-freeze-warnings.d.ts.map +1 -0
  431. package/dist/core/process-evidence-freeze-warnings.js +153 -0
  432. package/dist/core/process-evidence-freeze-warnings.js.map +1 -0
  433. package/dist/core/schema/index.d.ts +5 -0
  434. package/dist/core/schema/index.d.ts.map +1 -0
  435. package/dist/core/schema/index.js +6 -0
  436. package/dist/core/schema/index.js.map +1 -0
  437. package/dist/core/schema/model-tiers-config.d.ts +41 -0
  438. package/dist/core/schema/model-tiers-config.d.ts.map +1 -0
  439. package/dist/core/schema/model-tiers-config.js +85 -0
  440. package/dist/core/schema/model-tiers-config.js.map +1 -0
  441. package/dist/core/schema/process-verification-config.d.ts +18 -0
  442. package/dist/core/schema/process-verification-config.d.ts.map +1 -0
  443. package/dist/core/schema/process-verification-config.js +74 -0
  444. package/dist/core/schema/process-verification-config.js.map +1 -0
  445. package/dist/core/schema/stage-extensions-config.d.ts +28 -0
  446. package/dist/core/schema/stage-extensions-config.d.ts.map +1 -0
  447. package/dist/core/schema/stage-extensions-config.js +228 -0
  448. package/dist/core/schema/stage-extensions-config.js.map +1 -0
  449. package/dist/core/schema/types.d.ts +262 -0
  450. package/dist/core/schema/types.d.ts.map +1 -0
  451. package/dist/core/schema/types.js +51 -0
  452. package/dist/core/schema/types.js.map +1 -0
  453. package/dist/core/schema/writing-plans-config.d.ts +11 -0
  454. package/dist/core/schema/writing-plans-config.d.ts.map +1 -0
  455. package/dist/core/schema/writing-plans-config.js +40 -0
  456. package/dist/core/schema/writing-plans-config.js.map +1 -0
  457. package/dist/core/schemas/archive-summary.d.ts +131 -0
  458. package/dist/core/schemas/archive-summary.d.ts.map +1 -0
  459. package/dist/core/schemas/archive-summary.js +31 -0
  460. package/dist/core/schemas/archive-summary.js.map +1 -0
  461. package/dist/core/schemas/process-evidence.d.ts +156 -0
  462. package/dist/core/schemas/process-evidence.d.ts.map +1 -0
  463. package/dist/core/schemas/process-evidence.js +12 -0
  464. package/dist/core/schemas/process-evidence.js.map +1 -0
  465. package/dist/core/schemas/scope-entries.d.ts +68 -0
  466. package/dist/core/schemas/scope-entries.d.ts.map +1 -0
  467. package/dist/core/schemas/scope-entries.js +47 -0
  468. package/dist/core/schemas/scope-entries.js.map +1 -0
  469. package/dist/core/schemas/severity.d.ts +58 -0
  470. package/dist/core/schemas/severity.d.ts.map +1 -0
  471. package/dist/core/schemas/severity.js +26 -0
  472. package/dist/core/schemas/severity.js.map +1 -0
  473. package/dist/core/scope/aggregator.d.ts +49 -0
  474. package/dist/core/scope/aggregator.d.ts.map +1 -0
  475. package/dist/core/scope/aggregator.js +141 -0
  476. package/dist/core/scope/aggregator.js.map +1 -0
  477. package/dist/core/scope/index.d.ts +2 -0
  478. package/dist/core/scope/index.d.ts.map +1 -0
  479. package/dist/core/scope/index.js +2 -0
  480. package/dist/core/scope/index.js.map +1 -0
  481. package/dist/core/specs-sync/apply.d.ts +8 -0
  482. package/dist/core/specs-sync/apply.d.ts.map +1 -0
  483. package/dist/core/specs-sync/apply.js +26 -0
  484. package/dist/core/specs-sync/apply.js.map +1 -0
  485. package/dist/core/specs-sync/deltas.d.ts +15 -0
  486. package/dist/core/specs-sync/deltas.d.ts.map +1 -0
  487. package/dist/core/specs-sync/deltas.js +27 -0
  488. package/dist/core/specs-sync/deltas.js.map +1 -0
  489. package/dist/core/specs-sync/index.d.ts +3 -0
  490. package/dist/core/specs-sync/index.d.ts.map +1 -0
  491. package/dist/core/specs-sync/index.js +4 -0
  492. package/dist/core/specs-sync/index.js.map +1 -0
  493. package/dist/core/stage-extensions/convergence-judge.d.ts +35 -0
  494. package/dist/core/stage-extensions/convergence-judge.d.ts.map +1 -0
  495. package/dist/core/stage-extensions/convergence-judge.js +47 -0
  496. package/dist/core/stage-extensions/convergence-judge.js.map +1 -0
  497. package/dist/core/stage-extensions/index.d.ts +13 -0
  498. package/dist/core/stage-extensions/index.d.ts.map +1 -0
  499. package/dist/core/stage-extensions/index.js +11 -0
  500. package/dist/core/stage-extensions/index.js.map +1 -0
  501. package/dist/core/stage-extensions/output-watcher.d.ts +93 -0
  502. package/dist/core/stage-extensions/output-watcher.d.ts.map +1 -0
  503. package/dist/core/stage-extensions/output-watcher.js +163 -0
  504. package/dist/core/stage-extensions/output-watcher.js.map +1 -0
  505. package/dist/core/stage-extensions/severity-mapper.d.ts +21 -0
  506. package/dist/core/stage-extensions/severity-mapper.d.ts.map +1 -0
  507. package/dist/core/stage-extensions/severity-mapper.js +26 -0
  508. package/dist/core/stage-extensions/severity-mapper.js.map +1 -0
  509. package/dist/core/stage-extensions/state-machine.d.ts +43 -0
  510. package/dist/core/stage-extensions/state-machine.d.ts.map +1 -0
  511. package/dist/core/stage-extensions/state-machine.js +19 -0
  512. package/dist/core/stage-extensions/state-machine.js.map +1 -0
  513. package/dist/core/stage-extensions/thread-map.d.ts +60 -0
  514. package/dist/core/stage-extensions/thread-map.d.ts.map +1 -0
  515. package/dist/core/stage-extensions/thread-map.js +107 -0
  516. package/dist/core/stage-extensions/thread-map.js.map +1 -0
  517. package/dist/core/stage-extensions/trend-analyzer.d.ts +29 -0
  518. package/dist/core/stage-extensions/trend-analyzer.d.ts.map +1 -0
  519. package/dist/core/stage-extensions/trend-analyzer.js +60 -0
  520. package/dist/core/stage-extensions/trend-analyzer.js.map +1 -0
  521. package/dist/core/stage-extensions/types.d.ts +39 -0
  522. package/dist/core/stage-extensions/types.d.ts.map +1 -0
  523. package/dist/core/stage-extensions/types.js +5 -0
  524. package/dist/core/stage-extensions/types.js.map +1 -0
  525. package/dist/core/staging-lock.d.ts +36 -0
  526. package/dist/core/staging-lock.d.ts.map +1 -0
  527. package/dist/core/staging-lock.js +122 -0
  528. package/dist/core/staging-lock.js.map +1 -0
  529. package/dist/core/templates/commands/ack-confirm.md +32 -0
  530. package/dist/core/templates/commands/apply.md +220 -0
  531. package/dist/core/templates/commands/archive.md +178 -0
  532. package/dist/core/templates/commands/brainstorm.md +58 -0
  533. package/dist/core/templates/commands/codex-adversarial.md +95 -0
  534. package/dist/core/templates/commands/explore.md +29 -0
  535. package/dist/core/templates/commands/index.d.ts +12 -0
  536. package/dist/core/templates/commands/index.d.ts.map +1 -0
  537. package/dist/core/templates/commands/index.js +26 -0
  538. package/dist/core/templates/commands/index.js.map +1 -0
  539. package/dist/core/templates/commands/propose.md +90 -0
  540. package/dist/core/templates/commands/review.md +105 -0
  541. package/dist/core/templates/commands/upgrade.md +58 -0
  542. package/dist/core/templates/commands/verify.md +186 -0
  543. package/dist/core/templates/index.d.ts +3 -0
  544. package/dist/core/templates/index.d.ts.map +1 -0
  545. package/dist/core/templates/index.js +5 -0
  546. package/dist/core/templates/index.js.map +1 -0
  547. package/dist/core/templates/skills/_shared/scope-category-guidance.md +40 -0
  548. package/dist/core/templates/skills/brainstorming.md +161 -0
  549. package/dist/core/templates/skills/dispatching-parallel-agents.md +209 -0
  550. package/dist/core/templates/skills/exploring.md +476 -0
  551. package/dist/core/templates/skills/finishing-a-development-branch.md +251 -0
  552. package/dist/core/templates/skills/index.d.ts +17 -0
  553. package/dist/core/templates/skills/index.d.ts.map +1 -0
  554. package/dist/core/templates/skills/index.js +53 -0
  555. package/dist/core/templates/skills/index.js.map +1 -0
  556. package/dist/core/templates/skills/process-evidence.md +146 -0
  557. package/dist/core/templates/skills/receiving-code-review.md +294 -0
  558. package/dist/core/templates/skills/requesting-code-review.md +108 -0
  559. package/dist/core/templates/skills/subagent-driven-development.md +405 -0
  560. package/dist/core/templates/skills/subagent-driven-discipline/references/codex-tools.md +72 -0
  561. package/dist/core/templates/skills/subagent-driven-discipline/references/opencode-tools.md +104 -0
  562. package/dist/core/templates/skills/subagent-driven-discipline.md +725 -0
  563. package/dist/core/templates/skills/systematic-debugging.md +297 -0
  564. package/dist/core/templates/skills/test-driven-development.md +402 -0
  565. package/dist/core/templates/skills/using-forge.md +163 -0
  566. package/dist/core/templates/skills/using-git-worktrees.md +229 -0
  567. package/dist/core/templates/skills/verification-before-completion.md +175 -0
  568. package/dist/core/templates/skills/verifying-three-dimensions.md +245 -0
  569. package/dist/core/templates/skills/writing-plans.md +259 -0
  570. package/dist/core/templates/skills/writing-skills.md +214 -0
  571. package/dist/core/test-reporters/index.d.ts +41 -0
  572. package/dist/core/test-reporters/index.d.ts.map +1 -0
  573. package/dist/core/test-reporters/index.js +39 -0
  574. package/dist/core/test-reporters/index.js.map +1 -0
  575. package/dist/core/test-reporters/junit.d.ts +8 -0
  576. package/dist/core/test-reporters/junit.d.ts.map +1 -0
  577. package/dist/core/test-reporters/junit.js +94 -0
  578. package/dist/core/test-reporters/junit.js.map +1 -0
  579. package/dist/core/test-reporters/tap.d.ts +18 -0
  580. package/dist/core/test-reporters/tap.d.ts.map +1 -0
  581. package/dist/core/test-reporters/tap.js +73 -0
  582. package/dist/core/test-reporters/tap.js.map +1 -0
  583. package/dist/core/test-reporters/vitest-json.d.ts +8 -0
  584. package/dist/core/test-reporters/vitest-json.d.ts.map +1 -0
  585. package/dist/core/test-reporters/vitest-json.js +56 -0
  586. package/dist/core/test-reporters/vitest-json.js.map +1 -0
  587. package/dist/core/upgrade/resign-markers.d.ts +14 -0
  588. package/dist/core/upgrade/resign-markers.d.ts.map +1 -0
  589. package/dist/core/upgrade/resign-markers.js +245 -0
  590. package/dist/core/upgrade/resign-markers.js.map +1 -0
  591. package/dist/core/validate/archive-summary-schema.d.ts +8 -0
  592. package/dist/core/validate/archive-summary-schema.d.ts.map +1 -0
  593. package/dist/core/validate/archive-summary-schema.js +186 -0
  594. package/dist/core/validate/archive-summary-schema.js.map +1 -0
  595. package/dist/core/validate/auto-findings.d.ts +36 -0
  596. package/dist/core/validate/auto-findings.d.ts.map +1 -0
  597. package/dist/core/validate/auto-findings.js +38 -0
  598. package/dist/core/validate/auto-findings.js.map +1 -0
  599. package/dist/core/validate/candidate-validators.d.ts +22 -0
  600. package/dist/core/validate/candidate-validators.d.ts.map +1 -0
  601. package/dist/core/validate/candidate-validators.js +46 -0
  602. package/dist/core/validate/candidate-validators.js.map +1 -0
  603. package/dist/core/validate/change.d.ts +3 -0
  604. package/dist/core/validate/change.d.ts.map +1 -0
  605. package/dist/core/validate/change.js +205 -0
  606. package/dist/core/validate/change.js.map +1 -0
  607. package/dist/core/validate/coverage-gap.d.ts +37 -0
  608. package/dist/core/validate/coverage-gap.d.ts.map +1 -0
  609. package/dist/core/validate/coverage-gap.js +181 -0
  610. package/dist/core/validate/coverage-gap.js.map +1 -0
  611. package/dist/core/validate/finding-hash.d.ts +14 -0
  612. package/dist/core/validate/finding-hash.d.ts.map +1 -0
  613. package/dist/core/validate/finding-hash.js +29 -0
  614. package/dist/core/validate/finding-hash.js.map +1 -0
  615. package/dist/core/validate/index.d.ts +15 -0
  616. package/dist/core/validate/index.d.ts.map +1 -0
  617. package/dist/core/validate/index.js +19 -0
  618. package/dist/core/validate/index.js.map +1 -0
  619. package/dist/core/validate/marker-integrity.d.ts +28 -0
  620. package/dist/core/validate/marker-integrity.d.ts.map +1 -0
  621. package/dist/core/validate/marker-integrity.js +170 -0
  622. package/dist/core/validate/marker-integrity.js.map +1 -0
  623. package/dist/core/validate/marker-schema.d.ts +10 -0
  624. package/dist/core/validate/marker-schema.d.ts.map +1 -0
  625. package/dist/core/validate/marker-schema.js +661 -0
  626. package/dist/core/validate/marker-schema.js.map +1 -0
  627. package/dist/core/validate/orphan-tmp.d.ts +13 -0
  628. package/dist/core/validate/orphan-tmp.d.ts.map +1 -0
  629. package/dist/core/validate/orphan-tmp.js +49 -0
  630. package/dist/core/validate/orphan-tmp.js.map +1 -0
  631. package/dist/core/validate/proposal.d.ts +4 -0
  632. package/dist/core/validate/proposal.d.ts.map +1 -0
  633. package/dist/core/validate/proposal.js +40 -0
  634. package/dist/core/validate/proposal.js.map +1 -0
  635. package/dist/core/validate/scope-entries.d.ts +23 -0
  636. package/dist/core/validate/scope-entries.d.ts.map +1 -0
  637. package/dist/core/validate/scope-entries.js +108 -0
  638. package/dist/core/validate/scope-entries.js.map +1 -0
  639. package/dist/core/validate/specs.d.ts +4 -0
  640. package/dist/core/validate/specs.d.ts.map +1 -0
  641. package/dist/core/validate/specs.js +74 -0
  642. package/dist/core/validate/specs.js.map +1 -0
  643. package/dist/core/validate/tasks.d.ts +4 -0
  644. package/dist/core/validate/tasks.d.ts.map +1 -0
  645. package/dist/core/validate/tasks.js +48 -0
  646. package/dist/core/validate/tasks.js.map +1 -0
  647. package/dist/core/validate/test-failure-stub.d.ts +23 -0
  648. package/dist/core/validate/test-failure-stub.d.ts.map +1 -0
  649. package/dist/core/validate/test-failure-stub.js +21 -0
  650. package/dist/core/validate/test-failure-stub.js.map +1 -0
  651. package/dist/core/validate/types.d.ts +33 -0
  652. package/dist/core/validate/types.d.ts.map +1 -0
  653. package/dist/core/validate/types.js +20 -0
  654. package/dist/core/validate/types.js.map +1 -0
  655. package/dist/core/worktree.d.ts +52 -0
  656. package/dist/core/worktree.d.ts.map +1 -0
  657. package/dist/core/worktree.js +145 -0
  658. package/dist/core/worktree.js.map +1 -0
  659. package/dist/index.d.ts +12 -0
  660. package/dist/index.d.ts.map +1 -0
  661. package/dist/index.js +14 -0
  662. package/dist/index.js.map +1 -0
  663. package/package.json +82 -0
@@ -0,0 +1,689 @@
1
+ // forge archive 子命令 — 归档 change(spec §3.5)
2
+ // 支持:
3
+ // forge archive <changeId> — 正常归档(检查 marker + hash + lock)
4
+ // forge archive <changeId> --force — 接受 human-override 标记 或 非 git 项目
5
+ // forge archive --recover — 从半完成状态恢复
6
+ // forge archive --resume-summary <archiveId> — 恢复半完成 .tmp summary rename
7
+ import { Command } from 'commander';
8
+ import { readFile, rm, rename, readdir, copyFile, mkdir, writeFile } from 'node:fs/promises';
9
+ import { existsSync, statSync } from 'node:fs';
10
+ import { execFileSync } from 'node:child_process';
11
+ import { join } from 'node:path';
12
+ import { parse as parseYaml } from 'yaml';
13
+ import Anthropic from '@anthropic-ai/sdk';
14
+ import { parseMarker } from '../../core/markers/index.js';
15
+ import { validateMarkerSchema } from '../../core/validate/index.js';
16
+ import { validateEvidence, validateReviewGitIntegrity, validateReviewOutcomes, } from '../../core/validate/marker-integrity.js';
17
+ import { computeTasksHash, computeContentHash } from '../../core/hash/index.js';
18
+ import { archiveTransaction } from '../../core/archive/transaction.js';
19
+ import { acquireLock, LockHeldError } from '../../core/archive/lock.js';
20
+ import { recover } from '../../core/archive/recover.js';
21
+ import { promptRecoverChoice } from '../../core/archive/recover-prompt.js';
22
+ import { applyDeltas } from '../../core/specs-sync/index.js';
23
+ import { loadAnchorsFile } from '../../core/legacy-bridge/anchors.js';
24
+ import { checkAck } from '../../core/legacy-bridge/ack.js';
25
+ import { runSyncCheck } from '../../core/legacy-bridge/sync-check.js';
26
+ import { renderDiffMarkdown, renderDiffYaml, hasCriticalPending, } from '../../core/legacy-bridge/diff-report.js';
27
+ import { readAnchorFile } from '../../core/legacy-bridge/encoding.js';
28
+ // Task 8 (plan-9a §9): cross-cutting fence framework — 9g 实施完整 13 不变量逻辑
29
+ import { crossCuttingFenceCheck } from '../../core/archive/fence.js';
30
+ // plan-9d Task 6:verify_findings fence + ack-log consistency
31
+ import { validateVerifyFindingsFence } from '../../core/archive/verify-findings-fence.js';
32
+ import { validateAckLogConsistency } from '../../core/archive/ack-log-consistency.js';
33
+ // plan-9c Task 2:pause_decisions fence
34
+ import { validatePauseDecisionsFence } from '../../core/archive/pause-decisions-fence.js';
35
+ // plan-9e1 Task 4:三级 fence + summary builder + render + ScopeEntriesIntegrityError(v2 BLOCKER 4)
36
+ import { validateThreeLevelFence } from '../../core/archive/three-level-fence.js';
37
+ import { buildArchiveSummary, ScopeEntriesIntegrityError, } from '../../core/archive/summary-builder.js';
38
+ import { renderArchiveSummaryOutput } from '../../core/archive/summary-render.js';
39
+ // plan-backlog-registry Task 7:archive 成功后自动重生成 forge/backlog/
40
+ import { generateBacklog } from '../../core/backlog/index.js';
41
+ // plan-9e1 Task 5:resume-summary 子模式
42
+ import { resumeArchiveSummary } from '../../core/archive/resume-summary.js';
43
+ // plan-9j Task 5:legacy-exemption + version-retrograde fence
44
+ import { validateLegacyExemption } from '../../core/archive/legacy-exemption.js';
45
+ import { validateVersionRetrograde } from '../../core/archive/version-retrograde-fence.js';
46
+ /**
47
+ * 检测当前目录是否真实处于 git 工作树中
48
+ * P1 修复:用真实 git 状态决定,不信 marker 字段
49
+ * @param cwd 要检测的目录路径
50
+ * @returns true = 真实 git 工作树, false = 非 git
51
+ */
52
+ function isProjectActuallyGit(cwd) {
53
+ try {
54
+ execFileSync('git', ['rev-parse', '--is-inside-work-tree'], {
55
+ cwd,
56
+ encoding: 'utf8',
57
+ stdio: ['ignore', 'pipe', 'ignore'],
58
+ });
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ export function buildArchiveCommand() {
66
+ return new Command('archive')
67
+ .argument('[changeId]', 'change directory id (e.g., add-login)')
68
+ .description('Archive a verified+reviewed change')
69
+ .option('--force', 'accept human-override or non-git review markers')
70
+ .option('--recover', 'recover from a half-completed archive transaction')
71
+ .option('--resume-summary <archiveId>', 'resume rename archive_summary.tmp.yaml → archive_summary.yaml (rare half-completed state, plan-9e1)')
72
+ .action(async (changeId, opts) => {
73
+ const forgeRoot = join(process.cwd(), 'forge');
74
+ // —— --recover 独立路径 ——
75
+ if (opts.recover) {
76
+ let release;
77
+ try {
78
+ release = await acquireLock(forgeRoot, 'recover');
79
+ const r = await recover(forgeRoot);
80
+ console.log(r.message);
81
+ // Plan 6:case C 处理 — 完整性 check + 交互二选一
82
+ if (r.case === 'C' && r.caseCData) {
83
+ const { backupIntegrity, archiveIntegrity } = r.caseCData;
84
+ // 任一不完整 → 退出码 4(spec §3.5 case C 末尾"任一不完整 → 输出诊断 + 退出码 4")
85
+ if (!backupIntegrity.ok || !archiveIntegrity.ok) {
86
+ console.error('✗ case C 完整性 check 失败,需人工介入:');
87
+ if (!backupIntegrity.ok)
88
+ console.error(` backup: ${backupIntegrity.reason}`);
89
+ if (!archiveIntegrity.ok)
90
+ console.error(` archive: ${archiveIntegrity.reason}`);
91
+ const rel = release;
92
+ release = undefined;
93
+ if (rel)
94
+ await rel();
95
+ process.exit(4);
96
+ }
97
+ // 两者都完整 → 交互式二选一
98
+ const choice = await promptRecoverChoice();
99
+ if (choice === 'complete-archive') {
100
+ // 完成归档:重跑 Sync(applyDeltas)+ 删 backup
101
+ await applyDeltas(r.caseCData.currentSpecsDir, r.caseCData.deltas);
102
+ await rm(r.caseCData.backupDir, { recursive: true, force: true });
103
+ console.log('✓ case C 选择 [1] 完成归档:Sync 重跑成功,backup 已清理');
104
+ }
105
+ else {
106
+ // 撤销归档:从 backup 恢复 forge/specs/ + 反向 rename
107
+ await restoreSpecsFromBackup(r.caseCData.backupDir, r.caseCData.currentSpecsDir);
108
+ // rename 失败时 specs 已还原但 archive 仍在原位,整体可重入(再跑 --recover 仍可完成)
109
+ await rename(r.caseCData.archiveChangeDir, join(forgeRoot, 'changes', r.caseCData.changeOrigId));
110
+ await rm(r.caseCData.backupDir, { recursive: true, force: true });
111
+ console.log('✓ case C 选择 [2] 撤销归档:specs 已还原,archive 反向 rename 完成');
112
+ }
113
+ const rel = release;
114
+ release = undefined;
115
+ if (rel)
116
+ await rel();
117
+ process.exit(0);
118
+ }
119
+ if (r.case === 'corrupt') {
120
+ // C2 修复:先 release lock 再 exit,避免 process.exit 跳过 finally
121
+ // 置 undefined 防止 finally 再次调用
122
+ const rel = release;
123
+ release = undefined;
124
+ if (rel)
125
+ await rel();
126
+ process.exit(4);
127
+ }
128
+ // C2 修复:先 release lock 再 exit,置 undefined 防止 finally 重复调用
129
+ const rel = release;
130
+ release = undefined;
131
+ if (rel)
132
+ await rel();
133
+ process.exit(0);
134
+ }
135
+ catch (err) {
136
+ if (err instanceof LockHeldError) {
137
+ console.error(err.message);
138
+ // LockHeldError 时 release 未赋值,无需 release
139
+ process.exit(5);
140
+ }
141
+ throw err;
142
+ }
143
+ finally {
144
+ if (release)
145
+ await release();
146
+ }
147
+ }
148
+ // —— plan-9e1 Task 5:--resume-summary 独立路径(v2 BLOCKER 1 + 5 修订)——
149
+ if (opts.resumeSummary) {
150
+ let release;
151
+ try {
152
+ release = await acquireLock(forgeRoot, 'resume-summary');
153
+ const r = await resumeArchiveSummary(forgeRoot, opts.resumeSummary);
154
+ if (r.kind === 'ok') {
155
+ console.log(r.message);
156
+ const rel = release;
157
+ release = undefined;
158
+ if (rel)
159
+ await rel();
160
+ process.exit(0);
161
+ }
162
+ // v2 BLOCKER 5:corrupt → exit 3(沿 master §3.12.3 corrupt 档)
163
+ if (r.kind === 'corrupt') {
164
+ console.error(r.message);
165
+ const rel = release;
166
+ release = undefined;
167
+ if (rel)
168
+ await rel();
169
+ process.exit(3);
170
+ }
171
+ // conflict / missing 都是 business-fail → exit 1
172
+ console.error(r.message);
173
+ const rel = release;
174
+ release = undefined;
175
+ if (rel)
176
+ await rel();
177
+ process.exit(1);
178
+ }
179
+ catch (err) {
180
+ if (err instanceof LockHeldError) {
181
+ // v2 BLOCKER 1:lock-held → exit 2(对齐 master §3.12.3 freeze;v0.4 --recover exit 5 是遗留)
182
+ console.error(err.message);
183
+ process.exit(2);
184
+ }
185
+ throw err;
186
+ }
187
+ finally {
188
+ if (release)
189
+ await release();
190
+ }
191
+ }
192
+ // —— 正常 archive 路径 ——
193
+ if (!changeId) {
194
+ console.error('✗ changeId required (unless using --recover)');
195
+ process.exit(1);
196
+ }
197
+ // C2 修复:改为 let,允许在 process.exit 前先 release
198
+ let archiveRelease;
199
+ try {
200
+ archiveRelease = await acquireLock(forgeRoot, 'archive');
201
+ // Plan 7 PREFLIGHT(spec §2.5 line 183-204):acquireLock 之后、archive 严格门禁(marker check)之前。
202
+ // 设计意图:用户立即拿到 sync-state 报告,不被 marker 失败遮蔽。
203
+ // 决策 #23:复用 archive.lock,不再 acquire legacy-bridge.lock。
204
+ // preflight 不再 process.exit,改返 PreflightResult,caller 在 try 块内手动 release+exit
205
+ // 与 marker check 现有 inline-release convention 一致(避免 process.exit 跳过 finally 致锁残留)
206
+ const preflightResult = await runArchivePreflight(forgeRoot, changeId);
207
+ if (preflightResult.kind !== 'ok') {
208
+ console.error(preflightResult.message);
209
+ await archiveRelease();
210
+ process.exit(2);
211
+ }
212
+ // plan-9g 默认开启 14 不变量 fence(brainstorm v6 删两 opt-in flag);所有 archive 调用都跑
213
+ const fenceResult = await crossCuttingFenceCheck(join(forgeRoot, 'changes', changeId));
214
+ if (!fenceResult.ok) {
215
+ console.error('✗ cross-cutting fence rejected archive:');
216
+ for (const r of fenceResult.results) {
217
+ if (!r.ok)
218
+ console.error(` - ${r.invariant}: ${r.reason}`);
219
+ }
220
+ const rel = archiveRelease;
221
+ archiveRelease = undefined;
222
+ if (rel)
223
+ await rel();
224
+ process.exit(1);
225
+ }
226
+ const changeDir = join(forgeRoot, 'changes', changeId);
227
+ const verifyPath = join(changeDir, '.verify-passed');
228
+ const reviewPath = join(changeDir, '.review-passed');
229
+ // 步骤 1:检查 .verify-passed 和 .review-passed 都存在
230
+ if (!existsSync(verifyPath)) {
231
+ console.error(`✗ archive 拒绝:缺 .verify-passed (in ${changeDir})`);
232
+ // C2 修复:先 release lock 再 exit
233
+ await archiveRelease();
234
+ process.exit(2);
235
+ }
236
+ if (!existsSync(reviewPath)) {
237
+ console.error(`✗ archive 拒绝:缺 .review-passed (in ${changeDir})`);
238
+ // C2 修复:先 release lock 再 exit
239
+ await archiveRelease();
240
+ process.exit(2);
241
+ }
242
+ // 步骤 2:解析 + schema 校验两个 marker
243
+ const verifyText = await readFile(verifyPath, 'utf8');
244
+ const reviewText = await readFile(reviewPath, 'utf8');
245
+ const verifyMarker = parseMarker(verifyText);
246
+ const reviewMarker = parseMarker(reviewText);
247
+ // 步骤 2a:schema 结构校验
248
+ const verifyResult = validateMarkerSchema(verifyMarker, verifyPath);
249
+ if (!verifyResult.valid) {
250
+ console.error(`✗ .verify-passed marker schema 校验失败:${verifyResult.errors[0]?.message}`);
251
+ // C2 修复:先 release lock 再 exit
252
+ await archiveRelease();
253
+ process.exit(2);
254
+ }
255
+ const reviewResult = validateMarkerSchema(reviewMarker, reviewPath);
256
+ if (!reviewResult.valid) {
257
+ console.error(`✗ .review-passed marker schema 校验失败:${reviewResult.errors[0]?.message}`);
258
+ // C2 修复:先 release lock 再 exit
259
+ await archiveRelease();
260
+ process.exit(2);
261
+ }
262
+ // 步骤 2b:P1.1 — schema 类型限定(.verify-passed 必须是 forge-verify/v1)
263
+ // 通过 unknown 中转以绕过 TS 的交叉类型检查
264
+ const verifyRec = verifyMarker;
265
+ const reviewRec = reviewMarker;
266
+ if (verifyRec['schema'] !== 'forge-verify/v1') {
267
+ console.error(`✗ .verify-passed 必须是 forge-verify/v1,实际:${String(verifyRec['schema'])}`);
268
+ await archiveRelease();
269
+ process.exit(2);
270
+ }
271
+ if (reviewRec['schema'] !== 'forge-review/v1') {
272
+ console.error(`✗ .review-passed 必须是 forge-review/v1,实际:${String(reviewRec['schema'])}`);
273
+ await archiveRelease();
274
+ process.exit(2);
275
+ }
276
+ // 步骤 3:重算 tasks_hash 和 content_hash + 比对
277
+ const tasksContent = await readFile(join(changeDir, 'tasks.md'), 'utf8');
278
+ const tasksHashNow = computeTasksHash(tasksContent);
279
+ const contentHashNow = await computeContentHash(changeDir);
280
+ // 将 marker 转为 Record 以便访问字段
281
+ const vRec = verifyRec;
282
+ const rRec = reviewRec;
283
+ // 比对 verify marker 里的 hash
284
+ if (tasksHashNow !== vRec['tasks_hash'] || contentHashNow !== vRec['content_hash']) {
285
+ console.error('✗ .verify-passed marker 已过期(tasks/content hash 不匹配),请重跑 verify');
286
+ // C2 修复:先 release lock 再 exit
287
+ // plan-9d Task 6 v2 M-1 修订:hash mismatch = fence business-fail,exit 1(沿 master §3.12.3)
288
+ await archiveRelease();
289
+ process.exit(1);
290
+ }
291
+ // 比对 review marker 里的 hash
292
+ if (tasksHashNow !== rRec['tasks_hash'] || contentHashNow !== rRec['content_hash']) {
293
+ console.error('✗ .review-passed marker 已过期(tasks/content hash 不匹配),请重跑 review');
294
+ // C2 修复:先 release lock 再 exit
295
+ // plan-9d Task 6 v2 M-1 修订:hash mismatch = fence business-fail,exit 1
296
+ await archiveRelease();
297
+ process.exit(1);
298
+ }
299
+ // 步骤 3.4(plan-9j Task 5):legacy-exemption + version-retrograde fence
300
+ // 沿 design §3.4.4.1 + §3.4.4.3 — 在 evidence 校验之前拦截 legacy marker 异常
301
+ const legacyVerifyResult = validateLegacyExemption(verifyRec, verifyPath);
302
+ if (!legacyVerifyResult.valid) {
303
+ console.error('✗ legacy-exemption fence 拒签(verify-passed):');
304
+ for (const e of legacyVerifyResult.errors)
305
+ console.error(` - ${e.field}: ${e.message}`);
306
+ await archiveRelease();
307
+ process.exit(1);
308
+ }
309
+ const legacyReviewResult = validateLegacyExemption(reviewRec, reviewPath);
310
+ if (!legacyReviewResult.valid) {
311
+ console.error('✗ legacy-exemption fence 拒签(review-passed):');
312
+ for (const e of legacyReviewResult.errors)
313
+ console.error(` - ${e.field}: ${e.message}`);
314
+ await archiveRelease();
315
+ process.exit(1);
316
+ }
317
+ const retrogradeVerifyResult = await validateVersionRetrograde(verifyPath, verifyRec, process.cwd());
318
+ if (!retrogradeVerifyResult.valid) {
319
+ console.error('✗ version-retrograde fence 拒签(verify-passed):');
320
+ for (const e of retrogradeVerifyResult.errors)
321
+ console.error(` - ${e.field}: ${e.message}`);
322
+ await archiveRelease();
323
+ process.exit(1);
324
+ }
325
+ const retrogradeReviewResult = await validateVersionRetrograde(reviewPath, reviewRec, process.cwd());
326
+ if (!retrogradeReviewResult.valid) {
327
+ console.error('✗ version-retrograde fence 拒签(review-passed):');
328
+ for (const e of retrogradeReviewResult.errors)
329
+ console.error(` - ${e.field}: ${e.message}`);
330
+ await archiveRelease();
331
+ process.exit(1);
332
+ }
333
+ // 步骤 3.5:P1.2 — 验证 evidence 完整性
334
+ const evResult = await validateEvidence(verifyRec, verifyPath);
335
+ if (!evResult.valid) {
336
+ console.error('✗ verify evidence 校验失败:');
337
+ for (const e of evResult.errors)
338
+ console.error(` - ${e.field}: ${e.message}`);
339
+ // plan-9d Task 6 v2 M-1 修订:evidence 校验失败 = fence business-fail,exit 1
340
+ await archiveRelease();
341
+ process.exit(1);
342
+ }
343
+ // 步骤 3.6:plan-9d Task 6 — verify_findings fence 三级 × resolved × ack 矩阵 + finding_hash 篡改拒签
344
+ const vfResult = validateVerifyFindingsFence(verifyRec, verifyPath);
345
+ if (!vfResult.valid) {
346
+ console.error('✗ verify_findings fence 拒签:');
347
+ for (const e of vfResult.errors)
348
+ console.error(` - ${e.field}: ${e.message}`);
349
+ await archiveRelease();
350
+ process.exit(1);
351
+ }
352
+ // 步骤 3.7:plan-9c Task 2 — pause_decisions fence(option 1-4 五类业务校验 + CRITICAL 重定向)
353
+ // v2 codex MAJOR 4 修订:对 verifyRec + reviewRec 都跑 fence
354
+ // v4 codex NEW-MAJOR A6 + B4 联动:fence 不再需要 ctx 参数(B4 改用 parseMarkdown 局部段校验,
355
+ // 不再调 validateScopeEntries → ctx unused → 沿 YAGNI 移除)
356
+ const pdVerifyResult = await validatePauseDecisionsFence(verifyRec, changeDir, verifyPath);
357
+ if (!pdVerifyResult.valid) {
358
+ console.error('✗ pause_decisions fence 拒签(verify-passed):');
359
+ for (const e of pdVerifyResult.errors)
360
+ console.error(` - ${e.field}: ${e.message}`);
361
+ await archiveRelease();
362
+ process.exit(1);
363
+ }
364
+ const pdReviewResult = await validatePauseDecisionsFence(reviewRec, changeDir, reviewPath);
365
+ if (!pdReviewResult.valid) {
366
+ console.error('✗ pause_decisions fence 拒签(review-passed):');
367
+ for (const e of pdReviewResult.errors)
368
+ console.error(` - ${e.field}: ${e.message}`);
369
+ await archiveRelease();
370
+ process.exit(1);
371
+ }
372
+ // 步骤 3.8:plan-9d Task 6 v2 B-4 — ack-log 一致性 cross-check
373
+ // v3 codex BLOCKER 2 修订:对 verifyRec + reviewRec 都跑 cross-check
374
+ // (review marker 同样可承载 pause_decisions superset additive,沿 9c Task 1 schema)
375
+ const ackVerifyResult = await validateAckLogConsistency(changeDir, verifyRec, changeId);
376
+ if (!ackVerifyResult.valid) {
377
+ console.error('✗ ack-log 一致性校验失败(verify-passed):');
378
+ for (const e of ackVerifyResult.errors)
379
+ console.error(` - ${e.field}: ${e.message}`);
380
+ await archiveRelease();
381
+ process.exit(1);
382
+ }
383
+ const ackReviewResult = await validateAckLogConsistency(changeDir, reviewRec, changeId);
384
+ if (!ackReviewResult.valid) {
385
+ console.error('✗ ack-log 一致性校验失败(review-passed):');
386
+ for (const e of ackReviewResult.errors)
387
+ console.error(` - ${e.field}: ${e.message}`);
388
+ await archiveRelease();
389
+ process.exit(1);
390
+ }
391
+ // 步骤 3.9:plan-9e1 Task 4 — 三级业务行为 fence(沿 design §2.4.2)
392
+ // CRITICAL+resolved=false 拒签(sanity 双重保险)/ WARNING+resolved=false+无 ack 拒签 /
393
+ // WARNING+resolved=false+acked 通过 / SUGGESTION+resolved=false 通过(handoff to backlog)
394
+ const tlfResult = validateThreeLevelFence(verifyRec, reviewRec, verifyPath, reviewPath);
395
+ if (!tlfResult.valid) {
396
+ console.error('✗ 三级业务行为 fence 拒签:');
397
+ for (const e of tlfResult.errors)
398
+ console.error(` - ${e.field}: ${e.message}`);
399
+ await archiveRelease();
400
+ process.exit(1);
401
+ }
402
+ // 步骤 4:human-override + 真实 git 状态校验 + outcomes 校验
403
+ const verifyBy = vRec['verified_by'];
404
+ const reviewBy = rRec['reviewed_by'];
405
+ const reviewGit = reviewRec['git'];
406
+ const markerSaysGit = reviewGit?.['is_git_repo'] === true;
407
+ // P1 修复:用真实 git 状态决定,不信 marker 字段
408
+ const projectIsGit = isProjectActuallyGit(process.cwd());
409
+ // 4a. human-override 必须 --force
410
+ if (verifyBy === 'human-override' || reviewBy === 'human-override') {
411
+ if (!opts.force) {
412
+ console.error('✗ human-override 标记需要 --force 接受\n' +
413
+ ' verified_by=' +
414
+ verifyBy +
415
+ ' reviewed_by=' +
416
+ reviewBy);
417
+ // C2 修复:先 release lock 再 exit
418
+ await archiveRelease();
419
+ process.exit(2);
420
+ }
421
+ }
422
+ // 4b. marker 与真实 git 状态不一致 → 可疑伪造,拒绝(--force 也不能覆盖)
423
+ if (projectIsGit && !markerSaysGit) {
424
+ console.error('✗ review marker 标记 is_git_repo=false,但项目实际是 git。可能为伪造,拒绝(即使 --force)');
425
+ await archiveRelease();
426
+ process.exit(2);
427
+ }
428
+ if (!projectIsGit && markerSaysGit) {
429
+ console.error('✗ review marker 标记 is_git_repo=true,但项目实际不是 git。可能为伪造,拒绝');
430
+ await archiveRelease();
431
+ process.exit(2);
432
+ }
433
+ // 4c. 真非 git → 必须 --force(spec §3.4 要求)
434
+ if (!projectIsGit && !opts.force) {
435
+ console.error(`✗ 非 git 项目下 review 标记不绑定代码 diff,archive 必须 --force 才接受`);
436
+ await archiveRelease();
437
+ process.exit(2);
438
+ }
439
+ // 4d. 真 git → 跑 git integrity(重算 head + diff_hash)
440
+ if (projectIsGit) {
441
+ const gitResult = await validateReviewGitIntegrity(reviewRec, process.cwd(), reviewPath);
442
+ if (!gitResult.valid) {
443
+ console.error('✗ review git 完整性校验失败:');
444
+ for (const e of gitResult.errors)
445
+ console.error(` - ${e.field}: ${e.message}`);
446
+ await archiveRelease();
447
+ process.exit(2);
448
+ }
449
+ }
450
+ // 4e. review_outcomes:accepted=true 必须 resolved=true(已实现,不变)
451
+ const outResult = validateReviewOutcomes(reviewRec, reviewPath);
452
+ if (!outResult.valid) {
453
+ console.error('✗ review_outcomes 校验失败:');
454
+ for (const e of outResult.errors)
455
+ console.error(` - ${e.field}: ${e.message}`);
456
+ await archiveRelease();
457
+ process.exit(2);
458
+ }
459
+ // 步骤 4.5:plan-9e1 Task 4 — 构造 archive_summary(传给 transaction 落 .tmp)
460
+ // v2 BLOCKER 4 修订:try/catch ScopeEntriesIntegrityError → fence business-fail exit 1
461
+ const archiveDate = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
462
+ let archiveSummary;
463
+ try {
464
+ // plan-9e2 Task 2 同步改:加 fenceResult 入参(沿 archive.ts:231 现有 crossCuttingFenceCheck 输出)— Task 4 进一步整理调用顺序
465
+ archiveSummary = await buildArchiveSummary(verifyRec, reviewRec, changeDir, // 沿用 line 213 已定义的 changeDir
466
+ changeId, fenceResult);
467
+ }
468
+ catch (err) {
469
+ if (err instanceof ScopeEntriesIntegrityError) {
470
+ console.error(`✗ scope-entries 完整性 fence 拒签(${err.artifactName} section ${err.anchorId}):${err.message}`);
471
+ await archiveRelease();
472
+ process.exit(1);
473
+ }
474
+ throw err;
475
+ }
476
+ // 步骤 5:调 archiveTransaction(Move→Sync,含 .tmp 写 / rename / 回滚)
477
+ await archiveTransaction({ forgeRoot, changeId, archiveDate, archiveSummary });
478
+ // 步骤 5.5:Plan 7 post-archive hook(enforce_sync=false 时不阻塞,只产报告)
479
+ await runArchivePostHook(forgeRoot, changeId);
480
+ // 步骤 6:plan-9e1 Task 4 — 渲染 archive_summary 输出(沿 design §2.4.4)
481
+ const archiveDirName = `${archiveDate}-${changeId}`;
482
+ console.log(renderArchiveSummaryOutput(archiveSummary, archiveDirName));
483
+ // 步骤 6.5:plan-backlog-registry — 重生成 forge/backlog/ 注册表
484
+ // 失败不回滚 archive(archive 主流程已成功,backlog 是衍生产物)
485
+ try {
486
+ const bl = await generateBacklog(forgeRoot);
487
+ console.log(`Backlog: forge/backlog/active.md (${bl.openCount} open, ${bl.warningCount} warnings)`);
488
+ }
489
+ catch (blErr) {
490
+ const m = blErr instanceof Error ? blErr.message : String(blErr);
491
+ console.error(`⚠ backlog 重生成失败(不影响 archive):${m} —— 可手动跑 \`forge backlog\``);
492
+ }
493
+ }
494
+ catch (err) {
495
+ // exit code 映射 — spec §3.5
496
+ if (err instanceof LockHeldError) {
497
+ // lock 被占用 → exit 5
498
+ console.error(err.message);
499
+ if (archiveRelease)
500
+ await archiveRelease();
501
+ process.exit(5);
502
+ }
503
+ const msg = err instanceof Error ? err.message : String(err);
504
+ if (msg.includes('AND rollback failed')) {
505
+ // 同步失败且回滚也失败 → 需人工介入 → exit 3
506
+ console.error(`✗ ${msg}`);
507
+ if (archiveRelease)
508
+ await archiveRelease();
509
+ process.exit(3);
510
+ }
511
+ if (msg.includes('rolled back')) {
512
+ // 同步失败但回滚成功 → 可重试 → exit 2
513
+ console.error(`✗ ${msg}`);
514
+ if (archiveRelease)
515
+ await archiveRelease();
516
+ process.exit(2);
517
+ }
518
+ // 兜底:未知错误 → exit 1
519
+ console.error(`✗ ${msg}`);
520
+ if (archiveRelease)
521
+ await archiveRelease();
522
+ process.exit(1);
523
+ }
524
+ finally {
525
+ // finally 作为最终兜底(catch 内 process.exit 会跳过 finally,release 函数幂等)
526
+ if (archiveRelease)
527
+ await archiveRelease();
528
+ }
529
+ });
530
+ }
531
+ /**
532
+ * 从 backup 目录把所有备份的 specs 文件还原到 currentSpecsDir(case C [2] 撤销归档用)。
533
+ *
534
+ * 简单语义:backup 内每个 .md 文件 copy 回 currentSpecsDir/ 同名位置,
535
+ * 对应的 currentSpecsDir 内文件被覆盖。
536
+ * 不删除 currentSpecsDir 中"backup 没有的文件"(理由:那些是 archive 没影响的旧文件)。
537
+ */
538
+ async function restoreSpecsFromBackup(backupDir, currentSpecsDir) {
539
+ const entries = await readdir(backupDir);
540
+ await mkdir(currentSpecsDir, { recursive: true });
541
+ for (const name of entries) {
542
+ if (!name.endsWith('.md'))
543
+ continue;
544
+ await copyFile(join(backupDir, name), join(currentSpecsDir, name));
545
+ }
546
+ }
547
+ /**
548
+ * Plan 7 §2.5:archive preflight — enforce_sync=true 时阻塞 critical 差异。
549
+ *
550
+ * Graceful skip 路径(全部返 {kind:'ok'}):
551
+ * 1. forge/config.yaml 不存在
552
+ * 2. legacy-anchors.yaml 不存在
553
+ * 3. legacy_bridge.allow_llm_calls != true
554
+ * 4. legacy_bridge.enforce_sync != true
555
+ *
556
+ * 走 LLM 路径时:
557
+ * - ack 不就绪 → 返 {kind:'ack-missing'}
558
+ * - 含 critical pending → sync-state 已写后返 {kind:'critical-pending'}
559
+ * - 全过 → 返 {kind:'ok'}
560
+ *
561
+ * **不再调 process.exit / console.error**:caller(archive 命令)负责打印消息 +
562
+ * release archive.lock + exit,避免本函数内 process.exit 跳过 caller finally
563
+ * 导致 archive.lock 文件残留。
564
+ */
565
+ export async function runArchivePreflight(forgeRoot, changeId) {
566
+ const configPath = join(forgeRoot, 'config.yaml');
567
+ if (!existsSync(configPath))
568
+ return { kind: 'ok' };
569
+ const config = parseYaml(await readFile(configPath, 'utf8'));
570
+ // §2.5:仅当 legacy-anchors.yaml 存在 AND allow_llm_calls=true AND enforce_sync=true 时进入 preflight
571
+ const anchors = await loadAnchorsFile(forgeRoot).catch(() => null);
572
+ if (!anchors)
573
+ return { kind: 'ok' };
574
+ if (!config.legacy_bridge?.allow_llm_calls)
575
+ return { kind: 'ok' };
576
+ if (!config.legacy_bridge?.enforce_sync)
577
+ return { kind: 'ok' };
578
+ const ack = await checkAck(forgeRoot, config, anchors);
579
+ if (!ack.ok) {
580
+ return {
581
+ kind: 'ack-missing',
582
+ message: `legacy_bridge.enforce_sync=true 但 ack 未就绪:${ack.reason};请先跑 forge legacy-bridge --acknowledge-data-transfer`,
583
+ };
584
+ }
585
+ // 拼 change context(同 sync-check 命令)
586
+ const changesDir = join(forgeRoot, 'changes', changeId);
587
+ let changeContext = '';
588
+ const affectedModules = [];
589
+ if (existsSync(join(changesDir, 'proposal.md'))) {
590
+ changeContext += await readFile(join(changesDir, 'proposal.md'), 'utf8');
591
+ }
592
+ const specsDir = join(changesDir, 'specs');
593
+ if (existsSync(specsDir)) {
594
+ const files = await readdir(specsDir);
595
+ for (const f of files) {
596
+ changeContext += `\n## specs/${f}\n${await readFile(join(specsDir, f), 'utf8')}`;
597
+ affectedModules.push(f.replace(/\.md$/, ''));
598
+ }
599
+ }
600
+ // 跑 sync-check(决策 #23:复用 archive.lock,不再 acquire legacy-bridge.lock)
601
+ // 运行时动态加载 forge-eval/load-env(避免 src/ rootDir 静态分析边界限制)
602
+ const evalLoadEnvPath = new URL('../../../forge-eval/load-env.js', import.meta.url).href;
603
+ const { loadEnv } = (await import(/* @vite-ignore */ evalLoadEnvPath));
604
+ const { anthropicApiKey } = loadEnv();
605
+ const client = new Anthropic({ apiKey: anthropicApiKey });
606
+ const out = await runSyncCheck(client, {
607
+ changeId,
608
+ changeContext,
609
+ affectedModules,
610
+ anchors,
611
+ autoResolveCrossAnchor: config.legacy_bridge.auto_resolve_cross_anchor ?? false,
612
+ mtimeOf: (p) => {
613
+ try {
614
+ return Math.floor(statSync(p).mtimeMs / 1000);
615
+ }
616
+ catch {
617
+ return 0;
618
+ }
619
+ },
620
+ }, async (path) => (await readAnchorFile(path)).text);
621
+ await mkdir(join(forgeRoot, 'legacy-sync-state'), { recursive: true });
622
+ await writeFile(join(forgeRoot, 'legacy-sync-state', `${changeId}.md`), renderDiffMarkdown(out.syncState), 'utf8');
623
+ await writeFile(join(forgeRoot, 'legacy-sync-state', `${changeId}.yaml`), renderDiffYaml(out.syncState), 'utf8');
624
+ if (hasCriticalPending(out.syncState)) {
625
+ const criticalCount = out.syncState.diffs.filter((d) => d.severity === 'critical' && d.status === 'pending').length;
626
+ return {
627
+ kind: 'critical-pending',
628
+ criticalCount,
629
+ message: `✗ ${criticalCount} 项 critical 差异未 resolve;\n` +
630
+ `跑 forge legacy-bridge resolve ${changeId} 后重试,或在 forge/legacy-sync-state/${changeId}.yaml 标 ack`,
631
+ };
632
+ }
633
+ return { kind: 'ok' };
634
+ }
635
+ /**
636
+ * Plan 7 §2.5:post-archive hook — 不阻塞,仅在 enforce_sync=false 时跑(产报告)。
637
+ * enforce_sync=true 已由 preflight 跑过;graceful skip 路径同 preflight。
638
+ */
639
+ export async function runArchivePostHook(forgeRoot, changeId) {
640
+ const configPath = join(forgeRoot, 'config.yaml');
641
+ if (!existsSync(configPath))
642
+ return;
643
+ const config = parseYaml(await readFile(configPath, 'utf8'));
644
+ if (!config.legacy_bridge?.allow_llm_calls)
645
+ return;
646
+ if (config.legacy_bridge?.enforce_sync)
647
+ return; // 已在 preflight 跑过
648
+ const anchors = await loadAnchorsFile(forgeRoot).catch(() => null);
649
+ if (!anchors)
650
+ return;
651
+ const ack = await checkAck(forgeRoot, config, anchors);
652
+ if (!ack.ok)
653
+ return; // ack 不就绪 → graceful skip
654
+ // 跑 sync-check 但不阻塞
655
+ const changesDir = join(forgeRoot, 'changes', 'archive', `${new Date().toISOString().slice(0, 10)}-${changeId}`);
656
+ const proposalPath = existsSync(join(changesDir, 'proposal.md'))
657
+ ? join(changesDir, 'proposal.md')
658
+ : join(forgeRoot, 'changes', changeId, 'proposal.md');
659
+ let changeContext = '';
660
+ if (existsSync(proposalPath)) {
661
+ changeContext = await readFile(proposalPath, 'utf8');
662
+ }
663
+ const affectedModules = [];
664
+ // 简化:从 changeId 推测 module(占位,真实环境靠 specs/<area>.md)
665
+ const evalLoadEnvPath = new URL('../../../forge-eval/load-env.js', import.meta.url).href;
666
+ const { loadEnv } = (await import(/* @vite-ignore */ evalLoadEnvPath));
667
+ const { anthropicApiKey } = loadEnv();
668
+ const client = new Anthropic({ apiKey: anthropicApiKey });
669
+ const out = await runSyncCheck(client, {
670
+ changeId,
671
+ changeContext,
672
+ affectedModules,
673
+ anchors,
674
+ autoResolveCrossAnchor: config.legacy_bridge.auto_resolve_cross_anchor ?? false,
675
+ mtimeOf: (p) => {
676
+ try {
677
+ return Math.floor(statSync(p).mtimeMs / 1000);
678
+ }
679
+ catch {
680
+ return 0;
681
+ }
682
+ },
683
+ }, async (path) => (await readAnchorFile(path)).text);
684
+ await mkdir(join(forgeRoot, 'legacy-sync-state'), { recursive: true });
685
+ await writeFile(join(forgeRoot, 'legacy-sync-state', `${changeId}.md`), renderDiffMarkdown(out.syncState), 'utf8');
686
+ await writeFile(join(forgeRoot, 'legacy-sync-state', `${changeId}.yaml`), renderDiffYaml(out.syncState), 'utf8');
687
+ console.log(`⚠ ${out.syncState.diffs.length} 项老文档可能需更新,详见 forge/legacy-sync-state/${changeId}.md`);
688
+ }
689
+ //# sourceMappingURL=archive.js.map