agent-hitch 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/README.md +14 -1
  2. package/dist/scripts/canary-buildkit-secrets.js +166 -0
  3. package/dist/scripts/canary-buildkit-secrets.js.map +1 -0
  4. package/dist/scripts/canary-collision-domains.js +77 -0
  5. package/dist/scripts/canary-collision-domains.js.map +1 -0
  6. package/dist/scripts/canary-docker-image-observation.js +181 -0
  7. package/dist/scripts/canary-docker-image-observation.js.map +1 -0
  8. package/dist/scripts/canary-gpu-hardware.js +95 -0
  9. package/dist/scripts/canary-gpu-hardware.js.map +1 -0
  10. package/dist/scripts/canary-harbor-load.js +365 -0
  11. package/dist/scripts/canary-harbor-load.js.map +1 -0
  12. package/dist/scripts/canary-packaged-harness.js +75 -0
  13. package/dist/scripts/canary-packaged-harness.js.map +1 -0
  14. package/dist/scripts/canary-resource-load.js +188 -0
  15. package/dist/scripts/canary-resource-load.js.map +1 -0
  16. package/dist/scripts/check-architecture.js +8 -4
  17. package/dist/scripts/check-architecture.js.map +1 -1
  18. package/dist/scripts/docker-reaper-crash-child.js +21 -0
  19. package/dist/scripts/docker-reaper-crash-child.js.map +1 -0
  20. package/dist/src/adapters/catalog.js +1 -0
  21. package/dist/src/adapters/catalog.js.map +1 -1
  22. package/dist/src/adapters/discovery.js +1 -1
  23. package/dist/src/adapters/discovery.js.map +1 -1
  24. package/dist/src/adapters/providers/claude.js +6 -0
  25. package/dist/src/adapters/providers/claude.js.map +1 -1
  26. package/dist/src/adapters/providers/codex.js +6 -0
  27. package/dist/src/adapters/providers/codex.js.map +1 -1
  28. package/dist/src/adapters/providers/deepseek.js +6 -0
  29. package/dist/src/adapters/providers/deepseek.js.map +1 -1
  30. package/dist/src/adapters/providers/opencode.js +6 -0
  31. package/dist/src/adapters/providers/opencode.js.map +1 -1
  32. package/dist/src/adapters/providers/pi.js +6 -0
  33. package/dist/src/adapters/providers/pi.js.map +1 -1
  34. package/dist/src/artifacts/index.js +1 -0
  35. package/dist/src/artifacts/index.js.map +1 -1
  36. package/dist/src/backends/harbor/backend.js +55 -104
  37. package/dist/src/backends/harbor/backend.js.map +1 -1
  38. package/dist/src/backends/harbor/environment-config.js +92 -0
  39. package/dist/src/backends/harbor/environment-config.js.map +1 -0
  40. package/dist/src/backends/harbor/index.js +5 -1
  41. package/dist/src/backends/harbor/index.js.map +1 -1
  42. package/dist/src/backends/harbor/model-proxy-config.js +23 -0
  43. package/dist/src/backends/harbor/model-proxy-config.js.map +1 -0
  44. package/dist/src/backends/harbor/process.js +177 -0
  45. package/dist/src/backends/harbor/process.js.map +1 -0
  46. package/dist/src/backends/harbor/runtime-toolchain.js +30 -0
  47. package/dist/src/backends/harbor/runtime-toolchain.js.map +1 -0
  48. package/dist/src/backends/harbor/supervisor.js +74 -0
  49. package/dist/src/backends/harbor/supervisor.js.map +1 -0
  50. package/dist/src/backends/harbor/task-resources.js +206 -0
  51. package/dist/src/backends/harbor/task-resources.js.map +1 -0
  52. package/dist/src/backends/harbor/tools.js +6 -29
  53. package/dist/src/backends/harbor/tools.js.map +1 -1
  54. package/dist/src/backends/harbor/verifier-config.js +11 -0
  55. package/dist/src/backends/harbor/verifier-config.js.map +1 -0
  56. package/dist/src/backends/index.js +4 -1
  57. package/dist/src/backends/index.js.map +1 -1
  58. package/dist/src/cli/arguments.js +14 -0
  59. package/dist/src/cli/arguments.js.map +1 -1
  60. package/dist/src/cli/commands/daemon.js +135 -8
  61. package/dist/src/cli/commands/daemon.js.map +1 -1
  62. package/dist/src/cli/commands/eval.js +214 -4
  63. package/dist/src/cli/commands/eval.js.map +1 -1
  64. package/dist/src/cli/commands/images.js +40 -0
  65. package/dist/src/cli/commands/images.js.map +1 -0
  66. package/dist/src/cli/commands/run.js +6 -3
  67. package/dist/src/cli/commands/run.js.map +1 -1
  68. package/dist/src/cli/commands/runs.js +25 -3
  69. package/dist/src/cli/commands/runs.js.map +1 -1
  70. package/dist/src/cli/commands/worker.js +79 -0
  71. package/dist/src/cli/commands/worker.js.map +1 -0
  72. package/dist/src/cli/main.js +4 -0
  73. package/dist/src/cli/main.js.map +1 -1
  74. package/dist/src/cli/output.js +72 -3
  75. package/dist/src/cli/output.js.map +1 -1
  76. package/dist/src/control-plane/build-admission.js +69 -0
  77. package/dist/src/control-plane/build-admission.js.map +1 -0
  78. package/dist/src/control-plane/build-records.js +6 -0
  79. package/dist/src/control-plane/build-records.js.map +1 -0
  80. package/dist/src/control-plane/collisions.js +40 -0
  81. package/dist/src/control-plane/collisions.js.map +1 -0
  82. package/dist/src/control-plane/eval-control-state.js +22 -0
  83. package/dist/src/control-plane/eval-control-state.js.map +1 -0
  84. package/dist/src/control-plane/eval-control-work.js +39 -0
  85. package/dist/src/control-plane/eval-control-work.js.map +1 -0
  86. package/dist/src/control-plane/eval-image-resolution.js +52 -0
  87. package/dist/src/control-plane/eval-image-resolution.js.map +1 -0
  88. package/dist/src/control-plane/eval-image-services.js +30 -0
  89. package/dist/src/control-plane/eval-image-services.js.map +1 -0
  90. package/dist/src/control-plane/eval-records.js +252 -0
  91. package/dist/src/control-plane/eval-records.js.map +1 -0
  92. package/dist/src/control-plane/eval-recovery.js +181 -0
  93. package/dist/src/control-plane/eval-recovery.js.map +1 -0
  94. package/dist/src/control-plane/eval-scheduler.js +447 -0
  95. package/dist/src/control-plane/eval-scheduler.js.map +1 -0
  96. package/dist/src/control-plane/index.js +20 -0
  97. package/dist/src/control-plane/index.js.map +1 -0
  98. package/dist/src/control-plane/local-worker.js +49 -0
  99. package/dist/src/control-plane/local-worker.js.map +1 -0
  100. package/dist/src/control-plane/model-capture-planning.js +12 -0
  101. package/dist/src/control-plane/model-capture-planning.js.map +1 -0
  102. package/dist/src/control-plane/remote-result-transport.js +172 -0
  103. package/dist/src/control-plane/remote-result-transport.js.map +1 -0
  104. package/dist/src/control-plane/remote-work-coordinator.js +332 -0
  105. package/dist/src/control-plane/remote-work-coordinator.js.map +1 -0
  106. package/dist/src/control-plane/remote-work-inputs.js +266 -0
  107. package/dist/src/control-plane/remote-work-inputs.js.map +1 -0
  108. package/dist/src/control-plane/remote-work-recovery.js +181 -0
  109. package/dist/src/control-plane/remote-work-recovery.js.map +1 -0
  110. package/dist/src/control-plane/remote-worker-artifacts.js +135 -0
  111. package/dist/src/control-plane/remote-worker-artifacts.js.map +1 -0
  112. package/dist/src/control-plane/remote-worker-client.js +202 -0
  113. package/dist/src/control-plane/remote-worker-client.js.map +1 -0
  114. package/dist/src/control-plane/remote-worker-configuration.js +34 -0
  115. package/dist/src/control-plane/remote-worker-configuration.js.map +1 -0
  116. package/dist/src/control-plane/remote-worker-credentials.js +58 -0
  117. package/dist/src/control-plane/remote-worker-credentials.js.map +1 -0
  118. package/dist/src/control-plane/remote-worker-protocol.js +510 -0
  119. package/dist/src/control-plane/remote-worker-protocol.js.map +1 -0
  120. package/dist/src/control-plane/remote-worker-runner.js +214 -0
  121. package/dist/src/control-plane/remote-worker-runner.js.map +1 -0
  122. package/dist/src/control-plane/remote-workers.js +377 -0
  123. package/dist/src/control-plane/remote-workers.js.map +1 -0
  124. package/dist/src/control-plane/rerun-scheduler.js +411 -0
  125. package/dist/src/control-plane/rerun-scheduler.js.map +1 -0
  126. package/dist/src/control-plane/rerun-submission.js +56 -0
  127. package/dist/src/control-plane/rerun-submission.js.map +1 -0
  128. package/dist/src/control-plane/resources.js +182 -0
  129. package/dist/src/control-plane/resources.js.map +1 -0
  130. package/dist/src/control-plane/scheduler-eval-entry.js +32 -0
  131. package/dist/src/control-plane/scheduler-eval-entry.js.map +1 -0
  132. package/dist/src/control-plane/synthetic-result.js +21 -0
  133. package/dist/src/control-plane/synthetic-result.js.map +1 -0
  134. package/dist/src/control-plane/work-admission.js +21 -0
  135. package/dist/src/control-plane/work-admission.js.map +1 -0
  136. package/dist/src/control-plane/work-dispatcher.js +229 -0
  137. package/dist/src/control-plane/work-dispatcher.js.map +1 -0
  138. package/dist/src/controller-runtime/hash.js +12 -1
  139. package/dist/src/controller-runtime/hash.js.map +1 -1
  140. package/dist/src/controller-runtime/index.js +1 -1
  141. package/dist/src/controller-runtime/index.js.map +1 -1
  142. package/dist/src/controller-runtime/store.js +15 -6
  143. package/dist/src/controller-runtime/store.js.map +1 -1
  144. package/dist/src/daemon/client.js.map +1 -1
  145. package/dist/src/daemon/event-stream.js +46 -0
  146. package/dist/src/daemon/event-stream.js.map +1 -0
  147. package/dist/src/daemon/health.js +66 -0
  148. package/dist/src/daemon/health.js.map +1 -0
  149. package/dist/src/daemon/launcher.js +28 -1
  150. package/dist/src/daemon/launcher.js.map +1 -1
  151. package/dist/src/daemon/logging.js +23 -0
  152. package/dist/src/daemon/logging.js.map +1 -0
  153. package/dist/src/daemon/scheduler.js +26 -5
  154. package/dist/src/daemon/scheduler.js.map +1 -1
  155. package/dist/src/daemon/server.js +255 -98
  156. package/dist/src/daemon/server.js.map +1 -1
  157. package/dist/src/daemon/telemetry.js +163 -0
  158. package/dist/src/daemon/telemetry.js.map +1 -0
  159. package/dist/src/daemon/worker-routes.js +219 -0
  160. package/dist/src/daemon/worker-routes.js.map +1 -0
  161. package/dist/src/domain/bundles.js +2 -0
  162. package/dist/src/domain/bundles.js.map +1 -0
  163. package/dist/src/domain/control-plane.js +2 -0
  164. package/dist/src/domain/control-plane.js.map +1 -0
  165. package/dist/src/domain/execution-evidence.js +2 -0
  166. package/dist/src/domain/execution-evidence.js.map +1 -0
  167. package/dist/src/domain/execution-plan.js +2 -0
  168. package/dist/src/domain/execution-plan.js.map +1 -0
  169. package/dist/src/domain/images.js +2 -0
  170. package/dist/src/domain/images.js.map +1 -0
  171. package/dist/src/domain/index.js +9 -0
  172. package/dist/src/domain/index.js.map +1 -1
  173. package/dist/src/domain/interactions.js +2 -0
  174. package/dist/src/domain/interactions.js.map +1 -0
  175. package/dist/src/domain/providers.js +2 -0
  176. package/dist/src/domain/providers.js.map +1 -0
  177. package/dist/src/domain/resources.js +2 -0
  178. package/dist/src/domain/resources.js.map +1 -0
  179. package/dist/src/domain/workers.js +2 -0
  180. package/dist/src/domain/workers.js.map +1 -0
  181. package/dist/src/evals/collect-only-rerun.js +182 -0
  182. package/dist/src/evals/collect-only-rerun.js.map +1 -0
  183. package/dist/src/evals/directory.js +30 -0
  184. package/dist/src/evals/directory.js.map +1 -0
  185. package/dist/src/evals/docker-engine-stats.js +89 -0
  186. package/dist/src/evals/docker-engine-stats.js.map +1 -0
  187. package/dist/src/evals/docker-ownership.js +51 -0
  188. package/dist/src/evals/docker-ownership.js.map +1 -0
  189. package/dist/src/evals/docker-reaper.js +144 -0
  190. package/dist/src/evals/docker-reaper.js.map +1 -0
  191. package/dist/src/evals/docker-resource-observer.js +207 -0
  192. package/dist/src/evals/docker-resource-observer.js.map +1 -0
  193. package/dist/src/evals/environment-image-planning.js +164 -0
  194. package/dist/src/evals/environment-image-planning.js.map +1 -0
  195. package/dist/src/evals/eval-artifact-planning.js +56 -0
  196. package/dist/src/evals/eval-artifact-planning.js.map +1 -0
  197. package/dist/src/evals/eval-finalization.js +10 -0
  198. package/dist/src/evals/eval-finalization.js.map +1 -0
  199. package/dist/src/evals/eval-lifecycle-events.js +16 -0
  200. package/dist/src/evals/eval-lifecycle-events.js.map +1 -0
  201. package/dist/src/evals/events.js +53 -5
  202. package/dist/src/evals/events.js.map +1 -1
  203. package/dist/src/evals/execution-evidence.js +116 -0
  204. package/dist/src/evals/execution-evidence.js.map +1 -0
  205. package/dist/src/evals/execution-leases.js +342 -0
  206. package/dist/src/evals/execution-leases.js.map +1 -0
  207. package/dist/src/evals/execution-plan-artifacts.js +72 -0
  208. package/dist/src/evals/execution-plan-artifacts.js.map +1 -0
  209. package/dist/src/evals/execution-plan-images.js +69 -0
  210. package/dist/src/evals/execution-plan-images.js.map +1 -0
  211. package/dist/src/evals/execution-plan-resources.js +174 -0
  212. package/dist/src/evals/execution-plan-resources.js.map +1 -0
  213. package/dist/src/evals/execution-plan.js +415 -0
  214. package/dist/src/evals/execution-plan.js.map +1 -0
  215. package/dist/src/evals/harbor-artifact-builder-image.js +99 -0
  216. package/dist/src/evals/harbor-artifact-builder-image.js.map +1 -0
  217. package/dist/src/evals/harbor-artifact-builder.js +354 -0
  218. package/dist/src/evals/harbor-artifact-builder.js.map +1 -0
  219. package/dist/src/evals/harbor-bridge-error.js +39 -3
  220. package/dist/src/evals/harbor-bridge-error.js.map +1 -1
  221. package/dist/src/evals/harbor-phase-timings.js +60 -0
  222. package/dist/src/evals/harbor-phase-timings.js.map +1 -0
  223. package/dist/src/evals/index.js +26 -3
  224. package/dist/src/evals/index.js.map +1 -1
  225. package/dist/src/evals/infrastructure-retry.js +218 -0
  226. package/dist/src/evals/infrastructure-retry.js.map +1 -0
  227. package/dist/src/evals/interaction-capture-import.js +49 -0
  228. package/dist/src/evals/interaction-capture-import.js.map +1 -0
  229. package/dist/src/evals/local-docker-provider.js +372 -0
  230. package/dist/src/evals/local-docker-provider.js.map +1 -0
  231. package/dist/src/evals/local-eval-planning.js +80 -0
  232. package/dist/src/evals/local-eval-planning.js.map +1 -0
  233. package/dist/src/evals/model-capture-plan.js +22 -0
  234. package/dist/src/evals/model-capture-plan.js.map +1 -0
  235. package/dist/src/evals/model-capture-runtime.js +114 -0
  236. package/dist/src/evals/model-capture-runtime.js.map +1 -0
  237. package/dist/src/evals/model-proxy-runtime-state.js +53 -0
  238. package/dist/src/evals/model-proxy-runtime-state.js.map +1 -0
  239. package/dist/src/evals/planned-execution-support.js +54 -0
  240. package/dist/src/evals/planned-execution-support.js.map +1 -0
  241. package/dist/src/evals/planned-execution.js +461 -0
  242. package/dist/src/evals/planned-execution.js.map +1 -0
  243. package/dist/src/evals/planned-remote-execution.js +40 -0
  244. package/dist/src/evals/planned-remote-execution.js.map +1 -0
  245. package/dist/src/evals/planned-retry-lifecycle.js +186 -0
  246. package/dist/src/evals/planned-retry-lifecycle.js.map +1 -0
  247. package/dist/src/evals/prepared-harness.js +76 -0
  248. package/dist/src/evals/prepared-harness.js.map +1 -0
  249. package/dist/src/evals/progress.js +4 -4
  250. package/dist/src/evals/progress.js.map +1 -1
  251. package/dist/src/evals/records.js +20 -3
  252. package/dist/src/evals/records.js.map +1 -1
  253. package/dist/src/evals/recovery.js +192 -0
  254. package/dist/src/evals/recovery.js.map +1 -0
  255. package/dist/src/evals/remote-infrastructure-retry.js +99 -0
  256. package/dist/src/evals/remote-infrastructure-retry.js.map +1 -0
  257. package/dist/src/evals/request.js +14 -1
  258. package/dist/src/evals/request.js.map +1 -1
  259. package/dist/src/evals/rerun-inputs.js +89 -0
  260. package/dist/src/evals/rerun-inputs.js.map +1 -0
  261. package/dist/src/evals/rerun-slots.js +12 -3
  262. package/dist/src/evals/rerun-slots.js.map +1 -1
  263. package/dist/src/evals/rerun-types.js +49 -0
  264. package/dist/src/evals/rerun-types.js.map +1 -0
  265. package/dist/src/evals/rerun.js +113 -75
  266. package/dist/src/evals/rerun.js.map +1 -1
  267. package/dist/src/evals/result-helpers.js +65 -0
  268. package/dist/src/evals/result-helpers.js.map +1 -0
  269. package/dist/src/evals/resume-state.js +36 -0
  270. package/dist/src/evals/resume-state.js.map +1 -0
  271. package/dist/src/evals/service-types.js +2 -0
  272. package/dist/src/evals/service-types.js.map +1 -0
  273. package/dist/src/evals/service.js +327 -237
  274. package/dist/src/evals/service.js.map +1 -1
  275. package/dist/src/evals/task-resources.js +209 -0
  276. package/dist/src/evals/task-resources.js.map +1 -0
  277. package/dist/src/evals/trial-environment-evidence.js +87 -0
  278. package/dist/src/evals/trial-environment-evidence.js.map +1 -0
  279. package/dist/src/evals/trial-execution-evidence.js +13 -0
  280. package/dist/src/evals/trial-execution-evidence.js.map +1 -0
  281. package/dist/src/evals/trial-import-identity.js +31 -0
  282. package/dist/src/evals/trial-import-identity.js.map +1 -0
  283. package/dist/src/evals/trial-import.js +166 -168
  284. package/dist/src/evals/trial-import.js.map +1 -1
  285. package/dist/src/evals/trial-publication-recovery.js +104 -0
  286. package/dist/src/evals/trial-publication-recovery.js.map +1 -0
  287. package/dist/src/evals/trial-publication.js +25 -0
  288. package/dist/src/evals/trial-publication.js.map +1 -0
  289. package/dist/src/evals/verifier-diagnostics.js +235 -0
  290. package/dist/src/evals/verifier-diagnostics.js.map +1 -0
  291. package/dist/src/evals/work-item-artifacts.js +23 -0
  292. package/dist/src/evals/work-item-artifacts.js.map +1 -0
  293. package/dist/src/foundation/config.js +17 -0
  294. package/dist/src/foundation/config.js.map +1 -1
  295. package/dist/src/foundation/credential-redaction.js +137 -0
  296. package/dist/src/foundation/credential-redaction.js.map +1 -0
  297. package/dist/src/foundation/environment-image-references.js +59 -0
  298. package/dist/src/foundation/environment-image-references.js.map +1 -0
  299. package/dist/src/foundation/executable.js +45 -5
  300. package/dist/src/foundation/executable.js.map +1 -1
  301. package/dist/src/foundation/index.js +5 -2
  302. package/dist/src/foundation/index.js.map +1 -1
  303. package/dist/src/foundation/process-identity.js +69 -0
  304. package/dist/src/foundation/process-identity.js.map +1 -0
  305. package/dist/src/images/context.js +47 -0
  306. package/dist/src/images/context.js.map +1 -0
  307. package/dist/src/images/docker-buildkit.js +137 -0
  308. package/dist/src/images/docker-buildkit.js.map +1 -0
  309. package/dist/src/images/dockerfile.js +67 -0
  310. package/dist/src/images/dockerfile.js.map +1 -0
  311. package/dist/src/images/gc.js +261 -0
  312. package/dist/src/images/gc.js.map +1 -0
  313. package/dist/src/images/index.js +10 -0
  314. package/dist/src/images/index.js.map +1 -0
  315. package/dist/src/images/manifest.js +109 -0
  316. package/dist/src/images/manifest.js.map +1 -0
  317. package/dist/src/images/ownership.js +5 -0
  318. package/dist/src/images/ownership.js.map +1 -0
  319. package/dist/src/images/records.js +32 -0
  320. package/dist/src/images/records.js.map +1 -0
  321. package/dist/src/images/registry.js +154 -0
  322. package/dist/src/images/registry.js.map +1 -0
  323. package/dist/src/images/service.js +224 -0
  324. package/dist/src/images/service.js.map +1 -0
  325. package/dist/src/model-access/capture.js +255 -0
  326. package/dist/src/model-access/capture.js.map +1 -0
  327. package/dist/src/model-access/index.js +5 -0
  328. package/dist/src/model-access/index.js.map +1 -0
  329. package/dist/src/model-access/policy.js +49 -0
  330. package/dist/src/model-access/policy.js.map +1 -0
  331. package/dist/src/model-access/proxy.js +336 -0
  332. package/dist/src/model-access/proxy.js.map +1 -0
  333. package/dist/src/model-access/records.js +167 -0
  334. package/dist/src/model-access/records.js.map +1 -0
  335. package/dist/src/runs/bundle.js +450 -0
  336. package/dist/src/runs/bundle.js.map +1 -0
  337. package/dist/src/runs/events.js +12 -1
  338. package/dist/src/runs/events.js.map +1 -1
  339. package/dist/src/runs/executor.js +24 -17
  340. package/dist/src/runs/executor.js.map +1 -1
  341. package/dist/src/runs/index.js +3 -1
  342. package/dist/src/runs/index.js.map +1 -1
  343. package/dist/src/runs/manifest.js +5 -5
  344. package/dist/src/runs/manifest.js.map +1 -1
  345. package/dist/src/runs/request.js +6 -1
  346. package/dist/src/runs/request.js.map +1 -1
  347. package/dist/src/runs/training-candidate.js +161 -0
  348. package/dist/src/runs/training-candidate.js.map +1 -0
  349. package/dist/src/trajectories/provider-capture.js +15 -24
  350. package/dist/src/trajectories/provider-capture.js.map +1 -1
  351. package/dist/src/trajectories/providers/deepseek.js +3 -3
  352. package/dist/src/trajectories/providers/deepseek.js.map +1 -1
  353. package/dist/src/workers/index.js +3 -0
  354. package/dist/src/workers/index.js.map +1 -0
  355. package/dist/src/workers/remote-harbor-work-spec.js +97 -0
  356. package/dist/src/workers/remote-harbor-work-spec.js.map +1 -0
  357. package/dist/src/workers/remote-harbor-worker.js +220 -0
  358. package/dist/src/workers/remote-harbor-worker.js.map +1 -0
  359. package/docs/schemas/environment-build-index.schema.json +13 -0
  360. package/docs/schemas/environment-build-record.schema.json +25 -0
  361. package/docs/schemas/environment-image-manifest.schema.json +62 -0
  362. package/docs/schemas/eval-control.schema.json +36 -0
  363. package/docs/schemas/eval-execution-plan.schema.json +216 -0
  364. package/docs/schemas/eval-request.schema.json +2 -0
  365. package/docs/schemas/eval-rerun-result.schema.json +53 -0
  366. package/docs/schemas/eval-rerun-state.schema.json +61 -0
  367. package/docs/schemas/eval-rerun-submission.schema.json +58 -0
  368. package/docs/schemas/eval-result.schema.json +34 -1
  369. package/docs/schemas/eval-submission-input.schema.json +14 -0
  370. package/docs/schemas/eval-submission.schema.json +68 -0
  371. package/docs/schemas/eval-trial-publication.schema.json +39 -0
  372. package/docs/schemas/execution-evidence.schema.json +96 -0
  373. package/docs/schemas/execution-lease.schema.json +50 -0
  374. package/docs/schemas/execution-provider-status.schema.json +65 -0
  375. package/docs/schemas/execution-worker.schema.json +53 -0
  376. package/docs/schemas/harbor-process-exit.schema.json +14 -0
  377. package/docs/schemas/interaction-capture-ref.schema.json +45 -0
  378. package/docs/schemas/local-provider-execution.schema.json +33 -0
  379. package/docs/schemas/model-interaction.schema.json +41 -0
  380. package/docs/schemas/remote-result-envelope.schema.json +32 -0
  381. package/docs/schemas/remote-tree-envelope.schema.json +25 -0
  382. package/docs/schemas/remote-work-offer.schema.json +58 -0
  383. package/docs/schemas/remote-work-receipt.schema.json +50 -0
  384. package/docs/schemas/remote-worker-artifact.schema.json +17 -0
  385. package/docs/schemas/remote-worker-event.schema.json +18 -0
  386. package/docs/schemas/remote-worker-heartbeat.schema.json +37 -0
  387. package/docs/schemas/remote-worker-registration.schema.json +52 -0
  388. package/docs/schemas/result-bundle-index.schema.json +133 -0
  389. package/docs/schemas/run-environment-images.schema.json +39 -0
  390. package/docs/schemas/training-data-candidate.schema.json +46 -0
  391. package/integrations/harbor/hitch_harbor_agent.py +300 -547
  392. package/integrations/harbor/hitch_harbor_environment.py +331 -0
  393. package/integrations/harbor/hitch_harbor_task_resources.py +275 -0
  394. package/integrations/harbor/hitch_harbor_verifier.py +337 -0
  395. package/package.json +16 -2
