codex-orchestrator 0.1.51 → 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 +21 -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 -170
  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,14 @@
1
+ ---
2
+ name: acceptance-proof
3
+ description: Independently prove a checked change against frozen acceptance criteria and return a typed proof report.
4
+ ---
5
+
6
+ # Acceptance Proof
7
+
8
+ Independently prove the checked change against every frozen acceptance criterion. Inspect the issue snapshot, actual diff, configured check receipts, and available repository evidence. Classify each criterion as non-visual or visual from the criterion and changed behavior, preserve every frozen criterion ID, and require concrete evidence for every declared surface.
9
+
10
+ For a browser surface, read and follow [references/browser.md](references/browser.md). For Android, follow [references/android.md](references/android.md) and use only `tools/android-lease.mjs`. For iOS, follow [references/ios.md](references/ios.md) and use only `tools/ios-lease.mjs`. Resolve every reference/helper from this exact immutable skill snapshot and use only the proof-bound arguments supplied by the runner. Apply the selected platform procedure's real-workflow, state capture, diagnostics, freshness, analysis, and artifact-classification requirements.
11
+
12
+ Do not edit product code, repair the implementation, change lifecycle state, or perform publication. Do not commit, push, open or edit a pull request, mutate GitHub labels/comments, publish packages, deploy, or use external credentials. Do not copy or print credential bytes or auth/secret paths. Report a typed external blocker only when proof genuinely depends on unavailable external authority.
13
+
14
+ Return only the JSON object required by the exact output schema supplied by the runner. Do not add prose around the report and do not independently restate or modify its fields.
@@ -0,0 +1,14 @@
1
+ # Android Proof Procedure
2
+
3
+ Use Android proof only when a frozen criterion describes user-visible Android behavior or the checked diff changes that behavior. Keep the exact frozen criterion IDs and declare `decision.mode: visual`, target `android`, and an `android` surface for each applicable criterion.
4
+
5
+ 1. Discover current Android and Flutter ownership before mutation. Require exactly one online emulator, no physical device, and no live process for the selected application ID. If a user-owned app or runtime is present, return a typed tool blocker and do not install, launch, stop, replace, or clear it.
6
+ 2. Acquire the runner lease before installing or launching the app by invoking the exact immutable `tools/android-lease.mjs` path and lease arguments supplied by the runner. Keep its token private. If acquisition is blocked, do not bypass it with direct `adb` commands.
7
+ 3. Install and launch only the selected application ID on the leased emulator. Resolve the actual application PID and bind it with the same helper, proof ID, token, lease root, and lease artifact path before interacting with the app.
8
+ 4. Complete the real workflow through its final interaction. Use an accessibility/UI hierarchy dump to locate controls and derive interaction coordinates; do not guess coordinates. Recheck that the exact leased application PID is still live after the final interaction.
9
+ 5. After the final interaction, capture a fresh PNG screenshot, a fresh UI hierarchy XML, and a device log scoped to the exact application PID. Verify the lease again after all captures. The screenshot and hierarchy must prove the same final state.
10
+ 6. Review spacing, padding, clipping, overlap, alignment, and the specific visual complaint. Separately review visible user-facing copy against the frozen criterion. Link both reviews to exact evidence IDs.
11
+ 7. Write every artifact below the runner-provided proof directory. Mark the UI hierarchy, device log, and lease record `publishable: false`. Mark a screenshot publishable only when it contains no credential, secret, private user path, or unrelated account data. Never place serials, application IDs, PIDs, lease tokens, local paths, credential bytes, authorization data, environment values, or user-owned device data in the publishable receipt.
12
+ 8. Build the exact generated Proof Report. Each Android criterion must reference both screenshot and hierarchy evidence. Visual evidence must include workflow entrypoint/steps/final state, Android capture dimensions, device-log ref, lease ref, `capturedAfterFinalInteraction: true`, and evidence-linked layout/copy reviews.
13
+
14
+ The runner releases the lease after terminal proof settlement. Do not release it early. A screenshot alone, missing hierarchy/log/lease, stale evidence, changed application PID, guessed interaction, rewritten criterion, unanalysed image, or secret-bearing artifact cannot pass. Return `needs-rework` for product defects and a typed `external-block` only for genuinely unavailable emulator/tool/service authority.
@@ -0,0 +1,13 @@
1
+ # Browser Proof Procedure
2
+
3
+ Use browser proof only when at least one frozen criterion describes user-visible web behavior or when the checked diff changes that behavior. Keep the exact frozen criterion IDs and declare `decision.mode: visual`, target `browser`, and a `browser` surface for each applicable criterion.
4
+
5
+ 1. Identify the real local application or fixture entrypoint and the complete user workflow required by the criterion. Do not substitute a nearby route, first reachable screen, static file, or unrelated demo.
6
+ 2. Launch a real browser against HTTP(S). Complete the workflow through its final interaction and assert the requested final state from live DOM text/state.
7
+ 3. Repeat the final workflow at one desktop width of at least 1024 pixels and one narrow responsive width of at most 480 pixels. Capture a fresh screenshot and DOM-state JSON after the last interaction at each viewport.
8
+ 4. Record browser console errors and failed network requests in separate JSON files even when both lists are empty.
9
+ 5. Review spacing, padding, clipping, overlap, alignment, responsive reflow, and the specific visual complaint. Separately review visible user-facing copy against the frozen criterion. Link each finding to the exact evidence IDs used.
10
+ 6. Write every artifact below the runner-provided proof directory. Mark screenshots publishable only when they contain no credential, secret, private user path, or unrelated account data. Mark DOM, console, and network artifacts `publishable: false`. Never include credential bytes, authorization headers, environment values, cookies, storage state, or local auth paths.
11
+ 7. Build the exact generated Proof Report. Each browser criterion must reference both screenshot and DOM evidence at every required viewport. The visual evidence must include workflow entrypoint/steps/final state, viewport captures, console/network refs, `capturedAfterFinalInteraction: true`, and evidence-linked layout/copy reviews.
12
+
13
+ A screenshot by itself, stale file, one viewport, missing DOM/diagnostics, irrelevant route, rewritten criterion, unanalysed image, or secret-bearing artifact cannot pass. Return `needs-rework` for product behavior defects and a typed `external-block` only for genuinely unavailable browser tooling or service authority.
@@ -0,0 +1,14 @@
1
+ # iOS Proof Procedure
2
+
3
+ Use iOS proof only when a frozen criterion describes user-visible iOS behavior or the checked diff changes that behavior. Keep exact criterion IDs and declare `decision.mode: visual`, target `ios`, and an `ios` surface for each applicable criterion.
4
+
5
+ 1. Perform read-only Xcode/Simulator discovery. If any Simulator is already booted or Flutter, VM Service, XCTest, Simulator UI, or IDE ownership is ambiguous, return a typed tool blocker without mutation.
6
+ 2. Acquire the lease with the exact immutable helper, lease root, artifact, proof ID, bundle ID, owner PID, xcrun path, runtime ID, and device-type ID supplied by the runner. The helper creates a new proof-bound Simulator after durable intent. Never select, boot, install into, or delete an existing device; never use the `booted` alias.
7
+ 3. Boot, build, install, and launch only through the returned UDID. Bind the exact bundle/process with the helper before accepting evidence. Every later `simctl` or test command must contain that literal UDID.
8
+ 4. Complete the workflow with XCUITest or an equivalent accessibility driver. Select controls by accessibility identity or hierarchy, never guessed coordinates. Capture pre/final accessibility hierarchy and prove the requested final state from live accessibility text/state.
9
+ 5. While the exact final app process remains live, capture a fresh Simulator PNG and process-scoped Simulator log, then verify the same lease/app/process again. Broad logs are forbidden.
10
+ 6. Review spacing, padding, clipping, overlap, alignment, and the specific visual complaint. Separately review visible copy against the frozen criterion and link both reviews to exact evidence IDs.
11
+ 7. Write artifacts only below the proof directory. Keep hierarchy, logs, and lease local-only. A screenshot may be publishable only when it contains no credential, secret, private path, or unrelated account data. Keep UDID, bundle/process identity, lease token, raw logs, and local paths out of publishable results.
12
+ 8. Emit the exact generated Proof Report with screenshot plus hierarchy linked to every iOS criterion, process-log and lease refs, workflow/final state, post-interaction freshness, and evidence-linked layout/copy reviews.
13
+
14
+ The runner reconciles shutdown/delete and releases the lease after terminal proof settlement. Do not release early. Screenshot-only, stale, unleased, target-drifted, guessed-interaction, broad-log, rewritten-criterion, or secret-bearing evidence cannot pass.
@@ -0,0 +1,280 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFile } from 'node:child_process';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { lstat, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
6
+ import { dirname, join, resolve } from 'node:path';
7
+ import { promisify } from 'node:util';
8
+
9
+ const execFileAsync = promisify(execFile);
10
+ const LEASE_FILE = 'android.json';
11
+ const LEASE_MS = 15 * 60 * 1000;
12
+
13
+ class Blocked extends Error {}
14
+
15
+ try {
16
+ const [command, ...argv] = process.argv.slice(2);
17
+ const args = parseArgs(argv);
18
+ const result = await execute(command, args);
19
+ process.stdout.write(`${JSON.stringify(result)}\n`);
20
+ } catch (error) {
21
+ const blocked = error instanceof Blocked;
22
+ process.stdout.write(`${JSON.stringify({
23
+ status: blocked ? 'blocked' : 'internal-error',
24
+ reason: blocked ? error.message : 'Android lease helper failed internally.',
25
+ })}\n`);
26
+ process.exitCode = blocked ? 20 : 70;
27
+ }
28
+
29
+ async function execute(command, args) {
30
+ const leaseRoot = requiredPath(args['lease-root'], 'lease root');
31
+ const artifactPath = requiredPath(args.artifact, 'lease artifact');
32
+ const proofId = requiredString(args['proof-id'], 'proof ID');
33
+ const adb = args.adb
34
+ ? requiredPath(args.adb, 'adb path')
35
+ : process.env.ANDROID_ADB || join(process.env.HOME || '', 'Library', 'Android', 'sdk', 'platform-tools', 'adb');
36
+ const now = parseNow();
37
+ await ensureDirectDirectory(leaseRoot);
38
+ await ensureDirectDirectory(dirname(artifactPath));
39
+ const leasePath = join(leaseRoot, LEASE_FILE);
40
+
41
+ if (command === 'acquire') {
42
+ const appId = requiredAppId(args['app-id']);
43
+ const ownerPid = requiredPid(args['owner-pid']);
44
+ const target = await selectEmulator(adb);
45
+ const existing = await readLease(leasePath);
46
+ if (existing) {
47
+ if (existing.proofId === proofId && existing.appId === appId && existing.ownerPid === ownerPid) {
48
+ await verifyTarget(adb, existing, false);
49
+ return publicResult('reused', existing);
50
+ }
51
+ if (!(Date.parse(existing.expiresAt) < now.getTime() && !pidAlive(existing.ownerPid))) {
52
+ throw new Blocked('An active foreign Android lease already exists.');
53
+ }
54
+ if (existing.serial !== target.serial || existing.appId !== appId) {
55
+ throw new Blocked('A stale Android lease does not match the requested target identity.');
56
+ }
57
+ await rm(leasePath);
58
+ }
59
+ const livePid = await appPid(adb, target.serial, appId);
60
+ if (livePid !== undefined) throw new Blocked('The requested Android app already has a user-owned live process.');
61
+ const lease = {
62
+ schema: 'codex-orchestrator.android-lease',
63
+ version: 1,
64
+ status: 'active',
65
+ proofId,
66
+ token: randomUUID(),
67
+ serial: target.serial,
68
+ appId,
69
+ ownerPid,
70
+ appPid: null,
71
+ acquiredAt: now.toISOString(),
72
+ expiresAt: new Date(now.getTime() + LEASE_MS).toISOString(),
73
+ updatedAt: now.toISOString(),
74
+ };
75
+ await createExclusiveJson(leasePath, lease);
76
+ await writeAtomicJson(artifactPath, lease);
77
+ return publicResult('acquired', lease);
78
+ }
79
+
80
+ const token = requiredString(args.token, 'lease token');
81
+ const lease = await requireOwnedLease(leasePath, proofId, token, now);
82
+ if (command === 'bind') {
83
+ await verifyTarget(adb, lease, false, true);
84
+ const pid = await appPid(adb, lease.serial, lease.appId);
85
+ if (pid === undefined) throw new Blocked('The leased Android app is not running.');
86
+ const bound = { ...lease, appPid: pid, updatedAt: now.toISOString() };
87
+ await replaceJson(leasePath, bound);
88
+ await writeAtomicJson(artifactPath, bound);
89
+ return publicResult('bound', bound);
90
+ }
91
+ if (command === 'verify') {
92
+ await verifyTarget(adb, lease, true);
93
+ await writeAtomicJson(artifactPath, { ...lease, updatedAt: now.toISOString() });
94
+ return publicResult('verified', lease);
95
+ }
96
+ if (command === 'release') {
97
+ await verifyTarget(adb, lease, Number.isSafeInteger(lease.appPid));
98
+ const released = { ...lease, status: 'released', updatedAt: now.toISOString() };
99
+ await writeAtomicJson(artifactPath, released);
100
+ await rm(leasePath);
101
+ await syncDirectory(dirname(leasePath));
102
+ return publicResult('released', released);
103
+ }
104
+ throw new Blocked('Unknown Android lease command.');
105
+ }
106
+
107
+ async function selectEmulator(adb) {
108
+ const output = await adbCommand(adb, ['devices', '-l']);
109
+ const rows = output.stdout.split(/\r?\n/u).slice(1).map((line) => line.trim()).filter(Boolean).map((line) => {
110
+ const [serial, state] = line.split(/\s+/u);
111
+ return { serial, state };
112
+ });
113
+ if (rows.some((row) => !row.serial.startsWith('emulator-'))) throw new Blocked('Physical Android devices are not eligible for runner leases.');
114
+ if (rows.length !== 1 || rows[0].state !== 'device') throw new Blocked('Exactly one online Android emulator is required.');
115
+ const boot = await adbCommand(adb, ['-s', rows[0].serial, 'shell', 'getprop', 'sys.boot_completed']);
116
+ if (boot.stdout.trim() !== '1') throw new Blocked('The Android emulator has not completed boot.');
117
+ return rows[0];
118
+ }
119
+
120
+ async function verifyTarget(adb, lease, requireBoundApp, allowUnboundLive = false) {
121
+ const target = await selectEmulator(adb);
122
+ if (target.serial !== lease.serial) throw new Blocked('The leased Android emulator identity changed.');
123
+ const currentPid = await appPid(adb, lease.serial, lease.appId);
124
+ if (requireBoundApp) {
125
+ if (!Number.isSafeInteger(lease.appPid) || currentPid !== lease.appPid) {
126
+ throw new Blocked('The leased Android app PID changed or disappeared.');
127
+ }
128
+ } else if (!allowUnboundLive && lease.appPid === null && currentPid !== undefined) {
129
+ throw new Blocked('The leased Android app became live before runner binding.');
130
+ }
131
+ }
132
+
133
+ async function appPid(adb, serial, appId) {
134
+ const result = await adbCommand(adb, ['-s', serial, 'shell', 'pidof', '-s', appId], true);
135
+ const value = result.stdout.trim();
136
+ if (!value) return undefined;
137
+ const pid = Number(value);
138
+ if (!Number.isSafeInteger(pid) || pid < 1) throw new Blocked('Android app PID observation is invalid.');
139
+ return pid;
140
+ }
141
+
142
+ async function adbCommand(adb, args, allowFailure = false) {
143
+ try {
144
+ return await execFileAsync(adb, args, { timeout: 15_000, maxBuffer: 1024 * 1024, env: process.env });
145
+ } catch (error) {
146
+ if (allowFailure && typeof error === 'object' && error !== null && 'stdout' in error) {
147
+ return { stdout: String(error.stdout || ''), stderr: String(error.stderr || '') };
148
+ }
149
+ throw new Blocked('Android tooling did not return a usable target observation.');
150
+ }
151
+ }
152
+
153
+ function parseArgs(argv) {
154
+ const result = {};
155
+ for (let index = 0; index < argv.length; index += 1) {
156
+ const arg = argv[index];
157
+ if (!arg.startsWith('--')) throw new Blocked('Android lease arguments are invalid.');
158
+ const equals = arg.indexOf('=');
159
+ if (equals > 2) {
160
+ result[arg.slice(2, equals)] = arg.slice(equals + 1);
161
+ continue;
162
+ }
163
+ const value = argv[++index];
164
+ if (!value || value.startsWith('--')) throw new Blocked('Android lease argument value is missing.');
165
+ result[arg.slice(2)] = value;
166
+ }
167
+ return result;
168
+ }
169
+
170
+ function parseNow() {
171
+ const value = process.env.CODEX_ORCHESTRATOR_NOW || new Date().toISOString();
172
+ const date = new Date(value);
173
+ if (Number.isNaN(date.getTime()) || date.toISOString() !== value) throw new Error('invalid lease clock');
174
+ return date;
175
+ }
176
+
177
+ async function requireOwnedLease(path, proofId, token, now) {
178
+ const lease = await readLease(path);
179
+ if (!lease || lease.proofId !== proofId || lease.token !== token) throw new Blocked('Android lease ownership does not match.');
180
+ if (lease.status !== 'active' || Date.parse(lease.expiresAt) < now.getTime()) throw new Blocked('Android lease is not active.');
181
+ return lease;
182
+ }
183
+
184
+ async function readLease(path) {
185
+ try {
186
+ return validateLease(JSON.parse(await readFile(path, 'utf8')));
187
+ } catch (error) {
188
+ if (typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') return undefined;
189
+ throw new Blocked('Android lease state is malformed.');
190
+ }
191
+ }
192
+
193
+ function validateLease(value) {
194
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('invalid lease');
195
+ const keys = ['schema', 'version', 'status', 'proofId', 'token', 'serial', 'appId', 'ownerPid', 'appPid', 'acquiredAt', 'expiresAt', 'updatedAt'].sort();
196
+ const actual = Object.keys(value).sort();
197
+ if (actual.length !== keys.length || actual.some((key, index) => key !== keys[index])) throw new Error('invalid lease keys');
198
+ if (value.schema !== 'codex-orchestrator.android-lease' || value.version !== 1 || !['active', 'released'].includes(value.status)) throw new Error('invalid lease schema');
199
+ requiredString(value.proofId, 'proof ID');
200
+ requiredString(value.token, 'token');
201
+ if (!/^emulator-[0-9]+$/u.test(value.serial)) throw new Error('invalid serial');
202
+ requiredAppId(value.appId);
203
+ requiredPid(value.ownerPid);
204
+ if (value.appPid !== null) requiredPid(value.appPid);
205
+ for (const field of ['acquiredAt', 'expiresAt', 'updatedAt']) {
206
+ if (new Date(value[field]).toISOString() !== value[field]) throw new Error('invalid lease timestamp');
207
+ }
208
+ return value;
209
+ }
210
+
211
+ async function ensureDirectDirectory(path) {
212
+ const absolute = resolve(path);
213
+ await mkdir(absolute, { recursive: true, mode: 0o700 });
214
+ const info = await lstat(absolute);
215
+ if (!info.isDirectory() || info.isSymbolicLink()) throw new Error('unsafe lease directory');
216
+ }
217
+
218
+ async function createExclusiveJson(path, value) {
219
+ const handle = await open(path, 'wx', 0o600);
220
+ try {
221
+ await handle.writeFile(`${JSON.stringify(value)}\n`);
222
+ await handle.sync();
223
+ } finally {
224
+ await handle.close();
225
+ }
226
+ await syncDirectory(dirname(path));
227
+ }
228
+
229
+ async function replaceJson(path, value) {
230
+ await writeAtomicJson(path, value);
231
+ }
232
+
233
+ async function writeAtomicJson(path, value) {
234
+ const temp = `${path}.tmp-${process.pid}-${randomUUID()}`;
235
+ const handle = await open(temp, 'wx', 0o600);
236
+ try {
237
+ await handle.writeFile(`${JSON.stringify(value)}\n`);
238
+ await handle.sync();
239
+ } finally {
240
+ await handle.close();
241
+ }
242
+ await rename(temp, path);
243
+ await syncDirectory(dirname(path));
244
+ }
245
+
246
+ async function syncDirectory(path) {
247
+ const handle = await open(path, 'r');
248
+ try { await handle.sync(); } finally { await handle.close(); }
249
+ }
250
+
251
+ function publicResult(status, lease) {
252
+ return { status, proofId: lease.proofId, token: lease.token, serial: lease.serial, appId: lease.appId, appPid: lease.appPid, expiresAt: lease.expiresAt };
253
+ }
254
+
255
+ function requiredPath(value, field) {
256
+ const text = requiredString(value, field);
257
+ if (!text.startsWith('/')) throw new Blocked(`${field} must be absolute.`);
258
+ return resolve(text);
259
+ }
260
+
261
+ function requiredString(value, field) {
262
+ if (typeof value !== 'string' || value.length === 0 || value.length > 4096) throw new Blocked(`${field} is invalid.`);
263
+ return value;
264
+ }
265
+
266
+ function requiredAppId(value) {
267
+ const text = requiredString(value, 'app ID');
268
+ if (!/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/u.test(text)) throw new Blocked('Android app ID is invalid.');
269
+ return text;
270
+ }
271
+
272
+ function requiredPid(value) {
273
+ const pid = Number(value);
274
+ if (!Number.isSafeInteger(pid) || pid < 1) throw new Blocked('Android owner PID is invalid.');
275
+ return pid;
276
+ }
277
+
278
+ function pidAlive(pid) {
279
+ try { process.kill(pid, 0); return true; } catch (error) { return error?.code === 'EPERM'; }
280
+ }
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFile } from 'node:child_process';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { lstat, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
6
+ import { dirname, join, resolve } from 'node:path';
7
+ import { promisify } from 'node:util';
8
+
9
+ const execFileAsync = promisify(execFile);
10
+ const LEASE_FILE = 'ios.json';
11
+ const LEASE_MS = 20 * 60 * 1000;
12
+ const UDID_PATTERN = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/iu;
13
+
14
+ class Blocked extends Error {}
15
+
16
+ try {
17
+ const [command, ...argv] = process.argv.slice(2);
18
+ const args = parseArgs(argv);
19
+ const result = await execute(command, args);
20
+ process.stdout.write(`${JSON.stringify(result)}\n`);
21
+ } catch (error) {
22
+ const blocked = error instanceof Blocked;
23
+ process.stdout.write(`${JSON.stringify({
24
+ status: blocked ? 'blocked' : 'internal-error',
25
+ reason: blocked ? error.message : 'iOS lease helper failed internally.',
26
+ })}\n`);
27
+ process.exitCode = blocked ? 20 : 70;
28
+ }
29
+
30
+ async function execute(command, args) {
31
+ const leaseRoot = requiredPath(args['lease-root'], 'lease root');
32
+ const artifactPath = requiredPath(args.artifact, 'lease artifact');
33
+ const proofId = requiredString(args['proof-id'], 'proof ID');
34
+ const xcrun = requiredPath(args.xcrun || '/usr/bin/xcrun', 'xcrun path');
35
+ const now = parseNow();
36
+ await ensureDirectDirectory(leaseRoot);
37
+ await ensureDirectDirectory(dirname(artifactPath));
38
+ const leasePath = join(leaseRoot, LEASE_FILE);
39
+
40
+ if (command === 'acquire') {
41
+ const bundleId = requiredBundleId(args['bundle-id']);
42
+ const ownerPid = requiredPid(args['owner-pid']);
43
+ const runtimeId = requiredIdentifier(args.runtime, 'runtime ID', 'com.apple.CoreSimulator.SimRuntime.');
44
+ const deviceTypeId = requiredIdentifier(args['device-type'], 'device type ID', 'com.apple.CoreSimulator.SimDeviceType.');
45
+ const existing = await readLease(leasePath);
46
+ const booted = await listDevices(xcrun, 'booted');
47
+ if (booted.some((device) => device.udid !== existing?.udid)) {
48
+ throw new Blocked('A user-owned booted Simulator session already exists.');
49
+ }
50
+ if (existing) {
51
+ if (existing.status === 'active' && existing.proofId === proofId && existing.bundleId === bundleId
52
+ && existing.ownerPid === ownerPid && Date.parse(existing.expiresAt) >= now.getTime()) {
53
+ await requireRecordedTarget(xcrun, existing, false);
54
+ return publicResult('reused', existing);
55
+ }
56
+ if (!(Date.parse(existing.expiresAt) < now.getTime() && !pidAlive(existing.ownerPid))) {
57
+ throw new Blocked('An active foreign iOS lease already exists.');
58
+ }
59
+ await cleanupRecordedTarget(xcrun, existing);
60
+ await rm(leasePath);
61
+ await syncDirectory(dirname(leasePath));
62
+ }
63
+ if (booted.length !== 0) throw new Blocked('A booted Simulator appeared before lease acquisition.');
64
+
65
+ const deviceName = `Codex ${proofId}`;
66
+ const preparing = {
67
+ schema: 'codex-orchestrator.ios-lease', version: 1, status: 'preparing', proofId, token: randomUUID(),
68
+ udid: null, deviceName, bundleId, ownerPid, appPid: null, runtimeId, deviceTypeId, runnerCreated: true,
69
+ acquiredAt: now.toISOString(), expiresAt: new Date(now.getTime() + LEASE_MS).toISOString(), updatedAt: now.toISOString(),
70
+ };
71
+ await createExclusiveJson(leasePath, preparing);
72
+ let createdUdid;
73
+ try {
74
+ const created = await simctl(xcrun, ['create', deviceName, deviceTypeId, runtimeId]);
75
+ createdUdid = created.stdout.trim();
76
+ if (!UDID_PATTERN.test(createdUdid)) throw new Blocked('simctl create returned an invalid Simulator identity.');
77
+ const active = { ...preparing, status: 'active', udid: createdUdid, updatedAt: now.toISOString() };
78
+ await replaceJson(leasePath, active);
79
+ await writeAtomicJson(artifactPath, active);
80
+ return publicResult('acquired', active);
81
+ } catch (error) {
82
+ if (createdUdid && UDID_PATTERN.test(createdUdid)) await simctl(xcrun, ['delete', createdUdid], true);
83
+ await rm(leasePath, { force: true });
84
+ await syncDirectory(dirname(leasePath));
85
+ throw error;
86
+ }
87
+ }
88
+
89
+ const token = requiredString(args.token, 'lease token');
90
+ const lease = await requireOwnedLease(leasePath, proofId, token, now);
91
+ if (command === 'bind') {
92
+ const appPid = requiredPid(args['app-pid']);
93
+ await verifyAppTarget(xcrun, lease, appPid);
94
+ const bound = { ...lease, appPid, updatedAt: now.toISOString() };
95
+ await replaceJson(leasePath, bound);
96
+ await writeAtomicJson(artifactPath, bound);
97
+ return publicResult('bound', bound);
98
+ }
99
+ if (command === 'verify') {
100
+ if (!Number.isSafeInteger(lease.appPid)) throw new Blocked('The iOS lease is not bound to an app process.');
101
+ await verifyAppTarget(xcrun, lease, lease.appPid);
102
+ await writeAtomicJson(artifactPath, { ...lease, updatedAt: now.toISOString() });
103
+ return publicResult('verified', lease);
104
+ }
105
+ if (command === 'release') {
106
+ await cleanupRecordedTarget(xcrun, lease, true);
107
+ const released = { ...lease, status: 'released', updatedAt: now.toISOString() };
108
+ await writeAtomicJson(artifactPath, released);
109
+ await rm(leasePath);
110
+ await syncDirectory(dirname(leasePath));
111
+ return publicResult('released', released);
112
+ }
113
+ throw new Blocked('Unknown iOS lease command.');
114
+ }
115
+
116
+ async function listDevices(xcrun, scope = 'all') {
117
+ const args = scope === 'booted' ? ['list', 'devices', 'booted', '-j'] : ['list', 'devices', '-j'];
118
+ const result = await simctl(xcrun, args);
119
+ let parsed;
120
+ try { parsed = JSON.parse(result.stdout); } catch { throw new Blocked('simctl device inventory is malformed.'); }
121
+ return Object.values(parsed.devices || {}).flat().filter((device) => device && device.isAvailable !== false).map((device) => ({
122
+ udid: device.udid, name: device.name, state: device.state,
123
+ }));
124
+ }
125
+
126
+ async function requireRecordedTarget(xcrun, lease, requireBooted) {
127
+ if (!lease.runnerCreated || !UDID_PATTERN.test(String(lease.udid))) throw new Blocked('The iOS lease lacks a runner-created target.');
128
+ const matches = (await listDevices(xcrun)).filter((device) => device.udid === lease.udid);
129
+ if (matches.length !== 1) throw new Blocked('The leased Simulator identity is absent or ambiguous.');
130
+ if (requireBooted && matches[0].state !== 'Booted') throw new Blocked('The leased Simulator is not booted.');
131
+ return matches[0];
132
+ }
133
+
134
+ async function verifyAppTarget(xcrun, lease, appPid) {
135
+ await requireRecordedTarget(xcrun, lease, true);
136
+ const container = (await simctl(xcrun, ['get_app_container', lease.udid, lease.bundleId, 'app'])).stdout.trim();
137
+ if (!container.endsWith('.app') || container.includes('\n')) throw new Blocked('The leased iOS app container is invalid.');
138
+ const services = (await simctl(xcrun, ['spawn', lease.udid, 'launchctl', 'list'])).stdout;
139
+ const matches = services.split(/\r?\n/u).map((line) => /^\s*(\d+)\s+\S+\s+UIKitApplication:([^[]+)\[/u.exec(line))
140
+ .filter((match) => match && match[2] === lease.bundleId);
141
+ if (matches.length !== 1 || Number(matches[0][1]) !== appPid) {
142
+ throw new Blocked('The leased iOS app PID changed or does not match its bundle container.');
143
+ }
144
+ }
145
+
146
+ async function cleanupRecordedTarget(xcrun, lease, allowAbsent = false) {
147
+ if (!lease.runnerCreated) throw new Blocked('Only runner-created Simulators may be released.');
148
+ const devices = await listDevices(xcrun);
149
+ let matches = lease.udid
150
+ ? devices.filter((device) => device.udid === lease.udid)
151
+ : devices.filter((device) => device.name === lease.deviceName);
152
+ if (matches.length === 0 && allowAbsent) return;
153
+ if (matches.length !== 1 || !UDID_PATTERN.test(matches[0].udid)) throw new Blocked('Runner-created Simulator cleanup identity is absent or ambiguous.');
154
+ if (matches[0].state === 'Booted') await simctl(xcrun, ['shutdown', matches[0].udid]);
155
+ await simctl(xcrun, ['delete', matches[0].udid]);
156
+ matches = (await listDevices(xcrun)).filter((device) => device.udid === matches[0].udid);
157
+ if (matches.length !== 0) throw new Blocked('Runner-created Simulator deletion was not confirmed.');
158
+ }
159
+
160
+ async function simctl(xcrun, args, allowFailure = false) {
161
+ try {
162
+ return await execFileAsync(xcrun, ['simctl', ...args], { timeout: 20_000, maxBuffer: 1024 * 1024, env: process.env });
163
+ } catch (error) {
164
+ if (allowFailure) return { stdout: '', stderr: '' };
165
+ throw new Blocked('iOS Simulator tooling did not return a usable target observation.');
166
+ }
167
+ }
168
+
169
+ function parseArgs(argv) {
170
+ const result = {};
171
+ for (let index = 0; index < argv.length; index += 1) {
172
+ const arg = argv[index];
173
+ if (!arg.startsWith('--')) throw new Blocked('iOS lease arguments are invalid.');
174
+ const equals = arg.indexOf('=');
175
+ if (equals > 2) { result[arg.slice(2, equals)] = arg.slice(equals + 1); continue; }
176
+ const value = argv[++index];
177
+ if (!value || value.startsWith('--')) throw new Blocked('iOS lease argument value is missing.');
178
+ result[arg.slice(2)] = value;
179
+ }
180
+ return result;
181
+ }
182
+
183
+ function parseNow() {
184
+ const value = process.env.CODEX_ORCHESTRATOR_NOW || new Date().toISOString();
185
+ const date = new Date(value);
186
+ if (Number.isNaN(date.getTime()) || date.toISOString() !== value) throw new Error('invalid lease clock');
187
+ return date;
188
+ }
189
+
190
+ async function requireOwnedLease(path, proofId, token, now) {
191
+ const lease = await readLease(path);
192
+ if (!lease || lease.status !== 'active' || lease.proofId !== proofId || lease.token !== token) throw new Blocked('iOS lease ownership does not match.');
193
+ if (Date.parse(lease.expiresAt) < now.getTime()) throw new Blocked('iOS lease is not active.');
194
+ return lease;
195
+ }
196
+
197
+ async function readLease(path) {
198
+ try { return validateLease(JSON.parse(await readFile(path, 'utf8'))); }
199
+ catch (error) {
200
+ if (error?.code === 'ENOENT') return undefined;
201
+ throw new Blocked('iOS lease state is malformed.');
202
+ }
203
+ }
204
+
205
+ function validateLease(value) {
206
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('invalid lease');
207
+ const keys = ['schema', 'version', 'status', 'proofId', 'token', 'udid', 'deviceName', 'bundleId', 'ownerPid', 'appPid', 'runtimeId', 'deviceTypeId', 'runnerCreated', 'acquiredAt', 'expiresAt', 'updatedAt'].sort();
208
+ const actual = Object.keys(value).sort();
209
+ if (actual.length !== keys.length || actual.some((key, index) => key !== keys[index])) throw new Error('invalid lease keys');
210
+ if (value.schema !== 'codex-orchestrator.ios-lease' || value.version !== 1 || !['preparing', 'active', 'released'].includes(value.status)) throw new Error('invalid lease schema');
211
+ requiredString(value.proofId, 'proof ID');
212
+ requiredString(value.token, 'token');
213
+ requiredString(value.deviceName, 'device name');
214
+ requiredBundleId(value.bundleId);
215
+ requiredPid(value.ownerPid);
216
+ if (value.appPid !== null) requiredPid(value.appPid);
217
+ requiredIdentifier(value.runtimeId, 'runtime ID', 'com.apple.CoreSimulator.SimRuntime.');
218
+ requiredIdentifier(value.deviceTypeId, 'device type ID', 'com.apple.CoreSimulator.SimDeviceType.');
219
+ if (value.runnerCreated !== true) throw new Error('invalid runner ownership');
220
+ if (value.status === 'preparing' ? value.udid !== null : !UDID_PATTERN.test(String(value.udid))) throw new Error('invalid UDID');
221
+ for (const field of ['acquiredAt', 'expiresAt', 'updatedAt']) if (new Date(value[field]).toISOString() !== value[field]) throw new Error('invalid timestamp');
222
+ return value;
223
+ }
224
+
225
+ async function ensureDirectDirectory(path) {
226
+ const absolute = resolve(path);
227
+ await mkdir(absolute, { recursive: true, mode: 0o700 });
228
+ const info = await lstat(absolute);
229
+ if (!info.isDirectory() || info.isSymbolicLink()) throw new Error('unsafe lease directory');
230
+ }
231
+
232
+ async function createExclusiveJson(path, value) {
233
+ const handle = await open(path, 'wx', 0o600);
234
+ try { await handle.writeFile(`${JSON.stringify(value)}\n`); await handle.sync(); } finally { await handle.close(); }
235
+ await syncDirectory(dirname(path));
236
+ }
237
+
238
+ async function replaceJson(path, value) { await writeAtomicJson(path, value); }
239
+
240
+ async function writeAtomicJson(path, value) {
241
+ const temp = `${path}.tmp-${process.pid}-${randomUUID()}`;
242
+ const handle = await open(temp, 'wx', 0o600);
243
+ try { await handle.writeFile(`${JSON.stringify(value)}\n`); await handle.sync(); } finally { await handle.close(); }
244
+ await rename(temp, path);
245
+ await syncDirectory(dirname(path));
246
+ }
247
+
248
+ async function syncDirectory(path) {
249
+ const handle = await open(path, 'r');
250
+ try { await handle.sync(); } finally { await handle.close(); }
251
+ }
252
+
253
+ function publicResult(status, lease) {
254
+ return { status, proofId: lease.proofId, token: lease.token, udid: lease.udid, bundleId: lease.bundleId, appPid: lease.appPid, expiresAt: lease.expiresAt };
255
+ }
256
+
257
+ function requiredPath(value, field) {
258
+ const text = requiredString(value, field);
259
+ if (!text.startsWith('/')) throw new Blocked(`${field} must be absolute.`);
260
+ return resolve(text);
261
+ }
262
+
263
+ function requiredString(value, field) {
264
+ if (typeof value !== 'string' || value.length === 0 || value.length > 4096) throw new Blocked(`${field} is invalid.`);
265
+ return value;
266
+ }
267
+
268
+ function requiredIdentifier(value, field, prefix) {
269
+ const text = requiredString(value, field);
270
+ if (!text.startsWith(prefix) || !/^[A-Za-z0-9.-]+$/u.test(text)) throw new Blocked(`${field} is invalid.`);
271
+ return text;
272
+ }
273
+
274
+ function requiredBundleId(value) {
275
+ const text = requiredString(value, 'bundle ID');
276
+ if (!/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/u.test(text)) throw new Blocked('iOS bundle ID is invalid.');
277
+ return text;
278
+ }
279
+
280
+ function requiredPid(value) {
281
+ const pid = Number(value);
282
+ if (!Number.isSafeInteger(pid) || pid < 1) throw new Blocked('iOS process ID is invalid.');
283
+ return pid;
284
+ }
285
+
286
+ function pidAlive(pid) {
287
+ try { process.kill(pid, 0); return true; } catch (error) { return error?.code === 'EPERM'; }
288
+ }
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: agent-auto
3
+ description: Implement one prepared GitHub issue inside the runner-owned worktree and return a typed implementation report.
4
+ ---
5
+
6
+ # Agent Auto
7
+
8
+ Implement one issue end to end inside the prepared worktree. Treat the supplied issue snapshot, frozen acceptance criteria, repository instructions, and runner-provided output schema as authoritative.
9
+
10
+ Inspect the repository, choose the smallest complete strategy, and use native Codex subagents when useful. Apply TDD for behavior changes, run focused validation, repair failures that are within the issue scope, and leave the worktree ready for independent acceptance proof.
11
+
12
+ The runner owns authorization and every external effect. Do not commit, push, open or edit a pull request, mutate GitHub labels/comments, publish packages, deploy, or use external credentials. Do not copy or print credential bytes or auth/secret paths. If completion depends on a credential, unavailable tool/service, or product decision, return the typed external blocker instead of widening authority.
13
+
14
+ Return only the JSON object required by the exact output schema supplied by the runner. Do not add prose around the report and do not independently restate or modify its fields.