codex-orchestrator 0.1.50 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +45 -389
  3. package/dist/src/index.d.ts +16 -46
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +8 -24
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/v2/acceptance-proof.d.ts +111 -0
  8. package/dist/src/v2/acceptance-proof.d.ts.map +1 -0
  9. package/dist/src/v2/acceptance-proof.js +427 -0
  10. package/dist/src/v2/acceptance-proof.js.map +1 -0
  11. package/dist/src/v2/adapters/command.d.ts.map +1 -0
  12. package/dist/src/v2/adapters/command.js.map +1 -0
  13. package/dist/src/v2/adapters/durable-atomic-file.d.ts.map +1 -0
  14. package/dist/src/v2/adapters/durable-atomic-file.js.map +1 -0
  15. package/dist/src/v2/adapters/gh-cli.d.ts.map +1 -0
  16. package/dist/src/v2/adapters/gh-cli.js.map +1 -0
  17. package/dist/src/v2/adapters/gh-issue-adapter.d.ts.map +1 -0
  18. package/dist/src/v2/adapters/gh-issue-adapter.js.map +1 -0
  19. package/dist/src/v2/adapters/gh-pull-request-adapter.d.ts.map +1 -0
  20. package/dist/src/v2/adapters/gh-pull-request-adapter.js.map +1 -0
  21. package/dist/src/v2/adapters/issues.d.ts.map +1 -0
  22. package/dist/src/v2/adapters/issues.js.map +1 -0
  23. package/dist/src/v2/adapters/mission-coordinator-lock.d.ts.map +1 -0
  24. package/dist/src/v2/adapters/mission-coordinator-lock.js.map +1 -0
  25. package/dist/src/v2/adapters/path-policy.d.ts.map +1 -0
  26. package/dist/src/v2/adapters/path-policy.js.map +1 -0
  27. package/dist/src/v2/adapters/pull-requests.d.ts.map +1 -0
  28. package/dist/src/v2/adapters/pull-requests.js.map +1 -0
  29. package/dist/src/v2/adapters/target-activity-fence.d.ts.map +1 -0
  30. package/dist/src/{runner → v2/adapters}/target-activity-fence.js +1 -1
  31. package/dist/src/v2/adapters/target-activity-fence.js.map +1 -0
  32. package/dist/src/{git → v2/adapters}/worktree.d.ts +1 -1
  33. package/dist/src/v2/adapters/worktree.d.ts.map +1 -0
  34. package/dist/src/{git → v2/adapters}/worktree.js +2 -2
  35. package/dist/src/v2/adapters/worktree.js.map +1 -0
  36. package/dist/src/v2/atomic-store.d.ts +36 -0
  37. package/dist/src/v2/atomic-store.d.ts.map +1 -0
  38. package/dist/src/v2/atomic-store.js +328 -0
  39. package/dist/src/v2/atomic-store.js.map +1 -0
  40. package/dist/src/v2/candidate-cli.d.ts +22 -0
  41. package/dist/src/v2/candidate-cli.d.ts.map +1 -0
  42. package/dist/src/v2/candidate-cli.js +161 -0
  43. package/dist/src/v2/candidate-cli.js.map +1 -0
  44. package/dist/src/v2/checked-change.d.ts +49 -0
  45. package/dist/src/v2/checked-change.d.ts.map +1 -0
  46. package/dist/src/v2/checked-change.js +139 -0
  47. package/dist/src/v2/checked-change.js.map +1 -0
  48. package/dist/src/v2/cli-contract.d.ts +8 -0
  49. package/dist/src/v2/cli-contract.d.ts.map +1 -0
  50. package/dist/src/v2/cli-contract.js +32 -0
  51. package/dist/src/v2/cli-contract.js.map +1 -0
  52. package/dist/src/v2/codex-process.d.ts +71 -0
  53. package/dist/src/v2/codex-process.d.ts.map +1 -0
  54. package/dist/src/v2/codex-process.js +404 -0
  55. package/dist/src/v2/codex-process.js.map +1 -0
  56. package/dist/src/v2/config.d.ts +45 -0
  57. package/dist/src/v2/config.d.ts.map +1 -0
  58. package/dist/src/v2/config.js +139 -0
  59. package/dist/src/v2/config.js.map +1 -0
  60. package/dist/src/v2/containment.d.ts +55 -0
  61. package/dist/src/v2/containment.d.ts.map +1 -0
  62. package/dist/src/v2/containment.js +370 -0
  63. package/dist/src/v2/containment.js.map +1 -0
  64. package/dist/src/v2/implementation-report.d.ts +18 -0
  65. package/dist/src/v2/implementation-report.d.ts.map +1 -0
  66. package/dist/src/v2/implementation-report.js +147 -0
  67. package/dist/src/v2/implementation-report.js.map +1 -0
  68. package/dist/src/v2/legacy-cutover.d.ts +52 -0
  69. package/dist/src/v2/legacy-cutover.d.ts.map +1 -0
  70. package/dist/src/v2/legacy-cutover.js +87 -0
  71. package/dist/src/v2/legacy-cutover.js.map +1 -0
  72. package/dist/src/v2/mobile-lease.d.ts +97 -0
  73. package/dist/src/v2/mobile-lease.d.ts.map +1 -0
  74. package/dist/src/v2/mobile-lease.js +253 -0
  75. package/dist/src/v2/mobile-lease.js.map +1 -0
  76. package/dist/src/v2/proof-report.d.ts +118 -0
  77. package/dist/src/v2/proof-report.d.ts.map +1 -0
  78. package/dist/src/v2/proof-report.js +703 -0
  79. package/dist/src/v2/proof-report.js.map +1 -0
  80. package/dist/src/v2/proof-store.d.ts +42 -0
  81. package/dist/src/v2/proof-store.d.ts.map +1 -0
  82. package/dist/src/v2/proof-store.js +180 -0
  83. package/dist/src/v2/proof-store.js.map +1 -0
  84. package/dist/src/v2/report-envelope.d.ts +4 -0
  85. package/dist/src/v2/report-envelope.d.ts.map +1 -0
  86. package/dist/src/v2/report-envelope.js +46 -0
  87. package/dist/src/v2/report-envelope.js.map +1 -0
  88. package/dist/src/v2/run-issue.d.ts +213 -0
  89. package/dist/src/v2/run-issue.d.ts.map +1 -0
  90. package/dist/src/v2/run-issue.js +906 -0
  91. package/dist/src/v2/run-issue.js.map +1 -0
  92. package/dist/src/v2/run-store.d.ts +136 -0
  93. package/dist/src/v2/run-store.d.ts.map +1 -0
  94. package/dist/src/v2/run-store.js +346 -0
  95. package/dist/src/v2/run-store.js.map +1 -0
  96. package/dist/src/v2/runtime-assets.d.ts +31 -0
  97. package/dist/src/v2/runtime-assets.d.ts.map +1 -0
  98. package/dist/src/v2/runtime-assets.js +473 -0
  99. package/dist/src/v2/runtime-assets.js.map +1 -0
  100. package/dist/src/v2/runtime.d.ts +137 -0
  101. package/dist/src/v2/runtime.d.ts.map +1 -0
  102. package/dist/src/v2/runtime.js +847 -0
  103. package/dist/src/v2/runtime.js.map +1 -0
  104. package/dist/src/v2/setup-cli.d.ts +5 -0
  105. package/dist/src/v2/setup-cli.d.ts.map +1 -0
  106. package/dist/src/v2/setup-cli.js +83 -0
  107. package/dist/src/v2/setup-cli.js.map +1 -0
  108. package/dist/src/v2/setup-runtime.d.ts +6 -0
  109. package/dist/src/v2/setup-runtime.d.ts.map +1 -0
  110. package/dist/src/v2/setup-runtime.js +213 -0
  111. package/dist/src/v2/setup-runtime.js.map +1 -0
  112. package/dist/src/v2/setup-store.d.ts +19 -0
  113. package/dist/src/v2/setup-store.d.ts.map +1 -0
  114. package/dist/src/v2/setup-store.js +208 -0
  115. package/dist/src/v2/setup-store.js.map +1 -0
  116. package/dist/src/v2/setup.d.ts +147 -0
  117. package/dist/src/v2/setup.d.ts.map +1 -0
  118. package/dist/src/v2/setup.js +529 -0
  119. package/dist/src/v2/setup.js.map +1 -0
  120. package/docs/deep-dive.md +54 -803
  121. package/internal-skills/acceptance-proof/SKILL.md +14 -0
  122. package/internal-skills/acceptance-proof/references/android.md +14 -0
  123. package/internal-skills/acceptance-proof/references/browser.md +13 -0
  124. package/internal-skills/acceptance-proof/references/ios.md +14 -0
  125. package/internal-skills/acceptance-proof/tools/android-lease.mjs +280 -0
  126. package/internal-skills/acceptance-proof/tools/ios-lease.mjs +288 -0
  127. package/internal-skills/agent-auto/SKILL.md +14 -0
  128. package/package.json +11 -18
  129. package/bridge-runtime.json +0 -2719
  130. package/dist/src/bridge-runtime.d.ts +0 -17
  131. package/dist/src/bridge-runtime.d.ts.map +0 -1
  132. package/dist/src/bridge-runtime.js +0 -168
  133. package/dist/src/bridge-runtime.js.map +0 -1
  134. package/dist/src/cli.d.ts +0 -3
  135. package/dist/src/cli.d.ts.map +0 -1
  136. package/dist/src/cli.js +0 -569
  137. package/dist/src/cli.js.map +0 -1
  138. package/dist/src/codex/command-adapter.d.ts +0 -47
  139. package/dist/src/codex/command-adapter.d.ts.map +0 -1
  140. package/dist/src/codex/command-adapter.js +0 -169
  141. package/dist/src/codex/command-adapter.js.map +0 -1
  142. package/dist/src/codex/mobile-device-guard.d.ts +0 -7
  143. package/dist/src/codex/mobile-device-guard.d.ts.map +0 -1
  144. package/dist/src/codex/mobile-device-guard.js +0 -63
  145. package/dist/src/codex/mobile-device-guard.js.map +0 -1
  146. package/dist/src/config/constants.d.ts +0 -6
  147. package/dist/src/config/constants.d.ts.map +0 -1
  148. package/dist/src/config/constants.js +0 -19
  149. package/dist/src/config/constants.js.map +0 -1
  150. package/dist/src/config/schema.d.ts +0 -234
  151. package/dist/src/config/schema.d.ts.map +0 -1
  152. package/dist/src/config/schema.js +0 -673
  153. package/dist/src/config/schema.js.map +0 -1
  154. package/dist/src/fs/durable-atomic-file.d.ts.map +0 -1
  155. package/dist/src/fs/durable-atomic-file.js.map +0 -1
  156. package/dist/src/git/base-branch.d.ts +0 -26
  157. package/dist/src/git/base-branch.d.ts.map +0 -1
  158. package/dist/src/git/base-branch.js +0 -45
  159. package/dist/src/git/base-branch.js.map +0 -1
  160. package/dist/src/git/worktree.d.ts.map +0 -1
  161. package/dist/src/git/worktree.js.map +0 -1
  162. package/dist/src/github/gh-cli.d.ts.map +0 -1
  163. package/dist/src/github/gh-cli.js.map +0 -1
  164. package/dist/src/github/gh-issue-adapter.d.ts.map +0 -1
  165. package/dist/src/github/gh-issue-adapter.js.map +0 -1
  166. package/dist/src/github/gh-pull-request-adapter.d.ts.map +0 -1
  167. package/dist/src/github/gh-pull-request-adapter.js.map +0 -1
  168. package/dist/src/github/issues.d.ts.map +0 -1
  169. package/dist/src/github/issues.js.map +0 -1
  170. package/dist/src/github/pull-requests.d.ts.map +0 -1
  171. package/dist/src/github/pull-requests.js.map +0 -1
  172. package/dist/src/package-info.d.ts +0 -6
  173. package/dist/src/package-info.d.ts.map +0 -1
  174. package/dist/src/package-info.js +0 -13
  175. package/dist/src/package-info.js.map +0 -1
  176. package/dist/src/path-policy.d.ts.map +0 -1
  177. package/dist/src/path-policy.js.map +0 -1
  178. package/dist/src/process/command.d.ts.map +0 -1
  179. package/dist/src/process/command.js.map +0 -1
  180. package/dist/src/review-handoff.d.ts +0 -3
  181. package/dist/src/review-handoff.d.ts.map +0 -1
  182. package/dist/src/review-handoff.js +0 -8
  183. package/dist/src/review-handoff.js.map +0 -1
  184. package/dist/src/runner/acceptance-proof-loop.d.ts +0 -97
  185. package/dist/src/runner/acceptance-proof-loop.d.ts.map +0 -1
  186. package/dist/src/runner/acceptance-proof-loop.js +0 -404
  187. package/dist/src/runner/acceptance-proof-loop.js.map +0 -1
  188. package/dist/src/runner/acceptance-proof-runner.d.ts +0 -24
  189. package/dist/src/runner/acceptance-proof-runner.d.ts.map +0 -1
  190. package/dist/src/runner/acceptance-proof-runner.js +0 -121
  191. package/dist/src/runner/acceptance-proof-runner.js.map +0 -1
  192. package/dist/src/runner/acceptance-proof.d.ts +0 -189
  193. package/dist/src/runner/acceptance-proof.d.ts.map +0 -1
  194. package/dist/src/runner/acceptance-proof.js +0 -594
  195. package/dist/src/runner/acceptance-proof.js.map +0 -1
  196. package/dist/src/runner/agent-attempt.d.ts +0 -105
  197. package/dist/src/runner/agent-attempt.d.ts.map +0 -1
  198. package/dist/src/runner/agent-attempt.js +0 -245
  199. package/dist/src/runner/agent-attempt.js.map +0 -1
  200. package/dist/src/runner/android-visual-proof-command.d.ts +0 -26
  201. package/dist/src/runner/android-visual-proof-command.d.ts.map +0 -1
  202. package/dist/src/runner/android-visual-proof-command.js +0 -592
  203. package/dist/src/runner/android-visual-proof-command.js.map +0 -1
  204. package/dist/src/runner/auto-visual-proof-command.d.ts +0 -15
  205. package/dist/src/runner/auto-visual-proof-command.d.ts.map +0 -1
  206. package/dist/src/runner/auto-visual-proof-command.js +0 -64
  207. package/dist/src/runner/auto-visual-proof-command.js.map +0 -1
  208. package/dist/src/runner/browser-proof-contract.d.ts +0 -134
  209. package/dist/src/runner/browser-proof-contract.d.ts.map +0 -1
  210. package/dist/src/runner/browser-proof-contract.js +0 -400
  211. package/dist/src/runner/browser-proof-contract.js.map +0 -1
  212. package/dist/src/runner/browser-visual-proof-command.d.ts +0 -101
  213. package/dist/src/runner/browser-visual-proof-command.d.ts.map +0 -1
  214. package/dist/src/runner/browser-visual-proof-command.js +0 -532
  215. package/dist/src/runner/browser-visual-proof-command.js.map +0 -1
  216. package/dist/src/runner/command-utils.d.ts +0 -15
  217. package/dist/src/runner/command-utils.d.ts.map +0 -1
  218. package/dist/src/runner/command-utils.js +0 -228
  219. package/dist/src/runner/command-utils.js.map +0 -1
  220. package/dist/src/runner/completion-report.d.ts +0 -121
  221. package/dist/src/runner/completion-report.d.ts.map +0 -1
  222. package/dist/src/runner/completion-report.js +0 -381
  223. package/dist/src/runner/completion-report.js.map +0 -1
  224. package/dist/src/runner/context-snapshot.d.ts +0 -33
  225. package/dist/src/runner/context-snapshot.d.ts.map +0 -1
  226. package/dist/src/runner/context-snapshot.js +0 -99
  227. package/dist/src/runner/context-snapshot.js.map +0 -1
  228. package/dist/src/runner/daemon-command.d.ts +0 -30
  229. package/dist/src/runner/daemon-command.d.ts.map +0 -1
  230. package/dist/src/runner/daemon-command.js +0 -262
  231. package/dist/src/runner/daemon-command.js.map +0 -1
  232. package/dist/src/runner/doctor-command.d.ts +0 -41
  233. package/dist/src/runner/doctor-command.d.ts.map +0 -1
  234. package/dist/src/runner/doctor-command.js +0 -177
  235. package/dist/src/runner/doctor-command.js.map +0 -1
  236. package/dist/src/runner/durable-run-summary.d.ts +0 -80
  237. package/dist/src/runner/durable-run-summary.d.ts.map +0 -1
  238. package/dist/src/runner/durable-run-summary.js +0 -200
  239. package/dist/src/runner/durable-run-summary.js.map +0 -1
  240. package/dist/src/runner/flutter-sdk-discovery.d.ts +0 -5
  241. package/dist/src/runner/flutter-sdk-discovery.d.ts.map +0 -1
  242. package/dist/src/runner/flutter-sdk-discovery.js +0 -103
  243. package/dist/src/runner/flutter-sdk-discovery.js.map +0 -1
  244. package/dist/src/runner/fresh-context-review.d.ts +0 -22
  245. package/dist/src/runner/fresh-context-review.d.ts.map +0 -1
  246. package/dist/src/runner/fresh-context-review.js +0 -177
  247. package/dist/src/runner/fresh-context-review.js.map +0 -1
  248. package/dist/src/runner/handoff-evidence.d.ts +0 -141
  249. package/dist/src/runner/handoff-evidence.d.ts.map +0 -1
  250. package/dist/src/runner/handoff-evidence.js +0 -543
  251. package/dist/src/runner/handoff-evidence.js.map +0 -1
  252. package/dist/src/runner/hygiene-cleanup.d.ts +0 -15
  253. package/dist/src/runner/hygiene-cleanup.d.ts.map +0 -1
  254. package/dist/src/runner/hygiene-cleanup.js +0 -25
  255. package/dist/src/runner/hygiene-cleanup.js.map +0 -1
  256. package/dist/src/runner/ios-visual-proof-command.d.ts +0 -25
  257. package/dist/src/runner/ios-visual-proof-command.d.ts.map +0 -1
  258. package/dist/src/runner/ios-visual-proof-command.js +0 -353
  259. package/dist/src/runner/ios-visual-proof-command.js.map +0 -1
  260. package/dist/src/runner/issue-state-machine.d.ts +0 -39
  261. package/dist/src/runner/issue-state-machine.d.ts.map +0 -1
  262. package/dist/src/runner/issue-state-machine.js +0 -124
  263. package/dist/src/runner/issue-state-machine.js.map +0 -1
  264. package/dist/src/runner/issue-tree.d.ts +0 -65
  265. package/dist/src/runner/issue-tree.d.ts.map +0 -1
  266. package/dist/src/runner/issue-tree.js +0 -474
  267. package/dist/src/runner/issue-tree.js.map +0 -1
  268. package/dist/src/runner/lifecycle-events.d.ts +0 -44
  269. package/dist/src/runner/lifecycle-events.d.ts.map +0 -1
  270. package/dist/src/runner/lifecycle-events.js +0 -108
  271. package/dist/src/runner/lifecycle-events.js.map +0 -1
  272. package/dist/src/runner/local-execution-session.d.ts +0 -112
  273. package/dist/src/runner/local-execution-session.d.ts.map +0 -1
  274. package/dist/src/runner/local-execution-session.js +0 -1064
  275. package/dist/src/runner/local-execution-session.js.map +0 -1
  276. package/dist/src/runner/local-state.d.ts +0 -44
  277. package/dist/src/runner/local-state.d.ts.map +0 -1
  278. package/dist/src/runner/local-state.js +0 -150
  279. package/dist/src/runner/local-state.js.map +0 -1
  280. package/dist/src/runner/mission-activation.d.ts +0 -29
  281. package/dist/src/runner/mission-activation.d.ts.map +0 -1
  282. package/dist/src/runner/mission-activation.js +0 -54
  283. package/dist/src/runner/mission-activation.js.map +0 -1
  284. package/dist/src/runner/mission-agent-broker.d.ts +0 -53
  285. package/dist/src/runner/mission-agent-broker.d.ts.map +0 -1
  286. package/dist/src/runner/mission-agent-broker.js +0 -182
  287. package/dist/src/runner/mission-agent-broker.js.map +0 -1
  288. package/dist/src/runner/mission-cancellation.d.ts +0 -77
  289. package/dist/src/runner/mission-cancellation.d.ts.map +0 -1
  290. package/dist/src/runner/mission-cancellation.js +0 -180
  291. package/dist/src/runner/mission-cancellation.js.map +0 -1
  292. package/dist/src/runner/mission-canonical-path.d.ts +0 -34
  293. package/dist/src/runner/mission-canonical-path.d.ts.map +0 -1
  294. package/dist/src/runner/mission-canonical-path.js +0 -121
  295. package/dist/src/runner/mission-canonical-path.js.map +0 -1
  296. package/dist/src/runner/mission-capability-kernel.d.ts +0 -34
  297. package/dist/src/runner/mission-capability-kernel.d.ts.map +0 -1
  298. package/dist/src/runner/mission-capability-kernel.js +0 -158
  299. package/dist/src/runner/mission-capability-kernel.js.map +0 -1
  300. package/dist/src/runner/mission-check-policy.d.ts +0 -17
  301. package/dist/src/runner/mission-check-policy.d.ts.map +0 -1
  302. package/dist/src/runner/mission-check-policy.js +0 -31
  303. package/dist/src/runner/mission-check-policy.js.map +0 -1
  304. package/dist/src/runner/mission-coordinator-lock.d.ts.map +0 -1
  305. package/dist/src/runner/mission-coordinator-lock.js.map +0 -1
  306. package/dist/src/runner/mission-deployment.d.ts +0 -21
  307. package/dist/src/runner/mission-deployment.d.ts.map +0 -1
  308. package/dist/src/runner/mission-deployment.js +0 -108
  309. package/dist/src/runner/mission-deployment.js.map +0 -1
  310. package/dist/src/runner/mission-evaluation.d.ts +0 -61
  311. package/dist/src/runner/mission-evaluation.d.ts.map +0 -1
  312. package/dist/src/runner/mission-evaluation.js +0 -183
  313. package/dist/src/runner/mission-evaluation.js.map +0 -1
  314. package/dist/src/runner/mission-executor-probe.d.ts +0 -10
  315. package/dist/src/runner/mission-executor-probe.d.ts.map +0 -1
  316. package/dist/src/runner/mission-executor-probe.js +0 -180
  317. package/dist/src/runner/mission-executor-probe.js.map +0 -1
  318. package/dist/src/runner/mission-git-contracts.d.ts +0 -75
  319. package/dist/src/runner/mission-git-contracts.d.ts.map +0 -1
  320. package/dist/src/runner/mission-git-contracts.js +0 -201
  321. package/dist/src/runner/mission-git-contracts.js.map +0 -1
  322. package/dist/src/runner/mission-git-runtime-owner-ref.d.ts +0 -13
  323. package/dist/src/runner/mission-git-runtime-owner-ref.d.ts.map +0 -1
  324. package/dist/src/runner/mission-git-runtime-owner-ref.js +0 -111
  325. package/dist/src/runner/mission-git-runtime-owner-ref.js.map +0 -1
  326. package/dist/src/runner/mission-git-transaction.d.ts +0 -97
  327. package/dist/src/runner/mission-git-transaction.d.ts.map +0 -1
  328. package/dist/src/runner/mission-git-transaction.js +0 -1009
  329. package/dist/src/runner/mission-git-transaction.js.map +0 -1
  330. package/dist/src/runner/mission-identifiers.d.ts +0 -31
  331. package/dist/src/runner/mission-identifiers.d.ts.map +0 -1
  332. package/dist/src/runner/mission-identifiers.js +0 -75
  333. package/dist/src/runner/mission-identifiers.js.map +0 -1
  334. package/dist/src/runner/mission-input-snapshot.d.ts +0 -21
  335. package/dist/src/runner/mission-input-snapshot.d.ts.map +0 -1
  336. package/dist/src/runner/mission-input-snapshot.js +0 -63
  337. package/dist/src/runner/mission-input-snapshot.js.map +0 -1
  338. package/dist/src/runner/mission-ownership.d.ts +0 -38
  339. package/dist/src/runner/mission-ownership.d.ts.map +0 -1
  340. package/dist/src/runner/mission-ownership.js +0 -88
  341. package/dist/src/runner/mission-ownership.js.map +0 -1
  342. package/dist/src/runner/mission-patch-audit.d.ts +0 -21
  343. package/dist/src/runner/mission-patch-audit.d.ts.map +0 -1
  344. package/dist/src/runner/mission-patch-audit.js +0 -186
  345. package/dist/src/runner/mission-patch-audit.js.map +0 -1
  346. package/dist/src/runner/mission-path-language.d.ts +0 -6
  347. package/dist/src/runner/mission-path-language.d.ts.map +0 -1
  348. package/dist/src/runner/mission-path-language.js +0 -106
  349. package/dist/src/runner/mission-path-language.js.map +0 -1
  350. package/dist/src/runner/mission-permit-authority.d.ts +0 -26
  351. package/dist/src/runner/mission-permit-authority.d.ts.map +0 -1
  352. package/dist/src/runner/mission-permit-authority.js +0 -145
  353. package/dist/src/runner/mission-permit-authority.js.map +0 -1
  354. package/dist/src/runner/mission-plan-parent-coordinator.d.ts +0 -87
  355. package/dist/src/runner/mission-plan-parent-coordinator.d.ts.map +0 -1
  356. package/dist/src/runner/mission-plan-parent-coordinator.js +0 -441
  357. package/dist/src/runner/mission-plan-parent-coordinator.js.map +0 -1
  358. package/dist/src/runner/mission-plan-parent.d.ts +0 -156
  359. package/dist/src/runner/mission-plan-parent.d.ts.map +0 -1
  360. package/dist/src/runner/mission-plan-parent.js +0 -589
  361. package/dist/src/runner/mission-plan-parent.js.map +0 -1
  362. package/dist/src/runner/mission-process-executor.d.ts +0 -25
  363. package/dist/src/runner/mission-process-executor.d.ts.map +0 -1
  364. package/dist/src/runner/mission-process-executor.js +0 -182
  365. package/dist/src/runner/mission-process-executor.js.map +0 -1
  366. package/dist/src/runner/mission-publication-git.d.ts +0 -21
  367. package/dist/src/runner/mission-publication-git.d.ts.map +0 -1
  368. package/dist/src/runner/mission-publication-git.js +0 -61
  369. package/dist/src/runner/mission-publication-git.js.map +0 -1
  370. package/dist/src/runner/mission-publication.d.ts +0 -192
  371. package/dist/src/runner/mission-publication.d.ts.map +0 -1
  372. package/dist/src/runner/mission-publication.js +0 -1001
  373. package/dist/src/runner/mission-publication.js.map +0 -1
  374. package/dist/src/runner/mission-quarantine-patch-executor.d.ts +0 -29
  375. package/dist/src/runner/mission-quarantine-patch-executor.d.ts.map +0 -1
  376. package/dist/src/runner/mission-quarantine-patch-executor.js +0 -121
  377. package/dist/src/runner/mission-quarantine-patch-executor.js.map +0 -1
  378. package/dist/src/runner/mission-repository-executor.d.ts +0 -54
  379. package/dist/src/runner/mission-repository-executor.d.ts.map +0 -1
  380. package/dist/src/runner/mission-repository-executor.js +0 -192
  381. package/dist/src/runner/mission-repository-executor.js.map +0 -1
  382. package/dist/src/runner/mission-repository-observer.d.ts +0 -8
  383. package/dist/src/runner/mission-repository-observer.d.ts.map +0 -1
  384. package/dist/src/runner/mission-repository-observer.js +0 -24
  385. package/dist/src/runner/mission-repository-observer.js.map +0 -1
  386. package/dist/src/runner/mission-reservations.d.ts +0 -15
  387. package/dist/src/runner/mission-reservations.d.ts.map +0 -1
  388. package/dist/src/runner/mission-reservations.js +0 -116
  389. package/dist/src/runner/mission-reservations.js.map +0 -1
  390. package/dist/src/runner/mission-resolution-loop.d.ts +0 -172
  391. package/dist/src/runner/mission-resolution-loop.d.ts.map +0 -1
  392. package/dist/src/runner/mission-resolution-loop.js +0 -318
  393. package/dist/src/runner/mission-resolution-loop.js.map +0 -1
  394. package/dist/src/runner/mission-runtime-owner.d.ts +0 -36
  395. package/dist/src/runner/mission-runtime-owner.d.ts.map +0 -1
  396. package/dist/src/runner/mission-runtime-owner.js +0 -174
  397. package/dist/src/runner/mission-runtime-owner.js.map +0 -1
  398. package/dist/src/runner/mission-safe-executor.d.ts +0 -96
  399. package/dist/src/runner/mission-safe-executor.d.ts.map +0 -1
  400. package/dist/src/runner/mission-safe-executor.js +0 -288
  401. package/dist/src/runner/mission-safe-executor.js.map +0 -1
  402. package/dist/src/runner/mission-sandbox.d.ts +0 -16
  403. package/dist/src/runner/mission-sandbox.d.ts.map +0 -1
  404. package/dist/src/runner/mission-sandbox.js +0 -91
  405. package/dist/src/runner/mission-sandbox.js.map +0 -1
  406. package/dist/src/runner/mission-scheduler.d.ts +0 -57
  407. package/dist/src/runner/mission-scheduler.d.ts.map +0 -1
  408. package/dist/src/runner/mission-scheduler.js +0 -205
  409. package/dist/src/runner/mission-scheduler.js.map +0 -1
  410. package/dist/src/runner/mission-scope-expansion.d.ts +0 -47
  411. package/dist/src/runner/mission-scope-expansion.d.ts.map +0 -1
  412. package/dist/src/runner/mission-scope-expansion.js +0 -147
  413. package/dist/src/runner/mission-scope-expansion.js.map +0 -1
  414. package/dist/src/runner/mission-state-machine.d.ts +0 -118
  415. package/dist/src/runner/mission-state-machine.d.ts.map +0 -1
  416. package/dist/src/runner/mission-state-machine.js +0 -316
  417. package/dist/src/runner/mission-state-machine.js.map +0 -1
  418. package/dist/src/runner/mission-state-store.d.ts +0 -70
  419. package/dist/src/runner/mission-state-store.d.ts.map +0 -1
  420. package/dist/src/runner/mission-state-store.js +0 -916
  421. package/dist/src/runner/mission-state-store.js.map +0 -1
  422. package/dist/src/runner/mobile-device-lease.d.ts +0 -11
  423. package/dist/src/runner/mobile-device-lease.d.ts.map +0 -1
  424. package/dist/src/runner/mobile-device-lease.js +0 -121
  425. package/dist/src/runner/mobile-device-lease.js.map +0 -1
  426. package/dist/src/runner/mobile-visual-proof-command.d.ts +0 -17
  427. package/dist/src/runner/mobile-visual-proof-command.d.ts.map +0 -1
  428. package/dist/src/runner/mobile-visual-proof-command.js +0 -168
  429. package/dist/src/runner/mobile-visual-proof-command.js.map +0 -1
  430. package/dist/src/runner/plan-auto-command.d.ts +0 -35
  431. package/dist/src/runner/plan-auto-command.d.ts.map +0 -1
  432. package/dist/src/runner/plan-auto-command.js +0 -918
  433. package/dist/src/runner/plan-auto-command.js.map +0 -1
  434. package/dist/src/runner/plan-auto-recovery.d.ts +0 -83
  435. package/dist/src/runner/plan-auto-recovery.d.ts.map +0 -1
  436. package/dist/src/runner/plan-auto-recovery.js +0 -303
  437. package/dist/src/runner/plan-auto-recovery.js.map +0 -1
  438. package/dist/src/runner/prompt.d.ts +0 -68
  439. package/dist/src/runner/prompt.d.ts.map +0 -1
  440. package/dist/src/runner/prompt.js +0 -202
  441. package/dist/src/runner/prompt.js.map +0 -1
  442. package/dist/src/runner/proof-routing.d.ts +0 -73
  443. package/dist/src/runner/proof-routing.d.ts.map +0 -1
  444. package/dist/src/runner/proof-routing.js +0 -182
  445. package/dist/src/runner/proof-routing.js.map +0 -1
  446. package/dist/src/runner/proof-strategy.d.ts +0 -21
  447. package/dist/src/runner/proof-strategy.d.ts.map +0 -1
  448. package/dist/src/runner/proof-strategy.js +0 -26
  449. package/dist/src/runner/proof-strategy.js.map +0 -1
  450. package/dist/src/runner/recovery.d.ts +0 -25
  451. package/dist/src/runner/recovery.d.ts.map +0 -1
  452. package/dist/src/runner/recovery.js +0 -89
  453. package/dist/src/runner/recovery.js.map +0 -1
  454. package/dist/src/runner/review-gate-policy.d.ts +0 -13
  455. package/dist/src/runner/review-gate-policy.d.ts.map +0 -1
  456. package/dist/src/runner/review-gate-policy.js +0 -241
  457. package/dist/src/runner/review-gate-policy.js.map +0 -1
  458. package/dist/src/runner/review-gates.d.ts +0 -28
  459. package/dist/src/runner/review-gates.d.ts.map +0 -1
  460. package/dist/src/runner/review-gates.js +0 -328
  461. package/dist/src/runner/review-gates.js.map +0 -1
  462. package/dist/src/runner/rework-policy.d.ts +0 -48
  463. package/dist/src/runner/rework-policy.d.ts.map +0 -1
  464. package/dist/src/runner/rework-policy.js +0 -150
  465. package/dist/src/runner/rework-policy.js.map +0 -1
  466. package/dist/src/runner/run-log.d.ts +0 -18
  467. package/dist/src/runner/run-log.d.ts.map +0 -1
  468. package/dist/src/runner/run-log.js +0 -53
  469. package/dist/src/runner/run-log.js.map +0 -1
  470. package/dist/src/runner/runner-handoff-decision.d.ts +0 -48
  471. package/dist/src/runner/runner-handoff-decision.d.ts.map +0 -1
  472. package/dist/src/runner/runner-handoff-decision.js +0 -93
  473. package/dist/src/runner/runner-handoff-decision.js.map +0 -1
  474. package/dist/src/runner/safety.d.ts +0 -14
  475. package/dist/src/runner/safety.d.ts.map +0 -1
  476. package/dist/src/runner/safety.js +0 -31
  477. package/dist/src/runner/safety.js.map +0 -1
  478. package/dist/src/runner/scope-isolation-policy.d.ts +0 -17
  479. package/dist/src/runner/scope-isolation-policy.d.ts.map +0 -1
  480. package/dist/src/runner/scope-isolation-policy.js +0 -82
  481. package/dist/src/runner/scope-isolation-policy.js.map +0 -1
  482. package/dist/src/runner/scoped-auto-command.d.ts +0 -90
  483. package/dist/src/runner/scoped-auto-command.d.ts.map +0 -1
  484. package/dist/src/runner/scoped-auto-command.js +0 -561
  485. package/dist/src/runner/scoped-auto-command.js.map +0 -1
  486. package/dist/src/runner/scoped-recovery.d.ts +0 -78
  487. package/dist/src/runner/scoped-recovery.d.ts.map +0 -1
  488. package/dist/src/runner/scoped-recovery.js +0 -601
  489. package/dist/src/runner/scoped-recovery.js.map +0 -1
  490. package/dist/src/runner/session-home.d.ts +0 -8
  491. package/dist/src/runner/session-home.d.ts.map +0 -1
  492. package/dist/src/runner/session-home.js +0 -18
  493. package/dist/src/runner/session-home.js.map +0 -1
  494. package/dist/src/runner/status-command.d.ts +0 -38
  495. package/dist/src/runner/status-command.d.ts.map +0 -1
  496. package/dist/src/runner/status-command.js +0 -97
  497. package/dist/src/runner/status-command.js.map +0 -1
  498. package/dist/src/runner/target-activity-fence.d.ts.map +0 -1
  499. package/dist/src/runner/target-activity-fence.js.map +0 -1
  500. package/dist/src/runner/terminal-outcome.d.ts +0 -58
  501. package/dist/src/runner/terminal-outcome.d.ts.map +0 -1
  502. package/dist/src/runner/terminal-outcome.js +0 -73
  503. package/dist/src/runner/terminal-outcome.js.map +0 -1
  504. package/dist/src/runner/visual-proof-runner.d.ts +0 -27
  505. package/dist/src/runner/visual-proof-runner.d.ts.map +0 -1
  506. package/dist/src/runner/visual-proof-runner.js +0 -379
  507. package/dist/src/runner/visual-proof-runner.js.map +0 -1
  508. package/dist/src/runner/worktree-cleanup.d.ts +0 -27
  509. package/dist/src/runner/worktree-cleanup.d.ts.map +0 -1
  510. package/dist/src/runner/worktree-cleanup.js +0 -63
  511. package/dist/src/runner/worktree-cleanup.js.map +0 -1
  512. package/dist/src/setup/codex-command-resolver.d.ts +0 -10
  513. package/dist/src/setup/codex-command-resolver.d.ts.map +0 -1
  514. package/dist/src/setup/codex-command-resolver.js +0 -91
  515. package/dist/src/setup/codex-command-resolver.js.map +0 -1
  516. package/dist/src/setup/github-label-adapter.d.ts +0 -13
  517. package/dist/src/setup/github-label-adapter.d.ts.map +0 -1
  518. package/dist/src/setup/github-label-adapter.js +0 -28
  519. package/dist/src/setup/github-label-adapter.js.map +0 -1
  520. package/dist/src/setup/labels.d.ts +0 -27
  521. package/dist/src/setup/labels.d.ts.map +0 -1
  522. package/dist/src/setup/labels.js +0 -42
  523. package/dist/src/setup/labels.js.map +0 -1
  524. package/dist/src/setup/project-config.d.ts +0 -24
  525. package/dist/src/setup/project-config.d.ts.map +0 -1
  526. package/dist/src/setup/project-config.js +0 -678
  527. package/dist/src/setup/project-config.js.map +0 -1
  528. package/dist/src/setup/prompt-sync.d.ts +0 -14
  529. package/dist/src/setup/prompt-sync.d.ts.map +0 -1
  530. package/dist/src/setup/prompt-sync.js +0 -228
  531. package/dist/src/setup/prompt-sync.js.map +0 -1
  532. package/dist/src/setup/setup-command.d.ts +0 -29
  533. package/dist/src/setup/setup-command.d.ts.map +0 -1
  534. package/dist/src/setup/setup-command.js +0 -304
  535. package/dist/src/setup/setup-command.js.map +0 -1
  536. package/dist/src/setup/skill-runtime-v2-preparation.d.ts +0 -56
  537. package/dist/src/setup/skill-runtime-v2-preparation.d.ts.map +0 -1
  538. package/dist/src/setup/skill-runtime-v2-preparation.js +0 -304
  539. package/dist/src/setup/skill-runtime-v2-preparation.js.map +0 -1
  540. package/dist/src/setup/workflows.d.ts +0 -10
  541. package/dist/src/setup/workflows.d.ts.map +0 -1
  542. package/dist/src/setup/workflows.js +0 -41
  543. package/dist/src/setup/workflows.js.map +0 -1
  544. package/prompts/setup-skill.md +0 -12
  545. package/prompts/workflows/acceptance-proof.md +0 -29
  546. package/prompts/workflows/breakdown-review.md +0 -48
  547. package/prompts/workflows/issue-breakdown.md +0 -155
  548. package/prompts/workflows/issue-tree-orchestration.md +0 -163
  549. package/prompts/workflows/prd.md +0 -80
  550. package/prompts/workflows/scoped-implementation.md +0 -129
  551. package/prompts/workflows/triage.md +0 -149
  552. /package/dist/src/{process → v2/adapters}/command.d.ts +0 -0
  553. /package/dist/src/{process → v2/adapters}/command.js +0 -0
  554. /package/dist/src/{fs → v2/adapters}/durable-atomic-file.d.ts +0 -0
  555. /package/dist/src/{fs → v2/adapters}/durable-atomic-file.js +0 -0
  556. /package/dist/src/{github → v2/adapters}/gh-cli.d.ts +0 -0
  557. /package/dist/src/{github → v2/adapters}/gh-cli.js +0 -0
  558. /package/dist/src/{github → v2/adapters}/gh-issue-adapter.d.ts +0 -0
  559. /package/dist/src/{github → v2/adapters}/gh-issue-adapter.js +0 -0
  560. /package/dist/src/{github → v2/adapters}/gh-pull-request-adapter.d.ts +0 -0
  561. /package/dist/src/{github → v2/adapters}/gh-pull-request-adapter.js +0 -0
  562. /package/dist/src/{github → v2/adapters}/issues.d.ts +0 -0
  563. /package/dist/src/{github → v2/adapters}/issues.js +0 -0
  564. /package/dist/src/{runner → v2/adapters}/mission-coordinator-lock.d.ts +0 -0
  565. /package/dist/src/{runner → v2/adapters}/mission-coordinator-lock.js +0 -0
  566. /package/dist/src/{path-policy.d.ts → v2/adapters/path-policy.d.ts} +0 -0
  567. /package/dist/src/{path-policy.js → v2/adapters/path-policy.js} +0 -0
  568. /package/dist/src/{github → v2/adapters}/pull-requests.d.ts +0 -0
  569. /package/dist/src/{github → v2/adapters}/pull-requests.js +0 -0
  570. /package/dist/src/{runner → v2/adapters}/target-activity-fence.d.ts +0 -0
