niceeval 0.13.3 → 0.13.4-canary.39

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 (487) hide show
  1. package/INDEX.md +5 -5
  2. package/dist/agents/index.cjs +2 -2
  3. package/dist/agents/index.cjs.map +1 -1
  4. package/dist/agents/project.json +6 -0
  5. package/dist/agents/streaming.cjs.map +1 -1
  6. package/dist/agents/types.cjs.map +1 -1
  7. package/dist/agents/types.d.cts +1 -1
  8. package/dist/agents/types.d.mts +1 -1
  9. package/dist/agents/types.d.ts +1 -1
  10. package/dist/analysis/bindings.d.cts +8 -8
  11. package/dist/analysis/bindings.d.mts +8 -8
  12. package/dist/analysis/bindings.d.ts +8 -8
  13. package/dist/analysis/contracts.cjs.map +1 -1
  14. package/dist/analysis/contracts.d.cts +8 -19
  15. package/dist/analysis/contracts.d.mts +8 -19
  16. package/dist/analysis/contracts.d.ts +8 -19
  17. package/dist/analysis/experiment-groups.cjs +7 -14
  18. package/dist/analysis/experiment-groups.cjs.map +1 -1
  19. package/dist/analysis/index.cjs.map +1 -1
  20. package/dist/analysis/index.d.cts +1 -1
  21. package/dist/analysis/index.d.mts +1 -1
  22. package/dist/analysis/index.d.ts +1 -1
  23. package/dist/cli/application.cjs +4 -13
  24. package/dist/cli/application.cjs.map +1 -1
  25. package/dist/cli/application.d.cts +62 -59
  26. package/dist/cli/application.d.mts +62 -59
  27. package/dist/cli/application.d.ts +62 -59
  28. package/dist/cli/application.js +6 -12
  29. package/dist/cli/bootstrap.cjs +28 -2
  30. package/dist/cli/bootstrap.cjs.map +1 -1
  31. package/dist/cli/contribution.cjs +185 -0
  32. package/dist/cli/contribution.cjs.map +1 -0
  33. package/dist/cli/contribution.d.cts +55 -0
  34. package/dist/cli/contribution.d.mts +55 -0
  35. package/dist/cli/contribution.d.ts +55 -0
  36. package/dist/cli/contribution.js +20 -0
  37. package/dist/cli/contribution.js.map +1 -0
  38. package/dist/cli/node-application.cjs +119 -87
  39. package/dist/cli/node-application.cjs.map +1 -1
  40. package/dist/cli/node-application.d.cts +2 -8
  41. package/dist/cli/node-application.d.mts +2 -8
  42. package/dist/cli/node-application.d.ts +2 -8
  43. package/dist/cli/node-application.js +12 -22
  44. package/dist/cli/program.cjs +87 -2756
  45. package/dist/cli/program.cjs.map +1 -1
  46. package/dist/cli/program.d.cts +11 -332
  47. package/dist/cli/program.d.mts +11 -332
  48. package/dist/cli/program.d.ts +11 -332
  49. package/dist/cli/program.js +4 -28
  50. package/dist/cli.cjs +0 -3
  51. package/dist/cli.cjs.map +1 -1
  52. package/dist/cli.d.cts +0 -1
  53. package/dist/cli.d.mts +0 -1
  54. package/dist/cli.d.ts +0 -1
  55. package/dist/cli.js +6 -14
  56. package/dist/define.cjs +1 -1
  57. package/dist/define.cjs.map +1 -1
  58. package/dist/docker/cache-administration.cjs +8 -0
  59. package/dist/docker/cache-administration.cjs.map +1 -0
  60. package/dist/docker/cache-administration.d.cts +33 -0
  61. package/dist/docker/cache-administration.d.mts +33 -0
  62. package/dist/docker/cache-administration.d.ts +33 -0
  63. package/dist/docker/cache-administration.js +6 -0
  64. package/dist/docker/cache-administration.js.map +1 -0
  65. package/dist/docker/cache-live.cjs +27 -0
  66. package/dist/docker/cache-live.cjs.map +1 -0
  67. package/dist/docker/cache-live.d.cts +3 -0
  68. package/dist/docker/cache-live.d.mts +3 -0
  69. package/dist/docker/cache-live.d.ts +3 -0
  70. package/dist/docker/cache-live.js +6 -0
  71. package/dist/docker/cache-live.js.map +1 -0
  72. package/dist/docker/cli/contribution.cjs +223 -0
  73. package/dist/docker/cli/contribution.cjs.map +1 -0
  74. package/dist/docker/cli/contribution.d.cts +48 -0
  75. package/dist/docker/cli/contribution.d.mts +48 -0
  76. package/dist/docker/cli/contribution.d.ts +48 -0
  77. package/dist/docker/cli/contribution.js +8 -0
  78. package/dist/docker/cli/contribution.js.map +1 -0
  79. package/dist/eval/cli/contribution.cjs +62 -0
  80. package/dist/eval/cli/contribution.cjs.map +1 -0
  81. package/dist/eval/cli/contribution.d.cts +21 -0
  82. package/dist/eval/cli/contribution.d.mts +21 -0
  83. package/dist/eval/cli/contribution.d.ts +21 -0
  84. package/dist/eval/cli/contribution.js +8 -0
  85. package/dist/eval/cli/contribution.js.map +1 -0
  86. package/dist/eval/host/index.cjs +23 -0
  87. package/dist/eval/host/index.cjs.map +1 -0
  88. package/dist/eval/host/index.d.cts +27 -0
  89. package/dist/eval/host/index.d.mts +27 -0
  90. package/dist/eval/host/index.d.ts +27 -0
  91. package/dist/eval/host/index.js +8 -0
  92. package/dist/eval/host/index.js.map +1 -0
  93. package/dist/eval/host/index.mjs +8 -0
  94. package/dist/eval/host/index.mjs.map +1 -0
  95. package/dist/experiment/host/cli/contribution.cjs +835 -0
  96. package/dist/experiment/host/cli/contribution.cjs.map +1 -0
  97. package/dist/experiment/host/cli/contribution.d.cts +329 -0
  98. package/dist/experiment/host/cli/contribution.d.mts +329 -0
  99. package/dist/experiment/host/cli/contribution.d.ts +329 -0
  100. package/dist/experiment/host/cli/contribution.js +22 -0
  101. package/dist/experiment/host/cli/contribution.js.map +1 -0
  102. package/dist/experiment/host/cli/index.cjs +9 -0
  103. package/dist/experiment/host/cli/index.cjs.map +1 -0
  104. package/dist/experiment/host/cli/index.d.cts +2 -0
  105. package/dist/experiment/host/cli/index.d.mts +2 -0
  106. package/dist/experiment/host/cli/index.d.ts +2 -0
  107. package/dist/experiment/host/cli/index.js +10 -0
  108. package/dist/experiment/host/cli/index.js.map +1 -0
  109. package/dist/experiment/host/cli/terminal.cjs +15 -0
  110. package/dist/experiment/host/cli/terminal.cjs.map +1 -0
  111. package/dist/experiment/host/cli/terminal.d.cts +14 -0
  112. package/dist/experiment/host/cli/terminal.d.mts +14 -0
  113. package/dist/experiment/host/cli/terminal.d.ts +14 -0
  114. package/dist/experiment/host/cli/terminal.js +8 -0
  115. package/dist/experiment/host/cli/terminal.js.map +1 -0
  116. package/dist/experiment/host/index.cjs +35 -58
  117. package/dist/experiment/host/index.cjs.map +1 -1
  118. package/dist/experiment/host/index.d.cts +5 -79
  119. package/dist/experiment/host/index.d.mts +5 -79
  120. package/dist/experiment/host/index.d.ts +5 -79
  121. package/dist/experiment/host/index.js +4 -2
  122. package/dist/experiment/host/index.mjs +4 -2
  123. package/dist/experiment/host/operations.cjs +678 -0
  124. package/dist/experiment/host/operations.cjs.map +1 -0
  125. package/dist/experiment/host/operations.d.cts +19 -0
  126. package/dist/experiment/host/operations.d.mts +19 -0
  127. package/dist/experiment/host/operations.d.ts +19 -0
  128. package/dist/experiment/host/operations.js +24 -0
  129. package/dist/experiment/host/operations.js.map +1 -0
  130. package/dist/experiment/host/presentation.cjs +81 -0
  131. package/dist/experiment/host/presentation.cjs.map +1 -0
  132. package/dist/experiment/host/presentation.d.cts +9 -0
  133. package/dist/experiment/host/presentation.d.mts +9 -0
  134. package/dist/experiment/host/presentation.d.ts +9 -0
  135. package/dist/experiment/host/presentation.js +8 -0
  136. package/dist/experiment/host/presentation.js.map +1 -0
  137. package/dist/experiment/host/teardown.cjs +394 -0
  138. package/dist/experiment/host/teardown.cjs.map +1 -0
  139. package/dist/experiment/host/teardown.d.cts +5 -0
  140. package/dist/experiment/host/teardown.d.mts +5 -0
  141. package/dist/experiment/host/teardown.d.ts +5 -0
  142. package/dist/experiment/host/teardown.js +8 -0
  143. package/dist/experiment/host/teardown.js.map +1 -0
  144. package/dist/experiment/host/types.cjs +9 -0
  145. package/dist/experiment/host/types.cjs.map +1 -0
  146. package/dist/experiment/host/types.d.cts +423 -0
  147. package/dist/experiment/host/types.d.mts +423 -0
  148. package/dist/experiment/host/types.d.ts +423 -0
  149. package/dist/experiment/host/types.js +6 -0
  150. package/dist/experiment/host/types.js.map +1 -0
  151. package/dist/i18n/en.cjs +8 -50
  152. package/dist/i18n/en.cjs.map +1 -1
  153. package/dist/i18n/en.d.cts +2 -6
  154. package/dist/i18n/en.d.mts +2 -6
  155. package/dist/i18n/en.d.ts +2 -6
  156. package/dist/o11y/project.json +6 -0
  157. package/dist/project/cli/contribution.cjs +66 -0
  158. package/dist/project/cli/contribution.cjs.map +1 -0
  159. package/dist/project/cli/contribution.d.cts +17 -0
  160. package/dist/project/cli/contribution.d.mts +17 -0
  161. package/dist/project/cli/contribution.d.ts +17 -0
  162. package/dist/project/cli/contribution.js +8 -0
  163. package/dist/project/cli/contribution.js.map +1 -0
  164. package/dist/project/cli/index.cjs +7 -0
  165. package/dist/project/cli/index.cjs.map +1 -0
  166. package/dist/project/cli/index.d.cts +1 -0
  167. package/dist/project/cli/index.d.mts +1 -0
  168. package/dist/project/cli/index.d.ts +1 -0
  169. package/dist/project/cli/index.js +8 -0
  170. package/dist/project/cli/index.js.map +1 -0
  171. package/dist/project/host/index.cjs +11 -0
  172. package/dist/project/host/index.cjs.map +1 -0
  173. package/dist/project/host/index.d.cts +4 -0
  174. package/dist/project/host/index.d.mts +4 -0
  175. package/dist/project/host/index.d.ts +4 -0
  176. package/dist/project/host/index.js +14 -0
  177. package/dist/project/host/index.js.map +1 -0
  178. package/dist/project/host/index.mjs +14 -0
  179. package/dist/project/host/index.mjs.map +1 -0
  180. package/dist/project/host.cjs +59 -0
  181. package/dist/project/host.cjs.map +1 -0
  182. package/dist/project/host.d.cts +17 -0
  183. package/dist/project/host.d.mts +17 -0
  184. package/dist/project/host.d.ts +17 -0
  185. package/dist/project/host.js +6 -0
  186. package/dist/project/host.js.map +1 -0
  187. package/dist/project/index.cjs +11 -0
  188. package/dist/project/index.cjs.map +1 -0
  189. package/dist/project/index.d.cts +4 -0
  190. package/dist/project/index.d.mts +4 -0
  191. package/dist/project/index.d.ts +4 -0
  192. package/dist/project/index.js +14 -0
  193. package/dist/project/index.js.map +1 -0
  194. package/dist/project/node.cjs +91 -0
  195. package/dist/project/node.cjs.map +1 -0
  196. package/dist/project/node.d.cts +6 -0
  197. package/dist/project/node.d.mts +6 -0
  198. package/dist/project/node.d.ts +6 -0
  199. package/dist/project/node.js +12 -0
  200. package/dist/project/node.js.map +1 -0
  201. package/dist/project/services.cjs +17 -0
  202. package/dist/project/services.cjs.map +1 -0
  203. package/dist/project/services.d.cts +47 -0
  204. package/dist/project/services.d.mts +47 -0
  205. package/dist/project/services.d.ts +47 -0
  206. package/dist/project/services.js +12 -0
  207. package/dist/project/services.js.map +1 -0
  208. package/dist/project/templates.cjs +28 -0
  209. package/dist/project/templates.cjs.map +1 -0
  210. package/dist/project/templates.d.cts +4 -0
  211. package/dist/project/templates.d.mts +4 -0
  212. package/dist/project/templates.d.ts +4 -0
  213. package/dist/project/templates.js +12 -0
  214. package/dist/project/templates.js.map +1 -0
  215. package/dist/project.json +6 -0
  216. package/dist/record/family/catalog.d.cts +10 -10
  217. package/dist/record/family/catalog.d.mts +10 -10
  218. package/dist/record/family/catalog.d.ts +10 -10
  219. package/dist/record/family/file-changes.d.cts +8 -8
  220. package/dist/record/family/file-changes.d.mts +8 -8
  221. package/dist/record/family/file-changes.d.ts +8 -8
  222. package/dist/record/host/cli/contribution.cjs +206 -0
  223. package/dist/record/host/cli/contribution.cjs.map +1 -0
  224. package/dist/record/host/cli/contribution.d.cts +32 -0
  225. package/dist/record/host/cli/contribution.d.mts +32 -0
  226. package/dist/record/host/cli/contribution.d.ts +32 -0
  227. package/dist/record/host/cli/contribution.js +10 -0
  228. package/dist/record/host/cli/contribution.js.map +1 -0
  229. package/dist/record/host/cli/index.cjs +8 -0
  230. package/dist/record/host/cli/index.cjs.map +1 -0
  231. package/dist/record/host/cli/index.d.cts +1 -0
  232. package/dist/record/host/cli/index.d.mts +1 -0
  233. package/dist/record/host/cli/index.d.ts +1 -0
  234. package/dist/record/host/cli/index.js +10 -0
  235. package/dist/record/host/cli/index.js.map +1 -0
  236. package/dist/record/host/cli/presentation.cjs +122 -0
  237. package/dist/record/host/cli/presentation.cjs.map +1 -0
  238. package/dist/record/host/cli/presentation.d.cts +7 -0
  239. package/dist/record/host/cli/presentation.d.mts +7 -0
  240. package/dist/record/host/cli/presentation.d.ts +7 -0
  241. package/dist/record/host/cli/presentation.js +12 -0
  242. package/dist/record/host/cli/presentation.js.map +1 -0
  243. package/dist/record/host/index.cjs.map +1 -1
  244. package/dist/record/host/index.d.cts +1 -1
  245. package/dist/record/host/index.d.mts +1 -1
  246. package/dist/record/host/index.d.ts +1 -1
  247. package/dist/record/host/runtime.cjs +184 -1
  248. package/dist/record/host/runtime.cjs.map +1 -1
  249. package/dist/record/host/types.cjs.map +1 -1
  250. package/dist/record/host/types.d.cts +120 -0
  251. package/dist/record/host/types.d.mts +120 -0
  252. package/dist/record/host/types.d.ts +120 -0
  253. package/dist/record/project.json +6 -0
  254. package/dist/report/assets/styles.css +80 -0
  255. package/dist/report/cli/contribution.cjs +325 -0
  256. package/dist/report/cli/contribution.cjs.map +1 -0
  257. package/dist/report/cli/contribution.d.cts +143 -0
  258. package/dist/report/cli/contribution.d.mts +143 -0
  259. package/dist/report/cli/contribution.d.ts +143 -0
  260. package/dist/report/cli/contribution.js +12 -0
  261. package/dist/report/cli/contribution.js.map +1 -0
  262. package/dist/report/client-dist/app.js +9 -9
  263. package/dist/report/components/attempt-detail/content.cjs +1 -1
  264. package/dist/report/components/attempt-detail/content.cjs.map +1 -1
  265. package/dist/report/components/entity-lists/compute.cjs +5 -0
  266. package/dist/report/components/entity-lists/compute.cjs.map +1 -1
  267. package/dist/report/components/entity-lists/compute.d.cts +2 -0
  268. package/dist/report/components/entity-lists/compute.d.mts +2 -0
  269. package/dist/report/components/entity-lists/compute.d.ts +2 -0
  270. package/dist/report/components/entity-lists/content.cjs +35 -12
  271. package/dist/report/components/entity-lists/content.cjs.map +1 -1
  272. package/dist/report/components/entity-lists/index.cjs +0 -3
  273. package/dist/report/components/entity-lists/index.cjs.map +1 -1
  274. package/dist/report/components/summaries/index.cjs +2 -4
  275. package/dist/report/components/summaries/index.cjs.map +1 -1
  276. package/dist/report/definition/cell.cjs +7 -2
  277. package/dist/report/definition/cell.cjs.map +1 -1
  278. package/dist/report/definition/cell.d.cts +2 -0
  279. package/dist/report/definition/cell.d.mts +2 -0
  280. package/dist/report/definition/cell.d.ts +2 -0
  281. package/dist/report/definition/primitives/assertion-evidence.cjs +190 -4
  282. package/dist/report/definition/primitives/assertion-evidence.cjs.map +1 -1
  283. package/dist/report/definition/primitives/assertion-evidence.d.cts +4 -0
  284. package/dist/report/definition/primitives/assertion-evidence.d.mts +4 -0
  285. package/dist/report/definition/primitives/assertion-evidence.d.ts +4 -0
  286. package/dist/report/execution/machine.cjs +2 -3
  287. package/dist/report/execution/machine.cjs.map +1 -1
  288. package/dist/report/execution/machine.d.cts +11 -8
  289. package/dist/report/execution/machine.d.mts +11 -8
  290. package/dist/report/execution/machine.d.ts +11 -8
  291. package/dist/report/host/from-record.cjs +13 -8
  292. package/dist/report/host/from-record.cjs.map +1 -1
  293. package/dist/report/host/index.cjs +5 -1
  294. package/dist/report/host/index.cjs.map +1 -1
  295. package/dist/report/host/index.d.cts +1 -0
  296. package/dist/report/host/index.d.mts +1 -0
  297. package/dist/report/host/index.d.ts +1 -0
  298. package/dist/report/host/index.js +8 -2
  299. package/dist/report/host/index.mjs +8 -2
  300. package/dist/report/host/machine.cjs +23 -22
  301. package/dist/report/host/machine.cjs.map +1 -1
  302. package/dist/report/host/machine.d.cts +1 -1
  303. package/dist/report/host/machine.d.mts +1 -1
  304. package/dist/report/host/machine.d.ts +1 -1
  305. package/dist/report/host/node/loader.cjs +4 -2
  306. package/dist/report/host/node/loader.cjs.map +1 -1
  307. package/dist/report/host/node/loader.d.cts +3 -1
  308. package/dist/report/host/node/loader.d.mts +3 -1
  309. package/dist/report/host/node/loader.d.ts +3 -1
  310. package/dist/report/host/node.cjs +44 -9
  311. package/dist/report/host/node.cjs.map +1 -1
  312. package/dist/report/host/node.d.cts +13 -3
  313. package/dist/report/host/node.d.mts +13 -3
  314. package/dist/report/host/node.d.ts +13 -3
  315. package/dist/report/host/node.js +44 -32
  316. package/dist/report/host/operations.cjs +14 -0
  317. package/dist/report/host/operations.cjs.map +1 -0
  318. package/dist/report/host/operations.d.cts +39 -0
  319. package/dist/report/host/operations.d.mts +39 -0
  320. package/dist/report/host/operations.d.ts +39 -0
  321. package/dist/report/host/operations.js +10 -0
  322. package/dist/report/host/operations.js.map +1 -0
  323. package/dist/report/model/chart/plot.cjs +1 -1
  324. package/dist/report/model/chart/plot.cjs.map +1 -1
  325. package/dist/report/model/locale.cjs +4 -0
  326. package/dist/report/model/locale.cjs.map +1 -1
  327. package/dist/report/model/locale.d.cts +3 -1
  328. package/dist/report/model/locale.d.mts +3 -1
  329. package/dist/report/model/locale.d.ts +3 -1
  330. package/dist/report/react/styles.css +80 -0
  331. package/dist/runner/build-preparation.cjs +5 -5
  332. package/dist/runner/build-preparation.cjs.map +1 -1
  333. package/dist/runner/build-preparation.d.cts +2 -3
  334. package/dist/runner/build-preparation.d.mts +2 -3
  335. package/dist/runner/build-preparation.d.ts +2 -3
  336. package/dist/runner/feedback/coordinator.cjs +18 -15
  337. package/dist/runner/feedback/coordinator.cjs.map +1 -1
  338. package/dist/runner/feedback/coordinator.d.cts +6 -0
  339. package/dist/runner/feedback/coordinator.d.mts +6 -0
  340. package/dist/runner/feedback/coordinator.d.ts +6 -0
  341. package/dist/runner/ledger.cjs +3 -13
  342. package/dist/runner/ledger.cjs.map +1 -1
  343. package/dist/runner/ledger.d.cts +1 -3
  344. package/dist/runner/ledger.d.mts +1 -3
  345. package/dist/runner/ledger.d.ts +1 -3
  346. package/dist/runner/run.cjs +63 -18
  347. package/dist/runner/run.cjs.map +1 -1
  348. package/dist/runner/session.cjs +10 -0
  349. package/dist/runner/session.cjs.map +1 -1
  350. package/dist/runner/session.d.cts +25 -0
  351. package/dist/runner/session.d.mts +25 -0
  352. package/dist/runner/session.d.ts +25 -0
  353. package/dist/runner/types.cjs.map +1 -1
  354. package/dist/runner/types.d.cts +1 -2
  355. package/dist/runner/types.d.mts +1 -2
  356. package/dist/runner/types.d.ts +1 -2
  357. package/dist/sandbox/build-coordinator.cjs +38 -19
  358. package/dist/sandbox/build-coordinator.cjs.map +1 -1
  359. package/dist/sandbox/build-coordinator.d.cts +47 -7
  360. package/dist/sandbox/build-coordinator.d.mts +47 -7
  361. package/dist/sandbox/build-coordinator.d.ts +47 -7
  362. package/dist/sandbox/build-coordinator.js +8 -4
  363. package/dist/sandbox/cli/contribution.cjs +128 -0
  364. package/dist/sandbox/cli/contribution.cjs.map +1 -0
  365. package/dist/sandbox/cli/contribution.d.cts +71 -0
  366. package/dist/sandbox/cli/contribution.d.mts +71 -0
  367. package/dist/sandbox/cli/contribution.d.ts +71 -0
  368. package/dist/sandbox/cli/contribution.js +8 -0
  369. package/dist/sandbox/cli/contribution.js.map +1 -0
  370. package/dist/sandbox/cli-commands.cjs +14 -21
  371. package/dist/sandbox/cli-commands.cjs.map +1 -1
  372. package/dist/sandbox/cli-commands.d.cts +12 -8
  373. package/dist/sandbox/cli-commands.d.mts +12 -8
  374. package/dist/sandbox/cli-commands.d.ts +12 -8
  375. package/dist/sandbox/compose.cjs +22 -2
  376. package/dist/sandbox/compose.cjs.map +1 -1
  377. package/dist/sandbox/compose.d.cts +1 -1
  378. package/dist/sandbox/compose.d.mts +1 -1
  379. package/dist/sandbox/compose.d.ts +1 -1
  380. package/dist/sandbox/docker-profile/cli.cjs +13 -9
  381. package/dist/sandbox/docker-profile/cli.cjs.map +1 -1
  382. package/dist/sandbox/docker-profile/cli.d.cts +2 -0
  383. package/dist/sandbox/docker-profile/cli.d.mts +2 -0
  384. package/dist/sandbox/docker-profile/cli.d.ts +2 -0
  385. package/dist/sandbox/docker-profile/runtime.cjs +68 -7
  386. package/dist/sandbox/docker-profile/runtime.cjs.map +1 -1
  387. package/dist/sandbox/docker-profile/runtime.d.cts +19 -1
  388. package/dist/sandbox/docker-profile/runtime.d.mts +19 -1
  389. package/dist/sandbox/docker-profile/runtime.d.ts +19 -1
  390. package/dist/sandbox/docker-profile/runtime.js +10 -8
  391. package/dist/sandbox/docker-profile/schema.cjs +68 -19
  392. package/dist/sandbox/docker-profile/schema.cjs.map +1 -1
  393. package/dist/sandbox/docker-profile/schema.d.cts +23 -9
  394. package/dist/sandbox/docker-profile/schema.d.mts +23 -9
  395. package/dist/sandbox/docker-profile/schema.d.ts +23 -9
  396. package/dist/sandbox/docker-task-build-cache.cjs +532 -0
  397. package/dist/sandbox/docker-task-build-cache.cjs.map +1 -0
  398. package/dist/sandbox/docker-task-build-cache.d.cts +68 -0
  399. package/dist/sandbox/docker-task-build-cache.d.mts +68 -0
  400. package/dist/sandbox/docker-task-build-cache.d.ts +68 -0
  401. package/dist/sandbox/docker-task-build-cache.js +20 -0
  402. package/dist/sandbox/docker-task-build-cache.js.map +1 -0
  403. package/dist/sandbox/docker.cjs +50 -0
  404. package/dist/sandbox/docker.cjs.map +1 -1
  405. package/dist/sandbox/docker.d.cts +15 -0
  406. package/dist/sandbox/docker.d.mts +15 -0
  407. package/dist/sandbox/docker.d.ts +15 -0
  408. package/dist/sandbox/dockerfile-build.cjs +55 -5
  409. package/dist/sandbox/dockerfile-build.cjs.map +1 -1
  410. package/dist/sandbox/dockerfile-build.d.cts +2 -2
  411. package/dist/sandbox/dockerfile-build.d.mts +2 -2
  412. package/dist/sandbox/dockerfile-build.d.ts +2 -2
  413. package/dist/sandbox/index.cjs +5 -3
  414. package/dist/sandbox/index.cjs.map +1 -1
  415. package/dist/sandbox/index.d.cts +4 -3
  416. package/dist/sandbox/index.d.mts +4 -3
  417. package/dist/sandbox/index.d.ts +4 -3
  418. package/dist/sandbox/index.js +16 -14
  419. package/dist/sandbox/index.mjs +16 -14
  420. package/dist/sandbox/keep.cjs +1 -3
  421. package/dist/sandbox/keep.cjs.map +1 -1
  422. package/dist/sandbox/layer.cjs +70 -79
  423. package/dist/sandbox/layer.cjs.map +1 -1
  424. package/dist/sandbox/layer.d.cts +6 -12
  425. package/dist/sandbox/layer.d.mts +6 -12
  426. package/dist/sandbox/layer.d.ts +6 -12
  427. package/dist/sandbox/layer.js +16 -18
  428. package/dist/sandbox/ledger-paths.cjs +4 -18
  429. package/dist/sandbox/ledger-paths.cjs.map +1 -1
  430. package/dist/sandbox/ledger-paths.d.cts +3 -13
  431. package/dist/sandbox/ledger-paths.d.mts +3 -13
  432. package/dist/sandbox/ledger-paths.d.ts +3 -13
  433. package/dist/sandbox/ledger-paths.js +4 -8
  434. package/dist/sandbox/registry.cjs +1 -1
  435. package/dist/sandbox/registry.cjs.map +1 -1
  436. package/dist/sandbox/runtime.cjs +27 -37
  437. package/dist/sandbox/runtime.cjs.map +1 -1
  438. package/dist/sandbox/runtime.d.cts +1 -2
  439. package/dist/sandbox/runtime.d.mts +1 -2
  440. package/dist/sandbox/runtime.d.ts +1 -2
  441. package/dist/sandbox/runtime.js +6 -8
  442. package/dist/sandbox/types.cjs.map +1 -1
  443. package/dist/sandbox/types.d.cts +3 -3
  444. package/dist/sandbox/types.d.mts +3 -3
  445. package/dist/sandbox/types.d.ts +3 -3
  446. package/dist/sources/project.json +6 -0
  447. package/dist/vendor/remark/remark-gfm.cjs +72 -72
  448. package/dist/vendor/remark/remark-gfm.cjs.map +1 -1
  449. package/dist/vendor/remark/remark-parse.cjs +54 -54
  450. package/dist/vendor/remark/remark-parse.cjs.map +1 -1
  451. package/dist/vendor/remark/remark.cjs +125 -125
  452. package/dist/vendor/remark/remark.cjs.map +2 -2
  453. package/docs-site/zh/README.md +1 -1
  454. package/docs-site/zh/explanation/assert.mdx +4 -0
  455. package/docs-site/zh/explanation/judge.mdx +40 -9
  456. package/docs-site/zh/reference/cli.mdx +67 -43
  457. package/docs-site/zh/reference/define-agent.mdx +2 -2
  458. package/docs-site/zh/reference/report-components.mdx +4 -3
  459. package/docs-site/zh/troubleshooting/debug-sandbox.mdx +6 -0
  460. package/docs-site/zh/troubleshooting/debugging.mdx +28 -1
  461. package/docs-site/zh/tutorials/agent-feedback-loop.mdx +4 -2
  462. package/docs-site/zh/tutorials/concurrency.mdx +2 -2
  463. package/docs-site/zh/tutorials/custom-reports.mdx +175 -9
  464. package/docs-site/zh/tutorials/docker-in-docker.mdx +52 -7
  465. package/docs-site/zh/tutorials/eval-groups.mdx +1 -2
  466. package/docs-site/zh/tutorials/evaluation-kinds.mdx +39 -6
  467. package/docs-site/zh/tutorials/nixos-managed-dind.mdx +14 -5
  468. package/docs-site/zh/tutorials/sandbox-providers.mdx +1 -28
  469. package/docs-site/zh/tutorials/sandbox-reuse.mdx +1 -1
  470. package/docs-site/zh/tutorials/viewing-results.mdx +2 -0
  471. package/package.json +24 -19
  472. package/README.md +0 -176
  473. package/README.zh.md +0 -176
  474. package/dist/cli/record.cjs +0 -246
  475. package/dist/cli/record.cjs.map +0 -1
  476. package/dist/cli/record.d.cts +0 -40
  477. package/dist/cli/record.d.mts +0 -40
  478. package/dist/cli/record.d.ts +0 -40
  479. package/dist/cli/record.js +0 -10
  480. package/dist/cli/record.js.map +0 -1
  481. package/dist/sandbox/local.cjs +0 -361
  482. package/dist/sandbox/local.cjs.map +0 -1
  483. package/dist/sandbox/local.d.cts +0 -80
  484. package/dist/sandbox/local.d.mts +0 -80
  485. package/dist/sandbox/local.d.ts +0 -80
  486. package/dist/sandbox/local.js +0 -6
  487. package/dist/sandbox/local.js.map +0 -1
