agent-hitch 0.2.9 → 0.2.11

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 (427) hide show
  1. package/README.md +208 -138
  2. package/README.zh-CN.md +195 -120
  3. package/dist/scripts/canary-native-training.js +221 -0
  4. package/dist/scripts/canary-native-training.js.map +1 -0
  5. package/dist/scripts/canary-remote-training.js +246 -0
  6. package/dist/scripts/canary-remote-training.js.map +1 -0
  7. package/dist/scripts/canary-remote-verifier.js +124 -0
  8. package/dist/scripts/canary-remote-verifier.js.map +1 -0
  9. package/dist/scripts/canary-worker-host.js +113 -0
  10. package/dist/scripts/canary-worker-host.js.map +1 -0
  11. package/dist/scripts/canary-worker-peer.js +188 -0
  12. package/dist/scripts/canary-worker-peer.js.map +1 -0
  13. package/dist/scripts/check-architecture.js +4 -3
  14. package/dist/scripts/check-architecture.js.map +1 -1
  15. package/dist/src/adapters/catalog.js +2 -1
  16. package/dist/src/adapters/catalog.js.map +1 -1
  17. package/dist/src/adapters/providers/codex.js +65 -2
  18. package/dist/src/adapters/providers/codex.js.map +1 -1
  19. package/dist/src/adapters/providers/model-call.js +17 -1
  20. package/dist/src/adapters/providers/model-call.js.map +1 -1
  21. package/dist/src/adapters/providers/training-tool.js +29 -0
  22. package/dist/src/adapters/providers/training-tool.js.map +1 -0
  23. package/dist/src/artifacts/index.js +1 -1
  24. package/dist/src/artifacts/index.js.map +1 -1
  25. package/dist/src/artifacts/store.js +15 -10
  26. package/dist/src/artifacts/store.js.map +1 -1
  27. package/dist/src/backends/harbor/backend.js +24 -15
  28. package/dist/src/backends/harbor/backend.js.map +1 -1
  29. package/dist/src/backends/harbor/bridge-environment.js +12 -0
  30. package/dist/src/backends/harbor/bridge-environment.js.map +1 -0
  31. package/dist/src/backends/harbor/environment-config.js +2 -2
  32. package/dist/src/backends/harbor/environment-config.js.map +1 -1
  33. package/dist/src/backends/harbor/host-credential-helper.js +81 -0
  34. package/dist/src/backends/harbor/host-credential-helper.js.map +1 -0
  35. package/dist/src/backends/harbor/index.js +3 -0
  36. package/dist/src/backends/harbor/index.js.map +1 -1
  37. package/dist/src/backends/harbor/model-proxy-config.js +18 -1
  38. package/dist/src/backends/harbor/model-proxy-config.js.map +1 -1
  39. package/dist/src/backends/harbor/observation.js +61 -0
  40. package/dist/src/backends/harbor/observation.js.map +1 -0
  41. package/dist/src/backends/harbor/portable-regrade.js +150 -0
  42. package/dist/src/backends/harbor/portable-regrade.js.map +1 -0
  43. package/dist/src/backends/harbor/process.js +26 -5
  44. package/dist/src/backends/harbor/process.js.map +1 -1
  45. package/dist/src/backends/harbor/regrade.js +4 -1
  46. package/dist/src/backends/harbor/regrade.js.map +1 -1
  47. package/dist/src/backends/harbor/supervisor.js +22 -0
  48. package/dist/src/backends/harbor/supervisor.js.map +1 -1
  49. package/dist/src/backends/harbor/tools.js +2 -0
  50. package/dist/src/backends/harbor/tools.js.map +1 -1
  51. package/dist/src/backends/index.js +3 -0
  52. package/dist/src/backends/index.js.map +1 -1
  53. package/dist/src/cli/arguments.js +33 -0
  54. package/dist/src/cli/arguments.js.map +1 -1
  55. package/dist/src/cli/commands/capabilities.js +15 -1
  56. package/dist/src/cli/commands/capabilities.js.map +1 -1
  57. package/dist/src/cli/commands/daemon.js +19 -0
  58. package/dist/src/cli/commands/daemon.js.map +1 -1
  59. package/dist/src/cli/commands/eval.js +38 -10
  60. package/dist/src/cli/commands/eval.js.map +1 -1
  61. package/dist/src/cli/commands/local.js +130 -0
  62. package/dist/src/cli/commands/local.js.map +1 -0
  63. package/dist/src/cli/commands/model-node.js +26 -0
  64. package/dist/src/cli/commands/model-node.js.map +1 -0
  65. package/dist/src/cli/commands/models.js +72 -0
  66. package/dist/src/cli/commands/models.js.map +1 -0
  67. package/dist/src/cli/commands/run.js +36 -1
  68. package/dist/src/cli/commands/run.js.map +1 -1
  69. package/dist/src/cli/commands/training.js +32 -0
  70. package/dist/src/cli/commands/training.js.map +1 -0
  71. package/dist/src/cli/commands/verifier.js +54 -3
  72. package/dist/src/cli/commands/verifier.js.map +1 -1
  73. package/dist/src/cli/commands/worker.js +30 -2
  74. package/dist/src/cli/commands/worker.js.map +1 -1
  75. package/dist/src/cli/main.js +8 -0
  76. package/dist/src/cli/main.js.map +1 -1
  77. package/dist/src/cli/output.js +26 -2
  78. package/dist/src/cli/output.js.map +1 -1
  79. package/dist/src/control-plane/eval-records.js +2 -0
  80. package/dist/src/control-plane/eval-records.js.map +1 -1
  81. package/dist/src/control-plane/eval-recovery.js +7 -1
  82. package/dist/src/control-plane/eval-recovery.js.map +1 -1
  83. package/dist/src/control-plane/eval-scheduler.js +24 -50
  84. package/dist/src/control-plane/eval-scheduler.js.map +1 -1
  85. package/dist/src/control-plane/eval-submission-persist.js +30 -0
  86. package/dist/src/control-plane/eval-submission-persist.js.map +1 -0
  87. package/dist/src/control-plane/execution-observation-contract.js +60 -0
  88. package/dist/src/control-plane/execution-observation-contract.js.map +1 -0
  89. package/dist/src/control-plane/index.js +10 -0
  90. package/dist/src/control-plane/index.js.map +1 -1
  91. package/dist/src/control-plane/inference-manager.js +357 -0
  92. package/dist/src/control-plane/inference-manager.js.map +1 -0
  93. package/dist/src/control-plane/managed-gateway-receipt.js +26 -0
  94. package/dist/src/control-plane/managed-gateway-receipt.js.map +1 -0
  95. package/dist/src/control-plane/managed-service-recovery.js +158 -0
  96. package/dist/src/control-plane/managed-service-recovery.js.map +1 -0
  97. package/dist/src/control-plane/model-capture-planning.js +15 -1
  98. package/dist/src/control-plane/model-capture-planning.js.map +1 -1
  99. package/dist/src/control-plane/ordered-eval-control.js +221 -0
  100. package/dist/src/control-plane/ordered-eval-control.js.map +1 -0
  101. package/dist/src/control-plane/remote-backend-result.js +18 -0
  102. package/dist/src/control-plane/remote-backend-result.js.map +1 -0
  103. package/dist/src/control-plane/remote-execution-lease.js +15 -0
  104. package/dist/src/control-plane/remote-execution-lease.js.map +1 -0
  105. package/dist/src/control-plane/remote-execution-observation.js +108 -0
  106. package/dist/src/control-plane/remote-execution-observation.js.map +1 -0
  107. package/dist/src/control-plane/remote-model-routes.js +107 -0
  108. package/dist/src/control-plane/remote-model-routes.js.map +1 -0
  109. package/dist/src/control-plane/remote-observation-reporter.js +37 -0
  110. package/dist/src/control-plane/remote-observation-reporter.js.map +1 -0
  111. package/dist/src/control-plane/remote-offer-contract.js +48 -0
  112. package/dist/src/control-plane/remote-offer-contract.js.map +1 -0
  113. package/dist/src/control-plane/remote-rerun-journal.js +61 -0
  114. package/dist/src/control-plane/remote-rerun-journal.js.map +1 -0
  115. package/dist/src/control-plane/remote-result-transport.js +55 -9
  116. package/dist/src/control-plane/remote-result-transport.js.map +1 -1
  117. package/dist/src/control-plane/remote-verifier-import.js +52 -0
  118. package/dist/src/control-plane/remote-verifier-import.js.map +1 -0
  119. package/dist/src/control-plane/remote-verifier-result.js +61 -0
  120. package/dist/src/control-plane/remote-verifier-result.js.map +1 -0
  121. package/dist/src/control-plane/remote-verifier-source-transport.js +68 -0
  122. package/dist/src/control-plane/remote-verifier-source-transport.js.map +1 -0
  123. package/dist/src/control-plane/remote-work-coordinator.js +103 -47
  124. package/dist/src/control-plane/remote-work-coordinator.js.map +1 -1
  125. package/dist/src/control-plane/remote-work-inputs.js +26 -5
  126. package/dist/src/control-plane/remote-work-inputs.js.map +1 -1
  127. package/dist/src/control-plane/remote-work-recovery.js +123 -34
  128. package/dist/src/control-plane/remote-work-recovery.js.map +1 -1
  129. package/dist/src/control-plane/remote-worker-artifacts.js +10 -7
  130. package/dist/src/control-plane/remote-worker-artifacts.js.map +1 -1
  131. package/dist/src/control-plane/remote-worker-cleanup.js +104 -0
  132. package/dist/src/control-plane/remote-worker-cleanup.js.map +1 -0
  133. package/dist/src/control-plane/remote-worker-client.js +156 -14
  134. package/dist/src/control-plane/remote-worker-client.js.map +1 -1
  135. package/dist/src/control-plane/remote-worker-codecs.js +160 -0
  136. package/dist/src/control-plane/remote-worker-codecs.js.map +1 -0
  137. package/dist/src/control-plane/remote-worker-generation-recovery.js +67 -0
  138. package/dist/src/control-plane/remote-worker-generation-recovery.js.map +1 -0
  139. package/dist/src/control-plane/remote-worker-ownership.js +51 -0
  140. package/dist/src/control-plane/remote-worker-ownership.js.map +1 -0
  141. package/dist/src/control-plane/remote-worker-protocol.js +85 -119
  142. package/dist/src/control-plane/remote-worker-protocol.js.map +1 -1
  143. package/dist/src/control-plane/remote-worker-runner.js +95 -18
  144. package/dist/src/control-plane/remote-worker-runner.js.map +1 -1
  145. package/dist/src/control-plane/remote-workers.js +33 -5
  146. package/dist/src/control-plane/remote-workers.js.map +1 -1
  147. package/dist/src/control-plane/rerun-recovery.js +89 -0
  148. package/dist/src/control-plane/rerun-recovery.js.map +1 -0
  149. package/dist/src/control-plane/rerun-scheduler.js +70 -96
  150. package/dist/src/control-plane/rerun-scheduler.js.map +1 -1
  151. package/dist/src/control-plane/rerun-source.js +57 -0
  152. package/dist/src/control-plane/rerun-source.js.map +1 -0
  153. package/dist/src/control-plane/worker-model-relay.js +76 -0
  154. package/dist/src/control-plane/worker-model-relay.js.map +1 -0
  155. package/dist/src/controller-runtime/hash.js +3 -0
  156. package/dist/src/controller-runtime/hash.js.map +1 -1
  157. package/dist/src/controller-runtime/index.js +2 -0
  158. package/dist/src/controller-runtime/index.js.map +1 -1
  159. package/dist/src/controller-runtime/observation.js +29 -0
  160. package/dist/src/controller-runtime/observation.js.map +1 -0
  161. package/dist/src/controller-runtime/resident.js +22 -0
  162. package/dist/src/controller-runtime/resident.js.map +1 -0
  163. package/dist/src/daemon/client.js +34 -1
  164. package/dist/src/daemon/client.js.map +1 -1
  165. package/dist/src/daemon/execution-observation.js +38 -0
  166. package/dist/src/daemon/execution-observation.js.map +1 -0
  167. package/dist/src/daemon/http.js +57 -0
  168. package/dist/src/daemon/http.js.map +1 -0
  169. package/dist/src/daemon/inference-prepare.js +47 -0
  170. package/dist/src/daemon/inference-prepare.js.map +1 -0
  171. package/dist/src/daemon/scheduler.js +4 -1
  172. package/dist/src/daemon/scheduler.js.map +1 -1
  173. package/dist/src/daemon/server.js +80 -82
  174. package/dist/src/daemon/server.js.map +1 -1
  175. package/dist/src/daemon/worker-observation.js +34 -0
  176. package/dist/src/daemon/worker-observation.js.map +1 -0
  177. package/dist/src/daemon/worker-ownership.js +71 -0
  178. package/dist/src/daemon/worker-ownership.js.map +1 -0
  179. package/dist/src/daemon/worker-routes.js +83 -15
  180. package/dist/src/daemon/worker-routes.js.map +1 -1
  181. package/dist/src/domain/execution-observation.js +2 -0
  182. package/dist/src/domain/execution-observation.js.map +1 -0
  183. package/dist/src/domain/index.js +1 -0
  184. package/dist/src/domain/index.js.map +1 -1
  185. package/dist/src/domain/inference.js +2 -0
  186. package/dist/src/domain/inference.js.map +1 -0
  187. package/dist/src/domain/runs.js.map +1 -1
  188. package/dist/src/domain/training.js +2 -0
  189. package/dist/src/domain/training.js.map +1 -0
  190. package/dist/src/domain/validation.js +11 -0
  191. package/dist/src/domain/validation.js.map +1 -1
  192. package/dist/src/domain/verifier-source.js +2 -0
  193. package/dist/src/domain/verifier-source.js.map +1 -0
  194. package/dist/src/domain/worker-recovery.js +2 -0
  195. package/dist/src/domain/worker-recovery.js.map +1 -0
  196. package/dist/src/evals/eval-logical-plan.js +8 -1
  197. package/dist/src/evals/eval-logical-plan.js.map +1 -1
  198. package/dist/src/evals/execution-leases.js +15 -2
  199. package/dist/src/evals/execution-leases.js.map +1 -1
  200. package/dist/src/evals/execution-plan.js +11 -1
  201. package/dist/src/evals/execution-plan.js.map +1 -1
  202. package/dist/src/evals/harbor-bridge-error.js +8 -0
  203. package/dist/src/evals/harbor-bridge-error.js.map +1 -1
  204. package/dist/src/evals/index.js +20 -0
  205. package/dist/src/evals/index.js.map +1 -1
  206. package/dist/src/evals/model-capture-plan.js +12 -0
  207. package/dist/src/evals/model-capture-plan.js.map +1 -1
  208. package/dist/src/evals/model-capture-runtime.js +25 -0
  209. package/dist/src/evals/model-capture-runtime.js.map +1 -1
  210. package/dist/src/evals/physical-work-plan.js +57 -0
  211. package/dist/src/evals/physical-work-plan.js.map +1 -0
  212. package/dist/src/evals/preparation-rerun.js +6 -0
  213. package/dist/src/evals/preparation-rerun.js.map +1 -1
  214. package/dist/src/evals/recovery.js +8 -1
  215. package/dist/src/evals/recovery.js.map +1 -1
  216. package/dist/src/evals/regrade-evidence.js +4 -4
  217. package/dist/src/evals/regrade-evidence.js.map +1 -1
  218. package/dist/src/evals/remote-execution-ownership.js +50 -0
  219. package/dist/src/evals/remote-execution-ownership.js.map +1 -0
  220. package/dist/src/evals/remote-infrastructure-retry.js +2 -0
  221. package/dist/src/evals/remote-infrastructure-retry.js.map +1 -1
  222. package/dist/src/evals/remote-lease-release.js +58 -0
  223. package/dist/src/evals/remote-lease-release.js.map +1 -0
  224. package/dist/src/evals/remote-rerun-execution.js +85 -0
  225. package/dist/src/evals/remote-rerun-execution.js.map +1 -0
  226. package/dist/src/evals/remote-trial.js +6 -0
  227. package/dist/src/evals/remote-trial.js.map +1 -0
  228. package/dist/src/evals/remote-verifier-assessment.js +85 -0
  229. package/dist/src/evals/remote-verifier-assessment.js.map +1 -0
  230. package/dist/src/evals/remote-verifier-contract.js +43 -0
  231. package/dist/src/evals/remote-verifier-contract.js.map +1 -0
  232. package/dist/src/evals/remote-verifier-execution.js +105 -0
  233. package/dist/src/evals/remote-verifier-execution.js.map +1 -0
  234. package/dist/src/evals/remote-verifier-journal.js +21 -0
  235. package/dist/src/evals/remote-verifier-journal.js.map +1 -0
  236. package/dist/src/evals/remote-verifier-outcome.js +51 -0
  237. package/dist/src/evals/remote-verifier-outcome.js.map +1 -0
  238. package/dist/src/evals/remote-verifier-rerun.js +134 -0
  239. package/dist/src/evals/remote-verifier-rerun.js.map +1 -0
  240. package/dist/src/evals/remote-verifier-selection.js +61 -0
  241. package/dist/src/evals/remote-verifier-selection.js.map +1 -0
  242. package/dist/src/evals/remote-verifier-source.js +33 -0
  243. package/dist/src/evals/remote-verifier-source.js.map +1 -0
  244. package/dist/src/evals/remote-worker-cleanup.js +46 -0
  245. package/dist/src/evals/remote-worker-cleanup.js.map +1 -0
  246. package/dist/src/evals/request.js +58 -1
  247. package/dist/src/evals/request.js.map +1 -1
  248. package/dist/src/evals/rerun-completion.js +39 -0
  249. package/dist/src/evals/rerun-completion.js.map +1 -0
  250. package/dist/src/evals/rerun-resume.js +70 -0
  251. package/dist/src/evals/rerun-resume.js.map +1 -0
  252. package/dist/src/evals/rerun-state.js +25 -0
  253. package/dist/src/evals/rerun-state.js.map +1 -0
  254. package/dist/src/evals/rerun-types.js.map +1 -1
  255. package/dist/src/evals/rerun.js +90 -46
  256. package/dist/src/evals/rerun.js.map +1 -1
  257. package/dist/src/evals/service.js +59 -5
  258. package/dist/src/evals/service.js.map +1 -1
  259. package/dist/src/evals/verifier-artifacts.js +98 -153
  260. package/dist/src/evals/verifier-artifacts.js.map +1 -1
  261. package/dist/src/evals/verifier-diagnostic-repair.js +276 -0
  262. package/dist/src/evals/verifier-diagnostic-repair.js.map +1 -0
  263. package/dist/src/evals/verifier-only-rerun.js +2 -16
  264. package/dist/src/evals/verifier-only-rerun.js.map +1 -1
  265. package/dist/src/evals/verifier-rerun-result.js +24 -0
  266. package/dist/src/evals/verifier-rerun-result.js.map +1 -0
  267. package/dist/src/evals/verifier-source-import.js +48 -0
  268. package/dist/src/evals/verifier-source-import.js.map +1 -0
  269. package/dist/src/evals/verifier-source.js +139 -0
  270. package/dist/src/evals/verifier-source.js.map +1 -0
  271. package/dist/src/foundation/base64.js +19 -0
  272. package/dist/src/foundation/base64.js.map +1 -0
  273. package/dist/src/foundation/config.js +10 -0
  274. package/dist/src/foundation/config.js.map +1 -1
  275. package/dist/src/foundation/credential-redaction.js +22 -9
  276. package/dist/src/foundation/credential-redaction.js.map +1 -1
  277. package/dist/src/foundation/index.js +1 -0
  278. package/dist/src/foundation/index.js.map +1 -1
  279. package/dist/src/foundation/process-identity.js +13 -9
  280. package/dist/src/foundation/process-identity.js.map +1 -1
  281. package/dist/src/inference/daemon-capacity.js +41 -0
  282. package/dist/src/inference/daemon-capacity.js.map +1 -0
  283. package/dist/src/inference/device-reservation.js +58 -0
  284. package/dist/src/inference/device-reservation.js.map +1 -0
  285. package/dist/src/inference/doctor.js +95 -0
  286. package/dist/src/inference/doctor.js.map +1 -0
  287. package/dist/src/inference/generation-recovery.js +83 -0
  288. package/dist/src/inference/generation-recovery.js.map +1 -0
  289. package/dist/src/inference/index.js +24 -0
  290. package/dist/src/inference/index.js.map +1 -0
  291. package/dist/src/inference/lock.js +331 -0
  292. package/dist/src/inference/lock.js.map +1 -0
  293. package/dist/src/inference/managed-launcher.js +35 -0
  294. package/dist/src/inference/managed-launcher.js.map +1 -0
  295. package/dist/src/inference/manifest.js +262 -0
  296. package/dist/src/inference/manifest.js.map +1 -0
  297. package/dist/src/inference/materialize.js +66 -0
  298. package/dist/src/inference/materialize.js.map +1 -0
  299. package/dist/src/inference/model-location.js +34 -0
  300. package/dist/src/inference/model-location.js.map +1 -0
  301. package/dist/src/inference/model-store.js +439 -0
  302. package/dist/src/inference/model-store.js.map +1 -0
  303. package/dist/src/inference/node-client.js +167 -0
  304. package/dist/src/inference/node-client.js.map +1 -0
  305. package/dist/src/inference/node-registry.js +79 -0
  306. package/dist/src/inference/node-registry.js.map +1 -0
  307. package/dist/src/inference/observation.js +79 -0
  308. package/dist/src/inference/observation.js.map +1 -0
  309. package/dist/src/inference/preflight.js +132 -0
  310. package/dist/src/inference/preflight.js.map +1 -0
  311. package/dist/src/inference/process-sglang.js +169 -0
  312. package/dist/src/inference/process-sglang.js.map +1 -0
  313. package/dist/src/inference/protocol-probe.js +29 -0
  314. package/dist/src/inference/protocol-probe.js.map +1 -0
  315. package/dist/src/inference/remote-model-store.js +24 -0
  316. package/dist/src/inference/remote-model-store.js.map +1 -0
  317. package/dist/src/inference/runtime-catalog.js +41 -0
  318. package/dist/src/inference/runtime-catalog.js.map +1 -0
  319. package/dist/src/inference/runtime-store.js +93 -0
  320. package/dist/src/inference/runtime-store.js.map +1 -0
  321. package/dist/src/inference/service-attachment.js +46 -0
  322. package/dist/src/inference/service-attachment.js.map +1 -0
  323. package/dist/src/inference/service-inspection.js +38 -0
  324. package/dist/src/inference/service-inspection.js.map +1 -0
  325. package/dist/src/inference/sglang.js +279 -0
  326. package/dist/src/inference/sglang.js.map +1 -0
  327. package/dist/src/inference/supervisor.js +460 -0
  328. package/dist/src/inference/supervisor.js.map +1 -0
  329. package/dist/src/model-access/environment.js +28 -0
  330. package/dist/src/model-access/environment.js.map +1 -0
  331. package/dist/src/model-access/index.js +4 -0
  332. package/dist/src/model-access/index.js.map +1 -1
  333. package/dist/src/model-access/local-gateway-request.js +139 -0
  334. package/dist/src/model-access/local-gateway-request.js.map +1 -0
  335. package/dist/src/model-access/local-gateway.js +323 -0
  336. package/dist/src/model-access/local-gateway.js.map +1 -0
  337. package/dist/src/model-access/proxy.js +90 -5
  338. package/dist/src/model-access/proxy.js.map +1 -1
  339. package/dist/src/model-access/remote-model.js +58 -0
  340. package/dist/src/model-access/remote-model.js.map +1 -0
  341. package/dist/src/model-access/training.js +115 -0
  342. package/dist/src/model-access/training.js.map +1 -0
  343. package/dist/src/runs/adapter-process.js +2 -2
  344. package/dist/src/runs/adapter-process.js.map +1 -1
  345. package/dist/src/runs/executor-types.js +2 -0
  346. package/dist/src/runs/executor-types.js.map +1 -0
  347. package/dist/src/runs/executor.js +54 -34
  348. package/dist/src/runs/executor.js.map +1 -1
  349. package/dist/src/runs/index.js +4 -2
  350. package/dist/src/runs/index.js.map +1 -1
  351. package/dist/src/runs/local-inference-environment.js +59 -0
  352. package/dist/src/runs/local-inference-environment.js.map +1 -0
  353. package/dist/src/runs/local-inference-run.js +53 -0
  354. package/dist/src/runs/local-inference-run.js.map +1 -0
  355. package/dist/src/runs/outcome.js +22 -0
  356. package/dist/src/runs/outcome.js.map +1 -1
  357. package/dist/src/runs/records.js +9 -0
  358. package/dist/src/runs/records.js.map +1 -1
  359. package/dist/src/runs/request.js +58 -3
  360. package/dist/src/runs/request.js.map +1 -1
  361. package/dist/src/runs/training-evidence.js +22 -0
  362. package/dist/src/runs/training-evidence.js.map +1 -0
  363. package/dist/src/runs/training-runtime.js +20 -0
  364. package/dist/src/runs/training-runtime.js.map +1 -0
  365. package/dist/src/runs/verifier-diagnostic-storage.js +237 -0
  366. package/dist/src/runs/verifier-diagnostic-storage.js.map +1 -0
  367. package/dist/src/runs/verifier-diagnostic-supplement.js +228 -0
  368. package/dist/src/runs/verifier-diagnostic-supplement.js.map +1 -0
  369. package/dist/src/runs/verifier-evidence.js +119 -118
  370. package/dist/src/runs/verifier-evidence.js.map +1 -1
  371. package/dist/src/trajectories/providers/deepseek.js +52 -38
  372. package/dist/src/trajectories/providers/deepseek.js.map +1 -1
  373. package/dist/src/trajectories/store.js +17 -0
  374. package/dist/src/trajectories/store.js.map +1 -1
  375. package/dist/src/workers/execution-observation.js +32 -0
  376. package/dist/src/workers/execution-observation.js.map +1 -0
  377. package/dist/src/workers/index.js +2 -0
  378. package/dist/src/workers/index.js.map +1 -1
  379. package/dist/src/workers/remote-harbor-ownership.js +266 -0
  380. package/dist/src/workers/remote-harbor-ownership.js.map +1 -0
  381. package/dist/src/workers/remote-harbor-verifier.js +76 -0
  382. package/dist/src/workers/remote-harbor-verifier.js.map +1 -0
  383. package/dist/src/workers/remote-harbor-work-spec.js +66 -10
  384. package/dist/src/workers/remote-harbor-work-spec.js.map +1 -1
  385. package/dist/src/workers/remote-harbor-worker.js +56 -49
  386. package/dist/src/workers/remote-harbor-worker.js.map +1 -1
  387. package/dist/src/workers/remote-worker-host.js +33 -0
  388. package/dist/src/workers/remote-worker-host.js.map +1 -0
  389. package/docs/local-model-inference-spec.zh-CN.md +666 -0
  390. package/docs/schemas/controller-runtime-observation.schema.json +21 -0
  391. package/docs/schemas/eval-execution-plan.schema.json +1 -0
  392. package/docs/schemas/eval-request.schema.json +3 -1
  393. package/docs/schemas/execution-lease.schema.json +95 -1
  394. package/docs/schemas/execution-provider-status.schema.json +162 -28
  395. package/docs/schemas/inference-execution-evidence.schema.json +487 -0
  396. package/docs/schemas/inference-lock.schema.json +487 -0
  397. package/docs/schemas/inference-runtime-manifest.schema.json +156 -0
  398. package/docs/schemas/inference-service-record.schema.json +227 -0
  399. package/docs/schemas/local-inference-selection.schema.json +98 -0
  400. package/docs/schemas/local-model-manifest.schema.json +43 -0
  401. package/docs/schemas/model-node-binding.schema.json +34 -0
  402. package/docs/schemas/model-node-generation-release.schema.json +46 -0
  403. package/docs/schemas/ordered-eval-control.schema.json +39 -0
  404. package/docs/schemas/remote-execution-lease-grant.schema.json +45 -0
  405. package/docs/schemas/remote-harbor-work-spec.schema.json +325 -0
  406. package/docs/schemas/remote-model-binding.schema.json +21 -0
  407. package/docs/schemas/remote-physical-execution.schema.json +108 -0
  408. package/docs/schemas/remote-result-envelope.schema.json +9 -3
  409. package/docs/schemas/remote-tree-envelope.schema.json +17 -3
  410. package/docs/schemas/remote-verifier-result.schema.json +203 -0
  411. package/docs/schemas/remote-verifier-source.schema.json +52 -0
  412. package/docs/schemas/remote-verifier-work.schema.json +125 -0
  413. package/docs/schemas/remote-work-offer.schema.json +170 -34
  414. package/docs/schemas/remote-worker-execution-admission.schema.json +214 -0
  415. package/docs/schemas/remote-worker-generation-cleanup.schema.json +199 -0
  416. package/docs/schemas/remote-worker-registration.schema.json +226 -25
  417. package/docs/schemas/run-manifest.schema.json +211 -44
  418. package/docs/schemas/run-request.schema.json +2 -1
  419. package/docs/schemas/training-external-binding.schema.json +26 -0
  420. package/docs/schemas/verifier-diagnostic-page.schema.json +97 -0
  421. package/integrations/harbor/hitch_harbor_agent.py +241 -13
  422. package/integrations/harbor/hitch_harbor_environment.py +22 -1
  423. package/integrations/harbor/hitch_host_credentials.py +354 -0
  424. package/integrations/harbor/hitch_private_exec.py +150 -0
  425. package/integrations/model-call/cli.js +13 -5
  426. package/integrations/training-tool/cli.js +72 -0
  427. package/package.json +8 -2
