niceeval 0.13.1 → 0.13.2

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 (548) hide show
  1. package/INDEX.md +25 -2
  2. package/README.md +9 -10
  3. package/README.zh.md +9 -10
  4. package/dist/agents/ai-sdk.cjs.map +1 -1
  5. package/dist/agents/ai-sdk.d.cts +1 -1
  6. package/dist/agents/ai-sdk.d.mts +1 -1
  7. package/dist/agents/ai-sdk.d.ts +1 -1
  8. package/dist/agents/bub-install-spec.cjs +19 -5
  9. package/dist/agents/bub-install-spec.cjs.map +1 -1
  10. package/dist/agents/bub-install-spec.d.cts +9 -2
  11. package/dist/agents/bub-install-spec.d.mts +9 -2
  12. package/dist/agents/bub-install-spec.d.ts +9 -2
  13. package/dist/agents/bub-install-spec.js +14 -12
  14. package/dist/agents/bub.cjs +10 -6
  15. package/dist/agents/bub.cjs.map +1 -1
  16. package/dist/agents/bub.d.cts +2 -2
  17. package/dist/agents/bub.d.mts +2 -2
  18. package/dist/agents/bub.d.ts +2 -2
  19. package/dist/agents/claude-code.cjs.map +1 -1
  20. package/dist/agents/claude-code.d.cts +2 -2
  21. package/dist/agents/claude-code.d.mts +2 -2
  22. package/dist/agents/claude-code.d.ts +2 -2
  23. package/dist/agents/codex.cjs +4 -4
  24. package/dist/agents/codex.cjs.map +1 -1
  25. package/dist/agents/codex.d.cts +3 -3
  26. package/dist/agents/codex.d.mts +3 -3
  27. package/dist/agents/codex.d.ts +3 -3
  28. package/dist/agents/coding-cli-versions.cjs +10 -1
  29. package/dist/agents/coding-cli-versions.cjs.map +1 -1
  30. package/dist/agents/coding-cli-versions.d.cts +8 -3
  31. package/dist/agents/coding-cli-versions.d.mts +8 -3
  32. package/dist/agents/coding-cli-versions.d.ts +8 -3
  33. package/dist/agents/coding-cli-versions.js +18 -12
  34. package/dist/agents/deepseek-harness.cjs +151 -0
  35. package/dist/agents/deepseek-harness.cjs.map +1 -0
  36. package/dist/agents/deepseek-harness.d.cts +14 -0
  37. package/dist/agents/deepseek-harness.d.mts +14 -0
  38. package/dist/agents/deepseek-harness.d.ts +14 -0
  39. package/dist/agents/deepseek-harness.js +7 -0
  40. package/dist/agents/deepseek-harness.js.map +1 -0
  41. package/dist/agents/exact-npm-plugins.cjs +28 -0
  42. package/dist/agents/exact-npm-plugins.cjs.map +1 -0
  43. package/dist/agents/exact-npm-plugins.d.cts +10 -0
  44. package/dist/agents/exact-npm-plugins.d.mts +10 -0
  45. package/dist/agents/exact-npm-plugins.d.ts +10 -0
  46. package/dist/agents/exact-npm-plugins.js +8 -0
  47. package/dist/agents/exact-npm-plugins.js.map +1 -0
  48. package/dist/agents/index.cjs +5 -1
  49. package/dist/agents/index.cjs.map +1 -1
  50. package/dist/agents/index.d.cts +4 -0
  51. package/dist/agents/index.d.mts +4 -0
  52. package/dist/agents/index.d.ts +4 -0
  53. package/dist/agents/index.js +54 -50
  54. package/dist/agents/index.mjs +54 -50
  55. package/dist/agents/omp.cjs +170 -0
  56. package/dist/agents/omp.cjs.map +1 -0
  57. package/dist/agents/omp.d.cts +14 -0
  58. package/dist/agents/omp.d.mts +14 -0
  59. package/dist/agents/omp.d.ts +14 -0
  60. package/dist/agents/omp.js +7 -0
  61. package/dist/agents/omp.js.map +1 -0
  62. package/dist/agents/openclaw.cjs +51 -2
  63. package/dist/agents/openclaw.cjs.map +1 -1
  64. package/dist/agents/openclaw.d.cts +2 -0
  65. package/dist/agents/openclaw.d.mts +2 -0
  66. package/dist/agents/openclaw.d.ts +2 -0
  67. package/dist/agents/types.cjs.map +1 -1
  68. package/dist/agents/types.d.cts +4 -4
  69. package/dist/agents/types.d.mts +4 -4
  70. package/dist/agents/types.d.ts +4 -4
  71. package/dist/agents/ui-message-stream.cjs +24 -7
  72. package/dist/agents/ui-message-stream.cjs.map +1 -1
  73. package/dist/analysis/api.cjs +28 -2
  74. package/dist/analysis/api.cjs.map +1 -1
  75. package/dist/analysis/api.d.cts +22 -1
  76. package/dist/analysis/api.d.mts +22 -1
  77. package/dist/analysis/api.d.ts +22 -1
  78. package/dist/analysis/api.js +8 -6
  79. package/dist/analysis/bindings.cjs +11 -18
  80. package/dist/analysis/bindings.cjs.map +1 -1
  81. package/dist/analysis/bindings.d.cts +177 -49
  82. package/dist/analysis/bindings.d.mts +177 -49
  83. package/dist/analysis/bindings.d.ts +177 -49
  84. package/dist/analysis/contracts.cjs +1 -0
  85. package/dist/analysis/contracts.cjs.map +1 -1
  86. package/dist/analysis/contracts.d.cts +43 -3
  87. package/dist/analysis/contracts.d.mts +43 -3
  88. package/dist/analysis/contracts.d.ts +43 -3
  89. package/dist/analysis/cost-projection.cjs +2 -1
  90. package/dist/analysis/cost-projection.cjs.map +1 -1
  91. package/dist/analysis/cost-projection.d.cts +1 -1
  92. package/dist/analysis/cost-projection.d.mts +1 -1
  93. package/dist/analysis/cost-projection.d.ts +1 -1
  94. package/dist/analysis/cost.cjs +13 -3
  95. package/dist/analysis/cost.cjs.map +1 -1
  96. package/dist/analysis/cost.d.cts +10 -3
  97. package/dist/analysis/cost.d.mts +10 -3
  98. package/dist/analysis/cost.d.ts +10 -3
  99. package/dist/analysis/experiment-groups.cjs +96 -0
  100. package/dist/analysis/experiment-groups.cjs.map +1 -0
  101. package/dist/analysis/experiment-groups.d.cts +9 -0
  102. package/dist/analysis/experiment-groups.d.mts +9 -0
  103. package/dist/analysis/experiment-groups.d.ts +9 -0
  104. package/dist/analysis/experiment-groups.js +10 -0
  105. package/dist/analysis/experiment-groups.js.map +1 -0
  106. package/dist/analysis/index.cjs +4 -1
  107. package/dist/analysis/index.cjs.map +1 -1
  108. package/dist/analysis/index.d.cts +4 -2
  109. package/dist/analysis/index.d.mts +4 -2
  110. package/dist/analysis/index.d.ts +4 -2
  111. package/dist/analysis/index.js +40 -36
  112. package/dist/analysis/index.mjs +40 -36
  113. package/dist/assertions/limits.cjs +4 -0
  114. package/dist/assertions/limits.cjs.map +1 -1
  115. package/dist/assertions/limits.d.cts +4 -0
  116. package/dist/assertions/limits.d.mts +4 -0
  117. package/dist/assertions/limits.d.ts +4 -0
  118. package/dist/assertions/match.cjs +63 -25
  119. package/dist/assertions/match.cjs.map +1 -1
  120. package/dist/assertions/match.d.cts +7 -0
  121. package/dist/assertions/match.d.mts +7 -0
  122. package/dist/assertions/match.d.ts +7 -0
  123. package/dist/assertions/record/attachment.cjs +32 -4
  124. package/dist/assertions/record/attachment.cjs.map +1 -1
  125. package/dist/assertions/record/diff.cjs +10 -4
  126. package/dist/assertions/record/diff.cjs.map +1 -1
  127. package/dist/assertions/record/producer.cjs +101 -4
  128. package/dist/assertions/record/producer.cjs.map +1 -1
  129. package/dist/assertions/record/producer.d.cts +4 -1
  130. package/dist/assertions/record/producer.d.mts +4 -1
  131. package/dist/assertions/record/producer.d.ts +4 -1
  132. package/dist/assertions/runtime.cjs +45 -5
  133. package/dist/assertions/runtime.cjs.map +1 -1
  134. package/dist/cli/record.cjs +113 -8
  135. package/dist/cli/record.cjs.map +1 -1
  136. package/dist/cli/record.d.cts +20 -1
  137. package/dist/cli/record.d.mts +20 -1
  138. package/dist/cli/record.d.ts +20 -1
  139. package/dist/cli/record.js +4 -2
  140. package/dist/cli.cjs +386 -31
  141. package/dist/cli.cjs.map +1 -1
  142. package/dist/cli.d.cts +10 -2
  143. package/dist/cli.d.mts +10 -2
  144. package/dist/cli.d.ts +10 -2
  145. package/dist/context/send-retry.cjs +4 -4
  146. package/dist/context/send-retry.cjs.map +1 -1
  147. package/dist/coordination/host/runtime.cjs +8 -30
  148. package/dist/coordination/host/runtime.cjs.map +1 -1
  149. package/dist/coordination/host/runtime.d.cts +3 -3
  150. package/dist/coordination/host/runtime.d.mts +3 -3
  151. package/dist/coordination/host/runtime.d.ts +3 -3
  152. package/dist/coordination/host/types.cjs.map +1 -1
  153. package/dist/coordination/host/types.d.cts +0 -5
  154. package/dist/coordination/host/types.d.mts +0 -5
  155. package/dist/coordination/host/types.d.ts +0 -5
  156. package/dist/coordination/platform/node.cjs +90 -9
  157. package/dist/coordination/platform/node.cjs.map +1 -1
  158. package/dist/define.cjs +25 -1
  159. package/dist/define.cjs.map +1 -1
  160. package/dist/experiment/host/index.cjs +1 -0
  161. package/dist/experiment/host/index.cjs.map +1 -1
  162. package/dist/i18n/en.cjs +26 -8
  163. package/dist/i18n/en.cjs.map +1 -1
  164. package/dist/i18n/en.d.cts +19 -6
  165. package/dist/i18n/en.d.mts +19 -6
  166. package/dist/i18n/en.d.ts +19 -6
  167. package/dist/index.cjs.map +1 -1
  168. package/dist/index.d.cts +1 -1
  169. package/dist/index.d.mts +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/o11y/parsers/hermes.cjs +1 -1
  172. package/dist/o11y/parsers/hermes.cjs.map +1 -1
  173. package/dist/o11y/prices.json +1 -1
  174. package/dist/o11y/record/families.cjs +12 -3
  175. package/dist/o11y/record/families.cjs.map +1 -1
  176. package/dist/o11y/record/families.d.cts +8 -8
  177. package/dist/o11y/record/families.d.mts +8 -8
  178. package/dist/o11y/record/families.d.ts +8 -8
  179. package/dist/o11y/record/family-projectors.d.cts +66 -18
  180. package/dist/o11y/record/family-projectors.d.mts +66 -18
  181. package/dist/o11y/record/family-projectors.d.ts +66 -18
  182. package/dist/o11y/record/family-writers.d.cts +11 -3
  183. package/dist/o11y/record/family-writers.d.mts +11 -3
  184. package/dist/o11y/record/family-writers.d.ts +11 -3
  185. package/dist/o11y/record/runner-producer.cjs +14 -4
  186. package/dist/o11y/record/runner-producer.cjs.map +1 -1
  187. package/dist/record/codec/core.d.cts +2 -2
  188. package/dist/record/codec/core.d.mts +2 -2
  189. package/dist/record/codec/core.d.ts +2 -2
  190. package/dist/record/family/catalog.d.cts +44 -12
  191. package/dist/record/family/catalog.d.mts +44 -12
  192. package/dist/record/family/catalog.d.ts +44 -12
  193. package/dist/record/family/index.js +128 -124
  194. package/dist/record/family/observability-v1.cjs +35 -0
  195. package/dist/record/family/observability-v1.cjs.map +1 -0
  196. package/dist/record/family/observability-v1.d.cts +3 -0
  197. package/dist/record/family/observability-v1.d.mts +3 -0
  198. package/dist/record/family/observability-v1.d.ts +3 -0
  199. package/dist/record/family/observability-v1.js +6 -0
  200. package/dist/record/family/observability-v1.js.map +1 -0
  201. package/dist/record/family/observability.cjs +58 -9
  202. package/dist/record/family/observability.cjs.map +1 -1
  203. package/dist/record/family/observability.d.cts +1014 -15
  204. package/dist/record/family/observability.d.mts +1014 -15
  205. package/dist/record/family/observability.d.ts +1014 -15
  206. package/dist/record/family/observability.js +22 -18
  207. package/dist/record/host/runtime.cjs +600 -31
  208. package/dist/record/host/runtime.cjs.map +1 -1
  209. package/dist/record/host/types.cjs.map +1 -1
  210. package/dist/record/host/types.d.cts +33 -9
  211. package/dist/record/host/types.d.mts +33 -9
  212. package/dist/record/host/types.d.ts +33 -9
  213. package/dist/record/maintenance/runtime.cjs +1 -2
  214. package/dist/record/maintenance/runtime.cjs.map +1 -1
  215. package/dist/record/model/core.cjs.map +1 -1
  216. package/dist/record/model/core.d.cts +1 -1
  217. package/dist/record/model/core.d.mts +1 -1
  218. package/dist/record/model/core.d.ts +1 -1
  219. package/dist/record/model/definition.d.cts +6 -6
  220. package/dist/record/model/definition.d.mts +6 -6
  221. package/dist/record/model/definition.d.ts +6 -6
  222. package/dist/record/model/identifiers.cjs +1 -1
  223. package/dist/record/model/identifiers.cjs.map +1 -1
  224. package/dist/record/model/identifiers.d.cts +1 -1
  225. package/dist/record/model/identifiers.d.mts +1 -1
  226. package/dist/record/model/identifiers.d.ts +1 -1
  227. package/dist/record/platform/node.cjs +159 -23
  228. package/dist/record/platform/node.cjs.map +1 -1
  229. package/dist/record/platform/services.cjs.map +1 -1
  230. package/dist/record/platform/services.d.cts +15 -2
  231. package/dist/record/platform/services.d.mts +15 -2
  232. package/dist/record/platform/services.d.ts +15 -2
  233. package/dist/record/reader/errors.cjs +37 -1
  234. package/dist/record/reader/errors.cjs.map +1 -1
  235. package/dist/record/reader/errors.d.cts +49 -1
  236. package/dist/record/reader/errors.d.mts +49 -1
  237. package/dist/record/reader/errors.d.ts +49 -1
  238. package/dist/record/reader/errors.js +22 -12
  239. package/dist/record/reader/format.cjs +76 -17
  240. package/dist/record/reader/format.cjs.map +1 -1
  241. package/dist/record/reader/format.d.cts +11 -4
  242. package/dist/record/reader/format.d.mts +11 -4
  243. package/dist/record/reader/format.d.ts +11 -4
  244. package/dist/record/reader/format.js +2 -0
  245. package/dist/record/reader/index.js +32 -18
  246. package/dist/record/reader/runtime.cjs +64 -0
  247. package/dist/record/reader/runtime.cjs.map +1 -1
  248. package/dist/record/reader/runtime.d.cts +15 -0
  249. package/dist/record/reader/runtime.d.mts +15 -0
  250. package/dist/record/reader/runtime.d.ts +15 -0
  251. package/dist/record/reader/runtime.js +2 -0
  252. package/dist/report/assets/styles.css +53 -29
  253. package/dist/report/built-in/analysis-values.cjs +21 -13
  254. package/dist/report/built-in/analysis-values.cjs.map +1 -1
  255. package/dist/report/built-in/analysis-values.d.cts +11 -22
  256. package/dist/report/built-in/analysis-values.d.mts +11 -22
  257. package/dist/report/built-in/analysis-values.d.ts +11 -22
  258. package/dist/report/built-in/analysis-values.js +4 -6
  259. package/dist/report/built-in/index.cjs +1 -3
  260. package/dist/report/built-in/index.cjs.map +1 -1
  261. package/dist/report/built-in/index.d.cts +1 -1
  262. package/dist/report/built-in/index.d.mts +1 -1
  263. package/dist/report/built-in/index.d.ts +1 -1
  264. package/dist/report/built-in/index.js +4 -8
  265. package/dist/report/built-in/index.mjs +4 -8
  266. package/dist/report/built-in/machine.cjs +0 -2
  267. package/dist/report/built-in/machine.cjs.map +1 -1
  268. package/dist/report/built-in/machine.d.cts +0 -2
  269. package/dist/report/built-in/machine.d.mts +0 -2
  270. package/dist/report/built-in/machine.d.ts +0 -2
  271. package/dist/report/built-in/result-components.cjs +49 -51
  272. package/dist/report/built-in/result-components.cjs.map +1 -1
  273. package/dist/report/built-in/result-components.d.cts +16 -17
  274. package/dist/report/built-in/result-components.d.mts +16 -17
  275. package/dist/report/built-in/result-components.d.ts +16 -17
  276. package/dist/report/built-in/result-components.js +0 -4
  277. package/dist/report/built-in/run-membership-overview.cjs +126 -17
  278. package/dist/report/built-in/run-membership-overview.cjs.map +1 -1
  279. package/dist/report/built-in/run-membership-overview.d.cts +14 -0
  280. package/dist/report/built-in/run-membership-overview.d.mts +14 -0
  281. package/dist/report/built-in/run-membership-overview.d.ts +14 -0
  282. package/dist/report/built-in/run-membership-overview.js +4 -2
  283. package/dist/report/built-in/standard.cjs +80 -45
  284. package/dist/report/built-in/standard.cjs.map +1 -1
  285. package/dist/report/built-in/standard.d.cts +19 -41
  286. package/dist/report/built-in/standard.d.mts +19 -41
  287. package/dist/report/built-in/standard.d.ts +19 -41
  288. package/dist/report/built-in/standard.js +6 -6
  289. package/dist/report/components/attempt-detail/compute.cjs +78 -2
  290. package/dist/report/components/attempt-detail/compute.cjs.map +1 -1
  291. package/dist/report/components/attempt-detail/compute.d.cts +1 -1
  292. package/dist/report/components/attempt-detail/compute.d.mts +1 -1
  293. package/dist/report/components/attempt-detail/compute.d.ts +1 -1
  294. package/dist/report/components/attempt-detail/content.cjs +1 -1
  295. package/dist/report/components/attempt-detail/content.cjs.map +1 -1
  296. package/dist/report/components/entity-lists/compute.cjs +42 -5
  297. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  298. package/dist/report/components/entity-lists/compute.d.cts +10 -8
  299. package/dist/report/components/entity-lists/compute.d.mts +10 -8
  300. package/dist/report/components/entity-lists/compute.d.ts +10 -8
  301. package/dist/report/components/entity-lists/content.cjs +31 -6
  302. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  303. package/dist/report/components/entity-lists/index.cjs +9 -4
  304. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  305. package/dist/report/components/entity-lists/index.d.cts +4 -7
  306. package/dist/report/components/entity-lists/index.d.mts +4 -7
  307. package/dist/report/components/entity-lists/index.d.ts +4 -7
  308. package/dist/report/components/summaries/compute.cjs +8 -1
  309. package/dist/report/components/summaries/compute.cjs.map +1 -1
  310. package/dist/report/components/summaries/compute.d.cts +9 -1
  311. package/dist/report/components/summaries/compute.d.mts +9 -1
  312. package/dist/report/components/summaries/compute.d.ts +9 -1
  313. package/dist/report/components/summaries/index.cjs +48 -4
  314. package/dist/report/components/summaries/index.cjs.map +1 -1
  315. package/dist/report/components/summaries/index.d.cts +7 -4
  316. package/dist/report/components/summaries/index.d.mts +7 -4
  317. package/dist/report/components/summaries/index.d.ts +7 -4
  318. package/dist/report/definition/cell.cjs +3 -0
  319. package/dist/report/definition/cell.cjs.map +1 -1
  320. package/dist/report/definition/cell.d.cts +2 -0
  321. package/dist/report/definition/cell.d.mts +2 -0
  322. package/dist/report/definition/cell.d.ts +2 -0
  323. package/dist/report/definition/primitives/chart.cjs +8 -5
  324. package/dist/report/definition/primitives/chart.cjs.map +1 -1
  325. package/dist/report/definition/primitives/points-dataset.cjs +1 -0
  326. package/dist/report/definition/primitives/points-dataset.cjs.map +1 -1
  327. package/dist/report/definition/primitives.cjs +15 -2
  328. package/dist/report/definition/primitives.cjs.map +1 -1
  329. package/dist/report/definition/report.cjs +27 -3
  330. package/dist/report/definition/report.cjs.map +1 -1
  331. package/dist/report/definition/report.d.cts +8 -0
  332. package/dist/report/definition/report.d.mts +8 -0
  333. package/dist/report/definition/report.d.ts +8 -0
  334. package/dist/report/execution/machine.cjs +30 -14
  335. package/dist/report/execution/machine.cjs.map +1 -1
  336. package/dist/report/execution/machine.d.cts +20 -10
  337. package/dist/report/execution/machine.d.mts +20 -10
  338. package/dist/report/execution/machine.d.ts +20 -10
  339. package/dist/report/execution/machine.js +6 -6
  340. package/dist/report/host/execute.cjs +25 -16
  341. package/dist/report/host/execute.cjs.map +1 -1
  342. package/dist/report/host/execute.d.cts +4 -0
  343. package/dist/report/host/execute.d.mts +4 -0
  344. package/dist/report/host/execute.d.ts +4 -0
  345. package/dist/report/host/from-record.cjs +22 -5
  346. package/dist/report/host/from-record.cjs.map +1 -1
  347. package/dist/report/host/machine.cjs +53 -11
  348. package/dist/report/host/machine.cjs.map +1 -1
  349. package/dist/report/host/site-runtime.cjs +9 -8
  350. package/dist/report/host/site-runtime.cjs.map +1 -1
  351. package/dist/report/host/site-runtime.d.cts +1 -1
  352. package/dist/report/host/site-runtime.d.mts +1 -1
  353. package/dist/report/host/site-runtime.d.ts +1 -1
  354. package/dist/report/host/static.cjs +56 -9
  355. package/dist/report/host/static.cjs.map +1 -1
  356. package/dist/report/index.cjs.map +1 -1
  357. package/dist/report/index.d.cts +1 -1
  358. package/dist/report/index.d.mts +1 -1
  359. package/dist/report/index.d.ts +1 -1
  360. package/dist/report/model/dataset.cjs +7 -2
  361. package/dist/report/model/dataset.cjs.map +1 -1
  362. package/dist/report/model/locale.cjs +2 -0
  363. package/dist/report/model/locale.cjs.map +1 -1
  364. package/dist/report/model/locale.d.cts +1 -0
  365. package/dist/report/model/locale.d.mts +1 -0
  366. package/dist/report/model/locale.d.ts +1 -0
  367. package/dist/report/model/metrics.cjs +3 -1
  368. package/dist/report/model/metrics.cjs.map +1 -1
  369. package/dist/report/model/pricing.cjs +16 -11
  370. package/dist/report/model/pricing.cjs.map +1 -1
  371. package/dist/report/react/styles.css +53 -29
  372. package/dist/runner/adoption.cjs +1 -0
  373. package/dist/runner/adoption.cjs.map +1 -1
  374. package/dist/runner/attempt.cjs +44 -5
  375. package/dist/runner/attempt.cjs.map +1 -1
  376. package/dist/runner/attempt.d.cts +13 -1
  377. package/dist/runner/attempt.d.mts +13 -1
  378. package/dist/runner/attempt.d.ts +13 -1
  379. package/dist/runner/config-identity.cjs +10 -2
  380. package/dist/runner/config-identity.cjs.map +1 -1
  381. package/dist/runner/config-identity.d.cts +4 -2
  382. package/dist/runner/config-identity.d.mts +4 -2
  383. package/dist/runner/config-identity.d.ts +4 -2
  384. package/dist/runner/feedback/human.cjs +298 -59
  385. package/dist/runner/feedback/human.cjs.map +1 -1
  386. package/dist/runner/feedback/json.cjs +14 -6
  387. package/dist/runner/feedback/json.cjs.map +1 -1
  388. package/dist/runner/feedback/json.d.cts +3 -2
  389. package/dist/runner/feedback/json.d.mts +3 -2
  390. package/dist/runner/feedback/json.d.ts +3 -2
  391. package/dist/runner/feedback/reducer.cjs +2 -0
  392. package/dist/runner/feedback/reducer.cjs.map +1 -1
  393. package/dist/runner/judge-config.cjs +1 -1
  394. package/dist/runner/judge-config.cjs.map +1 -1
  395. package/dist/runner/ledger.cjs +124 -12
  396. package/dist/runner/ledger.cjs.map +1 -1
  397. package/dist/runner/project-current.cjs +13 -5
  398. package/dist/runner/project-current.cjs.map +1 -1
  399. package/dist/runner/run.cjs +564 -256
  400. package/dist/runner/run.cjs.map +1 -1
  401. package/dist/runner/sandbox-pool.cjs +161 -30
  402. package/dist/runner/sandbox-pool.cjs.map +1 -1
  403. package/dist/runner/sandbox-pool.d.cts +34 -2
  404. package/dist/runner/sandbox-pool.d.mts +34 -2
  405. package/dist/runner/sandbox-pool.d.ts +34 -2
  406. package/dist/runner/shared-state-lease.cjs +803 -0
  407. package/dist/runner/shared-state-lease.cjs.map +1 -0
  408. package/dist/runner/shared-state-lease.d.cts +121 -0
  409. package/dist/runner/shared-state-lease.d.mts +121 -0
  410. package/dist/runner/shared-state-lease.d.ts +121 -0
  411. package/dist/runner/shared-state-lease.js +24 -0
  412. package/dist/runner/shared-state-lease.js.map +1 -0
  413. package/dist/runner/teardown-registry.cjs +97 -34
  414. package/dist/runner/teardown-registry.cjs.map +1 -1
  415. package/dist/runner/teardown-registry.d.cts +27 -1
  416. package/dist/runner/teardown-registry.d.mts +27 -1
  417. package/dist/runner/teardown-registry.d.ts +27 -1
  418. package/dist/runner/teardown-registry.js +20 -16
  419. package/dist/runner/types.cjs.map +1 -1
  420. package/dist/runner/types.d.cts +31 -5
  421. package/dist/runner/types.d.mts +31 -5
  422. package/dist/runner/types.d.ts +31 -5
  423. package/dist/sample/analysis.cjs +249 -459
  424. package/dist/sample/analysis.cjs.map +1 -1
  425. package/dist/sample/capability.cjs +138 -7
  426. package/dist/sample/capability.cjs.map +1 -1
  427. package/dist/sample/capability.d.cts +3 -1
  428. package/dist/sample/capability.d.mts +3 -1
  429. package/dist/sample/capability.d.ts +3 -1
  430. package/dist/sample/capability.js +8 -6
  431. package/dist/sandbox/docker-agent-image.cjs +5 -1
  432. package/dist/sandbox/docker-agent-image.cjs.map +1 -1
  433. package/dist/sandbox/docker-agent-image.d.cts +2 -0
  434. package/dist/sandbox/docker-agent-image.d.mts +2 -0
  435. package/dist/sandbox/docker-agent-image.d.ts +2 -0
  436. package/dist/sandbox/docker-agent-image.js +14 -10
  437. package/dist/sandbox/docker-profile/schema.cjs +283 -534
  438. package/dist/sandbox/docker-profile/schema.cjs.map +1 -1
  439. package/dist/sandbox/docker-profile/schema.d.cts +10 -27
  440. package/dist/sandbox/docker-profile/schema.d.mts +10 -27
  441. package/dist/sandbox/docker-profile/schema.d.ts +10 -27
  442. package/dist/sandbox/e2b-agent-template.cjs +5 -2
  443. package/dist/sandbox/e2b-agent-template.cjs.map +1 -1
  444. package/dist/sandbox/index.cjs +4 -2
  445. package/dist/sandbox/index.cjs.map +1 -1
  446. package/dist/sandbox/index.d.cts +1 -1
  447. package/dist/sandbox/index.d.mts +1 -1
  448. package/dist/sandbox/index.d.ts +1 -1
  449. package/dist/sandbox/index.js +120 -116
  450. package/dist/sandbox/index.mjs +120 -116
  451. package/dist/sandbox/keep-registry.cjs +28 -66
  452. package/dist/sandbox/keep-registry.cjs.map +1 -1
  453. package/dist/sandbox/types.cjs.map +1 -1
  454. package/dist/sandbox/types.d.cts +1 -1
  455. package/dist/sandbox/types.d.mts +1 -1
  456. package/dist/sandbox/types.d.ts +1 -1
  457. package/dist/shared/aggregate.cjs +16 -6
  458. package/dist/shared/aggregate.cjs.map +1 -1
  459. package/dist/shared/aggregate.d.cts +12 -4
  460. package/dist/shared/aggregate.d.mts +12 -4
  461. package/dist/shared/aggregate.d.ts +12 -4
  462. package/dist/shared/turn-label.cjs +20 -2
  463. package/dist/shared/turn-label.cjs.map +1 -1
  464. package/dist/shared/turn-label.d.cts +2 -0
  465. package/dist/shared/turn-label.d.mts +2 -0
  466. package/dist/shared/turn-label.d.ts +2 -0
  467. package/dist/shared/turn-label.js +4 -2
  468. package/dist/vendor/remark/remark-gfm.cjs +7 -7
  469. package/dist/vendor/remark/remark-gfm.cjs.map +1 -1
  470. package/dist/vendor/remark/remark-parse.cjs +12 -12
  471. package/dist/vendor/remark/remark-parse.cjs.map +1 -1
  472. package/dist/vendor/remark/remark.cjs +13 -13
  473. package/dist/vendor/remark/remark.cjs.map +1 -1
  474. package/dist/view/server.cjs +6 -0
  475. package/dist/view/server.cjs.map +1 -1
  476. package/docs-site/images/hitl-handshake-zh.svg +3 -3
  477. package/docs-site/zh/examples/ai-agent-application.mdx +1 -1
  478. package/docs-site/zh/examples/coding-agent-extensions.mdx +1 -1
  479. package/docs-site/zh/examples/integrations/ai-sdk-v7.mdx +4 -3
  480. package/docs-site/zh/examples/integrations/claude-sdk.mdx +3 -3
  481. package/docs-site/zh/examples/integrations/codex-sdk.mdx +5 -5
  482. package/docs-site/zh/examples/integrations/langgraph.mdx +4 -4
  483. package/docs-site/zh/examples/integrations/pi-sdk.mdx +5 -5
  484. package/docs-site/zh/explanation/adapter.mdx +5 -5
  485. package/docs-site/zh/explanation/assert.mdx +7 -7
  486. package/docs-site/zh/explanation/drive.mdx +4 -2
  487. package/docs-site/zh/explanation/evals.mdx +10 -8
  488. package/docs-site/zh/explanation/experiment.mdx +2 -2
  489. package/docs-site/zh/explanation/hitl.mdx +9 -9
  490. package/docs-site/zh/explanation/judge.mdx +5 -5
  491. package/docs-site/zh/explanation/overview.mdx +3 -3
  492. package/docs-site/zh/explanation/runner.mdx +1 -1
  493. package/docs-site/zh/index.mdx +3 -3
  494. package/docs-site/zh/reference/builtin-agents.mdx +13 -13
  495. package/docs-site/zh/reference/capabilities.mdx +1 -1
  496. package/docs-site/zh/reference/cli.mdx +18 -12
  497. package/docs-site/zh/reference/define-agent.mdx +130 -5
  498. package/docs-site/zh/reference/define-config.mdx +2 -2
  499. package/docs-site/zh/reference/define-eval.mdx +4 -4
  500. package/docs-site/zh/reference/events.mdx +11 -11
  501. package/docs-site/zh/reference/official-adapters.mdx +6 -6
  502. package/docs-site/zh/reference/results-data.mdx +6 -0
  503. package/docs-site/zh/troubleshooting/debugging.mdx +1 -1
  504. package/docs-site/zh/troubleshooting/recover-after-kill.mdx +37 -5
  505. package/docs-site/zh/tutorials/accept-results.mdx +72 -0
  506. package/docs-site/zh/tutorials/agent-onboarding.mdx +6 -6
  507. package/docs-site/zh/tutorials/authoring.mdx +9 -13
  508. package/docs-site/zh/tutorials/ci-integration.mdx +6 -6
  509. package/docs-site/zh/tutorials/compare-runs.mdx +61 -0
  510. package/docs-site/zh/tutorials/concurrency.mdx +13 -12
  511. package/docs-site/zh/tutorials/configuration.mdx +4 -6
  512. package/docs-site/zh/tutorials/connect-your-agent.mdx +1 -1
  513. package/docs-site/zh/tutorials/control-run-cost.mdx +58 -0
  514. package/docs-site/zh/tutorials/criteria-files.mdx +2 -2
  515. package/docs-site/zh/tutorials/custom-reports.mdx +2 -2
  516. package/docs-site/zh/tutorials/debug-lifecycle-plan.mdx +46 -0
  517. package/docs-site/zh/tutorials/docker-in-docker.mdx +52 -43
  518. package/docs-site/zh/tutorials/eval-groups.mdx +6 -6
  519. package/docs-site/zh/tutorials/evaluation-kinds.mdx +3 -3
  520. package/docs-site/zh/tutorials/experiments.mdx +2 -3
  521. package/docs-site/zh/tutorials/handle-execution-failures.mdx +18 -10
  522. package/docs-site/zh/tutorials/install-custom-sandbox-agent.mdx +16 -8
  523. package/docs-site/zh/tutorials/nixos-managed-dind.mdx +160 -0
  524. package/docs-site/zh/tutorials/plugins.mdx +14 -0
  525. package/docs-site/zh/tutorials/rerun-and-cache.mdx +4 -2
  526. package/docs-site/zh/tutorials/sandbox-agent.mdx +17 -11
  527. package/docs-site/zh/tutorials/sandbox-providers.mdx +17 -13
  528. package/docs-site/zh/tutorials/sandbox-reuse.mdx +12 -19
  529. package/docs-site/zh/tutorials/select-and-preview.mdx +65 -0
  530. package/docs-site/zh/tutorials/verify-judge.mdx +78 -0
  531. package/docs-site/zh/tutorials/viewing-results.mdx +38 -1
  532. package/docs-site/zh/tutorials/write-experiment.mdx +7 -5
  533. package/docs-site/zh/tutorials/write-send.mdx +9 -8
  534. package/package.json +9 -5
  535. package/dist/report/built-in/overview.cjs +0 -44
  536. package/dist/report/built-in/overview.cjs.map +0 -1
  537. package/dist/report/built-in/overview.d.cts +0 -6
  538. package/dist/report/built-in/overview.d.mts +0 -6
  539. package/dist/report/built-in/overview.d.ts +0 -6
  540. package/dist/report/built-in/overview.js +0 -9
  541. package/dist/report/built-in/overview.js.map +0 -1
  542. package/dist/runner/gate-lease.cjs +0 -283
  543. package/dist/runner/gate-lease.cjs.map +0 -1
  544. package/dist/runner/gate-lease.d.cts +0 -62
  545. package/dist/runner/gate-lease.d.mts +0 -62
  546. package/dist/runner/gate-lease.d.ts +0 -62
  547. package/dist/runner/gate-lease.js +0 -22
  548. package/dist/runner/gate-lease.js.map +0 -1