@@ -0,0 +1,906 @@
1
+ import { resolve } from 'node:path';
2
+ import { checkedChangePayloadSha256, } from './checked-change.js';
3
+ import { parseAgentAutoConfig } from './config.js';
4
+ import { canonicalJson, sha256 } from './containment.js';
5
+ import { validateImplementationReport } from './implementation-report.js';
6
+ import { ProofQuiescenceError } from './acceptance-proof.js';
7
+ export class OwnerLockSafetyError extends Error {
8
+ }
9
+ export class RunIssue {
10
+ dependencies;
11
+ signal;
12
+ constructor(dependencies) {
13
+ this.dependencies = dependencies;
14
+ this.signal = dependencies.signal ?? new AbortController().signal;
15
+ }
16
+ async reconcileClaim(starting, config) {
17
+ let active = starting;
18
+ const { issueNumber, runId, branchName } = active.record;
19
+ const expectedLabels = sortedUnique([config.github.labels.auto.name, config.github.labels.running.name]);
20
+ if (active.record.intent && !['claim-labels', 'comment'].includes(active.record.intent.kind)) {
21
+ return { result: await this.publicationDiverged(active, 'claim-intent-diverged') };
22
+ }
23
+ let observation = await this.readIssue(issueNumber);
24
+ if (!observation || observation.state !== 'OPEN')
25
+ return { result: await this.publicationDiverged(active, 'claim-issue-missing') };
26
+ if (active.record.intent?.kind === 'claim-labels') {
27
+ if (!sameStrings(observation.labels, expectedLabels)) {
28
+ const labels = new Set(observation.labels);
29
+ if (!labels.has(config.github.labels.auto.name)
30
+ || labels.has(config.github.labels.blocked.name)
31
+ || labels.has(config.github.labels.review.name)) {
32
+ return { result: await this.publicationDiverged(active, 'claim-labels-diverged') };
33
+ }
34
+ try {
35
+ await this.dependencies.issues.setLabels(issueNumber, expectedLabels);
36
+ }
37
+ catch {
38
+ return { result: await this.invokedFailure(active, 'claim-labels-delivery-unknown') };
39
+ }
40
+ observation = await this.readIssue(issueNumber);
41
+ }
42
+ if (!observation || !sameStrings(observation.labels, expectedLabels)) {
43
+ return { result: await this.publicationDiverged(active, 'claim-labels-observation-diverged') };
44
+ }
45
+ active = await this.confirmEffect(active);
46
+ }
47
+ else if (!sameStrings(observation.labels, expectedLabels)) {
48
+ return { result: await this.publicationDiverged(active, 'claim-labels-missing-before-comment') };
49
+ }
50
+ const body = claimComment(runId, issueNumber, branchName);
51
+ const marker = body.split('\n')[0];
52
+ if (!active.record.intent) {
53
+ active = await this.persist(active, { intent: { kind: 'comment', issueNumber, marker, bodySha256: sha256(body) } });
54
+ }
55
+ if (active.record.intent?.kind !== 'comment' || active.record.intent.marker !== marker || active.record.intent.bodySha256 !== sha256(body)) {
56
+ return { result: await this.publicationDiverged(active, 'claim-comment-intent-diverged') };
57
+ }
58
+ observation = await this.readIssue(issueNumber);
59
+ let comments = observation ? commentsWithMarker(observation, marker) : [];
60
+ if (comments.some((comment) => comment.body !== body) || comments.length > 1) {
61
+ return { result: await this.publicationDiverged(active, 'claim-comment-diverged') };
62
+ }
63
+ if (comments.length === 0) {
64
+ try {
65
+ await this.dependencies.issues.postComment(issueNumber, body);
66
+ }
67
+ catch {
68
+ return { result: await this.invokedFailure(active, 'claim-comment-delivery-unknown') };
69
+ }
70
+ observation = await this.readIssue(issueNumber);
71
+ comments = observation ? commentsWithMarker(observation, marker) : [];
72
+ }
73
+ if (comments.length !== 1 || comments[0].body !== body
74
+ || !['OWNER', 'MEMBER', 'COLLABORATOR'].includes(comments[0].authorAssociation)) {
75
+ return { result: await this.publicationDiverged(active, 'claim-comment-observation-diverged') };
76
+ }
77
+ active = await this.confirmEffect(active);
78
+ return { active };
79
+ }
80
+ async publish(starting, config, issue, issueNumber) {
81
+ let active = starting;
82
+ const { runId, branchName, worktreePath, baseSha } = active.record;
83
+ const message = `feat: implement #${issueNumber}`;
84
+ let commitSha = await this.dependencies.git.getHead(worktreePath);
85
+ if (active.record.intent?.kind === 'commit' || !active.record.intent) {
86
+ if (!active.record.intent) {
87
+ if (commitSha === baseSha) {
88
+ active = await this.persist(active, {
89
+ intent: { kind: 'commit', parentSha: baseSha, treeSha: await this.dependencies.git.getTreeSha(worktreePath), message },
90
+ });
91
+ }
92
+ }
93
+ const intent = active.record.intent;
94
+ if (intent?.kind === 'commit') {
95
+ if (commitSha === intent.parentSha) {
96
+ if (await this.dependencies.git.getTreeSha(worktreePath) !== intent.treeSha)
97
+ return await this.publicationDiverged(active, 'commit-tree-diverged');
98
+ if (this.signal.aborted)
99
+ return await this.terminal(await this.clearIntent(active), { status: 'cancelled' });
100
+ if (!await this.authorized(issueNumber, runId, branchName, config))
101
+ return await this.revoked(active);
102
+ try {
103
+ commitSha = await this.dependencies.git.commit({ worktreePath, message: intent.message });
104
+ }
105
+ catch {
106
+ return await this.invokedFailure(active, 'commit-delivery-unknown');
107
+ }
108
+ }
109
+ const observed = await this.dependencies.git.inspectHead(worktreePath);
110
+ if (observed.sha !== commitSha || observed.parentSha !== intent.parentSha || observed.treeSha !== intent.treeSha || observed.message !== intent.message) {
111
+ return await this.publicationDiverged(active, 'commit-observation-diverged');
112
+ }
113
+ active = await this.confirmEffect(active);
114
+ }
115
+ }
116
+ const commit = await this.dependencies.git.inspectHead(worktreePath);
117
+ if (commit.sha !== commitSha || commit.parentSha !== baseSha || commit.message !== message || commit.treeSha !== await this.dependencies.git.getTreeSha(worktreePath)) {
118
+ return await this.publicationDiverged(active, 'commit-identity-diverged');
119
+ }
120
+ if (active.record.intent?.kind === 'push' || !active.record.intent) {
121
+ if (!active.record.intent)
122
+ active = await this.persist(active, { intent: { kind: 'push', branch: branchName, sha: commitSha } });
123
+ const intent = active.record.intent;
124
+ if (intent?.kind !== 'push' || intent.branch !== branchName || intent.sha !== commitSha)
125
+ return await this.publicationDiverged(active, 'push-intent-diverged');
126
+ let remoteSha = await this.dependencies.git.getRemoteBranchSha(worktreePath, branchName);
127
+ if (remoteSha && remoteSha !== commitSha)
128
+ return await this.publicationDiverged(active, 'remote-branch-diverged');
129
+ if (!remoteSha) {
130
+ if (this.signal.aborted)
131
+ return await this.terminal(await this.clearIntent(active), { status: 'cancelled' });
132
+ if (!await this.authorized(issueNumber, runId, branchName, config))
133
+ return await this.revoked(active);
134
+ try {
135
+ await this.dependencies.git.push({ worktreePath, branchName });
136
+ }
137
+ catch {
138
+ return await this.invokedFailure(active, 'push-delivery-unknown');
139
+ }
140
+ remoteSha = await this.dependencies.git.getRemoteBranchSha(worktreePath, branchName);
141
+ }
142
+ if (remoteSha !== commitSha)
143
+ return await this.publicationDiverged(active, 'push-observation-diverged');
144
+ active = await this.confirmEffect(active);
145
+ }
146
+ else if (await this.dependencies.git.getRemoteBranchSha(worktreePath, branchName) !== commitSha) {
147
+ return await this.publicationDiverged(active, 'push-missing-before-later-effect');
148
+ }
149
+ const prMarker = `<!-- codex-orchestrator:run:${runId}:pr -->`;
150
+ const prBody = `${prMarker}\n\nCloses #${issueNumber}`;
151
+ if (active.record.intent?.kind === 'pr' || !active.record.intent) {
152
+ if (!active.record.intent) {
153
+ active = await this.persist(active, {
154
+ intent: {
155
+ kind: 'pr', owner: config.github.owner, repo: config.github.repo, head: branchName,
156
+ base: config.github.baseBranch, issueNumber, marker: prMarker,
157
+ },
158
+ });
159
+ }
160
+ let observed = await this.dependencies.pullRequests.findOpen({ headBranch: branchName, baseBranch: config.github.baseBranch });
161
+ if (observed && observed.body !== prBody)
162
+ return await this.publicationDiverged(active, 'pr-marker-diverged');
163
+ if (!observed) {
164
+ if (this.signal.aborted)
165
+ return await this.terminal(await this.clearIntent(active), { status: 'cancelled' });
166
+ if (!await this.authorized(issueNumber, runId, branchName, config))
167
+ return await this.revoked(active);
168
+ try {
169
+ await this.dependencies.pullRequests.createDraft({
170
+ title: `Implement #${issueNumber}: ${issue.title}`,
171
+ body: prBody,
172
+ headBranch: branchName,
173
+ baseBranch: config.github.baseBranch,
174
+ });
175
+ }
176
+ catch {
177
+ return await this.invokedFailure(active, 'pr-delivery-unknown');
178
+ }
179
+ observed = await this.dependencies.pullRequests.findOpen({ headBranch: branchName, baseBranch: config.github.baseBranch });
180
+ }
181
+ if (!observed || observed.body !== prBody)
182
+ return await this.publicationDiverged(active, 'pr-observation-diverged');
183
+ active = await this.confirmEffect(active);
184
+ }
185
+ const pullRequest = await this.dependencies.pullRequests.findOpen({ headBranch: branchName, baseBranch: config.github.baseBranch });
186
+ if (!pullRequest || pullRequest.body !== prBody)
187
+ return await this.publicationDiverged(active, 'pr-missing-before-handoff');
188
+ const handoffMarker = `<!-- codex-orchestrator:run:${runId}:handoff -->`;
189
+ const handoffBody = `${handoffMarker}\nReview-ready draft PR: ${pullRequest.url}`;
190
+ if (active.record.intent?.kind === 'comment' || !active.record.intent) {
191
+ if (!active.record.intent) {
192
+ active = await this.persist(active, {
193
+ intent: { kind: 'comment', issueNumber, marker: handoffMarker, bodySha256: sha256(handoffBody) },
194
+ });
195
+ }
196
+ let observation = await this.readIssue(issueNumber);
197
+ if (!observation)
198
+ return await this.publicationDiverged(active, 'issue-missing-during-handoff');
199
+ let matching = commentsWithMarker(observation, handoffMarker);
200
+ if (matching.some((comment) => sha256(comment.body) !== sha256(handoffBody)) || matching.length > 1) {
201
+ return await this.publicationDiverged(active, 'handoff-comment-diverged');
202
+ }
203
+ if (matching.length === 0) {
204
+ if (this.signal.aborted)
205
+ return await this.terminal(await this.clearIntent(active), { status: 'cancelled' });
206
+ if (!await this.authorized(issueNumber, runId, branchName, config))
207
+ return await this.revoked(active);
208
+ try {
209
+ await this.dependencies.issues.postComment(issueNumber, handoffBody);
210
+ }
211
+ catch {
212
+ return await this.invokedFailure(active, 'handoff-comment-delivery-unknown');
213
+ }
214
+ observation = await this.readIssue(issueNumber);
215
+ matching = observation ? commentsWithMarker(observation, handoffMarker) : [];
216
+ }
217
+ if (matching.length !== 1 || sha256(matching[0].body) !== sha256(handoffBody)) {
218
+ return await this.publicationDiverged(active, 'handoff-comment-observation-diverged');
219
+ }
220
+ active = await this.confirmEffect(active);
221
+ }
222
+ const terminalLabels = [config.github.labels.review.name];
223
+ if (active.record.intent?.kind === 'labels' || !active.record.intent) {
224
+ if (!active.record.intent)
225
+ active = await this.persist(active, { intent: { kind: 'labels', issueNumber, expected: terminalLabels } });
226
+ let observation = await this.readIssue(issueNumber);
227
+ if (!observation)
228
+ return await this.publicationDiverged(active, 'issue-missing-during-labels');
229
+ if (!sameStrings(observation.labels, terminalLabels)) {
230
+ if (this.signal.aborted)
231
+ return await this.terminal(await this.clearIntent(active), { status: 'cancelled' });
232
+ if (!await this.authorized(issueNumber, runId, branchName, config))
233
+ return await this.revoked(active);
234
+ try {
235
+ await this.dependencies.issues.setLabels(issueNumber, terminalLabels);
236
+ }
237
+ catch {
238
+ return await this.invokedFailure(active, 'terminal-labels-delivery-unknown');
239
+ }
240
+ observation = await this.readIssue(issueNumber);
241
+ }
242
+ if (!observation || !sameStrings(observation.labels, terminalLabels))
243
+ return await this.publicationDiverged(active, 'terminal-labels-diverged');
244
+ }
245
+ const evidence = await this.dependencies.writeEvidence({ runId, code: 'review-ready', summary: pullRequest.url });
246
+ const outcome = { status: 'review-ready', pullRequestUrl: pullRequest.url, evidencePath: evidence.path };
247
+ try {
248
+ await this.persist(active, { lifecycle: 'review-ready', intent: undefined, outcomeEvidenceId: evidence.id, terminalOutcome: outcome });
249
+ }
250
+ catch {
251
+ throw new PostEffectStateError(active);
252
+ }
253
+ return outcome;
254
+ }
255
+ publicationDiverged(active, code) {
256
+ return this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, code);
257
+ }
258
+ async runIssue(input) {
259
+ let owner;
260
+ let active;
261
+ try {
262
+ assertPositiveInteger(input.issueNumber, 'issueNumber');
263
+ const targetRoot = resolve(input.targetRoot);
264
+ const initialConfig = await this.readStrictConfig(targetRoot);
265
+ const canonicalRepository = `${initialConfig.config.github.owner.toLowerCase()}/${initialConfig.config.github.repo.toLowerCase()}`;
266
+ try {
267
+ owner = await this.dependencies.ownerLock.acquire({ canonicalRepository, targetRoot });
268
+ }
269
+ catch (error) {
270
+ if (error instanceof OwnerLockSafetyError) {
271
+ const evidence = await this.dependencies.writeEvidence({
272
+ runId: `issue-${input.issueNumber}`,
273
+ code: 'owner-lock-blocked',
274
+ summary: 'Repository ownership is ambiguous or already held.',
275
+ });
276
+ return { status: 'blocked', kind: 'safety', resumable: true, evidencePath: evidence.path };
277
+ }
278
+ return await this.preClaimInternal('state-write-failed', input.issueNumber);
279
+ }
280
+ const confirmedConfig = await this.readStrictConfig(targetRoot);
281
+ if (!confirmedConfig.bytes.equals(initialConfig.bytes)
282
+ || canonicalRepository !== `${confirmedConfig.config.github.owner.toLowerCase()}/${confirmedConfig.config.github.repo.toLowerCase()}`) {
283
+ return await this.preClaimInternal('config-changed-during-owner-acquire', input.issueNumber);
284
+ }
285
+ const config = confirmedConfig.config;
286
+ try {
287
+ await this.dependencies.validateContainment(config);
288
+ }
289
+ catch {
290
+ const evidence = await this.dependencies.writeEvidence({
291
+ runId: `issue-${input.issueNumber}`,
292
+ code: 'containment-certificate-invalid',
293
+ summary: 'Containment certification is unavailable or stale.',
294
+ });
295
+ return { status: 'blocked', kind: 'safety', resumable: true, evidencePath: evidence.path };
296
+ }
297
+ if (this.signal.aborted)
298
+ return await this.preClaimCancelled(input.issueNumber);
299
+ let issue;
300
+ try {
301
+ issue = await this.dependencies.issues.read(input.issueNumber);
302
+ }
303
+ catch {
304
+ return await this.preClaimTransport(input.issueNumber);
305
+ }
306
+ const persisted = await this.dependencies.runRecords.read();
307
+ const matchingRuns = persisted.runs.filter((run) => run.issueNumber === input.issueNumber && run.canonicalRepository === canonicalRepository);
308
+ if (matchingRuns.length > 1)
309
+ return await this.preClaimInternal('ambiguous-run-state', input.issueNumber);
310
+ const existing = matchingRuns[0];
311
+ let issueSnapshot;
312
+ let frozenCriteria;
313
+ let runId;
314
+ let branchName;
315
+ let worktreePath;
316
+ let baseSha;
317
+ if (existing) {
318
+ const expectedBranch = `codex/issue-${input.issueNumber}`;
319
+ const expectedWorktree = resolve(targetRoot, config.runner.workspaceRoot, `issue-${input.issueNumber}`);
320
+ if (existing.branchName !== expectedBranch || existing.worktreePath !== expectedWorktree) {
321
+ return await this.preClaimInternal('run-identity-mismatch', input.issueNumber);
322
+ }
323
+ if (existing.terminalOutcome)
324
+ return publicOutcome(existing.terminalOutcome);
325
+ active = { state: persisted, record: existing };
326
+ issueSnapshot = structuredClone(existing.issueSnapshot);
327
+ frozenCriteria = structuredClone(existing.frozenCriteria);
328
+ runId = existing.runId;
329
+ branchName = existing.branchName;
330
+ worktreePath = existing.worktreePath;
331
+ baseSha = existing.baseSha;
332
+ if (existing.lifecycle === 'publishing') {
333
+ return await this.publish(active, config, issueSnapshot, input.issueNumber);
334
+ }
335
+ if (existing.lifecycle === 'claimed') {
336
+ const claim = await this.reconcileClaim(active, config);
337
+ if ('result' in claim)
338
+ return claim.result;
339
+ active = claim.active;
340
+ const worktree = await this.dependencies.git.inspectWorktree({ worktreePath, branchName, baseSha });
341
+ if (worktree === 'diverged')
342
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, 'claim-worktree-diverged');
343
+ if (worktree === 'absent') {
344
+ try {
345
+ await this.dependencies.git.createWorktree({ targetRoot, worktreePath, branchName, baseBranch: config.github.baseBranch, baseSha });
346
+ }
347
+ catch {
348
+ return await this.terminal(active, { status: 'internal-error', code: 'local-git-effect-failed' });
349
+ }
350
+ }
351
+ active = await this.persist(active, { lifecycle: 'implementing' });
352
+ }
353
+ else {
354
+ if (existing.lifecycle === 'safe-halt')
355
+ return await this.publicationDiverged(active, 'safe-halt-requires-process-absence');
356
+ if (!['implementing', 'reworking', 'checking', 'proving'].includes(existing.lifecycle)) {
357
+ return await this.terminal(active, { status: 'internal-error', code: 'resume-phase-not-reconciled' });
358
+ }
359
+ if (existing.cycle >= config.runner.maxCycles) {
360
+ return await this.terminal(active, { status: 'blocked', kind: 'exhausted', resumable: true });
361
+ }
362
+ if (!await this.authorized(input.issueNumber, runId, branchName, config))
363
+ return await this.revoked(active);
364
+ active = await this.startNextCycle(active, [`Recovered interrupted ${existing.lifecycle} phase.`]);
365
+ }
366
+ }
367
+ else {
368
+ const ineligible = await this.ineligibilityReason(issue, config);
369
+ if (ineligible) {
370
+ const evidence = await this.dependencies.writeEvidence({ runId: `issue-${input.issueNumber}`, code: 'not-eligible', summary: ineligible });
371
+ return { status: 'not-eligible', reason: ineligible, evidencePath: evidence.path };
372
+ }
373
+ issueSnapshot = snapshotIssue(issue);
374
+ frozenCriteria = freezeCriteria(issueSnapshot);
375
+ runId = this.dependencies.createRunId();
376
+ assertUuid(runId);
377
+ branchName = `codex/issue-${input.issueNumber}`;
378
+ worktreePath = resolve(targetRoot, config.runner.workspaceRoot, `issue-${input.issueNumber}`);
379
+ baseSha = await this.dependencies.git.getBaseSha({ targetRoot, baseBranch: config.github.baseBranch });
380
+ assertGitSha(baseSha, 'baseSha');
381
+ const runningLabels = sortedUnique([config.github.labels.auto.name, config.github.labels.running.name]);
382
+ active = await this.createRun({
383
+ runId, issueNumber: input.issueNumber, canonicalRepository, baseSha, branchName, worktreePath,
384
+ issueSnapshot, frozenCriteria,
385
+ intent: { kind: 'claim-labels', issueNumber: input.issueNumber, expected: runningLabels },
386
+ });
387
+ const claim = await this.reconcileClaim(active, config);
388
+ if ('result' in claim)
389
+ return claim.result;
390
+ active = claim.active;
391
+ try {
392
+ await this.dependencies.git.createWorktree({ targetRoot, worktreePath, branchName, baseBranch: config.github.baseBranch, baseSha });
393
+ }
394
+ catch {
395
+ return await this.terminal(active, { status: 'internal-error', code: 'local-git-effect-failed' });
396
+ }
397
+ active = await this.persist(active, { lifecycle: 'implementing' });
398
+ }
399
+ attemptLoop: while (true) {
400
+ if (!await this.authorized(input.issueNumber, runId, branchName, config)) {
401
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true });
402
+ }
403
+ if (this.signal.aborted)
404
+ return await this.terminal(active, { status: 'cancelled' });
405
+ const implementationBaseline = await this.dependencies.git.snapshot(worktreePath);
406
+ const deniedPathsBaseline = await this.dependencies.git.fingerprintDeniedPaths(worktreePath, config.deny.readPaths);
407
+ let implementation = await this.runImplementation({
408
+ runId,
409
+ worktreePath,
410
+ issue: issueSnapshot,
411
+ frozenCriteria,
412
+ cycle: active.record.cycle,
413
+ reworkFindings: active.record.reworkFindings,
414
+ repairOnly: false,
415
+ });
416
+ if (implementation.kind === 'safe-halt') {
417
+ active = await this.persist(active, { lifecycle: 'safe-halt', process: implementation.process });
418
+ while (true) {
419
+ try {
420
+ await implementation.waitForAbsence();
421
+ break;
422
+ }
423
+ catch {
424
+ await new Promise((resolveWait) => setTimeout(resolveWait, 25));
425
+ }
426
+ }
427
+ if (await this.dependencies.git.fingerprintDeniedPaths(worktreePath, config.deny.readPaths) !== deniedPathsBaseline) {
428
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, 'denied-path-modified');
429
+ }
430
+ return await this.terminal(active, { status: 'transport-failed', resumable: false }, 'process-quiescence-delayed');
431
+ }
432
+ if (await this.dependencies.git.fingerprintDeniedPaths(worktreePath, config.deny.readPaths) !== deniedPathsBaseline) {
433
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, 'denied-path-modified');
434
+ }
435
+ if (implementation.kind === 'transport-failed' && implementation.resumable && active.record.transportRetries === 0) {
436
+ const afterTransport = await this.dependencies.git.snapshot(worktreePath);
437
+ if (!sameFreshness(implementationBaseline, afterTransport)) {
438
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, 'transport-baseline-changed');
439
+ }
440
+ active = await this.persist(active, { transportRetries: 1 });
441
+ continue attemptLoop;
442
+ }
443
+ if (implementation.kind !== 'completed')
444
+ return await this.mapImplementationFailure(active, implementation);
445
+ let report;
446
+ try {
447
+ report = validateImplementationReport(implementation.report);
448
+ }
449
+ catch {
450
+ if (active.record.reportRepairs >= 1) {
451
+ return await this.terminal(active, { status: 'internal-error', code: 'implementation-report-malformed' });
452
+ }
453
+ const repairBaseline = await this.dependencies.git.snapshot(worktreePath);
454
+ active = await this.persist(active, { reportRepairs: 1 });
455
+ implementation = await this.runImplementation({
456
+ runId,
457
+ worktreePath,
458
+ issue: issueSnapshot,
459
+ frozenCriteria,
460
+ cycle: active.record.cycle,
461
+ reworkFindings: ['The previous implementation report did not match the generated schema.'],
462
+ repairOnly: true,
463
+ });
464
+ if (implementation.kind === 'safe-halt') {
465
+ active = await this.persist(active, { lifecycle: 'safe-halt', process: implementation.process });
466
+ while (true) {
467
+ try {
468
+ await implementation.waitForAbsence();
469
+ break;
470
+ }
471
+ catch {
472
+ await new Promise((resolveWait) => setTimeout(resolveWait, 25));
473
+ }
474
+ }
475
+ return await this.terminal(active, { status: 'transport-failed', resumable: false }, 'process-quiescence-delayed');
476
+ }
477
+ if (implementation.kind !== 'completed')
478
+ return await this.mapImplementationFailure(active, implementation);
479
+ const afterRepair = await this.dependencies.git.snapshot(worktreePath);
480
+ if (!sameFreshness(repairBaseline, afterRepair)) {
481
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true }, 'report-repair-modified-worktree');
482
+ }
483
+ try {
484
+ report = validateImplementationReport(implementation.report);
485
+ }
486
+ catch {
487
+ return await this.terminal(active, { status: 'internal-error', code: 'implementation-report-malformed' });
488
+ }
489
+ }
490
+ if (report.status === 'external-block') {
491
+ return await this.terminal(active, { status: 'blocked', kind: 'external', resumable: true });
492
+ }
493
+ if (await this.dependencies.git.getHead(worktreePath) !== baseSha) {
494
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true });
495
+ }
496
+ const changedFiles = await this.dependencies.git.listChangedFiles(worktreePath);
497
+ if (changedFiles.length === 0 || !sameStrings(changedFiles, report.changedFiles)) {
498
+ return await this.terminal(active, { status: 'internal-error', code: 'implementation-change-set-invalid' });
499
+ }
500
+ active = await this.persist(active, { lifecycle: 'checking' });
501
+ for (const [id, command] of Object.entries(config.checks)) {
502
+ if (this.signal.aborted)
503
+ return await this.terminal(active, { status: 'cancelled' });
504
+ let check;
505
+ try {
506
+ check = await this.dependencies.checks.run({ id, command, cwd: worktreePath, signal: this.signal });
507
+ }
508
+ catch {
509
+ return await this.terminal(active, { status: 'internal-error', code: 'configured-check-execution-failed' });
510
+ }
511
+ if (this.signal.aborted)
512
+ return await this.terminal(active, { status: 'cancelled' });
513
+ const row = { id, command, status: check.status, outputSha256: sha256(check.output) };
514
+ active = await this.persist(active, { checks: [...active.record.checks, row] });
515
+ if (check.status !== 'passed') {
516
+ if (active.record.cycle >= config.runner.maxCycles) {
517
+ return await this.terminal(active, { status: 'blocked', kind: 'exhausted', resumable: true });
518
+ }
519
+ active = await this.startNextCycle(active, [`Check ${id} failed:\n${check.output.toString('utf8').slice(0, 8 * 1024)}`]);
520
+ continue attemptLoop;
521
+ }
522
+ }
523
+ try {
524
+ await this.dependencies.git.stageAll(worktreePath);
525
+ }
526
+ catch {
527
+ return await this.terminal(active, { status: 'internal-error', code: 'local-git-effect-failed' });
528
+ }
529
+ if (await this.dependencies.git.getHead(worktreePath) !== baseSha) {
530
+ return await this.terminal(active, { status: 'blocked', kind: 'safety', resumable: true });
531
+ }
532
+ const proofChangedFiles = await this.dependencies.git.listChangedFiles(worktreePath);
533
+ const freshness = await this.dependencies.git.snapshot(worktreePath);
534
+ const payload = {
535
+ version: 1,
536
+ canonicalRepository,
537
+ runId,
538
+ issueNumber: input.issueNumber,
539
+ cycle: active.record.cycle,
540
+ baseSha,
541
+ headSha: freshness.headSha,
542
+ indexTreeSha: freshness.indexTreeSha,
543
+ trackedContentSha256: freshness.trackedContentSha256,
544
+ untrackedContentSha256: freshness.untrackedContentSha256,
545
+ worktreeIdentity: freshness.worktreeIdentity,
546
+ changedFiles: proofChangedFiles,
547
+ checks: active.record.checks.map((check) => ({ ...check, status: 'passed' })),
548
+ checkPolicySha256: sha256(canonicalJson(config.checks)),
549
+ packageVersion: this.dependencies.packageVersion,
550
+ proofSchemaVersion: 1,
551
+ };
552
+ const checkedChange = this.dependencies.checkedChangeMint.mint(payload);
553
+ const checkedChangeSha256 = checkedChangePayloadSha256(payload);
554
+ const proofId = this.dependencies.createProofId();
555
+ assertNonEmptyString(proofId, 'proofId');
556
+ active = await this.persist(active, { lifecycle: 'proving', checkedChangeSha256, proofId });
557
+ let proof;
558
+ try {
559
+ proof = await this.dependencies.proof.proveChange({ proofId, issue: issueSnapshot, frozenCriteria, checkedChange });
560
+ }
561
+ catch (error) {
562
+ if (error instanceof ProofQuiescenceError) {
563
+ active = await this.persist(active, {
564
+ lifecycle: 'safe-halt',
565
+ process: {
566
+ pid: error.pid,
567
+ processGroupId: error.processGroupId,
568
+ startedAt: this.timestamp(),
569
+ baseline: {
570
+ headSha: freshness.headSha,
571
+ indexTreeSha: freshness.indexTreeSha,
572
+ trackedContentSha256: freshness.trackedContentSha256,
573
+ untrackedContentSha256: freshness.untrackedContentSha256,
574
+ worktreeIdentity: freshness.worktreeIdentity,
575
+ },
576
+ },
577
+ });
578
+ while (true) {
579
+ try {
580
+ await error.waitForAbsence();
581
+ break;
582
+ }
583
+ catch {
584
+ await new Promise((resolveWait) => setTimeout(resolveWait, 25));
585
+ }
586
+ }
587
+ return await this.terminal(active, { status: 'transport-failed', resumable: false }, 'proof-process-quiescence-delayed');
588
+ }
589
+ return await this.terminal(active, { status: 'internal-error', code: 'acceptance-proof-internal-failure' });
590
+ }
591
+ if (this.signal.aborted)
592
+ return await this.terminal(active, { status: 'cancelled' });
593
+ if (proof.status === 'needs-rework') {
594
+ if (active.record.cycle >= config.runner.maxCycles) {
595
+ return await this.terminal(active, { status: 'blocked', kind: 'exhausted', resumable: true });
596
+ }
597
+ active = await this.startNextCycle(active, proof.findings);
598
+ continue attemptLoop;
599
+ }
600
+ if (proof.status !== 'passed')
601
+ return await this.mapProofFailure(active, proof);
602
+ active = await this.persist(active, { lifecycle: 'publishing', proofReceipt: proof.receipt, reworkFindings: [] });
603
+ break;
604
+ }
605
+ return await this.publish(active, config, issueSnapshot, input.issueNumber);
606
+ }
607
+ catch (error) {
608
+ if (!active && error instanceof TransportReadError) {
609
+ return await this.preClaimTransport(input.issueNumber);
610
+ }
611
+ if (active && error instanceof PostEffectStateError) {
612
+ return await this.invokedFailure(error.active, 'post-effect-state-write-failed');
613
+ }
614
+ if (active && error instanceof TransportReadError) {
615
+ return await this.invokedFailure(active, 'authorization-read-failed');
616
+ }
617
+ if (active) {
618
+ try {
619
+ return await this.terminal(active, { status: 'internal-error', code: 'state-write-failed' });
620
+ }
621
+ catch {
622
+ const evidence = await this.dependencies.writeEvidence({ runId: active.record.runId, code: 'state-write-failed', summary: 'Run state failed.' });
623
+ return { status: 'internal-error', evidencePath: evidence.path };
624
+ }
625
+ }
626
+ return await this.preClaimInternal('state-write-failed', input.issueNumber);
627
+ }
628
+ finally {
629
+ if (owner) {
630
+ try {
631
+ await owner.release();
632
+ }
633
+ catch {
634
+ const evidence = await this.dependencies.writeEvidence({
635
+ runId: active?.record.runId ?? `issue-${input.issueNumber}`,
636
+ code: 'owner-lock-release-failed',
637
+ summary: 'Owner lock release failed.',
638
+ });
639
+ return { status: 'internal-error', evidencePath: evidence.path };
640
+ }
641
+ }
642
+ }
643
+ }
644
+ async readStrictConfig(targetRoot) {
645
+ const value = await this.dependencies.readConfig(targetRoot);
646
+ return { bytes: Buffer.from(value.bytes), config: parseAgentAutoConfig(structuredClone(value.config)) };
647
+ }
648
+ async ineligibilityReason(issue, config) {
649
+ if (!issue)
650
+ return 'Issue does not exist.';
651
+ const labels = new Set(issue.labels);
652
+ if (issue.state !== 'OPEN')
653
+ return 'Issue is not open.';
654
+ if (!labels.has(config.github.labels.auto.name))
655
+ return 'Issue lacks the auto label.';
656
+ if ([config.github.labels.running.name, config.github.labels.blocked.name, config.github.labels.review.name].some((label) => labels.has(label))) {
657
+ return 'Issue already has a terminal or running label.';
658
+ }
659
+ const branchName = `codex/issue-${issue.number}`;
660
+ try {
661
+ if (await this.dependencies.pullRequests.findOpen({ headBranch: branchName, baseBranch: config.github.baseBranch }))
662
+ return 'An open pull request already exists.';
663
+ }
664
+ catch {
665
+ throw new TransportReadError();
666
+ }
667
+ return undefined;
668
+ }
669
+ async createRun(input) {
670
+ const state = await this.dependencies.runRecords.read();
671
+ const now = this.timestamp();
672
+ const record = {
673
+ ...input,
674
+ lifecycle: 'claimed', cycle: 1, reportRepairs: 0, transportRetries: 0,
675
+ reworkFindings: [],
676
+ packageVersion: this.dependencies.packageVersion,
677
+ skillHashes: structuredClone(this.dependencies.skillHashes),
678
+ checks: [], createdAt: now, updatedAt: now,
679
+ };
680
+ const saved = await this.dependencies.runRecords.compareAndSwap(state.generation, {
681
+ schema: 'codex-orchestrator.agent-auto-state', version: 1, runs: [...state.runs, record],
682
+ });
683
+ return { state: saved, record: findRun(saved, input.runId) };
684
+ }
685
+ async persist(active, changes) {
686
+ const record = { ...active.record, ...changes, updatedAt: this.timestamp() };
687
+ if (Object.hasOwn(changes, 'intent') && changes.intent === undefined)
688
+ delete record.intent;
689
+ if (Object.hasOwn(changes, 'process') && changes.process === undefined)
690
+ delete record.process;
691
+ for (const key of ['checkedChangeSha256', 'proofId', 'proofReceipt', 'terminalOutcome', 'outcomeEvidenceId']) {
692
+ if (Object.hasOwn(changes, key) && changes[key] === undefined)
693
+ delete record[key];
694
+ }
695
+ const runs = active.state.runs.map((candidate) => candidate.runId === record.runId ? record : candidate);
696
+ const saved = await this.dependencies.runRecords.compareAndSwap(active.state.generation, {
697
+ schema: 'codex-orchestrator.agent-auto-state', version: 1, runs,
698
+ });
699
+ return { state: saved, record: findRun(saved, record.runId) };
700
+ }
701
+ clearIntent(active) {
702
+ return this.persist(active, { intent: undefined });
703
+ }
704
+ async confirmEffect(active) {
705
+ try {
706
+ return await this.clearIntent(active);
707
+ }
708
+ catch {
709
+ throw new PostEffectStateError(active);
710
+ }
711
+ }
712
+ async authorized(issueNumber, runId, branchName, config) {
713
+ const issue = await this.readIssue(issueNumber);
714
+ if (!issue || issue.state !== 'OPEN')
715
+ return false;
716
+ const labels = new Set(issue.labels);
717
+ if (!labels.has(config.github.labels.auto.name) || !labels.has(config.github.labels.running.name))
718
+ return false;
719
+ const exactBody = claimComment(runId, issueNumber, branchName);
720
+ const markerPattern = /^<!-- codex-orchestrator:run:([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}):claim -->$/u;
721
+ const markers = issue.comments.filter((comment) => markerPattern.test(comment.body.split('\n')[0] ?? ''));
722
+ if (issue.comments.some((comment) => {
723
+ const firstLine = comment.body.split('\n')[0] ?? '';
724
+ return firstLine.startsWith(`<!-- codex-orchestrator:run:${runId}:claim`) && !markerPattern.test(firstLine);
725
+ }))
726
+ return false;
727
+ if (markers.some((comment) => (comment.body.split('\n')[0] ?? '').match(markerPattern)?.[1] !== runId))
728
+ return false;
729
+ const current = markers.filter((comment) => comment.body === exactBody);
730
+ return current.length === 1 && ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(current[0].authorAssociation);
731
+ }
732
+ async readIssue(issueNumber) {
733
+ try {
734
+ return await this.dependencies.issues.read(issueNumber);
735
+ }
736
+ catch {
737
+ throw new TransportReadError();
738
+ }
739
+ }
740
+ async runImplementation(input) {
741
+ try {
742
+ return await this.dependencies.implementationAgent.run({ ...input, signal: this.signal });
743
+ }
744
+ catch {
745
+ return { kind: 'internal-error' };
746
+ }
747
+ }
748
+ async startNextCycle(active, findings) {
749
+ active = await this.persist(active, { lifecycle: 'reworking', reworkFindings: [...findings] });
750
+ return this.persist(active, {
751
+ lifecycle: 'implementing',
752
+ cycle: (active.record.cycle + 1),
753
+ packageVersion: this.dependencies.packageVersion,
754
+ skillHashes: structuredClone(this.dependencies.skillHashes),
755
+ checks: [],
756
+ checkedChangeSha256: undefined,
757
+ proofId: undefined,
758
+ proofReceipt: undefined,
759
+ });
760
+ }
761
+ async mapImplementationFailure(active, result) {
762
+ if (result.kind === 'transport-failed')
763
+ return this.terminal(active, { status: 'transport-failed', resumable: result.resumable });
764
+ if (result.kind === 'cancelled')
765
+ return this.terminal(active, { status: 'cancelled' });
766
+ return this.terminal(active, { status: 'internal-error', code: 'implementation-agent-internal-failure' });
767
+ }
768
+ async mapProofFailure(active, proof) {
769
+ if (proof.status === 'needs-rework')
770
+ return this.terminal(active, { status: 'internal-error', code: 'proof-rework-loop-not-yet-implemented' });
771
+ if (proof.status === 'external-block')
772
+ return this.terminal(active, { status: 'blocked', kind: 'external', resumable: true });
773
+ if (proof.status === 'transport-failed')
774
+ return this.terminal(active, { status: 'transport-failed', resumable: proof.resumable });
775
+ if (proof.status === 'cancelled')
776
+ return this.terminal(active, { status: 'cancelled' });
777
+ return this.terminal(active, { status: 'internal-error', code: 'acceptance-proof-internal-failure' });
778
+ }
779
+ async revoked(active) {
780
+ return this.terminal(await this.clearIntent(active), { status: 'blocked', kind: 'safety', resumable: true });
781
+ }
782
+ async invokedFailure(active, code) {
783
+ const evidence = await this.dependencies.writeEvidence({ runId: active.record.runId, code, summary: 'Publication delivery requires reconciliation.' });
784
+ return { status: 'transport-failed', resumable: true, evidencePath: evidence.path };
785
+ }
786
+ async terminal(active, outcome, evidenceCode = outcome.status, retainIntent = false) {
787
+ const evidence = await this.dependencies.writeEvidence({ runId: active.record.runId, code: evidenceCode, summary: outcome.status });
788
+ const terminalOutcome = { ...outcome, evidencePath: evidence.path };
789
+ const changes = {
790
+ lifecycle: outcome.status,
791
+ terminalOutcome,
792
+ outcomeEvidenceId: evidence.id,
793
+ process: undefined,
794
+ };
795
+ if (!retainIntent)
796
+ changes.intent = undefined;
797
+ await this.persist(active, changes);
798
+ return publicOutcome(terminalOutcome);
799
+ }
800
+ async preClaimInternal(code, issueNumber) {
801
+ const evidence = await this.dependencies.writeEvidence({ runId: `issue-${issueNumber}`, code, summary: code });
802
+ return { status: 'internal-error', evidencePath: evidence.path };
803
+ }
804
+ async preClaimCancelled(issueNumber) {
805
+ const evidence = await this.dependencies.writeEvidence({ runId: `issue-${issueNumber}`, code: 'cancelled', summary: 'Cancelled.' });
806
+ return { status: 'cancelled', evidencePath: evidence.path };
807
+ }
808
+ async preClaimTransport(issueNumber) {
809
+ const evidence = await this.dependencies.writeEvidence({ runId: `issue-${issueNumber}`, code: 'issue-read-failed', summary: 'Issue read failed.' });
810
+ return { status: 'transport-failed', resumable: true, evidencePath: evidence.path };
811
+ }
812
+ timestamp() {
813
+ const value = this.dependencies.now();
814
+ if (Number.isNaN(Date.parse(value)) || new Date(value).toISOString() !== value)
815
+ throw new Error('runtime clock is invalid');
816
+ return value;
817
+ }
818
+ }
819
+ class TransportReadError extends Error {
820
+ }
821
+ class PostEffectStateError extends Error {
822
+ active;
823
+ constructor(active) {
824
+ super('post-effect state write failed');
825
+ this.active = active;
826
+ }
827
+ }
828
+ function snapshotIssue(issue) {
829
+ if (issue.state !== 'OPEN')
830
+ throw new Error('cannot snapshot a closed issue');
831
+ return {
832
+ number: issue.number,
833
+ title: issue.title,
834
+ body: issue.body,
835
+ url: issue.url,
836
+ state: 'OPEN',
837
+ labels: sortedUnique(issue.labels),
838
+ };
839
+ }
840
+ function freezeCriteria(issue) {
841
+ const lines = issue.body.split(/\r?\n/u);
842
+ const heading = lines.findIndex((line) => /^#{1,6}\s+acceptance criteria\s*$/iu.test(line.trim()));
843
+ const texts = [];
844
+ if (heading >= 0) {
845
+ for (const line of lines.slice(heading + 1)) {
846
+ if (/^#{1,6}\s+/u.test(line.trim()))
847
+ break;
848
+ const match = line.match(/^\s*[-*]\s+(?:\[[ xX]\]\s*)?(.+?)\s*$/u);
849
+ const text = match?.[1]?.trim();
850
+ if (text && !texts.includes(text))
851
+ texts.push(text);
852
+ }
853
+ }
854
+ if (texts.length === 0)
855
+ return [{ id: 'fallback-001', order: 1, source: 'fallback', text: `${issue.title}\n\n${issue.body}` }];
856
+ return texts.map((text, index) => ({ id: `ac-${String(index + 1).padStart(3, '0')}`, order: index + 1, source: 'explicit', text }));
857
+ }
858
+ function claimComment(runId, issueNumber, branchName) {
859
+ return `<!-- codex-orchestrator:run:${runId}:claim -->\ncodex-orchestrator claimed #${issueNumber} for branch ${branchName}`;
860
+ }
861
+ function findRun(state, runId) {
862
+ const record = state.runs.find((candidate) => candidate.runId === runId);
863
+ if (!record)
864
+ throw new Error('persisted run is missing');
865
+ return record;
866
+ }
867
+ function publicOutcome(outcome) {
868
+ if (outcome.status === 'internal-error')
869
+ return { status: 'internal-error', evidencePath: outcome.evidencePath };
870
+ return structuredClone(outcome);
871
+ }
872
+ function sameStrings(left, right) {
873
+ const a = [...left].sort();
874
+ const b = [...right].sort();
875
+ return a.length === b.length && a.every((value, index) => value === b[index]);
876
+ }
877
+ function sameFreshness(left, right) {
878
+ return left.headSha === right.headSha
879
+ && left.indexTreeSha === right.indexTreeSha
880
+ && left.trackedContentSha256 === right.trackedContentSha256
881
+ && left.untrackedContentSha256 === right.untrackedContentSha256
882
+ && left.worktreeIdentity === right.worktreeIdentity;
883
+ }
884
+ function commentsWithMarker(issue, marker) {
885
+ return issue.comments.filter((comment) => comment.body.split('\n')[0] === marker);
886
+ }
887
+ function sortedUnique(values) {
888
+ return [...new Set(values)].sort();
889
+ }
890
+ function assertUuid(value) {
891
+ if (typeof value !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(value))
892
+ throw new Error('runId is invalid');
893
+ }
894
+ function assertGitSha(value, field) {
895
+ if (typeof value !== 'string' || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u.test(value))
896
+ throw new Error(`${field} is invalid`);
897
+ }
898
+ function assertPositiveInteger(value, field) {
899
+ if (!Number.isSafeInteger(value) || value <= 0)
900
+ throw new Error(`${field} is invalid`);
901
+ }
902
+ function assertNonEmptyString(value, field) {
903
+ if (typeof value !== 'string' || value.length === 0 || value.length > 16 * 1024)
904
+ throw new Error(`${field} is invalid`);
905
+ }
906
+ //# sourceMappingURL=run-issue.js.map