@@ -0,0 +1,228 @@
1
+ import { lstat, realpath } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { openContainedRegularFile, sha256Bytes, statePaths } from "../foundation/index.js";
4
+ import { verifyResultBundleIndex } from "./bundle.js";
5
+ import { loadRunRecord } from "./records.js";
6
+ const DIAGNOSTICS_INDEX_REF = "verifier/diagnostics.json";
7
+ const MAX_INDEX_BYTES = 1024 * 1024;
8
+ const ARTIFACT_NAMES = new Set(["ctrf.json", "test-stdout.txt", "test-stderr.txt", "stdout.txt", "stderr.txt"]);
9
+ export function verifierDiagnosticSupplementRelative(runId, originalIndexSha256) {
10
+ if (!/^run_[a-f0-9]{32}$/.test(runId) || !/^sha256:[0-9a-f]{64}$/.test(originalIndexSha256)) {
11
+ throw new TypeError("verifier diagnostic supplement identity is invalid");
12
+ }
13
+ return path.join(runId, originalIndexSha256.slice("sha256:".length));
14
+ }
15
+ export function verifierDiagnosticSupplementBase(root) {
16
+ return path.join(statePaths(root).root, "derived", "verifier-diagnostics");
17
+ }
18
+ export async function loadVerifierDiagnosticSupplement(root, runRoot, runId) {
19
+ let originalIndex;
20
+ try {
21
+ originalIndex = await readContained(runRoot, DIAGNOSTICS_INDEX_REF, MAX_INDEX_BYTES);
22
+ }
23
+ catch (error) {
24
+ if (error.code === "ENOENT")
25
+ return null;
26
+ throw error;
27
+ }
28
+ const originalIndexSha256 = sha256Bytes(originalIndex);
29
+ const relative = verifierDiagnosticSupplementRelative(runId, originalIndexSha256);
30
+ const base = verifierDiagnosticSupplementBase(await canonicalStateRoot(root));
31
+ let canonicalBase;
32
+ try {
33
+ const info = await lstat(base);
34
+ if (info.isSymbolicLink() || !info.isDirectory())
35
+ throw new TypeError("verifier diagnostic supplement root is unsafe");
36
+ canonicalBase = await realpath(base);
37
+ if (canonicalBase !== path.resolve(base))
38
+ throw new TypeError("verifier diagnostic supplement root is unsafe");
39
+ }
40
+ catch (error) {
41
+ if (error.code === "ENOENT")
42
+ return null;
43
+ throw error;
44
+ }
45
+ const manifestRef = path.join(relative, "repair.json").split(path.sep).join("/");
46
+ let manifestBytes;
47
+ try {
48
+ manifestBytes = await readContained(canonicalBase, manifestRef, MAX_INDEX_BYTES);
49
+ }
50
+ catch (error) {
51
+ if (error.code === "ENOENT")
52
+ return null;
53
+ throw error;
54
+ }
55
+ const manifest = parseVerifierDiagnosticRepairManifest(JSON.parse(manifestBytes.toString("utf8")));
56
+ const run = await loadRunRecord(runRoot, { verifyTrajectory: false });
57
+ const parent = run.record.parent;
58
+ if (manifest.run_id !== runId || !parent || run.record.context.kind !== "benchmark_task"
59
+ || manifest.parent.eval_id !== parent.eval_id || manifest.parent.trial_id !== parent.trial_id
60
+ || manifest.parent.attempt !== parent.attempt || manifest.parent.task_id !== run.record.context.task_id) {
61
+ throw new TypeError("verifier diagnostic repair parent identity mismatch");
62
+ }
63
+ const bundle = await verifyResultBundleIndex(runRoot);
64
+ const bundleIndexSha256 = sha256Bytes(await readContained(runRoot, "bundle.index.json", MAX_INDEX_BYTES));
65
+ if (manifest.original.bundle_digest !== bundle.bundle_digest
66
+ || manifest.original.bundle_index_sha256 !== bundleIndexSha256
67
+ || manifest.original.diagnostics_index_sha256 !== originalIndexSha256) {
68
+ throw new TypeError("verifier diagnostic repair original bundle identity mismatch");
69
+ }
70
+ const expectedSources = sourceIdentitiesFromLegacyIndex(JSON.parse(originalIndex.toString("utf8")));
71
+ if (JSON.stringify(manifest.source.artifacts) !== JSON.stringify(expectedSources)) {
72
+ throw new TypeError("verifier diagnostic repair source identity mismatch");
73
+ }
74
+ const repairedIndexRef = path.join(relative, DIAGNOSTICS_INDEX_REF).split(path.sep).join("/");
75
+ const repairedIndex = await readContained(canonicalBase, repairedIndexRef, MAX_INDEX_BYTES);
76
+ if (sha256Bytes(repairedIndex) !== manifest.repaired.diagnostics_index_sha256) {
77
+ throw new TypeError("verifier diagnostic repair index digest mismatch");
78
+ }
79
+ const repairedValue = JSON.parse(repairedIndex.toString("utf8"));
80
+ if (repairedValue.schema_version !== "2" || repairedValue.kind !== "verifier-diagnostics"
81
+ || !Array.isArray(repairedValue.artifacts) || !Array.isArray(repairedValue.losses)
82
+ || repairedValue.losses.length !== 0) {
83
+ throw new TypeError("verifier diagnostic repair index is incomplete");
84
+ }
85
+ return {
86
+ directory: path.join(canonicalBase, relative),
87
+ manifest,
88
+ repair_sha256: sha256Bytes(manifestBytes),
89
+ };
90
+ }
91
+ async function canonicalStateRoot(root) {
92
+ const resolved = path.resolve(root);
93
+ const info = await lstat(resolved);
94
+ if (info.isSymbolicLink() || !info.isDirectory())
95
+ throw new TypeError("Hitch state root is unsafe");
96
+ const canonical = await realpath(resolved);
97
+ const canonicalInfo = await lstat(canonical);
98
+ if (canonicalInfo.isSymbolicLink() || !canonicalInfo.isDirectory())
99
+ throw new TypeError("Hitch state root is unsafe");
100
+ return canonical;
101
+ }
102
+ export function sourceIdentitiesFromLegacyIndex(value) {
103
+ if (!value || typeof value !== "object" || Array.isArray(value))
104
+ throw new TypeError("verifier diagnostics index is invalid");
105
+ const index = value;
106
+ if (index.schema_version !== "1" || index.kind !== "verifier-diagnostics" || !Array.isArray(index.artifacts)) {
107
+ throw new TypeError("verifier diagnostics repair requires a legacy index");
108
+ }
109
+ const seen = new Set();
110
+ const artifacts = index.artifacts.map((raw) => {
111
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
112
+ throw new TypeError("legacy verifier diagnostic artifact is invalid");
113
+ const artifact = raw;
114
+ const name = artifact.name;
115
+ if (typeof name !== "string" || !ARTIFACT_NAMES.has(name) || seen.has(name)
116
+ || artifact.ref !== `verifier/${name}` || typeof artifact.truncated !== "boolean"
117
+ || !Number.isSafeInteger(artifact.source_bytes) || Number(artifact.source_bytes) < 0
118
+ || typeof artifact.source_sha256 !== "string" || !/^sha256:[0-9a-f]{64}$/.test(artifact.source_sha256)) {
119
+ throw new TypeError("legacy verifier diagnostic artifact identity is invalid");
120
+ }
121
+ seen.add(name);
122
+ return {
123
+ name: name,
124
+ bytes: Number(artifact.source_bytes),
125
+ sha256: artifact.source_sha256,
126
+ };
127
+ });
128
+ return artifacts.sort((left, right) => left.name.localeCompare(right.name));
129
+ }
130
+ export function legacyIndexNeedsDiagnosticRepair(value) {
131
+ if (!value || typeof value !== "object" || Array.isArray(value))
132
+ return false;
133
+ const index = value;
134
+ return index.schema_version === "1" && Array.isArray(index.artifacts)
135
+ && index.artifacts.some((raw) => Boolean(raw && typeof raw === "object" && !Array.isArray(raw) && raw.truncated === true));
136
+ }
137
+ async function readContained(root, relative, maximumBytes) {
138
+ const opened = await openContainedRegularFile(root, relative, maximumBytes);
139
+ try {
140
+ const bytes = Buffer.allocUnsafe(opened.size);
141
+ let position = 0;
142
+ while (position < bytes.length) {
143
+ const read = await opened.handle.read(bytes, position, bytes.length - position, position);
144
+ if (read.bytesRead === 0)
145
+ throw new TypeError("verifier diagnostic evidence changed while being read");
146
+ position += read.bytesRead;
147
+ }
148
+ if ((await opened.handle.read(Buffer.allocUnsafe(1), 0, 1, bytes.length)).bytesRead !== 0) {
149
+ throw new TypeError("verifier diagnostic evidence changed while being read");
150
+ }
151
+ await opened.assertUnchanged();
152
+ return bytes;
153
+ }
154
+ finally {
155
+ await opened.handle.close();
156
+ }
157
+ }
158
+ function parseVerifierDiagnosticRepairManifest(value) {
159
+ if (!value || typeof value !== "object" || Array.isArray(value))
160
+ throw new TypeError("verifier diagnostic repair manifest is invalid");
161
+ const record = value;
162
+ exact(record, ["schema_version", "kind", "run_id", "parent", "original", "source", "repaired", "created_at"]);
163
+ if (record.schema_version !== "1" || record.kind !== "verifier-diagnostics-repair"
164
+ || typeof record.run_id !== "string" || !/^run_[a-f0-9]{32}$/.test(record.run_id)
165
+ || typeof record.created_at !== "string" || !Number.isFinite(Date.parse(record.created_at))) {
166
+ throw new TypeError("verifier diagnostic repair manifest identity is invalid");
167
+ }
168
+ const parent = object(record.parent, "verifier diagnostic repair parent");
169
+ exact(parent, ["eval_id", "trial_id", "attempt", "task_id"]);
170
+ if (typeof parent.eval_id !== "string" || !/^eval_[a-f0-9]{32}$/.test(parent.eval_id)
171
+ || typeof parent.trial_id !== "string" || !parent.trial_id || typeof parent.task_id !== "string" || !parent.task_id
172
+ || !Number.isSafeInteger(parent.attempt) || Number(parent.attempt) < 1)
173
+ throw new TypeError("verifier diagnostic repair parent is invalid");
174
+ const original = object(record.original, "verifier diagnostic repair original identity");
175
+ exact(original, ["bundle_digest", "bundle_index_sha256", "diagnostics_index_sha256"]);
176
+ const source = object(record.source, "verifier diagnostic repair source");
177
+ exact(source, ["kind", "relative_trial_directory", "artifacts"]);
178
+ const repaired = object(record.repaired, "verifier diagnostic repair output");
179
+ exact(repaired, ["diagnostics_index_sha256"]);
180
+ for (const digest of [original.bundle_digest, original.bundle_index_sha256, original.diagnostics_index_sha256, repaired.diagnostics_index_sha256]) {
181
+ if (typeof digest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(digest))
182
+ throw new TypeError("verifier diagnostic repair digest is invalid");
183
+ }
184
+ if (source.kind !== "harbor-trial" || typeof source.relative_trial_directory !== "string"
185
+ || !validRelativePath(source.relative_trial_directory) || !Array.isArray(source.artifacts)) {
186
+ throw new TypeError("verifier diagnostic repair source is invalid");
187
+ }
188
+ const artifacts = source.artifacts.map((raw) => {
189
+ const artifact = object(raw, "verifier diagnostic repair source artifact");
190
+ exact(artifact, ["name", "bytes", "sha256"]);
191
+ if (typeof artifact.name !== "string" || !ARTIFACT_NAMES.has(artifact.name)
192
+ || !Number.isSafeInteger(artifact.bytes) || Number(artifact.bytes) < 0
193
+ || typeof artifact.sha256 !== "string" || !/^sha256:[0-9a-f]{64}$/.test(artifact.sha256)) {
194
+ throw new TypeError("verifier diagnostic repair source artifact is invalid");
195
+ }
196
+ return { name: artifact.name, bytes: Number(artifact.bytes), sha256: artifact.sha256 };
197
+ });
198
+ const canonical = [...artifacts].sort((left, right) => left.name.localeCompare(right.name));
199
+ if (new Set(artifacts.map((entry) => entry.name)).size !== artifacts.length || JSON.stringify(canonical) !== JSON.stringify(artifacts)) {
200
+ throw new TypeError("verifier diagnostic repair source artifacts are not canonical");
201
+ }
202
+ return {
203
+ schema_version: "1", kind: "verifier-diagnostics-repair", run_id: record.run_id,
204
+ parent: { eval_id: parent.eval_id, trial_id: parent.trial_id, attempt: Number(parent.attempt), task_id: parent.task_id },
205
+ original: {
206
+ bundle_digest: original.bundle_digest,
207
+ bundle_index_sha256: original.bundle_index_sha256,
208
+ diagnostics_index_sha256: original.diagnostics_index_sha256,
209
+ },
210
+ source: { kind: "harbor-trial", relative_trial_directory: source.relative_trial_directory, artifacts },
211
+ repaired: { diagnostics_index_sha256: repaired.diagnostics_index_sha256 },
212
+ created_at: record.created_at,
213
+ };
214
+ }
215
+ function object(value, label) {
216
+ if (!value || typeof value !== "object" || Array.isArray(value))
217
+ throw new TypeError(`${label} is invalid`);
218
+ return value;
219
+ }
220
+ function exact(value, fields) {
221
+ if (Object.keys(value).some((field) => !fields.includes(field)))
222
+ throw new TypeError("verifier diagnostic repair has unknown fields");
223
+ }
224
+ function validRelativePath(value) {
225
+ return value === value.normalize("NFC") && !path.posix.isAbsolute(value) && !value.includes("\\")
226
+ && value.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
227
+ }
228
+ //# sourceMappingURL=verifier-diagnostic-supplement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier-diagnostic-supplement.js","sourceRoot":"","sources":["../../../src/runs/verifier-diagnostic-supplement.ts"],"names":[],"mappings":"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"}
@@ -4,21 +4,19 @@ import { validateRelativePath } from "../domain/index.js";
4
4
  import { HitchError, PROVIDER_ENVIRONMENT_NAMES, credentialValuesFromEnv, openContainedRegularFile, safeDiagnosticMessage, sha256Bytes, statePaths, } from "../foundation/index.js";