@@ -49,9 +49,11 @@ function readerClosed() {
49
49
  function handleInvalid() {
50
50
  return new errors_ts_3.RecordHandleInvalid({ code: "record-handle-invalid" });
51
51
  }
52
- function migrationInterrupted() {
52
+ function migrationInterrupted(restoreCommit, restoreSafe) {
53
53
  return new errors_ts_3.RecordMigrationInterruptedState({
54
54
  code: "record-migration-interrupted",
55
+ ...(restoreCommit === undefined ? {} : { restoreCommit }),
56
+ ...(restoreSafe === undefined ? {} : { restoreSafe }),
55
57
  });
56
58
  }
57
59
  function bootstrapInvalid() {
@@ -115,10 +117,12 @@ function sameRoot(left, right) {
115
117
  leftPaths.portableRoot === rightPaths.portableRoot;
116
118
  }
117
119
  function currentFormatInspection(fileSystem, root) {
118
- return (0, format_ts_1.readCurrentRecordFormat)(fileSystem, root).pipe(effect_1.Effect.map(() => ({
119
- state: "already-current",
120
+ return (0, format_ts_1.readRecordFormatForMaintenance)(fileSystem, root).pipe(effect_1.Effect.flatMap((format) => effect_1.Effect.map(planAttachmentMigration({ fileSystem, root }), (attachments) => ({
121
+ state: format.sourceSchemaVersion === identifiers_ts_1.RECORD_SCHEMA_VERSION && attachments.targets.length === 0
122
+ ? "already-current"
123
+ : "migration-required",
120
124
  format: identifiers_ts_1.RECORD_FORMAT,
121
- })), effect_1.Effect.catchAll((error) => error instanceof errors_ts_3.RecordFormatUnsupported
125
+ }))), effect_1.Effect.catchAll((error) => error instanceof errors_ts_3.RecordFormatUnsupported
122
126
  ? effect_1.Effect.succeed({
123
127
  state: "unsupported-format",
124
128
  format: error.format,
@@ -126,7 +130,7 @@ function currentFormatInspection(fileSystem, root) {
126
130
  : effect_1.Effect.fail(error)));
127
131
  }
128
132
  function isSealedRun(fileSystem, root, runId) {
129
- return effect_1.Effect.map(fileSystem.pathKind(runPath(root, runId, "complete")), (kind) => kind === "file");
133
+ return fileSystem.isCompleteMarker({ root, runId });
130
134
  }
131
135
  function readRunDocument(fileSystem, root, runId) {
132
136
  return effect_1.Effect.map(readJson(fileSystem, runPath(root, runId, "run.json")), (json) => {
@@ -224,6 +228,19 @@ function readRunAttempts(fileSystem, root, runId) {
224
228
  return Object.freeze(attempts);
225
229
  });
226
230
  }
231
+ function maintenanceReaderRuntime(root, record) {
232
+ return {
233
+ root,
234
+ record,
235
+ lifecycle: { closed: false },
236
+ runs: new WeakMap(),
237
+ attempts: new WeakMap(),
238
+ owners: new WeakMap(),
239
+ runsById: new Map(),
240
+ attemptsByKey: new Map(),
241
+ sealedCoreSnapshot: undefined,
242
+ };
243
+ }
227
244
  /**
228
245
  * The reader deliberately reconstructs the complete published aggregate only
229
246
  * at the point where it is about to sign a Run/Attempt as available. This is
@@ -439,9 +456,11 @@ function readFixedFamily(input) {
439
456
  runId: owner.runId,
440
457
  descriptor: descriptor,
441
458
  payload: value.value,
442
- }).pipe(effect_1.Effect.map((joined) => joined
459
+ }).pipe(effect_1.Effect.map((join) => join.state === "joined"
443
460
  ? value
444
- : Object.freeze({ state: "invalid", issues: coreInvalid().issues })));
461
+ : join.state === "migration-required" || join.state === "unsupported"
462
+ ? join
463
+ : Object.freeze({ state: "invalid", issues: coreInvalid().issues })));
445
464
  }));
446
465
  }
447
466
  const descriptor = input.descriptor;
@@ -467,9 +486,11 @@ function readFixedFamily(input) {
467
486
  attemptId: owner.ref.attemptId,
468
487
  descriptor: descriptor,
469
488
  payload: value.value,
470
- }).pipe(effect_1.Effect.map((joined) => joined
489
+ }).pipe(effect_1.Effect.map((join) => join.state === "joined"
471
490
  ? value
472
- : Object.freeze({ state: "invalid", issues: coreInvalid().issues })));
491
+ : join.state === "migration-required" || join.state === "unsupported"
492
+ ? join
493
+ : Object.freeze({ state: "invalid", issues: coreInvalid().issues })));
473
494
  }));
474
495
  });
475
496
  }
@@ -486,11 +507,20 @@ function isSourceNavigationDescriptor(descriptor) {
486
507
  function hasSourceFrames(payload) {
487
508
  return payload.diagnostics.diagnostics.some((diagnostic) => diagnostic.sourceFrame !== null);
488
509
  }
510
+ const joinedCrossFamily = Object.freeze({ state: "joined" });
511
+ const invalidCrossFamily = Object.freeze({ state: "invalid" });
512
+ function dependentFamilyJoin(read) {
513
+ if (read.state === "available")
514
+ return joinedCrossFamily;
515
+ if (read.state === "migration-required" || read.state === "unsupported")
516
+ return read;
517
+ return invalidCrossFamily;
518
+ }
489
519
  /** Common cross-family closure boundary used by both reader and writer seal. */
490
520
  function validateObservabilitySourceFrameJoin(input) {
491
521
  return effect_1.Effect.gen(function* () {
492
522
  if (!hasSourceFrames(input.payload))
493
- return true;
523
+ return joinedCrossFamily;
494
524
  const sources = yield* (0, runtime_ts_1.readFixedRecordAttachment)({
495
525
  fileSystem: input.fileSystem,
496
526
  root: input.root,
@@ -498,8 +528,8 @@ function validateObservabilitySourceFrameJoin(input) {
498
528
  descriptor: catalog_ts_1.NiceEvalRecordFamilyCatalog.sources,
499
529
  });
500
530
  if (sources.state !== "available")
501
- return false;
502
- return (0, observability_ts_1.observabilitySourceFrameIntegrityIssues)(input.payload, sources.value).length === 0;
531
+ return dependentFamilyJoin(sources);
532
+ return (0, observability_ts_1.observabilitySourceFrameIntegrityIssues)(input.payload, sources.value).length === 0 ? joinedCrossFamily : invalidCrossFamily;
503
533
  });
504
534
  }
505
535
  function hasMappedNavigationRows(payload) {
@@ -522,7 +552,7 @@ function validateFixedCrossFamilyJoin(input) {
522
552
  if (isAssertionsDescriptor(input.descriptor)) {
523
553
  const payload = input.payload;
524
554
  if (payload.sourceSites.length === 0)
525
- return effect_1.Effect.succeed(true);
555
+ return effect_1.Effect.succeed(joinedCrossFamily);
526
556
  return effect_1.Effect.gen(function* () {
527
557
  const sources = yield* (0, runtime_ts_1.readFixedRecordAttachment)({
528
558
  fileSystem: input.fileSystem,
@@ -530,14 +560,17 @@ function validateFixedCrossFamilyJoin(input) {
530
560
  location: Object.freeze({ owner: "run", runId: input.runId }),
531
561
  descriptor: catalog_ts_1.NiceEvalRecordFamilyCatalog.sources,
532
562
  });
533
- return sources.state === "available" &&
534
- (0, assertions_ts_1.assertionsSourceSiteIntegrityIssues)(payload, sources.value).length === 0;
563
+ if (sources.state !== "available")
564
+ return dependentFamilyJoin(sources);
565
+ return (0, assertions_ts_1.assertionsSourceSiteIntegrityIssues)(payload, sources.value).length === 0
566
+ ? joinedCrossFamily
567
+ : invalidCrossFamily;
535
568
  });
536
569
  }
537
570
  if (isSourceNavigationDescriptor(input.descriptor)) {
538
571
  const payload = input.payload;
539
572
  if (input.attemptId === undefined)
540
- return effect_1.Effect.succeed(false);
573
+ return effect_1.Effect.succeed(invalidCrossFamily);
541
574
  return effect_1.Effect.gen(function* () {
542
575
  const observability = yield* (0, runtime_ts_1.readFixedRecordAttachment)({
543
576
  fileSystem: input.fileSystem,
@@ -550,7 +583,7 @@ function validateFixedCrossFamilyJoin(input) {
550
583
  descriptor: catalog_ts_1.NiceEvalRecordFamilyCatalog.observability.attempt,
551
584
  });
552
585
  if (observability.state !== "available")
553
- return false;
586
+ return dependentFamilyJoin(observability);
554
587
  const sources = hasMappedNavigationRows(payload)
555
588
  ? yield* (0, runtime_ts_1.readFixedRecordAttachment)({
556
589
  fileSystem: input.fileSystem,
@@ -559,16 +592,18 @@ function validateFixedCrossFamilyJoin(input) {
559
592
  descriptor: catalog_ts_1.NiceEvalRecordFamilyCatalog.sources,
560
593
  })
561
594
  : undefined;
562
- if (sources !== undefined && sources.state !== "available")
563
- return false;
595
+ if (sources !== undefined) {
596
+ if (sources.state !== "available")
597
+ return dependentFamilyJoin(sources);
598
+ }
564
599
  return (0, source_navigation_ts_1.sourceNavigationIntegrityIssues)({
565
600
  payload,
566
601
  observability: observability.value,
567
602
  sources: sources?.state === "available" ? sources.value : undefined,
568
- }).length === 0;
603
+ }).length === 0 ? joinedCrossFamily : invalidCrossFamily;
569
604
  });
570
605
  }
571
- return effect_1.Effect.succeed(true);
606
+ return effect_1.Effect.succeed(joinedCrossFamily);
572
607
  }
573
608
  function makeReadSession(runtime, fileSystem) {
574
609
  const session = Object.freeze({
@@ -768,6 +803,7 @@ function openCurrentRead(input) {
768
803
  return yield* effect_1.Effect.fail(migrationInterrupted());
769
804
  }
770
805
  const current = yield* (0, format_ts_1.readCurrentRecordFormat)(fileSystem, input.root);
806
+ yield* ensureOrdinaryCurrentAttachments({ fileSystem, root: input.root });
771
807
  yield* coordination.verifyRecordIdentity({ root: input.root, recordId: current.document.recordId });
772
808
  const lifecycle = { closed: false };
773
809
  const runtime = {
@@ -1623,6 +1659,7 @@ function openNewRuntime(request) {
1623
1659
  }
1624
1660
  yield* initializeRecord({ root: request.root, fileSystem, entropy });
1625
1661
  const current = yield* (0, format_ts_1.readCurrentRecordFormat)(fileSystem, request.root);
1662
+ yield* ensureOrdinaryCurrentAttachments({ fileSystem, root: request.root });
1626
1663
  yield* coordination.verifyRecordIdentity({ root: request.root, recordId: current.document.recordId });
1627
1664
  const runId = yield* createFreshRunDirectory(request.root, fileSystem, entropy);
1628
1665
  const mutex = yield* effect_1.Effect.makeSemaphore(1);
@@ -1662,26 +1699,558 @@ function openNewRun(request) {
1662
1699
  function openNewReferenceRun(request) {
1663
1700
  return effect_1.Effect.map(openNewRuntime(request), makeReferenceRunSession);
1664
1701
  }
1702
+ function migrationDescriptor(descriptor) {
1703
+ return descriptor;
1704
+ }
1705
+ const runMigrationDescriptors = Object.freeze([
1706
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.observability.run),
1707
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.sources),
1708
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.artifacts.run),
1709
+ ]);
1710
+ const attemptMigrationDescriptors = Object.freeze([
1711
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.assertions),
1712
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.observability.attempt),
1713
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.fileChanges),
1714
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.sourceNavigation),
1715
+ migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.artifacts.attempt),
1716
+ ]);
1717
+ function validateAttachmentDirectoryInventory(input) {
1718
+ return effect_1.Effect.gen(function* () {
1719
+ const kind = yield* input.fileSystem.pathKind(input.directory);
1720
+ if (kind === "missing")
1721
+ return;
1722
+ if (kind !== "directory") {
1723
+ return yield* effect_1.Effect.fail(new errors_ts_3.RecordFormatUnsupported({
1724
+ code: "record-format-unsupported",
1725
+ format: "attachment-inventory",
1726
+ }));
1727
+ }
1728
+ const entries = yield* input.fileSystem.listDirectory({
1729
+ directory: input.directory,
1730
+ maximumEntries: 256,
1731
+ });
1732
+ const unsupported = entries.find((entry) => entry.kind !== "directory" || !input.allowed.has(entry.name));
1733
+ if (unsupported !== undefined) {
1734
+ return yield* effect_1.Effect.fail(new errors_ts_3.RecordFormatUnsupported({
1735
+ code: "record-format-unsupported",
1736
+ format: `unknown-family:${unsupported.name}`,
1737
+ }));
1738
+ }
1739
+ });
1740
+ }
1741
+ function validateCurrentFamilyInventory(fileSystem, root) {
1742
+ const runFamilies = new Set(runMigrationDescriptors.map((descriptor) => descriptor.family));
1743
+ const attemptFamilies = new Set(attemptMigrationDescriptors.map((descriptor) => descriptor.family));
1744
+ return effect_1.Effect.gen(function* () {
1745
+ const runs = yield* fileSystem.listDirectory({
1746
+ directory: (0, services_ts_1.recordPortablePath)(root, "runs"),
1747
+ maximumEntries: MAXIMUM_RUN_ENTRIES,
1748
+ });
1749
+ for (const entry of runs) {
1750
+ if (entry.kind !== "directory")
1751
+ continue;
1752
+ const runId = decodeRunId(entry.name);
1753
+ if (runId === undefined || !(yield* isSealedRun(fileSystem, root, runId)))
1754
+ continue;
1755
+ yield* validateAttachmentDirectoryInventory({
1756
+ fileSystem,
1757
+ directory: (0, services_ts_1.recordPortablePath)(root, "runs", runId, "attachments"),
1758
+ allowed: runFamilies,
1759
+ });
1760
+ const attemptsDirectory = (0, services_ts_1.recordPortablePath)(root, "runs", runId, "attempts");
1761
+ if ((yield* fileSystem.pathKind(attemptsDirectory)) !== "directory")
1762
+ continue;
1763
+ const attempts = yield* fileSystem.listDirectory({
1764
+ directory: attemptsDirectory,
1765
+ maximumEntries: MAXIMUM_ATTEMPT_ENTRIES,
1766
+ });
1767
+ for (const attempt of attempts) {
1768
+ if (attempt.kind !== "directory")
1769
+ continue;
1770
+ const attemptId = decodeAttemptId(attempt.name);
1771
+ if (attemptId === undefined)
1772
+ continue;
1773
+ yield* validateAttachmentDirectoryInventory({
1774
+ fileSystem,
1775
+ directory: (0, services_ts_1.recordPortablePath)(root, "runs", runId, "attempts", attemptId, "attachments"),
1776
+ allowed: attemptFamilies,
1777
+ });
1778
+ }
1779
+ }
1780
+ });
1781
+ }
1782
+ function migrationAttachmentDirectory(root, location) {
1783
+ return location.owner === "run"
1784
+ ? (0, services_ts_1.recordPortablePath)(root, "runs", location.runId, "attachments", location.descriptor.family)
1785
+ : (0, services_ts_1.recordPortablePath)(root, "runs", location.runId, "attempts", location.attemptId, "attachments", location.descriptor.family);
1786
+ }
1787
+ function migrationReaderLocation(location) {
1788
+ return location.owner === "run"
1789
+ ? Object.freeze({ owner: "run", runId: location.runId })
1790
+ : Object.freeze({
1791
+ owner: "attempt",
1792
+ runId: location.runId,
1793
+ attemptId: location.attemptId,
1794
+ });
1795
+ }
1796
+ /**
1797
+ * This traversal only addresses declared family directories. It deliberately
1798
+ * never enumerates an attachment directory, so unknown families cannot enter
1799
+ * the migration graph or be rewritten as a side effect.
1800
+ */
1801
+ function knownMigrationAttachments(fileSystem, root) {
1802
+ return effect_1.Effect.gen(function* () {
1803
+ const locations = [];
1804
+ const runs = yield* fileSystem.listDirectory({
1805
+ directory: (0, services_ts_1.recordPortablePath)(root, "runs"),
1806
+ maximumEntries: MAXIMUM_RUN_ENTRIES,
1807
+ });
1808
+ for (const entry of runs) {
1809
+ if (entry.kind !== "directory")
1810
+ continue;
1811
+ const runId = decodeRunId(entry.name);
1812
+ if (runId === undefined)
1813
+ continue;
1814
+ // Draft directories are not Runs and belong exclusively to `niceeval
1815
+ // clean`; maintenance must preserve every byte beneath them.
1816
+ if (!(yield* isSealedRun(fileSystem, root, runId)))
1817
+ continue;
1818
+ for (const descriptor of runMigrationDescriptors) {
1819
+ const location = Object.freeze({
1820
+ owner: "run",
1821
+ runId,
1822
+ descriptor,
1823
+ });
1824
+ if ((yield* fileSystem.pathKind(migrationAttachmentDirectory(root, location))) !== "missing") {
1825
+ locations.push(location);
1826
+ }
1827
+ }
1828
+ const attempts = yield* fileSystem.listDirectory({
1829
+ directory: (0, services_ts_1.recordPortablePath)(root, "runs", runId, "attempts"),
1830
+ maximumEntries: MAXIMUM_ATTEMPT_ENTRIES,
1831
+ });
1832
+ for (const attemptEntry of attempts) {
1833
+ if (attemptEntry.kind !== "directory")
1834
+ continue;
1835
+ const attemptId = decodeAttemptId(attemptEntry.name);
1836
+ if (attemptId === undefined)
1837
+ continue;
1838
+ for (const descriptor of attemptMigrationDescriptors) {
1839
+ const location = Object.freeze({
1840
+ owner: "attempt",
1841
+ runId,
1842
+ attemptId,
1843
+ descriptor,
1844
+ });
1845
+ if ((yield* fileSystem.pathKind(migrationAttachmentDirectory(root, location))) !== "missing") {
1846
+ locations.push(location);
1847
+ }
1848
+ }
1849
+ }
1850
+ }
1851
+ return Object.freeze(locations);
1852
+ });
1853
+ }
1854
+ function readKnownMigrationAttachment(fileSystem, root, location) {
1855
+ return (0, runtime_ts_1.readFixedRecordAttachment)({
1856
+ fileSystem,
1857
+ root,
1858
+ location: migrationReaderLocation(location),
1859
+ descriptor: location.descriptor,
1860
+ });
1861
+ }
1862
+ function migrationInvalid(family) {
1863
+ return new errors_ts_3.RecordMigrationInvalid({ code: "record-migration-invalid", family });
1864
+ }
1865
+ function migrationPlanStale() {
1866
+ return new errors_ts_3.RecordMigrationPlanStale({ code: "record-migration-plan-stale" });
1867
+ }
1868
+ function migrationFailureCode(error) {
1869
+ if (typeof error !== "object" || error === null)
1870
+ return "record-command-failed";
1871
+ const code = Reflect.get(error, "code");
1872
+ return typeof code === "string" ? code : "record-command-failed";
1873
+ }
1874
+ function migrationTarget(location) {
1875
+ return Object.freeze({
1876
+ family: location.descriptor.family,
1877
+ owner: location.owner,
1878
+ runId: location.runId,
1879
+ ...(location.attemptId === undefined ? {} : { attemptId: location.attemptId }),
1880
+ fromSchemaVersion: 1,
1881
+ toSchemaVersion: location.descriptor.schemaVersion,
1882
+ });
1883
+ }
1884
+ const RECORD_MIGRATION_IMPLEMENTATION_ID = "niceeval.record/root-1-observability-1-to-root-2-observability-2/v1";
1885
+ const migrationPlanSources = new WeakMap();
1886
+ function bytesEqual(left, right) {
1887
+ return left.byteLength === right.byteLength && left.every((byte, index) => byte === right[index]);
1888
+ }
1889
+ function migrationEnvelopePath(root, location) {
1890
+ return (0, services_ts_1.recordPortablePath)(root, ...migrationAttachmentDirectory(root, location).segments, "attachment.json");
1891
+ }
1892
+ function sameMigrationPlan(left, right) {
1893
+ if (left.state !== right.state || left.format !== right.format)
1894
+ return false;
1895
+ if (left.state !== "migration-required" || right.state !== "migration-required")
1896
+ return true;
1897
+ if (JSON.stringify(left.backup) !== JSON.stringify(right.backup))
1898
+ return false;
1899
+ if (JSON.stringify(left.root) !== JSON.stringify(right.root))
1900
+ return false;
1901
+ if (left.attachments.length !== right.attachments.length)
1902
+ return false;
1903
+ return left.attachments.every((target, index) => {
1904
+ const candidate = right.attachments[index];
1905
+ return candidate !== undefined &&
1906
+ target.family === candidate.family &&
1907
+ target.owner === candidate.owner &&
1908
+ target.runId === candidate.runId &&
1909
+ target.attemptId === candidate.attemptId &&
1910
+ target.fromSchemaVersion === candidate.fromSchemaVersion &&
1911
+ target.toSchemaVersion === candidate.toSchemaVersion;
1912
+ });
1913
+ }
1914
+ function planAttachmentMigration(input) {
1915
+ return effect_1.Effect.gen(function* () {
1916
+ yield* validateCurrentFamilyInventory(input.fileSystem, input.root);
1917
+ const targets = [];
1918
+ const sources = [];
1919
+ for (const location of yield* knownMigrationAttachments(input.fileSystem, input.root)) {
1920
+ const read = yield* readKnownMigrationAttachment(input.fileSystem, input.root, location);
1921
+ if (read.state === "available")
1922
+ continue;
1923
+ if (read.state === "migration-required" &&
1924
+ location.descriptor.family === catalog_ts_1.NiceEvalRecordAttachments.observability.family &&
1925
+ read.fromSchemaVersion === 1 &&
1926
+ read.toSchemaVersion === 2) {
1927
+ const target = migrationTarget(location);
1928
+ const envelopeBytes = yield* input.fileSystem.readFile({
1929
+ file: migrationEnvelopePath(input.root, location),
1930
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
1931
+ });
1932
+ if (envelopeBytes === undefined) {
1933
+ return yield* effect_1.Effect.fail(migrationInvalid(location.descriptor.family));
1934
+ }
1935
+ targets.push(target);
1936
+ sources.push(Object.freeze({ target, envelopeBytes }));
1937
+ continue;
1938
+ }
1939
+ if (read.state === "unsupported") {
1940
+ return yield* effect_1.Effect.fail(new errors_ts_3.RecordFormatUnsupported({
1941
+ code: "record-format-unsupported",
1942
+ format: `${read.family}@${read.schemaVersion}`,
1943
+ }));
1944
+ }
1945
+ return yield* effect_1.Effect.fail(migrationInvalid(location.descriptor.family));
1946
+ }
1947
+ return Object.freeze({
1948
+ targets: Object.freeze(targets),
1949
+ sources: Object.freeze(sources),
1950
+ });
1951
+ });
1952
+ }
1953
+ function ensureOrdinaryCurrentAttachments(input) {
1954
+ return planAttachmentMigration(input).pipe(effect_1.Effect.flatMap((plan) => plan.targets.length === 0
1955
+ ? effect_1.Effect.void
1956
+ : effect_1.Effect.fail(new errors_ts_3.RecordMigrationRequired({
1957
+ code: "record-migration-required",
1958
+ source: "niceeval.record attachment predecessor",
1959
+ target: `${identifiers_ts_1.RECORD_FORMAT}@${identifiers_ts_1.RECORD_SCHEMA_VERSION}`,
1960
+ command: "niceeval migrate",
1961
+ }))), effect_1.Effect.mapError((error) => error instanceof errors_ts_3.RecordMigrationInvalid
1962
+ ? bootstrapInvalid()
1963
+ : error));
1964
+ }
1965
+ function migrationPlan(input) {
1966
+ return effect_1.Effect.gen(function* () {
1967
+ const format = yield* (0, format_ts_1.readRecordFormatForMaintenance)(input.fileSystem, input.root);
1968
+ yield* validateSealedCoreForMigration(input.fileSystem, input.root, format.document);
1969
+ const attachments = yield* planAttachmentMigration(input);
1970
+ const rootMigration = format.sourceSchemaVersion === identifiers_ts_1.RECORD_SCHEMA_VERSION
1971
+ ? null
1972
+ : Object.freeze({
1973
+ fromSchemaVersion: format.sourceSchemaVersion,
1974
+ toSchemaVersion: identifiers_ts_1.RECORD_SCHEMA_VERSION,
1975
+ });
1976
+ if (rootMigration === null && attachments.targets.length === 0) {
1977
+ return Object.freeze({ state: "already-current", format: identifiers_ts_1.RECORD_FORMAT });
1978
+ }
1979
+ const backup = yield* input.git.inspectBackupState(input.root);
1980
+ const plan = Object.freeze({
1981
+ state: "migration-required",
1982
+ format: identifiers_ts_1.RECORD_FORMAT,
1983
+ backup,
1984
+ root: rootMigration,
1985
+ attachments: attachments.targets,
1986
+ });
1987
+ migrationPlanSources.set(plan, Object.freeze({
1988
+ attachments: attachments.sources,
1989
+ rootBytes: rootMigration === null ? null : format.sourceBytes,
1990
+ record: format.document,
1991
+ implementationIdentity: RECORD_MIGRATION_IMPLEMENTATION_ID,
1992
+ }));
1993
+ return plan;
1994
+ });
1995
+ }
1996
+ function validateSealedCoreForMigration(fileSystem, root, record) {
1997
+ return effect_1.Effect.flatMap(loadSealedCoreSnapshot(maintenanceReaderRuntime(root, record), fileSystem), (snapshot) => snapshot.state === "available"
1998
+ ? effect_1.Effect.void
1999
+ : effect_1.Effect.fail(migrationInvalid("niceeval.core")));
2000
+ }
2001
+ function loadObservabilityV1Maintenance() {
2002
+ const loader = catalog_ts_1.NiceEvalRecordAttachments.observability.maintenance;
2003
+ if (loader === undefined)
2004
+ return effect_1.Effect.fail(migrationInvalid(catalog_ts_1.NiceEvalRecordAttachments.observability.family));
2005
+ return effect_1.Effect.tryPromise({
2006
+ try: loader,
2007
+ catch: () => migrationInvalid(catalog_ts_1.NiceEvalRecordAttachments.observability.family),
2008
+ });
2009
+ }
2010
+ function migrateObservabilityAttachment(input) {
2011
+ return effect_1.Effect.gen(function* () {
2012
+ if (input.target.family !== catalog_ts_1.NiceEvalRecordAttachments.observability.family ||
2013
+ input.target.fromSchemaVersion !== 1 ||
2014
+ input.target.toSchemaVersion !== 2) {
2015
+ return yield* effect_1.Effect.fail(migrationInvalid(input.target.family));
2016
+ }
2017
+ const descriptor = input.target.owner === "run"
2018
+ ? migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.observability.run)
2019
+ : migrationDescriptor(catalog_ts_1.NiceEvalRecordFamilyCatalog.observability.attempt);
2020
+ const location = input.target.owner === "run"
2021
+ ? Object.freeze({ owner: "run", runId: input.target.runId, descriptor })
2022
+ : Object.freeze({
2023
+ owner: "attempt",
2024
+ runId: input.target.runId,
2025
+ attemptId: input.target.attemptId,
2026
+ descriptor,
2027
+ });
2028
+ const facet = yield* loadObservabilityV1Maintenance();
2029
+ const historical = facet.historicalCodecs.find((codec) => codec.schemaVersion === 1);
2030
+ const step = facet.adjacentMigrations.find((migration) => migration.fromSchemaVersion === 1 && migration.toSchemaVersion === 2);
2031
+ if (historical === undefined || step === undefined) {
2032
+ return yield* effect_1.Effect.fail(migrationInvalid(input.target.family));
2033
+ }
2034
+ const envelopePath = migrationEnvelopePath(input.root, location);
2035
+ const sourceBeforeValidation = yield* input.fileSystem.readFile({
2036
+ file: envelopePath,
2037
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
2038
+ });
2039
+ if (sourceBeforeValidation === undefined || !bytesEqual(sourceBeforeValidation, input.expectedEnvelopeBytes)) {
2040
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2041
+ }
2042
+ const valid = yield* (0, runtime_ts_1.validateFixedRecordAttachmentMigrationSource)({
2043
+ fileSystem: input.fileSystem,
2044
+ root: input.root,
2045
+ location: migrationReaderLocation(location),
2046
+ descriptor,
2047
+ fromSchemaVersion: 1,
2048
+ decodeHistorical: historical.decode,
2049
+ migrate: step.migrate,
2050
+ });
2051
+ if (!valid) {
2052
+ const sourceAfterInvalid = yield* input.fileSystem.readFile({
2053
+ file: envelopePath,
2054
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
2055
+ });
2056
+ if (sourceAfterInvalid === undefined || !bytesEqual(sourceAfterInvalid, input.expectedEnvelopeBytes)) {
2057
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2058
+ }
2059
+ return yield* effect_1.Effect.fail(migrationInvalid(input.target.family));
2060
+ }
2061
+ const envelope = (0, catalog_ts_1.encodeFixedRecordAttachmentEnvelope)({
2062
+ family: catalog_ts_1.NiceEvalRecordAttachments.observability.family,
2063
+ schemaVersion: 2,
2064
+ });
2065
+ if (effect_1.Either.isLeft(envelope))
2066
+ return yield* effect_1.Effect.fail(migrationInvalid(input.target.family));
2067
+ const sourceBeforeWrite = yield* input.fileSystem.readFile({
2068
+ file: envelopePath,
2069
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
2070
+ });
2071
+ if (sourceBeforeWrite === undefined || !bytesEqual(sourceBeforeWrite, input.expectedEnvelopeBytes)) {
2072
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2073
+ }
2074
+ yield* input.fileSystem.writeFile({
2075
+ file: envelopePath,
2076
+ bytes: jsonBytes(envelope.right),
2077
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
2078
+ mode: "replace-no-follow",
2079
+ });
2080
+ });
2081
+ }
2082
+ function validateCurrentKnownAttachments(input) {
2083
+ return effect_1.Effect.gen(function* () {
2084
+ for (const location of yield* knownMigrationAttachments(input.fileSystem, input.root)) {
2085
+ const read = yield* readKnownMigrationAttachment(input.fileSystem, input.root, location);
2086
+ if (read.state !== "available") {
2087
+ return yield* effect_1.Effect.fail(migrationInvalid(location.descriptor.family));
2088
+ }
2089
+ const joined = yield* validateFixedCrossFamilyJoin({
2090
+ fileSystem: input.fileSystem,
2091
+ root: input.root,
2092
+ runId: location.runId,
2093
+ ...(location.attemptId === undefined ? {} : { attemptId: location.attemptId }),
2094
+ descriptor: location.descriptor,
2095
+ payload: read.value,
2096
+ });
2097
+ if (joined.state !== "joined") {
2098
+ return yield* effect_1.Effect.fail(migrationInvalid(location.descriptor.family));
2099
+ }
2100
+ }
2101
+ });
2102
+ }
2103
+ function migrationRecoveryIsSafe(input) {
2104
+ return effect_1.Effect.gen(function* () {
2105
+ const encoded = (0, catalog_ts_1.encodeFixedRecordAttachmentEnvelope)({
2106
+ family: catalog_ts_1.NiceEvalRecordAttachments.observability.family,
2107
+ schemaVersion: 2,
2108
+ });
2109
+ if (effect_1.Either.isLeft(encoded))
2110
+ return false;
2111
+ const currentEnvelopeBytes = jsonBytes(encoded.right);
2112
+ const expectedPaths = [(0, services_ts_1.recordPortablePath)(input.root, "migration.in-progress")];
2113
+ const currentRoot = yield* input.fileSystem.readFile({
2114
+ file: (0, services_ts_1.recordPortablePath)(input.root, "record.json"),
2115
+ maximumBytes: format_ts_1.RECORD_FORMAT_DOCUMENT_MAXIMUM_BYTES,
2116
+ });
2117
+ if (currentRoot !== undefined) {
2118
+ const parsed = parseJson(currentRoot);
2119
+ if (typeof parsed === "object" && parsed !== null &&
2120
+ Reflect.get(parsed, "schemaVersion") === identifiers_ts_1.RECORD_SCHEMA_VERSION)
2121
+ expectedPaths.push((0, services_ts_1.recordPortablePath)(input.root, "record.json"));
2122
+ }
2123
+ for (const location of yield* knownMigrationAttachments(input.fileSystem, input.root)) {
2124
+ if (location.descriptor.family !== catalog_ts_1.NiceEvalRecordAttachments.observability.family)
2125
+ continue;
2126
+ const path = migrationEnvelopePath(input.root, location);
2127
+ const bytes = yield* input.fileSystem.readFile({
2128
+ file: path,
2129
+ maximumBytes: limits_ts_1.RECORD_JSON_MAXIMUM_BYTES,
2130
+ });
2131
+ if (bytes !== undefined && bytesEqual(bytes, currentEnvelopeBytes))
2132
+ expectedPaths.push(path);
2133
+ }
2134
+ return yield* input.git.recoveryChangesAreExpected({
2135
+ root: input.root,
2136
+ restoreCommit: input.restoreCommit,
2137
+ expectedPaths,
2138
+ });
2139
+ }).pipe(effect_1.Effect.catchAll(() => effect_1.Effect.succeed(false)));
2140
+ }
1665
2141
  function openMaintenance(input) {
1666
2142
  return effect_1.Effect.gen(function* () {
1667
2143
  const coordination = yield* record_leases_ts_1.RecordCoordination;
1668
2144
  const fileSystem = yield* services_ts_1.RecordFileSystem;
2145
+ const git = yield* services_ts_1.RecordGit;
1669
2146
  yield* coordination.enterRecordMaintenance(input.root);
1670
2147
  if (yield* fileSystem.migrationSentinelPresent(input.root)) {
1671
- return yield* effect_1.Effect.fail(migrationInterrupted());
2148
+ const restoreCommit = yield* fileSystem.readMigrationSentinelRestoreCommit(input.root);
2149
+ const restoreSafe = restoreCommit === undefined
2150
+ ? false
2151
+ : yield* migrationRecoveryIsSafe({ fileSystem, git, root: input.root, restoreCommit });
2152
+ return yield* effect_1.Effect.fail(migrationInterrupted(restoreCommit, restoreSafe));
1672
2153
  }
1673
2154
  const inspect = () => currentFormatInspection(fileSystem, input.root);
2155
+ const planMigrate = () => effect_1.Effect.gen(function* () {
2156
+ const format = yield* (0, format_ts_1.readRecordFormatForMaintenance)(fileSystem, input.root);
2157
+ yield* coordination.verifyRecordIdentity({ root: input.root, recordId: format.document.recordId });
2158
+ return yield* migrationPlan({ fileSystem, root: input.root, git });
2159
+ });
1674
2160
  return Object.freeze({
1675
2161
  inspect,
1676
- planMigrate: () => effect_1.Effect.map(inspect(), (inspection) => inspection.state === "already-current"
1677
- ? Object.freeze({ state: "already-current", format: inspection.format })
1678
- : Object.freeze({ state: "unsupported-format", format: inspection.format })),
1679
- applyMigrate: (plan) => plan.state === "already-current" && plan.format === identifiers_ts_1.RECORD_FORMAT
1680
- ? effect_1.Effect.succeed(Object.freeze({ state: "already-current", format: identifiers_ts_1.RECORD_FORMAT }))
1681
- : effect_1.Effect.fail(new errors_ts_3.RecordFormatUnsupported({
1682
- code: "record-format-unsupported",
1683
- format: plan.format,
1684
- })),
2162
+ planMigrate,
2163
+ applyMigrate: (plan) => effect_1.Effect.gen(function* () {
2164
+ const currentPlan = yield* planMigrate();
2165
+ if (!sameMigrationPlan(plan, currentPlan)) {
2166
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2167
+ }
2168
+ if (currentPlan.state === "already-current") {
2169
+ return Object.freeze({ state: "already-current", format: identifiers_ts_1.RECORD_FORMAT });
2170
+ }
2171
+ if (currentPlan.state === "unsupported-format") {
2172
+ return yield* effect_1.Effect.fail(new errors_ts_3.RecordFormatUnsupported({
2173
+ code: "record-format-unsupported",
2174
+ format: currentPlan.format,
2175
+ }));
2176
+ }
2177
+ if (currentPlan.backup.state !== "git-restore-point") {
2178
+ return yield* effect_1.Effect.fail(new errors_ts_3.RecordMigrationGitRestoreRequired({
2179
+ code: "record-migration-git-restore-required",
2180
+ }));
2181
+ }
2182
+ const restoreCommit = currentPlan.backup.commit;
2183
+ const plannedSources = migrationPlanSources.get(currentPlan);
2184
+ if (plannedSources === undefined ||
2185
+ plannedSources.implementationIdentity !== RECORD_MIGRATION_IMPLEMENTATION_ID ||
2186
+ plannedSources.attachments.length !== currentPlan.attachments.length ||
2187
+ (currentPlan.root === null) !== (plannedSources.rootBytes === null)) {
2188
+ return yield* effect_1.Effect.fail(migrationInvalid(catalog_ts_1.NiceEvalRecordAttachments.observability.family));
2189
+ }
2190
+ let portableTargetWritten = false;
2191
+ // The sentinel is the first portable write. Any later failure or
2192
+ // interruption intentionally leaves it behind for Git recovery.
2193
+ yield* fileSystem.createMigrationSentinel(input.root, restoreCommit);
2194
+ const sentinelOnly = yield* git.recoveryChangesAreExpected({
2195
+ root: input.root,
2196
+ restoreCommit,
2197
+ expectedPaths: [(0, services_ts_1.recordPortablePath)(input.root, "migration.in-progress")],
2198
+ });
2199
+ if (!sentinelOnly) {
2200
+ yield* fileSystem.removeMigrationSentinel(input.root);
2201
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2202
+ }
2203
+ yield* effect_1.Effect.gen(function* () {
2204
+ for (const source of plannedSources.attachments) {
2205
+ yield* migrateObservabilityAttachment({
2206
+ fileSystem,
2207
+ root: input.root,
2208
+ target: source.target,
2209
+ expectedEnvelopeBytes: source.envelopeBytes,
2210
+ });
2211
+ portableTargetWritten = true;
2212
+ }
2213
+ if (plannedSources.rootBytes !== null) {
2214
+ const rootPath = (0, services_ts_1.recordPortablePath)(input.root, "record.json");
2215
+ const sourceBeforeRootWrite = yield* fileSystem.readFile({
2216
+ file: rootPath,
2217
+ maximumBytes: format_ts_1.RECORD_FORMAT_DOCUMENT_MAXIMUM_BYTES,
2218
+ });
2219
+ if (sourceBeforeRootWrite === undefined ||
2220
+ !bytesEqual(sourceBeforeRootWrite, plannedSources.rootBytes))
2221
+ return yield* effect_1.Effect.fail(migrationPlanStale());
2222
+ const encodedRoot = (0, index_ts_1.encodeRecordDocument)(plannedSources.record);
2223
+ if (effect_1.Either.isLeft(encodedRoot))
2224
+ return yield* effect_1.Effect.fail(migrationInvalid("niceeval.core"));
2225
+ yield* fileSystem.writeFile({
2226
+ file: rootPath,
2227
+ bytes: jsonBytes(encodedRoot.right),
2228
+ maximumBytes: format_ts_1.RECORD_FORMAT_DOCUMENT_MAXIMUM_BYTES,
2229
+ mode: "replace-no-follow",
2230
+ });
2231
+ portableTargetWritten = true;
2232
+ }
2233
+ const current = yield* (0, format_ts_1.readCurrentRecordFormat)(fileSystem, input.root);
2234
+ yield* validateSealedCoreForMigration(fileSystem, input.root, current.document);
2235
+ yield* validateCurrentKnownAttachments({ fileSystem, root: input.root });
2236
+ yield* fileSystem.removeMigrationSentinel(input.root);
2237
+ }).pipe(effect_1.Effect.catchAll((error) => {
2238
+ const recoveryRequired = () => effect_1.Effect.flatMap(migrationRecoveryIsSafe({ fileSystem, git, root: input.root, restoreCommit }), (restoreSafe) => effect_1.Effect.fail(new errors_ts_3.RecordMigrationRecoveryRequired({
2239
+ code: "record-migration-recovery-required",
2240
+ causeCode: migrationFailureCode(error),
2241
+ restoreCommit,
2242
+ restoreSafe,
2243
+ })));
2244
+ if (error instanceof errors_ts_3.RecordMigrationPlanStale && !portableTargetWritten) {
2245
+ return fileSystem.removeMigrationSentinel(input.root).pipe(effect_1.Effect.matchEffect({
2246
+ onFailure: () => recoveryRequired(),
2247
+ onSuccess: () => effect_1.Effect.fail(error),
2248
+ }));
2249
+ }
2250
+ return recoveryRequired();
2251
+ }));
2252
+ return Object.freeze({ state: "migrated", format: identifiers_ts_1.RECORD_FORMAT });
2253
+ }),
1685
2254
  });
1686
2255
  });
1687
2256
  }