@tangle-network/agent-eval 0.136.0 → 0.138.0

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 (231) hide show
  1. package/CHANGELOG.md +86 -1
  2. package/README.md +37 -2
  3. package/dist/{agent-profile-cell-OhuTee9n.js → agent-profile-cell-CbfBm2g6.js} +2 -2
  4. package/dist/{agent-profile-cell-OhuTee9n.js.map → agent-profile-cell-CbfBm2g6.js.map} +1 -1
  5. package/dist/{agent-profile-cell-CCm3l2v2.d.ts → agent-profile-cell-Cw0PVwDr.d.ts} +2 -2
  6. package/dist/{agent-profile-cell-CCm3l2v2.d.ts.map → agent-profile-cell-Cw0PVwDr.d.ts.map} +1 -1
  7. package/dist/analyst/index.d.ts +574 -18
  8. package/dist/analyst/index.d.ts.map +1 -1
  9. package/dist/analyst/index.js +25 -5
  10. package/dist/analyst/index.js.map +1 -1
  11. package/dist/{analyze-runs-jjCmF8pU.js → analyze-runs-BScZvqMV.js} +6 -6
  12. package/dist/{analyze-runs-jjCmF8pU.js.map → analyze-runs-BScZvqMV.js.map} +1 -1
  13. package/dist/{analyze-runs-Cda5Xkj1.d.ts → analyze-runs-CPYxfPWT.d.ts} +6 -6
  14. package/dist/{analyze-runs-Cda5Xkj1.d.ts.map → analyze-runs-CPYxfPWT.d.ts.map} +1 -1
  15. package/dist/{baseline-BUeFcgrn.js → baseline-C-GocmIW.js} +2 -2
  16. package/dist/{baseline-BUeFcgrn.js.map → baseline-C-GocmIW.js.map} +1 -1
  17. package/dist/benchmark-D8dkki-J.js +554 -0
  18. package/dist/benchmark-D8dkki-J.js.map +1 -0
  19. package/dist/benchmark-DlQgU_XI.d.ts +236 -0
  20. package/dist/benchmark-DlQgU_XI.d.ts.map +1 -0
  21. package/dist/benchmark-command-CMqVqReF.js +4332 -0
  22. package/dist/benchmark-command-CMqVqReF.js.map +1 -0
  23. package/dist/benchmarks/index.d.ts +1 -1
  24. package/dist/benchmarks/index.js +1 -1
  25. package/dist/{benchmarks-Dfgm9ts5.js → benchmarks-BJ_xK5rQ.js} +4 -3
  26. package/dist/{benchmarks-Dfgm9ts5.js.map → benchmarks-BJ_xK5rQ.js.map} +1 -1
  27. package/dist/builder-eval/index.js +2 -2
  28. package/dist/campaign/index.d.ts +6 -6
  29. package/dist/campaign/index.js +4 -4
  30. package/dist/{campaign-Dz8uQnhC.js → campaign-BIBS-NHV.js} +219 -78
  31. package/dist/campaign-BIBS-NHV.js.map +1 -0
  32. package/dist/cli.js +9 -2
  33. package/dist/cli.js.map +1 -1
  34. package/dist/client-BwPKohkJ.d.ts +202 -0
  35. package/dist/client-BwPKohkJ.d.ts.map +1 -0
  36. package/dist/completion-verifier-B4-IMYcS.d.ts +240 -0
  37. package/dist/completion-verifier-B4-IMYcS.d.ts.map +1 -0
  38. package/dist/contract/index.d.ts +10 -9
  39. package/dist/contract/index.d.ts.map +1 -1
  40. package/dist/contract/index.js +13 -13
  41. package/dist/control.d.ts +2 -2
  42. package/dist/control.js +1 -1
  43. package/dist/{cost-ledger-fGS_u_O1.d.ts → cost-ledger-B1D3COAc.d.ts} +6 -5
  44. package/dist/{cost-ledger-fGS_u_O1.d.ts.map → cost-ledger-B1D3COAc.d.ts.map} +1 -1
  45. package/dist/{cost-ledger-DHAjwNj7.js → cost-ledger-CHDLA0Ss.js} +91 -46
  46. package/dist/cost-ledger-CHDLA0Ss.js.map +1 -0
  47. package/dist/{dataset-BvtnC8Dc.d.ts → dataset-v_Y5902-.d.ts} +2 -2
  48. package/dist/{dataset-BvtnC8Dc.d.ts.map → dataset-v_Y5902-.d.ts.map} +1 -1
  49. package/dist/{default-registry-Brxr728w.d.ts → default-registry-PUhIVRWz.d.ts} +77 -138
  50. package/dist/default-registry-PUhIVRWz.d.ts.map +1 -0
  51. package/dist/{default-registry-CHmdy2An.js → default-registry-lp5R0lve.js} +1617 -291
  52. package/dist/default-registry-lp5R0lve.js.map +1 -0
  53. package/dist/{errors-8YnH8WlF.js → errors-D-LKuDhb.js} +8 -2
  54. package/dist/errors-D-LKuDhb.js.map +1 -0
  55. package/dist/{errors-CEk209JS.d.ts → errors-DkfjIDvD.d.ts} +9 -3
  56. package/dist/errors-DkfjIDvD.d.ts.map +1 -0
  57. package/dist/{eval-campaign-Cc8WZJ6b.js → eval-campaign-9MozgKL7.js} +6 -6
  58. package/dist/{eval-campaign-Cc8WZJ6b.js.map → eval-campaign-9MozgKL7.js.map} +1 -1
  59. package/dist/exact-types-Dpw2LeHA.d.ts +234 -0
  60. package/dist/exact-types-Dpw2LeHA.d.ts.map +1 -0
  61. package/dist/{extract-usage-DIQpN-ww.js → extract-usage-CS391dOE.js} +3 -3
  62. package/dist/{extract-usage-DIQpN-ww.js.map → extract-usage-CS391dOE.js.map} +1 -1
  63. package/dist/{feedback-trajectory-CVaeREXV.d.ts → feedback-trajectory-CoNep7rl.d.ts} +91 -3
  64. package/dist/feedback-trajectory-CoNep7rl.d.ts.map +1 -0
  65. package/dist/fuzz.d.ts +1 -1
  66. package/dist/fuzz.js +2 -2
  67. package/dist/hosted/index.d.ts +3 -2
  68. package/dist/hosted/index.d.ts.map +1 -1
  69. package/dist/{index-AbhwHp0V.d.ts → index-B2-IxCMB.d.ts} +2 -2
  70. package/dist/{index-AbhwHp0V.d.ts.map → index-B2-IxCMB.d.ts.map} +1 -1
  71. package/dist/index-BipJlj-C.d.ts +316 -0
  72. package/dist/index-BipJlj-C.d.ts.map +1 -0
  73. package/dist/{index-CQsJcqch.d.ts → index-CjVYlVBK.d.ts} +5 -5
  74. package/dist/{index-CQsJcqch.d.ts.map → index-CjVYlVBK.d.ts.map} +1 -1
  75. package/dist/{index-B4Fjfo5U.d.ts → index-D0cxAdaV.d.ts} +89 -317
  76. package/dist/index-D0cxAdaV.d.ts.map +1 -0
  77. package/dist/{index-DuhJaaiH.d.ts → index-DEb46kc6.d.ts} +2 -2
  78. package/dist/index-DEb46kc6.d.ts.map +1 -0
  79. package/dist/{index-C2fkZhv_.d.ts → index-sMN_hI4E.d.ts} +3 -3
  80. package/dist/{index-C2fkZhv_.d.ts.map → index-sMN_hI4E.d.ts.map} +1 -1
  81. package/dist/index.d.ts +30 -70
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +175 -35
  84. package/dist/index.js.map +1 -1
  85. package/dist/{client-DcvgkaZi.d.ts → insight-report-CXd8VBDR.d.ts} +5 -203
  86. package/dist/insight-report-CXd8VBDR.d.ts.map +1 -0
  87. package/dist/{integrity-rmVhXWA7.d.ts → integrity-B-MLFz0I.d.ts} +3 -3
  88. package/dist/{integrity-rmVhXWA7.d.ts.map → integrity-B-MLFz0I.d.ts.map} +1 -1
  89. package/dist/integrity-CCXTftiL.js +1360 -0
  90. package/dist/integrity-CCXTftiL.js.map +1 -0
  91. package/dist/{integrity-BzRbCHzi.js → integrity-fdt8XPAv.js} +2 -2
  92. package/dist/{integrity-BzRbCHzi.js.map → integrity-fdt8XPAv.js.map} +1 -1
  93. package/dist/ledger-core/index.d.ts +1 -1
  94. package/dist/ledger-core/index.js +1 -1
  95. package/dist/{ledger-core-DAKFKRzi.js → ledger-core-C0Yx1I14.js} +303 -110
  96. package/dist/ledger-core-C0Yx1I14.js.map +1 -0
  97. package/dist/{llm-client-DHx8pzyJ.js → llm-client-Cj3c7PEm.js} +6 -6
  98. package/dist/llm-client-Cj3c7PEm.js.map +1 -0
  99. package/dist/meta-eval/index.d.ts +2 -2
  100. package/dist/meta-eval/index.js +3 -3
  101. package/dist/{mint-DyRUc9k6.js → mint-Ctwk079K.js} +4 -4
  102. package/dist/{mint-DyRUc9k6.js.map → mint-Ctwk079K.js.map} +1 -1
  103. package/dist/multishot/index.d.ts +2 -2
  104. package/dist/openapi.json +1 -1
  105. package/dist/{paired-arms-BbFKrAU-.js → paired-arms-iZ08VFMN.js} +3 -3
  106. package/dist/{paired-arms-BbFKrAU-.js.map → paired-arms-iZ08VFMN.js.map} +1 -1
  107. package/dist/pipelines/index.js +2 -2
  108. package/dist/profile-cell.d.ts +1 -1
  109. package/dist/profile-cell.js +1 -1
  110. package/dist/{proposal-findings-DCawte-y.js → proposal-findings-2GIUo1et.js} +2 -68
  111. package/dist/proposal-findings-2GIUo1et.js.map +1 -0
  112. package/dist/{propose-review-control-SQ-n9-We.js → propose-review-control-DLXz4FCX.js} +2 -2
  113. package/dist/{propose-review-control-SQ-n9-We.js.map → propose-review-control-DLXz4FCX.js.map} +1 -1
  114. package/dist/registry-C4yJTza7.d.ts +178 -0
  115. package/dist/registry-C4yJTza7.d.ts.map +1 -0
  116. package/dist/{release-report-DooPguBc.js → release-report-B5XPBvAU.js} +4 -4
  117. package/dist/{release-report-DooPguBc.js.map → release-report-B5XPBvAU.js.map} +1 -1
  118. package/dist/{release-report-DpBxGGI1.d.ts → release-report-CoyvyLBs.d.ts} +4 -4
  119. package/dist/{release-report-DpBxGGI1.d.ts.map → release-report-CoyvyLBs.d.ts.map} +1 -1
  120. package/dist/{replay-C6wRg47C.js → replay-Cb-4Vf0k.js} +249 -8
  121. package/dist/replay-Cb-4Vf0k.js.map +1 -0
  122. package/dist/{replay-BRfMIs81.d.ts → replay-DbIYwso6.d.ts} +227 -52
  123. package/dist/replay-DbIYwso6.d.ts.map +1 -0
  124. package/dist/reporting.d.ts +4 -4
  125. package/dist/reporting.js +4 -4
  126. package/dist/{researcher-Doo95b50.d.ts → researcher-BCeOEjtR.d.ts} +6 -7
  127. package/dist/researcher-BCeOEjtR.d.ts.map +1 -0
  128. package/dist/{reward-hacking-a-kYs0-i.js → reward-hacking-GyN0kMd8.js} +3 -3
  129. package/dist/{reward-hacking-a-kYs0-i.js.map → reward-hacking-GyN0kMd8.js.map} +1 -1
  130. package/dist/{reward-hacking-D-QqXvg-.d.ts → reward-hacking-sE2l_NV6.d.ts} +2 -2
  131. package/dist/{reward-hacking-D-QqXvg-.d.ts.map → reward-hacking-sE2l_NV6.d.ts.map} +1 -1
  132. package/dist/rl.d.ts +6 -6
  133. package/dist/rl.js +9 -9
  134. package/dist/rollout/index.d.ts +1 -1
  135. package/dist/rollout/index.js +3 -3
  136. package/dist/{rollout-DLSUIWLu.js → rollout-DQFl0UXA.js} +2 -2
  137. package/dist/{rollout-DLSUIWLu.js.map → rollout-DQFl0UXA.js.map} +1 -1
  138. package/dist/{rubric-predictive-validity-BJf-8ejY.js → rubric-predictive-validity-BRR632r1.js} +2 -2
  139. package/dist/{rubric-predictive-validity-BJf-8ejY.js.map → rubric-predictive-validity-BRR632r1.js.map} +1 -1
  140. package/dist/{rubric-predictive-validity-C1dCLcvb.d.ts → rubric-predictive-validity-w2klGv1u.d.ts} +2 -2
  141. package/dist/{rubric-predictive-validity-C1dCLcvb.d.ts.map → rubric-predictive-validity-w2klGv1u.d.ts.map} +1 -1
  142. package/dist/{run-evidence-DokQtX0-.d.ts → run-evidence-CbE0A8Xg.d.ts} +3 -3
  143. package/dist/{run-evidence-DokQtX0-.d.ts.map → run-evidence-CbE0A8Xg.d.ts.map} +1 -1
  144. package/dist/{run-record-DcObtIGh.d.ts → run-record-DwHMk1Ai.d.ts} +4 -4
  145. package/dist/{run-record-DcObtIGh.d.ts.map → run-record-DwHMk1Ai.d.ts.map} +1 -1
  146. package/dist/{run-record-BIwU2wdV.js → run-record-vRgqWmJw.js} +3 -3
  147. package/dist/{run-record-BIwU2wdV.js.map → run-record-vRgqWmJw.js.map} +1 -1
  148. package/dist/{semantic-concept-judge-Btozx3Vc.js → semantic-concept-judge-DYXDPZW0.js} +12 -6
  149. package/dist/semantic-concept-judge-DYXDPZW0.js.map +1 -0
  150. package/dist/{server-Bz3WQJs6.js → server-DLEvyW2z.js} +3 -3
  151. package/dist/{server-Bz3WQJs6.js.map → server-DLEvyW2z.js.map} +1 -1
  152. package/dist/single-run-lock-D_bS5xhj.js +318 -0
  153. package/dist/single-run-lock-D_bS5xhj.js.map +1 -0
  154. package/dist/{skill-usage-BDQVPIG1.d.ts → skill-usage-Bv3G4VkA.d.ts} +36 -48
  155. package/dist/skill-usage-Bv3G4VkA.d.ts.map +1 -0
  156. package/dist/{skillopt-optimization-method-0UmPD6aP.js → skillopt-optimization-method-CjKMZy0d.js} +10 -185
  157. package/dist/skillopt-optimization-method-CjKMZy0d.js.map +1 -0
  158. package/dist/{skillopt-optimization-method-CwSYkv35.d.ts → skillopt-optimization-method-CzfnA8O-.d.ts} +11 -12
  159. package/dist/skillopt-optimization-method-CzfnA8O-.d.ts.map +1 -0
  160. package/dist/{statistics-CnGCLLqc.js → statistics-ByxzSiOM.js} +2 -2
  161. package/dist/{statistics-CnGCLLqc.js.map → statistics-ByxzSiOM.js.map} +1 -1
  162. package/dist/{statistics-CKOqre5S.d.ts → statistics-mf70aXKp.d.ts} +2 -2
  163. package/dist/{statistics-CKOqre5S.d.ts.map → statistics-mf70aXKp.d.ts.map} +1 -1
  164. package/dist/store-otlp-BenKynPE.js +1688 -0
  165. package/dist/store-otlp-BenKynPE.js.map +1 -0
  166. package/dist/{summary-report-BEk8OFLs.js → summary-report-9A5y7EsK.js} +4 -4
  167. package/dist/{summary-report-BEk8OFLs.js.map → summary-report-9A5y7EsK.js.map} +1 -1
  168. package/dist/{summary-report-CPMINBqs.d.ts → summary-report-BKinV4yD.d.ts} +3 -3
  169. package/dist/{summary-report-CPMINBqs.d.ts.map → summary-report-BKinV4yD.d.ts.map} +1 -1
  170. package/dist/supervisor-run/index.d.ts +3 -2
  171. package/dist/supervisor-run/index.js +3 -2
  172. package/dist/{supervisor-run-Dr5HnTup.js → supervisor-run-B2EWUmQY.js} +28 -454
  173. package/dist/supervisor-run-B2EWUmQY.js.map +1 -0
  174. package/dist/{test-graded-scenario-BsqWLmPt.js → test-graded-scenario-JHcKQNpq.js} +2 -2
  175. package/dist/{test-graded-scenario-BsqWLmPt.js.map → test-graded-scenario-JHcKQNpq.js.map} +1 -1
  176. package/dist/tools-DZGdROtG.js +255 -0
  177. package/dist/tools-DZGdROtG.js.map +1 -0
  178. package/dist/traces.d.ts +6 -7
  179. package/dist/traces.js +6 -6
  180. package/dist/types-5q2T25iW.d.ts +804 -0
  181. package/dist/types-5q2T25iW.d.ts.map +1 -0
  182. package/dist/{types-DVjczBM9.d.ts → types-BtJhn8v6.d.ts} +260 -6
  183. package/dist/types-BtJhn8v6.d.ts.map +1 -0
  184. package/dist/{index-CyC1BTmn.d.ts → types-Dea6tiVI.d.ts} +16 -238
  185. package/dist/types-Dea6tiVI.d.ts.map +1 -0
  186. package/dist/{types-DiWLru6Z.d.ts → types-zFYez3PK.d.ts} +5 -5
  187. package/dist/{types-DiWLru6Z.d.ts.map → types-zFYez3PK.d.ts.map} +1 -1
  188. package/dist/wire/index.d.ts +3 -3
  189. package/dist/wire/index.js +1 -1
  190. package/docs/feedback-trajectories.md +100 -1
  191. package/docs/trace-analysis.md +494 -58
  192. package/package.json +9 -3
  193. package/dist/analyst-BkTS3C58.d.ts +0 -89
  194. package/dist/analyst-BkTS3C58.d.ts.map +0 -1
  195. package/dist/analyst-j5je5J7c.js +0 -152
  196. package/dist/analyst-j5je5J7c.js.map +0 -1
  197. package/dist/campaign-Dz8uQnhC.js.map +0 -1
  198. package/dist/client-DcvgkaZi.d.ts.map +0 -1
  199. package/dist/concurrency-MUjT7VjM.js +0 -109
  200. package/dist/concurrency-MUjT7VjM.js.map +0 -1
  201. package/dist/cost-ledger-DHAjwNj7.js.map +0 -1
  202. package/dist/default-registry-Brxr728w.d.ts.map +0 -1
  203. package/dist/default-registry-CHmdy2An.js.map +0 -1
  204. package/dist/errors-8YnH8WlF.js.map +0 -1
  205. package/dist/errors-CEk209JS.d.ts.map +0 -1
  206. package/dist/feedback-trajectory-CVaeREXV.d.ts.map +0 -1
  207. package/dist/index-B4Fjfo5U.d.ts.map +0 -1
  208. package/dist/index-CyC1BTmn.d.ts.map +0 -1
  209. package/dist/index-DuhJaaiH.d.ts.map +0 -1
  210. package/dist/ledger-core-DAKFKRzi.js.map +0 -1
  211. package/dist/llm-client-BiK4HW0u.d.ts +0 -290
  212. package/dist/llm-client-BiK4HW0u.d.ts.map +0 -1
  213. package/dist/llm-client-DHx8pzyJ.js.map +0 -1
  214. package/dist/proposal-findings-DCawte-y.js.map +0 -1
  215. package/dist/raw-provider-sink-BU29Sh8h.d.ts +0 -134
  216. package/dist/raw-provider-sink-BU29Sh8h.d.ts.map +0 -1
  217. package/dist/replay-BRfMIs81.d.ts.map +0 -1
  218. package/dist/replay-C6wRg47C.js.map +0 -1
  219. package/dist/researcher-Doo95b50.d.ts.map +0 -1
  220. package/dist/semantic-concept-judge-Btozx3Vc.js.map +0 -1
  221. package/dist/skill-usage-BDQVPIG1.d.ts.map +0 -1
  222. package/dist/skillopt-optimization-method-0UmPD6aP.js.map +0 -1
  223. package/dist/skillopt-optimization-method-CwSYkv35.d.ts.map +0 -1
  224. package/dist/store-CxJry_cs.d.ts +0 -229
  225. package/dist/store-CxJry_cs.d.ts.map +0 -1
  226. package/dist/supervisor-run-Dr5HnTup.js.map +0 -1
  227. package/dist/tools-D8yTtNSN.js +0 -1190
  228. package/dist/tools-D8yTtNSN.js.map +0 -1
  229. package/dist/types-Cc3qbqzj.d.ts +0 -387
  230. package/dist/types-Cc3qbqzj.d.ts.map +0 -1
  231. package/dist/types-DVjczBM9.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,85 @@ All notable changes to `@tangle-network/agent-eval` and its sibling `agent-eval-
4
4
 
5
5
  ---
6
6
 
7
+ ## [0.138.0] - 2026-07-30 - exact analyst runs with sealed receipts
8
+
9
+ ### Fixed
10
+
11
+ - A release version bump no longer invalidates the published analyst benchmark evidence.
12
+ The dependency-lock pin now tracks the current lockfiles, the evidence keeps its own creation-time digest and package version, and a test proves the two locks differ by the version stamp alone — a real dependency change still forces a new benchmark run or explicit retirement of the evidence.
13
+
14
+ ### Added
15
+
16
+ - `AnalystRegistry.runExact()` requires ordered analyst ids and an explicit value for every run-policy field.
17
+ It never inherits registry insertion order or the constructor's default budget.
18
+ Disabled budgets, timeouts, cancellation, cost attribution, tags, and prior findings use explicit `null` values.
19
+ Exact runs bind analyst, ledger, hook, chat, and policy identities with non-secret configuration digests.
20
+ They use the registry's shared serial execution path and persist canonical equal or weighted allocations instead of adding a second scheduler or allocator.
21
+ Exact receipts explicitly distinguish complete execution from a failed ordered prefix.
22
+ `ExactAnalystRunExecutionError.result` is always a canonical immutable failed receipt with valid completed work and accounting.
23
+ - `defineTraceAnalyst()` accepts canonical `executionConfig` and returns an exact-capable custom analyst when it is supplied, while preserving its existing minimal form.
24
+ - **Breaking:** `AnalystBenchmarkCase` now requires `clusterId` and `labelState`.
25
+ A case must identify its independent source unit and state whether labels prove an issue, prove no issue, or leave the outcome unknown.
26
+ The benchmark no longer guesses either field from an empty issue list.
27
+ - `agent-eval analyst-benchmark` compares an empty baseline with a real-model AgentRx or CodeTraceBench analyst through any OpenAI-compatible endpoint.
28
+ It requires an explicit case limit and immutable dataset revision, validates labeled spans before paid work, uses benchmark-specific output adapters, and writes complete JSON plus Markdown results.
29
+ CodeTraceBench cases also retain hashed final verification artifacts, parse known upstream result formats, and mark missing outcomes unavailable.
30
+ Limited hash samples report source-versus-selected class, agent, model, difficulty, and solved distributions without claiming representativeness.
31
+ The published all-row score is retained, while a calibrated view measures solved label-empty trajectories as trusted negatives and keeps failed or unknown label-empty trajectories unlabeled.
32
+ Interrupted runs persist hash-chained observations and resume only when public inputs, model settings, local paths, and endpoint still match.
33
+ Reports include pooled and per-case step-localization metrics, exact source-quote coverage, final-result availability, and imported runtime duration.
34
+ External runner failures retain reported token, cost, duration, and metadata instead of becoming telemetry gaps.
35
+ Public model runs use one structured model call over a bounded trace projection.
36
+ A durable run-wide cost ledger enforces `--max-cost-usd` across concurrency and resume.
37
+ Paid responses are cached under deterministic call ids before settlement, so resume neither loses a completed response nor creates a second reservation after interruption.
38
+ Completed results retain a digest of every behavior-defining source file and are read through one strict recursive schema.
39
+ The repository includes one pinned 32-case CodeTraceBench input, two complete 64-call GLM-5.2 Agent Eval runs, and a failure-inclusive run of pinned CodeTracer on the same trajectories.
40
+ Exact source, input, result, resume, usage, cost, and secret-scan checks are committed with the results.
41
+
42
+ ### Fixed
43
+
44
+ - Canonical `trace://<trace>/span/<span>` evidence is classified as span evidence instead of artifact evidence.
45
+ - Public model output selects positive integer assistant step ids.
46
+ The runner builds canonical trace URIs and exact action excerpts from those spans, and rejects missing, non-assistant, or empty steps.
47
+ - Capped concurrent paid calls wait for active reservations to settle when their final spend may still fit.
48
+ They fail immediately only when committed spend plus the next enforced maximum exceeds the run limit.
49
+ - Releasing a single-run lock now removes its process exit listener instead of leaking one callback per completed campaign.
50
+ - Phoenix evaluator tests use OpenTelemetry Core 2.10 instead of the vulnerable 1.x transitive dependency.
51
+ - CodeTracer prediction adapters accept the published schema and both flat and grouped step-label outputs emitted by CodeTracer 0.2.
52
+ - The CodeTraceBench model prompt now matches the public incorrect-step task by scoring wrong actions that are later recovered, instead of treating final task success as proof that earlier steps were correct.
53
+ - JSON-text finding rows reach the existing per-row schema repair instead of failing the entire trace analyst response.
54
+
55
+ ## [0.137.0] - 2026-07-29 - trace analyst measurement and review integrity
56
+
57
+ ### Added
58
+
59
+ - `CONTROL_INTEGRITY_ANALYST` checks existing `SupervisorRunSources` and `SupervisorRunTree` values for duplicate or detached identities, parent cycles, impossible event order, orphan terminal events, and steer request or acknowledgement mismatches.
60
+ Missing transcripts, profile ids, worker logs, and declared tree gaps remain unavailable instead of becoming clean results.
61
+ - Trace analyst benchmarks now retain dataset revision, case and runner metadata, labeled issue recall, finding precision, critical-step accuracy, citation coverage, label-location agreement, actual location resolution, clean-case failures and false positives, repeat agreement, execution order, failures, latency, every reported token counter, and cost.
62
+ - Paired analyst comparisons average repetitions within independent cases before computing intervals and report both case and observation counts.
63
+ - Phoenix Evaluators and Braintrust Autoevals can run as campaign judges through structural adapters, without copying either scorer implementation.
64
+ - `defineTraceAnalyst()` provides the minimal custom analyst entry point and requires an explicit cost declaration.
65
+ - Reviewed analyst runs can become feedback trajectories while preserving findings, evidence, per-analyst status, trace references, and cost.
66
+ - AgentRx and CodeTraceBench label adapters load public step-localization and root-cause cases without imposing a trajectory format, and output translators score the maintained upstream engines directly.
67
+
68
+ ### Changed
69
+
70
+ - Generated analyst findings become digest-bound review requests and cannot enter optimizer data until every finding has one explicit external decision.
71
+ - Every analyst run requires one independent completeness assessment before optimizer export.
72
+ Optimizer quality is F1 over confirmed findings and independently identified misses, with precision, recall, F1, and counts retained in metadata.
73
+ - Trace analyst prompt optimization scores typed issue identity and exact evidence locations instead of matching phrases in generated prose.
74
+ - Analyst benchmarks use the upstream `linear-sum-assignment` implementation to maximize one-to-one label coverage and then critical-step localization, so duplicate predictions reduce precision and ambiguous findings are scored consistently.
75
+ - AgentRx evaluation targets its published root-cause task by default, accepts its maintained `failures` report shape, and treats `failure_case: 0` as a no-error prediction.
76
+ - CodeTraceBench uses its published incorrect-step labels by default; the combined incorrect-and-unuseful task must be selected explicitly.
77
+
78
+ ### Fixed
79
+
80
+ - Phoenix and Autoevals model-backed judges now share campaign cancellation and paid-call accounting.
81
+ They refuse unmetered execution, retain late provider receipts after cancellation, and reject incomplete token or cost capture.
82
+ - Analyst review requests and decisions bind to the canonical digest of one complete run, so decisions cannot be replayed across runs and repeated findings cannot collide in review queues.
83
+ - AgentRx category quality and root-step accuracy are scored independently; `traceAnalystQualityJudge` averages them when a root-step label exists.
84
+ - Analyst runner comparisons reject invalid confidence and resample controls instead of returning non-finite intervals.
85
+
7
86
  ## [0.136.0] - 2026-07-29 - preserve recursive evidence and complete profile changes