5
5
  import { verifyResultBundleIndex } from "./bundle.js";
6
6
  import { loadRunRecord } from "./records.js";
7
+ import { readVerifierDiagnosticStorage, VERIFIER_DIAGNOSTIC_ARTIFACT_NAMES, } from "./verifier-diagnostic-storage.js";
7
8
  import { sanitizeVerifierJson, sanitizeVerifierText } from "./verifier-evidence-redaction.js";
9
+ import { loadVerifierDiagnosticSupplement } from "./verifier-diagnostic-supplement.js";
8
10
  import { loadStructuredVerifierEvidence } from "./verifier-structured-evidence.js";
9
11
  export const MAX_VERIFIER_RESULT_BYTES = 1024 * 1024;
10
12
  export const MAX_VERIFIER_ARTIFACT_OUTPUT_BYTES = 64 * 1024;
11
- const DIAGNOSTICS_INDEX_REF = "verifier/diagnostics.json";
12
- const ARTIFACT_NAMES = [
13
- "ctrf.json", "test-stdout.txt", "test-stderr.txt", "stdout.txt", "stderr.txt",
14
- ];
13
+ export const MAX_VERIFIER_DIAGNOSTIC_PAGE_BYTES = 64 * 1024;
15
14
  const JSON_DIAGNOSTIC_REFS = [
16
15
  "verifier/infrastructure-error.json",
17
16
  "verifier/infrastructure-retry-history.json",
18
17
  ];
