@rpamis/comet 0.4.0-beta.5 → 0.4.0-beta.7

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 (714) hide show
  1. package/README.md +215 -77
  2. package/assets/manifest.json +14 -5
  3. package/assets/skills/comet/SKILL.md +17 -282
  4. package/assets/skills/comet/reference/comet-yaml-fields.md +5 -3
  5. package/assets/skills/comet/reference/context-recovery.md +3 -3
  6. package/assets/skills/comet/reference/intent-frame.md +2 -2
  7. package/assets/skills/comet/reference/scripts.md +2 -2
  8. package/assets/skills/comet/rules/comet-workflow-guard.en.md +32 -0
  9. package/assets/skills/comet/rules/comet-workflow-guard.md +32 -0
  10. package/assets/skills/comet/scripts/comet-entry-runtime.mjs +7834 -0
  11. package/assets/skills/comet/scripts/comet-hook-router.mjs +10307 -0
  12. package/assets/skills/comet/scripts/comet-runtime.mjs +782 -425
  13. package/assets/skills/comet-any/SKILL.md +4 -4
  14. package/assets/skills/comet-any/reference/authoring-subagents.md +1 -1
  15. package/assets/skills/comet-any/reference/bundle-authoring.md +1 -1
  16. package/assets/skills/comet-any/reference/subagents/reference-author.md +1 -1
  17. package/assets/skills/comet-any/reference/subagents/script-author.md +1 -1
  18. package/assets/skills/comet-any/reference/subagents/skill-core-author.md +1 -1
  19. package/assets/skills/comet-any/reference/subagents/skill-reviewer.md +2 -2
  20. package/assets/skills/comet-any/reference/subagents/workflow-entry-author.md +3 -3
  21. package/assets/skills/comet-archive/SKILL.md +7 -9
  22. package/assets/skills/comet-build/SKILL.md +17 -11
  23. package/assets/skills/comet-classic/SKILL.md +293 -0
  24. package/assets/skills/comet-design/SKILL.md +1 -1
  25. package/assets/skills/comet-hotfix/SKILL.md +20 -6
  26. package/assets/skills/comet-native/SKILL.md +257 -0
  27. package/assets/skills/comet-native/reference/artifacts.md +204 -0
  28. package/assets/skills/comet-native/reference/commands.md +118 -0
  29. package/assets/skills/comet-native/reference/recovery.md +143 -0
  30. package/assets/skills/comet-native/scripts/comet-native-hook-guard.mjs +4 -0
  31. package/assets/skills/comet-native/scripts/comet-native-runtime.mjs +28898 -0
  32. package/assets/skills/comet-open/SKILL.md +4 -4
  33. package/assets/skills/comet-tweak/SKILL.md +22 -10
  34. package/assets/skills/comet-verify/SKILL.md +2 -0
  35. package/assets/skills-zh/comet/SKILL.md +17 -270
  36. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +5 -3
  37. package/assets/skills-zh/comet/reference/context-recovery.md +3 -3
  38. package/assets/skills-zh/comet/reference/intent-frame.md +2 -2
  39. package/assets/skills-zh/comet/reference/scripts.md +2 -2
  40. package/assets/skills-zh/comet-any/SKILL.md +4 -4
  41. package/assets/skills-zh/comet-any/reference/authoring-subagents.md +1 -1
  42. package/assets/skills-zh/comet-any/reference/bundle-authoring.md +1 -1
  43. package/assets/skills-zh/comet-any/reference/subagents/reference-author.md +1 -1
  44. package/assets/skills-zh/comet-any/reference/subagents/script-author.md +1 -1
  45. package/assets/skills-zh/comet-any/reference/subagents/skill-core-author.md +1 -1
  46. package/assets/skills-zh/comet-any/reference/subagents/skill-reviewer.md +2 -2
  47. package/assets/skills-zh/comet-any/reference/subagents/workflow-entry-author.md +3 -3
  48. package/assets/skills-zh/comet-archive/SKILL.md +7 -9
  49. package/assets/skills-zh/comet-build/SKILL.md +17 -11
  50. package/assets/skills-zh/comet-classic/SKILL.md +281 -0
  51. package/assets/skills-zh/comet-design/SKILL.md +1 -1
  52. package/assets/skills-zh/comet-hotfix/SKILL.md +20 -6
  53. package/assets/skills-zh/comet-native/SKILL.md +257 -0
  54. package/assets/skills-zh/comet-native/reference/artifacts.md +206 -0
  55. package/assets/skills-zh/comet-native/reference/commands.md +118 -0
  56. package/assets/skills-zh/comet-native/reference/recovery.md +143 -0
  57. package/assets/skills-zh/comet-open/SKILL.md +4 -4
  58. package/assets/skills-zh/comet-tweak/SKILL.md +22 -10
  59. package/assets/skills-zh/comet-verify/SKILL.md +2 -0
  60. package/dist/app/cli/index.js +59 -13
  61. package/dist/app/cli/index.js.map +1 -1
  62. package/dist/app/commands/command-result.d.ts +6 -0
  63. package/dist/app/commands/command-result.d.ts.map +1 -0
  64. package/dist/app/commands/command-result.js +4 -0
  65. package/dist/app/commands/command-result.js.map +1 -0
  66. package/dist/app/commands/doctor.d.ts +1 -0
  67. package/dist/app/commands/doctor.d.ts.map +1 -1
  68. package/dist/app/commands/doctor.js +201 -26
  69. package/dist/app/commands/doctor.js.map +1 -1
  70. package/dist/app/commands/eval.d.ts +3 -1
  71. package/dist/app/commands/eval.d.ts.map +1 -1
  72. package/dist/app/commands/eval.js +17 -7
  73. package/dist/app/commands/eval.js.map +1 -1
  74. package/dist/app/commands/i18n.d.ts +1 -1
  75. package/dist/app/commands/i18n.d.ts.map +1 -1
  76. package/dist/app/commands/i18n.js +6 -2
  77. package/dist/app/commands/i18n.js.map +1 -1
  78. package/dist/app/commands/init.d.ts +10 -2
  79. package/dist/app/commands/init.d.ts.map +1 -1
  80. package/dist/app/commands/init.js +331 -50
  81. package/dist/app/commands/init.js.map +1 -1
  82. package/dist/app/commands/native.d.ts +2 -0
  83. package/dist/app/commands/native.d.ts.map +1 -0
  84. package/dist/app/commands/native.js +10 -0
  85. package/dist/app/commands/native.js.map +1 -0
  86. package/dist/app/commands/project-scope-selection.d.ts.map +1 -1
  87. package/dist/app/commands/project-scope-selection.js +2 -0
  88. package/dist/app/commands/project-scope-selection.js.map +1 -1
  89. package/dist/app/commands/resume-probe.d.ts.map +1 -1
  90. package/dist/app/commands/resume-probe.js +8 -2
  91. package/dist/app/commands/resume-probe.js.map +1 -1
  92. package/dist/app/commands/status.d.ts +0 -31
  93. package/dist/app/commands/status.d.ts.map +1 -1
  94. package/dist/app/commands/status.js +49 -172
  95. package/dist/app/commands/status.js.map +1 -1
  96. package/dist/app/commands/update.d.ts +20 -4
  97. package/dist/app/commands/update.d.ts.map +1 -1
  98. package/dist/app/commands/update.js +698 -90
  99. package/dist/app/commands/update.js.map +1 -1
  100. package/dist/app/commands/workflow.d.ts +6 -0
  101. package/dist/app/commands/workflow.d.ts.map +1 -0
  102. package/dist/app/commands/workflow.js +11 -0
  103. package/dist/app/commands/workflow.js.map +1 -0
  104. package/dist/config/repository-layout.json +21 -1
  105. package/dist/domains/comet-classic/classic-archive.d.ts.map +1 -1
  106. package/dist/domains/comet-classic/classic-archive.js +3 -0
  107. package/dist/domains/comet-classic/classic-archive.js.map +1 -1
  108. package/dist/domains/comet-classic/classic-branch-binding.d.ts +51 -0
  109. package/dist/domains/comet-classic/classic-branch-binding.d.ts.map +1 -0
  110. package/dist/domains/comet-classic/classic-branch-binding.js +107 -0
  111. package/dist/domains/comet-classic/classic-branch-binding.js.map +1 -0
  112. package/dist/domains/comet-classic/classic-current-change.d.ts +3 -5
  113. package/dist/domains/comet-classic/classic-current-change.d.ts.map +1 -1
  114. package/dist/domains/comet-classic/classic-current-change.js +59 -68
  115. package/dist/domains/comet-classic/classic-current-change.js.map +1 -1
  116. package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
  117. package/dist/domains/comet-classic/classic-guard.js +40 -10
  118. package/dist/domains/comet-classic/classic-guard.js.map +1 -1
  119. package/dist/domains/comet-classic/classic-hook-guard.d.ts +9 -0
  120. package/dist/domains/comet-classic/classic-hook-guard.d.ts.map +1 -1
  121. package/dist/domains/comet-classic/classic-hook-guard.js +109 -13
  122. package/dist/domains/comet-classic/classic-hook-guard.js.map +1 -1
  123. package/dist/domains/comet-classic/classic-project-config.d.ts.map +1 -1
  124. package/dist/domains/comet-classic/classic-project-config.js +12 -8
  125. package/dist/domains/comet-classic/classic-project-config.js.map +1 -1
  126. package/dist/domains/comet-classic/classic-runtime-run.d.ts.map +1 -1
  127. package/dist/domains/comet-classic/classic-runtime-run.js +9 -1
  128. package/dist/domains/comet-classic/classic-runtime-run.js.map +1 -1
  129. package/dist/domains/comet-classic/classic-state-command.d.ts.map +1 -1
  130. package/dist/domains/comet-classic/classic-state-command.js +94 -4
  131. package/dist/domains/comet-classic/classic-state-command.js.map +1 -1
  132. package/dist/domains/comet-classic/classic-state-events.d.ts +1 -1
  133. package/dist/domains/comet-classic/classic-state-events.d.ts.map +1 -1
  134. package/dist/domains/comet-classic/classic-state.d.ts +2 -1
  135. package/dist/domains/comet-classic/classic-state.d.ts.map +1 -1
  136. package/dist/domains/comet-classic/classic-state.js +3 -0
  137. package/dist/domains/comet-classic/classic-state.js.map +1 -1
  138. package/dist/domains/comet-classic/classic-transitions.d.ts.map +1 -1
  139. package/dist/domains/comet-classic/classic-transitions.js +1 -0
  140. package/dist/domains/comet-classic/classic-transitions.js.map +1 -1
  141. package/dist/domains/comet-classic/classic-validate-command.d.ts.map +1 -1
  142. package/dist/domains/comet-classic/classic-validate-command.js +6 -0
  143. package/dist/domains/comet-classic/classic-validate-command.js.map +1 -1
  144. package/dist/domains/comet-entry/current-selection-repair.d.ts +17 -0
  145. package/dist/domains/comet-entry/current-selection-repair.d.ts.map +1 -0
  146. package/dist/domains/comet-entry/current-selection-repair.js +19 -0
  147. package/dist/domains/comet-entry/current-selection-repair.js.map +1 -0
  148. package/dist/domains/comet-entry/current-selection.d.ts +28 -0
  149. package/dist/domains/comet-entry/current-selection.d.ts.map +1 -0
  150. package/dist/domains/comet-entry/current-selection.js +116 -0
  151. package/dist/domains/comet-entry/current-selection.js.map +1 -0
  152. package/dist/domains/comet-entry/entry-runtime-entry.d.ts +2 -0
  153. package/dist/domains/comet-entry/entry-runtime-entry.d.ts.map +1 -0
  154. package/dist/domains/comet-entry/entry-runtime-entry.js +3 -0
  155. package/dist/domains/comet-entry/entry-runtime-entry.js.map +1 -0
  156. package/dist/domains/comet-entry/entry-runtime.d.ts +7 -0
  157. package/dist/domains/comet-entry/entry-runtime.d.ts.map +1 -0
  158. package/dist/domains/comet-entry/entry-runtime.js +55 -0
  159. package/dist/domains/comet-entry/entry-runtime.js.map +1 -0
  160. package/dist/domains/comet-entry/hook-adapter.d.ts +6 -0
  161. package/dist/domains/comet-entry/hook-adapter.d.ts.map +1 -0
  162. package/dist/domains/comet-entry/hook-adapter.js +202 -0
  163. package/dist/domains/comet-entry/hook-adapter.js.map +1 -0
  164. package/dist/domains/comet-entry/hook-router-entry.d.ts +8 -0
  165. package/dist/domains/comet-entry/hook-router-entry.d.ts.map +1 -0
  166. package/dist/domains/comet-entry/hook-router-entry.js +92 -0
  167. package/dist/domains/comet-entry/hook-router-entry.js.map +1 -0
  168. package/dist/domains/comet-entry/hook-router.d.ts +32 -0
  169. package/dist/domains/comet-entry/hook-router.d.ts.map +1 -0
  170. package/dist/domains/comet-entry/hook-router.js +133 -0
  171. package/dist/domains/comet-entry/hook-router.js.map +1 -0
  172. package/dist/domains/comet-entry/hook-types.d.ts +20 -0
  173. package/dist/domains/comet-entry/hook-types.d.ts.map +1 -0
  174. package/dist/domains/comet-entry/hook-types.js +2 -0
  175. package/dist/domains/comet-entry/hook-types.js.map +1 -0
  176. package/dist/domains/comet-entry/init-workflow.d.ts +16 -0
  177. package/dist/domains/comet-entry/init-workflow.d.ts.map +1 -0
  178. package/dist/domains/comet-entry/init-workflow.js +103 -0
  179. package/dist/domains/comet-entry/init-workflow.js.map +1 -0
  180. package/dist/domains/comet-entry/project-status.d.ts +3 -0
  181. package/dist/domains/comet-entry/project-status.d.ts.map +1 -0
  182. package/dist/domains/comet-entry/project-status.js +222 -0
  183. package/dist/domains/comet-entry/project-status.js.map +1 -0
  184. package/dist/domains/comet-entry/resolve-entry.d.ts +3 -0
  185. package/dist/domains/comet-entry/resolve-entry.d.ts.map +1 -0
  186. package/dist/domains/comet-entry/resolve-entry.js +22 -0
  187. package/dist/domains/comet-entry/resolve-entry.js.map +1 -0
  188. package/dist/domains/comet-entry/resume-probe.d.ts +34 -0
  189. package/dist/domains/comet-entry/resume-probe.d.ts.map +1 -0
  190. package/dist/domains/comet-entry/resume-probe.js +458 -0
  191. package/dist/domains/comet-entry/resume-probe.js.map +1 -0
  192. package/dist/domains/comet-entry/types.d.ts +59 -0
  193. package/dist/domains/comet-entry/types.d.ts.map +1 -0
  194. package/dist/domains/comet-entry/types.js +2 -0
  195. package/dist/domains/comet-entry/types.js.map +1 -0
  196. package/dist/domains/comet-entry/workflow-resolution.d.ts +8 -0
  197. package/dist/domains/comet-entry/workflow-resolution.d.ts.map +1 -0
  198. package/dist/domains/comet-entry/workflow-resolution.js +16 -0
  199. package/dist/domains/comet-entry/workflow-resolution.js.map +1 -0
  200. package/dist/domains/comet-native/index.d.ts +35 -0
  201. package/dist/domains/comet-native/index.d.ts.map +1 -0
  202. package/dist/domains/comet-native/index.js +35 -0
  203. package/dist/domains/comet-native/index.js.map +1 -0
  204. package/dist/domains/comet-native/native-acceptance.d.ts +42 -0
  205. package/dist/domains/comet-native/native-acceptance.d.ts.map +1 -0
  206. package/dist/domains/comet-native/native-acceptance.js +503 -0
  207. package/dist/domains/comet-native/native-acceptance.js.map +1 -0
  208. package/dist/domains/comet-native/native-archive-content.d.ts +26 -0
  209. package/dist/domains/comet-native/native-archive-content.d.ts.map +1 -0
  210. package/dist/domains/comet-native/native-archive-content.js +159 -0
  211. package/dist/domains/comet-native/native-archive-content.js.map +1 -0
  212. package/dist/domains/comet-native/native-archive-inspection.d.ts +9 -0
  213. package/dist/domains/comet-native/native-archive-inspection.d.ts.map +1 -0
  214. package/dist/domains/comet-native/native-archive-inspection.js +94 -0
  215. package/dist/domains/comet-native/native-archive-inspection.js.map +1 -0
  216. package/dist/domains/comet-native/native-archive-preflight.d.ts +52 -0
  217. package/dist/domains/comet-native/native-archive-preflight.d.ts.map +1 -0
  218. package/dist/domains/comet-native/native-archive-preflight.js +214 -0
  219. package/dist/domains/comet-native/native-archive-preflight.js.map +1 -0
  220. package/dist/domains/comet-native/native-archive-transaction.d.ts +19 -0
  221. package/dist/domains/comet-native/native-archive-transaction.d.ts.map +1 -0
  222. package/dist/domains/comet-native/native-archive-transaction.js +1181 -0
  223. package/dist/domains/comet-native/native-archive-transaction.js.map +1 -0
  224. package/dist/domains/comet-native/native-archive.d.ts +36 -0
  225. package/dist/domains/comet-native/native-archive.d.ts.map +1 -0
  226. package/dist/domains/comet-native/native-archive.js +403 -0
  227. package/dist/domains/comet-native/native-archive.js.map +1 -0
  228. package/dist/domains/comet-native/native-artifacts.d.ts +10 -0
  229. package/dist/domains/comet-native/native-artifacts.d.ts.map +1 -0
  230. package/dist/domains/comet-native/native-artifacts.js +204 -0
  231. package/dist/domains/comet-native/native-artifacts.js.map +1 -0
  232. package/dist/domains/comet-native/native-atomic-file.d.ts +10 -0
  233. package/dist/domains/comet-native/native-atomic-file.d.ts.map +1 -0
  234. package/dist/domains/comet-native/native-atomic-file.js +175 -0
  235. package/dist/domains/comet-native/native-atomic-file.js.map +1 -0
  236. package/dist/domains/comet-native/native-bounded-file.d.ts +19 -0
  237. package/dist/domains/comet-native/native-bounded-file.d.ts.map +1 -0
  238. package/dist/domains/comet-native/native-bounded-file.js +180 -0
  239. package/dist/domains/comet-native/native-bounded-file.js.map +1 -0
  240. package/dist/domains/comet-native/native-build-evidence.d.ts +42 -0
  241. package/dist/domains/comet-native/native-build-evidence.d.ts.map +1 -0
  242. package/dist/domains/comet-native/native-build-evidence.js +257 -0
  243. package/dist/domains/comet-native/native-build-evidence.js.map +1 -0
  244. package/dist/domains/comet-native/native-canonical-hash.d.ts +10 -0
  245. package/dist/domains/comet-native/native-canonical-hash.d.ts.map +1 -0
  246. package/dist/domains/comet-native/native-canonical-hash.js +100 -0
  247. package/dist/domains/comet-native/native-canonical-hash.js.map +1 -0
  248. package/dist/domains/comet-native/native-change-recovery.d.ts +11 -0
  249. package/dist/domains/comet-native/native-change-recovery.d.ts.map +1 -0
  250. package/dist/domains/comet-native/native-change-recovery.js +15 -0
  251. package/dist/domains/comet-native/native-change-recovery.js.map +1 -0
  252. package/dist/domains/comet-native/native-change.d.ts +61 -0
  253. package/dist/domains/comet-native/native-change.d.ts.map +1 -0
  254. package/dist/domains/comet-native/native-change.js +696 -0
  255. package/dist/domains/comet-native/native-change.js.map +1 -0
  256. package/dist/domains/comet-native/native-check-receipt-model.d.ts +63 -0
  257. package/dist/domains/comet-native/native-check-receipt-model.d.ts.map +1 -0
  258. package/dist/domains/comet-native/native-check-receipt-model.js +347 -0
  259. package/dist/domains/comet-native/native-check-receipt-model.js.map +1 -0
  260. package/dist/domains/comet-native/native-check-receipt-storage.d.ts +10 -0
  261. package/dist/domains/comet-native/native-check-receipt-storage.d.ts.map +1 -0
  262. package/dist/domains/comet-native/native-check-receipt-storage.js +196 -0
  263. package/dist/domains/comet-native/native-check-receipt-storage.js.map +1 -0
  264. package/dist/domains/comet-native/native-check-receipt.d.ts +19 -0
  265. package/dist/domains/comet-native/native-check-receipt.d.ts.map +1 -0
  266. package/dist/domains/comet-native/native-check-receipt.js +446 -0
  267. package/dist/domains/comet-native/native-check-receipt.js.map +1 -0
  268. package/dist/domains/comet-native/native-check.d.ts +18 -0
  269. package/dist/domains/comet-native/native-check.d.ts.map +1 -0
  270. package/dist/domains/comet-native/native-check.js +29 -0
  271. package/dist/domains/comet-native/native-check.js.map +1 -0
  272. package/dist/domains/comet-native/native-checkpoint-journal.d.ts +13 -0
  273. package/dist/domains/comet-native/native-checkpoint-journal.d.ts.map +1 -0
  274. package/dist/domains/comet-native/native-checkpoint-journal.js +53 -0
  275. package/dist/domains/comet-native/native-checkpoint-journal.js.map +1 -0
  276. package/dist/domains/comet-native/native-checkpoint-storage.d.ts +43 -0
  277. package/dist/domains/comet-native/native-checkpoint-storage.d.ts.map +1 -0
  278. package/dist/domains/comet-native/native-checkpoint-storage.js +487 -0
  279. package/dist/domains/comet-native/native-checkpoint-storage.js.map +1 -0
  280. package/dist/domains/comet-native/native-cli-entry.d.ts +2 -0
  281. package/dist/domains/comet-native/native-cli-entry.d.ts.map +1 -0
  282. package/dist/domains/comet-native/native-cli-entry.js +18 -0
  283. package/dist/domains/comet-native/native-cli-entry.js.map +1 -0
  284. package/dist/domains/comet-native/native-cli.d.ts +7 -0
  285. package/dist/domains/comet-native/native-cli.d.ts.map +1 -0
  286. package/dist/domains/comet-native/native-cli.js +642 -0
  287. package/dist/domains/comet-native/native-cli.js.map +1 -0
  288. package/dist/domains/comet-native/native-config.d.ts +15 -0
  289. package/dist/domains/comet-native/native-config.d.ts.map +1 -0
  290. package/dist/domains/comet-native/native-config.js +281 -0
  291. package/dist/domains/comet-native/native-config.js.map +1 -0
  292. package/dist/domains/comet-native/native-conflict-inspection.d.ts +17 -0
  293. package/dist/domains/comet-native/native-conflict-inspection.d.ts.map +1 -0
  294. package/dist/domains/comet-native/native-conflict-inspection.js +90 -0
  295. package/dist/domains/comet-native/native-conflict-inspection.js.map +1 -0
  296. package/dist/domains/comet-native/native-conflict-radar.d.ts +75 -0
  297. package/dist/domains/comet-native/native-conflict-radar.d.ts.map +1 -0
  298. package/dist/domains/comet-native/native-conflict-radar.js +326 -0
  299. package/dist/domains/comet-native/native-conflict-radar.js.map +1 -0
  300. package/dist/domains/comet-native/native-continuation.d.ts +9 -0
  301. package/dist/domains/comet-native/native-continuation.d.ts.map +1 -0
  302. package/dist/domains/comet-native/native-continuation.js +146 -0
  303. package/dist/domains/comet-native/native-continuation.js.map +1 -0
  304. package/dist/domains/comet-native/native-contract-files.d.ts +24 -0
  305. package/dist/domains/comet-native/native-contract-files.d.ts.map +1 -0
  306. package/dist/domains/comet-native/native-contract-files.js +66 -0
  307. package/dist/domains/comet-native/native-contract-files.js.map +1 -0
  308. package/dist/domains/comet-native/native-contract.d.ts +41 -0
  309. package/dist/domains/comet-native/native-contract.d.ts.map +1 -0
  310. package/dist/domains/comet-native/native-contract.js +141 -0
  311. package/dist/domains/comet-native/native-contract.js.map +1 -0
  312. package/dist/domains/comet-native/native-diagnostics.d.ts +18 -0
  313. package/dist/domains/comet-native/native-diagnostics.d.ts.map +1 -0
  314. package/dist/domains/comet-native/native-diagnostics.js +522 -0
  315. package/dist/domains/comet-native/native-diagnostics.js.map +1 -0
  316. package/dist/domains/comet-native/native-doctor.d.ts +12 -0
  317. package/dist/domains/comet-native/native-doctor.d.ts.map +1 -0
  318. package/dist/domains/comet-native/native-doctor.js +768 -0
  319. package/dist/domains/comet-native/native-doctor.js.map +1 -0
  320. package/dist/domains/comet-native/native-evidence-retention.d.ts +37 -0
  321. package/dist/domains/comet-native/native-evidence-retention.d.ts.map +1 -0
  322. package/dist/domains/comet-native/native-evidence-retention.js +885 -0
  323. package/dist/domains/comet-native/native-evidence-retention.js.map +1 -0
  324. package/dist/domains/comet-native/native-evidence-storage.d.ts +41 -0
  325. package/dist/domains/comet-native/native-evidence-storage.d.ts.map +1 -0
  326. package/dist/domains/comet-native/native-evidence-storage.js +351 -0
  327. package/dist/domains/comet-native/native-evidence-storage.js.map +1 -0
  328. package/dist/domains/comet-native/native-findings.d.ts +8 -0
  329. package/dist/domains/comet-native/native-findings.d.ts.map +1 -0
  330. package/dist/domains/comet-native/native-findings.js +238 -0
  331. package/dist/domains/comet-native/native-findings.js.map +1 -0
  332. package/dist/domains/comet-native/native-guards.d.ts +7 -0
  333. package/dist/domains/comet-native/native-guards.d.ts.map +1 -0
  334. package/dist/domains/comet-native/native-guards.js +126 -0
  335. package/dist/domains/comet-native/native-guards.js.map +1 -0
  336. package/dist/domains/comet-native/native-hash.d.ts +3 -0
  337. package/dist/domains/comet-native/native-hash.d.ts.map +1 -0
  338. package/dist/domains/comet-native/native-hash.js +12 -0
  339. package/dist/domains/comet-native/native-hash.js.map +1 -0
  340. package/dist/domains/comet-native/native-hook-guard.d.ts +17 -0
  341. package/dist/domains/comet-native/native-hook-guard.d.ts.map +1 -0
  342. package/dist/domains/comet-native/native-hook-guard.js +154 -0
  343. package/dist/domains/comet-native/native-hook-guard.js.map +1 -0
  344. package/dist/domains/comet-native/native-lock.d.ts +47 -0
  345. package/dist/domains/comet-native/native-lock.d.ts.map +1 -0
  346. package/dist/domains/comet-native/native-lock.js +395 -0
  347. package/dist/domains/comet-native/native-lock.js.map +1 -0
  348. package/dist/domains/comet-native/native-mutation-lock.d.ts +5 -0
  349. package/dist/domains/comet-native/native-mutation-lock.d.ts.map +1 -0
  350. package/dist/domains/comet-native/native-mutation-lock.js +66 -0
  351. package/dist/domains/comet-native/native-mutation-lock.js.map +1 -0
  352. package/dist/domains/comet-native/native-paths.d.ts +10 -0
  353. package/dist/domains/comet-native/native-paths.d.ts.map +1 -0
  354. package/dist/domains/comet-native/native-paths.js +171 -0
  355. package/dist/domains/comet-native/native-paths.js.map +1 -0
  356. package/dist/domains/comet-native/native-progress-checkpoint.d.ts +13 -0
  357. package/dist/domains/comet-native/native-progress-checkpoint.d.ts.map +1 -0
  358. package/dist/domains/comet-native/native-progress-checkpoint.js +104 -0
  359. package/dist/domains/comet-native/native-progress-checkpoint.js.map +1 -0
  360. package/dist/domains/comet-native/native-protected-file.d.ts +113 -0
  361. package/dist/domains/comet-native/native-protected-file.d.ts.map +1 -0
  362. package/dist/domains/comet-native/native-protected-file.js +509 -0
  363. package/dist/domains/comet-native/native-protected-file.js.map +1 -0
  364. package/dist/domains/comet-native/native-redaction.d.ts +2 -0
  365. package/dist/domains/comet-native/native-redaction.d.ts.map +1 -0
  366. package/dist/domains/comet-native/native-redaction.js +18 -0
  367. package/dist/domains/comet-native/native-redaction.js.map +1 -0
  368. package/dist/domains/comet-native/native-repair-integration.d.ts +42 -0
  369. package/dist/domains/comet-native/native-repair-integration.d.ts.map +1 -0
  370. package/dist/domains/comet-native/native-repair-integration.js +184 -0
  371. package/dist/domains/comet-native/native-repair-integration.js.map +1 -0
  372. package/dist/domains/comet-native/native-repair-runtime.d.ts +73 -0
  373. package/dist/domains/comet-native/native-repair-runtime.d.ts.map +1 -0
  374. package/dist/domains/comet-native/native-repair-runtime.js +509 -0
  375. package/dist/domains/comet-native/native-repair-runtime.js.map +1 -0
  376. package/dist/domains/comet-native/native-repair-stagnation.d.ts +85 -0
  377. package/dist/domains/comet-native/native-repair-stagnation.d.ts.map +1 -0
  378. package/dist/domains/comet-native/native-repair-stagnation.js +256 -0
  379. package/dist/domains/comet-native/native-repair-stagnation.js.map +1 -0
  380. package/dist/domains/comet-native/native-resume-view.d.ts +14 -0
  381. package/dist/domains/comet-native/native-resume-view.d.ts.map +1 -0
  382. package/dist/domains/comet-native/native-resume-view.js +105 -0
  383. package/dist/domains/comet-native/native-resume-view.js.map +1 -0
  384. package/dist/domains/comet-native/native-revision.d.ts +20 -0
  385. package/dist/domains/comet-native/native-revision.d.ts.map +1 -0
  386. package/dist/domains/comet-native/native-revision.js +32 -0
  387. package/dist/domains/comet-native/native-revision.js.map +1 -0
  388. package/dist/domains/comet-native/native-root-move.d.ts +20 -0
  389. package/dist/domains/comet-native/native-root-move.d.ts.map +1 -0
  390. package/dist/domains/comet-native/native-root-move.js +812 -0
  391. package/dist/domains/comet-native/native-root-move.js.map +1 -0
  392. package/dist/domains/comet-native/native-run-consistency.d.ts +3 -0
  393. package/dist/domains/comet-native/native-run-consistency.d.ts.map +1 -0
  394. package/dist/domains/comet-native/native-run-consistency.js +136 -0
  395. package/dist/domains/comet-native/native-run-consistency.js.map +1 -0
  396. package/dist/domains/comet-native/native-run-store.d.ts +41 -0
  397. package/dist/domains/comet-native/native-run-store.d.ts.map +1 -0
  398. package/dist/domains/comet-native/native-run-store.js +451 -0
  399. package/dist/domains/comet-native/native-run-store.js.map +1 -0
  400. package/dist/domains/comet-native/native-runtime-package.d.ts +16 -0
  401. package/dist/domains/comet-native/native-runtime-package.d.ts.map +1 -0
  402. package/dist/domains/comet-native/native-runtime-package.js +72 -0
  403. package/dist/domains/comet-native/native-runtime-package.js.map +1 -0
  404. package/dist/domains/comet-native/native-schema-migration.d.ts +11 -0
  405. package/dist/domains/comet-native/native-schema-migration.d.ts.map +1 -0
  406. package/dist/domains/comet-native/native-schema-migration.js +899 -0
  407. package/dist/domains/comet-native/native-schema-migration.js.map +1 -0
  408. package/dist/domains/comet-native/native-selection.d.ts +12 -0
  409. package/dist/domains/comet-native/native-selection.d.ts.map +1 -0
  410. package/dist/domains/comet-native/native-selection.js +52 -0
  411. package/dist/domains/comet-native/native-selection.js.map +1 -0
  412. package/dist/domains/comet-native/native-sensitive-paths.d.ts +7 -0
  413. package/dist/domains/comet-native/native-sensitive-paths.d.ts.map +1 -0
  414. package/dist/domains/comet-native/native-sensitive-paths.js +69 -0
  415. package/dist/domains/comet-native/native-sensitive-paths.js.map +1 -0
  416. package/dist/domains/comet-native/native-snapshot.d.ts +74 -0
  417. package/dist/domains/comet-native/native-snapshot.d.ts.map +1 -0
  418. package/dist/domains/comet-native/native-snapshot.js +2308 -0
  419. package/dist/domains/comet-native/native-snapshot.js.map +1 -0
  420. package/dist/domains/comet-native/native-specs.d.ts +12 -0
  421. package/dist/domains/comet-native/native-specs.d.ts.map +1 -0
  422. package/dist/domains/comet-native/native-specs.js +270 -0
  423. package/dist/domains/comet-native/native-specs.js.map +1 -0
  424. package/dist/domains/comet-native/native-trajectory-limits.d.ts +7 -0
  425. package/dist/domains/comet-native/native-trajectory-limits.d.ts.map +1 -0
  426. package/dist/domains/comet-native/native-trajectory-limits.js +13 -0
  427. package/dist/domains/comet-native/native-trajectory-limits.js.map +1 -0
  428. package/dist/domains/comet-native/native-trajectory-recovery.d.ts +37 -0
  429. package/dist/domains/comet-native/native-trajectory-recovery.d.ts.map +1 -0
  430. package/dist/domains/comet-native/native-trajectory-recovery.js +133 -0
  431. package/dist/domains/comet-native/native-trajectory-recovery.js.map +1 -0
  432. package/dist/domains/comet-native/native-trajectory.d.ts +16 -0
  433. package/dist/domains/comet-native/native-trajectory.d.ts.map +1 -0
  434. package/dist/domains/comet-native/native-trajectory.js +27 -0
  435. package/dist/domains/comet-native/native-trajectory.js.map +1 -0
  436. package/dist/domains/comet-native/native-transaction.d.ts +45 -0
  437. package/dist/domains/comet-native/native-transaction.d.ts.map +1 -0
  438. package/dist/domains/comet-native/native-transaction.js +846 -0
  439. package/dist/domains/comet-native/native-transaction.js.map +1 -0
  440. package/dist/domains/comet-native/native-transition-evidence.d.ts +4 -0
  441. package/dist/domains/comet-native/native-transition-evidence.d.ts.map +1 -0
  442. package/dist/domains/comet-native/native-transition-evidence.js +20 -0
  443. package/dist/domains/comet-native/native-transition-evidence.js.map +1 -0
  444. package/dist/domains/comet-native/native-transition-journal.d.ts +30 -0
  445. package/dist/domains/comet-native/native-transition-journal.d.ts.map +1 -0
  446. package/dist/domains/comet-native/native-transition-journal.js +819 -0
  447. package/dist/domains/comet-native/native-transition-journal.js.map +1 -0
  448. package/dist/domains/comet-native/native-transitions.d.ts +13 -0
  449. package/dist/domains/comet-native/native-transitions.d.ts.map +1 -0
  450. package/dist/domains/comet-native/native-transitions.js +632 -0
  451. package/dist/domains/comet-native/native-transitions.js.map +1 -0
  452. package/dist/domains/comet-native/native-types.d.ts +547 -0
  453. package/dist/domains/comet-native/native-types.d.ts.map +1 -0
  454. package/dist/domains/comet-native/native-types.js +8 -0
  455. package/dist/domains/comet-native/native-types.js.map +1 -0
  456. package/dist/domains/comet-native/native-verification-evidence.d.ts +86 -0
  457. package/dist/domains/comet-native/native-verification-evidence.d.ts.map +1 -0
  458. package/dist/domains/comet-native/native-verification-evidence.js +480 -0
  459. package/dist/domains/comet-native/native-verification-evidence.js.map +1 -0
  460. package/dist/domains/comet-native/native-verification-runtime.d.ts +58 -0
  461. package/dist/domains/comet-native/native-verification-runtime.d.ts.map +1 -0
  462. package/dist/domains/comet-native/native-verification-runtime.js +321 -0
  463. package/dist/domains/comet-native/native-verification-runtime.js.map +1 -0
  464. package/dist/domains/comet-native/native-verification-scope.d.ts +117 -0
  465. package/dist/domains/comet-native/native-verification-scope.d.ts.map +1 -0
  466. package/dist/domains/comet-native/native-verification-scope.js +1040 -0
  467. package/dist/domains/comet-native/native-verification-scope.js.map +1 -0
  468. package/dist/domains/comet-native/native-workspace.d.ts +46 -0
  469. package/dist/domains/comet-native/native-workspace.d.ts.map +1 -0
  470. package/dist/domains/comet-native/native-workspace.js +276 -0
  471. package/dist/domains/comet-native/native-workspace.js.map +1 -0
  472. package/dist/domains/dashboard/collector.d.ts.map +1 -1
  473. package/dist/domains/dashboard/collector.js +9 -1
  474. package/dist/domains/dashboard/collector.js.map +1 -1
  475. package/dist/domains/dashboard/native-adapter.d.ts +157 -0
  476. package/dist/domains/dashboard/native-adapter.d.ts.map +1 -0
  477. package/dist/domains/dashboard/native-adapter.js +302 -0
  478. package/dist/domains/dashboard/native-adapter.js.map +1 -0
  479. package/dist/domains/dashboard/native-collector.d.ts +6 -0
  480. package/dist/domains/dashboard/native-collector.d.ts.map +1 -0
  481. package/dist/domains/dashboard/native-collector.js +285 -0
  482. package/dist/domains/dashboard/native-collector.js.map +1 -0
  483. package/dist/domains/dashboard/types.d.ts +5 -0
  484. package/dist/domains/dashboard/types.d.ts.map +1 -1
  485. package/dist/domains/dashboard/web/assets/{arc-TGVUG2WN.js → arc-CxdiLJ50.js} +1 -1
  486. package/dist/domains/dashboard/web/assets/{architectureDiagram-3BPJPVTR-ASHmiHoP.js → architectureDiagram-3BPJPVTR-D5YCQu4e.js} +1 -1
  487. package/dist/domains/dashboard/web/assets/{blockDiagram-GPEHLZMM-CwASxBKe.js → blockDiagram-GPEHLZMM-8NfdCOQ8.js} +1 -1
  488. package/dist/domains/dashboard/web/assets/{c4Diagram-AAUBKEIU-BU8z_WNk.js → c4Diagram-AAUBKEIU-B3cFnNT7.js} +1 -1
  489. package/dist/domains/dashboard/web/assets/channel-B6AFly29.js +1 -0
  490. package/dist/domains/dashboard/web/assets/{chunk-2J33WTMH-CBGlUx4_.js → chunk-2J33WTMH-CBNfW-Dr.js} +1 -1
  491. package/dist/domains/dashboard/web/assets/{chunk-4BX2VUAB-CS-iGcFz.js → chunk-4BX2VUAB-vWyemRBr.js} +1 -1
  492. package/dist/domains/dashboard/web/assets/{chunk-55IACEB6-BUtCVJat.js → chunk-55IACEB6-H6haOo2C.js} +1 -1
  493. package/dist/domains/dashboard/web/assets/{chunk-727SXJPM-C94tj_pf.js → chunk-727SXJPM-D02UjGND.js} +1 -1
  494. package/dist/domains/dashboard/web/assets/{chunk-AQP2D5EJ-BFOKcpdG.js → chunk-AQP2D5EJ-wKsbOw_T.js} +1 -1
  495. package/dist/domains/dashboard/web/assets/{chunk-FMBD7UC4-Dmx8B-st.js → chunk-FMBD7UC4-eYFEZimP.js} +1 -1
  496. package/dist/domains/dashboard/web/assets/{chunk-ND2GUHAM-DYV00CNn.js → chunk-ND2GUHAM-fMaIDDI2.js} +1 -1
  497. package/dist/domains/dashboard/web/assets/{chunk-QZHKN3VN-DMJJyQnw.js → chunk-QZHKN3VN-C9rhF6Hm.js} +1 -1
  498. package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-BcnrxOTt.js +1 -0
  499. package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-BcnrxOTt.js +1 -0
  500. package/dist/domains/dashboard/web/assets/{cose-bilkent-S5V4N54A-P4nE2rea.js → cose-bilkent-S5V4N54A-CbaShPub.js} +1 -1
  501. package/dist/domains/dashboard/web/assets/{cynefin-VYW2F7L2-C-R1HXDv.js → cynefin-VYW2F7L2-DN4emAQv.js} +1 -1
  502. package/dist/domains/dashboard/web/assets/{dagre-BM42HDAG-BH8d-C9z.js → dagre-BM42HDAG-BpSzbk_V.js} +1 -1
  503. package/dist/domains/dashboard/web/assets/demo-BuVau32v.js +25 -0
  504. package/dist/domains/dashboard/web/assets/{diagram-2AECGRRQ-DpXTgQIH.js → diagram-2AECGRRQ-CfXwGGpQ.js} +1 -1
  505. package/dist/domains/dashboard/web/assets/{diagram-5GNKFQAL-DSiFJzSw.js → diagram-5GNKFQAL-DMp0Zmot.js} +1 -1
  506. package/dist/domains/dashboard/web/assets/{diagram-KO2AKTUF-DULMkben.js → diagram-KO2AKTUF-C7ZvofsM.js} +1 -1
  507. package/dist/domains/dashboard/web/assets/{diagram-LMA3HP47-Pi8m_NO9.js → diagram-LMA3HP47-BjmxFnap.js} +1 -1
  508. package/dist/domains/dashboard/web/assets/{diagram-OG6HWLK6-BSe6bCWm.js → diagram-OG6HWLK6-DFBG1Iqy.js} +1 -1
  509. package/dist/domains/dashboard/web/assets/{erDiagram-TEJ5UH35-zb-FEcbq.js → erDiagram-TEJ5UH35-MpNT7dzt.js} +1 -1
  510. package/dist/domains/dashboard/web/assets/{flowDiagram-I6XJVG4X-Dr-Gk0z2.js → flowDiagram-I6XJVG4X-_1wAR6c1.js} +1 -1
  511. package/dist/domains/dashboard/web/assets/{ganttDiagram-6RSMTGT7-qs6Zb2A6.js → ganttDiagram-6RSMTGT7-DJKjDeWl.js} +1 -1
  512. package/dist/domains/dashboard/web/assets/{gitGraphDiagram-PVQCEYII-BQ314orT.js → gitGraphDiagram-PVQCEYII-BL7yUEn-.js} +1 -1
  513. package/dist/domains/dashboard/web/assets/index-CjE9mHGb.js +24 -0
  514. package/dist/domains/dashboard/web/assets/index-D-AGxvI4.css +1 -0
  515. package/dist/domains/dashboard/web/assets/{infoDiagram-5YYISTIA-O0bQp98A.js → infoDiagram-5YYISTIA-Bt5fqrOd.js} +1 -1
  516. package/dist/domains/dashboard/web/assets/{ishikawaDiagram-YF4QCWOH-BPC7wbKh.js → ishikawaDiagram-YF4QCWOH-COCMcjBM.js} +1 -1
  517. package/dist/domains/dashboard/web/assets/{journeyDiagram-JHISSGLW-ohViOd4b.js → journeyDiagram-JHISSGLW-DGcpcWny.js} +1 -1
  518. package/dist/domains/dashboard/web/assets/{kanban-definition-UN3LZRKU-CHleNdbG.js → kanban-definition-UN3LZRKU-QSBNsWMP.js} +1 -1
  519. package/dist/domains/dashboard/web/assets/{linear-CyqiW--Q.js → linear-9uyeeBZf.js} +1 -1
  520. package/dist/domains/dashboard/web/assets/{mermaid.core-qS9XvtaK.js → mermaid.core-CkNdB471.js} +4 -4
  521. package/dist/domains/dashboard/web/assets/{mindmap-definition-RKZ34NQL-oaGkqO9l.js → mindmap-definition-RKZ34NQL-CiNxI0gP.js} +1 -1
  522. package/dist/domains/dashboard/web/assets/{pieDiagram-4H26LBE5-CPcB-AFh.js → pieDiagram-4H26LBE5-BLJ6QnRO.js} +1 -1
  523. package/dist/domains/dashboard/web/assets/{quadrantDiagram-W4KKPZXB-LFy52Qtj.js → quadrantDiagram-W4KKPZXB-CflW-eFH.js} +1 -1
  524. package/dist/domains/dashboard/web/assets/{requirementDiagram-4Y6WPE33-BdjeaYP_.js → requirementDiagram-4Y6WPE33-B9HLmRWH.js} +1 -1
  525. package/dist/domains/dashboard/web/assets/{sankeyDiagram-5OEKKPKP-DDJ4styL.js → sankeyDiagram-5OEKKPKP-6xnco5k5.js} +1 -1
  526. package/dist/domains/dashboard/web/assets/{sequenceDiagram-3UESZ5HK-BL5bFNoz.js → sequenceDiagram-3UESZ5HK-Dp1rujNZ.js} +1 -1
  527. package/dist/domains/dashboard/web/assets/{stateDiagram-AJRCARHV-BNUfikui.js → stateDiagram-AJRCARHV-C1Xc90ek.js} +1 -1
  528. package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-p-qmzXyE.js +1 -0
  529. package/dist/domains/dashboard/web/assets/{timeline-definition-PNZ67QCA--ps2uu6L.js → timeline-definition-PNZ67QCA-g9s-m5Z4.js} +1 -1
  530. package/dist/domains/dashboard/web/assets/{vennDiagram-CIIHVFJN-C2q8q26c.js → vennDiagram-CIIHVFJN-rkEyhyCc.js} +1 -1
  531. package/dist/domains/dashboard/web/assets/{wardleyDiagram-YWT4CUSO-BUH9gXqd.js → wardleyDiagram-YWT4CUSO-CJLrWGXc.js} +1 -1
  532. package/dist/domains/dashboard/web/assets/{xychartDiagram-2RQKCTM6-B-DielEy.js → xychartDiagram-2RQKCTM6-BxJvPNqo.js} +1 -1
  533. package/dist/domains/dashboard/web/index.html +2 -2
  534. package/dist/domains/engine/storage-layout.d.ts +14 -0
  535. package/dist/domains/engine/storage-layout.d.ts.map +1 -0
  536. package/dist/domains/engine/storage-layout.js +32 -0
  537. package/dist/domains/engine/storage-layout.js.map +1 -0
  538. package/dist/domains/engine/storage-run.d.ts +9 -0
  539. package/dist/domains/engine/storage-run.d.ts.map +1 -0
  540. package/dist/domains/engine/storage-run.js +116 -0
  541. package/dist/domains/engine/storage-run.js.map +1 -0
  542. package/dist/domains/factory/package.d.ts.map +1 -1
  543. package/dist/domains/factory/package.js +5 -3
  544. package/dist/domains/factory/package.js.map +1 -1
  545. package/dist/domains/integrations/openspec.d.ts.map +1 -1
  546. package/dist/domains/integrations/openspec.js +8 -6
  547. package/dist/domains/integrations/openspec.js.map +1 -1
  548. package/dist/domains/skill/find.d.ts.map +1 -1
  549. package/dist/domains/skill/find.js +7 -1
  550. package/dist/domains/skill/find.js.map +1 -1
  551. package/dist/domains/skill/platform-inspect.d.ts +6 -2
  552. package/dist/domains/skill/platform-inspect.d.ts.map +1 -1
  553. package/dist/domains/skill/platform-inspect.js +52 -8
  554. package/dist/domains/skill/platform-inspect.js.map +1 -1
  555. package/dist/domains/skill/platform-install.d.ts +18 -7
  556. package/dist/domains/skill/platform-install.d.ts.map +1 -1
  557. package/dist/domains/skill/platform-install.js +338 -71
  558. package/dist/domains/skill/platform-install.js.map +1 -1
  559. package/dist/domains/skill/project-instructions.d.ts.map +1 -1
  560. package/dist/domains/skill/project-instructions.js +12 -6
  561. package/dist/domains/skill/project-instructions.js.map +1 -1
  562. package/dist/domains/skill/uninstall.d.ts.map +1 -1
  563. package/dist/domains/skill/uninstall.js +15 -3
  564. package/dist/domains/skill/uninstall.js.map +1 -1
  565. package/dist/domains/workflow-contract/builtins.d.ts +6 -0
  566. package/dist/domains/workflow-contract/builtins.d.ts.map +1 -1
  567. package/dist/domains/workflow-contract/builtins.js +137 -0
  568. package/dist/domains/workflow-contract/builtins.js.map +1 -1
  569. package/dist/domains/workflow-contract/index.d.ts +3 -1
  570. package/dist/domains/workflow-contract/index.d.ts.map +1 -1
  571. package/dist/domains/workflow-contract/index.js +2 -1
  572. package/dist/domains/workflow-contract/index.js.map +1 -1
  573. package/dist/domains/workflow-contract/normalize.d.ts.map +1 -1
  574. package/dist/domains/workflow-contract/normalize.js +28 -10
  575. package/dist/domains/workflow-contract/normalize.js.map +1 -1
  576. package/dist/domains/workflow-contract/project-config.d.ts +7 -0
  577. package/dist/domains/workflow-contract/project-config.d.ts.map +1 -0
  578. package/dist/domains/workflow-contract/project-config.js +110 -0
  579. package/dist/domains/workflow-contract/project-config.js.map +1 -0
  580. package/dist/domains/workflow-contract/types.d.ts +4 -2
  581. package/dist/domains/workflow-contract/types.d.ts.map +1 -1
  582. package/dist/domains/workflow-contract/validation.d.ts.map +1 -1
  583. package/dist/domains/workflow-contract/validation.js +14 -5
  584. package/dist/domains/workflow-contract/validation.js.map +1 -1
  585. package/dist/platform/install/detect.d.ts +3 -1
  586. package/dist/platform/install/detect.d.ts.map +1 -1
  587. package/dist/platform/install/detect.js +4 -1
  588. package/dist/platform/install/detect.js.map +1 -1
  589. package/dist/platform/install/project-registry.js +2 -2
  590. package/dist/platform/install/project-registry.js.map +1 -1
  591. package/dist/platform/paths/repository-layout.d.ts +16 -0
  592. package/dist/platform/paths/repository-layout.d.ts.map +1 -1
  593. package/dist/platform/paths/repository-layout.js.map +1 -1
  594. package/eval/local/README.md +50 -0
  595. package/eval/local/scripts/compare_baselines.py +127 -1
  596. package/eval/local/scripts/regression_check.py +3 -4
  597. package/eval/local/tasks/comet-native-clarification/environment/Dockerfile +27 -0
  598. package/eval/local/tasks/comet-native-clarification/environment/test_wordcount.py +25 -0
  599. package/eval/local/tasks/comet-native-clarification/environment/wordcount.py +36 -0
  600. package/eval/local/tasks/comet-native-clarification/instruction.md +7 -0
  601. package/eval/local/tasks/comet-native-clarification/task.toml +40 -0
  602. package/eval/local/tasks/comet-native-clarification/validation/test_native_clarification.py +193 -0
  603. package/eval/local/tasks/comet-native-clarification-modes/environment/Dockerfile +27 -0
  604. package/eval/local/tasks/comet-native-clarification-modes/environment/test_wordcount.py +25 -0
  605. package/eval/local/tasks/comet-native-clarification-modes/environment/wordcount.py +36 -0
  606. package/eval/local/tasks/comet-native-clarification-modes/instruction.md +13 -0
  607. package/eval/local/tasks/comet-native-clarification-modes/task.toml +39 -0
  608. package/eval/local/tasks/comet-native-clarification-modes/validation/test_native_clarification_modes.py +235 -0
  609. package/eval/local/tasks/comet-native-interrupted-transition/environment/.comet/config.yaml +6 -0
  610. package/eval/local/tasks/comet-native-interrupted-transition/environment/Dockerfile +28 -0
  611. package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/brief.md +17 -0
  612. package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/comet-state.yaml +12 -0
  613. package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/runtime/transition.json +69 -0
  614. package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/specs/character-counting/spec.md +3 -0
  615. package/eval/local/tasks/comet-native-interrupted-transition/environment/test_wordcount.py +20 -0
  616. package/eval/local/tasks/comet-native-interrupted-transition/environment/wordcount.py +27 -0
  617. package/eval/local/tasks/comet-native-interrupted-transition/instruction.md +7 -0
  618. package/eval/local/tasks/comet-native-interrupted-transition/task.toml +35 -0
  619. package/eval/local/tasks/comet-native-interrupted-transition/validation/test_native_interrupted_transition.py +63 -0
  620. package/eval/local/tasks/comet-native-repository-fact/environment/Dockerfile +26 -0
  621. package/eval/local/tasks/comet-native-repository-fact/environment/PRODUCT_RULES.md +3 -0
  622. package/eval/local/tasks/comet-native-repository-fact/environment/test_wordcount.py +20 -0
  623. package/eval/local/tasks/comet-native-repository-fact/environment/wordcount.py +27 -0
  624. package/eval/local/tasks/comet-native-repository-fact/instruction.md +7 -0
  625. package/eval/local/tasks/comet-native-repository-fact/task.toml +35 -0
  626. package/eval/local/tasks/comet-native-repository-fact/validation/test_native_repository_fact.py +53 -0
  627. package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/Dockerfile +27 -0
  628. package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/test_wordcount.py +27 -0
  629. package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/wordcount.py +36 -0
  630. package/eval/local/tasks/comet-native-wave-b-decision-resume/instruction.md +9 -0
  631. package/eval/local/tasks/comet-native-wave-b-decision-resume/task.toml +40 -0
  632. package/eval/local/tasks/comet-native-wave-b-decision-resume/validation/test_native_wave_b_decision_resume.py +208 -0
  633. package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/Dockerfile +27 -0
  634. package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/test_wordcount.py +27 -0
  635. package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/wordcount.py +36 -0
  636. package/eval/local/tasks/comet-native-wave-c-verification-integrity/instruction.md +11 -0
  637. package/eval/local/tasks/comet-native-wave-c-verification-integrity/task.toml +36 -0
  638. package/eval/local/tasks/comet-native-wave-c-verification-integrity/validation/test_native_wave_c_verification_integrity.py +344 -0
  639. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/Dockerfile +27 -0
  640. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/test_wordcount.py +27 -0
  641. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/wordcount.py +36 -0
  642. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/instruction.md +11 -0
  643. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/task.toml +37 -0
  644. package/eval/local/tasks/comet-native-wave-d-stagnation-stop/validation/test_native_wave_d_stagnation_stop.py +284 -0
  645. package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/.include-trusted-native-runtime +1 -0
  646. package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/Dockerfile +27 -0
  647. package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/test_wordcount.py +27 -0
  648. package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/wordcount.py +36 -0
  649. package/eval/local/tasks/comet-native-wave-e-parallel-safety/instruction.md +9 -0
  650. package/eval/local/tasks/comet-native-wave-e-parallel-safety/task.toml +37 -0
  651. package/eval/local/tasks/comet-native-wave-e-parallel-safety/validation/test_native_wave_e_parallel_safety.py +309 -0
  652. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/.include-current-comet-cli +1 -0
  653. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/Dockerfile +31 -0
  654. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet-package.json +18 -0
  655. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet.sh +14 -0
  656. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/test_wordcount.py +27 -0
  657. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/wordcount.py +36 -0
  658. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/instruction.md +7 -0
  659. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/task.toml +36 -0
  660. package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/validation/test_native_wave_f_dashboard_readonly.py +469 -0
  661. package/eval/local/tasks/comet-native-workflow/environment/Dockerfile +27 -0
  662. package/eval/local/tasks/comet-native-workflow/environment/test_wordcount.py +25 -0
  663. package/eval/local/tasks/comet-native-workflow/environment/wordcount.py +36 -0
  664. package/eval/local/tasks/comet-native-workflow/instruction.md +14 -0
  665. package/eval/local/tasks/comet-native-workflow/task.toml +36 -0
  666. package/eval/local/tasks/comet-native-workflow/validation/test_native_workflow.py +149 -0
  667. package/eval/local/tasks/index.yaml +61 -0
  668. package/eval/local/tests/conftest.py +407 -22
  669. package/eval/local/tests/scaffold/test_aligned_comparison.py +1012 -0
  670. package/eval/local/tests/scaffold/test_conftest_helpers.py +187 -7
  671. package/eval/local/tests/scaffold/test_logging.py +135 -1
  672. package/eval/local/tests/scaffold/test_manifests.py +2 -0
  673. package/eval/local/tests/scaffold/test_native_aligned_eval.py +346 -0
  674. package/eval/local/tests/scaffold/test_native_wave_evaluations.py +1889 -0
  675. package/eval/local/tests/scaffold/test_profiles.py +33 -0
  676. package/eval/local/tests/scaffold/test_sample_quality.py +57 -0
  677. package/eval/local/tests/scaffold/test_tasks.py +377 -1
  678. package/eval/local/tests/scaffold/test_treatments.py +59 -13
  679. package/eval/local/tests/scaffold/test_utils.py +277 -4
  680. package/eval/local/tests/tasks/__init__.py +1 -0
  681. package/eval/local/tests/tasks/test_tasks.py +104 -78
  682. package/eval/local/tests/tasks/test_validation_scripts.py +37 -0
  683. package/eval/local/treatments/comet/comet_native_phase1.yaml +66 -0
  684. package/eval/scaffold/python/aligned_comparison.py +1631 -0
  685. package/eval/scaffold/python/generic_llm_judge.py +3 -1
  686. package/eval/scaffold/python/llm_judge.py +0 -3
  687. package/eval/scaffold/python/logging.py +115 -16
  688. package/eval/scaffold/python/manifests.py +2 -0
  689. package/eval/scaffold/python/native_eval.py +138 -0
  690. package/eval/scaffold/python/pass_at_k.py +0 -1
  691. package/eval/scaffold/python/report_outputs.py +226 -44
  692. package/eval/scaffold/python/sample_quality.py +45 -2
  693. package/eval/scaffold/python/tasks.py +11 -0
  694. package/eval/scaffold/python/utils.py +108 -20
  695. package/eval/scaffold/python/validation/__init__.py +15 -5
  696. package/eval/scaffold/python/validation/comet_workflow.py +10 -5
  697. package/eval/scaffold/python/validation/generic_rubric.py +1 -2
  698. package/eval/scaffold/python/validation/native_wave.py +2154 -0
  699. package/eval/scaffold/python/validation/native_workflow.py +252 -0
  700. package/eval/scaffold/python/validation/rubric.py +0 -2
  701. package/eval/scaffold/shell/completion-point.sh +18 -0
  702. package/eval/scaffold/shell/decision-point.sh +35 -0
  703. package/eval/scaffold/shell/docker.sh +150 -9
  704. package/eval/scaffold/shell/run-claude-loop.sh +57 -27
  705. package/package.json +19 -5
  706. package/dist/domains/dashboard/web/assets/channel-kp6Ng2JJ.js +0 -1
  707. package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-yBDjgMY_.js +0 -1
  708. package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-yBDjgMY_.js +0 -1
  709. package/dist/domains/dashboard/web/assets/demo-DQyfozbi.js +0 -1
  710. package/dist/domains/dashboard/web/assets/index-BLAfkNTu.css +0 -1
  711. package/dist/domains/dashboard/web/assets/index-DtLUOcAW.js +0 -24
  712. package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-DGrsmWts.js +0 -1
  713. package/eval/.env.example +0 -52
  714. package/eval/langsmith/.env.example +0 -16