8
87
 
9
88
  ### Fixed
@@ -16,12 +95,18 @@ All notable changes to `@tangle-network/agent-eval` and its sibling `agent-eval-
16
95
  - Spawned invocations retain an explicit `supervisor` or `worker` role, and structured verdicts retain their numeric score in rollout rewards and per-worker report rows.
17
96
  - Accepted-patch counts are unavailable when the source did not retain worker deliverables, even when a worker event claimed patch bytes.
18
97
  - Manager and worker token totals have independent unavailable reasons, so an uncaptured channel is not reported as zero and a captured zero remains zero.
98
+ - Supervisor-run integrity checks share one typed source parse, correlate worker control rows by stable invocation id, and distinguish captured-empty control artifacts from missing artifacts.
99
+ - Claude Code child agents remain workers when they delegate, and steer counts use the original tool-use request id.
100
+ - Malformed journal and worker-control rows make dependent checks unavailable instead of producing missing-parent claims or clean zero counts.
19
101
 
20
- ### Changed — BREAKING
102
+ ### Breaking changes
21
103
 
22
104
  - Custom `SupervisorRunSources` readers must add `managerTokens` and `workerTokens` to `SourceLimits`.
23
105
  Set each field to `null` only when that role's aggregate token channel is complete; otherwise set the reason it is unavailable.
24
106
  Readers with no source limitations can continue to use `NO_SOURCE_LIMITS`.
107
+ - `SupervisorRunTree.gaps` now contains typed `{ code, message, nodeId?, count? }` records instead of free-form strings.
108
+ - `WorkerLogFacts.steersQueued` and `steersDelivered` are now nullable.
109
+ `null` means malformed, incomplete, or uncorrelated control rows prevent exact request-id accounting.
25
110
 
26
111
  ## [0.135.4] - 2026-07-29 - keep rich source evidence in one schema cohort
27
112
 
package/README.md CHANGED
@@ -355,7 +355,41 @@ pnpm tsx examples/selfimprove-quickstart/index.ts
355
355
  ## Start From Existing Runs
356
356
 
357
357
  You do not need a runnable agent to analyze data you already captured.
358
- Use `analyzeRuns()` for `RunRecord[]`, or use the feedback and OpenTelemetry adapters to normalize existing data first.
358
+ Use `analyzeRuns()` for `RunRecord[]`.
359
+ For traces, run a registry of built-in or custom analysts, measure it on labeled issues and exact span locations, then turn only reviewed findings into eval data.
360
+ For a public quality check, convert CodeTraceBench with `traces import-codetracebench`, then run `agent-eval analyst-benchmark` against the pinned labels and a real model.
361
+
362
+ Use `AnalystRegistry.runExact()` when the caller, rather than registry defaults, must own every execution choice.
363
+ The ordered `analystIds` array is the execution order, and `null` explicitly disables optional budget, timeout, cancellation, cost, tag, or prior-finding channels.
364
+ Exact runs are serial; callers that need recursive or concurrent scheduling compose them through their runtime rather than adding a second scheduler here.
365
+
366
+ ```ts
367
+ const result = await registry.runExact('analysis-1', inputs, {
368
+ analystIds: ['failure-mode', 'improvement'],
369
+ budget: { kind: 'equal', totalUsd: 2 },
370
+ totalTimeoutMs: 30_000,
371
+ signal: null,
372
+ costLedger: null,
373
+ costLedgerIdentity: null,
374
+ costPhase: null,
375
+ tags: null,
376
+ priorFindings: null,
377
+ chainFindings: true,
378
+ missingInputMode: 'abort',
379
+ applyRegistryHooks: false,
380
+ useRegistryChat: false,
381
+ })
382
+ ```
383
+
384
+ Custom analysts passed to `runExact()` declare canonical `executionConfig`.
385
+ The same `defineTraceAnalyst()` helper returns an exact-capable analyst when that field is present.
386
+ Built-in analysts already declare it.
387
+ Trace analysts selected by `runExact()` also require `aiIdentity`, using the same non-secret `id`, `version`, and canonical `config` shape as cost ledgers, registry hooks, and registry chat clients.
388
+ Exact lifecycle hooks receive frozen snapshots for observation; they cannot rewrite the planned context.
389
+ Persisted results store configuration digests, not raw configuration.
390
+ The persisted plan records the exact equal or weighted allocation for every routed analyst, and archival validates summaries against that same plan.
391
+ Every exact receipt says whether it is `complete` or `failed`; a complete receipt must cover the full plan, while a failed receipt may contain only the executed prefix.
392
+ Any failure after an exact run starts rejects with `ExactAnalystRunExecutionError`; its immutable failed receipt preserves valid completed summaries, findings, usage, and cost.
359
393
 
360
394
  See [concepts](./docs/concepts.md), [customer paths](./docs/customer-journeys.md), and [trace analysis](./docs/trace-analysis.md).
361
395
 
@@ -368,8 +402,9 @@ See [concepts](./docs/concepts.md), [customer paths](./docs/customer-journeys.md
368
402
  | `@tangle-network/agent-eval/profile-cell` | Create and validate portable agent-profile identities. |
369
403
  | `@tangle-network/agent-eval/ledger-core` | Generic hash-chained append-only journal: idempotent append, chain verification, trusted-head pinning, replay-to-projection, cross-process locking. |
370
404
  | `@tangle-network/agent-eval/reporting` | Statistical comparisons and report rendering. |
371
- | `@tangle-network/agent-eval/analyst` | Model-assisted failure analysis. |
405
+ | `@tangle-network/agent-eval/analyst` | Built-in and custom trace analysts, labeled comparison, costs, and reports. |
372
406
  | `@tangle-network/agent-eval/traces` | Store, replay, and inspect structured traces. |
407
+ | `@tangle-network/agent-eval/supervisor-run` | Read and analyze recursive supervisor runs without collapsing missing measurements to zero. |
373
408
  | `@tangle-network/agent-eval/benchmarks` | Benchmark adapters and retrieval metrics. |
374
409
  | `@tangle-network/agent-eval/rl` | Export rewards, preferences, and training rows. |
375
410
  | `@tangle-network/agent-eval/wire` | HTTP and RPC schemas for other languages. |
@@ -1,4 +1,4 @@
1
- import { s as ValidationError } from "./errors-8YnH8WlF.js";
1
+ import { c as ValidationError } from "./errors-D-LKuDhb.js";
2
2
  //#region src/pre-registration.ts
3
3
  /**
4
4
  * Deterministic JSON canonicalization — sort object keys recursively.
@@ -332,4 +332,4 @@ async function buildAgentInterfaceProfileCell(profile, input) {
332
332
  //#endregion
333
333
  export { verifyManifest as _, assertRunAgentProfileCell as a, groupRunsByAgentProfileCell as c, validateAgentProfileCell as d, verifyAgentProfileCell as f, signManifest as g, hashJson as h, agentProfileCellKey as i, requireAgentProfileCell as l, evaluateHypothesis as m, AgentProfileCellValidationError as n, buildAgentInterfaceProfileCell as o, canonicalize as p, agentProfileCellHashMaterial as r, buildAgentProfileCell as s, AGENT_PROFILE_KINDS as t, toAgentProfileJson as u };
334
334
 
335
- //# sourceMappingURL=agent-profile-cell-OhuTee9n.js.map
335
+ //# sourceMappingURL=agent-profile-cell-CbfBm2g6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-profile-cell-OhuTee9n.js","names":[],"sources":["../src/pre-registration.ts","../src/agent-profile-cell.ts"],"sourcesContent":["/**\n * Pre-registered hypotheses — declare what you're testing BEFORE the\n * run, check it AFTER. Prevents p-hacking, optional stopping, and the\n * \"we ran until it looked good\" failure mode.\n *\n * Manifest is a plain JSON-friendly object. Sign it with a content hash\n * + timestamp; the registered record becomes immutable. Post-run,\n * evaluate the manifest against observed results — the library refuses\n * to let you re-interpret a different metric as the declared one.\n */\n\nexport interface HypothesisManifest {\n id: string\n /** Human prose — goes into the audit trail. */\n hypothesis: string\n /** Metric the hypothesis claims to move. */\n metric: string\n /** 'increase' = candidate should score higher than baseline; 'decrease' = lower. */\n direction: 'increase' | 'decrease'\n /** Minimum effect size to count (same units as the metric). */\n minEffect: number\n /** Alpha threshold. */\n alpha: number\n /** Target statistical power at which sample size was pre-computed. */\n power: number\n /** Declared N per arm before running. */\n preRegisteredN: number\n /** ISO8601 timestamp the manifest was registered. */\n registeredAt: string\n /** Optional identifiers to tie into the trace corpus. */\n baselineLabel?: string\n candidateLabel?: string\n}\n\n/**\n * Identifier for the hashing scheme used to produce `contentHash`.\n *\n * `'sha256-content'` — sha256 hex over the canonicalized manifest with\n * the `contentHash` and `algo` fields stripped. Held as a string union\n * so future schemes can be added without breaking parsers; SignedManifest\n * values without `algo` deserialize cleanly because the field is optional.\n */\nexport type SignedManifestAlgo = 'sha256-content'\n\nexport interface SignedManifest extends HypothesisManifest {\n /** sha256 hex of canonicalized manifest (everything except contentHash and algo). */\n contentHash: string\n /**\n * Algorithm string describing how `contentHash` was produced.\n *\n * Optional on the type so serialized manifests without it still parse,\n * but ALWAYS populated by {@link signManifest}. Consumers that want to\n * enforce a known algorithm should reject manifests where this field\n * is missing or unrecognized.\n */\n algo?: SignedManifestAlgo\n}\n\nexport interface HypothesisResult {\n manifest: SignedManifest\n observedN: number\n observedEffect: number\n observedPValue: number\n /** True iff the observed effect hits the pre-declared direction with\n * magnitude ≥ minEffect AND p < alpha. */\n confirmed: boolean\n /** Enumerated reasons the hypothesis was rejected (each a machine-tag). */\n rejectionReasons: Array<\n 'wrong_direction' | 'effect_too_small' | 'not_significant' | 'undersampled'\n >\n notes?: string\n}\n\n/**\n * Deterministic JSON canonicalization — sort object keys recursively.\n *\n * Two semantically-equal objects produce byte-identical canonicalized output;\n * this is what makes a content-hash stable across encoders, key insertion\n * orders, and runtime versions. Exported for any consumer that needs the same\n * canonicalization guarantee outside the manifest-signing path (e.g., signing\n * an artifact bundle, hashing a dataset version, etc.).\n */\nexport function canonicalize(v: unknown): unknown {\n if (v === null || typeof v !== 'object') return v\n if (Array.isArray(v)) return v.map(canonicalize)\n const keys = Object.keys(v as Record<string, unknown>).sort()\n const out: Record<string, unknown> = {}\n for (const k of keys) out[k] = canonicalize((v as Record<string, unknown>)[k])\n return out\n}\n\n/**\n * SHA-256 hex (full 64 chars) over the canonicalized JSON encoding of `obj`.\n *\n * The same primitive `signManifest` and `verifyManifest` are built on, exposed\n * directly so consumers signing arbitrary structured content (artifact bundles,\n * production packets, dataset manifests, etc.) don't have to re-derive\n * canonicalize+sha256 from scratch.\n *\n * Stable across:\n * - object key insertion order (canonicalization sorts keys recursively)\n * - encoder choice (UTF-8 via TextEncoder, fixed)\n * - runtime (uses the Web Crypto subtle digest, present in Node ≥18 and browsers)\n *\n * Named `hashJson` to disambiguate from `prompt-registry.ts`'s `hashContent`,\n * which takes a string input and returns a truncated 12-char prompt id.\n * Use `hashJson` when you mean \"canonicalize then hash.\"\n *\n * @example\n * const hash = await hashJson({ id: '1', kind: 'spec' })\n * // 'a3f1...' (64 hex chars)\n */\nexport async function hashJson<T>(obj: T): Promise<string> {\n const canonical = canonicalize(obj)\n const bytes = new TextEncoder().encode(JSON.stringify(canonical))\n const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes)\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Sign a manifest with a SHA-256 content hash.\n *\n * The hash covers the canonicalized manifest with the `contentHash`\n * and `algo` fields stripped; this lets verifiers re-sign the rest and\n * compare. Returned manifest always carries `algo: 'sha256-content'`\n * so downstream consumers can identify the scheme; manifests without\n * `algo` still verify because it is stripped before hashing on both sides.\n */\nexport async function signManifest(m: HypothesisManifest): Promise<SignedManifest> {\n const hash = await hashJson(m)\n return { ...m, contentHash: hash, algo: 'sha256-content' }\n}\n\n/**\n * Verify that a signed manifest has not been tampered with.\n *\n * Strips `contentHash` and `algo` before re-signing so manifests without\n * `algo` verify identically to ones that carry it.\n */\nexport async function verifyManifest(m: SignedManifest): Promise<boolean> {\n const { contentHash, algo: _algo, ...rest } = m\n void _algo\n const resigned = await signManifest(rest)\n return resigned.contentHash === contentHash\n}\n\n/**\n * Evaluate a pre-registered hypothesis against observed results.\n * Mechanical — no re-interpretation permitted.\n */\nexport async function evaluateHypothesis(\n manifest: SignedManifest,\n observed: { n: number; effect: number; pValue: number },\n): Promise<HypothesisResult> {\n if (!(await verifyManifest(manifest))) {\n throw new Error('evaluateHypothesis: manifest content hash mismatch (tampered)')\n }\n const reasons: HypothesisResult['rejectionReasons'] = []\n const directionOk = manifest.direction === 'increase' ? observed.effect > 0 : observed.effect < 0\n if (!directionOk) reasons.push('wrong_direction')\n if (Math.abs(observed.effect) < manifest.minEffect) reasons.push('effect_too_small')\n if (observed.pValue >= manifest.alpha) reasons.push('not_significant')\n if (observed.n < manifest.preRegisteredN) reasons.push('undersampled')\n return {\n manifest,\n observedN: observed.n,\n observedEffect: observed.effect,\n observedPValue: observed.pValue,\n confirmed: reasons.length === 0,\n rejectionReasons: reasons,\n }\n}\n","import type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ValidationError } from './errors'\nimport { hashJson } from './pre-registration'\n\nexport type AgentProfileCellSchemaVersion = 'agent-profile-cell/v1'\n\nexport type AgentProfileJsonObject = { [key: string]: AgentProfileJson }\n\nexport type AgentProfileJson =\n | string\n | number\n | boolean\n | null\n | AgentProfileJson[]\n | AgentProfileJsonObject\n\nexport type AgentProfileDimensionValue = string | number | boolean | null\n\nexport interface AgentProfileSource {\n /** Runtime/profile contract being fingerprinted, e.g. `agent-interface-profile`. */\n kind: string\n /** sha256 over the canonical source profile object. */\n hash: string\n}\n\nexport interface AgentProfileSourceInput {\n kind: string\n /** Precomputed sha256 for callers that already sign their profile artifact. */\n hash?: string\n /** Full canonical runtime profile; hashed and then discarded from the cell. */\n profile?: AgentProfileJson\n}\n\nexport interface AgentProfileHarness {\n id: string\n version?: string\n hash?: string\n}\n\nexport interface AgentProfileCellInput {\n profileId: string\n sourceProfile: AgentProfileSourceInput\n harness?: AgentProfileHarness\n model?: string\n promptHash?: string\n dimensions?: Record<string, AgentProfileDimensionValue>\n}\n\nexport interface AgentProfileCell {\n schemaVersion: AgentProfileCellSchemaVersion\n cellId: string\n profileId: string\n sourceProfile: AgentProfileSource\n harness?: AgentProfileHarness\n model?: string\n promptHash?: string\n dimensions?: Record<string, AgentProfileDimensionValue>\n}\n\nexport class AgentProfileCellValidationError extends ValidationError {\n readonly path: string\n constructor(message: string, path = '') {\n super(path ? `${message} (at ${path})` : message)\n this.path = path\n }\n}\n\nconst SHA256_HEX = /^[0-9a-f]{64}$/\nconst CELL_ID = /^agent-profile-cell:sha256:[0-9a-f]{64}$/\n\nexport async function buildAgentProfileCell(\n input: AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n const material = await normalizeAgentProfileCellInput(input)\n const cellId = `agent-profile-cell:sha256:${await hashJson(material)}`\n return { ...material, cellId }\n}\n\nexport function agentProfileCellHashMaterial(\n cell: AgentProfileCell,\n): Omit<AgentProfileCell, 'cellId'> {\n const { cellId: _cellId, ...material } = cell\n void _cellId\n return normalizeAgentProfileCell(material)\n}\n\n/**\n * Verify an `AgentProfileCell`'s `cellId` matches the sha256 of its hash-material fields, confirming the record has not been tampered with.\n */\nexport async function verifyAgentProfileCell(cell: AgentProfileCell): Promise<boolean> {\n validateAgentProfileCell(cell)\n return (\n cell.cellId ===\n `agent-profile-cell:sha256:${await hashJson(agentProfileCellHashMaterial(cell))}`\n )\n}\n\nexport function validateAgentProfileCell(input: unknown): AgentProfileCell {\n if (input === null || typeof input !== 'object') {\n throw new AgentProfileCellValidationError('expected object')\n }\n const obj = input as Record<string, unknown>\n expectLiteral(obj.schemaVersion, 'agent-profile-cell/v1', 'schemaVersion')\n if (typeof obj.cellId !== 'string' || !CELL_ID.test(obj.cellId)) {\n throw new AgentProfileCellValidationError(\n 'cellId must match agent-profile-cell:sha256:<64 lowercase hex chars>',\n 'cellId',\n )\n }\n expectString(obj.profileId, 'profileId')\n validateSource(obj.sourceProfile, 'sourceProfile')\n if (obj.harness !== undefined) validateHarness(obj.harness, 'harness')\n if (obj.model !== undefined) expectString(obj.model, 'model')\n if (obj.promptHash !== undefined) expectString(obj.promptHash, 'promptHash')\n if (obj.dimensions !== undefined) validateDimensions(obj.dimensions, 'dimensions')\n return input as AgentProfileCell\n}\n\nexport function requireAgentProfileCell(record: {\n runId: string\n agentProfile?: AgentProfileCell\n}): AgentProfileCell {\n if (!record.agentProfile) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" is missing agentProfile; profile-cell grouping requires explicit profile identity`,\n 'agentProfile',\n )\n }\n return validateAgentProfileCell(record.agentProfile)\n}\n\nexport function agentProfileCellKey(record: {\n runId: string\n agentProfile?: AgentProfileCell\n}): string {\n return requireAgentProfileCell(record).cellId\n}\n\nexport async function assertRunAgentProfileCell(record: {\n runId: string\n model: string\n promptHash: string\n agentProfile?: AgentProfileCell\n}): Promise<AgentProfileCell> {\n const profile = requireAgentProfileCell(record)\n if (!(await verifyAgentProfileCell(profile))) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" has an agentProfile.cellId that does not match its content`,\n 'agentProfile.cellId',\n )\n }\n if (profile.model !== undefined && profile.model !== record.model) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" agentProfile.model \"${profile.model}\" does not match model \"${record.model}\"`,\n 'agentProfile.model',\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== record.promptHash) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" agentProfile.promptHash \"${profile.promptHash}\" does not match promptHash \"${record.promptHash}\"`,\n 'agentProfile.promptHash',\n )\n }\n return profile\n}\n\nexport function groupRunsByAgentProfileCell<\n T extends { runId: string; agentProfile?: AgentProfileCell },\n>(records: readonly T[]): Map<string, T[]> {\n const groups = new Map<string, T[]>()\n for (const record of records) {\n const key = agentProfileCellKey(record)\n const bucket = groups.get(key)\n if (bucket) bucket.push(record)\n else groups.set(key, [record])\n }\n return groups\n}\n\nasync function normalizeAgentProfileCellInput(\n input: AgentProfileCellInput,\n): Promise<Omit<AgentProfileCell, 'cellId'>> {\n return normalizeAgentProfileCell({\n schemaVersion: 'agent-profile-cell/v1',\n profileId: input.profileId,\n sourceProfile: await normalizeSourceInput(input.sourceProfile),\n harness: input.harness,\n model: input.model,\n promptHash: input.promptHash,\n dimensions: input.dimensions,\n })\n}\n\nfunction normalizeAgentProfileCell(\n input: Omit<AgentProfileCell, 'cellId'>,\n): Omit<AgentProfileCell, 'cellId'> {\n return compactObject({\n schemaVersion: 'agent-profile-cell/v1' as const,\n profileId: requireNonEmpty(input.profileId, 'profileId'),\n sourceProfile: normalizeSource(input.sourceProfile),\n harness: input.harness ? normalizeHarness(input.harness, 'harness') : undefined,\n model: optionalNonEmpty(input.model, 'model'),\n promptHash: optionalNonEmpty(input.promptHash, 'promptHash'),\n dimensions: input.dimensions\n ? nonEmptyRecord(normalizeDimensions(input.dimensions))\n : undefined,\n })\n}\n\nasync function normalizeSourceInput(input: AgentProfileSourceInput): Promise<AgentProfileSource> {\n const kind = requireNonEmpty(input.kind, 'sourceProfile.kind')\n if (input.hash !== undefined && input.profile !== undefined) {\n throw new AgentProfileCellValidationError(\n 'sourceProfile must provide either hash or profile, not both',\n 'sourceProfile',\n )\n }\n if (input.hash !== undefined) {\n return { kind, hash: requireSha256Hex(input.hash, 'sourceProfile.hash') }\n }\n if (input.profile === undefined) {\n throw new AgentProfileCellValidationError(\n 'sourceProfile must provide hash or profile',\n 'sourceProfile',\n )\n }\n assertJson(input.profile, 'sourceProfile.profile')\n return { kind, hash: await hashJson(input.profile) }\n}\n\nfunction normalizeSource(input: AgentProfileSource): AgentProfileSource {\n return {\n kind: requireNonEmpty(input.kind, 'sourceProfile.kind'),\n hash: requireSha256Hex(input.hash, 'sourceProfile.hash'),\n }\n}\n\nfunction normalizeHarness(input: AgentProfileHarness, path: string): AgentProfileHarness {\n return compactObject({\n id: requireNonEmpty(input.id, `${path}.id`),\n version: optionalNonEmpty(input.version, `${path}.version`),\n hash: optionalNonEmpty(input.hash, `${path}.hash`),\n })\n}\n\nfunction normalizeDimensions(\n input: Record<string, AgentProfileDimensionValue>,\n): Record<string, AgentProfileDimensionValue> {\n const out: Record<string, AgentProfileDimensionValue> = {}\n for (const key of Object.keys(input).sort()) {\n const value = input[key]\n requireNonEmpty(key, 'dimensions.<key>')\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new AgentProfileCellValidationError(\n 'expected primitive dimension value',\n `dimensions.${key}`,\n )\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw new AgentProfileCellValidationError('expected finite number', `dimensions.${key}`)\n }\n out[key] = value\n }\n return out\n}\n\nfunction compactObject<T extends Record<string, unknown>>(input: T): T {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) out[key] = value\n }\n return out as T\n}\n\nfunction nonEmptyRecord<T extends Record<string, unknown>>(input: T): T | undefined {\n return Object.keys(input).length > 0 ? input : undefined\n}\n\nfunction validateSource(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n const rec = value as Record<string, unknown>\n expectString(rec.kind, `${path}.kind`)\n requireSha256Hex(rec.hash, `${path}.hash`)\n}\n\nfunction validateHarness(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n const rec = value as Record<string, unknown>\n expectString(rec.id, `${path}.id`)\n if (rec.version !== undefined) expectString(rec.version, `${path}.version`)\n if (rec.hash !== undefined) expectString(rec.hash, `${path}.hash`)\n}\n\nfunction validateDimensions(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n normalizeDimensions(value as Record<string, AgentProfileDimensionValue>)\n}\n\nfunction assertJson(value: AgentProfileJson, path: string): void {\n if (value === null) return\n const type = typeof value\n if (type === 'string' || type === 'boolean') return\n if (type === 'number') {\n if (!Number.isFinite(value)) {\n throw new AgentProfileCellValidationError('expected finite number', path)\n }\n return\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n assertJson(item, `${path}[${index}]`)\n })\n return\n }\n if (type === 'object') {\n for (const [key, nested] of Object.entries(value)) {\n requireNonEmpty(key, `${path}.<key>`)\n assertJson(nested, `${path}.${key}`)\n }\n return\n }\n throw new AgentProfileCellValidationError('expected JSON-compatible value', path)\n}\n\nfunction expectLiteral(value: unknown, expected: string, path: string): void {\n if (value !== expected) {\n throw new AgentProfileCellValidationError(`expected ${expected}`, path)\n }\n}\n\nfunction expectString(value: unknown, path: string): void {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AgentProfileCellValidationError('expected non-empty string', path)\n }\n}\n\nfunction requireNonEmpty(value: string, path: string): string {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AgentProfileCellValidationError('expected non-empty string', path)\n }\n return value\n}\n\nfunction optionalNonEmpty(value: string | undefined, path: string): string | undefined {\n if (value === undefined) return undefined\n return requireNonEmpty(value, path)\n}\n\nfunction requireSha256Hex(value: unknown, path: string): string {\n if (typeof value !== 'string' || !SHA256_HEX.test(value)) {\n throw new AgentProfileCellValidationError('expected 64 lowercase sha256 hex chars', path)\n }\n return value\n}\n\n// ── Consumer helpers ─────────────────────────────────────────────────\n//\n// Boilerplate every product consuming `buildAgentProfileCell` used to duplicate:\n//\n// 1. A `JSON.parse(JSON.stringify(value))` helper that canonicalizes an\n// arbitrary `@tangle-network/agent-interface` `AgentProfile` into the recursive\n// `AgentProfileJson` shape, with a fail-loud error when the profile\n// is not JSON-serializable.\n//\n// 2. The magic string `'agent-interface-profile'` for `sourceProfile.kind`.\n//\n// Both belong here so the cross-product cell join (same canonical profile\n// hashes to the same `sourceProfile.hash` across products) is enforced by\n// the type system, not by every consumer remembering to do it right.\n// See blueprint-agent issue tangle-network/agent-eval#82.\n\n/** Canonical `sourceProfile.kind` values. Two products fingerprinting the\n * same canonical profile MUST use the same kind for their cells to share\n * `sourceProfile.hash`. Extend rather than create new strings — adding a\n * new kind is a deliberate cross-product schema change. */\nexport const AGENT_PROFILE_KINDS = {\n /** A profile declared via `defineAgentProfile(...)` from\n * `@tangle-network/agent-interface`. The default kind for router-backed\n * and sandbox-backed products. */\n AGENT_INTERFACE_PROFILE: 'agent-interface-profile',\n} as const\n\nexport type AgentProfileKind = (typeof AGENT_PROFILE_KINDS)[keyof typeof AGENT_PROFILE_KINDS]\n\n/** Canonicalize an arbitrary value into `AgentProfileJson` by JSON\n * round-trip. Throws when the value contains anything not representable\n * as JSON (functions, BigInt, cycles) — non-portable profiles fail loud\n * rather than silently dropping fields. */\nexport function toAgentProfileJson(value: unknown): AgentProfileJson {\n let serialized: string | undefined\n try {\n serialized = JSON.stringify(value)\n } catch (err) {\n throw new AgentProfileCellValidationError(\n `agent profile must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`,\n 'sourceProfile.profile',\n )\n }\n if (serialized === undefined) {\n throw new AgentProfileCellValidationError(\n 'agent profile must be JSON-serializable (got undefined after JSON.stringify)',\n 'sourceProfile.profile',\n )\n }\n return JSON.parse(serialized) as AgentProfileJson\n}\n\n/** Canonical AgentProfile shape required when deriving a stable cell id. */\nexport type AgentInterfaceProfileLike = AgentProfile & { name: string; version: string }\n\n/** Higher-level helper that hard-codes the canonical\n * `agent-interface-profile` kind plus the JSON canonicalization. Equivalent\n * to calling `buildAgentProfileCell` with `profileId = \\`${name}@${version}\\``\n * and `sourceProfile = { kind: AGENT_INTERFACE_PROFILE, profile: <round-tripped> }`.\n *\n * Use this from any product consuming an agent-interface `AgentProfile`; the\n * manual `buildAgentProfileCell` call is reserved for advanced cases\n * (custom kinds, pre-computed source hashes, alternate profileId\n * conventions). */\nexport async function buildAgentInterfaceProfileCell(\n profile: AgentInterfaceProfileLike,\n input: Omit<AgentProfileCellInput, 'profileId' | 'sourceProfile'>,\n): Promise<AgentProfileCell> {\n if (!profile || typeof profile !== 'object') {\n throw new AgentProfileCellValidationError('AgentProfile must be an object', 'profile')\n }\n if (typeof profile.name !== 'string' || profile.name.length === 0) {\n throw new AgentProfileCellValidationError(\n 'AgentProfile must have a non-empty `name`',\n 'profile.name',\n )\n }\n if (typeof profile.version !== 'string' || profile.version.length === 0) {\n throw new AgentProfileCellValidationError(\n 'AgentProfile must have a non-empty `version`',\n 'profile.version',\n )\n }\n return buildAgentProfileCell({\n ...input,\n profileId: `${profile.name}@${profile.version}`,\n sourceProfile: {\n kind: AGENT_PROFILE_KINDS.AGENT_INTERFACE_PROFILE,\n profile: toAgentProfileJson(profile),\n },\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-profile-cell-CbfBm2g6.js","names":[],"sources":["../src/pre-registration.ts","../src/agent-profile-cell.ts"],"sourcesContent":["/**\n * Pre-registered hypotheses — declare what you're testing BEFORE the\n * run, check it AFTER. Prevents p-hacking, optional stopping, and the\n * \"we ran until it looked good\" failure mode.\n *\n * Manifest is a plain JSON-friendly object. Sign it with a content hash\n * + timestamp; the registered record becomes immutable. Post-run,\n * evaluate the manifest against observed results — the library refuses\n * to let you re-interpret a different metric as the declared one.\n */\n\nexport interface HypothesisManifest {\n id: string\n /** Human prose — goes into the audit trail. */\n hypothesis: string\n /** Metric the hypothesis claims to move. */\n metric: string\n /** 'increase' = candidate should score higher than baseline; 'decrease' = lower. */\n direction: 'increase' | 'decrease'\n /** Minimum effect size to count (same units as the metric). */\n minEffect: number\n /** Alpha threshold. */\n alpha: number\n /** Target statistical power at which sample size was pre-computed. */\n power: number\n /** Declared N per arm before running. */\n preRegisteredN: number\n /** ISO8601 timestamp the manifest was registered. */\n registeredAt: string\n /** Optional identifiers to tie into the trace corpus. */\n baselineLabel?: string\n candidateLabel?: string\n}\n\n/**\n * Identifier for the hashing scheme used to produce `contentHash`.\n *\n * `'sha256-content'` — sha256 hex over the canonicalized manifest with\n * the `contentHash` and `algo` fields stripped. Held as a string union\n * so future schemes can be added without breaking parsers; SignedManifest\n * values without `algo` deserialize cleanly because the field is optional.\n */\nexport type SignedManifestAlgo = 'sha256-content'\n\nexport interface SignedManifest extends HypothesisManifest {\n /** sha256 hex of canonicalized manifest (everything except contentHash and algo). */\n contentHash: string\n /**\n * Algorithm string describing how `contentHash` was produced.\n *\n * Optional on the type so serialized manifests without it still parse,\n * but ALWAYS populated by {@link signManifest}. Consumers that want to\n * enforce a known algorithm should reject manifests where this field\n * is missing or unrecognized.\n */\n algo?: SignedManifestAlgo\n}\n\nexport interface HypothesisResult {\n manifest: SignedManifest\n observedN: number\n observedEffect: number\n observedPValue: number\n /** True iff the observed effect hits the pre-declared direction with\n * magnitude ≥ minEffect AND p < alpha. */\n confirmed: boolean\n /** Enumerated reasons the hypothesis was rejected (each a machine-tag). */\n rejectionReasons: Array<\n 'wrong_direction' | 'effect_too_small' | 'not_significant' | 'undersampled'\n >\n notes?: string\n}\n\n/**\n * Deterministic JSON canonicalization — sort object keys recursively.\n *\n * Two semantically-equal objects produce byte-identical canonicalized output;\n * this is what makes a content-hash stable across encoders, key insertion\n * orders, and runtime versions. Exported for any consumer that needs the same\n * canonicalization guarantee outside the manifest-signing path (e.g., signing\n * an artifact bundle, hashing a dataset version, etc.).\n */\nexport function canonicalize(v: unknown): unknown {\n if (v === null || typeof v !== 'object') return v\n if (Array.isArray(v)) return v.map(canonicalize)\n const keys = Object.keys(v as Record<string, unknown>).sort()\n const out: Record<string, unknown> = {}\n for (const k of keys) out[k] = canonicalize((v as Record<string, unknown>)[k])\n return out\n}\n\n/**\n * SHA-256 hex (full 64 chars) over the canonicalized JSON encoding of `obj`.\n *\n * The same primitive `signManifest` and `verifyManifest` are built on, exposed\n * directly so consumers signing arbitrary structured content (artifact bundles,\n * production packets, dataset manifests, etc.) don't have to re-derive\n * canonicalize+sha256 from scratch.\n *\n * Stable across:\n * - object key insertion order (canonicalization sorts keys recursively)\n * - encoder choice (UTF-8 via TextEncoder, fixed)\n * - runtime (uses the Web Crypto subtle digest, present in Node ≥18 and browsers)\n *\n * Named `hashJson` to disambiguate from `prompt-registry.ts`'s `hashContent`,\n * which takes a string input and returns a truncated 12-char prompt id.\n * Use `hashJson` when you mean \"canonicalize then hash.\"\n *\n * @example\n * const hash = await hashJson({ id: '1', kind: 'spec' })\n * // 'a3f1...' (64 hex chars)\n */\nexport async function hashJson<T>(obj: T): Promise<string> {\n const canonical = canonicalize(obj)\n const bytes = new TextEncoder().encode(JSON.stringify(canonical))\n const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes)\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Sign a manifest with a SHA-256 content hash.\n *\n * The hash covers the canonicalized manifest with the `contentHash`\n * and `algo` fields stripped; this lets verifiers re-sign the rest and\n * compare. Returned manifest always carries `algo: 'sha256-content'`\n * so downstream consumers can identify the scheme; manifests without\n * `algo` still verify because it is stripped before hashing on both sides.\n */\nexport async function signManifest(m: HypothesisManifest): Promise<SignedManifest> {\n const hash = await hashJson(m)\n return { ...m, contentHash: hash, algo: 'sha256-content' }\n}\n\n/**\n * Verify that a signed manifest has not been tampered with.\n *\n * Strips `contentHash` and `algo` before re-signing so manifests without\n * `algo` verify identically to ones that carry it.\n */\nexport async function verifyManifest(m: SignedManifest): Promise<boolean> {\n const { contentHash, algo: _algo, ...rest } = m\n void _algo\n const resigned = await signManifest(rest)\n return resigned.contentHash === contentHash\n}\n\n/**\n * Evaluate a pre-registered hypothesis against observed results.\n * Mechanical — no re-interpretation permitted.\n */\nexport async function evaluateHypothesis(\n manifest: SignedManifest,\n observed: { n: number; effect: number; pValue: number },\n): Promise<HypothesisResult> {\n if (!(await verifyManifest(manifest))) {\n throw new Error('evaluateHypothesis: manifest content hash mismatch (tampered)')\n }\n const reasons: HypothesisResult['rejectionReasons'] = []\n const directionOk = manifest.direction === 'increase' ? observed.effect > 0 : observed.effect < 0\n if (!directionOk) reasons.push('wrong_direction')\n if (Math.abs(observed.effect) < manifest.minEffect) reasons.push('effect_too_small')\n if (observed.pValue >= manifest.alpha) reasons.push('not_significant')\n if (observed.n < manifest.preRegisteredN) reasons.push('undersampled')\n return {\n manifest,\n observedN: observed.n,\n observedEffect: observed.effect,\n observedPValue: observed.pValue,\n confirmed: reasons.length === 0,\n rejectionReasons: reasons,\n }\n}\n","import type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ValidationError } from './errors'\nimport { hashJson } from './pre-registration'\n\nexport type AgentProfileCellSchemaVersion = 'agent-profile-cell/v1'\n\nexport type AgentProfileJsonObject = { [key: string]: AgentProfileJson }\n\nexport type AgentProfileJson =\n | string\n | number\n | boolean\n | null\n | AgentProfileJson[]\n | AgentProfileJsonObject\n\nexport type AgentProfileDimensionValue = string | number | boolean | null\n\nexport interface AgentProfileSource {\n /** Runtime/profile contract being fingerprinted, e.g. `agent-interface-profile`. */\n kind: string\n /** sha256 over the canonical source profile object. */\n hash: string\n}\n\nexport interface AgentProfileSourceInput {\n kind: string\n /** Precomputed sha256 for callers that already sign their profile artifact. */\n hash?: string\n /** Full canonical runtime profile; hashed and then discarded from the cell. */\n profile?: AgentProfileJson\n}\n\nexport interface AgentProfileHarness {\n id: string\n version?: string\n hash?: string\n}\n\nexport interface AgentProfileCellInput {\n profileId: string\n sourceProfile: AgentProfileSourceInput\n harness?: AgentProfileHarness\n model?: string\n promptHash?: string\n dimensions?: Record<string, AgentProfileDimensionValue>\n}\n\nexport interface AgentProfileCell {\n schemaVersion: AgentProfileCellSchemaVersion\n cellId: string\n profileId: string\n sourceProfile: AgentProfileSource\n harness?: AgentProfileHarness\n model?: string\n promptHash?: string\n dimensions?: Record<string, AgentProfileDimensionValue>\n}\n\nexport class AgentProfileCellValidationError extends ValidationError {\n readonly path: string\n constructor(message: string, path = '') {\n super(path ? `${message} (at ${path})` : message)\n this.path = path\n }\n}\n\nconst SHA256_HEX = /^[0-9a-f]{64}$/\nconst CELL_ID = /^agent-profile-cell:sha256:[0-9a-f]{64}$/\n\nexport async function buildAgentProfileCell(\n input: AgentProfileCellInput,\n): Promise<AgentProfileCell> {\n const material = await normalizeAgentProfileCellInput(input)\n const cellId = `agent-profile-cell:sha256:${await hashJson(material)}`\n return { ...material, cellId }\n}\n\nexport function agentProfileCellHashMaterial(\n cell: AgentProfileCell,\n): Omit<AgentProfileCell, 'cellId'> {\n const { cellId: _cellId, ...material } = cell\n void _cellId\n return normalizeAgentProfileCell(material)\n}\n\n/**\n * Verify an `AgentProfileCell`'s `cellId` matches the sha256 of its hash-material fields, confirming the record has not been tampered with.\n */\nexport async function verifyAgentProfileCell(cell: AgentProfileCell): Promise<boolean> {\n validateAgentProfileCell(cell)\n return (\n cell.cellId ===\n `agent-profile-cell:sha256:${await hashJson(agentProfileCellHashMaterial(cell))}`\n )\n}\n\nexport function validateAgentProfileCell(input: unknown): AgentProfileCell {\n if (input === null || typeof input !== 'object') {\n throw new AgentProfileCellValidationError('expected object')\n }\n const obj = input as Record<string, unknown>\n expectLiteral(obj.schemaVersion, 'agent-profile-cell/v1', 'schemaVersion')\n if (typeof obj.cellId !== 'string' || !CELL_ID.test(obj.cellId)) {\n throw new AgentProfileCellValidationError(\n 'cellId must match agent-profile-cell:sha256:<64 lowercase hex chars>',\n 'cellId',\n )\n }\n expectString(obj.profileId, 'profileId')\n validateSource(obj.sourceProfile, 'sourceProfile')\n if (obj.harness !== undefined) validateHarness(obj.harness, 'harness')\n if (obj.model !== undefined) expectString(obj.model, 'model')\n if (obj.promptHash !== undefined) expectString(obj.promptHash, 'promptHash')\n if (obj.dimensions !== undefined) validateDimensions(obj.dimensions, 'dimensions')\n return input as AgentProfileCell\n}\n\nexport function requireAgentProfileCell(record: {\n runId: string\n agentProfile?: AgentProfileCell\n}): AgentProfileCell {\n if (!record.agentProfile) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" is missing agentProfile; profile-cell grouping requires explicit profile identity`,\n 'agentProfile',\n )\n }\n return validateAgentProfileCell(record.agentProfile)\n}\n\nexport function agentProfileCellKey(record: {\n runId: string\n agentProfile?: AgentProfileCell\n}): string {\n return requireAgentProfileCell(record).cellId\n}\n\nexport async function assertRunAgentProfileCell(record: {\n runId: string\n model: string\n promptHash: string\n agentProfile?: AgentProfileCell\n}): Promise<AgentProfileCell> {\n const profile = requireAgentProfileCell(record)\n if (!(await verifyAgentProfileCell(profile))) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" has an agentProfile.cellId that does not match its content`,\n 'agentProfile.cellId',\n )\n }\n if (profile.model !== undefined && profile.model !== record.model) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" agentProfile.model \"${profile.model}\" does not match model \"${record.model}\"`,\n 'agentProfile.model',\n )\n }\n if (profile.promptHash !== undefined && profile.promptHash !== record.promptHash) {\n throw new AgentProfileCellValidationError(\n `run \"${record.runId}\" agentProfile.promptHash \"${profile.promptHash}\" does not match promptHash \"${record.promptHash}\"`,\n 'agentProfile.promptHash',\n )\n }\n return profile\n}\n\nexport function groupRunsByAgentProfileCell<\n T extends { runId: string; agentProfile?: AgentProfileCell },\n>(records: readonly T[]): Map<string, T[]> {\n const groups = new Map<string, T[]>()\n for (const record of records) {\n const key = agentProfileCellKey(record)\n const bucket = groups.get(key)\n if (bucket) bucket.push(record)\n else groups.set(key, [record])\n }\n return groups\n}\n\nasync function normalizeAgentProfileCellInput(\n input: AgentProfileCellInput,\n): Promise<Omit<AgentProfileCell, 'cellId'>> {\n return normalizeAgentProfileCell({\n schemaVersion: 'agent-profile-cell/v1',\n profileId: input.profileId,\n sourceProfile: await normalizeSourceInput(input.sourceProfile),\n harness: input.harness,\n model: input.model,\n promptHash: input.promptHash,\n dimensions: input.dimensions,\n })\n}\n\nfunction normalizeAgentProfileCell(\n input: Omit<AgentProfileCell, 'cellId'>,\n): Omit<AgentProfileCell, 'cellId'> {\n return compactObject({\n schemaVersion: 'agent-profile-cell/v1' as const,\n profileId: requireNonEmpty(input.profileId, 'profileId'),\n sourceProfile: normalizeSource(input.sourceProfile),\n harness: input.harness ? normalizeHarness(input.harness, 'harness') : undefined,\n model: optionalNonEmpty(input.model, 'model'),\n promptHash: optionalNonEmpty(input.promptHash, 'promptHash'),\n dimensions: input.dimensions\n ? nonEmptyRecord(normalizeDimensions(input.dimensions))\n : undefined,\n })\n}\n\nasync function normalizeSourceInput(input: AgentProfileSourceInput): Promise<AgentProfileSource> {\n const kind = requireNonEmpty(input.kind, 'sourceProfile.kind')\n if (input.hash !== undefined && input.profile !== undefined) {\n throw new AgentProfileCellValidationError(\n 'sourceProfile must provide either hash or profile, not both',\n 'sourceProfile',\n )\n }\n if (input.hash !== undefined) {\n return { kind, hash: requireSha256Hex(input.hash, 'sourceProfile.hash') }\n }\n if (input.profile === undefined) {\n throw new AgentProfileCellValidationError(\n 'sourceProfile must provide hash or profile',\n 'sourceProfile',\n )\n }\n assertJson(input.profile, 'sourceProfile.profile')\n return { kind, hash: await hashJson(input.profile) }\n}\n\nfunction normalizeSource(input: AgentProfileSource): AgentProfileSource {\n return {\n kind: requireNonEmpty(input.kind, 'sourceProfile.kind'),\n hash: requireSha256Hex(input.hash, 'sourceProfile.hash'),\n }\n}\n\nfunction normalizeHarness(input: AgentProfileHarness, path: string): AgentProfileHarness {\n return compactObject({\n id: requireNonEmpty(input.id, `${path}.id`),\n version: optionalNonEmpty(input.version, `${path}.version`),\n hash: optionalNonEmpty(input.hash, `${path}.hash`),\n })\n}\n\nfunction normalizeDimensions(\n input: Record<string, AgentProfileDimensionValue>,\n): Record<string, AgentProfileDimensionValue> {\n const out: Record<string, AgentProfileDimensionValue> = {}\n for (const key of Object.keys(input).sort()) {\n const value = input[key]\n requireNonEmpty(key, 'dimensions.<key>')\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new AgentProfileCellValidationError(\n 'expected primitive dimension value',\n `dimensions.${key}`,\n )\n }\n if (typeof value === 'number' && !Number.isFinite(value)) {\n throw new AgentProfileCellValidationError('expected finite number', `dimensions.${key}`)\n }\n out[key] = value\n }\n return out\n}\n\nfunction compactObject<T extends Record<string, unknown>>(input: T): T {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) out[key] = value\n }\n return out as T\n}\n\nfunction nonEmptyRecord<T extends Record<string, unknown>>(input: T): T | undefined {\n return Object.keys(input).length > 0 ? input : undefined\n}\n\nfunction validateSource(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n const rec = value as Record<string, unknown>\n expectString(rec.kind, `${path}.kind`)\n requireSha256Hex(rec.hash, `${path}.hash`)\n}\n\nfunction validateHarness(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n const rec = value as Record<string, unknown>\n expectString(rec.id, `${path}.id`)\n if (rec.version !== undefined) expectString(rec.version, `${path}.version`)\n if (rec.hash !== undefined) expectString(rec.hash, `${path}.hash`)\n}\n\nfunction validateDimensions(value: unknown, path: string): void {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new AgentProfileCellValidationError('expected object', path)\n }\n normalizeDimensions(value as Record<string, AgentProfileDimensionValue>)\n}\n\nfunction assertJson(value: AgentProfileJson, path: string): void {\n if (value === null) return\n const type = typeof value\n if (type === 'string' || type === 'boolean') return\n if (type === 'number') {\n if (!Number.isFinite(value)) {\n throw new AgentProfileCellValidationError('expected finite number', path)\n }\n return\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n assertJson(item, `${path}[${index}]`)\n })\n return\n }\n if (type === 'object') {\n for (const [key, nested] of Object.entries(value)) {\n requireNonEmpty(key, `${path}.<key>`)\n assertJson(nested, `${path}.${key}`)\n }\n return\n }\n throw new AgentProfileCellValidationError('expected JSON-compatible value', path)\n}\n\nfunction expectLiteral(value: unknown, expected: string, path: string): void {\n if (value !== expected) {\n throw new AgentProfileCellValidationError(`expected ${expected}`, path)\n }\n}\n\nfunction expectString(value: unknown, path: string): void {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AgentProfileCellValidationError('expected non-empty string', path)\n }\n}\n\nfunction requireNonEmpty(value: string, path: string): string {\n if (typeof value !== 'string' || value.length === 0) {\n throw new AgentProfileCellValidationError('expected non-empty string', path)\n }\n return value\n}\n\nfunction optionalNonEmpty(value: string | undefined, path: string): string | undefined {\n if (value === undefined) return undefined\n return requireNonEmpty(value, path)\n}\n\nfunction requireSha256Hex(value: unknown, path: string): string {\n if (typeof value !== 'string' || !SHA256_HEX.test(value)) {\n throw new AgentProfileCellValidationError('expected 64 lowercase sha256 hex chars', path)\n }\n return value\n}\n\n// ── Consumer helpers ─────────────────────────────────────────────────\n//\n// Boilerplate every product consuming `buildAgentProfileCell` used to duplicate:\n//\n// 1. A `JSON.parse(JSON.stringify(value))` helper that canonicalizes an\n// arbitrary `@tangle-network/agent-interface` `AgentProfile` into the recursive\n// `AgentProfileJson` shape, with a fail-loud error when the profile\n// is not JSON-serializable.\n//\n// 2. The magic string `'agent-interface-profile'` for `sourceProfile.kind`.\n//\n// Both belong here so the cross-product cell join (same canonical profile\n// hashes to the same `sourceProfile.hash` across products) is enforced by\n// the type system, not by every consumer remembering to do it right.\n// See blueprint-agent issue tangle-network/agent-eval#82.\n\n/** Canonical `sourceProfile.kind` values. Two products fingerprinting the\n * same canonical profile MUST use the same kind for their cells to share\n * `sourceProfile.hash`. Extend rather than create new strings — adding a\n * new kind is a deliberate cross-product schema change. */\nexport const AGENT_PROFILE_KINDS = {\n /** A profile declared via `defineAgentProfile(...)` from\n * `@tangle-network/agent-interface`. The default kind for router-backed\n * and sandbox-backed products. */\n AGENT_INTERFACE_PROFILE: 'agent-interface-profile',\n} as const\n\nexport type AgentProfileKind = (typeof AGENT_PROFILE_KINDS)[keyof typeof AGENT_PROFILE_KINDS]\n\n/** Canonicalize an arbitrary value into `AgentProfileJson` by JSON\n * round-trip. Throws when the value contains anything not representable\n * as JSON (functions, BigInt, cycles) — non-portable profiles fail loud\n * rather than silently dropping fields. */\nexport function toAgentProfileJson(value: unknown): AgentProfileJson {\n let serialized: string | undefined\n try {\n serialized = JSON.stringify(value)\n } catch (err) {\n throw new AgentProfileCellValidationError(\n `agent profile must be JSON-serializable: ${err instanceof Error ? err.message : String(err)}`,\n 'sourceProfile.profile',\n )\n }\n if (serialized === undefined) {\n throw new AgentProfileCellValidationError(\n 'agent profile must be JSON-serializable (got undefined after JSON.stringify)',\n 'sourceProfile.profile',\n )\n }\n return JSON.parse(serialized) as AgentProfileJson\n}\n\n/** Canonical AgentProfile shape required when deriving a stable cell id. */\nexport type AgentInterfaceProfileLike = AgentProfile & { name: string; version: string }\n\n/** Higher-level helper that hard-codes the canonical\n * `agent-interface-profile` kind plus the JSON canonicalization. Equivalent\n * to calling `buildAgentProfileCell` with `profileId = \\`${name}@${version}\\``\n * and `sourceProfile = { kind: AGENT_INTERFACE_PROFILE, profile: <round-tripped> }`.\n *\n * Use this from any product consuming an agent-interface `AgentProfile`; the\n * manual `buildAgentProfileCell` call is reserved for advanced cases\n * (custom kinds, pre-computed source hashes, alternate profileId\n * conventions). */\nexport async function buildAgentInterfaceProfileCell(\n profile: AgentInterfaceProfileLike,\n input: Omit<AgentProfileCellInput, 'profileId' | 'sourceProfile'>,\n): Promise<AgentProfileCell> {\n if (!profile || typeof profile !== 'object') {\n throw new AgentProfileCellValidationError('AgentProfile must be an object', 'profile')\n }\n if (typeof profile.name !== 'string' || profile.name.length === 0) {\n throw new AgentProfileCellValidationError(\n 'AgentProfile must have a non-empty `name`',\n 'profile.name',\n )\n }\n if (typeof profile.version !== 'string' || profile.version.length === 0) {\n throw new AgentProfileCellValidationError(\n 'AgentProfile must have a non-empty `version`',\n 'profile.version',\n )\n }\n return buildAgentProfileCell({\n ...input,\n profileId: `${profile.name}@${profile.version}`,\n sourceProfile: {\n kind: AGENT_PROFILE_KINDS.AGENT_INTERFACE_PROFILE,\n profile: toAgentProfileJson(profile),\n },\n })\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as ValidationError } from "./errors-CEk209JS.js";
1
+ import { l as ValidationError } from "./errors-DkfjIDvD.js";
2
2
  import { AgentProfile } from "@tangle-network/agent-interface";
