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,703 @@
1
+ import { posix } from 'node:path';
2
+ import { agentReportEnvelopeSchema } from './report-envelope.js';
3
+ const MAX_STRING_LENGTH = 16 * 1024;
4
+ const MAX_SUMMARY_LENGTH = 4 * 1024;
5
+ const MAX_ARRAY_LENGTH = 256;
6
+ const SHA256_PATTERN = /^[0-9a-f]{64}$/;
7
+ const SURFACES = ['non-visual', 'browser', 'android', 'ios'];
8
+ const TARGETS = ['browser', 'android', 'ios'];
9
+ const ARTIFACT_KINDS = [
10
+ 'command-output', 'static-inspection', 'generated-file', 'screenshot',
11
+ 'dom-snapshot', 'console-log', 'network-log', 'ui-hierarchy', 'device-log', 'lease-record',
12
+ ];
13
+ export function validateProofReport(value) {
14
+ assertRecord(value, 'proof report');
15
+ const commonKeys = ['version', 'status', 'decision', 'criteria', 'checks', 'artifacts', 'findings', 'residualRisks'];
16
+ const visualReport = value.status !== 'external-block' && isRecord(value.decision) && value.decision.mode === 'visual';
17
+ if (value.status === 'passed' || value.status === 'needs-rework') {
18
+ assertExactObject(value, visualReport ? [...commonKeys, 'visualEvidence'] : commonKeys, 'proof report');
19
+ }
20
+ else if (value.status === 'external-block') {
21
+ assertExactObject(value, [...commonKeys, 'blocker'], 'proof report');
22
+ }
23
+ else {
24
+ throw new Error('proof report.status is invalid');
25
+ }
26
+ if (value.version !== 1)
27
+ throw new Error('proof report.version must be 1');
28
+ validateDecision(value.decision);
29
+ validateCriteria(value.criteria, value.status);
30
+ validateChecks(value.checks, value.status);
31
+ validateArtifacts(value.artifacts);
32
+ assertStringArray(value.findings, 'proof report.findings');
33
+ assertStringArray(value.residualRisks, 'proof report.residualRisks');
34
+ if (value.status === 'passed' && value.findings.length !== 0)
35
+ throw new Error('passed proof report forbids findings');
36
+ if (value.status === 'needs-rework' && value.findings.length === 0)
37
+ throw new Error('needs-rework proof report requires findings');
38
+ if (value.status === 'external-block')
39
+ validateExternalBlocker(value.blocker, 'proof report.blocker');
40
+ const decision = value.decision;
41
+ const criteria = value.criteria;
42
+ if (decision.mode === 'non-visual') {
43
+ if (criteria.some((criterion) => criterion.surfaces.some((surface) => surface !== 'non-visual'))) {
44
+ throw new Error('non-visual proof may use only non-visual criterion surfaces');
45
+ }
46
+ }
47
+ else {
48
+ const available = new Set(['non-visual', ...decision.targets]);
49
+ if (criteria.some((criterion) => criterion.surfaces.some((surface) => !available.has(surface)))) {
50
+ throw new Error('visual proof criterion surface is absent from decision targets');
51
+ }
52
+ }
53
+ if (visualReport) {
54
+ validateVisualEvidence(value.visualEvidence, criteria, value.artifacts, decision);
55
+ }
56
+ const evidenceIds = new Set([
57
+ ...value.checks.map((check) => check.id),
58
+ ...value.artifacts.map((artifact) => artifact.id),
59
+ ]);
60
+ for (const criterion of criteria) {
61
+ for (const ref of criterion.evidenceRefs) {
62
+ if (!evidenceIds.has(ref))
63
+ throw new Error(`criterion ${criterion.id} references unknown evidence ${ref}`);
64
+ }
65
+ if (value.status === 'passed' && criterion.evidenceRefs.length < criterion.surfaces.length) {
66
+ throw new Error(`passed criterion ${criterion.id} lacks evidence for every surface`);
67
+ }
68
+ }
69
+ return value;
70
+ }
71
+ export function createProofReceipt(input) {
72
+ assertBoundedString(input.proofId, 'proofId', MAX_STRING_LENGTH, true);
73
+ assertSha256(input.bindingSha256, 'bindingSha256');
74
+ assertBoundedString(input.summary, 'summary', MAX_SUMMARY_LENGTH, true);
75
+ assertBoundedString(input.localEvidenceId, 'localEvidenceId', MAX_STRING_LENGTH, true);
76
+ const report = validateProofReport(input.report);
77
+ return {
78
+ proofId: input.proofId,
79
+ bindingSha256: input.bindingSha256,
80
+ summary: input.summary,
81
+ publishableEvidence: report.artifacts
82
+ .filter((artifact) => artifact.publishable)
83
+ .map((artifact) => ({
84
+ ref: artifact.id,
85
+ kind: artifact.kind === 'screenshot' ? 'screenshot' : 'summary',
86
+ sha256: artifact.sha256,
87
+ description: artifact.description,
88
+ })),
89
+ localEvidenceId: input.localEvidenceId,
90
+ };
91
+ }
92
+ export function proofReportOutputSchema() {
93
+ return agentReportEnvelopeSchema({
94
+ type: 'object',
95
+ additionalProperties: false,
96
+ required: [
97
+ 'version', 'status', 'decision', 'criteria', 'checks', 'artifacts',
98
+ 'visualEvidence', 'findings', 'residualRisks', 'blocker',
99
+ ],
100
+ properties: {
101
+ version: { type: 'integer', const: 1 },
102
+ status: { type: 'string', enum: ['passed', 'needs-rework', 'external-block'] },
103
+ decision: decisionSchema(),
104
+ criteria: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: criterionSchema(false) },
105
+ checks: { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: checkSchema(false) },
106
+ artifacts: { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: artifactSchema() },
107
+ visualEvidence: {
108
+ anyOf: [browserVisualEvidenceSchema(), androidVisualEvidenceSchema(), iosVisualEvidenceSchema(), { type: 'null' }],
109
+ },
110
+ findings: stringArraySchema(),
111
+ residualRisks: stringArraySchema(),
112
+ blocker: { anyOf: [externalBlockerSchema(), { type: 'null' }] },
113
+ },
114
+ });
115
+ }
116
+ export function proofReportRepairDiagnostic(error) {
117
+ const detail = error instanceof Error ? error.message : 'unknown validation failure';
118
+ return `Return one complete JSON object matching the supplied proof output schema. Validation failed: ${detail}`;
119
+ }
120
+ export function proofReportSkillExcerpt() {
121
+ return 'Independently prove the frozen criteria and return only the JSON object required by the runner-supplied output schema. Do not edit product code, publish, or include credential/path material.';
122
+ }
123
+ function decisionSchema() {
124
+ return {
125
+ anyOf: [
126
+ nonVisualDecisionSchema(),
127
+ {
128
+ type: 'object',
129
+ additionalProperties: false,
130
+ required: ['mode', 'targets'],
131
+ properties: {
132
+ mode: { type: 'string', const: 'visual' },
133
+ targets: { type: 'array', minItems: 1, maxItems: TARGETS.length, items: { type: 'string', enum: TARGETS } },
134
+ },
135
+ },
136
+ ],
137
+ };
138
+ }
139
+ function nonVisualDecisionSchema() {
140
+ return {
141
+ type: 'object',
142
+ additionalProperties: false,
143
+ required: ['mode', 'targets'],
144
+ properties: {
145
+ mode: { type: 'string', const: 'non-visual' },
146
+ targets: { type: 'array', maxItems: 0, items: { type: 'string', enum: TARGETS } },
147
+ },
148
+ };
149
+ }
150
+ function browserDecisionSchema() {
151
+ return {
152
+ type: 'object',
153
+ additionalProperties: false,
154
+ required: ['mode', 'targets'],
155
+ properties: {
156
+ mode: { type: 'string', const: 'visual' },
157
+ targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'browser' } },
158
+ },
159
+ };
160
+ }
161
+ function androidDecisionSchema() {
162
+ return {
163
+ type: 'object',
164
+ additionalProperties: false,
165
+ required: ['mode', 'targets'],
166
+ properties: {
167
+ mode: { type: 'string', const: 'visual' },
168
+ targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'android' } },
169
+ },
170
+ };
171
+ }
172
+ function iosDecisionSchema() {
173
+ return {
174
+ type: 'object',
175
+ additionalProperties: false,
176
+ required: ['mode', 'targets'],
177
+ properties: {
178
+ mode: { type: 'string', const: 'visual' },
179
+ targets: { type: 'array', minItems: 1, maxItems: 1, items: { type: 'string', const: 'ios' } },
180
+ },
181
+ };
182
+ }
183
+ function criterionSchema(passed) {
184
+ return {
185
+ type: 'object',
186
+ additionalProperties: false,
187
+ required: ['id', 'status', 'confidence', 'surfaces', 'evidenceRefs', 'analysis'],
188
+ properties: {
189
+ id: boundedStringSchema(MAX_STRING_LENGTH),
190
+ status: passed ? { type: 'string', const: 'passed' } : { type: 'string', enum: ['passed', 'failed', 'unknown'] },
191
+ confidence: passed ? { type: 'string', const: 'high' } : { type: 'string', enum: ['high', 'medium', 'low'] },
192
+ surfaces: { type: 'array', minItems: 1, maxItems: SURFACES.length, items: { type: 'string', enum: SURFACES } },
193
+ evidenceRefs: {
194
+ type: 'array',
195
+ minItems: passed ? 1 : 0,
196
+ maxItems: MAX_ARRAY_LENGTH,
197
+ items: boundedStringSchema(MAX_STRING_LENGTH),
198
+ },
199
+ analysis: boundedStringSchema(MAX_SUMMARY_LENGTH),
200
+ },
201
+ };
202
+ }
203
+ function checkSchema(passed) {
204
+ return {
205
+ type: 'object',
206
+ additionalProperties: false,
207
+ required: ['id', 'command', 'status', 'summary', 'outputSha256'],
208
+ properties: {
209
+ id: boundedStringSchema(MAX_STRING_LENGTH),
210
+ command: boundedStringSchema(MAX_STRING_LENGTH),
211
+ status: passed ? { type: 'string', const: 'passed' } : { type: 'string', enum: ['passed', 'failed'] },
212
+ summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
213
+ outputSha256: sha256Schema(),
214
+ },
215
+ };
216
+ }
217
+ function artifactSchema() {
218
+ return {
219
+ type: 'object',
220
+ additionalProperties: false,
221
+ required: ['id', 'kind', 'relativePath', 'sha256', 'publishable', 'description'],
222
+ properties: {
223
+ id: boundedStringSchema(MAX_STRING_LENGTH),
224
+ kind: { type: 'string', enum: ARTIFACT_KINDS },
225
+ relativePath: relativePathSchema(),
226
+ sha256: sha256Schema(),
227
+ publishable: { type: 'boolean' },
228
+ description: boundedStringSchema(MAX_SUMMARY_LENGTH),
229
+ },
230
+ };
231
+ }
232
+ function browserVisualEvidenceSchema() {
233
+ const reviewSchema = {
234
+ type: 'array',
235
+ minItems: 1,
236
+ maxItems: MAX_ARRAY_LENGTH,
237
+ items: {
238
+ type: 'object',
239
+ additionalProperties: false,
240
+ required: ['summary', 'evidenceRefs'],
241
+ properties: {
242
+ summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
243
+ evidenceRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
244
+ },
245
+ },
246
+ };
247
+ return {
248
+ type: 'object',
249
+ additionalProperties: false,
250
+ required: ['workflow', 'captures', 'diagnostics', 'freshness', 'layoutReview', 'copyReview'],
251
+ properties: {
252
+ workflow: {
253
+ type: 'object', additionalProperties: false, required: ['entrypoint', 'steps', 'finalState'],
254
+ properties: {
255
+ entrypoint: boundedStringSchema(MAX_STRING_LENGTH),
256
+ steps: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
257
+ finalState: boundedStringSchema(MAX_SUMMARY_LENGTH),
258
+ },
259
+ },
260
+ captures: {
261
+ type: 'array', minItems: 2, maxItems: MAX_ARRAY_LENGTH,
262
+ items: {
263
+ type: 'object', additionalProperties: false,
264
+ required: ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'],
265
+ properties: {
266
+ target: { type: 'string', const: 'browser' },
267
+ name: boundedStringSchema(MAX_STRING_LENGTH),
268
+ width: { type: 'integer' },
269
+ height: { type: 'integer' },
270
+ criteriaRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
271
+ screenshotRef: boundedStringSchema(MAX_STRING_LENGTH),
272
+ stateRef: boundedStringSchema(MAX_STRING_LENGTH),
273
+ },
274
+ },
275
+ },
276
+ diagnostics: {
277
+ type: 'object', additionalProperties: false, required: ['consoleRef', 'networkRef'],
278
+ properties: { consoleRef: boundedStringSchema(MAX_STRING_LENGTH), networkRef: boundedStringSchema(MAX_STRING_LENGTH) },
279
+ },
280
+ freshness: {
281
+ type: 'object', additionalProperties: false, required: ['capturedAfterFinalInteraction'],
282
+ properties: { capturedAfterFinalInteraction: { type: 'boolean', const: true } },
283
+ },
284
+ layoutReview: reviewSchema,
285
+ copyReview: reviewSchema,
286
+ },
287
+ };
288
+ }
289
+ function androidVisualEvidenceSchema() {
290
+ return mobileVisualEvidenceSchema('android');
291
+ }
292
+ function iosVisualEvidenceSchema() {
293
+ return mobileVisualEvidenceSchema('ios');
294
+ }
295
+ function mobileVisualEvidenceSchema(target) {
296
+ const reviewSchema = {
297
+ type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH,
298
+ items: {
299
+ type: 'object', additionalProperties: false, required: ['summary', 'evidenceRefs'],
300
+ properties: {
301
+ summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
302
+ evidenceRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
303
+ },
304
+ },
305
+ };
306
+ return {
307
+ type: 'object',
308
+ additionalProperties: false,
309
+ required: ['workflow', 'captures', 'diagnostics', 'lease', 'freshness', 'layoutReview', 'copyReview'],
310
+ properties: {
311
+ workflow: {
312
+ type: 'object', additionalProperties: false, required: ['entrypoint', 'steps', 'finalState'],
313
+ properties: {
314
+ entrypoint: boundedStringSchema(MAX_STRING_LENGTH),
315
+ steps: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
316
+ finalState: boundedStringSchema(MAX_SUMMARY_LENGTH),
317
+ },
318
+ },
319
+ captures: {
320
+ type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH,
321
+ items: {
322
+ type: 'object', additionalProperties: false,
323
+ required: ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'],
324
+ properties: {
325
+ target: { type: 'string', const: target },
326
+ name: boundedStringSchema(MAX_STRING_LENGTH),
327
+ width: { type: 'integer' },
328
+ height: { type: 'integer' },
329
+ criteriaRefs: { type: 'array', minItems: 1, maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) },
330
+ screenshotRef: boundedStringSchema(MAX_STRING_LENGTH),
331
+ stateRef: boundedStringSchema(MAX_STRING_LENGTH),
332
+ },
333
+ },
334
+ },
335
+ diagnostics: {
336
+ type: 'object', additionalProperties: false, required: ['deviceLogRef'],
337
+ properties: { deviceLogRef: boundedStringSchema(MAX_STRING_LENGTH) },
338
+ },
339
+ lease: {
340
+ type: 'object', additionalProperties: false, required: ['leaseRef'],
341
+ properties: { leaseRef: boundedStringSchema(MAX_STRING_LENGTH) },
342
+ },
343
+ freshness: {
344
+ type: 'object', additionalProperties: false, required: ['capturedAfterFinalInteraction'],
345
+ properties: { capturedAfterFinalInteraction: { type: 'boolean', const: true } },
346
+ },
347
+ layoutReview: reviewSchema,
348
+ copyReview: reviewSchema,
349
+ },
350
+ };
351
+ }
352
+ function validateDecision(value) {
353
+ assertExactObject(value, ['mode', 'targets'], 'proof report.decision');
354
+ if (value.mode !== 'non-visual' && value.mode !== 'visual')
355
+ throw new Error('proof report.decision.mode is invalid');
356
+ assertEnumArray(value.targets, TARGETS, 'proof report.decision.targets');
357
+ if (value.mode === 'non-visual' && value.targets.length !== 0)
358
+ throw new Error('non-visual decision forbids targets');
359
+ if (value.mode === 'visual' && value.targets.length === 0)
360
+ throw new Error('visual decision requires targets');
361
+ }
362
+ function validateCriteria(value, reportStatus) {
363
+ if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ARRAY_LENGTH) {
364
+ throw new Error('proof report.criteria must contain 1 to 256 entries');
365
+ }
366
+ const ids = [];
367
+ for (const [index, criterion] of value.entries()) {
368
+ const field = `proof report.criteria[${index}]`;
369
+ assertExactObject(criterion, ['id', 'status', 'confidence', 'surfaces', 'evidenceRefs', 'analysis'], field);
370
+ assertBoundedString(criterion.id, `${field}.id`, MAX_STRING_LENGTH, true);
371
+ if (!['passed', 'failed', 'unknown'].includes(criterion.status))
372
+ throw new Error(`${field}.status is invalid`);
373
+ if (!['high', 'medium', 'low'].includes(criterion.confidence))
374
+ throw new Error(`${field}.confidence is invalid`);
375
+ assertEnumArray(criterion.surfaces, SURFACES, `${field}.surfaces`, true);
376
+ assertStringArray(criterion.evidenceRefs, `${field}.evidenceRefs`);
377
+ assertUnique(criterion.evidenceRefs, `${field}.evidenceRefs`);
378
+ assertBoundedString(criterion.analysis, `${field}.analysis`, MAX_SUMMARY_LENGTH, true);
379
+ if (reportStatus === 'passed' && (criterion.status !== 'passed' || criterion.confidence !== 'high')) {
380
+ throw new Error('passed proof requires every criterion passed with high confidence');
381
+ }
382
+ if (reportStatus === 'passed' && criterion.evidenceRefs.length === 0) {
383
+ throw new Error('passed proof requires criterion evidence');
384
+ }
385
+ ids.push(criterion.id);
386
+ }
387
+ assertUnique(ids, 'proof report.criteria ids');
388
+ }
389
+ function validateChecks(value, reportStatus) {
390
+ if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
391
+ throw new Error('proof report.checks must contain at most 256 entries');
392
+ const ids = [];
393
+ for (const [index, check] of value.entries()) {
394
+ const field = `proof report.checks[${index}]`;
395
+ assertExactObject(check, ['id', 'command', 'status', 'summary', 'outputSha256'], field);
396
+ assertBoundedString(check.id, `${field}.id`, MAX_STRING_LENGTH, true);
397
+ assertBoundedString(check.command, `${field}.command`, MAX_STRING_LENGTH, true);
398
+ if (check.status !== 'passed' && check.status !== 'failed')
399
+ throw new Error(`${field}.status is invalid`);
400
+ if (reportStatus === 'passed' && check.status !== 'passed')
401
+ throw new Error('passed proof forbids failed checks');
402
+ assertBoundedString(check.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
403
+ assertSha256(check.outputSha256, `${field}.outputSha256`);
404
+ ids.push(check.id);
405
+ }
406
+ assertUnique(ids, 'proof report.check ids');
407
+ }
408
+ function validateArtifacts(value) {
409
+ if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
410
+ throw new Error('proof report.artifacts must contain at most 256 entries');
411
+ const ids = [];
412
+ for (const [index, artifact] of value.entries()) {
413
+ const field = `proof report.artifacts[${index}]`;
414
+ assertExactObject(artifact, ['id', 'kind', 'relativePath', 'sha256', 'publishable', 'description'], field);
415
+ assertBoundedString(artifact.id, `${field}.id`, MAX_STRING_LENGTH, true);
416
+ if (!ARTIFACT_KINDS.includes(artifact.kind)) {
417
+ throw new Error(`${field}.kind is invalid`);
418
+ }
419
+ assertRelativePath(artifact.relativePath, `${field}.relativePath`);
420
+ assertSha256(artifact.sha256, `${field}.sha256`);
421
+ if (typeof artifact.publishable !== 'boolean')
422
+ throw new Error(`${field}.publishable must be boolean`);
423
+ if (artifact.publishable && artifact.kind !== 'screenshot' && artifact.kind !== 'generated-file') {
424
+ throw new Error('only screenshots or sanitized generated summaries may be publishable');
425
+ }
426
+ if (['dom-snapshot', 'console-log', 'network-log', 'ui-hierarchy', 'device-log', 'lease-record'].includes(artifact.kind)
427
+ && artifact.publishable !== false) {
428
+ throw new Error(`${field}.kind must remain local-only`);
429
+ }
430
+ assertBoundedString(artifact.description, `${field}.description`, MAX_SUMMARY_LENGTH, true);
431
+ ids.push(artifact.id);
432
+ }
433
+ assertUnique(ids, 'proof report.artifact ids');
434
+ }
435
+ function validateVisualEvidence(value, criteria, artifacts, decision) {
436
+ if (decision.targets.length !== 1)
437
+ throw new Error('visual proof requires one settled platform target');
438
+ if (decision.targets[0] === 'browser')
439
+ return validateBrowserVisualEvidence(value, criteria, artifacts, decision);
440
+ if (decision.targets[0] === 'android')
441
+ return validateAndroidVisualEvidence(value, criteria, artifacts, decision);
442
+ if (decision.targets[0] === 'ios')
443
+ return validateIosVisualEvidence(value, criteria, artifacts, decision);
444
+ throw new Error('visual proof target is not implemented');
445
+ }
446
+ function validateBrowserVisualEvidence(value, criteria, artifacts, decision) {
447
+ if (decision.targets.length !== 1 || decision.targets[0] !== 'browser') {
448
+ throw new Error('Spec 3 visual proof supports the browser target only');
449
+ }
450
+ assertExactObject(value, ['workflow', 'captures', 'diagnostics', 'freshness', 'layoutReview', 'copyReview'], 'proof report.visualEvidence');
451
+ assertExactObject(value.workflow, ['entrypoint', 'steps', 'finalState'], 'proof report.visualEvidence.workflow');
452
+ assertBoundedString(value.workflow.entrypoint, 'proof report.visualEvidence.workflow.entrypoint', MAX_STRING_LENGTH, true);
453
+ if (!/^https?:\/\//u.test(value.workflow.entrypoint))
454
+ throw new Error('visual workflow entrypoint must be HTTP(S)');
455
+ assertStringArray(value.workflow.steps, 'proof report.visualEvidence.workflow.steps');
456
+ if (value.workflow.steps.length === 0)
457
+ throw new Error('visual workflow requires steps');
458
+ assertBoundedString(value.workflow.finalState, 'proof report.visualEvidence.workflow.finalState', MAX_SUMMARY_LENGTH, true);
459
+ const artifactById = new Map(artifacts.map((artifact) => [artifact.id, artifact]));
460
+ const browserCriteria = criteria.filter((criterion) => criterion.surfaces.includes('browser'));
461
+ const browserCriterionIds = new Set(browserCriteria.map((criterion) => criterion.id));
462
+ if (browserCriteria.length === 0)
463
+ throw new Error('browser decision requires a browser criterion surface');
464
+ if (!Array.isArray(value.captures) || value.captures.length < 2 || value.captures.length > MAX_ARRAY_LENGTH) {
465
+ throw new Error('browser visual evidence requires at least two captures');
466
+ }
467
+ const captureNames = [];
468
+ for (const [index, capture] of value.captures.entries()) {
469
+ const field = `proof report.visualEvidence.captures[${index}]`;
470
+ assertExactObject(capture, ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'], field);
471
+ if (capture.target !== 'browser')
472
+ throw new Error(`${field}.target must be browser`);
473
+ assertBoundedString(capture.name, `${field}.name`, MAX_STRING_LENGTH, true);
474
+ if (!Number.isSafeInteger(capture.width) || !Number.isSafeInteger(capture.height)
475
+ || capture.width < 1 || capture.height < 1
476
+ || capture.width > 10_000 || capture.height > 10_000) {
477
+ throw new Error(`${field} dimensions are invalid`);
478
+ }
479
+ assertStringArray(capture.criteriaRefs, `${field}.criteriaRefs`);
480
+ assertUnique(capture.criteriaRefs, `${field}.criteriaRefs`);
481
+ if (capture.criteriaRefs.length === 0 || capture.criteriaRefs.some((id) => !browserCriterionIds.has(id))) {
482
+ throw new Error(`${field} has irrelevant criterion mapping`);
483
+ }
484
+ for (const criterionId of browserCriterionIds) {
485
+ if (!capture.criteriaRefs.includes(criterionId))
486
+ throw new Error(`${field} omits browser criterion ${criterionId}`);
487
+ }
488
+ assertBoundedString(capture.screenshotRef, `${field}.screenshotRef`, MAX_STRING_LENGTH, true);
489
+ assertBoundedString(capture.stateRef, `${field}.stateRef`, MAX_STRING_LENGTH, true);
490
+ const screenshot = artifactById.get(capture.screenshotRef);
491
+ const state = artifactById.get(capture.stateRef);
492
+ if (screenshot?.kind !== 'screenshot')
493
+ throw new Error(`${field} lacks screenshot evidence`);
494
+ if (state?.kind !== 'dom-snapshot')
495
+ throw new Error(`${field} lacks DOM state evidence`);
496
+ for (const criterionId of capture.criteriaRefs) {
497
+ const criterion = browserCriteria.find((candidate) => candidate.id === criterionId);
498
+ if (!criterion.evidenceRefs.includes(screenshot.id) || !criterion.evidenceRefs.includes(state.id)) {
499
+ throw new Error(`${field} evidence is not linked to criterion ${criterionId}`);
500
+ }
501
+ }
502
+ captureNames.push(capture.name);
503
+ }
504
+ assertUnique(captureNames, 'proof report.visualEvidence capture names');
505
+ if (!value.captures.some((capture) => capture.width >= 1024)) {
506
+ throw new Error('browser visual evidence lacks desktop coverage');
507
+ }
508
+ if (!value.captures.some((capture) => capture.width <= 480)) {
509
+ throw new Error('browser visual evidence lacks narrow responsive coverage');
510
+ }
511
+ assertExactObject(value.diagnostics, ['consoleRef', 'networkRef'], 'proof report.visualEvidence.diagnostics');
512
+ if (artifactById.get(value.diagnostics.consoleRef)?.kind !== 'console-log') {
513
+ throw new Error('browser visual evidence lacks console diagnostics');
514
+ }
515
+ if (artifactById.get(value.diagnostics.networkRef)?.kind !== 'network-log') {
516
+ throw new Error('browser visual evidence lacks network diagnostics');
517
+ }
518
+ assertExactObject(value.freshness, ['capturedAfterFinalInteraction'], 'proof report.visualEvidence.freshness');
519
+ if (value.freshness.capturedAfterFinalInteraction !== true)
520
+ throw new Error('browser evidence is not post-interaction');
521
+ validateVisualReview(value.layoutReview, 'layoutReview', artifactById);
522
+ validateVisualReview(value.copyReview, 'copyReview', artifactById);
523
+ }
524
+ function validateAndroidVisualEvidence(value, criteria, artifacts, decision) {
525
+ validateMobileVisualEvidence(value, criteria, artifacts, decision, 'android');
526
+ }
527
+ function validateIosVisualEvidence(value, criteria, artifacts, decision) {
528
+ validateMobileVisualEvidence(value, criteria, artifacts, decision, 'ios');
529
+ }
530
+ function validateMobileVisualEvidence(value, criteria, artifacts, decision, target) {
531
+ if (decision.targets.length !== 1 || decision.targets[0] !== target)
532
+ throw new Error(`${target} visual target mismatch`);
533
+ assertExactObject(value, ['workflow', 'captures', 'diagnostics', 'lease', 'freshness', 'layoutReview', 'copyReview'], 'proof report.visualEvidence');
534
+ assertExactObject(value.workflow, ['entrypoint', 'steps', 'finalState'], 'proof report.visualEvidence.workflow');
535
+ assertBoundedString(value.workflow.entrypoint, 'proof report.visualEvidence.workflow.entrypoint', MAX_STRING_LENGTH, true);
536
+ assertStringArray(value.workflow.steps, 'proof report.visualEvidence.workflow.steps');
537
+ if (value.workflow.steps.length === 0)
538
+ throw new Error(`${target} visual workflow requires steps`);
539
+ assertBoundedString(value.workflow.finalState, 'proof report.visualEvidence.workflow.finalState', MAX_SUMMARY_LENGTH, true);
540
+ const artifactById = new Map(artifacts.map((artifact) => [artifact.id, artifact]));
541
+ const androidCriteria = criteria.filter((criterion) => criterion.surfaces.includes(target));
542
+ const androidCriterionIds = new Set(androidCriteria.map((criterion) => criterion.id));
543
+ if (androidCriteria.length === 0)
544
+ throw new Error(`${target} decision requires a ${target} criterion surface`);
545
+ if (!Array.isArray(value.captures) || value.captures.length === 0 || value.captures.length > MAX_ARRAY_LENGTH) {
546
+ throw new Error(`${target} visual evidence requires a capture`);
547
+ }
548
+ const captureNames = [];
549
+ for (const [index, capture] of value.captures.entries()) {
550
+ const field = `proof report.visualEvidence.captures[${index}]`;
551
+ assertExactObject(capture, ['target', 'name', 'width', 'height', 'criteriaRefs', 'screenshotRef', 'stateRef'], field);
552
+ if (capture.target !== target)
553
+ throw new Error(`${field}.target must be ${target}`);
554
+ assertBoundedString(capture.name, `${field}.name`, MAX_STRING_LENGTH, true);
555
+ if (!Number.isSafeInteger(capture.width) || !Number.isSafeInteger(capture.height)
556
+ || capture.width < 1 || capture.height < 1
557
+ || capture.width > 10_000 || capture.height > 10_000) {
558
+ throw new Error(`${field} dimensions are invalid`);
559
+ }
560
+ assertStringArray(capture.criteriaRefs, `${field}.criteriaRefs`);
561
+ assertUnique(capture.criteriaRefs, `${field}.criteriaRefs`);
562
+ if (capture.criteriaRefs.length === 0 || capture.criteriaRefs.some((id) => !androidCriterionIds.has(id))) {
563
+ throw new Error(`${field} has irrelevant criterion mapping`);
564
+ }
565
+ for (const criterionId of androidCriterionIds) {
566
+ if (!capture.criteriaRefs.includes(criterionId))
567
+ throw new Error(`${field} omits ${target} criterion ${criterionId}`);
568
+ }
569
+ assertBoundedString(capture.screenshotRef, `${field}.screenshotRef`, MAX_STRING_LENGTH, true);
570
+ assertBoundedString(capture.stateRef, `${field}.stateRef`, MAX_STRING_LENGTH, true);
571
+ const screenshot = artifactById.get(capture.screenshotRef);
572
+ const hierarchy = artifactById.get(capture.stateRef);
573
+ if (screenshot?.kind !== 'screenshot')
574
+ throw new Error(`${field} lacks screenshot evidence`);
575
+ if (hierarchy?.kind !== 'ui-hierarchy')
576
+ throw new Error(`${field} lacks UI hierarchy evidence`);
577
+ for (const criterionId of capture.criteriaRefs) {
578
+ const criterion = androidCriteria.find((candidate) => candidate.id === criterionId);
579
+ if (!criterion.evidenceRefs.includes(screenshot.id) || !criterion.evidenceRefs.includes(hierarchy.id)) {
580
+ throw new Error(`${field} evidence is not linked to criterion ${criterionId}`);
581
+ }
582
+ }
583
+ captureNames.push(capture.name);
584
+ }
585
+ assertUnique(captureNames, 'proof report.visualEvidence capture names');
586
+ assertExactObject(value.diagnostics, ['deviceLogRef'], 'proof report.visualEvidence.diagnostics');
587
+ if (artifactById.get(value.diagnostics.deviceLogRef)?.kind !== 'device-log') {
588
+ throw new Error(`${target} visual evidence lacks device log diagnostics`);
589
+ }
590
+ assertExactObject(value.lease, ['leaseRef'], 'proof report.visualEvidence.lease');
591
+ if (artifactById.get(value.lease.leaseRef)?.kind !== 'lease-record') {
592
+ throw new Error(`${target} visual evidence lacks lease record`);
593
+ }
594
+ assertExactObject(value.freshness, ['capturedAfterFinalInteraction'], 'proof report.visualEvidence.freshness');
595
+ if (value.freshness.capturedAfterFinalInteraction !== true)
596
+ throw new Error(`${target} evidence is not post-interaction`);
597
+ validateVisualReview(value.layoutReview, 'layoutReview', artifactById);
598
+ validateVisualReview(value.copyReview, 'copyReview', artifactById);
599
+ }
600
+ function validateVisualReview(value, fieldName, artifactById) {
601
+ if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ARRAY_LENGTH) {
602
+ throw new Error(`proof report.visualEvidence.${fieldName} must be non-empty`);
603
+ }
604
+ for (const [index, finding] of value.entries()) {
605
+ const field = `proof report.visualEvidence.${fieldName}[${index}]`;
606
+ assertExactObject(finding, ['summary', 'evidenceRefs'], field);
607
+ assertBoundedString(finding.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
608
+ assertStringArray(finding.evidenceRefs, `${field}.evidenceRefs`);
609
+ assertUnique(finding.evidenceRefs, `${field}.evidenceRefs`);
610
+ if (finding.evidenceRefs.length === 0 || finding.evidenceRefs.some((ref) => !artifactById.has(ref))) {
611
+ throw new Error(`${field} has invalid evidence references`);
612
+ }
613
+ }
614
+ }
615
+ function validateExternalBlocker(value, field) {
616
+ assertExactObject(value, ['kind', 'summary', 'attempted'], field);
617
+ if (!['credential', 'tool', 'service', 'product-decision'].includes(value.kind))
618
+ throw new Error(`${field}.kind is invalid`);
619
+ assertBoundedString(value.summary, `${field}.summary`, MAX_SUMMARY_LENGTH, true);
620
+ assertStringArray(value.attempted, `${field}.attempted`);
621
+ }
622
+ function externalBlockerSchema() {
623
+ return {
624
+ type: 'object',
625
+ additionalProperties: false,
626
+ required: ['kind', 'summary', 'attempted'],
627
+ properties: {
628
+ kind: { type: 'string', enum: ['credential', 'tool', 'service', 'product-decision'] },
629
+ summary: boundedStringSchema(MAX_SUMMARY_LENGTH),
630
+ attempted: stringArraySchema(),
631
+ },
632
+ };
633
+ }
634
+ function stringArraySchema() {
635
+ return { type: 'array', maxItems: MAX_ARRAY_LENGTH, items: boundedStringSchema(MAX_STRING_LENGTH) };
636
+ }
637
+ function boundedStringSchema(maxLength) {
638
+ return { type: 'string', minLength: 1, maxLength };
639
+ }
640
+ function sha256Schema() {
641
+ return { type: 'string', pattern: '^[0-9a-f]{64}$' };
642
+ }
643
+ function relativePathSchema() {
644
+ return {
645
+ type: 'string',
646
+ minLength: 1,
647
+ maxLength: MAX_STRING_LENGTH,
648
+ pattern: '^[^/\\\\]$|^[^/\\\\][^\\\\]*[^/\\\\]$',
649
+ };
650
+ }
651
+ function assertRelativePath(value, field) {
652
+ assertBoundedString(value, field, MAX_STRING_LENGTH, true);
653
+ if (value.startsWith('/') || value.includes('\\') || posix.normalize(value) !== value) {
654
+ throw new Error(`${field} must be a normalized repository-relative POSIX path`);
655
+ }
656
+ const segments = value.split('/');
657
+ if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
658
+ throw new Error(`${field} must not contain empty, dot, or dot-dot segments`);
659
+ }
660
+ }
661
+ function assertEnumArray(value, allowed, field, requireNonEmpty = false) {
662
+ if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH || (requireNonEmpty && value.length === 0)) {
663
+ throw new Error(`${field} has invalid length`);
664
+ }
665
+ if (value.some((item) => typeof item !== 'string' || !allowed.includes(item)))
666
+ throw new Error(`${field} has invalid entries`);
667
+ assertUnique(value, field);
668
+ }
669
+ function assertStringArray(value, field) {
670
+ if (!Array.isArray(value) || value.length > MAX_ARRAY_LENGTH)
671
+ throw new Error(`${field} must contain at most 256 strings`);
672
+ for (const item of value)
673
+ assertBoundedString(item, `${field} entry`, MAX_STRING_LENGTH, true);
674
+ }
675
+ function assertUnique(values, field) {
676
+ if (new Set(values).size !== values.length)
677
+ throw new Error(`${field} must be unique`);
678
+ }
679
+ function assertSha256(value, field) {
680
+ if (typeof value !== 'string' || !SHA256_PATTERN.test(value))
681
+ throw new Error(`${field} must be lowercase SHA-256`);
682
+ }
683
+ function assertBoundedString(value, field, maxLength, requireNonEmpty) {
684
+ if (typeof value !== 'string' || value.length > maxLength || (requireNonEmpty && value.length === 0)) {
685
+ throw new Error(`${field} must be a bounded string`);
686
+ }
687
+ }
688
+ function assertRecord(value, field) {
689
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
690
+ throw new Error(`${field} must be an object`);
691
+ }
692
+ function isRecord(value) {
693
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
694
+ }
695
+ function assertExactObject(value, keys, field) {
696
+ assertRecord(value, field);
697
+ const actual = Object.keys(value).sort();
698
+ const expected = [...keys].sort();
699
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
700
+ throw new Error(`${field} has unknown or missing keys`);
701
+ }
702
+ }
703
+ //# sourceMappingURL=proof-report.js.map