@@ -0,0 +1,261 @@
1
+ import { readdir, rm } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { HitchError, atomicWriteJSON, hitchRootId, readEvalEnvironmentImageReferences, readJSON, runCommand, sha256JSON, statePaths, withEnvironmentImageReferenceLock, withFileLock } from "../foundation/index.js";
4
+ import { parseEnvironmentBuildRecord, parseEnvironmentImageManifest } from "./manifest.js";
5
+ import { ENVIRONMENT_IMAGE_LABELS } from "./ownership.js";
6
+ import { environmentBuildRecordPath, environmentImageManifestPath, loadEnvironmentImageManifest } from "./service.js";
7
+ const TERMINAL_EVAL_STATES = new Set(["succeeded", "failed", "cancelled"]);
8
+ export async function pinEnvironmentImage(root, imageId, reason) {
9
+ validateRootAndImage(root, imageId);
10
+ if (reason !== undefined && (!reason.trim() || reason.length > 1_024 || /[\0\r\n]/.test(reason)))
11
+ throw new TypeError("environment image pin reason is invalid");
12
+ await withEnvironmentImageReferenceLock(root, async () => {
13
+ await loadEnvironmentImageManifest(root, imageId);
14
+ const file = environmentImagePinPath(root, imageId);
15
+ const existing = await readJSON(file, null);
16
+ if (existing !== null) {
17
+ parsePin(existing, imageId);
18
+ return;
19
+ }
20
+ await atomicWriteJSON(file, {
21
+ schema_version: "1",
22
+ image_id: imageId,
23
+ pinned_at: new Date().toISOString(),
24
+ ...(reason === undefined ? {} : { reason }),
25
+ });
26
+ });
27
+ }
28
+ export async function unpinEnvironmentImage(root, imageId) {
29
+ validateRootAndImage(root, imageId);
30
+ await withEnvironmentImageReferenceLock(root, () => rm(environmentImagePinPath(root, imageId), { force: true }));
31
+ }
32
+ export async function gcEnvironmentImages(input) {
33
+ if (!input.root || typeof input.dryRun !== "boolean")
34
+ throw new TypeError("environment image GC input is invalid");
35
+ const minimumAgeMs = input.minimumAgeMs ?? 24 * 60 * 60 * 1_000;
36
+ if (!Number.isSafeInteger(minimumAgeMs) || minimumAgeMs < 0)
37
+ throw new TypeError("environment image GC minimum age is invalid");
38
+ const env = input.env ?? process.env;
39
+ const command = input.run ?? ((args) => runCommand(env.HITCH_DOCKER_PATH || "docker", args, {
40
+ env,
41
+ ...(input.signal ? { signal: input.signal } : {}),
42
+ timeoutMs: 30_000,
43
+ failureCode: "environment_image_gc_docker_failed",
44
+ failureExitCode: 12,
45
+ }));
46
+ return withEnvironmentImageReferenceLock(input.root, async () => {
47
+ const references = await referencedEnvironmentImages(input.root);
48
+ const manifests = await storedManifests(input.root);
49
+ const retained = [];
50
+ const eligible = [];
51
+ const removed = [];
52
+ const skipped = [];
53
+ for (const manifest of manifests) {
54
+ const reasons = [...(references.get(manifest.image_id) ?? [])].sort(compare);
55
+ if (reasons.length > 0) {
56
+ retained.push({ image_id: manifest.image_id, reasons });
57
+ continue;
58
+ }
59
+ if (manifest.source.kind === "registry") {
60
+ retained.push({ image_id: manifest.image_id, reasons: ["external-registry-image"] });
61
+ continue;
62
+ }
63
+ if (Date.now() - Date.parse(manifest.created_at) < minimumAgeMs) {
64
+ retained.push({ image_id: manifest.image_id, reasons: ["minimum-age"] });
65
+ continue;
66
+ }
67
+ const candidate = await withFileLock(statePaths(input.root).buildLocks, manifest.build.cache_key, async () => {
68
+ const current = await loadEnvironmentImageManifest(input.root, manifest.image_id);
69
+ if (JSON.stringify(current) !== JSON.stringify(manifest))
70
+ throw gcError("environment image changed during GC");
71
+ return inspectGcCandidate(input.root, manifest, command);
72
+ }, { timeoutCode: "environment_image_gc_build_locked", timeoutExitCode: 12, ...(input.signal ? { signal: input.signal } : {}) });
73
+ if ("code" in candidate) {
74
+ skipped.push({ image_id: manifest.image_id, code: candidate.code });
75
+ continue;
76
+ }
77
+ eligible.push(candidate);
78
+ if (input.dryRun)
79
+ continue;
80
+ const deleted = await withFileLock(statePaths(input.root).buildLocks, manifest.build.cache_key, async () => {
81
+ const current = await loadEnvironmentImageManifest(input.root, manifest.image_id);
82
+ if (JSON.stringify(current) !== JSON.stringify(manifest))
83
+ throw gcError("environment image changed during GC");
84
+ const rechecked = await inspectGcCandidate(input.root, manifest, command);
85
+ if ("code" in rechecked)
86
+ return rechecked;
87
+ await command(["image", "rm", manifest.output.reference]);
88
+ await removeEnvironmentImageRecords(input.root, manifest);
89
+ return rechecked;
90
+ }, { timeoutCode: "environment_image_gc_build_locked", timeoutExitCode: 12, ...(input.signal ? { signal: input.signal } : {}) });
91
+ if ("code" in deleted)
92
+ skipped.push({ image_id: manifest.image_id, code: deleted.code });
93
+ else
94
+ removed.push(deleted);
95
+ }
96
+ return {
97
+ schema_version: "1",
98
+ dry_run: input.dryRun,
99
+ scanned: manifests.length,
100
+ retained: retained.sort(byImageId),
101
+ eligible: eligible.sort(byImageId),
102
+ removed: removed.sort(byImageId),
103
+ skipped: skipped.sort(byImageId),
104
+ };
105
+ });
106
+ }
107
+ async function inspectGcCandidate(root, manifest, command) {
108
+ if (!/^hitch-environment:[a-f0-9]{32}$/.test(manifest.output.reference) || !manifest.output.config_digest)
109
+ return { code: "not-owned-build-output" };
110
+ const record = parseEnvironmentBuildRecord(await readJSON(environmentBuildRecordPath(root, manifest.build.cache_key)));
111
+ if (record.state !== "succeeded" || record.image_id !== manifest.image_id || record.cache_key !== manifest.build.cache_key)
112
+ throw gcError("environment image build record does not match manifest");
113
+ let inspected;
114
+ try {
115
+ inspected = JSON.parse((await command(["image", "inspect", "--format", "{{json .}}", manifest.output.reference])).stdout);
116
+ }
117
+ catch {
118
+ return { code: "docker-image-unavailable" };
119
+ }
120
+ if (!inspected || typeof inspected !== "object" || Array.isArray(inspected))
121
+ return { code: "docker-inspect-invalid" };
122
+ const image = inspected;
123
+ const config = image.Config && typeof image.Config === "object" && !Array.isArray(image.Config) ? image.Config : {};
124
+ const labels = config.Labels && typeof config.Labels === "object" && !Array.isArray(config.Labels) ? config.Labels : {};
125
+ if (image.Id !== manifest.output.config_digest)
126
+ return { code: "config-digest-mismatch" };
127
+ if (labels[ENVIRONMENT_IMAGE_LABELS.rootId] !== hitchRootId(root)
128
+ || labels[ENVIRONMENT_IMAGE_LABELS.cacheKey] !== manifest.build.cache_key)
129
+ return { code: "ownership-label-mismatch" };
130
+ return { image_id: manifest.image_id, reference: manifest.output.reference, config_digest: manifest.output.config_digest };
131
+ }
132
+ async function referencedEnvironmentImages(root) {
133
+ const result = new Map();
134
+ const paths = statePaths(root);
135
+ for (const entry of await directories(paths.evals)) {
136
+ if (!/^eval_[a-f0-9]{32}$/.test(entry))
137
+ continue;
138
+ const directory = path.join(paths.evals, entry);
139
+ const control = await readJSON(path.join(directory, "control.json"), null);
140
+ const terminalResult = await readJSON(path.join(directory, "result.json"), null);
141
+ const terminal = TERMINAL_EVAL_STATES.has(String(control?.state)) || TERMINAL_EVAL_STATES.has(String(terminalResult?.status));
142
+ if (terminal)
143
+ continue;
144
+ const request = await readJSON(path.join(directory, "request.json"), null);
145
+ if (request === null && control === null)
146
+ continue;
147
+ const references = await readEvalEnvironmentImageReferences(directory, entry);
148
+ if (!references)
149
+ throw gcError(`active eval has no environment image reference fence: ${entry}`);
150
+ if (references.state !== "planned")
151
+ throw gcError(`active eval image planning is incomplete: ${entry}`);
152
+ for (const imageId of references.image_ids)
153
+ addReference(result, imageId, "active-eval");
154
+ }
155
+ for (const entry of await directories(paths.runs)) {
156
+ const index = await readJSON(path.join(paths.runs, entry, "bundle.index.json"), null);
157
+ if (index === null)
158
+ continue;
159
+ const manifest = await readJSON(path.join(paths.runs, entry, "manifest.json"), null);
160
+ const { bundle_digest: bundleDigest, created_at: _createdAt, ...bundleIdentity } = index;
161
+ if (index.schema_version !== "1" || index.sealed !== true || typeof index.run_id !== "string"
162
+ || typeof bundleDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(bundleDigest)
163
+ || sha256JSON(bundleIdentity) !== bundleDigest
164
+ || manifest?.sealed !== true || manifest.run_id !== index.run_id)
165
+ throw gcError(`sealed bundle index is invalid: ${entry}`);
166
+ if (index.environment === undefined)
167
+ continue;
168
+ const environment = record(index.environment);
169
+ if (!environment || !Array.isArray(environment.images))
170
+ throw gcError(`sealed bundle environment is invalid: ${entry}`);
171
+ for (const image of environment.images) {
172
+ const value = record(image);
173
+ if (!value || typeof value.image_id !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value.image_id))
174
+ throw gcError(`sealed bundle image reference is invalid: ${entry}`);
175
+ addReference(result, value.image_id, "sealed-bundle");
176
+ }
177
+ }
178
+ for (const entry of await files(paths.environmentImagePins)) {
179
+ if (!/^[a-f0-9]{64}\.json$/.test(entry))
180
+ throw gcError("environment image pin filename is invalid");
181
+ const imageId = `sha256:${entry.slice(0, 64)}`;
182
+ parsePin(await readJSON(path.join(paths.environmentImagePins, entry)), imageId);
183
+ addReference(result, imageId, "operator-pin");
184
+ }
185
+ return result;
186
+ }
187
+ async function storedManifests(root) {
188
+ const result = [];
189
+ for (const entry of await directories(statePaths(root).environmentImages)) {
190
+ if (!/^[a-f0-9]{64}$/.test(entry))
191
+ throw gcError("environment image store entry is invalid");
192
+ const manifest = parseEnvironmentImageManifest(await readJSON(path.join(statePaths(root).environmentImages, entry, "manifest.json")));
193
+ if (manifest.image_id !== `sha256:${entry}`)
194
+ throw gcError("environment image store path does not match manifest");
195
+ result.push(manifest);
196
+ }
197
+ return result.sort((left, right) => compare(left.image_id, right.image_id));
198
+ }
199
+ async function removeEnvironmentImageRecords(root, manifest) {
200
+ const paths = statePaths(root);
201
+ const manifestDirectory = path.dirname(environmentImageManifestPath(root, manifest.image_id));
202
+ const recordDirectory = path.dirname(environmentBuildRecordPath(root, manifest.build.cache_key));
203
+ const buildId = `build_${manifest.build.cache_key.slice("sha256:".length, "sha256:".length + 32)}`;
204
+ await rm(path.join(paths.buildIndexes, `${buildId}.json`), { force: true });
205
+ await rm(recordDirectory, { recursive: true, force: true });
206
+ await rm(manifestDirectory, { recursive: true, force: true });
207
+ }
208
+ function environmentImagePinPath(root, imageId) {
209
+ return path.join(statePaths(root).environmentImagePins, `${imageId.slice("sha256:".length)}.json`);
210
+ }
211
+ function parsePin(value, expectedImageId) {
212
+ const pin = record(value);
213
+ if (!pin || Object.keys(pin).some((key) => !["schema_version", "image_id", "pinned_at", "reason"].includes(key))
214
+ || pin.schema_version !== "1" || pin.image_id !== expectedImageId
215
+ || typeof pin.pinned_at !== "string" || !Number.isFinite(Date.parse(pin.pinned_at))
216
+ || pin.reason !== undefined && (typeof pin.reason !== "string" || !pin.reason || pin.reason.length > 1_024 || /[\0\r\n]/.test(pin.reason))) {
217
+ throw gcError("environment image pin is invalid");
218
+ }
219
+ }
220
+ async function directories(root) {
221
+ try {
222
+ return (await readdir(root, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compare);
223
+ }
224
+ catch (error) {
225
+ if (error.code === "ENOENT")
226
+ return [];
227
+ throw error;
228
+ }
229
+ }
230
+ async function files(root) {
231
+ try {
232
+ return (await readdir(root, { withFileTypes: true })).filter((entry) => entry.isFile()).map((entry) => entry.name).sort(compare);
233
+ }
234
+ catch (error) {
235
+ if (error.code === "ENOENT")
236
+ return [];
237
+ throw error;
238
+ }
239
+ }
240
+ function addReference(target, imageId, reason) {
241
+ const reasons = target.get(imageId) ?? new Set();
242
+ reasons.add(reason);
243
+ target.set(imageId, reasons);
244
+ }
245
+ function record(value) {
246
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
247
+ }
248
+ function validateRootAndImage(root, imageId) {
249
+ if (!root || !/^sha256:[a-f0-9]{64}$/.test(imageId))
250
+ throw new TypeError("environment image pin identity is invalid");
251
+ }
252
+ function gcError(message) {
253
+ return new HitchError(message, { code: "environment_image_gc_reference_scan_failed", exitCode: 12 });
254
+ }
255
+ function byImageId(left, right) {
256
+ return compare(left.image_id, right.image_id);
257
+ }
258
+ function compare(left, right) {
259
+ return Buffer.compare(Buffer.from(left), Buffer.from(right));
260
+ }
261
+ //# sourceMappingURL=gc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../src/images/gc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { resolveBuildContext } from "./context.js";
2
+ export { inspectPinnedDockerfileBases } from "./dockerfile.js";
3
+ export { environmentImageIdentity, parseEnvironmentBuildRecord, parseEnvironmentImageManifest } from "./manifest.js";
4
+ export { EnvironmentImageService, loadEnvironmentImageManifest } from "./service.js";
5
+ export { DockerBuildKitBuilder } from "./docker-buildkit.js";
6
+ export { ENVIRONMENT_IMAGE_LABELS } from "./ownership.js";
7
+ export { gcEnvironmentImages, pinEnvironmentImage, unpinEnvironmentImage } from "./gc.js";
8
+ export { inspectEnvironmentBuild } from "./records.js";
9
+ export { DockerRegistryResolver, resolveRegistryEnvironmentImage } from "./registry.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/images/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AACrH,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { sha256JSON } from "../foundation/index.js";
2
+ const SHA256 = /^sha256:[a-f0-9]{64}$/;
3
+ export function environmentImageIdentity(value) {
4
+ return sha256JSON({
5
+ source: value.source,
6
+ platform: value.platform,
7
+ build: value.build,
8
+ output: {
9
+ manifest_digest: value.output.manifest_digest,
10
+ ...(value.output.config_digest ? { config_digest: value.output.config_digest } : {}),
11
+ },
12
+ base_images: value.base_images,
13
+ });
14
+ }
15
+ export function parseEnvironmentImageManifest(value) {
16
+ const manifest = exact(value, ["schema_version", "image_id", "source", "platform", "build", "output", "base_images", "created_at"], "environment image manifest");
17
+ if (manifest.schema_version !== "1" || !digest(manifest.image_id) || typeof manifest.platform !== "string" || !manifest.platform
18
+ || typeof manifest.created_at !== "string" || !Number.isFinite(Date.parse(manifest.created_at)))
19
+ throw new TypeError("environment image manifest identity is invalid");
20
+ const source = exact(manifest.source, ["kind", "benchmark_id", "benchmark_revision"], "environment image source", ["task_id", "context_digest", "dockerfile_digest"]);
21
+ if (!new Set(["registry", "build-context", "compose-build"]).has(String(source.kind))
22
+ || typeof source.benchmark_id !== "string" || !source.benchmark_id
23
+ || typeof source.benchmark_revision !== "string" || !source.benchmark_revision)
24
+ throw new TypeError("environment image source is invalid");
25
+ for (const name of ["task_id"])
26
+ if (source[name] !== undefined && (typeof source[name] !== "string" || !source[name]))
27
+ throw new TypeError(`environment image source ${name} is invalid`);
28
+ for (const name of ["context_digest", "dockerfile_digest"])
29
+ if (source[name] !== undefined && !digest(source[name]))
30
+ throw new TypeError(`environment image source ${name} is invalid`);
31
+ if (source.kind !== "registry" && (!digest(source.context_digest) || !digest(source.dockerfile_digest)))
32
+ throw new TypeError("built image source digests are missing");
33
+ const build = exact(manifest.build, ["builder", "secret_names", "cache_key"], "environment image build", ["buildkit_version", "builder_id", "frontend", "target", "build_args_sha256"]);
34
+ if (build.builder !== "buildkit" || !digest(build.cache_key))
35
+ throw new TypeError("environment image build identity is invalid");
36
+ for (const name of ["buildkit_version", "builder_id", "frontend", "target"])
37
+ if (build[name] !== undefined && (typeof build[name] !== "string" || !build[name]))
38
+ throw new TypeError(`environment image build ${name} is invalid`);
39
+ if (build.build_args_sha256 !== undefined && !digest(build.build_args_sha256))
40
+ throw new TypeError("environment image build args digest is invalid");
41
+ const secretNames = stringSet(build.secret_names, "environment image secret names", /^[A-Za-z_][A-Za-z0-9_]*$/);
42
+ const output = exact(manifest.output, ["reference", "manifest_digest"], "environment image output", ["config_digest"]);
43
+ if (typeof output.reference !== "string" || !output.reference || !digest(output.manifest_digest)
44
+ || (output.config_digest !== undefined && !digest(output.config_digest)))
45
+ throw new TypeError("environment image output is invalid");
46
+ if (!Array.isArray(manifest.base_images))
47
+ throw new TypeError("environment image base images are invalid");
48
+ const baseImages = manifest.base_images.map((entry) => {
49
+ const base = exact(entry, ["reference", "digest"], "environment image base image");
50
+ if (typeof base.reference !== "string" || !base.reference || !digest(base.digest))
51
+ throw new TypeError("environment image base image is invalid");
52
+ return { reference: base.reference, digest: base.digest };
53
+ });
54
+ if (!canonical(baseImages.map((entry) => entry.reference)) || new Set(baseImages.map((entry) => entry.reference)).size !== baseImages.length)
55
+ throw new TypeError("environment image base images are not canonical");
56
+ const parsed = {
57
+ schema_version: "1",
58
+ image_id: manifest.image_id,
59
+ source: source,
60
+ platform: manifest.platform,
61
+ build: { ...build, secret_names: secretNames },
62
+ output: output,
63
+ base_images: baseImages,
64
+ created_at: manifest.created_at,
65
+ };
66
+ const { image_id: _imageId, created_at: _createdAt, ...identity } = parsed;
67
+ if (environmentImageIdentity(identity) !== parsed.image_id)
68
+ throw new TypeError("environment image id does not match its identity");
69
+ return parsed;
70
+ }
71
+ export function parseEnvironmentBuildRecord(value) {
72
+ const record = exact(value, ["schema_version", "build_id", "cache_key", "state", "owner_id", "builder_id", "started_at"], "environment build record", ["completed_at", "image_id", "error"]);
73
+ if (record.schema_version !== "1" || typeof record.build_id !== "string" || !/^build_[a-f0-9]{32}$/.test(record.build_id)
74
+ || !digest(record.cache_key) || !new Set(["running", "succeeded", "failed"]).has(String(record.state))
75
+ || typeof record.owner_id !== "string" || !record.owner_id || typeof record.builder_id !== "string" || !record.builder_id
76
+ || typeof record.started_at !== "string" || !Number.isFinite(Date.parse(record.started_at)))
77
+ throw new TypeError("environment build record identity is invalid");
78
+ const terminal = record.state === "succeeded" || record.state === "failed";
79
+ if (terminal !== (typeof record.completed_at === "string" && Number.isFinite(Date.parse(record.completed_at))))
80
+ throw new TypeError("environment build terminal state is inconsistent");
81
+ if ((record.state === "succeeded") !== digest(record.image_id))
82
+ throw new TypeError("environment build image identity is inconsistent");
83
+ const error = record.error;
84
+ if ((record.state === "failed") !== Boolean(error) || (error && (typeof error !== "object" || Array.isArray(error)
85
+ || typeof error.code !== "string" || typeof error.message !== "string")))
86
+ throw new TypeError("environment build failure is inconsistent");
87
+ return record;
88
+ }
89
+ function exact(value, required, label, optional = []) {
90
+ if (!value || typeof value !== "object" || Array.isArray(value))
91
+ throw new TypeError(`${label} must be an object`);
92
+ const record = value;
93
+ if (required.some((key) => !(key in record)) || Object.keys(record).some((key) => !required.includes(key) && !optional.includes(key)))
94
+ throw new TypeError(`${label} fields are invalid`);
95
+ return record;
96
+ }
97
+ function digest(value) {
98
+ return typeof value === "string" && SHA256.test(value);
99
+ }
100
+ function stringSet(value, label, pattern) {
101
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || !pattern.test(entry)) || !canonical(value)
102
+ || new Set(value).size !== value.length)
103
+ throw new TypeError(`${label} are invalid`);
104
+ return value;
105
+ }
106
+ function canonical(values) {
107
+ return values.every((value, index) => index === 0 || Buffer.compare(Buffer.from(values[index - 1]), Buffer.from(value)) < 0);
108
+ }
109
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/images/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export const ENVIRONMENT_IMAGE_LABELS = {
2
+ rootId: "io.hitch.environment-image-root-id",
3
+ cacheKey: "io.hitch.environment-image-cache-key",
4
+ };
5
+ //# sourceMappingURL=ownership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownership.js","sourceRoot":"","sources":["../../../src/images/ownership.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,MAAM,EAAE,oCAAoC;IAC5C,QAAQ,EAAE,sCAAsC;CACxC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import path from "node:path";
2
+ import { readJSON, statePaths } from "../foundation/index.js";
3
+ import { parseEnvironmentBuildRecord, parseEnvironmentImageManifest } from "./manifest.js";
4
+ import { environmentBuildRecordPath, environmentImageManifestPath } from "./service.js";
5
+ export async function inspectEnvironmentBuild(root, buildId) {
6
+ if (!/^build_[a-f0-9]{32}$/.test(buildId))
7
+ throw new TypeError("environment build id is invalid");
8
+ const index = await readJSON(path.join(statePaths(root).buildIndexes, `${buildId}.json`), null);
9
+ if (!index)
10
+ return null;
11
+ if (Object.keys(index).some((key) => !new Set(["schema_version", "build_id", "cache_key"]).has(key))
12
+ || index.schema_version !== "1" || index.build_id !== buildId || typeof index.cache_key !== "string"
13
+ || !/^sha256:[a-f0-9]{64}$/.test(index.cache_key)
14
+ || buildId !== `build_${index.cache_key.slice("sha256:".length, "sha256:".length + 32)}`)
15
+ throw new TypeError("environment build index is invalid");
16
+ const recordValue = await readJSON(environmentBuildRecordPath(root, index.cache_key), null);
17
+ if (!recordValue)
18
+ throw new TypeError("environment build record is missing");
19
+ const record = parseEnvironmentBuildRecord(recordValue);
20
+ if (record.build_id !== buildId || record.cache_key !== index.cache_key)
21
+ throw new TypeError("environment build record does not match its index");
22
+ if (!record.image_id)
23
+ return { record, manifest: null };
24
+ const manifestValue = await readJSON(environmentImageManifestPath(root, record.image_id), null);
25
+ if (!manifestValue)
26
+ throw new TypeError("environment image manifest is missing");
27
+ const manifest = parseEnvironmentImageManifest(manifestValue);
28
+ if (manifest.image_id !== record.image_id || manifest.build.cache_key !== record.cache_key)
29
+ throw new TypeError("environment image manifest does not match its build");
30
+ return { record, manifest };
31
+ }
32
+ //# sourceMappingURL=records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.js","sourceRoot":"","sources":["../../../src/images/records.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAOxF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAY,EAAE,OAAe;IACzE,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IAClG,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAiC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,GAAG,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IAChI,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,gBAAgB,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;WAC/F,KAAK,CAAC,cAAc,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;WACjG,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;WAC9C,OAAO,KAAK,SAAS,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IACtJ,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAiB,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,SAAmB,CAAC,EAAE,IAAI,CAAC,CAAC;IACtH,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;IAClJ,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACxD,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAiB,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAChH,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,6BAA6B,CAAC,aAAa,CAAC,CAAC;IAC9D,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;IACvK,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,154 @@
1
+ import { lstat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { HitchError, atomicWriteJSON, ensureDir, readJSON, runCommand, sha256JSON } from "../foundation/index.js";
4
+ import { environmentImageIdentity, parseEnvironmentImageManifest } from "./manifest.js";
5
+ import { environmentImageManifestPath } from "./service.js";
6
+ export async function resolveRegistryEnvironmentImage(input) {
7
+ if (!input.root || !input.benchmarkId || !input.benchmarkRevision || !validReference(input.reference) || !input.platform || !input.resolver.id) {
8
+ throw new TypeError("registry image request identity is invalid");
9
+ }
10
+ const secretNames = canonicalNames(input.secretNames ?? []);
11
+ const resolved = await input.resolver.resolve(input.reference, input.platform, input.signal);
12
+ if (resolved.platform !== input.platform || !digest(resolved.manifest_digest) || (resolved.config_digest !== undefined && !digest(resolved.config_digest))
13
+ || !validReference(resolved.reference) || repositoryOf(resolved.reference) !== repositoryOf(input.reference)
14
+ || !resolved.reference.endsWith(`@${resolved.manifest_digest}`)) {
15
+ throw new HitchError("registry image identity does not match the request", { code: "image_output_mismatch", exitCode: 12 });
16
+ }
17
+ const requestedDigest = input.reference.match(/@(sha256:[a-f0-9]{64})$/)?.[1];
18
+ if (requestedDigest && requestedDigest !== resolved.manifest_digest)
19
+ throw new HitchError("registry digest resolution changed an immutable reference", { code: "image_digest_mismatch", exitCode: 12 });
20
+ const cacheKey = sha256JSON({ kind: "registry", requested_reference: input.reference, manifest_digest: resolved.manifest_digest, platform: input.platform });
21
+ const withoutIdentity = {
22
+ schema_version: "1",
23
+ source: {
24
+ kind: "registry",
25
+ benchmark_id: input.benchmarkId,
26
+ benchmark_revision: input.benchmarkRevision,
27
+ ...(input.taskId ? { task_id: input.taskId } : {}),
28
+ },
29
+ platform: input.platform,
30
+ build: {
31
+ builder: "buildkit",
32
+ builder_id: input.resolver.id,
33
+ frontend: "registry-resolution",
34
+ secret_names: secretNames,
35
+ cache_key: cacheKey,
36
+ },
37
+ output: {
38
+ reference: resolved.reference,
39
+ manifest_digest: resolved.manifest_digest,
40
+ ...(resolved.config_digest ? { config_digest: resolved.config_digest } : {}),
41
+ },
42
+ base_images: [],
43
+ };
44
+ const manifest = parseEnvironmentImageManifest({
45
+ ...withoutIdentity,
46
+ image_id: environmentImageIdentity(withoutIdentity),
47
+ created_at: new Date().toISOString(),
48
+ });
49
+ const file = environmentImageManifestPath(input.root, manifest.image_id);
50
+ const cacheHit = await regularFile(file);
51
+ if (cacheHit) {
52
+ const persisted = parseEnvironmentImageManifest(await readJSON(file));
53
+ if (persisted.image_id !== manifest.image_id || persisted.output.manifest_digest !== manifest.output.manifest_digest)
54
+ throw new TypeError("registry image cache identity changed");
55
+ return { manifest: persisted, cacheHit: true };
56
+ }
57
+ await ensureDir(path.dirname(file));
58
+ await atomicWriteJSON(file, manifest);
59
+ return { manifest: parseEnvironmentImageManifest(await readJSON(file)), cacheHit: false };
60
+ }
61
+ export class DockerRegistryResolver {
62
+ id;
63
+ docker;
64
+ env;
65
+ constructor({ dockerExecutable, env = process.env, id = "local-docker-registry" } = {}) {
66
+ if (!id)
67
+ throw new TypeError("Docker registry resolver id is invalid");
68
+ this.id = id;
69
+ this.docker = dockerExecutable || env.HITCH_DOCKER_PATH || "docker";
70
+ this.env = env;
71
+ }
72
+ async resolve(reference, platform, signal) {
73
+ if (!validReference(reference) || !platform)
74
+ throw new TypeError("Docker registry image request is invalid");
75
+ try {
76
+ await runCommand(this.docker, ["pull", "--platform", platform, reference], {
77
+ env: this.env,
78
+ failureCode: "image_registry_unavailable",
79
+ failureExitCode: 3,
80
+ ...(signal ? { signal } : {}),
81
+ });
82
+ const result = await runCommand(this.docker, ["image", "inspect", "--format", "{{json .}}", reference], {
83
+ env: this.env,
84
+ failureCode: "image_unavailable",
85
+ failureExitCode: 12,
86
+ timeoutMs: 30_000,
87
+ ...(signal ? { signal } : {}),
88
+ });
89
+ return parseDockerInspection(reference, platform, result.stdout);
90
+ }
91
+ catch (error) {
92
+ if (error.code === "cancelled")
93
+ throw error;
94
+ throw new HitchError("registry image resolution failed", { code: error.code || "image_registry_unavailable", exitCode: 12, cause: error });
95
+ }
96
+ }
97
+ }
98
+ function parseDockerInspection(requested, platform, stdout) {
99
+ let value;
100
+ try {
101
+ value = JSON.parse(stdout);
102
+ }
103
+ catch {
104
+ throw new TypeError("Docker registry inspection is invalid");
105
+ }
106
+ if (!value || typeof value !== "object" || Array.isArray(value))
107
+ throw new TypeError("Docker registry inspection is invalid");
108
+ const image = value;
109
+ if (!digest(image.Id) || typeof image.Os !== "string" || typeof image.Architecture !== "string" || !Array.isArray(image.RepoDigests))
110
+ throw new TypeError("Docker registry image identity is invalid");
111
+ const actualPlatform = `${image.Os}/${image.Architecture}${typeof image.Variant === "string" && image.Variant ? `/${image.Variant}` : ""}`;
112
+ if (actualPlatform !== platform)
113
+ throw new HitchError("registry image platform does not match", { code: "image_platform_mismatch", exitCode: 12 });
114
+ const candidates = image.RepoDigests.filter((entry) => typeof entry === "string" && /@sha256:[a-f0-9]{64}$/.test(entry));
115
+ const requestedDigest = requested.match(/@(sha256:[a-f0-9]{64})$/)?.[1];
116
+ const repository = repositoryOf(requested);
117
+ const selected = candidates.find((entry) => entry === `${repository}@${requestedDigest}`)
118
+ ?? candidates.find((entry) => entry.startsWith(`${repository}@`))
119
+ ?? (candidates.length === 1 ? candidates[0] : undefined);
120
+ if (!selected)
121
+ throw new TypeError("Docker registry manifest digest is unavailable");
122
+ const manifestDigest = selected.slice(selected.lastIndexOf("@") + 1);
123
+ if (requestedDigest && manifestDigest !== requestedDigest)
124
+ throw new HitchError("Docker registry digest does not match", { code: "image_digest_mismatch", exitCode: 12 });
125
+ return { reference: `${repository}@${manifestDigest}`, manifest_digest: manifestDigest, config_digest: image.Id, platform: actualPlatform };
126
+ }
127
+ function repositoryOf(reference) {
128
+ const withoutDigest = reference.split("@")[0];
129
+ const slash = withoutDigest.lastIndexOf("/");
130
+ const colon = withoutDigest.lastIndexOf(":");
131
+ return colon > slash ? withoutDigest.slice(0, colon) : withoutDigest;
132
+ }
133
+ function validReference(value) {
134
+ return typeof value === "string" && value.length > 0 && value.length <= 1_024 && !/[\s\0]/.test(value) && !value.includes("://");
135
+ }
136
+ function digest(value) {
137
+ return typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value);
138
+ }
139
+ function canonicalNames(value) {
140
+ if (value.some((name) => !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)))
141
+ throw new TypeError("registry secret names are invalid");
142
+ return [...new Set(value)].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
143
+ }
144
+ async function regularFile(file) {
145
+ try {
146
+ return (await lstat(file)).isFile();
147
+ }
148
+ catch (error) {
149
+ if (error.code === "ENOENT")
150
+ return false;
151
+ throw error;
152
+ }
153
+ }
154
+ //# sourceMappingURL=registry.js.map