@prismatic-io/lux 0.0.2-preview.3 → 0.0.2-preview.32

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 (727) hide show
  1. package/lib/answerers/claude-code/index.d.ts +15 -3
  2. package/lib/answerers/claude-code/index.d.ts.map +1 -1
  3. package/lib/answerers/claude-code/index.js +6 -5
  4. package/lib/answerers/claude-code/index.js.map +1 -1
  5. package/lib/answerers/persona/index.d.ts +44 -5
  6. package/lib/answerers/persona/index.d.ts.map +1 -1
  7. package/lib/answerers/persona/index.js +60 -34
  8. package/lib/answerers/persona/index.js.map +1 -1
  9. package/lib/answerers/terminal/index.d.ts +9 -3
  10. package/lib/answerers/terminal/index.d.ts.map +1 -1
  11. package/lib/answerers/terminal/index.js +7 -5
  12. package/lib/answerers/terminal/index.js.map +1 -1
  13. package/lib/assertions/authoring.d.ts +2 -2
  14. package/lib/assertions/authoring.d.ts.map +1 -1
  15. package/lib/assertions/authoring.js.map +1 -1
  16. package/lib/assertions/core/command-exits-zero.d.ts +4 -1
  17. package/lib/assertions/core/command-exits-zero.d.ts.map +1 -1
  18. package/lib/assertions/core/command-exits-zero.js +50 -7
  19. package/lib/assertions/core/command-exits-zero.js.map +1 -1
  20. package/lib/assertions/core/event-checks.d.ts +3 -0
  21. package/lib/assertions/core/event-checks.d.ts.map +1 -1
  22. package/lib/assertions/core/event-checks.js +49 -3
  23. package/lib/assertions/core/event-checks.js.map +1 -1
  24. package/lib/assertions/core/file-checks.d.ts +6 -0
  25. package/lib/assertions/core/file-checks.d.ts.map +1 -1
  26. package/lib/assertions/core/helpers.d.ts +2 -7
  27. package/lib/assertions/core/helpers.d.ts.map +1 -1
  28. package/lib/assertions/core/helpers.js +2 -6
  29. package/lib/assertions/core/helpers.js.map +1 -1
  30. package/lib/assertions/core/index.d.ts.map +1 -1
  31. package/lib/assertions/core/index.js +2 -1
  32. package/lib/assertions/core/index.js.map +1 -1
  33. package/lib/assertions/core/json-pointer-equals.d.ts +1 -0
  34. package/lib/assertions/core/json-pointer-equals.d.ts.map +1 -1
  35. package/lib/assertions/core/output-checks.d.ts +3 -0
  36. package/lib/assertions/core/output-checks.d.ts.map +1 -1
  37. package/lib/assertions/core/predicate.d.ts +1 -0
  38. package/lib/assertions/core/predicate.d.ts.map +1 -1
  39. package/lib/assertions/core/resource-checks.d.ts +25 -0
  40. package/lib/assertions/core/resource-checks.d.ts.map +1 -1
  41. package/lib/assertions/core/resource-checks.js +35 -5
  42. package/lib/assertions/core/resource-checks.js.map +1 -1
  43. package/lib/assertions/rubric/index.d.ts +28 -3
  44. package/lib/assertions/rubric/index.d.ts.map +1 -1
  45. package/lib/assertions/rubric/index.js +59 -13
  46. package/lib/assertions/rubric/index.js.map +1 -1
  47. package/lib/assertions/rubric/internal.d.ts +30 -5
  48. package/lib/assertions/rubric/internal.d.ts.map +1 -1
  49. package/lib/assertions/rubric/internal.js +181 -28
  50. package/lib/assertions/rubric/internal.js.map +1 -1
  51. package/lib/authoring.d.ts +36 -2
  52. package/lib/authoring.d.ts.map +1 -1
  53. package/lib/authoring.js +36 -1
  54. package/lib/authoring.js.map +1 -1
  55. package/lib/cli/bin.js +2 -13
  56. package/lib/cli/bin.js.map +1 -1
  57. package/lib/cli/command-runtime.d.ts +3 -3
  58. package/lib/cli/command-runtime.d.ts.map +1 -1
  59. package/lib/cli/command-runtime.js +17 -6
  60. package/lib/cli/command-runtime.js.map +1 -1
  61. package/lib/cli/doctor.d.ts +55 -0
  62. package/lib/cli/doctor.d.ts.map +1 -0
  63. package/lib/cli/doctor.js +14 -0
  64. package/lib/cli/doctor.js.map +1 -0
  65. package/lib/cli/harness-plan.d.ts +26 -0
  66. package/lib/cli/harness-plan.d.ts.map +1 -0
  67. package/lib/cli/harness-plan.js +75 -0
  68. package/lib/cli/harness-plan.js.map +1 -0
  69. package/lib/cli/init-templates.d.ts +11 -0
  70. package/lib/cli/init-templates.d.ts.map +1 -0
  71. package/lib/cli/init-templates.js +215 -0
  72. package/lib/cli/init-templates.js.map +1 -0
  73. package/lib/cli/init.d.ts +10 -0
  74. package/lib/cli/init.d.ts.map +1 -1
  75. package/lib/cli/init.js +34 -173
  76. package/lib/cli/init.js.map +1 -1
  77. package/lib/cli/output-schemas.d.ts +1408 -0
  78. package/lib/cli/output-schemas.d.ts.map +1 -0
  79. package/lib/cli/output-schemas.js +91 -0
  80. package/lib/cli/output-schemas.js.map +1 -0
  81. package/lib/cli/program.d.ts +140 -12
  82. package/lib/cli/program.d.ts.map +1 -1
  83. package/lib/cli/program.js +779 -646
  84. package/lib/cli/program.js.map +1 -1
  85. package/lib/cli/render/reporter.d.ts.map +1 -1
  86. package/lib/cli/render/reporter.js +48 -8
  87. package/lib/cli/render/reporter.js.map +1 -1
  88. package/lib/cli/run-options.d.ts +20 -4
  89. package/lib/cli/run-options.d.ts.map +1 -1
  90. package/lib/cli/run-options.js +100 -19
  91. package/lib/cli/run-options.js.map +1 -1
  92. package/lib/cli/view.d.ts +15 -0
  93. package/lib/cli/view.d.ts.map +1 -0
  94. package/lib/cli/view.js +168 -0
  95. package/lib/cli/view.js.map +1 -0
  96. package/lib/container/driver.d.ts +27 -0
  97. package/lib/container/driver.d.ts.map +1 -0
  98. package/lib/container/driver.js +197 -0
  99. package/lib/container/driver.js.map +1 -0
  100. package/lib/container/protocol.d.ts +12 -0
  101. package/lib/container/protocol.d.ts.map +1 -0
  102. package/lib/container/protocol.js +38 -0
  103. package/lib/container/protocol.js.map +1 -0
  104. package/lib/container/resources.d.ts +12 -0
  105. package/lib/container/resources.d.ts.map +1 -0
  106. package/lib/container/resources.js +133 -0
  107. package/lib/container/resources.js.map +1 -0
  108. package/lib/container/worker.d.ts +2 -0
  109. package/lib/container/worker.d.ts.map +1 -0
  110. package/lib/container/worker.js +85 -0
  111. package/lib/container/worker.js.map +1 -0
  112. package/lib/core/action-events.d.ts +29 -0
  113. package/lib/core/action-events.d.ts.map +1 -0
  114. package/lib/core/action-events.js +51 -0
  115. package/lib/core/action-events.js.map +1 -0
  116. package/lib/core/agent-activity.d.ts +49 -0
  117. package/lib/core/agent-activity.d.ts.map +1 -0
  118. package/lib/core/agent-activity.js +206 -0
  119. package/lib/core/agent-activity.js.map +1 -0
  120. package/lib/core/agent-environment.d.ts +5 -0
  121. package/lib/core/agent-environment.d.ts.map +1 -0
  122. package/lib/core/agent-environment.js +47 -0
  123. package/lib/core/agent-environment.js.map +1 -0
  124. package/lib/core/agent-events.d.ts +26 -0
  125. package/lib/core/agent-events.d.ts.map +1 -0
  126. package/lib/core/agent-events.js +13 -0
  127. package/lib/core/agent-events.js.map +1 -0
  128. package/lib/core/annotation.d.ts +6 -2
  129. package/lib/core/annotation.d.ts.map +1 -1
  130. package/lib/core/annotation.js +2 -1
  131. package/lib/core/annotation.js.map +1 -1
  132. package/lib/core/answerer.d.ts +12 -0
  133. package/lib/core/answerer.d.ts.map +1 -1
  134. package/lib/core/answerer.js +2 -0
  135. package/lib/core/answerer.js.map +1 -1
  136. package/lib/core/artifact-evidence.d.ts +8 -0
  137. package/lib/core/artifact-evidence.d.ts.map +1 -1
  138. package/lib/core/artifact-evidence.js +36 -4
  139. package/lib/core/artifact-evidence.js.map +1 -1
  140. package/lib/core/assertion.d.ts +20 -2
  141. package/lib/core/assertion.d.ts.map +1 -1
  142. package/lib/core/assertion.js +19 -1
  143. package/lib/core/assertion.js.map +1 -1
  144. package/lib/core/case.d.ts +111 -3
  145. package/lib/core/case.d.ts.map +1 -1
  146. package/lib/core/case.js +17 -2
  147. package/lib/core/case.js.map +1 -1
  148. package/lib/core/command-verification.d.ts +10 -0
  149. package/lib/core/command-verification.d.ts.map +1 -0
  150. package/lib/core/command-verification.js +66 -0
  151. package/lib/core/command-verification.js.map +1 -0
  152. package/lib/core/driver-execution.d.ts +83 -0
  153. package/lib/core/driver-execution.d.ts.map +1 -0
  154. package/lib/core/driver-execution.js +72 -0
  155. package/lib/core/driver-execution.js.map +1 -0
  156. package/lib/core/driver-metrics.d.ts +98 -0
  157. package/lib/core/driver-metrics.d.ts.map +1 -0
  158. package/lib/core/driver-metrics.js +36 -0
  159. package/lib/core/driver-metrics.js.map +1 -0
  160. package/lib/core/driver.d.ts +64 -0
  161. package/lib/core/driver.d.ts.map +1 -1
  162. package/lib/core/driver.js +28 -0
  163. package/lib/core/driver.js.map +1 -1
  164. package/lib/core/duration.d.ts +5 -0
  165. package/lib/core/duration.d.ts.map +1 -0
  166. package/lib/core/duration.js +49 -0
  167. package/lib/core/duration.js.map +1 -0
  168. package/lib/core/environment.d.ts +18 -0
  169. package/lib/core/environment.d.ts.map +1 -0
  170. package/lib/core/environment.js +21 -0
  171. package/lib/core/environment.js.map +1 -0
  172. package/lib/core/evaluation-clusters.d.ts +17 -0
  173. package/lib/core/evaluation-clusters.d.ts.map +1 -0
  174. package/lib/core/evaluation-clusters.js +23 -0
  175. package/lib/core/evaluation-clusters.js.map +1 -0
  176. package/lib/core/events.d.ts +36 -0
  177. package/lib/core/events.d.ts.map +1 -1
  178. package/lib/core/events.js +12 -2
  179. package/lib/core/events.js.map +1 -1
  180. package/lib/core/experiment.d.ts +32 -2
  181. package/lib/core/experiment.d.ts.map +1 -1
  182. package/lib/core/experiment.js +35 -18
  183. package/lib/core/experiment.js.map +1 -1
  184. package/lib/core/file-tree.d.ts +7 -0
  185. package/lib/core/file-tree.d.ts.map +1 -0
  186. package/lib/core/file-tree.js +35 -0
  187. package/lib/core/file-tree.js.map +1 -0
  188. package/lib/core/global-id.d.ts +6 -0
  189. package/lib/core/global-id.d.ts.map +1 -0
  190. package/lib/core/global-id.js +17 -0
  191. package/lib/core/global-id.js.map +1 -0
  192. package/lib/core/harness-catalog.d.ts +35 -0
  193. package/lib/core/harness-catalog.d.ts.map +1 -0
  194. package/lib/core/harness-catalog.js +45 -0
  195. package/lib/core/harness-catalog.js.map +1 -0
  196. package/lib/core/harness-catalogs/antigravity.d.ts +11 -0
  197. package/lib/core/harness-catalogs/antigravity.d.ts.map +1 -0
  198. package/lib/core/harness-catalogs/antigravity.js +23 -0
  199. package/lib/core/harness-catalogs/antigravity.js.map +1 -0
  200. package/lib/core/harness-catalogs/claude-code.d.ts +12 -0
  201. package/lib/core/harness-catalogs/claude-code.d.ts.map +1 -0
  202. package/lib/core/harness-catalogs/claude-code.js +24 -0
  203. package/lib/core/harness-catalogs/claude-code.js.map +1 -0
  204. package/lib/core/harness-catalogs/codex.d.ts +11 -0
  205. package/lib/core/harness-catalogs/codex.d.ts.map +1 -0
  206. package/lib/core/harness-catalogs/codex.js +26 -0
  207. package/lib/core/harness-catalogs/codex.js.map +1 -0
  208. package/lib/core/harness-catalogs/copilot.d.ts +29 -0
  209. package/lib/core/harness-catalogs/copilot.d.ts.map +1 -0
  210. package/lib/core/harness-catalogs/copilot.js +45 -0
  211. package/lib/core/harness-catalogs/copilot.js.map +1 -0
  212. package/lib/core/harness-catalogs/cursor.d.ts +2 -0
  213. package/lib/core/harness-catalogs/cursor.d.ts.map +1 -0
  214. package/lib/core/harness-catalogs/cursor.js +13 -0
  215. package/lib/core/harness-catalogs/cursor.js.map +1 -0
  216. package/lib/core/harness-catalogs/grok-build.d.ts +7 -0
  217. package/lib/core/harness-catalogs/grok-build.d.ts.map +1 -0
  218. package/lib/core/harness-catalogs/grok-build.js +18 -0
  219. package/lib/core/harness-catalogs/grok-build.js.map +1 -0
  220. package/lib/core/harness-catalogs/index.d.ts +73 -0
  221. package/lib/core/harness-catalogs/index.d.ts.map +1 -0
  222. package/lib/core/harness-catalogs/index.js +17 -0
  223. package/lib/core/harness-catalogs/index.js.map +1 -0
  224. package/lib/core/harness-matrix.d.ts +154 -0
  225. package/lib/core/harness-matrix.d.ts.map +1 -0
  226. package/lib/core/harness-matrix.js +204 -0
  227. package/lib/core/harness-matrix.js.map +1 -0
  228. package/lib/core/index.d.ts +12 -0
  229. package/lib/core/index.d.ts.map +1 -1
  230. package/lib/core/index.js +12 -0
  231. package/lib/core/index.js.map +1 -1
  232. package/lib/core/lifecycle-fixtures.d.ts.map +1 -1
  233. package/lib/core/lifecycle-fixtures.js +4 -2
  234. package/lib/core/lifecycle-fixtures.js.map +1 -1
  235. package/lib/core/model-cli.d.ts +9 -11
  236. package/lib/core/model-cli.d.ts.map +1 -1
  237. package/lib/core/model-cli.js +31 -19
  238. package/lib/core/model-cli.js.map +1 -1
  239. package/lib/core/platform-process.d.ts +6 -1
  240. package/lib/core/platform-process.d.ts.map +1 -1
  241. package/lib/core/platform-process.js +49 -11
  242. package/lib/core/platform-process.js.map +1 -1
  243. package/lib/core/rubric.d.ts +1 -0
  244. package/lib/core/rubric.d.ts.map +1 -1
  245. package/lib/core/run.d.ts +293 -1
  246. package/lib/core/run.d.ts.map +1 -1
  247. package/lib/core/run.js +27 -0
  248. package/lib/core/run.js.map +1 -1
  249. package/lib/core/secure-copy.d.ts.map +1 -0
  250. package/lib/core/secure-copy.js.map +1 -0
  251. package/lib/core/usage.d.ts +5 -0
  252. package/lib/core/usage.d.ts.map +1 -1
  253. package/lib/core/usage.js +3 -0
  254. package/lib/core/usage.js.map +1 -1
  255. package/lib/core/wire.d.ts +12 -0
  256. package/lib/core/wire.d.ts.map +1 -1
  257. package/lib/core/wire.js +5 -1
  258. package/lib/core/wire.js.map +1 -1
  259. package/lib/drivers/antigravity/artifacts.d.ts +2 -0
  260. package/lib/drivers/antigravity/artifacts.d.ts.map +1 -0
  261. package/lib/drivers/antigravity/artifacts.js +33 -0
  262. package/lib/drivers/antigravity/artifacts.js.map +1 -0
  263. package/lib/drivers/antigravity/config.d.ts +88 -0
  264. package/lib/drivers/antigravity/config.d.ts.map +1 -0
  265. package/lib/drivers/antigravity/config.js +87 -0
  266. package/lib/drivers/antigravity/config.js.map +1 -0
  267. package/lib/drivers/antigravity/events.d.ts +4 -0
  268. package/lib/drivers/antigravity/events.d.ts.map +1 -0
  269. package/lib/drivers/antigravity/events.js +241 -0
  270. package/lib/drivers/antigravity/events.js.map +1 -0
  271. package/lib/drivers/antigravity/index.d.ts +114 -0
  272. package/lib/drivers/antigravity/index.d.ts.map +1 -0
  273. package/lib/drivers/antigravity/index.js +113 -0
  274. package/lib/drivers/antigravity/index.js.map +1 -0
  275. package/lib/drivers/antigravity/runtime.d.ts +7 -0
  276. package/lib/drivers/antigravity/runtime.d.ts.map +1 -0
  277. package/lib/drivers/antigravity/runtime.js +83 -0
  278. package/lib/drivers/antigravity/runtime.js.map +1 -0
  279. package/lib/drivers/claude-code/deferred-process.d.ts +17 -0
  280. package/lib/drivers/claude-code/deferred-process.d.ts.map +1 -0
  281. package/lib/drivers/claude-code/deferred-process.js +108 -0
  282. package/lib/drivers/claude-code/deferred-process.js.map +1 -0
  283. package/lib/drivers/claude-code/index.d.ts +180 -10
  284. package/lib/drivers/claude-code/index.d.ts.map +1 -1
  285. package/lib/drivers/claude-code/index.js +186 -252
  286. package/lib/drivers/claude-code/index.js.map +1 -1
  287. package/lib/drivers/claude-code/isolation.d.ts +8 -0
  288. package/lib/drivers/claude-code/isolation.d.ts.map +1 -0
  289. package/lib/drivers/claude-code/isolation.js +199 -0
  290. package/lib/drivers/claude-code/isolation.js.map +1 -0
  291. package/lib/drivers/claude-code/parse-events.d.ts.map +1 -1
  292. package/lib/drivers/claude-code/parse-events.js +73 -8
  293. package/lib/drivers/claude-code/parse-events.js.map +1 -1
  294. package/lib/drivers/codex/app-events.d.ts +9 -2
  295. package/lib/drivers/codex/app-events.d.ts.map +1 -1
  296. package/lib/drivers/codex/app-events.js +104 -12
  297. package/lib/drivers/codex/app-events.js.map +1 -1
  298. package/lib/drivers/codex/config.d.ts +66 -5
  299. package/lib/drivers/codex/config.d.ts.map +1 -1
  300. package/lib/drivers/codex/config.js +39 -8
  301. package/lib/drivers/codex/config.js.map +1 -1
  302. package/lib/drivers/codex/exec-events.d.ts +4 -0
  303. package/lib/drivers/codex/exec-events.d.ts.map +1 -0
  304. package/lib/drivers/codex/exec-events.js +230 -0
  305. package/lib/drivers/codex/exec-events.js.map +1 -0
  306. package/lib/drivers/codex/index.d.ts +138 -4
  307. package/lib/drivers/codex/index.d.ts.map +1 -1
  308. package/lib/drivers/codex/index.js +112 -276
  309. package/lib/drivers/codex/index.js.map +1 -1
  310. package/lib/drivers/copilot/config.d.ts +84 -0
  311. package/lib/drivers/copilot/config.d.ts.map +1 -0
  312. package/lib/drivers/copilot/config.js +57 -0
  313. package/lib/drivers/copilot/config.js.map +1 -0
  314. package/lib/drivers/copilot/index.d.ts +107 -0
  315. package/lib/drivers/copilot/index.d.ts.map +1 -0
  316. package/lib/drivers/copilot/index.js +268 -0
  317. package/lib/drivers/copilot/index.js.map +1 -0
  318. package/lib/drivers/cursor/config.d.ts +28 -0
  319. package/lib/drivers/cursor/config.d.ts.map +1 -0
  320. package/lib/drivers/cursor/config.js +28 -0
  321. package/lib/drivers/cursor/config.js.map +1 -0
  322. package/lib/drivers/cursor/index.d.ts +44 -0
  323. package/lib/drivers/cursor/index.d.ts.map +1 -0
  324. package/lib/drivers/cursor/index.js +286 -0
  325. package/lib/drivers/cursor/index.js.map +1 -0
  326. package/lib/drivers/cursor/interaction.d.ts +6 -0
  327. package/lib/drivers/cursor/interaction.d.ts.map +1 -0
  328. package/lib/drivers/cursor/interaction.js +55 -0
  329. package/lib/drivers/cursor/interaction.js.map +1 -0
  330. package/lib/drivers/grok-build/config.d.ts +68 -0
  331. package/lib/drivers/grok-build/config.d.ts.map +1 -0
  332. package/lib/drivers/grok-build/config.js +40 -0
  333. package/lib/drivers/grok-build/config.js.map +1 -0
  334. package/lib/drivers/grok-build/index.d.ts +87 -0
  335. package/lib/drivers/grok-build/index.d.ts.map +1 -0
  336. package/lib/drivers/grok-build/index.js +293 -0
  337. package/lib/drivers/grok-build/index.js.map +1 -0
  338. package/lib/drivers/mcp/index.d.ts +37 -4
  339. package/lib/drivers/mcp/index.d.ts.map +1 -1
  340. package/lib/drivers/mcp/index.js +25 -11
  341. package/lib/drivers/mcp/index.js.map +1 -1
  342. package/lib/drivers/shared/acp-events.d.ts +15 -0
  343. package/lib/drivers/shared/acp-events.d.ts.map +1 -0
  344. package/lib/drivers/shared/acp-events.js +83 -0
  345. package/lib/drivers/shared/acp-events.js.map +1 -0
  346. package/lib/drivers/shared/acp-interaction.d.ts +7 -0
  347. package/lib/drivers/shared/acp-interaction.d.ts.map +1 -0
  348. package/lib/drivers/shared/acp-interaction.js +20 -0
  349. package/lib/drivers/shared/acp-interaction.js.map +1 -0
  350. package/lib/drivers/shared/acp-session.d.ts +4 -0
  351. package/lib/drivers/shared/acp-session.d.ts.map +1 -0
  352. package/lib/drivers/shared/acp-session.js +23 -0
  353. package/lib/drivers/shared/acp-session.js.map +1 -0
  354. package/lib/drivers/shared/acp-transport.d.ts +40 -0
  355. package/lib/drivers/shared/acp-transport.d.ts.map +1 -0
  356. package/lib/drivers/shared/acp-transport.js +152 -0
  357. package/lib/drivers/shared/acp-transport.js.map +1 -0
  358. package/lib/drivers/shared/artifacts.d.ts.map +1 -1
  359. package/lib/drivers/shared/artifacts.js +3 -2
  360. package/lib/drivers/shared/artifacts.js.map +1 -1
  361. package/lib/drivers/shared/experiment-behavior.d.ts +13 -0
  362. package/lib/drivers/shared/experiment-behavior.d.ts.map +1 -0
  363. package/lib/drivers/shared/experiment-behavior.js +197 -0
  364. package/lib/drivers/shared/experiment-behavior.js.map +1 -0
  365. package/lib/drivers/shared/experiment-policy.d.ts +4 -0
  366. package/lib/drivers/shared/experiment-policy.d.ts.map +1 -0
  367. package/lib/drivers/shared/experiment-policy.js +143 -0
  368. package/lib/drivers/shared/experiment-policy.js.map +1 -0
  369. package/lib/drivers/subprocess/index.d.ts +39 -4
  370. package/lib/drivers/subprocess/index.d.ts.map +1 -1
  371. package/lib/drivers/subprocess/index.js +56 -12
  372. package/lib/drivers/subprocess/index.js.map +1 -1
  373. package/lib/index.d.ts +22 -8
  374. package/lib/index.d.ts.map +1 -1
  375. package/lib/index.js +20 -6
  376. package/lib/index.js.map +1 -1
  377. package/lib/optimization/reflective.d.ts +3 -1
  378. package/lib/optimization/reflective.d.ts.map +1 -1
  379. package/lib/optimization/reflective.js +3 -2
  380. package/lib/optimization/reflective.js.map +1 -1
  381. package/lib/orchestrator/annotation-loader.d.ts +6 -2
  382. package/lib/orchestrator/annotation-loader.d.ts.map +1 -1
  383. package/lib/orchestrator/annotation-loader.js +8 -0
  384. package/lib/orchestrator/annotation-loader.js.map +1 -1
  385. package/lib/orchestrator/annotation-store.d.ts.map +1 -1
  386. package/lib/orchestrator/annotation-store.js +16 -2
  387. package/lib/orchestrator/annotation-store.js.map +1 -1
  388. package/lib/orchestrator/artifact-origin.d.ts +3 -0
  389. package/lib/orchestrator/artifact-origin.d.ts.map +1 -0
  390. package/lib/orchestrator/artifact-origin.js +40 -0
  391. package/lib/orchestrator/artifact-origin.js.map +1 -0
  392. package/lib/orchestrator/campaign-lifecycle.d.ts +1 -0
  393. package/lib/orchestrator/campaign-lifecycle.d.ts.map +1 -1
  394. package/lib/orchestrator/campaign-lifecycle.js +4 -1
  395. package/lib/orchestrator/campaign-lifecycle.js.map +1 -1
  396. package/lib/orchestrator/candidates.d.ts.map +1 -1
  397. package/lib/orchestrator/candidates.js +3 -2
  398. package/lib/orchestrator/candidates.js.map +1 -1
  399. package/lib/orchestrator/compare.d.ts +19 -3
  400. package/lib/orchestrator/compare.d.ts.map +1 -1
  401. package/lib/orchestrator/compare.js +32 -6
  402. package/lib/orchestrator/compare.js.map +1 -1
  403. package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
  404. package/lib/orchestrator/comparison-identity.js +2 -0
  405. package/lib/orchestrator/comparison-identity.js.map +1 -1
  406. package/lib/orchestrator/config.d.ts +179 -1
  407. package/lib/orchestrator/config.d.ts.map +1 -1
  408. package/lib/orchestrator/config.js +18 -4
  409. package/lib/orchestrator/config.js.map +1 -1
  410. package/lib/orchestrator/discover.d.ts +1 -0
  411. package/lib/orchestrator/discover.d.ts.map +1 -1
  412. package/lib/orchestrator/discover.js +7 -1
  413. package/lib/orchestrator/discover.js.map +1 -1
  414. package/lib/orchestrator/doctor.d.ts +1 -0
  415. package/lib/orchestrator/doctor.d.ts.map +1 -1
  416. package/lib/orchestrator/doctor.js +121 -33
  417. package/lib/orchestrator/doctor.js.map +1 -1
  418. package/lib/orchestrator/driver-capabilities.d.ts +4 -0
  419. package/lib/orchestrator/driver-capabilities.d.ts.map +1 -0
  420. package/lib/orchestrator/driver-capabilities.js +13 -0
  421. package/lib/orchestrator/driver-capabilities.js.map +1 -0
  422. package/lib/orchestrator/driver-identity.d.ts +5 -0
  423. package/lib/orchestrator/driver-identity.d.ts.map +1 -0
  424. package/lib/orchestrator/driver-identity.js +51 -0
  425. package/lib/orchestrator/driver-identity.js.map +1 -0
  426. package/lib/orchestrator/experiment-context.d.ts +51 -3
  427. package/lib/orchestrator/experiment-context.d.ts.map +1 -1
  428. package/lib/orchestrator/experiment-context.js.map +1 -1
  429. package/lib/orchestrator/experiment-contracts.d.ts +30 -1
  430. package/lib/orchestrator/experiment-contracts.d.ts.map +1 -1
  431. package/lib/orchestrator/experiment-corpus.d.ts +2 -1
  432. package/lib/orchestrator/experiment-corpus.d.ts.map +1 -1
  433. package/lib/orchestrator/experiment-corpus.js +28 -22
  434. package/lib/orchestrator/experiment-corpus.js.map +1 -1
  435. package/lib/orchestrator/experiment-effects.d.ts +33 -0
  436. package/lib/orchestrator/experiment-effects.d.ts.map +1 -0
  437. package/lib/orchestrator/experiment-effects.js +44 -0
  438. package/lib/orchestrator/experiment-effects.js.map +1 -0
  439. package/lib/orchestrator/experiment-evaluation.d.ts.map +1 -1
  440. package/lib/orchestrator/experiment-evaluation.js +56 -5
  441. package/lib/orchestrator/experiment-evaluation.js.map +1 -1
  442. package/lib/orchestrator/experiment-identity.d.ts +3 -0
  443. package/lib/orchestrator/experiment-identity.d.ts.map +1 -1
  444. package/lib/orchestrator/experiment-identity.js +22 -33
  445. package/lib/orchestrator/experiment-identity.js.map +1 -1
  446. package/lib/orchestrator/experiment-loader.d.ts +8 -3
  447. package/lib/orchestrator/experiment-loader.d.ts.map +1 -1
  448. package/lib/orchestrator/experiment-preflight.d.ts +3 -0
  449. package/lib/orchestrator/experiment-preflight.d.ts.map +1 -0
  450. package/lib/orchestrator/experiment-preflight.js +21 -0
  451. package/lib/orchestrator/experiment-preflight.js.map +1 -0
  452. package/lib/orchestrator/experiment-report.d.ts +90 -1
  453. package/lib/orchestrator/experiment-report.d.ts.map +1 -1
  454. package/lib/orchestrator/experiment-report.js +9 -1
  455. package/lib/orchestrator/experiment-report.js.map +1 -1
  456. package/lib/orchestrator/experiment-runs.d.ts +61 -2
  457. package/lib/orchestrator/experiment-runs.d.ts.map +1 -1
  458. package/lib/orchestrator/experiment-runs.js +13 -5
  459. package/lib/orchestrator/experiment-runs.js.map +1 -1
  460. package/lib/orchestrator/experiment-runtime-identity.d.ts +0 -16
  461. package/lib/orchestrator/experiment-runtime-identity.d.ts.map +1 -1
  462. package/lib/orchestrator/experiment-runtime-identity.js +5 -220
  463. package/lib/orchestrator/experiment-runtime-identity.js.map +1 -1
  464. package/lib/orchestrator/experiment-selection.d.ts.map +1 -1
  465. package/lib/orchestrator/experiment-selection.js +52 -0
  466. package/lib/orchestrator/experiment-selection.js.map +1 -1
  467. package/lib/orchestrator/experiment.d.ts +3 -3
  468. package/lib/orchestrator/experiment.d.ts.map +1 -1
  469. package/lib/orchestrator/experiment.js +26 -21
  470. package/lib/orchestrator/experiment.js.map +1 -1
  471. package/lib/orchestrator/fixture-identity.d.ts +1 -0
  472. package/lib/orchestrator/fixture-identity.d.ts.map +1 -1
  473. package/lib/orchestrator/fixture-identity.js +6 -1
  474. package/lib/orchestrator/fixture-identity.js.map +1 -1
  475. package/lib/orchestrator/fs-read.d.ts +1 -6
  476. package/lib/orchestrator/fs-read.d.ts.map +1 -1
  477. package/lib/orchestrator/fs-read.js +2 -32
  478. package/lib/orchestrator/fs-read.js.map +1 -1
  479. package/lib/orchestrator/grader-experiment.d.ts +33 -3
  480. package/lib/orchestrator/grader-experiment.d.ts.map +1 -1
  481. package/lib/orchestrator/grader-experiment.js +54 -9
  482. package/lib/orchestrator/grader-experiment.js.map +1 -1
  483. package/lib/orchestrator/grading.d.ts +2 -1
  484. package/lib/orchestrator/grading.d.ts.map +1 -1
  485. package/lib/orchestrator/grading.js +46 -31
  486. package/lib/orchestrator/grading.js.map +1 -1
  487. package/lib/orchestrator/harness-catalog-drift.d.ts +22 -0
  488. package/lib/orchestrator/harness-catalog-drift.d.ts.map +1 -0
  489. package/lib/orchestrator/harness-catalog-drift.js +90 -0
  490. package/lib/orchestrator/harness-catalog-drift.js.map +1 -0
  491. package/lib/orchestrator/harness-registry.d.ts +4 -0
  492. package/lib/orchestrator/harness-registry.d.ts.map +1 -0
  493. package/lib/orchestrator/harness-registry.js +5 -0
  494. package/lib/orchestrator/harness-registry.js.map +1 -0
  495. package/lib/orchestrator/index.d.ts +1 -1
  496. package/lib/orchestrator/index.d.ts.map +1 -1
  497. package/lib/orchestrator/index.js +1 -1
  498. package/lib/orchestrator/index.js.map +1 -1
  499. package/lib/orchestrator/list-runs.d.ts +8 -1
  500. package/lib/orchestrator/list-runs.d.ts.map +1 -1
  501. package/lib/orchestrator/list-runs.js +81 -14
  502. package/lib/orchestrator/list-runs.js.map +1 -1
  503. package/lib/orchestrator/optimization-lifecycle.d.ts.map +1 -1
  504. package/lib/orchestrator/optimization-lifecycle.js +3 -1
  505. package/lib/orchestrator/optimization-lifecycle.js.map +1 -1
  506. package/lib/orchestrator/orchestrator.d.ts +18 -2
  507. package/lib/orchestrator/orchestrator.d.ts.map +1 -1
  508. package/lib/orchestrator/orchestrator.js +50 -168
  509. package/lib/orchestrator/orchestrator.js.map +1 -1
  510. package/lib/orchestrator/paired-effects.d.ts +34 -0
  511. package/lib/orchestrator/paired-effects.d.ts.map +1 -0
  512. package/lib/orchestrator/paired-effects.js +158 -0
  513. package/lib/orchestrator/paired-effects.js.map +1 -0
  514. package/lib/orchestrator/provenance.d.ts +5 -1
  515. package/lib/orchestrator/provenance.d.ts.map +1 -1
  516. package/lib/orchestrator/provenance.js +16 -3
  517. package/lib/orchestrator/provenance.js.map +1 -1
  518. package/lib/orchestrator/regrade.d.ts +9 -1
  519. package/lib/orchestrator/regrade.d.ts.map +1 -1
  520. package/lib/orchestrator/rubric-loader.js +1 -1
  521. package/lib/orchestrator/rubric-loader.js.map +1 -1
  522. package/lib/orchestrator/run-dir.d.ts +2 -0
  523. package/lib/orchestrator/run-dir.d.ts.map +1 -1
  524. package/lib/orchestrator/run-dir.js +1 -1
  525. package/lib/orchestrator/run-dir.js.map +1 -1
  526. package/lib/orchestrator/run-execution.d.ts +3 -0
  527. package/lib/orchestrator/run-execution.d.ts.map +1 -1
  528. package/lib/orchestrator/run-execution.js +66 -12
  529. package/lib/orchestrator/run-execution.js.map +1 -1
  530. package/lib/orchestrator/run-lifecycle.d.ts +1 -0
  531. package/lib/orchestrator/run-lifecycle.d.ts.map +1 -1
  532. package/lib/orchestrator/run-lifecycle.js +3 -2
  533. package/lib/orchestrator/run-lifecycle.js.map +1 -1
  534. package/lib/orchestrator/run-workspace.d.ts +10 -0
  535. package/lib/orchestrator/run-workspace.d.ts.map +1 -0
  536. package/lib/orchestrator/run-workspace.js +58 -0
  537. package/lib/orchestrator/run-workspace.js.map +1 -0
  538. package/lib/orchestrator/suite-compare.d.ts +37 -0
  539. package/lib/orchestrator/suite-compare.d.ts.map +1 -1
  540. package/lib/orchestrator/suite-compare.js +27 -17
  541. package/lib/orchestrator/suite-compare.js.map +1 -1
  542. package/lib/orchestrator/suite-runs.d.ts +6 -1
  543. package/lib/orchestrator/suite-runs.d.ts.map +1 -1
  544. package/lib/orchestrator/suite-runs.js +14 -2
  545. package/lib/orchestrator/suite-runs.js.map +1 -1
  546. package/lib/orchestrator/suite-summary.d.ts +77 -0
  547. package/lib/orchestrator/suite-summary.d.ts.map +1 -1
  548. package/lib/orchestrator/suite-summary.js +61 -12
  549. package/lib/orchestrator/suite-summary.js.map +1 -1
  550. package/lib/previewer/artifacts.d.ts +25 -0
  551. package/lib/previewer/artifacts.d.ts.map +1 -0
  552. package/lib/previewer/artifacts.js +180 -0
  553. package/lib/previewer/artifacts.js.map +1 -0
  554. package/lib/previewer/server.d.ts +111 -0
  555. package/lib/previewer/server.d.ts.map +1 -0
  556. package/lib/previewer/server.js +558 -0
  557. package/lib/previewer/server.js.map +1 -0
  558. package/package.json +3 -3
  559. package/skills/lux-answerer/SKILL.md +2 -2
  560. package/src/answerers/claude-code/index.ts +6 -5
  561. package/src/answerers/persona/index.ts +75 -34
  562. package/src/answerers/terminal/index.ts +8 -12
  563. package/src/assertions/authoring.ts +2 -0
  564. package/src/assertions/core/command-exits-zero.ts +61 -7
  565. package/src/assertions/core/event-checks.ts +64 -3
  566. package/src/assertions/core/helpers.ts +3 -6
  567. package/src/assertions/core/index.ts +2 -0
  568. package/src/assertions/core/resource-checks.ts +38 -5
  569. package/src/assertions/rubric/index.ts +68 -13
  570. package/src/assertions/rubric/internal.ts +227 -27
  571. package/src/authoring.ts +345 -2
  572. package/src/cli/bin.ts +2 -12
  573. package/src/cli/command-runtime.ts +20 -9
  574. package/src/cli/doctor.ts +17 -0
  575. package/src/cli/harness-plan.ts +117 -0
  576. package/src/cli/init-templates.ts +238 -0
  577. package/src/cli/init.ts +53 -184
  578. package/src/cli/output-schemas.ts +106 -0
  579. package/src/cli/program.ts +691 -721
  580. package/src/cli/render/reporter.ts +50 -8
  581. package/src/cli/run-options.ts +132 -25
  582. package/src/cli/view.ts +129 -0
  583. package/src/container/driver.ts +211 -0
  584. package/src/container/protocol.ts +48 -0
  585. package/src/container/resources.ts +153 -0
  586. package/src/container/worker.ts +107 -0
  587. package/src/core/action-events.ts +59 -0
  588. package/src/core/agent-activity.ts +236 -0
  589. package/src/core/agent-environment.ts +64 -0
  590. package/src/core/agent-events.ts +17 -0
  591. package/src/core/annotation.ts +2 -1
  592. package/src/core/answerer.ts +9 -0
  593. package/src/core/artifact-evidence.ts +47 -4
  594. package/src/core/assertion.ts +21 -1
  595. package/src/core/case.ts +21 -3
  596. package/src/core/command-verification.ts +74 -0
  597. package/src/core/driver-execution.ts +84 -0
  598. package/src/core/driver-metrics.ts +51 -0
  599. package/src/core/driver.ts +76 -0
  600. package/src/core/duration.ts +52 -0
  601. package/src/core/environment.ts +22 -0
  602. package/src/core/evaluation-clusters.ts +35 -0
  603. package/src/core/events.ts +14 -2
  604. package/src/core/experiment.ts +64 -24
  605. package/src/core/file-tree.ts +35 -0
  606. package/src/core/global-id.ts +26 -0
  607. package/src/core/harness-catalog.ts +100 -0
  608. package/src/core/harness-catalogs/antigravity.ts +24 -0
  609. package/src/core/harness-catalogs/claude-code.ts +25 -0
  610. package/src/core/harness-catalogs/codex.ts +27 -0
  611. package/src/core/harness-catalogs/copilot.ts +46 -0
  612. package/src/core/harness-catalogs/cursor.ts +13 -0
  613. package/src/core/harness-catalogs/grok-build.ts +19 -0
  614. package/src/core/harness-catalogs/index.ts +31 -0
  615. package/src/core/harness-matrix.ts +316 -0
  616. package/src/core/index.ts +12 -0
  617. package/src/core/lifecycle-fixtures.ts +4 -2
  618. package/src/core/model-cli.ts +52 -23
  619. package/src/core/platform-process.ts +58 -10
  620. package/src/core/run.ts +31 -0
  621. package/src/core/usage.ts +8 -0
  622. package/src/core/wire.ts +5 -1
  623. package/src/drivers/antigravity/README.md +171 -0
  624. package/src/drivers/antigravity/artifacts.ts +37 -0
  625. package/src/drivers/antigravity/config.ts +92 -0
  626. package/src/drivers/antigravity/events.ts +290 -0
  627. package/src/drivers/antigravity/index.ts +132 -0
  628. package/src/drivers/antigravity/runtime.ts +94 -0
  629. package/src/drivers/claude-code/deferred-process.ts +118 -0
  630. package/src/drivers/claude-code/index.ts +216 -281
  631. package/src/drivers/claude-code/isolation.ts +228 -0
  632. package/src/drivers/claude-code/parse-events.ts +98 -12
  633. package/src/drivers/codex/app-events.ts +126 -16
  634. package/src/drivers/codex/config.ts +50 -8
  635. package/src/drivers/codex/exec-events.ts +258 -0
  636. package/src/drivers/codex/index.ts +144 -312
  637. package/src/drivers/copilot/README.md +60 -0
  638. package/src/drivers/copilot/config.ts +61 -0
  639. package/src/drivers/copilot/index.ts +310 -0
  640. package/src/drivers/cursor/README.md +66 -0
  641. package/src/drivers/cursor/config.ts +31 -0
  642. package/src/drivers/cursor/index.ts +326 -0
  643. package/src/drivers/cursor/interaction.ts +74 -0
  644. package/src/drivers/grok-build/README.md +112 -0
  645. package/src/drivers/grok-build/config.ts +43 -0
  646. package/src/drivers/grok-build/index.ts +331 -0
  647. package/src/drivers/mcp/index.ts +25 -11
  648. package/src/drivers/shared/acp-events.ts +94 -0
  649. package/src/drivers/shared/acp-interaction.ts +27 -0
  650. package/src/drivers/shared/acp-session.ts +40 -0
  651. package/src/drivers/shared/acp-transport.ts +187 -0
  652. package/src/drivers/shared/artifacts.ts +6 -2
  653. package/src/drivers/shared/experiment-behavior.ts +214 -0
  654. package/src/drivers/shared/experiment-policy.ts +195 -0
  655. package/src/drivers/subprocess/index.ts +55 -12
  656. package/src/index.ts +115 -10
  657. package/src/optimization/reflective.ts +3 -2
  658. package/src/orchestrator/annotation-loader.ts +10 -0
  659. package/src/orchestrator/annotation-store.ts +24 -3
  660. package/src/orchestrator/artifact-origin.ts +50 -0
  661. package/src/orchestrator/campaign-lifecycle.ts +5 -1
  662. package/src/orchestrator/candidates.ts +3 -2
  663. package/src/orchestrator/compare.ts +41 -6
  664. package/src/orchestrator/comparison-identity.ts +2 -0
  665. package/src/orchestrator/config.ts +20 -3
  666. package/src/orchestrator/discover.ts +8 -1
  667. package/src/orchestrator/doctor.ts +189 -28
  668. package/src/orchestrator/driver-capabilities.ts +21 -0
  669. package/src/orchestrator/driver-identity.ts +69 -0
  670. package/src/orchestrator/experiment-context.ts +3 -2
  671. package/src/orchestrator/experiment-corpus.ts +53 -37
  672. package/src/orchestrator/experiment-effects.ts +61 -0
  673. package/src/orchestrator/experiment-evaluation.ts +71 -10
  674. package/src/orchestrator/experiment-identity.ts +42 -48
  675. package/src/orchestrator/experiment-preflight.ts +27 -0
  676. package/src/orchestrator/experiment-report.ts +21 -1
  677. package/src/orchestrator/experiment-runs.ts +11 -4
  678. package/src/orchestrator/experiment-runtime-identity.ts +5 -243
  679. package/src/orchestrator/experiment-selection.ts +77 -0
  680. package/src/orchestrator/experiment.ts +29 -29
  681. package/src/orchestrator/fixture-identity.ts +9 -1
  682. package/src/orchestrator/fs-read.ts +2 -32
  683. package/src/orchestrator/grader-experiment.ts +74 -13
  684. package/src/orchestrator/grading.ts +67 -28
  685. package/src/orchestrator/harness-catalog-drift.ts +132 -0
  686. package/src/orchestrator/harness-registry.ts +12 -0
  687. package/src/orchestrator/index.ts +1 -0
  688. package/src/orchestrator/list-runs.ts +98 -13
  689. package/src/orchestrator/optimization-lifecycle.ts +4 -1
  690. package/src/orchestrator/orchestrator.ts +92 -216
  691. package/src/orchestrator/paired-effects.ts +209 -0
  692. package/src/orchestrator/provenance.ts +23 -3
  693. package/src/orchestrator/rubric-loader.ts +1 -1
  694. package/src/orchestrator/run-dir.ts +8 -1
  695. package/src/orchestrator/run-execution.ts +77 -11
  696. package/src/orchestrator/run-lifecycle.ts +4 -2
  697. package/src/orchestrator/run-workspace.ts +62 -0
  698. package/src/orchestrator/suite-compare.ts +29 -19
  699. package/src/orchestrator/suite-runs.ts +13 -2
  700. package/src/orchestrator/suite-summary.ts +122 -13
  701. package/src/previewer/artifacts.ts +221 -0
  702. package/src/previewer/server.ts +787 -0
  703. package/viewer/app.css +2079 -0
  704. package/viewer/app.js +627 -0
  705. package/viewer/artifact-view.js +48 -0
  706. package/viewer/charts.js +86 -0
  707. package/viewer/detail.js +1237 -0
  708. package/viewer/format.js +129 -0
  709. package/viewer/index.html +151 -0
  710. package/lib/answerers/scripted/index.d.ts +0 -8
  711. package/lib/answerers/scripted/index.d.ts.map +0 -1
  712. package/lib/answerers/scripted/index.js +0 -163
  713. package/lib/answerers/scripted/index.js.map +0 -1
  714. package/lib/cli/skills.d.ts +0 -38
  715. package/lib/cli/skills.d.ts.map +0 -1
  716. package/lib/cli/skills.js +0 -84
  717. package/lib/cli/skills.js.map +0 -1
  718. package/lib/drivers/shared/secure-copy.d.ts.map +0 -1
  719. package/lib/drivers/shared/secure-copy.js.map +0 -1
  720. package/skills/lux/SKILL.md +0 -85
  721. package/skills/lux/references/cli.md +0 -102
  722. package/skills/lux/references/eval-authoring.md +0 -105
  723. package/src/answerers/scripted/index.ts +0 -186
  724. package/src/cli/skills.ts +0 -129
  725. /package/lib/{drivers/shared → core}/secure-copy.d.ts +0 -0
  726. /package/lib/{drivers/shared → core}/secure-copy.js +0 -0
  727. /package/src/{drivers/shared → core}/secure-copy.ts +0 -0