@@ -32,6 +32,7 @@ const DEFAULT_TICK_INTERVAL_MS = 250;
32
32
  function createFeedbackCoordinator(options) {
33
33
  const { profile, renderer, io } = options;
34
34
  const onEvent = options.onEvent;
35
+ const shouldActivateSink = options.activateSink !== false;
35
36
  const tickIntervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS;
36
37
  let phase = "idle";
37
38
  let state = (0, reducer_ts_1.createInitialRunFeedbackState)();
@@ -263,21 +264,23 @@ function createFeedbackCoordinator(options) {
263
264
  }
264
265
  phase = "active";
265
266
  startedAtMs = io.clock.now();
266
- deactivate = (0, sink_ts_1.activateFeedbackSink)({
267
- activity,
268
- diagnostic,
269
- interrupted,
270
- reporterError,
271
- failure,
272
- budgetExhausted,
273
- kept,
274
- experimentHook,
275
- experimentProgress,
276
- precheck,
277
- lockWait,
278
- runActivity,
279
- lifecycle,
280
- });
267
+ if (shouldActivateSink) {
268
+ deactivate = (0, sink_ts_1.activateFeedbackSink)({
269
+ activity,
270
+ diagnostic,
271
+ interrupted,
272
+ reporterError,
273
+ failure,
274
+ budgetExhausted,
275
+ kept,
276
+ experimentHook,
277
+ experimentProgress,
278
+ precheck,
279
+ lockWait,
280
+ runActivity,
281
+ lifecycle,
282
+ });
283
+ }
281
284
  emit({ type: "plan", at: startedAtMs, plan });
282
285
  tickHandle = io.clock.setInterval(() => {
283
286
  if (phase !== "active")
@@ -1 +1 @@
1
- {"version":3,"file":"coordinator.js","sourceRoot":"","sources":["coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["// FeedbackCoordinator:一个 run 内唯一的终端协调者(见 docs/feature/experiments/cli.md\n// 「输出流和落盘节奏」与 plan 第 2 节「一个 run 内只有一个终端协调者」)。\n//\n// 职责边界:\n// - 维护 RunFeedbackState(纯 reducer,见 reducer.ts)——每次 emit() 后同步更新,\n// `coordinator.state` 永远读到最新值,不经过下面的异步队列。\n// - 把每个事件按「lifecycle / tick / durable」分派给当前 profile 的 FeedbackRenderer\n// (renderer.ts),并对 durable 事件保证 clearDynamic → appendDurable → redrawDynamic\n// 三步原子执行(内部单队列串行处理,不会被下一个事件插入打断)。\n// - 驱动 tick 定时器(周期性推进 elapsedMs、给 renderer 重画/heartbeat 判断的机会),\n// 在 stopDynamic() 时停止,停止后保证不再有 timer 驱动的重画。\n// - 通过 sink.ts 的活跃栈,成为底层模块(sandbox provider、budget 记账、reporter 兜底……)\n// 的统一诊断出口 —— start() 时激活自己,finish() 时退出。\n//\n// 不负责:\n// - 具体怎么画(ANSI dashboard 或 NDJSON 事件)—— 那是各 renderer 自己的事,\n// coordinator 只保证「什么时候、按什么顺序」调用 renderer。\n// - 从 runner 实际生命周期(sandbox provision / agent setup / …)推导 LifecyclePhase 并发出\n// attempt:start/phase/progress 事件 —— `attempt.ts` / `run.ts` 负责生产,coordinator 只消费。\n// - 在 cli.ts 里决定何时构造 coordinator、传哪个 renderer —— CLI 接线已经独立负责这件事。\nimport { createInitialRunFeedbackState, reduceRunFeedback } from \"./reducer.ts\";\nimport { activateFeedbackSink, type BudgetExhaustedInput, type DiagnosticInput, type ExperimentHookInput, type ExperimentProgressInput, type PrecheckInput, type LockWaitInput, type RunActivityInput, type FailureInput, type FeedbackSink, type KeptInput, } from \"./sink.ts\";\nimport type { FeedbackIO, FeedbackTimerHandle } from \"./io.ts\";\nimport type { FeedbackRenderer } from \"./renderer.ts\";\nimport { writeStderrLine } from \"../../tty-line.ts\";\nimport { t } from \"../../i18n/index.ts\";\nimport type { AttemptLifecycleEvent, DurableFeedbackEvent, FeedbackTickEvent, InvocationCompletion, InvocationReceipt, InvocationSummary, OutputProfile, RunFeedbackEvent, RunFeedbackPlan, RunFeedbackState, } from \"../types.ts\";\n/** 默认 tick 周期:250ms(每秒最多 4 次重画机会),对应 docs 里 human dashboard「最多每秒\n * 4 帧」的上限 —— coordinator 只保证「不超过这个频率的重画机会」,合并/节流到「真的要不要\n * 重画这一帧」由 renderer 自己判断(见 renderer.ts 的 onTick 注释)。 */\nconst DEFAULT_TICK_INTERVAL_MS = 250;\nexport interface FeedbackCoordinatorOptions {\n profile: OutputProfile;\n renderer: FeedbackRenderer;\n io: FeedbackIO;\n /** 覆盖默认 tick 周期;测试/未来某个 profile 需要更粗或更细的节奏时用。 */\n tickIntervalMs?: number;\n /** 观察同一份 reducer 事实的轻量索引(如 Experiment Session);观察者不得改变事件。 */\n onEvent?: (event: RunFeedbackEvent, state: RunFeedbackState) => void;\n}\nexport interface FeedbackCoordinator extends FeedbackSink {\n readonly profile: OutputProfile;\n /** 当前 reducer 状态快照;每次 emit() 后同步更新(不经过内部异步队列,读到的永远是\n * emit() 调用那一刻算出的最新值)。 */\n readonly state: RunFeedbackState;\n /**\n * invocation:start 等价物:emit 一次 \"plan\" 永久事件、把自己注册为 sink.ts 的活跃目的地(此后\n * `reportActivity`/`reportDiagnostic`/… 转发给它)、启动 tick 定时器。只能调用一次 ——\n * 重复调用是编程错误(意味着同一个 coordinator 实例被跨 run 复用),直接抛错。\n */\n start(plan: RunFeedbackPlan): void;\n /**\n * 任意 `RunFeedbackEvent` 的通用入口:lifecycle/tick/durable 都走这里。`diagnostic()`/\n * `activity()`/`interrupted()`/`reporterError()` 是构造 durable 事件的便捷封装,内部\n * 也调用这个方法,保证 typed lifecycle emitter 与 sink.ts 运行级出口\n * 共用同一套 reducer 更新与 renderer 分派逻辑。\n */\n emit(event: RunFeedbackEvent): void;\n /**\n * 键盘/终端自愈重绘的唯一入口(见 docs/feature/experiments/cli.md「键盘输入与画面自愈」):\n * 清除动态区域后立即整帧重绘,绕过 renderer 自己的「同帧不写」判断——`input-guard.ts` 收到\n * 回车或 SIGWINCH 时调用这个方法,而不是直接拿着 renderer 去调 clearDynamic/redrawDynamic:\n * 这里经内部 `queue` 排队执行,与正常永久事件的 clear→append→redraw 三步共用同一条串行队列,\n * 不会与它们交错写终端。只在 \"active\" 阶段(dashboard 存在)有意义;其它阶段静默 no-op。\n */\n forceRedraw(): void;\n /**\n * 关闭顺序第 1-2 步:停止 tick 定时器、清空 dynamic 区域(见 docs「明确 sink 关闭顺序」)。\n * 之后 `diagnostic()`/`activity()` 仍可调用(reporter 收尾阶段可能还有诊断要报),但不会\n * 再触发 clearDynamic/redrawDynamic —— 只是纯追加,不会有 timer 再驱动一次重画。幂等:\n * 重复调用只有第一次生效。\n */\n stopDynamic(): Promise<void>;\n /**\n * 关闭顺序最后一步:确保 stopDynamic() 已执行,追加 \"summary\"/\"receipt\" 两个永久事件,\n * 排空内部队列,通知 `renderer.close()`,并把自己从 sink.ts 的活跃栈里摘下(之后\n * `reportActivity()` 等调用会落回 bootstrap 兜底)。resolve 后保证不会再有任何 timer 或\n * 排队任务写终端 —— 调用方(CLI 接线阶段)应在这一步之前完成全部 reporter 收尾\n * (`onInvocationComplete` 等),让 reporter 收尾期间产生的诊断仍能走 stopDynamic() 之后的\n * 纯追加路径,而不是彻底没有出口。\n */\n finish(input: {\n summary: InvocationSummary;\n completion: InvocationCompletion;\n receipt: InvocationReceipt;\n }): Promise<void>;\n}\ntype Phase = \"idle\" | \"active\" | \"dynamicStopped\" | \"finished\";\nexport function createFeedbackCoordinator(options: FeedbackCoordinatorOptions): FeedbackCoordinator {\n const { profile, renderer, io } = options;\n const onEvent = options.onEvent;\n const tickIntervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS;\n let phase: Phase = \"idle\";\n let state: RunFeedbackState = createInitialRunFeedbackState();\n let startedAtMs = 0;\n let tickHandle: FeedbackTimerHandle | undefined;\n let deactivate: (() => void) | undefined;\n const queue = new SerialQueue();\n function guardWritable(): boolean {\n if (phase === \"idle\") {\n throw new Error(\"FeedbackCoordinator: cannot report before start() has been called.\");\n }\n return phase !== \"finished\";\n }\n function emit(event: RunFeedbackEvent): void {\n if (!guardWritable())\n return;\n // dynamic 区域是否该围着这次投递做 clear/redraw,由「emit() 被调用那一刻」的 phase 决定,\n // 不是「排队任务真正执行那一刻」—— 队列是异步的,stopDynamic() 可能在这次投递已经入队、\n // 但还没轮到执行之前就同步翻转 phase。若在任务体内才读 phase,会让「stopDynamic() 调用\n // 前就已经合法入队」的 clear/redraw 被事后取消,产生「明明还在 active 阶段发生的事件,\n // 却因为收尾快了一步而丢了动态区域重建」的错误行为。这里同步捕获、随事件一起传下去,\n // 让「这次投递该不该有动态区域包裹」在入队瞬间就已经确定,不受后续 phase 变化影响。\n const bracket = phase === \"active\";\n state = reduceRunFeedback(state, event);\n try {\n onEvent?.(event, state);\n }\n catch (e) {\n // Session/索引观察者不是反馈主链;观察者故障不能改变运行结果或阻断 renderer。\n writeStderrLine(`feedback observer error: ${e instanceof Error ? e.message : String(e)}\\n`);\n }\n const run = state;\n switch (event.type) {\n case \"attempt:queued\":\n case \"attempt:start\":\n case \"attempt:phase\":\n case \"attempt:progress\":\n case \"attempt:complete\":\n case \"attempt:early-exit\":\n queue.push(() => renderer.onLifecycle?.(event, run));\n return;\n case \"experiment:progress\":\n // 短命状态,只进 reducer(上面已更新 state.experimentHooks 的 detail);下一次 tick 的\n // 重画会读到新值,不为每条 progress 单独排一次渲染任务。\n return;\n case \"tick\":\n queue.push(() => renderer.onTick?.(event, run));\n return;\n default: {\n // 穷尽性检查:剩下的只能是 DurableFeedbackEvent 的某个变体。新增 lifecycle/tick 事件\n // 类型时,这里会在编译期报错提醒补上对应 case —— 不会被无声地误分类成 durable\n // 并因此错误地触发 clearDynamic/redrawDynamic。反过来,新增 DurableFeedbackEvent\n // 的变体不需要动这个 switch(default 分支天然覆盖)。\n const durable: DurableFeedbackEvent = event;\n queue.push(() => deliverDurable(durable, run, bracket));\n return;\n }\n }\n }\n async function deliverDurable(event: DurableFeedbackEvent, run: RunFeedbackState, bracket: boolean): Promise<void> {\n try {\n if (bracket)\n await renderer.clearDynamic?.();\n await renderer.appendDurable(event, run);\n if (bracket)\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, event.type, fallbackTextFor(event));\n }\n }\n function forceRedraw(): void {\n if (phase !== \"active\")\n return; // 没有活跃 dashboard 可重绘(idle/dynamicStopped/finished)\n const run = state;\n queue.push(async () => {\n try {\n await renderer.clearDynamic?.();\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, \"forceRedraw\", undefined);\n }\n });\n }\n function activity(text: string): void {\n if (!guardWritable())\n return;\n const bracket = phase === \"active\"; // 同上,入队瞬间捕获。\n const run = state;\n queue.push(async () => {\n try {\n if (bracket)\n await renderer.clearDynamic?.();\n await renderer.activity?.(text, run);\n if (bracket)\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, \"activity\", text);\n }\n });\n }\n function diagnostic(input: DiagnosticInput): void {\n emit({\n type: \"diagnostic\",\n at: io.clock.now(),\n key: input.key,\n ...(input.code !== undefined ? { code: input.code } : {}),\n severity: input.severity,\n message: input.message,\n identity: input.identity,\n data: input.data,\n });\n }\n function interrupted(): void {\n emit({ type: \"interrupted\", at: io.clock.now() });\n }\n function failure(input: FailureInput): void {\n emit({\n type: \"failure\",\n at: io.clock.now(),\n locator: input.locator,\n identity: input.identity,\n who: input.who,\n verdict: input.verdict,\n reason: input.reason,\n ...(input.fact !== undefined ? { fact: input.fact } : {}),\n ...(input.phase !== undefined ? { phase: input.phase } : {}),\n ...(input.code !== undefined ? { code: input.code } : {}),\n ...(input.origin !== undefined ? { origin: input.origin } : {}),\n });\n }\n function kept(input: KeptInput): void {\n emit({\n type: \"kept\",\n at: io.clock.now(),\n locator: input.locator,\n identity: input.identity,\n who: input.who,\n verdict: input.verdict,\n provider: input.provider,\n sandboxId: input.sandboxId,\n ...(input.enter !== undefined ? { enter: input.enter } : {}),\n });\n }\n function budgetExhausted(input: BudgetExhaustedInput): void {\n emit({\n type: \"budget-exhausted\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n spent: input.spent,\n unstarted: input.unstarted,\n });\n }\n function experimentHook(input: ExperimentHookInput): void {\n emit({\n type: \"experiment-hook\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n hook: input.hook,\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n ...(input.recovery !== undefined ? { recovery: input.recovery } : {}),\n });\n }\n function experimentProgress(input: ExperimentProgressInput): void {\n emit({ type: \"experiment:progress\", at: io.clock.now(), experimentId: input.experimentId, detail: input.detail });\n }\n function precheck(input: PrecheckInput): void {\n emit({\n type: \"precheck\",\n at: io.clock.now(),\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n });\n }\n function lockWait(input: LockWaitInput): void {\n emit({\n type: \"lock-wait\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n evalId: input.evalId,\n status: input.status,\n ...(input.holderPid !== undefined ? { holderPid: input.holderPid } : {}),\n ...(input.holderHost !== undefined ? { holderHost: input.holderHost } : {}),\n ...(input.attempts !== undefined ? { attempts: input.attempts } : {}),\n ...(input.carried !== undefined ? { carried: input.carried } : {}),\n ...(input.dispatched !== undefined ? { dispatched: input.dispatched } : {}),\n ...(input.waitedMs !== undefined ? { waitedMs: input.waitedMs } : {}),\n });\n }\n function runActivity(input: RunActivityInput): void {\n emit({\n type: \"run-activity\",\n at: io.clock.now(),\n id: input.id,\n key: input.key,\n label: input.label,\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n });\n }\n function reporterError(input: {\n reporter: string;\n required: boolean;\n message: string;\n }): void {\n emit({\n type: \"reporter-error\",\n at: io.clock.now(),\n reporter: input.reporter,\n required: input.required,\n message: input.message,\n });\n }\n /** `FeedbackSink.lifecycle` 实现:`emit` 已经穷尽处理 `AttemptLifecycleEvent`(见上面的\n * switch),这里只是把 sink.ts 的窄接口对上同一个入口 —— 不是第二套分派逻辑。 */\n function lifecycle(event: AttemptLifecycleEvent): void {\n emit(event);\n }\n function onRendererError(e: unknown, context: string, fallbackMessage: string | undefined): void {\n const detail = e instanceof Error ? e.message : String(e);\n // renderer 自己崩了:这是「feedback sink 自己」的兜底出口,允许保留裸写(见 docs 的\n // 「删除与搜索验收」允许清单)—— 没有更下层的 coordinator 可以再兜一次。\n writeStderrLine(t(\"feedback.rendererError\", { context, message: detail }));\n if (fallbackMessage)\n writeStderrLine(` · ${fallbackMessage}\\n`);\n }\n function start(plan: RunFeedbackPlan): void {\n if (phase !== \"idle\") {\n throw new Error(\"FeedbackCoordinator: start() called more than once.\");\n }\n phase = \"active\";\n startedAtMs = io.clock.now();\n deactivate = activateFeedbackSink({\n activity,\n diagnostic,\n interrupted,\n reporterError,\n failure,\n budgetExhausted,\n kept,\n experimentHook,\n experimentProgress,\n precheck,\n lockWait,\n runActivity,\n lifecycle,\n });\n emit({ type: \"plan\", at: startedAtMs, plan });\n tickHandle = io.clock.setInterval(() => {\n if (phase !== \"active\")\n return;\n const now = io.clock.now();\n emit({ type: \"tick\", at: now, elapsedMs: now - startedAtMs });\n }, tickIntervalMs);\n }\n async function stopDynamic(): Promise<void> {\n if (phase === \"idle\") {\n throw new Error(\"FeedbackCoordinator: stopDynamic() called before start().\");\n }\n if (phase !== \"active\")\n return; // 已经 stopDynamic 过(dynamicStopped)或已 finish,幂等\n phase = \"dynamicStopped\";\n if (tickHandle !== undefined) {\n io.clock.clearInterval(tickHandle);\n tickHandle = undefined;\n }\n // 无条件再清一次:即便前面某个仍在队列里的任务已经清过,重复调用 clearDynamic 必须安全\n // (renderer.ts 对它的幂等性有明确要求)。这一步保证「不管前面发生了什么交错,收尾时\n // dynamic 区域一定是空的」。\n queue.push(() => renderer.clearDynamic?.());\n await queue.drain();\n }\n async function finish(input: {\n summary: InvocationSummary;\n completion: InvocationCompletion;\n receipt: InvocationReceipt;\n }): Promise<void> {\n if (phase === \"finished\")\n return; // 幂等\n await stopDynamic();\n emit({ type: \"summary\", at: io.clock.now(), summary: input.summary, completion: input.completion });\n emit({ type: \"receipt\", at: io.clock.now(), receipt: input.receipt });\n await queue.drain();\n try {\n await renderer.close?.();\n }\n catch (e) {\n onRendererError(e, \"close\", undefined);\n }\n phase = \"finished\";\n deactivate?.();\n deactivate = undefined;\n }\n return {\n profile,\n get state() {\n return state;\n },\n start,\n emit,\n forceRedraw,\n activity,\n diagnostic,\n interrupted,\n reporterError,\n failure,\n budgetExhausted,\n kept,\n experimentHook,\n experimentProgress,\n precheck,\n lockWait,\n runActivity,\n lifecycle,\n stopDynamic,\n finish,\n };\n}\n/** 渲染失败时的兜底文本 —— 保证一条真正的失败/诊断证据不会因为 renderer 自己抛错而彻底\n * 消失。\"plan\"/\"summary\"/\"receipt\" 不需要兜底文本:它们描述的信息在 RunFeedbackState / 落盘\n * 结果里仍然完整,renderer 崩溃只是丢了这一次的终端展示,不是丢了数据本身。 */\nfunction fallbackTextFor(event: DurableFeedbackEvent): string | undefined {\n switch (event.type) {\n case \"failure\":\n return `${event.who} ${event.verdict}: ${event.reason}`;\n case \"diagnostic\":\n return event.message;\n case \"budget-exhausted\":\n return `budget exhausted for ${event.experimentId} (spent ${event.spent}, unstarted ${event.unstarted})`;\n case \"interrupted\":\n return \"run interrupted\";\n case \"reporter-error\":\n return `reporter \"${event.reporter}\" failed: ${event.message}`;\n case \"plan\":\n case \"summary\":\n case \"receipt\":\n case \"experiment-hook\":\n case \"precheck\":\n case \"lock-wait\":\n case \"kept\":\n case \"run-activity\":\n // 钩子/预检/锁等待起止都不是失败证据:setup 失败与预检失败的每条 attempt 都另有\n // \"failure\" 事件兜底,锁等待解决与否不改变任何 verdict——\n // renderer 崩溃丢一行起止不丢数据。kept 与 Run activity 也另有 registry / timing 事实。\n return undefined;\n default: {\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n}\n/**\n * 一个先进先出的异步串行队列:保证一批 push() 进来的任务严格按顺序、一个跑完才跑下一个 ——\n * durable 事件的 clear→append→redraw 三步,以及跨多个事件的整体顺序,都靠它保证原子性,\n * 不需要每个调用方自己加锁。单个任务抛错不会让队列卡死(catch 后继续跑下一个)—— 各调用方\n * (deliverDurable/activity)已经各自兜错,这里的 catch 只是双保险,防止兜底逻辑本身的\n * bug poison 掉整条链。\n */\nclass SerialQueue {\n private tail: Promise<void> = Promise.resolve();\n push(task: () => void | Promise<void>): void {\n this.tail = this.tail.then(async () => {\n try {\n await task();\n }\n catch {\n // 见类内注释:双保险,不应该正常触发。\n }\n });\n }\n async drain(): Promise<void> {\n await this.tail;\n }\n}\n"]}
1
+ {"version":3,"file":"coordinator.js","sourceRoot":"","sources":["coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["// FeedbackCoordinator:一个 run 内唯一的终端协调者(见 docs/feature/experiments/cli.md\n// 「输出流和落盘节奏」与 plan 第 2 节「一个 run 内只有一个终端协调者」)。\n//\n// 职责边界:\n// - 维护 RunFeedbackState(纯 reducer,见 reducer.ts)——每次 emit() 后同步更新,\n// `coordinator.state` 永远读到最新值,不经过下面的异步队列。\n// - 把每个事件按「lifecycle / tick / durable」分派给当前 profile 的 FeedbackRenderer\n// (renderer.ts),并对 durable 事件保证 clearDynamic → appendDurable → redrawDynamic\n// 三步原子执行(内部单队列串行处理,不会被下一个事件插入打断)。\n// - 驱动 tick 定时器(周期性推进 elapsedMs、给 renderer 重画/heartbeat 判断的机会),\n// 在 stopDynamic() 时停止,停止后保证不再有 timer 驱动的重画。\n// - 通过 sink.ts 的活跃栈,成为底层模块(sandbox provider、budget 记账、reporter 兜底……)\n// 的统一诊断出口 —— start() 时激活自己,finish() 时退出。\n//\n// 不负责:\n// - 具体怎么画(ANSI dashboard 或 NDJSON 事件)—— 那是各 renderer 自己的事,\n// coordinator 只保证「什么时候、按什么顺序」调用 renderer。\n// - 从 runner 实际生命周期(sandbox provision / agent setup / …)推导 LifecyclePhase 并发出\n// attempt:start/phase/progress 事件 —— `attempt.ts` / `run.ts` 负责生产,coordinator 只消费。\n// - 在 cli.ts 里决定何时构造 coordinator、传哪个 renderer —— CLI 接线已经独立负责这件事。\nimport { createInitialRunFeedbackState, reduceRunFeedback } from \"./reducer.ts\";\nimport { activateFeedbackSink, type BudgetExhaustedInput, type DiagnosticInput, type ExperimentHookInput, type ExperimentProgressInput, type PrecheckInput, type LockWaitInput, type RunActivityInput, type FailureInput, type FeedbackSink, type KeptInput, } from \"./sink.ts\";\nimport type { FeedbackIO, FeedbackTimerHandle } from \"./io.ts\";\nimport type { FeedbackRenderer } from \"./renderer.ts\";\nimport { writeStderrLine } from \"../../tty-line.ts\";\nimport { t } from \"../../i18n/index.ts\";\nimport type { AttemptLifecycleEvent, DurableFeedbackEvent, FeedbackTickEvent, InvocationCompletion, InvocationReceipt, InvocationSummary, OutputProfile, RunFeedbackEvent, RunFeedbackPlan, RunFeedbackState, } from \"../types.ts\";\n/** 默认 tick 周期:250ms(每秒最多 4 次重画机会),对应 docs 里 human dashboard「最多每秒\n * 4 帧」的上限 —— coordinator 只保证「不超过这个频率的重画机会」,合并/节流到「真的要不要\n * 重画这一帧」由 renderer 自己判断(见 renderer.ts 的 onTick 注释)。 */\nconst DEFAULT_TICK_INTERVAL_MS = 250;\nexport interface FeedbackCoordinatorOptions {\n profile: OutputProfile;\n renderer: FeedbackRenderer;\n io: FeedbackIO;\n /** 覆盖默认 tick 周期;测试/未来某个 profile 需要更粗或更细的节奏时用。 */\n tickIntervalMs?: number;\n /** 观察同一份 reducer 事实的轻量索引(如 Experiment Session);观察者不得改变事件。 */\n onEvent?: (event: RunFeedbackEvent, state: RunFeedbackState) => void;\n /**\n * The default coordinator installs itself as the active Runner sink. A Host\n * that must multiplex the same lossless events to another lifecycle owner\n * can disable that registration and install the wrapper itself.\n */\n activateSink?: boolean;\n}\nexport interface FeedbackCoordinator extends FeedbackSink {\n readonly profile: OutputProfile;\n /** 当前 reducer 状态快照;每次 emit() 后同步更新(不经过内部异步队列,读到的永远是\n * emit() 调用那一刻算出的最新值)。 */\n readonly state: RunFeedbackState;\n /**\n * invocation:start 等价物:emit 一次 \"plan\" 永久事件、把自己注册为 sink.ts 的活跃目的地(此后\n * `reportActivity`/`reportDiagnostic`/… 转发给它)、启动 tick 定时器。只能调用一次 ——\n * 重复调用是编程错误(意味着同一个 coordinator 实例被跨 run 复用),直接抛错。\n */\n start(plan: RunFeedbackPlan): void;\n /**\n * 任意 `RunFeedbackEvent` 的通用入口:lifecycle/tick/durable 都走这里。`diagnostic()`/\n * `activity()`/`interrupted()`/`reporterError()` 是构造 durable 事件的便捷封装,内部\n * 也调用这个方法,保证 typed lifecycle emitter 与 sink.ts 运行级出口\n * 共用同一套 reducer 更新与 renderer 分派逻辑。\n */\n emit(event: RunFeedbackEvent): void;\n /**\n * 键盘/终端自愈重绘的唯一入口(见 docs/feature/experiments/cli.md「键盘输入与画面自愈」):\n * 清除动态区域后立即整帧重绘,绕过 renderer 自己的「同帧不写」判断——`input-guard.ts` 收到\n * 回车或 SIGWINCH 时调用这个方法,而不是直接拿着 renderer 去调 clearDynamic/redrawDynamic:\n * 这里经内部 `queue` 排队执行,与正常永久事件的 clear→append→redraw 三步共用同一条串行队列,\n * 不会与它们交错写终端。只在 \"active\" 阶段(dashboard 存在)有意义;其它阶段静默 no-op。\n */\n forceRedraw(): void;\n /**\n * 关闭顺序第 1-2 步:停止 tick 定时器、清空 dynamic 区域(见 docs「明确 sink 关闭顺序」)。\n * 之后 `diagnostic()`/`activity()` 仍可调用(reporter 收尾阶段可能还有诊断要报),但不会\n * 再触发 clearDynamic/redrawDynamic —— 只是纯追加,不会有 timer 再驱动一次重画。幂等:\n * 重复调用只有第一次生效。\n */\n stopDynamic(): Promise<void>;\n /**\n * 关闭顺序最后一步:确保 stopDynamic() 已执行,追加 \"summary\"/\"receipt\" 两个永久事件,\n * 排空内部队列,通知 `renderer.close()`,并把自己从 sink.ts 的活跃栈里摘下(之后\n * `reportActivity()` 等调用会落回 bootstrap 兜底)。resolve 后保证不会再有任何 timer 或\n * 排队任务写终端 —— 调用方(CLI 接线阶段)应在这一步之前完成全部 reporter 收尾\n * (`onInvocationComplete` 等),让 reporter 收尾期间产生的诊断仍能走 stopDynamic() 之后的\n * 纯追加路径,而不是彻底没有出口。\n */\n finish(input: {\n summary: InvocationSummary;\n completion: InvocationCompletion;\n receipt: InvocationReceipt;\n }): Promise<void>;\n}\ntype Phase = \"idle\" | \"active\" | \"dynamicStopped\" | \"finished\";\nexport function createFeedbackCoordinator(options: FeedbackCoordinatorOptions): FeedbackCoordinator {\n const { profile, renderer, io } = options;\n const onEvent = options.onEvent;\n const shouldActivateSink = options.activateSink !== false;\n const tickIntervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS;\n let phase: Phase = \"idle\";\n let state: RunFeedbackState = createInitialRunFeedbackState();\n let startedAtMs = 0;\n let tickHandle: FeedbackTimerHandle | undefined;\n let deactivate: (() => void) | undefined;\n const queue = new SerialQueue();\n function guardWritable(): boolean {\n if (phase === \"idle\") {\n throw new Error(\"FeedbackCoordinator: cannot report before start() has been called.\");\n }\n return phase !== \"finished\";\n }\n function emit(event: RunFeedbackEvent): void {\n if (!guardWritable())\n return;\n // dynamic 区域是否该围着这次投递做 clear/redraw,由「emit() 被调用那一刻」的 phase 决定,\n // 不是「排队任务真正执行那一刻」—— 队列是异步的,stopDynamic() 可能在这次投递已经入队、\n // 但还没轮到执行之前就同步翻转 phase。若在任务体内才读 phase,会让「stopDynamic() 调用\n // 前就已经合法入队」的 clear/redraw 被事后取消,产生「明明还在 active 阶段发生的事件,\n // 却因为收尾快了一步而丢了动态区域重建」的错误行为。这里同步捕获、随事件一起传下去,\n // 让「这次投递该不该有动态区域包裹」在入队瞬间就已经确定,不受后续 phase 变化影响。\n const bracket = phase === \"active\";\n state = reduceRunFeedback(state, event);\n try {\n onEvent?.(event, state);\n }\n catch (e) {\n // Session/索引观察者不是反馈主链;观察者故障不能改变运行结果或阻断 renderer。\n writeStderrLine(`feedback observer error: ${e instanceof Error ? e.message : String(e)}\\n`);\n }\n const run = state;\n switch (event.type) {\n case \"attempt:queued\":\n case \"attempt:start\":\n case \"attempt:phase\":\n case \"attempt:progress\":\n case \"attempt:complete\":\n case \"attempt:early-exit\":\n queue.push(() => renderer.onLifecycle?.(event, run));\n return;\n case \"experiment:progress\":\n // 短命状态,只进 reducer(上面已更新 state.experimentHooks 的 detail);下一次 tick 的\n // 重画会读到新值,不为每条 progress 单独排一次渲染任务。\n return;\n case \"tick\":\n queue.push(() => renderer.onTick?.(event, run));\n return;\n default: {\n // 穷尽性检查:剩下的只能是 DurableFeedbackEvent 的某个变体。新增 lifecycle/tick 事件\n // 类型时,这里会在编译期报错提醒补上对应 case —— 不会被无声地误分类成 durable\n // 并因此错误地触发 clearDynamic/redrawDynamic。反过来,新增 DurableFeedbackEvent\n // 的变体不需要动这个 switch(default 分支天然覆盖)。\n const durable: DurableFeedbackEvent = event;\n queue.push(() => deliverDurable(durable, run, bracket));\n return;\n }\n }\n }\n async function deliverDurable(event: DurableFeedbackEvent, run: RunFeedbackState, bracket: boolean): Promise<void> {\n try {\n if (bracket)\n await renderer.clearDynamic?.();\n await renderer.appendDurable(event, run);\n if (bracket)\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, event.type, fallbackTextFor(event));\n }\n }\n function forceRedraw(): void {\n if (phase !== \"active\")\n return; // 没有活跃 dashboard 可重绘(idle/dynamicStopped/finished)\n const run = state;\n queue.push(async () => {\n try {\n await renderer.clearDynamic?.();\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, \"forceRedraw\", undefined);\n }\n });\n }\n function activity(text: string): void {\n if (!guardWritable())\n return;\n const bracket = phase === \"active\"; // 同上,入队瞬间捕获。\n const run = state;\n queue.push(async () => {\n try {\n if (bracket)\n await renderer.clearDynamic?.();\n await renderer.activity?.(text, run);\n if (bracket)\n await renderer.redrawDynamic?.(run);\n }\n catch (e) {\n onRendererError(e, \"activity\", text);\n }\n });\n }\n function diagnostic(input: DiagnosticInput): void {\n emit({\n type: \"diagnostic\",\n at: io.clock.now(),\n key: input.key,\n ...(input.code !== undefined ? { code: input.code } : {}),\n severity: input.severity,\n message: input.message,\n identity: input.identity,\n data: input.data,\n });\n }\n function interrupted(): void {\n emit({ type: \"interrupted\", at: io.clock.now() });\n }\n function failure(input: FailureInput): void {\n emit({\n type: \"failure\",\n at: io.clock.now(),\n locator: input.locator,\n identity: input.identity,\n who: input.who,\n verdict: input.verdict,\n reason: input.reason,\n ...(input.fact !== undefined ? { fact: input.fact } : {}),\n ...(input.phase !== undefined ? { phase: input.phase } : {}),\n ...(input.code !== undefined ? { code: input.code } : {}),\n ...(input.origin !== undefined ? { origin: input.origin } : {}),\n });\n }\n function kept(input: KeptInput): void {\n emit({\n type: \"kept\",\n at: io.clock.now(),\n locator: input.locator,\n identity: input.identity,\n who: input.who,\n verdict: input.verdict,\n provider: input.provider,\n sandboxId: input.sandboxId,\n ...(input.enter !== undefined ? { enter: input.enter } : {}),\n });\n }\n function budgetExhausted(input: BudgetExhaustedInput): void {\n emit({\n type: \"budget-exhausted\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n spent: input.spent,\n unstarted: input.unstarted,\n });\n }\n function experimentHook(input: ExperimentHookInput): void {\n emit({\n type: \"experiment-hook\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n hook: input.hook,\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n ...(input.recovery !== undefined ? { recovery: input.recovery } : {}),\n });\n }\n function experimentProgress(input: ExperimentProgressInput): void {\n emit({ type: \"experiment:progress\", at: io.clock.now(), experimentId: input.experimentId, detail: input.detail });\n }\n function precheck(input: PrecheckInput): void {\n emit({\n type: \"precheck\",\n at: io.clock.now(),\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n });\n }\n function lockWait(input: LockWaitInput): void {\n emit({\n type: \"lock-wait\",\n at: io.clock.now(),\n experimentId: input.experimentId,\n evalId: input.evalId,\n status: input.status,\n ...(input.holderPid !== undefined ? { holderPid: input.holderPid } : {}),\n ...(input.holderHost !== undefined ? { holderHost: input.holderHost } : {}),\n ...(input.attempts !== undefined ? { attempts: input.attempts } : {}),\n ...(input.carried !== undefined ? { carried: input.carried } : {}),\n ...(input.dispatched !== undefined ? { dispatched: input.dispatched } : {}),\n ...(input.waitedMs !== undefined ? { waitedMs: input.waitedMs } : {}),\n });\n }\n function runActivity(input: RunActivityInput): void {\n emit({\n type: \"run-activity\",\n at: io.clock.now(),\n id: input.id,\n key: input.key,\n label: input.label,\n status: input.status,\n ...(input.durationMs !== undefined ? { durationMs: input.durationMs } : {}),\n });\n }\n function reporterError(input: {\n reporter: string;\n required: boolean;\n message: string;\n }): void {\n emit({\n type: \"reporter-error\",\n at: io.clock.now(),\n reporter: input.reporter,\n required: input.required,\n message: input.message,\n });\n }\n /** `FeedbackSink.lifecycle` 实现:`emit` 已经穷尽处理 `AttemptLifecycleEvent`(见上面的\n * switch),这里只是把 sink.ts 的窄接口对上同一个入口 —— 不是第二套分派逻辑。 */\n function lifecycle(event: AttemptLifecycleEvent): void {\n emit(event);\n }\n function onRendererError(e: unknown, context: string, fallbackMessage: string | undefined): void {\n const detail = e instanceof Error ? e.message : String(e);\n // renderer 自己崩了:这是「feedback sink 自己」的兜底出口,允许保留裸写(见 docs 的\n // 「删除与搜索验收」允许清单)—— 没有更下层的 coordinator 可以再兜一次。\n writeStderrLine(t(\"feedback.rendererError\", { context, message: detail }));\n if (fallbackMessage)\n writeStderrLine(` · ${fallbackMessage}\\n`);\n }\n function start(plan: RunFeedbackPlan): void {\n if (phase !== \"idle\") {\n throw new Error(\"FeedbackCoordinator: start() called more than once.\");\n }\n phase = \"active\";\n startedAtMs = io.clock.now();\n if (shouldActivateSink) {\n deactivate = activateFeedbackSink({\n activity,\n diagnostic,\n interrupted,\n reporterError,\n failure,\n budgetExhausted,\n kept,\n experimentHook,\n experimentProgress,\n precheck,\n lockWait,\n runActivity,\n lifecycle,\n });\n }\n emit({ type: \"plan\", at: startedAtMs, plan });\n tickHandle = io.clock.setInterval(() => {\n if (phase !== \"active\")\n return;\n const now = io.clock.now();\n emit({ type: \"tick\", at: now, elapsedMs: now - startedAtMs });\n }, tickIntervalMs);\n }\n async function stopDynamic(): Promise<void> {\n if (phase === \"idle\") {\n throw new Error(\"FeedbackCoordinator: stopDynamic() called before start().\");\n }\n if (phase !== \"active\")\n return; // 已经 stopDynamic 过(dynamicStopped)或已 finish,幂等\n phase = \"dynamicStopped\";\n if (tickHandle !== undefined) {\n io.clock.clearInterval(tickHandle);\n tickHandle = undefined;\n }\n // 无条件再清一次:即便前面某个仍在队列里的任务已经清过,重复调用 clearDynamic 必须安全\n // (renderer.ts 对它的幂等性有明确要求)。这一步保证「不管前面发生了什么交错,收尾时\n // dynamic 区域一定是空的」。\n queue.push(() => renderer.clearDynamic?.());\n await queue.drain();\n }\n async function finish(input: {\n summary: InvocationSummary;\n completion: InvocationCompletion;\n receipt: InvocationReceipt;\n }): Promise<void> {\n if (phase === \"finished\")\n return; // 幂等\n await stopDynamic();\n emit({ type: \"summary\", at: io.clock.now(), summary: input.summary, completion: input.completion });\n emit({ type: \"receipt\", at: io.clock.now(), receipt: input.receipt });\n await queue.drain();\n try {\n await renderer.close?.();\n }\n catch (e) {\n onRendererError(e, \"close\", undefined);\n }\n phase = \"finished\";\n deactivate?.();\n deactivate = undefined;\n }\n return {\n profile,\n get state() {\n return state;\n },\n start,\n emit,\n forceRedraw,\n activity,\n diagnostic,\n interrupted,\n reporterError,\n failure,\n budgetExhausted,\n kept,\n experimentHook,\n experimentProgress,\n precheck,\n lockWait,\n runActivity,\n lifecycle,\n stopDynamic,\n finish,\n };\n}\n/** 渲染失败时的兜底文本 —— 保证一条真正的失败/诊断证据不会因为 renderer 自己抛错而彻底\n * 消失。\"plan\"/\"summary\"/\"receipt\" 不需要兜底文本:它们描述的信息在 RunFeedbackState / 落盘\n * 结果里仍然完整,renderer 崩溃只是丢了这一次的终端展示,不是丢了数据本身。 */\nfunction fallbackTextFor(event: DurableFeedbackEvent): string | undefined {\n switch (event.type) {\n case \"failure\":\n return `${event.who} ${event.verdict}: ${event.reason}`;\n case \"diagnostic\":\n return event.message;\n case \"budget-exhausted\":\n return `budget exhausted for ${event.experimentId} (spent ${event.spent}, unstarted ${event.unstarted})`;\n case \"interrupted\":\n return \"run interrupted\";\n case \"reporter-error\":\n return `reporter \"${event.reporter}\" failed: ${event.message}`;\n case \"plan\":\n case \"summary\":\n case \"receipt\":\n case \"experiment-hook\":\n case \"precheck\":\n case \"lock-wait\":\n case \"kept\":\n case \"run-activity\":\n // 钩子/预检/锁等待起止都不是失败证据:setup 失败与预检失败的每条 attempt 都另有\n // \"failure\" 事件兜底,锁等待解决与否不改变任何 verdict——\n // renderer 崩溃丢一行起止不丢数据。kept 与 Run activity 也另有 registry / timing 事实。\n return undefined;\n default: {\n const exhaustive: never = event;\n return exhaustive;\n }\n }\n}\n/**\n * 一个先进先出的异步串行队列:保证一批 push() 进来的任务严格按顺序、一个跑完才跑下一个 ——\n * durable 事件的 clear→append→redraw 三步,以及跨多个事件的整体顺序,都靠它保证原子性,\n * 不需要每个调用方自己加锁。单个任务抛错不会让队列卡死(catch 后继续跑下一个)—— 各调用方\n * (deliverDurable/activity)已经各自兜错,这里的 catch 只是双保险,防止兜底逻辑本身的\n * bug poison 掉整条链。\n */\nclass SerialQueue {\n private tail: Promise<void> = Promise.resolve();\n push(task: () => void | Promise<void>): void {\n this.tail = this.tail.then(async () => {\n try {\n await task();\n }\n catch {\n // 见类内注释:双保险,不应该正常触发。\n }\n });\n }\n async drain(): Promise<void> {\n await this.tail;\n }\n}\n"]}
@@ -10,6 +10,12 @@ export interface FeedbackCoordinatorOptions {
10
10
  tickIntervalMs?: number;
11
11
  /** 观察同一份 reducer 事实的轻量索引(如 Experiment Session);观察者不得改变事件。 */
12
12
  onEvent?: (event: RunFeedbackEvent, state: RunFeedbackState) => void;
13
+ /**
14
+ * The default coordinator installs itself as the active Runner sink. A Host
15
+ * that must multiplex the same lossless events to another lifecycle owner
16
+ * can disable that registration and install the wrapper itself.
17
+ */
18
+ activateSink?: boolean;
13
19
  }
14
20
  export interface FeedbackCoordinator extends FeedbackSink {
15
21
  readonly profile: OutputProfile;
@@ -10,6 +10,12 @@ export interface FeedbackCoordinatorOptions {
10
10
  tickIntervalMs?: number;
11
11
  /** 观察同一份 reducer 事实的轻量索引(如 Experiment Session);观察者不得改变事件。 */
12
12
  onEvent?: (event: RunFeedbackEvent, state: RunFeedbackState) => void;
13
+ /**
14
+ * The default coordinator installs itself as the active Runner sink. A Host
15
+ * that must multiplex the same lossless events to another lifecycle owner
16
+ * can disable that registration and install the wrapper itself.
17
+ */
18
+ activateSink?: boolean;
13
19
  }
14
20
  export interface FeedbackCoordinator extends FeedbackSink {
15
21
  readonly profile: OutputProfile;
@@ -10,6 +10,12 @@ export interface FeedbackCoordinatorOptions {
10
10
  tickIntervalMs?: number;
11
11
  /** 观察同一份 reducer 事实的轻量索引(如 Experiment Session);观察者不得改变事件。 */
12
12
  onEvent?: (event: RunFeedbackEvent, state: RunFeedbackState) => void;
13
+ /**
14
+ * The default coordinator installs itself as the active Runner sink. A Host
15
+ * that must multiplex the same lossless events to another lifecycle owner
16
+ * can disable that registration and install the wrapper itself.
17
+ */
18
+ activateSink?: boolean;
13
19
  }
14
20
  export interface FeedbackCoordinator extends FeedbackSink {
15
21
  readonly profile: OutputProfile;
@@ -17,13 +17,9 @@ const backend_ts_1 = require("../sandbox/backend.cjs");
17
17
  const ledger_paths_ts_1 = require("../sandbox/ledger-paths.cjs");
18
18
  /**
19
19
  * ledger 的私有 git 目录:workdir 之外、runner 控制;agent 的工具默认不会去 /tmp 翻它。这是
20
- * 沙箱内 provider(docker/e2b/vercel)的默认值——每个实例都是全新隔离文件系统,固定路径不会
21
- * 跨实例踩踏。宿主本身即工作树的 provider(如 local)按 sandboxId 登记专属路径覆盖它
22
- * (见 sandbox/ledger-paths.ts),避免同机多次运行共享同一个 /tmp。
20
+ * 沙箱内 provider(docker/e2b/vercel)的固定值——每个实例都是全新隔离文件系统。
23
21
  */
24
22
  exports.LEDGER_GIT_DIR = ledger_paths_ts_1.DEFAULT_LEDGER_GIT_DIR;
25
- /** 整相导出文件的落点(与 ledger 同前缀,同样是 runner 私有路径;覆盖规则同上)。 */
26
- const EXPORT_DIR = "/tmp/.niceeval-ledger-export";
27
23
  /** 默认归因排除清单(锚点时冻结):依赖、构建产物、包管理器缓存与用户项目里的 .niceeval 记录目录。
28
24
  * 框架自己不往 workdir 写任何东西(见 docs/observability.md「宿主侧行为断言:t.o11y」),
29
25
  * 所以这里没有框架路径要排。 */
@@ -99,8 +95,6 @@ const EXPORT_MANIFEST_HEADER = "niceeval-ledger-export-parts v1";
99
95
  function buildExportScript(exportDir) {
100
96
  return [
101
97
  "set -eu",
102
- // shellQuote:多数 provider 的 exportDir 是固定字面量(无空格);local 的 exportDir 来自
103
- // mkdtemp(可能落在含空格的自定义 TMPDIR 下),赋值行不加引号会被 shell 拆成多个词。
104
98
  `D=${shellQuote(exportDir)}`,
105
99
  'rm -rf "$D" && mkdir -p "$D"',
106
100
  'OUT=$D/export.bin',
@@ -279,12 +273,8 @@ async function createChangeLedger(sandbox, opts) {
279
273
  const includes = canonicalPolicyEntries(opts?.include ?? [], "include");
280
274
  const ignored = canonicalPolicyEntries(opts?.ignore ?? [], "ignore");
281
275
  const excludes = [...DEFAULT_EXCLUDES, ...ignored];
282
- // 多数 provider 用固定的宿主内私有路径(每实例全新隔离文件系统,天然不冲突);宿主本身即
283
- // 工作树的 provider(如 local)按 sandboxId 登记专属路径,避免同机多次运行互相踩踏
284
- // (见 sandbox/ledger-paths.ts —— 这里不认 provider 名,只问登记表)。
285
- const paths = (0, ledger_paths_ts_1.ledgerPathsFor)(sandbox.sandboxId);
286
- const gitDir = paths?.gitDir ?? exports.LEDGER_GIT_DIR;
287
- const exportDir = paths?.exportDir ?? EXPORT_DIR;
276
+ const gitDir = exports.LEDGER_GIT_DIR;
277
+ const exportDir = ledger_paths_ts_1.DEFAULT_LEDGER_EXPORT_DIR;
288
278
  const env = gitEnv(sandbox, gitDir);
289
279
  const rootCommands = (0, backend_ts_1.sandboxSupportsRootCommands)(sandbox);
290
280
  // 只给 runner 私有 ledger 命令提权,以便读取题目故意设置的受限文件。脚本不 chmod/chown
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.js","sourceRoot":"","sources":["ledger.ts"],"names":[],"mappings":"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","sourcesContent":["// 变更分类账(私有 git ledger):回答「**agent** 改了什么」,不是「workspace 相对空目录变了什么」。\n// 契约见 docs/feature/sandbox/architecture.md「变更归因:send 窗口与分类账」:\n// - ledger 的 git 目录在沙箱内、workdir 外(runner 私有路径),以 workdir 为 work-tree——\n// workdir 保持素净:agent 看不到 runner 的 .git,eval 需要真实 git repo 时自己 git init,\n// agent 在 workdir 里的任何 git 操作都碰不到分类账。\n// - 三类 commit 时点:锚点一笔(workspace.baseline);每次 t.send() 进入前 workdir 有未记录\n// 变化就落一笔 eval 归因;t.send() 返回后落一笔 agent 归因(send 窗口内的全部变化)。\n// - 归因排除清单 runner 私有、锚点时冻结:项目自己的 .gitignore 不参与归因判断(add -f 绕过),\n// 排除靠 pathspec,include 显式打洞加回。\n// - agent 归因增量 = 逐窗口 delta 序列(DiffWindow[]),不做跨窗口压缩。\nimport { createHash } from \"node:crypto\";\nimport type { DiffArtifact, DiffWindow, Sandbox, WindowChange } from \"../types.ts\";\nimport type { AgentWorkspaceDiffPolicy } from \"../assertions/workspace-diff.ts\";\nimport { sandboxSupportsRootCommands } from \"../sandbox/backend.ts\";\nimport { DEFAULT_LEDGER_GIT_DIR, ledgerPathsFor } from \"../sandbox/ledger-paths.ts\";\n/**\n * ledger 的私有 git 目录:workdir 之外、runner 控制;agent 的工具默认不会去 /tmp 翻它。这是\n * 沙箱内 provider(docker/e2b/vercel)的默认值——每个实例都是全新隔离文件系统,固定路径不会\n * 跨实例踩踏。宿主本身即工作树的 provider(如 local)按 sandboxId 登记专属路径覆盖它\n * (见 sandbox/ledger-paths.ts),避免同机多次运行共享同一个 /tmp。\n */\nexport const LEDGER_GIT_DIR = DEFAULT_LEDGER_GIT_DIR;\n/** 整相导出文件的落点(与 ledger 同前缀,同样是 runner 私有路径;覆盖规则同上)。 */\nconst EXPORT_DIR = \"/tmp/.niceeval-ledger-export\";\n/** 默认归因排除清单(锚点时冻结):依赖、构建产物、包管理器缓存与用户项目里的 .niceeval 记录目录。\n * 框架自己不往 workdir 写任何东西(见 docs/observability.md「宿主侧行为断言:t.o11y」),\n * 所以这里没有框架路径要排。 */\nconst DEFAULT_EXCLUDES = [\n \".git\",\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \".turbo\",\n \".niceeval\",\n \"coverage\",\n \".cache\",\n \".pnpm-store\",\n \".npm\",\n \".yarn\",\n \"*venv*/\",\n \".venv\",\n \"__pycache__\",\n];\nconst MAX_POLICY_ENTRIES = 256;\nconst MAX_POLICY_ENTRY_UTF8_BYTES = 4096;\nconst policyEncoder = new TextEncoder();\nfunction compareAscii(left: string, right: string): number {\n return left === right ? 0 : left < right ? -1 : 1;\n}\n/** Reject an unrecordable policy before the collector starts, then freeze its canonical evidence form. */\nfunction canonicalPolicyEntries(entries: readonly string[], name: \"include\" | \"ignore\"): readonly string[] {\n if (entries.length > MAX_POLICY_ENTRIES) {\n throw new Error(`defineEval({ diff }).${name} may contain at most ${MAX_POLICY_ENTRIES} entries`);\n }\n for (const [index, entry] of entries.entries()) {\n if (typeof entry !== \"string\") {\n throw new TypeError(`defineEval({ diff }).${name}[${index}] must be a string`);\n }\n if (policyEncoder.encode(entry).byteLength > MAX_POLICY_ENTRY_UTF8_BYTES) {\n throw new Error(`defineEval({ diff }).${name}[${index}] exceeds ${MAX_POLICY_ENTRY_UTF8_BYTES} UTF-8 bytes`);\n }\n }\n return Object.freeze([...new Set(entries)].sort(compareAscii));\n}\n/**\n * 单个 send 窗口的导出扫描安全上限。File Changes 的 10,000-change durable 上限由 collector\n * 保留确定性前缀并写 collection-cap-reached;导出层必须先把更大的候选集合交给 collector,\n * 不能在同一个 10,000 边界提前把已知 partial 证据降格成 unavailable。\n * 字节预算只数**真正要传输的文本** before/after:二进制与超过单文件阈值的文本不内联内容、\n * 只记字节数(WindowChange.elided),因此不占预算——编译产物型窗口(成百上千个 .o 加几个大\n * 文本)不该因为「按尺寸计」被判越界。\n */\nconst MAX_EXPORTED_WINDOW_PATHS = 100000;\nconst MAX_EXPORTED_WINDOW_TEXT_BYTES = 256 * 1024 * 1024;\n/** 单个文本 blob 的内联阈值:任一侧超过它,该条目按二进制同款处理(记字节数、内容省略)。 */\nconst MAX_FILE_TEXT_BYTES = 1024 * 1024;\n/** Provider 文件 API 的单次安全读取边界,以及整次 Attempt 导出的硬上限。 */\nconst EXPORT_PART_BYTES = 4000000;\nconst MAX_EXPORT_BYTES = 512 * 1024 * 1024;\nconst MAX_EXPORT_PARTS = Math.ceil(MAX_EXPORT_BYTES / EXPORT_PART_BYTES);\nconst EXPORT_MANIFEST_HEADER = \"niceeval-ledger-export-parts v1\";\n/**\n * 整相导出:一条 POSIX shell 命令枚举**全部** agent 窗口并把证据写进沙箱内导出文件,宿主随后\n * 经文件通道一次下载——provider 往返数与窗口数、文件数都无关。对沙箱环境的全部要求是 git 与\n * POSIX 工具(sh/awk/wc/sort/grep),不依赖 node、python 等运行时。\n *\n * 沙箱内不组装 JSON:导出文件直接拼接 git 原生输出——每窗口四段,`diff-tree -z`(状态 + 前后\n * blob sha + 路径,NUL 安全)、`numstat -z`(二进制识别)、`cat-file --batch-check`(全部 blob\n * 尺寸)、`cat-file --batch`(要内联的文本 blob 内容,输出自带长度帧)——解析与校验全部在宿主侧完成。\n * 需要在沙箱内做的两个判断都不解析路径列:sha 提取用 awk 取 diff-tree 原始输出的第 3/4 列\n * (路径在其后,含空格也不影响);二进制排除靠 numstat 与 diff-tree 输出的行号对齐。\n * 尺寸核算(--batch-check)先于内容读取(--batch),越界在产出任何内容前失败;预算只累计真正\n * 要传输的文本 blob(二进制与单文件超限文本只出字节数,不进 --batch 请求、不计预算)。\n * 宿主侧从 sizes + numstat 两段就能判出哪些条目内容被省略,沙箱不额外输出一份判定清单。\n */\nfunction buildExportScript(exportDir: string): string {\n return [\n \"set -eu\",\n // shellQuote:多数 provider 的 exportDir 是固定字面量(无空格);local 的 exportDir 来自\n // mkdtemp(可能落在含空格的自定义 TMPDIR 下),赋值行不加引号会被 shell 拆成多个词。\n `D=${shellQuote(exportDir)}`,\n 'rm -rf \"$D\" && mkdir -p \"$D\"',\n 'OUT=$D/export.bin',\n ': > \"$OUT\"',\n 'fail() { printf \"%s\\\\n\" \"$1\" >&2; exit 2; }',\n // 帧格式:`section <name> <bytes>` 头一行,后跟原始字节;长度前缀让内容里的任意字节都安全。\n 'emit() { printf \"section %s %s\\\\n\" \"$1\" \"$(($(wc -c < \"$2\")))\" >> \"$OUT\"; cat \"$2\" >> \"$OUT\"; }',\n 'git log --reverse --format=\"%H %s\" > \"$D/log.txt\"',\n \"while IFS= read -r line; do\",\n ' hash=${line%% *}',\n ' subject=${line#* }',\n ' case $subject in \"agent \"*) ;; *) continue ;; esac',\n ' label=${subject#agent }',\n // 非 -z 的 diff-tree 把特殊路径引号转义成单行,一行 = 一个条目:wc -l 即路径数,awk 列取 sha 不碰路径。\n ' git diff-tree -r --no-renames \"$hash^\" \"$hash\" > \"$D/dt.txt\"',\n ' n=$(($(wc -l < \"$D/dt.txt\")))',\n ` [ \"$n\" -le ${MAX_EXPORTED_WINDOW_PATHS} ] || fail \"niceeval diff window contains $n paths; export scan limit is ${MAX_EXPORTED_WINDOW_PATHS}; narrow defineEval({ diff }) include/ignore rules\"`,\n ' git diff-tree -r --no-renames --numstat \"$hash^\" \"$hash\" > \"$D/ns.txt\"',\n // 全部 blob 出现次数(before + after,零 sha = 无此侧,排除)→ 逐次尺寸核算。\n \" awk '$3 !~ /^0+$/ { print $3 } $4 !~ /^0+$/ { print $4 }' \\\"$D/dt.txt\\\" > \\\"$D/occ.txt\\\"\",\n ' git cat-file --batch-check < \"$D/occ.txt\" > \"$D/sizes.txt\"',\n ' if grep -q \" missing$\" \"$D/sizes.txt\"; then fail \"niceeval ledger export: blob object missing\"; fi',\n // 逐条目分类:numstat 第 1 列为 \"-\" 的行是二进制,按行号对齐标 B,其余标 T,后跟前后 blob sha。\n ' awk \\'NR==FNR { bin[FNR] = ($1 == \"-\"); next } { printf \"%s %s %s\\\\n\", (bin[FNR] ? \"B\" : \"T\"), $3, $4 }\\' \"$D/ns.txt\" \"$D/dt.txt\" > \"$D/entries.txt\"',\n // 要内联的文本 blob(去重):二进制条目与任一侧超过单文件阈值的文本条目都不请求内容,\n // 也不计入窗口预算——它们只出字节数(宿主据同一份 sizes 判成 elided)。\n ` awk -v LIMIT=${MAX_FILE_TEXT_BYTES} -v TOTAL=\"$D/total.txt\" 'NR==FNR { sz[$1] = $3; next } $1 == \"T\" { b = $2; a = $3; if (b !~ /^0+$/ && sz[b] > LIMIT) next; if (a !~ /^0+$/ && sz[a] > LIMIT) next; if (b !~ /^0+$/ && !(b in seen)) { seen[b] = 1; total += sz[b]; print b } if (a !~ /^0+$/ && !(a in seen)) { seen[a] = 1; total += sz[a]; print a } } END { print total+0 > TOTAL }' \"$D/sizes.txt\" \"$D/entries.txt\" > \"$D/text.txt\"`,\n ' bytes=$(cat \"$D/total.txt\")',\n ` [ \"$bytes\" -le ${MAX_EXPORTED_WINDOW_TEXT_BYTES} ] || fail \"niceeval diff window transfers $bytes text blob bytes; export scan limit is ${MAX_EXPORTED_WINDOW_TEXT_BYTES}; narrow defineEval({ diff }) include/ignore rules\"`,\n ' git cat-file --batch < \"$D/text.txt\" > \"$D/blobs.bin\"',\n ' git diff-tree -r --no-renames -z \"$hash^\" \"$hash\" > \"$D/dtz.bin\"',\n ' git diff-tree -r --no-renames --numstat -z \"$hash^\" \"$hash\" > \"$D/nsz.bin\"',\n ' printf \"window %s %s\\\\n\" \"$hash\" \"$label\" >> \"$OUT\"',\n ' emit difftree \"$D/dtz.bin\"',\n ' emit numstat \"$D/nsz.bin\"',\n ' emit sizes \"$D/sizes.txt\"',\n ' emit blobs \"$D/blobs.bin\"',\n 'done < \"$D/log.txt\"',\n // Provider 文件 API 可能拒绝超过 4 MiB 的单对象读取。这里按固定原始字节切片,并在最后\n // 原子发布 manifest;宿主只接受连续序号、精确长度和 Git blob checksum。\n 'total=$(($(wc -c < \"$OUT\")))',\n ` [ \"$total\" -le ${MAX_EXPORT_BYTES} ] || fail \"niceeval ledger export contains $total bytes; attempt export limit is ${MAX_EXPORT_BYTES}\"`,\n `parts=$(( (total + ${EXPORT_PART_BYTES} - 1) / ${EXPORT_PART_BYTES} ))`,\n ` [ \"$parts\" -le ${MAX_EXPORT_PARTS} ] || fail \"niceeval ledger export needs $parts parts; attempt part limit is ${MAX_EXPORT_PARTS}\"`,\n 'MANIFEST_TMP=$D/manifest.tmp',\n 'MANIFEST=$D/manifest.txt',\n `printf \"%s\\\\ntotal %s\\\\nparts %s\\\\n\" \"${EXPORT_MANIFEST_HEADER}\" \"$total\" \"$parts\" > \"$MANIFEST_TMP\"`,\n 'i=0',\n 'while [ \"$i\" -lt \"$parts\" ]; do',\n ' suffix=$(printf \"%06d\" \"$i\")',\n ' part=$D/export.part.$suffix',\n ` dd if=\"$OUT\" of=\"$part\" bs=${EXPORT_PART_BYTES} skip=\"$i\" count=1 2>/dev/null`,\n ' size=$(($(wc -c < \"$part\")))',\n ' oid=$(git hash-object --no-filters \"$part\")',\n ' printf \"part %s %s %s\\\\n\" \"$suffix\" \"$size\" \"$oid\" >> \"$MANIFEST_TMP\"',\n ' i=$((i + 1))',\n 'done',\n 'mv \"$MANIFEST_TMP\" \"$MANIFEST\"',\n 'rm -f \"$OUT\"',\n // root ledger commands may create private exports with a restrictive umask. These artifacts are\n // outside workdir and are deleted immediately after the provider file channel consumes them.\n 'chmod 0644 \"$MANIFEST\"',\n 'for part in \"$D\"/export.part.*; do [ -f \"$part\" ] || continue; chmod 0644 \"$part\"; done',\n ].join(\"\\n\");\n}\nexport interface ChangeLedger {\n /** send 进入前:workdir 有未记录变化就落一笔 eval 归因(fixture / setup / runCommand 副作用)。 */\n commitEvalWindow(label: string): Promise<void>;\n /** send 返回后:落一笔 agent 归因——这个 send 窗口内的全部 workspace 变化(无变化也落空窗口)。 */\n commitAgentWindow(label: string): Promise<void>;\n /** workspace.diff 阶段:从分类账导出每个 send 窗口自己的 before/after,按时序。 */\n exportWindows(): Promise<DiffArtifact>;\n /** 回到创建时的题间锚点,并保留归因排除清单排除的动态环境。 */\n resetToAnchor(): Promise<void>;\n /**\n * 建账时探测到的执行身份是否为 root(仅当 provider 支持 root ledger 命令时才探测得到,\n * 否则恒为 false)。sandboxReuse 复用池据此在实例进池前拒绝(见 docs/feature/sandbox/reuse.md);\n * `resetToAnchor()` 内的同款判断作纵深防御保留。\n */\n readonly rootExecutionIdentity: boolean;\n /** Frozen semantic identity consumed by the Attempt-owned diff Attachment. */\n readonly attribution: AgentWorkspaceDiffPolicy;\n}\ninterface LedgerOptions {\n /** defineEval({ diff }) 的归因调整:ignore 追加排除,include 打洞加回(优先级最高)。 */\n include?: string[];\n ignore?: string[];\n}\n/** 每条 git 命令都带上私有 GIT_DIR + workdir work-tree;项目/全局 gitignore 一律不参与。 */\nfunction gitEnv(sandbox: Sandbox, gitDir: string): globalThis.Record<string, string> {\n return {\n GIT_DIR: gitDir,\n GIT_WORK_TREE: sandbox.workdir,\n GIT_AUTHOR_NAME: \"niceeval\",\n GIT_AUTHOR_EMAIL: \"niceeval@localhost\",\n GIT_COMMITTER_NAME: \"niceeval\",\n GIT_COMMITTER_EMAIL: \"niceeval@localhost\",\n // Internal root Git must never consume configuration or hooks writable by the Agent.\n GIT_CONFIG_NOSYSTEM: \"1\",\n GIT_CONFIG_GLOBAL: \"/dev/null\",\n GIT_CONFIG_COUNT: \"1\",\n GIT_CONFIG_KEY_0: \"core.hooksPath\",\n GIT_CONFIG_VALUE_0: \"/dev/null\",\n GIT_TERMINAL_PROMPT: \"0\",\n HOME: \"/tmp\",\n };\n}\nfunction shellQuote(s: string): string {\n return `'${s.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n/**\n * Root Git can faithfully restore bytes but would otherwise recreate ordinary fixture files as root.\n * Keep a content-free metadata mirror inside the private (0700) ledger and reapply uid/gid/mode after\n * reset. The batched xargs loops preserve arbitrary Git path bytes without exposing objects to the Agent.\n */\nfunction captureBaselineMetadataScript(): string {\n return [\n 'META=\"$GIT_DIR/niceeval-baseline-metadata\"',\n 'rm -rf \"$META\" && mkdir -p \"$META/files\" \"$META/dirs\"',\n \"export META\",\n \"git ls-files -z | xargs -0 -n 100 sh -c '\",\n \" for p do\",\n ' src=\"$GIT_WORK_TREE/$p\"',\n ' ref=\"$META/files/$p\"',\n ' mkdir -p \"$(dirname \"$ref\")\" && : > \"$ref\"',\n ' owner=$(stat -c \"%u:%g\" \"$src\") && mode=$(stat -c \"%a\" \"$src\")',\n ' chown -h \"$owner\" \"$ref\" && chmod \"$mode\" \"$ref\"',\n ' d=$(dirname \"$p\")',\n ' while [ \"$d\" != \".\" ]; do',\n ' dref=\"$META/dirs/$d/.ref\"',\n ' if [ ! -e \"$dref\" ]; then',\n ' mkdir -p \"$(dirname \"$dref\")\" && : > \"$dref\"',\n ' downer=$(stat -c \"%u:%g\" \"$GIT_WORK_TREE/$d\") && dmode=$(stat -c \"%a\" \"$GIT_WORK_TREE/$d\")',\n ' chown \"$downer\" \"$dref\" && chmod \"$dmode\" \"$dref\"',\n \" fi\",\n ' d=$(dirname \"$d\")',\n \" done\",\n \" done\",\n \"' niceeval-meta\",\n // Agent and any background process share the ordinary sandbox uid. Keep both objects and the\n // metadata mirror root-private for the whole attempt; reset never opens this directory to that uid.\n 'chmod go-rwx \"$GIT_DIR\"',\n ].join(\"\\n\");\n}\nfunction restoreBaselineMetadataScript(): string {\n return [\n 'META=\"$GIT_DIR/niceeval-baseline-metadata\"',\n \"export META\",\n 'if [ -d \"$META/files\" ]; then',\n \" find \\\"$META/files\\\" -type f -print0 | xargs -0 -n 100 sh -c '\",\n \" for ref do\",\n ' p=${ref#\"$META/files/\"}',\n ' target=\"$GIT_WORK_TREE/$p\"',\n ' if [ -e \"$target\" ] || [ -L \"$target\" ]; then',\n ' owner=$(stat -c \"%u:%g\" \"$ref\") && mode=$(stat -c \"%a\" \"$ref\")',\n ' chown -h \"$owner\" \"$target\"',\n ' [ -L \"$target\" ] || chmod \"$mode\" \"$target\"',\n \" fi\",\n \" done\",\n \" ' niceeval-meta-restore\",\n \"fi\",\n // Apply directory metadata last so restrictive parent modes cannot interfere with child repair.\n 'if [ -d \"$META/dirs\" ]; then',\n \" find \\\"$META/dirs\\\" -type f -name .ref -print0 | xargs -0 -n 100 sh -c '\",\n \" for ref do\",\n ' d=${ref%/.ref}',\n ' p=${d#\"$META/dirs/\"}',\n ' target=\"$GIT_WORK_TREE/$p\"',\n ' if [ -d \"$target\" ]; then',\n ' owner=$(stat -c \"%u:%g\" \"$ref\") && mode=$(stat -c \"%a\" \"$ref\")',\n ' chown \"$owner\" \"$target\" && chmod \"$mode\" \"$target\"',\n \" fi\",\n \" done\",\n \" ' niceeval-dir-meta-restore\",\n \"fi\",\n 'chmod go-rwx \"$GIT_DIR\"',\n ].join(\"\\n\");\n}\n/**\n * 把仓库根语义的 gitignore 风格规则编译成 ledger pathspec。\n * 无斜杠的名字匹配任意深度;有斜杠的规则相对 workdir 根;目录本身与后代一起处理。\n */\nfunction gitignorePathspecs(pattern: string, exclude: boolean): string[] {\n let normalized = pattern;\n while (normalized.startsWith(\"./\"))\n normalized = normalized.slice(2);\n if (normalized.startsWith(\"/\"))\n normalized = normalized.slice(1);\n normalized = normalized.replace(/\\/+$/, \"\");\n if (!normalized)\n return [];\n const glob = normalized.includes(\"/\") ? normalized : `**/${normalized}`;\n const globs = exclude && !glob.endsWith(\"/**\") ? [glob, `${glob}/**`] : [glob];\n const magic = exclude ? \":(glob,exclude)\" : \":(glob)\";\n return [...new Set(globs)].map((value) => `${magic}${value}`);\n}\n/** 打分类账锚点(workspace.baseline 阶段,环境层钩子之后):git init + 冻结排除清单 + 首笔 commit。 */\nexport async function createChangeLedger(sandbox: Sandbox, opts?: LedgerOptions): Promise<ChangeLedger> {\n const includes = canonicalPolicyEntries(opts?.include ?? [], \"include\");\n const ignored = canonicalPolicyEntries(opts?.ignore ?? [], \"ignore\");\n const excludes = [...DEFAULT_EXCLUDES, ...ignored];\n // 多数 provider 用固定的宿主内私有路径(每实例全新隔离文件系统,天然不冲突);宿主本身即\n // 工作树的 provider(如 local)按 sandboxId 登记专属路径,避免同机多次运行互相踩踏\n // (见 sandbox/ledger-paths.ts —— 这里不认 provider 名,只问登记表)。\n const paths = ledgerPathsFor(sandbox.sandboxId);\n const gitDir = paths?.gitDir ?? LEDGER_GIT_DIR;\n const exportDir = paths?.exportDir ?? EXPORT_DIR;\n const env = gitEnv(sandbox, gitDir);\n const rootCommands = sandboxSupportsRootCommands(sandbox);\n // 只给 runner 私有 ledger 命令提权,以便读取题目故意设置的受限文件。脚本不 chmod/chown\n // workdir,Agent 命令仍沿标准非 root 身份;不支持提权的 provider 保持既有用户态路径。\n const commandOptions = rootCommands ? { env, user: \"root\" as const } : { env };\n const captureMetadata = rootCommands ? ` && ${captureBaselineMetadataScript()}` : \"\";\n const lockPrivateLedger = rootCommands ? ' && chmod go-rwx \"$GIT_DIR\"' : \"\";\n let ordinaryUid: string | undefined;\n if (rootCommands) {\n // Capture before Agent setup/send can mutate the VM. A post-attempt `id` probe would not be a\n // trustworthy boundary when the configured execution identity itself is root.\n const identity = await sandbox.runShell(\"command -p id -u\", { env });\n ensureCommandSucceeded(identity, \"detect sandbox execution identity for reuse\", false);\n ordinaryUid = identity.stdout.trim();\n }\n // add -A -f:绕过项目自己的 .gitignore(项目 ignore 的文件照常记录);排除靠 pathspec\n // (runner 私有清单,agent / fixture 写 .gitignore 影响不了它);include 用第二次 add 打洞加回。\n const excludeSpecs = excludes.flatMap((pattern) => gitignorePathspecs(pattern, true)).map(shellQuote).join(\" \");\n // include 打洞:路径此刻可能还不存在(如 agent 之后才写),unmatched pathspec 不算错。\n const includeSpecs = includes.flatMap((pattern) => gitignorePathspecs(pattern, false)).map(shellQuote).join(\" \");\n const includeAdd = includeSpecs.length > 0 ? ` && { git -c advice.addEmbeddedRepo=false add -A -f -- ${includeSpecs} 2>/dev/null || true; }` : \"\";\n const rejectGitlinks = \" && nested=$(git ls-files --stage | awk '$1 == \\\"160000\\\" { sub(/^[^\\\\t]*\\\\t/, \\\"\\\"); print; exit }')\" +\n ' && if [ -n \"$nested\" ]; then printf \\'%s\\\\n\\' \"niceeval ledger cannot track nested Git repository $nested as file-level evidence; move the checkout to sandbox.workdir root, or add the whole path to defineEval({ diff: { ignore: [...] } }) when it is intentionally out of scope\" >&2; exit 2; fi';\n const addAll = `git -c advice.addEmbeddedRepo=false add -A -f -- . ${excludeSpecs}${includeAdd}${rejectGitlinks}`;\n const anchor = await sandbox.runShell(\n // The path is predictable inside an isolated VM. Remove any image/prepare-time occupant or\n // symlink, then recreate the exact runner-private directory as root 0700 before Git touches it.\n `rm -rf -- ${shellQuote(gitDir)} && mkdir -p -m 0700 -- ${shellQuote(gitDir)} && ` +\n `git init -q \"${gitDir}\" && ${addAll} && git commit -q --allow-empty -m \"anchor\" && ` +\n `(git rev-parse -q --verify niceeval-reuse-anchor >/dev/null || git tag niceeval-reuse-anchor)` +\n captureMetadata, {\n ...commandOptions,\n });\n ensureCommandSucceeded(anchor, \"create change ledger anchor\", rootCommands);\n return {\n rootExecutionIdentity: ordinaryUid === \"0\",\n attribution: Object.freeze({\n defaultPolicy: \"niceeval.sandbox-ledger/default-excludes/v1\" as const,\n include: includes,\n ignore: ignored,\n }),\n async commitEvalWindow(label: string): Promise<void> {\n // 有未记录变化才落这一笔;干净时不产生空的 eval 归因 commit。\n const result = await sandbox.runShell(`${addAll} && (git diff --cached --quiet || git commit -q -m ${shellQuote(`eval ${label}`)})${lockPrivateLedger}`, {\n ...commandOptions,\n });\n ensureCommandSucceeded(result, `commit eval window ${label}`, rootCommands);\n },\n async commitAgentWindow(label: string): Promise<void> {\n // 窗口内没有变化时也落一条(--allow-empty),diff.json 里该窗口 changes 为空对象。\n const result = await sandbox.runShell(`${addAll} && git commit -q --allow-empty -m ${shellQuote(`agent ${label}`)}${lockPrivateLedger}`, commandOptions);\n ensureCommandSucceeded(result, `commit agent window ${label}`, rootCommands);\n },\n async exportWindows(): Promise<DiffArtifact> {\n return exportAgentWindows(sandbox, commandOptions, exportDir, rootCommands);\n },\n async resetToAnchor(): Promise<void> {\n if (ordinaryUid === \"0\") {\n throw new Error(\"sandboxReuse cannot safely reuse a root-agent sandbox: the Agent could read private ledger objects from prior attempts; use a non-root execution user or disable sandboxReuse\");\n }\n // Root performs the byte reset, then reapplies the content-free baseline metadata mirror so\n // ordinary files return to their original uid/gid/mode instead of becoming root-owned. The\n // private object database stays 0700 throughout; no Agent/background process can read it.\n const result = await sandbox.runShell(`git reset -q --hard niceeval-reuse-anchor && ` +\n `git clean -fd ${excludes.map((pattern) => `-e ${shellQuote(pattern)}`).join(\" \")} && ` +\n restoreBaselineMetadataScript(), commandOptions);\n ensureCommandSucceeded(result, \"reset reusable sandbox to anchor and restore ownership\", rootCommands);\n },\n };\n}\nasync function exportAgentWindows(sandbox: Sandbox, commandOptions: {\n readonly env: globalThis.Record<string, string>;\n readonly user?: \"root\";\n}, exportDir: string, rootCommands: boolean): Promise<DiffArtifact> {\n try {\n const result = await sandbox.runShell(buildExportScript(exportDir), commandOptions);\n ensureCommandSucceeded(result, \"export agent windows\", rootCommands);\n const manifest = parseExportManifest(await sandbox.readText(`${exportDir}/manifest.txt`));\n const chunks: Buffer[] = [];\n for (const part of manifest.parts) {\n const bytes = Buffer.from(await sandbox.readBytes(`${exportDir}/export.part.${part.suffix}`));\n if (bytes.byteLength !== part.bytes) {\n throw new Error(`niceeval ledger export: part ${part.suffix} has ${bytes.byteLength} bytes, expected ${part.bytes}`);\n }\n const algorithm = part.oid.length === 40 ? \"sha1\" : \"sha256\";\n const actual = createHash(algorithm)\n .update(`blob ${bytes.byteLength}\\0`, \"utf8\")\n .update(bytes)\n .digest(\"hex\");\n if (actual !== part.oid) {\n throw new Error(`niceeval ledger export: checksum mismatch for part ${part.suffix}`);\n }\n chunks.push(bytes);\n }\n const payload = Buffer.concat(chunks, manifest.totalBytes);\n if (payload.byteLength !== manifest.totalBytes) {\n throw new Error(\"niceeval ledger export: assembled payload length mismatch\");\n }\n return parseExportPayload(payload);\n }\n finally {\n await sandbox.runShell(`rm -rf ${shellQuote(exportDir)}`, commandOptions).catch(() => undefined);\n }\n}\ninterface ExportManifestPart {\n readonly suffix: string;\n readonly bytes: number;\n readonly oid: string;\n}\ninterface ExportManifest {\n readonly totalBytes: number;\n readonly parts: readonly ExportManifestPart[];\n}\nfunction manifestInteger(text: string, label: string, maximum: number): number {\n if (!/^(?:0|[1-9][0-9]*)$/.test(text)) {\n throw new Error(`niceeval ledger export: invalid manifest ${label}`);\n }\n const value = Number(text);\n if (!Number.isSafeInteger(value) || value < 0 || value > maximum) {\n throw new Error(`niceeval ledger export: manifest ${label} exceeds its limit`);\n }\n return value;\n}\nfunction parseExportManifest(text: string): ExportManifest {\n const lines = text.endsWith(\"\\n\") ? text.slice(0, -1).split(\"\\n\") : text.split(\"\\n\");\n if (lines[0] !== EXPORT_MANIFEST_HEADER) {\n throw new Error(\"niceeval ledger export: unsupported manifest header\");\n }\n const totalMatch = /^total ([0-9]+)$/.exec(lines[1] ?? \"\");\n const partsMatch = /^parts ([0-9]+)$/.exec(lines[2] ?? \"\");\n if (totalMatch === null || partsMatch === null) {\n throw new Error(\"niceeval ledger export: malformed manifest summary\");\n }\n const totalBytes = manifestInteger(totalMatch[1]!, \"total bytes\", MAX_EXPORT_BYTES);\n const partCount = manifestInteger(partsMatch[1]!, \"part count\", MAX_EXPORT_PARTS);\n const expectedPartCount = Math.ceil(totalBytes / EXPORT_PART_BYTES);\n if (partCount !== expectedPartCount || lines.length !== partCount + 3) {\n throw new Error(\"niceeval ledger export: manifest part count mismatch\");\n }\n const parts: ExportManifestPart[] = [];\n let retainedBytes = 0;\n for (let index = 0; index < partCount; index += 1) {\n const match = /^part ([0-9]{6}) ([0-9]+) ([0-9a-f]{40}|[0-9a-f]{64})$/.exec(lines[index + 3] ?? \"\");\n const suffix = String(index).padStart(6, \"0\");\n if (match === null || match[1] !== suffix) {\n throw new Error(`niceeval ledger export: invalid or non-contiguous part ${suffix}`);\n }\n const expectedBytes = Math.min(EXPORT_PART_BYTES, totalBytes - retainedBytes);\n const bytes = manifestInteger(match[2]!, `part ${suffix} bytes`, EXPORT_PART_BYTES);\n if (bytes !== expectedBytes || bytes === 0) {\n throw new Error(`niceeval ledger export: invalid length for part ${suffix}`);\n }\n retainedBytes += bytes;\n parts.push(Object.freeze({ suffix, bytes, oid: match[3]! }));\n }\n if (retainedBytes !== totalBytes) {\n throw new Error(\"niceeval ledger export: manifest total length mismatch\");\n }\n return Object.freeze({ totalBytes, parts: Object.freeze(parts) });\n}\nfunction ensureCommandSucceeded(result: {\n exitCode: number;\n stderr: string;\n}, operation: string, rootCommands: boolean, permissionGuidance?: string): void {\n if (result.exitCode === 0)\n return;\n const lines = result.stderr.trim().split(\"\\n\").filter(Boolean);\n const permission = lines.find((line) => /permission denied|operation not permitted/i.test(line));\n if (permission !== undefined) {\n const guidance = permissionGuidance ?? (rootCommands\n ? \"the provider declared root command support, but root ledger execution still could not read the workspace; check its root command mapping\"\n : \"this sandbox provider does not support root ledger commands; use a root-capable provider for tasks that intentionally start with unreadable files instead of chmod/chowning away the task condition\");\n throw new Error(`${operation} failed (exit ${result.exitCode}): ${permission}; ${guidance}`);\n }\n // git 可能先输出 advisory warning,再输出 niceeval 的可操作诊断;最后一行最接近失败根因。\n const detail = lines.at(-1);\n throw new Error(`${operation} failed (exit ${result.exitCode})${detail ? `: ${detail}` : \"\"}`);\n}\n// ---------- 导出文件的宿主侧解析(严格校验:帧、git 输出形状、尺寸与内容的完备性) ----------\nconst ZERO_SHA = /^0+$/;\nfunction parseExportPayload(payload: Buffer): DiffArtifact {\n const windows: DiffWindow[] = [];\n let offset = 0;\n const readLine = (): string => {\n const newline = payload.indexOf(0x0a, offset);\n if (newline === -1)\n throw new Error(\"niceeval ledger export: truncated header\");\n const line = payload.subarray(offset, newline).toString(\"utf8\");\n offset = newline + 1;\n return line;\n };\n const readSection = (expected: string): Buffer => {\n const header = readLine().split(\" \");\n if (header.length !== 3 || header[0] !== \"section\" || header[1] !== expected) {\n throw new Error(`niceeval ledger export: expected section ${expected}, got ${JSON.stringify(header.join(\" \"))}`);\n }\n const length = Number(header[2]);\n if (!isNonNegativeInteger(length) || offset + length > payload.length) {\n throw new Error(`niceeval ledger export: invalid ${expected} section length`);\n }\n const body = payload.subarray(offset, offset + length);\n offset += length;\n return body;\n };\n while (offset < payload.length) {\n const header = readLine();\n if (!header.startsWith(\"window \"))\n throw new Error(`niceeval ledger export: expected window header, got ${JSON.stringify(header)}`);\n const rest = header.slice(\"window \".length);\n const space = rest.indexOf(\" \");\n const label = space === -1 ? \"\" : rest.slice(space + 1);\n const entries = parseDiffTree(readSection(\"difftree\"), label);\n const binaryPaths = parseBinaryPaths(readSection(\"numstat\"), label);\n const sizeBySha = parseSizes(readSection(\"sizes\"), label);\n const contentBySha = parseBlobBatch(readSection(\"blobs\"), label);\n const changes: globalThis.Record<string, WindowChange> = {};\n for (const entry of entries) {\n const change: WindowChange = { status: entry.status };\n // 沙箱侧决定「哪些文本 blob 进 --batch」的两条判据在宿主侧同样成立(binary 段 + sizes 段\n // 都在导出文件里),所以这里独立重算,不需要沙箱再输出一份省略清单。\n const beforeBytes = entry.status === \"added\" ? undefined : requireSize(sizeBySha, entry.beforeSha, label, entry.path);\n const afterBytes = entry.status === \"deleted\" ? undefined : requireSize(sizeBySha, entry.afterSha, label, entry.path);\n const binary = binaryPaths.has(entry.path);\n const oversized = (beforeBytes ?? 0) > MAX_FILE_TEXT_BYTES || (afterBytes ?? 0) > MAX_FILE_TEXT_BYTES;\n if (binary || oversized) {\n change.elided = { reason: binary ? \"binary\" : \"oversized-text\" };\n if (beforeBytes !== undefined)\n change.elided.beforeBytes = beforeBytes;\n if (afterBytes !== undefined)\n change.elided.afterBytes = afterBytes;\n }\n else {\n if (entry.status !== \"added\")\n change.before = requireContent(contentBySha, entry.beforeSha, label, entry.path);\n if (entry.status !== \"deleted\")\n change.after = requireContent(contentBySha, entry.afterSha, label, entry.path);\n }\n changes[entry.path] = change;\n }\n windows.push({ window: label, changes });\n }\n return windows;\n}\ninterface DiffTreeEntry {\n path: string;\n status: WindowChange[\"status\"];\n beforeSha: string;\n afterSha: string;\n}\n/** `git diff-tree -r --no-renames -z` 原始输出:`:mode mode sha sha status NUL path NUL` 重复。 */\nfunction parseDiffTree(section: Buffer, label: string): DiffTreeEntry[] {\n const parts = section.toString(\"utf8\").split(\"\\0\");\n const entries: DiffTreeEntry[] = [];\n for (let i = 0; i < parts.length;) {\n const meta = parts[i++];\n if (!meta)\n continue;\n const path = parts[i++];\n const fields = meta.split(\" \");\n if (path === undefined || fields.length !== 5 || !fields[0]!.startsWith(\":\")) {\n throw new Error(`export window ${label}: malformed git diff-tree output`);\n }\n const code = fields[4]!;\n const status = code.startsWith(\"A\") ? \"added\" : code.startsWith(\"D\") ? \"deleted\" : \"modified\";\n entries.push({ path, status, beforeSha: fields[2]!, afterSha: fields[3]! });\n }\n return entries;\n}\n/** `git diff-tree --numstat -z`:二进制条目的 added/removed 计数是 `-`。 */\nfunction parseBinaryPaths(section: Buffer, label: string): Set<string> {\n const paths = new Set<string>();\n for (const record of section.toString(\"utf8\").split(\"\\0\")) {\n if (!record)\n continue;\n const firstTab = record.indexOf(\"\\t\");\n const secondTab = record.indexOf(\"\\t\", firstTab + 1);\n if (firstTab === -1 || secondTab === -1)\n throw new Error(`export window ${label}: malformed git --numstat output`);\n if (record.slice(0, firstTab) === \"-\" && record.slice(firstTab + 1, secondTab) === \"-\") {\n paths.add(record.slice(secondTab + 1));\n }\n }\n return paths;\n}\n/** `git cat-file --batch-check`:每行 `sha type size`(输入是逐出现次数的 sha,重复无害)。 */\nfunction parseSizes(section: Buffer, label: string): Map<string, number> {\n const sizes = new Map<string, number>();\n for (const line of section.toString(\"utf8\").split(\"\\n\")) {\n if (!line)\n continue;\n const fields = line.split(\" \");\n const size = Number(fields[fields.length - 1]);\n if (fields.length < 3 || !isNonNegativeInteger(size)) {\n throw new Error(`export window ${label}: malformed git cat-file --batch-check output`);\n }\n sizes.set(fields[0]!, size);\n }\n return sizes;\n}\n/** `git cat-file --batch`:自带长度帧——`sha type size\\n` + size 字节内容 + `\\n`。 */\nfunction parseBlobBatch(section: Buffer, label: string): Map<string, string> {\n const contents = new Map<string, string>();\n let offset = 0;\n while (offset < section.length) {\n const newline = section.indexOf(0x0a, offset);\n if (newline === -1)\n throw new Error(`export window ${label}: malformed git cat-file --batch header`);\n const fields = section.subarray(offset, newline).toString(\"utf8\").split(\" \");\n const size = Number(fields[fields.length - 1]);\n if (fields.length < 3 || !isNonNegativeInteger(size)) {\n throw new Error(`export window ${label}: malformed git cat-file --batch header`);\n }\n const contentStart = newline + 1;\n const contentEnd = contentStart + size;\n if (contentEnd >= section.length || section[contentEnd] !== 0x0a) {\n throw new Error(`export window ${label}: truncated git cat-file --batch content`);\n }\n contents.set(fields[0]!, section.subarray(contentStart, contentEnd).toString(\"utf8\"));\n offset = contentEnd + 1;\n }\n return contents;\n}\nfunction requireSize(sizes: Map<string, number>, sha: string, label: string, path: string): number {\n const size = sizes.get(sha);\n if (size === undefined || ZERO_SHA.test(sha))\n throw new Error(`export window ${label}: missing blob size for ${JSON.stringify(path)}`);\n return size;\n}\nfunction requireContent(contents: Map<string, string>, sha: string, label: string, path: string): string {\n const content = contents.get(sha);\n if (content === undefined || ZERO_SHA.test(sha))\n throw new Error(`export window ${label}: missing blob content for ${JSON.stringify(path)}`);\n return content;\n}\nfunction isNonNegativeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n"]}
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["ledger.ts"],"names":[],"mappings":"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","sourcesContent":["// 变更分类账(私有 git ledger):回答「**agent** 改了什么」,不是「workspace 相对空目录变了什么」。\n// 契约见 docs/feature/sandbox/architecture.md「变更归因:send 窗口与分类账」:\n// - ledger 的 git 目录在沙箱内、workdir 外(runner 私有路径),以 workdir 为 work-tree——\n// workdir 保持素净:agent 看不到 runner 的 .git,eval 需要真实 git repo 时自己 git init,\n// agent 在 workdir 里的任何 git 操作都碰不到分类账。\n// - 三类 commit 时点:锚点一笔(workspace.baseline);每次 t.send() 进入前 workdir 有未记录\n// 变化就落一笔 eval 归因;t.send() 返回后落一笔 agent 归因(send 窗口内的全部变化)。\n// - 归因排除清单 runner 私有、锚点时冻结:项目自己的 .gitignore 不参与归因判断(add -f 绕过),\n// 排除靠 pathspec,include 显式打洞加回。\n// - agent 归因增量 = 逐窗口 delta 序列(DiffWindow[]),不做跨窗口压缩。\nimport { createHash } from \"node:crypto\";\nimport type { DiffArtifact, DiffWindow, Sandbox, WindowChange } from \"../types.ts\";\nimport type { AgentWorkspaceDiffPolicy } from \"../assertions/workspace-diff.ts\";\nimport { sandboxSupportsRootCommands } from \"../sandbox/backend.ts\";\nimport { DEFAULT_LEDGER_EXPORT_DIR, DEFAULT_LEDGER_GIT_DIR } from \"../sandbox/ledger-paths.ts\";\n/**\n * ledger 的私有 git 目录:workdir 之外、runner 控制;agent 的工具默认不会去 /tmp 翻它。这是\n * 沙箱内 provider(docker/e2b/vercel)的固定值——每个实例都是全新隔离文件系统。\n */\nexport const LEDGER_GIT_DIR = DEFAULT_LEDGER_GIT_DIR;\n/** 默认归因排除清单(锚点时冻结):依赖、构建产物、包管理器缓存与用户项目里的 .niceeval 记录目录。\n * 框架自己不往 workdir 写任何东西(见 docs/observability.md「宿主侧行为断言:t.o11y」),\n * 所以这里没有框架路径要排。 */\nconst DEFAULT_EXCLUDES = [\n \".git\",\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \".turbo\",\n \".niceeval\",\n \"coverage\",\n \".cache\",\n \".pnpm-store\",\n \".npm\",\n \".yarn\",\n \"*venv*/\",\n \".venv\",\n \"__pycache__\",\n];\nconst MAX_POLICY_ENTRIES = 256;\nconst MAX_POLICY_ENTRY_UTF8_BYTES = 4096;\nconst policyEncoder = new TextEncoder();\nfunction compareAscii(left: string, right: string): number {\n return left === right ? 0 : left < right ? -1 : 1;\n}\n/** Reject an unrecordable policy before the collector starts, then freeze its canonical evidence form. */\nfunction canonicalPolicyEntries(entries: readonly string[], name: \"include\" | \"ignore\"): readonly string[] {\n if (entries.length > MAX_POLICY_ENTRIES) {\n throw new Error(`defineEval({ diff }).${name} may contain at most ${MAX_POLICY_ENTRIES} entries`);\n }\n for (const [index, entry] of entries.entries()) {\n if (typeof entry !== \"string\") {\n throw new TypeError(`defineEval({ diff }).${name}[${index}] must be a string`);\n }\n if (policyEncoder.encode(entry).byteLength > MAX_POLICY_ENTRY_UTF8_BYTES) {\n throw new Error(`defineEval({ diff }).${name}[${index}] exceeds ${MAX_POLICY_ENTRY_UTF8_BYTES} UTF-8 bytes`);\n }\n }\n return Object.freeze([...new Set(entries)].sort(compareAscii));\n}\n/**\n * 单个 send 窗口的导出扫描安全上限。File Changes 的 10,000-change durable 上限由 collector\n * 保留确定性前缀并写 collection-cap-reached;导出层必须先把更大的候选集合交给 collector,\n * 不能在同一个 10,000 边界提前把已知 partial 证据降格成 unavailable。\n * 字节预算只数**真正要传输的文本** before/after:二进制与超过单文件阈值的文本不内联内容、\n * 只记字节数(WindowChange.elided),因此不占预算——编译产物型窗口(成百上千个 .o 加几个大\n * 文本)不该因为「按尺寸计」被判越界。\n */\nconst MAX_EXPORTED_WINDOW_PATHS = 100000;\nconst MAX_EXPORTED_WINDOW_TEXT_BYTES = 256 * 1024 * 1024;\n/** 单个文本 blob 的内联阈值:任一侧超过它,该条目按二进制同款处理(记字节数、内容省略)。 */\nconst MAX_FILE_TEXT_BYTES = 1024 * 1024;\n/** Provider 文件 API 的单次安全读取边界,以及整次 Attempt 导出的硬上限。 */\nconst EXPORT_PART_BYTES = 4000000;\nconst MAX_EXPORT_BYTES = 512 * 1024 * 1024;\nconst MAX_EXPORT_PARTS = Math.ceil(MAX_EXPORT_BYTES / EXPORT_PART_BYTES);\nconst EXPORT_MANIFEST_HEADER = \"niceeval-ledger-export-parts v1\";\n/**\n * 整相导出:一条 POSIX shell 命令枚举**全部** agent 窗口并把证据写进沙箱内导出文件,宿主随后\n * 经文件通道一次下载——provider 往返数与窗口数、文件数都无关。对沙箱环境的全部要求是 git 与\n * POSIX 工具(sh/awk/wc/sort/grep),不依赖 node、python 等运行时。\n *\n * 沙箱内不组装 JSON:导出文件直接拼接 git 原生输出——每窗口四段,`diff-tree -z`(状态 + 前后\n * blob sha + 路径,NUL 安全)、`numstat -z`(二进制识别)、`cat-file --batch-check`(全部 blob\n * 尺寸)、`cat-file --batch`(要内联的文本 blob 内容,输出自带长度帧)——解析与校验全部在宿主侧完成。\n * 需要在沙箱内做的两个判断都不解析路径列:sha 提取用 awk 取 diff-tree 原始输出的第 3/4 列\n * (路径在其后,含空格也不影响);二进制排除靠 numstat 与 diff-tree 输出的行号对齐。\n * 尺寸核算(--batch-check)先于内容读取(--batch),越界在产出任何内容前失败;预算只累计真正\n * 要传输的文本 blob(二进制与单文件超限文本只出字节数,不进 --batch 请求、不计预算)。\n * 宿主侧从 sizes + numstat 两段就能判出哪些条目内容被省略,沙箱不额外输出一份判定清单。\n */\nfunction buildExportScript(exportDir: string): string {\n return [\n \"set -eu\",\n `D=${shellQuote(exportDir)}`,\n 'rm -rf \"$D\" && mkdir -p \"$D\"',\n 'OUT=$D/export.bin',\n ': > \"$OUT\"',\n 'fail() { printf \"%s\\\\n\" \"$1\" >&2; exit 2; }',\n // 帧格式:`section <name> <bytes>` 头一行,后跟原始字节;长度前缀让内容里的任意字节都安全。\n 'emit() { printf \"section %s %s\\\\n\" \"$1\" \"$(($(wc -c < \"$2\")))\" >> \"$OUT\"; cat \"$2\" >> \"$OUT\"; }',\n 'git log --reverse --format=\"%H %s\" > \"$D/log.txt\"',\n \"while IFS= read -r line; do\",\n ' hash=${line%% *}',\n ' subject=${line#* }',\n ' case $subject in \"agent \"*) ;; *) continue ;; esac',\n ' label=${subject#agent }',\n // 非 -z 的 diff-tree 把特殊路径引号转义成单行,一行 = 一个条目:wc -l 即路径数,awk 列取 sha 不碰路径。\n ' git diff-tree -r --no-renames \"$hash^\" \"$hash\" > \"$D/dt.txt\"',\n ' n=$(($(wc -l < \"$D/dt.txt\")))',\n ` [ \"$n\" -le ${MAX_EXPORTED_WINDOW_PATHS} ] || fail \"niceeval diff window contains $n paths; export scan limit is ${MAX_EXPORTED_WINDOW_PATHS}; narrow defineEval({ diff }) include/ignore rules\"`,\n ' git diff-tree -r --no-renames --numstat \"$hash^\" \"$hash\" > \"$D/ns.txt\"',\n // 全部 blob 出现次数(before + after,零 sha = 无此侧,排除)→ 逐次尺寸核算。\n \" awk '$3 !~ /^0+$/ { print $3 } $4 !~ /^0+$/ { print $4 }' \\\"$D/dt.txt\\\" > \\\"$D/occ.txt\\\"\",\n ' git cat-file --batch-check < \"$D/occ.txt\" > \"$D/sizes.txt\"',\n ' if grep -q \" missing$\" \"$D/sizes.txt\"; then fail \"niceeval ledger export: blob object missing\"; fi',\n // 逐条目分类:numstat 第 1 列为 \"-\" 的行是二进制,按行号对齐标 B,其余标 T,后跟前后 blob sha。\n ' awk \\'NR==FNR { bin[FNR] = ($1 == \"-\"); next } { printf \"%s %s %s\\\\n\", (bin[FNR] ? \"B\" : \"T\"), $3, $4 }\\' \"$D/ns.txt\" \"$D/dt.txt\" > \"$D/entries.txt\"',\n // 要内联的文本 blob(去重):二进制条目与任一侧超过单文件阈值的文本条目都不请求内容,\n // 也不计入窗口预算——它们只出字节数(宿主据同一份 sizes 判成 elided)。\n ` awk -v LIMIT=${MAX_FILE_TEXT_BYTES} -v TOTAL=\"$D/total.txt\" 'NR==FNR { sz[$1] = $3; next } $1 == \"T\" { b = $2; a = $3; if (b !~ /^0+$/ && sz[b] > LIMIT) next; if (a !~ /^0+$/ && sz[a] > LIMIT) next; if (b !~ /^0+$/ && !(b in seen)) { seen[b] = 1; total += sz[b]; print b } if (a !~ /^0+$/ && !(a in seen)) { seen[a] = 1; total += sz[a]; print a } } END { print total+0 > TOTAL }' \"$D/sizes.txt\" \"$D/entries.txt\" > \"$D/text.txt\"`,\n ' bytes=$(cat \"$D/total.txt\")',\n ` [ \"$bytes\" -le ${MAX_EXPORTED_WINDOW_TEXT_BYTES} ] || fail \"niceeval diff window transfers $bytes text blob bytes; export scan limit is ${MAX_EXPORTED_WINDOW_TEXT_BYTES}; narrow defineEval({ diff }) include/ignore rules\"`,\n ' git cat-file --batch < \"$D/text.txt\" > \"$D/blobs.bin\"',\n ' git diff-tree -r --no-renames -z \"$hash^\" \"$hash\" > \"$D/dtz.bin\"',\n ' git diff-tree -r --no-renames --numstat -z \"$hash^\" \"$hash\" > \"$D/nsz.bin\"',\n ' printf \"window %s %s\\\\n\" \"$hash\" \"$label\" >> \"$OUT\"',\n ' emit difftree \"$D/dtz.bin\"',\n ' emit numstat \"$D/nsz.bin\"',\n ' emit sizes \"$D/sizes.txt\"',\n ' emit blobs \"$D/blobs.bin\"',\n 'done < \"$D/log.txt\"',\n // Provider 文件 API 可能拒绝超过 4 MiB 的单对象读取。这里按固定原始字节切片,并在最后\n // 原子发布 manifest;宿主只接受连续序号、精确长度和 Git blob checksum。\n 'total=$(($(wc -c < \"$OUT\")))',\n ` [ \"$total\" -le ${MAX_EXPORT_BYTES} ] || fail \"niceeval ledger export contains $total bytes; attempt export limit is ${MAX_EXPORT_BYTES}\"`,\n `parts=$(( (total + ${EXPORT_PART_BYTES} - 1) / ${EXPORT_PART_BYTES} ))`,\n ` [ \"$parts\" -le ${MAX_EXPORT_PARTS} ] || fail \"niceeval ledger export needs $parts parts; attempt part limit is ${MAX_EXPORT_PARTS}\"`,\n 'MANIFEST_TMP=$D/manifest.tmp',\n 'MANIFEST=$D/manifest.txt',\n `printf \"%s\\\\ntotal %s\\\\nparts %s\\\\n\" \"${EXPORT_MANIFEST_HEADER}\" \"$total\" \"$parts\" > \"$MANIFEST_TMP\"`,\n 'i=0',\n 'while [ \"$i\" -lt \"$parts\" ]; do',\n ' suffix=$(printf \"%06d\" \"$i\")',\n ' part=$D/export.part.$suffix',\n ` dd if=\"$OUT\" of=\"$part\" bs=${EXPORT_PART_BYTES} skip=\"$i\" count=1 2>/dev/null`,\n ' size=$(($(wc -c < \"$part\")))',\n ' oid=$(git hash-object --no-filters \"$part\")',\n ' printf \"part %s %s %s\\\\n\" \"$suffix\" \"$size\" \"$oid\" >> \"$MANIFEST_TMP\"',\n ' i=$((i + 1))',\n 'done',\n 'mv \"$MANIFEST_TMP\" \"$MANIFEST\"',\n 'rm -f \"$OUT\"',\n // root ledger commands may create private exports with a restrictive umask. These artifacts are\n // outside workdir and are deleted immediately after the provider file channel consumes them.\n 'chmod 0644 \"$MANIFEST\"',\n 'for part in \"$D\"/export.part.*; do [ -f \"$part\" ] || continue; chmod 0644 \"$part\"; done',\n ].join(\"\\n\");\n}\nexport interface ChangeLedger {\n /** send 进入前:workdir 有未记录变化就落一笔 eval 归因(fixture / setup / runCommand 副作用)。 */\n commitEvalWindow(label: string): Promise<void>;\n /** send 返回后:落一笔 agent 归因——这个 send 窗口内的全部 workspace 变化(无变化也落空窗口)。 */\n commitAgentWindow(label: string): Promise<void>;\n /** workspace.diff 阶段:从分类账导出每个 send 窗口自己的 before/after,按时序。 */\n exportWindows(): Promise<DiffArtifact>;\n /** 回到创建时的题间锚点,并保留归因排除清单排除的动态环境。 */\n resetToAnchor(): Promise<void>;\n /**\n * 建账时探测到的执行身份是否为 root(仅当 provider 支持 root ledger 命令时才探测得到,\n * 否则恒为 false)。sandboxReuse 复用池据此在实例进池前拒绝(见 docs/feature/sandbox/reuse.md);\n * `resetToAnchor()` 内的同款判断作纵深防御保留。\n */\n readonly rootExecutionIdentity: boolean;\n /** Frozen semantic identity consumed by the Attempt-owned diff Attachment. */\n readonly attribution: AgentWorkspaceDiffPolicy;\n}\ninterface LedgerOptions {\n /** defineEval({ diff }) 的归因调整:ignore 追加排除,include 打洞加回(优先级最高)。 */\n include?: string[];\n ignore?: string[];\n}\n/** 每条 git 命令都带上私有 GIT_DIR + workdir work-tree;项目/全局 gitignore 一律不参与。 */\nfunction gitEnv(sandbox: Sandbox, gitDir: string): globalThis.Record<string, string> {\n return {\n GIT_DIR: gitDir,\n GIT_WORK_TREE: sandbox.workdir,\n GIT_AUTHOR_NAME: \"niceeval\",\n GIT_AUTHOR_EMAIL: \"niceeval@localhost\",\n GIT_COMMITTER_NAME: \"niceeval\",\n GIT_COMMITTER_EMAIL: \"niceeval@localhost\",\n // Internal root Git must never consume configuration or hooks writable by the Agent.\n GIT_CONFIG_NOSYSTEM: \"1\",\n GIT_CONFIG_GLOBAL: \"/dev/null\",\n GIT_CONFIG_COUNT: \"1\",\n GIT_CONFIG_KEY_0: \"core.hooksPath\",\n GIT_CONFIG_VALUE_0: \"/dev/null\",\n GIT_TERMINAL_PROMPT: \"0\",\n HOME: \"/tmp\",\n };\n}\nfunction shellQuote(s: string): string {\n return `'${s.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n/**\n * Root Git can faithfully restore bytes but would otherwise recreate ordinary fixture files as root.\n * Keep a content-free metadata mirror inside the private (0700) ledger and reapply uid/gid/mode after\n * reset. The batched xargs loops preserve arbitrary Git path bytes without exposing objects to the Agent.\n */\nfunction captureBaselineMetadataScript(): string {\n return [\n 'META=\"$GIT_DIR/niceeval-baseline-metadata\"',\n 'rm -rf \"$META\" && mkdir -p \"$META/files\" \"$META/dirs\"',\n \"export META\",\n \"git ls-files -z | xargs -0 -n 100 sh -c '\",\n \" for p do\",\n ' src=\"$GIT_WORK_TREE/$p\"',\n ' ref=\"$META/files/$p\"',\n ' mkdir -p \"$(dirname \"$ref\")\" && : > \"$ref\"',\n ' owner=$(stat -c \"%u:%g\" \"$src\") && mode=$(stat -c \"%a\" \"$src\")',\n ' chown -h \"$owner\" \"$ref\" && chmod \"$mode\" \"$ref\"',\n ' d=$(dirname \"$p\")',\n ' while [ \"$d\" != \".\" ]; do',\n ' dref=\"$META/dirs/$d/.ref\"',\n ' if [ ! -e \"$dref\" ]; then',\n ' mkdir -p \"$(dirname \"$dref\")\" && : > \"$dref\"',\n ' downer=$(stat -c \"%u:%g\" \"$GIT_WORK_TREE/$d\") && dmode=$(stat -c \"%a\" \"$GIT_WORK_TREE/$d\")',\n ' chown \"$downer\" \"$dref\" && chmod \"$dmode\" \"$dref\"',\n \" fi\",\n ' d=$(dirname \"$d\")',\n \" done\",\n \" done\",\n \"' niceeval-meta\",\n // Agent and any background process share the ordinary sandbox uid. Keep both objects and the\n // metadata mirror root-private for the whole attempt; reset never opens this directory to that uid.\n 'chmod go-rwx \"$GIT_DIR\"',\n ].join(\"\\n\");\n}\nfunction restoreBaselineMetadataScript(): string {\n return [\n 'META=\"$GIT_DIR/niceeval-baseline-metadata\"',\n \"export META\",\n 'if [ -d \"$META/files\" ]; then',\n \" find \\\"$META/files\\\" -type f -print0 | xargs -0 -n 100 sh -c '\",\n \" for ref do\",\n ' p=${ref#\"$META/files/\"}',\n ' target=\"$GIT_WORK_TREE/$p\"',\n ' if [ -e \"$target\" ] || [ -L \"$target\" ]; then',\n ' owner=$(stat -c \"%u:%g\" \"$ref\") && mode=$(stat -c \"%a\" \"$ref\")',\n ' chown -h \"$owner\" \"$target\"',\n ' [ -L \"$target\" ] || chmod \"$mode\" \"$target\"',\n \" fi\",\n \" done\",\n \" ' niceeval-meta-restore\",\n \"fi\",\n // Apply directory metadata last so restrictive parent modes cannot interfere with child repair.\n 'if [ -d \"$META/dirs\" ]; then',\n \" find \\\"$META/dirs\\\" -type f -name .ref -print0 | xargs -0 -n 100 sh -c '\",\n \" for ref do\",\n ' d=${ref%/.ref}',\n ' p=${d#\"$META/dirs/\"}',\n ' target=\"$GIT_WORK_TREE/$p\"',\n ' if [ -d \"$target\" ]; then',\n ' owner=$(stat -c \"%u:%g\" \"$ref\") && mode=$(stat -c \"%a\" \"$ref\")',\n ' chown \"$owner\" \"$target\" && chmod \"$mode\" \"$target\"',\n \" fi\",\n \" done\",\n \" ' niceeval-dir-meta-restore\",\n \"fi\",\n 'chmod go-rwx \"$GIT_DIR\"',\n ].join(\"\\n\");\n}\n/**\n * 把仓库根语义的 gitignore 风格规则编译成 ledger pathspec。\n * 无斜杠的名字匹配任意深度;有斜杠的规则相对 workdir 根;目录本身与后代一起处理。\n */\nfunction gitignorePathspecs(pattern: string, exclude: boolean): string[] {\n let normalized = pattern;\n while (normalized.startsWith(\"./\"))\n normalized = normalized.slice(2);\n if (normalized.startsWith(\"/\"))\n normalized = normalized.slice(1);\n normalized = normalized.replace(/\\/+$/, \"\");\n if (!normalized)\n return [];\n const glob = normalized.includes(\"/\") ? normalized : `**/${normalized}`;\n const globs = exclude && !glob.endsWith(\"/**\") ? [glob, `${glob}/**`] : [glob];\n const magic = exclude ? \":(glob,exclude)\" : \":(glob)\";\n return [...new Set(globs)].map((value) => `${magic}${value}`);\n}\n/** 打分类账锚点(workspace.baseline 阶段,环境层钩子之后):git init + 冻结排除清单 + 首笔 commit。 */\nexport async function createChangeLedger(sandbox: Sandbox, opts?: LedgerOptions): Promise<ChangeLedger> {\n const includes = canonicalPolicyEntries(opts?.include ?? [], \"include\");\n const ignored = canonicalPolicyEntries(opts?.ignore ?? [], \"ignore\");\n const excludes = [...DEFAULT_EXCLUDES, ...ignored];\n const gitDir = LEDGER_GIT_DIR;\n const exportDir = DEFAULT_LEDGER_EXPORT_DIR;\n const env = gitEnv(sandbox, gitDir);\n const rootCommands = sandboxSupportsRootCommands(sandbox);\n // 只给 runner 私有 ledger 命令提权,以便读取题目故意设置的受限文件。脚本不 chmod/chown\n // workdir,Agent 命令仍沿标准非 root 身份;不支持提权的 provider 保持既有用户态路径。\n const commandOptions = rootCommands ? { env, user: \"root\" as const } : { env };\n const captureMetadata = rootCommands ? ` && ${captureBaselineMetadataScript()}` : \"\";\n const lockPrivateLedger = rootCommands ? ' && chmod go-rwx \"$GIT_DIR\"' : \"\";\n let ordinaryUid: string | undefined;\n if (rootCommands) {\n // Capture before Agent setup/send can mutate the VM. A post-attempt `id` probe would not be a\n // trustworthy boundary when the configured execution identity itself is root.\n const identity = await sandbox.runShell(\"command -p id -u\", { env });\n ensureCommandSucceeded(identity, \"detect sandbox execution identity for reuse\", false);\n ordinaryUid = identity.stdout.trim();\n }\n // add -A -f:绕过项目自己的 .gitignore(项目 ignore 的文件照常记录);排除靠 pathspec\n // (runner 私有清单,agent / fixture 写 .gitignore 影响不了它);include 用第二次 add 打洞加回。\n const excludeSpecs = excludes.flatMap((pattern) => gitignorePathspecs(pattern, true)).map(shellQuote).join(\" \");\n // include 打洞:路径此刻可能还不存在(如 agent 之后才写),unmatched pathspec 不算错。\n const includeSpecs = includes.flatMap((pattern) => gitignorePathspecs(pattern, false)).map(shellQuote).join(\" \");\n const includeAdd = includeSpecs.length > 0 ? ` && { git -c advice.addEmbeddedRepo=false add -A -f -- ${includeSpecs} 2>/dev/null || true; }` : \"\";\n const rejectGitlinks = \" && nested=$(git ls-files --stage | awk '$1 == \\\"160000\\\" { sub(/^[^\\\\t]*\\\\t/, \\\"\\\"); print; exit }')\" +\n ' && if [ -n \"$nested\" ]; then printf \\'%s\\\\n\\' \"niceeval ledger cannot track nested Git repository $nested as file-level evidence; move the checkout to sandbox.workdir root, or add the whole path to defineEval({ diff: { ignore: [...] } }) when it is intentionally out of scope\" >&2; exit 2; fi';\n const addAll = `git -c advice.addEmbeddedRepo=false add -A -f -- . ${excludeSpecs}${includeAdd}${rejectGitlinks}`;\n const anchor = await sandbox.runShell(\n // The path is predictable inside an isolated VM. Remove any image/prepare-time occupant or\n // symlink, then recreate the exact runner-private directory as root 0700 before Git touches it.\n `rm -rf -- ${shellQuote(gitDir)} && mkdir -p -m 0700 -- ${shellQuote(gitDir)} && ` +\n `git init -q \"${gitDir}\" && ${addAll} && git commit -q --allow-empty -m \"anchor\" && ` +\n `(git rev-parse -q --verify niceeval-reuse-anchor >/dev/null || git tag niceeval-reuse-anchor)` +\n captureMetadata, {\n ...commandOptions,\n });\n ensureCommandSucceeded(anchor, \"create change ledger anchor\", rootCommands);\n return {\n rootExecutionIdentity: ordinaryUid === \"0\",\n attribution: Object.freeze({\n defaultPolicy: \"niceeval.sandbox-ledger/default-excludes/v1\" as const,\n include: includes,\n ignore: ignored,\n }),\n async commitEvalWindow(label: string): Promise<void> {\n // 有未记录变化才落这一笔;干净时不产生空的 eval 归因 commit。\n const result = await sandbox.runShell(`${addAll} && (git diff --cached --quiet || git commit -q -m ${shellQuote(`eval ${label}`)})${lockPrivateLedger}`, {\n ...commandOptions,\n });\n ensureCommandSucceeded(result, `commit eval window ${label}`, rootCommands);\n },\n async commitAgentWindow(label: string): Promise<void> {\n // 窗口内没有变化时也落一条(--allow-empty),diff.json 里该窗口 changes 为空对象。\n const result = await sandbox.runShell(`${addAll} && git commit -q --allow-empty -m ${shellQuote(`agent ${label}`)}${lockPrivateLedger}`, commandOptions);\n ensureCommandSucceeded(result, `commit agent window ${label}`, rootCommands);\n },\n async exportWindows(): Promise<DiffArtifact> {\n return exportAgentWindows(sandbox, commandOptions, exportDir, rootCommands);\n },\n async resetToAnchor(): Promise<void> {\n if (ordinaryUid === \"0\") {\n throw new Error(\"sandboxReuse cannot safely reuse a root-agent sandbox: the Agent could read private ledger objects from prior attempts; use a non-root execution user or disable sandboxReuse\");\n }\n // Root performs the byte reset, then reapplies the content-free baseline metadata mirror so\n // ordinary files return to their original uid/gid/mode instead of becoming root-owned. The\n // private object database stays 0700 throughout; no Agent/background process can read it.\n const result = await sandbox.runShell(`git reset -q --hard niceeval-reuse-anchor && ` +\n `git clean -fd ${excludes.map((pattern) => `-e ${shellQuote(pattern)}`).join(\" \")} && ` +\n restoreBaselineMetadataScript(), commandOptions);\n ensureCommandSucceeded(result, \"reset reusable sandbox to anchor and restore ownership\", rootCommands);\n },\n };\n}\nasync function exportAgentWindows(sandbox: Sandbox, commandOptions: {\n readonly env: globalThis.Record<string, string>;\n readonly user?: \"root\";\n}, exportDir: string, rootCommands: boolean): Promise<DiffArtifact> {\n try {\n const result = await sandbox.runShell(buildExportScript(exportDir), commandOptions);\n ensureCommandSucceeded(result, \"export agent windows\", rootCommands);\n const manifest = parseExportManifest(await sandbox.readText(`${exportDir}/manifest.txt`));\n const chunks: Buffer[] = [];\n for (const part of manifest.parts) {\n const bytes = Buffer.from(await sandbox.readBytes(`${exportDir}/export.part.${part.suffix}`));\n if (bytes.byteLength !== part.bytes) {\n throw new Error(`niceeval ledger export: part ${part.suffix} has ${bytes.byteLength} bytes, expected ${part.bytes}`);\n }\n const algorithm = part.oid.length === 40 ? \"sha1\" : \"sha256\";\n const actual = createHash(algorithm)\n .update(`blob ${bytes.byteLength}\\0`, \"utf8\")\n .update(bytes)\n .digest(\"hex\");\n if (actual !== part.oid) {\n throw new Error(`niceeval ledger export: checksum mismatch for part ${part.suffix}`);\n }\n chunks.push(bytes);\n }\n const payload = Buffer.concat(chunks, manifest.totalBytes);\n if (payload.byteLength !== manifest.totalBytes) {\n throw new Error(\"niceeval ledger export: assembled payload length mismatch\");\n }\n return parseExportPayload(payload);\n }\n finally {\n await sandbox.runShell(`rm -rf ${shellQuote(exportDir)}`, commandOptions).catch(() => undefined);\n }\n}\ninterface ExportManifestPart {\n readonly suffix: string;\n readonly bytes: number;\n readonly oid: string;\n}\ninterface ExportManifest {\n readonly totalBytes: number;\n readonly parts: readonly ExportManifestPart[];\n}\nfunction manifestInteger(text: string, label: string, maximum: number): number {\n if (!/^(?:0|[1-9][0-9]*)$/.test(text)) {\n throw new Error(`niceeval ledger export: invalid manifest ${label}`);\n }\n const value = Number(text);\n if (!Number.isSafeInteger(value) || value < 0 || value > maximum) {\n throw new Error(`niceeval ledger export: manifest ${label} exceeds its limit`);\n }\n return value;\n}\nfunction parseExportManifest(text: string): ExportManifest {\n const lines = text.endsWith(\"\\n\") ? text.slice(0, -1).split(\"\\n\") : text.split(\"\\n\");\n if (lines[0] !== EXPORT_MANIFEST_HEADER) {\n throw new Error(\"niceeval ledger export: unsupported manifest header\");\n }\n const totalMatch = /^total ([0-9]+)$/.exec(lines[1] ?? \"\");\n const partsMatch = /^parts ([0-9]+)$/.exec(lines[2] ?? \"\");\n if (totalMatch === null || partsMatch === null) {\n throw new Error(\"niceeval ledger export: malformed manifest summary\");\n }\n const totalBytes = manifestInteger(totalMatch[1]!, \"total bytes\", MAX_EXPORT_BYTES);\n const partCount = manifestInteger(partsMatch[1]!, \"part count\", MAX_EXPORT_PARTS);\n const expectedPartCount = Math.ceil(totalBytes / EXPORT_PART_BYTES);\n if (partCount !== expectedPartCount || lines.length !== partCount + 3) {\n throw new Error(\"niceeval ledger export: manifest part count mismatch\");\n }\n const parts: ExportManifestPart[] = [];\n let retainedBytes = 0;\n for (let index = 0; index < partCount; index += 1) {\n const match = /^part ([0-9]{6}) ([0-9]+) ([0-9a-f]{40}|[0-9a-f]{64})$/.exec(lines[index + 3] ?? \"\");\n const suffix = String(index).padStart(6, \"0\");\n if (match === null || match[1] !== suffix) {\n throw new Error(`niceeval ledger export: invalid or non-contiguous part ${suffix}`);\n }\n const expectedBytes = Math.min(EXPORT_PART_BYTES, totalBytes - retainedBytes);\n const bytes = manifestInteger(match[2]!, `part ${suffix} bytes`, EXPORT_PART_BYTES);\n if (bytes !== expectedBytes || bytes === 0) {\n throw new Error(`niceeval ledger export: invalid length for part ${suffix}`);\n }\n retainedBytes += bytes;\n parts.push(Object.freeze({ suffix, bytes, oid: match[3]! }));\n }\n if (retainedBytes !== totalBytes) {\n throw new Error(\"niceeval ledger export: manifest total length mismatch\");\n }\n return Object.freeze({ totalBytes, parts: Object.freeze(parts) });\n}\nfunction ensureCommandSucceeded(result: {\n exitCode: number;\n stderr: string;\n}, operation: string, rootCommands: boolean, permissionGuidance?: string): void {\n if (result.exitCode === 0)\n return;\n const lines = result.stderr.trim().split(\"\\n\").filter(Boolean);\n const permission = lines.find((line) => /permission denied|operation not permitted/i.test(line));\n if (permission !== undefined) {\n const guidance = permissionGuidance ?? (rootCommands\n ? \"the provider declared root command support, but root ledger execution still could not read the workspace; check its root command mapping\"\n : \"this sandbox provider does not support root ledger commands; use a root-capable provider for tasks that intentionally start with unreadable files instead of chmod/chowning away the task condition\");\n throw new Error(`${operation} failed (exit ${result.exitCode}): ${permission}; ${guidance}`);\n }\n // git 可能先输出 advisory warning,再输出 niceeval 的可操作诊断;最后一行最接近失败根因。\n const detail = lines.at(-1);\n throw new Error(`${operation} failed (exit ${result.exitCode})${detail ? `: ${detail}` : \"\"}`);\n}\n// ---------- 导出文件的宿主侧解析(严格校验:帧、git 输出形状、尺寸与内容的完备性) ----------\nconst ZERO_SHA = /^0+$/;\nfunction parseExportPayload(payload: Buffer): DiffArtifact {\n const windows: DiffWindow[] = [];\n let offset = 0;\n const readLine = (): string => {\n const newline = payload.indexOf(0x0a, offset);\n if (newline === -1)\n throw new Error(\"niceeval ledger export: truncated header\");\n const line = payload.subarray(offset, newline).toString(\"utf8\");\n offset = newline + 1;\n return line;\n };\n const readSection = (expected: string): Buffer => {\n const header = readLine().split(\" \");\n if (header.length !== 3 || header[0] !== \"section\" || header[1] !== expected) {\n throw new Error(`niceeval ledger export: expected section ${expected}, got ${JSON.stringify(header.join(\" \"))}`);\n }\n const length = Number(header[2]);\n if (!isNonNegativeInteger(length) || offset + length > payload.length) {\n throw new Error(`niceeval ledger export: invalid ${expected} section length`);\n }\n const body = payload.subarray(offset, offset + length);\n offset += length;\n return body;\n };\n while (offset < payload.length) {\n const header = readLine();\n if (!header.startsWith(\"window \"))\n throw new Error(`niceeval ledger export: expected window header, got ${JSON.stringify(header)}`);\n const rest = header.slice(\"window \".length);\n const space = rest.indexOf(\" \");\n const label = space === -1 ? \"\" : rest.slice(space + 1);\n const entries = parseDiffTree(readSection(\"difftree\"), label);\n const binaryPaths = parseBinaryPaths(readSection(\"numstat\"), label);\n const sizeBySha = parseSizes(readSection(\"sizes\"), label);\n const contentBySha = parseBlobBatch(readSection(\"blobs\"), label);\n const changes: globalThis.Record<string, WindowChange> = {};\n for (const entry of entries) {\n const change: WindowChange = { status: entry.status };\n // 沙箱侧决定「哪些文本 blob 进 --batch」的两条判据在宿主侧同样成立(binary 段 + sizes 段\n // 都在导出文件里),所以这里独立重算,不需要沙箱再输出一份省略清单。\n const beforeBytes = entry.status === \"added\" ? undefined : requireSize(sizeBySha, entry.beforeSha, label, entry.path);\n const afterBytes = entry.status === \"deleted\" ? undefined : requireSize(sizeBySha, entry.afterSha, label, entry.path);\n const binary = binaryPaths.has(entry.path);\n const oversized = (beforeBytes ?? 0) > MAX_FILE_TEXT_BYTES || (afterBytes ?? 0) > MAX_FILE_TEXT_BYTES;\n if (binary || oversized) {\n change.elided = { reason: binary ? \"binary\" : \"oversized-text\" };\n if (beforeBytes !== undefined)\n change.elided.beforeBytes = beforeBytes;\n if (afterBytes !== undefined)\n change.elided.afterBytes = afterBytes;\n }\n else {\n if (entry.status !== \"added\")\n change.before = requireContent(contentBySha, entry.beforeSha, label, entry.path);\n if (entry.status !== \"deleted\")\n change.after = requireContent(contentBySha, entry.afterSha, label, entry.path);\n }\n changes[entry.path] = change;\n }\n windows.push({ window: label, changes });\n }\n return windows;\n}\ninterface DiffTreeEntry {\n path: string;\n status: WindowChange[\"status\"];\n beforeSha: string;\n afterSha: string;\n}\n/** `git diff-tree -r --no-renames -z` 原始输出:`:mode mode sha sha status NUL path NUL` 重复。 */\nfunction parseDiffTree(section: Buffer, label: string): DiffTreeEntry[] {\n const parts = section.toString(\"utf8\").split(\"\\0\");\n const entries: DiffTreeEntry[] = [];\n for (let i = 0; i < parts.length;) {\n const meta = parts[i++];\n if (!meta)\n continue;\n const path = parts[i++];\n const fields = meta.split(\" \");\n if (path === undefined || fields.length !== 5 || !fields[0]!.startsWith(\":\")) {\n throw new Error(`export window ${label}: malformed git diff-tree output`);\n }\n const code = fields[4]!;\n const status = code.startsWith(\"A\") ? \"added\" : code.startsWith(\"D\") ? \"deleted\" : \"modified\";\n entries.push({ path, status, beforeSha: fields[2]!, afterSha: fields[3]! });\n }\n return entries;\n}\n/** `git diff-tree --numstat -z`:二进制条目的 added/removed 计数是 `-`。 */\nfunction parseBinaryPaths(section: Buffer, label: string): Set<string> {\n const paths = new Set<string>();\n for (const record of section.toString(\"utf8\").split(\"\\0\")) {\n if (!record)\n continue;\n const firstTab = record.indexOf(\"\\t\");\n const secondTab = record.indexOf(\"\\t\", firstTab + 1);\n if (firstTab === -1 || secondTab === -1)\n throw new Error(`export window ${label}: malformed git --numstat output`);\n if (record.slice(0, firstTab) === \"-\" && record.slice(firstTab + 1, secondTab) === \"-\") {\n paths.add(record.slice(secondTab + 1));\n }\n }\n return paths;\n}\n/** `git cat-file --batch-check`:每行 `sha type size`(输入是逐出现次数的 sha,重复无害)。 */\nfunction parseSizes(section: Buffer, label: string): Map<string, number> {\n const sizes = new Map<string, number>();\n for (const line of section.toString(\"utf8\").split(\"\\n\")) {\n if (!line)\n continue;\n const fields = line.split(\" \");\n const size = Number(fields[fields.length - 1]);\n if (fields.length < 3 || !isNonNegativeInteger(size)) {\n throw new Error(`export window ${label}: malformed git cat-file --batch-check output`);\n }\n sizes.set(fields[0]!, size);\n }\n return sizes;\n}\n/** `git cat-file --batch`:自带长度帧——`sha type size\\n` + size 字节内容 + `\\n`。 */\nfunction parseBlobBatch(section: Buffer, label: string): Map<string, string> {\n const contents = new Map<string, string>();\n let offset = 0;\n while (offset < section.length) {\n const newline = section.indexOf(0x0a, offset);\n if (newline === -1)\n throw new Error(`export window ${label}: malformed git cat-file --batch header`);\n const fields = section.subarray(offset, newline).toString(\"utf8\").split(\" \");\n const size = Number(fields[fields.length - 1]);\n if (fields.length < 3 || !isNonNegativeInteger(size)) {\n throw new Error(`export window ${label}: malformed git cat-file --batch header`);\n }\n const contentStart = newline + 1;\n const contentEnd = contentStart + size;\n if (contentEnd >= section.length || section[contentEnd] !== 0x0a) {\n throw new Error(`export window ${label}: truncated git cat-file --batch content`);\n }\n contents.set(fields[0]!, section.subarray(contentStart, contentEnd).toString(\"utf8\"));\n offset = contentEnd + 1;\n }\n return contents;\n}\nfunction requireSize(sizes: Map<string, number>, sha: string, label: string, path: string): number {\n const size = sizes.get(sha);\n if (size === undefined || ZERO_SHA.test(sha))\n throw new Error(`export window ${label}: missing blob size for ${JSON.stringify(path)}`);\n return size;\n}\nfunction requireContent(contents: Map<string, string>, sha: string, label: string, path: string): string {\n const content = contents.get(sha);\n if (content === undefined || ZERO_SHA.test(sha))\n throw new Error(`export window ${label}: missing blob content for ${JSON.stringify(path)}`);\n return content;\n}\nfunction isNonNegativeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n"]}