@tangle-network/agent-eval 0.208.2 → 0.209.1

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 (201) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/adapters/http.d.ts +2 -2
  3. package/dist/{agent-profile-CEhxR_I3.d.ts → agent-profile-BGyt2z8U.d.ts} +3 -3
  4. package/dist/{agent-profile-CEhxR_I3.d.ts.map → agent-profile-BGyt2z8U.d.ts.map} +1 -1
  5. package/dist/{agent-profile-cell-BHcB-mZX.d.ts → agent-profile-cell-BNp-Js9F.d.ts} +2 -3
  6. package/dist/agent-profile-cell-BNp-Js9F.d.ts.map +1 -0
  7. package/dist/{agent-profile-cell-DcFW4vOc.js → agent-profile-cell-BYc0bxsL.js} +2 -2
  8. package/dist/agent-profile-cell-BYc0bxsL.js.map +1 -0
  9. package/dist/analyst/index.d.ts +11 -11
  10. package/dist/analyst/index.js +5 -5
  11. package/dist/{analyze-runs-GZ0VSwui.js → analyze-runs-0cdYMgob.js} +5 -5
  12. package/dist/{analyze-runs-GZ0VSwui.js.map → analyze-runs-0cdYMgob.js.map} +1 -1
  13. package/dist/{analyze-runs-CTJyUplR.d.ts → analyze-runs-BlslTkOJ.d.ts} +4 -4
  14. package/dist/{analyze-runs-CTJyUplR.d.ts.map → analyze-runs-BlslTkOJ.d.ts.map} +1 -1
  15. package/dist/{benchmark-command-BC265T1r.js → benchmark-command-Cve7mHNC.js} +5 -5
  16. package/dist/{benchmark-command-BC265T1r.js.map → benchmark-command-Cve7mHNC.js.map} +1 -1
  17. package/dist/benchmarks/index.d.ts +5 -7
  18. package/dist/benchmarks/index.d.ts.map +1 -1
  19. package/dist/benchmarks/index.js +3 -3
  20. package/dist/builder-eval/index.js +1 -1
  21. package/dist/campaign/index.d.ts +6 -6
  22. package/dist/campaign/index.js +8 -8
  23. package/dist/{campaign-C5pjR-Qn.js → campaign-CvhmiLKa.js} +13 -13
  24. package/dist/{campaign-C5pjR-Qn.js.map → campaign-CvhmiLKa.js.map} +1 -1
  25. package/dist/{campaign-evidence-DW3Krxov.js → campaign-evidence-B5qsCHEn.js} +3 -3
  26. package/dist/{campaign-evidence-DW3Krxov.js.map → campaign-evidence-B5qsCHEn.js.map} +1 -1
  27. package/dist/cli.js +7 -7
  28. package/dist/contract/index.d.ts +9 -9
  29. package/dist/contract/index.js +7 -7
  30. package/dist/{default-registry-DZFWY2_E.d.ts → default-registry-Crk3QEy1.d.ts} +6 -6
  31. package/dist/{default-registry-DZFWY2_E.d.ts.map → default-registry-Crk3QEy1.d.ts.map} +1 -1
  32. package/dist/{default-registry-DX5R7_n9.js → default-registry-DF4Yp7HQ.js} +2 -2
  33. package/dist/{default-registry-DX5R7_n9.js.map → default-registry-DF4Yp7HQ.js.map} +1 -1
  34. package/dist/{define-agent-eval-BjKXcDQp.js → define-agent-eval-Csd47ur_.js} +7 -7
  35. package/dist/{define-agent-eval-BjKXcDQp.js.map → define-agent-eval-Csd47ur_.js.map} +1 -1
  36. package/dist/{define-agent-eval-C8zBSbsc.d.ts → define-agent-eval-_nyV5nev.d.ts} +7 -7
  37. package/dist/{define-agent-eval-C8zBSbsc.d.ts.map → define-agent-eval-_nyV5nev.d.ts.map} +1 -1
  38. package/dist/diagnosis/index.d.ts +2 -5
  39. package/dist/diagnosis/index.d.ts.map +1 -1
  40. package/dist/diagnosis/index.js +2 -26
  41. package/dist/diagnosis/index.js.map +1 -1
  42. package/dist/{dspy-rlm-engine-sHwdSxK3.js → dspy-rlm-engine-BpaKVKJA.js} +2 -2
  43. package/dist/{dspy-rlm-engine-sHwdSxK3.js.map → dspy-rlm-engine-BpaKVKJA.js.map} +1 -1
  44. package/dist/{engine-DProXJ7A.d.ts → engine-D-YZ32ZJ.d.ts} +5 -12
  45. package/dist/engine-D-YZ32ZJ.d.ts.map +1 -0
  46. package/dist/{eval-campaign-DU_p8qVt.js → eval-campaign-C31Qbv77.js} +4 -4
  47. package/dist/{eval-campaign-DU_p8qVt.js.map → eval-campaign-C31Qbv77.js.map} +1 -1
  48. package/dist/evaluation.d.ts +2 -2
  49. package/dist/{exact-types-Cq6xXNVR.d.ts → exact-types-DjhfZglz.d.ts} +2 -2
  50. package/dist/{exact-types-Cq6xXNVR.d.ts.map → exact-types-DjhfZglz.d.ts.map} +1 -1
  51. package/dist/experiment/index.d.ts +2 -2
  52. package/dist/experiment/index.js +5 -5
  53. package/dist/{feedback-trajectory-C6Z8PRoF.d.ts → feedback-trajectory-CX01700m.d.ts} +3 -3
  54. package/dist/{feedback-trajectory-C6Z8PRoF.d.ts.map → feedback-trajectory-CX01700m.d.ts.map} +1 -1
  55. package/dist/hosted/index.js +1 -1
  56. package/dist/{index-nwNoS582.d.ts → index-BHh9Z9El.d.ts} +9 -9
  57. package/dist/{index-nwNoS582.d.ts.map → index-BHh9Z9El.d.ts.map} +1 -1
  58. package/dist/{index-Bzto04CY.d.ts → index-Ddi5M-TQ.d.ts} +8 -8
  59. package/dist/{index-Bzto04CY.d.ts.map → index-Ddi5M-TQ.d.ts.map} +1 -1
  60. package/dist/{index-CbBfavbT.d.ts → index-H-u7f-w3.d.ts} +2 -2
  61. package/dist/{index-CbBfavbT.d.ts.map → index-H-u7f-w3.d.ts.map} +1 -1
  62. package/dist/{index-DkucR0KJ.d.ts → index-UxNTvn-w.d.ts} +6 -6
  63. package/dist/{index-DkucR0KJ.d.ts.map → index-UxNTvn-w.d.ts.map} +1 -1
  64. package/dist/index.d.ts +27 -36
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +25 -87
  67. package/dist/index.js.map +1 -1
  68. package/dist/{kind-factory-Cn1lbsAd.js → kind-factory-ivTx6koH.js} +2 -11
  69. package/dist/{kind-factory-Cn1lbsAd.js.map → kind-factory-ivTx6koH.js.map} +1 -1
  70. package/dist/{llm-judge-HLWASwUJ.js → llm-judge-C0256VT_.js} +7 -7
  71. package/dist/{llm-judge-HLWASwUJ.js.map → llm-judge-C0256VT_.js.map} +1 -1
  72. package/dist/{matrix-Cqkk7eYI.d.ts → matrix-jHTsHEkR.d.ts} +2 -2
  73. package/dist/{matrix-Cqkk7eYI.d.ts.map → matrix-jHTsHEkR.d.ts.map} +1 -1
  74. package/dist/meta-eval/index.d.ts +1 -1
  75. package/dist/meta-eval/index.js +1 -1
  76. package/dist/{mint-C1W8w5wo.d.ts → mint-CDy-brUR.d.ts} +2 -2
  77. package/dist/{mint-C1W8w5wo.d.ts.map → mint-CDy-brUR.d.ts.map} +1 -1
  78. package/dist/{mint-CWG-s2mI.js → mint-Csor1BLJ.js} +2 -2
  79. package/dist/{mint-CWG-s2mI.js.map → mint-Csor1BLJ.js.map} +1 -1
  80. package/dist/multishot/golden/index.d.ts +1 -1
  81. package/dist/multishot/index.d.ts +2 -2
  82. package/dist/openapi.json +1 -1
  83. package/dist/{paired-arms-CgWT7sHy.js → paired-arms-B5v-X7No.js} +2 -4
  84. package/dist/{paired-arms-CgWT7sHy.js.map → paired-arms-B5v-X7No.js.map} +1 -1
  85. package/dist/pipelines/index.d.ts +1 -1
  86. package/dist/pipelines/index.js +2 -2
  87. package/dist/{prime-protocol-Csr9kcOM.d.ts → prime-protocol-B7et3tI7.d.ts} +2 -2
  88. package/dist/{prime-protocol-Csr9kcOM.d.ts.map → prime-protocol-B7et3tI7.d.ts.map} +1 -1
  89. package/dist/{produced-state-Bzlh09oj.js → produced-state-CgB9g0VX.js} +3 -3
  90. package/dist/{produced-state-Bzlh09oj.js.map → produced-state-CgB9g0VX.js.map} +1 -1
  91. package/dist/profile-cell.d.ts +2 -2
  92. package/dist/profile-cell.js +2 -2
  93. package/dist/{query-DlV0pdx4.js → query-B1D1qp2Z.js} +2 -2
  94. package/dist/{query-DlV0pdx4.js.map → query-B1D1qp2Z.js.map} +1 -1
  95. package/dist/{query-DBUQhehH.d.ts → query-DK1nWcmp.d.ts} +2 -3
  96. package/dist/{query-DBUQhehH.d.ts.map → query-DK1nWcmp.d.ts.map} +1 -1
  97. package/dist/{registry-DMkmhBQ5.d.ts → registry-BL7H33tj.d.ts} +3 -3
  98. package/dist/{registry-DMkmhBQ5.d.ts.map → registry-BL7H33tj.d.ts.map} +1 -1
  99. package/dist/{release-confidence-CkoXFx9I.d.ts → release-confidence-C4kI7lQi.d.ts} +4 -12
  100. package/dist/release-confidence-C4kI7lQi.d.ts.map +1 -0
  101. package/dist/{release-confidence-CiFg1EPq.js → release-confidence-Dbe9AS_X.js} +2 -2
  102. package/dist/{release-confidence-CiFg1EPq.js.map → release-confidence-Dbe9AS_X.js.map} +1 -1
  103. package/dist/{report-command-pXtxg5YK.js → report-command-CtIIsQKP.js} +3 -28
  104. package/dist/{report-command-pXtxg5YK.js.map → report-command-CtIIsQKP.js.map} +1 -1
  105. package/dist/reporting.d.ts +3 -3
  106. package/dist/reporting.js +3 -3
  107. package/dist/{researcher-CZFZjj-u.d.ts → researcher-DuIJ9IaA.d.ts} +4 -4
  108. package/dist/{researcher-CZFZjj-u.d.ts.map → researcher-DuIJ9IaA.d.ts.map} +1 -1
  109. package/dist/{reward-hacking-Cyk-QHk9.d.ts → reward-hacking-C6Kp54Av.d.ts} +2 -2
  110. package/dist/{reward-hacking-Cyk-QHk9.d.ts.map → reward-hacking-C6Kp54Av.d.ts.map} +1 -1
  111. package/dist/reward-nw2xZGZG.js.map +1 -1
  112. package/dist/rl.d.ts +10 -29
  113. package/dist/rl.d.ts.map +1 -1
  114. package/dist/rl.js +6 -6
  115. package/dist/rl.js.map +1 -1
  116. package/dist/rollout/index.d.ts +2 -2
  117. package/dist/rollout/index.js +2 -2
  118. package/dist/{rollout-l9w3Gdvh.js → rollout-BZqQc0YY.js} +2 -2
  119. package/dist/{rollout-l9w3Gdvh.js.map → rollout-BZqQc0YY.js.map} +1 -1
  120. package/dist/{rubric-predictive-validity-DIUwJJ9Y.d.ts → rubric-predictive-validity-BiNNEjpG.d.ts} +2 -2
  121. package/dist/{rubric-predictive-validity-DIUwJJ9Y.d.ts.map → rubric-predictive-validity-BiNNEjpG.d.ts.map} +1 -1
  122. package/dist/{run-record-BRlM99rX.js → run-record-DlTZ_lqe.js} +3 -13
  123. package/dist/run-record-DlTZ_lqe.js.map +1 -0
  124. package/dist/{run-record-BB290Y9A.js → run-record-ES07wfz9.js} +2 -2
  125. package/dist/{run-record-BB290Y9A.js.map → run-record-ES07wfz9.js.map} +1 -1
  126. package/dist/{run-record-DF-fuu31.d.ts → run-record-p2AYTrCn.d.ts} +3 -7
  127. package/dist/run-record-p2AYTrCn.d.ts.map +1 -0
  128. package/dist/search/index.d.ts +2 -24
  129. package/dist/search/index.d.ts.map +1 -1
  130. package/dist/search/index.js +3 -3
  131. package/dist/{search-kernel-CIie6xig.js → search-kernel-Bfe3kzRk.js} +2 -2
  132. package/dist/{search-kernel-CIie6xig.js.map → search-kernel-Bfe3kzRk.js.map} +1 -1
  133. package/dist/{search-kernel-uKdPVRAe.d.ts → search-kernel-ah2GESe3.d.ts} +3 -3
  134. package/dist/{search-kernel-uKdPVRAe.d.ts.map → search-kernel-ah2GESe3.d.ts.map} +1 -1
  135. package/dist/{search-ledger-CXQPwdWz.js → search-ledger-aMTNQn_m.js} +2 -2
  136. package/dist/{search-ledger-CXQPwdWz.js.map → search-ledger-aMTNQn_m.js.map} +1 -1
  137. package/dist/{search-shipper-DhhofkDX.js → search-shipper-DKXWuLnp.js} +2 -2
  138. package/dist/{search-shipper-DhhofkDX.js.map → search-shipper-DKXWuLnp.js.map} +1 -1
  139. package/dist/{search-summary-BV5uehLd.js → search-summary-DK1bwTAf.js} +2 -2
  140. package/dist/{search-summary-BV5uehLd.js.map → search-summary-DK1bwTAf.js.map} +1 -1
  141. package/dist/{semantic-concept-judge-D1wH-YKc.js → semantic-concept-judge-BQxZyXdN.js} +3 -3
  142. package/dist/{semantic-concept-judge-D1wH-YKc.js.map → semantic-concept-judge-BQxZyXdN.js.map} +1 -1
  143. package/dist/{sequential-DMqr3sni.js → sequential-BOzBND4t.js} +2 -2
  144. package/dist/{sequential-DMqr3sni.js.map → sequential-BOzBND4t.js.map} +1 -1
  145. package/dist/{skillopt-optimization-method-Dcnh5Pvr.js → skillopt-optimization-method-BCojvoP1.js} +4 -4
  146. package/dist/{skillopt-optimization-method-Dcnh5Pvr.js.map → skillopt-optimization-method-BCojvoP1.js.map} +1 -1
  147. package/dist/{statistical-heldout-DFKtp-Qm.d.ts → statistical-heldout-D0rX_IDl.d.ts} +4 -5
  148. package/dist/statistical-heldout-D0rX_IDl.d.ts.map +1 -0
  149. package/dist/{store-otlp-BA7G1Du-.js → store-otlp-__ebQ6Hn.js} +2 -2
  150. package/dist/{store-otlp-BA7G1Du-.js.map → store-otlp-__ebQ6Hn.js.map} +1 -1
  151. package/dist/{store-tool-spans-DKoVbE-w.js → store-tool-spans-TbRBuIM7.js} +3 -3
  152. package/dist/{store-tool-spans-DKoVbE-w.js.map → store-tool-spans-TbRBuIM7.js.map} +1 -1
  153. package/dist/{store-tool-spans-9YJNMP-z.d.ts → store-tool-spans-wQ9idsnn.d.ts} +5 -5
  154. package/dist/{store-tool-spans-9YJNMP-z.d.ts.map → store-tool-spans-wQ9idsnn.d.ts.map} +1 -1
  155. package/dist/{summary-report-fXurE2TR.js → summary-report-BsaEFEwA.js} +3 -3
  156. package/dist/{summary-report-fXurE2TR.js.map → summary-report-BsaEFEwA.js.map} +1 -1
  157. package/dist/{summary-report-DvvesgR_.d.ts → summary-report-CK0ueoJd.d.ts} +2 -2
  158. package/dist/{summary-report-DvvesgR_.d.ts.map → summary-report-CK0ueoJd.d.ts.map} +1 -1
  159. package/dist/supervisor-run/index.d.ts +0 -8
  160. package/dist/supervisor-run/index.d.ts.map +1 -1
  161. package/dist/supervisor-run/index.js +2 -2
  162. package/dist/{systemone-review-Bt4JcxMc.d.ts → systemone-review-BReh3mvm.d.ts} +2 -2
  163. package/dist/{systemone-review-Bt4JcxMc.d.ts.map → systemone-review-BReh3mvm.d.ts.map} +1 -1
  164. package/dist/systemone.d.ts +3 -3
  165. package/dist/{tool-groups-j19pmOfP.d.ts → tool-groups-v28A-ZAF.d.ts} +3 -3
  166. package/dist/tool-groups-v28A-ZAF.d.ts.map +1 -0
  167. package/dist/{tool-waste-x_E8h9Ih.js → tool-waste-BYt5rdt8.js} +2 -2
  168. package/dist/{tool-waste-x_E8h9Ih.js.map → tool-waste-BYt5rdt8.js.map} +1 -1
  169. package/dist/{tool-waste-DxlebQkx.d.ts → tool-waste-Wi4g6Ekb.d.ts} +2 -2
  170. package/dist/{tool-waste-DxlebQkx.d.ts.map → tool-waste-Wi4g6Ekb.d.ts.map} +1 -1
  171. package/dist/{trace-questions-dRvmsbTk.d.ts → trace-questions-C26UvI3D.d.ts} +3 -3
  172. package/dist/{trace-questions-dRvmsbTk.d.ts.map → trace-questions-C26UvI3D.d.ts.map} +1 -1
  173. package/dist/trace-repair/index.d.ts +2 -9
  174. package/dist/trace-repair/index.d.ts.map +1 -1
  175. package/dist/trace-repair/index.js +1 -1
  176. package/dist/traces.d.ts +6 -8
  177. package/dist/traces.d.ts.map +1 -1
  178. package/dist/traces.js +6 -6
  179. package/dist/trajectory-replay/index.d.ts +0 -2
  180. package/dist/trajectory-replay/index.d.ts.map +1 -1
  181. package/dist/trajectory-replay/index.js +1 -1
  182. package/dist/{tree-CJOXbVcv.js → tree-CZ78tiPg.js} +4 -24
  183. package/dist/tree-CZ78tiPg.js.map +1 -0
  184. package/dist/{types-CFCUZk0B.d.ts → types-Dv9sYwBB.d.ts} +4 -4
  185. package/dist/{types-CFCUZk0B.d.ts.map → types-Dv9sYwBB.d.ts.map} +1 -1
  186. package/dist/{types-DAPpAkd4.d.ts → types-KEkKkETv.d.ts} +2 -2
  187. package/dist/{types-DAPpAkd4.d.ts.map → types-KEkKkETv.d.ts.map} +1 -1
  188. package/dist/{types-BlSBUNRd.d.ts → types-tWFY6bON.d.ts} +3 -3
  189. package/dist/{types-BlSBUNRd.d.ts.map → types-tWFY6bON.d.ts.map} +1 -1
  190. package/dist/wire/index.d.ts +1 -1
  191. package/docs/public-api.md +399 -424
  192. package/package.json +3 -3
  193. package/dist/agent-profile-cell-BHcB-mZX.d.ts.map +0 -1
  194. package/dist/agent-profile-cell-DcFW4vOc.js.map +0 -1
  195. package/dist/engine-DProXJ7A.d.ts.map +0 -1
  196. package/dist/release-confidence-CkoXFx9I.d.ts.map +0 -1
  197. package/dist/run-record-BRlM99rX.js.map +0 -1
  198. package/dist/run-record-DF-fuu31.d.ts.map +0 -1
  199. package/dist/statistical-heldout-DFKtp-Qm.d.ts.map +0 -1
  200. package/dist/tool-groups-j19pmOfP.d.ts.map +0 -1
  201. package/dist/tree-CJOXbVcv.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["SEVERITIES"],"sources":["../../src/diagnosis/first-failure.ts","../../src/diagnosis/spans.ts","../../src/diagnosis/deterministic.ts","../../src/diagnosis/findings.ts","../../src/diagnosis/model-pass.ts","../../src/diagnosis/engine.ts"],"sourcesContent":["/**\n * The first failure in one run, ranked by a fixed precedence and never read off\n * timing correlation.\n *\n * Precedence:\n * 1. `error-span`: a span with status ERROR or `agent.outcome` \"error\" that\n * contains no other such span. A span whose failure is explained by a\n * failing span inside it does not rank; containment is recorded structure.\n * Among the rest, the span that ended first ranks first, because its end\n * is when the failure was recorded.\n * 2. `failed-outcome`: no span errored, but a span carries `agent.outcome`\n * \"fail\". The run completed and its graded work failed.\n * 3. `none`: neither exists, and at least one span recorded a definitive\n * OK or ERROR status. This describes the recorded spans. It is not a\n * verdict that the run succeeded, only that nothing failed among what\n * was recorded.\n *\n * A trace where no span recorded OK or ERROR — every span is UNSET, the\n * common shape for a capture that failed before any status was written —\n * ranks `unknown`, not `none`. `none` asserts something was observed and\n * nothing failed in it; a trace of pure UNSET spans observed nothing, so\n * treating it as a clean run manufactures a false negative for whatever\n * consumed it (a comparison, a pass/fail gate).\n *\n * When the leading candidates end at the same instant, or a candidate has no\n * end time, the result is `ambiguous` and names the candidates. The rank never\n * picks one.\n *\n * The failing span's status message is classified by the failure taxonomy\n * (`classifyFailureReason`), whose `blame` separates machine and provider\n * failures from the agent's own. A span without a message is `unreported` and\n * blamed `unknown`. A failed outcome with no error span is blamed `unknown`\n * too: the machine and the provider recorded no failure, but absence of a\n * recorded cause is not evidence the agent caused it. Blame only reads\n * `agent` when the taxonomy names the agent from actual evidence.\n */\n\nimport type { SpanKind } from '@tangle-network/agent-trace-contract'\nimport {\n classifyFailureReason,\n type FailureBlame,\n type FailureClassification,\n} from '../failure-taxonomy'\nimport type { DiagnosisSpan } from './spans'\n\n/** Span ids listed beside a result; the count carries the rest. */\nexport const MAX_FIRST_FAILURE_IDS = 8\n\nconst OUTCOME_ATTR = 'agent.outcome'\n\nexport type FirstFailureStage = 'error-span' | 'failed-outcome'\n\nexport interface FirstFailureFound {\n status: 'found'\n traceId: string\n stage: FirstFailureStage\n spanId: string\n name: string\n kind: SpanKind\n /** The span's status message after secret filtering; null when absent or withheld. */\n message: string | null\n /** The taxonomy's reading of `message`; null for a failed outcome, which has none. */\n classification: FailureClassification | null\n blame: FailureBlame\n /** Other candidates at the same stage, in rank order, capped at {@link MAX_FIRST_FAILURE_IDS}. */\n later: string[]\n laterCount: number\n}\n\nexport interface FirstFailureAmbiguous {\n status: 'ambiguous'\n traceId: string\n stage: FirstFailureStage\n /** The candidates the rank could not order, capped at {@link MAX_FIRST_FAILURE_IDS}. */\n candidates: string[]\n candidateCount: number\n reason: string\n}\n\nexport interface FirstFailureNone {\n status: 'none'\n traceId: string\n reason: string\n}\n\n/**\n * No span recorded a definitive OK or ERROR status, so the recording says\n * nothing about whether the run failed. Distinct from `none`, which asserts\n * spans were observed and none of them failed.\n */\nexport interface FirstFailureUnknown {\n status: 'unknown'\n traceId: string\n /** Count of spans with UNSET status among the spans ranked. */\n unsetCount: number\n reason: string\n}\n\nexport type FirstFailure =\n | FirstFailureFound\n | FirstFailureAmbiguous\n | FirstFailureNone\n | FirstFailureUnknown\n\n/** Rank the first failure of one trace. Throws when the spans belong to more than one trace. */\nexport function rankFirstFailure(spans: readonly DiagnosisSpan[]): FirstFailure {\n const traceId = spans[0]?.traceId\n if (traceId === undefined) throw new TypeError('rankFirstFailure: no spans')\n if (spans.some((span) => span.traceId !== traceId)) {\n throw new TypeError('rankFirstFailure: spans belong to more than one trace')\n }\n\n const errors = spans.filter(isErrorSpan)\n if (errors.length > 0) {\n const innermost = withoutFailingDescendants(spans, errors)\n if (innermost.length === 0) {\n return ambiguous(\n traceId,\n 'error-span',\n errors,\n 'every failing span contains another failing span, so containment is cyclic',\n )\n }\n return rank(traceId, 'error-span', innermost)\n }\n\n const failed = spans.filter((span) => span.attributes[OUTCOME_ATTR] === 'fail')\n if (failed.length > 0) return rank(traceId, 'failed-outcome', failed)\n\n const unsetCount = spans.filter((span) => span.status === 'UNSET').length\n if (unsetCount === spans.length && spans.length > 0) {\n return {\n status: 'unknown',\n traceId,\n unsetCount,\n reason: `none of ${spans.length} spans has status OK or ERROR (all UNSET), so whether the run failed was never recorded`,\n }\n }\n\n return {\n status: 'none',\n traceId,\n reason: `none of ${spans.length} spans has status ERROR or an agent.outcome of error or fail`,\n }\n}\n\nfunction isErrorSpan(span: DiagnosisSpan): boolean {\n return span.status === 'ERROR' || span.attributes[OUTCOME_ATTR] === 'error'\n}\n\n/** The failing spans with no failing span beneath them. */\nfunction withoutFailingDescendants(\n spans: readonly DiagnosisSpan[],\n failing: readonly DiagnosisSpan[],\n): DiagnosisSpan[] {\n const parentOf = new Map(spans.map((span) => [span.spanId, span.parentSpanId]))\n const explained = new Set<string>()\n for (const span of failing) {\n const seen = new Set([span.spanId])\n let parent = span.parentSpanId\n while (parent !== null && parentOf.has(parent) && !seen.has(parent)) {\n explained.add(parent)\n seen.add(parent)\n parent = parentOf.get(parent) ?? null\n }\n }\n return failing.filter((span) => !explained.has(span.spanId))\n}\n\nfunction rank(\n traceId: string,\n stage: FirstFailureStage,\n candidates: readonly DiagnosisSpan[],\n): FirstFailure {\n if (candidates.length > 1) {\n const untimed = candidates.filter((span) => span.endMs === null)\n if (untimed.length > 0) {\n return ambiguous(\n traceId,\n stage,\n candidates,\n `${untimed.length} of ${candidates.length} candidates have no end time, so their order is unknown`,\n )\n }\n }\n const ordered = [...candidates].sort(\n (a, b) => (a.endMs ?? 0) - (b.endMs ?? 0) || a.spanId.localeCompare(b.spanId),\n )\n const first = ordered[0]!\n const tied = ordered.filter((span) => span.endMs === first.endMs)\n if (tied.length > 1) {\n return ambiguous(\n traceId,\n stage,\n tied,\n `${tied.length} candidates ended at the same instant, so none ranks first`,\n )\n }\n const classification = stage === 'error-span' ? classifyFailureReason(first.statusMessage) : null\n const later = ordered.slice(1)\n return {\n status: 'found',\n traceId,\n stage,\n spanId: first.spanId,\n name: first.name,\n kind: first.kind,\n message: first.statusMessage,\n classification,\n blame: classification?.blame ?? 'unknown',\n later: later.slice(0, MAX_FIRST_FAILURE_IDS).map((span) => span.spanId),\n laterCount: later.length,\n }\n}\n\nfunction ambiguous(\n traceId: string,\n stage: FirstFailureStage,\n candidates: readonly DiagnosisSpan[],\n reason: string,\n): FirstFailureAmbiguous {\n const ids = candidates.map((span) => span.spanId).sort()\n return {\n status: 'ambiguous',\n traceId,\n stage,\n candidates: ids.slice(0, MAX_FIRST_FAILURE_IDS),\n candidateCount: ids.length,\n reason,\n }\n}\n","/**\n * Ingest for the diagnosis engine: flat spans in, filtered and normalized spans\n * out. Nothing downstream of this file sees an unfiltered value.\n *\n * Input is the flat-span shape trace-adapters and the traces CLI emit, one\n * object per span: `{trace_id, span_id, parent_span_id, name, kind,\n * start_time, end_time, status | status_code, status_message, attributes,\n * resource?}`. Times may be OTLP nanosecond strings, epoch milliseconds, or\n * ISO-8601; the generic OTLP line reader treats every digit string as\n * milliseconds, so time parsing is owned here.\n */\n\nimport { createHmac, randomBytes } from 'node:crypto'\nimport {\n type ContractSpan,\n MODEL_ATTR_KEYS,\n resolveSpanKind,\n SPAN_KINDS,\n type SpanKind,\n TOOL_NAME_ATTR_KEYS,\n} from '@tangle-network/agent-trace-contract'\nimport { emptyRedactionReport, type RedactionReport, redact, redactText } from '../trace/redact'\n\nexport type DiagnosisSpanStatus = 'OK' | 'ERROR' | 'UNSET'\n\nexport interface DiagnosisSpan {\n traceId: string\n spanId: string\n parentSpanId: string | null\n name: string\n kind: SpanKind\n startMs: number | null\n endMs: number | null\n status: DiagnosisSpanStatus\n statusMessage: string | null\n toolName: string | null\n model: string | null\n /**\n * Keyed fingerprint of the tool call's input, taken before redaction so calls\n * that differ only in secret material stay distinct. The key is random per\n * ingest, so the fingerprint cannot be matched against a guessed payload or\n * joined across diagnoses. Null when the span carries no input.\n */\n inputDigest: string | null\n attributes: Record<string, unknown>\n}\n\nexport interface IngestReport {\n received: number\n accepted: number\n /** Lines without a trace id or span id, which no evidence could ever cite. */\n unreadable: number\n /** Identical (trace id, span id) pairs seen again; the first occurrence is kept. */\n duplicateSpans: number\n /** Span ids that occur in more than one trace, which evidence cannot cite unambiguously. */\n ambiguousSpanIds: string[]\n secrets: RedactionReport\n /** Attribute keys removed because content was not included. */\n droppedAttributes: string[]\n}\n\n/**\n * Attributes that carry prompt, response, or tool payload text. When content is\n * not included they are removed before anything reads the span, rather than\n * trusting pattern redaction over free-form prose.\n */\nconst CONTENT_ATTRIBUTE =\n /^(?:input\\.value|output\\.value|input|output|result|prompt|completion|text|thinking|message|messages|tool\\.(?:input|output|arguments|result)|tool_input|tool_output|tool_arguments|arguments|args|full_command|gen_ai\\.(?:prompt|completion|input\\.messages|output\\.messages|system_instructions|tool\\.call\\.(?:arguments|result))(?:\\..*)?|llm\\.(?:input|output)_messages(?:\\..*)?|llm\\.prompts?(?:\\..*)?|content|body|request|response|command)$|\\.content$/i\nconst PROSE_ATTRIBUTE =\n /(?:^|[._])(?:error|exception|status)(?:[._][a-zA-Z0-9]+)*[._](?:message|stacktrace|stack|description|details|reason)$|^(?:error|exception|status)$|^(?:log|event)[._]message$|^otel\\.status_description$|^(?:events?|logs?)$/i\n\nconst INPUT_ATTRIBUTE_KEYS = [\n 'input.value',\n 'input',\n 'tool.input',\n 'tool.arguments',\n 'tool_input',\n 'tool_arguments',\n 'arguments',\n 'args',\n 'full_command',\n 'gen_ai.tool.call.arguments',\n]\n\nexport function isContentAttribute(key: string): boolean {\n return CONTENT_ATTRIBUTE.test(key) || PROSE_ATTRIBUTE.test(key)\n}\n\n/**\n * Filter secrets from every string, drop content attributes unless content is\n * included, and normalize each span. Order matters: the input fingerprint is\n * keyed and taken before redaction and the content drop, so repeated-call\n * detection works on metadata-only runs without the payload itself surviving.\n */\nexport function ingestSpans(\n raw: readonly unknown[],\n options: { contentIncluded: boolean },\n): { spans: DiagnosisSpan[]; report: IngestReport } {\n const secrets = emptyRedactionReport()\n const dropped = new Set<string>()\n const seen = new Set<string>()\n const spans: DiagnosisSpan[] = []\n let unreadable = 0\n let duplicateSpans = 0\n const traceOfSpan = new Map<string, string>()\n const ambiguous = new Set<string>()\n const digestKey = randomBytes(32)\n for (const line of raw) {\n if (line === null || typeof line !== 'object' || Array.isArray(line)) {\n unreadable += 1\n continue\n }\n const record = line as Record<string, unknown>\n const traceId = idField(record, 'trace_id', 'traceId')\n const spanId = idField(record, 'span_id', 'spanId')\n if (!traceId || !spanId) {\n unreadable += 1\n continue\n }\n const key = `${traceId}\\u0000${spanId}`\n if (seen.has(key)) {\n duplicateSpans += 1\n continue\n }\n seen.add(key)\n const firstTrace = traceOfSpan.get(spanId)\n if (firstTrace === undefined) traceOfSpan.set(spanId, traceId)\n else if (firstTrace !== traceId) ambiguous.add(spanId)\n const merged = mergedAttributes(record)\n const inputDigest = digestInput(merged, digestKey)\n const attributes = redact(merged, { report: secrets }).value\n if (!options.contentIncluded) {\n for (const [key, value] of Object.entries(attributes)) {\n if (isContentAttribute(key) || (value !== null && typeof value === 'object')) {\n delete attributes[key]\n dropped.add(key)\n }\n }\n }\n const status = readStatus(record)\n const statusMessage =\n status.message === null ? null : redactText(status.message, { report: secrets })\n const toolName = firstString(attributes, TOOL_NAME_ATTR_KEYS)\n const model = firstString(attributes, MODEL_ATTR_KEYS)\n const name = redactText(stringOr(record.name, 'unknown'), { report: secrets })\n spans.push({\n traceId,\n spanId,\n parentSpanId: idField(record, 'parent_span_id', 'parentSpanId') ?? null,\n name,\n kind: resolveKind(record.kind, name, attributes),\n startMs: epochMillis(record.start_time ?? record.startTime ?? record.startTimeUnixNano),\n endMs: epochMillis(record.end_time ?? record.endTime ?? record.endTimeUnixNano),\n status: status.code,\n statusMessage: options.contentIncluded ? statusMessage : null,\n toolName,\n model,\n inputDigest,\n attributes,\n })\n }\n return {\n spans,\n report: {\n received: raw.length,\n accepted: spans.length,\n unreadable,\n duplicateSpans,\n ambiguousSpanIds: [...ambiguous].sort(),\n secrets,\n droppedAttributes: [...dropped].sort(),\n },\n }\n}\n\n/** The contract shape `validateTraceSpans` reads. */\nexport function toContractSpan(span: DiagnosisSpan): ContractSpan {\n return {\n trace_id: span.traceId,\n span_id: span.spanId,\n parent_span_id: span.parentSpanId,\n name: span.name,\n ...(span.kind === 'UNKNOWN' ? {} : { kind: span.kind }),\n start_time: isoOrEmpty(span.startMs),\n end_time: isoOrEmpty(span.endMs),\n status: {\n code:\n span.status === 'ERROR'\n ? 'STATUS_CODE_ERROR'\n : span.status === 'OK'\n ? 'STATUS_CODE_OK'\n : 'STATUS_CODE_UNSET',\n ...(span.statusMessage ? { message: span.statusMessage } : {}),\n },\n attributes: span.attributes,\n }\n}\n\nexport function durationMs(span: DiagnosisSpan): number | null {\n return span.startMs !== null && span.endMs !== null\n ? Math.max(0, span.endMs - span.startMs)\n : null\n}\n\n/**\n * Epoch milliseconds from OTLP nanoseconds, epoch milliseconds, epoch seconds,\n * or ISO-8601. Digit strings are classified by length: 17 or more digits are\n * nanoseconds, 15-16 microseconds, 12-14 milliseconds, and fewer are seconds.\n */\nexport function epochMillis(value: unknown): number | null {\n if (typeof value === 'number')\n return Number.isFinite(value) ? scaleEpoch(value, String(Math.trunc(value)).length) : null\n if (typeof value !== 'string' || value.length === 0) return null\n if (/^\\d+$/.test(value)) {\n if (value.length >= 17) return Number(BigInt(value) / 1_000_000n)\n return scaleEpoch(Number(value), value.length)\n }\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? null : parsed\n}\n\nfunction scaleEpoch(value: number, digits: number): number {\n if (digits >= 17) return Math.trunc(value / 1_000_000)\n if (digits >= 15) return Math.trunc(value / 1_000)\n if (digits >= 12) return value\n return value * 1000\n}\n\nfunction isoOrEmpty(ms: number | null): string {\n return ms === null ? '' : new Date(ms).toISOString()\n}\n\nfunction mergedAttributes(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const resource = record.resource\n if (resource && typeof resource === 'object' && !Array.isArray(resource)) {\n const attrs = (resource as Record<string, unknown>).attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n }\n const attrs = record.attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n if (typeof record.scope_name === 'string' && out['otel.scope.name'] === undefined) {\n out['otel.scope.name'] = record.scope_name\n }\n return out\n}\n\nfunction readStatus(record: Record<string, unknown>): {\n code: DiagnosisSpanStatus\n message: string | null\n} {\n let code: unknown = record.status_code\n let message: unknown = record.status_message\n const status = record.status\n if (status && typeof status === 'object' && !Array.isArray(status)) {\n const object = status as Record<string, unknown>\n code = object.code ?? code\n message = object.message ?? message\n }\n const text = typeof code === 'string' ? code.toUpperCase() : code\n const normalized: DiagnosisSpanStatus =\n text === 2 || text === 'STATUS_CODE_ERROR' || text === 'ERROR' || text === '2'\n ? 'ERROR'\n : text === 1 || text === 'STATUS_CODE_OK' || text === 'OK' || text === '1'\n ? 'OK'\n : 'UNSET'\n return {\n code: normalized,\n message: typeof message === 'string' && message.length > 0 ? message : null,\n }\n}\n\n/**\n * The contract's classifier decides the kind, so the capability table and the\n * findings count the same tool and LLM spans. A top-level `kind` counts as a\n * declaration only when it is a contract kind; OTLP words such as\n * SPAN_KIND_INTERNAL fall through to the attribute and name signals.\n */\nfunction resolveKind(kind: unknown, name: string, attributes: Record<string, unknown>): SpanKind {\n const declared =\n typeof kind === 'string' && (SPAN_KINDS as readonly string[]).includes(kind.toUpperCase())\n ? kind.toUpperCase()\n : undefined\n return resolveSpanKind({ ...(declared ? { kind: declared } : {}), name, attributes })\n}\n\nfunction digestInput(attributes: Record<string, unknown>, key: Buffer): string | null {\n for (const name of INPUT_ATTRIBUTE_KEYS) {\n const value = attributes[name]\n if (value === undefined || value === null || value === '') continue\n const text = typeof value === 'string' ? value : JSON.stringify(value)\n return createHmac('sha256', key).update(text).digest('hex').slice(0, 16)\n }\n return null\n}\n\nfunction idField(\n record: Record<string, unknown>,\n snake: string,\n camel: string,\n): string | undefined {\n const value = record[snake] ?? record[camel]\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction firstString(attributes: Record<string, unknown>, keys: readonly string[]): string | null {\n for (const key of keys) {\n const value = attributes[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return null\n}\n\nfunction stringOr(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.length > 0 ? value : fallback\n}\n","/**\n * The deterministic pass: everything the engine can say without a model.\n *\n * It produces the capability table (the trace contract's own validator, so the\n * reasons are the trace's reasons), execution facts with token and cost\n * accounting (agent-eval's `fromOtelSpans` + `summarizeExecution`), and\n * `observed` findings computed directly from span data. Every observed finding\n * carries a measure with its denominator and cites the spans it counted.\n */\n\nimport { createHash } from 'node:crypto'\nimport { type TraceValidation, validateTraceSpans } from '@tangle-network/agent-trace-contract'\nimport { type ExecutionReport, summarizeExecution } from '../contract/analyze-runs'\nimport { fromOtelSpans } from '../contract/intake/otel-spans'\nimport type { TraceSpanEvent } from '../hosted/types'\nimport type {\n DiagnosisCapability,\n DiagnosisFinding,\n DiagnosisSeverity,\n DiagnosisSkippedAnalysis,\n} from './findings'\nimport { type FirstFailure, rankFirstFailure } from './first-failure'\nimport { type DiagnosisSpan, durationMs, toContractSpan } from './spans'\n\n/** Evidence ids cited per finding; the measure carries the full count. */\nexport const MAX_EVIDENCE_PER_FINDING = 8\n/**\n * Identical tool calls with no different tool call between them that count as\n * a repeated-call run. Model turns between the calls do not break the run: an\n * agent that calls, reads, and calls again with the same input is the waste\n * this detects.\n */\nexport const REPEAT_RUN_LENGTH = 3\n/** A tool is reported only once it has at least this many calls. */\nexport const MIN_TOOL_CALLS = 3\n\n/** The analysis each capability gates, as the report names it. */\nconst CAPABILITY_ANALYSES: Record<string, string> = {\n 'token-accounting': 'token accounting',\n 'cost-attribution': 'cost attribution',\n 'tool-usage': 'tool failure rates and repeated-call detection',\n 'loop-convergence': 'loop convergence (did round N+1 improve on round N)',\n 'tree-comparison': 'arm-vs-arm comparison across branches of one run',\n 'steering-chain': 'steering chain (which verdict caused which retry)',\n 'latency-analysis': 'latency distribution',\n}\n\n/**\n * Capabilities the engine reports but does not analyze itself, with where to\n * go instead. All three point at `@tangle-network/traces`, which reads\n * `links` (causal edges) that this engine's `DiagnosisSpan` does not carry —\n * extending it is the prerequisite for building these here instead of\n * pointing away from here.\n */\nconst NOT_BUILT = new Map([\n [\n 'loop-convergence',\n 'the engine has no round-over-round convergence analysis yet; ' +\n '@tangle-network/traces reads it from agent.loop.id/agent.loop.iteration (loopConvergence in src/loop-analysis)',\n ],\n [\n 'tree-comparison',\n 'the engine does not pick which arms to compare; diff two arms with diffSteps from /pipelines ' +\n '(traces diff <file>#branch=<a> <file>#branch=<b>)',\n ],\n [\n 'steering-chain',\n 'the engine has no steering-chain analysis yet; @tangle-network/traces reads it from span links ' +\n \"(steeringChain in src/loop-analysis, which this engine's DiagnosisSpan does not carry)\",\n ],\n])\n\nexport interface ExecutionFacts {\n runs: number\n spans: number\n spansByKind: Record<string, number>\n errorSpans: number\n toolCalls: number\n models: string[]\n /** The first failure of each run, in trace id order. See `rankFirstFailure`. */\n firstFailures: FirstFailure[]\n /** agent-eval execution summary; null with a reason when it could not be computed. */\n execution: ExecutionReport | null\n executionError?: string\n}\n\nexport interface DeterministicResult {\n validation: TraceValidation\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n facts: ExecutionFacts\n findings: DiagnosisFinding[]\n window: string\n}\n\nexport function runDeterministicPass(spans: readonly DiagnosisSpan[]): DeterministicResult {\n const validation = validateTraceSpans(spans.map(toContractSpan))\n const capabilities: Record<string, DiagnosisCapability> = {}\n const skipped: DiagnosisSkippedAnalysis[] = []\n for (const capability of validation.capabilities) {\n capabilities[capability.name] = capability.available\n ? { available: true }\n : {\n available: false,\n reason: capability.reason ?? 'the trace contract validator gave no reason',\n }\n const analysis = CAPABILITY_ANALYSES[capability.name] ?? capability.name\n if (!capability.available) {\n skipped.push({ analysis, reason: capability.reason ?? 'capability unavailable' })\n } else if (NOT_BUILT.has(capability.name)) {\n skipped.push({ analysis, reason: NOT_BUILT.get(capability.name)! })\n }\n }\n\n const traces = groupByTrace(spans)\n const findings: DiagnosisFinding[] = []\n const tools = spans.filter((span) => span.kind === 'TOOL')\n if (tools.length > 0) {\n findings.push(...toolFailureFindings(tools))\n const withDigest = tools.filter((span) => span.inputDigest !== null).length\n if (withDigest > 0) findings.push(...repeatedCallFindings(traces))\n else\n skipped.push({\n analysis: 'repeated identical tool calls',\n reason: `none of ${tools.length} tool spans carries its input, so identical calls cannot be told apart`,\n })\n } else {\n skipped.push({ analysis: 'tool failure rates', reason: 'no span resolves to kind TOOL' })\n }\n findings.push(...failedRunFindings(traces))\n\n const facts = executionFacts(spans, traces)\n return { validation, capabilities, skipped, facts, findings, window: timeWindow(spans) }\n}\n\nexport function groupByTrace(spans: readonly DiagnosisSpan[]): Map<string, DiagnosisSpan[]> {\n const traces = new Map<string, DiagnosisSpan[]>()\n for (const span of spans) {\n const list = traces.get(span.traceId)\n if (list) list.push(span)\n else traces.set(span.traceId, [span])\n }\n for (const list of traces.values()) list.sort(byStart)\n return traces\n}\n\nfunction toolFailureFindings(tools: readonly DiagnosisSpan[]): DiagnosisFinding[] {\n const byTool = new Map<string, DiagnosisSpan[]>()\n for (const span of tools) {\n const name = span.toolName ?? span.name\n const list = byTool.get(name)\n if (list) list.push(span)\n else byTool.set(name, [span])\n }\n const findings: DiagnosisFinding[] = []\n for (const [tool, calls] of byTool) {\n const failed = calls.filter((span) => span.status === 'ERROR')\n if (calls.length < MIN_TOOL_CALLS || failed.length < 2) continue\n const rate = failed.length / calls.length\n const severity: DiagnosisSeverity =\n rate >= 0.5 && failed.length >= 5 ? 'high' : rate >= 0.2 ? 'medium' : 'low'\n findings.push({\n id: stableId('tool-failures', tool),\n severity,\n claim: `${failed.length} of ${calls.length} calls to the ${tool} tool failed.`,\n consequence: `Each failed call spends a model turn noticing the error and retrying, so ${pct(rate)} of this tool's calls bought no progress.`,\n measure: {\n name: `${tool} tool failure rate`,\n value: round(rate * 100),\n unit: '%',\n denominator: `${calls.length} calls to ${tool}`,\n },\n evidence: failed.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation: `Read the failed ${tool} calls' status messages and fix the most common cause, or give the agent the precondition it keeps missing.`,\n })\n }\n return findings.sort((a, b) => (b.measure?.value ?? 0) - (a.measure?.value ?? 0)).slice(0, 10)\n}\n\nfunction repeatedCallFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const runs: DiagnosisSpan[][] = []\n let digestCalls = 0\n for (const spans of traces.values()) {\n let current: DiagnosisSpan[] = []\n for (const span of spans) {\n if (span.kind !== 'TOOL' || span.inputDigest === null) continue\n digestCalls += 1\n const last = current[current.length - 1]\n if (\n last &&\n last.inputDigest === span.inputDigest &&\n (last.toolName ?? last.name) === (span.toolName ?? span.name)\n ) {\n current.push(span)\n } else {\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n current = [span]\n }\n }\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n }\n if (runs.length === 0) return []\n const wasted = runs.reduce((sum, run) => sum + run.length - 1, 0)\n const tracesAffected = new Set(runs.map((run) => run[0]!.traceId)).size\n runs.sort((a, b) => b.length - a.length)\n const evidence = runs\n .flatMap((run) => run.slice(0, 2).map((span) => span.spanId))\n .slice(0, MAX_EVIDENCE_PER_FINDING)\n const rate = wasted / digestCalls\n return [\n {\n id: stableId('repeated-calls', String(runs.length)),\n severity: rate >= 0.1 ? 'high' : rate >= 0.03 ? 'medium' : 'low',\n claim: `The agent made the same tool call with the same input ${REPEAT_RUN_LENGTH} or more times with no other tool call in between, ${runs.length} times across ${tracesAffected} runs; the longest streak was ${runs[0]!.length} calls.`,\n consequence: `${wasted} calls repeated the previous tool call with the same input, which is work the agent paid for twice without new information.`,\n measure: {\n name: 'repeated identical tool calls',\n value: wasted,\n unit: 'calls',\n denominator: `${digestCalls} tool calls with recorded input`,\n },\n evidence,\n confidence: 'observed',\n recommendation:\n 'Detect a repeated identical call in the harness and stop or change strategy after the second attempt.',\n },\n ]\n}\n\nfunction failedRunFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const failedRoots: DiagnosisSpan[] = []\n for (const spans of traces.values()) {\n const ids = new Set(spans.map((span) => span.spanId))\n const root = spans.find((span) => span.parentSpanId === null || !ids.has(span.parentSpanId))\n if (root?.status === 'ERROR') failedRoots.push(root)\n }\n if (failedRoots.length === 0) return []\n const rate = failedRoots.length / traces.size\n return [\n {\n id: stableId('failed-runs', String(traces.size)),\n severity: rate >= 0.25 ? 'critical' : rate >= 0.1 ? 'high' : 'medium',\n claim: `${failedRoots.length} of ${traces.size} runs ended with an error on their root span.`,\n consequence:\n 'A run that ends in an error delivered nothing its caller can use, and any tokens it spent are lost.',\n measure: {\n name: 'failed runs',\n value: round(rate * 100),\n unit: '%',\n denominator: `${traces.size} runs`,\n },\n evidence: failedRoots.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation:\n 'Group the failed runs by their root status message and fix the largest group first.',\n },\n ]\n}\n\nfunction executionFacts(\n spans: readonly DiagnosisSpan[],\n traces: ReadonlyMap<string, DiagnosisSpan[]>,\n): ExecutionFacts {\n const spansByKind: Record<string, number> = {}\n const models = new Set<string>()\n let errorSpans = 0\n let toolCalls = 0\n for (const span of spans) {\n spansByKind[span.kind] = (spansByKind[span.kind] ?? 0) + 1\n if (span.status === 'ERROR') errorSpans += 1\n if (span.kind === 'TOOL') toolCalls += 1\n if (span.model) models.add(span.model)\n }\n const facts: ExecutionFacts = {\n runs: traces.size,\n spans: spans.length,\n spansByKind,\n errorSpans,\n toolCalls,\n models: [...models].sort(),\n firstFailures: [...traces.keys()]\n .sort()\n .map((traceId) => rankFirstFailure(traces.get(traceId)!)),\n execution: null,\n }\n try {\n facts.execution = summarizeExecution({\n runs: fromOtelSpans({ spans: spans.map(toTraceSpanEvent) }),\n })\n } catch (error) {\n facts.executionError = error instanceof Error ? error.message : String(error)\n }\n return facts\n}\n\nfunction toTraceSpanEvent(span: DiagnosisSpan): TraceSpanEvent {\n const attributes: Record<string, string | number | boolean> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (typeof value === 'string' || typeof value === 'boolean') attributes[key] = value\n else if (typeof value === 'number' && Number.isFinite(value)) attributes[key] = value\n }\n if (span.kind !== 'UNKNOWN' && attributes['openinference.span.kind'] === undefined) {\n attributes['openinference.span.kind'] = span.kind\n }\n const start = span.startMs ?? 0\n const end = span.endMs ?? start\n return {\n traceId: span.traceId,\n spanId: span.spanId,\n ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),\n name: span.name,\n startTimeUnixNano: `${BigInt(Math.trunc(start)) * 1_000_000n}`,\n endTimeUnixNano: `${BigInt(Math.trunc(end)) * 1_000_000n}`,\n attributes,\n status: { code: span.status, ...(span.statusMessage ? { message: span.statusMessage } : {}) },\n }\n}\n\nfunction timeWindow(spans: readonly DiagnosisSpan[]): string {\n let first = Number.POSITIVE_INFINITY\n let last = Number.NEGATIVE_INFINITY\n for (const span of spans) {\n if (span.startMs !== null) first = Math.min(first, span.startMs)\n const end = span.endMs ?? span.startMs\n if (end !== null) last = Math.max(last, end)\n }\n if (!Number.isFinite(first) || !Number.isFinite(last)) return 'unknown'\n return `${new Date(first).toISOString()}/${new Date(last).toISOString()}`\n}\n\nfunction byStart(a: DiagnosisSpan, b: DiagnosisSpan): number {\n return (a.startMs ?? 0) - (b.startMs ?? 0) || (durationMs(b) ?? 0) - (durationMs(a) ?? 0)\n}\n\nexport function stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}-${createHash('sha256').update(parts.join('\\u0000')).digest('hex').slice(0, 12)}`\n}\n\nfunction pct(rate: number): string {\n return `${round(rate * 100)}%`\n}\n\nfunction round(value: number): number {\n return Math.round(value * 10) / 10\n}\n","/**\n * The diagnosis findings document: what the engine returns and what the\n * diagnosis report renders. It mirrors the kit's JSON Schema\n * (`https://tangle.tools/schemas/diagnosis-findings-v1.json`, owned by the\n * traces repository's diagnosis kit) field for field, including its closed\n * objects, so a document that passes {@link validateDiagnosisFindings} passes\n * that schema.\n */\n\nexport const DIAGNOSIS_FINDINGS_SCHEMA_ID =\n 'https://tangle.tools/schemas/diagnosis-findings-v1.json'\n\nexport type DiagnosisSeverity = 'critical' | 'high' | 'medium' | 'low'\n\n/** `observed` is read directly off the trace; `inferred` is a model's reading of it. */\nexport type DiagnosisConfidence = 'observed' | 'inferred'\n\nexport interface DiagnosisMeasure {\n name: string\n value: number\n unit: string\n /** What the value is out of. The engine always sets it; a rate without one is not reportable. */\n denominator: string\n}\n\nexport interface DiagnosisFinding {\n id: string\n severity: DiagnosisSeverity\n claim: string\n consequence: string\n measure?: DiagnosisMeasure\n /** Verbatim span ids from the input. Never empty. */\n evidence: string[]\n reproduce?: string\n confidence: DiagnosisConfidence\n recommendation?: string\n}\n\nexport interface DiagnosisCapability {\n available: boolean\n reason?: string\n}\n\nexport interface DiagnosisSkippedAnalysis {\n analysis: string\n reason: string\n}\n\nexport interface DiagnosisRedaction {\n redactionCount: number\n byRule: Record<string, number>\n droppedAttributes: string[]\n}\n\nexport interface DiagnosisFindingsDocument {\n schemaVersion: 1\n subject: {\n label: string\n runCount: number\n window: string\n contentIncluded?: boolean\n }\n coverage: {\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n redaction?: DiagnosisRedaction\n }\n findings: DiagnosisFinding[]\n}\n\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\nexport const SEVERITY_RANK: Record<DiagnosisSeverity, number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n}\n\n/**\n * Structural check against the v1 schema plus the two rules the schema states\n * in prose: an unavailable capability carries a reason, and a measure carries a\n * denominator. When `spanIds` is given, every evidence id must resolve to it.\n * Returns the list of defects; empty means valid.\n */\nexport function validateDiagnosisFindings(\n document: unknown,\n options: { spanIds?: ReadonlySet<string> } = {},\n): string[] {\n const errors: string[] = []\n if (!isObject(document)) return ['document is not an object']\n closed(document, ['schemaVersion', 'subject', 'coverage', 'findings'], '', errors)\n if (document.schemaVersion !== 1) errors.push('schemaVersion must be 1')\n\n const subject = document.subject\n if (!isObject(subject)) errors.push('subject must be an object')\n else {\n closed(subject, ['label', 'runCount', 'window', 'contentIncluded'], 'subject', errors)\n if (typeof subject.label !== 'string') errors.push('subject.label must be a string')\n if (!Number.isInteger(subject.runCount) || (subject.runCount as number) < 0)\n errors.push('subject.runCount must be a non-negative integer')\n if (typeof subject.window !== 'string') errors.push('subject.window must be a string')\n if (subject.contentIncluded !== undefined && typeof subject.contentIncluded !== 'boolean')\n errors.push('subject.contentIncluded must be a boolean')\n }\n\n const coverage = document.coverage\n if (!isObject(coverage)) errors.push('coverage must be an object')\n else {\n closed(coverage, ['capabilities', 'skipped', 'redaction'], 'coverage', errors)\n if (!isObject(coverage.capabilities)) errors.push('coverage.capabilities must be an object')\n else {\n for (const [name, capability] of Object.entries(coverage.capabilities)) {\n if (!isObject(capability) || typeof capability.available !== 'boolean') {\n errors.push(`coverage.capabilities.${name}.available must be a boolean`)\n } else if (\n !capability.available &&\n !(typeof capability.reason === 'string' && capability.reason)\n ) {\n errors.push(`coverage.capabilities.${name} is unavailable without a reason`)\n }\n }\n }\n if (!Array.isArray(coverage.skipped)) errors.push('coverage.skipped must be an array')\n else\n coverage.skipped.forEach((entry, index) => {\n if (\n !isObject(entry) ||\n typeof entry.analysis !== 'string' ||\n typeof entry.reason !== 'string'\n )\n errors.push(`coverage.skipped[${index}] needs analysis and reason strings`)\n })\n if (coverage.redaction !== undefined) {\n const redaction = coverage.redaction\n if (!isObject(redaction)) errors.push('coverage.redaction must be an object')\n else {\n if (!Number.isInteger(redaction.redactionCount) || (redaction.redactionCount as number) < 0)\n errors.push('coverage.redaction.redactionCount must be a non-negative integer')\n if (redaction.byRule !== undefined && !isObject(redaction.byRule))\n errors.push('coverage.redaction.byRule must be an object')\n if (\n redaction.droppedAttributes !== undefined &&\n !Array.isArray(redaction.droppedAttributes)\n )\n errors.push('coverage.redaction.droppedAttributes must be an array')\n }\n }\n }\n\n if (!Array.isArray(document.findings)) errors.push('findings must be an array')\n else\n document.findings.forEach((finding, index) => {\n const at = `findings[${index}]`\n if (!isObject(finding)) {\n errors.push(`${at} must be an object`)\n return\n }\n closed(\n finding,\n [\n 'id',\n 'severity',\n 'claim',\n 'consequence',\n 'measure',\n 'evidence',\n 'reproduce',\n 'confidence',\n 'recommendation',\n ],\n at,\n errors,\n )\n for (const key of ['id', 'claim', 'consequence'] as const) {\n if (typeof finding[key] !== 'string' || !(finding[key] as string))\n errors.push(`${at}.${key} must be a non-empty string`)\n }\n if (!SEVERITIES.has(finding.severity as string)) errors.push(`${at}.severity is invalid`)\n if (finding.confidence !== 'observed' && finding.confidence !== 'inferred')\n errors.push(`${at}.confidence must be observed or inferred`)\n if (!Array.isArray(finding.evidence) || finding.evidence.length === 0)\n errors.push(`${at}.evidence must be a non-empty array`)\n else\n for (const id of finding.evidence) {\n if (typeof id !== 'string') errors.push(`${at}.evidence holds a non-string`)\n else if (options.spanIds && !options.spanIds.has(id))\n errors.push(`${at}.evidence ${id} does not resolve`)\n }\n if (finding.measure !== undefined) {\n const measure = finding.measure\n if (\n !isObject(measure) ||\n typeof measure.name !== 'string' ||\n typeof measure.value !== 'number' ||\n !Number.isFinite(measure.value) ||\n typeof measure.unit !== 'string'\n ) {\n errors.push(`${at}.measure needs name, finite value and unit`)\n } else if (!(typeof measure.denominator === 'string' && measure.denominator)) {\n errors.push(`${at}.measure has no denominator`)\n }\n }\n for (const key of ['reproduce', 'recommendation'] as const) {\n if (finding[key] !== undefined && typeof finding[key] !== 'string')\n errors.push(`${at}.${key} must be a string`)\n }\n })\n return errors\n}\n\nfunction closed(\n value: Record<string, unknown>,\n allowed: readonly string[],\n at: string,\n errors: string[],\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) errors.push(`${at ? `${at}.` : ''}${key} is not allowed`)\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n","/**\n * The model pass: one prime-protocol exchange per selected run.\n *\n * The run's filtered spans are inlined into the prompt (prime has no trace\n * tools), the reply is one fenced JSON block of short rows, and each row that\n * claims a defect must cite span ids from that run. A row citing an id the run\n * does not hold, or an id that several runs share, is rejected with the reason\n * recorded, never repaired by guessing. Every accepted finding is `inferred`:\n * it is the model's reading, and the report keeps it apart from what the\n * deterministic pass observed.\n */\n\nimport type { PrimeBridgeTransport } from '../analyst/prime-bridge-transport'\nimport {\n buildPrimePrompt,\n type PrimeRawUsage,\n type PrimeReplyContract,\n primeProtocolSha256,\n runPrimeExchange,\n} from '../analyst/prime-protocol'\nimport { stableId } from './deterministic'\nimport type { DiagnosisFinding, DiagnosisSeverity } from './findings'\nimport { type DiagnosisSpan, durationMs } from './spans'\n\nexport interface DiagnosisModelOptions {\n /** One POST-shaped call to an OpenAI-compatible chat endpoint, or an equivalent local runner. */\n transport: PrimeBridgeTransport\n /** Endpoint the transport receives, e.g. `http://127.0.0.1:4181/v1/chat/completions`. */\n url: string\n /** Model id as the endpoint names it, e.g. `deepseek/deepseek-v4.1-flash`. */\n model: string\n /** Runs read by the model per diagnosis. Default 6. */\n maxTraces?: number\n /** Deadline for one exchange turn. Default 10 minutes. */\n timeoutMs?: number\n /** Inline budget for one rendered run. Default 400,000 characters. */\n maxInlineChars?: number\n /** Per-attribute character cap for the rendering. Default 600. */\n attributeChars?: number\n /** Segments of one long run the model reads, most errors first. Default 3. */\n maxSegmentsPerRun?: number\n /** Exact token rates; without them cost stays uncaptured. */\n pricing?: { inputUsdPerMillion: number; outputUsdPerMillion: number }\n}\n\nexport interface ModelRowNote {\n kind: 'operator' | 'topology'\n text: string\n evidence: string[]\n traceId?: string\n project?: string\n}\n\nexport interface ModelQuestion {\n question: string\n project?: string\n traceId?: string\n}\n\nexport interface ModelRejection {\n traceId?: string\n reason: string\n}\n\nexport interface ModelRunRecord {\n traceId: string\n ok: boolean\n failure?: string\n delivery?: { segment: number; segments: number; renderedChars: number }\n usage: PrimeRawUsage\n rows: number\n}\n\nexport interface ModelPassResult {\n findings: DiagnosisFinding[]\n questions: ModelQuestion[]\n notes: ModelRowNote[]\n summaries: Array<{ traceId: string; answer: string }>\n rejected: ModelRejection[]\n /** Runs the model read only in part, with which segments it read. */\n uncovered: ModelRejection[]\n runs: ModelRunRecord[]\n promptSha256: string\n}\n\nexport interface ModelPassInput {\n subject: 'internal' | 'customer'\n focus?: string\n projects?: readonly string[]\n contentIncluded: boolean\n}\n\ninterface RawRow {\n kind: 'finding' | 'question' | 'operator' | 'topology'\n severity?: DiagnosisSeverity\n claim?: string\n consequence?: string\n recommendation?: string\n question?: string\n project?: string\n evidence: string[]\n}\n\nconst MAX_ROWS = 12\nconst MAX_STRING = 400\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\n\nexport function modelQuestion(input: ModelPassInput): string {\n const focus = input.focus ? ` The owner's question: ${input.focus}` : ''\n const projects =\n input.projects && input.projects.length > 0\n ? ` The runs belong to these projects: ${input.projects.join(', ')}; set \"project\" on a row to one of these names when the run shows which one it concerns.`\n : ''\n const withheld = input.contentIncluded\n ? ''\n : \" Prompt, response and tool payload content was withheld at the owner's choice; do not report its absence as a defect, and reason from span names, kinds, order, timing, status and the remaining attributes.\"\n return input.subject === 'internal'\n ? `Diagnose this coding-agent session from our own fleet: find concrete agent failures, wasted work, unsupported claims of success, and where the human operator's instructions caused trouble.${withheld}${projects}${focus}`\n : `Diagnose this agent run: find concrete failures, wasted work, and unsupported claims of success that cost the owner money, time, or correct results.${withheld}${projects}${focus}`\n}\n\nexport function modelContractLines(subject: 'internal' | 'customer'): string[] {\n const kinds =\n subject === 'internal' ? '\"finding\" | \"question\" | \"operator\"' : '\"finding\" | \"question\"'\n return [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) summarising what went wrong in this run, or that nothing did.',\n ` \"rows\": an array of at most ${MAX_ROWS} objects, each with \"kind\": ${kinds}.`,\n 'A \"finding\" row: {\"kind\":\"finding\",\"severity\":\"critical|high|medium|low\",\"claim\":\"one sentence stating the defect\",\"consequence\":\"what it cost in money, time, failed work or escalations\",\"recommendation\":\"the fix\",\"evidence\":[\"<span_id>\", ...]}.',\n 'A \"question\" row: {\"kind\":\"question\",\"question\":\"a concrete question the owner should answer\",\"evidence\":[]}.',\n ...(subject === 'internal'\n ? [\n 'An \"operator\" row: {\"kind\":\"operator\",\"claim\":\"one sentence critiquing how the human operator instructed or steered the agent\",\"evidence\":[\"<span_id>\", ...]}.',\n ]\n : []),\n 'Add \"project\": \"<repo or project name>\" to any row when the run shows which project it belongs to.',\n 'Every \"finding\" and \"operator\" row cites 1-8 span ids copied VERBATIM from the \"id\" fields of the trajectory. Rows citing ids that are not in the trajectory are discarded.',\n 'For elapsed wall time, compare the start and end timestamps and count overlapping spans only once. Do not add overlapping ms durations or call their sum a stall. If timestamps are missing, do not claim a total wall delay.',\n 'Keep every string under 400 characters. Report only what the trajectory shows; an empty rows array is a valid answer.',\n ]\n}\n\nexport async function runModelPass(\n traces: ReadonlyArray<{ traceId: string; spans: readonly DiagnosisSpan[] }>,\n ambiguousSpanIds: ReadonlySet<string>,\n input: ModelPassInput,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<ModelPassResult> {\n const question = modelQuestion(input)\n const contractLines = modelContractLines(input.subject)\n const promptSha256 = primeProtocolSha256({\n question,\n contractLines,\n repairContractLines: contractLines,\n limits: { maxRows: MAX_ROWS, maxString: MAX_STRING },\n })\n const result: ModelPassResult = {\n findings: [],\n questions: [],\n notes: [],\n summaries: [],\n rejected: [],\n uncovered: [],\n runs: [],\n promptSha256,\n }\n const maxInlineChars = options.maxInlineChars ?? 400_000\n const attributeChars = options.attributeChars ?? 600\n\n const maxSegments = options.maxSegmentsPerRun ?? 3\n for (const { traceId, spans } of traces) {\n const segments = segmentRun(spans, attributeChars, input.contentIncluded, maxInlineChars)\n const chosen = segments\n .map((segment, index) => ({ ...segment, index }))\n .sort((a, b) => b.errors - a.errors || a.index - b.index)\n .slice(0, maxSegments)\n .sort((a, b) => a.index - b.index)\n if (segments.length > chosen.length) {\n result.uncovered.push({\n traceId,\n reason: `the run renders to ${segments.length} segments of at most ${maxInlineChars} characters; the model read the ${chosen.length} with the most errors (${chosen.map((segment) => segment.index + 1).join(', ')})`,\n })\n }\n for (const segment of chosen) {\n const label =\n segments.length > 1 ? `${traceId} segment ${segment.index + 1}/${segments.length}` : traceId\n const ids = new Set(segment.spans.map((span) => span.spanId))\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, input.subject),\n } satisfies PrimeReplyContract<RawRow>,\n prompt: buildPrimePrompt({\n question,\n contractLines,\n trajectoryHeader: `TRAJECTORY (run ${label}; ${segment.spans.length} of the run's ${spans.length} spans, in start order; secrets redacted as [REDACTED:<kind>]):`,\n renderedTrajectory: segment.rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const delivery = {\n segment: segment.index + 1,\n segments: segments.length,\n renderedChars: segment.rendered.length,\n }\n if (!outcome.ok) {\n result.runs.push({\n traceId,\n ok: false,\n failure: `${label}: ${outcome.failure.kind}: ${outcome.failure.message}`,\n delivery,\n usage: outcome.usage,\n rows: 0,\n })\n continue\n }\n for (const rejection of outcome.rejected) {\n result.rejected.push({ traceId, reason: `row ${rejection.index}: ${rejection.reason}` })\n }\n if (outcome.overflow > 0) {\n result.rejected.push({\n traceId,\n reason: `${outcome.overflow} valid rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (outcome.answer)\n result.summaries.push({ traceId, answer: outcome.answer.slice(0, MAX_STRING) })\n acceptRows(result, outcome.rows, traceId, ids, ambiguousSpanIds)\n result.runs.push({\n traceId,\n ok: true,\n delivery,\n usage: outcome.usage,\n rows: outcome.rows.length,\n })\n }\n }\n return result\n}\n\n/** The topology reading: one exchange over the caller's run-graph summary, internal runs only. */\nexport async function runTopologyPass(\n topology: unknown,\n runIds: ReadonlySet<string>,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<{\n notes: ModelRowNote[]\n questions: ModelQuestion[]\n rejected: ModelRejection[]\n run: ModelRunRecord\n}> {\n const contractLines = [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) on how the agent fleet was organised today.',\n ` \"rows\": at most ${MAX_ROWS} objects, each either {\"kind\":\"topology\",\"claim\":\"one sentence on a spawn, messaging, hand-off or resume pattern that helped or hurt\",\"evidence\":[\"<run id>\", ...],\"project\":\"<optional>\"} or {\"kind\":\"question\",\"question\":\"...\",\"project\":\"<optional>\",\"evidence\":[]}.`,\n 'Every \"topology\" row cites 1-8 run ids copied VERBATIM from the graph. Keep every string under 400 characters.',\n ]\n const rendered = JSON.stringify(topology)\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, 'topology'),\n },\n prompt: buildPrimePrompt({\n question:\n \"Analyse the topology of this agent fleet's runs: who spawned whom, who messaged whom, hand-offs and resumes. Name patterns that wasted work or lost context, and what to change.\",\n contractLines,\n trajectoryHeader: `RUN GRAPH (${runIds.size} runs):`,\n renderedTrajectory:\n rendered.length > (options.maxInlineChars ?? 400_000)\n ? rendered.slice(0, options.maxInlineChars ?? 400_000)\n : rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const notes: ModelRowNote[] = []\n const questions: ModelQuestion[] = []\n const rejected: ModelRejection[] = []\n if (outcome.ok && outcome.overflow > 0) {\n rejected.push({\n reason: `${outcome.overflow} valid topology rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (!outcome.ok) {\n return {\n notes,\n questions,\n rejected,\n run: {\n traceId: 'topology',\n ok: false,\n failure: `${outcome.failure.kind}: ${outcome.failure.message}`,\n usage: outcome.usage,\n rows: 0,\n },\n }\n }\n for (const row of outcome.rows) {\n if (row.kind === 'question') {\n questions.push({ question: row.question!, ...(row.project ? { project: row.project } : {}) })\n continue\n }\n const cited = row.evidence.filter((id) => runIds.has(id))\n if (cited.length === 0) {\n rejected.push({\n reason: `topology row \"${(row.claim ?? '').slice(0, 80)}\" cites no run id from the graph`,\n })\n continue\n }\n notes.push({\n kind: 'topology',\n text: row.claim!,\n evidence: cited,\n ...(row.project ? { project: row.project } : {}),\n })\n }\n if (outcome.answer)\n notes.unshift({ kind: 'topology', text: outcome.answer.slice(0, MAX_STRING), evidence: [] })\n return {\n notes,\n questions,\n rejected,\n run: { traceId: 'topology', ok: true, usage: outcome.usage, rows: outcome.rows.length },\n }\n}\n\nfunction acceptRows(\n result: ModelPassResult,\n rows: readonly RawRow[],\n traceId: string,\n ids: ReadonlySet<string>,\n ambiguousSpanIds: ReadonlySet<string>,\n): void {\n for (const row of rows) {\n const unresolved = row.evidence.filter((id) => !ids.has(id))\n const ambiguous = row.evidence.filter((id) => ambiguousSpanIds.has(id))\n const cited = row.evidence.filter((id) => ids.has(id) && !ambiguousSpanIds.has(id))\n if (unresolved.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids not in the segment it read: ${unresolved.slice(0, 5).join(', ')}`,\n })\n if (ambiguous.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids shared by several runs: ${ambiguous.slice(0, 5).join(', ')}`,\n })\n if (row.kind === 'question') {\n result.questions.push({\n question: row.question!,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n // A claim that leaned on an invalid id is not supported by the valid ones\n // left over, so the whole row goes rather than a trimmed version of it.\n if (unresolved.length > 0 || ambiguous.length > 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" discarded: it cites invalid evidence`,\n })\n continue\n }\n if (cited.length === 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" has no resolvable evidence`,\n })\n continue\n }\n if (row.kind === 'operator') {\n result.notes.push({\n kind: 'operator',\n text: row.claim!,\n evidence: cited,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n result.findings.push({\n id: stableId('inferred', traceId, row.claim!),\n severity: row.severity!,\n claim: row.claim!,\n consequence: row.consequence!,\n evidence: cited,\n confidence: 'inferred',\n ...(row.recommendation ? { recommendation: row.recommendation } : {}),\n })\n }\n}\n\ninterface RunSegment {\n spans: DiagnosisSpan[]\n rendered: string\n errors: number\n}\n\n/**\n * Split a run, in start order, into contiguous segments that each render\n * within the inline budget. Inline is prime's only delivery, so a long run is\n * read as whole segments rather than silently truncated; which segments were\n * read and which were not is recorded by the caller.\n */\nexport function segmentRun(\n spans: readonly DiagnosisSpan[],\n attributeChars: number,\n contentIncluded: boolean,\n maxInlineChars: number,\n): RunSegment[] {\n const segments: RunSegment[] = []\n let current: DiagnosisSpan[] = []\n let parts: string[] = []\n let size = 2\n let errors = 0\n const flush = () => {\n if (current.length === 0) return\n segments.push({ spans: current, rendered: `[${parts.join(',')}]`, errors })\n current = []\n parts = []\n size = 2\n errors = 0\n }\n for (const span of spans) {\n let part = JSON.stringify(renderSpan(span, attributeChars, contentIncluded))\n if (part.length + 2 > maxInlineChars)\n part = JSON.stringify(renderSpan(span, 120, contentIncluded))\n if (size + part.length + 1 > maxInlineChars) flush()\n current.push(span)\n parts.push(part)\n size += part.length + 1\n if (span.status === 'ERROR') errors += 1\n }\n flush()\n return segments\n}\n\nfunction decodeRow(\n row: unknown,\n mode: 'internal' | 'customer' | 'topology',\n): { ok: true; row: RawRow } | { ok: false; reason: string } {\n if (row === null || typeof row !== 'object' || Array.isArray(row))\n return { ok: false, reason: 'row is not an object' }\n const value = row as Record<string, unknown>\n const kind = value.kind\n const allowed =\n mode === 'internal'\n ? ['finding', 'question', 'operator']\n : mode === 'customer'\n ? ['finding', 'question']\n : ['topology', 'question']\n if (typeof kind !== 'string' || !allowed.includes(kind))\n return { ok: false, reason: `kind ${String(kind)} is not allowed here` }\n const evidence = Array.isArray(value.evidence)\n ? value.evidence\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .slice(0, 8)\n : []\n const project = shortString(value.project)\n if (kind === 'question') {\n const question = shortString(value.question)\n if (!question) return { ok: false, reason: 'question row has no question' }\n return { ok: true, row: { kind, question, evidence, ...(project ? { project } : {}) } }\n }\n const claim = shortString(value.claim)\n if (!claim) return { ok: false, reason: `${kind} row has no claim` }\n if (kind !== 'finding')\n return {\n ok: true,\n row: { kind: kind as RawRow['kind'], claim, evidence, ...(project ? { project } : {}) },\n }\n const severity = value.severity\n if (typeof severity !== 'string' || !SEVERITIES.has(severity))\n return { ok: false, reason: `severity ${String(severity)} is invalid` }\n const consequence = shortString(value.consequence)\n if (!consequence) return { ok: false, reason: 'finding row has no consequence' }\n const recommendation = shortString(value.recommendation)\n return {\n ok: true,\n row: {\n kind: 'finding',\n severity: severity as DiagnosisSeverity,\n claim,\n consequence,\n evidence,\n ...(recommendation ? { recommendation } : {}),\n ...(project ? { project } : {}),\n },\n }\n}\n\n/** One span as the model reads it: the pivots, then the attributes that remain after filtering. */\nfunction renderSpan(\n span: DiagnosisSpan,\n attributeChars: number,\n contentIncluded: boolean,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {\n id: span.spanId,\n parent: span.parentSpanId,\n kind: span.kind,\n name: span.name,\n }\n if (span.toolName) out.tool = span.toolName\n if (span.model) out.model = span.model\n if (span.status !== 'UNSET') out.status = span.status\n if (span.statusMessage) out.status_message = clip(span.statusMessage, attributeChars)\n const duration = durationMs(span)\n if (duration !== null) out.ms = duration\n if (span.startMs !== null && span.endMs !== null) {\n out.start = new Date(span.startMs).toISOString()\n out.end = new Date(span.endMs).toISOString()\n }\n const attrs: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (SKIP_ATTRIBUTES.has(key)) continue\n if (typeof value === 'string') attrs[key] = clip(value, attributeChars)\n else if (typeof value === 'number' || typeof value === 'boolean') attrs[key] = value\n else if (value !== null && value !== undefined)\n attrs[key] = clip(JSON.stringify(value), attributeChars)\n }\n if (Object.keys(attrs).length > 0) out.attrs = attrs\n if (!contentIncluded) out.content = 'withheld'\n return out\n}\n\n/** Pivots already rendered above, and resource noise that repeats on every span. */\nconst SKIP_ATTRIBUTES = new Set([\n 'openinference.span.kind',\n 'tool.name',\n 'gen_ai.tool.name',\n 'llm.model_name',\n 'gen_ai.request.model',\n 'service.name',\n 'agent.name',\n 'source_file',\n 'otel.scope.name',\n 'telemetry.sdk.name',\n 'telemetry.sdk.language',\n 'telemetry.sdk.version',\n])\n\nfunction clip(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max)}…[+${value.length - max} chars]`\n}\n\nfunction shortString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n if (!trimmed) return undefined\n return trimmed.length <= MAX_STRING ? trimmed : `${trimmed.slice(0, MAX_STRING)}…`\n}\n","/**\n * The agent-failure diagnosis engine: flat spans plus context in, a findings\n * document out.\n *\n * It is a plain function. Its only side effect is the model call made through\n * the caller's transport, and in deterministic mode it makes none. It keeps no\n * storage, files no issues, and retains nothing: where the spans came from and\n * where the findings go belong to the caller. That is what lets one engine\n * serve both the internal daily mining run and a customer diagnosis while their\n * data paths stay separate.\n *\n * Order of operations, each step reading only the previous step's output:\n * 1. secret filter and content drop over every input (spans, focus, topology);\n * 2. the deterministic pass: capability table, execution facts, observed findings;\n * 3. in model mode, the prime-protocol pass over the highest-signal runs;\n * 4. evidence resolution: every cited id must be a span id of the input that\n * no other run shares; findings left without evidence are rejected.\n */\n\nimport { packageVersion } from '../package-version'\nimport { redact, redactText } from '../trace/redact'\nimport { type DeterministicResult, groupByTrace, runDeterministicPass } from './deterministic'\nimport {\n type DiagnosisFinding,\n type DiagnosisFindingsDocument,\n SEVERITY_RANK,\n validateDiagnosisFindings,\n} from './findings'\nimport {\n type DiagnosisModelOptions,\n type ModelQuestion,\n type ModelRejection,\n type ModelRowNote,\n type ModelRunRecord,\n runModelPass,\n runTopologyPass,\n} from './model-pass'\nimport { type IngestReport, ingestSpans } from './spans'\n\nexport interface DiagnosisContext {\n /** Whose traces these are. Operator critique and topology run only for `internal`. */\n subject: 'internal' | 'customer'\n /** What was analysed, in the owner's words. Never an internal id for a customer. */\n label: string\n /** The owner's question, e.g. from the intake form. */\n focus?: string\n /**\n * Whether prompt, response and tool payload attributes may be read. Default\n * false: they are dropped before anything reads the spans.\n */\n contentIncluded?: boolean\n /** Project or repository names the runs belong to, for grouping questions. */\n projects?: string[]\n /** A run-graph summary (internal only), e.g. from the lineage graph. */\n topology?: { runs: Array<{ id: string } & Record<string, unknown>> } & Record<string, unknown>\n}\n\nexport type DiagnosisOptions =\n | { mode: 'deterministic'; reason?: string; signal?: AbortSignal }\n | { mode: 'model'; model: DiagnosisModelOptions; signal?: AbortSignal }\n\nexport interface DiagnosisUsage {\n exchanges: number\n inputTokens: number | null\n outputTokens: number | null\n usd: number | null\n}\n\nexport interface DiagnosisResult {\n /** Validates against diagnosis-findings-v1. The only part a customer report renders. */\n document: DiagnosisFindingsDocument\n /** Questions for the owner, grouped later by project. */\n questions: ModelQuestion[]\n /** Operator critique and topology notes; internal runs only. */\n notes: ModelRowNote[]\n /** The model's one-paragraph reading of each run it read. */\n summaries: Array<{ traceId: string; answer: string }>\n facts: DeterministicResult['facts']\n conformance: DeterministicResult['validation']['findings']\n ingest: IngestReport\n /** Model rows and findings dropped, each with why. */\n rejected: ModelRejection[]\n model: {\n used: boolean\n model: string | null\n runs: ModelRunRecord[]\n promptSha256: string | null\n usage: DiagnosisUsage\n }\n engine: { name: 'agent-eval/diagnosis'; version: string }\n}\n\nexport const DEFAULT_MAX_MODEL_TRACES = 6\n/** Runs with fewer spans carry too little for the model to read. */\nexport const MIN_MODEL_SPANS = 3\n\nexport async function diagnoseSpans(\n spans: readonly unknown[],\n context: DiagnosisContext,\n options: DiagnosisOptions,\n): Promise<DiagnosisResult> {\n if (context.subject !== 'internal' && context.subject !== 'customer') {\n throw new TypeError(\n `diagnoseSpans: subject must be internal or customer, got ${String(context.subject)}`,\n )\n }\n if (context.subject === 'customer' && context.topology !== undefined) {\n throw new TypeError(\n 'diagnoseSpans: topology analysis is internal only; a customer context must not carry one',\n )\n }\n const contentIncluded = context.contentIncluded === true\n const { spans: filtered, report: ingest } = ingestSpans(spans, { contentIncluded })\n const focus =\n context.focus === undefined ? undefined : redactText(context.focus, { report: ingest.secrets })\n const deterministic = runDeterministicPass(filtered)\n const skipped = [...deterministic.skipped]\n const ambiguous = new Set(ingest.ambiguousSpanIds)\n const rejected: ModelRejection[] = []\n const questions: ModelQuestion[] = []\n const notes: ModelRowNote[] = []\n const summaries: Array<{ traceId: string; answer: string }> = []\n const runs: ModelRunRecord[] = []\n let promptSha256: string | null = null\n let modelFindings: DiagnosisFinding[] = []\n\n const traces = groupByTrace(filtered)\n if (options.mode === 'deterministic') {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: options.reason ?? 'deterministic mode: no model call was made',\n })\n } else {\n const maxTraces = options.model.maxTraces ?? DEFAULT_MAX_MODEL_TRACES\n const ranked = rankTraces(traces)\n const selected = ranked.slice(0, maxTraces)\n const short = traces.size - ranked.length\n if (ranked.length === 0) {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: `no run has the ${MIN_MODEL_SPANS} spans the model needs to read it; ${traces.size} runs were too short`,\n })\n } else if (short > 0) {\n skipped.push({\n analysis: `model reading of ${short} of ${traces.size} runs`,\n reason: `those runs have fewer than ${MIN_MODEL_SPANS} spans, too few for the model to read`,\n })\n }\n if (ranked.length > selected.length) {\n skipped.push({\n analysis: `model reading of ${ranked.length - selected.length} of ${ranked.length} runs`,\n reason: `the model reads at most ${maxTraces} runs per diagnosis, chosen by error count then size`,\n })\n }\n const pass = await runModelPass(\n selected,\n ambiguous,\n {\n subject: context.subject,\n contentIncluded,\n ...(focus ? { focus } : {}),\n ...(context.projects ? { projects: context.projects } : {}),\n },\n options.model,\n options.signal,\n )\n promptSha256 = pass.promptSha256\n modelFindings = pass.findings\n questions.push(...pass.questions)\n notes.push(...(context.subject === 'internal' ? pass.notes : []))\n summaries.push(...pass.summaries)\n rejected.push(...pass.rejected)\n runs.push(...pass.runs)\n for (const gap of pass.uncovered) {\n skipped.push({ analysis: `model reading of part of run ${gap.traceId}`, reason: gap.reason })\n }\n for (const run of pass.runs) {\n if (!run.ok)\n skipped.push({\n analysis: `model reading of run ${run.traceId}`,\n reason: run.failure ?? 'failed',\n })\n }\n if (context.subject === 'internal' && context.topology) {\n const topology = redact(context.topology, { report: ingest.secrets }).value\n const runIds = new Set(\n (topology.runs ?? [])\n .map((run) => run.id)\n .filter((id): id is string => typeof id === 'string'),\n )\n const reading = await runTopologyPass(topology, runIds, options.model, options.signal)\n notes.push(...reading.notes)\n questions.push(...reading.questions)\n rejected.push(...reading.rejected)\n runs.push(reading.run)\n if (!reading.run.ok)\n skipped.push({ analysis: 'topology reading', reason: reading.run.failure ?? 'failed' })\n }\n }\n\n const spanIds = new Set(filtered.map((span) => span.spanId))\n const findings = resolveEvidence(\n [...deterministic.findings, ...modelFindings],\n spanIds,\n ambiguous,\n rejected,\n ).sort(\n (a, b) =>\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] ||\n (a.confidence === b.confidence ? 0 : a.confidence === 'observed' ? -1 : 1),\n )\n\n const document: DiagnosisFindingsDocument = {\n schemaVersion: 1,\n subject: {\n label: redactText(context.label, { report: ingest.secrets }),\n runCount: traces.size,\n window: deterministic.window,\n contentIncluded,\n },\n coverage: {\n capabilities: deterministic.capabilities,\n skipped,\n redaction: {\n redactionCount: ingest.secrets.redactionCount,\n byRule: { ...ingest.secrets.byDetector },\n droppedAttributes: ingest.droppedAttributes,\n },\n },\n findings,\n }\n const defects = validateDiagnosisFindings(document, { spanIds })\n if (defects.length > 0) {\n throw new Error(\n `diagnoseSpans produced an invalid findings document: ${defects.slice(0, 5).join('; ')}`,\n )\n }\n const pricing = options.mode === 'model' ? options.model.pricing : undefined\n return {\n document,\n questions,\n notes,\n summaries,\n facts: deterministic.facts,\n conformance: deterministic.validation.findings,\n ingest,\n rejected,\n model: {\n used: options.mode === 'model',\n model: options.mode === 'model' ? options.model.model : null,\n runs,\n promptSha256,\n usage: totalUsage(runs, pricing),\n },\n engine: { name: 'agent-eval/diagnosis', version: packageVersion() },\n }\n}\n\n/** Runs with more errors first, then larger runs; runs under MIN_MODEL_SPANS are left out. */\nfunction rankTraces(traces: ReadonlyMap<string, import('./spans').DiagnosisSpan[]>) {\n return [...traces.entries()]\n .filter(([, spans]) => spans.length >= MIN_MODEL_SPANS)\n .map(([traceId, spans]) => ({\n traceId,\n spans,\n errors: spans.filter((span) => span.status === 'ERROR').length,\n }))\n .sort(\n (a, b) =>\n b.errors - a.errors ||\n b.spans.length - a.spans.length ||\n a.traceId.localeCompare(b.traceId),\n )\n}\n\nfunction resolveEvidence(\n findings: DiagnosisFinding[],\n spanIds: ReadonlySet<string>,\n ambiguous: ReadonlySet<string>,\n rejected: ModelRejection[],\n): DiagnosisFinding[] {\n const kept: DiagnosisFinding[] = []\n for (const finding of findings) {\n const evidence = finding.evidence.filter((id) => spanIds.has(id) && !ambiguous.has(id))\n if (evidence.length === 0) {\n rejected.push({\n reason: `finding ${finding.id} lost all evidence: its span ids are missing or shared by several runs`,\n })\n continue\n }\n kept.push({ ...finding, evidence })\n }\n return kept\n}\n\n/**\n * Token and cost totals over the model exchanges. No exchange attempted is a\n * measured zero. An exchange that failed without reporting usage may still\n * have been billed, so it makes the totals unknown (null) rather than zero.\n */\nfunction totalUsage(\n runs: readonly ModelRunRecord[],\n pricing: DiagnosisModelOptions['pricing'],\n): DiagnosisUsage {\n let inputTokens: number | null = 0\n let outputTokens: number | null = 0\n let exchanges = 0\n for (const run of runs) {\n exchanges += 1\n inputTokens =\n inputTokens === null || run.usage.inputTokens === null\n ? null\n : inputTokens + run.usage.inputTokens\n outputTokens =\n outputTokens === null || run.usage.outputTokens === null\n ? null\n : outputTokens + run.usage.outputTokens\n }\n const usd =\n exchanges === 0\n ? 0\n : pricing && inputTokens !== null && outputTokens !== null\n ? (inputTokens * pricing.inputUsdPerMillion + outputTokens * pricing.outputUsdPerMillion) /\n 1_000_000\n : null\n return { exchanges, inputTokens, outputTokens, usd }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["SEVERITIES"],"sources":["../../src/diagnosis/first-failure.ts","../../src/diagnosis/spans.ts","../../src/diagnosis/deterministic.ts","../../src/diagnosis/findings.ts","../../src/diagnosis/model-pass.ts","../../src/diagnosis/engine.ts"],"sourcesContent":["/**\n * The first failure in one run, ranked by a fixed precedence and never read off\n * timing correlation.\n *\n * Precedence:\n * 1. `error-span`: a span with status ERROR or `agent.outcome` \"error\" that\n * contains no other such span. A span whose failure is explained by a\n * failing span inside it does not rank; containment is recorded structure.\n * Among the rest, the span that ended first ranks first, because its end\n * is when the failure was recorded.\n * 2. `failed-outcome`: no span errored, but a span carries `agent.outcome`\n * \"fail\". The run completed and its graded work failed.\n * 3. `none`: neither exists, and at least one span recorded a definitive\n * OK or ERROR status. This describes the recorded spans. It is not a\n * verdict that the run succeeded, only that nothing failed among what\n * was recorded.\n *\n * A trace where no span recorded OK or ERROR — every span is UNSET, the\n * common shape for a capture that failed before any status was written —\n * ranks `unknown`, not `none`. `none` asserts something was observed and\n * nothing failed in it; a trace of pure UNSET spans observed nothing, so\n * treating it as a clean run manufactures a false negative for whatever\n * consumed it (a comparison, a pass/fail gate).\n *\n * When the leading candidates end at the same instant, or a candidate has no\n * end time, the result is `ambiguous` and names the candidates. The rank never\n * picks one.\n *\n * The failing span's status message is classified by the failure taxonomy\n * (`classifyFailureReason`), whose `blame` separates machine and provider\n * failures from the agent's own. A span without a message is `unreported` and\n * blamed `unknown`. A failed outcome with no error span is blamed `unknown`\n * too: the machine and the provider recorded no failure, but absence of a\n * recorded cause is not evidence the agent caused it. Blame only reads\n * `agent` when the taxonomy names the agent from actual evidence.\n */\n\nimport type { SpanKind } from '@tangle-network/agent-trace-contract'\nimport {\n classifyFailureReason,\n type FailureBlame,\n type FailureClassification,\n} from '../failure-taxonomy'\nimport type { DiagnosisSpan } from './spans'\n\n/** Span ids listed beside a result; the count carries the rest. */\nexport const MAX_FIRST_FAILURE_IDS = 8\n\nconst OUTCOME_ATTR = 'agent.outcome'\n\nexport type FirstFailureStage = 'error-span' | 'failed-outcome'\n\nexport interface FirstFailureFound {\n status: 'found'\n traceId: string\n stage: FirstFailureStage\n spanId: string\n name: string\n kind: SpanKind\n /** The span's status message after secret filtering; null when absent or withheld. */\n message: string | null\n /** The taxonomy's reading of `message`; null for a failed outcome, which has none. */\n classification: FailureClassification | null\n blame: FailureBlame\n /** Other candidates at the same stage, in rank order, capped at {@link MAX_FIRST_FAILURE_IDS}. */\n later: string[]\n laterCount: number\n}\n\nexport interface FirstFailureAmbiguous {\n status: 'ambiguous'\n traceId: string\n stage: FirstFailureStage\n /** The candidates the rank could not order, capped at {@link MAX_FIRST_FAILURE_IDS}. */\n candidates: string[]\n candidateCount: number\n reason: string\n}\n\nexport interface FirstFailureNone {\n status: 'none'\n traceId: string\n reason: string\n}\n\n/**\n * No span recorded a definitive OK or ERROR status, so the recording says\n * nothing about whether the run failed. Distinct from `none`, which asserts\n * spans were observed and none of them failed.\n */\nexport interface FirstFailureUnknown {\n status: 'unknown'\n traceId: string\n /** Count of spans with UNSET status among the spans ranked. */\n unsetCount: number\n reason: string\n}\n\nexport type FirstFailure =\n | FirstFailureFound\n | FirstFailureAmbiguous\n | FirstFailureNone\n | FirstFailureUnknown\n\n/** Rank the first failure of one trace. Throws when the spans belong to more than one trace. */\nexport function rankFirstFailure(spans: readonly DiagnosisSpan[]): FirstFailure {\n const traceId = spans[0]?.traceId\n if (traceId === undefined) throw new TypeError('rankFirstFailure: no spans')\n if (spans.some((span) => span.traceId !== traceId)) {\n throw new TypeError('rankFirstFailure: spans belong to more than one trace')\n }\n\n const errors = spans.filter(isErrorSpan)\n if (errors.length > 0) {\n const innermost = withoutFailingDescendants(spans, errors)\n if (innermost.length === 0) {\n return ambiguous(\n traceId,\n 'error-span',\n errors,\n 'every failing span contains another failing span, so containment is cyclic',\n )\n }\n return rank(traceId, 'error-span', innermost)\n }\n\n const failed = spans.filter((span) => span.attributes[OUTCOME_ATTR] === 'fail')\n if (failed.length > 0) return rank(traceId, 'failed-outcome', failed)\n\n const unsetCount = spans.filter((span) => span.status === 'UNSET').length\n if (unsetCount === spans.length && spans.length > 0) {\n return {\n status: 'unknown',\n traceId,\n unsetCount,\n reason: `none of ${spans.length} spans has status OK or ERROR (all UNSET), so whether the run failed was never recorded`,\n }\n }\n\n return {\n status: 'none',\n traceId,\n reason: `none of ${spans.length} spans has status ERROR or an agent.outcome of error or fail`,\n }\n}\n\nfunction isErrorSpan(span: DiagnosisSpan): boolean {\n return span.status === 'ERROR' || span.attributes[OUTCOME_ATTR] === 'error'\n}\n\n/** The failing spans with no failing span beneath them. */\nfunction withoutFailingDescendants(\n spans: readonly DiagnosisSpan[],\n failing: readonly DiagnosisSpan[],\n): DiagnosisSpan[] {\n const parentOf = new Map(spans.map((span) => [span.spanId, span.parentSpanId]))\n const explained = new Set<string>()\n for (const span of failing) {\n const seen = new Set([span.spanId])\n let parent = span.parentSpanId\n while (parent !== null && parentOf.has(parent) && !seen.has(parent)) {\n explained.add(parent)\n seen.add(parent)\n parent = parentOf.get(parent) ?? null\n }\n }\n return failing.filter((span) => !explained.has(span.spanId))\n}\n\nfunction rank(\n traceId: string,\n stage: FirstFailureStage,\n candidates: readonly DiagnosisSpan[],\n): FirstFailure {\n if (candidates.length > 1) {\n const untimed = candidates.filter((span) => span.endMs === null)\n if (untimed.length > 0) {\n return ambiguous(\n traceId,\n stage,\n candidates,\n `${untimed.length} of ${candidates.length} candidates have no end time, so their order is unknown`,\n )\n }\n }\n const ordered = [...candidates].sort(\n (a, b) => (a.endMs ?? 0) - (b.endMs ?? 0) || a.spanId.localeCompare(b.spanId),\n )\n const first = ordered[0]!\n const tied = ordered.filter((span) => span.endMs === first.endMs)\n if (tied.length > 1) {\n return ambiguous(\n traceId,\n stage,\n tied,\n `${tied.length} candidates ended at the same instant, so none ranks first`,\n )\n }\n const classification = stage === 'error-span' ? classifyFailureReason(first.statusMessage) : null\n const later = ordered.slice(1)\n return {\n status: 'found',\n traceId,\n stage,\n spanId: first.spanId,\n name: first.name,\n kind: first.kind,\n message: first.statusMessage,\n classification,\n blame: classification?.blame ?? 'unknown',\n later: later.slice(0, MAX_FIRST_FAILURE_IDS).map((span) => span.spanId),\n laterCount: later.length,\n }\n}\n\nfunction ambiguous(\n traceId: string,\n stage: FirstFailureStage,\n candidates: readonly DiagnosisSpan[],\n reason: string,\n): FirstFailureAmbiguous {\n const ids = candidates.map((span) => span.spanId).sort()\n return {\n status: 'ambiguous',\n traceId,\n stage,\n candidates: ids.slice(0, MAX_FIRST_FAILURE_IDS),\n candidateCount: ids.length,\n reason,\n }\n}\n","/**\n * Ingest for the diagnosis engine: flat spans in, filtered and normalized spans\n * out. Nothing downstream of this file sees an unfiltered value.\n *\n * Input is the flat-span shape trace-adapters and the traces CLI emit, one\n * object per span: `{trace_id, span_id, parent_span_id, name, kind,\n * start_time, end_time, status | status_code, status_message, attributes,\n * resource?}`. Times may be OTLP nanosecond strings, epoch milliseconds, or\n * ISO-8601; the generic OTLP line reader treats every digit string as\n * milliseconds, so time parsing is owned here.\n */\n\nimport { createHmac, randomBytes } from 'node:crypto'\nimport {\n type ContractSpan,\n MODEL_ATTR_KEYS,\n resolveSpanKind,\n SPAN_KINDS,\n type SpanKind,\n TOOL_NAME_ATTR_KEYS,\n} from '@tangle-network/agent-trace-contract'\nimport { emptyRedactionReport, type RedactionReport, redact, redactText } from '../trace/redact'\n\nexport type DiagnosisSpanStatus = 'OK' | 'ERROR' | 'UNSET'\n\nexport interface DiagnosisSpan {\n traceId: string\n spanId: string\n parentSpanId: string | null\n name: string\n kind: SpanKind\n startMs: number | null\n endMs: number | null\n status: DiagnosisSpanStatus\n statusMessage: string | null\n toolName: string | null\n model: string | null\n /**\n * Keyed fingerprint of the tool call's input, taken before redaction so calls\n * that differ only in secret material stay distinct. The key is random per\n * ingest, so the fingerprint cannot be matched against a guessed payload or\n * joined across diagnoses. Null when the span carries no input.\n */\n inputDigest: string | null\n attributes: Record<string, unknown>\n}\n\nexport interface IngestReport {\n received: number\n accepted: number\n /** Lines without a trace id or span id, which no evidence could ever cite. */\n unreadable: number\n /** Identical (trace id, span id) pairs seen again; the first occurrence is kept. */\n duplicateSpans: number\n /** Span ids that occur in more than one trace, which evidence cannot cite unambiguously. */\n ambiguousSpanIds: string[]\n secrets: RedactionReport\n /** Attribute keys removed because content was not included. */\n droppedAttributes: string[]\n}\n\n/**\n * Attributes that carry prompt, response, or tool payload text. When content is\n * not included they are removed before anything reads the span, rather than\n * trusting pattern redaction over free-form prose.\n */\nconst CONTENT_ATTRIBUTE =\n /^(?:input\\.value|output\\.value|input|output|result|prompt|completion|text|thinking|message|messages|tool\\.(?:input|output|arguments|result)|tool_input|tool_output|tool_arguments|arguments|args|full_command|gen_ai\\.(?:prompt|completion|input\\.messages|output\\.messages|system_instructions|tool\\.call\\.(?:arguments|result))(?:\\..*)?|llm\\.(?:input|output)_messages(?:\\..*)?|llm\\.prompts?(?:\\..*)?|content|body|request|response|command)$|\\.content$/i\nconst PROSE_ATTRIBUTE =\n /(?:^|[._])(?:error|exception|status)(?:[._][a-zA-Z0-9]+)*[._](?:message|stacktrace|stack|description|details|reason)$|^(?:error|exception|status)$|^(?:log|event)[._]message$|^otel\\.status_description$|^(?:events?|logs?)$/i\n\nconst INPUT_ATTRIBUTE_KEYS = [\n 'input.value',\n 'input',\n 'tool.input',\n 'tool.arguments',\n 'tool_input',\n 'tool_arguments',\n 'arguments',\n 'args',\n 'full_command',\n 'gen_ai.tool.call.arguments',\n]\n\nexport function isContentAttribute(key: string): boolean {\n return CONTENT_ATTRIBUTE.test(key) || PROSE_ATTRIBUTE.test(key)\n}\n\n/**\n * Filter secrets from every string, drop content attributes unless content is\n * included, and normalize each span. Order matters: the input fingerprint is\n * keyed and taken before redaction and the content drop, so repeated-call\n * detection works on metadata-only runs without the payload itself surviving.\n */\nexport function ingestSpans(\n raw: readonly unknown[],\n options: { contentIncluded: boolean },\n): { spans: DiagnosisSpan[]; report: IngestReport } {\n const secrets = emptyRedactionReport()\n const dropped = new Set<string>()\n const seen = new Set<string>()\n const spans: DiagnosisSpan[] = []\n let unreadable = 0\n let duplicateSpans = 0\n const traceOfSpan = new Map<string, string>()\n const ambiguous = new Set<string>()\n const digestKey = randomBytes(32)\n for (const line of raw) {\n if (line === null || typeof line !== 'object' || Array.isArray(line)) {\n unreadable += 1\n continue\n }\n const record = line as Record<string, unknown>\n const traceId = idField(record, 'trace_id', 'traceId')\n const spanId = idField(record, 'span_id', 'spanId')\n if (!traceId || !spanId) {\n unreadable += 1\n continue\n }\n const key = `${traceId}\\u0000${spanId}`\n if (seen.has(key)) {\n duplicateSpans += 1\n continue\n }\n seen.add(key)\n const firstTrace = traceOfSpan.get(spanId)\n if (firstTrace === undefined) traceOfSpan.set(spanId, traceId)\n else if (firstTrace !== traceId) ambiguous.add(spanId)\n const merged = mergedAttributes(record)\n const inputDigest = digestInput(merged, digestKey)\n const attributes = redact(merged, { report: secrets }).value\n if (!options.contentIncluded) {\n for (const [key, value] of Object.entries(attributes)) {\n if (isContentAttribute(key) || (value !== null && typeof value === 'object')) {\n delete attributes[key]\n dropped.add(key)\n }\n }\n }\n const status = readStatus(record)\n const statusMessage =\n status.message === null ? null : redactText(status.message, { report: secrets })\n const toolName = firstString(attributes, TOOL_NAME_ATTR_KEYS)\n const model = firstString(attributes, MODEL_ATTR_KEYS)\n const name = redactText(stringOr(record.name, 'unknown'), { report: secrets })\n spans.push({\n traceId,\n spanId,\n parentSpanId: idField(record, 'parent_span_id', 'parentSpanId') ?? null,\n name,\n kind: resolveKind(record.kind, name, attributes),\n startMs: epochMillis(record.start_time ?? record.startTime ?? record.startTimeUnixNano),\n endMs: epochMillis(record.end_time ?? record.endTime ?? record.endTimeUnixNano),\n status: status.code,\n statusMessage: options.contentIncluded ? statusMessage : null,\n toolName,\n model,\n inputDigest,\n attributes,\n })\n }\n return {\n spans,\n report: {\n received: raw.length,\n accepted: spans.length,\n unreadable,\n duplicateSpans,\n ambiguousSpanIds: [...ambiguous].sort(),\n secrets,\n droppedAttributes: [...dropped].sort(),\n },\n }\n}\n\n/** The contract shape `validateTraceSpans` reads. */\nexport function toContractSpan(span: DiagnosisSpan): ContractSpan {\n return {\n trace_id: span.traceId,\n span_id: span.spanId,\n parent_span_id: span.parentSpanId,\n name: span.name,\n ...(span.kind === 'UNKNOWN' ? {} : { kind: span.kind }),\n start_time: isoOrEmpty(span.startMs),\n end_time: isoOrEmpty(span.endMs),\n status: {\n code:\n span.status === 'ERROR'\n ? 'STATUS_CODE_ERROR'\n : span.status === 'OK'\n ? 'STATUS_CODE_OK'\n : 'STATUS_CODE_UNSET',\n ...(span.statusMessage ? { message: span.statusMessage } : {}),\n },\n attributes: span.attributes,\n }\n}\n\nexport function durationMs(span: DiagnosisSpan): number | null {\n return span.startMs !== null && span.endMs !== null\n ? Math.max(0, span.endMs - span.startMs)\n : null\n}\n\n/**\n * Epoch milliseconds from OTLP nanoseconds, epoch milliseconds, epoch seconds,\n * or ISO-8601. Digit strings are classified by length: 17 or more digits are\n * nanoseconds, 15-16 microseconds, 12-14 milliseconds, and fewer are seconds.\n */\nexport function epochMillis(value: unknown): number | null {\n if (typeof value === 'number')\n return Number.isFinite(value) ? scaleEpoch(value, String(Math.trunc(value)).length) : null\n if (typeof value !== 'string' || value.length === 0) return null\n if (/^\\d+$/.test(value)) {\n if (value.length >= 17) return Number(BigInt(value) / 1_000_000n)\n return scaleEpoch(Number(value), value.length)\n }\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? null : parsed\n}\n\nfunction scaleEpoch(value: number, digits: number): number {\n if (digits >= 17) return Math.trunc(value / 1_000_000)\n if (digits >= 15) return Math.trunc(value / 1_000)\n if (digits >= 12) return value\n return value * 1000\n}\n\nfunction isoOrEmpty(ms: number | null): string {\n return ms === null ? '' : new Date(ms).toISOString()\n}\n\nfunction mergedAttributes(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const resource = record.resource\n if (resource && typeof resource === 'object' && !Array.isArray(resource)) {\n const attrs = (resource as Record<string, unknown>).attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n }\n const attrs = record.attributes\n if (attrs && typeof attrs === 'object' && !Array.isArray(attrs)) Object.assign(out, attrs)\n if (typeof record.scope_name === 'string' && out['otel.scope.name'] === undefined) {\n out['otel.scope.name'] = record.scope_name\n }\n return out\n}\n\nfunction readStatus(record: Record<string, unknown>): {\n code: DiagnosisSpanStatus\n message: string | null\n} {\n let code: unknown = record.status_code\n let message: unknown = record.status_message\n const status = record.status\n if (status && typeof status === 'object' && !Array.isArray(status)) {\n const object = status as Record<string, unknown>\n code = object.code ?? code\n message = object.message ?? message\n }\n const text = typeof code === 'string' ? code.toUpperCase() : code\n const normalized: DiagnosisSpanStatus =\n text === 2 || text === 'STATUS_CODE_ERROR' || text === 'ERROR' || text === '2'\n ? 'ERROR'\n : text === 1 || text === 'STATUS_CODE_OK' || text === 'OK' || text === '1'\n ? 'OK'\n : 'UNSET'\n return {\n code: normalized,\n message: typeof message === 'string' && message.length > 0 ? message : null,\n }\n}\n\n/**\n * The contract's classifier decides the kind, so the capability table and the\n * findings count the same tool and LLM spans. A top-level `kind` counts as a\n * declaration only when it is a contract kind; OTLP words such as\n * SPAN_KIND_INTERNAL fall through to the attribute and name signals.\n */\nfunction resolveKind(kind: unknown, name: string, attributes: Record<string, unknown>): SpanKind {\n const declared =\n typeof kind === 'string' && (SPAN_KINDS as readonly string[]).includes(kind.toUpperCase())\n ? kind.toUpperCase()\n : undefined\n return resolveSpanKind({ ...(declared ? { kind: declared } : {}), name, attributes })\n}\n\nfunction digestInput(attributes: Record<string, unknown>, key: Buffer): string | null {\n for (const name of INPUT_ATTRIBUTE_KEYS) {\n const value = attributes[name]\n if (value === undefined || value === null || value === '') continue\n const text = typeof value === 'string' ? value : JSON.stringify(value)\n return createHmac('sha256', key).update(text).digest('hex').slice(0, 16)\n }\n return null\n}\n\nfunction idField(\n record: Record<string, unknown>,\n snake: string,\n camel: string,\n): string | undefined {\n const value = record[snake] ?? record[camel]\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction firstString(attributes: Record<string, unknown>, keys: readonly string[]): string | null {\n for (const key of keys) {\n const value = attributes[key]\n if (typeof value === 'string' && value.length > 0) return value\n }\n return null\n}\n\nfunction stringOr(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.length > 0 ? value : fallback\n}\n","/**\n * The deterministic pass: everything the engine can say without a model.\n *\n * It produces the capability table (the trace contract's own validator, so the\n * reasons are the trace's reasons), execution facts with token and cost\n * accounting (agent-eval's `fromOtelSpans` + `summarizeExecution`), and\n * `observed` findings computed directly from span data. Every observed finding\n * carries a measure with its denominator and cites the spans it counted.\n */\n\nimport { createHash } from 'node:crypto'\nimport { type TraceValidation, validateTraceSpans } from '@tangle-network/agent-trace-contract'\nimport { type ExecutionReport, summarizeExecution } from '../contract/analyze-runs'\nimport { fromOtelSpans } from '../contract/intake/otel-spans'\nimport type { TraceSpanEvent } from '../hosted/types'\nimport type {\n DiagnosisCapability,\n DiagnosisFinding,\n DiagnosisSeverity,\n DiagnosisSkippedAnalysis,\n} from './findings'\nimport { type FirstFailure, rankFirstFailure } from './first-failure'\nimport { type DiagnosisSpan, durationMs, toContractSpan } from './spans'\n\n/** Evidence ids cited per finding; the measure carries the full count. */\nexport const MAX_EVIDENCE_PER_FINDING = 8\n/**\n * Identical tool calls with no different tool call between them that count as\n * a repeated-call run. Model turns between the calls do not break the run: an\n * agent that calls, reads, and calls again with the same input is the waste\n * this detects.\n */\nexport const REPEAT_RUN_LENGTH = 3\n/** A tool is reported only once it has at least this many calls. */\nexport const MIN_TOOL_CALLS = 3\n\n/** The analysis each capability gates, as the report names it. */\nconst CAPABILITY_ANALYSES: Record<string, string> = {\n 'token-accounting': 'token accounting',\n 'cost-attribution': 'cost attribution',\n 'tool-usage': 'tool failure rates and repeated-call detection',\n 'loop-convergence': 'loop convergence (did round N+1 improve on round N)',\n 'tree-comparison': 'arm-vs-arm comparison across branches of one run',\n 'steering-chain': 'steering chain (which verdict caused which retry)',\n 'latency-analysis': 'latency distribution',\n}\n\n/**\n * Capabilities the engine reports but does not analyze itself, with where to\n * go instead. All three point at `@tangle-network/traces`, which reads\n * `links` (causal edges) that this engine's `DiagnosisSpan` does not carry —\n * extending it is the prerequisite for building these here instead of\n * pointing away from here.\n */\nconst NOT_BUILT = new Map([\n [\n 'loop-convergence',\n 'the engine has no round-over-round convergence analysis yet; ' +\n '@tangle-network/traces reads it from agent.loop.id/agent.loop.iteration (loopConvergence in src/loop-analysis)',\n ],\n [\n 'tree-comparison',\n 'the engine does not pick which arms to compare; diff two arms with diffSteps from /pipelines ' +\n '(traces diff <file>#branch=<a> <file>#branch=<b>)',\n ],\n [\n 'steering-chain',\n 'the engine has no steering-chain analysis yet; @tangle-network/traces reads it from span links ' +\n \"(steeringChain in src/loop-analysis, which this engine's DiagnosisSpan does not carry)\",\n ],\n])\n\nexport interface ExecutionFacts {\n runs: number\n spans: number\n spansByKind: Record<string, number>\n errorSpans: number\n toolCalls: number\n models: string[]\n /** The first failure of each run, in trace id order. See `rankFirstFailure`. */\n firstFailures: FirstFailure[]\n /** agent-eval execution summary; null with a reason when it could not be computed. */\n execution: ExecutionReport | null\n executionError?: string\n}\n\nexport interface DeterministicResult {\n validation: TraceValidation\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n facts: ExecutionFacts\n findings: DiagnosisFinding[]\n window: string\n}\n\nexport function runDeterministicPass(spans: readonly DiagnosisSpan[]): DeterministicResult {\n const validation = validateTraceSpans(spans.map(toContractSpan))\n const capabilities: Record<string, DiagnosisCapability> = {}\n const skipped: DiagnosisSkippedAnalysis[] = []\n for (const capability of validation.capabilities) {\n capabilities[capability.name] = capability.available\n ? { available: true }\n : {\n available: false,\n reason: capability.reason ?? 'the trace contract validator gave no reason',\n }\n const analysis = CAPABILITY_ANALYSES[capability.name] ?? capability.name\n if (!capability.available) {\n skipped.push({ analysis, reason: capability.reason ?? 'capability unavailable' })\n } else if (NOT_BUILT.has(capability.name)) {\n skipped.push({ analysis, reason: NOT_BUILT.get(capability.name)! })\n }\n }\n\n const traces = groupByTrace(spans)\n const findings: DiagnosisFinding[] = []\n const tools = spans.filter((span) => span.kind === 'TOOL')\n if (tools.length > 0) {\n findings.push(...toolFailureFindings(tools))\n const withDigest = tools.filter((span) => span.inputDigest !== null).length\n if (withDigest > 0) findings.push(...repeatedCallFindings(traces))\n else\n skipped.push({\n analysis: 'repeated identical tool calls',\n reason: `none of ${tools.length} tool spans carries its input, so identical calls cannot be told apart`,\n })\n } else {\n skipped.push({ analysis: 'tool failure rates', reason: 'no span resolves to kind TOOL' })\n }\n findings.push(...failedRunFindings(traces))\n\n const facts = executionFacts(spans, traces)\n return { validation, capabilities, skipped, facts, findings, window: timeWindow(spans) }\n}\n\nexport function groupByTrace(spans: readonly DiagnosisSpan[]): Map<string, DiagnosisSpan[]> {\n const traces = new Map<string, DiagnosisSpan[]>()\n for (const span of spans) {\n const list = traces.get(span.traceId)\n if (list) list.push(span)\n else traces.set(span.traceId, [span])\n }\n for (const list of traces.values()) list.sort(byStart)\n return traces\n}\n\nfunction toolFailureFindings(tools: readonly DiagnosisSpan[]): DiagnosisFinding[] {\n const byTool = new Map<string, DiagnosisSpan[]>()\n for (const span of tools) {\n const name = span.toolName ?? span.name\n const list = byTool.get(name)\n if (list) list.push(span)\n else byTool.set(name, [span])\n }\n const findings: DiagnosisFinding[] = []\n for (const [tool, calls] of byTool) {\n const failed = calls.filter((span) => span.status === 'ERROR')\n if (calls.length < MIN_TOOL_CALLS || failed.length < 2) continue\n const rate = failed.length / calls.length\n const severity: DiagnosisSeverity =\n rate >= 0.5 && failed.length >= 5 ? 'high' : rate >= 0.2 ? 'medium' : 'low'\n findings.push({\n id: stableId('tool-failures', tool),\n severity,\n claim: `${failed.length} of ${calls.length} calls to the ${tool} tool failed.`,\n consequence: `Each failed call spends a model turn noticing the error and retrying, so ${pct(rate)} of this tool's calls bought no progress.`,\n measure: {\n name: `${tool} tool failure rate`,\n value: round(rate * 100),\n unit: '%',\n denominator: `${calls.length} calls to ${tool}`,\n },\n evidence: failed.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation: `Read the failed ${tool} calls' status messages and fix the most common cause, or give the agent the precondition it keeps missing.`,\n })\n }\n return findings.sort((a, b) => (b.measure?.value ?? 0) - (a.measure?.value ?? 0)).slice(0, 10)\n}\n\nfunction repeatedCallFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const runs: DiagnosisSpan[][] = []\n let digestCalls = 0\n for (const spans of traces.values()) {\n let current: DiagnosisSpan[] = []\n for (const span of spans) {\n if (span.kind !== 'TOOL' || span.inputDigest === null) continue\n digestCalls += 1\n const last = current[current.length - 1]\n if (\n last &&\n last.inputDigest === span.inputDigest &&\n (last.toolName ?? last.name) === (span.toolName ?? span.name)\n ) {\n current.push(span)\n } else {\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n current = [span]\n }\n }\n if (current.length >= REPEAT_RUN_LENGTH) runs.push(current)\n }\n if (runs.length === 0) return []\n const wasted = runs.reduce((sum, run) => sum + run.length - 1, 0)\n const tracesAffected = new Set(runs.map((run) => run[0]!.traceId)).size\n runs.sort((a, b) => b.length - a.length)\n const evidence = runs\n .flatMap((run) => run.slice(0, 2).map((span) => span.spanId))\n .slice(0, MAX_EVIDENCE_PER_FINDING)\n const rate = wasted / digestCalls\n return [\n {\n id: stableId('repeated-calls', String(runs.length)),\n severity: rate >= 0.1 ? 'high' : rate >= 0.03 ? 'medium' : 'low',\n claim: `The agent made the same tool call with the same input ${REPEAT_RUN_LENGTH} or more times with no other tool call in between, ${runs.length} times across ${tracesAffected} runs; the longest streak was ${runs[0]!.length} calls.`,\n consequence: `${wasted} calls repeated the previous tool call with the same input, which is work the agent paid for twice without new information.`,\n measure: {\n name: 'repeated identical tool calls',\n value: wasted,\n unit: 'calls',\n denominator: `${digestCalls} tool calls with recorded input`,\n },\n evidence,\n confidence: 'observed',\n recommendation:\n 'Detect a repeated identical call in the harness and stop or change strategy after the second attempt.',\n },\n ]\n}\n\nfunction failedRunFindings(traces: ReadonlyMap<string, DiagnosisSpan[]>): DiagnosisFinding[] {\n const failedRoots: DiagnosisSpan[] = []\n for (const spans of traces.values()) {\n const ids = new Set(spans.map((span) => span.spanId))\n const root = spans.find((span) => span.parentSpanId === null || !ids.has(span.parentSpanId))\n if (root?.status === 'ERROR') failedRoots.push(root)\n }\n if (failedRoots.length === 0) return []\n const rate = failedRoots.length / traces.size\n return [\n {\n id: stableId('failed-runs', String(traces.size)),\n severity: rate >= 0.25 ? 'critical' : rate >= 0.1 ? 'high' : 'medium',\n claim: `${failedRoots.length} of ${traces.size} runs ended with an error on their root span.`,\n consequence:\n 'A run that ends in an error delivered nothing its caller can use, and any tokens it spent are lost.',\n measure: {\n name: 'failed runs',\n value: round(rate * 100),\n unit: '%',\n denominator: `${traces.size} runs`,\n },\n evidence: failedRoots.slice(0, MAX_EVIDENCE_PER_FINDING).map((span) => span.spanId),\n confidence: 'observed',\n recommendation:\n 'Group the failed runs by their root status message and fix the largest group first.',\n },\n ]\n}\n\nfunction executionFacts(\n spans: readonly DiagnosisSpan[],\n traces: ReadonlyMap<string, DiagnosisSpan[]>,\n): ExecutionFacts {\n const spansByKind: Record<string, number> = {}\n const models = new Set<string>()\n let errorSpans = 0\n let toolCalls = 0\n for (const span of spans) {\n spansByKind[span.kind] = (spansByKind[span.kind] ?? 0) + 1\n if (span.status === 'ERROR') errorSpans += 1\n if (span.kind === 'TOOL') toolCalls += 1\n if (span.model) models.add(span.model)\n }\n const facts: ExecutionFacts = {\n runs: traces.size,\n spans: spans.length,\n spansByKind,\n errorSpans,\n toolCalls,\n models: [...models].sort(),\n firstFailures: [...traces.keys()]\n .sort()\n .map((traceId) => rankFirstFailure(traces.get(traceId)!)),\n execution: null,\n }\n try {\n facts.execution = summarizeExecution({\n runs: fromOtelSpans({ spans: spans.map(toTraceSpanEvent) }),\n })\n } catch (error) {\n facts.executionError = error instanceof Error ? error.message : String(error)\n }\n return facts\n}\n\nfunction toTraceSpanEvent(span: DiagnosisSpan): TraceSpanEvent {\n const attributes: Record<string, string | number | boolean> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (typeof value === 'string' || typeof value === 'boolean') attributes[key] = value\n else if (typeof value === 'number' && Number.isFinite(value)) attributes[key] = value\n }\n if (span.kind !== 'UNKNOWN' && attributes['openinference.span.kind'] === undefined) {\n attributes['openinference.span.kind'] = span.kind\n }\n const start = span.startMs ?? 0\n const end = span.endMs ?? start\n return {\n traceId: span.traceId,\n spanId: span.spanId,\n ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),\n name: span.name,\n startTimeUnixNano: `${BigInt(Math.trunc(start)) * 1_000_000n}`,\n endTimeUnixNano: `${BigInt(Math.trunc(end)) * 1_000_000n}`,\n attributes,\n status: { code: span.status, ...(span.statusMessage ? { message: span.statusMessage } : {}) },\n }\n}\n\nfunction timeWindow(spans: readonly DiagnosisSpan[]): string {\n let first = Number.POSITIVE_INFINITY\n let last = Number.NEGATIVE_INFINITY\n for (const span of spans) {\n if (span.startMs !== null) first = Math.min(first, span.startMs)\n const end = span.endMs ?? span.startMs\n if (end !== null) last = Math.max(last, end)\n }\n if (!Number.isFinite(first) || !Number.isFinite(last)) return 'unknown'\n return `${new Date(first).toISOString()}/${new Date(last).toISOString()}`\n}\n\nfunction byStart(a: DiagnosisSpan, b: DiagnosisSpan): number {\n return (a.startMs ?? 0) - (b.startMs ?? 0) || (durationMs(b) ?? 0) - (durationMs(a) ?? 0)\n}\n\nexport function stableId(prefix: string, ...parts: string[]): string {\n return `${prefix}-${createHash('sha256').update(parts.join('\\u0000')).digest('hex').slice(0, 12)}`\n}\n\nfunction pct(rate: number): string {\n return `${round(rate * 100)}%`\n}\n\nfunction round(value: number): number {\n return Math.round(value * 10) / 10\n}\n","/**\n * The diagnosis findings document: what the engine returns and what the\n * diagnosis report renders. It mirrors the kit's JSON Schema\n * (`https://tangle.tools/schemas/diagnosis-findings-v1.json`, owned by the\n * traces repository's diagnosis kit) field for field, including its closed\n * objects, so a document that passes {@link validateDiagnosisFindings} passes\n * that schema.\n */\n\nexport const DIAGNOSIS_FINDINGS_SCHEMA_ID =\n 'https://tangle.tools/schemas/diagnosis-findings-v1.json'\n\nexport type DiagnosisSeverity = 'critical' | 'high' | 'medium' | 'low'\n\n/** `observed` is read directly off the trace; `inferred` is a model's reading of it. */\nexport type DiagnosisConfidence = 'observed' | 'inferred'\n\nexport interface DiagnosisMeasure {\n name: string\n value: number\n unit: string\n /** What the value is out of. The engine always sets it; a rate without one is not reportable. */\n denominator: string\n}\n\nexport interface DiagnosisFinding {\n id: string\n severity: DiagnosisSeverity\n claim: string\n consequence: string\n measure?: DiagnosisMeasure\n /** Verbatim span ids from the input. Never empty. */\n evidence: string[]\n reproduce?: string\n confidence: DiagnosisConfidence\n recommendation?: string\n}\n\nexport interface DiagnosisCapability {\n available: boolean\n reason?: string\n}\n\nexport interface DiagnosisSkippedAnalysis {\n analysis: string\n reason: string\n}\n\nexport interface DiagnosisRedaction {\n redactionCount: number\n byRule: Record<string, number>\n droppedAttributes: string[]\n}\n\nexport interface DiagnosisFindingsDocument {\n schemaVersion: 1\n subject: {\n label: string\n runCount: number\n window: string\n contentIncluded?: boolean\n }\n coverage: {\n capabilities: Record<string, DiagnosisCapability>\n skipped: DiagnosisSkippedAnalysis[]\n redaction?: DiagnosisRedaction\n }\n findings: DiagnosisFinding[]\n}\n\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\nexport const SEVERITY_RANK: Record<DiagnosisSeverity, number> = {\n critical: 0,\n high: 1,\n medium: 2,\n low: 3,\n}\n\n/**\n * Structural check against the v1 schema plus the two rules the schema states\n * in prose: an unavailable capability carries a reason, and a measure carries a\n * denominator. When `spanIds` is given, every evidence id must resolve to it.\n * Returns the list of defects; empty means valid.\n */\nexport function validateDiagnosisFindings(\n document: unknown,\n options: { spanIds?: ReadonlySet<string> } = {},\n): string[] {\n const errors: string[] = []\n if (!isObject(document)) return ['document is not an object']\n closed(document, ['schemaVersion', 'subject', 'coverage', 'findings'], '', errors)\n if (document.schemaVersion !== 1) errors.push('schemaVersion must be 1')\n\n const subject = document.subject\n if (!isObject(subject)) errors.push('subject must be an object')\n else {\n closed(subject, ['label', 'runCount', 'window', 'contentIncluded'], 'subject', errors)\n if (typeof subject.label !== 'string') errors.push('subject.label must be a string')\n if (!Number.isInteger(subject.runCount) || (subject.runCount as number) < 0)\n errors.push('subject.runCount must be a non-negative integer')\n if (typeof subject.window !== 'string') errors.push('subject.window must be a string')\n if (subject.contentIncluded !== undefined && typeof subject.contentIncluded !== 'boolean')\n errors.push('subject.contentIncluded must be a boolean')\n }\n\n const coverage = document.coverage\n if (!isObject(coverage)) errors.push('coverage must be an object')\n else {\n closed(coverage, ['capabilities', 'skipped', 'redaction'], 'coverage', errors)\n if (!isObject(coverage.capabilities)) errors.push('coverage.capabilities must be an object')\n else {\n for (const [name, capability] of Object.entries(coverage.capabilities)) {\n if (!isObject(capability) || typeof capability.available !== 'boolean') {\n errors.push(`coverage.capabilities.${name}.available must be a boolean`)\n } else if (\n !capability.available &&\n !(typeof capability.reason === 'string' && capability.reason)\n ) {\n errors.push(`coverage.capabilities.${name} is unavailable without a reason`)\n }\n }\n }\n if (!Array.isArray(coverage.skipped)) errors.push('coverage.skipped must be an array')\n else\n coverage.skipped.forEach((entry, index) => {\n if (\n !isObject(entry) ||\n typeof entry.analysis !== 'string' ||\n typeof entry.reason !== 'string'\n )\n errors.push(`coverage.skipped[${index}] needs analysis and reason strings`)\n })\n if (coverage.redaction !== undefined) {\n const redaction = coverage.redaction\n if (!isObject(redaction)) errors.push('coverage.redaction must be an object')\n else {\n if (!Number.isInteger(redaction.redactionCount) || (redaction.redactionCount as number) < 0)\n errors.push('coverage.redaction.redactionCount must be a non-negative integer')\n if (redaction.byRule !== undefined && !isObject(redaction.byRule))\n errors.push('coverage.redaction.byRule must be an object')\n if (\n redaction.droppedAttributes !== undefined &&\n !Array.isArray(redaction.droppedAttributes)\n )\n errors.push('coverage.redaction.droppedAttributes must be an array')\n }\n }\n }\n\n if (!Array.isArray(document.findings)) errors.push('findings must be an array')\n else\n document.findings.forEach((finding, index) => {\n const at = `findings[${index}]`\n if (!isObject(finding)) {\n errors.push(`${at} must be an object`)\n return\n }\n closed(\n finding,\n [\n 'id',\n 'severity',\n 'claim',\n 'consequence',\n 'measure',\n 'evidence',\n 'reproduce',\n 'confidence',\n 'recommendation',\n ],\n at,\n errors,\n )\n for (const key of ['id', 'claim', 'consequence'] as const) {\n if (typeof finding[key] !== 'string' || !(finding[key] as string))\n errors.push(`${at}.${key} must be a non-empty string`)\n }\n if (!SEVERITIES.has(finding.severity as string)) errors.push(`${at}.severity is invalid`)\n if (finding.confidence !== 'observed' && finding.confidence !== 'inferred')\n errors.push(`${at}.confidence must be observed or inferred`)\n if (!Array.isArray(finding.evidence) || finding.evidence.length === 0)\n errors.push(`${at}.evidence must be a non-empty array`)\n else\n for (const id of finding.evidence) {\n if (typeof id !== 'string') errors.push(`${at}.evidence holds a non-string`)\n else if (options.spanIds && !options.spanIds.has(id))\n errors.push(`${at}.evidence ${id} does not resolve`)\n }\n if (finding.measure !== undefined) {\n const measure = finding.measure\n if (\n !isObject(measure) ||\n typeof measure.name !== 'string' ||\n typeof measure.value !== 'number' ||\n !Number.isFinite(measure.value) ||\n typeof measure.unit !== 'string'\n ) {\n errors.push(`${at}.measure needs name, finite value and unit`)\n } else if (!(typeof measure.denominator === 'string' && measure.denominator)) {\n errors.push(`${at}.measure has no denominator`)\n }\n }\n for (const key of ['reproduce', 'recommendation'] as const) {\n if (finding[key] !== undefined && typeof finding[key] !== 'string')\n errors.push(`${at}.${key} must be a string`)\n }\n })\n return errors\n}\n\nfunction closed(\n value: Record<string, unknown>,\n allowed: readonly string[],\n at: string,\n errors: string[],\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) errors.push(`${at ? `${at}.` : ''}${key} is not allowed`)\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n","/**\n * The model pass: one prime-protocol exchange per selected run.\n *\n * The run's filtered spans are inlined into the prompt (prime has no trace\n * tools), the reply is one fenced JSON block of short rows, and each row that\n * claims a defect must cite span ids from that run. A row citing an id the run\n * does not hold, or an id that several runs share, is rejected with the reason\n * recorded, never repaired by guessing. Every accepted finding is `inferred`:\n * it is the model's reading, and the report keeps it apart from what the\n * deterministic pass observed.\n */\n\nimport type { PrimeBridgeTransport } from '../analyst/prime-bridge-transport'\nimport {\n buildPrimePrompt,\n type PrimeRawUsage,\n type PrimeReplyContract,\n primeProtocolSha256,\n runPrimeExchange,\n} from '../analyst/prime-protocol'\nimport { stableId } from './deterministic'\nimport type { DiagnosisFinding, DiagnosisSeverity } from './findings'\nimport { type DiagnosisSpan, durationMs } from './spans'\n\nexport interface DiagnosisModelOptions {\n /** One POST-shaped call to an OpenAI-compatible chat endpoint, or an equivalent local runner. */\n transport: PrimeBridgeTransport\n /** Endpoint the transport receives, e.g. `http://127.0.0.1:4181/v1/chat/completions`. */\n url: string\n /** Model id as the endpoint names it, e.g. `deepseek/deepseek-v4.1-flash`. */\n model: string\n /** Runs read by the model per diagnosis. Default 6. */\n maxTraces?: number\n /** Deadline for one exchange turn. Default 10 minutes. */\n timeoutMs?: number\n /** Inline budget for one rendered run. Default 400,000 characters. */\n maxInlineChars?: number\n /** Per-attribute character cap for the rendering. Default 600. */\n attributeChars?: number\n /** Segments of one long run the model reads, most errors first. Default 3. */\n maxSegmentsPerRun?: number\n /** Exact token rates; without them cost stays uncaptured. */\n pricing?: { inputUsdPerMillion: number; outputUsdPerMillion: number }\n}\n\nexport interface ModelRowNote {\n kind: 'operator' | 'topology'\n text: string\n evidence: string[]\n traceId?: string\n project?: string\n}\n\nexport interface ModelQuestion {\n question: string\n project?: string\n traceId?: string\n}\n\nexport interface ModelRejection {\n traceId?: string\n reason: string\n}\n\nexport interface ModelRunRecord {\n traceId: string\n ok: boolean\n failure?: string\n delivery?: { segment: number; segments: number; renderedChars: number }\n usage: PrimeRawUsage\n rows: number\n}\n\nexport interface ModelPassResult {\n findings: DiagnosisFinding[]\n questions: ModelQuestion[]\n notes: ModelRowNote[]\n summaries: Array<{ traceId: string; answer: string }>\n rejected: ModelRejection[]\n /** Runs the model read only in part, with which segments it read. */\n uncovered: ModelRejection[]\n runs: ModelRunRecord[]\n promptSha256: string\n}\n\nexport interface ModelPassInput {\n subject: 'internal' | 'customer'\n focus?: string\n projects?: readonly string[]\n contentIncluded: boolean\n}\n\ninterface RawRow {\n kind: 'finding' | 'question' | 'operator' | 'topology'\n severity?: DiagnosisSeverity\n claim?: string\n consequence?: string\n recommendation?: string\n question?: string\n project?: string\n evidence: string[]\n}\n\nconst MAX_ROWS = 12\nconst MAX_STRING = 400\nconst SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])\n\nexport function modelQuestion(input: ModelPassInput): string {\n const focus = input.focus ? ` The owner's question: ${input.focus}` : ''\n const projects =\n input.projects && input.projects.length > 0\n ? ` The runs belong to these projects: ${input.projects.join(', ')}; set \"project\" on a row to one of these names when the run shows which one it concerns.`\n : ''\n const withheld = input.contentIncluded\n ? ''\n : \" Prompt, response and tool payload content was withheld at the owner's choice; do not report its absence as a defect, and reason from span names, kinds, order, timing, status and the remaining attributes.\"\n return input.subject === 'internal'\n ? `Diagnose this coding-agent session from our own fleet: find concrete agent failures, wasted work, unsupported claims of success, and where the human operator's instructions caused trouble.${withheld}${projects}${focus}`\n : `Diagnose this agent run: find concrete failures, wasted work, and unsupported claims of success that cost the owner money, time, or correct results.${withheld}${projects}${focus}`\n}\n\nexport function modelContractLines(subject: 'internal' | 'customer'): string[] {\n const kinds =\n subject === 'internal' ? '\"finding\" | \"question\" | \"operator\"' : '\"finding\" | \"question\"'\n return [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) summarising what went wrong in this run, or that nothing did.',\n ` \"rows\": an array of at most ${MAX_ROWS} objects, each with \"kind\": ${kinds}.`,\n 'A \"finding\" row: {\"kind\":\"finding\",\"severity\":\"critical|high|medium|low\",\"claim\":\"one sentence stating the defect\",\"consequence\":\"what it cost in money, time, failed work or escalations\",\"recommendation\":\"the fix\",\"evidence\":[\"<span_id>\", ...]}.',\n 'A \"question\" row: {\"kind\":\"question\",\"question\":\"a concrete question the owner should answer\",\"evidence\":[]}.',\n ...(subject === 'internal'\n ? [\n 'An \"operator\" row: {\"kind\":\"operator\",\"claim\":\"one sentence critiquing how the human operator instructed or steered the agent\",\"evidence\":[\"<span_id>\", ...]}.',\n ]\n : []),\n 'Add \"project\": \"<repo or project name>\" to any row when the run shows which project it belongs to.',\n 'Every \"finding\" and \"operator\" row cites 1-8 span ids copied VERBATIM from the \"id\" fields of the trajectory. Rows citing ids that are not in the trajectory are discarded.',\n 'For elapsed wall time, compare the start and end timestamps and count overlapping spans only once. Do not add overlapping ms durations or call their sum a stall. If timestamps are missing, do not claim a total wall delay.',\n 'Keep every string under 400 characters. Report only what the trajectory shows; an empty rows array is a valid answer.',\n ]\n}\n\nexport async function runModelPass(\n traces: ReadonlyArray<{ traceId: string; spans: readonly DiagnosisSpan[] }>,\n ambiguousSpanIds: ReadonlySet<string>,\n input: ModelPassInput,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<ModelPassResult> {\n const question = modelQuestion(input)\n const contractLines = modelContractLines(input.subject)\n const promptSha256 = primeProtocolSha256({\n question,\n contractLines,\n repairContractLines: contractLines,\n limits: { maxRows: MAX_ROWS, maxString: MAX_STRING },\n })\n const result: ModelPassResult = {\n findings: [],\n questions: [],\n notes: [],\n summaries: [],\n rejected: [],\n uncovered: [],\n runs: [],\n promptSha256,\n }\n const maxInlineChars = options.maxInlineChars ?? 400_000\n const attributeChars = options.attributeChars ?? 600\n\n const maxSegments = options.maxSegmentsPerRun ?? 3\n for (const { traceId, spans } of traces) {\n const segments = segmentRun(spans, attributeChars, input.contentIncluded, maxInlineChars)\n const chosen = segments\n .map((segment, index) => ({ ...segment, index }))\n .sort((a, b) => b.errors - a.errors || a.index - b.index)\n .slice(0, maxSegments)\n .sort((a, b) => a.index - b.index)\n if (segments.length > chosen.length) {\n result.uncovered.push({\n traceId,\n reason: `the run renders to ${segments.length} segments of at most ${maxInlineChars} characters; the model read the ${chosen.length} with the most errors (${chosen.map((segment) => segment.index + 1).join(', ')})`,\n })\n }\n for (const segment of chosen) {\n const label =\n segments.length > 1 ? `${traceId} segment ${segment.index + 1}/${segments.length}` : traceId\n const ids = new Set(segment.spans.map((span) => span.spanId))\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, input.subject),\n } satisfies PrimeReplyContract<RawRow>,\n prompt: buildPrimePrompt({\n question,\n contractLines,\n trajectoryHeader: `TRAJECTORY (run ${label}; ${segment.spans.length} of the run's ${spans.length} spans, in start order; secrets redacted as [REDACTED:<kind>]):`,\n renderedTrajectory: segment.rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const delivery = {\n segment: segment.index + 1,\n segments: segments.length,\n renderedChars: segment.rendered.length,\n }\n if (!outcome.ok) {\n result.runs.push({\n traceId,\n ok: false,\n failure: `${label}: ${outcome.failure.kind}: ${outcome.failure.message}`,\n delivery,\n usage: outcome.usage,\n rows: 0,\n })\n continue\n }\n for (const rejection of outcome.rejected) {\n result.rejected.push({ traceId, reason: `row ${rejection.index}: ${rejection.reason}` })\n }\n if (outcome.overflow > 0) {\n result.rejected.push({\n traceId,\n reason: `${outcome.overflow} valid rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (outcome.answer)\n result.summaries.push({ traceId, answer: outcome.answer.slice(0, MAX_STRING) })\n acceptRows(result, outcome.rows, traceId, ids, ambiguousSpanIds)\n result.runs.push({\n traceId,\n ok: true,\n delivery,\n usage: outcome.usage,\n rows: outcome.rows.length,\n })\n }\n }\n return result\n}\n\n/** The topology reading: one exchange over the caller's run-graph summary, internal runs only. */\nexport async function runTopologyPass(\n topology: unknown,\n runIds: ReadonlySet<string>,\n options: DiagnosisModelOptions,\n signal?: AbortSignal,\n): Promise<{\n notes: ModelRowNote[]\n questions: ModelQuestion[]\n rejected: ModelRejection[]\n run: ModelRunRecord\n}> {\n const contractLines = [\n 'Reply with ONE fenced ```json block and nothing after it. The object has exactly two fields:',\n ' \"answer\": one paragraph (at most 400 characters) on how the agent fleet was organised today.',\n ` \"rows\": at most ${MAX_ROWS} objects, each either {\"kind\":\"topology\",\"claim\":\"one sentence on a spawn, messaging, hand-off or resume pattern that helped or hurt\",\"evidence\":[\"<run id>\", ...],\"project\":\"<optional>\"} or {\"kind\":\"question\",\"question\":\"...\",\"project\":\"<optional>\",\"evidence\":[]}.`,\n 'Every \"topology\" row cites 1-8 run ids copied VERBATIM from the graph. Keep every string under 400 characters.',\n ]\n const rendered = JSON.stringify(topology)\n const outcome = await runPrimeExchange({\n contract: {\n rowsField: 'rows',\n contractLines,\n repairContractLines: contractLines,\n maxRows: MAX_ROWS,\n decodeRow: (row) => decodeRow(row, 'topology'),\n },\n prompt: buildPrimePrompt({\n question:\n \"Analyse the topology of this agent fleet's runs: who spawned whom, who messaged whom, hand-offs and resumes. Name patterns that wasted work or lost context, and what to change.\",\n contractLines,\n trajectoryHeader: `RUN GRAPH (${runIds.size} runs):`,\n renderedTrajectory:\n rendered.length > (options.maxInlineChars ?? 400_000)\n ? rendered.slice(0, options.maxInlineChars ?? 400_000)\n : rendered,\n }),\n transport: options.transport,\n url: options.url,\n model: options.model,\n timeoutMs: options.timeoutMs ?? 600_000,\n repair: true,\n ...(signal ? { signal } : {}),\n })\n const notes: ModelRowNote[] = []\n const questions: ModelQuestion[] = []\n const rejected: ModelRejection[] = []\n if (outcome.ok && outcome.overflow > 0) {\n rejected.push({\n reason: `${outcome.overflow} valid topology rows beyond the ${MAX_ROWS}-row cap were dropped`,\n })\n }\n if (!outcome.ok) {\n return {\n notes,\n questions,\n rejected,\n run: {\n traceId: 'topology',\n ok: false,\n failure: `${outcome.failure.kind}: ${outcome.failure.message}`,\n usage: outcome.usage,\n rows: 0,\n },\n }\n }\n for (const row of outcome.rows) {\n if (row.kind === 'question') {\n questions.push({ question: row.question!, ...(row.project ? { project: row.project } : {}) })\n continue\n }\n const cited = row.evidence.filter((id) => runIds.has(id))\n if (cited.length === 0) {\n rejected.push({\n reason: `topology row \"${(row.claim ?? '').slice(0, 80)}\" cites no run id from the graph`,\n })\n continue\n }\n notes.push({\n kind: 'topology',\n text: row.claim!,\n evidence: cited,\n ...(row.project ? { project: row.project } : {}),\n })\n }\n if (outcome.answer)\n notes.unshift({ kind: 'topology', text: outcome.answer.slice(0, MAX_STRING), evidence: [] })\n return {\n notes,\n questions,\n rejected,\n run: { traceId: 'topology', ok: true, usage: outcome.usage, rows: outcome.rows.length },\n }\n}\n\nfunction acceptRows(\n result: ModelPassResult,\n rows: readonly RawRow[],\n traceId: string,\n ids: ReadonlySet<string>,\n ambiguousSpanIds: ReadonlySet<string>,\n): void {\n for (const row of rows) {\n const unresolved = row.evidence.filter((id) => !ids.has(id))\n const ambiguous = row.evidence.filter((id) => ambiguousSpanIds.has(id))\n const cited = row.evidence.filter((id) => ids.has(id) && !ambiguousSpanIds.has(id))\n if (unresolved.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids not in the segment it read: ${unresolved.slice(0, 5).join(', ')}`,\n })\n if (ambiguous.length > 0)\n result.rejected.push({\n traceId,\n reason: `${row.kind} row cites ids shared by several runs: ${ambiguous.slice(0, 5).join(', ')}`,\n })\n if (row.kind === 'question') {\n result.questions.push({\n question: row.question!,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n // A claim that leaned on an invalid id is not supported by the valid ones\n // left over, so the whole row goes rather than a trimmed version of it.\n if (unresolved.length > 0 || ambiguous.length > 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" discarded: it cites invalid evidence`,\n })\n continue\n }\n if (cited.length === 0) {\n result.rejected.push({\n traceId,\n reason: `${row.kind} row \"${(row.claim ?? '').slice(0, 80)}\" has no resolvable evidence`,\n })\n continue\n }\n if (row.kind === 'operator') {\n result.notes.push({\n kind: 'operator',\n text: row.claim!,\n evidence: cited,\n traceId,\n ...(row.project ? { project: row.project } : {}),\n })\n continue\n }\n result.findings.push({\n id: stableId('inferred', traceId, row.claim!),\n severity: row.severity!,\n claim: row.claim!,\n consequence: row.consequence!,\n evidence: cited,\n confidence: 'inferred',\n ...(row.recommendation ? { recommendation: row.recommendation } : {}),\n })\n }\n}\n\ninterface RunSegment {\n spans: DiagnosisSpan[]\n rendered: string\n errors: number\n}\n\n/**\n * Split a run, in start order, into contiguous segments that each render\n * within the inline budget. Inline is prime's only delivery, so a long run is\n * read as whole segments rather than silently truncated; which segments were\n * read and which were not is recorded by the caller.\n */\nexport function segmentRun(\n spans: readonly DiagnosisSpan[],\n attributeChars: number,\n contentIncluded: boolean,\n maxInlineChars: number,\n): RunSegment[] {\n const segments: RunSegment[] = []\n let current: DiagnosisSpan[] = []\n let parts: string[] = []\n let size = 2\n let errors = 0\n const flush = () => {\n if (current.length === 0) return\n segments.push({ spans: current, rendered: `[${parts.join(',')}]`, errors })\n current = []\n parts = []\n size = 2\n errors = 0\n }\n for (const span of spans) {\n let part = JSON.stringify(renderSpan(span, attributeChars, contentIncluded))\n if (part.length + 2 > maxInlineChars)\n part = JSON.stringify(renderSpan(span, 120, contentIncluded))\n if (size + part.length + 1 > maxInlineChars) flush()\n current.push(span)\n parts.push(part)\n size += part.length + 1\n if (span.status === 'ERROR') errors += 1\n }\n flush()\n return segments\n}\n\nfunction decodeRow(\n row: unknown,\n mode: 'internal' | 'customer' | 'topology',\n): { ok: true; row: RawRow } | { ok: false; reason: string } {\n if (row === null || typeof row !== 'object' || Array.isArray(row))\n return { ok: false, reason: 'row is not an object' }\n const value = row as Record<string, unknown>\n const kind = value.kind\n const allowed =\n mode === 'internal'\n ? ['finding', 'question', 'operator']\n : mode === 'customer'\n ? ['finding', 'question']\n : ['topology', 'question']\n if (typeof kind !== 'string' || !allowed.includes(kind))\n return { ok: false, reason: `kind ${String(kind)} is not allowed here` }\n const evidence = Array.isArray(value.evidence)\n ? value.evidence\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n .slice(0, 8)\n : []\n const project = shortString(value.project)\n if (kind === 'question') {\n const question = shortString(value.question)\n if (!question) return { ok: false, reason: 'question row has no question' }\n return { ok: true, row: { kind, question, evidence, ...(project ? { project } : {}) } }\n }\n const claim = shortString(value.claim)\n if (!claim) return { ok: false, reason: `${kind} row has no claim` }\n if (kind !== 'finding')\n return {\n ok: true,\n row: { kind: kind as RawRow['kind'], claim, evidence, ...(project ? { project } : {}) },\n }\n const severity = value.severity\n if (typeof severity !== 'string' || !SEVERITIES.has(severity))\n return { ok: false, reason: `severity ${String(severity)} is invalid` }\n const consequence = shortString(value.consequence)\n if (!consequence) return { ok: false, reason: 'finding row has no consequence' }\n const recommendation = shortString(value.recommendation)\n return {\n ok: true,\n row: {\n kind: 'finding',\n severity: severity as DiagnosisSeverity,\n claim,\n consequence,\n evidence,\n ...(recommendation ? { recommendation } : {}),\n ...(project ? { project } : {}),\n },\n }\n}\n\n/** One span as the model reads it: the pivots, then the attributes that remain after filtering. */\nfunction renderSpan(\n span: DiagnosisSpan,\n attributeChars: number,\n contentIncluded: boolean,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {\n id: span.spanId,\n parent: span.parentSpanId,\n kind: span.kind,\n name: span.name,\n }\n if (span.toolName) out.tool = span.toolName\n if (span.model) out.model = span.model\n if (span.status !== 'UNSET') out.status = span.status\n if (span.statusMessage) out.status_message = clip(span.statusMessage, attributeChars)\n const duration = durationMs(span)\n if (duration !== null) out.ms = duration\n if (span.startMs !== null && span.endMs !== null) {\n out.start = new Date(span.startMs).toISOString()\n out.end = new Date(span.endMs).toISOString()\n }\n const attrs: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(span.attributes)) {\n if (SKIP_ATTRIBUTES.has(key)) continue\n if (typeof value === 'string') attrs[key] = clip(value, attributeChars)\n else if (typeof value === 'number' || typeof value === 'boolean') attrs[key] = value\n else if (value !== null && value !== undefined)\n attrs[key] = clip(JSON.stringify(value), attributeChars)\n }\n if (Object.keys(attrs).length > 0) out.attrs = attrs\n if (!contentIncluded) out.content = 'withheld'\n return out\n}\n\n/** Pivots already rendered above, and resource noise that repeats on every span. */\nconst SKIP_ATTRIBUTES = new Set([\n 'openinference.span.kind',\n 'tool.name',\n 'gen_ai.tool.name',\n 'llm.model_name',\n 'gen_ai.request.model',\n 'service.name',\n 'agent.name',\n 'source_file',\n 'otel.scope.name',\n 'telemetry.sdk.name',\n 'telemetry.sdk.language',\n 'telemetry.sdk.version',\n])\n\nfunction clip(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max)}…[+${value.length - max} chars]`\n}\n\nfunction shortString(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n if (!trimmed) return undefined\n return trimmed.length <= MAX_STRING ? trimmed : `${trimmed.slice(0, MAX_STRING)}…`\n}\n","/**\n * The agent-failure diagnosis engine: flat spans plus context in, a findings\n * document out.\n *\n * It is a plain function. Its only side effect is the model call made through\n * the caller's transport, and in deterministic mode it makes none. It keeps no\n * storage, files no issues, and retains nothing: where the spans came from and\n * where the findings go belong to the caller. That is what lets one engine\n * serve both the internal daily mining run and a customer diagnosis while their\n * data paths stay separate.\n *\n * Order of operations, each step reading only the previous step's output:\n * 1. secret filter and content drop over every input (spans, focus, topology);\n * 2. the deterministic pass: capability table, execution facts, observed findings;\n * 3. in model mode, the prime-protocol pass over the highest-signal runs;\n * 4. evidence resolution: every cited id must be a span id of the input that\n * no other run shares; findings left without evidence are rejected.\n */\n\nimport { packageVersion } from '../package-version'\nimport { redact, redactText } from '../trace/redact'\nimport { type DeterministicResult, groupByTrace, runDeterministicPass } from './deterministic'\nimport {\n type DiagnosisFinding,\n type DiagnosisFindingsDocument,\n SEVERITY_RANK,\n validateDiagnosisFindings,\n} from './findings'\nimport {\n type DiagnosisModelOptions,\n type ModelQuestion,\n type ModelRejection,\n type ModelRowNote,\n type ModelRunRecord,\n runModelPass,\n runTopologyPass,\n} from './model-pass'\nimport { type IngestReport, ingestSpans } from './spans'\n\nexport interface DiagnosisContext {\n /** Whose traces these are. Operator critique and topology run only for `internal`. */\n subject: 'internal' | 'customer'\n /** What was analysed, in the owner's words. Never an internal id for a customer. */\n label: string\n /** The owner's question, e.g. from the intake form. */\n focus?: string\n /**\n * Whether prompt, response and tool payload attributes may be read. Default\n * false: they are dropped before anything reads the spans.\n */\n contentIncluded?: boolean\n /** Project or repository names the runs belong to, for grouping questions. */\n projects?: string[]\n /** A run-graph summary (internal only), e.g. from the lineage graph. */\n topology?: { runs: Array<{ id: string } & Record<string, unknown>> } & Record<string, unknown>\n}\n\nexport type DiagnosisOptions =\n | { mode: 'deterministic'; reason?: string; signal?: AbortSignal }\n | { mode: 'model'; model: DiagnosisModelOptions; signal?: AbortSignal }\n\nexport interface DiagnosisUsage {\n exchanges: number\n inputTokens: number | null\n outputTokens: number | null\n usd: number | null\n}\n\nexport interface DiagnosisResult {\n /** Validates against diagnosis-findings-v1. The only part a customer report renders. */\n document: DiagnosisFindingsDocument\n /** Questions for the owner, grouped later by project. */\n questions: ModelQuestion[]\n /** Operator critique and topology notes; internal runs only. */\n notes: ModelRowNote[]\n /** The model's one-paragraph reading of each run it read. */\n summaries: Array<{ traceId: string; answer: string }>\n facts: DeterministicResult['facts']\n conformance: DeterministicResult['validation']['findings']\n ingest: IngestReport\n /** Model rows and findings dropped, each with why. */\n rejected: ModelRejection[]\n model: {\n used: boolean\n model: string | null\n runs: ModelRunRecord[]\n promptSha256: string | null\n usage: DiagnosisUsage\n }\n engine: { name: 'agent-eval/diagnosis'; version: string }\n}\n\nexport const DEFAULT_MAX_MODEL_TRACES = 6\n/** Runs with fewer spans carry too little for the model to read. */\nexport const MIN_MODEL_SPANS = 3\n\nexport async function diagnoseSpans(\n spans: readonly unknown[],\n context: DiagnosisContext,\n options: DiagnosisOptions,\n): Promise<DiagnosisResult> {\n if (context.subject !== 'internal' && context.subject !== 'customer') {\n throw new TypeError(\n `diagnoseSpans: subject must be internal or customer, got ${String(context.subject)}`,\n )\n }\n if (context.subject === 'customer' && context.topology !== undefined) {\n throw new TypeError(\n 'diagnoseSpans: topology analysis is internal only; a customer context must not carry one',\n )\n }\n const contentIncluded = context.contentIncluded === true\n const { spans: filtered, report: ingest } = ingestSpans(spans, { contentIncluded })\n const focus =\n context.focus === undefined ? undefined : redactText(context.focus, { report: ingest.secrets })\n const deterministic = runDeterministicPass(filtered)\n const skipped = [...deterministic.skipped]\n const ambiguous = new Set(ingest.ambiguousSpanIds)\n const rejected: ModelRejection[] = []\n const questions: ModelQuestion[] = []\n const notes: ModelRowNote[] = []\n const summaries: Array<{ traceId: string; answer: string }> = []\n const runs: ModelRunRecord[] = []\n let promptSha256: string | null = null\n let modelFindings: DiagnosisFinding[] = []\n\n const traces = groupByTrace(filtered)\n if (options.mode === 'deterministic') {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: options.reason ?? 'deterministic mode: no model call was made',\n })\n } else {\n const maxTraces = options.model.maxTraces ?? DEFAULT_MAX_MODEL_TRACES\n const ranked = rankTraces(traces)\n const selected = ranked.slice(0, maxTraces)\n const short = traces.size - ranked.length\n if (ranked.length === 0) {\n skipped.push({\n analysis: 'model reading of the runs',\n reason: `no run has the ${MIN_MODEL_SPANS} spans the model needs to read it; ${traces.size} runs were too short`,\n })\n } else if (short > 0) {\n skipped.push({\n analysis: `model reading of ${short} of ${traces.size} runs`,\n reason: `those runs have fewer than ${MIN_MODEL_SPANS} spans, too few for the model to read`,\n })\n }\n if (ranked.length > selected.length) {\n skipped.push({\n analysis: `model reading of ${ranked.length - selected.length} of ${ranked.length} runs`,\n reason: `the model reads at most ${maxTraces} runs per diagnosis, chosen by error count then size`,\n })\n }\n const pass = await runModelPass(\n selected,\n ambiguous,\n {\n subject: context.subject,\n contentIncluded,\n ...(focus ? { focus } : {}),\n ...(context.projects ? { projects: context.projects } : {}),\n },\n options.model,\n options.signal,\n )\n promptSha256 = pass.promptSha256\n modelFindings = pass.findings\n questions.push(...pass.questions)\n notes.push(...(context.subject === 'internal' ? pass.notes : []))\n summaries.push(...pass.summaries)\n rejected.push(...pass.rejected)\n runs.push(...pass.runs)\n for (const gap of pass.uncovered) {\n skipped.push({ analysis: `model reading of part of run ${gap.traceId}`, reason: gap.reason })\n }\n for (const run of pass.runs) {\n if (!run.ok)\n skipped.push({\n analysis: `model reading of run ${run.traceId}`,\n reason: run.failure ?? 'failed',\n })\n }\n if (context.subject === 'internal' && context.topology) {\n const topology = redact(context.topology, { report: ingest.secrets }).value\n const runIds = new Set(\n (topology.runs ?? [])\n .map((run) => run.id)\n .filter((id): id is string => typeof id === 'string'),\n )\n const reading = await runTopologyPass(topology, runIds, options.model, options.signal)\n notes.push(...reading.notes)\n questions.push(...reading.questions)\n rejected.push(...reading.rejected)\n runs.push(reading.run)\n if (!reading.run.ok)\n skipped.push({ analysis: 'topology reading', reason: reading.run.failure ?? 'failed' })\n }\n }\n\n const spanIds = new Set(filtered.map((span) => span.spanId))\n const findings = resolveEvidence(\n [...deterministic.findings, ...modelFindings],\n spanIds,\n ambiguous,\n rejected,\n ).sort(\n (a, b) =>\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] ||\n (a.confidence === b.confidence ? 0 : a.confidence === 'observed' ? -1 : 1),\n )\n\n const document: DiagnosisFindingsDocument = {\n schemaVersion: 1,\n subject: {\n label: redactText(context.label, { report: ingest.secrets }),\n runCount: traces.size,\n window: deterministic.window,\n contentIncluded,\n },\n coverage: {\n capabilities: deterministic.capabilities,\n skipped,\n redaction: {\n redactionCount: ingest.secrets.redactionCount,\n byRule: { ...ingest.secrets.byDetector },\n droppedAttributes: ingest.droppedAttributes,\n },\n },\n findings,\n }\n const defects = validateDiagnosisFindings(document, { spanIds })\n if (defects.length > 0) {\n throw new Error(\n `diagnoseSpans produced an invalid findings document: ${defects.slice(0, 5).join('; ')}`,\n )\n }\n const pricing = options.mode === 'model' ? options.model.pricing : undefined\n return {\n document,\n questions,\n notes,\n summaries,\n facts: deterministic.facts,\n conformance: deterministic.validation.findings,\n ingest,\n rejected,\n model: {\n used: options.mode === 'model',\n model: options.mode === 'model' ? options.model.model : null,\n runs,\n promptSha256,\n usage: totalUsage(runs, pricing),\n },\n engine: { name: 'agent-eval/diagnosis', version: packageVersion() },\n }\n}\n\n/** Runs with more errors first, then larger runs; runs under MIN_MODEL_SPANS are left out. */\nfunction rankTraces(traces: ReadonlyMap<string, import('./spans').DiagnosisSpan[]>) {\n return [...traces.entries()]\n .filter(([, spans]) => spans.length >= MIN_MODEL_SPANS)\n .map(([traceId, spans]) => ({\n traceId,\n spans,\n errors: spans.filter((span) => span.status === 'ERROR').length,\n }))\n .sort(\n (a, b) =>\n b.errors - a.errors ||\n b.spans.length - a.spans.length ||\n a.traceId.localeCompare(b.traceId),\n )\n}\n\nfunction resolveEvidence(\n findings: DiagnosisFinding[],\n spanIds: ReadonlySet<string>,\n ambiguous: ReadonlySet<string>,\n rejected: ModelRejection[],\n): DiagnosisFinding[] {\n const kept: DiagnosisFinding[] = []\n for (const finding of findings) {\n const evidence = finding.evidence.filter((id) => spanIds.has(id) && !ambiguous.has(id))\n if (evidence.length === 0) {\n rejected.push({\n reason: `finding ${finding.id} lost all evidence: its span ids are missing or shared by several runs`,\n })\n continue\n }\n kept.push({ ...finding, evidence })\n }\n return kept\n}\n\n/**\n * Token and cost totals over the model exchanges. No exchange attempted is a\n * measured zero. An exchange that failed without reporting usage may still\n * have been billed, so it makes the totals unknown (null) rather than zero.\n */\nfunction totalUsage(\n runs: readonly ModelRunRecord[],\n pricing: DiagnosisModelOptions['pricing'],\n): DiagnosisUsage {\n let inputTokens: number | null = 0\n let outputTokens: number | null = 0\n let exchanges = 0\n for (const run of runs) {\n exchanges += 1\n inputTokens =\n inputTokens === null || run.usage.inputTokens === null\n ? null\n : inputTokens + run.usage.inputTokens\n outputTokens =\n outputTokens === null || run.usage.outputTokens === null\n ? null\n : outputTokens + run.usage.outputTokens\n }\n const usd =\n exchanges === 0\n ? 0\n : pricing && inputTokens !== null && outputTokens !== null\n ? (inputTokens * pricing.inputUsdPerMillion + outputTokens * pricing.outputUsdPerMillion) /\n 1_000_000\n : null\n return { exchanges, inputTokens, outputTokens, usd }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { a as resolveModelPricing } from "./metrics-DOMpkoeb.js";