@@ -86,6 +86,7 @@ export const ExperimentSelectionSchema = z.object({
86
86
  z.object({
87
87
  candidateId: CandidateIdSchema,
88
88
  metric: z.string(),
89
+ relativeTo: z.exactOptional(z.literal("baseline")),
89
90
  profile: z.exactOptional(z.string()),
90
91
  split: z.enum(["train", "validation", "test"]),
91
92
  values: z.array(z.number()),
@@ -738,6 +739,7 @@ export const resumeExperimentRun = async (path: string): Promise<OpenedExperimen
738
739
 
739
740
  export const listExperimentRuns = async (
740
741
  runsRoot: string,
742
+ options: { onReadError?: (path: string, error: unknown) => void } = {},
741
743
  ): Promise<Array<ExperimentRun & { experimentDir: string }>> => {
742
744
  const root = join(resolve(runsRoot), EXPERIMENTS_DIR);
743
745
  if (!existsSync(root)) return [];
@@ -745,10 +747,15 @@ export const listExperimentRuns = async (
745
747
  .filter((entry) => entry.isDirectory())
746
748
  .map((entry) => join(root, entry.name));
747
749
  const runs = await Promise.all(
748
- directories.map(async (experimentDir) => ({
749
- experimentDir,
750
- experiment: await loadExperimentRun(experimentDir),
751
- })),
750
+ directories.map(async (experimentDir) => {
751
+ try {
752
+ return { experimentDir, experiment: await loadExperimentRun(experimentDir) };
753
+ } catch (error) {
754
+ if (!options.onReadError) throw error;
755
+ options.onReadError(experimentDir, error);
756
+ return { experimentDir, experiment: null };
757
+ }
758
+ }),
752
759
  );
753
760
  return runs
754
761
  .flatMap(({ experimentDir, experiment }) =>
@@ -1,61 +1,14 @@
1
1
  import { createHash } from "node:crypto";
2
- import { access, constants, lstat, open, readFile, realpath } from "node:fs/promises";
3
- import { homedir } from "node:os";
2
+ import { access, constants, lstat, open, realpath } from "node:fs/promises";
4
3
  import { delimiter, isAbsolute, join, resolve } from "node:path";
5
4
  import { z } from "zod";
6
- import { contentHash, discoverCliVersion, valueHash } from "../core/index.js";
7
- import { walkAuthoredFiles } from "./fs-read.js";
8
- import { boundExperimentDriverConfig } from "./orchestrator.js";
5
+ import { discoverCliVersion, valueHash } from "../core/index.js";
9
6
 
10
7
  export { LUX_VERSION } from "./package-version.js";
11
8
 
12
- const ClaudeSettingsFileSchema = z.looseObject({
13
- enabledPlugins: z.record(z.string(), z.boolean()).optional(),
14
- });
15
- const ClaudeInstalledPluginRecordSchema = z.looseObject({
16
- installPath: z.string(),
17
- });
18
- const ClaudeInstalledPluginsFileSchema = z.looseObject({
19
- plugins: z.record(z.string(), z.array(ClaudeInstalledPluginRecordSchema)),
20
- });
21
-
22
- export const referencedCli = (
23
- reference: unknown,
24
- ): { name: string; command: string } | undefined => {
25
- let name: string | undefined;
26
- if (typeof reference === "string") {
27
- name = reference;
28
- } else if (
29
- typeof reference === "object" &&
30
- reference !== null &&
31
- typeof (reference as { name?: unknown }).name === "string"
32
- ) {
33
- name = (reference as { name: string }).name;
34
- }
35
- const config =
36
- typeof reference === "object" && reference !== null
37
- ? (reference as { config?: unknown }).config
38
- : undefined;
39
- if (name === "subprocess") {
40
- if (
41
- typeof config !== "object" ||
42
- config === null ||
43
- typeof (config as { command?: unknown }).command !== "string"
44
- ) {
45
- return undefined;
46
- }
47
- return { name, command: (config as { command: string }).command };
48
- }
49
- if (name !== "claude-code" && name !== "codex") return undefined;
50
- let command = name === "codex" ? "codex" : "claude";
51
- if (
52
- typeof config === "object" &&
53
- config !== null &&
54
- typeof (config as { command?: unknown }).command === "string"
55
- ) {
56
- command = (config as { command: string }).command;
57
- }
58
- return { name, command };
9
+ const driverConfigRecord = (reference: unknown): Record<string, unknown> => {
10
+ const config = (reference as { config?: unknown } | null)?.config;
11
+ return config && typeof config === "object" ? (config as Record<string, unknown>) : {};
59
12
  };
60
13
 
61
14
  export const referencedAnswererCli = (
@@ -261,197 +214,6 @@ export const cliIdentity = async (command: string, baseRoot: string): Promise<Cl
261
214
  });
262
215
  };
263
216
 
264
- const optionalRegularFileHash = async (path: string): Promise<string | null> => {
265
- try {
266
- const info = await lstat(path);
267
- if (info.isSymbolicLink() || !info.isFile()) {
268
- throw new Error(`behavior-affecting settings must be a regular file: ${path}`);
269
- }
270
- return contentHash(await readFile(path));
271
- } catch (error) {
272
- if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
273
- throw error;
274
- }
275
- };
276
-
277
- const driverConfigRecord = (driver: unknown): Record<string, unknown> => {
278
- if (!driver || typeof driver !== "object") return {};
279
- const config = (driver as { config?: unknown }).config;
280
- return config && typeof config === "object" ? (config as Record<string, unknown>) : {};
281
- };
282
-
283
- export const claudeConfigRoot = (driver: unknown): string => {
284
- const config = driverConfigRecord(driver);
285
- const env =
286
- config.env && typeof config.env === "object"
287
- ? (config.env as Record<string, unknown>)
288
- : undefined;
289
- const configured = env?.CLAUDE_CONFIG_DIR;
290
- const root =
291
- typeof configured === "string"
292
- ? configured
293
- : (process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude"));
294
- if (!isAbsolute(root)) {
295
- throw new Error("CLAUDE_CONFIG_DIR must be absolute for reproducible experiment identity");
296
- }
297
- return resolve(root);
298
- };
299
-
300
- const hashBehaviorDirectory = async (
301
- root: string,
302
- label: string,
303
- ): Promise<Array<{ path: string; hash: string }>> => {
304
- try {
305
- const info = await lstat(root);
306
- if (info.isSymbolicLink() || !info.isDirectory()) {
307
- throw new Error(`behavior-affecting Claude source must be a real directory: ${root}`);
308
- }
309
- } catch (error) {
310
- if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
311
- throw error;
312
- }
313
- const paths = await walkAuthoredFiles(root);
314
- if (paths.length > 5_000) {
315
- throw new Error(`behavior-affecting Claude source '${label}' exceeds 5000 files`);
316
- }
317
- let bytes = 0;
318
- const hashes: Array<{ path: string; hash: string }> = [];
319
- for (const path of paths) {
320
- const content = await readFile(join(root, path));
321
- bytes += content.length;
322
- if (bytes > 256 * 1024 * 1024) {
323
- throw new Error(`behavior-affecting Claude source '${label}' exceeds 256 MiB`);
324
- }
325
- hashes.push({ path: `${label}/${path}`, hash: contentHash(content) });
326
- }
327
- return hashes;
328
- };
329
-
330
- /**
331
- * Hash every intentionally loaded user behavior source without persisting its
332
- * contents. This covers user instructions/rules/output styles and the exact
333
- * installed contents of plugins enabled by settings.json.
334
- */
335
- export const claudeUserBehaviorHash = async (configRoot: string): Promise<string | null> => {
336
- const settingsPath = join(configRoot, "settings.json");
337
- const settingsHash = await optionalRegularFileHash(settingsPath);
338
- const sources: Array<{ path: string; hash: string }> = [];
339
- if (settingsHash) sources.push({ path: "settings.json", hash: settingsHash });
340
- const claudeMdHash = await optionalRegularFileHash(join(configRoot, "CLAUDE.md"));
341
- if (claudeMdHash) sources.push({ path: "CLAUDE.md", hash: claudeMdHash });
342
- for (const directory of ["rules", "output-styles", "agents", "commands", "skills"]) {
343
- sources.push(...(await hashBehaviorDirectory(join(configRoot, directory), directory)));
344
- }
345
-
346
- let settings: unknown;
347
- try {
348
- const contents = await readFile(settingsPath, "utf8");
349
- try {
350
- settings = JSON.parse(contents);
351
- } catch {
352
- throw new Error("Claude settings.json contains invalid JSON");
353
- }
354
- } catch (error) {
355
- if ((error as NodeJS.ErrnoException).code === "ENOENT") {
356
- settings = undefined;
357
- } else {
358
- throw error;
359
- }
360
- }
361
- const parsedSettings = ClaudeSettingsFileSchema.safeParse(settings);
362
- if (settings !== undefined && !parsedSettings.success) {
363
- throw new Error("Claude settings.json has an invalid enabledPlugins map");
364
- }
365
- const enabledPlugins = parsedSettings.success ? parsedSettings.data.enabledPlugins : undefined;
366
- const enabledIds = Object.entries(enabledPlugins ?? {})
367
- .filter(([, value]) => value === true)
368
- .map(([id]) => id)
369
- .sort();
370
- if (enabledIds.length > 0) {
371
- const installedPath = join(configRoot, "plugins", "installed_plugins.json");
372
- const installedHash = await optionalRegularFileHash(installedPath);
373
- if (installedHash) {
374
- sources.push({ path: "plugins/installed_plugins.json", hash: installedHash });
375
- }
376
- let installed: unknown;
377
- try {
378
- installed = JSON.parse(await readFile(installedPath, "utf8"));
379
- } catch {
380
- installed = undefined;
381
- }
382
- const parsedInstalled = ClaudeInstalledPluginsFileSchema.safeParse(installed);
383
- if (!parsedInstalled.success) {
384
- throw new Error("enabled Claude plugins have invalid installed metadata");
385
- }
386
- const plugins = parsedInstalled.data.plugins;
387
- for (const id of enabledIds) {
388
- const records = plugins[id];
389
- if (!records || records.length === 0) {
390
- throw new Error(`enabled Claude plugin '${id}' has no installed content to hash`);
391
- }
392
- for (const [index, record] of records.entries()) {
393
- const installPath = record.installPath;
394
- sources.push(
395
- ...(await hashBehaviorDirectory(resolve(installPath), `plugins/enabled/${id}/${index}`)),
396
- );
397
- }
398
- }
399
- }
400
- return sources.length === 0 ? null : valueHash(sources);
401
- };
402
-
403
- export const configuredClaudeSourceHashes = async (
404
- driver: unknown,
405
- baseRoot: string,
406
- cache: Map<string, Promise<string>> = new Map(),
407
- ): Promise<Array<{ kind: "plugin" | "read"; path: string; hash: string }>> => {
408
- const driverCli = referencedCli(driver);
409
- if (!driverCli) return [];
410
- const config = driverConfigRecord(driver);
411
- // This also rejects path-bearing extraArgs that would evade the source
412
- // hashes below. Runtime applies the same guard before driver creation.
413
- boundExperimentDriverConfig(driverCli.name, config, "identity-check");
414
- const isolation =
415
- config.isolation && typeof config.isolation === "object"
416
- ? (config.isolation as Record<string, unknown>)
417
- : undefined;
418
- const configured = [
419
- ...(driverCli.name === "claude-code" && Array.isArray(config.pluginDirs)
420
- ? config.pluginDirs.map((path) => ({ kind: "plugin" as const, path }))
421
- : []),
422
- ...(Array.isArray(config.addDirs)
423
- ? config.addDirs.map((path) => ({ kind: "read" as const, path }))
424
- : []),
425
- ...(driverCli.name === "claude-code" && isolation && Array.isArray(isolation.allowRead)
426
- ? isolation.allowRead.map((path) => ({ kind: "read" as const, path }))
427
- : []),
428
- ].filter(
429
- (entry): entry is { kind: "plugin" | "read"; path: string } =>
430
- typeof entry.path === "string" && entry.path.length > 0,
431
- );
432
- return Promise.all(
433
- configured
434
- .sort((a, b) => `${a.kind}:${a.path}`.localeCompare(`${b.kind}:${b.path}`))
435
- .map(async ({ kind, path }) => {
436
- const absolute = resolve(baseRoot, path);
437
- const key = `${kind}:${absolute}`;
438
- let hash = cache.get(key);
439
- if (!hash) {
440
- hash = hashBehaviorDirectory(
441
- absolute,
442
- `driver/${kind}/${contentHash(absolute).slice(0, 12)}`,
443
- ).then(valueHash);
444
- cache.set(key, hash);
445
- }
446
- return {
447
- kind,
448
- path: absolute,
449
- hash: await hash,
450
- };
451
- }),
452
- );
453
- };
454
-
455
217
  export const runtimeCliIdentityHashForReferences = async (
456
218
  references: readonly RuntimeCliReference[],
457
219
  ): Promise<string> =>
@@ -13,6 +13,7 @@ import {
13
13
  ExperimentSelectionSchema,
14
14
  type OpenedExperimentRun,
15
15
  } from "./experiment-runs.js";
16
+ import { confidenceGateIssue, type PairedEffect, pairedEffect } from "./paired-effects.js";
16
17
 
17
18
  type ExperimentSplit = "train" | "validation" | "test";
18
19
 
@@ -103,6 +104,7 @@ const satisfiesConstraint = (
103
104
  constraint: ExperimentConstraint,
104
105
  experiment: OpenedExperimentRun["manifest"],
105
106
  ): boolean => {
107
+ if (constraint.relativeTo && candidate.id === "baseline") return true;
106
108
  let profiles: (string | undefined)[];
107
109
  if (constraint.metric === "subject.bytes" || constraint.profile) {
108
110
  profiles = [constraint.profile];
@@ -110,6 +112,16 @@ const satisfiesConstraint = (
110
112
  profiles = campaign.profiles;
111
113
  }
112
114
  return profiles.every((profile) => {
115
+ if (constraint.relativeTo) {
116
+ const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
117
+ if (effect.note || effect.meanDelta === null) return false;
118
+ const lower = effect.interval?.lower ?? effect.meanDelta;
119
+ const upper = effect.interval?.upper ?? effect.meanDelta;
120
+ return (
121
+ (constraint.min === undefined || lower >= constraint.min) &&
122
+ (constraint.max === undefined || upper <= constraint.max)
123
+ );
124
+ }
113
125
  const values = metricValues(
114
126
  candidate,
115
127
  constraint.metric,
@@ -135,6 +147,7 @@ const satisfiesConstraint = (
135
147
  return sampleGroups.every((samples) => {
136
148
  try {
137
149
  const interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
150
+ if (confidenceGateIssue(interval)) return false;
138
151
  return (
139
152
  (constraint.min === undefined || interval.lower >= constraint.min) &&
140
153
  (constraint.max === undefined || interval.upper <= constraint.max)
@@ -156,12 +169,29 @@ const satisfiesConstraint = (
156
169
  export const average = (values: readonly number[]): number =>
157
170
  values.reduce((sum, value) => sum + value, 0) / Math.max(values.length, 1);
158
171
 
172
+ const relativeConstraintEffect = (
173
+ candidate: ExperimentDecisionCandidate,
174
+ constraint: ExperimentConstraint,
175
+ profile: string | undefined,
176
+ experiment: OpenedExperimentRun["manifest"],
177
+ ): PairedEffect => {
178
+ const scope = (entry: ExperimentEvaluation): boolean =>
179
+ entry.profileId === profile && entry.split === constraint.split;
180
+ return pairedEffect(
181
+ candidateEvaluations(experiment, "baseline").find(scope),
182
+ candidateEvaluations(experiment, candidate.id).find(scope),
183
+ constraint.metric,
184
+ constraint.confidence,
185
+ );
186
+ };
187
+
159
188
  const normalizedConstraintViolation = (
160
189
  campaign: ExperimentCampaign,
161
190
  candidate: ExperimentDecisionCandidate,
162
191
  constraint: ExperimentConstraint,
163
192
  experiment: OpenedExperimentRun["manifest"],
164
193
  ): number => {
194
+ if (constraint.relativeTo && candidate.id === "baseline") return 0;
165
195
  let profiles: Array<string | undefined> = campaign.profiles;
166
196
  if (constraint.metric === "subject.bytes" || constraint.profile) {
167
197
  profiles = [constraint.profile];
@@ -177,6 +207,18 @@ const normalizedConstraintViolation = (
177
207
  );
178
208
  let worst = 0;
179
209
  for (const profile of profiles) {
210
+ if (constraint.relativeTo) {
211
+ const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
212
+ if (effect.note || effect.meanDelta === null) return Number.POSITIVE_INFINITY;
213
+ worst = Math.max(
214
+ worst,
215
+ violation(
216
+ effect.interval?.lower ?? effect.meanDelta,
217
+ effect.interval?.upper ?? effect.meanDelta,
218
+ ),
219
+ );
220
+ continue;
221
+ }
180
222
  if (constraint.confidence) {
181
223
  const groups = metricSampleGroups(
182
224
  candidate,
@@ -189,6 +231,7 @@ const normalizedConstraintViolation = (
189
231
  for (const samples of groups) {
190
232
  try {
191
233
  const interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
234
+ if (confidenceGateIssue(interval)) return Number.POSITIVE_INFINITY;
192
235
  worst = Math.max(worst, violation(interval.lower, interval.upper));
193
236
  } catch {
194
237
  return Number.POSITIVE_INFINITY;
@@ -379,6 +422,36 @@ export const searchFrontier = (
379
422
  });
380
423
  };
381
424
 
425
+ const relativeConstraintReport = (
426
+ campaign: ExperimentCampaign,
427
+ candidate: ExperimentDecisionCandidate,
428
+ constraint: ExperimentConstraint,
429
+ profile: string | undefined,
430
+ experiment: OpenedExperimentRun["manifest"],
431
+ ): ExperimentSelection["constraints"][number] => {
432
+ const effect = relativeConstraintEffect(candidate, constraint, profile, experiment);
433
+ const reference = candidate.id === "baseline";
434
+ let values = effect.meanDelta === null ? [] : [effect.meanDelta];
435
+ if (reference) values = [0];
436
+ const note = reference ? "baseline reference; relative gate does not apply" : effect.note;
437
+ return {
438
+ candidateId: candidate.id,
439
+ metric: constraint.metric,
440
+ relativeTo: "baseline",
441
+ ...(profile ? { profile } : {}),
442
+ split: constraint.split,
443
+ values,
444
+ passed: satisfiesConstraint(
445
+ campaign,
446
+ candidate,
447
+ { ...constraint, ...(profile ? { profile } : {}) },
448
+ experiment,
449
+ ),
450
+ ...(!reference && effect.interval ? { interval: effect.interval } : {}),
451
+ ...(note ? { note } : {}),
452
+ };
453
+ };
454
+
382
455
  export const deriveExperimentSelection = (
383
456
  campaign: ExperimentCampaign,
384
457
  candidates: readonly ExperimentDecisionCandidate[],
@@ -405,6 +478,9 @@ export const deriveExperimentSelection = (
405
478
  ? [constraint.profile]
406
479
  : campaign.profiles;
407
480
  return profiles.map((profile) => {
481
+ if (constraint.relativeTo) {
482
+ return relativeConstraintReport(campaign, candidate, constraint, profile, experiment);
483
+ }
408
484
  const values = metricValues(
409
485
  candidate,
410
486
  constraint.metric,
@@ -426,6 +502,7 @@ export const deriveExperimentSelection = (
426
502
  if (samples) {
427
503
  try {
428
504
  interval = bootstrapMeanConfidenceInterval(samples, constraint.confidence);
505
+ note = confidenceGateIssue(interval);
429
506
  } catch (error) {
430
507
  note = error instanceof Error ? error.message : String(error);
431
508
  }
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { rm } from "node:fs/promises";
3
3
  import type { z } from "zod";
4
+ import { independentClusterCount } from "../core/evaluation-clusters.js";
4
5
  import {
5
6
  bootstrapMeanConfidenceInterval,
6
7
  type Candidate,
@@ -47,6 +48,7 @@ import {
47
48
  resolvedProfileSnapshot,
48
49
  runtimeCliReferences,
49
50
  } from "./experiment-identity.js";
51
+ import { preparePlanningCorpus } from "./experiment-preflight.js";
50
52
  import {
51
53
  type ExperimentEvaluation,
52
54
  loadExperimentCandidates,
@@ -55,14 +57,7 @@ import {
55
57
  openExperimentRun,
56
58
  resumeExperimentRun,
57
59
  } from "./experiment-runs.js";
58
- import {
59
- claudeConfigRoot,
60
- claudeUserBehaviorHash,
61
- cliIdentity,
62
- configuredClaudeSourceHashes,
63
- LUX_VERSION,
64
- runtimeCliIdentityHashForReferences,
65
- } from "./experiment-runtime-identity.js";
60
+ import { LUX_VERSION, runtimeCliIdentityHashForReferences } from "./experiment-runtime-identity.js";
66
61
  import {
67
62
  candidateEvaluations,
68
63
  type ExperimentSelectionDerivationOptionsSchema,
@@ -188,6 +183,7 @@ const evaluateAcross = async (options: {
188
183
  export const planExperimentCampaign = async (
189
184
  execution: CampaignExecutionOptions,
190
185
  mode: "experiment" | "optimize",
186
+ options: { static?: boolean } = {},
191
187
  ): Promise<ExperimentCampaignPlan> => {
192
188
  const campaign = execution.loaded.campaign;
193
189
  if (mode === "optimize") {
@@ -198,11 +194,7 @@ export const planExperimentCampaign = async (
198
194
  }
199
195
  const baseline = await captureSeedCandidate(execution.loaded.subjectRoot, campaign.subject);
200
196
  await assertGraderSubject(execution, baseline);
201
- const corpus = await prepareCorpus(execution);
202
- // Plan is the deterministic preflight for execution. Build the exact same
203
- // identity now so profile, behavior-tree, and custom CLI failures happen
204
- // before a user approves any model spend.
205
- await evaluationIdentity(execution, corpus, mode);
197
+ const corpus = await preparePlanningCorpus(execution, mode, options.static ?? false);
206
198
  const splitSelectors = selectorsBySplit(campaign);
207
199
  const graderAnnotations = execution.loaded.graderAnnotations?.annotations ?? [];
208
200
  const splits = splitSelectors.map(({ name, selector }) => ({
@@ -254,50 +246,57 @@ export const planExperimentCampaign = async (
254
246
  const splitSelector = splitSelectors.find((split) => split.name === constraint.split)?.selector;
255
247
  let examples = splits.find((split) => split.split === constraint.split)?.examples ?? 0;
256
248
  if (corpus.kind === "grader" && splitSelector) {
257
- const selected = selectGraderAnnotations(graderAnnotations, splitSelector);
249
+ let selected = selectGraderAnnotations(graderAnnotations, splitSelector);
258
250
  if (constraint.metric === "grader.macroFalsePositiveRate") {
259
- examples = selected.filter((annotation) =>
251
+ selected = selected.filter((annotation) =>
260
252
  [
261
253
  annotation.expected.casePassed,
262
254
  ...Object.values(annotation.expected.assertions).map((label) => label.passed),
263
255
  ].includes(false),
264
- ).length;
256
+ );
265
257
  } else if (constraint.metric === "grader.macroFalseNegativeRate") {
266
- examples = selected.filter((annotation) =>
258
+ selected = selected.filter((annotation) =>
267
259
  [
268
260
  annotation.expected.casePassed,
269
261
  ...Object.values(annotation.expected.assertions).map((label) => label.passed),
270
262
  ].includes(true),
271
- ).length;
263
+ );
272
264
  } else if (constraint.metric === "grader.scoreMae") {
273
- examples = selected.filter(
265
+ selected = selected.filter(
274
266
  (annotation) =>
275
267
  annotation.expected.caseScore !== undefined ||
276
268
  Object.values(annotation.expected.assertions).some(
277
269
  (label) => label.score !== undefined,
278
270
  ),
279
- ).length;
271
+ );
280
272
  } else if (constraint.metric === "grader.caseAgreement") {
281
- examples = selected.filter(
273
+ selected = selected.filter(
282
274
  (annotation) =>
283
275
  annotation.expected.casePassed !== undefined ||
284
276
  annotation.expected.caseScore !== undefined,
285
- ).length;
277
+ );
286
278
  } else if (constraint.metric === "grader.assertionAgreement") {
287
- examples = selected.filter(
279
+ selected = selected.filter(
288
280
  (annotation) => Object.keys(annotation.expected.assertions).length > 0,
289
- ).length;
281
+ );
290
282
  } else if (
291
283
  constraint.metric === "grader.abstentionRate" ||
284
+ constraint.metric === "grader.insufficientEvidenceRate" ||
285
+ constraint.metric === "grader.operationalErrorRate" ||
292
286
  constraint.metric === "grader.coverage"
293
287
  ) {
294
- examples = selected.filter(
288
+ selected = selected.filter(
295
289
  (annotation) =>
296
290
  annotation.expected.casePassed !== undefined ||
297
291
  Object.keys(annotation.expected.assertions).length > 0,
298
- ).length;
292
+ );
299
293
  }
294
+ examples = independentClusterCount(
295
+ selected.map((annotation) => ({ id: annotation.id, cluster: annotation.meta?.cluster })),
296
+ );
300
297
  }
298
+ if (corpus.kind === "agent" && splitSelector)
299
+ examples = independentClusterCount(selectCases(corpus.cases, splitSelector));
301
300
  if (constraint.metric === "subject.bytes" || constraint.metric === "quality.caseRegressions") {
302
301
  examples = 1;
303
302
  }
@@ -318,6 +317,10 @@ export const planExperimentCampaign = async (
318
317
  Array<number>(examples).fill(0),
319
318
  constraint.confidence,
320
319
  );
320
+ if (constraint.relativeTo) {
321
+ bestForMin.lower = 2 * bestForMin.lower - 1;
322
+ bestForMax.upper = 2 * bestForMax.upper - 1;
323
+ }
321
324
  if (constraint.min !== undefined && bestForMin.lower < constraint.min) {
322
325
  notes.push(
323
326
  `${constraint.split} metric '${constraint.metric}' cannot attain confidence lower bound ${constraint.min} with only ${examples} samples (best ${bestForMin.lower.toFixed(3)})`,
@@ -986,6 +989,3 @@ export const optimizeExperimentCampaign = async (
986
989
  new CampaignExecution(execution, "optimize", runOptimizationCampaignWork),
987
990
  );
988
991
  };
989
-
990
- // Internal exports for identity contract tests.
991
- export { claudeConfigRoot, claudeUserBehaviorHash, cliIdentity, configuredClaudeSourceHashes };
@@ -5,6 +5,7 @@ import { contentHash, type FixturesRef, valueHash } from "../core/index.js";
5
5
  export type FixtureIdentity = {
6
6
  rootDir: string;
7
7
  hash: string;
8
+ fileHashes: ReadonlyMap<string, string>;
8
9
  };
9
10
 
10
11
  const fixtureEntries = async (
@@ -63,5 +64,12 @@ export const fixtureIdentity = async (
63
64
  if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
64
65
  throw new Error(`fixtures: expected a real directory: ${rootDir}`);
65
66
  }
66
- return { rootDir, hash: valueHash(await fixtureEntries(rootDir)) };
67
+ const entries = await fixtureEntries(rootDir);
68
+ return {
69
+ rootDir,
70
+ hash: valueHash(entries),
71
+ fileHashes: new Map(
72
+ entries.flatMap((entry) => (entry.hash === undefined ? [] : [[entry.path, entry.hash]])),
73
+ ),
74
+ };
67
75
  };
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import type { FileHandle } from "node:fs/promises";
3
3
  import { readdir, readFile } from "node:fs/promises";
4
- import { join, relative, resolve } from "node:path";
4
+ import { join, relative } from "node:path";
5
5
  import type { z } from "zod";
6
6
 
7
7
  const errorMessage = (error: unknown): string =>
@@ -93,34 +93,4 @@ export const walkFiles = async (root: string, maxFiles?: number): Promise<string
93
93
  return out.sort();
94
94
  };
95
95
 
96
- /**
97
- * Walk authored trees without silently following or omitting a symlink that
98
- * can change outside the experiment identity. Exact ignored paths support
99
- * generated state directories whose names are project-configurable.
100
- */
101
- export const walkAuthoredFiles = async (
102
- root: string,
103
- ignoredDirectoryNames: ReadonlySet<string> = new Set(),
104
- ignoredPaths: ReadonlySet<string> = new Set(),
105
- ): Promise<string[]> => {
106
- if (!existsSync(root)) return [];
107
- const out: string[] = [];
108
- const stack = [root];
109
- while (stack.length > 0) {
110
- const dir = stack.pop();
111
- if (!dir) continue;
112
- for (const entry of await readdir(dir, { withFileTypes: true })) {
113
- const full = join(dir, entry.name);
114
- if (ignoredPaths.has(resolve(full))) continue;
115
- if (entry.isDirectory() && ignoredDirectoryNames.has(entry.name)) continue;
116
- if (entry.isSymbolicLink()) {
117
- throw new Error(
118
- `authored evaluation trees cannot contain symlinks: ${relative(root, full)}`,
119
- );
120
- }
121
- if (entry.isDirectory()) stack.push(full);
122
- else if (entry.isFile()) out.push(relative(root, full));
123
- }
124
- }
125
- return out.sort();
126
- };
96
+ export { walkAuthoredFiles } from "../core/file-tree.js";