@@ -126,17 +126,17 @@ var require_visit = __commonJS({
126
126
  visit.BREAK = BREAK;
127
127
  visit.SKIP = SKIP;
128
128
  visit.REMOVE = REMOVE;
129
- function visit_(key, node, visitor, path22) {
130
- const ctrl = callVisitor(key, node, visitor, path22);
129
+ function visit_(key, node, visitor, path24) {
130
+ const ctrl = callVisitor(key, node, visitor, path24);
131
131
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
132
- replaceNode(key, path22, ctrl);
133
- return visit_(key, ctrl, visitor, path22);
132
+ replaceNode(key, path24, ctrl);
133
+ return visit_(key, ctrl, visitor, path24);
134
134
  }
135
135
  if (typeof ctrl !== "symbol") {
136
136
  if (identity.isCollection(node)) {
137
- path22 = Object.freeze(path22.concat(node));
137
+ path24 = Object.freeze(path24.concat(node));
138
138
  for (let i = 0; i < node.items.length; ++i) {
139
- const ci = visit_(i, node.items[i], visitor, path22);
139
+ const ci = visit_(i, node.items[i], visitor, path24);
140
140
  if (typeof ci === "number")
141
141
  i = ci - 1;
142
142
  else if (ci === BREAK)
@@ -147,13 +147,13 @@ var require_visit = __commonJS({
147
147
  }
148
148
  }
149
149
  } else if (identity.isPair(node)) {
150
- path22 = Object.freeze(path22.concat(node));
151
- const ck = visit_("key", node.key, visitor, path22);
150
+ path24 = Object.freeze(path24.concat(node));
151
+ const ck = visit_("key", node.key, visitor, path24);
152
152
  if (ck === BREAK)
153
153
  return BREAK;
154
154
  else if (ck === REMOVE)
155
155
  node.key = null;
156
- const cv = visit_("value", node.value, visitor, path22);
156
+ const cv = visit_("value", node.value, visitor, path24);
157
157
  if (cv === BREAK)
158
158
  return BREAK;
159
159
  else if (cv === REMOVE)
@@ -174,17 +174,17 @@ var require_visit = __commonJS({
174
174
  visitAsync.BREAK = BREAK;
175
175
  visitAsync.SKIP = SKIP;
176
176
  visitAsync.REMOVE = REMOVE;
177
- async function visitAsync_(key, node, visitor, path22) {
178
- const ctrl = await callVisitor(key, node, visitor, path22);
177
+ async function visitAsync_(key, node, visitor, path24) {
178
+ const ctrl = await callVisitor(key, node, visitor, path24);
179
179
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
180
- replaceNode(key, path22, ctrl);
181
- return visitAsync_(key, ctrl, visitor, path22);
180
+ replaceNode(key, path24, ctrl);
181
+ return visitAsync_(key, ctrl, visitor, path24);
182
182
  }
183
183
  if (typeof ctrl !== "symbol") {
184
184
  if (identity.isCollection(node)) {
185
- path22 = Object.freeze(path22.concat(node));
185
+ path24 = Object.freeze(path24.concat(node));
186
186
  for (let i = 0; i < node.items.length; ++i) {
187
- const ci = await visitAsync_(i, node.items[i], visitor, path22);
187
+ const ci = await visitAsync_(i, node.items[i], visitor, path24);
188
188
  if (typeof ci === "number")
189
189
  i = ci - 1;
190
190
  else if (ci === BREAK)
@@ -195,13 +195,13 @@ var require_visit = __commonJS({
195
195
  }
196
196
  }
197
197
  } else if (identity.isPair(node)) {
198
- path22 = Object.freeze(path22.concat(node));
199
- const ck = await visitAsync_("key", node.key, visitor, path22);
198
+ path24 = Object.freeze(path24.concat(node));
199
+ const ck = await visitAsync_("key", node.key, visitor, path24);
200
200
  if (ck === BREAK)
201
201
  return BREAK;
202
202
  else if (ck === REMOVE)
203
203
  node.key = null;
204
- const cv = await visitAsync_("value", node.value, visitor, path22);
204
+ const cv = await visitAsync_("value", node.value, visitor, path24);
205
205
  if (cv === BREAK)
206
206
  return BREAK;
207
207
  else if (cv === REMOVE)
@@ -228,23 +228,23 @@ var require_visit = __commonJS({
228
228
  }
229
229
  return visitor;
230
230
  }
231
- function callVisitor(key, node, visitor, path22) {
231
+ function callVisitor(key, node, visitor, path24) {
232
232
  if (typeof visitor === "function")
233
- return visitor(key, node, path22);
233
+ return visitor(key, node, path24);
234
234
  if (identity.isMap(node))
235
- return visitor.Map?.(key, node, path22);
235
+ return visitor.Map?.(key, node, path24);
236
236
  if (identity.isSeq(node))
237
- return visitor.Seq?.(key, node, path22);
237
+ return visitor.Seq?.(key, node, path24);
238
238
  if (identity.isPair(node))
239
- return visitor.Pair?.(key, node, path22);
239
+ return visitor.Pair?.(key, node, path24);
240
240
  if (identity.isScalar(node))
241
- return visitor.Scalar?.(key, node, path22);
241
+ return visitor.Scalar?.(key, node, path24);
242
242
  if (identity.isAlias(node))
243
- return visitor.Alias?.(key, node, path22);
243
+ return visitor.Alias?.(key, node, path24);
244
244
  return void 0;
245
245
  }
246
- function replaceNode(key, path22, node) {
247
- const parent = path22[path22.length - 1];
246
+ function replaceNode(key, path24, node) {
247
+ const parent = path24[path24.length - 1];
248
248
  if (identity.isCollection(parent)) {
249
249
  parent.items[key] = node;
250
250
  } else if (identity.isPair(parent)) {
@@ -854,10 +854,10 @@ var require_Collection = __commonJS({
854
854
  var createNode = require_createNode();
855
855
  var identity = require_identity();
856
856
  var Node = require_Node();
857
- function collectionFromPath(schema, path22, value) {
857
+ function collectionFromPath(schema, path24, value) {
858
858
  let v = value;
859
- for (let i = path22.length - 1; i >= 0; --i) {
860
- const k = path22[i];
859
+ for (let i = path24.length - 1; i >= 0; --i) {
860
+ const k = path24[i];
861
861
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
862
862
  const a = [];
863
863
  a[k] = v;
@@ -876,7 +876,7 @@ var require_Collection = __commonJS({
876
876
  sourceObjects: /* @__PURE__ */ new Map()
877
877
  });
878
878
  }
879
- var isEmptyPath = (path22) => path22 == null || typeof path22 === "object" && !!path22[Symbol.iterator]().next().done;
879
+ var isEmptyPath = (path24) => path24 == null || typeof path24 === "object" && !!path24[Symbol.iterator]().next().done;
880
880
  var Collection = class extends Node.NodeBase {
881
881
  constructor(type, schema) {
882
882
  super(type);
@@ -906,11 +906,11 @@ var require_Collection = __commonJS({
906
906
  * be a Pair instance or a `{ key, value }` object, which may not have a key
907
907
  * that already exists in the map.
908
908
  */
909
- addIn(path22, value) {
910
- if (isEmptyPath(path22))
909
+ addIn(path24, value) {
910
+ if (isEmptyPath(path24))
911
911
  this.add(value);
912
912
  else {
913
- const [key, ...rest] = path22;
913
+ const [key, ...rest] = path24;
914
914
  const node = this.get(key, true);
915
915
  if (identity.isCollection(node))
916
916
  node.addIn(rest, value);
@@ -924,8 +924,8 @@ var require_Collection = __commonJS({
924
924
  * Removes a value from the collection.
925
925
  * @returns `true` if the item was found and removed.
926
926
  */
927
- deleteIn(path22) {
928
- const [key, ...rest] = path22;
927
+ deleteIn(path24) {
928
+ const [key, ...rest] = path24;
929
929
  if (rest.length === 0)
930
930
  return this.delete(key);
931
931
  const node = this.get(key, true);
@@ -939,8 +939,8 @@ var require_Collection = __commonJS({
939
939
  * scalar values from their surrounding node; to disable set `keepScalar` to
940
940
  * `true` (collections are always returned intact).
941
941
  */
942
- getIn(path22, keepScalar) {
943
- const [key, ...rest] = path22;
942
+ getIn(path24, keepScalar) {
943
+ const [key, ...rest] = path24;
944
944
  const node = this.get(key, true);
945
945
  if (rest.length === 0)
946
946
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -958,8 +958,8 @@ var require_Collection = __commonJS({
958
958
  /**
959
959
  * Checks if the collection includes a value with the key `key`.
960
960
  */
961
- hasIn(path22) {
962
- const [key, ...rest] = path22;
961
+ hasIn(path24) {
962
+ const [key, ...rest] = path24;
963
963
  if (rest.length === 0)
964
964
  return this.has(key);
965
965
  const node = this.get(key, true);
@@ -969,8 +969,8 @@ var require_Collection = __commonJS({
969
969
  * Sets a value in this collection. For `!!set`, `value` needs to be a
970
970
  * boolean to add/remove the item from the set.
971
971
  */
972
- setIn(path22, value) {
973
- const [key, ...rest] = path22;
972
+ setIn(path24, value) {
973
+ const [key, ...rest] = path24;
974
974
  if (rest.length === 0) {
975
975
  this.set(key, value);
976
976
  } else {
@@ -3485,9 +3485,9 @@ var require_Document = __commonJS({
3485
3485
  this.contents.add(value);
3486
3486
  }
3487
3487
  /** Adds a value to the document. */
3488
- addIn(path22, value) {
3488
+ addIn(path24, value) {
3489
3489
  if (assertCollection(this.contents))
3490
- this.contents.addIn(path22, value);
3490
+ this.contents.addIn(path24, value);
3491
3491
  }
3492
3492
  /**
3493
3493
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3562,14 +3562,14 @@ var require_Document = __commonJS({
3562
3562
  * Removes a value from the document.
3563
3563
  * @returns `true` if the item was found and removed.
3564
3564
  */
3565
- deleteIn(path22) {
3566
- if (Collection.isEmptyPath(path22)) {
3565
+ deleteIn(path24) {
3566
+ if (Collection.isEmptyPath(path24)) {
3567
3567
  if (this.contents == null)
3568
3568
  return false;
3569
3569
  this.contents = null;
3570
3570
  return true;
3571
3571
  }
3572
- return assertCollection(this.contents) ? this.contents.deleteIn(path22) : false;
3572
+ return assertCollection(this.contents) ? this.contents.deleteIn(path24) : false;
3573
3573
  }
3574
3574
  /**
3575
3575
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
3584
3584
  * scalar values from their surrounding node; to disable set `keepScalar` to
3585
3585
  * `true` (collections are always returned intact).
3586
3586
  */
3587
- getIn(path22, keepScalar) {
3588
- if (Collection.isEmptyPath(path22))
3587
+ getIn(path24, keepScalar) {
3588
+ if (Collection.isEmptyPath(path24))
3589
3589
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3590
- return identity.isCollection(this.contents) ? this.contents.getIn(path22, keepScalar) : void 0;
3590
+ return identity.isCollection(this.contents) ? this.contents.getIn(path24, keepScalar) : void 0;
3591
3591
  }
3592
3592
  /**
3593
3593
  * Checks if the document includes a value with the key `key`.
@@ -3598,10 +3598,10 @@ var require_Document = __commonJS({
3598
3598
  /**
3599
3599
  * Checks if the document includes a value at `path`.
3600
3600
  */
3601
- hasIn(path22) {
3602
- if (Collection.isEmptyPath(path22))
3601
+ hasIn(path24) {
3602
+ if (Collection.isEmptyPath(path24))
3603
3603
  return this.contents !== void 0;
3604
- return identity.isCollection(this.contents) ? this.contents.hasIn(path22) : false;
3604
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path24) : false;
3605
3605
  }
3606
3606
  /**
3607
3607
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3618,13 +3618,13 @@ var require_Document = __commonJS({
3618
3618
  * Sets a value in this document. For `!!set`, `value` needs to be a
3619
3619
  * boolean to add/remove the item from the set.
3620
3620
  */
3621
- setIn(path22, value) {
3622
- if (Collection.isEmptyPath(path22)) {
3621
+ setIn(path24, value) {
3622
+ if (Collection.isEmptyPath(path24)) {
3623
3623
  this.contents = value;
3624
3624
  } else if (this.contents == null) {
3625
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path22), value);
3625
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path24), value);
3626
3626
  } else if (assertCollection(this.contents)) {
3627
- this.contents.setIn(path22, value);
3627
+ this.contents.setIn(path24, value);
3628
3628
  }
3629
3629
  }
3630
3630
  /**
@@ -5584,9 +5584,9 @@ var require_cst_visit = __commonJS({
5584
5584
  visit.BREAK = BREAK;
5585
5585
  visit.SKIP = SKIP;
5586
5586
  visit.REMOVE = REMOVE;
5587
- visit.itemAtPath = (cst, path22) => {
5587
+ visit.itemAtPath = (cst, path24) => {
5588
5588
  let item = cst;
5589
- for (const [field2, index] of path22) {
5589
+ for (const [field2, index] of path24) {
5590
5590
  const tok = item?.[field2];
5591
5591
  if (tok && "items" in tok) {
5592
5592
  item = tok.items[index];
@@ -5595,23 +5595,23 @@ var require_cst_visit = __commonJS({
5595
5595
  }
5596
5596
  return item;
5597
5597
  };
5598
- visit.parentCollection = (cst, path22) => {
5599
- const parent = visit.itemAtPath(cst, path22.slice(0, -1));
5600
- const field2 = path22[path22.length - 1][0];
5598
+ visit.parentCollection = (cst, path24) => {
5599
+ const parent = visit.itemAtPath(cst, path24.slice(0, -1));
5600
+ const field2 = path24[path24.length - 1][0];
5601
5601
  const coll = parent?.[field2];
5602
5602
  if (coll && "items" in coll)
5603
5603
  return coll;
5604
5604
  throw new Error("Parent collection not found");
5605
5605
  };
5606
- function _visit(path22, item, visitor) {
5607
- let ctrl = visitor(item, path22);
5606
+ function _visit(path24, item, visitor) {
5607
+ let ctrl = visitor(item, path24);
5608
5608
  if (typeof ctrl === "symbol")
5609
5609
  return ctrl;
5610
5610
  for (const field2 of ["key", "value"]) {
5611
5611
  const token = item[field2];
5612
5612
  if (token && "items" in token) {
5613
5613
  for (let i = 0; i < token.items.length; ++i) {
5614
- const ci = _visit(Object.freeze(path22.concat([[field2, i]])), token.items[i], visitor);
5614
+ const ci = _visit(Object.freeze(path24.concat([[field2, i]])), token.items[i], visitor);
5615
5615
  if (typeof ci === "number")
5616
5616
  i = ci - 1;
5617
5617
  else if (ci === BREAK)
@@ -5622,10 +5622,10 @@ var require_cst_visit = __commonJS({
5622
5622
  }
5623
5623
  }
5624
5624
  if (typeof ctrl === "function" && field2 === "key")
5625
- ctrl = ctrl(item, path22);
5625
+ ctrl = ctrl(item, path24);
5626
5626
  }
5627
5627
  }
5628
- return typeof ctrl === "function" ? ctrl(item, path22) : ctrl;
5628
+ return typeof ctrl === "function" ? ctrl(item, path24) : ctrl;
5629
5629
  }
5630
5630
  exports.visit = visit;
5631
5631
  }
@@ -6927,14 +6927,14 @@ var require_parser = __commonJS({
6927
6927
  case "scalar":
6928
6928
  case "single-quoted-scalar":
6929
6929
  case "double-quoted-scalar": {
6930
- const fs21 = this.flowScalar(this.type);
6930
+ const fs23 = this.flowScalar(this.type);
6931
6931
  if (atNextItem || it.value) {
6932
- map.items.push({ start, key: fs21, sep: [] });
6932
+ map.items.push({ start, key: fs23, sep: [] });
6933
6933
  this.onKeyLine = true;
6934
6934
  } else if (it.sep) {
6935
- this.stack.push(fs21);
6935
+ this.stack.push(fs23);
6936
6936
  } else {
6937
- Object.assign(it, { key: fs21, sep: [] });
6937
+ Object.assign(it, { key: fs23, sep: [] });
6938
6938
  this.onKeyLine = true;
6939
6939
  }
6940
6940
  return;
@@ -7062,13 +7062,13 @@ var require_parser = __commonJS({
7062
7062
  case "scalar":
7063
7063
  case "single-quoted-scalar":
7064
7064
  case "double-quoted-scalar": {
7065
- const fs21 = this.flowScalar(this.type);
7065
+ const fs23 = this.flowScalar(this.type);
7066
7066
  if (!it || it.value)
7067
- fc.items.push({ start: [], key: fs21, sep: [] });
7067
+ fc.items.push({ start: [], key: fs23, sep: [] });
7068
7068
  else if (it.sep)
7069
- this.stack.push(fs21);
7069
+ this.stack.push(fs23);
7070
7070
  else
7071
- Object.assign(it, { key: fs21, sep: [] });
7071
+ Object.assign(it, { key: fs23, sep: [] });
7072
7072
  return;
7073
7073
  }
7074
7074
  case "flow-map-end":
@@ -7257,7 +7257,7 @@ var require_public_api = __commonJS({
7257
7257
  return docs;
7258
7258
  return Object.assign([], { empty: true }, composer$1.streamInfo());
7259
7259
  }
7260
- function parseDocument7(source, options = {}) {
7260
+ function parseDocument8(source, options = {}) {
7261
7261
  const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options);
7262
7262
  const parser$1 = new parser.Parser(lineCounter2?.addNewLine);
7263
7263
  const composer$1 = new composer.Composer(options);
@@ -7283,7 +7283,7 @@ var require_public_api = __commonJS({
7283
7283
  } else if (options === void 0 && reviver && typeof reviver === "object") {
7284
7284
  options = reviver;
7285
7285
  }
7286
- const doc = parseDocument7(src, options);
7286
+ const doc = parseDocument8(src, options);
7287
7287
  if (!doc)
7288
7288
  return null;
7289
7289
  doc.warnings.forEach((warning) => log.warn(doc.options.logLevel, warning));
@@ -7319,7 +7319,7 @@ var require_public_api = __commonJS({
7319
7319
  }
7320
7320
  exports.parse = parse2;
7321
7321
  exports.parseAllDocuments = parseAllDocuments;
7322
- exports.parseDocument = parseDocument7;
7322
+ exports.parseDocument = parseDocument8;
7323
7323
  exports.stringify = stringify;
7324
7324
  }
7325
7325
  });
@@ -7546,8 +7546,8 @@ import { pathToFileURL } from "url";
7546
7546
  // domains/comet-classic/classic-archive.ts
7547
7547
  import { createHash as createHash3 } from "crypto";
7548
7548
  import { spawnSync } from "child_process";
7549
- import { promises as fs11 } from "fs";
7550
- import path12 from "path";
7549
+ import { promises as fs14 } from "fs";
7550
+ import path15 from "path";
7551
7551
 
7552
7552
  // domains/comet-classic/classic-paths.ts
7553
7553
  import { promises as fs } from "fs";
@@ -7824,6 +7824,7 @@ var CLASSIC_WIRE_KEYS = [
7824
7824
  "tdd_mode",
7825
7825
  "review_mode",
7826
7826
  "isolation",
7827
+ "bound_branch",
7827
7828
  "verify_mode",
7828
7829
  "auto_transition",
7829
7830
  "base_ref",
@@ -7942,6 +7943,7 @@ function classicStateFromDocument(doc) {
7942
7943
  tddMode: enumValue(doc, "tdd_mode", TDD_MODES),
7943
7944
  reviewMode: enumValue(doc, "review_mode", REVIEW_MODES),
7944
7945
  isolation: enumValue(doc, "isolation", ISOLATIONS),
7946
+ boundBranch: nullableString(doc, "bound_branch"),
7945
7947
  verifyMode: enumValue(doc, "verify_mode", VERIFY_MODES),
7946
7948
  autoTransition: booleanValue(doc, "auto_transition"),
7947
7949
  baseRef: nullableString(doc, "base_ref"),
@@ -8007,6 +8009,7 @@ function classicStateToDocument(state) {
8007
8009
  tdd_mode: state.tddMode,
8008
8010
  review_mode: state.reviewMode,
8009
8011
  isolation: state.isolation,
8012
+ bound_branch: state.boundBranch,
8010
8013
  verify_mode: state.verifyMode,
8011
8014
  auto_transition: state.autoTransition,
8012
8015
  base_ref: state.baseRef,
@@ -9013,6 +9016,11 @@ async function fileExists2(file) {
9013
9016
  throw error;
9014
9017
  }
9015
9018
  }
9019
+ async function isClassicRuntimePackageRoot(root) {
9020
+ if (!await directoryExists(root)) return false;
9021
+ if (await fileExists2(path10.join(root, "skill.yaml"))) return true;
9022
+ return await fileExists2(path10.join(root, "SKILL.md")) && await fileExists2(path10.join(root, "comet", "skill.yaml"));
9023
+ }
9016
9024
  function embeddedClassicRuntimePackage(root) {
9017
9025
  return {
9018
9026
  root,
@@ -9251,7 +9259,7 @@ async function classicRuntimeRoot() {
9251
9259
  path10.resolve("assets", "skills", "comet-classic")
9252
9260
  ].filter((candidate) => Boolean(candidate));
9253
9261
  for (const candidate of candidates) {
9254
- if (await directoryExists(candidate)) return candidate;
9262
+ if (await isClassicRuntimePackageRoot(candidate)) return candidate;
9255
9263
  }
9256
9264
  return null;
9257
9265
  }
@@ -9493,6 +9501,7 @@ function applyClassicTransition(current, event, options = {}) {
9493
9501
  setField(classic, effects, "tddMode", null);
9494
9502
  setField(classic, effects, "reviewMode", null);
9495
9503
  setField(classic, effects, "isolation", null);
9504
+ setField(classic, effects, "boundBranch", null);
9496
9505
  setField(classic, effects, "verifyMode", null);
9497
9506
  setField(classic, effects, "directOverride", null);
9498
9507
  } else if (event === "archive-confirm") {
@@ -9521,6 +9530,324 @@ function applyClassicTransition(current, event, options = {}) {
9521
9530
  return { classic, effects, definition };
9522
9531
  }
9523
9532
 
9533
+ // domains/comet-classic/classic-current-change.ts
9534
+ import { promises as fs13 } from "fs";
9535
+ import path14 from "path";
9536
+
9537
+ // domains/comet-entry/current-selection.ts
9538
+ import { randomUUID as randomUUID6 } from "crypto";
9539
+ import { promises as fs11 } from "fs";
9540
+ import path12 from "path";
9541
+ var COMET_CURRENT_SELECTION_SCHEMA = "comet.selection.v2";
9542
+ var COMET_CURRENT_SELECTION_MAX_BYTES = 16 * 1024;
9543
+ function cometCurrentSelectionFile(projectRoot2) {
9544
+ return path12.join(projectRoot2, ".comet", "current-change.json");
9545
+ }
9546
+ function isRecord(value) {
9547
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
9548
+ }
9549
+ function validBranch(value) {
9550
+ return value === null || typeof value === "string";
9551
+ }
9552
+ function parseSelection(source) {
9553
+ let value;
9554
+ try {
9555
+ value = JSON.parse(source);
9556
+ } catch (error) {
9557
+ throw new Error(
9558
+ `current change selection contains invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
9559
+ { cause: error }
9560
+ );
9561
+ }
9562
+ if (!isRecord(value)) {
9563
+ throw new Error("current change selection must be a JSON object");
9564
+ }
9565
+ if (value.version === 1) {
9566
+ if (typeof value.change !== "string") {
9567
+ throw new Error("legacy current change selection change must be a string");
9568
+ }
9569
+ if (value.branch !== void 0 && !validBranch(value.branch)) {
9570
+ throw new Error("legacy current change selection branch must be a string or null");
9571
+ }
9572
+ return {
9573
+ selection: {
9574
+ schema: COMET_CURRENT_SELECTION_SCHEMA,
9575
+ workflow: "classic",
9576
+ change: value.change,
9577
+ branch: value.branch ?? null
9578
+ },
9579
+ legacy: true
9580
+ };
9581
+ }
9582
+ if (value.schema !== COMET_CURRENT_SELECTION_SCHEMA) {
9583
+ throw new Error(`current change selection schema must be ${COMET_CURRENT_SELECTION_SCHEMA}`);
9584
+ }
9585
+ if (value.workflow !== "native" && value.workflow !== "classic") {
9586
+ throw new Error("current change selection workflow must be native or classic");
9587
+ }
9588
+ if (typeof value.change !== "string") {
9589
+ throw new Error("current change selection change must be a string");
9590
+ }
9591
+ if (!validBranch(value.branch)) {
9592
+ throw new Error("current change selection branch must be a string or null");
9593
+ }
9594
+ if (value.workflow === "native" && value.branch !== null) {
9595
+ throw new Error("Native current change selection branch must be null");
9596
+ }
9597
+ return { selection: value, legacy: false };
9598
+ }
9599
+ async function readCometCurrentSelection(projectRoot2) {
9600
+ let source;
9601
+ try {
9602
+ const stat = await fs11.lstat(cometCurrentSelectionFile(projectRoot2));
9603
+ if (stat.isSymbolicLink() || !stat.isFile()) {
9604
+ throw new Error("current change selection must be a regular file");
9605
+ }
9606
+ if (stat.size > COMET_CURRENT_SELECTION_MAX_BYTES) {
9607
+ throw new Error(
9608
+ `current change selection exceeds ${COMET_CURRENT_SELECTION_MAX_BYTES} bytes`
9609
+ );
9610
+ }
9611
+ source = await fs11.readFile(cometCurrentSelectionFile(projectRoot2), "utf8");
9612
+ } catch (error) {
9613
+ if (error.code === "ENOENT") return { status: "missing" };
9614
+ throw new Error(
9615
+ `cannot read current change selection: ${error instanceof Error ? error.message : String(error)}`,
9616
+ { cause: error }
9617
+ );
9618
+ }
9619
+ const parsed = parseSelection(source);
9620
+ return { status: "selected", ...parsed };
9621
+ }
9622
+ async function writeCometCurrentSelection(projectRoot2, selection) {
9623
+ const parsed = parseSelection(JSON.stringify(selection));
9624
+ if (parsed.legacy) throw new Error("cannot write a legacy current change selection");
9625
+ const file = cometCurrentSelectionFile(projectRoot2);
9626
+ const temporary = `${file}.${randomUUID6()}.tmp`;
9627
+ await fs11.mkdir(path12.dirname(file), { recursive: true });
9628
+ try {
9629
+ await fs11.writeFile(temporary, `${JSON.stringify(parsed.selection, null, 2)}
9630
+ `, "utf8");
9631
+ await fs11.rename(temporary, file);
9632
+ } catch (error) {
9633
+ await fs11.rm(temporary, { force: true });
9634
+ throw error;
9635
+ }
9636
+ }
9637
+ async function clearCometCurrentSelection(projectRoot2) {
9638
+ await fs11.rm(cometCurrentSelectionFile(projectRoot2), { force: true });
9639
+ }
9640
+ async function clearCometCurrentSelectionIf(projectRoot2, workflow, change) {
9641
+ const current = await readCometCurrentSelection(projectRoot2);
9642
+ if (current.status !== "selected" || current.selection.workflow !== workflow || current.selection.change !== change) {
9643
+ return false;
9644
+ }
9645
+ await clearCometCurrentSelection(projectRoot2);
9646
+ return true;
9647
+ }
9648
+
9649
+ // domains/comet-classic/classic-branch-binding.ts
9650
+ var import_yaml3 = __toESM(require_dist(), 1);
9651
+ import { execFileSync } from "child_process";
9652
+ import { randomUUID as randomUUID7 } from "crypto";
9653
+ import { promises as fs12 } from "fs";
9654
+ import path13 from "path";
9655
+ function liveGitBranch(cwd) {
9656
+ try {
9657
+ const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
9658
+ cwd,
9659
+ encoding: "utf8",
9660
+ stdio: ["ignore", "pipe", "ignore"]
9661
+ }).trim();
9662
+ return branch && branch !== "HEAD" ? branch : null;
9663
+ } catch {
9664
+ return null;
9665
+ }
9666
+ }
9667
+ function isGitWorkTree(cwd) {
9668
+ try {
9669
+ return execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
9670
+ cwd,
9671
+ encoding: "utf8",
9672
+ stdio: ["ignore", "pipe", "ignore"]
9673
+ }).trim() === "true";
9674
+ } catch {
9675
+ return false;
9676
+ }
9677
+ }
9678
+ var BOUND_BRANCH_ISOLATIONS = ["current", "branch", "worktree"];
9679
+ function requiresBranchBinding(isolation) {
9680
+ return BOUND_BRANCH_ISOLATIONS.includes(isolation);
9681
+ }
9682
+ function evaluateBranchBinding(input) {
9683
+ if (!requiresBranchBinding(input.isolation)) return { status: "not-applicable" };
9684
+ if (input.boundBranch === null && input.currentBranch === null && input.gitWorkTree === false) {
9685
+ return { status: "not-applicable" };
9686
+ }
9687
+ if (input.boundBranch === null) {
9688
+ return input.currentBranch === null ? { status: "unbound-detached" } : { status: "needs-heal", branch: input.currentBranch };
9689
+ }
9690
+ if (input.currentBranch === input.boundBranch) return { status: "ok" };
9691
+ return { status: "drift", boundBranch: input.boundBranch, currentBranch: input.currentBranch };
9692
+ }
9693
+ async function resolveBranchBinding(changeDir, options) {
9694
+ const file = path13.join(changeDir, ".comet.yaml");
9695
+ const document = (0, import_yaml3.parseDocument)(await fs12.readFile(file, "utf8"), { uniqueKeys: false });
9696
+ if (document.errors.length > 0) {
9697
+ throw new Error(`Invalid .comet.yaml: ${document.errors[0].message}`);
9698
+ }
9699
+ const record = document.toJS() ?? {};
9700
+ const isolation = typeof record.isolation === "string" ? record.isolation : null;
9701
+ const boundBranch = typeof record.bound_branch === "string" && record.bound_branch !== "" ? record.bound_branch : null;
9702
+ const bindingRequired = requiresBranchBinding(isolation);
9703
+ const currentBranch = liveGitBranch(options.cwd);
9704
+ const gitWorkTree = bindingRequired && boundBranch === null && currentBranch === null ? isGitWorkTree(options.cwd) : true;
9705
+ const verdict = evaluateBranchBinding({ isolation, boundBranch, currentBranch, gitWorkTree });
9706
+ if (verdict.status === "needs-heal" && options.heal) {
9707
+ await healBoundBranch(changeDir, verdict.branch);
9708
+ return { status: "healed", branch: verdict.branch, bindingRequired, currentBranch };
9709
+ }
9710
+ return { ...verdict, bindingRequired, currentBranch };
9711
+ }
9712
+ async function healBoundBranch(changeDir, branch) {
9713
+ const file = path13.join(changeDir, ".comet.yaml");
9714
+ const document = (0, import_yaml3.parseDocument)(await fs12.readFile(file, "utf8"), { uniqueKeys: false });
9715
+ document.set("bound_branch", branch);
9716
+ const temporary = `${file}.${randomUUID7()}.tmp`;
9717
+ try {
9718
+ await fs12.writeFile(temporary, document.toString(), "utf8");
9719
+ await fs12.rename(temporary, file);
9720
+ } catch (error) {
9721
+ await fs12.rm(temporary, { force: true });
9722
+ throw error;
9723
+ }
9724
+ }
9725
+ function branchLabel(currentBranch) {
9726
+ return currentBranch ?? "detached HEAD";
9727
+ }
9728
+ function driftBlockedMessage(change, boundBranch, currentBranch) {
9729
+ return `change '${change}' is bound to branch '${boundBranch}', but current branch is '${branchLabel(currentBranch)}'.
9730
+ Next: ask the user to confirm — switch back to '${boundBranch}', or run \`comet state rebind ${change}\` after explicit confirmation.`;
9731
+ }
9732
+ function driftStaleReason(change, boundBranch, currentBranch) {
9733
+ return `change '${change}' is bound to branch '${boundBranch}', but current branch is '${branchLabel(currentBranch)}'`;
9734
+ }
9735
+ function unboundDetachedMessage(change) {
9736
+ return `change '${change}' uses a branch-bound workspace mode but has no bound branch and HEAD is detached; checkout a branch first before continuing.`;
9737
+ }
9738
+
9739
+ // domains/comet-classic/classic-current-change.ts
9740
+ function changeDirectory(projectRoot2, changeName) {
9741
+ return path14.join(projectRoot2, "openspec", "changes", changeName);
9742
+ }
9743
+ async function validateActiveChange(projectRoot2, changeName) {
9744
+ assertOpenSpecChangeName(changeName);
9745
+ const changeDir = changeDirectory(projectRoot2, changeName);
9746
+ try {
9747
+ await fs13.access(path14.join(changeDir, ".comet.yaml"));
9748
+ } catch (error) {
9749
+ if (error.code === "ENOENT") {
9750
+ throw new Error(
9751
+ `Cannot select current change '${changeName}': active change state not found`,
9752
+ {
9753
+ cause: error
9754
+ }
9755
+ );
9756
+ }
9757
+ throw error;
9758
+ }
9759
+ const projection = await readClassicState(changeDir, { migrate: false });
9760
+ if (!projection.classic) {
9761
+ throw new Error(`Cannot select current change '${changeName}': Classic state is incomplete`);
9762
+ }
9763
+ if (projection.classic.archived) {
9764
+ throw new Error(`Cannot select current change '${changeName}': change is archived`);
9765
+ }
9766
+ }
9767
+ async function selectCurrentChange(projectRoot2, changeName) {
9768
+ await validateActiveChange(projectRoot2, changeName);
9769
+ const outcome = await resolveBranchBinding(changeDirectory(projectRoot2, changeName), {
9770
+ heal: true,
9771
+ cwd: projectRoot2
9772
+ });
9773
+ if (outcome.status === "drift") {
9774
+ throw new Error(driftStaleReason(changeName, outcome.boundBranch, outcome.currentBranch));
9775
+ }
9776
+ if (outcome.status === "unbound-detached") {
9777
+ throw new Error(unboundDetachedMessage(changeName));
9778
+ }
9779
+ const selection = {
9780
+ schema: "comet.selection.v2",
9781
+ workflow: "classic",
9782
+ change: changeName,
9783
+ branch: outcome.currentBranch
9784
+ };
9785
+ await writeCometCurrentSelection(projectRoot2, selection);
9786
+ return selection;
9787
+ }
9788
+ async function resolveCurrentChange(projectRoot2) {
9789
+ let current;
9790
+ try {
9791
+ current = await readCometCurrentSelection(projectRoot2);
9792
+ } catch (error) {
9793
+ return {
9794
+ status: "stale",
9795
+ reason: error instanceof Error ? error.message : String(error)
9796
+ };
9797
+ }
9798
+ if (current.status === "missing") return { status: "missing" };
9799
+ if (current.selection.workflow !== "classic") {
9800
+ return {
9801
+ status: "stale",
9802
+ reason: `current change '${current.selection.change}' belongs to Native, not Classic`
9803
+ };
9804
+ }
9805
+ const selection = current.selection;
9806
+ try {
9807
+ await validateActiveChange(projectRoot2, selection.change);
9808
+ } catch (error) {
9809
+ return {
9810
+ status: "stale",
9811
+ reason: error instanceof Error ? error.message : String(error)
9812
+ };
9813
+ }
9814
+ const outcome = await resolveBranchBinding(changeDirectory(projectRoot2, selection.change), {
9815
+ heal: false,
9816
+ cwd: projectRoot2
9817
+ });
9818
+ if (outcome.status === "drift") {
9819
+ return {
9820
+ status: "stale",
9821
+ reason: driftStaleReason(selection.change, outcome.boundBranch, outcome.currentBranch)
9822
+ };
9823
+ }
9824
+ if (outcome.status === "unbound-detached") {
9825
+ return { status: "stale", reason: unboundDetachedMessage(selection.change) };
9826
+ }
9827
+ if (outcome.status === "ok") return { status: "selected", selection };
9828
+ if (selection.branch !== null && outcome.currentBranch !== selection.branch) {
9829
+ return {
9830
+ status: "stale",
9831
+ reason: `current change '${selection.change}' was selected on branch '${selection.branch}', current branch is '${outcome.currentBranch ?? "detached HEAD"}'`
9832
+ };
9833
+ }
9834
+ return { status: "selected", selection };
9835
+ }
9836
+ async function clearCurrentChange(projectRoot2) {
9837
+ let current;
9838
+ try {
9839
+ current = await readCometCurrentSelection(projectRoot2);
9840
+ } catch {
9841
+ return;
9842
+ }
9843
+ if (current.status === "selected" && current.selection.workflow === "classic") {
9844
+ await clearCometCurrentSelection(projectRoot2);
9845
+ }
9846
+ }
9847
+ async function clearCurrentChangeIf(projectRoot2, change) {
9848
+ return clearCometCurrentSelectionIf(projectRoot2, "classic", change);
9849
+ }
9850
+
9524
9851
  // domains/comet-classic/classic-archive.ts
9525
9852
  var GREEN = "\x1B[32m";
9526
9853
  var RED = "\x1B[31m";
@@ -9555,7 +9882,7 @@ var ArchiveOutput = class {
9555
9882
  };
9556
9883
  async function exists2(file) {
9557
9884
  try {
9558
- await fs11.access(file);
9885
+ await fs14.access(file);
9559
9886
  return true;
9560
9887
  } catch (error) {
9561
9888
  if (error.code === "ENOENT") return false;
@@ -9609,10 +9936,10 @@ async function findArchiveDir(change, preferred) {
9609
9936
  if (await exists2(preferred)) return preferred;
9610
9937
  const archiveRoot = "openspec/changes/archive";
9611
9938
  if (!await exists2(archiveRoot)) return null;
9612
- for (const entry2 of (await fs11.readdir(archiveRoot)).sort()) {
9939
+ for (const entry2 of (await fs14.readdir(archiveRoot)).sort()) {
9613
9940
  if (!entry2.endsWith(`-${change}`)) continue;
9614
9941
  const candidate = `${archiveRoot}/${entry2}`;
9615
- if ((await fs11.stat(candidate)).isDirectory()) return candidate;
9942
+ if ((await fs14.stat(candidate)).isDirectory()) return candidate;
9616
9943
  }
9617
9944
  return null;
9618
9945
  }
@@ -9642,9 +9969,9 @@ async function annotateFrontmatter(output, file, archiveName, extraFields, dryRu
9642
9969
  output.stepsTotal += 1;
9643
9970
  return;
9644
9971
  }
9645
- const original = await fs11.readFile(file, "utf8");
9972
+ const original = await fs14.readFile(file, "utf8");
9646
9973
  const updated = annotatedMarkdown(original, archiveName, extraFields);
9647
- await fs11.writeFile(file, updated);
9974
+ await fs14.writeFile(file, updated);
9648
9975
  output.stderr.push(green(` [OK] Annotated: ${file}`));
9649
9976
  output.stepsOk += 1;
9650
9977
  output.stepsTotal += 1;
@@ -9653,10 +9980,10 @@ async function verifyMainSpecsClean() {
9653
9980
  const specsRoot = "openspec/specs";
9654
9981
  if (!await exists2(specsRoot)) return;
9655
9982
  let found = false;
9656
- for (const entry2 of await fs11.readdir(specsRoot)) {
9983
+ for (const entry2 of await fs14.readdir(specsRoot)) {
9657
9984
  const specFile = `${specsRoot}/${entry2}/spec.md`;
9658
9985
  if (!await exists2(specFile)) continue;
9659
- const matches = (await fs11.readFile(specFile, "utf8")).split(/\r?\n/u).map((line, index) => ({ line, number: index + 1 })).filter((item) => /^## (ADDED|MODIFIED|REMOVED|RENAMED) Requirements$/u.test(item.line));
9986
+ const matches = (await fs14.readFile(specFile, "utf8")).split(/\r?\n/u).map((line, index) => ({ line, number: index + 1 })).filter((item) => /^## (ADDED|MODIFIED|REMOVED|RENAMED) Requirements$/u.test(item.line));
9660
9987
  if (matches.length > 0) {
9661
9988
  found = true;
9662
9989
  process.stderr.write(
@@ -9688,7 +10015,7 @@ var classicArchiveCommand = async (args) => {
9688
10015
  }
9689
10016
  if (recoveredArchive) {
9690
10017
  archiveDir = recoveredArchive;
9691
- archiveName = path12.basename(recoveredArchive);
10018
+ archiveName = path15.basename(recoveredArchive);
9692
10019
  }
9693
10020
  const projection = await readClassicState(changeDir);
9694
10021
  if (!projection.classic) {
@@ -9783,7 +10110,7 @@ var classicArchiveCommand = async (args) => {
9783
10110
  return output.toResult(1);
9784
10111
  }
9785
10112
  archiveDir = resolvedArchive;
9786
- archiveName = path12.basename(resolvedArchive);
10113
+ archiveName = path15.basename(resolvedArchive);
9787
10114
  output.stderr.push(green(` [OK] OpenSpec archive completed: ${archiveDir}`));
9788
10115
  output.stepsOk += 1;
9789
10116
  output.stepsTotal += 1;
@@ -9890,6 +10217,7 @@ var classicArchiveCommand = async (args) => {
9890
10217
  output.stepsOk += 1;
9891
10218
  output.stepsTotal += 1;
9892
10219
  }
10220
+ if (!dryRun) await clearCurrentChangeIf(process.cwd(), change);
9893
10221
  output.stderr.push("");
9894
10222
  output.stderr.push(
9895
10223
  dryRun ? yellow(`Dry run complete. ${output.stepsOk}/${output.stepsTotal} steps would succeed.`) : green(`Archive complete. ${output.stepsOk}/${output.stepsTotal} steps succeeded.`)
@@ -9907,30 +10235,30 @@ var classicArchiveCommand = async (args) => {
9907
10235
  };
9908
10236
 
9909
10237
  // domains/comet-classic/classic-guard.ts
9910
- var import_yaml5 = __toESM(require_dist(), 1);
10238
+ var import_yaml6 = __toESM(require_dist(), 1);
9911
10239
  import { spawnSync as spawnSync2 } from "child_process";
9912
10240
  import { createHash as createHash4 } from "crypto";
9913
- import { existsSync, promises as fs15, readFileSync } from "fs";
9914
- import path16 from "path";
10241
+ import { existsSync, promises as fs18, readFileSync } from "fs";
10242
+ import path19 from "path";
9915
10243
 
9916
10244
  // domains/comet-classic/classic-command-checks.ts
9917
- import path13 from "path";
10245
+ import path16 from "path";
9918
10246
  function validateScope(scope) {
9919
10247
  if (scope !== "build" && scope !== "verify") {
9920
10248
  throw new Error(`Invalid command check scope: '${String(scope)}'`);
9921
10249
  }
9922
10250
  }
9923
10251
  function projectRoot(changeDir) {
9924
- return path13.resolve(changeDir, "..", "..", "..");
10252
+ return path16.resolve(changeDir, "..", "..", "..");
9925
10253
  }
9926
10254
  function normalizedCwd(changeDir, cwd = ".") {
9927
10255
  if (cwd.trim().length === 0) throw new Error("Command check cwd cannot be blank");
9928
10256
  const root = projectRoot(changeDir);
9929
- const target = path13.resolve(root, cwd);
9930
- if (target !== root && !target.startsWith(root + path13.sep)) {
10257
+ const target = path16.resolve(root, cwd);
10258
+ if (target !== root && !target.startsWith(root + path16.sep)) {
9931
10259
  throw new Error(`Command check cwd must resolve within the project root: '${cwd}'`);
9932
10260
  }
9933
- return path13.relative(root, target).replaceAll("\\", "/") || ".";
10261
+ return path16.relative(root, target).replaceAll("\\", "/") || ".";
9934
10262
  }
9935
10263
  function validRecord(changeDir, event) {
9936
10264
  if (event.type !== "command_check_recorded") return null;
@@ -10091,9 +10419,9 @@ async function inspectClassicChange(changeDir, name) {
10091
10419
  }
10092
10420
 
10093
10421
  // domains/comet-classic/classic-validate-command.ts
10094
- var import_yaml3 = __toESM(require_dist(), 1);
10095
- import { promises as fs12 } from "fs";
10096
- import path14 from "path";
10422
+ var import_yaml4 = __toESM(require_dist(), 1);
10423
+ import { promises as fs15 } from "fs";
10424
+ import path17 from "path";
10097
10425
  var GREEN2 = "\x1B[32m";
10098
10426
  var RED2 = "\x1B[31m";
10099
10427
  var YELLOW2 = "\x1B[33m";
@@ -10143,7 +10471,7 @@ function color(code, message) {
10143
10471
  }
10144
10472
  async function exists3(file) {
10145
10473
  try {
10146
- await fs12.access(file);
10474
+ await fs15.access(file);
10147
10475
  return true;
10148
10476
  } catch (error) {
10149
10477
  if (error.code === "ENOENT") return false;
@@ -10164,7 +10492,7 @@ var classicValidateCommand = async (args) => {
10164
10492
  };
10165
10493
  }
10166
10494
  const { directory, label } = await resolveClassicChangeDirectory(name);
10167
- const yamlFile = path14.join(directory, ".comet.yaml");
10495
+ const yamlFile = path17.join(directory, ".comet.yaml");
10168
10496
  const lines = [`[VALIDATE] ${label}/.comet.yaml`];
10169
10497
  let errors = 0;
10170
10498
  let warnings = 0;
@@ -10178,7 +10506,7 @@ var classicValidateCommand = async (args) => {
10178
10506
  };
10179
10507
  let source;
10180
10508
  try {
10181
- source = await fs12.readFile(yamlFile, "utf8");
10509
+ source = await fs15.readFile(yamlFile, "utf8");
10182
10510
  } catch (error) {
10183
10511
  if (error.code === "ENOENT") {
10184
10512
  fail3(".comet.yaml does not exist");
@@ -10187,10 +10515,10 @@ var classicValidateCommand = async (args) => {
10187
10515
  }
10188
10516
  throw error;
10189
10517
  }
10190
- const document = (0, import_yaml3.parseDocument)(source);
10191
- if (document.errors.length > 0 || !(0, import_yaml3.isMap)(document.contents)) {
10518
+ const document = (0, import_yaml4.parseDocument)(source);
10519
+ if (document.errors.length > 0 || !(0, import_yaml4.isMap)(document.contents)) {
10192
10520
  for (const error of document.errors) fail3(error.message);
10193
- if (!(0, import_yaml3.isMap)(document.contents)) fail3("document root must be a mapping");
10521
+ if (!(0, import_yaml4.isMap)(document.contents)) fail3("document root must be a mapping");
10194
10522
  lines.push("", color(RED2, `${errors} error(s), ${warnings} warning(s) — validation FAILED`));
10195
10523
  return { exitCode: 1, stderr: lines.join("\n") };
10196
10524
  }
@@ -10213,6 +10541,12 @@ var classicValidateCommand = async (args) => {
10213
10541
  fail3(`${field2}='${value}' is not valid. Expected: ${values.join(" ")}`);
10214
10542
  }
10215
10543
  }
10544
+ if (Object.prototype.hasOwnProperty.call(record, "bound_branch")) {
10545
+ const value = record.bound_branch;
10546
+ if (value !== null && typeof value !== "string") {
10547
+ fail3(`bound_branch='${text(value)}' is not a string or null`);
10548
+ }
10549
+ }
10216
10550
  if (Object.prototype.hasOwnProperty.call(record, "verify_failures")) {
10217
10551
  const value = record.verify_failures;
10218
10552
  if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
@@ -10221,7 +10555,7 @@ var classicValidateCommand = async (args) => {
10221
10555
  }
10222
10556
  for (const field2 of ["design_doc", "plan", "handoff_context"]) {
10223
10557
  const value = text(record[field2]);
10224
- if (value && !await exists3(path14.resolve(value))) {
10558
+ if (value && !await exists3(path17.resolve(value))) {
10225
10559
  fail3(`${field2}='${value}' does not exist on disk`);
10226
10560
  }
10227
10561
  }
@@ -10244,16 +10578,16 @@ var classicValidateCommand = async (args) => {
10244
10578
  };
10245
10579
 
10246
10580
  // domains/comet-classic/classic-project-config.ts
10247
- var import_yaml4 = __toESM(require_dist(), 1);
10581
+ var import_yaml5 = __toESM(require_dist(), 1);
10248
10582
  import os from "os";
10249
- import { promises as fs14 } from "fs";
10250
- import path15 from "path";
10583
+ import { promises as fs17 } from "fs";
10584
+ import path18 from "path";
10251
10585
 
10252
10586
  // platform/fs/file-system.ts
10253
- import { promises as fs13 } from "fs";
10587
+ import { promises as fs16 } from "fs";
10254
10588
  async function fileExists3(filePath) {
10255
10589
  try {
10256
- await fs13.access(filePath);
10590
+ await fs16.access(filePath);
10257
10591
  return true;
10258
10592
  } catch (error) {
10259
10593
  if (isNotFoundError(error)) return false;
@@ -10262,7 +10596,7 @@ async function fileExists3(filePath) {
10262
10596
  }
10263
10597
  async function readDir(dirPath) {
10264
10598
  try {
10265
- return await fs13.readdir(dirPath);
10599
+ return await fs16.readdir(dirPath);
10266
10600
  } catch (error) {
10267
10601
  const code = error?.code;
10268
10602
  if (code === "ENOENT" || code === "ENOTDIR") {
@@ -10280,9 +10614,9 @@ function configCandidates(options = {}) {
10280
10614
  const cwd = options.cwd ?? process.cwd();
10281
10615
  const homeDir = options.homeDir ?? os.homedir();
10282
10616
  const candidates = [
10283
- { file: path15.resolve(cwd, ".comet", "config.yaml"), source: ".comet/config.yaml" },
10617
+ { file: path18.resolve(cwd, ".comet", "config.yaml"), source: ".comet/config.yaml" },
10284
10618
  {
10285
- file: path15.resolve(homeDir, ".comet", "config.yaml"),
10619
+ file: path18.resolve(homeDir, ".comet", "config.yaml"),
10286
10620
  source: "~/.comet/config.yaml"
10287
10621
  }
10288
10622
  ];
@@ -10293,10 +10627,14 @@ function configCandidates(options = {}) {
10293
10627
  async function readClassicConfigValue(field2, options = {}) {
10294
10628
  for (const candidate of configCandidates(options)) {
10295
10629
  if (!await fileExists3(candidate.file)) continue;
10296
- const document = (0, import_yaml4.parseDocument)(await fs14.readFile(candidate.file, "utf8"), {
10630
+ const document = (0, import_yaml5.parseDocument)(await fs17.readFile(candidate.file, "utf8"), {
10297
10631
  uniqueKeys: false
10298
10632
  });
10299
- const value = document.get(field2);
10633
+ const root = document.toJS();
10634
+ if (!root || typeof root !== "object" || Array.isArray(root)) continue;
10635
+ const classic = root.classic;
10636
+ if (!classic || typeof classic !== "object" || Array.isArray(classic)) continue;
10637
+ const value = classic[field2];
10300
10638
  if (value === null || value === void 0) continue;
10301
10639
  return { value: String(value), source: candidate.source };
10302
10640
  }
@@ -10367,7 +10705,7 @@ var GuardOutput = class {
10367
10705
  };
10368
10706
  async function exists4(file) {
10369
10707
  try {
10370
- await fs15.access(file);
10708
+ await fs18.access(file);
10371
10709
  return true;
10372
10710
  } catch (error) {
10373
10711
  if (error.code === "ENOENT") return false;
@@ -10376,7 +10714,7 @@ async function exists4(file) {
10376
10714
  }
10377
10715
  async function nonempty(file) {
10378
10716
  try {
10379
- return (await fs15.stat(file)).size > 0;
10717
+ return (await fs18.stat(file)).size > 0;
10380
10718
  } catch (error) {
10381
10719
  if (error.code === "ENOENT") return false;
10382
10720
  throw error;
@@ -10390,8 +10728,8 @@ async function resolveChangeDir(name) {
10390
10728
  return (await resolveClassicChangeDirectory(name)).label;
10391
10729
  }
10392
10730
  async function readField(changeDir, field2) {
10393
- const file = path16.join(changeDir, ".comet.yaml");
10394
- const document = (0, import_yaml5.parseDocument)(await fs15.readFile(file, "utf8"), { uniqueKeys: false });
10731
+ const file = path19.join(changeDir, ".comet.yaml");
10732
+ const document = (0, import_yaml6.parseDocument)(await fs18.readFile(file, "utf8"), { uniqueKeys: false });
10395
10733
  if (document.errors.length > 0) {
10396
10734
  throw new GuardFailure(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
10397
10735
  }
@@ -10432,7 +10770,7 @@ function countEnglishWords(source) {
10432
10770
  }
10433
10771
  async function documentLanguageMatchesConfigured(changeDir, file) {
10434
10772
  const language = await configuredLanguage(changeDir);
10435
- const source = stripFencedCodeBlocks(await fs15.readFile(file, "utf8"));
10773
+ const source = stripFencedCodeBlocks(await fs18.readFile(file, "utf8"));
10436
10774
  const cjk = countCjkChars(source);
10437
10775
  const englishWords = countEnglishWords(source);
10438
10776
  if (language === "zh-CN" && cjk < 20 && englishWords >= 20) {
@@ -10456,7 +10794,7 @@ async function handoffSourceFiles(changeDir) {
10456
10794
  const files = [`${changeDir}/proposal.md`, `${changeDir}/design.md`, `${changeDir}/tasks.md`];
10457
10795
  const specs = `${changeDir}/specs`;
10458
10796
  if (await exists4(specs)) {
10459
- for (const entry2 of (await fs15.readdir(specs)).sort()) {
10797
+ for (const entry2 of (await fs18.readdir(specs)).sort()) {
10460
10798
  const spec = `${specs}/${entry2}/spec.md`;
10461
10799
  if (await exists4(spec)) files.push(spec);
10462
10800
  }
@@ -10476,7 +10814,7 @@ async function preflight(changeDir, name) {
10476
10814
  if (!await exists4(changeDir)) {
10477
10815
  throw new GuardFailure(red2(`FATAL: change directory not found: ${changeDir}`));
10478
10816
  }
10479
- if (!await exists4(path16.join(changeDir, ".comet.yaml"))) {
10817
+ if (!await exists4(path19.join(changeDir, ".comet.yaml"))) {
10480
10818
  throw new GuardFailure(red2(`FATAL: .comet.yaml not found in ${changeDir}`));
10481
10819
  }
10482
10820
  const result5 = await classicValidateCommand([name], { json: false });
@@ -10546,9 +10884,9 @@ var INFERRED_COMMAND_SOURCES = [
10546
10884
  "Cargo.toml"
10547
10885
  ];
10548
10886
  async function removedProjectCommandField(field2) {
10549
- const config = path16.join(".comet", "config.yaml");
10887
+ const config = path19.join(".comet", "config.yaml");
10550
10888
  if (!await exists4(config)) return false;
10551
- const document = (0, import_yaml5.parseDocument)(await fs15.readFile(config, "utf8"));
10889
+ const document = (0, import_yaml6.parseDocument)(await fs18.readFile(config, "utf8"));
10552
10890
  if (document.errors.length > 0) {
10553
10891
  throw new Error(
10554
10892
  `.comet/config.yaml is invalid YAML (${document.errors[0].message}); cannot check for removed "${field2}" field. Fix the config and retry.`
@@ -10629,14 +10967,14 @@ ${recoveryCommand(change, scope, recorded.command)}`
10629
10967
  return { status: 0, output: evidenceDetail(recorded) };
10630
10968
  }
10631
10969
  async function tasksAllDone(changeDir) {
10632
- const tasks = path16.join(changeDir, "tasks.md");
10970
+ const tasks = path19.join(changeDir, "tasks.md");
10633
10971
  if (!await exists4(tasks)) {
10634
10972
  return fail(
10635
10973
  `tasks.md is missing at ${tasks}
10636
10974
  Next: restore or create tasks.md for this change before leaving build.`
10637
10975
  );
10638
10976
  }
10639
- const source = await fs15.readFile(tasks, "utf8");
10977
+ const source = await fs18.readFile(tasks, "utf8");
10640
10978
  if (!/- \[x\]/u.test(source)) {
10641
10979
  return fail(
10642
10980
  "tasks.md has no completed tasks.\nNext: complete implementation tasks and mark them with '- [x]'."
@@ -10653,9 +10991,9 @@ Next: complete or explicitly remove unfinished tasks, then mark tasks.md with '-
10653
10991
  return pass();
10654
10992
  }
10655
10993
  async function tasksHasAny(changeDir) {
10656
- const tasks = path16.join(changeDir, "tasks.md");
10994
+ const tasks = path19.join(changeDir, "tasks.md");
10657
10995
  if (!await exists4(tasks)) return false;
10658
- return /- \[/u.test(await fs15.readFile(tasks, "utf8"));
10996
+ return /- \[/u.test(await fs18.readFile(tasks, "utf8"));
10659
10997
  }
10660
10998
  async function planTasksAllDone(changeDir) {
10661
10999
  const plan = await readField(changeDir, "plan");
@@ -10666,7 +11004,7 @@ async function planTasksAllDone(changeDir) {
10666
11004
  Next: restore the Superpowers plan file or update .comet.yaml plan before leaving build.`
10667
11005
  );
10668
11006
  }
10669
- const source = await fs15.readFile(plan, "utf8");
11007
+ const source = await fs18.readFile(plan, "utf8");
10670
11008
  const unfinished = source.split(/\r?\n/u).map((line, index) => ({ line, number: index + 1 })).filter((entry2) => /^\s*- \[ \]/u.test(entry2.line));
10671
11009
  if (unfinished.length > 0) {
10672
11010
  return fail(
@@ -10677,14 +11015,36 @@ Next: check off corresponding completed plan tasks, then commit the plan update.
10677
11015
  }
10678
11016
  return pass();
10679
11017
  }
11018
+ async function boundBranchMatches(changeDir, change) {
11019
+ let outcome;
11020
+ try {
11021
+ outcome = await resolveBranchBinding(changeDir, { heal: true, cwd: process.cwd() });
11022
+ } catch (error) {
11023
+ throw new GuardFailure(`ERROR: ${error instanceof Error ? error.message : String(error)}`);
11024
+ }
11025
+ switch (outcome.status) {
11026
+ case "drift":
11027
+ return fail(driftBlockedMessage(change, outcome.boundBranch, outcome.currentBranch));
11028
+ case "unbound-detached":
11029
+ return fail(unboundDetachedMessage(change));
11030
+ case "healed":
11031
+ return pass(`bound_branch lazily set to ${outcome.branch}`);
11032
+ case "needs-heal":
11033
+ case "ok":
11034
+ case "not-applicable":
11035
+ return pass();
11036
+ default: {
11037
+ const exhaustive = outcome;
11038
+ throw new Error(`unhandled branch binding status: ${JSON.stringify(exhaustive)}`);
11039
+ }
11040
+ }
11041
+ }
10680
11042
  async function isolationSelected(changeDir, change) {
10681
11043
  const isolation = await readField(changeDir, "isolation");
10682
- const workflow = await readField(changeDir, "workflow");
10683
- if (isolation === "branch" || isolation === "worktree") return pass();
10684
- if (isolation === "current" && (workflow === "hotfix" || workflow === "tweak")) return pass();
10685
- const allowedValues = workflow === "full" ? "<branch|worktree>" : "<current|branch|worktree>";
11044
+ if (isolation === "current" || isolation === "branch" || isolation === "worktree") return pass();
11045
+ const allowedValues = "<current|branch|worktree>";
10686
11046
  return fail(
10687
- `isolation must be ${workflow === "full" ? "branch or worktree" : "current, branch, or worktree"}, got '${isolation || "null"}'
11047
+ `isolation must be current, branch, or worktree, got '${isolation || "null"}'
10688
11048
  Next: choose a valid workspace mode, prepare it when needed, then run:
10689
11049
  comet state set ${change} isolation ${allowedValues}`
10690
11050
  );
@@ -10758,7 +11118,7 @@ async function archivedIsTrue(changeDir) {
10758
11118
  return await readField(changeDir, "archived") === "true";
10759
11119
  }
10760
11120
  async function designDocFrontmatterHas(designDoc, field2, expected) {
10761
- const source = (await fs15.readFile(designDoc, "utf8")).replace(/^\uFEFF/u, "");
11121
+ const source = (await fs18.readFile(designDoc, "utf8")).replace(/^\uFEFF/u, "");
10762
11122
  let inFrontmatter = false;
10763
11123
  for (const line of source.split(/\r?\n/u)) {
10764
11124
  if (!inFrontmatter) {
@@ -10823,7 +11183,7 @@ async function designHandoffMarkdownTraceable(changeDir) {
10823
11183
  const markdown = `${context.replace(/\.json$/u, "")}.md`;
10824
11184
  if (!await nonempty(markdown))
10825
11185
  return fail(`design handoff markdown is missing or empty: ${markdown}`);
10826
- const source = await fs15.readFile(markdown, "utf8");
11186
+ const source = await fs18.readFile(markdown, "utf8");
10827
11187
  const problems = [];
10828
11188
  if (!/^Generated-by: comet-handoff\.sh$/mu.test(source)) {
10829
11189
  problems.push("handoff markdown is missing Generated-by marker");
@@ -10850,7 +11210,7 @@ async function betaSpecJsonStructurallyValid(changeDir) {
10850
11210
  const context = await readField(changeDir, "handoff_context");
10851
11211
  if (!context || context === "null") return fail("handoff_context is missing from .comet.yaml");
10852
11212
  if (!await nonempty(context)) return fail(`spec-context.json is missing or empty: ${context}`);
10853
- const source = await fs15.readFile(context, "utf8");
11213
+ const source = await fs18.readFile(context, "utf8");
10854
11214
  const problems = [];
10855
11215
  let parsed;
10856
11216
  try {
@@ -10887,19 +11247,19 @@ async function guardOpenChecks(output, changeDir) {
10887
11247
  const checks = [
10888
11248
  check(
10889
11249
  "proposal.md exists and non-empty",
10890
- async () => await nonempty(path16.join(changeDir, "proposal.md")) ? pass() : fail("")
11250
+ async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
10891
11251
  ),
10892
11252
  check(
10893
11253
  "proposal.md matches configured language",
10894
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "proposal.md"))
11254
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
10895
11255
  ),
10896
11256
  check(
10897
11257
  "tasks.md exists and non-empty",
10898
- async () => await nonempty(path16.join(changeDir, "tasks.md")) ? pass() : fail("")
11258
+ async () => await nonempty(path19.join(changeDir, "tasks.md")) ? pass() : fail("")
10899
11259
  ),
10900
11260
  check(
10901
11261
  "tasks.md matches configured language",
10902
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "tasks.md"))
11262
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "tasks.md"))
10903
11263
  ),
10904
11264
  check(
10905
11265
  "tasks.md has at least one task",
@@ -10912,11 +11272,11 @@ async function guardOpenChecks(output, changeDir) {
10912
11272
  0,
10913
11273
  check(
10914
11274
  "design.md exists and non-empty",
10915
- async () => await nonempty(path16.join(changeDir, "design.md")) ? pass() : fail("")
11275
+ async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
10916
11276
  ),
10917
11277
  check(
10918
11278
  "design.md matches configured language",
10919
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "design.md"))
11279
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "design.md"))
10920
11280
  )
10921
11281
  );
10922
11282
  }
@@ -10928,27 +11288,27 @@ async function guardDesignChecks(output, changeDir, change) {
10928
11288
  const builders = [
10929
11289
  check(
10930
11290
  "proposal.md exists",
10931
- async () => await nonempty(path16.join(changeDir, "proposal.md")) ? pass() : fail("")
11291
+ async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
10932
11292
  ),
10933
11293
  check(
10934
11294
  "proposal.md matches configured language",
10935
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "proposal.md"))
11295
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
10936
11296
  ),
10937
11297
  check(
10938
11298
  "design.md exists",
10939
- async () => await nonempty(path16.join(changeDir, "design.md")) ? pass() : fail("")
11299
+ async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
10940
11300
  ),
10941
11301
  check(
10942
11302
  "design.md matches configured language",
10943
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "design.md"))
11303
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "design.md"))
10944
11304
  ),
10945
11305
  check(
10946
11306
  "tasks.md exists",
10947
- async () => await nonempty(path16.join(changeDir, "tasks.md")) ? pass() : fail("")
11307
+ async () => await nonempty(path19.join(changeDir, "tasks.md")) ? pass() : fail("")
10948
11308
  ),
10949
11309
  check(
10950
11310
  "tasks.md matches configured language",
10951
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "tasks.md"))
11311
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "tasks.md"))
10952
11312
  ),
10953
11313
  check("design handoff context exists", () => designHandoffContextValid(changeDir, change)),
10954
11314
  check("design handoff markdown is traceable", () => designHandoffMarkdownTraceable(changeDir))
@@ -10999,6 +11359,7 @@ async function guardDesignChecks(output, changeDir, change) {
10999
11359
  }
11000
11360
  async function guardBuildChecks(output, changeDir, change, run) {
11001
11361
  return runChecks(output, [
11362
+ check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
11002
11363
  check("isolation selected", () => isolationSelected(changeDir, change)),
11003
11364
  check("build_mode selected", () => buildModeSelected(changeDir, change)),
11004
11365
  check("build_mode allowed for workflow", () => buildModeAllowedForWorkflow(changeDir)),
@@ -11009,11 +11370,11 @@ async function guardBuildChecks(output, changeDir, change, run) {
11009
11370
  check("Superpowers plan all tasks checked", () => planTasksAllDone(changeDir)),
11010
11371
  check(
11011
11372
  "proposal.md exists",
11012
- async () => await nonempty(path16.join(changeDir, "proposal.md")) ? pass() : fail("")
11373
+ async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
11013
11374
  ),
11014
11375
  check(
11015
11376
  "proposal.md matches configured language",
11016
- () => documentLanguageMatchesConfigured(changeDir, path16.join(changeDir, "proposal.md"))
11377
+ () => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
11017
11378
  ),
11018
11379
  check("Superpowers plan matches configured language", async () => {
11019
11380
  const plan = await readField(changeDir, "plan");
@@ -11030,6 +11391,7 @@ async function guardBuildChecks(output, changeDir, change, run) {
11030
11391
  }
11031
11392
  async function guardVerifyChecks(output, changeDir, change, run) {
11032
11393
  return runChecks(output, [
11394
+ check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
11033
11395
  check("tasks.md all tasks checked", () => tasksAllDone(changeDir)),
11034
11396
  // Verification command runs after tasks check — no point running tests
11035
11397
  // if tasks.md is incomplete.
@@ -11048,16 +11410,17 @@ async function guardVerifyChecks(output, changeDir, change, run) {
11048
11410
  })
11049
11411
  ]);
11050
11412
  }
11051
- async function guardArchiveChecks(output, changeDir) {
11413
+ async function guardArchiveChecks(output, changeDir, change) {
11052
11414
  return runChecks(output, [
11415
+ check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
11053
11416
  check("archived is true", async () => await archivedIsTrue(changeDir) ? pass() : fail("")),
11054
11417
  check(
11055
11418
  "proposal.md exists",
11056
- async () => await nonempty(path16.join(changeDir, "proposal.md")) ? pass() : fail("")
11419
+ async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
11057
11420
  ),
11058
11421
  check(
11059
11422
  "design.md exists",
11060
- async () => await nonempty(path16.join(changeDir, "design.md")) ? pass() : fail("")
11423
+ async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
11061
11424
  ),
11062
11425
  check("tasks.md all tasks checked", () => tasksAllDone(changeDir)),
11063
11426
  check(
@@ -11066,9 +11429,10 @@ async function guardArchiveChecks(output, changeDir) {
11066
11429
  )
11067
11430
  ]);
11068
11431
  }
11069
- async function applyStateUpdate(output, change, changeDir, phase, context) {
11432
+ async function applyStateUpdate(output, change, changeDir, phase) {
11070
11433
  const event = CLASSIC_GUARD_TRANSITION_EVENT[phase];
11071
11434
  if (!event) return;
11435
+ const context = await ensureClassicRuntimeRun(changeDir);
11072
11436
  const result5 = applyClassicTransition(context.classic, event);
11073
11437
  await transitionClassicRuntimeRun(changeDir, result5.classic, context.run, {
11074
11438
  event,
@@ -11122,7 +11486,7 @@ Valid phases: open, design, build, verify, archive`
11122
11486
  blocked2 = await guardBuildChecks(output, changeDir, change, runContext.run);
11123
11487
  else if (phase === "verify")
11124
11488
  blocked2 = await guardVerifyChecks(output, changeDir, change, runContext.run);
11125
- else blocked2 = await guardArchiveChecks(output, changeDir);
11489
+ else blocked2 = await guardArchiveChecks(output, changeDir, change);
11126
11490
  if (blocked2) {
11127
11491
  output.stderr.push("");
11128
11492
  output.stderr.push(red2("BLOCKED — fix failing checks before proceeding to next phase"));
@@ -11131,7 +11495,7 @@ Valid phases: open, design, build, verify, archive`
11131
11495
  output.stderr.push("");
11132
11496
  output.stderr.push(green2("ALL CHECKS PASSED — ready for next phase"));
11133
11497
  if (flag === "--apply") {
11134
- await applyStateUpdate(output, change, changeDir, phase, runContext);
11498
+ await applyStateUpdate(output, change, changeDir, phase);
11135
11499
  }
11136
11500
  return output.toResult(0);
11137
11501
  } catch (error) {
@@ -11144,10 +11508,10 @@ Valid phases: open, design, build, verify, archive`
11144
11508
  };
11145
11509
 
11146
11510
  // domains/comet-classic/classic-handoff.ts
11147
- var import_yaml6 = __toESM(require_dist(), 1);
11511
+ var import_yaml7 = __toESM(require_dist(), 1);
11148
11512
  import { createHash as createHash5 } from "crypto";
11149
- import { promises as fs16, readFileSync as readFileSync2 } from "fs";
11150
- import path17 from "path";
11513
+ import { promises as fs19, readFileSync as readFileSync2 } from "fs";
11514
+ import path20 from "path";
11151
11515
  var GREEN4 = "\x1B[32m";
11152
11516
  var RED4 = "\x1B[31m";
11153
11517
  var YELLOW4 = "\x1B[33m";
@@ -11181,7 +11545,7 @@ var HandoffOutput = class {
11181
11545
  };
11182
11546
  async function exists5(file) {
11183
11547
  try {
11184
- await fs16.access(file);
11548
+ await fs19.access(file);
11185
11549
  return true;
11186
11550
  } catch (error) {
11187
11551
  if (error.code === "ENOENT") return false;
@@ -11190,7 +11554,7 @@ async function exists5(file) {
11190
11554
  }
11191
11555
  async function nonempty2(file) {
11192
11556
  try {
11193
- return (await fs16.stat(file)).size > 0;
11557
+ return (await fs19.stat(file)).size > 0;
11194
11558
  } catch (error) {
11195
11559
  if (error.code === "ENOENT") return false;
11196
11560
  throw error;
@@ -11219,7 +11583,7 @@ async function handoffSourceFiles2(changeDir) {
11219
11583
  const files = [`${changeDir}/proposal.md`, `${changeDir}/design.md`, `${changeDir}/tasks.md`];
11220
11584
  const specs = `${changeDir}/specs`;
11221
11585
  if (await exists5(specs)) {
11222
- for (const entry2 of (await fs16.readdir(specs)).sort()) {
11586
+ for (const entry2 of (await fs19.readdir(specs)).sort()) {
11223
11587
  const spec = `${specs}/${entry2}/spec.md`;
11224
11588
  if (await exists5(spec)) files.push(spec);
11225
11589
  }
@@ -11267,7 +11631,7 @@ async function writeMarkdownContext(changeDir, change, mode, contextHash, output
11267
11631
  ];
11268
11632
  for (const file of await handoffSourceFiles2(changeDir)) {
11269
11633
  if (!await exists5(file)) continue;
11270
- const content = await fs16.readFile(file, "utf8");
11634
+ const content = await fs19.readFile(file, "utf8");
11271
11635
  const total = lineCount(content);
11272
11636
  lines.push(
11273
11637
  `## ${file}`,
@@ -11292,7 +11656,7 @@ async function writeMarkdownContext(changeDir, change, mode, contextHash, output
11292
11656
  }
11293
11657
  lines.push("");
11294
11658
  }
11295
- await fs16.writeFile(output, lines.join("\n"));
11659
+ await fs19.writeFile(output, lines.join("\n"));
11296
11660
  }
11297
11661
  async function writeJsonContext(changeDir, change, mode, contextHash, output) {
11298
11662
  const entries = [];
@@ -11315,7 +11679,7 @@ async function writeJsonContext(changeDir, change, mode, contextHash, output) {
11315
11679
  "}",
11316
11680
  ""
11317
11681
  ].join("\n");
11318
- await fs16.writeFile(output, document);
11682
+ await fs19.writeFile(output, document);
11319
11683
  }
11320
11684
  async function writeSpecProjectionForFile(file, content) {
11321
11685
  return [
@@ -11355,11 +11719,11 @@ async function writeSpecMarkdownContext(changeDir, change, contextHash, output)
11355
11719
  const specs = `${changeDir}/specs`;
11356
11720
  let projected = false;
11357
11721
  if (await exists5(specs)) {
11358
- for (const entry2 of (await fs16.readdir(specs)).sort()) {
11722
+ for (const entry2 of (await fs19.readdir(specs)).sort()) {
11359
11723
  const spec = `${specs}/${entry2}/spec.md`;
11360
11724
  if (!await exists5(spec)) continue;
11361
11725
  projected = true;
11362
- lines.push(...await writeSpecProjectionForFile(spec, await fs16.readFile(spec, "utf8")));
11726
+ lines.push(...await writeSpecProjectionForFile(spec, await fs19.readFile(spec, "utf8")));
11363
11727
  }
11364
11728
  }
11365
11729
  if (!projected) {
@@ -11368,7 +11732,7 @@ async function writeSpecMarkdownContext(changeDir, change, contextHash, output)
11368
11732
  lines.push(
11369
11733
  "Full source files remain canonical. If a required heading or scenario is missing here, regenerate the handoff or read the source spec directly. Supporting files (proposal, design, tasks) are referenced by hash only."
11370
11734
  );
11371
- await fs16.writeFile(output, lines.join("\n"));
11735
+ await fs19.writeFile(output, lines.join("\n"));
11372
11736
  }
11373
11737
  async function writeSpecJsonContext(changeDir, change, contextHash, output) {
11374
11738
  const entries = [];
@@ -11377,7 +11741,7 @@ async function writeSpecJsonContext(changeDir, change, contextHash, output) {
11377
11741
  const role = /\/specs\/[^/]+\/spec\.md$/u.test(file) ? "spec" : "supporting";
11378
11742
  entries.push({ path: file, sha256: hashFile2(file), role });
11379
11743
  }
11380
- await fs16.writeFile(
11744
+ await fs19.writeFile(
11381
11745
  output,
11382
11746
  `${JSON.stringify(
11383
11747
  {
@@ -11396,8 +11760,8 @@ async function writeSpecJsonContext(changeDir, change, contextHash, output) {
11396
11760
  );
11397
11761
  }
11398
11762
  async function readField2(changeDir, field2) {
11399
- const file = path17.join(changeDir, ".comet.yaml");
11400
- const document = (0, import_yaml6.parseDocument)(await fs16.readFile(file, "utf8"), { uniqueKeys: false });
11763
+ const file = path20.join(changeDir, ".comet.yaml");
11764
+ const document = (0, import_yaml7.parseDocument)(await fs19.readFile(file, "utf8"), { uniqueKeys: false });
11401
11765
  if (document.errors.length > 0) {
11402
11766
  throw new HandoffFailure(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
11403
11767
  }
@@ -11431,7 +11795,7 @@ async function completedHandoffIsCurrent(changeDir, run, contextHash, contextJso
11431
11795
  readCheckpoint(changeDir, run.checkpointRef)
11432
11796
  ]);
11433
11797
  if (!await exists5(contextJson) || !await exists5(contextMd)) return false;
11434
- if (context !== await fs16.readFile(contextMd, "utf8")) return false;
11798
+ if (context !== await fs19.readFile(contextMd, "utf8")) return false;
11435
11799
  if (artifacts.handoff_context !== contextJson || artifacts.handoff_markdown !== contextMd) {
11436
11800
  return false;
11437
11801
  }
@@ -11554,7 +11918,7 @@ var classicHandoffCommand = async (args) => {
11554
11918
  run: pendingRun,
11555
11919
  unknownKeys: (await readClassicState(changeDir)).unknownKeys
11556
11920
  });
11557
- await fs16.mkdir(handoffDir, { recursive: true });
11921
+ await fs19.mkdir(handoffDir, { recursive: true });
11558
11922
  if (handoffMode === "beta") {
11559
11923
  await writeSpecMarkdownContext(changeDir, change, contextHash, contextMd);
11560
11924
  await writeSpecJsonContext(changeDir, change, contextHash, contextJson);
@@ -11562,7 +11926,7 @@ var classicHandoffCommand = async (args) => {
11562
11926
  await writeMarkdownContext(changeDir, change, handoffMode, contextHash, contextMd);
11563
11927
  await writeJsonContext(changeDir, change, handoffMode, contextHash, contextJson);
11564
11928
  }
11565
- const context = await fs16.readFile(contextMd, "utf8");
11929
+ const context = await fs19.readFile(contextMd, "utf8");
11566
11930
  await writeContext(changeDir, pendingRun.contextRef, context);
11567
11931
  const artifacts = {
11568
11932
  ...await readArtifacts(changeDir, pendingRun.artifactsRef),
@@ -11619,140 +11983,8 @@ var classicHandoffCommand = async (args) => {
11619
11983
  };
11620
11984
 
11621
11985
  // domains/comet-classic/classic-hook-guard.ts
11622
- import { existsSync as existsSync2, promises as fs18, readFileSync as readFileSync3 } from "fs";
11623
- import path19 from "path";
11624
-
11625
- // domains/comet-classic/classic-current-change.ts
11626
- import { execFileSync } from "child_process";
11627
- import { randomUUID as randomUUID6 } from "crypto";
11628
- import { promises as fs17 } from "fs";
11629
- import path18 from "path";
11630
- function currentChangeFile(projectRoot2) {
11631
- return path18.join(projectRoot2, ".comet", "current-change.json");
11632
- }
11633
- function currentBranch(projectRoot2) {
11634
- try {
11635
- const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
11636
- cwd: projectRoot2,
11637
- encoding: "utf8",
11638
- stdio: ["ignore", "pipe", "ignore"]
11639
- }).trim();
11640
- return branch && branch !== "HEAD" ? branch : null;
11641
- } catch {
11642
- return null;
11643
- }
11644
- }
11645
- function changeDirectory(projectRoot2, changeName) {
11646
- return path18.join(projectRoot2, "openspec", "changes", changeName);
11647
- }
11648
- async function validateActiveChange(projectRoot2, changeName) {
11649
- assertOpenSpecChangeName(changeName);
11650
- const changeDir = changeDirectory(projectRoot2, changeName);
11651
- try {
11652
- await fs17.access(path18.join(changeDir, ".comet.yaml"));
11653
- } catch (error) {
11654
- if (error.code === "ENOENT") {
11655
- throw new Error(
11656
- `Cannot select current change '${changeName}': active change state not found`,
11657
- {
11658
- cause: error
11659
- }
11660
- );
11661
- }
11662
- throw error;
11663
- }
11664
- const projection = await readClassicState(changeDir, { migrate: false });
11665
- if (!projection.classic) {
11666
- throw new Error(`Cannot select current change '${changeName}': Classic state is incomplete`);
11667
- }
11668
- if (projection.classic.archived) {
11669
- throw new Error(`Cannot select current change '${changeName}': change is archived`);
11670
- }
11671
- }
11672
- function parseSelection(source) {
11673
- let value;
11674
- try {
11675
- value = JSON.parse(source);
11676
- } catch (error) {
11677
- throw new Error(
11678
- `current change selection contains invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
11679
- { cause: error }
11680
- );
11681
- }
11682
- if (!value || typeof value !== "object" || Array.isArray(value)) {
11683
- throw new Error("current change selection must be a JSON object");
11684
- }
11685
- const record = value;
11686
- if (record.version !== 1) {
11687
- throw new Error("current change selection version must be 1");
11688
- }
11689
- if (typeof record.change !== "string") {
11690
- throw new Error("current change selection change must be a string");
11691
- }
11692
- assertOpenSpecChangeName(record.change);
11693
- if (record.branch !== null && typeof record.branch !== "string") {
11694
- throw new Error("current change selection branch must be a string or null");
11695
- }
11696
- return {
11697
- version: 1,
11698
- change: record.change,
11699
- branch: record.branch
11700
- };
11701
- }
11702
- async function selectCurrentChange(projectRoot2, changeName) {
11703
- await validateActiveChange(projectRoot2, changeName);
11704
- const selection = {
11705
- version: 1,
11706
- change: changeName,
11707
- branch: currentBranch(projectRoot2)
11708
- };
11709
- const file = currentChangeFile(projectRoot2);
11710
- const temporary = `${file}.${randomUUID6()}.tmp`;
11711
- await fs17.mkdir(path18.dirname(file), { recursive: true });
11712
- try {
11713
- await fs17.writeFile(temporary, JSON.stringify(selection, null, 2) + "\n", "utf8");
11714
- await fs17.rename(temporary, file);
11715
- } catch (error) {
11716
- await fs17.rm(temporary, { force: true });
11717
- throw error;
11718
- }
11719
- return selection;
11720
- }
11721
- async function resolveCurrentChange(projectRoot2) {
11722
- let source;
11723
- try {
11724
- source = await fs17.readFile(currentChangeFile(projectRoot2), "utf8");
11725
- } catch (error) {
11726
- if (error.code === "ENOENT") return { status: "missing" };
11727
- return {
11728
- status: "stale",
11729
- reason: `cannot read current change selection: ${error instanceof Error ? error.message : String(error)}`
11730
- };
11731
- }
11732
- let selection;
11733
- try {
11734
- selection = parseSelection(source);
11735
- await validateActiveChange(projectRoot2, selection.change);
11736
- } catch (error) {
11737
- return {
11738
- status: "stale",
11739
- reason: error instanceof Error ? error.message : String(error)
11740
- };
11741
- }
11742
- const branch = currentBranch(projectRoot2);
11743
- if (selection.branch !== null && branch !== selection.branch) {
11744
- return {
11745
- status: "stale",
11746
- reason: `current change '${selection.change}' was selected on branch '${selection.branch}', current branch is '${branch ?? "detached HEAD"}'`
11747
- };
11748
- }
11749
- return { status: "selected", selection };
11750
- }
11751
- async function clearCurrentChange(projectRoot2) {
11752
- await fs17.rm(currentChangeFile(projectRoot2), { force: true });
11753
- }
11754
-
11755
- // domains/comet-classic/classic-hook-guard.ts
11986
+ import { existsSync as existsSync2, promises as fs20, readFileSync as readFileSync3 } from "fs";
11987
+ import path21 from "path";
11756
11988
  function result(exitCode, message) {
11757
11989
  return { exitCode, stderr: message + "\n" };
11758
11990
  }
@@ -11781,52 +12013,52 @@ function comparisonKey(value) {
11781
12013
  function parseProjectRoot(args) {
11782
12014
  const index = args.indexOf("--project-root");
11783
12015
  const value = index >= 0 ? args[index + 1] : void 0;
11784
- return path19.resolve(value && !value.startsWith("--") ? value : process.cwd());
12016
+ return path21.resolve(value && !value.startsWith("--") ? value : process.cwd());
11785
12017
  }
11786
12018
  function relativeToProjectRoot(target, projectRoot2) {
11787
- const relative = normalized(path19.relative(projectRoot2, target));
12019
+ const relative = normalized(path21.relative(projectRoot2, target));
11788
12020
  if (relative === "") return "";
11789
- if (relative.startsWith("../") || relative === ".." || path19.isAbsolute(relative)) return null;
12021
+ if (relative.startsWith("../") || relative === ".." || path21.isAbsolute(relative)) return null;
11790
12022
  return relative;
11791
12023
  }
11792
12024
  async function physicalPathForPossiblyMissingTarget(target) {
11793
- const resolved = path19.resolve(target);
11794
- const root = path19.parse(resolved).root;
12025
+ const resolved = path21.resolve(target);
12026
+ const root = path21.parse(resolved).root;
11795
12027
  const missingSegments = [];
11796
12028
  let cursor = resolved;
11797
12029
  while (cursor && cursor !== root) {
11798
12030
  try {
11799
- const physicalBase = await fs18.realpath(cursor);
11800
- return path19.join(physicalBase, ...missingSegments.reverse());
12031
+ const physicalBase = await fs20.realpath(cursor);
12032
+ return path21.join(physicalBase, ...missingSegments.reverse());
11801
12033
  } catch (error) {
11802
12034
  const code = error.code;
11803
12035
  if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
11804
- missingSegments.push(path19.basename(cursor));
11805
- cursor = path19.dirname(cursor);
12036
+ missingSegments.push(path21.basename(cursor));
12037
+ cursor = path21.dirname(cursor);
11806
12038
  }
11807
12039
  }
11808
12040
  try {
11809
- const physicalRoot = await fs18.realpath(root);
11810
- return path19.join(physicalRoot, ...missingSegments.reverse());
12041
+ const physicalRoot = await fs20.realpath(root);
12042
+ return path21.join(physicalRoot, ...missingSegments.reverse());
11811
12043
  } catch {
11812
12044
  return null;
11813
12045
  }
11814
12046
  }
11815
12047
  async function projectRelative(target, projectRoot2) {
11816
- const rawCandidate = path19.isAbsolute(target) ? target : path19.resolve(process.cwd(), target);
12048
+ const rawCandidate = path21.isAbsolute(target) ? target : path21.resolve(process.cwd(), target);
11817
12049
  let candidate = normalized(rawCandidate);
11818
12050
  const rootRelative = relativeToProjectRoot(rawCandidate, projectRoot2);
11819
12051
  if (rootRelative !== null) return rootRelative;
11820
12052
  try {
11821
12053
  const physicalCandidate = await physicalPathForPossiblyMissingTarget(rawCandidate);
11822
- const physicalRoot = await fs18.realpath(projectRoot2);
12054
+ const physicalRoot = await fs20.realpath(projectRoot2);
11823
12055
  if (physicalCandidate) {
11824
12056
  const physicalRootRelative = relativeToProjectRoot(physicalCandidate, physicalRoot);
11825
12057
  if (physicalRootRelative !== null) return physicalRootRelative;
11826
12058
  candidate = normalized(physicalCandidate);
11827
12059
  }
11828
12060
  } catch {
11829
- if (!path19.isAbsolute(target)) return normalized(target).replace(/^\.\//u, "");
12061
+ if (!path21.isAbsolute(target)) return normalized(target).replace(/^\.\//u, "");
11830
12062
  }
11831
12063
  return candidate.replace(/^\.\//u, "");
11832
12064
  }
@@ -11856,15 +12088,15 @@ async function loadGoverningChange(changeDir) {
11856
12088
  }
11857
12089
  }
11858
12090
  async function activeChanges(projectRoot2) {
11859
- const changesDir = path19.join(projectRoot2, "openspec", "changes");
12091
+ const changesDir = path21.join(projectRoot2, "openspec", "changes");
11860
12092
  const governingChanges = [];
11861
12093
  if (!existsSync2(changesDir)) return governingChanges;
11862
- for (const entry2 of (await fs18.readdir(changesDir, { withFileTypes: true })).sort(
12094
+ for (const entry2 of (await fs20.readdir(changesDir, { withFileTypes: true })).sort(
11863
12095
  (left, right) => left.name.localeCompare(right.name)
11864
12096
  )) {
11865
12097
  if (!entry2.isDirectory() || entry2.name === "archive") continue;
11866
- const changeDir = path19.join(changesDir, entry2.name);
11867
- if (!existsSync2(path19.join(changeDir, ".comet.yaml"))) continue;
12098
+ const changeDir = path21.join(changesDir, entry2.name);
12099
+ if (!existsSync2(path21.join(changeDir, ".comet.yaml"))) continue;
11868
12100
  const governing = await loadGoverningChange(changeDir);
11869
12101
  if (!governing || governing.archived) continue;
11870
12102
  governingChanges.push(governing);
@@ -11912,7 +12144,7 @@ function allowsSuperpowersArtifacts(governing) {
11912
12144
  return governing.phase === "design" || governing.phase === "build" || governing.phase === "verify";
11913
12145
  }
11914
12146
  function governingChangeName(governing) {
11915
- return governing.changeDir ? path19.basename(governing.changeDir) : null;
12147
+ return governing.changeDir ? path21.basename(governing.changeDir) : null;
11916
12148
  }
11917
12149
  var SUPERPOWERS_ARTIFACT_SUFFIXES = /* @__PURE__ */ new Set([
11918
12150
  "design",
@@ -11959,9 +12191,20 @@ async function superpowersArtifactGoverningChange(relativePath2, projectRoot2) {
11959
12191
  if (named) return { governing: named, match: "named" };
11960
12192
  return null;
11961
12193
  }
11962
- async function repoSourceGoverningChange(projectRoot2, relativePath2) {
12194
+ async function repoSourceGoverningChange(projectRoot2, relativePath2, selectedChangeName) {
11963
12195
  const active = await activeChanges(projectRoot2);
11964
12196
  if (active.length === 0) return null;
12197
+ if (selectedChangeName) {
12198
+ const selected = active.find(
12199
+ (governing) => governingChangeName(governing) === selectedChangeName
12200
+ );
12201
+ return selected ?? {
12202
+ blockedResult: blockedStaleSelection(
12203
+ relativePath2,
12204
+ `selected change '${selectedChangeName}' is no longer active`
12205
+ )
12206
+ };
12207
+ }
11965
12208
  const current = await resolveCurrentChange(projectRoot2);
11966
12209
  if (current.status === "stale") {
11967
12210
  return { blockedResult: blockedStaleSelection(relativePath2, current.reason) };
@@ -11978,7 +12221,30 @@ async function repoSourceGoverningChange(projectRoot2, relativePath2) {
11978
12221
  )
11979
12222
  };
11980
12223
  }
11981
- if (active.length === 1) return active[0];
12224
+ if (active.length === 1) {
12225
+ const sole = active[0];
12226
+ if (sole.changeDir !== null) {
12227
+ const outcome = await resolveBranchBinding(sole.changeDir, {
12228
+ heal: false,
12229
+ cwd: projectRoot2
12230
+ });
12231
+ const name = governingChangeName(sole) ?? "unknown";
12232
+ if (outcome.status === "drift") {
12233
+ return {
12234
+ blockedResult: blockedStaleSelection(
12235
+ relativePath2,
12236
+ driftStaleReason(name, outcome.boundBranch, outcome.currentBranch)
12237
+ )
12238
+ };
12239
+ }
12240
+ if (outcome.status === "unbound-detached") {
12241
+ return {
12242
+ blockedResult: blockedStaleSelection(relativePath2, unboundDetachedMessage(name))
12243
+ };
12244
+ }
12245
+ }
12246
+ return sole;
12247
+ }
11982
12248
  return {
11983
12249
  blockedResult: blockedMultipleChanges(
11984
12250
  relativePath2,
@@ -11986,14 +12252,14 @@ async function repoSourceGoverningChange(projectRoot2, relativePath2) {
11986
12252
  )
11987
12253
  };
11988
12254
  }
11989
- async function governingChange(relativePath2, projectRoot2) {
12255
+ async function governingChange(relativePath2, projectRoot2, selectedChangeName) {
11990
12256
  const prefix = "openspec/changes/";
11991
12257
  if (relativePath2.startsWith(prefix)) {
11992
12258
  const rest = relativePath2.slice(prefix.length);
11993
12259
  const [name] = rest.split("/");
11994
12260
  if (name && name !== "archive") {
11995
- const changeDir = path19.join(projectRoot2, "openspec", "changes", name);
11996
- const stateFile2 = path19.join(changeDir, ".comet.yaml");
12261
+ const changeDir = path21.join(projectRoot2, "openspec", "changes", name);
12262
+ const stateFile2 = path21.join(changeDir, ".comet.yaml");
11997
12263
  if (existsSync2(stateFile2)) {
11998
12264
  const governing = await loadGoverningChange(changeDir);
11999
12265
  if (governing) return governing;
@@ -12016,7 +12282,11 @@ async function governingChange(relativePath2, projectRoot2) {
12016
12282
  } : { ...superpowers.governing, superpowersArtifact: "matched" };
12017
12283
  }
12018
12284
  if (slot) {
12019
- const candidate = await repoSourceGoverningChange(projectRoot2, relativePath2);
12285
+ const candidate = await repoSourceGoverningChange(
12286
+ projectRoot2,
12287
+ relativePath2,
12288
+ selectedChangeName
12289
+ );
12020
12290
  if (!candidate || "blockedResult" in candidate) return candidate;
12021
12291
  return {
12022
12292
  ...candidate,
@@ -12024,10 +12294,11 @@ async function governingChange(relativePath2, projectRoot2) {
12024
12294
  superpowersSlot: slot
12025
12295
  };
12026
12296
  }
12027
- const fallback = (await activeChanges(projectRoot2))[0] ?? null;
12297
+ const active = await activeChanges(projectRoot2);
12298
+ const fallback = selectedChangeName ? active.find((candidate) => governingChangeName(candidate) === selectedChangeName) ?? null : active[0] ?? null;
12028
12299
  return fallback ? { ...fallback, superpowersArtifact: "unmatched" } : null;
12029
12300
  }
12030
- return repoSourceGoverningChange(projectRoot2, relativePath2);
12301
+ return repoSourceGoverningChange(projectRoot2, relativePath2, selectedChangeName);
12031
12302
  }
12032
12303
  function isRootMarkdown(relativePath2) {
12033
12304
  return !relativePath2.includes("/") && relativePath2.endsWith(".md");
@@ -12183,10 +12454,7 @@ function blockedStaleSelection(relativePath2, reason) {
12183
12454
  ].join("\n")
12184
12455
  );
12185
12456
  }
12186
- var classicHookGuardCommand = async (args) => {
12187
- const projectRoot2 = parseProjectRoot(args);
12188
- const target = inputTarget();
12189
- if (!target) return allowed("no file path in tool input");
12457
+ async function inspectClassicHookTarget(projectRoot2, target, selectedChangeName) {
12190
12458
  const relativePath2 = await projectRelative(target, projectRoot2);
12191
12459
  if (isCometConfig(relativePath2)) {
12192
12460
  return allowed(`${relativePath2} (whitelist: comet config)`);
@@ -12202,7 +12470,7 @@ var classicHookGuardCommand = async (args) => {
12202
12470
  }
12203
12471
  let governing;
12204
12472
  try {
12205
- governing = await governingChange(relativePath2, projectRoot2);
12473
+ governing = await governingChange(relativePath2, projectRoot2, selectedChangeName);
12206
12474
  } catch (error) {
12207
12475
  return result(
12208
12476
  2,
@@ -12230,6 +12498,12 @@ var classicHookGuardCommand = async (args) => {
12230
12498
  return allowed(`${relativePath2} (phase: ${phase})`);
12231
12499
  }
12232
12500
  return blocked(relativePath2, phase);
12501
+ }
12502
+ var classicHookGuardCommand = async (args) => {
12503
+ const projectRoot2 = parseProjectRoot(args);
12504
+ const target = inputTarget();
12505
+ if (!target) return allowed("no file path in tool input");
12506
+ return inspectClassicHookTarget(projectRoot2, target);
12233
12507
  };
12234
12508
 
12235
12509
  // domains/comet-classic/classic-intent.ts
@@ -12285,7 +12559,7 @@ ${issues.map((issue) => `- ${issue}`).join("\n")}`);
12285
12559
  }
12286
12560
  issues;
12287
12561
  };
12288
- function isRecord(value) {
12562
+ function isRecord2(value) {
12289
12563
  return typeof value === "object" && value !== null && !Array.isArray(value);
12290
12564
  }
12291
12565
  function enumValue2(value, allowed2, field2, issues) {
@@ -12338,15 +12612,15 @@ function nonNegativeIntegerValue(value, field2, issues) {
12338
12612
  }
12339
12613
  function validateFrame(input) {
12340
12614
  const issues = [];
12341
- if (!isRecord(input)) throw new CometIntentValidationError(["frame must be an object"]);
12342
- const intent = isRecord(input.intent) ? input.intent : {};
12343
- if (!isRecord(input.intent)) issues.push("intent must be an object");
12344
- const slots = isRecord(input.slots) ? input.slots : {};
12345
- if (!isRecord(input.slots)) issues.push("slots must be an object");
12346
- const context = isRecord(input.context) ? input.context : {};
12347
- if (!isRecord(input.context)) issues.push("context must be an object");
12348
- const proposedRouteInput = isRecord(input.proposed_route) ? input.proposed_route : {};
12349
- if (!isRecord(input.proposed_route)) issues.push("proposed_route must be an object");
12615
+ if (!isRecord2(input)) throw new CometIntentValidationError(["frame must be an object"]);
12616
+ const intent = isRecord2(input.intent) ? input.intent : {};
12617
+ if (!isRecord2(input.intent)) issues.push("intent must be an object");
12618
+ const slots = isRecord2(input.slots) ? input.slots : {};
12619
+ if (!isRecord2(input.slots)) issues.push("slots must be an object");
12620
+ const context = isRecord2(input.context) ? input.context : {};
12621
+ if (!isRecord2(input.context)) issues.push("context must be an object");
12622
+ const proposedRouteInput = isRecord2(input.proposed_route) ? input.proposed_route : {};
12623
+ if (!isRecord2(input.proposed_route)) issues.push("proposed_route must be an object");
12350
12624
  const entities = input.entities === void 0 ? [] : Array.isArray(input.entities) ? input.entities : [];
12351
12625
  if (input.entities !== void 0 && !Array.isArray(input.entities)) {
12352
12626
  issues.push("entities must be an array");
@@ -12367,8 +12641,8 @@ function validateFrame(input) {
12367
12641
  confidence: confidenceValue(intent.confidence, "intent.confidence", issues)
12368
12642
  },
12369
12643
  entities: entities.map((entity, index) => {
12370
- const record = isRecord(entity) ? entity : {};
12371
- if (!isRecord(entity)) issues.push(`entities[${index}] must be an object`);
12644
+ const record = isRecord2(entity) ? entity : {};
12645
+ if (!isRecord2(entity)) issues.push(`entities[${index}] must be an object`);
12372
12646
  return {
12373
12647
  type: enumValue2(record.type, ENTITY_TYPES, `entities[${index}].type`, issues) ?? "risk_signal",
12374
12648
  value: stringValue(record.value, `entities[${index}].value`, issues),
@@ -12416,7 +12690,7 @@ function validateFrame(input) {
12416
12690
  "context.active_changes_count",
12417
12691
  issues
12418
12692
  ),
12419
- active_change_names: isRecord(context) ? (() => {
12693
+ active_change_names: isRecord2(context) ? (() => {
12420
12694
  if (!Array.isArray(context.active_change_names)) {
12421
12695
  issues.push("context.active_change_names must be an array");
12422
12696
  return [];
@@ -12434,8 +12708,8 @@ function validateFrame(input) {
12434
12708
  )
12435
12709
  },
12436
12710
  evidence: evidence.map((item, index) => {
12437
- const record = isRecord(item) ? item : {};
12438
- if (!isRecord(item)) issues.push(`evidence[${index}] must be an object`);
12711
+ const record = isRecord2(item) ? item : {};
12712
+ if (!isRecord2(item)) issues.push(`evidence[${index}] must be an object`);
12439
12713
  return {
12440
12714
  field: stringValue(record.field, `evidence[${index}].field`, issues),
12441
12715
  quote: stringValue(record.quote, `evidence[${index}].quote`, issues),
@@ -12601,15 +12875,15 @@ var classicIntentCommand = async (args, _options) => {
12601
12875
  };
12602
12876
 
12603
12877
  // domains/comet-classic/classic-resume-probe.ts
12604
- import path20 from "path";
12605
- import { promises as fs19 } from "fs";
12878
+ import path22 from "path";
12879
+ import { promises as fs21 } from "fs";
12606
12880
  import { spawn } from "child_process";
12607
12881
  var COMET_RESUME_PROBE_SCHEMA_VERSION = "comet.resume_probe.v1";
12608
- function isRecord2(value) {
12882
+ function isRecord3(value) {
12609
12883
  return typeof value === "object" && value !== null && !Array.isArray(value);
12610
12884
  }
12611
12885
  function normalizeInput(input) {
12612
- if (!isRecord2(input)) {
12886
+ if (!isRecord3(input)) {
12613
12887
  throw new Error("Invalid CometResumeProbeInput: input must be an object");
12614
12888
  }
12615
12889
  if (input.schema_version !== COMET_RESUME_PROBE_SCHEMA_VERSION) {
@@ -12620,7 +12894,7 @@ function normalizeInput(input) {
12620
12894
  if (typeof input.utterance !== "string") {
12621
12895
  throw new Error("Invalid CometResumeProbeInput: utterance must be a string");
12622
12896
  }
12623
- const context = isRecord2(input.agent_context) ? input.agent_context : {};
12897
+ const context = isRecord3(input.agent_context) ? input.agent_context : {};
12624
12898
  return {
12625
12899
  schema_version: COMET_RESUME_PROBE_SCHEMA_VERSION,
12626
12900
  utterance: input.utterance,
@@ -12645,13 +12919,13 @@ function result3(action, change, confidence, reason, evidence = []) {
12645
12919
  }
12646
12920
  async function readIfExists(filePath) {
12647
12921
  if (!await fileExists3(filePath)) return "";
12648
- return fs19.readFile(filePath, "utf8");
12922
+ return fs21.readFile(filePath, "utf8");
12649
12923
  }
12650
12924
  async function changeSearchText(changeDir, classic) {
12651
12925
  const files = ["proposal.md", "design.md", "tasks.md"];
12652
12926
  const parts = [classic.name, classic.workflow, classic.phase];
12653
12927
  for (const file of files) {
12654
- parts.push(await readIfExists(path20.join(changeDir, file)));
12928
+ parts.push(await readIfExists(path22.join(changeDir, file)));
12655
12929
  }
12656
12930
  return parts.join("\n").toLowerCase();
12657
12931
  }
@@ -12715,19 +12989,19 @@ function diagnosticFromProjection(changeDir, name, projection) {
12715
12989
  };
12716
12990
  }
12717
12991
  async function hasOpenSpecChangeFiles(changeDir) {
12718
- return await fileExists3(path20.join(changeDir, "proposal.md")) || await fileExists3(path20.join(changeDir, "design.md")) || await fileExists3(path20.join(changeDir, "tasks.md"));
12992
+ return await fileExists3(path22.join(changeDir, "proposal.md")) || await fileExists3(path22.join(changeDir, "design.md")) || await fileExists3(path22.join(changeDir, "tasks.md"));
12719
12993
  }
12720
12994
  async function discoverActiveChanges(projectRoot2) {
12721
- const changesDir = path20.join(projectRoot2, "openspec", "changes");
12995
+ const changesDir = path22.join(projectRoot2, "openspec", "changes");
12722
12996
  if (!await fileExists3(changesDir)) return [];
12723
12997
  const entries = await readDir(changesDir);
12724
12998
  const changes = [];
12725
12999
  for (const entry2 of entries) {
12726
13000
  if (entry2 === "archive") continue;
12727
- const changeDir = path20.join(changesDir, entry2);
12728
- const stat = await fs19.stat(changeDir).catch(() => null);
13001
+ const changeDir = path22.join(changesDir, entry2);
13002
+ const stat = await fs21.stat(changeDir).catch(() => null);
12729
13003
  if (!stat?.isDirectory()) continue;
12730
- const hasCometState = await fileExists3(path20.join(changeDir, ".comet.yaml"));
13004
+ const hasCometState = await fileExists3(path22.join(changeDir, ".comet.yaml"));
12731
13005
  if (!hasCometState) {
12732
13006
  if (!await hasOpenSpecChangeFiles(changeDir)) continue;
12733
13007
  const missingStateChange = {
@@ -13027,11 +13301,11 @@ var classicResumeProbeCommand = async (args) => {
13027
13301
  };
13028
13302
 
13029
13303
  // domains/comet-classic/classic-state-command.ts
13030
- var import_yaml7 = __toESM(require_dist(), 1);
13304
+ var import_yaml8 = __toESM(require_dist(), 1);
13031
13305
  import { spawnSync as spawnSync3 } from "child_process";
13032
- import { randomUUID as randomUUID7 } from "crypto";
13033
- import { existsSync as existsSync3, promises as fs20 } from "fs";
13034
- import path21 from "path";
13306
+ import { randomUUID as randomUUID8 } from "crypto";
13307
+ import { existsSync as existsSync3, promises as fs22 } from "fs";
13308
+ import path23 from "path";
13035
13309
  init_state();
13036
13310
  var GREEN5 = "\x1B[32m";
13037
13311
  var RED5 = "\x1B[31m";
@@ -13046,7 +13320,8 @@ var MACHINE_OWNED_FIELDS = /* @__PURE__ */ new Set([
13046
13320
  "archive_confirmation",
13047
13321
  "verify_failures",
13048
13322
  "classic_profile",
13049
- "classic_migration"
13323
+ "classic_migration",
13324
+ "bound_branch"
13050
13325
  ]);
13051
13326
  var SETTABLE_FIELDS = new Set(
13052
13327
  CLASSIC_WIRE_KEYS.filter((field2) => !MACHINE_OWNED_FIELDS.has(field2))
@@ -13144,7 +13419,7 @@ function validateRelativePath(value, field2) {
13144
13419
  }
13145
13420
  async function exists6(file) {
13146
13421
  try {
13147
- await fs20.access(file);
13422
+ await fs22.access(file);
13148
13423
  return true;
13149
13424
  } catch (error) {
13150
13425
  if (error.code === "ENOENT") return false;
@@ -13153,7 +13428,7 @@ async function exists6(file) {
13153
13428
  }
13154
13429
  async function nonempty3(file) {
13155
13430
  try {
13156
- return (await fs20.stat(file)).size > 0;
13431
+ return (await fs22.stat(file)).size > 0;
13157
13432
  } catch (error) {
13158
13433
  if (error.code === "ENOENT") return false;
13159
13434
  throw error;
@@ -13165,27 +13440,27 @@ async function changeDirectory2(name) {
13165
13440
  async function readDocument2(file) {
13166
13441
  let source;
13167
13442
  try {
13168
- source = await fs20.readFile(file, "utf8");
13443
+ source = await fs22.readFile(file, "utf8");
13169
13444
  } catch (error) {
13170
13445
  if (error.code === "ENOENT") {
13171
13446
  fail2(
13172
- `ERROR: .comet.yaml not found at ${path21.relative(process.cwd(), file).replaceAll("\\", "/")}`
13447
+ `ERROR: .comet.yaml not found at ${path23.relative(process.cwd(), file).replaceAll("\\", "/")}`
13173
13448
  );
13174
13449
  }
13175
13450
  throw error;
13176
13451
  }
13177
- const document = (0, import_yaml7.parseDocument)(source, { uniqueKeys: false });
13452
+ const document = (0, import_yaml8.parseDocument)(source, { uniqueKeys: false });
13178
13453
  if (document.errors.length > 0) fail2(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
13179
13454
  return document;
13180
13455
  }
13181
13456
  async function atomicWrite2(file, content) {
13182
- await fs20.mkdir(path21.dirname(file), { recursive: true });
13183
- const temporary = `${file}.${randomUUID7()}.tmp`;
13457
+ await fs22.mkdir(path23.dirname(file), { recursive: true });
13458
+ const temporary = `${file}.${randomUUID8()}.tmp`;
13184
13459
  try {
13185
- await fs20.writeFile(temporary, content, "utf8");
13186
- await fs20.rename(temporary, file);
13460
+ await fs22.writeFile(temporary, content, "utf8");
13461
+ await fs22.rename(temporary, file);
13187
13462
  } catch (error) {
13188
- await fs20.rm(temporary, { force: true });
13463
+ await fs22.rm(temporary, { force: true });
13189
13464
  throw error;
13190
13465
  }
13191
13466
  }
@@ -13255,6 +13530,7 @@ function sparseClassicState(record) {
13255
13530
  ["current", "branch", "worktree"],
13256
13531
  null
13257
13532
  ),
13533
+ boundBranch: nullableRecordString(record, "bound_branch"),
13258
13534
  verifyMode: enumRecordValue(record, "verify_mode", ["light", "full"], null),
13259
13535
  autoTransition: nullableRecordBoolean(record, "auto_transition"),
13260
13536
  baseRef: nullableRecordString(record, "base_ref"),
@@ -13327,7 +13603,7 @@ async function stateFile(name) {
13327
13603
  const change = await changeDirectory2(name);
13328
13604
  return {
13329
13605
  ...change,
13330
- file: path21.join(change.directory, ".comet.yaml")
13606
+ file: path23.join(change.directory, ".comet.yaml")
13331
13607
  };
13332
13608
  }
13333
13609
  async function readField3(name, field2) {
@@ -13345,7 +13621,7 @@ async function readField3(name, field2) {
13345
13621
  return scalar(value);
13346
13622
  }
13347
13623
  function parsedValue(field2, value) {
13348
- const document = (0, import_yaml7.parseDocument)(`${field2}: ${value}
13624
+ const document = (0, import_yaml8.parseDocument)(`${field2}: ${value}
13349
13625
  `);
13350
13626
  if (document.errors.length > 0) fail2(`ERROR: Invalid value: '${value}'`);
13351
13627
  return document.get(field2);
@@ -13380,7 +13656,35 @@ async function setField2(output, name, field2, value, options = {}) {
13380
13656
  validateSetValue(field2, value);
13381
13657
  const { file, directory } = await stateFile(name);
13382
13658
  const document = await readDocument2(file);
13659
+ const previousRecord = document.toJS() ?? {};
13383
13660
  document.set(field2, parsedValue(field2, value));
13661
+ if (field2 === "isolation") {
13662
+ if (requiresBranchBinding(value)) {
13663
+ const previousIsolation = typeof previousRecord.isolation === "string" ? previousRecord.isolation : null;
13664
+ const existing = previousRecord.bound_branch;
13665
+ const alreadyBound = typeof existing === "string" && existing !== "";
13666
+ if (!alreadyBound || previousIsolation !== value) {
13667
+ const currentBranch = liveGitBranch(process.cwd());
13668
+ const verdict = evaluateBranchBinding({
13669
+ isolation: value,
13670
+ boundBranch: null,
13671
+ currentBranch,
13672
+ gitWorkTree: currentBranch === null ? isGitWorkTree(process.cwd()) : true
13673
+ });
13674
+ if (verdict.status === "needs-heal") {
13675
+ document.set("bound_branch", verdict.branch);
13676
+ } else if (verdict.status === "unbound-detached") {
13677
+ fail2(
13678
+ `ERROR: cannot bind isolation=${value} while HEAD is detached; checkout a branch first`
13679
+ );
13680
+ } else {
13681
+ document.set("bound_branch", null);
13682
+ }
13683
+ }
13684
+ } else {
13685
+ document.set("bound_branch", null);
13686
+ }
13687
+ }
13384
13688
  const run = await readRunState(directory);
13385
13689
  const projection = parseClassicStateDocument(document.toJS(), run);
13386
13690
  if (projection.run) {
@@ -13430,10 +13734,10 @@ async function init(output, name, workflow) {
13430
13734
  validateEnum(workflow, PROFILES);
13431
13735
  const { file, label, directory } = await stateFile(name);
13432
13736
  if (await exists6(file)) fail2(`ERROR: .comet.yaml already exists at ${label}/.comet.yaml`);
13433
- await fs20.mkdir(directory, { recursive: true });
13737
+ await fs22.mkdir(directory, { recursive: true });
13434
13738
  const preset = workflow !== "full";
13435
13739
  const reviewMode = preset ? "off" : await reviewModeDefault();
13436
- const document = new import_yaml7.Document({
13740
+ const document = new import_yaml8.Document({
13437
13741
  workflow,
13438
13742
  language: await projectLanguageDefault(),
13439
13743
  phase: "open",
@@ -13443,7 +13747,7 @@ async function init(output, name, workflow) {
13443
13747
  subagent_dispatch: null,
13444
13748
  tdd_mode: preset ? "direct" : null,
13445
13749
  review_mode: reviewMode,
13446
- isolation: preset ? "current" : null,
13750
+ isolation: null,
13447
13751
  verify_mode: preset ? "light" : null,
13448
13752
  auto_transition: await autoTransition() === "true",
13449
13753
  base_ref: gitOutput(["rev-parse", "--verify", "HEAD"]),
@@ -13475,10 +13779,10 @@ async function requireBuildDecisions(name) {
13475
13779
  const subagentDispatch = await readField3(name, "subagent_dispatch");
13476
13780
  const tddMode = await readField3(name, "tdd_mode");
13477
13781
  const reviewMode = await readField3(name, "review_mode");
13478
- const allowedIsolation = workflow === "full" ? ["branch", "worktree"] : ["current", "branch", "worktree"];
13782
+ const allowedIsolation = ["current", "branch", "worktree"];
13479
13783
  if (!allowedIsolation.includes(isolation)) {
13480
13784
  fail2(
13481
- `ERROR: Cannot transition '${name}': isolation must be ${workflow === "full" ? "branch or worktree" : "current, branch, or worktree"}, got '${isolation || "null"}'`
13785
+ `ERROR: Cannot transition '${name}': isolation must be current, branch, or worktree, got '${isolation || "null"}'`
13482
13786
  );
13483
13787
  }
13484
13788
  if (!["subagent-driven-development", "executing-plans", "direct"].includes(buildMode)) {
@@ -13511,13 +13815,13 @@ async function requireOpenArtifacts(name) {
13511
13815
  const { directory } = await stateFile(name);
13512
13816
  const workflow = await readField3(name, "workflow");
13513
13817
  for (const artifact of ["proposal.md", "tasks.md"]) {
13514
- if (!await nonempty3(path21.join(directory, artifact))) {
13818
+ if (!await nonempty3(path23.join(directory, artifact))) {
13515
13819
  fail2(
13516
13820
  `ERROR: Cannot transition '${name}': ${artifact} must exist and be non-empty before leaving open`
13517
13821
  );
13518
13822
  }
13519
13823
  }
13520
- if (workflow === "full" && !await nonempty3(path21.join(directory, "design.md"))) {
13824
+ if (workflow === "full" && !await nonempty3(path23.join(directory, "design.md"))) {
13521
13825
  fail2(
13522
13826
  `ERROR: Cannot transition '${name}': design.md must exist and be non-empty before leaving open`
13523
13827
  );
@@ -13525,14 +13829,14 @@ async function requireOpenArtifacts(name) {
13525
13829
  }
13526
13830
  async function requireDesignEvidence(name) {
13527
13831
  const designDoc = await readField3(name, "design_doc");
13528
- if (!designDoc || designDoc === "null" || !await nonempty3(path21.resolve(designDoc))) {
13832
+ if (!designDoc || designDoc === "null" || !await nonempty3(path23.resolve(designDoc))) {
13529
13833
  fail2(
13530
13834
  `ERROR: Cannot transition '${name}': design_doc must point to an existing Design Doc before leaving design`
13531
13835
  );
13532
13836
  }
13533
13837
  }
13534
13838
  async function writeSparseTransitionEffects(directory, effects) {
13535
- const file = path21.join(directory, ".comet.yaml");
13839
+ const file = path23.join(directory, ".comet.yaml");
13536
13840
  const document = await readDocument2(file);
13537
13841
  for (const effect of effects) {
13538
13842
  const field2 = wireField2(effect.field);
@@ -13547,7 +13851,7 @@ async function applyTransitionEvent(output, name, event) {
13547
13851
  let sparse = false;
13548
13852
  if (!classic) {
13549
13853
  if (projection.run) fail2("ERROR: Classic state projection is missing");
13550
- const document = await readDocument2(path21.join(directory, ".comet.yaml"));
13854
+ const document = await readDocument2(path23.join(directory, ".comet.yaml"));
13551
13855
  classic = sparseClassicState(document.toJS());
13552
13856
  sparse = true;
13553
13857
  }
@@ -13594,7 +13898,7 @@ async function transition(output, name, event) {
13594
13898
  } else if (event === "verify-pass") {
13595
13899
  await requirePhase(name, "verify");
13596
13900
  const report = await readField3(name, "verification_report");
13597
- if (!report || !await exists6(path21.resolve(report))) {
13901
+ if (!report || !await exists6(path23.resolve(report))) {
13598
13902
  fail2(
13599
13903
  `ERROR: Cannot transition '${name}': verification_report must point to an existing report file`
13600
13904
  );
@@ -13658,9 +13962,9 @@ async function next(output, name) {
13658
13962
  async function taskCheckoff(output, taskFile, taskText) {
13659
13963
  validateRelativePath(taskFile, "task file");
13660
13964
  if (!taskText) fail2("ERROR: Task text cannot be empty");
13661
- const file = path21.resolve(taskFile);
13965
+ const file = path23.resolve(taskFile);
13662
13966
  if (!await exists6(file)) fail2(`ERROR: Task file not found: ${taskFile}`);
13663
- const lines = (await fs20.readFile(file, "utf8")).split(/\r?\n/u);
13967
+ const lines = (await fs22.readFile(file, "utf8")).split(/\r?\n/u);
13664
13968
  const matches = lines.filter(
13665
13969
  (line) => [`- [ ] ${taskText}`, `- [x] ${taskText}`, `- [X] ${taskText}`].includes(line)
13666
13970
  );
@@ -13698,21 +14002,21 @@ async function check2(output, name, phase) {
13698
14002
  designDoc ? `design_doc=${designDoc} (expected: empty/null)` : "design_doc is empty/null"
13699
14003
  );
13700
14004
  for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
13701
- (await nonempty3(path21.join(directory, artifact)) ? pass2 : reject)(
13702
- `${artifact} ${await nonempty3(path21.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
14005
+ (await nonempty3(path23.join(directory, artifact)) ? pass2 : reject)(
14006
+ `${artifact} ${await nonempty3(path23.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
13703
14007
  );
13704
14008
  }
13705
14009
  } else if (phase === "build") {
13706
14010
  const workflow = await readField3(name, "workflow");
13707
14011
  const designDoc = await readField3(name, "design_doc");
13708
14012
  if (workflow === "full") {
13709
- (designDoc && designDoc !== "null" && await exists6(path21.resolve(designDoc)) ? pass2 : reject)(`design_doc=${designDoc} (expected: non-null and file exists)`);
14013
+ (designDoc && designDoc !== "null" && await exists6(path23.resolve(designDoc)) ? pass2 : reject)(`design_doc=${designDoc} (expected: non-null and file exists)`);
13710
14014
  } else {
13711
14015
  pass2(`workflow=${workflow} (design_doc not required)`);
13712
14016
  }
13713
14017
  for (const artifact of ["proposal.md", "tasks.md"]) {
13714
- (await nonempty3(path21.join(directory, artifact)) ? pass2 : reject)(
13715
- `${artifact} ${await nonempty3(path21.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
14018
+ (await nonempty3(path23.join(directory, artifact)) ? pass2 : reject)(
14019
+ `${artifact} ${await nonempty3(path23.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
13716
14020
  );
13717
14021
  }
13718
14022
  } else if (phase === "verify") {
@@ -13725,6 +14029,29 @@ async function check2(output, name, phase) {
13725
14029
  const archived = await readField3(name, "archived");
13726
14030
  (archived !== "true" ? pass2 : reject)(`archived=${archived} (expected: not true)`);
13727
14031
  }
14032
+ const binding = await resolveBranchBinding(directory, { heal: true, cwd: process.cwd() });
14033
+ if (binding.bindingRequired) {
14034
+ switch (binding.status) {
14035
+ case "drift":
14036
+ reject(driftBlockedMessage(name, binding.boundBranch, binding.currentBranch));
14037
+ break;
14038
+ case "unbound-detached":
14039
+ reject(unboundDetachedMessage(name));
14040
+ break;
14041
+ case "healed":
14042
+ pass2(`bound_branch lazily set to ${binding.branch}`);
14043
+ break;
14044
+ case "needs-heal":
14045
+ case "ok":
14046
+ case "not-applicable":
14047
+ pass2("bound_branch matches current branch");
14048
+ break;
14049
+ default: {
14050
+ const exhaustive = binding;
14051
+ throw new Error(`unhandled branch binding status: ${JSON.stringify(exhaustive)}`);
14052
+ }
14053
+ }
14054
+ }
13728
14055
  output.stdout.push("");
13729
14056
  if (blocked2) {
13730
14057
  output.stderr.push(red4("BLOCKED — fix failing checks before proceeding"));
@@ -13734,7 +14061,7 @@ async function check2(output, name, phase) {
13734
14061
  }
13735
14062
  function fieldStatus(field2, value, file) {
13736
14063
  if (!value || value === "null") return ` - ${field2}: PENDING`;
13737
- if (file && !existsSync3(path21.resolve(file))) {
14064
+ if (file && !existsSync3(path23.resolve(file))) {
13738
14065
  return ` - ${field2}: BROKEN (path ${value} does not exist)`;
13739
14066
  }
13740
14067
  return ` - ${field2}: DONE (${value})`;
@@ -13743,7 +14070,7 @@ async function recoverOpen(output, directory) {
13743
14070
  output.stdout.push(" Artifacts:");
13744
14071
  let complete = 0;
13745
14072
  for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
13746
- const done = await nonempty3(path21.join(directory, artifact));
14073
+ const done = await nonempty3(path23.join(directory, artifact));
13747
14074
  if (done) complete += 1;
13748
14075
  output.stdout.push(` - ${artifact}: ${done ? "DONE" : "PENDING"}`);
13749
14076
  }
@@ -13756,7 +14083,7 @@ async function recoverDesign(output, name, directory) {
13756
14083
  output.stdout.push(" Artifacts:");
13757
14084
  for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
13758
14085
  output.stdout.push(
13759
- ` - ${artifact}: ${await nonempty3(path21.join(directory, artifact)) ? "DONE" : "MISSING (unexpected in design phase)"}`
14086
+ ` - ${artifact}: ${await nonempty3(path23.join(directory, artifact)) ? "DONE" : "MISSING (unexpected in design phase)"}`
13760
14087
  );
13761
14088
  }
13762
14089
  const handoff = await readField3(name, "handoff_context");
@@ -13770,11 +14097,11 @@ async function recoverDesign(output, name, directory) {
13770
14097
  fieldStatus("design_doc", design, design),
13771
14098
  ""
13772
14099
  );
13773
- if (design && design !== "null" && await exists6(path21.resolve(design))) {
14100
+ if (design && design !== "null" && await exists6(path23.resolve(design))) {
13774
14101
  output.stdout.push(
13775
14102
  "Recovery action: Design Doc already created and linked. Run guard to transition to build."
13776
14103
  );
13777
- } else if (handoff && handoff !== "null" && await exists6(path21.resolve(handoff))) {
14104
+ } else if (handoff && handoff !== "null" && await exists6(path23.resolve(handoff))) {
13778
14105
  output.stdout.push(
13779
14106
  "Recovery action: Handoff generated but Design Doc not yet created. Resume from brainstorming confirmation (Step 1c)."
13780
14107
  );
@@ -13804,7 +14131,7 @@ async function recoverBuild(output, name, directory, workflow) {
13804
14131
  decisions.push(fieldStatus("subagent_dispatch", subagentDispatch));
13805
14132
  }
13806
14133
  output.stdout.push(...decisions, "", " Plan:", fieldStatus("plan", plan, plan), "");
13807
- const tasks = path21.join(directory, "tasks.md");
14134
+ const tasks = path23.join(directory, "tasks.md");
13808
14135
  if (!await exists6(tasks)) {
13809
14136
  output.stdout.push(
13810
14137
  " Tasks: tasks.md MISSING",
@@ -13813,14 +14140,14 @@ async function recoverBuild(output, name, directory, workflow) {
13813
14140
  );
13814
14141
  return;
13815
14142
  }
13816
- const lines = (await fs20.readFile(tasks, "utf8")).split(/\r?\n/u);
14143
+ const lines = (await fs22.readFile(tasks, "utf8")).split(/\r?\n/u);
13817
14144
  const total = lines.filter((line) => /^\s*- \[[ xX]\] /u.test(line)).length;
13818
14145
  const done = lines.filter((line) => /^\s*- \[[xX]\] /u.test(line)).length;
13819
14146
  const pending = total - done;
13820
14147
  let planTotal = 0;
13821
14148
  let planDone = 0;
13822
- if (plan && plan !== "null" && await exists6(path21.resolve(plan))) {
13823
- const planLines = (await fs20.readFile(path21.resolve(plan), "utf8")).split(/\r?\n/u);
14149
+ if (plan && plan !== "null" && await exists6(path23.resolve(plan))) {
14150
+ const planLines = (await fs22.readFile(path23.resolve(plan), "utf8")).split(/\r?\n/u);
13824
14151
  planTotal = planLines.filter((line) => /^\s*- \[[ xX]\] /u.test(line)).length;
13825
14152
  planDone = planLines.filter((line) => /^\s*- \[[xX]\] /u.test(line)).length;
13826
14153
  }
@@ -13951,19 +14278,19 @@ async function scale(output, name) {
13951
14278
  validateChangeName4(name);
13952
14279
  const { file, directory, label } = await stateFile(name);
13953
14280
  if (!await exists6(file)) fail2(`ERROR: .comet.yaml not found at ${label}/.comet.yaml`);
13954
- const tasksFile = path21.join(directory, "tasks.md");
13955
- const taskCount = await exists6(tasksFile) ? (await fs20.readFile(tasksFile, "utf8")).split(/\r?\n/u).filter((line) => /^- \[/u.test(line)).length : 0;
13956
- const specs = path21.join(directory, "specs");
14281
+ const tasksFile = path23.join(directory, "tasks.md");
14282
+ const taskCount = await exists6(tasksFile) ? (await fs22.readFile(tasksFile, "utf8")).split(/\r?\n/u).filter((line) => /^- \[/u.test(line)).length : 0;
14283
+ const specs = path23.join(directory, "specs");
13957
14284
  let deltaSpecs = 0;
13958
14285
  if (await exists6(specs)) {
13959
- for (const entry2 of await fs20.readdir(specs)) {
13960
- if (await exists6(path21.join(specs, entry2, "spec.md"))) deltaSpecs += 1;
14286
+ for (const entry2 of await fs22.readdir(specs)) {
14287
+ if (await exists6(path23.join(specs, entry2, "spec.md"))) deltaSpecs += 1;
13961
14288
  }
13962
14289
  }
13963
14290
  const plan = await readField3(name, "plan");
13964
14291
  let baseRef = "";
13965
- if (plan && plan !== "null" && await exists6(path21.resolve(plan))) {
13966
- const match = (await fs20.readFile(path21.resolve(plan), "utf8")).match(/^base-ref:\s*(.+)$/mu);
14292
+ if (plan && plan !== "null" && await exists6(path23.resolve(plan))) {
14293
+ const match = (await fs22.readFile(path23.resolve(plan), "utf8")).match(/^base-ref:\s*(.+)$/mu);
13967
14294
  baseRef = match?.[1].trim() ?? "";
13968
14295
  }
13969
14296
  if (!baseRef) baseRef = await readField3(name, "base_ref");
@@ -14043,15 +14370,42 @@ async function selectChange(output, name) {
14043
14370
  validateChangeName4(name);
14044
14371
  try {
14045
14372
  const selection = await selectCurrentChange(process.cwd(), name);
14373
+ const boundBranch = await readField3(name, "bound_branch");
14374
+ const bound = boundBranch && boundBranch !== "null" ? boundBranch : null;
14046
14375
  output.stderr.push(
14047
- green4(
14048
- `[SELECTED] current change: ${selection.change}${selection.branch ? ` (branch: ${selection.branch})` : ""}`
14049
- )
14376
+ green4(`[SELECTED] current change: ${selection.change}${bound ? ` (branch: ${bound})` : ""}`)
14050
14377
  );
14051
14378
  } catch (error) {
14052
14379
  fail2(`ERROR: ${error instanceof Error ? error.message : String(error)}`);
14053
14380
  }
14054
14381
  }
14382
+ async function rebind(output, name) {
14383
+ validateChangeName4(name);
14384
+ const { directory } = await stateFile(name);
14385
+ const boundBranch = await readField3(name, "bound_branch");
14386
+ if (!boundBranch || boundBranch === "null") {
14387
+ fail2(
14388
+ `ERROR: '${name}' is not yet bound; use 'comet state set ${name} isolation <current|branch|worktree>' to establish the first binding`
14389
+ );
14390
+ }
14391
+ const branch = liveGitBranch(process.cwd());
14392
+ if (branch === null) {
14393
+ fail2("ERROR: cannot rebind while HEAD is detached; checkout a branch first");
14394
+ }
14395
+ const before = await readClassicState(directory);
14396
+ if (!before.classic) fail2("ERROR: Classic state projection is missing");
14397
+ await healBoundBranch(directory, branch);
14398
+ const after = { ...before.classic, boundBranch: branch };
14399
+ await appendClassicStateEvent(directory, {
14400
+ change: name,
14401
+ event: "rebind",
14402
+ source: "comet-state",
14403
+ from: before.classic,
14404
+ to: after,
14405
+ effects: [{ field: "boundBranch", from: boundBranch, to: branch }]
14406
+ });
14407
+ output.stderr.push(green4(`[REBIND] bound_branch: ${boundBranch} → ${branch}`));
14408
+ }
14055
14409
  async function currentChange(output) {
14056
14410
  const resolution = await resolveCurrentChange(process.cwd());
14057
14411
  if (resolution.status === "selected") {
@@ -14105,6 +14459,9 @@ var classicStateCommand = async (args) => {
14105
14459
  } else if (subcommand === "task-checkoff") {
14106
14460
  required(rest, 2, "Usage: comet-state.mjs task-checkoff <file> <task-text>");
14107
14461
  await taskCheckoff(output, rest[0], rest[1]);
14462
+ } else if (subcommand === "rebind") {
14463
+ requiredExact(rest, 1, "Usage: comet-state.mjs rebind <change-name>");
14464
+ await rebind(output, rest[0]);
14108
14465
  } else if (subcommand === "select") {
14109
14466
  requiredExact(rest, 1, "Usage: comet-state.mjs select <change-name>");
14110
14467
  await selectChange(output, rest[0]);