@tangle-network/agent-eval 0.192.0 → 0.193.2

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 (141) hide show
  1. package/CHANGELOG.md +45 -2
  2. package/dist/adapters/http.d.ts +2 -2
  3. package/dist/analyst/index.d.ts +6 -6
  4. package/dist/analyst/index.js +4 -4
  5. package/dist/{analyze-runs-SCSWYpy0.js → analyze-runs-B6gv7vAT.js} +2 -2
  6. package/dist/{analyze-runs-SCSWYpy0.js.map → analyze-runs-B6gv7vAT.js.map} +1 -1
  7. package/dist/{benchmark-command-C458yEFK.js → benchmark-command-N5r3GXMP.js} +8 -8
  8. package/dist/{benchmark-command-C458yEFK.js.map → benchmark-command-N5r3GXMP.js.map} +1 -1
  9. package/dist/benchmarks/index.d.ts +3 -3
  10. package/dist/benchmarks/index.js +3 -3
  11. package/dist/campaign/index.d.ts +5 -5
  12. package/dist/campaign/index.js +11 -10
  13. package/dist/{campaign-BVQVBEfH.js → campaign-DnL0S4XL.js} +11 -10
  14. package/dist/{campaign-BVQVBEfH.js.map → campaign-DnL0S4XL.js.map} +1 -1
  15. package/dist/{campaign-evidence-DcQiYhJI.js → campaign-evidence-DJc60F9C.js} +2 -2
  16. package/dist/{campaign-evidence-DcQiYhJI.js.map → campaign-evidence-DJc60F9C.js.map} +1 -1
  17. package/dist/{chat-client-B_ItsSBw.js → chat-client-CJORSG_J.js} +2 -2
  18. package/dist/{chat-client-B_ItsSBw.js.map → chat-client-CJORSG_J.js.map} +1 -1
  19. package/dist/{chat-json-call-CXHBvUz8.js → chat-json-call-DnlDjpco.js} +2 -2
  20. package/dist/{chat-json-call-CXHBvUz8.js.map → chat-json-call-DnlDjpco.js.map} +1 -1
  21. package/dist/cli.js +49 -12
  22. package/dist/cli.js.map +1 -1
  23. package/dist/{client-wFyDisxi.d.ts → client-dMMKoQNS.d.ts} +2 -2
  24. package/dist/{client-wFyDisxi.d.ts.map → client-dMMKoQNS.d.ts.map} +1 -1
  25. package/dist/contract/index.d.ts +7 -7
  26. package/dist/contract/index.js +11 -11
  27. package/dist/{default-registry-DdqA_-_o.d.ts → default-registry-C3HTE08O.d.ts} +3 -3
  28. package/dist/{default-registry-DdqA_-_o.d.ts.map → default-registry-C3HTE08O.d.ts.map} +1 -1
  29. package/dist/{define-agent-eval-DcludNJS.d.ts → define-agent-eval-DQJvVa1P.d.ts} +6 -6
  30. package/dist/{define-agent-eval-DcludNJS.d.ts.map → define-agent-eval-DQJvVa1P.d.ts.map} +1 -1
  31. package/dist/{define-agent-eval-DQuos3Aw.js → define-agent-eval-qxAPjMSL.js} +6 -6
  32. package/dist/{define-agent-eval-DQuos3Aw.js.map → define-agent-eval-qxAPjMSL.js.map} +1 -1
  33. package/dist/diagnosis/index.d.ts +1 -1
  34. package/dist/diagnosis/index.d.ts.map +1 -1
  35. package/dist/diagnosis/index.js +12 -6
  36. package/dist/diagnosis/index.js.map +1 -1
  37. package/dist/{dspy-rlm-engine-BX34vPVY.js → dspy-rlm-engine-k_QdEBZo.js} +2 -2
  38. package/dist/{dspy-rlm-engine-BX34vPVY.js.map → dspy-rlm-engine-k_QdEBZo.js.map} +1 -1
  39. package/dist/{engine-C1DIAEpn.d.ts → engine-DjRV55F9.d.ts} +2 -2
  40. package/dist/{engine-C1DIAEpn.d.ts.map → engine-DjRV55F9.d.ts.map} +1 -1
  41. package/dist/{eval-campaign-CwsBn0Gm.js → eval-campaign-CXT2WYUe.js} +2 -2
  42. package/dist/{eval-campaign-CwsBn0Gm.js.map → eval-campaign-CXT2WYUe.js.map} +1 -1
  43. package/dist/evaluation.d.ts +1 -1
  44. package/dist/experiment/index.d.ts +2 -2
  45. package/dist/experiment/index.js +4 -4
  46. package/dist/{external-optimizer-process-D-Sab4v3.js → external-optimizer-process-_YIECYJ7.js} +2 -2
  47. package/dist/{external-optimizer-process-D-Sab4v3.js.map → external-optimizer-process-_YIECYJ7.js.map} +1 -1
  48. package/dist/{external-optimizer-subprocess-kbqC-iWf.js → external-optimizer-subprocess-BrghTvEp.js} +2 -2
  49. package/dist/{external-optimizer-subprocess-kbqC-iWf.js.map → external-optimizer-subprocess-BrghTvEp.js.map} +1 -1
  50. package/dist/hosted/index.d.ts +2 -2
  51. package/dist/hosted/index.js +1 -1
  52. package/dist/{index-DBoXFaz0.d.ts → index-0jEtpSM7.d.ts} +3 -3
  53. package/dist/{index-DBoXFaz0.d.ts.map → index-0jEtpSM7.d.ts.map} +1 -1
  54. package/dist/{index-DwQxdWve.d.ts → index-DMPLG226.d.ts} +89 -272
  55. package/dist/index-DMPLG226.d.ts.map +1 -0
  56. package/dist/{index-DNVzu9Vv.d.ts → index-DWQNDqPd.d.ts} +7 -7
  57. package/dist/{index-DNVzu9Vv.d.ts.map → index-DWQNDqPd.d.ts.map} +1 -1
  58. package/dist/index.d.ts +10 -10
  59. package/dist/index.js +60 -308
  60. package/dist/index.js.map +1 -1
  61. package/dist/jev.d.ts +1 -1
  62. package/dist/ledger-core/index.d.ts +1 -1
  63. package/dist/{llm-client-KYQBh9C8.js → llm-client-c_bKHTXz.js} +2 -2
  64. package/dist/{llm-client-KYQBh9C8.js.map → llm-client-c_bKHTXz.js.map} +1 -1
  65. package/dist/{llm-judge-Z6MkTkd0.js → llm-judge-Cififl_V.js} +1024 -237
  66. package/dist/llm-judge-Cififl_V.js.map +1 -0
  67. package/dist/{matrix-CQMMrEQ5.d.ts → matrix-CNu13gg8.d.ts} +2 -2
  68. package/dist/{matrix-CQMMrEQ5.d.ts.map → matrix-CNu13gg8.d.ts.map} +1 -1
  69. package/dist/multishot/golden/index.d.ts +1 -1
  70. package/dist/multishot/index.d.ts +2 -2
  71. package/dist/openapi.json +1 -1
  72. package/dist/{otel-spans-DS7t1t1J.js → otel-spans-CQmSxtcS.js} +2 -2
  73. package/dist/{otel-spans-DS7t1t1J.js.map → otel-spans-CQmSxtcS.js.map} +1 -1
  74. package/dist/paired-delta-test-BF-FEP8V.js +78 -0
  75. package/dist/paired-delta-test-BF-FEP8V.js.map +1 -0
  76. package/dist/{paired-promotion-decision-6cn3bLc3.js → paired-promotion-decision-DTKl6-G8.js} +4 -77
  77. package/dist/paired-promotion-decision-DTKl6-G8.js.map +1 -0
  78. package/dist/pipelines/index.d.ts +1 -1
  79. package/dist/{produced-state-CVmCPQDJ.js → produced-state-B2AhDRnq.js} +4 -4
  80. package/dist/{produced-state-CVmCPQDJ.js.map → produced-state-B2AhDRnq.js.map} +1 -1
  81. package/dist/{promotion-policy-CfMNUro2.js → promotion-policy-Cy5OV8BV.js} +3 -3
  82. package/dist/{promotion-policy-CfMNUro2.js.map → promotion-policy-Cy5OV8BV.js.map} +1 -1
  83. package/dist/{raw-provider-sink-DYh4Bszw.js → raw-provider-sink-CXuOhLvT.js} +2 -2
  84. package/dist/{raw-provider-sink-DYh4Bszw.js.map → raw-provider-sink-CXuOhLvT.js.map} +1 -1
  85. package/dist/{redact-CopuMxll.d.ts → redact-Cveoq6fJ.d.ts} +2 -2
  86. package/dist/{redact-CopuMxll.d.ts.map → redact-Cveoq6fJ.d.ts.map} +1 -1
  87. package/dist/{redact-B7rt9Zot.js → redact-Dk1ZdJEm.js} +59 -26
  88. package/dist/redact-Dk1ZdJEm.js.map +1 -0
  89. package/dist/rl.d.ts +1 -1
  90. package/dist/rl.js +2 -2
  91. package/dist/{search-ledger-Ck7tok0h.js → search-ledger-CJiAEU3j.js} +89 -27
  92. package/dist/search-ledger-CJiAEU3j.js.map +1 -0
  93. package/dist/{search-ledger-types-C9anU2DX.d.ts → search-ledger-types-B3El5xgS.d.ts} +95 -11
  94. package/dist/search-ledger-types-B3El5xgS.d.ts.map +1 -0
  95. package/dist/{search-shipper-BG182p-U.js → search-shipper-DUlwlCsK.js} +2 -2
  96. package/dist/{search-shipper-BG182p-U.js.map → search-shipper-DUlwlCsK.js.map} +1 -1
  97. package/dist/search-summary-BhY8p0Av.js +378 -0
  98. package/dist/search-summary-BhY8p0Av.js.map +1 -0
  99. package/dist/{semantic-concept-judge-Bg-560H0.js → semantic-concept-judge-Bh5lvKGg.js} +4 -4
  100. package/dist/{semantic-concept-judge-Bg-560H0.js.map → semantic-concept-judge-Bh5lvKGg.js.map} +1 -1
  101. package/dist/{sequential-lwJOTRON.js → sequential-C21_PP7F.js} +2 -2
  102. package/dist/{sequential-lwJOTRON.js.map → sequential-C21_PP7F.js.map} +1 -1
  103. package/dist/{server-DtetGGoA.js → server-D56r1lhp.js} +2 -2
  104. package/dist/{server-DtetGGoA.js.map → server-D56r1lhp.js.map} +1 -1
  105. package/dist/{skillopt-optimization-method-DoayuM6D.js → skillopt-optimization-method-C6DbFKnw.js} +8 -8
  106. package/dist/{skillopt-optimization-method-DoayuM6D.js.map → skillopt-optimization-method-C6DbFKnw.js.map} +1 -1
  107. package/dist/{spans-BWtjk_9c.d.ts → spans-D9_ehFuk.d.ts} +2 -2
  108. package/dist/{spans-BWtjk_9c.d.ts.map → spans-D9_ehFuk.d.ts.map} +1 -1
  109. package/dist/{statistical-heldout-C1Ej5Ce8.d.ts → statistical-heldout-D-xBpbrd.d.ts} +2 -2
  110. package/dist/{statistical-heldout-C1Ej5Ce8.d.ts.map → statistical-heldout-D-xBpbrd.d.ts.map} +1 -1
  111. package/dist/{statistical-heldout-GcLIPxk4.js → statistical-heldout-DANVmyug.js} +2 -2
  112. package/dist/{statistical-heldout-GcLIPxk4.js.map → statistical-heldout-DANVmyug.js.map} +1 -1
  113. package/dist/{store-tool-spans-BcC_5ef-.js → store-tool-spans-BaGakFc2.js} +2 -2
  114. package/dist/{store-tool-spans-BcC_5ef-.js.map → store-tool-spans-BaGakFc2.js.map} +1 -1
  115. package/dist/{store-tool-spans-ByLdU26j.d.ts → store-tool-spans-BxrfuU2t.d.ts} +4 -4
  116. package/dist/{store-tool-spans-ByLdU26j.d.ts.map → store-tool-spans-BxrfuU2t.d.ts.map} +1 -1
  117. package/dist/{task-failure-attributes-CEqEfuIY.js → task-failure-attributes-DngaLdE4.js} +4 -3
  118. package/dist/task-failure-attributes-DngaLdE4.js.map +1 -0
  119. package/dist/{tool-groups-DiBi16ns.d.ts → tool-groups-BC9O7Epn.d.ts} +2 -2
  120. package/dist/tool-groups-BC9O7Epn.d.ts.map +1 -0
  121. package/dist/trace-repair/index.d.ts +1 -1
  122. package/dist/traces.d.ts +3 -3
  123. package/dist/traces.js +4 -4
  124. package/dist/{types-C1CAD70_.d.ts → types-BWwRXofp.d.ts} +328 -4
  125. package/dist/types-BWwRXofp.d.ts.map +1 -0
  126. package/dist/{types-ByZslIlr.d.ts → types-qoxUfKQg.d.ts} +2 -2
  127. package/dist/{types-ByZslIlr.d.ts.map → types-qoxUfKQg.d.ts.map} +1 -1
  128. package/dist/wire/index.js +1 -1
  129. package/docs/search-ledger.md +71 -6
  130. package/package.json +2 -2
  131. package/dist/claim-BGOUqoMq.d.ts +0 -38
  132. package/dist/claim-BGOUqoMq.d.ts.map +0 -1
  133. package/dist/index-DwQxdWve.d.ts.map +0 -1
  134. package/dist/llm-judge-Z6MkTkd0.js.map +0 -1
  135. package/dist/paired-promotion-decision-6cn3bLc3.js.map +0 -1
  136. package/dist/redact-B7rt9Zot.js.map +0 -1
  137. package/dist/search-ledger-Ck7tok0h.js.map +0 -1
  138. package/dist/search-ledger-types-C9anU2DX.d.ts.map +0 -1
  139. package/dist/task-failure-attributes-CEqEfuIY.js.map +0 -1
  140. package/dist/tool-groups-DiBi16ns.d.ts.map +0 -1
  141. package/dist/types-C1CAD70_.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"paired-promotion-decision-6cn3bLc3.js","names":[],"sources":["../src/paired-delta-test.ts","../src/paired-promotion-decision.ts"],"sourcesContent":["import {\n type PairedBootstrapOptions,\n type PairedBootstrapResult,\n pairedBootstrap,\n pairedSignTest,\n} from './statistics'\n\nexport interface PairedDeltaTestOptions extends PairedBootstrapOptions {\n /** Smallest candidate-minus-baseline delta that counts as improvement. Default 0. */\n threshold?: number\n /** Caller-required paired observations. The exact test may impose a higher minimum. */\n minPairs?: number\n}\n\nexport interface PairedDeltaTestResult {\n bootstrap: PairedBootstrapResult\n method: 'bootstrap-ci' | 'exact-sign'\n /** Exact one-sided p-value below the bootstrap minimum; otherwise null. */\n pValue: number | null\n /** Effective observation minimum after accounting for confidence. */\n minimumPairs: number\n sufficient: boolean\n /**\n * The bootstrap interval has zero width (or is non-finite), so it carries no\n * information about how far the estimate could be wrong and cannot support a\n * decision in either direction. See {@link pairedDeltaTest}.\n */\n indeterminate: boolean\n significant: boolean\n}\n\n/** Smallest all-positive sample that can clear a one-sided exact sign test. */\nexport function minimumPairsForPairedDeltaTest(confidence = 0.95): number {\n if (!Number.isFinite(confidence) || confidence <= 0 || confidence >= 1) {\n throw new Error(\n `minimumPairsForPairedDeltaTest: confidence must be in (0,1), got ${confidence}`,\n )\n }\n const oneSidedAlpha = (1 - confidence) / 2\n return Math.ceil(Math.log2(1 / oneSidedAlpha))\n}\n\n/**\n * Tests whether a paired candidate-minus-baseline delta clears a threshold.\n *\n * At 20 or more pairs, the percentile bootstrap lower bound carries the\n * decision. Below that point the interval is descriptive only, so the function\n * switches to a pre-registered one-sided exact sign test. The exact path is\n * deliberately conservative: it requires both a point estimate above the\n * threshold and enough consistently positive paired differences.\n *\n * ## A zero-width interval is never significant\n *\n * When every paired delta is identical the resample distribution is a point\n * mass and the interval collapses: `[0, 0]` when all pairs tie, `[g, g]` on n\n * identical deltas of g. Neither says the effect is certain — both say the\n * sample carries no information about how far the estimate could be wrong, and\n * `low > threshold` then answers on the point estimate alone. It fails in both\n * directions: `[0, 0]` clears every NEGATIVE threshold, which is how a\n * tie-dominated pass/fail comparison laundered a regression into a\n * noninferiority pass, and `[g, g]` clears every threshold below g with no\n * spread behind it. Under a bounded asymmetric null whose true mean paired\n * delta is exactly 0 — 2 % of pairs dropping by 1.0, the rest gaining 0.0204 —\n * every sample that misses the drop is exactly that shape, and deciding on\n * `low > 0` promoted 65.65 % of samples at n = 20 against a nominal 5 %.\n *\n * So `indeterminate` is reported and `significant` is false whenever the\n * interval has zero width, on BOTH paths: at small n the exact sign test is a\n * test of the MEDIAN and a zero-spread sample is precisely where it stops\n * saying anything about the mean the caller is thresholding.\n *\n * `threshold` may be negative — that is a noninferiority margin, and it is the\n * regime the zero-width hole is worst in. For a two-point (pass/fail) outcome\n * the percentile bootstrap is not a valid interval at a nonzero margin at all;\n * use {@link decidePairedPromotion}, which routes those to Tango's score\n * interval, rather than thresholding this function's bootstrap directly.\n */\nexport function pairedDeltaTest(\n before: number[],\n after: number[],\n options: PairedDeltaTestOptions = {},\n): PairedDeltaTestResult {\n const threshold = options.threshold ?? 0\n if (!Number.isFinite(threshold)) {\n throw new Error(`pairedDeltaTest: threshold must be finite, got ${threshold}`)\n }\n const confidence = options.confidence ?? 0.95\n const exactMinimum = minimumPairsForPairedDeltaTest(confidence)\n const requestedMinimum = options.minPairs ?? exactMinimum\n if (!Number.isInteger(requestedMinimum) || requestedMinimum < 1) {\n throw new Error(`pairedDeltaTest: minPairs must be a positive integer, got ${requestedMinimum}`)\n }\n const minimumPairs = Math.max(requestedMinimum, exactMinimum)\n const bootstrap = pairedBootstrap(before, after, options)\n const sufficient = bootstrap.n >= minimumPairs\n // A point-mass resample distribution is an absence of evidence, not a\n // certainty, and it is the shape that clears every negative threshold. Both\n // paths refuse it: see the \"zero-width\" section of this function's docs.\n const indeterminate =\n bootstrap.n > 0 &&\n (!Number.isFinite(bootstrap.low) ||\n !Number.isFinite(bootstrap.high) ||\n bootstrap.low === bootstrap.high)\n\n if (bootstrap.gateEligible) {\n return {\n bootstrap,\n method: 'bootstrap-ci',\n pValue: null,\n minimumPairs,\n sufficient,\n indeterminate,\n significant: sufficient && !indeterminate && bootstrap.low > threshold,\n }\n }\n\n const differences = before.map((value, index) => after[index]! - value - threshold)\n const exact = pairedSignTest(differences, 'greater')\n const estimate = options.statistic === 'mean' ? bootstrap.mean : bootstrap.median\n return {\n bootstrap,\n method: 'exact-sign',\n pValue: exact.pValue,\n minimumPairs,\n sufficient,\n indeterminate,\n significant:\n sufficient &&\n !indeterminate &&\n estimate > threshold &&\n exact.pValue <= (1 - bootstrap.confidence) / 2,\n }\n}\n","/**\n * @module\n * ONE rule for \"does this paired interval clear a promotion threshold\".\n *\n * The rule below was derived on `HeldOutGate` (#479) after the same estimator\n * bug shipped twice. It then turned out that a SECOND gate — the composable\n * `heldOutGate`, plus everything else routed through `heldoutSignificance` —\n * still carried the original defect, because the rule had been written into one\n * gate's method body rather than into a shared function. Two copies of a\n * statistical rule is how a defect survives in one of them, so there is now\n * exactly one copy and both gates call it.\n *\n * Three things the rule does that a bare `pairedBootstrap(...).low > threshold`\n * does not:\n *\n * 1. **Two-point (pass/fail) outcomes decide on Tango's SCORE interval.** On a\n * pass/fail eval the paired delta vector is dominated by ties, so the\n * bootstrap of the mean is a resample of a lattice with three atoms and its\n * percentile interval is not valid at a nonzero margin. The score interval\n * (`pairedRiskDifferenceScore`) re-estimates the nuisance loss rate under\n * each hypothesised margin instead of fixing it at the observed value, which\n * is the only construction that stays a confidence interval as the margin\n * moves off zero — the regime every noninferiority threshold lives in.\n * Measured on the composable gate before this change, at a true risk\n * difference sitting exactly on the production caller's -0.05 margin and a\n * nominal 5 %: 14.60 % false promotion at n = 40 and 10.10 % at n = 76.\n * 2. **McNemar's exact test holds a VETO at every non-negative threshold.**\n * Redundant with the interval by construction and kept anyway, so that\n * swapping the estimator for one without that duality cannot silently\n * reintroduce \"promotes what the exact test refuses\". Witness: n = 6, b = 5,\n * c = 0 — no exact argument reaches alpha = 0.05 with 5 discordant pairs\n * (two-sided floor 2/2^5 = 0.0625), whatever an interval says. A NEGATIVE\n * threshold is a noninferiority question, which McNemar's test of \"no\n * difference\" is not the right test for, so the veto does not apply there.\n * 3. **A ZERO-WIDTH interval is refused, wherever it sits.** At [0, 0] it\n * cannot tell a gain from a regression and clears every negative threshold.\n * Away from zero it fails the opposite way: n identical positive deltas give\n * [g, g], which clears threshold 0 on no spread at all. Both are an absence\n * of evidence. Measured on the composable gate before this change, under a\n * bounded asymmetric null whose true mean paired delta is exactly 0: 88.50 %\n * false promotion at n = 6 and 65.65 % at n = 20 against a nominal 5 %.\n *\n * Eligibility follows the requested target. A continuous mean needs the\n * bootstrap minimum; binary outcomes and explicit median targets use the\n * exact-test minimum. A small-sample sign diagnostic cannot certify a mean\n * effect. These floors establish estimator eligibility, not adequate power.\n */\n\nimport { minimumPairsForPairedDeltaTest, pairedDeltaTest } from './paired-delta-test'\nimport {\n BOOTSTRAP_GATE_MIN_N,\n type PairedBootstrapResult,\n pairedBinaryScale,\n pairedDeltaTieFraction,\n pairedRiskDifferenceExact,\n pairedRiskDifferenceScore,\n} from './statistics'\n\n/** Which paired estimator produced the deciding interval. */\nexport type PairedDecisionStatistic =\n | 'paired_risk_difference'\n | 'mean_bootstrap'\n | 'median_bootstrap'\n\n/** Which test carried the decision, given the estimator and the sample size. */\nexport type PairedDecisionMethod = 'score-interval' | 'bootstrap-ci' | 'exact-sign'\n\n/** McNemar's exact paired-binary evidence, on the two-point path only. */\nexport interface PairedMcNemarEvidence {\n /** Discordant pairs the treatment won. */\n b: number\n /** Discordant pairs the control won. */\n c: number\n /** b + c — the only pairs carrying information. */\n nDiscordant: number\n /** Two-sided exact p-value. */\n pValue: number\n}\n\nexport interface PairedPromotionDecisionOptions {\n /** Smallest candidate-minus-baseline delta that counts as improvement, in the\n * caller's native units. May be negative (a noninferiority margin). Default 0. */\n threshold?: number\n /** Confidence level. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples, on the paths where a bootstrap decides. Default 2000. */\n resamples?: number\n /** Deterministic bootstrap seed. Omitted ⇒ derived from the deltas. */\n seed?: number\n /** Caller-required paired observations. The test also imposes its own\n * minimum: bootstrap eligibility for a continuous mean, or the exact-test\n * minimum for binary and explicit median targets. This is not a power guarantee. */\n minPairs?: number\n /**\n * `'mean'` (default) routes by SHAPE: a two-point (pass/fail) outcome on any\n * encoding decides on the score interval, everything else on the mean\n * bootstrap. `'median'` forces the median bootstrap on every input, including\n * shapes where it is structurally blind — kept for callers who want outlier\n * robustness on genuinely continuous outcomes and accept that cost.\n */\n statistic?: 'mean' | 'median'\n /** Declared binary support {0, binaryScale}, including when all observations\n * are zero. Must be finite and positive; every observation must use that\n * support. Uses the risk-difference mean, so cannot accompany 'median'.\n * Omitted: infer binary support from observed positive values. */\n binaryScale?: number\n /**\n * Declare the outcome continuous: never infer a two-point support from the\n * observed values, so the estimator is fixed before the data is seen. A\n * sealed call on a continuous measure must route to the bootstrap whatever\n * the sample happens to look like; with inference on, a sample whose values\n * all land on {0, s} is silently decided on the score interval instead.\n * Measured under discovery's E1 alternative (deltas in {+1, -0.5, 0} on a\n * zero baseline) at 20 pairs: 5.4 % of 2,000 simulated samples (seed 11)\n * re-route without this flag, 0 with it; the exact rate is 5.54 %\n * (`paired-promotion-power.test.ts`). Cannot accompany `binaryScale`.\n */\n continuous?: boolean\n}\n\nexport interface PairedPromotionDecision {\n /** Paired observations supplied. */\n n: number\n /** Threshold the interval was judged against, native units. */\n threshold: number\n confidence: number\n statistic: PairedDecisionStatistic\n method: PairedDecisionMethod\n /** Declared or inferred positive level ({0,1} ⇒ 1, {0,100} ⇒ 100),\n * or null when the outcome is not two-point. Non-null is exactly the\n * condition for the `paired_risk_difference` path, and it is the factor\n * `delta` / `low` / `high` were rescaled by. */\n binaryScale: number | null\n /** Exact-tie fraction over the paired deltas; null when there are no pairs. */\n tieFraction: number | null\n /** Point estimate of the DECIDING statistic, in the caller's native units. */\n delta: number\n /** Lower bound of the DECIDING interval, native units. */\n low: number\n /** Upper bound of the DECIDING interval, native units. */\n high: number\n /** The bootstrap that decided, or null when the score interval did. Callers\n * that need a bootstrap as a diagnostic on the two-point path compute their\n * own — it is not computed here, so the binary path costs no resamples. */\n bootstrap: PairedBootstrapResult | null\n /** McNemar's exact evidence, or null off the two-point path. */\n mcnemar: PairedMcNemarEvidence | null\n /** Exact one-sided sign-test p-value on the small-sample bootstrap path;\n * null otherwise. */\n pValue: number | null\n /** Effective observation minimum for the target, confidence, and caller floor. */\n minimumPairs: number\n /** n >= minimumPairs. */\n sufficient: boolean\n /** The deciding interval is zero-width at numeric precision or non-finite — no evidence in either\n * direction, so it cannot clear any threshold on evidence. */\n indeterminate: boolean\n /** McNemar's exact test refuses at a non-negative threshold. */\n exactTestVetoes: boolean\n /** The deciding interval clears the threshold, ignoring the other two guards. */\n clearsThreshold: boolean\n /** `sufficient && !indeterminate && clearsThreshold && !exactTestVetoes` —\n * the whole rule. */\n promote: boolean\n /** What `delta` measures, for a reason string. */\n label: 'success-rate' | 'mean' | 'median'\n /** Why a zero-width interval is zero-width; empty when it is not. */\n indeterminateCause: string\n /** Sentence naming the test when the exact sign test decided; else empty. */\n methodDetail: string\n}\n\n/** The shape facts that pick the estimator, without computing an interval. */\nexport interface PairedDecisionShape {\n statistic: PairedDecisionStatistic\n /** Declared or inferred positive binary level; null off the binary path. */\n binaryScale: number | null\n /** Exact-tie fraction over the paired deltas; null when there are no pairs. */\n tieFraction: number | null\n}\n\n/**\n * Which estimator {@link decidePairedPromotion} would use on this data, and the\n * shape facts behind it — for callers that must report the shape on a path\n * where no interval is computed at all (an early rejection, or zero pairs).\n * Cheap: no bootstrap, no interval.\n */\nexport function pairedDecisionShape(\n before: number[],\n after: number[],\n statistic: 'mean' | 'median' = 'mean',\n declaredBinaryScale?: number,\n continuous = false,\n): PairedDecisionShape {\n if (continuous && declaredBinaryScale !== undefined) {\n throw new Error('pairedDecisionShape: continuous cannot accompany binaryScale')\n }\n if (declaredBinaryScale !== undefined) {\n if (!Number.isFinite(declaredBinaryScale) || declaredBinaryScale <= 0) {\n throw new Error('pairedDecisionShape: binaryScale must be finite and positive')\n }\n if (statistic === 'median') {\n throw new Error('pairedDecisionShape: binaryScale requires the mean statistic, not median')\n }\n for (const [name, arm] of [\n ['before', before],\n ['after', after],\n ] as const) {\n for (let i = 0; i < arm.length; i++) {\n const value = arm[i]!\n if (value !== 0 && value !== declaredBinaryScale) {\n throw new Error(\n `pairedDecisionShape: ${name}[${i}] must be 0 or binaryScale (${declaredBinaryScale}); got ${value}`,\n )\n }\n }\n }\n }\n const tieFraction = before.length === 0 ? null : pairedDeltaTieFraction(before, after)\n if (statistic === 'median') {\n return { statistic: 'median_bootstrap', binaryScale: null, tieFraction }\n }\n if (continuous) {\n return { statistic: 'mean_bootstrap', binaryScale: null, tieFraction }\n }\n const binaryScale = declaredBinaryScale ?? pairedBinaryScale(before, after)\n if (binaryScale !== null) {\n return { statistic: 'paired_risk_difference', binaryScale, tieFraction }\n }\n return { statistic: 'mean_bootstrap', binaryScale: null, tieFraction }\n}\n\n/**\n * Decide whether a paired candidate-minus-baseline delta clears a promotion\n * threshold. `before` is the baseline arm, `after` the candidate arm, paired by\n * position. Throws on unequal lengths.\n */\nexport function decidePairedPromotion(\n before: number[],\n after: number[],\n options: PairedPromotionDecisionOptions = {},\n): PairedPromotionDecision {\n if (before.length !== after.length) {\n throw new Error(\n `decidePairedPromotion: unequal sample sizes (${before.length} vs ${after.length})`,\n )\n }\n const threshold = options.threshold ?? 0\n if (!Number.isFinite(threshold)) {\n throw new Error(`decidePairedPromotion: threshold must be finite, got ${threshold}`)\n }\n const confidence = options.confidence ?? 0.95\n const exactMinimum = minimumPairsForPairedDeltaTest(confidence)\n const requestedMinimum = options.minPairs ?? exactMinimum\n if (!Number.isInteger(requestedMinimum) || requestedMinimum < 1) {\n throw new Error(\n `decidePairedPromotion: minPairs must be a positive integer, got ${requestedMinimum}`,\n )\n }\n const { binaryScale, tieFraction } = pairedDecisionShape(\n before,\n after,\n options.statistic,\n options.binaryScale,\n options.continuous ?? false,\n )\n const estimatorMinimum =\n binaryScale === null && options.statistic !== 'median' ? BOOTSTRAP_GATE_MIN_N : exactMinimum\n const minimumPairs = Math.max(requestedMinimum, exactMinimum, estimatorMinimum)\n const n = before.length\n const sufficient = n >= minimumPairs\n\n let core: {\n statistic: PairedDecisionStatistic\n method: PairedDecisionMethod\n delta: number\n low: number\n high: number\n bootstrap: PairedBootstrapResult | null\n mcnemar: PairedMcNemarEvidence | null\n pValue: number | null\n clearsThreshold: boolean\n label: PairedPromotionDecision['label']\n methodDetail: string\n }\n\n if (binaryScale !== null) {\n // Normalise the two-point encoding to {0,1} so the estimators see the\n // pass/fail structure, then rescale the answer back into the caller's\n // native units — the threshold is read in the units of the scores, so a\n // 0-100 pass/fail dimension must be gated in points, not in a rate.\n const unitControl = before.map((v) => v / binaryScale)\n const unitTreatment = after.map((v) => v / binaryScale)\n // TWO estimators with different jobs, because no single one does both.\n // `exact` is the authority on RD = 0 and supplies the veto; its\n // Clopper-Pearson interval conditions on the discordant count and is\n // therefore NOT a confidence interval at a nonzero margin. `score` is\n // Tango's, which is.\n const exact = pairedRiskDifferenceExact(unitControl, unitTreatment, confidence)\n const score = pairedRiskDifferenceScore(unitControl, unitTreatment, confidence)\n const low = score.lower * binaryScale\n core = {\n statistic: 'paired_risk_difference',\n method: 'score-interval',\n delta: score.riskDifference * binaryScale,\n low,\n high: score.upper * binaryScale,\n bootstrap: null,\n mcnemar: {\n b: exact.b,\n c: exact.c,\n nDiscordant: exact.nDiscordant,\n pValue: exact.pValue,\n },\n pValue: null,\n clearsThreshold: low > threshold,\n label: 'success-rate',\n methodDetail: '',\n }\n } else {\n const bootstrapStatistic = options.statistic === 'median' ? 'median' : 'mean'\n const test = pairedDeltaTest(before, after, {\n confidence,\n resamples: options.resamples,\n statistic: bootstrapStatistic,\n seed: options.seed,\n threshold,\n minPairs: minimumPairs,\n })\n const ci = test.bootstrap\n core = {\n statistic: bootstrapStatistic === 'mean' ? 'mean_bootstrap' : 'median_bootstrap',\n method: test.method,\n delta: bootstrapStatistic === 'mean' ? ci.mean : ci.median,\n low: ci.low,\n high: ci.high,\n bootstrap: ci,\n mcnemar: null,\n pValue: test.pValue,\n clearsThreshold: test.significant,\n label: bootstrapStatistic,\n methodDetail:\n test.method === 'exact-sign'\n ? bootstrapStatistic === 'mean'\n ? ` The mean requires ${minimumPairs} pairs for bootstrap eligibility;` +\n ` the exact sign-test p=${fmt(test.pValue ?? 1)} does not establish a mean effect.`\n : ` Below ${BOOTSTRAP_GATE_MIN_N} pairs the interval is descriptive only;` +\n ` the median decision uses the exact one-sided sign test, p=${fmt(test.pValue ?? 1)}.`\n : '',\n }\n }\n\n // Equivalent deltas can differ by rounding after subtraction and averaging.\n // Use the interval's own scale so tiny score units retain the same decision\n // as a rescaled copy of the evidence.\n const intervalScale = Math.max(Math.abs(core.low), Math.abs(core.high))\n const intervalTolerance = intervalScale * Number.EPSILON * 8\n const indeterminate =\n !Number.isFinite(core.low) ||\n !Number.isFinite(core.high) ||\n core.high - core.low <= intervalTolerance\n const indeterminateCause = !indeterminate\n ? ''\n : tieFraction === 1\n ? 'every paired delta is an exact tie'\n : core.mcnemar !== null && core.mcnemar.nDiscordant === 0\n ? 'every pair is concordant (0 discordant pairs)'\n : `the ${core.label} CI collapsed to a point at ${fmt(core.low)}`\n // Only at a non-negative threshold: a negative threshold asks a\n // noninferiority question, which McNemar's test of \"no difference\" does not\n // answer.\n const exactTestVetoes =\n core.mcnemar !== null && threshold >= 0 && !(core.mcnemar.pValue < 1 - confidence)\n\n return {\n n,\n threshold,\n confidence,\n binaryScale,\n tieFraction,\n minimumPairs,\n sufficient,\n indeterminate,\n indeterminateCause,\n exactTestVetoes,\n promote: sufficient && !indeterminate && core.clearsThreshold && !exactTestVetoes,\n ...core,\n }\n}\n\nfunction fmt(x: number): string {\n return x.toFixed(4)\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"redact-B7rt9Zot.js","names":[],"sources":["../src/trace/redact.ts"],"sourcesContent":["/**\n * The redaction core: the one place that decides what must not leave a\n * process or a machine. Every trace writer, exporter, uploader and share path\n * calls it.\n *\n * Three profiles, each a superset of the one before:\n * - `default` removes credentials, found by key name and by value shape, and\n * personal data (email addresses, card numbers, SSNs, phone numbers).\n * Content is kept. Strings are capped at 1 MiB.\n * - `share` also removes phone, IP and postal-address fields, replaces\n * account, user, tenant, session and request identifiers with pseudonyms\n * that stay consistent within one call, and caps strings at 64 KiB.\n * - `strict` also removes prompt, completion, message, tool payload and other\n * raw-content fields and embedded media, and caps strings at 4 KiB.\n *\n * A string that holds a credential is replaced whole with\n * `[REDACTED:<detector>]`. Replacing only the matched span can leave part of a\n * secret behind when a pattern's boundary is wrong. Personal data inside prose\n * is replaced in place, so the rest of the text stays readable.\n *\n * `assessShareSafety` reads a value without changing it and returns SAFE,\n * SAFE_WITH_WARNINGS, UNSAFE or UNKNOWN. UNKNOWN means the scanner could not\n * read part of the value (a cycle, binary data, nesting past the depth limit);\n * it is never reported as safe. `redactForShare` redacts and then assesses the\n * redacted output, so a detector gap shows up as UNSAFE instead of a leak.\n *\n * Reports and findings carry paths, categories and detector ids, never the\n * values they matched.\n *\n * The key classifier and the credential detector list are adapted from\n * agent-inspect (MIT, commit 3c3cbeda). `scripts/redaction-corpus.json` holds\n * the must-flag and must-not-flag cases, including the copied agent-inspect\n * safety corpus with its MIT notice; `pnpm redaction:corpus` runs this module\n * over every case.\n */\n\nimport { createHmac, randomBytes } from 'node:crypto'\n\nexport type RedactionProfile = 'default' | 'share' | 'strict'\n\nexport const REDACTION_PROFILES: readonly RedactionProfile[] = ['default', 'share', 'strict']\n\n/** What a finding is about. `media` is embedded binary content (a `data:` URI) no text detector can read. */\nexport type SafetyCategory = 'credential' | 'personal-data' | 'identifier' | 'raw-content' | 'media'\n\n/**\n * Version of the detector set and profile rules. Stored work that depends on\n * redaction behavior (saved optimizer inputs, per-span redaction stamps) keys\n * on it, so bump it whenever a detector, key list, cap or marker changes.\n */\nexport const REDACTION_VERSION = '2.2.0'\n\nexport interface RedactionFinding {\n /** JSON Pointer (RFC 6901) to the value or key that was changed. */\n path: string\n category: SafetyCategory\n detector: string\n action: 'redacted' | 'pseudonymized' | 'truncated'\n}\n\nexport interface RedactionReport {\n version: string\n profile: RedactionProfile\n /** Values and keys replaced, pseudonymized or truncated. */\n redactionCount: number\n byDetector: Record<string, number>\n truncatedCount: number\n findings: RedactionFinding[]\n}\n\nexport interface RedactOptions {\n /** Default `default`. */\n profile?: RedactionProfile\n /** Lower the profile's per-string cap. A value above the profile cap is ignored. */\n maxStringBytes?: number\n /**\n * Exact values the caller knows are secret (an API key the run was given, a\n * password from the environment), whatever shape they have. Each occurrence\n * in a string, as written or base64, base64url or URL-encoded, becomes\n * `[REDACTED:known-secret]` and the text around it is kept. A key that\n * contains one, and a whole-string base64 payload that holds one at any byte\n * offset, is replaced whole.\n */\n knownSecrets?: readonly string[]\n /** Add this call's findings to an existing report instead of a new one. */\n report?: RedactionReport\n}\n\nexport interface AssessOptions {\n /** Default `default`. */\n profile?: RedactionProfile\n /** As in `RedactOptions`: any surviving occurrence makes the verdict UNSAFE. */\n knownSecrets?: readonly string[]\n}\n\nexport type ShareSafetyStatus = 'SAFE' | 'SAFE_WITH_WARNINGS' | 'UNSAFE' | 'UNKNOWN'\n\nexport interface ShareSafetyFinding {\n category: SafetyCategory\n detector: string\n severity: 'error' | 'warning'\n count: number\n /** Up to five JSON Pointers where the detector fired. */\n paths: string[]\n}\n\nexport interface ShareSafetyVerdict {\n status: ShareSafetyStatus\n profile: RedactionProfile\n findings: ShareSafetyFinding[]\n /** Parts the scanner could not read, as `<path>: <reason>`. Any entry makes the status UNKNOWN. */\n unreadable: string[]\n}\n\n// ── Profiles ─────────────────────────────────────────────────────────────\n\ninterface ProfileRules {\n maxStringBytes: number\n /** Key categories whose values are removed or pseudonymized. */\n redactKeys: ReadonlySet<'share-personal' | 'identifier' | 'raw-content'>\n redactMedia: boolean\n severity: Record<SafetyCategory, 'error' | 'warning' | undefined>\n}\n\nconst KIB = 1024\n\nconst PROFILE_RULES: Record<RedactionProfile, ProfileRules> = {\n default: {\n maxStringBytes: 1024 * KIB,\n redactKeys: new Set(),\n redactMedia: false,\n severity: {\n credential: 'error',\n 'personal-data': 'warning',\n identifier: undefined,\n 'raw-content': 'warning',\n media: 'warning',\n },\n },\n share: {\n maxStringBytes: 64 * KIB,\n redactKeys: new Set(['share-personal', 'identifier']),\n redactMedia: false,\n severity: {\n credential: 'error',\n 'personal-data': 'error',\n identifier: 'warning',\n 'raw-content': 'warning',\n media: 'warning',\n },\n },\n strict: {\n maxStringBytes: 4 * KIB,\n redactKeys: new Set(['share-personal', 'identifier', 'raw-content']),\n redactMedia: true,\n severity: {\n credential: 'error',\n 'personal-data': 'error',\n identifier: 'warning',\n 'raw-content': 'error',\n media: 'error',\n },\n },\n}\n\n// ── Key classifier ───────────────────────────────────────────────────────\n\n/**\n * Canonical snake_case form of a field name, so camelCase, kebab-case, dotted\n * and snake_case spellings match one list: `userPassword`, `user-password` and\n * `user.password` all become `user_password`.\n */\nexport function normalizeKey(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '')\n}\n\n/** Counts, limits and model vocabulary that contain the word \"token\" but are not credentials. */\nconst NON_CREDENTIAL_TOKEN_KEYS: ReadonlySet<string> = new Set([\n 'tokens',\n 'max_tokens',\n 'min_tokens',\n 'ls_max_tokens',\n 'token_count',\n 'token_limit',\n 'token_budget',\n 'input_tokens',\n 'output_tokens',\n 'total_tokens',\n 'cached_tokens',\n 'prompt_tokens',\n 'completion_tokens',\n 'reasoning_tokens',\n 'bos_token',\n 'eos_token',\n 'pad_token',\n 'unk_token',\n 'sep_token',\n 'cls_token',\n 'mask_token',\n 'stop_token',\n // Pagination cursors are opaque but not credentials.\n 'page_token',\n 'next_page_token',\n 'prev_page_token',\n 'next_token',\n 'continuation_token',\n 'cursor_token',\n 'sync_token',\n])\n\nconst CREDENTIAL_KEYS = [\n 'authorization',\n 'auth',\n 'cookie',\n 'api_key',\n 'apikey',\n 'api_token',\n 'access_key',\n 'secret_key',\n 'private_key',\n 'signing_key',\n 'encryption_key',\n 'master_key',\n 'session_key',\n 'client_secret',\n 'secret',\n 'password',\n 'passwd',\n 'passphrase',\n 'credential',\n 'credentials',\n 'bearer',\n 'dsn',\n 'database_url',\n 'connection_string',\n 'pat',\n] as const\n\n/** Email fields are personal data in every profile. */\nconst EMAIL_KEYS = ['email', 'email_address'] as const\n\n/** Personal-data fields removed by the share and strict profiles. */\nconst SHARE_PERSONAL_KEYS = [\n 'phone',\n 'phone_number',\n 'mobile',\n 'ip',\n 'ip_address',\n 'remote_addr',\n 'street_address',\n 'postal_address',\n 'home_address',\n 'billing_address',\n 'shipping_address',\n 'mailing_address',\n 'date_of_birth',\n 'dob',\n 'ssn',\n] as const\n\n/** Identifiers pseudonymized by the share and strict profiles. */\nconst IDENTIFIER_KEYS = [\n 'user_id',\n 'user_uuid',\n 'account_id',\n 'account_uuid',\n 'customer_id',\n 'tenant_id',\n 'org_id',\n 'organization_id',\n 'organisation_id',\n 'team_id',\n 'enduser_id',\n 'actor_id',\n 'principal_id',\n 'member_id',\n 'session_id',\n 'request_id',\n 'correlation_id',\n 'device_id',\n 'installation_id',\n] as const\n\n/** Fields that carry prompts, model output, tool payloads or other free text. Removed by `strict`. */\nconst RAW_CONTENT_KEYS = [\n 'prompt',\n 'prompts',\n 'system_prompt',\n 'completion',\n 'input',\n 'output',\n 'message',\n 'messages',\n 'content',\n 'text',\n 'thinking',\n 'reasoning',\n 'transcript',\n 'context',\n 'document',\n 'documents',\n 'chunk',\n 'chunks',\n 'retrieval',\n 'query',\n 'args',\n 'arguments',\n 'result',\n 'body',\n 'command',\n 'full_command',\n 'input_value',\n 'output_value',\n 'instructions',\n 'system_instructions',\n 'stdout',\n 'stderr',\n 'stacktrace',\n 'status_description',\n 'input_preview',\n 'output_preview',\n 'current_task',\n 'user_input',\n 'request_text',\n] as const\n\n/**\n * A key matches a list entry exactly or as a suffix (`openai_api_key`,\n * `db_password`, `tool_output`). Prefix compounds (`secret_name`,\n * `password_min_length`, `auth_type`, `content_type`) do not match: they name\n * or describe a value rather than hold it, and flagging them would make the\n * share verdict refuse ordinary traces. Value detectors still catch a\n * credential-shaped value under any key.\n */\nfunction matchesKeyList(normalized: string, keys: readonly string[]): boolean {\n for (const key of keys) {\n if (normalized === key || normalized.endsWith(`_${key}`)) return true\n }\n return false\n}\n\nfunction isTokenCredentialKey(normalized: string): boolean {\n if (NON_CREDENTIAL_TOKEN_KEYS.has(normalized)) return false\n if (normalized === 'token') return true\n // access_token and refreshToken are credentials; max_tokens and input_tokens are counts.\n if (normalized.endsWith('tokens')) return false\n return normalized.endsWith('token')\n}\n\ntype KeyClass = 'credential' | 'email' | 'share-personal' | 'identifier' | 'raw-content'\n\n/** Trace keys repeat on every span, so classifications are cached. */\nconst keyClassCache = new Map<string, KeyClass | null>()\n\nfunction classifyKeyName(key: string): KeyClass | undefined {\n const cached = keyClassCache.get(key)\n if (cached !== undefined) return cached ?? undefined\n const kind = classifyNormalizedKey(normalizeKey(key))\n if (keyClassCache.size >= 10_000) keyClassCache.clear()\n keyClassCache.set(key, kind ?? null)\n return kind\n}\n\nfunction classifyNormalizedKey(normalized: string): KeyClass | undefined {\n if (!normalized || NON_CREDENTIAL_TOKEN_KEYS.has(normalized)) return undefined\n if (isTokenCredentialKey(normalized)) return 'credential'\n if (matchesKeyList(normalized, CREDENTIAL_KEYS)) return 'credential'\n if (matchesKeyList(normalized, EMAIL_KEYS)) return 'email'\n if (matchesKeyList(normalized, SHARE_PERSONAL_KEYS)) return 'share-personal'\n if (matchesKeyList(normalized, IDENTIFIER_KEYS)) return 'identifier'\n if (matchesKeyList(normalized, RAW_CONTENT_KEYS)) return 'raw-content'\n return undefined\n}\n\n/**\n * The safety category a field name puts its value in, or undefined for an\n * ordinary field. Token counts and model limits (`inputTokens`, `max_tokens`,\n * `token_count`) and names such as `author` are not credentials.\n */\nexport function classifyKey(key: string): SafetyCategory | undefined {\n const kind = classifyKeyName(key)\n if (kind === undefined) return undefined\n if (kind === 'credential') return 'credential'\n if (kind === 'identifier') return 'identifier'\n if (kind === 'raw-content') return 'raw-content'\n return 'personal-data'\n}\n\n// ── Value detectors ──────────────────────────────────────────────────────\n\ninterface ValueDetector {\n id: string\n pattern: RegExp\n}\n\n/**\n * High-confidence credential shapes. A hit replaces the whole string. Each\n * pattern is written without the `g` flag so `test` stays stateless.\n */\nconst CREDENTIAL_DETECTORS: readonly ValueDetector[] = [\n { id: 'private-key', pattern: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/ },\n { id: 'jwt', pattern: /\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}/ },\n { id: 'bearer', pattern: /\\bbearer\\s+[A-Za-z0-9._~+/=-]{12,}/i },\n {\n id: 'authorization-header',\n pattern: /^\\s*(?:basic|digest|apikey)\\s+[A-Za-z0-9._~+/=:-]{8,}\\s*$/i,\n },\n { id: 'anthropic-key', pattern: /\\bsk-ant-[A-Za-z0-9_-]{16,}/ },\n { id: 'provider-key', pattern: /\\bsk-(?:proj-|tan-)?[A-Za-z0-9_-]{16,}/ },\n { id: 'stripe-key', pattern: /\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9_]{10,}/ },\n { id: 'google-api-key', pattern: /\\bAIza[0-9A-Za-z_-]{20,}/ },\n { id: 'github-token', pattern: /\\b(?:gh[pousr]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,})/ },\n { id: 'slack-token', pattern: /\\bxox[abeoprs]-[A-Za-z0-9-]{10,}/ },\n { id: 'aws-access-key', pattern: /\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b/ },\n { id: 'tangle-capability', pattern: /\\b(?:hubcap_|hct_)[A-Za-z0-9_=-]{8,}/ },\n { id: 'url-credentials', pattern: /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s/:@]+:[^\\s/@]+@/i },\n {\n id: 'url-secret-param',\n pattern:\n /[?&](?:access_token|api_key|apikey|auth|token|secret|password|sig|signature|x-amz-signature|x-goog-signature)=[^&\\s\"'#)]{8,}/i,\n },\n {\n // `GH_TOKEN=…`, `--api-key=…`, `\"client_secret\": \"…\"`, `password: …` in free\n // text. The value must mix letters and digits and be at least 12\n // characters, so prose (`token: string`), variable references (`$TOKEN`)\n // and dotenvx ciphertext (`encrypted:…`) pass. The pattern starts at the\n // key word itself, with no identifier prefix, so it scans in linear time.\n id: 'secret-assignment',\n pattern:\n /(?:api[_-]?key|apikey|access[_-]?key|secret[_-]?key|private[_-]?key|secret|token|password|passwd|passphrase|credentials?)[\"']?[ \\t]*[:=][ \\t]*[\"']?(?!encrypted:)(?![$`<[{(%])(?=[^\\s\"'`,;&|]*[0-9])(?=[^\\s\"'`,;&|]*[A-Za-z])[^\\s\"'`,;&|]{12,}/i,\n },\n {\n // `{\"password\": \"hunter2\"}` or `'client_secret': '…'` inside serialized\n // JSON, YAML or a log line. A quoted credential field name followed by a\n // quoted value holds a secret whatever the value's shape or length. Bare\n // `\"token\"` is left out: model logprob output uses it for text tokens.\n // Placeholders (`[REDACTED…]`, `$VAR`, `{env:VAR}`, `***`, `<value>`) and\n // prose with two or more spaces (a field description) do not match.\n id: 'json-secret',\n pattern:\n /[\"'][A-Za-z0-9_.-]{0,40}?(?:api[_-]?key|apikey|access[_-]?key|secret[_-]?key|private[_-]?key|client[_-]?secret|secret|password|passwd|passphrase|credentials?|(?:access|refresh|id|auth|session|bearer|api|github|gh|slack|npm)[_-]?token)[\"'][ \\t]*:[ \\t]*[\"'](?!\\[REDACTED|[$*{<])(?![^\"'\\r\\n]* [^\"'\\r\\n]* )[^\"'\\r\\n]{3,}[\"']/i,\n },\n {\n // `DB_PASSWORD=CorrectHorseBatteryStaple`, `PGPASSWORD=postgres`: unlike\n // `secret-assignment` above, the all-upper-case env-var name ending in a\n // credential word is itself the signal, so a letters-only or short real\n // password still matches (no digit-mixing or 12-char minimum). Requires\n // the name to be immediately followed by `=`, so `MAX_TOKENS=16` and\n // `TOKEN_EXPIRY=…` (the word isn't the end of the name) do not match.\n id: 'env-secret-assignment',\n pattern:\n /\\b[A-Z][A-Z0-9_]*?(?:PASSWORD|PASSWD|SECRET|PASSPHRASE|APIKEY|API_KEY|TOKEN|CREDENTIALS?)[ \\t]*=[ \\t]*(?!\\$|<|\\*|\\{|%|encrypted:)[^\\s\"'`,;&|]{4,}/,\n },\n // Bare-key shapes not covered above. Each requires a distinctive prefix so\n // it does not fire on ordinary identifiers.\n { id: 'huggingface-token', pattern: /\\bhf_[A-Za-z0-9]{20,}/ },\n { id: 'npm-token', pattern: /\\bnpm_[A-Za-z0-9]{20,}/ },\n { id: 'gitlab-token', pattern: /\\bglpat-[A-Za-z0-9_-]{16,}/ },\n { id: 'groq-key', pattern: /\\bgsk_[A-Za-z0-9]{20,}/ },\n { id: 'xai-key', pattern: /\\bxai-[A-Za-z0-9]{16,}/ },\n // ElevenLabs and similar bare `sk_<hex>` shapes — underscore, unlike the\n // hyphenated `sk-…` `provider-key` pattern above, so the two never overlap.\n { id: 'bare-sk-key', pattern: /\\bsk_[A-Za-z0-9]{32,}\\b/ },\n {\n // `Cookie: sessionid=…; csrftoken=…` in free text or a captured header.\n id: 'cookie-header',\n pattern: /\\bcookie\\s*:\\s*[A-Za-z0-9_-]+=[^;\\r\\n]{3,}(?:;\\s*[A-Za-z0-9_-]+=[^;\\r\\n]{3,})*/i,\n },\n]\n\n/** Personal-data shapes, replaced in place so the surrounding text survives. */\nconst PERSONAL_DATA_DETECTORS: readonly (ValueDetector & {\n /** A substring the text must contain before the pattern runs. */\n requires?: string\n accept?: (match: string) => boolean\n})[] = [\n {\n id: 'email',\n requires: '@',\n pattern: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g,\n accept: isEmailAddress,\n },\n {\n // Card numbers: a card-network prefix and a valid Luhn digit, written\n // unbroken (13-19 digits) or in printed groups (4-4-4-4, 4-4-4-4-3, Amex\n // 4-6-5). A word character or hyphen on either side rejects the match, so\n // digits inside UUIDs, dated file names and hyphenated ids never match.\n id: 'card-number',\n pattern:\n /(?<![\\w-])(?:\\d{13,19}|\\d{4}([ -])\\d{4}\\1\\d{4}\\1\\d{4}(?:\\1\\d{3})?|\\d{4}([ -])\\d{6}\\2\\d{5})(?![\\w-])/g,\n accept: (match) => {\n const digits = match.replace(/[ -]/g, '')\n return CARD_PREFIX.test(digits) && luhnValid(digits)\n },\n },\n { id: 'ssn', pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g },\n {\n // Separators are required: a bare ten-digit run is usually an epoch second or an id.\n id: 'phone',\n pattern: /(?:\\+1[-.\\s]?)?(?:\\(\\d{3}\\)\\s?|\\b\\d{3}[-.\\s])\\d{3}[-.\\s]\\d{4}\\b/g,\n },\n]\n\n/** Visa, Mastercard, Amex, Diners, JCB, Discover and UnionPay issuer prefixes. */\nconst CARD_PREFIX = /^(?:4|5[1-5]|2[2-7]|3[04-9]|6(?:011|4[4-9]|5|2))/\n\n/**\n * Top-level domains that are file extensions: `icon@2x.png`, `worker@3.service`\n * and `notes@AGENTS.md` are not addresses.\n */\nconst NON_EMAIL_TLDS: ReadonlySet<string> = new Set([\n 'md',\n 'mdx',\n 'txt',\n 'json',\n 'jsonl',\n 'yaml',\n 'yml',\n 'toml',\n 'lock',\n 'ts',\n 'tsx',\n 'js',\n 'jsx',\n 'mjs',\n 'cjs',\n 'py',\n 'rs',\n 'go',\n 'sh',\n 'css',\n 'html',\n 'svg',\n 'png',\n 'jpg',\n 'jpeg',\n 'gif',\n 'webp',\n 'service',\n 'socket',\n 'timer',\n 'mount',\n 'target',\n])\n\nfunction isEmailAddress(match: string): boolean {\n // `git@github.com:org/repo` is an SSH remote, not a person.\n if (match.toLowerCase().startsWith('git@')) return false\n const tld = match.slice(match.lastIndexOf('.') + 1).toLowerCase()\n return !NON_EMAIL_TLDS.has(tld)\n}\n\nfunction luhnValid(digits: string): boolean {\n if (/^(\\d)\\1+$/.test(digits)) return false\n let sum = 0\n let double = false\n for (let index = digits.length - 1; index >= 0; index -= 1) {\n let digit = digits.charCodeAt(index) - 48\n if (double) {\n digit *= 2\n if (digit > 9) digit -= 9\n }\n sum += digit\n double = !double\n }\n return sum % 10 === 0\n}\n\n/** The first credential detector that matches, or undefined. */\nexport function detectCredential(text: string): string | undefined {\n for (const detector of CREDENTIAL_DETECTORS) {\n if (detector.pattern.test(text)) return detector.id\n }\n return undefined\n}\n\n/** Personal-data detector ids that match somewhere in `text`. */\nexport function detectPersonalData(text: string): string[] {\n const hits: string[] = []\n for (const detector of PERSONAL_DATA_DETECTORS) {\n if (detector.requires && !text.includes(detector.requires)) continue\n detector.pattern.lastIndex = 0\n for (const match of text.matchAll(detector.pattern)) {\n if (!detector.accept || detector.accept(match[0])) {\n hits.push(detector.id)\n break\n }\n }\n }\n return hits\n}\n\n/**\n * Every form in which a known secret can appear in a trace: as written,\n * base64, base64url and URL-encoded. Values shorter than 4 characters are\n * ignored; they would match ordinary text.\n */\nfunction knownSecretForms(values: readonly string[] | undefined): string[] {\n const forms = new Set<string>()\n for (const value of values ?? []) {\n if (value.length < 4) continue\n const bytes = Buffer.from(value, 'utf8')\n forms.add(value)\n forms.add(bytes.toString('base64'))\n forms.add(bytes.toString('base64url'))\n forms.add(encodeURIComponent(value))\n }\n // Longest first, so a secret that contains another is reported as itself.\n return [...forms].sort((left, right) => right.length - left.length)\n}\n\nconst BASE64_TEXT = /^[A-Za-z0-9+/_-]+={0,2}$/\n\nfunction containsKnownSecret(text: string, forms: readonly string[]): boolean {\n if (forms.length === 0) return false\n if (forms.some((form) => text.includes(form))) return true\n // A whole-string base64 payload can hold a secret at any byte offset.\n if (text.length < 8 || !BASE64_TEXT.test(text)) return false\n const decoded = Buffer.from(\n text,\n text.includes('-') || text.includes('_') ? 'base64url' : 'base64',\n ).toString('utf8')\n return forms.some((form) => decoded.includes(form))\n}\n\n/** The detector that marks `text` as a credential: a known secret first, then the value shapes. */\nfunction credentialIn(text: string, knownSecrets: readonly string[]): string | undefined {\n return containsKnownSecret(text, knownSecrets) ? 'known-secret' : detectCredential(text)\n}\n\nconst MARKER_PREFIX = '[REDACTED:'\n\nfunction marker(detector: string): string {\n return `${MARKER_PREFIX}${detector}]`\n}\n\n/**\n * Placeholders other tools write for a removed value. A credential field that\n * holds one of these is already redacted and is not flagged again.\n */\nconst REDACTED_PLACEHOLDER =\n /^(?:\\[(?:REDACTED|redacted)(?::[^\\]]*)?\\]|\\[ID:[0-9a-f]{12}\\]|\\*{3,}|<redacted>|«redacted»|\\[HASH:[0-9a-f]{8,}\\])$/\n\nfunction isPlaceholder(value: string): boolean {\n return value === '' || REDACTED_PLACEHOLDER.test(value)\n}\n\n// The whole string must be the data URI — `$` at the end, not just a `^`\n// prefix check. A prefix-only check let `data:text/plain;base64,…\\n` PLUS\n// arbitrary trailing text through as unread \"media\", when the trailing text\n// (or, for text/json mimes, the payload itself once decoded) is exactly the\n// kind of prose a credential or personal-data detector should see.\nconst DATA_URI = /^data:([\\w.+-]+\\/[\\w.+-]+)(?:;[\\w.+-]+=[\\w.+-]+)*;base64,([A-Za-z0-9+/=\\s]*)$/i\n\n/** A data: URI's mime type and base64 payload, only when the whole string is the URI. */\nfunction matchDataUri(text: string): { mime: string; payload: string } | undefined {\n const m = DATA_URI.exec(text)\n if (!m) return undefined\n return { mime: (m[1] ?? '').toLowerCase(), payload: m[2] ?? '' }\n}\n\n/** Decodes a data: URI's base64 payload to text, or undefined if it is not valid base64. */\nfunction decodeDataUriPayload(payload: string): string | undefined {\n const cleaned = payload.replace(/\\s+/g, '')\n if (cleaned.length === 0) return ''\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleaned) || cleaned.length % 4 !== 0) return undefined\n try {\n return Buffer.from(cleaned, 'base64').toString('utf8')\n } catch {\n return undefined\n }\n}\n\nconst READABLE_IMAGE_MIME = /^image\\//\n/** Mimes whose payload is text a detector can read once decoded. */\nconst DECODABLE_TEXT_MIME = /^text\\/|^application\\/json$/\n\n/** Whether a decoded data: URI payload holds a credential or personal data,\n * by key name (for application/json) or by value shape (for any text). */\nfunction decodedPayloadIsUnsafe(\n decoded: string,\n mime: string,\n knownSecrets: readonly string[],\n): boolean {\n if (mime === 'application/json') {\n try {\n return jsonValueIsUnsafe(JSON.parse(decoded), knownSecrets)\n } catch {\n // Not actually valid JSON despite the mime type — fall through to plain text.\n }\n }\n if (credentialIn(decoded, knownSecrets)) return true\n return detectPersonalData(decoded).length > 0\n}\n\nfunction jsonValueIsUnsafe(value: unknown, knownSecrets: readonly string[]): boolean {\n if (value === null || value === undefined) return false\n if (typeof value === 'string')\n return credentialIn(value, knownSecrets) !== undefined || detectPersonalData(value).length > 0\n if (typeof value !== 'object') return false\n if (Array.isArray(value)) return value.some((item) => jsonValueIsUnsafe(item, knownSecrets))\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n const category = classifyKey(key)\n if (category === 'credential') return true\n if (category === 'personal-data' && (typeof item === 'string' || typeof item === 'number'))\n return true\n if (jsonValueIsUnsafe(item, knownSecrets)) return true\n }\n return false\n}\n\n// ── Redaction ────────────────────────────────────────────────────────────\n\nconst MAX_DEPTH = 64\n\ninterface WalkState {\n rules: ProfileRules\n maxStringBytes: number\n knownSecrets: string[]\n report: RedactionReport\n /** Created on first use: most calls pseudonymize nothing. */\n pseudonymKey?: Buffer\n seen: WeakSet<object>\n}\n\nfunction record(\n state: WalkState,\n path: string,\n category: SafetyCategory,\n detector: string,\n action: RedactionFinding['action'],\n): void {\n const report = state.report\n if (action === 'truncated') report.truncatedCount += 1\n report.redactionCount += 1\n report.byDetector[detector] = (report.byDetector[detector] ?? 0) + 1\n report.findings.push({ path, category, detector, action })\n}\n\nfunction pointer(parent: string, key: string | number): string {\n return `${parent}/${String(key).replace(/~/g, '~0').replace(/\\//g, '~1')}`\n}\n\nfunction truncateUtf8(text: string, maxBytes: number): string | undefined {\n if (text.length <= maxBytes / 4) return undefined\n const bytes = Buffer.from(text, 'utf8')\n if (bytes.length <= maxBytes) return undefined\n // Step back to the first byte of a UTF-8 sequence so no character is split.\n let cut = maxBytes\n while (cut > 0 && ((bytes[cut] ?? 0) & 0xc0) === 0x80) cut -= 1\n return `${bytes.subarray(0, cut).toString('utf8')}…[truncated ${bytes.length - cut} bytes]`\n}\n\nfunction redactStringAt(text: string, path: string, state: WalkState): string {\n if (isPlaceholder(text)) return text\n // A known secret is an exact value, so it is cut out where it stands and the\n // text around it survives: an error message keeps its diagnosis.\n let output = text\n for (const form of state.knownSecrets) {\n if (!output.includes(form)) continue\n output = output.split(form).join(marker('known-secret'))\n record(state, path, 'credential', 'known-secret', 'redacted')\n }\n const dataUri = matchDataUri(output)\n if (dataUri) {\n if (DECODABLE_TEXT_MIME.test(dataUri.mime)) {\n const decoded = decodeDataUriPayload(dataUri.payload)\n if (decoded === undefined) {\n // Can't verify what an undecodable payload holds — fail closed rather\n // than pass it through as if it were opaque, harmless media.\n record(state, path, 'credential', 'data-uri-payload', 'redacted')\n return marker('data-uri-payload')\n }\n if (decodedPayloadIsUnsafe(decoded, dataUri.mime, state.knownSecrets)) {\n record(state, path, 'credential', 'data-uri-payload', 'redacted')\n return marker('data-uri-payload')\n }\n // Decoded clean: still opaque bytes to a downstream reader once\n // embedded, so it's subject to the ordinary media rule below, same as\n // any other data URI.\n }\n if (!state.rules.redactMedia) return output\n record(state, path, 'media', 'media', 'redacted')\n return marker('media')\n }\n // A value shape, or a whole-string base64 payload that holds a known secret\n // at any byte offset, replaces the whole string.\n const credential = credentialIn(output, state.knownSecrets)\n if (credential) {\n record(state, path, 'credential', credential, 'redacted')\n return marker(credential)\n }\n for (const detector of PERSONAL_DATA_DETECTORS) {\n if (detector.requires && !output.includes(detector.requires)) continue\n output = output.replace(detector.pattern, (match) => {\n if (detector.accept && !detector.accept(match)) return match\n record(state, path, 'personal-data', detector.id, 'redacted')\n return marker(detector.id)\n })\n }\n const truncated = truncateUtf8(output, state.maxStringBytes)\n if (truncated === undefined) return output\n record(state, path, 'raw-content', 'size-cap', 'truncated')\n return truncated\n}\n\nfunction pseudonym(value: string | number, state: WalkState): string {\n state.pseudonymKey ??= randomBytes(32)\n const digest = createHmac('sha256', state.pseudonymKey).update(String(value)).digest('hex')\n return `[ID:${digest.slice(0, 12)}]`\n}\n\nfunction redactKeyed(\n key: string,\n value: unknown,\n path: string,\n depth: number,\n state: WalkState,\n): unknown {\n const kind = classifyKeyName(key)\n if (value === null || value === undefined || typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'string' && isPlaceholder(value)) return value\n // Numbers under a credential name are limits and counts (`password_max_age`), not secrets.\n if (kind === 'credential' && typeof value !== 'number') {\n record(state, path, 'credential', 'credential-key', 'redacted')\n return marker('credential-key')\n }\n if (\n kind === 'email' ||\n (kind === 'share-personal' && state.rules.redactKeys.has('share-personal'))\n ) {\n if (typeof value === 'string' || typeof value === 'number') {\n record(state, path, 'personal-data', 'personal-data-key', 'redacted')\n return marker('personal-data-key')\n }\n }\n if (kind === 'identifier' && state.rules.redactKeys.has('identifier')) {\n if (typeof value === 'string' || typeof value === 'number') {\n record(state, path, 'identifier', 'identifier-key', 'pseudonymized')\n return pseudonym(value, state)\n }\n }\n if (\n kind === 'raw-content' &&\n state.rules.redactKeys.has('raw-content') &&\n typeof value !== 'number'\n ) {\n record(state, path, 'raw-content', 'raw-content-key', 'redacted')\n return marker('raw-content-key')\n }\n return walk(value, path, depth + 1, state)\n}\n\nfunction walk(value: unknown, path: string, depth: number, state: WalkState): unknown {\n if (typeof value === 'string') return redactStringAt(value, path, state)\n if (value === null || typeof value !== 'object') return value\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {\n record(state, path, 'media', 'binary', 'redacted')\n return marker('binary')\n }\n if (value instanceof Date) return value\n if (depth > MAX_DEPTH) {\n record(state, path, 'raw-content', 'depth-limit', 'truncated')\n return marker('depth-limit')\n }\n if (state.seen.has(value)) {\n record(state, path, 'raw-content', 'circular', 'redacted')\n return marker('circular')\n }\n state.seen.add(value)\n try {\n if (Array.isArray(value)) {\n return value.map((item, index) => walk(item, pointer(path, index), depth + 1, state))\n }\n const out: Record<string, unknown> = {}\n let renamed = 0\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n let outKey = key\n const keyCredential = credentialIn(key, state.knownSecrets)\n if (keyCredential) {\n renamed += 1\n outKey = `${marker(keyCredential)}#${renamed}`\n record(state, pointer(path, outKey), 'credential', keyCredential, 'redacted')\n }\n out[outKey] = redactKeyed(key, item, pointer(path, outKey), depth, state)\n }\n return out\n } finally {\n state.seen.delete(value)\n }\n}\n\nfunction newReport(profile: RedactionProfile): RedactionReport {\n return {\n version: REDACTION_VERSION,\n profile,\n redactionCount: 0,\n byDetector: {},\n truncatedCount: 0,\n findings: [],\n }\n}\n\nfunction newState(options: RedactOptions, report?: RedactionReport): WalkState {\n const profile = options.profile ?? 'default'\n const rules = PROFILE_RULES[profile]\n if (!rules) throw new Error(`unknown redaction profile: ${String(profile)}`)\n const requested = options.maxStringBytes\n const maxStringBytes =\n typeof requested === 'number' && Number.isFinite(requested) && requested >= 0\n ? Math.min(Math.floor(requested), rules.maxStringBytes)\n : rules.maxStringBytes\n return {\n rules,\n maxStringBytes,\n knownSecrets: knownSecretForms(options.knownSecrets),\n report: report ?? newReport(profile),\n seen: new WeakSet(),\n }\n}\n\n/**\n * Return a redacted deep copy of `value` and a report of what changed. Pure:\n * the input is not mutated. Never throws on the value's shape; cycles, binary\n * data and nesting past 64 levels are replaced with markers.\n */\nexport function redact<T>(\n value: T,\n options: RedactOptions = {},\n): { value: T; report: RedactionReport } {\n const state = newState(options, options.report)\n const out = walk(value, '', 0, state) as T\n return { value: out, report: state.report }\n}\n\n/**\n * Redact one free-text string with the value detectors (no field name is\n * known). Pass `report` to accumulate counts across calls.\n */\nexport function redactText(text: string, options: RedactOptions = {}): string {\n const state = newState(options, options.report)\n return redactStringAt(text, '', state)\n}\n\n/** An empty report to accumulate `redactText` calls into. */\nexport function emptyRedactionReport(profile: RedactionProfile = 'default'): RedactionReport {\n return newReport(profile)\n}\n\n// ── Share-safety assessment ──────────────────────────────────────────────\n\ninterface ScanState {\n profile: RedactionProfile\n rules: ProfileRules\n knownSecrets: string[]\n findings: Map<string, ShareSafetyFinding>\n unreadable: string[]\n seen: WeakSet<object>\n}\n\nfunction flag(state: ScanState, path: string, category: SafetyCategory, detector: string): void {\n const severity = state.rules.severity[category]\n if (!severity) return\n const id = `${category}\\u0000${detector}`\n const existing = state.findings.get(id)\n if (existing) {\n existing.count += 1\n if (existing.paths.length < 5) existing.paths.push(path)\n return\n }\n state.findings.set(id, { category, detector, severity, count: 1, paths: [path] })\n}\n\nfunction scanString(text: string, path: string, state: ScanState): void {\n if (isPlaceholder(text)) return\n const dataUri = matchDataUri(text)\n if (dataUri) {\n scanDataUri(dataUri, path, state)\n return\n }\n const credential = credentialIn(text, state.knownSecrets)\n if (credential) {\n flag(state, path, 'credential', credential)\n return\n }\n for (const detector of detectPersonalData(text)) flag(state, path, 'personal-data', detector)\n}\n\nfunction scanDataUri(\n dataUri: { mime: string; payload: string },\n path: string,\n state: ScanState,\n): void {\n if (READABLE_IMAGE_MIME.test(dataUri.mime)) {\n flag(state, path, 'media', 'media')\n return\n }\n if (DECODABLE_TEXT_MIME.test(dataUri.mime)) {\n const decoded = decodeDataUriPayload(dataUri.payload)\n if (decoded === undefined) {\n state.unreadable.push(`${path || '/'}: data URI payload is not valid base64`)\n return\n }\n if (dataUri.mime === 'application/json') {\n try {\n scan(JSON.parse(decoded), path, 0, state)\n return\n } catch {\n // Not actually valid JSON despite the mime type — fall through to plain text.\n }\n }\n scanString(decoded, path, state)\n return\n }\n // audio/video/octet-stream/etc: bytes no text detector can read. A warning\n // under `default` (matches the existing image rule); under `share` and\n // `strict` — the profiles that actually gate whether something may be sent\n // off the machine — treat it as unreadable so the verdict is UNKNOWN\n // instead of silently allowing it through.\n if (state.profile === 'default') {\n flag(state, path, 'media', 'media')\n } else {\n state.unreadable.push(`${path || '/'}: ${dataUri.mime} data URI cannot be read`)\n }\n}\n\nfunction scanKeyed(\n key: string,\n value: unknown,\n path: string,\n depth: number,\n state: ScanState,\n): void {\n if (value === null || value === undefined || typeof value === 'boolean') return\n if (typeof value === 'string' && isPlaceholder(value)) return\n const category = classifyKey(key)\n if (category === 'credential' && typeof value !== 'number') {\n flag(state, path, 'credential', 'credential-key')\n return\n }\n const scalar = typeof value === 'string' || typeof value === 'number'\n if (category === 'personal-data' && scalar) {\n const kind = classifyKeyName(key)\n // Phone, IP and address fields are flagged from the share profile up; email always.\n if (kind === 'email' || state.profile !== 'default') {\n flag(state, path, 'personal-data', 'personal-data-key')\n return\n }\n }\n if (category === 'identifier' && scalar) flag(state, path, 'identifier', 'identifier-key')\n if (category === 'raw-content' && typeof value !== 'number')\n flag(state, path, 'raw-content', 'raw-content-key')\n scan(value, path, depth + 1, state)\n}\n\nfunction scan(value: unknown, path: string, depth: number, state: ScanState): void {\n if (typeof value === 'string') {\n scanString(value, path, state)\n return\n }\n if (value === null || typeof value !== 'object') return\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {\n state.unreadable.push(`${path || '/'}: binary data`)\n return\n }\n if (value instanceof Date) return\n if (depth > MAX_DEPTH) {\n state.unreadable.push(`${path || '/'}: nested deeper than ${MAX_DEPTH} levels`)\n return\n }\n if (state.seen.has(value)) {\n state.unreadable.push(`${path || '/'}: circular reference`)\n return\n }\n state.seen.add(value)\n try {\n if (Array.isArray(value)) {\n for (const [index, item] of value.entries())\n scan(item, pointer(path, index), depth + 1, state)\n return\n }\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n // A credential used as a key must not reach the finding paths.\n const keyCredential = credentialIn(key, state.knownSecrets)\n const segment = keyCredential ? marker(keyCredential) : key\n if (keyCredential) flag(state, pointer(path, segment), 'credential', keyCredential)\n scanKeyed(key, item, pointer(path, segment), depth, state)\n }\n } finally {\n state.seen.delete(value)\n }\n}\n\n/**\n * Read `value` without changing it and say whether it is safe to share under\n * `profile`. UNKNOWN when any part could not be read; UNSAFE when any\n * error-severity finding remains; SAFE_WITH_WARNINGS when only warnings\n * remain (raw content, embedded media, identifiers under `share`).\n */\nexport function assessShareSafety(value: unknown, options: AssessOptions = {}): ShareSafetyVerdict {\n const profile = options.profile ?? 'default'\n const rules = PROFILE_RULES[profile]\n if (!rules) throw new Error(`unknown redaction profile: ${String(profile)}`)\n const state: ScanState = {\n profile,\n rules,\n knownSecrets: knownSecretForms(options.knownSecrets),\n findings: new Map(),\n unreadable: [],\n seen: new WeakSet(),\n }\n scan(value, '', 0, state)\n return verdictFrom(profile, [...state.findings.values()], state.unreadable)\n}\n\n/**\n * One verdict over several parts (files in a directory, spans in a bundle).\n * Callers prefix each part's paths with its source before combining.\n */\nexport function combineVerdicts(\n profile: RedactionProfile,\n verdicts: readonly ShareSafetyVerdict[],\n unreadable: readonly string[] = [],\n): ShareSafetyVerdict {\n const findings = new Map<string, ShareSafetyFinding>()\n for (const verdict of verdicts) {\n for (const finding of verdict.findings) {\n const id = `${finding.category}\\u0000${finding.detector}`\n const existing = findings.get(id)\n if (!existing) {\n findings.set(id, { ...finding, paths: [...finding.paths] })\n continue\n }\n existing.count += finding.count\n for (const path of finding.paths) if (existing.paths.length < 5) existing.paths.push(path)\n }\n }\n return verdictFrom(\n profile,\n [...findings.values()],\n [...verdicts.flatMap((verdict) => verdict.unreadable), ...unreadable],\n )\n}\n\nfunction verdictFrom(\n profile: RedactionProfile,\n findings: readonly ShareSafetyFinding[],\n unreadable: readonly string[],\n): ShareSafetyVerdict {\n const status: ShareSafetyStatus =\n unreadable.length > 0\n ? 'UNKNOWN'\n : findings.some((finding) => finding.severity === 'error')\n ? 'UNSAFE'\n : findings.length > 0\n ? 'SAFE_WITH_WARNINGS'\n : 'SAFE'\n return { status, profile, findings: [...findings], unreadable: [...unreadable] }\n}\n\n/** Whether a verdict allows sharing: SAFE or SAFE_WITH_WARNINGS. UNSAFE and UNKNOWN refuse. */\nexport function shareAllowed(verdict: ShareSafetyVerdict): boolean {\n return verdict.status === 'SAFE' || verdict.status === 'SAFE_WITH_WARNINGS'\n}\n\n/**\n * Redact `value` under `profile`, then assess the redacted output. The\n * verdict describes what would actually be shared: a detector that failed to\n * remove something shows up as UNSAFE here.\n */\nexport function redactForShare<T>(\n value: T,\n options: RedactOptions = {},\n): { value: T; report: RedactionReport; verdict: ShareSafetyVerdict } {\n const redacted = redact(value, options)\n const verdict = assessShareSafety(redacted.value, {\n profile: options.profile,\n knownSecrets: options.knownSecrets,\n })\n return { value: redacted.value, report: redacted.report, verdict }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-ledger-Ck7tok0h.js","names":[],"sources":["../src/campaign/search-ledger-ordering.ts","../src/campaign/search-state.ts","../src/campaign/search-ledger-types.ts","../src/campaign/search-ledger.ts"],"sourcesContent":["import { canonicalString } from '../ledger-core'\nimport type { SearchArtifactRef } from './search-ledger-types'\n\nexport function artifactKey(artifact: SearchArtifactRef): string {\n return canonicalString(artifact)\n}\n\nexport function compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n","/**\n * `SearchState`: the one projection of a search ledger.\n *\n * The same code checks every invariant for the producer's journal, the kernel,\n * and the Intelligence verifier, and builds the read model they share. It keeps\n * compact indexes (nodes, edges, cells, per-unit score sums, running audit\n * totals), not the raw event list, and applies each entry in time proportional\n * to that entry, so a search of any length appends at a constant cost.\n *\n * The journal asks for a snapshot after every append. A snapshot is a\n * `SearchStateView` that reads the live indexes, so taking one costs nothing.\n * The view is valid until the state applies its next entry; a read after that\n * throws rather than returning numbers from a later ledger position. Read the\n * ledger's state again to see newer entries. The audit, header, head and claim\n * on a view are plain values and stay readable.\n */\n\nimport { createHash } from 'node:crypto'\nimport type { LedgerProjector } from '../ledger-core'\nimport { canonicalString, compareCodeUnits, hashCanonical } from '../ledger-core/canonical'\nimport type { RolloutSearchLineage } from '../rollout/mint'\nimport { type RunSearchCoordinates, searchCellRunId } from '../run-record'\nimport { SearchLedgerError, SearchLedgerIntegrityError } from './search-ledger-errors'\nimport { artifactKey } from './search-ledger-ordering'\nimport type {\n NodeEstimate,\n SearchArtifactRef,\n SearchAttemptAccounting,\n SearchAudit,\n SearchCandidateSurface,\n SearchCellAllocatedEvent,\n SearchCellCancelledEvent,\n SearchCellSettledEvent,\n SearchCellStage,\n SearchClaim,\n SearchClosedEvent,\n SearchEdgeRecordedEvent,\n SearchLedgerEntry,\n SearchLedgerEvent,\n SearchLedgerHash,\n SearchNodeDecidedEvent,\n SearchNodeDecision,\n SearchNodeRef,\n SearchNodeRegisteredEvent,\n SearchNodeStatus,\n SearchOpenedEvent,\n SearchOperationKind,\n SearchOperationRecordedEvent,\n SearchOperationStartedEvent,\n SearchReservation,\n SearchSplit,\n SearchTask,\n SearchTaskOutcome,\n} from './search-ledger-types'\n\n/** Deterministic node id: identical content in one search is one node. */\nexport function searchNodeId(searchId: string, artifactDigest: string): string {\n return `node_${shortDigest([searchId, artifactDigest])}`\n}\n\n/** Deterministic cell id: one node on one task in one split at one repeat. */\nexport function searchCellId(\n searchId: string,\n nodeId: string,\n taskId: string,\n split: SearchSplit,\n rep: number,\n): string {\n return `cell_${shortDigest([searchId, nodeId, taskId, split, rep])}`\n}\n\n/** Digest a split's task list in taskId order. */\nexport function searchTaskSetDigest(tasks: readonly SearchTask[]): SearchLedgerHash {\n return hashCanonical(\n [...tasks].sort((left, right) => compareCodeUnits(left.taskId, right.taskId)),\n )\n}\n\n/** 128 bits of SHA-256 over the canonical encoding: collision-safe and short\n * enough for directory names. */\nfunction shortDigest(value: unknown): string {\n return createHash('sha256').update(canonicalString(value)).digest('hex').slice(0, 32)\n}\n\nconst MAX_LABEL_CHARS = 200\nconst USD_TOLERANCE = 1e-9\nconst SPLITS: readonly SearchSplit[] = ['train', 'selection', 'test']\n\nexport interface SearchDecisionRecord {\n sequence: number\n decision: SearchNodeDecision\n basis: NodeEstimate | null\n rule: string\n reason: string\n}\n\nexport interface SearchSpend {\n knownUsd: number\n floorUsd: number\n unknownCostCells: number\n boxMinutes: number\n}\n\n/** Scores of one node on one unit of one split: the sum and count of its\n * scored cells. Repeats and sibling tasks of the unit average inside it. */\nexport interface SearchUnitScore {\n unitId: string\n sum: number\n count: number\n mean: number\n}\n\n/** A cell's scored attempt: the inputs of every per-unit statistic. */\nexport interface SearchScoredCell {\n cellId: string\n unitId: string\n /** The attempt that produced the score, which is the cell's last. */\n attempt: number\n score: number\n}\n\n/**\n * Per-unit means of scored cells, in unitId order. Each unit sums its cells in\n * cellId order, so the result depends on the set of cells alone, never on the\n * order they settled in: a verifier that reads the same cells from a database\n * gets the same bits.\n */\nexport function searchUnitScores(cells: readonly SearchScoredCell[]): SearchUnitScore[] {\n const byUnit = new Map<string, SearchScoredCell[]>()\n for (const cell of cells) {\n const unit = byUnit.get(cell.unitId)\n if (unit) unit.push(cell)\n else byUnit.set(cell.unitId, [cell])\n }\n return [...byUnit.entries()]\n .sort(([left], [right]) => compareCodeUnits(left, right))\n .map(([unitId, unitCells]) => {\n let sum = 0\n for (const cell of unitCells.sort((left, right) =>\n compareCodeUnits(left.cellId, right.cellId),\n )) {\n sum += cell.score\n }\n return { unitId, sum, count: unitCells.length, mean: sum / unitCells.length }\n })\n}\n\nexport interface SearchNode {\n nodeId: string\n /** Registration order; the root is 0. */\n ordinal: number\n artifactDigest: SearchLedgerHash\n artifact: SearchArtifactRef\n surfaces: readonly SearchCandidateSurface[]\n /** First in-search parent of the node's first edge; null for the root, a\n * derived root, or a node whose parents are unknown. */\n primaryParentId: string | null\n /** Edges from the root along primary parents; null while unknown. */\n depth: number | null\n /** Every parent named by any edge into the node, in edge order. */\n parents: readonly SearchNodeRef[]\n children: readonly string[]\n edgeIds: readonly string[]\n status: SearchNodeStatus | null\n rung: number | null\n /** The node was decided `finalist` at some point, so its test cells are legal. */\n finalist: boolean\n decisions: readonly SearchDecisionRecord[]\n cellCount: number\n spend: SearchSpend\n registeredSequence: number\n updatedSequence: number\n}\n\nexport interface SearchCell {\n cellId: string\n nodeId: string\n taskId: string\n unitId: string\n split: SearchSplit\n rep: number\n stage: SearchCellStage\n lane: string | null\n reservation: SearchReservation | null\n attempts: number\n lastRunId: string | null\n outcome: SearchTaskOutcome['status'] | null\n /** Score of the scored attempt; null when no attempt was scored. */\n score: number | null\n /** No further attempt is legal: a scored or non-retryable outcome. */\n final: boolean\n cancelled: SearchCellCancelledEvent['reason'] | null\n /** Known cost plus proven floors across attempts. */\n spentUsd: number\n /** Every attempt's cost is known. */\n costKnown: boolean\n traceId: string | null\n allocatedSequence: number\n updatedSequence: number\n}\n\nexport interface SearchOperation {\n operationId: string\n operationKind: SearchOperationKind\n reservation: SearchReservation | null\n recorded: boolean\n /** The recorded outcome; null until the operation is recorded. */\n outcome: SearchOperationRecordedEvent['outcome']['status'] | null\n /** Artifacts the recorded event bound, for example a proposal's output. */\n artifacts: readonly SearchArtifactRef[]\n spentUsd: number\n}\n\nexport interface SearchCompletion {\n complete: boolean\n reasons: string[]\n}\n\ninterface NodeRecord {\n event: SearchNodeRegisteredEvent\n ordinal: number\n registeredSequence: number\n updatedSequence: number\n edgeIds: string[]\n parents: SearchNodeRef[]\n parentKeys: Set<string>\n primaryParentId: string | null\n depth: number | null\n children: string[]\n decisions: SearchDecisionRecord[]\n finalist: boolean\n cellIds: string[]\n scoredCells: number\n spend: SearchSpend\n}\n\ntype CellRecord = SearchCell\ntype OperationRecord = SearchOperation\n\n/**\n * The pure, incremental projection of one search ledger. `apply` refuses any\n * entry that breaks an invariant; the journal then discards this instance and\n * replays into a new one, so a refused entry leaves no partial state behind.\n */\nexport class SearchState implements LedgerProjector<SearchLedgerEntry, SearchStateView> {\n readonly searchId: string\n private version = 0\n private header: SearchOpenedEvent | null = null\n private closed: SearchClosedEvent | null = null\n private head: { sequence: number; entryHash: SearchLedgerHash } | null = null\n private lastOccurredAt = Number.NEGATIVE_INFINITY\n private lastOccurredAtText: string | null = null\n private readonly tasks = new Map<string, { split: SearchSplit; unitId: string }>()\n private readonly nodes = new Map<string, NodeRecord>()\n private readonly nodeOrder: string[] = []\n private readonly nodeByDigest = new Map<string, string>()\n private readonly edges = new Map<string, SearchEdgeRecordedEvent>()\n private readonly edgeOrder: string[] = []\n private readonly cells = new Map<string, CellRecord>()\n private readonly operations = new Map<string, OperationRecord>()\n private selectedNodeId: string | null = null\n private claimUsedUsd = 0\n private readonly audit: SearchAudit\n\n constructor(searchId: string) {\n this.searchId = searchId\n this.audit = {\n searchId,\n eventCount: 0,\n headHash: null,\n status: 'open',\n closeReason: null,\n nodes: 0,\n nodesWithoutEdge: 0,\n undecidedNodes: 0,\n selectedNodeId: null,\n edges: { explicit: 0, correlated: 0, unknown: 0, reproposals: 0 },\n cells: { allocated: 0, settled: 0, cancelled: 0, open: 0 },\n attempts: 0,\n outcomes: { passed: 0, failed: 0, errored: 0 },\n operations: { started: 0, recorded: 0, open: 0 },\n spend: {\n knownUsd: 0,\n floorUsd: 0,\n unknownCostCells: 0,\n unknownCostOperations: 0,\n committedUsd: 0,\n openReservationUsd: 0,\n overspendUsd: 0,\n unreservedCells: 0,\n boxMinutes: 0,\n },\n tokens: { inputTokens: 0, outputTokens: 0, cachedTokens: 0, unknownTokenAttempts: 0 },\n }\n }\n\n apply(entry: SearchLedgerEntry, index: number): void {\n const event = entry.event\n if (this.closed) {\n throw integrity(`event ${event.eventId} follows search-closed ${this.closed.eventId}`)\n }\n const occurredAt = Date.parse(event.occurredAt)\n if (occurredAt < this.lastOccurredAt) {\n throw integrity(`event ${event.eventId} occurred before the preceding event`)\n }\n assertUnique(event.artifacts.map(artifactKey), 'artifact receipt', event.eventId)\n if (event.kind === 'search-opened') {\n if (index !== 0 || this.header) {\n throw integrity('search-opened must be the first and only opening event')\n }\n this.open(event)\n } else {\n if (!this.header) {\n throw integrity(`event ${event.eventId} appears before search-opened`)\n }\n this.applyEvent(event, index)\n }\n this.lastOccurredAt = occurredAt\n this.lastOccurredAtText = event.occurredAt\n this.head = { sequence: index, entryHash: entry.entryHash }\n this.audit.eventCount = index + 1\n this.audit.headHash = entry.entryHash\n this.version += 1\n }\n\n snapshot(): SearchStateView {\n return new SearchStateView(this, this.version)\n }\n\n /** @internal Views check this before every read of the live indexes. */\n isAt(version: number): boolean {\n return this.version === version\n }\n\n private applyEvent(event: Exclude<SearchLedgerEvent, SearchOpenedEvent>, index: number): void {\n switch (event.kind) {\n case 'operation-started':\n this.startOperation(event)\n return\n case 'operation-recorded':\n this.recordOperation(event)\n return\n case 'node-registered':\n this.registerNode(event, index)\n return\n case 'edge-recorded':\n this.recordEdge(event, index)\n return\n case 'cell-allocated':\n this.allocateCell(event, index)\n return\n case 'cell-settled':\n this.settleCell(event, index)\n return\n case 'cell-cancelled':\n this.cancelCell(event, index)\n return\n case 'node-decided':\n this.decideNode(event, index)\n return\n case 'search-closed':\n this.close(event)\n return\n }\n }\n\n private open(event: SearchOpenedEvent): void {\n if (event.containment?.searchId === this.searchId) {\n throw integrity('a search cannot contain itself')\n }\n if (event.derivedFrom?.searchId === this.searchId) {\n throw integrity('a search cannot derive from itself')\n }\n const units: Record<SearchSplit, Set<string>> = {\n train: new Set(),\n selection: new Set(),\n test: new Set(),\n }\n for (const split of SPLITS) {\n const { tasks, taskSetDigest } = event.splits[split]\n if (searchTaskSetDigest(tasks) !== taskSetDigest) {\n throw integrity(`the ${split} split's taskSetDigest does not match its tasks`)\n }\n for (const task of tasks) {\n const owner = this.tasks.get(task.taskId)\n if (owner) {\n throw integrity(`task ${task.taskId} is in both the ${owner.split} and ${split} splits`)\n }\n this.tasks.set(task.taskId, { split, unitId: task.unitId })\n units[split].add(task.unitId)\n }\n }\n if (event.splits.heldOutUnits) {\n const seen = [...units.test].filter(\n (unit) => units.train.has(unit) || units.selection.has(unit),\n )\n if (seen.length > 0) {\n throw integrity(\n `test units ${seen.join(', ')} also appear in train or selection, but the splits declare heldOutUnits`,\n )\n }\n }\n const { budget } = event\n if (budget.maxUsd !== null && budget.reservedClaimUsd > budget.maxUsd + USD_TOLERANCE) {\n throw integrity(\n `the claim reserve $${budget.reservedClaimUsd} exceeds the search cap $${budget.maxUsd}`,\n )\n }\n this.header = event\n }\n\n private startOperation(event: SearchOperationStartedEvent): void {\n if (this.operations.has(event.operationId)) {\n throw integrity(`operation ${event.operationId} was started twice`)\n }\n this.admit(event.reservation, false, `operation ${event.operationId}`)\n this.operations.set(event.operationId, {\n operationId: event.operationId,\n operationKind: event.operationKind,\n reservation: event.reservation,\n recorded: false,\n outcome: null,\n artifacts: [],\n spentUsd: 0,\n })\n this.audit.operations.started += 1\n this.audit.operations.open += 1\n this.audit.spend.openReservationUsd += event.reservation?.usd ?? 0\n }\n\n private recordOperation(event: SearchOperationRecordedEvent): void {\n const operation = this.operations.get(event.operationId)\n if (!operation) {\n throw integrity(`operation ${event.operationId} was recorded before it started`)\n }\n if (operation.recorded) {\n throw integrity(`operation ${event.operationId} was recorded twice`)\n }\n if (operation.operationKind !== event.operationKind) {\n throw integrity(\n `operation ${event.operationId} started as ${operation.operationKind} but recorded as ${event.operationKind}`,\n )\n }\n const cost = this.book(event.accounting)\n if (cost.unknown) this.audit.spend.unknownCostOperations += 1\n const reserved = operation.reservation?.usd ?? 0\n this.audit.spend.openReservationUsd -= reserved\n if (operation.reservation) {\n this.audit.spend.overspendUsd += Math.max(0, cost.usd - reserved)\n }\n operation.recorded = true\n operation.outcome = event.outcome.status\n operation.artifacts = event.artifacts\n operation.spentUsd = cost.usd\n this.audit.operations.recorded += 1\n this.audit.operations.open -= 1\n }\n\n private registerNode(event: SearchNodeRegisteredEvent, index: number): void {\n const expected = searchNodeId(this.searchId, event.artifactDigest)\n if (event.nodeId !== expected) {\n throw integrity(\n `node ${event.nodeId} does not match its artifact digest (expected ${expected})`,\n )\n }\n if (this.nodes.has(event.nodeId)) {\n throw integrity(\n `node ${event.nodeId} was registered twice; a re-proposal is a second edge into it`,\n )\n }\n assertUnique(\n event.surfaces.map((surface) => surface.surfaceId),\n 'surfaceId',\n event.eventId,\n )\n const maxNodes = this.header!.budget.maxNodes\n if (maxNodes !== null && this.nodes.size + 1 > maxNodes) {\n throw integrity(`node ${event.nodeId} exceeds the search's maxNodes ${maxNodes}`)\n }\n this.nodes.set(event.nodeId, {\n event,\n ordinal: this.nodeOrder.length,\n registeredSequence: index,\n updatedSequence: index,\n edgeIds: [],\n parents: [],\n parentKeys: new Set(),\n primaryParentId: null,\n depth: null,\n children: [],\n decisions: [],\n finalist: false,\n cellIds: [],\n scoredCells: 0,\n spend: { knownUsd: 0, floorUsd: 0, unknownCostCells: 0, boxMinutes: 0 },\n })\n this.nodeOrder.push(event.nodeId)\n this.nodeByDigest.set(event.artifactDigest, event.nodeId)\n this.audit.nodes += 1\n this.audit.nodesWithoutEdge += 1\n this.audit.undecidedNodes += 1\n }\n\n private recordEdge(event: SearchEdgeRecordedEvent, index: number): void {\n if (this.edges.has(event.edgeId)) {\n throw integrity(`edge ${event.edgeId} was recorded twice`)\n }\n const child = this.nodes.get(event.childNodeId)\n if (!child) {\n throw integrity(`edge ${event.edgeId} names unregistered child ${event.childNodeId}`)\n }\n if (event.label.length > MAX_LABEL_CHARS) {\n throw integrity(`edge ${event.edgeId} label exceeds ${MAX_LABEL_CHARS} characters`)\n }\n if (event.diffs.length !== event.parents.length) {\n throw integrity(`edge ${event.edgeId} needs one diff per parent`)\n }\n assertUnique(\n event.parents.map((parent) => canonicalString(parent)),\n 'parent',\n event.eventId,\n )\n const { operator, attribution, parents } = event\n if ((operator === 'seed') !== (event.proposer === null)) {\n throw integrity(`edge ${event.edgeId}: exactly the seed edge has no proposer`)\n }\n if (operator === 'seed' && (parents.length > 0 || attribution === 'unknown')) {\n throw integrity(`seed edge ${event.edgeId} must have no parents and a known attribution`)\n }\n if (attribution === 'unknown' && parents.length > 0) {\n throw integrity(`edge ${event.edgeId} has unknown attribution but names parents`)\n }\n if (operator !== 'seed' && attribution !== 'unknown' && parents.length === 0) {\n throw integrity(`${operator} edge ${event.edgeId} names no parent`)\n }\n if (operator === 'merge' && attribution !== 'unknown' && parents.length < 2) {\n throw integrity(`merge edge ${event.edgeId} needs at least two parents`)\n }\n const operationId = event.proposer?.operationId ?? null\n if (operationId !== null && !this.operations.has(operationId)) {\n throw integrity(`edge ${event.edgeId} names operation ${operationId}, which never started`)\n }\n const inSearch: NodeRecord[] = []\n for (const parent of parents) {\n if (parent.searchId !== this.searchId) {\n const from = this.header!.derivedFrom\n if (\n operator !== 'derive' ||\n parents.length !== 1 ||\n !from ||\n from.searchId !== parent.searchId ||\n from.nodeId !== parent.nodeId\n ) {\n throw integrity(\n `edge ${event.edgeId} names a parent in search ${parent.searchId}; only a derive edge matching derivedFrom may`,\n )\n }\n continue\n }\n if (operator === 'derive') {\n throw integrity(`derive edge ${event.edgeId} must name the parent in derivedFrom`)\n }\n const record = this.nodes.get(parent.nodeId)\n if (!record) {\n throw integrity(`edge ${event.edgeId} names unregistered parent ${parent.nodeId}`)\n }\n if (record.ordinal >= child.ordinal) {\n throw integrity(\n `edge ${event.edgeId}: parent ${parent.nodeId} registered after child ${child.event.nodeId}`,\n )\n }\n if (record.edgeIds.length === 0) {\n throw integrity(`edge ${event.edgeId}: parent ${parent.nodeId} has no edge of its own yet`)\n }\n inSearch.push(record)\n }\n\n if (child.edgeIds.length === 0) {\n const primary = inSearch[0]\n child.primaryParentId = primary?.event.nodeId ?? null\n child.depth =\n operator === 'seed' || operator === 'derive'\n ? 0\n : primary && primary.depth !== null\n ? primary.depth + 1\n : null\n this.audit.nodesWithoutEdge -= 1\n } else {\n this.audit.edges.reproposals += 1\n }\n child.edgeIds.push(event.edgeId)\n for (const parent of parents) {\n const key = canonicalString(parent)\n if (child.parentKeys.has(key)) continue\n child.parentKeys.add(key)\n child.parents.push(parent)\n }\n for (const parent of inSearch) {\n if (!parent.children.includes(child.event.nodeId)) parent.children.push(child.event.nodeId)\n }\n child.updatedSequence = index\n this.edges.set(event.edgeId, event)\n this.edgeOrder.push(event.edgeId)\n this.audit.edges[attribution] += 1\n }\n\n private allocateCell(event: SearchCellAllocatedEvent, index: number): void {\n const expected = searchCellId(this.searchId, event.nodeId, event.taskId, event.split, event.rep)\n if (event.cellId !== expected) {\n throw integrity(`cell ${event.cellId} does not match its coordinates (expected ${expected})`)\n }\n if (this.cells.has(event.cellId)) {\n throw integrity(`cell ${event.cellId} was allocated twice`)\n }\n const node = this.nodes.get(event.nodeId)\n if (!node) throw integrity(`cell ${event.cellId} names unregistered node ${event.nodeId}`)\n if (node.edgeIds.length === 0) {\n throw integrity(`cell ${event.cellId}: node ${event.nodeId} has no edge yet`)\n }\n const task = this.tasks.get(event.taskId)\n if (!task || task.split !== event.split) {\n throw integrity(\n `cell ${event.cellId}: task ${event.taskId} is not in the ${event.split} split`,\n )\n }\n if (task.unitId !== event.unitId) {\n throw integrity(`cell ${event.cellId}: task ${event.taskId} samples unit ${task.unitId}`)\n }\n assertStageSplit(event.cellId, event.stage, event.split, node.ordinal === 0)\n if (event.split === 'test' && node.ordinal !== 0 && !node.finalist) {\n throw integrity(\n `cell ${event.cellId}: the test split is sealed; only the root and finalists run on it`,\n )\n }\n const maxCells = this.header!.budget.maxCells\n if (maxCells !== null && this.audit.cells.allocated + 1 > maxCells) {\n throw integrity(`cell ${event.cellId} exceeds the search's maxCells ${maxCells}`)\n }\n this.admit(event.reservation, event.stage === 'claim', `cell ${event.cellId}`)\n this.cells.set(event.cellId, {\n cellId: event.cellId,\n nodeId: event.nodeId,\n taskId: event.taskId,\n unitId: event.unitId,\n split: event.split,\n rep: event.rep,\n stage: event.stage,\n lane: event.lane,\n reservation: event.reservation,\n attempts: 0,\n lastRunId: null,\n outcome: null,\n score: null,\n final: false,\n cancelled: null,\n spentUsd: 0,\n costKnown: true,\n traceId: null,\n allocatedSequence: index,\n updatedSequence: index,\n })\n node.cellIds.push(event.cellId)\n node.updatedSequence = index\n this.audit.cells.allocated += 1\n this.audit.cells.open += 1\n this.audit.spend.openReservationUsd += event.reservation?.usd ?? 0\n if (event.stage === 'claim') this.claimUsedUsd += event.reservation?.usd ?? 0\n }\n\n private settleCell(event: SearchCellSettledEvent, index: number): void {\n const cell = this.cells.get(event.cellId)\n if (!cell) throw integrity(`attempt ${event.eventId} names unallocated cell ${event.cellId}`)\n if (cell.cancelled) throw integrity(`cell ${event.cellId} was settled after it was cancelled`)\n if (cell.final) {\n throw integrity(\n `cell ${event.cellId} was attempted again after a final ${cell.outcome} outcome; only a retryable error admits another attempt`,\n )\n }\n if (event.attempt !== cell.attempts + 1) {\n throw integrity(\n `cell ${event.cellId} attempt ${event.attempt} is not contiguous (expected ${cell.attempts + 1})`,\n )\n }\n const runId = searchCellRunId({ cellId: event.cellId, attempt: event.attempt })\n if (event.runId !== runId) {\n throw integrity(`cell ${event.cellId} attempt ${event.attempt} must have runId ${runId}`)\n }\n const node = this.nodes.get(cell.nodeId)!\n const declared = new Set(node.event.surfaces.map((surface) => surface.surfaceId))\n assertUnique(\n event.surfaceEvidence.map((evidence) => evidence.surfaceId),\n 'surface evidence',\n event.eventId,\n )\n for (const evidence of event.surfaceEvidence) {\n if (!declared.has(evidence.surfaceId)) {\n throw integrity(\n `attempt ${event.eventId} reports surface ${evidence.surfaceId}, which node ${cell.nodeId} does not declare`,\n )\n }\n }\n if (event.artifacts.filter((artifact) => artifact.role === 'run-record').length > 1) {\n throw integrity(`attempt ${event.eventId} binds more than one RunRecord`)\n }\n\n const before = this.reservationParts(cell)\n const cost = this.book(event.accounting)\n if (cell.attempts === 0) {\n this.audit.cells.settled += 1\n this.audit.cells.open -= 1\n if (cell.reservation === null) this.audit.spend.unreservedCells += 1\n }\n if (cost.unknown && cell.costKnown) {\n cell.costKnown = false\n this.audit.spend.unknownCostCells += 1\n node.spend.unknownCostCells += 1\n }\n cell.attempts = event.attempt\n cell.lastRunId = runId\n cell.outcome = event.outcome.status\n cell.spentUsd += cost.usd\n cell.updatedSequence = index\n if ('traceId' in event.traceRef) cell.traceId = event.traceRef.traceId\n if (event.outcome.status === 'errored') {\n cell.final = !event.outcome.error.retryable\n } else {\n cell.final = true\n cell.score = event.outcome.score\n node.scoredCells += 1\n }\n const after = this.reservationParts(cell)\n this.audit.spend.openReservationUsd += after.open - before.open\n this.audit.spend.overspendUsd += after.over - before.over\n if (cell.stage === 'claim') this.claimUsedUsd += after.used - before.used\n\n if (cost.unknown) node.spend.floorUsd += cost.usd\n else node.spend.knownUsd += cost.usd\n const boxMinutes = event.boxMinutes ?? 0\n node.spend.boxMinutes += boxMinutes\n this.audit.spend.boxMinutes += boxMinutes\n node.updatedSequence = index\n this.audit.attempts += 1\n this.audit.outcomes[event.outcome.status] += 1\n }\n\n private cancelCell(event: SearchCellCancelledEvent, index: number): void {\n const cell = this.cells.get(event.cellId)\n if (!cell)\n throw integrity(`cancellation ${event.eventId} names unallocated cell ${event.cellId}`)\n if (cell.cancelled) throw integrity(`cell ${event.cellId} was cancelled twice`)\n if (cell.final) throw integrity(`cell ${event.cellId} was cancelled after a final outcome`)\n const before = this.reservationParts(cell)\n cell.cancelled = event.reason\n cell.updatedSequence = index\n const after = this.reservationParts(cell)\n this.audit.spend.openReservationUsd += after.open - before.open\n this.audit.spend.overspendUsd += after.over - before.over\n if (cell.stage === 'claim') this.claimUsedUsd += after.used - before.used\n if (cell.attempts === 0) {\n this.audit.cells.cancelled += 1\n this.audit.cells.open -= 1\n }\n this.nodes.get(cell.nodeId)!.updatedSequence = index\n }\n\n private decideNode(event: SearchNodeDecidedEvent, index: number): void {\n const node = this.nodes.get(event.nodeId)\n if (!node) throw integrity(`decision ${event.eventId} names unregistered node ${event.nodeId}`)\n if (node.edgeIds.length === 0) {\n throw integrity(`decision ${event.eventId}: node ${event.nodeId} has no edge yet`)\n }\n const status = event.decision.status\n if (status === 'selected') {\n if (this.selectedNodeId !== null && this.selectedNodeId !== event.nodeId) {\n throw integrity(\n `node ${event.nodeId} was selected while ${this.selectedNodeId} is still selected`,\n )\n }\n if (node.scoredCells === 0) {\n throw integrity(`node ${event.nodeId} cannot be selected without a scored cell`)\n }\n }\n const previous = node.decisions.at(-1)?.decision.status ?? null\n const wasUndecided = previous === null || previous === 'advanced'\n const isUndecided = status === 'advanced'\n this.audit.undecidedNodes += (isUndecided ? 1 : 0) - (wasUndecided ? 1 : 0)\n if (previous === 'selected' && status !== 'selected') this.selectedNodeId = null\n if (status === 'selected') this.selectedNodeId = event.nodeId\n if (status === 'finalist') node.finalist = true\n node.decisions.push({\n sequence: index,\n decision: event.decision,\n basis: event.basis,\n rule: event.rule,\n reason: event.reason,\n })\n node.updatedSequence = index\n this.audit.selectedNodeId = this.selectedNodeId\n }\n\n private close(event: SearchClosedEvent): void {\n const reasons = this.incompleteReasons()\n if (reasons.length > 0) {\n throw integrity(`search-closed while incomplete: ${reasons.join('; ')}`)\n }\n if (event.claim) this.checkClaim(event.claim)\n this.closed = event\n this.audit.status = 'closed'\n this.audit.closeReason = event.reason\n // Nothing runs after the close, so every hold is released.\n this.audit.spend.openReservationUsd = 0\n }\n\n private checkClaim(claim: SearchClaim): void {\n if (claim.finalists.length > 3) {\n throw integrity(`the claim names ${claim.finalists.length} finalists; at most 3 are allowed`)\n }\n assertUnique(\n claim.finalists.map((finalist) => finalist.nodeId),\n 'claim finalist',\n 'search-closed',\n )\n for (const finalist of claim.finalists) {\n if (!this.nodes.get(finalist.nodeId)?.finalist) {\n throw integrity(`claim finalist ${finalist.nodeId} was never decided finalist`)\n }\n }\n if (claim.selected !== this.selectedNodeId) {\n throw integrity(\n `the claim selects ${claim.selected ?? 'nothing'} but the selected node is ${this.selectedNodeId ?? 'none'}`,\n )\n }\n const root = this.nodeOrder[0] ?? null\n if (claim.decision === 'ship') {\n const shipped = claim.finalists.find((finalist) => finalist.nodeId === claim.selected)\n if (claim.selected === null || claim.selected === root || !shipped?.promote) {\n throw integrity('a ship claim must select a finalist that the paired test promoted')\n }\n if (!this.header!.splits.heldOutUnits) {\n throw integrity('a ship claim needs test units held out from train and selection')\n }\n } else if (claim.selected !== null && claim.selected !== root) {\n throw integrity(`a ${claim.decision} claim keeps the root; it cannot select another node`)\n }\n if (claim.decision === 'test-cannot-resolve') {\n for (const cell of this.cells.values()) {\n if (cell.split === 'test' && cell.attempts > 0) {\n throw integrity('a test-cannot-resolve claim spends nothing on test cells')\n }\n }\n }\n }\n\n /** @internal */\n incompleteReasons(): string[] {\n const reasons: string[] = []\n if (!this.header) reasons.push('search-opened is missing')\n if (this.audit.cells.open > 0)\n reasons.push(count(this.audit.cells.open, 'cell', 'has no outcome'))\n if (this.audit.operations.open > 0) {\n reasons.push(count(this.audit.operations.open, 'operation', 'is unrecorded'))\n }\n if (this.audit.nodesWithoutEdge > 0) {\n reasons.push(count(this.audit.nodesWithoutEdge, 'node', 'has no edge'))\n }\n if (this.audit.undecidedNodes > 0) {\n reasons.push(count(this.audit.undecidedNodes, 'node', 'has no terminal decision'))\n }\n return reasons\n }\n\n /** Book an attempt's or operation's accounting into the running totals. An\n * unknown cost counts as its proven floor. */\n private book(accounting: SearchAttemptAccounting): { usd: number; unknown: boolean } {\n const { tokens, cost } = accounting\n if (tokens.status === 'known') {\n this.audit.tokens.inputTokens += tokens.inputTokens\n this.audit.tokens.outputTokens += tokens.outputTokens\n this.audit.tokens.cachedTokens += tokens.cachedTokens\n } else {\n this.audit.tokens.unknownTokenAttempts += 1\n }\n const usd = cost.status === 'known' ? cost.usd : cost.knownLowerBoundUsd\n if (cost.status === 'known') this.audit.spend.knownUsd += usd\n else this.audit.spend.floorUsd += usd\n this.audit.spend.committedUsd += usd\n return { usd, unknown: cost.status === 'unknown' }\n }\n\n /** A cell's share of the open reservations, its overspend, and what it draws\n * from the claim reserve: the larger of its hold and its spend. */\n private reservationParts(cell: CellRecord): { open: number; over: number; used: number } {\n const reserved = cell.reservation?.usd ?? 0\n const holding = !cell.final && cell.cancelled === null\n return {\n open: holding ? Math.max(0, reserved - cell.spentUsd) : 0,\n over: cell.reservation ? Math.max(0, cell.spentUsd - reserved) : 0,\n used: holding ? Math.max(reserved, cell.spentUsd) : cell.spentUsd,\n }\n }\n\n /** The admission rule: committed spend, open holds, the unspent claim\n * reserve and the new hold stay within the cap. A claim cell draws on the\n * claim reserve instead of adding to it. */\n private admit(reservation: SearchReservation | null, claim: boolean, subject: string): void {\n const { maxUsd, reservedClaimUsd } = this.header!.budget\n if (maxUsd === null) return\n const hold = reservation?.usd ?? 0\n const remainingClaim = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n const total =\n this.audit.spend.committedUsd +\n this.audit.spend.openReservationUsd +\n (claim ? Math.max(0, remainingClaim - hold) : remainingClaim) +\n hold\n if (total > maxUsd + USD_TOLERANCE) {\n throw integrity(\n `${subject} is not admissible: committed $${round(this.audit.spend.committedUsd)} + open $${round(this.audit.spend.openReservationUsd)} + claim reserve $${round(remainingClaim)} + hold $${round(hold)} exceeds the cap $${maxUsd}`,\n )\n }\n }\n\n // ── Reads, for SearchStateView ─────────────────────────────────────────\n\n /** @internal The largest hold a new non-claim cell or operation may take,\n * and the claim reserve still unspent. */\n readBudget(): { headroomUsd: number | null; claimReserveUsd: number } {\n const { maxUsd, reservedClaimUsd } = this.header?.budget ?? {\n maxUsd: null,\n reservedClaimUsd: 0,\n }\n const claimReserveUsd = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n if (maxUsd === null) return { headroomUsd: null, claimReserveUsd }\n const used =\n this.audit.spend.committedUsd + this.audit.spend.openReservationUsd + claimReserveUsd\n return { headroomUsd: Math.max(0, maxUsd - used), claimReserveUsd }\n }\n\n /** @internal */\n readHeader(): SearchOpenedEvent | null {\n return this.header\n }\n\n /** @internal */\n readClosed(): SearchClosedEvent | null {\n return this.closed\n }\n\n /** @internal */\n readHead(): { sequence: number; entryHash: SearchLedgerHash } | null {\n return this.head\n }\n\n /** @internal */\n readLastOccurredAt(): string | null {\n return this.lastOccurredAtText\n }\n\n /** @internal */\n readAudit(): SearchAudit {\n const audit = this.audit\n return {\n ...audit,\n edges: { ...audit.edges },\n cells: { ...audit.cells },\n outcomes: { ...audit.outcomes },\n operations: { ...audit.operations },\n spend: { ...audit.spend },\n tokens: { ...audit.tokens },\n }\n }\n\n /** @internal */\n readNode(nodeId: string): SearchNode | undefined {\n const record = this.nodes.get(nodeId)\n return record ? nodeView(record) : undefined\n }\n\n /** @internal */\n readNodeIds(): readonly string[] {\n return this.nodeOrder\n }\n\n /** @internal */\n readHasNode(nodeId: string): boolean {\n return this.nodes.has(nodeId)\n }\n\n /** @internal */\n readNodeIdForDigest(artifactDigest: string): string | undefined {\n return this.nodeByDigest.get(artifactDigest)\n }\n\n /** @internal */\n readEdge(edgeId: string): SearchEdgeRecordedEvent | undefined {\n return this.edges.get(edgeId)\n }\n\n /** @internal */\n readEdgeIds(): readonly string[] {\n return this.edgeOrder\n }\n\n /** @internal */\n readCell(cellId: string): SearchCell | undefined {\n const cell = this.cells.get(cellId)\n return cell ? { ...cell } : undefined\n }\n\n /** @internal */\n readCellIds(nodeId?: string): readonly string[] {\n if (nodeId === undefined) return [...this.cells.keys()]\n return this.nodes.get(nodeId)?.cellIds ?? []\n }\n\n /** @internal */\n readOperation(operationId: string): SearchOperation | undefined {\n const operation = this.operations.get(operationId)\n return operation ? { ...operation } : undefined\n }\n\n /** @internal */\n readScoredCells(nodeId: string, split: SearchSplit): SearchScoredCell[] {\n const scored: SearchScoredCell[] = []\n for (const cellId of this.nodes.get(nodeId)?.cellIds ?? []) {\n const cell = this.cells.get(cellId)!\n if (cell.split === split && cell.score !== null) {\n scored.push({ cellId, unitId: cell.unitId, attempt: cell.attempts, score: cell.score })\n }\n }\n return scored\n }\n}\n\n/**\n * A read of `SearchState` at one ledger position. Header, head, audit and\n * claim are values. Node, edge, cell and score reads go to the live indexes and\n * throw once the state has applied a later entry.\n */\nexport class SearchStateView {\n readonly searchId: string\n readonly header: SearchOpenedEvent | null\n readonly closed: SearchClosedEvent | null\n readonly head: { sequence: number; entryHash: SearchLedgerHash } | null\n /** `occurredAt` of the head entry; a writer stamps later events at or after it. */\n readonly lastOccurredAt: string | null\n readonly audit: SearchAudit\n readonly completion: SearchCompletion\n /**\n * The admission rule's room: `headroomUsd` is the largest reservation a new\n * non-claim cell or operation may hold (committed spend, open holds and the\n * unspent claim reserve all count against the cap), or null when the search\n * declares no cap. `claimReserveUsd` is what claim cells may still draw.\n */\n readonly budget: { headroomUsd: number | null; claimReserveUsd: number }\n private readonly state: SearchState\n private readonly version: number\n\n constructor(state: SearchState, version: number) {\n this.state = state\n this.version = version\n this.searchId = state.searchId\n this.header = state.readHeader()\n this.closed = state.readClosed()\n this.head = state.readHead()\n this.lastOccurredAt = state.readLastOccurredAt()\n this.audit = state.readAudit()\n this.budget = state.readBudget()\n const reasons = state.incompleteReasons()\n if (!this.closed) reasons.unshift('search is open')\n this.completion = { complete: this.closed !== null, reasons }\n }\n\n /** The node the search started from: the first registered. */\n get rootNodeId(): string | null {\n return this.live().readNodeIds()[0] ?? null\n }\n\n node(nodeId: string): SearchNode | undefined {\n return this.live().readNode(nodeId)\n }\n\n hasNode(nodeId: string): boolean {\n return this.live().readHasNode(nodeId)\n }\n\n /** Node ids in registration order. */\n nodeIds(): string[] {\n return [...this.live().readNodeIds()]\n }\n\n /** Nodes in registration order. */\n nodes(): SearchNode[] {\n const state = this.live()\n return state.readNodeIds().map((nodeId) => state.readNode(nodeId)!)\n }\n\n nodeIdForDigest(artifactDigest: string): string | undefined {\n return this.live().readNodeIdForDigest(artifactDigest)\n }\n\n edge(edgeId: string): SearchEdgeRecordedEvent | undefined {\n return this.live().readEdge(edgeId)\n }\n\n /** Edges in ledger order. */\n edges(): SearchEdgeRecordedEvent[] {\n const state = this.live()\n return state.readEdgeIds().map((edgeId) => state.readEdge(edgeId)!)\n }\n\n cell(cellId: string): SearchCell | undefined {\n return this.live().readCell(cellId)\n }\n\n /** Cells in allocation order, optionally of one node. */\n cells(filter: { nodeId?: string } = {}): SearchCell[] {\n const state = this.live()\n return state.readCellIds(filter.nodeId).map((cellId) => state.readCell(cellId)!)\n }\n\n operation(operationId: string): SearchOperation | undefined {\n return this.live().readOperation(operationId)\n }\n\n /** A node's scored cells on one split, in allocation order. Unscored cells\n * (errored, cancelled or in flight) are absent, never zero. */\n scoredCells(nodeId: string, split: SearchSplit): SearchScoredCell[] {\n return this.live().readScoredCells(nodeId, split)\n }\n\n /** Per-unit score means of a node on one split, in unitId order. */\n unitScores(nodeId: string, split: SearchSplit): SearchUnitScore[] {\n return searchUnitScores(this.scoredCells(nodeId, split))\n }\n\n /** The lineage a RunRecord mint needs for one cell attempt. */\n lineage(coordinates: RunSearchCoordinates): RolloutSearchLineage {\n const state = this.live()\n if (coordinates.searchId !== this.searchId) {\n throw new SearchLedgerError(\n `coordinates name search ${coordinates.searchId}, not ${this.searchId}`,\n )\n }\n const cell = state.readCell(coordinates.cellId)\n if (!cell || cell.nodeId !== coordinates.nodeId) {\n throw new SearchLedgerError(\n `cell ${coordinates.cellId} of node ${coordinates.nodeId} is not in search ${this.searchId}`,\n )\n }\n if (coordinates.attempt < 1 || coordinates.attempt > cell.attempts) {\n throw new SearchLedgerError(\n `cell ${coordinates.cellId} has ${cell.attempts} settled attempt(s), not attempt ${coordinates.attempt}`,\n )\n }\n const node = state.readNode(cell.nodeId)!\n if (node.depth === null) {\n throw new SearchLedgerError(\n `node ${node.nodeId} has unknown lineage, so its depth is unknown`,\n )\n }\n const containment = this.header?.containment ?? null\n return {\n depth: node.depth,\n ordinal: node.ordinal,\n rep: cell.rep,\n containingRunId: containment\n ? searchCellRunId({ cellId: containment.cellId, attempt: containment.attempt })\n : null,\n }\n }\n\n private live(): SearchState {\n if (!this.state.isAt(this.version)) {\n throw new SearchLedgerError(\n `this SearchStateView is from sequence ${this.head?.sequence ?? -1}, and the ledger has moved on; read the ledger's state again`,\n )\n }\n return this.state\n }\n}\n\nfunction nodeView(record: NodeRecord): SearchNode {\n const latest = record.decisions.at(-1)?.decision ?? null\n return {\n nodeId: record.event.nodeId,\n ordinal: record.ordinal,\n artifactDigest: record.event.artifactDigest,\n artifact: record.event.artifact,\n surfaces: record.event.surfaces,\n primaryParentId: record.primaryParentId,\n depth: record.depth,\n parents: [...record.parents],\n children: [...record.children],\n edgeIds: [...record.edgeIds],\n status: latest?.status ?? null,\n rung: latest?.status === 'advanced' ? latest.rung : null,\n finalist: record.finalist,\n decisions: [...record.decisions],\n cellCount: record.cellIds.length,\n spend: { ...record.spend },\n registeredSequence: record.registeredSequence,\n updatedSequence: record.updatedSequence,\n }\n}\n\nfunction assertStageSplit(\n cellId: string,\n stage: SearchCellStage,\n split: SearchSplit,\n isRoot: boolean,\n): void {\n const allowed: Record<SearchCellStage, readonly SearchSplit[]> = {\n root: ['train', 'selection'],\n train: ['train'],\n screen: ['selection'],\n rung: ['selection'],\n claim: ['test'],\n external: ['train', 'selection'],\n }\n if (!allowed[stage].includes(split)) {\n throw integrity(`cell ${cellId}: a ${stage} cell cannot run on the ${split} split`)\n }\n if (stage === 'root' && !isRoot) {\n throw integrity(`cell ${cellId}: only the root node runs root cells`)\n }\n}\n\nfunction assertUnique(values: readonly string[], label: string, eventId: string): void {\n if (new Set(values).size !== values.length) {\n throw integrity(`event ${eventId} contains duplicate ${label} values`)\n }\n}\n\nfunction count(value: number, noun: string, predicate: string): string {\n const verb = predicate.replace(/^(has|is) /, (word) =>\n value === 1 ? word : word === 'has ' ? 'have ' : 'are ',\n )\n return `${value} ${value === 1 ? noun : `${noun}s`} ${verb}`\n}\n\nfunction round(usd: number): number {\n return Math.round(usd * 1e6) / 1e6\n}\n\nfunction integrity(message: string): SearchLedgerIntegrityError {\n return new SearchLedgerIntegrityError(message)\n}\n","import type { AgentProfileDiff } from '@tangle-network/agent-interface'\nimport type { EvaluationClaim } from '../experiment/claim'\nimport type { LedgerHash } from '../ledger-core'\n\n/**\n * Schema tag every search-ledger entry carries. A ledger written under another\n * tag, such as the retired `tangle.search-ledger.v1` candidate-slot format, is\n * refused with its tag named; it is never translated.\n */\nexport const SEARCH_LEDGER_SCHEMA = 'tangle.search-ledger.2026-09' as const\n\nexport type SearchLedgerHash = LedgerHash\n\nexport type SearchSurfaceKind =\n | 'prompt'\n | 'tool-contract'\n | 'runtime-config'\n | 'memory'\n | 'knowledge'\n | 'agent-profile'\n | 'code'\n | 'deployment'\n\n/** What a search's nodes are: a mutable agent surface, or an output artifact. */\nexport type SearchArtifactKind = SearchSurfaceKind | 'output'\n\n/** Content-addressed artifact or receipt. Mutable paths are locators only; the\n * digest and byte length bind the exact bytes. */\nexport interface SearchArtifactRef {\n role: string\n uri: string\n sha256: SearchLedgerHash\n byteLength: number\n}\n\n/** Repository, dataset, or package source pinned to an immutable commit or\n * content digest. Branches, tags, and bare package versions are rejected. */\nexport interface SearchSourceRef {\n uri: string\n revision: string\n}\n\n/** A fact the producer does not have, with the reason. Unknown is never 0. */\nexport interface SearchUnknown {\n unknown: string\n}\n\n/** The model an attempt ran: an immutable snapshot, or a moving alias whose\n * served snapshot the producer could not observe. */\nexport type SearchModelIdentity =\n | { provider: string; snapshot: string }\n | { provider: string; alias: string; unknown: string }\n\nexport interface SearchCandidateSurface {\n surfaceId: string\n kind: SearchSurfaceKind\n artifact: SearchArtifactRef\n}\n\nexport type SearchOperationKind =\n | 'candidate-generation'\n | 'analysis'\n | 'selection'\n | 'judge'\n | 'other'\n\n/** train is the proposer's feedback, selection is private to the policy and\n * allocator, and test is sealed for the claim. */\nexport type SearchSplit = 'train' | 'selection' | 'test'\n\nexport interface SearchTask {\n taskId: string\n /** The claim's independent unit this task samples. Repeats and sibling\n * tasks of one unit average inside it before any statistic. */\n unitId: string\n source: SearchSourceRef\n}\n\nexport interface SearchSplitTasks {\n /** `hashCanonical` of `tasks` in taskId order. */\n taskSetDigest: SearchLedgerHash\n tasks: SearchTask[]\n}\n\nexport interface SearchSplits {\n train: SearchSplitTasks\n selection: SearchSplitTasks\n test: SearchSplitTasks\n /**\n * True when no test unit is a train or selection unit. A search that ran\n * with shared units records false, and then its claim cannot ship: a test\n * run of a seen unit measures a fresh run of a seen task, not an\n * improvement on unseen ones.\n */\n heldOutUnits: boolean\n}\n\nexport interface SearchBudget {\n /** Hard dollar cap on committed spend plus open reservations; null = none declared. */\n maxUsd: number | null\n maxCells: number | null\n maxNodes: number | null\n /** ISO time after which the policy stops expanding. */\n deadline: string | null\n maxConcurrency: number | null\n /** Held back at start for the root's and finalists' test cells. */\n reservedClaimUsd: number\n}\n\n/** Where a cell ran relative to the search's decisions. */\nexport type SearchCellStage = 'root' | 'train' | 'screen' | 'rung' | 'claim' | 'external'\n\nexport type SearchEdgeOperator = 'seed' | 'draft' | 'improve' | 'debug' | 'merge' | 'derive'\n\n/**\n * How an edge's parents are known. `explicit`: the proposer that created the\n * child emitted the edge. `correlated`: an importer joined an optimizer's own\n * parent record by content digest. `unknown`: no parent record exists, and the\n * edge has no parents. Nothing is inferred from timing or order.\n */\nexport type SearchEdgeAttribution = 'explicit' | 'correlated' | 'unknown'\n\nexport type SearchProposerKind = NonNullable<AgentProfileDiff['source']>['kind']\n\nexport interface SearchProposer {\n kind: SearchProposerKind\n name: string\n /** The candidate-generation operation that produced the child, when one was recorded. */\n operationId: string | null\n source: SearchSourceRef\n}\n\nexport interface SearchNodeRef {\n searchId: string\n nodeId: string\n}\n\n/** Dollars held for a cell or operation before it runs. `hard`: the lane\n * enforces the maximum. `estimate`: the lane cannot, and overshoot is recorded. */\nexport interface SearchReservation {\n kind: 'hard' | 'estimate'\n usd: number\n}\n\nexport type SearchTokenAccounting =\n | {\n status: 'known'\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n }\n | {\n status: 'unknown'\n reason: string\n }\n\nexport type SearchCostAccounting =\n | {\n status: 'known'\n usd: number\n source: 'provider' | 'pricing-table' | 'free'\n }\n | {\n status: 'unknown'\n /** Proven part of the spend; the total may be higher. */\n knownLowerBoundUsd: number\n reason: string\n }\n\nexport interface SearchAttemptAccounting {\n tokens: SearchTokenAccounting\n cost: SearchCostAccounting\n}\n\nexport interface SearchFailureReason {\n code: string\n message: string\n}\n\n/** `failed` is the agent's defect and carries a score; `errored` is the\n * environment's fault, carries none, and may be retried. */\nexport type SearchTaskOutcome =\n | {\n status: 'passed'\n score: number\n metrics: Record<string, number>\n }\n | {\n status: 'failed'\n score: number\n metrics: Record<string, number>\n failure: SearchFailureReason\n }\n | {\n status: 'errored'\n metrics: Record<string, number>\n error: SearchFailureReason & { retryable: boolean }\n }\n\nexport type SearchSurfaceEffect =\n | {\n status: 'measured'\n metric: string\n baselineValue: number\n candidateValue: number\n delta: number\n }\n | {\n status: 'not-measured'\n reason: string\n }\n\n/** Per-attempt proof that a declared node surface did or did not fire. A\n * surface without evidence is unobserved, not fired. */\nexport interface SearchSurfaceEvidence {\n surfaceId: string\n fired: boolean\n firingCount: number\n effect: SearchSurfaceEffect\n evidence: SearchArtifactRef[]\n}\n\nexport type SearchTraceRef =\n | {\n traceId: string\n execRunId: string | null\n spansWritten: number | null\n spansDropped: number | null\n }\n | SearchUnknown\n\nexport interface SearchExecutionIdentity {\n model: SearchModelIdentity\n agent: SearchSourceRef\n benchmark: SearchSourceRef\n}\n\nexport type SearchEstimateMethod = 'none' | 'insufficient' | 'descriptive' | 'bootstrap'\n\n/**\n * A paired contrast of one node against another on shared units. `none` below\n * 2 pairs, `insufficient` below 6, `descriptive` below 20, `bootstrap` from 20.\n * `estimateNode` computes it; the ledger records the estimate a decision used.\n */\nexport interface NodeEstimate {\n against: string\n split: SearchSplit\n /** Units the node scored on the split. */\n units: number\n /** Units both nodes scored: the paired sample. */\n pairs: number\n /** Mean per-unit difference, node minus `against`, in the metric's units.\n * Null for `none`. */\n delta: number | null\n /** Bootstrap interval on `delta`: spread for `descriptive`, decision grade\n * for `bootstrap`. Null for `none`, `insufficient` and an indeterminate sample. */\n interval: [number, number] | null\n method: SearchEstimateMethod\n /** Exact one-sided sign-test p toward improvement; `descriptive` only. */\n exactSignP: number | null\n /** Every paired delta is equal, so an interval would have zero width and\n * carries no evidence either way. */\n indeterminate: boolean\n /** Digest of the cells read, which also seeds the bootstrap. */\n cellSetDigest: SearchLedgerHash\n estimator: SearchSourceRef\n}\n\nexport type SearchNodeDecision =\n | { status: 'advanced'; rung: number }\n | { status: 'pruned' }\n | { status: 'invalid' }\n | { status: 'finalist' }\n | { status: 'selected' }\n | { status: 'rejected' }\n\nexport type SearchNodeStatus = SearchNodeDecision['status']\n\nexport type SearchCloseReason =\n | 'budget'\n | 'deadline'\n | 'max-nodes'\n | 'patience'\n | 'converged'\n | 'aborted'\n\nexport type SearchCancelReason = 'pruned' | 'budget' | 'deadline' | 'aborted'\n\nexport type SearchClaimPower =\n | {\n adequate: boolean\n minimumEffect: number\n powerAtMinimumEffect: number\n units: number\n }\n | SearchUnknown\n\n/** The claim made once, on the sealed test split. `selected` names the node the\n * search keeps: a finalist on `ship`, the root otherwise (or null when the\n * search keeps nothing). */\nexport interface SearchClaim {\n power: SearchClaimPower\n finalists: Array<{ nodeId: string; estimate: NodeEstimate | null; promote: boolean }>\n selected: string | null\n decision: 'ship' | 'hold' | 'test-cannot-resolve'\n}\n\ninterface SearchLedgerEventBase {\n eventId: string\n occurredAt: string\n artifacts: SearchArtifactRef[]\n}\n\n/** First event, once: what is searched, against what, on which tasks, under which budget. */\nexport interface SearchOpenedEvent extends SearchLedgerEventBase {\n kind: 'search-opened'\n /** What the search improves, for example `vb/coder`. */\n subject: string\n process: { name: string; executionRef: SearchSourceRef }\n artifactKind: SearchArtifactKind\n objective: {\n metric: string\n direction: 'maximize' | 'minimize'\n judge: SearchSourceRef | SearchUnknown\n claim: EvaluationClaim\n }\n splits: SearchSplits\n policy: { expansion: string; allocation: string; seed: number }\n budget: SearchBudget\n /** The cell attempt of another search whose execution runs this one. */\n containment: { searchId: string; cellId: string; attempt: number } | null\n /** The node of another search this one starts from. */\n derivedFrom: { searchId: string; nodeId: string; headHash: SearchLedgerHash } | null\n identity: SearchExecutionIdentity\n}\n\nexport interface SearchOperationStartedEvent extends SearchLedgerEventBase {\n kind: 'operation-started'\n operationId: string\n operationKind: SearchOperationKind\n reservation: SearchReservation | null\n}\n\nexport interface SearchOperationRecordedEvent extends SearchLedgerEventBase {\n kind: 'operation-recorded'\n operationId: string\n operationKind: SearchOperationKind\n execution:\n | {\n kind: 'model'\n model: SearchModelIdentity\n source: SearchSourceRef\n }\n | {\n kind: 'deterministic'\n source: SearchSourceRef\n }\n outcome:\n | { status: 'completed' }\n | { status: 'partial'; failure: SearchFailureReason }\n | { status: 'failed'; failure: SearchFailureReason }\n accounting: SearchAttemptAccounting\n}\n\n/** A content-addressed artifact enters the search. `nodeId` is\n * `searchNodeId(searchId, artifactDigest)`, so a re-proposal of identical\n * content is a second edge into this node, never a second node. */\nexport interface SearchNodeRegisteredEvent extends SearchLedgerEventBase {\n kind: 'node-registered'\n nodeId: string\n artifactDigest: SearchLedgerHash\n artifact: SearchArtifactRef\n surfaces: SearchCandidateSurface[]\n}\n\n/** The proposal that derived a node from its parents. */\nexport interface SearchEdgeRecordedEvent extends SearchLedgerEventBase {\n kind: 'edge-recorded'\n edgeId: string\n childNodeId: string\n /** Primary parent first. Empty for `seed` and for `unknown` attribution; a\n * parent in another search appears only on a `derive` edge. */\n parents: SearchNodeRef[]\n operator: SearchEdgeOperator\n attribution: SearchEdgeAttribution\n /** Null only on a `seed` edge: the search's starting artifact was not proposed. */\n proposer: SearchProposer | null\n /** Why the policy chose these parents. */\n selection: { rule: string; evidence: Record<string, number> } | null\n /** The proposer's redacted rationale. */\n rationale: SearchArtifactRef | SearchUnknown\n /** One diff per parent, parent to child. */\n diffs: Array<SearchArtifactRef | SearchUnknown>\n /** At most 200 characters, redacted. */\n label: string\n}\n\n/** One node on one task in one split at one repeat is planned. `cellId` is\n * `searchCellId(searchId, nodeId, taskId, split, rep)`. */\nexport interface SearchCellAllocatedEvent extends SearchLedgerEventBase {\n kind: 'cell-allocated'\n cellId: string\n nodeId: string\n taskId: string\n unitId: string\n split: SearchSplit\n rep: number\n stage: SearchCellStage\n lane: string | null\n /** Null when no reservation was made: an external optimizer dispatched the cell. */\n reservation: SearchReservation | null\n}\n\n/** One attempt at a cell finished. Its RunRecord, when the producer minted one,\n * is an artifact with role `run-record`. */\nexport interface SearchCellSettledEvent extends SearchLedgerEventBase {\n kind: 'cell-settled'\n cellId: string\n /** Counted from 1 without gaps. */\n attempt: number\n /** `searchCellRunId({ cellId, attempt })`. */\n runId: string\n outcome: SearchTaskOutcome\n accounting: SearchAttemptAccounting\n boxMinutes: number | null\n wallMs: number | null\n queueMs: number | null\n placement: { lane: string; boxId: string | null } | null\n identity: SearchExecutionIdentity\n surfaceEvidence: SearchSurfaceEvidence[]\n traceRef: SearchTraceRef\n}\n\nexport interface SearchCellCancelledEvent extends SearchLedgerEventBase {\n kind: 'cell-cancelled'\n cellId: string\n reason: SearchCancelReason\n}\n\n/** A policy, allocator or claim decision about a node. May repeat; the latest wins. */\nexport interface SearchNodeDecidedEvent extends SearchLedgerEventBase {\n kind: 'node-decided'\n nodeId: string\n decision: SearchNodeDecision\n basis: NodeEstimate | null\n rule: string\n reason: string\n}\n\n/** Last event, once. More work on a closed search is a derived search. */\nexport interface SearchClosedEvent extends SearchLedgerEventBase {\n kind: 'search-closed'\n reason: SearchCloseReason\n claim: SearchClaim | null\n}\n\nexport type SearchLedgerEvent =\n | SearchOpenedEvent\n | SearchOperationStartedEvent\n | SearchOperationRecordedEvent\n | SearchNodeRegisteredEvent\n | SearchEdgeRecordedEvent\n | SearchCellAllocatedEvent\n | SearchCellSettledEvent\n | SearchCellCancelledEvent\n | SearchNodeDecidedEvent\n | SearchClosedEvent\n\nexport interface SearchLedgerEntry {\n schema: typeof SEARCH_LEDGER_SCHEMA\n searchId: string\n sequence: number\n previousHash: SearchLedgerHash | null\n event: SearchLedgerEvent\n entryHash: SearchLedgerHash\n}\n\n/** Counts and sums over the whole search. Every field is a number or a short\n * scalar, so reading the audit costs the same at any search size. */\nexport interface SearchAudit {\n searchId: string\n eventCount: number\n headHash: SearchLedgerHash | null\n status: 'open' | 'closed'\n closeReason: SearchCloseReason | null\n nodes: number\n /** Nodes with no edge yet: not placed in the tree. */\n nodesWithoutEdge: number\n /** Nodes whose latest decision is missing or `advanced`. */\n undecidedNodes: number\n selectedNodeId: string | null\n edges: { explicit: number; correlated: number; unknown: number; reproposals: number }\n cells: { allocated: number; settled: number; cancelled: number; open: number }\n attempts: number\n outcomes: { passed: number; failed: number; errored: number }\n operations: { started: number; recorded: number; open: number }\n spend: {\n /** Sum of known cell and operation costs. */\n knownUsd: number\n /** Sum of the proven lower bounds of unknown costs. */\n floorUsd: number\n unknownCostCells: number\n unknownCostOperations: number\n /** knownUsd + floorUsd. */\n committedUsd: number\n /** Reservations of unsettled cells and unrecorded operations, net of their spend so far. */\n openReservationUsd: number\n /** Spend above reservations. */\n overspendUsd: number\n /** Settled cells that ran without a reservation. */\n unreservedCells: number\n boxMinutes: number\n }\n tokens: {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n unknownTokenAttempts: number\n }\n}\n","/**\n * Durable, append-only event log of one search: nodes (content-addressed\n * artifacts), edges (the proposals that derived them), cells (one run of one\n * node on one task), operations, decisions, and the claim.\n *\n * The ledger is the search's only lineage record and its only resume\n * checkpoint. A RunRecord owns one measured run and `CostLedger` owns per-call\n * accounting; this ledger binds them by digest instead of copying them.\n *\n * The file format is canonical JSONL with a SHA-256 hash chain. Every append is\n * serialized across processes, fsynced before acknowledgement, and idempotent\n * by `eventId`. A malformed, non-canonical, truncated, reordered, or conflicting\n * log fails loudly; a bad row is never skipped. A ledger written under another\n * schema tag is refused with that tag named, never translated.\n *\n * The journal machinery is the generic `ledger-core` journal. This module is\n * the search codec: event schemas and canonical ordering. `SearchState` is the\n * state machine and read model.\n */\n\nimport { z } from 'zod'\nimport { evaluationClaimSchema } from '../experiment/claim'\nimport {\n canonicalString,\n FileLedgerJournal,\n hashCanonical,\n type LedgerJournalCodec,\n type LedgerLineContext,\n type LedgerTextStore,\n type LedgerTrustedHead,\n type LedgerTrustedHeadRemoval,\n MemoryLedgerJournal,\n replayLedgerText,\n} from '../ledger-core'\nimport { modelHasSnapshot } from '../run-record'\nimport {\n SearchLedgerConflictError,\n SearchLedgerError,\n SearchLedgerIntegrityError,\n} from './search-ledger-errors'\nimport { SEARCH_LEDGER_FILE_CONTEXT } from './search-ledger-file'\nimport { artifactKey, compareStrings } from './search-ledger-ordering'\nimport {\n SEARCH_LEDGER_SCHEMA,\n type SearchArtifactRef,\n type SearchLedgerEntry,\n type SearchLedgerEvent,\n type SearchTask,\n} from './search-ledger-types'\nimport { SearchState, type SearchStateView } from './search-state'\n\nexport { SearchLedgerConflictError, SearchLedgerError, SearchLedgerIntegrityError }\n\nconst NON_EMPTY = z\n .string()\n .min(1)\n .refine((value) => value.trim() === value, 'must not contain surrounding whitespace')\n\nconst HASH = z.string().regex(/^sha256:[a-f0-9]{64}$/)\n\nconst IMMUTABLE_REVISION = z\n .string()\n .regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64}|sha256:[a-f0-9]{64}|sha512:[A-Za-z0-9+/=]+)$/)\n\nconst ISO_TIMESTAMP = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/)\n .refine((value) => Number.isFinite(Date.parse(value)), 'invalid timestamp')\n\nconst NON_NEGATIVE_INT = z.number().int().nonnegative().safe()\nconst POSITIVE_INT = z.number().int().positive().safe()\nconst FINITE_NUMBER = z.number().finite()\nconst USD = z.number().finite().nonnegative()\n\nconst NODE_ID = z.string().regex(/^node_[a-f0-9]{32}$/)\nconst CELL_ID = z.string().regex(/^cell_[a-f0-9]{32}$/)\n\nconst ArtifactRefSchema = z\n .object({ role: NON_EMPTY, uri: NON_EMPTY, sha256: HASH, byteLength: NON_NEGATIVE_INT })\n .strict()\n\nconst SourceRefSchema = z.object({ uri: NON_EMPTY, revision: IMMUTABLE_REVISION }).strict()\n\nconst UnknownRefSchema = z.object({ unknown: NON_EMPTY }).strict()\n\nconst FailureReasonSchema = z.object({ code: NON_EMPTY, message: NON_EMPTY }).strict()\n\nconst ModelIdentitySchema = z.union([\n z\n .object({\n provider: NON_EMPTY,\n snapshot: NON_EMPTY.refine(modelHasSnapshot, 'model must include an immutable snapshot'),\n })\n .strict(),\n z.object({ provider: NON_EMPTY, alias: NON_EMPTY, unknown: NON_EMPTY }).strict(),\n])\n\nconst ExecutionIdentitySchema = z\n .object({ model: ModelIdentitySchema, agent: SourceRefSchema, benchmark: SourceRefSchema })\n .strict()\n\nconst SURFACE_KINDS = [\n 'prompt',\n 'tool-contract',\n 'runtime-config',\n 'memory',\n 'knowledge',\n 'agent-profile',\n 'code',\n 'deployment',\n] as const\n\nconst SPLIT = z.enum(['train', 'selection', 'test'])\n\nconst ReservationSchema = z.object({ kind: z.enum(['hard', 'estimate']), usd: USD }).strict()\n\nconst EventBaseShape = {\n eventId: NON_EMPTY,\n occurredAt: ISO_TIMESTAMP,\n artifacts: z.array(ArtifactRefSchema),\n}\n\nconst OperationKindSchema = z.enum([\n 'candidate-generation',\n 'analysis',\n 'selection',\n 'judge',\n 'other',\n])\n\nconst KnownTokensSchema = z\n .object({\n status: z.literal('known'),\n inputTokens: NON_NEGATIVE_INT,\n outputTokens: NON_NEGATIVE_INT,\n cachedTokens: NON_NEGATIVE_INT,\n })\n .strict()\n\nconst UnknownTokensSchema = z.object({ status: z.literal('unknown'), reason: NON_EMPTY }).strict()\n\nconst KnownCostSchema = z\n .object({\n status: z.literal('known'),\n usd: USD,\n source: z.enum(['provider', 'pricing-table', 'free']),\n })\n .strict()\n .superRefine((cost, ctx) => {\n if (cost.source === 'free' && cost.usd !== 0) {\n ctx.addIssue({ code: 'custom', message: 'free cost source must have usd 0' })\n }\n })\n\nconst UnknownCostSchema = z\n .object({ status: z.literal('unknown'), knownLowerBoundUsd: USD, reason: NON_EMPTY })\n .strict()\n\nconst AccountingSchema = z\n .object({\n tokens: z.discriminatedUnion('status', [KnownTokensSchema, UnknownTokensSchema]),\n cost: z.discriminatedUnion('status', [KnownCostSchema, UnknownCostSchema]),\n })\n .strict()\n\nconst MetricsSchema = z.record(NON_EMPTY, FINITE_NUMBER).superRefine((metrics, ctx) => {\n for (const key of Object.keys(metrics)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n ctx.addIssue({ code: 'custom', message: `unsafe metric key ${key}` })\n }\n }\n})\n\nconst OutcomeSchema = z.discriminatedUnion('status', [\n z.object({ status: z.literal('passed'), score: FINITE_NUMBER, metrics: MetricsSchema }).strict(),\n z\n .object({\n status: z.literal('failed'),\n score: FINITE_NUMBER,\n metrics: MetricsSchema,\n failure: FailureReasonSchema,\n })\n .strict(),\n z\n .object({\n status: z.literal('errored'),\n metrics: MetricsSchema,\n error: FailureReasonSchema.extend({ retryable: z.boolean() }).strict(),\n })\n .strict(),\n])\n\nconst EffectSchema = z.discriminatedUnion('status', [\n z\n .object({\n status: z.literal('measured'),\n metric: NON_EMPTY,\n baselineValue: FINITE_NUMBER,\n candidateValue: FINITE_NUMBER,\n delta: FINITE_NUMBER,\n })\n .strict()\n .superRefine((effect, ctx) => {\n const expected = effect.candidateValue - effect.baselineValue\n const tolerance = Number.EPSILON * Math.max(1, Math.abs(expected), Math.abs(effect.delta)) * 8\n if (Math.abs(effect.delta - expected) > tolerance) {\n ctx.addIssue({ code: 'custom', message: 'delta must equal candidateValue - baselineValue' })\n }\n }),\n z.object({ status: z.literal('not-measured'), reason: NON_EMPTY }).strict(),\n])\n\nconst SurfaceEvidenceSchema = z\n .object({\n surfaceId: NON_EMPTY,\n fired: z.boolean(),\n firingCount: NON_NEGATIVE_INT,\n effect: EffectSchema,\n evidence: z.array(ArtifactRefSchema).min(1),\n })\n .strict()\n .superRefine((evidence, ctx) => {\n if (evidence.fired !== evidence.firingCount > 0) {\n ctx.addIssue({ code: 'custom', message: 'fired must equal firingCount > 0' })\n }\n if (!evidence.fired && evidence.effect.status === 'measured' && evidence.effect.delta !== 0) {\n ctx.addIssue({ code: 'custom', message: 'a surface that did not fire has no effect' })\n }\n })\n\nconst TaskSchema = z\n .object({ taskId: NON_EMPTY, unitId: NON_EMPTY, source: SourceRefSchema })\n .strict()\n\nconst SplitTasksSchema = z.object({ taskSetDigest: HASH, tasks: z.array(TaskSchema) }).strict()\n\nconst SearchOpenedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('search-opened'),\n subject: NON_EMPTY,\n process: z.object({ name: NON_EMPTY, executionRef: SourceRefSchema }).strict(),\n artifactKind: z.enum([...SURFACE_KINDS, 'output']),\n objective: z\n .object({\n metric: NON_EMPTY,\n direction: z.enum(['maximize', 'minimize']),\n judge: z.union([SourceRefSchema, UnknownRefSchema]),\n claim: evaluationClaimSchema,\n })\n .strict(),\n splits: z\n .object({\n train: SplitTasksSchema,\n selection: SplitTasksSchema,\n test: SplitTasksSchema,\n heldOutUnits: z.boolean(),\n })\n .strict(),\n policy: z\n .object({ expansion: NON_EMPTY, allocation: NON_EMPTY, seed: z.number().int().safe() })\n .strict(),\n budget: z\n .object({\n maxUsd: USD.nullable(),\n maxCells: POSITIVE_INT.nullable(),\n maxNodes: POSITIVE_INT.nullable(),\n deadline: ISO_TIMESTAMP.nullable(),\n maxConcurrency: POSITIVE_INT.nullable(),\n reservedClaimUsd: USD,\n })\n .strict(),\n containment: z\n .object({ searchId: NON_EMPTY, cellId: CELL_ID, attempt: POSITIVE_INT })\n .strict()\n .nullable(),\n derivedFrom: z\n .object({ searchId: NON_EMPTY, nodeId: NODE_ID, headHash: HASH })\n .strict()\n .nullable(),\n identity: ExecutionIdentitySchema,\n })\n .strict()\n\nconst OperationStartedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('operation-started'),\n operationId: NON_EMPTY,\n operationKind: OperationKindSchema,\n reservation: ReservationSchema.nullable(),\n })\n .strict()\n\nconst OperationRecordedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('operation-recorded'),\n operationId: NON_EMPTY,\n operationKind: OperationKindSchema,\n execution: z.discriminatedUnion('kind', [\n z\n .object({ kind: z.literal('model'), model: ModelIdentitySchema, source: SourceRefSchema })\n .strict(),\n z.object({ kind: z.literal('deterministic'), source: SourceRefSchema }).strict(),\n ]),\n outcome: z.discriminatedUnion('status', [\n z.object({ status: z.literal('completed') }).strict(),\n z.object({ status: z.literal('partial'), failure: FailureReasonSchema }).strict(),\n z.object({ status: z.literal('failed'), failure: FailureReasonSchema }).strict(),\n ]),\n accounting: AccountingSchema,\n })\n .strict()\n\nconst NodeRegisteredSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('node-registered'),\n nodeId: NODE_ID,\n artifactDigest: HASH,\n artifact: ArtifactRefSchema,\n surfaces: z.array(\n z\n .object({ surfaceId: NON_EMPTY, kind: z.enum(SURFACE_KINDS), artifact: ArtifactRefSchema })\n .strict(),\n ),\n })\n .strict()\n\nconst NodeRefSchema = z.object({ searchId: NON_EMPTY, nodeId: NODE_ID }).strict()\n\nconst ArtifactOrUnknownSchema = z.union([ArtifactRefSchema, UnknownRefSchema])\n\nconst EdgeRecordedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('edge-recorded'),\n edgeId: z.string().regex(/^edge_[a-f0-9]{32}$/),\n childNodeId: NODE_ID,\n parents: z.array(NodeRefSchema),\n operator: z.enum(['seed', 'draft', 'improve', 'debug', 'merge', 'derive']),\n attribution: z.enum(['explicit', 'correlated', 'unknown']),\n proposer: z\n .object({\n kind: z.enum(['trace', 'frontier-author', 'human', 'optimizer', 'compound']),\n name: NON_EMPTY,\n operationId: NON_EMPTY.nullable(),\n source: SourceRefSchema,\n })\n .strict()\n .nullable(),\n selection: z\n .object({ rule: NON_EMPTY, evidence: z.record(NON_EMPTY, FINITE_NUMBER) })\n .strict()\n .nullable(),\n rationale: ArtifactOrUnknownSchema,\n diffs: z.array(ArtifactOrUnknownSchema),\n label: z.string(),\n })\n .strict()\n\nconst CellAllocatedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-allocated'),\n cellId: CELL_ID,\n nodeId: NODE_ID,\n taskId: NON_EMPTY,\n unitId: NON_EMPTY,\n split: SPLIT,\n rep: NON_NEGATIVE_INT,\n stage: z.enum(['root', 'train', 'screen', 'rung', 'claim', 'external']),\n lane: NON_EMPTY.nullable(),\n reservation: ReservationSchema.nullable(),\n })\n .strict()\n\nconst TraceRefSchema = z.union([\n z\n .object({\n traceId: NON_EMPTY,\n execRunId: NON_EMPTY.nullable(),\n spansWritten: NON_NEGATIVE_INT.nullable(),\n spansDropped: NON_NEGATIVE_INT.nullable(),\n })\n .strict(),\n UnknownRefSchema,\n])\n\nconst NON_NEGATIVE = z.number().finite().nonnegative()\n\nconst CellSettledSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-settled'),\n cellId: CELL_ID,\n attempt: POSITIVE_INT,\n runId: NON_EMPTY,\n outcome: OutcomeSchema,\n accounting: AccountingSchema,\n boxMinutes: NON_NEGATIVE.nullable(),\n wallMs: NON_NEGATIVE.nullable(),\n queueMs: NON_NEGATIVE.nullable(),\n placement: z.object({ lane: NON_EMPTY, boxId: NON_EMPTY.nullable() }).strict().nullable(),\n identity: ExecutionIdentitySchema,\n surfaceEvidence: z.array(SurfaceEvidenceSchema),\n traceRef: TraceRefSchema,\n })\n .strict()\n\nconst CellCancelledSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-cancelled'),\n cellId: CELL_ID,\n reason: z.enum(['pruned', 'budget', 'deadline', 'aborted']),\n })\n .strict()\n\nconst NodeEstimateSchema = z\n .object({\n against: NODE_ID,\n split: SPLIT,\n units: NON_NEGATIVE_INT,\n pairs: NON_NEGATIVE_INT,\n delta: FINITE_NUMBER.nullable(),\n interval: z.tuple([FINITE_NUMBER, FINITE_NUMBER]).nullable(),\n method: z.enum(['none', 'insufficient', 'descriptive', 'bootstrap']),\n exactSignP: z.number().min(0).max(1).nullable(),\n indeterminate: z.boolean(),\n cellSetDigest: HASH,\n estimator: SourceRefSchema,\n })\n .strict()\n\nconst NodeDecidedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('node-decided'),\n nodeId: NODE_ID,\n decision: z.discriminatedUnion('status', [\n z.object({ status: z.literal('advanced'), rung: NON_NEGATIVE_INT }).strict(),\n z.object({ status: z.literal('pruned') }).strict(),\n z.object({ status: z.literal('invalid') }).strict(),\n z.object({ status: z.literal('finalist') }).strict(),\n z.object({ status: z.literal('selected') }).strict(),\n z.object({ status: z.literal('rejected') }).strict(),\n ]),\n basis: NodeEstimateSchema.nullable(),\n rule: NON_EMPTY,\n reason: NON_EMPTY,\n })\n .strict()\n\nconst SearchClosedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('search-closed'),\n reason: z.enum(['budget', 'deadline', 'max-nodes', 'patience', 'converged', 'aborted']),\n claim: z\n .object({\n power: z.union([\n z\n .object({\n adequate: z.boolean(),\n minimumEffect: z.number().finite().positive(),\n powerAtMinimumEffect: z.number().min(0).max(1),\n units: NON_NEGATIVE_INT,\n })\n .strict(),\n UnknownRefSchema,\n ]),\n finalists: z.array(\n z\n .object({\n nodeId: NODE_ID,\n estimate: NodeEstimateSchema.nullable(),\n promote: z.boolean(),\n })\n .strict(),\n ),\n selected: NODE_ID.nullable(),\n decision: z.enum(['ship', 'hold', 'test-cannot-resolve']),\n })\n .strict()\n .nullable(),\n })\n .strict()\n\nconst EventSchema = z.discriminatedUnion('kind', [\n SearchOpenedSchema,\n OperationStartedSchema,\n OperationRecordedSchema,\n NodeRegisteredSchema,\n EdgeRecordedSchema,\n CellAllocatedSchema,\n CellSettledSchema,\n CellCancelledSchema,\n NodeDecidedSchema,\n SearchClosedSchema,\n])\n\nconst EntrySchema = z\n .object({\n schema: z.literal(SEARCH_LEDGER_SCHEMA),\n searchId: NON_EMPTY,\n sequence: NON_NEGATIVE_INT,\n previousHash: z.union([HASH, z.null()]),\n event: EventSchema,\n entryHash: HASH,\n })\n .strict()\n\n/** Validate and return a canonical copy. Arrays whose order carries no meaning\n * are sorted, so retries from different processes produce identical bytes. */\nexport function validateSearchLedgerEvent(input: unknown): SearchLedgerEvent {\n const parsed = EventSchema.safeParse(input)\n if (!parsed.success) {\n throw new SearchLedgerError(`invalid search ledger event: ${formatZodError(parsed.error)}`)\n }\n return normalizeEvent(parsed.data as SearchLedgerEvent)\n}\n\n/**\n * How this ledger uses its trusted head — the `(sequence, entryHash)` pin kept\n * in the sibling `<path>.head` file that a hash chain needs to prove entries\n * were not deleted from the end. `ledger-core/trusted-head.ts` holds the threat\n * model.\n *\n * - `pin` (default): every append records the new head, and a pin that is\n * present is verified on every read.\n * - `require`: additionally refuses to read a non-empty ledger whose pin is\n * gone, so deleting the sibling file cannot downgrade the guarantee.\n * - `off`: chain verification only. Truncation to a valid shorter prefix is\n * undetectable.\n */\nexport type SearchLedgerTrustedHeadMode = 'pin' | 'require' | 'off'\n\nexport interface OpenSearchLedgerOptions {\n path: string\n searchId: string\n trustedHead?: SearchLedgerTrustedHeadMode\n /**\n * Keep the ledger's text in this in-process store instead of a file, for a\n * run without a filesystem (an in-memory `CampaignStorage`, keyed by `path`).\n * The chain, parse and state rules are the file ledger's; there is no lock,\n * fsync or trusted head, and the ledger lives as long as the store.\n */\n store?: LedgerTextStore\n}\n\nexport interface SearchLedgerAppendResult {\n entry: SearchLedgerEntry\n /** False when the exact event was already durably present. */\n appended: boolean\n state: SearchStateView\n}\n\nexport interface SearchLedger {\n readonly path: string\n readonly searchId: string\n /** Sibling file holding this ledger's trusted head. */\n readonly trustedHeadPath: string\n append(event: SearchLedgerEvent): Promise<SearchLedgerAppendResult>\n /** The verified state at the file's current head. */\n state(): Promise<SearchStateView>\n /** The pinned head, or null when this ledger has never been pinned. */\n trustedHead(): Promise<LedgerTrustedHead | null>\n /** Pin the current verified head without rewriting a byte. */\n pinTrustedHead(): Promise<LedgerTrustedHead>\n /** Discard this ledger's pin, reporting what was discarded. It gives up the\n * deletion guarantee for every entry the pin covered. */\n clearTrustedHead(): Promise<LedgerTrustedHeadRemoval>\n}\n\n/** Open a durable filesystem search ledger. Construction performs no I/O; the\n * first `append` or `state` verifies the whole existing file. */\nexport function openSearchLedger(options: OpenSearchLedgerOptions): SearchLedger {\n if (options.store) return new MemorySearchLedger(options.path, options.searchId, options.store)\n return new FileSearchLedger(options.path, options.searchId, options.trustedHead)\n}\n\n/** Verify and project immutable search-ledger JSONL through the same codec as\n * `FileSearchLedger`. */\nexport function replaySearchLedgerText(\n text: string,\n searchId: string,\n source: string,\n): SearchStateView {\n return replayLedgerText(text, source, searchLedgerCodec(searchId))\n}\n\n/**\n * Verify one stored ledger line in isolation: the schema tag, the entry and\n * event schemas, canonical bytes, the entry's own hash, and its search. The\n * chain (sequence and previous hash) and the state machine are the caller's,\n * because they need the lines before this one. An ingest server runs this on\n * every received line, so it hashes exactly the bytes the producer hashed.\n */\nexport function parseSearchLedgerLine(\n line: string,\n searchId: string,\n context: LedgerLineContext,\n): SearchLedgerEntry {\n let raw: unknown\n try {\n raw = JSON.parse(line)\n } catch (error) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has invalid JSON at line ${context.line}`,\n { cause: error },\n )\n }\n const entry = parseSearchLedgerEntry(raw, context)\n if (entry.searchId !== searchId) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} belongs to search ${entry.searchId}, expected ${searchId}`,\n )\n }\n if (canonicalString(entry) !== line) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has non-canonical bytes at line ${context.line}`,\n )\n }\n const { entryHash, ...material } = entry\n const expected = hashCanonical(material)\n if (entryHash !== expected) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} hash mismatch: expected ${expected}, got ${entryHash}`,\n )\n }\n return entry\n}\n\ninterface SearchLedgerHeader {\n schema: typeof SEARCH_LEDGER_SCHEMA\n searchId: string\n}\n\nfunction searchLedgerCodec(\n searchId: string,\n): LedgerJournalCodec<SearchLedgerHeader, SearchLedgerEvent, SearchStateView> {\n return {\n ...SEARCH_LEDGER_FILE_CONTEXT,\n header: { schema: SEARCH_LEDGER_SCHEMA, searchId },\n conflictError: (message) => new SearchLedgerConflictError(message),\n parseEntry: parseSearchLedgerEntry,\n checkEntryHeader: (entry, index) => {\n if (entry.searchId !== searchId) {\n throw new SearchLedgerIntegrityError(\n `entry ${index} belongs to search ${entry.searchId}, expected ${searchId}`,\n )\n }\n },\n createProjector: () => new SearchState(searchId),\n }\n}\n\n/** Append-only file-backed search ledger with idempotent writes. */\nexport class FileSearchLedger implements SearchLedger {\n readonly path: string\n readonly searchId: string\n readonly trustedHeadPath: string\n private readonly trustedHeadMode: SearchLedgerTrustedHeadMode\n private readonly journal: FileLedgerJournal<\n SearchLedgerHeader,\n SearchLedgerEvent,\n SearchStateView\n >\n\n constructor(path: string, searchId: string, trustedHead: SearchLedgerTrustedHeadMode = 'pin') {\n if (path.trim().length === 0) throw new SearchLedgerError('ledger path is empty')\n if (searchId.length === 0 || searchId.trim() !== searchId) {\n throw new SearchLedgerError('searchId must be non-empty without surrounding whitespace')\n }\n this.searchId = searchId\n this.trustedHeadMode = trustedHead\n this.journal = new FileLedgerJournal(path, searchLedgerCodec(searchId), {\n requireTrustedHead: trustedHead === 'require',\n })\n this.path = this.journal.path\n this.trustedHeadPath = this.journal.trustedHeadPath\n }\n\n async state(): Promise<SearchStateView> {\n return this.journal.replay()\n }\n\n async append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult> {\n // Normalize before the journal hashes the event so retries from different\n // processes produce byte-identical entries.\n const event = validateSearchLedgerEvent(input)\n const { entry, appended, projection } = await this.journal.append(event, {\n pinHead: this.trustedHeadMode !== 'off',\n })\n return { entry, appended, state: projection }\n }\n\n async trustedHead(): Promise<LedgerTrustedHead | null> {\n return this.journal.trustedHead()\n }\n\n async pinTrustedHead(): Promise<LedgerTrustedHead> {\n return this.journal.pinTrustedHead()\n }\n\n async clearTrustedHead(): Promise<LedgerTrustedHeadRemoval> {\n return this.journal.clearTrustedHead()\n }\n}\n\n/** A search ledger held in an in-process text store. */\nclass MemorySearchLedger implements SearchLedger {\n readonly path: string\n readonly searchId: string\n readonly trustedHeadPath: string\n private readonly journal: MemoryLedgerJournal<\n SearchLedgerHeader,\n SearchLedgerEvent,\n SearchStateView\n >\n\n constructor(path: string, searchId: string, store: LedgerTextStore) {\n if (path.trim().length === 0) throw new SearchLedgerError('ledger path is empty')\n if (searchId.length === 0 || searchId.trim() !== searchId) {\n throw new SearchLedgerError('searchId must be non-empty without surrounding whitespace')\n }\n this.path = path\n this.searchId = searchId\n this.trustedHeadPath = `${path}.head`\n this.journal = new MemoryLedgerJournal(path, searchLedgerCodec(searchId), store)\n }\n\n async state(): Promise<SearchStateView> {\n return this.journal.replay()\n }\n\n async append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult> {\n const { entry, appended, projection } = await this.journal.append(\n validateSearchLedgerEvent(input),\n )\n return { entry, appended, state: projection }\n }\n\n async trustedHead(): Promise<LedgerTrustedHead | null> {\n return null\n }\n\n async pinTrustedHead(): Promise<LedgerTrustedHead> {\n throw new SearchLedgerError(\n `search ledger ${this.path} is held in memory; a trusted head protects only a file`,\n )\n }\n\n async clearTrustedHead(): Promise<LedgerTrustedHeadRemoval> {\n return { removed: false }\n }\n}\n\nfunction parseSearchLedgerEntry(raw: unknown, context: LedgerLineContext): SearchLedgerEntry {\n const schema = (raw as { schema?: unknown } | null)?.schema\n if (schema !== SEARCH_LEDGER_SCHEMA) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} was written under schema ${JSON.stringify(schema)}; this version reads only ${SEARCH_LEDGER_SCHEMA} and does not translate other formats`,\n )\n }\n const parsed = EntrySchema.safeParse(raw)\n if (!parsed.success) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has a malformed entry at line ${context.line}: ${formatZodError(parsed.error)}`,\n )\n }\n const entry = parsed.data as SearchLedgerEntry\n const normalizedEvent = validateSearchLedgerEvent(entry.event)\n if (canonicalString(normalizedEvent) !== canonicalString(entry.event)) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has non-canonical event ordering at line ${context.line}`,\n )\n }\n return entry\n}\n\nfunction normalizeEvent(event: SearchLedgerEvent): SearchLedgerEvent {\n const artifacts = sortArtifacts(event.artifacts)\n switch (event.kind) {\n case 'search-opened':\n return {\n ...event,\n artifacts,\n splits: {\n ...event.splits,\n train: { ...event.splits.train, tasks: sortTasks(event.splits.train.tasks) },\n selection: { ...event.splits.selection, tasks: sortTasks(event.splits.selection.tasks) },\n test: { ...event.splits.test, tasks: sortTasks(event.splits.test.tasks) },\n },\n }\n case 'node-registered':\n return {\n ...event,\n artifacts,\n surfaces: [...event.surfaces].sort((a, b) => compareStrings(a.surfaceId, b.surfaceId)),\n }\n case 'cell-settled':\n return {\n ...event,\n artifacts,\n surfaceEvidence: [...event.surfaceEvidence]\n .map((evidence) => ({ ...evidence, evidence: sortArtifacts(evidence.evidence) }))\n .sort((a, b) => compareStrings(a.surfaceId, b.surfaceId)),\n }\n default:\n return { ...event, artifacts }\n }\n}\n\nfunction sortTasks(tasks: SearchTask[]): SearchTask[] {\n return [...tasks].sort((a, b) => compareStrings(a.taskId, b.taskId))\n}\n\nfunction sortArtifacts(artifacts: SearchArtifactRef[]): SearchArtifactRef[] {\n return [...artifacts].sort((a, b) => compareStrings(artifactKey(a), artifactKey(b)))\n}\n\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.length > 0 ? issue.path.join('.') : '<root>'}: ${issue.message}`)\n .join('; ')\n}\n\nexport type * from './search-ledger-types'\nexport { SEARCH_LEDGER_SCHEMA }\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-ledger-types-C9anU2DX.d.ts","names":[],"sources":["../src/campaign/search-ledger-types.ts"],"mappings":"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"}