3
3
  //#region src/agent-profile-cell.d.ts
4
4
  type AgentProfileCellSchemaVersion = 'agent-profile-cell/v1';
@@ -105,4 +105,4 @@ type AgentInterfaceProfileLike = AgentProfile & {
105
105
  declare function buildAgentInterfaceProfileCell(profile: AgentInterfaceProfileLike, input: Omit<AgentProfileCellInput, 'profileId' | 'sourceProfile'>): Promise<AgentProfileCell>;
106
106
  //#endregion
107
107
  export { verifyAgentProfileCell as C, validateAgentProfileCell as S, buildAgentInterfaceProfileCell as _, AgentProfileCellSchemaVersion as a, requireAgentProfileCell as b, AgentProfileHarness as c, AgentProfileKind as d, AgentProfileSource as f, assertRunAgentProfileCell as g, agentProfileCellKey as h, AgentProfileCellInput as i, AgentProfileJson as l, agentProfileCellHashMaterial as m, AgentInterfaceProfileLike as n, AgentProfileCellValidationError as o, AgentProfileSourceInput as p, AgentProfileCell as r, AgentProfileDimensionValue as s, AGENT_PROFILE_KINDS as t, AgentProfileJsonObject as u, buildAgentProfileCell as v, toAgentProfileJson as x, groupRunsByAgentProfileCell as y };
108
- //# sourceMappingURL=agent-profile-cell-CCm3l2v2.d.ts.map
108
+ //# sourceMappingURL=agent-profile-cell-Cw0PVwDr.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-profile-cell-CCm3l2v2.d.ts","names":[],"sources":["../src/agent-profile-cell.ts"],"mappings":";;;KAIY;KAEA;GAA4B,cAAc;;KAE1C,sDAKR,qBACA;KAEQ;UAEK;;EAEf;;EAEA;;UAGe;EACf;;EAEA;;EAEA,UAAU;;UAGK;EACf;EACA;EACA;;UAGe;EACf;EACA,eAAe;EACf,UAAU;EACV;EACA;EACA,aAAa,eAAe;;UAGb;EACf,eAAe;EACf;EACA;EACA,eAAe;EACf,UAAU;EACV;EACA;EACA,aAAa,eAAe;;cAGjB,wCAAwC;WAC1C;EACT,YAAY,iBAAiB;;iBAST,sBACpB,OAAO,wBACN,QAAQ;iBAMK,6BACd,MAAM,mBACL,KAAK;;;;iBASc,uBAAuB,MAAM,mBAAmB;iBAQtD,yBAAyB,iBAAiB;iBAqB1C,wBAAwB;EACtC;EACA,eAAe;IACb;iBAUY,oBAAoB;EAClC;EACA,eAAe;;iBAKK,0BAA0B;EAC9C;EACA;EACA;EACA,eAAe;IACb,QAAQ;iBAuBI,4BACd;EAAY;EAAe,eAAe;GAC1C,kBAAkB,MAAM,YAAY;;;;;cA0NzB;;;;WAIX;;KAGU,2BAA2B,kCAAkC;;;;;iBAMzD,mBAAmB,iBAAiB;;KAoBxC,4BAA4B;EAAiB;EAAc;;;;;;;;;;;iBAWjD,+BACpB,SAAS,2BACT,OAAO,KAAK,wDACX,QAAQ"}
1
+ {"version":3,"file":"agent-profile-cell-Cw0PVwDr.d.ts","names":[],"sources":["../src/agent-profile-cell.ts"],"mappings":";;;KAIY;KAEA;GAA4B,cAAc;;KAE1C,sDAKR,qBACA;KAEQ;UAEK;;EAEf;;EAEA;;UAGe;EACf;;EAEA;;EAEA,UAAU;;UAGK;EACf;EACA;EACA;;UAGe;EACf;EACA,eAAe;EACf,UAAU;EACV;EACA;EACA,aAAa,eAAe;;UAGb;EACf,eAAe;EACf;EACA;EACA,eAAe;EACf,UAAU;EACV;EACA;EACA,aAAa,eAAe;;cAGjB,wCAAwC;WAC1C;EACT,YAAY,iBAAiB;;iBAST,sBACpB,OAAO,wBACN,QAAQ;iBAMK,6BACd,MAAM,mBACL,KAAK;;;;iBASc,uBAAuB,MAAM,mBAAmB;iBAQtD,yBAAyB,iBAAiB;iBAqB1C,wBAAwB;EACtC;EACA,eAAe;IACb;iBAUY,oBAAoB;EAClC;EACA,eAAe;;iBAKK,0BAA0B;EAC9C;EACA;EACA;EACA,eAAe;IACb,QAAQ;iBAuBI,4BACd;EAAY;EAAe,eAAe;GAC1C,kBAAkB,MAAM,YAAY;;;;;cA0NzB;;;;WAIX;;KAGU,2BAA2B,kCAAkC;;;;;iBAMzD,mBAAmB,iBAAiB;;KAoBxC,4BAA4B;EAAiB;EAAc;;;;;;;;;;;iBAWjD,+BACpB,SAAS,2BACT,OAAO,KAAK,wDACX,QAAQ"}