19
18
  const TRUNCATION_MARKER = "\n[... verifier artifact truncated ...]\n";
20
19
  const MAX_EVAL_IDENTITY_BYTES = 16 * 1024 * 1024;
21
- const MAX_PERSISTED_VERIFIER_ARTIFACT_BYTES = 16 * 1024 * 1024;
22
20
  export async function loadVerifierEvidence(root, runId, options = {}) {
23
21
  if (!/^run_[a-f0-9]{32}$/.test(runId))
24
22
  throw new TypeError(`invalid run ID: ${runId}`);
@@ -76,7 +74,8 @@ export async function loadVerifierEvidence(root, runId, options = {}) {
76
74
  }
77
75
  let diagnostics;
78
76
  try {
79
- diagnostics = await loadDiagnostics(runRoot, maxArtifactBytes, credentialValues, redactions);
77
+ const supplement = await loadVerifierDiagnosticSupplement(root, runRoot, runId);
78
+ diagnostics = await loadDiagnostics(runRoot, supplement?.directory ?? runRoot, maxArtifactBytes, credentialValues, redactions);
80
79
  }
81
80
  catch (error) {
82
81
  corrupt = true;
@@ -144,11 +143,103 @@ export async function loadVerifierEvidence(root, runId, options = {}) {
144
143
  ...(redactions.size === 0 ? {} : { redactions: canonicalCounts(redactions) }),
145
144
  };
146
145
  }
147
- async function loadDiagnostics(runRoot, maxBytes, credentialValues, redactions) {
148
- const indexFile = path.join(runRoot, ...DIAGNOSTICS_INDEX_REF.split("/"));
149
- const artifacts = await exists(indexFile)
150
- ? await indexedArtifacts(runRoot, maxBytes, credentialValues, redactions)
151
- : await legacyArtifacts(runRoot, maxBytes, credentialValues, redactions);
146
+ export async function loadVerifierDiagnosticPage(root, runId, name, options = {}) {
147
+ if (!/^run_[a-f0-9]{32}$/.test(runId))
148
+ throw new TypeError(`invalid run ID: ${runId}`);
149
+ if (!VERIFIER_DIAGNOSTIC_ARTIFACT_NAMES.includes(name))
150
+ throw new TypeError(`invalid verifier diagnostic artifact: ${name}`);
151
+ const offset = options.offset ?? 0;
152
+ if (!Number.isSafeInteger(offset) || offset < 0)
153
+ throw new TypeError("verifier diagnostic offset is invalid");
154
+ const maxBytes = options.maxBytes ?? MAX_VERIFIER_DIAGNOSTIC_PAGE_BYTES;
155
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 4 || maxBytes > MAX_VERIFIER_DIAGNOSTIC_PAGE_BYTES) {
156
+ throw new TypeError("verifier diagnostic page limit is invalid");
157
+ }
158
+ const runDirectory = path.join(statePaths(root).runs, runId);
159
+ const runRoot = await safeRunRoot(runDirectory, runId);
160
+ let loaded;
161
+ try {
162
+ loaded = await loadRunRecord(runDirectory, { verifyTrajectory: false });
163
+ if (loaded.record_status === "corrupt" || loaded.record.run_id !== runId)
164
+ throw new TypeError("run record integrity is corrupt");
165
+ if (await exists(path.join(runDirectory, "bundle.index.json")))
166
+ await verifyResultBundleIndex(runDirectory);
167
+ }
168
+ catch (error) {
169
+ throw new HitchError(`run ${runId} record is corrupt`, { code: "verifier_evidence_corrupt", exitCode: 3, cause: error });
170
+ }
171
+ const parentIssue = await verifierParentIssue(root, loaded.record);
172
+ if (parentIssue) {
173
+ throw new HitchError(`run ${runId} verifier parent is corrupt: ${parentIssue}`, {
174
+ code: "verifier_evidence_corrupt", exitCode: 3,
175
+ });
176
+ }
177
+ const credentialValues = await runCredentialValues(runRoot, loaded.record, options.env ?? process.env);
178
+ let source;
179
+ try {
180
+ const supplement = await loadVerifierDiagnosticSupplement(root, runRoot, runId);
181
+ const stored = await readVerifierDiagnosticStorage(supplement?.directory ?? runRoot, credentialValues);
182
+ const found = stored.artifacts.find((artifact) => artifact.name === name);
183
+ if (!found)
184
+ throw diagnosticNotFound(name);
185
+ source = found;
186
+ }
187
+ catch (error) {
188
+ if (error instanceof HitchError)
189
+ throw error;
190
+ throw new HitchError(`verifier diagnostic ${name} is corrupt`, {
191
+ code: "verifier_evidence_corrupt", exitCode: 3, cause: error,
192
+ });
193
+ }
194
+ if (options.expectedSha256 !== undefined && options.expectedSha256 !== source.sha256) {
195
+ throw new HitchError(`verifier diagnostic ${name} changed`, {
196
+ code: "verifier_diagnostic_version_mismatch", exitCode: 3,
197
+ });
198
+ }
199
+ const artifact = {
200
+ name,
201
+ media_type: source.mediaType,
202
+ bytes: source.bytes.length,
203
+ sha256: source.sha256,
204
+ source_complete: source.sourceComplete,
205
+ ...(source.lossReason ? { loss_reason: source.lossReason } : {}),
206
+ };
207
+ if (!source.sourceComplete) {
208
+ if (offset !== 0)
209
+ throw new TypeError("unavailable verifier diagnostic requires offset zero");
210
+ return {
211
+ schema_version: "1", kind: "verifier-diagnostic-page", run_id: runId, artifact,
212
+ page: { offset: 0, bytes: 0, text: "", eof: true },
213
+ };
214
+ }
215
+ if (offset > source.bytes.length || !isUtf8Boundary(source.bytes, offset)) {
216
+ throw new TypeError("verifier diagnostic offset is invalid");
217
+ }
218
+ let end = Math.min(source.bytes.length, offset + maxBytes);
219
+ while (end > offset && end < source.bytes.length && !isUtf8Boundary(source.bytes, end))
220
+ end -= 1;
221
+ if (end === offset && end < source.bytes.length)
222
+ throw new TypeError("verifier diagnostic page limit is too small");
223
+ const page = source.bytes.subarray(offset, end);
224
+ const eof = end === source.bytes.length;
225
+ return {
226
+ schema_version: "1", kind: "verifier-diagnostic-page", run_id: runId, artifact,
227
+ page: {
228
+ offset,
229
+ bytes: page.length,
230
+ text: page.toString("utf8"),
231
+ eof,
232
+ ...(eof ? {} : { next_offset: end }),
233
+ },
234
+ };
235
+ }
236
+ async function loadDiagnostics(runRoot, artifactRoot, maxBytes, credentialValues, redactions) {
237
+ const stored = await readVerifierDiagnosticStorage(artifactRoot, credentialValues);
238
+ mergeCounts(redactions, stored.redactions);
239
+ const artifacts = stored.artifacts.map((artifact) => {
240
+ const bounded = truncate(artifact.bytes, maxBytes);
241
+ return excerpt(artifact.name, artifact.mediaType, artifact.bytes.length, artifact.sha256, !artifact.sourceComplete || bounded.truncated, bounded.bytes);
242
+ });
152
243
  const ctrf = artifacts.find((artifact) => artifact.name === "ctrf.json");
153
244
  const stdout = artifacts.filter((artifact) => artifact.name === "test-stdout.txt" || artifact.name === "stdout.txt");
154
245
  const stderr = artifacts.filter((artifact) => artifact.name === "test-stderr.txt" || artifact.name === "stderr.txt");
@@ -164,95 +255,13 @@ async function loadDiagnostics(runRoot, maxBytes, credentialValues, redactions)
164
255
  ...(retryHistory === undefined ? {} : { retry_history: [retryHistory] }),
165
256
  };
166
257
  }
