@tangle-network/agent-eval 0.135.4 → 0.137.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 (211) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +4 -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 +139 -17
  8. package/dist/analyst/index.d.ts.map +1 -1
  9. package/dist/analyst/index.js +606 -4
  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-PVtnfjvA.d.ts} +6 -6
  14. package/dist/{analyze-runs-Cda5Xkj1.d.ts.map → analyze-runs-PVtnfjvA.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-CHX4orG7.d.ts +184 -0
  18. package/dist/benchmark-CHX4orG7.d.ts.map +1 -0
  19. package/dist/benchmark-YDrpumqB.js +414 -0
  20. package/dist/benchmark-YDrpumqB.js.map +1 -0
  21. package/dist/benchmarks/index.d.ts +1 -1
  22. package/dist/benchmarks/index.js +1 -1
  23. package/dist/{benchmarks-Dfgm9ts5.js → benchmarks-DCLkQOmc.js} +3 -3
  24. package/dist/{benchmarks-Dfgm9ts5.js.map → benchmarks-DCLkQOmc.js.map} +1 -1
  25. package/dist/builder-eval/index.js +2 -2
  26. package/dist/campaign/index.d.ts +6 -6
  27. package/dist/campaign/index.js +3 -3
  28. package/dist/{campaign-Dz8uQnhC.js → campaign-lgObcHFC.js} +212 -78
  29. package/dist/campaign-lgObcHFC.js.map +1 -0
  30. package/dist/cli.js +1 -1
  31. package/dist/client-C8L6h6Wf.d.ts +202 -0
  32. package/dist/client-C8L6h6Wf.d.ts.map +1 -0
  33. package/dist/completion-verifier-DSyRNVzU.d.ts +240 -0
  34. package/dist/completion-verifier-DSyRNVzU.d.ts.map +1 -0
  35. package/dist/contract/index.d.ts +10 -9
  36. package/dist/contract/index.d.ts.map +1 -1
  37. package/dist/contract/index.js +10 -10
  38. package/dist/control.d.ts +2 -2
  39. package/dist/control.js +1 -1
  40. package/dist/{cost-ledger-DHAjwNj7.js → cost-ledger-D-5_-dhi.js} +2 -2
  41. package/dist/{cost-ledger-DHAjwNj7.js.map → cost-ledger-D-5_-dhi.js.map} +1 -1
  42. package/dist/{cost-ledger-fGS_u_O1.d.ts → cost-ledger-D2o6JOrL.d.ts} +2 -2
  43. package/dist/{cost-ledger-fGS_u_O1.d.ts.map → cost-ledger-D2o6JOrL.d.ts.map} +1 -1
  44. package/dist/{dataset-BvtnC8Dc.d.ts → dataset-v_Y5902-.d.ts} +2 -2
  45. package/dist/{dataset-BvtnC8Dc.d.ts.map → dataset-v_Y5902-.d.ts.map} +1 -1
  46. package/dist/{default-registry-CHmdy2An.js → default-registry-CLXbRt0f.js} +119 -38
  47. package/dist/default-registry-CLXbRt0f.js.map +1 -0
  48. package/dist/{default-registry-Brxr728w.d.ts → default-registry-Dc5D_Loc.d.ts} +63 -137
  49. package/dist/default-registry-Dc5D_Loc.d.ts.map +1 -0
  50. package/dist/{errors-8YnH8WlF.js → errors-D-LKuDhb.js} +8 -2
  51. package/dist/errors-D-LKuDhb.js.map +1 -0
  52. package/dist/{errors-CEk209JS.d.ts → errors-DkfjIDvD.d.ts} +9 -3
  53. package/dist/errors-DkfjIDvD.d.ts.map +1 -0
  54. package/dist/{eval-campaign-Cc8WZJ6b.js → eval-campaign-CHqfLnff.js} +6 -6
  55. package/dist/{eval-campaign-Cc8WZJ6b.js.map → eval-campaign-CHqfLnff.js.map} +1 -1
  56. package/dist/{extract-usage-DIQpN-ww.js → extract-usage-p-56bh8q.js} +3 -3
  57. package/dist/{extract-usage-DIQpN-ww.js.map → extract-usage-p-56bh8q.js.map} +1 -1
  58. package/dist/{feedback-trajectory-CVaeREXV.d.ts → feedback-trajectory-N_F0PwHz.d.ts} +90 -3
  59. package/dist/feedback-trajectory-N_F0PwHz.d.ts.map +1 -0
  60. package/dist/fuzz.d.ts +1 -1
  61. package/dist/fuzz.js +2 -2
  62. package/dist/hosted/index.d.ts +3 -2
  63. package/dist/hosted/index.d.ts.map +1 -1
  64. package/dist/index-BipJlj-C.d.ts +316 -0
  65. package/dist/index-BipJlj-C.d.ts.map +1 -0
  66. package/dist/{index-CQsJcqch.d.ts → index-BnP1QJUv.d.ts} +5 -5
  67. package/dist/{index-CQsJcqch.d.ts.map → index-BnP1QJUv.d.ts.map} +1 -1
  68. package/dist/{index-B4Fjfo5U.d.ts → index-C-Pr4OWg.d.ts} +88 -317
  69. package/dist/index-C-Pr4OWg.d.ts.map +1 -0
  70. package/dist/{index-DuhJaaiH.d.ts → index-DEb46kc6.d.ts} +2 -2
  71. package/dist/{index-DuhJaaiH.d.ts.map → index-DEb46kc6.d.ts.map} +1 -1
  72. package/dist/{index-C2fkZhv_.d.ts → index-DRNl6g_N.d.ts} +3 -3
  73. package/dist/{index-C2fkZhv_.d.ts.map → index-DRNl6g_N.d.ts.map} +1 -1
  74. package/dist/{index-AbhwHp0V.d.ts → index-U3RHOShi.d.ts} +2 -2
  75. package/dist/{index-AbhwHp0V.d.ts.map → index-U3RHOShi.d.ts.map} +1 -1
  76. package/dist/index.d.ts +29 -70
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +507 -33
  79. package/dist/index.js.map +1 -1
  80. package/dist/{client-DcvgkaZi.d.ts → insight-report-B9ooYH_g.d.ts} +5 -203
  81. package/dist/insight-report-B9ooYH_g.d.ts.map +1 -0
  82. package/dist/integrity-CCXTftiL.js +1360 -0
  83. package/dist/integrity-CCXTftiL.js.map +1 -0
  84. package/dist/{integrity-rmVhXWA7.d.ts → integrity-CKxosZ5Z.d.ts} +3 -3
  85. package/dist/{integrity-rmVhXWA7.d.ts.map → integrity-CKxosZ5Z.d.ts.map} +1 -1
  86. package/dist/{integrity-BzRbCHzi.js → integrity-fdt8XPAv.js} +2 -2
  87. package/dist/{integrity-BzRbCHzi.js.map → integrity-fdt8XPAv.js.map} +1 -1
  88. package/dist/ledger-core/index.d.ts +1 -1
  89. package/dist/ledger-core/index.js +1 -1
  90. package/dist/{ledger-core-DAKFKRzi.js → ledger-core-t6sItivm.js} +85 -85
  91. package/dist/{ledger-core-DAKFKRzi.js.map → ledger-core-t6sItivm.js.map} +1 -1
  92. package/dist/{llm-client-DHx8pzyJ.js → llm-client-DKB25jV8.js} +3 -3
  93. package/dist/{llm-client-DHx8pzyJ.js.map → llm-client-DKB25jV8.js.map} +1 -1
  94. package/dist/meta-eval/index.d.ts +2 -2
  95. package/dist/meta-eval/index.js +3 -3
  96. package/dist/{mint-DyRUc9k6.js → mint-Ctwk079K.js} +4 -4
  97. package/dist/{mint-DyRUc9k6.js.map → mint-Ctwk079K.js.map} +1 -1
  98. package/dist/multishot/index.d.ts +2 -2
  99. package/dist/openapi.json +1 -1
  100. package/dist/{paired-arms-BbFKrAU-.js → paired-arms-iZ08VFMN.js} +3 -3
  101. package/dist/{paired-arms-BbFKrAU-.js.map → paired-arms-iZ08VFMN.js.map} +1 -1
  102. package/dist/pipelines/index.js +2 -2
  103. package/dist/profile-cell.d.ts +1 -1
  104. package/dist/profile-cell.js +1 -1
  105. package/dist/{propose-review-control-SQ-n9-We.js → propose-review-control-DLXz4FCX.js} +2 -2
  106. package/dist/{propose-review-control-SQ-n9-We.js.map → propose-review-control-DLXz4FCX.js.map} +1 -1
  107. package/dist/registry-BdM7SuTr.d.ts +124 -0
  108. package/dist/registry-BdM7SuTr.d.ts.map +1 -0
  109. package/dist/{release-report-DooPguBc.js → release-report-B5XPBvAU.js} +4 -4
  110. package/dist/{release-report-DooPguBc.js.map → release-report-B5XPBvAU.js.map} +1 -1
  111. package/dist/{release-report-DpBxGGI1.d.ts → release-report-CofgVNZt.d.ts} +4 -4
  112. package/dist/{release-report-DpBxGGI1.d.ts.map → release-report-CofgVNZt.d.ts.map} +1 -1
  113. package/dist/{replay-C6wRg47C.js → replay-Bju0T8Ls.js} +248 -8
  114. package/dist/replay-Bju0T8Ls.js.map +1 -0
  115. package/dist/{replay-BRfMIs81.d.ts → replay-K8FaC0CB.d.ts} +227 -52
  116. package/dist/replay-K8FaC0CB.d.ts.map +1 -0
  117. package/dist/reporting.d.ts +4 -4
  118. package/dist/reporting.js +4 -4
  119. package/dist/{researcher-Doo95b50.d.ts → researcher-Da0Wj-bt.d.ts} +6 -7
  120. package/dist/researcher-Da0Wj-bt.d.ts.map +1 -0
  121. package/dist/{reward-hacking-D-QqXvg-.d.ts → reward-hacking-CQ3hTCO3.d.ts} +2 -2
  122. package/dist/{reward-hacking-D-QqXvg-.d.ts.map → reward-hacking-CQ3hTCO3.d.ts.map} +1 -1
  123. package/dist/{reward-hacking-a-kYs0-i.js → reward-hacking-GyN0kMd8.js} +3 -3
  124. package/dist/{reward-hacking-a-kYs0-i.js.map → reward-hacking-GyN0kMd8.js.map} +1 -1
  125. package/dist/rl.d.ts +6 -6
  126. package/dist/rl.js +9 -9
  127. package/dist/rollout/index.d.ts +1 -1
  128. package/dist/rollout/index.js +3 -3
  129. package/dist/{rollout-DLSUIWLu.js → rollout-DQFl0UXA.js} +2 -2
  130. package/dist/{rollout-DLSUIWLu.js.map → rollout-DQFl0UXA.js.map} +1 -1
  131. package/dist/{rubric-predictive-validity-BJf-8ejY.js → rubric-predictive-validity-BRR632r1.js} +2 -2
  132. package/dist/{rubric-predictive-validity-BJf-8ejY.js.map → rubric-predictive-validity-BRR632r1.js.map} +1 -1
  133. package/dist/{rubric-predictive-validity-C1dCLcvb.d.ts → rubric-predictive-validity-C4sztLR3.d.ts} +2 -2
  134. package/dist/{rubric-predictive-validity-C1dCLcvb.d.ts.map → rubric-predictive-validity-C4sztLR3.d.ts.map} +1 -1
  135. package/dist/{run-evidence-DokQtX0-.d.ts → run-evidence-BDIircdA.d.ts} +3 -3
  136. package/dist/{run-evidence-DokQtX0-.d.ts.map → run-evidence-BDIircdA.d.ts.map} +1 -1
  137. package/dist/{run-record-DcObtIGh.d.ts → run-record-BPCa2rQ8.d.ts} +4 -4
  138. package/dist/{run-record-DcObtIGh.d.ts.map → run-record-BPCa2rQ8.d.ts.map} +1 -1
  139. package/dist/{run-record-BIwU2wdV.js → run-record-vRgqWmJw.js} +3 -3
  140. package/dist/{run-record-BIwU2wdV.js.map → run-record-vRgqWmJw.js.map} +1 -1
  141. package/dist/{semantic-concept-judge-Btozx3Vc.js → semantic-concept-judge-Bz64IckK.js} +4 -4
  142. package/dist/{semantic-concept-judge-Btozx3Vc.js.map → semantic-concept-judge-Bz64IckK.js.map} +1 -1
  143. package/dist/{server-Bz3WQJs6.js → server-KjXZZUDX.js} +3 -3
  144. package/dist/{server-Bz3WQJs6.js.map → server-KjXZZUDX.js.map} +1 -1
  145. package/dist/{skill-usage-BDQVPIG1.d.ts → skill-usage-CFDLLlhF.d.ts} +25 -47
  146. package/dist/skill-usage-CFDLLlhF.d.ts.map +1 -0
  147. package/dist/{skillopt-optimization-method-CwSYkv35.d.ts → skillopt-optimization-method-BpbnlvAZ.d.ts} +11 -12
  148. package/dist/skillopt-optimization-method-BpbnlvAZ.d.ts.map +1 -0
  149. package/dist/{skillopt-optimization-method-0UmPD6aP.js → skillopt-optimization-method-f4o9sUT4.js} +7 -7
  150. package/dist/{skillopt-optimization-method-0UmPD6aP.js.map → skillopt-optimization-method-f4o9sUT4.js.map} +1 -1
  151. package/dist/{statistics-CnGCLLqc.js → statistics-ByxzSiOM.js} +2 -2
  152. package/dist/{statistics-CnGCLLqc.js.map → statistics-ByxzSiOM.js.map} +1 -1
  153. package/dist/{statistics-CKOqre5S.d.ts → statistics-_7P642CN.d.ts} +2 -2
  154. package/dist/{statistics-CKOqre5S.d.ts.map → statistics-_7P642CN.d.ts.map} +1 -1
  155. package/dist/{summary-report-BEk8OFLs.js → summary-report-9A5y7EsK.js} +4 -4
  156. package/dist/{summary-report-BEk8OFLs.js.map → summary-report-9A5y7EsK.js.map} +1 -1
  157. package/dist/{summary-report-CPMINBqs.d.ts → summary-report-DHipz9Kx.d.ts} +3 -3
  158. package/dist/{summary-report-CPMINBqs.d.ts.map → summary-report-DHipz9Kx.d.ts.map} +1 -1
  159. package/dist/supervisor-run/index.d.ts +3 -2
  160. package/dist/supervisor-run/index.js +3 -2
  161. package/dist/{supervisor-run-B7lUGoyZ.js → supervisor-run-B2EWUmQY.js} +221 -519
  162. package/dist/supervisor-run-B2EWUmQY.js.map +1 -0
  163. package/dist/{test-graded-scenario-BsqWLmPt.js → test-graded-scenario-JHcKQNpq.js} +2 -2
  164. package/dist/{test-graded-scenario-BsqWLmPt.js.map → test-graded-scenario-JHcKQNpq.js.map} +1 -1
  165. package/dist/tools-DZk2Jn64.js +1876 -0
  166. package/dist/tools-DZk2Jn64.js.map +1 -0
  167. package/dist/traces.d.ts +6 -7
  168. package/dist/traces.js +5 -6
  169. package/dist/{types-DVjczBM9.d.ts → types-CKswbJGO.d.ts} +260 -6
  170. package/dist/types-CKswbJGO.d.ts.map +1 -0
  171. package/dist/{types-DiWLru6Z.d.ts → types-CTGbIm57.d.ts} +5 -5
  172. package/dist/{types-DiWLru6Z.d.ts.map → types-CTGbIm57.d.ts.map} +1 -1
  173. package/dist/types-CTvKfr5F.d.ts +804 -0
  174. package/dist/types-CTvKfr5F.d.ts.map +1 -0
  175. package/dist/{index-C61Wi7yg.d.ts → types-Dea6tiVI.d.ts} +47 -235
  176. package/dist/types-Dea6tiVI.d.ts.map +1 -0
  177. package/dist/wire/index.d.ts +3 -3
  178. package/dist/wire/index.js +1 -1
  179. package/docs/feedback-trajectories.md +100 -1
  180. package/docs/trace-analysis.md +374 -58
  181. package/package.json +7 -3
  182. package/dist/analyst-BkTS3C58.d.ts +0 -89
  183. package/dist/analyst-BkTS3C58.d.ts.map +0 -1
  184. package/dist/analyst-j5je5J7c.js +0 -152
  185. package/dist/analyst-j5je5J7c.js.map +0 -1
  186. package/dist/campaign-Dz8uQnhC.js.map +0 -1
  187. package/dist/client-DcvgkaZi.d.ts.map +0 -1
  188. package/dist/default-registry-Brxr728w.d.ts.map +0 -1
  189. package/dist/default-registry-CHmdy2An.js.map +0 -1
  190. package/dist/errors-8YnH8WlF.js.map +0 -1
  191. package/dist/errors-CEk209JS.d.ts.map +0 -1
  192. package/dist/feedback-trajectory-CVaeREXV.d.ts.map +0 -1
  193. package/dist/index-B4Fjfo5U.d.ts.map +0 -1
  194. package/dist/index-C61Wi7yg.d.ts.map +0 -1
  195. package/dist/llm-client-BiK4HW0u.d.ts +0 -290
  196. package/dist/llm-client-BiK4HW0u.d.ts.map +0 -1
  197. package/dist/raw-provider-sink-BU29Sh8h.d.ts +0 -134
  198. package/dist/raw-provider-sink-BU29Sh8h.d.ts.map +0 -1
  199. package/dist/replay-BRfMIs81.d.ts.map +0 -1
  200. package/dist/replay-C6wRg47C.js.map +0 -1
  201. package/dist/researcher-Doo95b50.d.ts.map +0 -1
  202. package/dist/skill-usage-BDQVPIG1.d.ts.map +0 -1
  203. package/dist/skillopt-optimization-method-CwSYkv35.d.ts.map +0 -1
  204. package/dist/store-CxJry_cs.d.ts +0 -229
  205. package/dist/store-CxJry_cs.d.ts.map +0 -1
  206. package/dist/supervisor-run-B7lUGoyZ.js.map +0 -1
  207. package/dist/tools-D8yTtNSN.js +0 -1190
  208. package/dist/tools-D8yTtNSN.js.map +0 -1
  209. package/dist/types-Cc3qbqzj.d.ts +0 -387
  210. package/dist/types-Cc3qbqzj.d.ts.map +0 -1
  211. package/dist/types-DVjczBM9.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity-CCXTftiL.js","names":[],"sources":["../src/supervisor-run/integrity-issues.ts","../src/supervisor-run/integrity-steer.ts","../src/supervisor-run/integrity-source.ts","../src/supervisor-run/integrity-tree.ts","../src/supervisor-run/integrity-types.ts","../src/supervisor-run/source-facts.ts","../src/supervisor-run/rollout-nodes.ts","../src/supervisor-run/integrity.ts"],"sourcesContent":["import type { SupervisorRunIntegrityEvidence, SupervisorRunIntegrityIssue } from './integrity-types'\n\nexport const MAX_EXAMPLES = 20\n\nexport function evidence(path: string, value: unknown): SupervisorRunIntegrityEvidence {\n return { path, value }\n}\n\nexport function issue(\n init: Omit<SupervisorRunIntegrityIssue, 'evidence'> & {\n evidence?: readonly SupervisorRunIntegrityEvidence[]\n },\n): SupervisorRunIntegrityIssue {\n return { ...init, evidence: init.evidence ?? [] }\n}\n","import { evidence, issue, MAX_EXAMPLES } from './integrity-issues'\nimport type { JoinedWorker } from './integrity-source'\nimport type { SupervisorRunIntegrityIssue } from './integrity-types'\n\nfunction idListDetail(ids: readonly string[]): string {\n const examples = ids\n .slice(0, MAX_EXAMPLES)\n .map((id) => JSON.stringify(id))\n .join(', ')\n return ids.length <= MAX_EXAMPLES\n ? examples\n : `${examples}, and ${ids.length - MAX_EXAMPLES} more`\n}\n\nexport function steerIssues(\n joined: JoinedWorker,\n rootCompleted: boolean,\n): SupervisorRunIntegrityIssue[] {\n const { facts } = joined\n const subject = facts.workerId ?? joined.spawn.id\n const prefix = `workers/${facts.sourceIndex}`\n const out: SupervisorRunIntegrityIssue[] = []\n if (\n !facts.inboxCaptured ||\n !facts.eventsCaptured ||\n facts.inboxInvalidRows > 0 ||\n facts.eventsInvalidRows > 0\n ) {\n const missing = [\n ...(facts.inboxCaptured ? [] : ['inbox']),\n ...(facts.eventsCaptured ? [] : ['events']),\n ]\n const malformed = [\n ...(facts.inboxInvalidRows > 0 ? [`inbox:${facts.inboxInvalidRows}`] : []),\n ...(facts.eventsInvalidRows > 0 ? [`events:${facts.eventsInvalidRows}`] : []),\n ]\n out.push(\n issue({\n code: 'worker-controls-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject,\n claim:\n 'Steer delivery integrity is unavailable for a worker with missing control artifacts',\n detail:\n missing.length > 0\n ? `${JSON.stringify(subject)} is missing ${missing.join(' and ')}.`\n : `${JSON.stringify(subject)} has malformed control rows (${malformed.join(', ')}).`,\n evidence: [\n ...missing.map((artifact) => evidence(`${prefix}/${artifact}`, null)),\n ...(facts.inboxInvalidRows > 0\n ? [evidence(`${prefix}/inbox/malformed-rows/count`, facts.inboxInvalidRows)]\n : []),\n ...(facts.eventsInvalidRows > 0\n ? [evidence(`${prefix}/events/malformed-rows/count`, facts.eventsInvalidRows)]\n : []),\n ],\n recommendedAction:\n 'Retain both control artifacts and repair malformed rows before correlating requests.',\n metadata: {\n assessment: 'unavailable',\n missing_artifacts: missing,\n malformed_rows: malformed,\n },\n }),\n )\n return out\n }\n\n const requestsById = new Map<string, typeof facts.steerRequests>()\n const unidentifiedRequests = facts.steerRequests.filter((request) => request.requestId === null)\n for (const request of facts.steerRequests) {\n if (request.requestId === null) continue\n const rows = requestsById.get(request.requestId) ?? []\n rows.push(request)\n requestsById.set(request.requestId, rows)\n }\n if (unidentifiedRequests.length > 0) {\n out.push(\n issue({\n code: 'steer-request-id-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject,\n claim: 'Some queued steer requests cannot be correlated because their ids are missing',\n detail: `${unidentifiedRequests.length} queued request(s) omit id.`,\n evidence: unidentifiedRequests\n .slice(0, MAX_EXAMPLES)\n .map((request) => evidence(`${prefix}/inbox/${request.row}/id`, null)),\n recommendedAction: 'Assign one stable request id before appending a steer to the inbox.',\n metadata: { assessment: 'unavailable', unavailable_count: unidentifiedRequests.length },\n }),\n )\n }\n const duplicateRequestIds = [...requestsById]\n .filter(([, rows]) => rows.length > 1)\n .map(([id]) => id)\n if (duplicateRequestIds.length > 0) {\n out.push(\n issue({\n code: 'duplicate-steer-request-id',\n area: 'control-integrity',\n severity: 'high',\n subject,\n claim: 'A worker inbox contains duplicate steer request ids',\n detail: `${duplicateRequestIds.length} duplicate id(s): ${idListDetail(duplicateRequestIds)}.`,\n evidence: [\n evidence(\n `${prefix}/inbox/duplicate-request-ids`,\n duplicateRequestIds.slice(0, MAX_EXAMPLES),\n ),\n ],\n recommendedAction: 'Generate a unique request id for every queued steer.',\n }),\n )\n }\n\n const acknowledgementsById = new Map<string, typeof facts.steerAcknowledgements>()\n const unidentifiedAcks = facts.steerAcknowledgements.filter((ack) => ack.requestId === null)\n for (const ack of facts.steerAcknowledgements) {\n if (ack.requestId === null) continue\n const rows = acknowledgementsById.get(ack.requestId) ?? []\n rows.push(ack)\n acknowledgementsById.set(ack.requestId, rows)\n }\n if (unidentifiedAcks.length > 0) {\n out.push(\n issue({\n code: 'steer-ack-id-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject,\n claim: 'Some steer acknowledgements cannot be correlated because requestId is missing',\n detail: `${unidentifiedAcks.length} down-leg event(s) omit requestId.`,\n evidence: unidentifiedAcks\n .slice(0, MAX_EXAMPLES)\n .map((ack) => evidence(`${prefix}/events/${ack.row}/requestId`, null)),\n recommendedAction: 'Echo the queued request id on every worker acknowledgement.',\n metadata: { assessment: 'unavailable', unavailable_count: unidentifiedAcks.length },\n }),\n )\n }\n\n const unknownAckIds = [...acknowledgementsById.keys()].filter((id) => !requestsById.has(id))\n if (unknownAckIds.length > 0) {\n out.push(\n issue({\n code: 'unknown-steer-ack',\n area: 'control-integrity',\n severity: 'high',\n subject,\n claim: 'A worker acknowledged steer request ids absent from its captured inbox',\n detail: `${unknownAckIds.length} unknown id(s): ${idListDetail(unknownAckIds)}.`,\n evidence: [\n evidence(`${prefix}/events/unknown-request-ids`, unknownAckIds.slice(0, MAX_EXAMPLES)),\n ],\n recommendedAction:\n 'Reject acknowledgements whose request id was not queued for this worker.',\n }),\n )\n }\n\n const duplicateAckIds = [...acknowledgementsById]\n .filter(([, rows]) => rows.length > 1)\n .map(([id]) => id)\n if (duplicateAckIds.length > 0) {\n out.push(\n issue({\n code: 'duplicate-steer-ack',\n area: 'control-integrity',\n severity: 'high',\n subject,\n claim: 'A worker emitted duplicate acknowledgements for steer request ids',\n detail: `${duplicateAckIds.length} duplicated id(s): ${idListDetail(duplicateAckIds)}.`,\n evidence: [\n evidence(\n `${prefix}/events/duplicate-request-ids`,\n duplicateAckIds.slice(0, MAX_EXAMPLES),\n ),\n ],\n recommendedAction: 'Make steer acknowledgement append idempotent by request id.',\n }),\n )\n }\n\n const missingAckIds = [...requestsById.keys()].filter((id) => !acknowledgementsById.has(id))\n if (rootCompleted && missingAckIds.length > 0) {\n out.push(\n issue({\n code: 'missing-steer-ack',\n area: 'control-integrity',\n severity: 'high',\n subject,\n claim: 'A completed supervisor run has queued steer requests without acknowledgements',\n detail: `${missingAckIds.length}/${requestsById.size} request id(s) are unacknowledged: ${idListDetail(missingAckIds)}.`,\n evidence: [\n evidence(\n `${prefix}/inbox/unacknowledged-request-ids`,\n missingAckIds.slice(0, MAX_EXAMPLES),\n ),\n ],\n recommendedAction:\n 'Record one delivered or failed acknowledgement for every queued request id.',\n }),\n )\n }\n\n const statusUnavailableIds: string[] = []\n const notDeliveredIds: string[] = []\n for (const [id, acknowledgements] of acknowledgementsById) {\n if (!requestsById.has(id) || acknowledgements.length !== 1) continue\n const delivered = acknowledgements[0]?.delivered\n if (delivered === null || delivered === undefined) statusUnavailableIds.push(id)\n else if (!delivered) notDeliveredIds.push(id)\n }\n if (statusUnavailableIds.length > 0) {\n out.push(\n issue({\n code: 'steer-ack-status-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject,\n claim: 'Some steer acknowledgements omit delivery status',\n detail: `${statusUnavailableIds.length} id(s): ${idListDetail(statusUnavailableIds)}.`,\n evidence: [\n evidence(\n `${prefix}/events/status-unavailable-request-ids`,\n statusUnavailableIds.slice(0, MAX_EXAMPLES),\n ),\n ],\n recommendedAction: 'Record delivered: true or delivered: false on each acknowledgement.',\n metadata: { assessment: 'unavailable', unavailable_count: statusUnavailableIds.length },\n }),\n )\n }\n if (notDeliveredIds.length > 0) {\n out.push(\n issue({\n code: 'steer-not-delivered',\n area: 'control-integrity',\n severity: 'high',\n subject,\n claim: 'Queued steer requests were acknowledged but not delivered',\n detail: `${notDeliveredIds.length} id(s): ${idListDetail(notDeliveredIds)}.`,\n evidence: [\n evidence(\n `${prefix}/events/not-delivered-request-ids`,\n notDeliveredIds.slice(0, MAX_EXAMPLES),\n ),\n ],\n recommendedAction:\n 'Retry or explicitly fail the control request instead of treating it as delivered.',\n }),\n )\n }\n return out\n}\n","import { evidence, issue, MAX_EXAMPLES } from './integrity-issues'\nimport { steerIssues } from './integrity-steer'\nimport type { SupervisorRunIntegrityIssue } from './integrity-types'\nimport type { SpawnRow, SupervisorTreeFacts, WorkerLogFacts } from './source-facts'\nimport type { SupervisorRunSources, SupervisorRunTree } from './types'\n\nfunction sourceIdentityIssues(facts: SupervisorTreeFacts): SupervisorRunIntegrityIssue[] {\n const out: SupervisorRunIntegrityIssue[] = []\n const malformedSpawns = facts.spawns.filter((spawn) => !spawn.valid)\n if (facts.journalInvalidRows > 0 || malformedSpawns.length > 0) {\n out.push(\n issue({\n code: 'source-row-malformed',\n area: 'capture-integrity',\n severity: 'high',\n subject: 'journal-rows',\n claim: 'Some supervisor journal rows are malformed',\n detail: `${facts.journalInvalidRows} non-object or invalid JSON row(s) and ${malformedSpawns.length} malformed spawn row(s) were excluded from structural conclusions.`,\n evidence: [\n evidence('journal/malformed-json-rows/count', facts.journalInvalidRows),\n ...malformedSpawns\n .slice(0, MAX_EXAMPLES)\n .map((spawn) =>\n evidence(`journal/spawns/${spawn.sourceRow}/invalid-fields`, spawn.invalidFields),\n ),\n ],\n recommendedAction:\n 'Repair or reject malformed journal rows before using the run for structural analysis.',\n metadata: {\n assessment: 'unavailable',\n malformed_json_rows: facts.journalInvalidRows,\n malformed_spawn_rows: malformedSpawns.length,\n },\n }),\n )\n }\n const unidentifiedSpawns = malformedSpawns.filter((spawn) => spawn.id.length === 0)\n const unidentifiedCloses = facts.closes.filter((close) => close.id.length === 0)\n if (unidentifiedSpawns.length + unidentifiedCloses.length > 0) {\n out.push(\n issue({\n code: 'source-event-identity-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: 'journal-event-identity',\n claim: 'Some supervisor journal events have no usable invocation id',\n detail: `${unidentifiedSpawns.length} spawn and ${unidentifiedCloses.length} terminal event(s) lack an id.`,\n evidence: [\n evidence('journal/unidentified-spawns/count', unidentifiedSpawns.length),\n evidence('journal/unidentified-terminals/count', unidentifiedCloses.length),\n ],\n recommendedAction: 'Reject or repair control events that omit their stable invocation id.',\n metadata: { assessment: 'unavailable', checks: ['journal-event-linkage'] },\n }),\n )\n }\n\n const spawnCounts = new Map<string, number>()\n for (const spawn of facts.spawns) {\n if (!spawn.valid || spawn.id.length === 0) continue\n spawnCounts.set(spawn.id, (spawnCounts.get(spawn.id) ?? 0) + 1)\n }\n for (const [id, count] of spawnCounts) {\n if (count < 2) continue\n out.push(\n issue({\n code: 'duplicate-spawn',\n area: 'control-integrity',\n severity: 'critical',\n subject: id,\n claim: 'An invocation has more than one spawned control event',\n detail: `${count} spawned events name invocation ${JSON.stringify(id)}.`,\n evidence: [evidence(`journal/spawn-count/${encodeURIComponent(id)}`, count)],\n recommendedAction: 'Make spawn event append idempotent.',\n }),\n )\n }\n\n const closeCounts = new Map<string, number>()\n for (const close of facts.closes) {\n if (close.id.length === 0) continue\n closeCounts.set(close.id, (closeCounts.get(close.id) ?? 0) + 1)\n }\n const uncertainSpawnIds = new Set(\n malformedSpawns.filter((spawn) => spawn.id.length > 0).map((spawn) => spawn.id),\n )\n if (unidentifiedSpawns.length === 0 && facts.journalInvalidRows === 0) {\n const orphanCloses = new Map<string, Array<(typeof facts.closes)[number]>>()\n for (const close of facts.closes) {\n if (close.id.length === 0 || spawnCounts.has(close.id) || uncertainSpawnIds.has(close.id)) {\n continue\n }\n const rows = orphanCloses.get(close.id) ?? []\n rows.push(close)\n orphanCloses.set(close.id, rows)\n }\n for (const [id, closes] of orphanCloses) {\n out.push(\n issue({\n code: 'orphan-terminal',\n area: 'control-integrity',\n severity: 'critical',\n subject: id,\n claim: 'A terminal control event names an invocation that was never spawned',\n detail: `${closes.length} terminal event(s) for ${JSON.stringify(id)} have no matching spawn.`,\n evidence: [\n evidence(`journal/closes/${encodeURIComponent(id)}/count`, closes.length),\n ...closes\n .slice(0, MAX_EXAMPLES)\n .map((close, index) =>\n evidence(`journal/closes/${encodeURIComponent(id)}/${index}`, close),\n ),\n ],\n recommendedAction: 'Retain the matching spawn event or reject the orphan terminal event.',\n }),\n )\n }\n }\n for (const [id, count] of closeCounts) {\n if (count < 2) continue\n out.push(\n issue({\n code: 'duplicate-terminal',\n area: 'control-integrity',\n severity: 'critical',\n subject: id,\n claim: 'An invocation has more than one terminal control event',\n detail: `${count} settled/cancelled events name invocation ${JSON.stringify(id)}.`,\n evidence: [evidence(`journal/terminal-count/${encodeURIComponent(id)}`, count)],\n recommendedAction: 'Make terminal event append idempotent.',\n }),\n )\n }\n return out\n}\n\nexport interface JoinedWorker {\n readonly spawn: SpawnRow\n readonly facts: WorkerLogFacts\n}\n\nfunction joinWorkerControls(facts: SupervisorTreeFacts): {\n joined: JoinedWorker[]\n issue: SupervisorRunIntegrityIssue | null\n} {\n const spawnsById = new Map<string, SpawnRow[]>()\n const spawnsByLabel = new Map<string, SpawnRow[]>()\n for (const spawn of facts.workerSpawns) {\n const ids = spawnsById.get(spawn.id) ?? []\n ids.push(spawn)\n spawnsById.set(spawn.id, ids)\n const labels = spawnsByLabel.get(spawn.label) ?? []\n labels.push(spawn)\n spawnsByLabel.set(spawn.label, labels)\n }\n const rowsWithoutIdByLabel = new Map<string, WorkerLogFacts[]>()\n for (const row of facts.workerLogRows) {\n if (row.workerId !== null && row.workerId.length > 0) continue\n const matches = rowsWithoutIdByLabel.get(row.label) ?? []\n matches.push(row)\n rowsWithoutIdByLabel.set(row.label, matches)\n }\n\n const rowsBySpawn = new Map<string, WorkerLogFacts[]>()\n const unmatchedRows: number[] = []\n const ambiguousRows: number[] = []\n for (const row of facts.workerLogRows) {\n const matches =\n row.workerId !== null && row.workerId.length > 0\n ? (spawnsById.get(row.workerId) ?? [])\n : (rowsWithoutIdByLabel.get(row.label)?.length ?? 0) === 1\n ? (spawnsByLabel.get(row.label) ?? [])\n : []\n if (matches.length === 0) {\n unmatchedRows.push(row.sourceIndex)\n continue\n }\n if (matches.length !== 1) {\n ambiguousRows.push(row.sourceIndex)\n continue\n }\n const spawn = matches[0] as SpawnRow\n const joined = rowsBySpawn.get(spawn.id) ?? []\n joined.push(row)\n rowsBySpawn.set(spawn.id, joined)\n }\n\n const joined: JoinedWorker[] = []\n const missingSpawnIds: string[] = []\n const duplicateSpawnIds: string[] = []\n for (const spawn of facts.workerSpawns) {\n if ((spawnsById.get(spawn.id)?.length ?? 0) !== 1) continue\n const rows = rowsBySpawn.get(spawn.id) ?? []\n if (rows.length === 0) missingSpawnIds.push(spawn.id)\n else if (rows.length > 1) duplicateSpawnIds.push(spawn.id)\n else joined.push({ spawn, facts: rows[0] as WorkerLogFacts })\n }\n\n if (\n missingSpawnIds.length === 0 &&\n duplicateSpawnIds.length === 0 &&\n unmatchedRows.length === 0 &&\n ambiguousRows.length === 0\n ) {\n return { joined, issue: null }\n }\n return {\n joined,\n issue: issue({\n code: 'worker-control-join-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: 'worker-control-join',\n claim: 'Worker control-log coverage does not match recorded child invocations',\n detail: `${missingSpawnIds.length} spawn(s) have no log, ${duplicateSpawnIds.length} have duplicate logs, ${unmatchedRows.length} log row(s) match no spawn, and ${ambiguousRows.length} row(s) are ambiguous.`,\n evidence: [\n evidence('workers/join/missing-spawn-ids', missingSpawnIds.slice(0, MAX_EXAMPLES)),\n evidence('workers/join/duplicate-spawn-ids', duplicateSpawnIds.slice(0, MAX_EXAMPLES)),\n evidence('workers/join/unmatched-source-rows', unmatchedRows.slice(0, MAX_EXAMPLES)),\n evidence('workers/join/ambiguous-source-rows', ambiguousRows.slice(0, MAX_EXAMPLES)),\n ],\n recommendedAction:\n 'Retain exactly one worker control row with workerId for every spawned invocation.',\n metadata: {\n assessment: 'unavailable',\n missing_count: missingSpawnIds.length,\n duplicate_count: duplicateSpawnIds.length,\n unmatched_count: unmatchedRows.length,\n ambiguous_count: ambiguousRows.length,\n },\n }),\n }\n}\n\nexport function sourceIssues(\n source: SupervisorRunSources,\n facts: SupervisorTreeFacts,\n tree: SupervisorRunTree,\n): SupervisorRunIntegrityIssue[] {\n const out = sourceIdentityIssues(facts)\n if (source.workers === null) {\n const reason = source.workersMissingReason ?? 'worker control-log store was not captured'\n out.push(\n issue({\n code: 'worker-controls-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject: 'steer-delivery',\n claim:\n 'Steer delivery integrity is unavailable because worker control logs were not captured',\n detail: reason,\n evidence: [evidence('sources/workers', null)],\n recommendedAction: 'Retain each worker inbox and event stream.',\n metadata: { assessment: 'unavailable', reason },\n }),\n )\n return out\n }\n\n const joined = joinWorkerControls(facts)\n if (joined.issue !== null) out.push(joined.issue)\n const rootCompleted =\n tree.rootId !== null &&\n tree.nodes.filter((node) => node.rollout_id === tree.rootId).length === 1 &&\n tree.nodes.find((node) => node.rollout_id === tree.rootId)?.outcome.is_completed === true\n for (const row of joined.joined) out.push(...steerIssues(row, rootCompleted))\n return out\n}\n","import { validateRolloutLine } from '../rollout/schema'\nimport { evidence, issue, MAX_EXAMPLES } from './integrity-issues'\nimport type { SupervisorRunIntegrityEvidence, SupervisorRunIntegrityIssue } from './integrity-types'\nimport type { SupervisorRunTree } from './types'\n\ninterface NodeRecord {\n readonly index: number\n readonly raw: Record<string, unknown>\n readonly errors: readonly string[]\n readonly id: string | null\n readonly parent: string | null | undefined\n readonly runId: string | null\n readonly role: string | null\n readonly messages: readonly unknown[] | null\n readonly profileId: string | null\n readonly completed: boolean | null\n readonly terminal: boolean | null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction parentValue(raw: Record<string, unknown>): string | null | undefined {\n if (raw.parent_rollout_id === null) return null\n return nonEmptyString(raw.parent_rollout_id) ?? undefined\n}\n\nfunction terminalValue(outcome: Record<string, unknown> | null): boolean | null {\n if (outcome === null) return null\n if (typeof outcome.is_completed !== 'boolean' || typeof outcome.is_truncated !== 'boolean') {\n return null\n }\n if (outcome.error !== null && typeof outcome.error !== 'string') return null\n return outcome.is_completed || outcome.is_truncated || outcome.error !== null\n}\n\nfunction nodeRecord(value: unknown, index: number): NodeRecord {\n const raw = isRecord(value) ? value : {}\n const policy = isRecord(raw.policy) ? raw.policy : null\n const outcome = isRecord(raw.outcome) ? raw.outcome : null\n return {\n index,\n raw,\n errors: validateRolloutLine(value),\n id: nonEmptyString(raw.rollout_id),\n parent: parentValue(raw),\n runId: nonEmptyString(raw.run_id),\n role: nonEmptyString(raw.role),\n messages: Array.isArray(raw.messages) ? raw.messages : null,\n profileId: policy === null ? null : nonEmptyString(policy.agent_profile_cell_id),\n completed:\n outcome !== null && typeof outcome.is_completed === 'boolean' ? outcome.is_completed : null,\n terminal: terminalValue(outcome),\n }\n}\n\nfunction metric(\n record: NodeRecord,\n keys: readonly string[],\n): { key: string; value: number } | null {\n const outcome = isRecord(record.raw.outcome) ? record.raw.outcome : null\n const metrics = outcome !== null && isRecord(outcome.metrics) ? outcome.metrics : null\n if (metrics === null) return null\n for (const key of keys) {\n const value = metrics[key]\n if (typeof value === 'number' && Number.isFinite(value)) return { key, value }\n }\n return null\n}\n\nfunction nodeEvidence(\n record: NodeRecord,\n path: string,\n value: unknown,\n): SupervisorRunIntegrityEvidence {\n const key = record.id ?? `index-${record.index}`\n return evidence(`nodes/${encodeURIComponent(key)}/${path}`, value)\n}\n\nfunction unavailableNodeChecks(record: NodeRecord): string[] {\n const checks: string[] = []\n if (record.id === null) checks.push('identity', 'root-membership', 'parent-link', 'cycle')\n if (record.parent === undefined) checks.push('parent-link', 'cycle')\n if (record.runId === null) checks.push('cross-run-parent')\n if (record.role === null) checks.push('root-role')\n if (!isRecord(record.raw.outcome)) checks.push('timing', 'terminal-state')\n return [...new Set(checks)]\n}\n\ninterface TreeIssueUncertainty {\n readonly unknownIdentityRows?: number\n readonly uncertainIds?: ReadonlySet<string>\n}\n\nexport function treeIssues(\n tree: SupervisorRunTree,\n uncertainty: TreeIssueUncertainty = {},\n): SupervisorRunIntegrityIssue[] {\n const out: SupervisorRunIntegrityIssue[] = []\n const records = (tree.nodes as readonly unknown[]).map(nodeRecord)\n const malformedSourceRows = tree.gaps\n .filter((gap) => gap.code === 'source-row-malformed')\n .reduce((count, gap) => count + (gap.count ?? 1), 0)\n\n for (const record of records) {\n if (record.errors.length === 0) continue\n out.push(\n issue({\n code: 'node-schema-invalid',\n area: 'capture-integrity',\n severity: 'high',\n subject: record.id ?? `node-${record.index}`,\n claim: 'A supervisor-tree node fails canonical rollout validation',\n detail: record.errors.join('; '),\n evidence: [evidence(`nodes/${record.index}/validation`, record.errors)],\n recommendedAction:\n 'Fix the producer so every node validates as the existing tangle.rollout.v1 shape before analysis.',\n metadata: { validation_errors: record.errors },\n }),\n )\n const unavailableChecks = unavailableNodeChecks(record)\n if (unavailableChecks.length === 0) continue\n out.push(\n issue({\n code: 'node-checks-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject: record.id ?? `node-${record.index}`,\n claim: 'Some integrity checks are unavailable for a malformed supervisor-tree node',\n detail: `Unavailable checks: ${unavailableChecks.join(', ')}.`,\n evidence: [evidence(`nodes/${record.index}/unavailable-checks`, unavailableChecks)],\n recommendedAction:\n 'Retain the named identity and relationship fields with their canonical types.',\n metadata: { assessment: 'unavailable', checks: unavailableChecks },\n }),\n )\n }\n\n const byId = new Map<string, NodeRecord[]>()\n for (const record of records) {\n if (record.id === null) continue\n const matches = byId.get(record.id) ?? []\n matches.push(record)\n byId.set(record.id, matches)\n }\n\n for (const [rolloutId, matches] of byId) {\n if (matches.length < 2) continue\n out.push(\n issue({\n code: 'duplicate-rollout-id',\n area: 'control-integrity',\n severity: 'critical',\n subject: rolloutId,\n claim: 'A rollout id is duplicated within one supervisor tree',\n detail: `${matches.length} nodes claim rollout_id ${JSON.stringify(rolloutId)}, so references are ambiguous.`,\n evidence: [\n evidence(`duplicates/${encodeURIComponent(rolloutId)}/count`, matches.length),\n ...matches.slice(0, MAX_EXAMPLES).map((record) =>\n evidence(`nodes/${record.index}/identity`, {\n rollout_id: record.id,\n parent_rollout_id: record.parent,\n role: record.role,\n }),\n ),\n ],\n recommendedAction: 'Give every invocation one stable rollout id and regenerate the tree.',\n }),\n )\n }\n\n const unknownIdentityRows =\n records.filter((record) => record.id === null).length +\n Math.max(malformedSourceRows, uncertainty.unknownIdentityRows ?? 0)\n const unique = records.filter(\n (record): record is NodeRecord & { readonly id: string } =>\n record.id !== null && byId.get(record.id)?.length === 1,\n )\n\n let root: NodeRecord | undefined\n if (tree.rootId === null) {\n out.push(\n issue({\n code: 'root-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: 'tree-root',\n claim: 'The supervisor-tree root is unavailable',\n detail: `rootId is null while ${records.length} node row(s) were captured.`,\n evidence: [evidence('rootId', null)],\n recommendedAction: 'Capture the root spawned event and preserve its rollout id as rootId.',\n metadata: { assessment: 'unavailable', node_rows: records.length },\n }),\n )\n } else {\n const rootRows = byId.get(tree.rootId) ?? []\n if (rootRows.length === 1) {\n root = rootRows[0]\n } else if (rootRows.length === 0 && unknownIdentityRows > 0) {\n out.push(\n issue({\n code: 'node-checks-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: tree.rootId,\n claim: 'Root membership is unavailable because a malformed node lost its rollout id',\n detail: `${unknownIdentityRows} malformed node row(s) have no usable rollout_id, so absence of root ${JSON.stringify(tree.rootId)} cannot be established.`,\n evidence: [evidence('rootId', tree.rootId)],\n recommendedAction: 'Retain rollout_id even when another node field fails validation.',\n metadata: { assessment: 'unavailable', checks: ['root-membership'] },\n }),\n )\n } else if (rootRows.length === 0) {\n out.push(\n issue({\n code: 'declared-root-missing',\n area: 'control-integrity',\n severity: 'critical',\n subject: tree.rootId,\n claim: 'The declared supervisor-tree root has no matching invocation node',\n detail: `rootId ${JSON.stringify(tree.rootId)} is absent from ${records.length} node row(s).`,\n evidence: [evidence('rootId', tree.rootId)],\n recommendedAction: 'Restore the root rollout row or correct rootId.',\n }),\n )\n }\n }\n\n if (root !== undefined) {\n if (root.parent !== undefined && root.parent !== null) {\n out.push(\n issue({\n code: 'root-has-parent',\n area: 'control-integrity',\n severity: 'critical',\n subject: root.id ?? tree.rootId ?? 'tree-root',\n claim: 'The declared supervisor-tree root has a parent',\n detail: `Root points to parent ${JSON.stringify(root.parent)}.`,\n evidence: [nodeEvidence(root, 'parent_rollout_id', root.parent)],\n recommendedAction: 'Record the root with parent_rollout_id null.',\n }),\n )\n }\n if (root.role !== null && root.role !== 'supervisor') {\n out.push(\n issue({\n code: 'root-role-invalid',\n area: 'control-integrity',\n severity: 'high',\n subject: root.id ?? tree.rootId ?? 'tree-root',\n claim: 'The declared supervisor-tree root is not labeled as a supervisor',\n detail: `Root has role ${JSON.stringify(root.role)}.`,\n evidence: [nodeEvidence(root, 'role', root.role)],\n recommendedAction:\n 'Preserve the root invocation role as supervisor when minting rollout rows.',\n }),\n )\n }\n }\n\n for (const record of unique) {\n if (record.parent === undefined) continue\n if (record.parent === null) {\n if (record.id !== tree.rootId) {\n out.push(\n issue({\n code: 'detached-node',\n area: 'control-integrity',\n severity: 'critical',\n subject: record.id,\n claim: 'A non-root invocation is recorded as a detached parentless root',\n detail: `Node ${JSON.stringify(record.id)} is parentless while rootId is ${JSON.stringify(tree.rootId)}.`,\n evidence: [\n nodeEvidence(record, 'parent_rollout_id', null),\n evidence('rootId', tree.rootId),\n ],\n recommendedAction:\n 'Attach the invocation to its spawning parent or record a separate run.',\n }),\n )\n }\n continue\n }\n\n const parentRows = byId.get(record.parent) ?? []\n if (parentRows.length === 0) {\n if (unknownIdentityRows > 0 || uncertainty.uncertainIds?.has(record.parent) === true) {\n out.push(\n issue({\n code: 'node-checks-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: record.id,\n claim: 'Parent membership is unavailable because a malformed node lost its rollout id',\n detail:\n uncertainty.uncertainIds?.has(record.parent) === true\n ? `Parent ${JSON.stringify(record.parent)} appears only in a malformed source row, so its absence cannot be established.`\n : `Parent ${JSON.stringify(record.parent)} cannot be matched while ${unknownIdentityRows} row(s) have no usable rollout_id.`,\n evidence: [nodeEvidence(record, 'parent_rollout_id', record.parent)],\n recommendedAction: 'Retain rollout_id on every row before assessing detached children.',\n metadata: { assessment: 'unavailable', checks: ['parent-membership'] },\n }),\n )\n } else {\n out.push(\n issue({\n code: 'parent-missing',\n area: 'control-integrity',\n severity: 'critical',\n subject: record.id,\n claim: 'An invocation points to a parent absent from the supervisor tree',\n detail: `Node ${JSON.stringify(record.id)} names missing parent ${JSON.stringify(record.parent)}.`,\n evidence: [nodeEvidence(record, 'parent_rollout_id', record.parent)],\n recommendedAction: 'Retain the parent invocation or remove the dangling edge.',\n }),\n )\n }\n continue\n }\n if (parentRows.length !== 1) continue\n const parent = parentRows[0] as NodeRecord\n\n if (record.runId !== null && parent.runId !== null && record.runId !== parent.runId) {\n out.push(\n issue({\n code: 'cross-run-parent',\n area: 'control-integrity',\n severity: 'critical',\n subject: record.id,\n claim: 'A parent-child edge crosses supervisor-run identities',\n detail: `Child run_id ${JSON.stringify(record.runId)} differs from parent run_id ${JSON.stringify(parent.runId)}.`,\n evidence: [\n nodeEvidence(record, 'run_id', record.runId),\n nodeEvidence(parent, 'run_id', parent.runId),\n ],\n recommendedAction:\n 'Keep one run_id across a supervision tree or remove the cross-run edge.',\n }),\n )\n }\n\n const childStart = metric(record, ['spawned_at', 'started_at'])\n const parentStart = metric(parent, ['spawned_at', 'started_at'])\n if (childStart !== null && parentStart !== null && childStart.value < parentStart.value) {\n out.push(\n issue({\n code: 'child-before-parent',\n area: 'control-integrity',\n severity: 'high',\n subject: record.id,\n claim: 'A child invocation is timestamped before its parent started',\n detail: `Child ${childStart.key} ${childStart.value} precedes parent ${parentStart.key} ${parentStart.value}.`,\n evidence: [\n nodeEvidence(record, `outcome.metrics.${childStart.key}`, childStart.value),\n nodeEvidence(parent, `outcome.metrics.${parentStart.key}`, parentStart.value),\n ],\n recommendedAction: 'Use one ordered clock for spawn events or retain clock metadata.',\n }),\n )\n }\n\n const parentClose = metric(parent, ['settled_at', 'completed_at', 'finished_at'])\n if (childStart !== null && parentClose !== null && childStart.value > parentClose.value) {\n out.push(\n issue({\n code: 'child-after-parent-close',\n area: 'control-integrity',\n severity: 'critical',\n subject: record.id,\n claim: 'A child invocation is timestamped after its parent closed',\n detail: `Child ${childStart.key} ${childStart.value} follows parent ${parentClose.key} ${parentClose.value}.`,\n evidence: [\n nodeEvidence(record, `outcome.metrics.${childStart.key}`, childStart.value),\n nodeEvidence(parent, `outcome.metrics.${parentClose.key}`, parentClose.value),\n ],\n recommendedAction:\n 'Correct the causal timestamps or attach the child to its actual spawner.',\n }),\n )\n }\n }\n\n for (const record of unique) {\n const start = metric(record, ['spawned_at', 'started_at'])\n const close = metric(record, ['settled_at', 'completed_at', 'finished_at'])\n if (start === null || close === null || close.value >= start.value) continue\n out.push(\n issue({\n code: 'close-before-start',\n area: 'control-integrity',\n severity: 'high',\n subject: record.id,\n claim: 'An invocation is timestamped as closing before it started',\n detail: `${start.key} is ${start.value} and ${close.key} is ${close.value}.`,\n evidence: [\n nodeEvidence(record, `outcome.metrics.${start.key}`, start.value),\n nodeEvidence(record, `outcome.metrics.${close.key}`, close.value),\n ],\n recommendedAction: 'Correct the event ordering or retain clock-domain metadata.',\n }),\n )\n }\n\n const emittedCycles = new Set<string>()\n const resolved = new Set<string>()\n for (const start of unique) {\n if (resolved.has(start.id)) continue\n const path: string[] = []\n const positions = new Map<string, number>()\n let current: string | null = start.id\n while (current !== null) {\n if (resolved.has(current)) break\n const position = positions.get(current)\n if (position !== undefined) {\n const cycle = path.slice(position)\n const key = [...cycle].sort().join('\\u0000')\n if (!emittedCycles.has(key)) {\n emittedCycles.add(key)\n out.push(\n issue({\n code: 'parent-cycle',\n area: 'control-integrity',\n severity: 'critical',\n subject: [...cycle].sort()[0] ?? 'cycle',\n claim: 'The supervisor tree contains a parent cycle',\n detail: `${cycle.join(' -> ')} -> ${cycle[0]}`,\n evidence: cycle.slice(0, MAX_EXAMPLES).flatMap((id) => {\n const rows = byId.get(id)\n const record = rows?.length === 1 ? rows[0] : undefined\n return record === undefined\n ? []\n : [nodeEvidence(record, 'parent_rollout_id', record.parent)]\n }),\n recommendedAction:\n 'Correct parent ids at ingestion; a cyclic graph is not a run tree.',\n }),\n )\n }\n break\n }\n positions.set(current, path.length)\n path.push(current)\n const rows = byId.get(current)\n if (rows?.length !== 1) break\n const parent = rows[0]?.parent\n if (parent === undefined) break\n current = parent\n }\n for (const id of path) resolved.add(id)\n }\n\n if (root?.completed === true) {\n const missingTerminal = unique.filter(\n (record) => record.id !== root?.id && record.terminal === false,\n )\n if (missingTerminal.length > 0) {\n out.push(\n issue({\n code: 'child-terminal-unavailable',\n area: 'capture-integrity',\n severity: 'high',\n subject: 'child-terminal-outcomes',\n claim: 'A completed supervisor run has children with no captured terminal outcome',\n detail: `${missingTerminal.length}/${Math.max(0, unique.length - 1)} child node(s) are neither completed, truncated, nor errored.`,\n evidence: [\n evidence('children/missing-terminal/count', missingTerminal.length),\n ...missingTerminal\n .slice(0, MAX_EXAMPLES)\n .map((record) => nodeEvidence(record, 'outcome', record.raw.outcome)),\n ],\n recommendedAction: 'Retain each child settlement or cancellation event.',\n metadata: { assessment: 'unavailable', unavailable_count: missingTerminal.length },\n }),\n )\n }\n }\n\n const missingTranscripts = records.filter((record) => record.messages?.length === 0)\n if (missingTranscripts.length > 0) {\n out.push(\n issue({\n code: 'transcript-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject: 'decision-transcripts',\n claim: 'Decision transcripts are unavailable for some supervisor-tree invocations',\n detail: `${missingTranscripts.length}/${records.length} node row(s) have messages: [].`,\n evidence: [\n evidence('capture/missing-transcripts/count', missingTranscripts.length),\n ...missingTranscripts\n .slice(0, MAX_EXAMPLES)\n .map((record) => nodeEvidence(record, 'messages', [])),\n ],\n recommendedAction: 'Hydrate canonical messages from the retained session transcript.',\n metadata: { assessment: 'unavailable', unavailable_count: missingTranscripts.length },\n }),\n )\n }\n\n const missingProfiles = records.filter((record) => record.profileId === null)\n if (missingProfiles.length > 0) {\n out.push(\n issue({\n code: 'profile-id-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject: 'agent-profile-identity',\n claim:\n 'Canonical agent-profile identity is unavailable for some supervisor-tree invocations',\n detail: `${missingProfiles.length}/${records.length} node row(s) omit policy.agent_profile_cell_id.`,\n evidence: [\n evidence('capture/missing-agent-profile-cell-id/count', missingProfiles.length),\n ...missingProfiles\n .slice(0, MAX_EXAMPLES)\n .map((record) => nodeEvidence(record, 'policy.agent_profile_cell_id', null)),\n ],\n recommendedAction:\n 'Record policy.agent_profile_cell_id on every invocation at dispatch time.',\n metadata: { assessment: 'unavailable', unavailable_count: missingProfiles.length },\n }),\n )\n }\n\n return out\n}\n","import type { SupervisorRunTree } from './types'\n\nexport const SUPERVISOR_RUN_INTEGRITY_SCHEMA = 'tangle.supervisor-run-integrity@1'\n\nexport type SupervisorRunIntegritySeverity = 'critical' | 'high' | 'medium' | 'low' | 'info'\n\nexport type SupervisorRunSourceOnlyCheckCode =\n | 'journal-event-cardinality'\n | 'worker-control-join'\n | 'steer-ack-correlation'\n\nexport type SupervisorRunIntegrityIssueCode =\n | 'source-checks-unavailable'\n | 'node-schema-invalid'\n | 'node-checks-unavailable'\n | 'root-unavailable'\n | 'duplicate-rollout-id'\n | 'declared-root-missing'\n | 'root-has-parent'\n | 'root-role-invalid'\n | 'detached-node'\n | 'parent-missing'\n | 'cross-run-parent'\n | 'child-before-parent'\n | 'child-after-parent-close'\n | 'close-before-start'\n | 'parent-cycle'\n | 'child-terminal-unavailable'\n | 'transcript-unavailable'\n | 'profile-id-unavailable'\n | 'source-row-malformed'\n | 'source-event-identity-unavailable'\n | 'duplicate-spawn'\n | 'orphan-terminal'\n | 'duplicate-terminal'\n | 'worker-controls-unavailable'\n | 'worker-control-join-unavailable'\n | 'steer-request-id-unavailable'\n | 'steer-ack-id-unavailable'\n | 'steer-ack-status-unavailable'\n | 'duplicate-steer-request-id'\n | 'missing-steer-ack'\n | 'duplicate-steer-ack'\n | 'unknown-steer-ack'\n | 'steer-not-delivered'\n\nexport interface SupervisorRunIntegrityEvidence {\n readonly path: string\n readonly value: unknown\n}\n\nexport interface SupervisorRunIntegrityIssue {\n readonly code: SupervisorRunIntegrityIssueCode\n readonly area: 'control-integrity' | 'capture-integrity'\n readonly severity: SupervisorRunIntegritySeverity\n readonly subject: string\n readonly claim: string\n readonly detail: string\n readonly evidence: readonly SupervisorRunIntegrityEvidence[]\n readonly recommendedAction: string\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\nexport interface SupervisorRunIntegrityReport {\n readonly schema: typeof SUPERVISOR_RUN_INTEGRITY_SCHEMA\n readonly runRef: string\n readonly input: 'sources' | 'tree'\n readonly tree: SupervisorRunTree\n readonly issues: readonly SupervisorRunIntegrityIssue[]\n}\n\nexport interface SupervisorRunIntegrityOptions {\n /** Pins rollout provenance when source input must be projected into a tree. */\n readonly capturedAt?: string\n}\n","import type { SupervisorRunNodeRole, SupervisorRunSources } from './types'\n\n// ---------------------------------------------------------------------------\n// Journal shapes — structurally parsed. The journal is the contract, not the type.\n// ---------------------------------------------------------------------------\n\ninterface JournalEvent {\n kind?: unknown\n id?: unknown\n parent?: unknown\n label?: unknown\n role?: unknown\n status?: unknown\n verdict?: unknown\n reason?: unknown\n seq?: unknown\n at?: unknown\n spend?: unknown\n spent?: unknown\n}\n\ninterface Tokens {\n input: number\n output: number\n cacheRead: number\n cacheWrite: number\n /** False when the event carried no cache counters at all — not \"zero cached\". */\n hasCache: boolean\n}\n\ninterface SpendLike {\n tokens: Tokens\n usd: number\n}\n\nexport function asRecord(v: unknown): Record<string, unknown> {\n return typeof v === 'object' && v !== null ? (v as Record<string, unknown>) : {}\n}\n\nfunction num(v: unknown): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : 0\n}\n\nfunction readSpend(v: unknown): SpendLike {\n const rec = asRecord(v)\n const tok = asRecord(rec.tokens)\n const cacheRead = tok.cacheRead ?? tok.cache_read\n const cacheWrite = tok.cacheWrite ?? tok.cache_write\n return {\n tokens: {\n input: num(tok.input),\n output: num(tok.output),\n cacheRead: num(cacheRead),\n cacheWrite: num(cacheWrite),\n hasCache: cacheRead !== undefined || cacheWrite !== undefined,\n },\n usd: num(rec.usd),\n }\n}\n\nexport function parseJsonl(text: string | null): Record<string, unknown>[] {\n return parseJsonlWithDiagnostics(text).rows\n}\n\ninterface ParsedJsonl {\n readonly rows: Record<string, unknown>[]\n readonly invalidRows: number\n}\n\nfunction parseJsonlWithDiagnostics(text: string | null): ParsedJsonl {\n if (text === null) return { rows: [], invalidRows: 0 }\n const out: Record<string, unknown>[] = []\n let invalidRows = 0\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n const parsed: unknown = JSON.parse(trimmed)\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n out.push(parsed as Record<string, unknown>)\n } else {\n invalidRows += 1\n }\n } catch {\n invalidRows += 1\n }\n }\n return { rows: out, invalidRows }\n}\n\nexport function parseJson(text: string | null): Record<string, unknown> | null {\n if (text === null) return null\n try {\n const parsed: unknown = JSON.parse(text)\n return typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : null\n } catch {\n return null\n }\n}\n\nfunction ms(at: unknown): number | null {\n if (typeof at !== 'string') return null\n const t = Date.parse(at)\n return Number.isFinite(t) ? t : null\n}\n\n// ---------------------------------------------------------------------------\n// The supervision tree, as parsed from the journal event stream.\n// ---------------------------------------------------------------------------\n\nexport interface SpawnRow {\n /** Zero-based row among parsed journal objects. */\n sourceRow: number\n id: string\n parent: string | null\n label: string\n role: SupervisorRunNodeRole\n at: number | null\n /** False when identity, parentage, label, or role was malformed. */\n valid: boolean\n invalidFields: readonly string[]\n}\n\nexport interface CloseRow {\n id: string\n kind: 'settled' | 'cancelled'\n status: string | null\n /** String verdict from legacy journals, or valid/invalid for a structured verdict. */\n verdict: string | null\n /** Structured verdict validity, when recorded. */\n valid: boolean | null\n /** Structured verdict score, preserved without boolean coercion. */\n score: number | null\n /** The verdict exactly as the journal carried it. */\n rawVerdict: unknown | null\n at: number | null\n spend: SpendLike\n /** False when the close event carried no spend object — not \"spent nothing\". */\n hasSpend: boolean\n}\n\nexport interface WorkerLogFacts {\n /** Position in `SupervisorRunSources.workers`, retained for exact evidence paths. */\n sourceIndex: number\n workerId: string | null\n label: string\n /** `false` means the artifact was missing; a captured empty artifact is `true`. */\n inboxCaptured: boolean\n eventsCaptured: boolean\n inboxInvalidRows: number\n eventsInvalidRows: number\n started: number | null\n /** True once a `finished` event was seen — independent of whether its `at` parsed. */\n finished: boolean\n finishedAt: number | null\n passed: boolean | null\n /** Numeric score exactly as the finished event recorded it. */\n score: number | null\n /** `patchBytes` as reported by the finished event (not the patch file's size). */\n finishedPatchBytes: number | null\n evidenceBytes: number\n /** Unique queued request ids, or null when exact accounting is unavailable. */\n steersQueued: number | null\n /** Unique matched request ids acknowledged as delivered, or null when unavailable. */\n steersDelivered: number | null\n steersQueuedUnavailable: string | null\n steersDeliveredUnavailable: string | null\n questions: number\n steerRequests: SteerRequestFact[]\n steerAcknowledgements: SteerAcknowledgementFact[]\n}\n\nexport interface SteerRequestFact {\n /** Durable inbox request id; null when the row did not retain one. */\n requestId: string | null\n row: number\n}\n\nexport interface SteerAcknowledgementFact {\n /** Worker event request id; null when the event cannot be correlated. */\n requestId: string | null\n /** `null` means the acknowledgement omitted delivery status. */\n delivered: boolean | null\n row: number\n}\n\n/**\n * The tree + timeline the report is computed from, exposed because the rollout-row\n * minter needs exactly the same parse (one parser, two consumers).\n */\nexport interface SupervisorTreeFacts {\n readonly rootId: string | null\n readonly spawns: readonly SpawnRow[]\n readonly closes: readonly CloseRow[]\n readonly workerSpawns: readonly SpawnRow[]\n readonly workerCloses: readonly CloseRow[]\n readonly brain: {\n tokensIn: number\n tokensOut: number\n cacheRead: number\n cacheWrite: number\n /** False when no metered event carried cache counters — not \"nothing cached\". */\n hasCache: boolean\n usd: number\n meteredCount: number\n }\n readonly workerLogs: ReadonlyMap<string, WorkerLogFacts>\n /** Every worker source row, including duplicate identities that a map cannot retain. */\n readonly workerLogRows: readonly WorkerLogFacts[]\n /** Non-empty journal lines that were not JSON objects. */\n readonly journalInvalidRows: number\n /** Parsed once with the journal and worker artifacts. */\n readonly state: Record<string, unknown> | null\n readonly startedAt: number | null\n readonly completedAt: number | null\n}\n\ninterface VerdictFacts {\n label: string | null\n valid: boolean | null\n score: number | null\n raw: unknown | null\n}\n\nfunction readVerdict(v: unknown): VerdictFacts {\n if (typeof v === 'string') return { label: v, valid: null, score: null, raw: v }\n if (typeof v !== 'object' || v === null) {\n return { label: null, valid: null, score: null, raw: null }\n }\n const rec = v as Record<string, unknown>\n const valid = typeof rec.valid === 'boolean' ? rec.valid : null\n return {\n label: valid === null ? null : valid ? 'valid' : 'invalid',\n valid,\n score: typeof rec.score === 'number' && Number.isFinite(rec.score) ? rec.score : null,\n raw: v,\n }\n}\n\nexport function workerSourceKey(\n worker: NonNullable<SupervisorRunSources['workers']>[number],\n): string {\n return worker.workerId ?? worker.label\n}\n\nexport function parseSupervisorTree(src: SupervisorRunSources): SupervisorTreeFacts {\n const parsedJournal = parseJsonlWithDiagnostics(src.journal)\n const events = parsedJournal.rows\n const state = parseJson(src.state)\n\n const spawns: SpawnRow[] = []\n const closes: CloseRow[] = []\n let brainIn = 0\n let brainOut = 0\n let brainCacheRead = 0\n let brainCacheWrite = 0\n let brainHasCache = false\n let brainUsd = 0\n let meteredCount = 0\n let rootId: string | null = null\n for (const [sourceRow, ev] of (events as JournalEvent[]).entries()) {\n const kind = typeof ev.kind === 'string' ? ev.kind : ''\n const id = typeof ev.id === 'string' ? ev.id : ''\n if (kind === 'spawned') {\n const parent = typeof ev.parent === 'string' && ev.parent.length > 0 ? ev.parent : null\n const label = typeof ev.label === 'string' ? ev.label : ''\n const invalidFields: string[] = []\n if (id.length === 0) invalidFields.push('id')\n const parentOmittedForFirstRoot = ev.parent === undefined && rootId === null\n if (\n ev.parent !== null &&\n !parentOmittedForFirstRoot &&\n !(typeof ev.parent === 'string' && ev.parent.length > 0)\n ) {\n invalidFields.push('parent')\n }\n if (label.length === 0) invalidFields.push('label')\n if (ev.role !== undefined && ev.role !== 'supervisor' && ev.role !== 'worker') {\n invalidFields.push('role')\n }\n const role: SupervisorRunNodeRole =\n ev.role === 'supervisor' || ev.role === 'worker'\n ? ev.role\n : parent === null\n ? 'supervisor'\n : 'worker'\n const valid = invalidFields.length === 0\n if (valid && parent === null && rootId === null) rootId = id\n spawns.push({\n sourceRow,\n id,\n parent,\n label,\n role,\n at: ms(ev.at),\n valid,\n invalidFields,\n })\n } else if (kind === 'settled') {\n const verdict = readVerdict(ev.verdict)\n closes.push({\n id,\n kind: 'settled',\n status: typeof ev.status === 'string' ? ev.status : null,\n verdict: verdict.label,\n valid: verdict.valid,\n score: verdict.score,\n rawVerdict: verdict.raw,\n at: ms(ev.at),\n spend: readSpend(ev.spent),\n hasSpend: asRecord(ev.spent).tokens !== undefined,\n })\n } else if (kind === 'cancelled') {\n closes.push({\n id,\n kind: 'cancelled',\n status: 'cancelled',\n verdict: typeof ev.reason === 'string' ? ev.reason : null,\n valid: null,\n score: null,\n rawVerdict: typeof ev.reason === 'string' ? ev.reason : null,\n at: ms(ev.at),\n spend: {\n tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, hasCache: false },\n usd: 0,\n },\n hasSpend: false,\n })\n } else if (kind === 'metered') {\n const s = readSpend(ev.spend)\n brainIn += s.tokens.input\n brainOut += s.tokens.output\n brainCacheRead += s.tokens.cacheRead\n brainCacheWrite += s.tokens.cacheWrite\n brainHasCache = brainHasCache || s.tokens.hasCache\n brainUsd += s.usd\n meteredCount += 1\n }\n }\n\n const workerSpawns = spawns.filter((s) => s.valid && s.id !== rootId)\n const workerIds = new Set(workerSpawns.map((s) => s.id))\n const workerCloses = closes.filter((c) => workerIds.has(c.id))\n\n const workerLogs = new Map<string, WorkerLogFacts>()\n const workerLogRows: WorkerLogFacts[] = []\n for (const [sourceIndex, w] of (src.workers ?? []).entries()) {\n const facts: WorkerLogFacts = {\n sourceIndex,\n workerId: w.workerId ?? null,\n label: w.label,\n inboxCaptured: w.inbox !== null,\n eventsCaptured: w.events !== null,\n inboxInvalidRows: 0,\n eventsInvalidRows: 0,\n started: null,\n finished: false,\n finishedAt: null,\n passed: null,\n score: null,\n finishedPatchBytes: null,\n evidenceBytes: 0,\n steersQueued: null,\n steersDelivered: null,\n steersQueuedUnavailable: null,\n steersDeliveredUnavailable: null,\n questions: 0,\n steerRequests: [],\n steerAcknowledgements: [],\n }\n const parsedInbox = parseJsonlWithDiagnostics(w.inbox)\n const parsedEvents = parseJsonlWithDiagnostics(w.events)\n facts.inboxInvalidRows = parsedInbox.invalidRows\n facts.eventsInvalidRows = parsedEvents.invalidRows\n for (const [row, req] of parsedInbox.rows.entries()) {\n if (typeof req.message !== 'string' || req.message.trim().length === 0) continue\n facts.steerRequests.push({\n requestId: typeof req.id === 'string' && req.id.length > 0 ? req.id : null,\n row,\n })\n }\n for (const [row, ev] of parsedEvents.rows.entries()) {\n const kind = ev.kind\n if (kind === 'message') {\n if (ev.direction === 'up') {\n facts.questions += 1\n continue\n }\n facts.steerAcknowledgements.push({\n requestId:\n typeof ev.requestId === 'string' && ev.requestId.length > 0 ? ev.requestId : null,\n delivered: typeof ev.delivered === 'boolean' ? ev.delivered : null,\n row,\n })\n } else if (kind === 'started') {\n facts.started = ms(ev.at)\n } else if (kind === 'finished') {\n facts.finished = true\n facts.finishedAt = ms(ev.at)\n facts.passed = typeof ev.passed === 'boolean' ? ev.passed : null\n facts.score = typeof ev.score === 'number' && Number.isFinite(ev.score) ? ev.score : null\n facts.finishedPatchBytes = typeof ev.patchBytes === 'number' ? ev.patchBytes : null\n facts.evidenceBytes = typeof ev.evidence === 'string' ? ev.evidence.length : 0\n }\n }\n const requestsById = new Map<string, number>()\n for (const request of facts.steerRequests) {\n if (request.requestId === null) continue\n requestsById.set(request.requestId, (requestsById.get(request.requestId) ?? 0) + 1)\n }\n const acknowledgementsById = new Map<string, SteerAcknowledgementFact[]>()\n for (const acknowledgement of facts.steerAcknowledgements) {\n if (acknowledgement.requestId === null) continue\n const matches = acknowledgementsById.get(acknowledgement.requestId) ?? []\n matches.push(acknowledgement)\n acknowledgementsById.set(acknowledgement.requestId, matches)\n }\n const queueProblems: string[] = []\n if (!facts.inboxCaptured) queueProblems.push('inbox absent')\n if (!facts.eventsCaptured) queueProblems.push('events absent')\n if (facts.inboxInvalidRows > 0) queueProblems.push('inbox contains malformed rows')\n if (facts.eventsInvalidRows > 0) queueProblems.push('events contain malformed rows')\n if (facts.steerRequests.some((request) => request.requestId === null)) {\n queueProblems.push('queued request id missing')\n }\n if ([...requestsById.values()].some((count) => count > 1)) {\n queueProblems.push('queued request id duplicated')\n }\n if (facts.steerAcknowledgements.some((acknowledgement) => acknowledgement.requestId === null)) {\n queueProblems.push('acknowledgement request id missing')\n }\n if ([...acknowledgementsById.keys()].some((id) => !requestsById.has(id))) {\n queueProblems.push('acknowledgement has no queued request')\n }\n if (queueProblems.length === 0) {\n facts.steersQueued = requestsById.size\n } else {\n facts.steersQueuedUnavailable = [...new Set(queueProblems)].join('; ')\n }\n\n const deliveryProblems = [...queueProblems]\n if ([...acknowledgementsById.values()].some((rows) => rows.length > 1)) {\n deliveryProblems.push('acknowledgement request id duplicated')\n }\n if (facts.steerAcknowledgements.some((acknowledgement) => acknowledgement.delivered === null)) {\n deliveryProblems.push('acknowledgement delivery status missing')\n }\n if (deliveryProblems.length === 0) {\n facts.steersDelivered = [...requestsById.keys()].filter((id) => {\n const acknowledgement = acknowledgementsById.get(id)\n return acknowledgement?.length === 1 && acknowledgement[0]?.delivered === true\n }).length\n } else {\n facts.steersDeliveredUnavailable = [...new Set(deliveryProblems)].join('; ')\n }\n workerLogRows.push(facts)\n workerLogs.set(workerSourceKey(w), facts)\n }\n\n const startedAt = ms(state?.startedAt) ?? spawns[0]?.at ?? null\n const completedAt =\n ms(state?.completedAt) ??\n [...spawns.map((s) => s.at), ...closes.map((c) => c.at)].reduce<number | null>(\n (acc, t) => (t === null ? acc : acc === null ? t : Math.max(acc, t)),\n null,\n )\n\n return {\n rootId,\n spawns,\n closes,\n workerSpawns,\n workerCloses,\n brain: {\n tokensIn: brainIn,\n tokensOut: brainOut,\n cacheRead: brainCacheRead,\n cacheWrite: brainCacheWrite,\n hasCache: brainHasCache,\n usd: brainUsd,\n meteredCount,\n },\n workerLogs,\n workerLogRows,\n journalInvalidRows: parsedJournal.invalidRows,\n state,\n startedAt,\n completedAt,\n }\n}\n","/**\n * The supervision tree as `tangle.rollout.v1` rows.\n *\n * A supervisor run IS a tree of rollouts, so its nodes are not a new shape:\n * the root becomes one `RolloutLine` with `role: 'supervisor'`, and every\n * spawned invocation keeps its explicit supervisor/worker role with\n * `parent_rollout_id` pointing at its spawner. The rows append to the same\n * ledger as solo-agent rollouts and join to them with the same keys.\n *\n * What the journal CANNOT supply is the transcript: a worker's messages live\n * in its harness store (opencode sqlite, Claude Code jsonl), which the\n * `src/rollout/readers/*` intake readers own. Rows minted here are therefore\n * GAP lines (`messages: []`, `provenance.gap` set) carrying identity,\n * structure, outcome and cost; hydrating them with messages is the readers'\n * job, keyed on `artifacts.transcript_ref`.\n *\n * Timing lives in `outcome.metrics` (`spawned_at` / `settled_at` / `wall_ms`)\n * rather than a schema field: `tangle.rollout.v1` describes ONE invocation,\n * and the inter-invocation event timeline — which is what waves, concurrency,\n * idle and utilization are computed from — is a property of the journal, not\n * of any single row. The analyzer reads that timeline; these rows carry the\n * per-node facts.\n */\n\nimport { unscreenedRewardFields } from '../rollout/reward'\nimport {\n isRolloutLine,\n ROLLOUT_SCHEMA,\n type RolloutLine,\n type RolloutSplit,\n} from '../rollout/schema'\nimport { asRecord, parseJson, parseSupervisorTree, type SupervisorTreeFacts } from './source-facts'\nimport type {\n SupervisorRunSources,\n SupervisorRunTree,\n SupervisorRunTreeGap,\n WorkerLogSource,\n} from './types'\n\nexport interface SupervisorRolloutOptions {\n /** Benchmark/suite id for `task.suite`. Defaults to `'supervisor-run'`. */\n readonly suite?: string\n /** `task.split`. Defaults to `'search'` (the trainable pool). */\n readonly split?: RolloutSplit\n /** Replicate index. Defaults to 0. */\n readonly rep?: number\n /** Sampling seed the campaign pinned. Defaults to null (not recorded). */\n readonly seed?: number | null\n /** `run_id` for every node. Defaults to the supervisor root id, else `runRef`. */\n readonly runId?: string\n /** Harness that drove the supervisor. */\n readonly supervisorHarness?: string | null\n /** Harness that drove the workers. */\n readonly workerHarness?: string | null\n /** Model the supervisor ran on. */\n readonly supervisorModel?: string | null\n /** Model the workers ran on. */\n readonly workerModel?: string | null\n readonly experimentId?: string | null\n readonly candidateId?: string | null\n readonly generation?: number | null\n readonly candidateIndex?: number | null\n /** Pins `provenance.captured_at`; defaults to now. */\n readonly capturedAt?: string\n}\n\nconst EMPTY_COST = {\n usd: null,\n tokens_in: null,\n tokens_out: null,\n tokens_reasoning: null,\n cache_read: null,\n cache_write: null,\n wall_s: null,\n} as const\n\nfunction hasWorkerId(\n worker: WorkerLogSource,\n): worker is WorkerLogSource & { readonly workerId: string } {\n return worker.workerId !== undefined\n}\n\n/**\n * Mint the supervision tree as rollout rows. Returns the rows plus the gaps\n * that made any of them incomplete — same unavailable-vs-zero discipline as\n * the report: a row with no transcript says WHY, it never pretends to be empty.\n */\nexport function supervisorRunRolloutLines(\n src: SupervisorRunSources,\n opts: SupervisorRolloutOptions = {},\n): SupervisorRunTree {\n return supervisorRunRolloutLinesFromFacts(src, parseSupervisorTree(src), opts)\n}\n\n/** Mint rollout rows from an already parsed source without reading its JSONL again. */\nexport function supervisorRunRolloutLinesFromFacts(\n src: SupervisorRunSources,\n tree: SupervisorTreeFacts,\n opts: SupervisorRolloutOptions = {},\n): SupervisorRunTree {\n const gaps: SupervisorRunTreeGap[] = []\n if (src.journal === null) {\n gaps.push({\n code: 'journal-unavailable',\n message: `${src.supRunDir === null ? 'no supervisor run dir' : 'journal absent'}; no nodes recoverable`,\n })\n return { rootId: null, nodes: [], gaps }\n }\n const malformedSourceRows =\n tree.journalInvalidRows + tree.spawns.filter((spawn) => !spawn.valid).length\n if (malformedSourceRows > 0) {\n gaps.push({\n code: 'source-row-malformed',\n message: `${malformedSourceRows} malformed journal row(s) were excluded from the tree`,\n count: malformedSourceRows,\n })\n }\n\n const state = tree.state\n const result = parseJson(src.result)\n const judge = parseJson(src.judge)\n const stateResult = asRecord(state?.result)\n\n const rootId = tree.rootId\n const runId = opts.runId ?? rootId ?? src.runRef\n const suite = opts.suite ?? 'supervisor-run'\n const instanceId = src.instanceId ?? src.runRef\n const split: RolloutSplit = opts.split ?? 'search'\n const capturedAt = opts.capturedAt ?? new Date().toISOString()\n\n const base = {\n schema: ROLLOUT_SCHEMA,\n run_id: runId,\n experiment_id: opts.experimentId ?? null,\n candidate_id: opts.candidateId ?? null,\n generation: opts.generation ?? null,\n candidate_index: opts.candidateIndex ?? null,\n task: {\n suite,\n instance_id: instanceId,\n split,\n seed: opts.seed ?? null,\n rep: opts.rep ?? 0,\n },\n messages: [] as RolloutLine['messages'],\n tool_defs: [] as RolloutLine['tool_defs'],\n } satisfies Partial<RolloutLine> & Record<string, unknown>\n\n const nodes: RolloutLine[] = []\n\n // ── root: the supervisor invocation ────────────────────────────────────\n if (rootId !== null) {\n const rootSpawn = tree.spawns.find((spawn) => spawn.valid && spawn.id === rootId)\n const judgeResolved = typeof judge?.resolved === 'boolean' ? judge.resolved : null\n const judgeScore = typeof judge?.score === 'number' ? judge.score : null\n const reward = judgeScore ?? (judgeResolved === null ? null : judgeResolved ? 1 : 0)\n if (reward === null) {\n gaps.push({\n code: 'root-reward-unavailable',\n message: 'no judge verdict for this run',\n nodeId: rootId,\n })\n }\n const wallMs =\n tree.startedAt !== null && tree.completedAt !== null && tree.completedAt >= tree.startedAt\n ? tree.completedAt - tree.startedAt\n : null\n nodes.push({\n ...base,\n rollout_id: rootId,\n parent_rollout_id: null,\n role: rootSpawn?.role ?? 'supervisor',\n policy: {\n harness: opts.supervisorHarness ?? null,\n harness_version: null,\n model: opts.supervisorModel ?? null,\n provider: null,\n profile_commit: null,\n sampling: null,\n },\n outcome: {\n // `reward` and `realness_gated` are written by one call, in the module\n // that owns the gate. This is the SECOND producer of rollout rewards —\n // the judge verdict in the supervision run dir, not `mintRolloutRows` —\n // and it wrote `reward` by hand while never stating the flag, so\n // `isLineRealnessGated` was structurally false for every supervisor and\n // worker row ever emitted here. `unscreenedRewardFields` is the honest\n // name for what this producer can claim: a supervision journal carries\n // no `RunRecord.outcome.realness`, so no authenticity gate has run on\n // this score, and `realness_gated: false` states that rather than\n // implying it by omission. These rows stay plain `RolloutLine`s, so a\n // caller feeding them to a training exporter must `assertMinted` first.\n ...unscreenedRewardFields(reward),\n reward_source: src.judgeSource,\n verdict: judge ?? null,\n metrics: {\n arm: src.arm,\n sup_status: typeof state?.status === 'string' ? state.status : null,\n sup_verdict: typeof state?.verdict === 'string' ? state.verdict : null,\n delivered: typeof stateResult.delivered === 'boolean' ? stateResult.delivered : null,\n verify_pass: typeof result?.verify_pass === 'boolean' ? result.verify_pass : null,\n started_at: tree.startedAt,\n completed_at: tree.completedAt,\n workers_spawned: tree.workerSpawns.length,\n brain_metered_events: tree.brain.meteredCount,\n },\n is_completed: state?.status === 'completed',\n is_truncated: false,\n error: null,\n realness_gated: false,\n },\n cost: {\n ...EMPTY_COST,\n usd:\n src.limits.spendUsd !== null\n ? null\n : typeof stateResult.spentUsd === 'number'\n ? stateResult.spentUsd\n : tree.brain.usd,\n tokens_in: src.limits.managerTokens === null ? tree.brain.tokensIn : null,\n tokens_out: src.limits.managerTokens === null ? tree.brain.tokensOut : null,\n cache_read:\n src.limits.managerTokens === null && tree.brain.hasCache ? tree.brain.cacheRead : null,\n cache_write:\n src.limits.managerTokens === null && tree.brain.hasCache ? tree.brain.cacheWrite : null,\n wall_s: wallMs === null ? null : wallMs / 1000,\n },\n artifacts: {\n patch_path: typeof result?.patchPath === 'string' ? result.patchPath : null,\n run_dir: src.supRunDir,\n transcript_ref:\n src.rootTranscriptRef !== undefined\n ? src.rootTranscriptRef\n : src.supRunDir === null\n ? null\n : `${src.supRunDir}/journal.jsonl`,\n },\n provenance: {\n captured_at: capturedAt,\n capture: 'backfill',\n gap: 'supervision journal carries structure and spend, not the brain transcript',\n },\n })\n } else {\n gaps.push({\n code: 'root-spawn-unavailable',\n message: 'no parentless spawned event in the journal',\n })\n }\n\n // ── workers: one node per spawn, keyed to its spawner ───────────────────\n const closeById = new Map(tree.closes.map((c) => [c.id, c]))\n const sourceById = new Map(\n (src.workers ?? []).filter(hasWorkerId).map((worker) => [worker.workerId, worker]),\n )\n const fallbackSourceByLabel = new Map(\n (src.workers ?? [])\n .filter((worker) => worker.workerId === undefined)\n .map((worker) => [worker.label, worker]),\n )\n // Stable ids are authoritative. Labels are a compatibility join for stores\n // that predate workerId and are only safe when the store keeps them unique.\n for (const spawn of tree.workerSpawns) {\n const close = closeById.get(spawn.id) ?? null\n const workerSource = sourceById.get(spawn.id) ?? fallbackSourceByLabel.get(spawn.label) ?? null\n const facts =\n tree.workerLogs.get(workerSource?.workerId ?? workerSource?.label ?? spawn.label) ?? null\n const wallMs =\n facts?.started != null && facts.finishedAt != null ? facts.finishedAt - facts.started : null\n const score = close?.score ?? facts?.score ?? null\n const passed = close?.valid ?? facts?.passed ?? null\n const reward = score ?? (passed === null ? null : passed ? 1 : 0)\n if (reward === null) {\n gaps.push({\n code: 'child-reward-unavailable',\n message: `child ${JSON.stringify(spawn.label)} has no verify verdict`,\n nodeId: spawn.id,\n })\n }\n const isSupervisor = spawn.role === 'supervisor'\n nodes.push({\n ...base,\n rollout_id: spawn.id,\n parent_rollout_id: spawn.parent,\n role: spawn.role,\n policy: {\n harness: isSupervisor ? (opts.supervisorHarness ?? null) : (opts.workerHarness ?? null),\n harness_version: null,\n model: isSupervisor ? (opts.supervisorModel ?? null) : (opts.workerModel ?? null),\n provider: null,\n profile_commit: null,\n sampling: null,\n },\n outcome: {\n // Same producer, same claim: a child reward is a self-verify verdict\n // from the journal that no realness gate has seen.\n ...unscreenedRewardFields(reward),\n reward_source:\n reward === null ? null : score === null ? 'worker-self-verify' : 'worker-verdict-score',\n verdict:\n close === null\n ? null\n : {\n kind: close.kind,\n status: close.status,\n verdict: close.rawVerdict,\n valid: close.valid,\n score: close.score,\n },\n metrics: {\n label: spawn.label,\n spawned_at: spawn.at,\n settled_at: close?.at ?? null,\n started_at: facts?.started ?? null,\n finished_at: facts?.finishedAt ?? null,\n wall_ms: wallMs,\n patch_bytes: workerSource?.patchBytes ?? facts?.finishedPatchBytes ?? null,\n evidence_bytes: facts?.evidenceBytes ?? null,\n steers_queued: facts?.steersQueued ?? null,\n steers_delivered: facts?.steersDelivered ?? null,\n questions: facts?.questions ?? null,\n },\n is_completed: close?.kind === 'settled',\n is_truncated: close?.kind === 'cancelled',\n error: close?.kind === 'cancelled' ? (close.verdict ?? 'cancelled') : null,\n realness_gated: false,\n },\n // `close.spend` is only a measurement when the close event carried one;\n // a store that never priced this worker must leave null, not 0.\n cost: {\n ...EMPTY_COST,\n usd: src.limits.spendUsd !== null || !close?.hasSpend ? null : close.spend.usd,\n tokens_in: workerSource?.tokensIn ?? (close?.hasSpend ? close.spend.tokens.input : null),\n tokens_out: workerSource?.tokensOut ?? (close?.hasSpend ? close.spend.tokens.output : null),\n // Mirror the tokens_in/out journal fallback so a loops-shaped store whose\n // `settled` spend carries cache counters is not reported as null cache\n // beside real tokens. Gate on `hasCache` — a spend object without cache\n // counters must stay null, not a fabricated 0.\n cache_read:\n workerSource?.cacheRead ??\n (close?.hasSpend && close.spend.tokens.hasCache ? close.spend.tokens.cacheRead : null),\n cache_write:\n workerSource?.cacheWrite ??\n (close?.hasSpend && close.spend.tokens.hasCache ? close.spend.tokens.cacheWrite : null),\n wall_s: wallMs === null ? null : wallMs / 1000,\n },\n // A reader that knows where its worker artifacts live says so; only the\n // loops layout is derivable from `supRunDir`, so guessing it for another\n // store would mint rows pointing at paths that never existed.\n artifacts: {\n patch_path:\n workerSource?.patchPath !== undefined\n ? workerSource.patchPath\n : src.supRunDir === null\n ? null\n : `${src.supRunDir}/workers/${spawn.label}.patch`,\n run_dir: src.supRunDir,\n transcript_ref:\n workerSource?.transcriptRef !== undefined\n ? workerSource.transcriptRef\n : src.supRunDir === null\n ? null\n : `${src.supRunDir}/workers/${spawn.label}.ndjson`,\n },\n provenance: {\n captured_at: capturedAt,\n capture: 'backfill',\n gap:\n workerSource?.transcriptRef == null\n ? 'worker transcript lives in the harness session store — hydrate via src/rollout/readers'\n : 'worker transcript recorded by the harness; messages not inlined into this row',\n },\n })\n }\n\n const invalid = nodes.filter((n) => !isRolloutLine(n))\n if (invalid.length > 0) {\n gaps.push({\n code: 'node-schema-invalid',\n message: `${invalid.length} node(s) failed tangle.rollout.v1 validation`,\n count: invalid.length,\n })\n }\n return { rootId, nodes, gaps }\n}\n","import { evidence, issue } from './integrity-issues'\nimport { sourceIssues } from './integrity-source'\nimport { treeIssues } from './integrity-tree'\nimport {\n SUPERVISOR_RUN_INTEGRITY_SCHEMA,\n type SupervisorRunIntegrityOptions,\n type SupervisorRunIntegrityReport,\n type SupervisorRunSourceOnlyCheckCode,\n} from './integrity-types'\nimport { supervisorRunRolloutLinesFromFacts } from './rollout-nodes'\nimport { parseSupervisorTree } from './source-facts'\nimport type { SupervisorRunSources, SupervisorRunTree } from './types'\n\nexport {\n SUPERVISOR_RUN_INTEGRITY_SCHEMA,\n type SupervisorRunIntegrityEvidence,\n type SupervisorRunIntegrityIssue,\n type SupervisorRunIntegrityIssueCode,\n type SupervisorRunIntegrityOptions,\n type SupervisorRunIntegrityReport,\n type SupervisorRunIntegritySeverity,\n type SupervisorRunSourceOnlyCheckCode,\n} from './integrity-types'\n\nfunction isTree(input: SupervisorRunSources | SupervisorRunTree): input is SupervisorRunTree {\n return 'nodes' in input && Array.isArray(input.nodes)\n}\n\nfunction treeRunRef(tree: SupervisorRunTree): string {\n const runIds = [\n ...new Set(\n tree.nodes\n .map((node) => node.run_id)\n .filter((runId): runId is string => typeof runId === 'string' && runId.length > 0),\n ),\n ].sort()\n if (runIds.length === 1) return runIds[0]!\n if (runIds.length > 1) return `mixed-runs:${runIds.join(',')}`\n return tree.rootId ?? 'unidentified-tree'\n}\n\n/**\n * Run deterministic integrity checks over source bytes or an already minted tree.\n * Source input is parsed exactly once and reused by projection and source-only checks.\n */\nexport function analyzeSupervisorRunIntegrity(\n input: SupervisorRunSources | SupervisorRunTree,\n options: SupervisorRunIntegrityOptions = {},\n): SupervisorRunIntegrityReport {\n if (isTree(input)) {\n const sourceOnlyChecks: readonly SupervisorRunSourceOnlyCheckCode[] = [\n 'journal-event-cardinality',\n 'worker-control-join',\n 'steer-ack-correlation',\n ]\n return {\n schema: SUPERVISOR_RUN_INTEGRITY_SCHEMA,\n runRef: treeRunRef(input),\n input: 'tree',\n tree: input,\n issues: [\n ...treeIssues(input),\n issue({\n code: 'source-checks-unavailable',\n area: 'capture-integrity',\n severity: 'medium',\n subject: 'source-only-control-checks',\n claim: 'Source-only control checks are unavailable for SupervisorRunTree input',\n detail:\n 'Rollout rows do not retain journal event multiplicity or worker inbox and acknowledgement rows.',\n evidence: [evidence('input/source-only-checks', sourceOnlyChecks)],\n recommendedAction:\n 'Pass SupervisorRunSources when journal and worker control checks are required.',\n metadata: { assessment: 'unavailable', checks: sourceOnlyChecks },\n }),\n ],\n }\n }\n\n const facts = parseSupervisorTree(input)\n const tree = supervisorRunRolloutLinesFromFacts(input, facts, {\n capturedAt: options.capturedAt,\n })\n return {\n schema: SUPERVISOR_RUN_INTEGRITY_SCHEMA,\n runRef: input.runRef,\n input: 'sources',\n tree,\n issues: [\n ...treeIssues(tree, {\n unknownIdentityRows:\n facts.journalInvalidRows +\n facts.spawns.filter((spawn) => !spawn.valid && spawn.id.length === 0).length,\n uncertainIds: new Set(\n facts.spawns\n .filter((spawn) => !spawn.valid && spawn.id.length > 0)\n .map((spawn) => spawn.id),\n ),\n }),\n ...sourceIssues(input, facts, tree),\n ],\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { r as CaptureIntegrityError } from "./errors-CEk209JS.js";
2
- import { l as RawProviderSink } from "./raw-provider-sink-BU29Sh8h.js";
1
+ import { r as CaptureIntegrityError } from "./errors-DkfjIDvD.js";
2
+ import { _t as RawProviderSink } from "./types-CTvKfr5F.js";
3
3
  import { s as TraceStore } from "./store-CT9YIIve.js";
4
4
  //#region src/trace/integrity.d.ts
5
5
  interface RunIntegrityExpectations {
@@ -58,4 +58,4 @@ declare function assertRunCaptured(store: TraceStore, runId: string, expectation
58
58
  declare function throwIfRunIncomplete(report: RunIntegrityReport): void;
59
59
  //#endregion
60
60
  export { RunIntegrityReport as a, RunIntegrityIssueCode as i, RunIntegrityExpectations as n, assertRunCaptured as o, RunIntegrityIssue as r, throwIfRunIncomplete as s, RunIntegrityError as t };
61
- //# sourceMappingURL=integrity-rmVhXWA7.d.ts.map
61
+ //# sourceMappingURL=integrity-CKxosZ5Z.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"integrity-rmVhXWA7.d.ts","names":[],"sources":["../src/trace/integrity.ts"],"mappings":";;;;UAyBiB;;EAEf;;EAEA;;EAEA;;;;;EAKA,UAAU;;EAEV;;;;;;EAMA;;EAEA;;KAGU;UAUK;EACf,MAAM;EACN;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA;IAAmB;IAAiB;;EACpC,QAAQ;;cAGG,0BAA0B;WACT,QAAQ;EAApC,YAA4B,QAAQ;;iBAOhB,kBACpB,OAAO,YACP,eACA,eAAc,2BACb,QAAQ;;iBA6GK,qBAAqB,QAAQ"}
1
+ {"version":3,"file":"integrity-CKxosZ5Z.d.ts","names":[],"sources":["../src/trace/integrity.ts"],"mappings":";;;;UAyBiB;;EAEf;;EAEA;;EAEA;;;;;EAKA,UAAU;;EAEV;;;;;;EAMA;;EAEA;;KAGU;UAUK;EACf,MAAM;EACN;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA;IAAmB;IAAiB;;EACpC,QAAQ;;cAGG,0BAA0B;WACT,QAAQ;EAApC,YAA4B,QAAQ;;iBAOhB,kBACpB,OAAO,YACP,eACA,eAAc,2BACb,QAAQ;;iBA6GK,qBAAqB,QAAQ"}
@@ -1,4 +1,4 @@
1
- import { n as CaptureIntegrityError } from "./errors-8YnH8WlF.js";
1
+ import { n as CaptureIntegrityError } from "./errors-D-LKuDhb.js";
2
2
  //#region src/trace/store.ts
3
3
  var InMemoryTraceStore = class {
4
4
  runs = /* @__PURE__ */ new Map();
@@ -421,4 +421,4 @@ function throwIfRunIncomplete(report) {
421
421
  //#endregion
422
422
  export { InMemoryTraceStore as a, FileSystemTraceStore as i, assertRunCaptured as n, throwIfRunIncomplete as r, RunIntegrityError as t };
423
423
 
424
- //# sourceMappingURL=integrity-BzRbCHzi.js.map
424
+ //# sourceMappingURL=integrity-fdt8XPAv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integrity-BzRbCHzi.js","names":[],"sources":["../src/trace/store.ts","../src/trace/integrity.ts"],"sourcesContent":["/**\n * TraceStore — persistence + query over the TraceSchema v1 corpus.\n *\n * Two implementations ship in the core:\n * - InMemoryTraceStore: dev + tests, fully in-process\n * - FileSystemTraceStore: NDJSON append-only files per entity, suitable\n * for long-running CI jobs; rolled over at 32MB\n *\n * Downstream adapters (DuckDB, Langfuse, R2 parquet) implement this same\n * interface — the rest of the framework is storage-agnostic.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n Run,\n RunStatus,\n Span,\n SpanKind,\n TraceEvent,\n} from './schema'\n\nexport interface RunFilter {\n scenarioId?: string\n variantId?: string\n status?: RunStatus\n since?: number\n until?: number\n tag?: { key: string; value: string }\n parentRunId?: string\n projectId?: string\n chatId?: string\n layer?: import('./schema').RunLayer\n}\n\nexport interface SpanFilter {\n runId?: string\n parentSpanId?: string\n kind?: SpanKind\n name?: string\n toolName?: string\n judgeId?: string\n since?: number\n until?: number\n}\n\nexport interface EventFilter {\n runId?: string\n spanId?: string\n kind?: EventKind\n since?: number\n until?: number\n}\n\nexport interface TraceStore {\n appendRun(run: Run): Promise<void>\n updateRun(runId: string, patch: Partial<Run>): Promise<void>\n appendSpan(span: Span): Promise<void>\n updateSpan(spanId: string, patch: Partial<Span>): Promise<void>\n appendEvent(event: TraceEvent): Promise<void>\n appendArtifact(artifact: Artifact): Promise<void>\n appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void>\n\n getRun(runId: string): Promise<Run | undefined>\n listRuns(filter?: RunFilter): Promise<Run[]>\n spans(filter?: SpanFilter): Promise<Span[]>\n events(filter?: EventFilter): Promise<TraceEvent[]>\n budget(runId: string): Promise<BudgetLedgerEntry[]>\n artifacts(runId: string): Promise<Artifact[]>\n}\n\n// ── In-memory ────────────────────────────────────────────────────────\n\nexport class InMemoryTraceStore implements TraceStore {\n private runs = new Map<string, Run>()\n private allSpans: Span[] = []\n private allEvents: TraceEvent[] = []\n private allArtifacts: Artifact[] = []\n private allBudget: BudgetLedgerEntry[] = []\n\n async appendRun(run: Run): Promise<void> {\n if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`)\n this.runs.set(run.runId, { ...run })\n }\n\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n const existing = this.runs.get(runId)\n if (!existing) throw new Error(`run ${runId} not found`)\n this.runs.set(runId, { ...existing, ...patch })\n }\n\n async appendSpan(span: Span): Promise<void> {\n this.allSpans.push({ ...span })\n }\n\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n const idx = this.allSpans.findIndex((s) => s.spanId === spanId)\n if (idx < 0) throw new Error(`span ${spanId} not found`)\n this.allSpans[idx] = { ...this.allSpans[idx], ...patch } as Span\n }\n\n async appendEvent(event: TraceEvent): Promise<void> {\n this.allEvents.push({ ...event })\n }\n\n async appendArtifact(artifact: Artifact): Promise<void> {\n this.allArtifacts.push({ ...artifact })\n }\n\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n this.allBudget.push({ ...entry })\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n const r = this.runs.get(runId)\n return r ? { ...r } : undefined\n }\n\n async listRuns(filter: RunFilter = {}): Promise<Run[]> {\n return [...this.runs.values()].filter((r) => matchesRun(r, filter))\n }\n\n async spans(filter: SpanFilter = {}): Promise<Span[]> {\n return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }))\n }\n\n async events(filter: EventFilter = {}): Promise<TraceEvent[]> {\n return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }))\n }\n\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }))\n }\n\n async artifacts(runId: string): Promise<Artifact[]> {\n return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }))\n }\n}\n\nfunction matchesRun(r: Run, f: RunFilter): boolean {\n if (f.scenarioId && r.scenarioId !== f.scenarioId) return false\n if (f.variantId && r.variantId !== f.variantId) return false\n if (f.status && r.status !== f.status) return false\n if (f.since !== undefined && r.startedAt < f.since) return false\n if (f.until !== undefined && r.startedAt > f.until) return false\n if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false\n if (f.parentRunId && r.parentRunId !== f.parentRunId) return false\n if (f.projectId && r.projectId !== f.projectId) return false\n if (f.chatId && r.chatId !== f.chatId) return false\n if (f.layer && r.layer !== f.layer) return false\n return true\n}\n\nfunction matchesSpan(s: Span, f: SpanFilter): boolean {\n if (f.runId && s.runId !== f.runId) return false\n if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false\n if (f.kind && s.kind !== f.kind) return false\n if (f.name && s.name !== f.name) return false\n if (f.toolName && (s.kind !== 'tool' || s.toolName !== f.toolName)) return false\n if (f.judgeId && (s.kind !== 'judge' || s.judgeId !== f.judgeId)) return false\n if (f.since !== undefined && s.startedAt < f.since) return false\n if (f.until !== undefined && s.startedAt > f.until) return false\n return true\n}\n\nfunction matchesEvent(e: TraceEvent, f: EventFilter): boolean {\n if (f.runId && e.runId !== f.runId) return false\n if (f.spanId && e.spanId !== f.spanId) return false\n if (f.kind && e.kind !== f.kind) return false\n if (f.since !== undefined && e.timestamp < f.since) return false\n if (f.until !== undefined && e.timestamp > f.until) return false\n return true\n}\n\n// ── Filesystem (NDJSON append-only, one file per entity) ─────────────\n\nexport interface FileSystemTraceStoreOptions {\n dir: string\n /** Roll over NDJSON files when they exceed this size in bytes. Default 32 MB. */\n maxBytes?: number\n}\n\nexport class FileSystemTraceStore implements TraceStore {\n private dir: string\n private maxBytes: number\n /** Lazy in-memory index for queries — populated on first read. */\n private index?: InMemoryTraceStore\n /** Memoized index build — concurrent first reads share one build, and an\n * append racing an in-flight load awaits this so its row isn't lost. */\n private indexPromise?: Promise<InMemoryTraceStore>\n /** Strictly-increasing rollover stamp. Date.now() alone collides when two\n * rollovers land in the same millisecond, overwriting a rolled file. */\n private lastRolloverStamp = 0\n /**\n * Per-file append serialization. stat → conditional-rename → appendFile is a\n * read-modify-write on the active file; without a lock two concurrent appends\n * to the same `name` can both pass the size check (exceeding maxBytes) or one\n * can append to a file the other just renamed away. Each entry chains the\n * next append behind the prior one for that file.\n */\n private appendLocks = new Map<string, Promise<void>>()\n\n constructor(options: FileSystemTraceStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: string, record: unknown): Promise<void> {\n // If an index load is in flight, wait for it. The row must hit disk AFTER\n // the load finished reading, so it lands in the completed index via the\n // mirror below — never lost in the gap before `this.index` is assigned.\n if (this.indexPromise) await this.indexPromise\n // Chain this append behind any in-flight append for the same file. The tail\n // promise never rejects (errors are isolated to each caller's `result`), so\n // one failed append can't break the lock chain for the next one.\n const prior = this.appendLocks.get(name) ?? Promise.resolve()\n const result = prior.then(() => this.appendLocked(name, record))\n const tail = result.then(\n () => {},\n () => {},\n )\n this.appendLocks.set(name, tail)\n try {\n await result\n } finally {\n // Drop the slot once this append is the current tail, so the map doesn't\n // grow without bound across many appends to the same file.\n if (this.appendLocks.get(name) === tail) this.appendLocks.delete(name)\n }\n }\n\n private async appendLocked(name: string, record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n // Strictly-increasing, collision-free even within one millisecond — a\n // bare Date.now() would let two same-ms rollovers overwrite each other.\n const stamp = Math.max(Date.now(), this.lastRolloverStamp + 1)\n this.lastRolloverStamp = stamp\n const rolled = path.join(this.dir, `${name}.${stamp}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n // Mirror genuinely-new rows into the lazy index. Update rows (marked\n // with `_update: true` by updateRun/updateSpan) are applied by those\n // methods directly via the index's update* APIs — re-inserting them\n // here triggers a duplicate-id error once the first read populates\n // the index. Await the mirror: a fire-and-forget would let an index\n // rejection go unhandled and let disk + index diverge silently.\n if (this.index && !(record as { _update?: boolean })?._update) {\n await this.insertInto(name, record)\n }\n }\n\n private async insertInto(name: string, record: unknown): Promise<void> {\n if (!this.index) return\n switch (name) {\n case 'runs':\n await this.index.appendRun(record as Run)\n break\n case 'spans':\n await this.index.appendSpan(record as Span)\n break\n case 'events':\n await this.index.appendEvent(record as TraceEvent)\n break\n case 'artifacts':\n await this.index.appendArtifact(record as Artifact)\n break\n case 'budget':\n await this.index.appendBudgetEntry(record as BudgetLedgerEntry)\n break\n }\n }\n\n private load(): Promise<InMemoryTraceStore> {\n // Memoize: concurrent first reads share one build, and an append racing an\n // in-flight load awaits this same promise (see append()).\n this.indexPromise ??= this.buildIndex()\n return this.indexPromise\n }\n\n private async buildIndex(): Promise<InMemoryTraceStore> {\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryTraceStore()\n let entries: string[]\n try {\n entries = await fs.readdir(this.dir)\n } catch {\n // No dir yet (first run / empty corpus). Anything past this point — parse\n // errors, missing patch bases — is real corruption and must fail loud.\n this.index = store\n return store\n }\n // Replay files in write order. For one entity, rolled files\n // (`name.<ts>.ndjson`) are older than the active bare file (`name.ndjson`),\n // and readdir order is not chronological — so without this sort a patch in\n // an older rolled file could be applied AFTER (overwrite) a newer patch in\n // the active file, silently restoring a stale field. Sort: per entity,\n // rolled ascending by timestamp, then the bare active file last.\n entries.sort((a, b) => {\n // Group by the same entity base the loop uses (`split('.')[0]`); within an\n // entity, real rollover files (`<base>.<ms>.ndjson`) sort by timestamp\n // ascending and the bare active file (no numeric segment) sorts last.\n // Non-rollover names tie (Infinity) and a stable sort preserves their\n // readdir order.\n const baseA = a.split('.')[0]!\n const baseB = b.split('.')[0]!\n if (baseA !== baseB) return baseA < baseB ? -1 : 1\n const ta = a.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tb = b.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tsA = ta ? Number(ta[1]) : Number.POSITIVE_INFINITY\n const tsB = tb ? Number(tb[1]) : Number.POSITIVE_INFINITY\n return tsA - tsB\n })\n {\n // Two-pass load. Pass 1 indexes all full (base) rows; pass 2 replays the\n // `_update` patch rows that updateRun/updateSpan append. readdir order is\n // not deterministic and rollover splits a stream across files, so a patch\n // can be read before its base. Applying patches in a separate pass — after\n // every base row is indexed — means a patch always finds its target.\n // Doing it in one pass let a patch hit the catch and append a runId-less\n // fragment, corrupting span/run counts cross-instance.\n const runUpdates: Array<Record<string, unknown>> = []\n const spanUpdates: Array<Record<string, unknown>> = []\n for (const file of entries) {\n if (!file.endsWith('.ndjson')) continue\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n const lines = content.split('\\n')\n for (let ln = 0; ln < lines.length; ln++) {\n const line = lines[ln]!\n if (!line.trim()) continue\n let record: ReturnType<typeof JSON.parse>\n try {\n record = JSON.parse(line)\n } catch (err) {\n // Fail loud WITH context — a bare SyntaxError loses which file/line\n // is corrupt and which valid rows surround it.\n throw new Error(\n `FileSystemTraceStore: corrupt NDJSON in ${file} line ${ln + 1}: ${\n err instanceof Error ? err.message : String(err)\n } — ${line.slice(0, 120)}`,\n )\n }\n if (base === 'runs') {\n if (record?._update) {\n runUpdates.push(record)\n continue\n }\n // A duplicate full row (same dir loaded twice into one stream) is\n // collapsed last-write-wins rather than thrown.\n try {\n await store.appendRun(record)\n } catch {\n await store.updateRun(record.runId, record)\n }\n } else if (base === 'spans') {\n // `updateSpan` appends an `_update: true` patch row instead of\n // rewriting the original span. Deferred to pass 2 so it collapses\n // onto the original span — otherwise a fresh FileSystemTraceStore\n // reading the same dir reports duplicate spans (one full, one\n // fragment with no runId/kind/name), which breaks any downstream\n // consumer that re-opens the store cross-process (e.g. the OTLP\n // converter).\n if (record?._update) {\n spanUpdates.push(record)\n continue\n }\n await store.appendSpan(record)\n } else if (base === 'events') {\n await store.appendEvent(record)\n } else if (base === 'artifacts') {\n await store.appendArtifact(record)\n } else if (base === 'budget') {\n await store.appendBudgetEntry(record)\n }\n }\n }\n // Pass 2: every base row is now indexed. A patch whose base is genuinely\n // absent (truncated/partial corpus) throws inside update* — we let it\n // propagate rather than silently appending a fragment, so a corrupt\n // corpus fails loud instead of polluting counts.\n for (const record of runUpdates) {\n await store.updateRun(record.runId as string, record as Partial<Run>)\n }\n for (const record of spanUpdates) {\n await store.updateSpan(record.spanId as string, record as Partial<Span>)\n }\n }\n this.index = store\n return store\n }\n\n async appendRun(run: Run): Promise<void> {\n await this.append('runs', run)\n }\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n // NDJSON is append-only; record updates as new rows with the same runId —\n // readers collapse by last-write-wins on load.\n await this.append('runs', { runId, ...patch, _update: true })\n if (this.index) await this.index.updateRun(runId, patch)\n }\n async appendSpan(span: Span): Promise<void> {\n await this.append('spans', span)\n }\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n await this.append('spans', { spanId, ...patch, _update: true })\n if (this.index) await this.index.updateSpan(spanId, patch)\n }\n async appendEvent(event: TraceEvent): Promise<void> {\n await this.append('events', event)\n }\n async appendArtifact(artifact: Artifact): Promise<void> {\n await this.append('artifacts', artifact)\n }\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n await this.append('budget', entry)\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n return (await this.load()).getRun(runId)\n }\n async listRuns(filter?: RunFilter): Promise<Run[]> {\n return (await this.load()).listRuns(filter)\n }\n async spans(filter?: SpanFilter): Promise<Span[]> {\n return (await this.load()).spans(filter)\n }\n async events(filter?: EventFilter): Promise<TraceEvent[]> {\n return (await this.load()).events(filter)\n }\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return (await this.load()).budget(runId)\n }\n async artifacts(runId: string): Promise<Artifact[]> {\n return (await this.load()).artifacts(runId)\n }\n}\n","/**\n * Run-completion integrity check — at end of run, verify the expected event\n * types were actually captured. The point is the launch-review failure mode:\n * a run *appears* successful but the raw provider events were never written,\n * so a downstream reviewer can't reconstruct what happened.\n *\n * Pattern:\n *\n * const report = await assertRunCaptured(store, runId, {\n * llmSpansMin: 1,\n * judgeSpansMin: 1,\n * rawSink: providerSink, // must have ≥ 1 event for this run\n * requireRawCoverageOfLlmSpans: true, // every llm span has matching raw events\n * })\n * if (!report.ok) throwIfRunIncomplete(report) // or mark run failed and continue\n *\n * The function is read-only on the store and returns a structured report;\n * the caller chooses the failure mode (throw, mark run failed, log warning).\n * `throwIfRunIncomplete` is the convenient strict mode.\n */\n\nimport { CaptureIntegrityError } from '../errors'\nimport type { RawProviderSink } from './raw-provider-sink'\nimport type { TraceStore } from './store'\n\nexport interface RunIntegrityExpectations {\n /** Minimum LLM span count. Default 0 (no requirement). */\n llmSpansMin?: number\n /** Minimum judge span count. Default 0. */\n judgeSpansMin?: number\n /** Minimum tool span count. Default 0. */\n toolSpansMin?: number\n /**\n * Raw provider sink to consult for capture verification. When present,\n * the check requires at least one raw event for the run.\n */\n rawSink?: RawProviderSink\n /** Minimum raw provider event count. Default 0; ignored when `rawSink` absent. */\n rawProviderEventsMin?: number\n /**\n * Every LLM span must have at least one matching raw `request` event\n * (matched by spanId). Catches the common bug where the structured span\n * was emitted but the raw HTTP capture was wired to a different sink.\n */\n requireRawCoverageOfLlmSpans?: boolean\n /** Run outcome must be set (not null/undefined). Default false. */\n requireOutcome?: boolean\n}\n\nexport type RunIntegrityIssueCode =\n | 'no_run'\n | 'missing_llm_spans'\n | 'missing_judge_spans'\n | 'missing_tool_spans'\n | 'missing_raw_events'\n | 'no_raw_sink'\n | 'orphan_llm_span'\n | 'missing_outcome'\n\nexport interface RunIntegrityIssue {\n code: RunIntegrityIssueCode\n message: string\n detail?: Record<string, unknown>\n}\n\nexport interface RunIntegrityReport {\n ok: boolean\n runId: string\n llmSpanCount: number\n judgeSpanCount: number\n toolSpanCount: number\n rawProviderEventCount: number\n /**\n * Coverage of LLM spans by raw provider events keyed on spanId.\n * `total` is the number of LLM spans; `covered` is the count with at\n * least one matching `request` raw event.\n */\n rawSpanCoverage: { covered: number; total: number }\n issues: RunIntegrityIssue[]\n}\n\nexport class RunIntegrityError extends CaptureIntegrityError {\n constructor(public readonly report: RunIntegrityReport) {\n super(\n `Run ${report.runId} failed integrity check: ${report.issues.map((i) => i.code).join(', ')}`,\n )\n }\n}\n\nexport async function assertRunCaptured(\n store: TraceStore,\n runId: string,\n expectations: RunIntegrityExpectations = {},\n): Promise<RunIntegrityReport> {\n const issues: RunIntegrityIssue[] = []\n const run = await store.getRun(runId)\n if (!run) {\n return {\n ok: false,\n runId,\n llmSpanCount: 0,\n judgeSpanCount: 0,\n toolSpanCount: 0,\n rawProviderEventCount: 0,\n rawSpanCoverage: { covered: 0, total: 0 },\n issues: [{ code: 'no_run', message: `Run ${runId} not found in store.` }],\n }\n }\n\n const spans = await store.spans({ runId })\n const llmSpans = spans.filter((s) => s.kind === 'llm')\n const judgeSpans = spans.filter((s) => s.kind === 'judge')\n const toolSpans = spans.filter((s) => s.kind === 'tool')\n\n const llmMin = expectations.llmSpansMin ?? 0\n const judgeMin = expectations.judgeSpansMin ?? 0\n const toolMin = expectations.toolSpansMin ?? 0\n\n if (llmSpans.length < llmMin) {\n issues.push({\n code: 'missing_llm_spans',\n message: `Expected ≥ ${llmMin} LLM spans, found ${llmSpans.length}.`,\n detail: { expected: llmMin, found: llmSpans.length },\n })\n }\n if (judgeSpans.length < judgeMin) {\n issues.push({\n code: 'missing_judge_spans',\n message: `Expected ≥ ${judgeMin} judge spans, found ${judgeSpans.length}.`,\n detail: { expected: judgeMin, found: judgeSpans.length },\n })\n }\n if (toolSpans.length < toolMin) {\n issues.push({\n code: 'missing_tool_spans',\n message: `Expected ≥ ${toolMin} tool spans, found ${toolSpans.length}.`,\n detail: { expected: toolMin, found: toolSpans.length },\n })\n }\n\n let rawEventCount = 0\n let coverage = { covered: 0, total: llmSpans.length }\n\n if (expectations.rawSink) {\n if (!expectations.rawSink.list) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Provided rawSink does not implement list(); cannot verify capture.',\n })\n } else {\n const events = await expectations.rawSink.list({ runId })\n rawEventCount = events.length\n const rawMin = expectations.rawProviderEventsMin ?? 1\n if (rawEventCount < rawMin) {\n issues.push({\n code: 'missing_raw_events',\n message: `Expected ≥ ${rawMin} raw provider events, found ${rawEventCount}.`,\n detail: { expected: rawMin, found: rawEventCount },\n })\n }\n if (expectations.requireRawCoverageOfLlmSpans) {\n const requestEventsBySpan = new Set(\n events.filter((e) => e.direction === 'request' && e.spanId).map((e) => e.spanId!),\n )\n const orphaned = llmSpans.filter((s) => !requestEventsBySpan.has(s.spanId))\n coverage = { covered: llmSpans.length - orphaned.length, total: llmSpans.length }\n if (orphaned.length > 0) {\n issues.push({\n code: 'orphan_llm_span',\n message: `${orphaned.length} LLM span(s) have no matching raw provider request event.`,\n detail: { orphanedSpanIds: orphaned.map((s) => s.spanId) },\n })\n }\n }\n }\n } else if (expectations.requireRawCoverageOfLlmSpans || expectations.rawProviderEventsMin) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Raw coverage required but no rawSink supplied to the integrity check.',\n })\n }\n\n if (expectations.requireOutcome && (run.outcome === undefined || run.outcome === null)) {\n issues.push({\n code: 'missing_outcome',\n message: `Run ${runId} has no outcome recorded.`,\n })\n }\n\n return {\n ok: issues.length === 0,\n runId,\n llmSpanCount: llmSpans.length,\n judgeSpanCount: judgeSpans.length,\n toolSpanCount: toolSpans.length,\n rawProviderEventCount: rawEventCount,\n rawSpanCoverage: coverage,\n issues,\n }\n}\n\n/** Strict mode: throws `RunIntegrityError` when the report isn't ok. */\nexport function throwIfRunIncomplete(report: RunIntegrityReport): void {\n if (!report.ok) throw new RunIntegrityError(report)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"integrity-fdt8XPAv.js","names":[],"sources":["../src/trace/store.ts","../src/trace/integrity.ts"],"sourcesContent":["/**\n * TraceStore — persistence + query over the TraceSchema v1 corpus.\n *\n * Two implementations ship in the core:\n * - InMemoryTraceStore: dev + tests, fully in-process\n * - FileSystemTraceStore: NDJSON append-only files per entity, suitable\n * for long-running CI jobs; rolled over at 32MB\n *\n * Downstream adapters (DuckDB, Langfuse, R2 parquet) implement this same\n * interface — the rest of the framework is storage-agnostic.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n Run,\n RunStatus,\n Span,\n SpanKind,\n TraceEvent,\n} from './schema'\n\nexport interface RunFilter {\n scenarioId?: string\n variantId?: string\n status?: RunStatus\n since?: number\n until?: number\n tag?: { key: string; value: string }\n parentRunId?: string\n projectId?: string\n chatId?: string\n layer?: import('./schema').RunLayer\n}\n\nexport interface SpanFilter {\n runId?: string\n parentSpanId?: string\n kind?: SpanKind\n name?: string\n toolName?: string\n judgeId?: string\n since?: number\n until?: number\n}\n\nexport interface EventFilter {\n runId?: string\n spanId?: string\n kind?: EventKind\n since?: number\n until?: number\n}\n\nexport interface TraceStore {\n appendRun(run: Run): Promise<void>\n updateRun(runId: string, patch: Partial<Run>): Promise<void>\n appendSpan(span: Span): Promise<void>\n updateSpan(spanId: string, patch: Partial<Span>): Promise<void>\n appendEvent(event: TraceEvent): Promise<void>\n appendArtifact(artifact: Artifact): Promise<void>\n appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void>\n\n getRun(runId: string): Promise<Run | undefined>\n listRuns(filter?: RunFilter): Promise<Run[]>\n spans(filter?: SpanFilter): Promise<Span[]>\n events(filter?: EventFilter): Promise<TraceEvent[]>\n budget(runId: string): Promise<BudgetLedgerEntry[]>\n artifacts(runId: string): Promise<Artifact[]>\n}\n\n// ── In-memory ────────────────────────────────────────────────────────\n\nexport class InMemoryTraceStore implements TraceStore {\n private runs = new Map<string, Run>()\n private allSpans: Span[] = []\n private allEvents: TraceEvent[] = []\n private allArtifacts: Artifact[] = []\n private allBudget: BudgetLedgerEntry[] = []\n\n async appendRun(run: Run): Promise<void> {\n if (this.runs.has(run.runId)) throw new Error(`run ${run.runId} already exists`)\n this.runs.set(run.runId, { ...run })\n }\n\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n const existing = this.runs.get(runId)\n if (!existing) throw new Error(`run ${runId} not found`)\n this.runs.set(runId, { ...existing, ...patch })\n }\n\n async appendSpan(span: Span): Promise<void> {\n this.allSpans.push({ ...span })\n }\n\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n const idx = this.allSpans.findIndex((s) => s.spanId === spanId)\n if (idx < 0) throw new Error(`span ${spanId} not found`)\n this.allSpans[idx] = { ...this.allSpans[idx], ...patch } as Span\n }\n\n async appendEvent(event: TraceEvent): Promise<void> {\n this.allEvents.push({ ...event })\n }\n\n async appendArtifact(artifact: Artifact): Promise<void> {\n this.allArtifacts.push({ ...artifact })\n }\n\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n this.allBudget.push({ ...entry })\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n const r = this.runs.get(runId)\n return r ? { ...r } : undefined\n }\n\n async listRuns(filter: RunFilter = {}): Promise<Run[]> {\n return [...this.runs.values()].filter((r) => matchesRun(r, filter))\n }\n\n async spans(filter: SpanFilter = {}): Promise<Span[]> {\n return this.allSpans.filter((s) => matchesSpan(s, filter)).map((s) => ({ ...s }))\n }\n\n async events(filter: EventFilter = {}): Promise<TraceEvent[]> {\n return this.allEvents.filter((e) => matchesEvent(e, filter)).map((e) => ({ ...e }))\n }\n\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return this.allBudget.filter((b) => b.runId === runId).map((b) => ({ ...b }))\n }\n\n async artifacts(runId: string): Promise<Artifact[]> {\n return this.allArtifacts.filter((a) => a.runId === runId).map((a) => ({ ...a }))\n }\n}\n\nfunction matchesRun(r: Run, f: RunFilter): boolean {\n if (f.scenarioId && r.scenarioId !== f.scenarioId) return false\n if (f.variantId && r.variantId !== f.variantId) return false\n if (f.status && r.status !== f.status) return false\n if (f.since !== undefined && r.startedAt < f.since) return false\n if (f.until !== undefined && r.startedAt > f.until) return false\n if (f.tag && r.tags?.[f.tag.key] !== f.tag.value) return false\n if (f.parentRunId && r.parentRunId !== f.parentRunId) return false\n if (f.projectId && r.projectId !== f.projectId) return false\n if (f.chatId && r.chatId !== f.chatId) return false\n if (f.layer && r.layer !== f.layer) return false\n return true\n}\n\nfunction matchesSpan(s: Span, f: SpanFilter): boolean {\n if (f.runId && s.runId !== f.runId) return false\n if (f.parentSpanId && s.parentSpanId !== f.parentSpanId) return false\n if (f.kind && s.kind !== f.kind) return false\n if (f.name && s.name !== f.name) return false\n if (f.toolName && (s.kind !== 'tool' || s.toolName !== f.toolName)) return false\n if (f.judgeId && (s.kind !== 'judge' || s.judgeId !== f.judgeId)) return false\n if (f.since !== undefined && s.startedAt < f.since) return false\n if (f.until !== undefined && s.startedAt > f.until) return false\n return true\n}\n\nfunction matchesEvent(e: TraceEvent, f: EventFilter): boolean {\n if (f.runId && e.runId !== f.runId) return false\n if (f.spanId && e.spanId !== f.spanId) return false\n if (f.kind && e.kind !== f.kind) return false\n if (f.since !== undefined && e.timestamp < f.since) return false\n if (f.until !== undefined && e.timestamp > f.until) return false\n return true\n}\n\n// ── Filesystem (NDJSON append-only, one file per entity) ─────────────\n\nexport interface FileSystemTraceStoreOptions {\n dir: string\n /** Roll over NDJSON files when they exceed this size in bytes. Default 32 MB. */\n maxBytes?: number\n}\n\nexport class FileSystemTraceStore implements TraceStore {\n private dir: string\n private maxBytes: number\n /** Lazy in-memory index for queries — populated on first read. */\n private index?: InMemoryTraceStore\n /** Memoized index build — concurrent first reads share one build, and an\n * append racing an in-flight load awaits this so its row isn't lost. */\n private indexPromise?: Promise<InMemoryTraceStore>\n /** Strictly-increasing rollover stamp. Date.now() alone collides when two\n * rollovers land in the same millisecond, overwriting a rolled file. */\n private lastRolloverStamp = 0\n /**\n * Per-file append serialization. stat → conditional-rename → appendFile is a\n * read-modify-write on the active file; without a lock two concurrent appends\n * to the same `name` can both pass the size check (exceeding maxBytes) or one\n * can append to a file the other just renamed away. Each entry chains the\n * next append behind the prior one for that file.\n */\n private appendLocks = new Map<string, Promise<void>>()\n\n constructor(options: FileSystemTraceStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: string, record: unknown): Promise<void> {\n // If an index load is in flight, wait for it. The row must hit disk AFTER\n // the load finished reading, so it lands in the completed index via the\n // mirror below — never lost in the gap before `this.index` is assigned.\n if (this.indexPromise) await this.indexPromise\n // Chain this append behind any in-flight append for the same file. The tail\n // promise never rejects (errors are isolated to each caller's `result`), so\n // one failed append can't break the lock chain for the next one.\n const prior = this.appendLocks.get(name) ?? Promise.resolve()\n const result = prior.then(() => this.appendLocked(name, record))\n const tail = result.then(\n () => {},\n () => {},\n )\n this.appendLocks.set(name, tail)\n try {\n await result\n } finally {\n // Drop the slot once this append is the current tail, so the map doesn't\n // grow without bound across many appends to the same file.\n if (this.appendLocks.get(name) === tail) this.appendLocks.delete(name)\n }\n }\n\n private async appendLocked(name: string, record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n // Strictly-increasing, collision-free even within one millisecond — a\n // bare Date.now() would let two same-ms rollovers overwrite each other.\n const stamp = Math.max(Date.now(), this.lastRolloverStamp + 1)\n this.lastRolloverStamp = stamp\n const rolled = path.join(this.dir, `${name}.${stamp}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n // Mirror genuinely-new rows into the lazy index. Update rows (marked\n // with `_update: true` by updateRun/updateSpan) are applied by those\n // methods directly via the index's update* APIs — re-inserting them\n // here triggers a duplicate-id error once the first read populates\n // the index. Await the mirror: a fire-and-forget would let an index\n // rejection go unhandled and let disk + index diverge silently.\n if (this.index && !(record as { _update?: boolean })?._update) {\n await this.insertInto(name, record)\n }\n }\n\n private async insertInto(name: string, record: unknown): Promise<void> {\n if (!this.index) return\n switch (name) {\n case 'runs':\n await this.index.appendRun(record as Run)\n break\n case 'spans':\n await this.index.appendSpan(record as Span)\n break\n case 'events':\n await this.index.appendEvent(record as TraceEvent)\n break\n case 'artifacts':\n await this.index.appendArtifact(record as Artifact)\n break\n case 'budget':\n await this.index.appendBudgetEntry(record as BudgetLedgerEntry)\n break\n }\n }\n\n private load(): Promise<InMemoryTraceStore> {\n // Memoize: concurrent first reads share one build, and an append racing an\n // in-flight load awaits this same promise (see append()).\n this.indexPromise ??= this.buildIndex()\n return this.indexPromise\n }\n\n private async buildIndex(): Promise<InMemoryTraceStore> {\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryTraceStore()\n let entries: string[]\n try {\n entries = await fs.readdir(this.dir)\n } catch {\n // No dir yet (first run / empty corpus). Anything past this point — parse\n // errors, missing patch bases — is real corruption and must fail loud.\n this.index = store\n return store\n }\n // Replay files in write order. For one entity, rolled files\n // (`name.<ts>.ndjson`) are older than the active bare file (`name.ndjson`),\n // and readdir order is not chronological — so without this sort a patch in\n // an older rolled file could be applied AFTER (overwrite) a newer patch in\n // the active file, silently restoring a stale field. Sort: per entity,\n // rolled ascending by timestamp, then the bare active file last.\n entries.sort((a, b) => {\n // Group by the same entity base the loop uses (`split('.')[0]`); within an\n // entity, real rollover files (`<base>.<ms>.ndjson`) sort by timestamp\n // ascending and the bare active file (no numeric segment) sorts last.\n // Non-rollover names tie (Infinity) and a stable sort preserves their\n // readdir order.\n const baseA = a.split('.')[0]!\n const baseB = b.split('.')[0]!\n if (baseA !== baseB) return baseA < baseB ? -1 : 1\n const ta = a.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tb = b.match(/^[^.]+\\.(\\d+)\\.ndjson$/)\n const tsA = ta ? Number(ta[1]) : Number.POSITIVE_INFINITY\n const tsB = tb ? Number(tb[1]) : Number.POSITIVE_INFINITY\n return tsA - tsB\n })\n {\n // Two-pass load. Pass 1 indexes all full (base) rows; pass 2 replays the\n // `_update` patch rows that updateRun/updateSpan append. readdir order is\n // not deterministic and rollover splits a stream across files, so a patch\n // can be read before its base. Applying patches in a separate pass — after\n // every base row is indexed — means a patch always finds its target.\n // Doing it in one pass let a patch hit the catch and append a runId-less\n // fragment, corrupting span/run counts cross-instance.\n const runUpdates: Array<Record<string, unknown>> = []\n const spanUpdates: Array<Record<string, unknown>> = []\n for (const file of entries) {\n if (!file.endsWith('.ndjson')) continue\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n const lines = content.split('\\n')\n for (let ln = 0; ln < lines.length; ln++) {\n const line = lines[ln]!\n if (!line.trim()) continue\n let record: ReturnType<typeof JSON.parse>\n try {\n record = JSON.parse(line)\n } catch (err) {\n // Fail loud WITH context — a bare SyntaxError loses which file/line\n // is corrupt and which valid rows surround it.\n throw new Error(\n `FileSystemTraceStore: corrupt NDJSON in ${file} line ${ln + 1}: ${\n err instanceof Error ? err.message : String(err)\n } — ${line.slice(0, 120)}`,\n )\n }\n if (base === 'runs') {\n if (record?._update) {\n runUpdates.push(record)\n continue\n }\n // A duplicate full row (same dir loaded twice into one stream) is\n // collapsed last-write-wins rather than thrown.\n try {\n await store.appendRun(record)\n } catch {\n await store.updateRun(record.runId, record)\n }\n } else if (base === 'spans') {\n // `updateSpan` appends an `_update: true` patch row instead of\n // rewriting the original span. Deferred to pass 2 so it collapses\n // onto the original span — otherwise a fresh FileSystemTraceStore\n // reading the same dir reports duplicate spans (one full, one\n // fragment with no runId/kind/name), which breaks any downstream\n // consumer that re-opens the store cross-process (e.g. the OTLP\n // converter).\n if (record?._update) {\n spanUpdates.push(record)\n continue\n }\n await store.appendSpan(record)\n } else if (base === 'events') {\n await store.appendEvent(record)\n } else if (base === 'artifacts') {\n await store.appendArtifact(record)\n } else if (base === 'budget') {\n await store.appendBudgetEntry(record)\n }\n }\n }\n // Pass 2: every base row is now indexed. A patch whose base is genuinely\n // absent (truncated/partial corpus) throws inside update* — we let it\n // propagate rather than silently appending a fragment, so a corrupt\n // corpus fails loud instead of polluting counts.\n for (const record of runUpdates) {\n await store.updateRun(record.runId as string, record as Partial<Run>)\n }\n for (const record of spanUpdates) {\n await store.updateSpan(record.spanId as string, record as Partial<Span>)\n }\n }\n this.index = store\n return store\n }\n\n async appendRun(run: Run): Promise<void> {\n await this.append('runs', run)\n }\n async updateRun(runId: string, patch: Partial<Run>): Promise<void> {\n // NDJSON is append-only; record updates as new rows with the same runId —\n // readers collapse by last-write-wins on load.\n await this.append('runs', { runId, ...patch, _update: true })\n if (this.index) await this.index.updateRun(runId, patch)\n }\n async appendSpan(span: Span): Promise<void> {\n await this.append('spans', span)\n }\n async updateSpan(spanId: string, patch: Partial<Span>): Promise<void> {\n await this.append('spans', { spanId, ...patch, _update: true })\n if (this.index) await this.index.updateSpan(spanId, patch)\n }\n async appendEvent(event: TraceEvent): Promise<void> {\n await this.append('events', event)\n }\n async appendArtifact(artifact: Artifact): Promise<void> {\n await this.append('artifacts', artifact)\n }\n async appendBudgetEntry(entry: BudgetLedgerEntry): Promise<void> {\n await this.append('budget', entry)\n }\n\n async getRun(runId: string): Promise<Run | undefined> {\n return (await this.load()).getRun(runId)\n }\n async listRuns(filter?: RunFilter): Promise<Run[]> {\n return (await this.load()).listRuns(filter)\n }\n async spans(filter?: SpanFilter): Promise<Span[]> {\n return (await this.load()).spans(filter)\n }\n async events(filter?: EventFilter): Promise<TraceEvent[]> {\n return (await this.load()).events(filter)\n }\n async budget(runId: string): Promise<BudgetLedgerEntry[]> {\n return (await this.load()).budget(runId)\n }\n async artifacts(runId: string): Promise<Artifact[]> {\n return (await this.load()).artifacts(runId)\n }\n}\n","/**\n * Run-completion integrity check — at end of run, verify the expected event\n * types were actually captured. The point is the launch-review failure mode:\n * a run *appears* successful but the raw provider events were never written,\n * so a downstream reviewer can't reconstruct what happened.\n *\n * Pattern:\n *\n * const report = await assertRunCaptured(store, runId, {\n * llmSpansMin: 1,\n * judgeSpansMin: 1,\n * rawSink: providerSink, // must have ≥ 1 event for this run\n * requireRawCoverageOfLlmSpans: true, // every llm span has matching raw events\n * })\n * if (!report.ok) throwIfRunIncomplete(report) // or mark run failed and continue\n *\n * The function is read-only on the store and returns a structured report;\n * the caller chooses the failure mode (throw, mark run failed, log warning).\n * `throwIfRunIncomplete` is the convenient strict mode.\n */\n\nimport { CaptureIntegrityError } from '../errors'\nimport type { RawProviderSink } from './raw-provider-sink'\nimport type { TraceStore } from './store'\n\nexport interface RunIntegrityExpectations {\n /** Minimum LLM span count. Default 0 (no requirement). */\n llmSpansMin?: number\n /** Minimum judge span count. Default 0. */\n judgeSpansMin?: number\n /** Minimum tool span count. Default 0. */\n toolSpansMin?: number\n /**\n * Raw provider sink to consult for capture verification. When present,\n * the check requires at least one raw event for the run.\n */\n rawSink?: RawProviderSink\n /** Minimum raw provider event count. Default 0; ignored when `rawSink` absent. */\n rawProviderEventsMin?: number\n /**\n * Every LLM span must have at least one matching raw `request` event\n * (matched by spanId). Catches the common bug where the structured span\n * was emitted but the raw HTTP capture was wired to a different sink.\n */\n requireRawCoverageOfLlmSpans?: boolean\n /** Run outcome must be set (not null/undefined). Default false. */\n requireOutcome?: boolean\n}\n\nexport type RunIntegrityIssueCode =\n | 'no_run'\n | 'missing_llm_spans'\n | 'missing_judge_spans'\n | 'missing_tool_spans'\n | 'missing_raw_events'\n | 'no_raw_sink'\n | 'orphan_llm_span'\n | 'missing_outcome'\n\nexport interface RunIntegrityIssue {\n code: RunIntegrityIssueCode\n message: string\n detail?: Record<string, unknown>\n}\n\nexport interface RunIntegrityReport {\n ok: boolean\n runId: string\n llmSpanCount: number\n judgeSpanCount: number\n toolSpanCount: number\n rawProviderEventCount: number\n /**\n * Coverage of LLM spans by raw provider events keyed on spanId.\n * `total` is the number of LLM spans; `covered` is the count with at\n * least one matching `request` raw event.\n */\n rawSpanCoverage: { covered: number; total: number }\n issues: RunIntegrityIssue[]\n}\n\nexport class RunIntegrityError extends CaptureIntegrityError {\n constructor(public readonly report: RunIntegrityReport) {\n super(\n `Run ${report.runId} failed integrity check: ${report.issues.map((i) => i.code).join(', ')}`,\n )\n }\n}\n\nexport async function assertRunCaptured(\n store: TraceStore,\n runId: string,\n expectations: RunIntegrityExpectations = {},\n): Promise<RunIntegrityReport> {\n const issues: RunIntegrityIssue[] = []\n const run = await store.getRun(runId)\n if (!run) {\n return {\n ok: false,\n runId,\n llmSpanCount: 0,\n judgeSpanCount: 0,\n toolSpanCount: 0,\n rawProviderEventCount: 0,\n rawSpanCoverage: { covered: 0, total: 0 },\n issues: [{ code: 'no_run', message: `Run ${runId} not found in store.` }],\n }\n }\n\n const spans = await store.spans({ runId })\n const llmSpans = spans.filter((s) => s.kind === 'llm')\n const judgeSpans = spans.filter((s) => s.kind === 'judge')\n const toolSpans = spans.filter((s) => s.kind === 'tool')\n\n const llmMin = expectations.llmSpansMin ?? 0\n const judgeMin = expectations.judgeSpansMin ?? 0\n const toolMin = expectations.toolSpansMin ?? 0\n\n if (llmSpans.length < llmMin) {\n issues.push({\n code: 'missing_llm_spans',\n message: `Expected ≥ ${llmMin} LLM spans, found ${llmSpans.length}.`,\n detail: { expected: llmMin, found: llmSpans.length },\n })\n }\n if (judgeSpans.length < judgeMin) {\n issues.push({\n code: 'missing_judge_spans',\n message: `Expected ≥ ${judgeMin} judge spans, found ${judgeSpans.length}.`,\n detail: { expected: judgeMin, found: judgeSpans.length },\n })\n }\n if (toolSpans.length < toolMin) {\n issues.push({\n code: 'missing_tool_spans',\n message: `Expected ≥ ${toolMin} tool spans, found ${toolSpans.length}.`,\n detail: { expected: toolMin, found: toolSpans.length },\n })\n }\n\n let rawEventCount = 0\n let coverage = { covered: 0, total: llmSpans.length }\n\n if (expectations.rawSink) {\n if (!expectations.rawSink.list) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Provided rawSink does not implement list(); cannot verify capture.',\n })\n } else {\n const events = await expectations.rawSink.list({ runId })\n rawEventCount = events.length\n const rawMin = expectations.rawProviderEventsMin ?? 1\n if (rawEventCount < rawMin) {\n issues.push({\n code: 'missing_raw_events',\n message: `Expected ≥ ${rawMin} raw provider events, found ${rawEventCount}.`,\n detail: { expected: rawMin, found: rawEventCount },\n })\n }\n if (expectations.requireRawCoverageOfLlmSpans) {\n const requestEventsBySpan = new Set(\n events.filter((e) => e.direction === 'request' && e.spanId).map((e) => e.spanId!),\n )\n const orphaned = llmSpans.filter((s) => !requestEventsBySpan.has(s.spanId))\n coverage = { covered: llmSpans.length - orphaned.length, total: llmSpans.length }\n if (orphaned.length > 0) {\n issues.push({\n code: 'orphan_llm_span',\n message: `${orphaned.length} LLM span(s) have no matching raw provider request event.`,\n detail: { orphanedSpanIds: orphaned.map((s) => s.spanId) },\n })\n }\n }\n }\n } else if (expectations.requireRawCoverageOfLlmSpans || expectations.rawProviderEventsMin) {\n issues.push({\n code: 'no_raw_sink',\n message: 'Raw coverage required but no rawSink supplied to the integrity check.',\n })\n }\n\n if (expectations.requireOutcome && (run.outcome === undefined || run.outcome === null)) {\n issues.push({\n code: 'missing_outcome',\n message: `Run ${runId} has no outcome recorded.`,\n })\n }\n\n return {\n ok: issues.length === 0,\n runId,\n llmSpanCount: llmSpans.length,\n judgeSpanCount: judgeSpans.length,\n toolSpanCount: toolSpans.length,\n rawProviderEventCount: rawEventCount,\n rawSpanCoverage: coverage,\n issues,\n }\n}\n\n/** Strict mode: throws `RunIntegrityError` when the report isn't ok. */\nexport function throwIfRunIncomplete(report: RunIntegrityReport): void {\n if (!report.ok) throw new RunIntegrityError(report)\n}\n"],"mappings":";;AA0EA,IAAa,qBAAb,MAAsD;CACpD,uBAAe,IAAI,IAAiB;CACpC,WAA2B,CAAC;CAC5B,YAAkC,CAAC;CACnC,eAAmC,CAAC;CACpC,YAAyC,CAAC;CAE1C,MAAM,UAAU,KAAyB;EACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,IAAI,MAAM,OAAO,IAAI,MAAM,gBAAgB;EAC/E,KAAK,KAAK,IAAI,IAAI,OAAO,EAAE,GAAG,IAAI,CAAC;CACrC;CAEA,MAAM,UAAU,OAAe,OAAoC;EACjE,MAAM,WAAW,KAAK,KAAK,IAAI,KAAK;EACpC,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,OAAO,MAAM,WAAW;EACvD,KAAK,KAAK,IAAI,OAAO;GAAE,GAAG;GAAU,GAAG;EAAM,CAAC;CAChD;CAEA,MAAM,WAAW,MAA2B;EAC1C,KAAK,SAAS,KAAK,EAAE,GAAG,KAAK,CAAC;CAChC;CAEA,MAAM,WAAW,QAAgB,OAAqC;EACpE,MAAM,MAAM,KAAK,SAAS,WAAW,MAAM,EAAE,WAAW,MAAM;EAC9D,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,QAAQ,OAAO,WAAW;EACvD,KAAK,SAAS,OAAO;GAAE,GAAG,KAAK,SAAS;GAAM,GAAG;EAAM;CACzD;CAEA,MAAM,YAAY,OAAkC;EAClD,KAAK,UAAU,KAAK,EAAE,GAAG,MAAM,CAAC;CAClC;CAEA,MAAM,eAAe,UAAmC;EACtD,KAAK,aAAa,KAAK,EAAE,GAAG,SAAS,CAAC;CACxC;CAEA,MAAM,kBAAkB,OAAyC;EAC/D,KAAK,UAAU,KAAK,EAAE,GAAG,MAAM,CAAC;CAClC;CAEA,MAAM,OAAO,OAAyC;EACpD,MAAM,IAAI,KAAK,KAAK,IAAI,KAAK;EAC7B,OAAO,IAAI,EAAE,GAAG,EAAE,IAAI,KAAA;CACxB;CAEA,MAAM,SAAS,SAAoB,CAAC,GAAmB;EACrD,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,WAAW,GAAG,MAAM,CAAC;CACpE;CAEA,MAAM,MAAM,SAAqB,CAAC,GAAoB;EACpD,OAAO,KAAK,SAAS,QAAQ,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,GAAG,EAAE,EAAE;CAClF;CAEA,MAAM,OAAO,SAAsB,CAAC,GAA0B;EAC5D,OAAO,KAAK,UAAU,QAAQ,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,GAAG,EAAE,EAAE;CACpF;CAEA,MAAM,OAAO,OAA6C;EACxD,OAAO,KAAK,UAAU,QAAQ,MAAM,EAAE,UAAU,KAAK,CAAC,CAAC,KAAK,OAAO,EAAE,GAAG,EAAE,EAAE;CAC9E;CAEA,MAAM,UAAU,OAAoC;EAClD,OAAO,KAAK,aAAa,QAAQ,MAAM,EAAE,UAAU,KAAK,CAAC,CAAC,KAAK,OAAO,EAAE,GAAG,EAAE,EAAE;CACjF;AACF;AAEA,SAAS,WAAW,GAAQ,GAAuB;CACjD,IAAI,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,OAAO;CAC1D,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,OAAO;CACvD,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,OAAO;CAC9C,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,SAAS,EAAE,IAAI,OAAO,OAAO;CACzD,IAAI,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,OAAO;CAC7D,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,OAAO;CACvD,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,OAAO;CAC9C,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,OAAO;CAC3C,OAAO;AACT;AAEA,SAAS,YAAY,GAAS,GAAwB;CACpD,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,OAAO;CAC3C,IAAI,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,OAAO;CAChE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO;CACxC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO;CACxC,IAAI,EAAE,aAAa,EAAE,SAAS,UAAU,EAAE,aAAa,EAAE,WAAW,OAAO;CAC3E,IAAI,EAAE,YAAY,EAAE,SAAS,WAAW,EAAE,YAAY,EAAE,UAAU,OAAO;CACzE,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,OAAO;AACT;AAEA,SAAS,aAAa,GAAe,GAAyB;CAC5D,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,OAAO;CAC3C,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,OAAO;CAC9C,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO;CACxC,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,IAAI,EAAE,UAAU,KAAA,KAAa,EAAE,YAAY,EAAE,OAAO,OAAO;CAC3D,OAAO;AACT;AAUA,IAAa,uBAAb,MAAwD;CACtD;CACA;;CAEA;;;CAGA;;;CAGA,oBAA4B;;;;;;;;CAQ5B,8BAAsB,IAAI,IAA2B;CAErD,YAAY,SAAsC;EAChD,KAAK,MAAM,QAAQ;EACnB,KAAK,WAAW,QAAQ,YAAY,KAAK,OAAO;CAClD;CAEA,MAAc,YAA2B;EAEvC,OAAM,MADW,OAAO,oBAAA,CACf,MAAM,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC;CAC9C;CAEA,MAAc,OAAO,MAAc,QAAgC;EAIjE,IAAI,KAAK,cAAc,MAAM,KAAK;EAKlC,MAAM,UADQ,KAAK,YAAY,IAAI,IAAI,KAAK,QAAQ,QAAQ,EAAA,CACvC,WAAW,KAAK,aAAa,MAAM,MAAM,CAAC;EAC/D,MAAM,OAAO,OAAO,WACZ,CAAC,SACD,CAAC,CACT;EACA,KAAK,YAAY,IAAI,MAAM,IAAI;EAC/B,IAAI;GACF,MAAM;EACR,UAAU;GAGR,IAAI,KAAK,YAAY,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,OAAO,IAAI;EACvE;CACF;CAEA,MAAc,aAAa,MAAc,QAAgC;EACvE,MAAM,KAAK,UAAU;EACrB,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,OAAO,MAAM,OAAO;EAC1B,MAAM,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,QAAQ;EACnD,IAAI;GAEF,KAAI,MADe,GAAG,KAAK,MAAM,EAAA,CACxB,QAAQ,KAAK,UAAU;IAG9B,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,oBAAoB,CAAC;IAC7D,KAAK,oBAAoB;IACzB,MAAM,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,MAAM,QAAQ;IAC5D,MAAM,GAAG,OAAO,QAAQ,MAAM;GAChC;EACF,QAAQ,CAER;EACA,MAAM,GAAG,WAAW,QAAQ,GAAG,KAAK,UAAU,MAAM,EAAE,KAAK,MAAM;EAOjE,IAAI,KAAK,SAAS,CAAE,QAAkC,SACpD,MAAM,KAAK,WAAW,MAAM,MAAM;CAEtC;CAEA,MAAc,WAAW,MAAc,QAAgC;EACrE,IAAI,CAAC,KAAK,OAAO;EACjB,QAAQ,MAAR;GACE,KAAK;IACH,MAAM,KAAK,MAAM,UAAU,MAAa;IACxC;GACF,KAAK;IACH,MAAM,KAAK,MAAM,WAAW,MAAc;IAC1C;GACF,KAAK;IACH,MAAM,KAAK,MAAM,YAAY,MAAoB;IACjD;GACF,KAAK;IACH,MAAM,KAAK,MAAM,eAAe,MAAkB;IAClD;GACF,KAAK;IACH,MAAM,KAAK,MAAM,kBAAkB,MAA2B;IAC9D;EACJ;CACF;CAEA,OAA4C;EAG1C,KAAK,iBAAiB,KAAK,WAAW;EACtC,OAAO,KAAK;CACd;CAEA,MAAc,aAA0C;EACtD,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,OAAO,MAAM,OAAO;EAC1B,MAAM,QAAQ,IAAI,mBAAmB;EACrC,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,GAAG,QAAQ,KAAK,GAAG;EACrC,QAAQ;GAGN,KAAK,QAAQ;GACb,OAAO;EACT;EAOA,QAAQ,MAAM,GAAG,MAAM;GAMrB,MAAM,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAC;GAC3B,MAAM,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAC;GAC3B,IAAI,UAAU,OAAO,OAAO,QAAQ,QAAQ,KAAK;GACjD,MAAM,KAAK,EAAE,MAAM,wBAAwB;GAC3C,MAAM,KAAK,EAAE,MAAM,wBAAwB;GAG3C,QAFY,KAAK,OAAO,GAAG,EAAE,IAAI,OAAO,sBAC5B,KAAK,OAAO,GAAG,EAAE,IAAI,OAAO;EAE1C,CAAC;EACD;GAQE,MAAM,aAA6C,CAAC;GACpD,MAAM,cAA8C,CAAC;GACrD,KAAK,MAAM,QAAQ,SAAS;IAC1B,IAAI,CAAC,KAAK,SAAS,SAAS,GAAG;IAC/B,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,IAAI;IACrC,MAAM,UAAU,MAAM,GAAG,SAAS,MAAM,MAAM;IAC9C,MAAM,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC;IAC7B,MAAM,QAAQ,QAAQ,MAAM,IAAI;IAChC,KAAK,IAAI,KAAK,GAAG,KAAK,MAAM,QAAQ,MAAM;KACxC,MAAM,OAAO,MAAM;KACnB,IAAI,CAAC,KAAK,KAAK,GAAG;KAClB,IAAI;KACJ,IAAI;MACF,SAAS,KAAK,MAAM,IAAI;KAC1B,SAAS,KAAK;MAGZ,MAAM,IAAI,MACR,2CAA2C,KAAK,QAAQ,KAAK,EAAE,IAC7D,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAChD,KAAK,KAAK,MAAM,GAAG,GAAG,GACzB;KACF;KACA,IAAI,SAAS,QAAQ;MACnB,IAAI,QAAQ,SAAS;OACnB,WAAW,KAAK,MAAM;OACtB;MACF;MAGA,IAAI;OACF,MAAM,MAAM,UAAU,MAAM;MAC9B,QAAQ;OACN,MAAM,MAAM,UAAU,OAAO,OAAO,MAAM;MAC5C;KACF,OAAO,IAAI,SAAS,SAAS;MAQ3B,IAAI,QAAQ,SAAS;OACnB,YAAY,KAAK,MAAM;OACvB;MACF;MACA,MAAM,MAAM,WAAW,MAAM;KAC/B,OAAO,IAAI,SAAS,UAClB,MAAM,MAAM,YAAY,MAAM;UACzB,IAAI,SAAS,aAClB,MAAM,MAAM,eAAe,MAAM;UAC5B,IAAI,SAAS,UAClB,MAAM,MAAM,kBAAkB,MAAM;IAExC;GACF;GAKA,KAAK,MAAM,UAAU,YACnB,MAAM,MAAM,UAAU,OAAO,OAAiB,MAAsB;GAEtE,KAAK,MAAM,UAAU,aACnB,MAAM,MAAM,WAAW,OAAO,QAAkB,MAAuB;EAE3E;EACA,KAAK,QAAQ;EACb,OAAO;CACT;CAEA,MAAM,UAAU,KAAyB;EACvC,MAAM,KAAK,OAAO,QAAQ,GAAG;CAC/B;CACA,MAAM,UAAU,OAAe,OAAoC;EAGjE,MAAM,KAAK,OAAO,QAAQ;GAAE;GAAO,GAAG;GAAO,SAAS;EAAK,CAAC;EAC5D,IAAI,KAAK,OAAO,MAAM,KAAK,MAAM,UAAU,OAAO,KAAK;CACzD;CACA,MAAM,WAAW,MAA2B;EAC1C,MAAM,KAAK,OAAO,SAAS,IAAI;CACjC;CACA,MAAM,WAAW,QAAgB,OAAqC;EACpE,MAAM,KAAK,OAAO,SAAS;GAAE;GAAQ,GAAG;GAAO,SAAS;EAAK,CAAC;EAC9D,IAAI,KAAK,OAAO,MAAM,KAAK,MAAM,WAAW,QAAQ,KAAK;CAC3D;CACA,MAAM,YAAY,OAAkC;EAClD,MAAM,KAAK,OAAO,UAAU,KAAK;CACnC;CACA,MAAM,eAAe,UAAmC;EACtD,MAAM,KAAK,OAAO,aAAa,QAAQ;CACzC;CACA,MAAM,kBAAkB,OAAyC;EAC/D,MAAM,KAAK,OAAO,UAAU,KAAK;CACnC;CAEA,MAAM,OAAO,OAAyC;EACpD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,OAAO,KAAK;CACzC;CACA,MAAM,SAAS,QAAoC;EACjD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,SAAS,MAAM;CAC5C;CACA,MAAM,MAAM,QAAsC;EAChD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,MAAM,MAAM;CACzC;CACA,MAAM,OAAO,QAA6C;EACxD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,OAAO,MAAM;CAC1C;CACA,MAAM,OAAO,OAA6C;EACxD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,OAAO,KAAK;CACzC;CACA,MAAM,UAAU,OAAoC;EAClD,QAAQ,MAAM,KAAK,KAAK,EAAA,CAAG,UAAU,KAAK;CAC5C;AACF;;;;;;;;;;;;;;;;;;;;;;;ACpXA,IAAa,oBAAb,cAAuC,sBAAsB;CAC/B;CAA5B,YAAY,QAA4C;EACtD,MACE,OAAO,OAAO,MAAM,2BAA2B,OAAO,OAAO,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,GAC3F;EAH0B,KAAA,SAAA;CAI5B;AACF;AAEA,eAAsB,kBACpB,OACA,OACA,eAAyC,CAAC,GACb;CAC7B,MAAM,SAA8B,CAAC;CACrC,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK;CACpC,IAAI,CAAC,KACH,OAAO;EACL,IAAI;EACJ;EACA,cAAc;EACd,gBAAgB;EAChB,eAAe;EACf,uBAAuB;EACvB,iBAAiB;GAAE,SAAS;GAAG,OAAO;EAAE;EACxC,QAAQ,CAAC;GAAE,MAAM;GAAU,SAAS,OAAO,MAAM;EAAsB,CAAC;CAC1E;CAGF,MAAM,QAAQ,MAAM,MAAM,MAAM,EAAE,MAAM,CAAC;CACzC,MAAM,WAAW,MAAM,QAAQ,MAAM,EAAE,SAAS,KAAK;CACrD,MAAM,aAAa,MAAM,QAAQ,MAAM,EAAE,SAAS,OAAO;CACzD,MAAM,YAAY,MAAM,QAAQ,MAAM,EAAE,SAAS,MAAM;CAEvD,MAAM,SAAS,aAAa,eAAe;CAC3C,MAAM,WAAW,aAAa,iBAAiB;CAC/C,MAAM,UAAU,aAAa,gBAAgB;CAE7C,IAAI,SAAS,SAAS,QACpB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,cAAc,OAAO,oBAAoB,SAAS,OAAO;EAClE,QAAQ;GAAE,UAAU;GAAQ,OAAO,SAAS;EAAO;CACrD,CAAC;CAEH,IAAI,WAAW,SAAS,UACtB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,cAAc,SAAS,sBAAsB,WAAW,OAAO;EACxE,QAAQ;GAAE,UAAU;GAAU,OAAO,WAAW;EAAO;CACzD,CAAC;CAEH,IAAI,UAAU,SAAS,SACrB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,cAAc,QAAQ,qBAAqB,UAAU,OAAO;EACrE,QAAQ;GAAE,UAAU;GAAS,OAAO,UAAU;EAAO;CACvD,CAAC;CAGH,IAAI,gBAAgB;CACpB,IAAI,WAAW;EAAE,SAAS;EAAG,OAAO,SAAS;CAAO;CAEpD,IAAI,aAAa,SACf,IAAI,CAAC,aAAa,QAAQ,MACxB,OAAO,KAAK;EACV,MAAM;EACN,SAAS;CACX,CAAC;MACI;EACL,MAAM,SAAS,MAAM,aAAa,QAAQ,KAAK,EAAE,MAAM,CAAC;EACxD,gBAAgB,OAAO;EACvB,MAAM,SAAS,aAAa,wBAAwB;EACpD,IAAI,gBAAgB,QAClB,OAAO,KAAK;GACV,MAAM;GACN,SAAS,cAAc,OAAO,8BAA8B,cAAc;GAC1E,QAAQ;IAAE,UAAU;IAAQ,OAAO;GAAc;EACnD,CAAC;EAEH,IAAI,aAAa,8BAA8B;GAC7C,MAAM,sBAAsB,IAAI,IAC9B,OAAO,QAAQ,MAAM,EAAE,cAAc,aAAa,EAAE,MAAM,CAAC,CAAC,KAAK,MAAM,EAAE,MAAO,CAClF;GACA,MAAM,WAAW,SAAS,QAAQ,MAAM,CAAC,oBAAoB,IAAI,EAAE,MAAM,CAAC;GAC1E,WAAW;IAAE,SAAS,SAAS,SAAS,SAAS;IAAQ,OAAO,SAAS;GAAO;GAChF,IAAI,SAAS,SAAS,GACpB,OAAO,KAAK;IACV,MAAM;IACN,SAAS,GAAG,SAAS,OAAO;IAC5B,QAAQ,EAAE,iBAAiB,SAAS,KAAK,MAAM,EAAE,MAAM,EAAE;GAC3D,CAAC;EAEL;CACF;MACK,IAAI,aAAa,gCAAgC,aAAa,sBACnE,OAAO,KAAK;EACV,MAAM;EACN,SAAS;CACX,CAAC;CAGH,IAAI,aAAa,mBAAmB,IAAI,YAAY,KAAA,KAAa,IAAI,YAAY,OAC/E,OAAO,KAAK;EACV,MAAM;EACN,SAAS,OAAO,MAAM;CACxB,CAAC;CAGH,OAAO;EACL,IAAI,OAAO,WAAW;EACtB;EACA,cAAc,SAAS;EACvB,gBAAgB,WAAW;EAC3B,eAAe,UAAU;EACzB,uBAAuB;EACvB,iBAAiB;EACjB;CACF;AACF;;AAGA,SAAgB,qBAAqB,QAAkC;CACrE,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,kBAAkB,MAAM;AACpD"}
@@ -1,2 +1,2 @@
1
- import { A as AtomicFileLock, C as withLedgerFileLock, D as LedgerHash, E as LedgerCanonicalizationError, F as AtomicFileLockUnavailable, I as probeAtomicFileLock, L as tryAcquireAtomicFileLock, M as AtomicFileLockError, N as AtomicFileLockOptions, O as canonicalString, P as AtomicFileLockOwner, S as tryWithLedgerFileLock, T as LEDGER_HASH_PATTERN, _ as trustedHeadPathFor, a as LedgerChainFields, b as LedgerFileContext, c as LedgerJournalCodec, d as LedgerReplayResult, f as LedgerAnchoredEntry, g as readTrustedHeadFile, h as LedgerTrustedHeadSubject, i as LedgerAppendResult, j as AtomicFileLockAcquisition, k as hashCanonical, l as LedgerLineContext, m as LedgerTrustedHeadRemoval, n as FileLedgerJournalOptions, o as LedgerEntryOf, p as LedgerTrustedHead, r as LedgerAppendOptions, s as LedgerEventBase, t as FileLedgerJournal, u as LedgerProjector, v as verifyEntriesAgainstTrustedHead, w as writeLedgerFileAtomically, x as appendLedgerLine, y as FileLockResult } from "../index-DuhJaaiH.js";
1
+ import { A as AtomicFileLock, C as withLedgerFileLock, D as LedgerHash, E as LedgerCanonicalizationError, F as AtomicFileLockUnavailable, I as probeAtomicFileLock, L as tryAcquireAtomicFileLock, M as AtomicFileLockError, N as AtomicFileLockOptions, O as canonicalString, P as AtomicFileLockOwner, S as tryWithLedgerFileLock, T as LEDGER_HASH_PATTERN, _ as trustedHeadPathFor, a as LedgerChainFields, b as LedgerFileContext, c as LedgerJournalCodec, d as LedgerReplayResult, f as LedgerAnchoredEntry, g as readTrustedHeadFile, h as LedgerTrustedHeadSubject, i as LedgerAppendResult, j as AtomicFileLockAcquisition, k as hashCanonical, l as LedgerLineContext, m as LedgerTrustedHeadRemoval, n as FileLedgerJournalOptions, o as LedgerEntryOf, p as LedgerTrustedHead, r as LedgerAppendOptions, s as LedgerEventBase, t as FileLedgerJournal, u as LedgerProjector, v as verifyEntriesAgainstTrustedHead, w as writeLedgerFileAtomically, x as appendLedgerLine, y as FileLockResult } from "../index-DEb46kc6.js";
2
2
  export { type AtomicFileLock, type AtomicFileLockAcquisition, AtomicFileLockError, type AtomicFileLockOptions, type AtomicFileLockOwner, type AtomicFileLockUnavailable, FileLedgerJournal, type FileLedgerJournalOptions, type FileLockResult, LEDGER_HASH_PATTERN, type LedgerAnchoredEntry, type LedgerAppendOptions, type LedgerAppendResult, LedgerCanonicalizationError, type LedgerChainFields, type LedgerEntryOf, type LedgerEventBase, type LedgerFileContext, type LedgerHash, type LedgerJournalCodec, type LedgerLineContext, type LedgerProjector, type LedgerReplayResult, type LedgerTrustedHead, type LedgerTrustedHeadRemoval, type LedgerTrustedHeadSubject, appendLedgerLine, canonicalString, hashCanonical, probeAtomicFileLock, readTrustedHeadFile, trustedHeadPathFor, tryAcquireAtomicFileLock, tryWithLedgerFileLock, verifyEntriesAgainstTrustedHead, withLedgerFileLock, writeLedgerFileAtomically };
@@ -1,2 +1,2 @@
1
- import { a as appendLedgerLine, c as writeLedgerFileAtomically, d as canonicalString, f as hashCanonical, h as tryAcquireAtomicFileLock, i as verifyEntriesAgainstTrustedHead, l as LEDGER_HASH_PATTERN, m as probeAtomicFileLock, n as readTrustedHeadFile, o as tryWithLedgerFileLock, p as AtomicFileLockError, r as trustedHeadPathFor, s as withLedgerFileLock, t as FileLedgerJournal, u as LedgerCanonicalizationError } from "../ledger-core-DAKFKRzi.js";
1
+ import { a as appendLedgerLine, c as writeLedgerFileAtomically, d as tryAcquireAtomicFileLock, f as LEDGER_HASH_PATTERN, h as hashCanonical, i as verifyEntriesAgainstTrustedHead, l as AtomicFileLockError, m as canonicalString, n as readTrustedHeadFile, o as tryWithLedgerFileLock, p as LedgerCanonicalizationError, r as trustedHeadPathFor, s as withLedgerFileLock, t as FileLedgerJournal, u as probeAtomicFileLock } from "../ledger-core-t6sItivm.js";
2
2
  export { AtomicFileLockError, FileLedgerJournal, LEDGER_HASH_PATTERN, LedgerCanonicalizationError, appendLedgerLine, canonicalString, hashCanonical, probeAtomicFileLock, readTrustedHeadFile, trustedHeadPathFor, tryAcquireAtomicFileLock, tryWithLedgerFileLock, verifyEntriesAgainstTrustedHead, withLedgerFileLock, writeLedgerFileAtomically };