2
2
  import { _ as removeCredentialEnvironment, a as closeServer, c as waitForActiveHandlers, d as assertExternalOptimizerModelBudget, i as startExternalOptimizerModelProxy, o as listenLocal, r as runWithCleanup, s as sendJsonIfOpen, t as runExternalOptimizerProcess, v as resolveExternalOptimizerCallbackLimits, y as resolveExternalOptimizerProcessLimits } from "./external-optimizer-subprocess-C0EsxEbI.js";
3
- import { P as RawAnalystFindingSchema, R as coerceJson, W as parseFindingSubject } from "./kind-factory-Cn1lbsAd.js";
3
+ import { L as coerceJson, N as RawAnalystFindingSchema, U as parseFindingSubject } from "./kind-factory-ivTx6koH.js";
4
4
  import { randomBytes } from "node:crypto";
5
5
  import { createServer } from "node:http";
6
6
  /**
@@ -462,4 +462,4 @@ function isRecord(value) {
462
462
  //#endregion
463
463
  export { decodeRawFindingArray as n, createDspyRlmTraceEngine as t };
464
464
 
465
- //# sourceMappingURL=dspy-rlm-engine-sHwdSxK3.js.map
465
+ //# sourceMappingURL=dspy-rlm-engine-BpaKVKJA.js.map