167
- async function indexedArtifacts(runRoot, maxBytes, credentialValues, redactions) {
168
- const indexBytes = await secureRead(runRoot, DIAGNOSTICS_INDEX_REF, MAX_VERIFIER_RESULT_BYTES);
169
- const index = asRecord(JSON.parse(indexBytes.toString("utf8")), "verifier diagnostics index");
170
- if (index.schema_version !== "1" || index.kind !== "verifier-diagnostics" || !Array.isArray(index.artifacts) || !Array.isArray(index.redactions)) {
171
- throw new TypeError("verifier diagnostics index is invalid");
172
- }
173
- const seen = new Set();
174
- for (const rule of index.redactions) {
175
- const parsed = asRecord(rule, "verifier diagnostics redaction");
176
- exactFields(parsed, ["rule_id", "count"], "verifier diagnostics redaction");
177
- if (typeof parsed.rule_id !== "string" || !/^[a-z0-9][a-z0-9._-]{0,127}$/.test(parsed.rule_id)
178
- || !Number.isSafeInteger(parsed.count) || Number(parsed.count) < 1) {
179
- throw new TypeError("verifier diagnostics redaction is invalid");
180
- }
181
- if (seen.has(`redaction:${parsed.rule_id}`))
182
- throw new TypeError("verifier diagnostics redactions are duplicated");
183
- seen.add(`redaction:${parsed.rule_id}`);
184
- increment(redactions, parsed.rule_id, Number(parsed.count));
185
- }
186
- const result = [];
187
- for (const raw of index.artifacts) {
188
- const artifact = asRecord(raw, "verifier diagnostic artifact");
189
- exactFields(artifact, [
190
- "name", "ref", "media_type", "source_bytes", "source_sha256", "bytes", "sha256",
191
- "stored_bytes", "stored_sha256", "truncated",
192
- ], "verifier diagnostic artifact");
193
- const name = artifact.name;
194
- if (!ARTIFACT_NAMES.includes(name) || seen.has(name) || artifact.ref !== `verifier/${name}`) {
195
- throw new TypeError("verifier diagnostic artifact identity is invalid");
196
- }
197
- seen.add(name);
198
- const mediaType = name === "ctrf.json" ? "application/json" : "text/plain";
199
- if (artifact.media_type !== mediaType)
200
- throw new TypeError("verifier diagnostic artifact media type is invalid");
201
- const persistedBytes = nonNegativeInteger(artifact.bytes, "verifier diagnostic bytes");
202
- const persistedDigest = sha256Value(artifact.sha256, "verifier diagnostic digest");
203
- nonNegativeInteger(artifact.source_bytes, "source verifier diagnostic bytes");
204
- sha256Value(artifact.source_sha256, "source verifier diagnostic digest");
205
- const storedBytes = nonNegativeInteger(artifact.stored_bytes, "stored verifier diagnostic bytes");
206
- const storedDigest = sha256Value(artifact.stored_sha256, "stored verifier diagnostic digest");
207
- if (typeof artifact.truncated !== "boolean" || storedBytes > MAX_PERSISTED_VERIFIER_ARTIFACT_BYTES) {
208
- throw new TypeError("stored verifier diagnostic exceeds its persistence limit");
209
- }
210
- const stored = await secureRead(runRoot, String(artifact.ref), MAX_PERSISTED_VERIFIER_ARTIFACT_BYTES);
211
- if (stored.length !== storedBytes || sha256Bytes(stored) !== storedDigest)
212
- throw new TypeError("stored verifier diagnostic integrity mismatch");
213
- if (artifact.truncated === false && (persistedBytes !== storedBytes || persistedDigest !== storedDigest)) {
214
- throw new TypeError("complete verifier diagnostic metadata mismatch");
215
- }
216
- const full = sanitizedArtifact(stored, mediaType, artifact.truncated === false, credentialValues, redactions);
217
- const bounded = truncate(full, maxBytes);
218
- result.push(excerpt(name, mediaType, full.length, sha256Bytes(full), artifact.truncated === true || bounded.truncated, bounded.bytes));
219
- }
220
- return result;
258
+ function diagnosticNotFound(name) {
259
+ return new HitchError(`verifier diagnostic not found: ${name}`, {
260
+ code: "verifier_diagnostic_not_found", exitCode: 3,
261
+ });
221
262
  }
222
- async function legacyArtifacts(runRoot, maxBytes, credentialValues, redactions) {
223
- const result = [];
224
- for (const name of ARTIFACT_NAMES) {
225
- const ref = `verifier/${name}`;
226
- if (!await exists(path.join(runRoot, ...ref.split("/"))))
227
- continue;
228
- let raw;
229
- try {
230
- raw = await secureRead(runRoot, ref, MAX_PERSISTED_VERIFIER_ARTIFACT_BYTES);
231
- }
232
- catch (error) {
233
- if (error?.message === "contained file exceeds its limit")
234
- continue;
235
- throw error;
236
- }
237
- const mediaType = name === "ctrf.json" ? "application/json" : "text/plain";
238
- const full = sanitizedArtifact(raw, mediaType, mediaType === "application/json", credentialValues, redactions);
239
- const stored = truncate(full, maxBytes);
240
- result.push(excerpt(name, mediaType, full.length, sha256Bytes(full), stored.truncated, stored.bytes));
241
- }
242
- return result;
243
- }
244
- function sanitizedArtifact(stored, mediaType, parseJson, credentials, redactions) {
245
- if (mediaType === "application/json" && parseJson) {
246
- const parsed = JSON.parse(stored.toString("utf8"));
247
- if (!isJsonValue(parsed))
248
- throw new TypeError("CTRF artifact is not JSON data");
249
- const safe = sanitizeVerifierJson(parsed, credentials);
250
- mergeCounts(redactions, safe.redactions);
251
- return Buffer.from(JSON.stringify(safe.value), "utf8");
252
- }
253
- const safe = sanitizeVerifierText(stored.toString("utf8"), credentials);
254
- mergeCounts(redactions, safe.redactions);
255
- return Buffer.from(safe.text, "utf8");
263
+ function isUtf8Boundary(value, offset) {
264
+ return offset === 0 || offset === value.length || (value[offset] & 0xc0) !== 0x80;
256
265
  }
257
266
  function excerpt(name, mediaType, bytes, digest, truncated, stored) {
258
267
  const common = { name, media_type: mediaType, bytes, sha256: digest, truncated: truncated === true };
@@ -351,10 +360,18 @@ async function secureRead(root, ref, maxBytes) {
351
360
  const relative = validateRelativePath(ref, "verifier evidence ref");
352
361
  const opened = await openContainedRegularFile(root, relative, maxBytes);
353
362
  try {
354
- const bytes = await opened.handle.readFile();
355
- await opened.assertUnchanged();
356
- if (bytes.length !== opened.size)
363
+ const bytes = Buffer.allocUnsafe(opened.size);
364
+ let position = 0;
365
+ while (position < bytes.length) {
366
+ const read = await opened.handle.read(bytes, position, bytes.length - position, position);
367
+ if (read.bytesRead === 0)
368
+ throw new TypeError(`${path.basename(ref)} changed while being read`);
369
+ position += read.bytesRead;
370
+ }
371
+ if ((await opened.handle.read(Buffer.allocUnsafe(1), 0, 1, bytes.length)).bytesRead !== 0) {
357
372
  throw new TypeError(`${path.basename(ref)} changed while being read`);
373
+ }
374
+ await opened.assertUnchanged();
358
375
  return bytes;
359
376
  }
360
377
  finally {
@@ -400,27 +417,11 @@ function positiveLimit(value, label) {
400
417
  throw new TypeError(`${label} limit is invalid`);
401
418
  return value;
402
419
  }
403
- function nonNegativeInteger(value, label) {
404
- if (!Number.isSafeInteger(value) || Number(value) < 0)
405
- throw new TypeError(`${label} is invalid`);
406
- return Number(value);
407
- }
408
- function sha256Value(value, label) {
409
- if (typeof value !== "string" || !/^sha256:[0-9a-f]{64}$/.test(value))
410
- throw new TypeError(`${label} is invalid`);
411
- return value;
412
- }
413
420
  function asRecord(value, label) {
414
421
  if (!value || typeof value !== "object" || Array.isArray(value))
415
422
  throw new TypeError(`${label} must be an object`);
416
423
  return value;
417
424
  }
418
- function exactFields(record, allowed, label) {
419
- const fields = new Set(allowed);
420
- const unexpected = Object.keys(record).find((field) => !fields.has(field));
421
- if (unexpected)
422
- throw new TypeError(`${label} has unknown field: ${unexpected}`);
423
- }
424
425
  function isJsonValue(value) {
425
426
  if (value === null || typeof value === "string" || typeof value === "boolean")
426
427
  return true;