@tangle-network/agent-eval 0.207.4 → 0.209.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/{agent-profile-CEhxR_I3.d.ts → agent-profile-BGyt2z8U.d.ts} +3 -3
- package/dist/{agent-profile-CEhxR_I3.d.ts.map → agent-profile-BGyt2z8U.d.ts.map} +1 -1
- package/dist/{agent-profile-cell-BHcB-mZX.d.ts → agent-profile-cell-BNp-Js9F.d.ts} +2 -3
- package/dist/agent-profile-cell-BNp-Js9F.d.ts.map +1 -0
- package/dist/{agent-profile-cell-DcFW4vOc.js → agent-profile-cell-BYc0bxsL.js} +2 -2
- package/dist/agent-profile-cell-BYc0bxsL.js.map +1 -0
- package/dist/analyst/index.d.ts +12 -12
- package/dist/analyst/index.js +5 -5
- package/dist/{analyze-runs-GZ0VSwui.js → analyze-runs-0cdYMgob.js} +5 -5
- package/dist/{analyze-runs-GZ0VSwui.js.map → analyze-runs-0cdYMgob.js.map} +1 -1
- package/dist/{analyze-runs-CTJyUplR.d.ts → analyze-runs-BlslTkOJ.d.ts} +4 -4
- package/dist/{analyze-runs-CTJyUplR.d.ts.map → analyze-runs-BlslTkOJ.d.ts.map} +1 -1
- package/dist/{benchmark-command-DiFof9bz.js → benchmark-command-Cve7mHNC.js} +8 -8
- package/dist/{benchmark-command-DiFof9bz.js.map → benchmark-command-Cve7mHNC.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +5 -7
- package/dist/benchmarks/index.d.ts.map +1 -1
- package/dist/benchmarks/index.js +4 -4
- package/dist/builder-eval/index.js +1 -1
- package/dist/campaign/index.d.ts +7 -7
- package/dist/campaign/index.js +10 -10
- package/dist/{campaign-B8MqboM0.js → campaign-CvhmiLKa.js} +15 -15
- package/dist/{campaign-B8MqboM0.js.map → campaign-CvhmiLKa.js.map} +1 -1
- package/dist/{campaign-evidence-DW3Krxov.js → campaign-evidence-B5qsCHEn.js} +3 -3
- package/dist/{campaign-evidence-DW3Krxov.js.map → campaign-evidence-B5qsCHEn.js.map} +1 -1
- package/dist/cli.js +7 -7
- package/dist/contract/index.d.ts +9 -9
- package/dist/contract/index.js +8 -8
- package/dist/{default-registry-DZFWY2_E.d.ts → default-registry-Crk3QEy1.d.ts} +6 -6
- package/dist/{default-registry-DZFWY2_E.d.ts.map → default-registry-Crk3QEy1.d.ts.map} +1 -1
- package/dist/{default-registry-DX5R7_n9.js → default-registry-DF4Yp7HQ.js} +2 -2
- package/dist/{default-registry-DX5R7_n9.js.map → default-registry-DF4Yp7HQ.js.map} +1 -1
- package/dist/{define-agent-eval-BpRdb_Oa.js → define-agent-eval-Csd47ur_.js} +8 -8
- package/dist/{define-agent-eval-BpRdb_Oa.js.map → define-agent-eval-Csd47ur_.js.map} +1 -1
- package/dist/{define-agent-eval-Bmc4AYiB.d.ts → define-agent-eval-_nyV5nev.d.ts} +7 -7
- package/dist/{define-agent-eval-Bmc4AYiB.d.ts.map → define-agent-eval-_nyV5nev.d.ts.map} +1 -1
- package/dist/diagnosis/index.d.ts +2 -5
- package/dist/diagnosis/index.d.ts.map +1 -1
- package/dist/diagnosis/index.js +2 -26
- package/dist/diagnosis/index.js.map +1 -1
- package/dist/{dspy-rlm-engine-AJqjFUUr.js → dspy-rlm-engine-BpaKVKJA.js} +3 -3
- package/dist/{dspy-rlm-engine-AJqjFUUr.js.map → dspy-rlm-engine-BpaKVKJA.js.map} +1 -1
- package/dist/{engine-DProXJ7A.d.ts → engine-D-YZ32ZJ.d.ts} +5 -12
- package/dist/engine-D-YZ32ZJ.d.ts.map +1 -0
- package/dist/{eval-campaign-DU_p8qVt.js → eval-campaign-C31Qbv77.js} +4 -4
- package/dist/{eval-campaign-DU_p8qVt.js.map → eval-campaign-C31Qbv77.js.map} +1 -1
- package/dist/evaluation.d.ts +2 -2
- package/dist/{exact-types-Cq6xXNVR.d.ts → exact-types-DjhfZglz.d.ts} +2 -2
- package/dist/{exact-types-Cq6xXNVR.d.ts.map → exact-types-DjhfZglz.d.ts.map} +1 -1
- package/dist/experiment/index.d.ts +2 -2
- package/dist/experiment/index.js +5 -5
- package/dist/{external-optimizer-process-Bemjoy8y.js → external-optimizer-process-D2Txd-7D.js} +2 -2
- package/dist/{external-optimizer-process-Bemjoy8y.js.map → external-optimizer-process-D2Txd-7D.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-d_EQrcTS.js → external-optimizer-subprocess-C0EsxEbI.js} +11 -3
- package/dist/{external-optimizer-subprocess-d_EQrcTS.js.map → external-optimizer-subprocess-C0EsxEbI.js.map} +1 -1
- package/dist/{feedback-trajectory-C6Z8PRoF.d.ts → feedback-trajectory-CX01700m.d.ts} +3 -3
- package/dist/{feedback-trajectory-C6Z8PRoF.d.ts.map → feedback-trajectory-CX01700m.d.ts.map} +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/{index-LAFht3x_.d.ts → index-BHh9Z9El.d.ts} +9 -9
- package/dist/{index-LAFht3x_.d.ts.map → index-BHh9Z9El.d.ts.map} +1 -1
- package/dist/{index-B9mXrS0W.d.ts → index-Ddi5M-TQ.d.ts} +8 -8
- package/dist/{index-B9mXrS0W.d.ts.map → index-Ddi5M-TQ.d.ts.map} +1 -1
- package/dist/{index-CbBfavbT.d.ts → index-H-u7f-w3.d.ts} +2 -2
- package/dist/{index-CbBfavbT.d.ts.map → index-H-u7f-w3.d.ts.map} +1 -1
- package/dist/{index-DkucR0KJ.d.ts → index-UxNTvn-w.d.ts} +6 -6
- package/dist/{index-DkucR0KJ.d.ts.map → index-UxNTvn-w.d.ts.map} +1 -1
- package/dist/index.d.ts +27 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -87
- package/dist/index.js.map +1 -1
- package/dist/{kind-factory-Cn1lbsAd.js → kind-factory-ivTx6koH.js} +2 -11
- package/dist/{kind-factory-Cn1lbsAd.js.map → kind-factory-ivTx6koH.js.map} +1 -1
- package/dist/{llm-judge-DBrxRG2D.js → llm-judge-C0256VT_.js} +8 -8
- package/dist/{llm-judge-DBrxRG2D.js.map → llm-judge-C0256VT_.js.map} +1 -1
- package/dist/{matrix-Cqkk7eYI.d.ts → matrix-jHTsHEkR.d.ts} +2 -2
- package/dist/{matrix-Cqkk7eYI.d.ts.map → matrix-jHTsHEkR.d.ts.map} +1 -1
- package/dist/meta-eval/index.d.ts +1 -1
- package/dist/meta-eval/index.js +1 -1
- package/dist/{mint-C1W8w5wo.d.ts → mint-CDy-brUR.d.ts} +2 -2
- package/dist/{mint-C1W8w5wo.d.ts.map → mint-CDy-brUR.d.ts.map} +1 -1
- package/dist/{mint-CWG-s2mI.js → mint-Csor1BLJ.js} +2 -2
- package/dist/{mint-CWG-s2mI.js.map → mint-Csor1BLJ.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/{paired-arms-CgWT7sHy.js → paired-arms-B5v-X7No.js} +2 -4
- package/dist/{paired-arms-CgWT7sHy.js.map → paired-arms-B5v-X7No.js.map} +1 -1
- package/dist/pipelines/index.d.ts +1 -1
- package/dist/pipelines/index.js +2 -2
- package/dist/{prime-protocol-Csr9kcOM.d.ts → prime-protocol-B7et3tI7.d.ts} +2 -2
- package/dist/{prime-protocol-Csr9kcOM.d.ts.map → prime-protocol-B7et3tI7.d.ts.map} +1 -1
- package/dist/{produced-state-DyTuvglz.js → produced-state-CgB9g0VX.js} +3 -3
- package/dist/{produced-state-DyTuvglz.js.map → produced-state-CgB9g0VX.js.map} +1 -1
- package/dist/profile-cell.d.ts +2 -2
- package/dist/profile-cell.js +2 -2
- package/dist/{query-DlV0pdx4.js → query-B1D1qp2Z.js} +2 -2
- package/dist/{query-DlV0pdx4.js.map → query-B1D1qp2Z.js.map} +1 -1
- package/dist/{query-DBUQhehH.d.ts → query-DK1nWcmp.d.ts} +2 -3
- package/dist/{query-DBUQhehH.d.ts.map → query-DK1nWcmp.d.ts.map} +1 -1
- package/dist/{registry-DMkmhBQ5.d.ts → registry-BL7H33tj.d.ts} +3 -3
- package/dist/{registry-DMkmhBQ5.d.ts.map → registry-BL7H33tj.d.ts.map} +1 -1
- package/dist/{release-confidence-CkoXFx9I.d.ts → release-confidence-C4kI7lQi.d.ts} +4 -12
- package/dist/release-confidence-C4kI7lQi.d.ts.map +1 -0
- package/dist/{release-confidence-CiFg1EPq.js → release-confidence-Dbe9AS_X.js} +2 -2
- package/dist/{release-confidence-CiFg1EPq.js.map → release-confidence-Dbe9AS_X.js.map} +1 -1
- package/dist/{report-command-pXtxg5YK.js → report-command-CtIIsQKP.js} +3 -28
- package/dist/{report-command-pXtxg5YK.js.map → report-command-CtIIsQKP.js.map} +1 -1
- package/dist/reporting.d.ts +3 -3
- package/dist/reporting.js +3 -3
- package/dist/{researcher-CZFZjj-u.d.ts → researcher-DuIJ9IaA.d.ts} +4 -4
- package/dist/{researcher-CZFZjj-u.d.ts.map → researcher-DuIJ9IaA.d.ts.map} +1 -1
- package/dist/{reward-hacking-Cyk-QHk9.d.ts → reward-hacking-C6Kp54Av.d.ts} +2 -2
- package/dist/{reward-hacking-Cyk-QHk9.d.ts.map → reward-hacking-C6Kp54Av.d.ts.map} +1 -1
- package/dist/reward-nw2xZGZG.js.map +1 -1
- package/dist/rl.d.ts +10 -29
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +6 -6
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +2 -2
- package/dist/rollout/index.js +2 -2
- package/dist/{rollout-l9w3Gdvh.js → rollout-BZqQc0YY.js} +2 -2
- package/dist/{rollout-l9w3Gdvh.js.map → rollout-BZqQc0YY.js.map} +1 -1
- package/dist/{rubric-predictive-validity-DIUwJJ9Y.d.ts → rubric-predictive-validity-BiNNEjpG.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-DIUwJJ9Y.d.ts.map → rubric-predictive-validity-BiNNEjpG.d.ts.map} +1 -1
- package/dist/{run-record-BRlM99rX.js → run-record-DlTZ_lqe.js} +3 -13
- package/dist/run-record-DlTZ_lqe.js.map +1 -0
- package/dist/{run-record-BB290Y9A.js → run-record-ES07wfz9.js} +2 -2
- package/dist/{run-record-BB290Y9A.js.map → run-record-ES07wfz9.js.map} +1 -1
- package/dist/{run-record-DF-fuu31.d.ts → run-record-p2AYTrCn.d.ts} +3 -7
- package/dist/run-record-p2AYTrCn.d.ts.map +1 -0
- package/dist/search/index.d.ts +2 -24
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +3 -3
- package/dist/{search-kernel-mzeNuzr8.js → search-kernel-Bfe3kzRk.js} +45 -3
- package/dist/search-kernel-Bfe3kzRk.js.map +1 -0
- package/dist/{search-kernel-CzTWtv5d.d.ts → search-kernel-ah2GESe3.d.ts} +19 -4
- package/dist/search-kernel-ah2GESe3.d.ts.map +1 -0
- package/dist/{search-ledger-CXQPwdWz.js → search-ledger-aMTNQn_m.js} +2 -2
- package/dist/{search-ledger-CXQPwdWz.js.map → search-ledger-aMTNQn_m.js.map} +1 -1
- package/dist/{search-shipper-DhhofkDX.js → search-shipper-DKXWuLnp.js} +2 -2
- package/dist/{search-shipper-DhhofkDX.js.map → search-shipper-DKXWuLnp.js.map} +1 -1
- package/dist/{search-summary-CDURlgZR.js → search-summary-DK1bwTAf.js} +2 -2
- package/dist/{search-summary-CDURlgZR.js.map → search-summary-DK1bwTAf.js.map} +1 -1
- package/dist/{semantic-concept-judge-DDxUiWIz.js → semantic-concept-judge-BQxZyXdN.js} +3 -3
- package/dist/{semantic-concept-judge-DDxUiWIz.js.map → semantic-concept-judge-BQxZyXdN.js.map} +1 -1
- package/dist/{sequential-DMqr3sni.js → sequential-BOzBND4t.js} +2 -2
- package/dist/{sequential-DMqr3sni.js.map → sequential-BOzBND4t.js.map} +1 -1
- package/dist/{skillopt-optimization-method-D0-bMRGu.js → skillopt-optimization-method-BCojvoP1.js} +6 -6
- package/dist/{skillopt-optimization-method-D0-bMRGu.js.map → skillopt-optimization-method-BCojvoP1.js.map} +1 -1
- package/dist/{statistical-heldout-DFKtp-Qm.d.ts → statistical-heldout-D0rX_IDl.d.ts} +4 -5
- package/dist/statistical-heldout-D0rX_IDl.d.ts.map +1 -0
- package/dist/{store-otlp-BA7G1Du-.js → store-otlp-__ebQ6Hn.js} +2 -2
- package/dist/{store-otlp-BA7G1Du-.js.map → store-otlp-__ebQ6Hn.js.map} +1 -1
- package/dist/{store-tool-spans-DKoVbE-w.js → store-tool-spans-TbRBuIM7.js} +3 -3
- package/dist/{store-tool-spans-DKoVbE-w.js.map → store-tool-spans-TbRBuIM7.js.map} +1 -1
- package/dist/{store-tool-spans-9YJNMP-z.d.ts → store-tool-spans-wQ9idsnn.d.ts} +5 -5
- package/dist/{store-tool-spans-9YJNMP-z.d.ts.map → store-tool-spans-wQ9idsnn.d.ts.map} +1 -1
- package/dist/{summary-report-fXurE2TR.js → summary-report-BsaEFEwA.js} +3 -3
- package/dist/{summary-report-fXurE2TR.js.map → summary-report-BsaEFEwA.js.map} +1 -1
- package/dist/{summary-report-DvvesgR_.d.ts → summary-report-CK0ueoJd.d.ts} +2 -2
- package/dist/{summary-report-DvvesgR_.d.ts.map → summary-report-CK0ueoJd.d.ts.map} +1 -1
- package/dist/supervisor-run/index.d.ts +0 -8
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +2 -2
- package/dist/{systemone-review-Bt4JcxMc.d.ts → systemone-review-BReh3mvm.d.ts} +2 -2
- package/dist/{systemone-review-Bt4JcxMc.d.ts.map → systemone-review-BReh3mvm.d.ts.map} +1 -1
- package/dist/systemone.d.ts +3 -3
- package/dist/{tool-groups-j19pmOfP.d.ts → tool-groups-v28A-ZAF.d.ts} +3 -3
- package/dist/tool-groups-v28A-ZAF.d.ts.map +1 -0
- package/dist/{tool-waste-x_E8h9Ih.js → tool-waste-BYt5rdt8.js} +2 -2
- package/dist/{tool-waste-x_E8h9Ih.js.map → tool-waste-BYt5rdt8.js.map} +1 -1
- package/dist/{tool-waste-DxlebQkx.d.ts → tool-waste-Wi4g6Ekb.d.ts} +2 -2
- package/dist/{tool-waste-DxlebQkx.d.ts.map → tool-waste-Wi4g6Ekb.d.ts.map} +1 -1
- package/dist/{trace-questions-dRvmsbTk.d.ts → trace-questions-C26UvI3D.d.ts} +3 -3
- package/dist/{trace-questions-dRvmsbTk.d.ts.map → trace-questions-C26UvI3D.d.ts.map} +1 -1
- package/dist/trace-repair/index.d.ts +2 -9
- package/dist/trace-repair/index.d.ts.map +1 -1
- package/dist/trace-repair/index.js +1 -1
- package/dist/traces.d.ts +6 -8
- package/dist/traces.d.ts.map +1 -1
- package/dist/traces.js +6 -6
- package/dist/trajectory-replay/index.d.ts +0 -2
- package/dist/trajectory-replay/index.d.ts.map +1 -1
- package/dist/trajectory-replay/index.js +1 -1
- package/dist/{tree-CN8mlzUO.js → tree-CZ78tiPg.js} +4 -24
- package/dist/tree-CZ78tiPg.js.map +1 -0
- package/dist/{types-CFCUZk0B.d.ts → types-Dv9sYwBB.d.ts} +4 -4
- package/dist/{types-CFCUZk0B.d.ts.map → types-Dv9sYwBB.d.ts.map} +1 -1
- package/dist/{types-DAPpAkd4.d.ts → types-KEkKkETv.d.ts} +2 -2
- package/dist/{types-DAPpAkd4.d.ts.map → types-KEkKkETv.d.ts.map} +1 -1
- package/dist/{types-BlSBUNRd.d.ts → types-tWFY6bON.d.ts} +3 -3
- package/dist/{types-BlSBUNRd.d.ts.map → types-tWFY6bON.d.ts.map} +1 -1
- package/dist/wire/index.d.ts +1 -1
- package/docs/public-api.md +399 -424
- package/docs/quickstart-external.md +268 -0
- package/docs/search-ledger.md +4 -1
- package/package.json +3 -3
- package/dist/agent-profile-cell-BHcB-mZX.d.ts.map +0 -1
- package/dist/agent-profile-cell-DcFW4vOc.js.map +0 -1
- package/dist/engine-DProXJ7A.d.ts.map +0 -1
- package/dist/release-confidence-CkoXFx9I.d.ts.map +0 -1
- package/dist/run-record-BRlM99rX.js.map +0 -1
- package/dist/run-record-DF-fuu31.d.ts.map +0 -1
- package/dist/search-kernel-CzTWtv5d.d.ts.map +0 -1
- package/dist/search-kernel-mzeNuzr8.js.map +0 -1
- package/dist/statistical-heldout-DFKtp-Qm.d.ts.map +0 -1
- package/dist/tool-groups-j19pmOfP.d.ts.map +0 -1
- package/dist/tree-CN8mlzUO.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-ledger-CXQPwdWz.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\n/** A claim tests at most this many finalists against the root. */\nexport const SEARCH_CLAIM_MAX_FINALISTS = 3\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 lineage parent: each parent an edge into the node names that was\n * registered before it, in edge order. A re-proposal from the node itself\n * or from a later node adds none, so parents and children stay acyclic. */\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 /** What ran the operation, for example a proposer's model; null until the\n * operation is recorded. */\n execution: SearchOperationRecordedEvent['execution'] | null\n /** Artifacts the started event bound, then those the recorded event bound,\n * for example a claim's plan or a proposal's output. */\n artifacts: readonly SearchArtifactRef[]\n /** Known cost, or the proven floor when `costKnown` is false. */\n spentUsd: number\n /** The recorded cost is known; false until the operation is recorded. */\n costKnown: boolean\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 /** Nodes ever decided `finalist`. */\n private readonly finalists = new Set<string>()\n /** Claim cells allocated. Once one exists, the finalists are fixed. */\n private claimCells = 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.assertSearching(`operation ${event.operationId}`)\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 execution: null,\n artifacts: event.artifacts,\n spentUsd: 0,\n costKnown: false,\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.execution = event.execution\n operation.artifacts = [...operation.artifacts, ...event.artifacts]\n operation.spentUsd = cost.usd\n operation.costKnown = !cost.unknown\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 this.assertSearching(`node ${event.nodeId}`)\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 this.assertSearching(`edge ${event.edgeId}`)\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 // A node's first edge fixes its lineage, so its parents were registered\n // before it and the lineage is acyclic. A later edge is a re-proposal:\n // the proposer produced the node's artifact again. Proposers return their\n // parent unchanged and revert edits, so a re-proposal may come from any\n // node the search holds, the node itself included; a parent registered at\n // or after the node is counted but never becomes lineage.\n const reproposal = child.edgeIds.length > 0\n const inSearch: NodeRecord[] = []\n const later = new Set<string>()\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 && !reproposal) {\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 if (record.decisions.at(-1)?.decision.status === 'invalid') {\n throw integrity(\n `edge ${event.edgeId}: parent ${parent.nodeId} was decided invalid, and an invalid node never becomes a parent`,\n )\n }\n if (record.ordinal >= child.ordinal) later.add(parent.nodeId)\n else inSearch.push(record)\n }\n\n if (!reproposal) {\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 (later.has(parent.nodeId) || 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 if (event.stage !== 'claim') this.assertSearching(`cell ${event.cellId}`)\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') {\n this.claimUsedUsd += event.reservation?.usd ?? 0\n this.claimCells += 1\n }\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 === 'finalist' && !this.finalists.has(event.nodeId)) {\n if (node.ordinal === 0) {\n throw integrity(`the root ${event.nodeId} is the claim's control and cannot be a finalist`)\n }\n if (this.claimCells > 0) {\n throw integrity(\n `node ${event.nodeId} was decided finalist after a claim cell ran; the finalists are fixed before the test`,\n )\n }\n if (this.finalists.size >= SEARCH_CLAIM_MAX_FINALISTS) {\n throw integrity(\n `node ${event.nodeId} would be finalist ${this.finalists.size + 1}; at most ${SEARCH_CLAIM_MAX_FINALISTS} are allowed`,\n )\n }\n this.finalists.add(event.nodeId)\n }\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 const named = claim.finalists.map((finalist) => finalist.nodeId)\n assertUnique(named, 'claim finalist', 'search-closed')\n for (const nodeId of named) {\n if (!this.finalists.has(nodeId)) {\n throw integrity(`claim finalist ${nodeId} was never decided finalist`)\n }\n }\n // Every finalist stays in the family the confidence is divided among, so\n // a finalist that lost cannot be dropped to relax the correction.\n for (const nodeId of this.finalists) {\n if (!named.includes(nodeId)) {\n throw integrity(`finalist ${nodeId} is missing from the claim`)\n }\n }\n const root = this.nodeOrder[0] ?? null\n const perFinalist = 1 - (1 - claim.confidence) / Math.max(1, named.length)\n for (const finalist of claim.finalists) {\n const { estimate, test } = finalist\n if (estimate && (estimate.against !== root || estimate.split !== 'test')) {\n throw integrity(\n `claim finalist ${finalist.nodeId} is estimated against something other than the root on test`,\n )\n }\n if (test && Math.abs(test.confidence - perFinalist) > 1e-12) {\n throw integrity(\n `claim finalist ${finalist.nodeId} is tested at confidence ${test.confidence}; ${named.length} finalists at family-wise ${claim.confidence} need ${perFinalist}`,\n )\n }\n if (finalist.promote && test === null) {\n throw integrity(`claim finalist ${finalist.nodeId} is promoted without a test`)\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 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 if ('unknown' in this.header!.objective.judge) {\n throw integrity(\n \"a ship claim needs a pinned judge; with an unknown judge a resumed search could mix two judges' verdicts\",\n )\n }\n const testUnits = new Set(this.header!.splits.test.tasks.map((task) => task.unitId))\n for (const nodeId of [root!, claim.selected]) {\n const scored = new Set(this.readScoredCells(nodeId, 'test').map((cell) => cell.unitId))\n const missing = [...testUnits].filter((unit) => !scored.has(unit))\n if (missing.length > 0) {\n throw integrity(\n `a ship claim needs every test unit scored by the root and the finalist; ${nodeId} has none on ${missing.join(', ')}`,\n )\n }\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 /** Once the first finalist is decided, the search only runs its claim:\n * nothing new is proposed, registered or allocated outside the test. */\n private assertSearching(subject: string): void {\n if (this.finalists.size > 0 || this.claimCells > 0) {\n throw integrity(\n `${subject} follows the start of the claim; the search stopped when its finalists were decided`,\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 *\n * The rule admits holds, not records. Spend above a hold is legal\n * overspend, so committed spend can pass the cap; an event that holds\n * nothing (the claim operation, a cell an external optimizer already ran)\n * and a claim cell the unspent reserve covers are then still admitted. The\n * reserve was set aside at the start and overspend elsewhere cannot take it\n * back; refusing them would leave a search that can never close. */\n private admit(reservation: SearchReservation | null, claim: boolean, subject: string): void {\n const { maxUsd, reservedClaimUsd } = this.header!.budget\n const hold = reservation?.usd ?? 0\n if (maxUsd === null || hold === 0) return\n const remainingClaim = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n if (claim && hold <= remainingClaim + USD_TOLERANCE) return\n const total =\n this.audit.spend.committedUsd +\n this.audit.spend.openReservationUsd +\n (claim ? 0 : 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\n/** How the claim's paired decision reads per-unit test means, fixed before any\n * test cell runs. `binary`: every unit mean is 0 or `scale` (a pass rate).\n * `continuous`: any other score. */\nexport type SearchClaimEstimator = { kind: 'continuous' } | { kind: 'binary'; scale: number }\n\n/**\n * Whether the test split can resolve the claim's minimum effect, checked on\n * selection data before any test cell runs. The power is the claim decision's\n * own promotion rate, simulated at a true improvement of `minimumEffect` with\n * the search's pooled between-unit variance.\n */\nexport type SearchClaimPower =\n | {\n adequate: boolean\n /** The improvement the test must resolve, in the metric's units. */\n minimumEffect: number\n powerAtMinimumEffect: number\n targetPower: number\n /** Independent test units. */\n units: number\n /** Finalists the family-wise confidence is divided among. */\n finalists: number\n /** Between-unit variance of selection improvements over the root, pooled\n * across every node with 2 or more shared units. */\n pooledVariance: number\n estimator: SearchClaimEstimator\n }\n | SearchUnknown\n\n/** A finalist's paired test against the root at its Bonferroni confidence. */\nexport interface SearchClaimTest {\n /** Test units the finalist and the root both scored. */\n pairs: number\n /** `1 - (1 - claim.confidence) / finalists`. */\n confidence: number\n method: 'score-interval' | 'bootstrap-ci' | 'exact-sign'\n /** Node minus root in the metric's units, like `NodeEstimate.delta`; a\n * `minimize` improvement is negative. */\n delta: number\n interval: [number, number]\n}\n\nexport interface SearchClaimFinalist {\n nodeId: string\n /** The node's test estimate against the root, as every view computes it.\n * Null when no test cell ran. */\n estimate: NodeEstimate | null\n /** The deciding test. Null when no test cell ran. */\n test: SearchClaimTest | null\n promote: boolean\n}\n\n/**\n * The claim made once, on the sealed test split. `selected` names the node the\n * search keeps: the shipped finalist on `ship`, the root otherwise (null when\n * the root has no scored cell).\n */\nexport interface SearchClaim {\n /** The claim procedure; its revision digests every rule and parameter. */\n rule: SearchSourceRef\n /** Family-wise confidence across the finalists. */\n confidence: number\n power: SearchClaimPower\n finalists: SearchClaimFinalist[]\n selected: string | null\n decision: 'ship' | 'hold' | 'test-cannot-resolve'\n /** Why the claim reached its decision. */\n reason: string\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. On a node's\n * first edge every parent was registered before the child. A later edge is a\n * re-proposal and may name the child itself or a node registered after it\n * (a proposal that changed nothing, or a revert); such a parent is not\n * lineage, so follow an edge for ancestry only through earlier parents. */\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 CONFIDENCE = z.number().gt(0).lt(1)\n\nconst ClaimEstimatorSchema = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('continuous') }).strict(),\n z.object({ kind: z.literal('binary'), scale: z.number().finite().positive() }).strict(),\n])\n\nconst ClaimSchema = z\n .object({\n rule: SourceRefSchema,\n confidence: CONFIDENCE,\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 targetPower: z.number().gt(0).max(1),\n units: NON_NEGATIVE_INT,\n finalists: POSITIVE_INT,\n pooledVariance: z.number().finite().nonnegative(),\n estimator: ClaimEstimatorSchema,\n })\n .strict(),\n UnknownRefSchema,\n ]),\n finalists: z.array(\n z\n .object({\n nodeId: NODE_ID,\n estimate: NodeEstimateSchema.nullable(),\n test: z\n .object({\n pairs: NON_NEGATIVE_INT,\n confidence: CONFIDENCE,\n method: z.enum(['score-interval', 'bootstrap-ci', 'exact-sign']),\n delta: FINITE_NUMBER,\n interval: z.tuple([FINITE_NUMBER, FINITE_NUMBER]),\n })\n .strict()\n .nullable(),\n promote: z.boolean(),\n })\n .strict(),\n ),\n selected: NODE_ID.nullable(),\n decision: z.enum(['ship', 'hold', 'test-cannot-resolve']),\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: ClaimSchema.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
|
+
{"version":3,"file":"search-ledger-aMTNQn_m.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\n/** A claim tests at most this many finalists against the root. */\nexport const SEARCH_CLAIM_MAX_FINALISTS = 3\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 lineage parent: each parent an edge into the node names that was\n * registered before it, in edge order. A re-proposal from the node itself\n * or from a later node adds none, so parents and children stay acyclic. */\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 /** What ran the operation, for example a proposer's model; null until the\n * operation is recorded. */\n execution: SearchOperationRecordedEvent['execution'] | null\n /** Artifacts the started event bound, then those the recorded event bound,\n * for example a claim's plan or a proposal's output. */\n artifacts: readonly SearchArtifactRef[]\n /** Known cost, or the proven floor when `costKnown` is false. */\n spentUsd: number\n /** The recorded cost is known; false until the operation is recorded. */\n costKnown: boolean\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 /** Nodes ever decided `finalist`. */\n private readonly finalists = new Set<string>()\n /** Claim cells allocated. Once one exists, the finalists are fixed. */\n private claimCells = 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.assertSearching(`operation ${event.operationId}`)\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 execution: null,\n artifacts: event.artifacts,\n spentUsd: 0,\n costKnown: false,\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.execution = event.execution\n operation.artifacts = [...operation.artifacts, ...event.artifacts]\n operation.spentUsd = cost.usd\n operation.costKnown = !cost.unknown\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 this.assertSearching(`node ${event.nodeId}`)\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 this.assertSearching(`edge ${event.edgeId}`)\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 // A node's first edge fixes its lineage, so its parents were registered\n // before it and the lineage is acyclic. A later edge is a re-proposal:\n // the proposer produced the node's artifact again. Proposers return their\n // parent unchanged and revert edits, so a re-proposal may come from any\n // node the search holds, the node itself included; a parent registered at\n // or after the node is counted but never becomes lineage.\n const reproposal = child.edgeIds.length > 0\n const inSearch: NodeRecord[] = []\n const later = new Set<string>()\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 && !reproposal) {\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 if (record.decisions.at(-1)?.decision.status === 'invalid') {\n throw integrity(\n `edge ${event.edgeId}: parent ${parent.nodeId} was decided invalid, and an invalid node never becomes a parent`,\n )\n }\n if (record.ordinal >= child.ordinal) later.add(parent.nodeId)\n else inSearch.push(record)\n }\n\n if (!reproposal) {\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 (later.has(parent.nodeId) || 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 if (event.stage !== 'claim') this.assertSearching(`cell ${event.cellId}`)\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') {\n this.claimUsedUsd += event.reservation?.usd ?? 0\n this.claimCells += 1\n }\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 === 'finalist' && !this.finalists.has(event.nodeId)) {\n if (node.ordinal === 0) {\n throw integrity(`the root ${event.nodeId} is the claim's control and cannot be a finalist`)\n }\n if (this.claimCells > 0) {\n throw integrity(\n `node ${event.nodeId} was decided finalist after a claim cell ran; the finalists are fixed before the test`,\n )\n }\n if (this.finalists.size >= SEARCH_CLAIM_MAX_FINALISTS) {\n throw integrity(\n `node ${event.nodeId} would be finalist ${this.finalists.size + 1}; at most ${SEARCH_CLAIM_MAX_FINALISTS} are allowed`,\n )\n }\n this.finalists.add(event.nodeId)\n }\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 const named = claim.finalists.map((finalist) => finalist.nodeId)\n assertUnique(named, 'claim finalist', 'search-closed')\n for (const nodeId of named) {\n if (!this.finalists.has(nodeId)) {\n throw integrity(`claim finalist ${nodeId} was never decided finalist`)\n }\n }\n // Every finalist stays in the family the confidence is divided among, so\n // a finalist that lost cannot be dropped to relax the correction.\n for (const nodeId of this.finalists) {\n if (!named.includes(nodeId)) {\n throw integrity(`finalist ${nodeId} is missing from the claim`)\n }\n }\n const root = this.nodeOrder[0] ?? null\n const perFinalist = 1 - (1 - claim.confidence) / Math.max(1, named.length)\n for (const finalist of claim.finalists) {\n const { estimate, test } = finalist\n if (estimate && (estimate.against !== root || estimate.split !== 'test')) {\n throw integrity(\n `claim finalist ${finalist.nodeId} is estimated against something other than the root on test`,\n )\n }\n if (test && Math.abs(test.confidence - perFinalist) > 1e-12) {\n throw integrity(\n `claim finalist ${finalist.nodeId} is tested at confidence ${test.confidence}; ${named.length} finalists at family-wise ${claim.confidence} need ${perFinalist}`,\n )\n }\n if (finalist.promote && test === null) {\n throw integrity(`claim finalist ${finalist.nodeId} is promoted without a test`)\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 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 if ('unknown' in this.header!.objective.judge) {\n throw integrity(\n \"a ship claim needs a pinned judge; with an unknown judge a resumed search could mix two judges' verdicts\",\n )\n }\n const testUnits = new Set(this.header!.splits.test.tasks.map((task) => task.unitId))\n for (const nodeId of [root!, claim.selected]) {\n const scored = new Set(this.readScoredCells(nodeId, 'test').map((cell) => cell.unitId))\n const missing = [...testUnits].filter((unit) => !scored.has(unit))\n if (missing.length > 0) {\n throw integrity(\n `a ship claim needs every test unit scored by the root and the finalist; ${nodeId} has none on ${missing.join(', ')}`,\n )\n }\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 /** Once the first finalist is decided, the search only runs its claim:\n * nothing new is proposed, registered or allocated outside the test. */\n private assertSearching(subject: string): void {\n if (this.finalists.size > 0 || this.claimCells > 0) {\n throw integrity(\n `${subject} follows the start of the claim; the search stopped when its finalists were decided`,\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 *\n * The rule admits holds, not records. Spend above a hold is legal\n * overspend, so committed spend can pass the cap; an event that holds\n * nothing (the claim operation, a cell an external optimizer already ran)\n * and a claim cell the unspent reserve covers are then still admitted. The\n * reserve was set aside at the start and overspend elsewhere cannot take it\n * back; refusing them would leave a search that can never close. */\n private admit(reservation: SearchReservation | null, claim: boolean, subject: string): void {\n const { maxUsd, reservedClaimUsd } = this.header!.budget\n const hold = reservation?.usd ?? 0\n if (maxUsd === null || hold === 0) return\n const remainingClaim = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n if (claim && hold <= remainingClaim + USD_TOLERANCE) return\n const total =\n this.audit.spend.committedUsd +\n this.audit.spend.openReservationUsd +\n (claim ? 0 : 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\n/** How the claim's paired decision reads per-unit test means, fixed before any\n * test cell runs. `binary`: every unit mean is 0 or `scale` (a pass rate).\n * `continuous`: any other score. */\nexport type SearchClaimEstimator = { kind: 'continuous' } | { kind: 'binary'; scale: number }\n\n/**\n * Whether the test split can resolve the claim's minimum effect, checked on\n * selection data before any test cell runs. The power is the claim decision's\n * own promotion rate, simulated at a true improvement of `minimumEffect` with\n * the search's pooled between-unit variance.\n */\nexport type SearchClaimPower =\n | {\n adequate: boolean\n /** The improvement the test must resolve, in the metric's units. */\n minimumEffect: number\n powerAtMinimumEffect: number\n targetPower: number\n /** Independent test units. */\n units: number\n /** Finalists the family-wise confidence is divided among. */\n finalists: number\n /** Between-unit variance of selection improvements over the root, pooled\n * across every node with 2 or more shared units. */\n pooledVariance: number\n estimator: SearchClaimEstimator\n }\n | SearchUnknown\n\n/** A finalist's paired test against the root at its Bonferroni confidence. */\nexport interface SearchClaimTest {\n /** Test units the finalist and the root both scored. */\n pairs: number\n /** `1 - (1 - claim.confidence) / finalists`. */\n confidence: number\n method: 'score-interval' | 'bootstrap-ci' | 'exact-sign'\n /** Node minus root in the metric's units, like `NodeEstimate.delta`; a\n * `minimize` improvement is negative. */\n delta: number\n interval: [number, number]\n}\n\nexport interface SearchClaimFinalist {\n nodeId: string\n /** The node's test estimate against the root, as every view computes it.\n * Null when no test cell ran. */\n estimate: NodeEstimate | null\n /** The deciding test. Null when no test cell ran. */\n test: SearchClaimTest | null\n promote: boolean\n}\n\n/**\n * The claim made once, on the sealed test split. `selected` names the node the\n * search keeps: the shipped finalist on `ship`, the root otherwise (null when\n * the root has no scored cell).\n */\nexport interface SearchClaim {\n /** The claim procedure; its revision digests every rule and parameter. */\n rule: SearchSourceRef\n /** Family-wise confidence across the finalists. */\n confidence: number\n power: SearchClaimPower\n finalists: SearchClaimFinalist[]\n selected: string | null\n decision: 'ship' | 'hold' | 'test-cannot-resolve'\n /** Why the claim reached its decision. */\n reason: string\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. On a node's\n * first edge every parent was registered before the child. A later edge is a\n * re-proposal and may name the child itself or a node registered after it\n * (a proposal that changed nothing, or a revert); such a parent is not\n * lineage, so follow an edge for ancestry only through earlier parents. */\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 CONFIDENCE = z.number().gt(0).lt(1)\n\nconst ClaimEstimatorSchema = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('continuous') }).strict(),\n z.object({ kind: z.literal('binary'), scale: z.number().finite().positive() }).strict(),\n])\n\nconst ClaimSchema = z\n .object({\n rule: SourceRefSchema,\n confidence: CONFIDENCE,\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 targetPower: z.number().gt(0).max(1),\n units: NON_NEGATIVE_INT,\n finalists: POSITIVE_INT,\n pooledVariance: z.number().finite().nonnegative(),\n estimator: ClaimEstimatorSchema,\n })\n .strict(),\n UnknownRefSchema,\n ]),\n finalists: z.array(\n z\n .object({\n nodeId: NODE_ID,\n estimate: NodeEstimateSchema.nullable(),\n test: z\n .object({\n pairs: NON_NEGATIVE_INT,\n confidence: CONFIDENCE,\n method: z.enum(['score-interval', 'bootstrap-ci', 'exact-sign']),\n delta: FINITE_NUMBER,\n interval: z.tuple([FINITE_NUMBER, FINITE_NUMBER]),\n })\n .strict()\n .nullable(),\n promote: z.boolean(),\n })\n .strict(),\n ),\n selected: NODE_ID.nullable(),\n decision: z.enum(['ship', 'hold', 'test-cannot-resolve']),\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: ClaimSchema.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":";;;;;;;;;AAGA,SAAgB,YAAY,UAAqC;CAC/D,OAAO,gBAAgB,QAAQ;AACjC;AAEA,SAAgB,eAAe,GAAW,GAAmB;CAC3D,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;;;;;;;;;;;;;;;;;;;;AC+CA,SAAgB,aAAa,UAAkB,gBAAgC;CAC7E,OAAO,QAAQ,YAAY,CAAC,UAAU,cAAc,CAAC;AACvD;;AAGA,SAAgB,aACd,UACA,QACA,QACA,OACA,KACQ;CACR,OAAO,QAAQ,YAAY;EAAC;EAAU;EAAQ;EAAQ;EAAO;CAAG,CAAC;AACnE;;AAGA,SAAgB,oBAAoB,OAAgD;CAClF,OAAO,cACL,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,MAAM,UAAU,iBAAiB,KAAK,QAAQ,MAAM,MAAM,CAAC,CAC9E;AACF;;;AAIA,SAAS,YAAY,OAAwB;CAC3C,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,gBAAgB,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;AACtF;AAEA,MAAM,kBAAkB;AACxB,MAAM,gBAAgB;AAGtB,MAAM,SAAiC;CAAC;CAAS;CAAa;AAAM;;;;;;;AAyCpE,SAAgB,iBAAiB,OAAuD;CACtF,MAAM,yBAAS,IAAI,IAAgC;CACnD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,IAAI,KAAK,MAAM;EACnC,IAAI,MAAM,KAAK,KAAK,IAAI;OACnB,OAAO,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC;CACrC;CACA,OAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CACzB,MAAM,CAAC,OAAO,CAAC,WAAW,iBAAiB,MAAM,KAAK,CAAC,CAAC,CACxD,KAAK,CAAC,QAAQ,eAAe;EAC5B,IAAI,MAAM;EACV,KAAK,MAAM,QAAQ,UAAU,MAAM,MAAM,UACvC,iBAAiB,KAAK,QAAQ,MAAM,MAAM,CAC5C,GACE,OAAO,KAAK;EAEd,OAAO;GAAE;GAAQ;GAAK,OAAO,UAAU;GAAQ,MAAM,MAAM,UAAU;EAAO;CAC9E,CAAC;AACL;;;;;;AA4GA,IAAa,cAAb,MAAwF;CACtF;CACA,UAAkB;CAClB,SAA2C;CAC3C,SAA2C;CAC3C,OAAyE;CACzE,iBAAyB,OAAO;CAChC,qBAA4C;CAC5C,wBAAyB,IAAI,IAAoD;CACjF,wBAAyB,IAAI,IAAwB;CACrD,YAAuC,CAAC;CACxC,+BAAgC,IAAI,IAAoB;CACxD,wBAAyB,IAAI,IAAqC;CAClE,YAAuC,CAAC;CACxC,wBAAyB,IAAI,IAAwB;CACrD,6BAA8B,IAAI,IAA6B;CAC/D,iBAAwC;CACxC,eAAuB;;CAEvB,4BAA6B,IAAI,IAAY;;CAE7C,aAAqB;CACrB;CAEA,YAAY,UAAkB;EAC5B,KAAK,WAAW;EAChB,KAAK,QAAQ;GACX;GACA,YAAY;GACZ,UAAU;GACV,QAAQ;GACR,aAAa;GACb,OAAO;GACP,kBAAkB;GAClB,gBAAgB;GAChB,gBAAgB;GAChB,OAAO;IAAE,UAAU;IAAG,YAAY;IAAG,SAAS;IAAG,aAAa;GAAE;GAChE,OAAO;IAAE,WAAW;IAAG,SAAS;IAAG,WAAW;IAAG,MAAM;GAAE;GACzD,UAAU;GACV,UAAU;IAAE,QAAQ;IAAG,QAAQ;IAAG,SAAS;GAAE;GAC7C,YAAY;IAAE,SAAS;IAAG,UAAU;IAAG,MAAM;GAAE;GAC/C,OAAO;IACL,UAAU;IACV,UAAU;IACV,kBAAkB;IAClB,uBAAuB;IACvB,cAAc;IACd,oBAAoB;IACpB,cAAc;IACd,iBAAiB;IACjB,YAAY;GACd;GACA,QAAQ;IAAE,aAAa;IAAG,cAAc;IAAG,cAAc;IAAG,sBAAsB;GAAE;EACtF;CACF;CAEA,MAAM,OAA0B,OAAqB;EACnD,MAAM,QAAQ,MAAM;EACpB,IAAI,KAAK,QACP,MAAM,UAAU,SAAS,MAAM,QAAQ,yBAAyB,KAAK,OAAO,SAAS;EAEvF,MAAM,aAAa,KAAK,MAAM,MAAM,UAAU;EAC9C,IAAI,aAAa,KAAK,gBACpB,MAAM,UAAU,SAAS,MAAM,QAAQ,qCAAqC;EAE9E,aAAa,MAAM,UAAU,IAAI,WAAW,GAAG,oBAAoB,MAAM,OAAO;EAChF,IAAI,MAAM,SAAS,iBAAiB;GAClC,IAAI,UAAU,KAAK,KAAK,QACtB,MAAM,UAAU,wDAAwD;GAE1E,KAAK,KAAK,KAAK;EACjB,OAAO;GACL,IAAI,CAAC,KAAK,QACR,MAAM,UAAU,SAAS,MAAM,QAAQ,8BAA8B;GAEvE,KAAK,WAAW,OAAO,KAAK;EAC9B;EACA,KAAK,iBAAiB;EACtB,KAAK,qBAAqB,MAAM;EAChC,KAAK,OAAO;GAAE,UAAU;GAAO,WAAW,MAAM;EAAU;EAC1D,KAAK,MAAM,aAAa,QAAQ;EAChC,KAAK,MAAM,WAAW,MAAM;EAC5B,KAAK,WAAW;CAClB;CAEA,WAA4B;EAC1B,OAAO,IAAI,gBAAgB,MAAM,KAAK,OAAO;CAC/C;;CAGA,KAAK,SAA0B;EAC7B,OAAO,KAAK,YAAY;CAC1B;CAEA,WAAmB,OAAsD,OAAqB;EAC5F,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,KAAK,eAAe,KAAK;IACzB;GACF,KAAK;IACH,KAAK,gBAAgB,KAAK;IAC1B;GACF,KAAK;IACH,KAAK,aAAa,OAAO,KAAK;IAC9B;GACF,KAAK;IACH,KAAK,WAAW,OAAO,KAAK;IAC5B;GACF,KAAK;IACH,KAAK,aAAa,OAAO,KAAK;IAC9B;GACF,KAAK;IACH,KAAK,WAAW,OAAO,KAAK;IAC5B;GACF,KAAK;IACH,KAAK,WAAW,OAAO,KAAK;IAC5B;GACF,KAAK;IACH,KAAK,WAAW,OAAO,KAAK;IAC5B;GACF,KAAK;IACH,KAAK,MAAM,KAAK;IAChB;EACJ;CACF;CAEA,KAAa,OAAgC;EAC3C,IAAI,MAAM,aAAa,aAAa,KAAK,UACvC,MAAM,UAAU,gCAAgC;EAElD,IAAI,MAAM,aAAa,aAAa,KAAK,UACvC,MAAM,UAAU,oCAAoC;EAEtD,MAAM,QAA0C;GAC9C,uBAAO,IAAI,IAAI;GACf,2BAAW,IAAI,IAAI;GACnB,sBAAM,IAAI,IAAI;EAChB;EACA,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,EAAE,OAAO,kBAAkB,MAAM,OAAO;GAC9C,IAAI,oBAAoB,KAAK,MAAM,eACjC,MAAM,UAAU,OAAO,MAAM,gDAAgD;GAE/E,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,MAAM;IACxC,IAAI,OACF,MAAM,UAAU,QAAQ,KAAK,OAAO,kBAAkB,MAAM,MAAM,OAAO,MAAM,QAAQ;IAEzF,KAAK,MAAM,IAAI,KAAK,QAAQ;KAAE;KAAO,QAAQ,KAAK;IAAO,CAAC;IAC1D,MAAM,MAAM,CAAC,IAAI,KAAK,MAAM;GAC9B;EACF;EACA,IAAI,MAAM,OAAO,cAAc;GAC7B,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,QAC1B,SAAS,MAAM,MAAM,IAAI,IAAI,KAAK,MAAM,UAAU,IAAI,IAAI,CAC7D;GACA,IAAI,KAAK,SAAS,GAChB,MAAM,UACJ,cAAc,KAAK,KAAK,IAAI,EAAE,wEAChC;EAEJ;EACA,MAAM,EAAE,WAAW;EACnB,IAAI,OAAO,WAAW,QAAQ,OAAO,mBAAmB,OAAO,SAAS,eACtE,MAAM,UACJ,sBAAsB,OAAO,iBAAiB,2BAA2B,OAAO,QAClF;EAEF,KAAK,SAAS;CAChB;CAEA,eAAuB,OAA0C;EAC/D,IAAI,KAAK,WAAW,IAAI,MAAM,WAAW,GACvC,MAAM,UAAU,aAAa,MAAM,YAAY,mBAAmB;EAEpE,KAAK,gBAAgB,aAAa,MAAM,aAAa;EACrD,KAAK,MAAM,MAAM,aAAa,OAAO,aAAa,MAAM,aAAa;EACrE,KAAK,WAAW,IAAI,MAAM,aAAa;GACrC,aAAa,MAAM;GACnB,eAAe,MAAM;GACrB,aAAa,MAAM;GACnB,UAAU;GACV,SAAS;GACT,WAAW;GACX,WAAW,MAAM;GACjB,UAAU;GACV,WAAW;EACb,CAAC;EACD,KAAK,MAAM,WAAW,WAAW;EACjC,KAAK,MAAM,WAAW,QAAQ;EAC9B,KAAK,MAAM,MAAM,sBAAsB,MAAM,aAAa,OAAO;CACnE;CAEA,gBAAwB,OAA2C;EACjE,MAAM,YAAY,KAAK,WAAW,IAAI,MAAM,WAAW;EACvD,IAAI,CAAC,WACH,MAAM,UAAU,aAAa,MAAM,YAAY,gCAAgC;EAEjF,IAAI,UAAU,UACZ,MAAM,UAAU,aAAa,MAAM,YAAY,oBAAoB;EAErE,IAAI,UAAU,kBAAkB,MAAM,eACpC,MAAM,UACJ,aAAa,MAAM,YAAY,cAAc,UAAU,cAAc,mBAAmB,MAAM,eAChG;EAEF,MAAM,OAAO,KAAK,KAAK,MAAM,UAAU;EACvC,IAAI,KAAK,SAAS,KAAK,MAAM,MAAM,yBAAyB;EAC5D,MAAM,WAAW,UAAU,aAAa,OAAO;EAC/C,KAAK,MAAM,MAAM,sBAAsB;EACvC,IAAI,UAAU,aACZ,KAAK,MAAM,MAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ;EAElE,UAAU,WAAW;EACrB,UAAU,UAAU,MAAM,QAAQ;EAClC,UAAU,YAAY,MAAM;EAC5B,UAAU,YAAY,CAAC,GAAG,UAAU,WAAW,GAAG,MAAM,SAAS;EACjE,UAAU,WAAW,KAAK;EAC1B,UAAU,YAAY,CAAC,KAAK;EAC5B,KAAK,MAAM,WAAW,YAAY;EAClC,KAAK,MAAM,WAAW,QAAQ;CAChC;CAEA,aAAqB,OAAkC,OAAqB;EAC1E,MAAM,WAAW,aAAa,KAAK,UAAU,MAAM,cAAc;EACjE,IAAI,MAAM,WAAW,UACnB,MAAM,UACJ,QAAQ,MAAM,OAAO,gDAAgD,SAAS,EAChF;EAEF,IAAI,KAAK,MAAM,IAAI,MAAM,MAAM,GAC7B,MAAM,UACJ,QAAQ,MAAM,OAAO,8DACvB;EAEF,KAAK,gBAAgB,QAAQ,MAAM,QAAQ;EAC3C,aACE,MAAM,SAAS,KAAK,YAAY,QAAQ,SAAS,GACjD,aACA,MAAM,OACR;EACA,MAAM,WAAW,KAAK,OAAQ,OAAO;EACrC,IAAI,aAAa,QAAQ,KAAK,MAAM,OAAO,IAAI,UAC7C,MAAM,UAAU,QAAQ,MAAM,OAAO,iCAAiC,UAAU;EAElF,KAAK,MAAM,IAAI,MAAM,QAAQ;GAC3B;GACA,SAAS,KAAK,UAAU;GACxB,oBAAoB;GACpB,iBAAiB;GACjB,SAAS,CAAC;GACV,SAAS,CAAC;GACV,4BAAY,IAAI,IAAI;GACpB,iBAAiB;GACjB,OAAO;GACP,UAAU,CAAC;GACX,WAAW,CAAC;GACZ,UAAU;GACV,SAAS,CAAC;GACV,aAAa;GACb,OAAO;IAAE,UAAU;IAAG,UAAU;IAAG,kBAAkB;IAAG,YAAY;GAAE;EACxE,CAAC;EACD,KAAK,UAAU,KAAK,MAAM,MAAM;EAChC,KAAK,aAAa,IAAI,MAAM,gBAAgB,MAAM,MAAM;EACxD,KAAK,MAAM,SAAS;EACpB,KAAK,MAAM,oBAAoB;EAC/B,KAAK,MAAM,kBAAkB;CAC/B;CAEA,WAAmB,OAAgC,OAAqB;EACtE,IAAI,KAAK,MAAM,IAAI,MAAM,MAAM,GAC7B,MAAM,UAAU,QAAQ,MAAM,OAAO,oBAAoB;EAE3D,MAAM,QAAQ,KAAK,MAAM,IAAI,MAAM,WAAW;EAC9C,IAAI,CAAC,OACH,MAAM,UAAU,QAAQ,MAAM,OAAO,4BAA4B,MAAM,aAAa;EAEtF,KAAK,gBAAgB,QAAQ,MAAM,QAAQ;EAC3C,IAAI,MAAM,MAAM,SAAS,iBACvB,MAAM,UAAU,QAAQ,MAAM,OAAO,iBAAiB,gBAAgB,YAAY;EAEpF,IAAI,MAAM,MAAM,WAAW,MAAM,QAAQ,QACvC,MAAM,UAAU,QAAQ,MAAM,OAAO,2BAA2B;EAElE,aACE,MAAM,QAAQ,KAAK,WAAW,gBAAgB,MAAM,CAAC,GACrD,UACA,MAAM,OACR;EACA,MAAM,EAAE,UAAU,aAAa,YAAY;EAC3C,IAAK,aAAa,YAAa,MAAM,aAAa,OAChD,MAAM,UAAU,QAAQ,MAAM,OAAO,wCAAwC;EAE/E,IAAI,aAAa,WAAW,QAAQ,SAAS,KAAK,gBAAgB,YAChE,MAAM,UAAU,aAAa,MAAM,OAAO,8CAA8C;EAE1F,IAAI,gBAAgB,aAAa,QAAQ,SAAS,GAChD,MAAM,UAAU,QAAQ,MAAM,OAAO,2CAA2C;EAElF,IAAI,aAAa,UAAU,gBAAgB,aAAa,QAAQ,WAAW,GACzE,MAAM,UAAU,GAAG,SAAS,QAAQ,MAAM,OAAO,iBAAiB;EAEpE,IAAI,aAAa,WAAW,gBAAgB,aAAa,QAAQ,SAAS,GACxE,MAAM,UAAU,cAAc,MAAM,OAAO,4BAA4B;EAEzE,MAAM,cAAc,MAAM,UAAU,eAAe;EACnD,IAAI,gBAAgB,QAAQ,CAAC,KAAK,WAAW,IAAI,WAAW,GAC1D,MAAM,UAAU,QAAQ,MAAM,OAAO,mBAAmB,YAAY,sBAAsB;EAQ5F,MAAM,aAAa,MAAM,QAAQ,SAAS;EAC1C,MAAM,WAAyB,CAAC;EAChC,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,OAAO,aAAa,KAAK,UAAU;IACrC,MAAM,OAAO,KAAK,OAAQ;IAC1B,IACE,aAAa,YACb,QAAQ,WAAW,KACnB,CAAC,QACD,KAAK,aAAa,OAAO,YACzB,KAAK,WAAW,OAAO,QAEvB,MAAM,UACJ,QAAQ,MAAM,OAAO,4BAA4B,OAAO,SAAS,8CACnE;IAEF;GACF;GACA,IAAI,aAAa,UACf,MAAM,UAAU,eAAe,MAAM,OAAO,qCAAqC;GAEnF,MAAM,SAAS,KAAK,MAAM,IAAI,OAAO,MAAM;GAC3C,IAAI,CAAC,QACH,MAAM,UAAU,QAAQ,MAAM,OAAO,6BAA6B,OAAO,QAAQ;GAEnF,IAAI,OAAO,WAAW,MAAM,WAAW,CAAC,YACtC,MAAM,UACJ,QAAQ,MAAM,OAAO,WAAW,OAAO,OAAO,0BAA0B,MAAM,MAAM,QACtF;GAEF,IAAI,OAAO,QAAQ,WAAW,GAC5B,MAAM,UAAU,QAAQ,MAAM,OAAO,WAAW,OAAO,OAAO,4BAA4B;GAE5F,IAAI,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,WAAW,WAC/C,MAAM,UACJ,QAAQ,MAAM,OAAO,WAAW,OAAO,OAAO,iEAChD;GAEF,IAAI,OAAO,WAAW,MAAM,SAAS,MAAM,IAAI,OAAO,MAAM;QACvD,SAAS,KAAK,MAAM;EAC3B;EAEA,IAAI,CAAC,YAAY;GACf,MAAM,UAAU,SAAS;GACzB,MAAM,kBAAkB,SAAS,MAAM,UAAU;GACjD,MAAM,QACJ,aAAa,UAAU,aAAa,WAChC,IACA,WAAW,QAAQ,UAAU,OAC3B,QAAQ,QAAQ,IAChB;GACR,KAAK,MAAM,oBAAoB;EACjC,OACE,KAAK,MAAM,MAAM,eAAe;EAElC,MAAM,QAAQ,KAAK,MAAM,MAAM;EAC/B,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,MAAM,gBAAgB,MAAM;GAClC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,MAAM,WAAW,IAAI,GAAG,GAAG;GAC3D,MAAM,WAAW,IAAI,GAAG;GACxB,MAAM,QAAQ,KAAK,MAAM;EAC3B;EACA,KAAK,MAAM,UAAU,UACnB,IAAI,CAAC,OAAO,SAAS,SAAS,MAAM,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,MAAM,MAAM,MAAM;EAE5F,MAAM,kBAAkB;EACxB,KAAK,MAAM,IAAI,MAAM,QAAQ,KAAK;EAClC,KAAK,UAAU,KAAK,MAAM,MAAM;EAChC,KAAK,MAAM,MAAM,gBAAgB;CACnC;CAEA,aAAqB,OAAiC,OAAqB;EACzE,MAAM,WAAW,aAAa,KAAK,UAAU,MAAM,QAAQ,MAAM,QAAQ,MAAM,OAAO,MAAM,GAAG;EAC/F,IAAI,MAAM,WAAW,UACnB,MAAM,UAAU,QAAQ,MAAM,OAAO,4CAA4C,SAAS,EAAE;EAE9F,IAAI,KAAK,MAAM,IAAI,MAAM,MAAM,GAC7B,MAAM,UAAU,QAAQ,MAAM,OAAO,qBAAqB;EAE5D,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM;EACxC,IAAI,CAAC,MAAM,MAAM,UAAU,QAAQ,MAAM,OAAO,2BAA2B,MAAM,QAAQ;EACzF,IAAI,KAAK,QAAQ,WAAW,GAC1B,MAAM,UAAU,QAAQ,MAAM,OAAO,SAAS,MAAM,OAAO,iBAAiB;EAE9E,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM;EACxC,IAAI,CAAC,QAAQ,KAAK,UAAU,MAAM,OAChC,MAAM,UACJ,QAAQ,MAAM,OAAO,SAAS,MAAM,OAAO,iBAAiB,MAAM,MAAM,OAC1E;EAEF,IAAI,KAAK,WAAW,MAAM,QACxB,MAAM,UAAU,QAAQ,MAAM,OAAO,SAAS,MAAM,OAAO,gBAAgB,KAAK,QAAQ;EAE1F,iBAAiB,MAAM,QAAQ,MAAM,OAAO,MAAM,OAAO,KAAK,YAAY,CAAC;EAC3E,IAAI,MAAM,UAAU,UAAU,KAAK,YAAY,KAAK,CAAC,KAAK,UACxD,MAAM,UACJ,QAAQ,MAAM,OAAO,kEACvB;EAEF,IAAI,MAAM,UAAU,SAAS,KAAK,gBAAgB,QAAQ,MAAM,QAAQ;EACxE,MAAM,WAAW,KAAK,OAAQ,OAAO;EACrC,IAAI,aAAa,QAAQ,KAAK,MAAM,MAAM,YAAY,IAAI,UACxD,MAAM,UAAU,QAAQ,MAAM,OAAO,iCAAiC,UAAU;EAElF,KAAK,MAAM,MAAM,aAAa,MAAM,UAAU,SAAS,QAAQ,MAAM,QAAQ;EAC7E,KAAK,MAAM,IAAI,MAAM,QAAQ;GAC3B,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,KAAK,MAAM;GACX,OAAO,MAAM;GACb,MAAM,MAAM;GACZ,aAAa,MAAM;GACnB,UAAU;GACV,WAAW;GACX,SAAS;GACT,OAAO;GACP,OAAO;GACP,WAAW;GACX,UAAU;GACV,WAAW;GACX,SAAS;GACT,mBAAmB;GACnB,iBAAiB;EACnB,CAAC;EACD,KAAK,QAAQ,KAAK,MAAM,MAAM;EAC9B,KAAK,kBAAkB;EACvB,KAAK,MAAM,MAAM,aAAa;EAC9B,KAAK,MAAM,MAAM,QAAQ;EACzB,KAAK,MAAM,MAAM,sBAAsB,MAAM,aAAa,OAAO;EACjE,IAAI,MAAM,UAAU,SAAS;GAC3B,KAAK,gBAAgB,MAAM,aAAa,OAAO;GAC/C,KAAK,cAAc;EACrB;CACF;CAEA,WAAmB,OAA+B,OAAqB;EACrE,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM;EACxC,IAAI,CAAC,MAAM,MAAM,UAAU,WAAW,MAAM,QAAQ,0BAA0B,MAAM,QAAQ;EAC5F,IAAI,KAAK,WAAW,MAAM,UAAU,QAAQ,MAAM,OAAO,oCAAoC;EAC7F,IAAI,KAAK,OACP,MAAM,UACJ,QAAQ,MAAM,OAAO,qCAAqC,KAAK,QAAQ,wDACzE;EAEF,IAAI,MAAM,YAAY,KAAK,WAAW,GACpC,MAAM,UACJ,QAAQ,MAAM,OAAO,WAAW,MAAM,QAAQ,+BAA+B,KAAK,WAAW,EAAE,EACjG;EAEF,MAAM,QAAQ,gBAAgB;GAAE,QAAQ,MAAM;GAAQ,SAAS,MAAM;EAAQ,CAAC;EAC9E,IAAI,MAAM,UAAU,OAClB,MAAM,UAAU,QAAQ,MAAM,OAAO,WAAW,MAAM,QAAQ,mBAAmB,OAAO;EAE1F,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM;EACvC,MAAM,WAAW,IAAI,IAAI,KAAK,MAAM,SAAS,KAAK,YAAY,QAAQ,SAAS,CAAC;EAChF,aACE,MAAM,gBAAgB,KAAK,aAAa,SAAS,SAAS,GAC1D,oBACA,MAAM,OACR;EACA,KAAK,MAAM,YAAY,MAAM,iBAC3B,IAAI,CAAC,SAAS,IAAI,SAAS,SAAS,GAClC,MAAM,UACJ,WAAW,MAAM,QAAQ,mBAAmB,SAAS,UAAU,eAAe,KAAK,OAAO,kBAC5F;EAGJ,IAAI,MAAM,UAAU,QAAQ,aAAa,SAAS,SAAS,YAAY,CAAC,CAAC,SAAS,GAChF,MAAM,UAAU,WAAW,MAAM,QAAQ,+BAA+B;EAG1E,MAAM,SAAS,KAAK,iBAAiB,IAAI;EACzC,MAAM,OAAO,KAAK,KAAK,MAAM,UAAU;EACvC,IAAI,KAAK,aAAa,GAAG;GACvB,KAAK,MAAM,MAAM,WAAW;GAC5B,KAAK,MAAM,MAAM,QAAQ;GACzB,IAAI,KAAK,gBAAgB,MAAM,KAAK,MAAM,MAAM,mBAAmB;EACrE;EACA,IAAI,KAAK,WAAW,KAAK,WAAW;GAClC,KAAK,YAAY;GACjB,KAAK,MAAM,MAAM,oBAAoB;GACrC,KAAK,MAAM,oBAAoB;EACjC;EACA,KAAK,WAAW,MAAM;EACtB,KAAK,YAAY;EACjB,KAAK,UAAU,MAAM,QAAQ;EAC7B,KAAK,YAAY,KAAK;EACtB,KAAK,kBAAkB;EACvB,IAAI,aAAa,MAAM,UAAU,KAAK,UAAU,MAAM,SAAS;EAC/D,IAAI,MAAM,QAAQ,WAAW,WAC3B,KAAK,QAAQ,CAAC,MAAM,QAAQ,MAAM;OAC7B;GACL,KAAK,QAAQ;GACb,KAAK,QAAQ,MAAM,QAAQ;GAC3B,KAAK,eAAe;EACtB;EACA,MAAM,QAAQ,KAAK,iBAAiB,IAAI;EACxC,KAAK,MAAM,MAAM,sBAAsB,MAAM,OAAO,OAAO;EAC3D,KAAK,MAAM,MAAM,gBAAgB,MAAM,OAAO,OAAO;EACrD,IAAI,KAAK,UAAU,SAAS,KAAK,gBAAgB,MAAM,OAAO,OAAO;EAErE,IAAI,KAAK,SAAS,KAAK,MAAM,YAAY,KAAK;OACzC,KAAK,MAAM,YAAY,KAAK;EACjC,MAAM,aAAa,MAAM,cAAc;EACvC,KAAK,MAAM,cAAc;EACzB,KAAK,MAAM,MAAM,cAAc;EAC/B,KAAK,kBAAkB;EACvB,KAAK,MAAM,YAAY;EACvB,KAAK,MAAM,SAAS,MAAM,QAAQ,WAAW;CAC/C;CAEA,WAAmB,OAAiC,OAAqB;EACvE,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM;EACxC,IAAI,CAAC,MACH,MAAM,UAAU,gBAAgB,MAAM,QAAQ,0BAA0B,MAAM,QAAQ;EACxF,IAAI,KAAK,WAAW,MAAM,UAAU,QAAQ,MAAM,OAAO,qBAAqB;EAC9E,IAAI,KAAK,OAAO,MAAM,UAAU,QAAQ,MAAM,OAAO,qCAAqC;EAC1F,MAAM,SAAS,KAAK,iBAAiB,IAAI;EACzC,KAAK,YAAY,MAAM;EACvB,KAAK,kBAAkB;EACvB,MAAM,QAAQ,KAAK,iBAAiB,IAAI;EACxC,KAAK,MAAM,MAAM,sBAAsB,MAAM,OAAO,OAAO;EAC3D,KAAK,MAAM,MAAM,gBAAgB,MAAM,OAAO,OAAO;EACrD,IAAI,KAAK,UAAU,SAAS,KAAK,gBAAgB,MAAM,OAAO,OAAO;EACrE,IAAI,KAAK,aAAa,GAAG;GACvB,KAAK,MAAM,MAAM,aAAa;GAC9B,KAAK,MAAM,MAAM,QAAQ;EAC3B;EACA,KAAK,MAAM,IAAI,KAAK,MAAM,CAAC,CAAE,kBAAkB;CACjD;CAEA,WAAmB,OAA+B,OAAqB;EACrE,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,MAAM;EACxC,IAAI,CAAC,MAAM,MAAM,UAAU,YAAY,MAAM,QAAQ,2BAA2B,MAAM,QAAQ;EAC9F,IAAI,KAAK,QAAQ,WAAW,GAC1B,MAAM,UAAU,YAAY,MAAM,QAAQ,SAAS,MAAM,OAAO,iBAAiB;EAEnF,MAAM,SAAS,MAAM,SAAS;EAC9B,IAAI,WAAW,cAAc,CAAC,KAAK,UAAU,IAAI,MAAM,MAAM,GAAG;GAC9D,IAAI,KAAK,YAAY,GACnB,MAAM,UAAU,YAAY,MAAM,OAAO,iDAAiD;GAE5F,IAAI,KAAK,aAAa,GACpB,MAAM,UACJ,QAAQ,MAAM,OAAO,sFACvB;GAEF,IAAI,KAAK,UAAU,QAAA,GACjB,MAAM,UACJ,QAAQ,MAAM,OAAO,qBAAqB,KAAK,UAAU,OAAO,EAAE,wBACpE;GAEF,KAAK,UAAU,IAAI,MAAM,MAAM;EACjC;EACA,IAAI,WAAW,YAAY;GACzB,IAAI,KAAK,mBAAmB,QAAQ,KAAK,mBAAmB,MAAM,QAChE,MAAM,UACJ,QAAQ,MAAM,OAAO,sBAAsB,KAAK,eAAe,mBACjE;GAEF,IAAI,KAAK,gBAAgB,GACvB,MAAM,UAAU,QAAQ,MAAM,OAAO,0CAA0C;EAEnF;EACA,MAAM,WAAW,KAAK,UAAU,GAAG,EAAE,CAAC,EAAE,SAAS,UAAU;EAC3D,MAAM,eAAe,aAAa,QAAQ,aAAa;EACvD,MAAM,cAAc,WAAW;EAC/B,KAAK,MAAM,mBAAmB,cAAc,IAAI,MAAM,eAAe,IAAI;EACzE,IAAI,aAAa,cAAc,WAAW,YAAY,KAAK,iBAAiB;EAC5E,IAAI,WAAW,YAAY,KAAK,iBAAiB,MAAM;EACvD,IAAI,WAAW,YAAY,KAAK,WAAW;EAC3C,KAAK,UAAU,KAAK;GAClB,UAAU;GACV,UAAU,MAAM;GAChB,OAAO,MAAM;GACb,MAAM,MAAM;GACZ,QAAQ,MAAM;EAChB,CAAC;EACD,KAAK,kBAAkB;EACvB,KAAK,MAAM,iBAAiB,KAAK;CACnC;CAEA,MAAc,OAAgC;EAC5C,MAAM,UAAU,KAAK,kBAAkB;EACvC,IAAI,QAAQ,SAAS,GACnB,MAAM,UAAU,mCAAmC,QAAQ,KAAK,IAAI,GAAG;EAEzE,IAAI,MAAM,OAAO,KAAK,WAAW,MAAM,KAAK;EAC5C,KAAK,SAAS;EACd,KAAK,MAAM,SAAS;EACpB,KAAK,MAAM,cAAc,MAAM;EAE/B,KAAK,MAAM,MAAM,qBAAqB;CACxC;CAEA,WAAmB,OAA0B;EAC3C,MAAM,QAAQ,MAAM,UAAU,KAAK,aAAa,SAAS,MAAM;EAC/D,aAAa,OAAO,kBAAkB,eAAe;EACrD,KAAK,MAAM,UAAU,OACnB,IAAI,CAAC,KAAK,UAAU,IAAI,MAAM,GAC5B,MAAM,UAAU,kBAAkB,OAAO,4BAA4B;EAKzE,KAAK,MAAM,UAAU,KAAK,WACxB,IAAI,CAAC,MAAM,SAAS,MAAM,GACxB,MAAM,UAAU,YAAY,OAAO,2BAA2B;EAGlE,MAAM,OAAO,KAAK,UAAU,MAAM;EAClC,MAAM,cAAc,KAAK,IAAI,MAAM,cAAc,KAAK,IAAI,GAAG,MAAM,MAAM;EACzE,KAAK,MAAM,YAAY,MAAM,WAAW;GACtC,MAAM,EAAE,UAAU,SAAS;GAC3B,IAAI,aAAa,SAAS,YAAY,QAAQ,SAAS,UAAU,SAC/D,MAAM,UACJ,kBAAkB,SAAS,OAAO,4DACpC;GAEF,IAAI,QAAQ,KAAK,IAAI,KAAK,aAAa,WAAW,IAAI,OACpD,MAAM,UACJ,kBAAkB,SAAS,OAAO,2BAA2B,KAAK,WAAW,IAAI,MAAM,OAAO,4BAA4B,MAAM,WAAW,QAAQ,aACrJ;GAEF,IAAI,SAAS,WAAW,SAAS,MAC/B,MAAM,UAAU,kBAAkB,SAAS,OAAO,4BAA4B;EAElF;EACA,IAAI,MAAM,aAAa,KAAK,gBAC1B,MAAM,UACJ,qBAAqB,MAAM,YAAY,UAAU,4BAA4B,KAAK,kBAAkB,QACtG;EAEF,IAAI,MAAM,aAAa,QAAQ;GAC7B,MAAM,UAAU,MAAM,UAAU,MAAM,aAAa,SAAS,WAAW,MAAM,QAAQ;GACrF,IAAI,MAAM,aAAa,QAAQ,MAAM,aAAa,QAAQ,CAAC,SAAS,SAClE,MAAM,UAAU,mEAAmE;GAErF,IAAI,CAAC,KAAK,OAAQ,OAAO,cACvB,MAAM,UAAU,iEAAiE;GAEnF,IAAI,aAAa,KAAK,OAAQ,UAAU,OACtC,MAAM,UACJ,0GACF;GAEF,MAAM,YAAY,IAAI,IAAI,KAAK,OAAQ,OAAO,KAAK,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC;GACnF,KAAK,MAAM,UAAU,CAAC,MAAO,MAAM,QAAQ,GAAG;IAC5C,MAAM,SAAS,IAAI,IAAI,KAAK,gBAAgB,QAAQ,MAAM,CAAC,CAAC,KAAK,SAAS,KAAK,MAAM,CAAC;IACtF,MAAM,UAAU,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC;IACjE,IAAI,QAAQ,SAAS,GACnB,MAAM,UACJ,2EAA2E,OAAO,eAAe,QAAQ,KAAK,IAAI,GACpH;GAEJ;EACF,OAAO,IAAI,MAAM,aAAa,QAAQ,MAAM,aAAa,MACvD,MAAM,UAAU,KAAK,MAAM,SAAS,qDAAqD;EAE3F,IAAI,MAAM,aAAa,uBAChB;QAAA,MAAM,QAAQ,KAAK,MAAM,OAAO,GACnC,IAAI,KAAK,UAAU,UAAU,KAAK,WAAW,GAC3C,MAAM,UAAU,0DAA0D;EAAA;CAIlF;;;CAIA,gBAAwB,SAAuB;EAC7C,IAAI,KAAK,UAAU,OAAO,KAAK,KAAK,aAAa,GAC/C,MAAM,UACJ,GAAG,QAAQ,oFACb;CAEJ;;CAGA,oBAA8B;EAC5B,MAAM,UAAoB,CAAC;EAC3B,IAAI,CAAC,KAAK,QAAQ,QAAQ,KAAK,0BAA0B;EACzD,IAAI,KAAK,MAAM,MAAM,OAAO,GAC1B,QAAQ,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,QAAQ,gBAAgB,CAAC;EACrE,IAAI,KAAK,MAAM,WAAW,OAAO,GAC/B,QAAQ,KAAK,MAAM,KAAK,MAAM,WAAW,MAAM,aAAa,eAAe,CAAC;EAE9E,IAAI,KAAK,MAAM,mBAAmB,GAChC,QAAQ,KAAK,MAAM,KAAK,MAAM,kBAAkB,QAAQ,aAAa,CAAC;EAExE,IAAI,KAAK,MAAM,iBAAiB,GAC9B,QAAQ,KAAK,MAAM,KAAK,MAAM,gBAAgB,QAAQ,0BAA0B,CAAC;EAEnF,OAAO;CACT;;;CAIA,KAAa,YAAwE;EACnF,MAAM,EAAE,QAAQ,SAAS;EACzB,IAAI,OAAO,WAAW,SAAS;GAC7B,KAAK,MAAM,OAAO,eAAe,OAAO;GACxC,KAAK,MAAM,OAAO,gBAAgB,OAAO;GACzC,KAAK,MAAM,OAAO,gBAAgB,OAAO;EAC3C,OACE,KAAK,MAAM,OAAO,wBAAwB;EAE5C,MAAM,MAAM,KAAK,WAAW,UAAU,KAAK,MAAM,KAAK;EACtD,IAAI,KAAK,WAAW,SAAS,KAAK,MAAM,MAAM,YAAY;OACrD,KAAK,MAAM,MAAM,YAAY;EAClC,KAAK,MAAM,MAAM,gBAAgB;EACjC,OAAO;GAAE;GAAK,SAAS,KAAK,WAAW;EAAU;CACnD;;;CAIA,iBAAyB,MAAgE;EACvF,MAAM,WAAW,KAAK,aAAa,OAAO;EAC1C,MAAM,UAAU,CAAC,KAAK,SAAS,KAAK,cAAc;EAClD,OAAO;GACL,MAAM,UAAU,KAAK,IAAI,GAAG,WAAW,KAAK,QAAQ,IAAI;GACxD,MAAM,KAAK,cAAc,KAAK,IAAI,GAAG,KAAK,WAAW,QAAQ,IAAI;GACjE,MAAM,UAAU,KAAK,IAAI,UAAU,KAAK,QAAQ,IAAI,KAAK;EAC3D;CACF;;;;;;;;;;;CAYA,MAAc,aAAuC,OAAgB,SAAuB;EAC1F,MAAM,EAAE,QAAQ,qBAAqB,KAAK,OAAQ;EAClD,MAAM,OAAO,aAAa,OAAO;EACjC,IAAI,WAAW,QAAQ,SAAS,GAAG;EACnC,MAAM,iBAAiB,KAAK,IAAI,GAAG,mBAAmB,KAAK,YAAY;EACvE,IAAI,SAAS,QAAQ,iBAAiB,eAAe;EAMrD,IAJE,KAAK,MAAM,MAAM,eACjB,KAAK,MAAM,MAAM,sBAChB,QAAQ,IAAI,kBACb,OACU,SAAS,eACnB,MAAM,UACJ,GAAG,QAAQ,iCAAiC,MAAM,KAAK,MAAM,MAAM,YAAY,EAAE,WAAW,MAAM,KAAK,MAAM,MAAM,kBAAkB,EAAE,oBAAoB,MAAM,cAAc,EAAE,WAAW,MAAM,IAAI,EAAE,oBAAoB,QAC9N;CAEJ;;;CAMA,aAAsE;EACpE,MAAM,EAAE,QAAQ,qBAAqB,KAAK,QAAQ,UAAU;GAC1D,QAAQ;GACR,kBAAkB;EACpB;EACA,MAAM,kBAAkB,KAAK,IAAI,GAAG,mBAAmB,KAAK,YAAY;EACxE,IAAI,WAAW,MAAM,OAAO;GAAE,aAAa;GAAM;EAAgB;EACjE,MAAM,OACJ,KAAK,MAAM,MAAM,eAAe,KAAK,MAAM,MAAM,qBAAqB;EACxE,OAAO;GAAE,aAAa,KAAK,IAAI,GAAG,SAAS,IAAI;GAAG;EAAgB;CACpE;;CAGA,aAAuC;EACrC,OAAO,KAAK;CACd;;CAGA,aAAuC;EACrC,OAAO,KAAK;CACd;;CAGA,WAAqE;EACnE,OAAO,KAAK;CACd;;CAGA,qBAAoC;EAClC,OAAO,KAAK;CACd;;CAGA,YAAyB;EACvB,MAAM,QAAQ,KAAK;EACnB,OAAO;GACL,GAAG;GACH,OAAO,EAAE,GAAG,MAAM,MAAM;GACxB,OAAO,EAAE,GAAG,MAAM,MAAM;GACxB,UAAU,EAAE,GAAG,MAAM,SAAS;GAC9B,YAAY,EAAE,GAAG,MAAM,WAAW;GAClC,OAAO,EAAE,GAAG,MAAM,MAAM;GACxB,QAAQ,EAAE,GAAG,MAAM,OAAO;EAC5B;CACF;;CAGA,SAAS,QAAwC;EAC/C,MAAM,SAAS,KAAK,MAAM,IAAI,MAAM;EACpC,OAAO,SAAS,SAAS,MAAM,IAAI,KAAA;CACrC;;CAGA,cAAiC;EAC/B,OAAO,KAAK;CACd;;CAGA,YAAY,QAAyB;EACnC,OAAO,KAAK,MAAM,IAAI,MAAM;CAC9B;;CAGA,oBAAoB,gBAA4C;EAC9D,OAAO,KAAK,aAAa,IAAI,cAAc;CAC7C;;CAGA,SAAS,QAAqD;EAC5D,OAAO,KAAK,MAAM,IAAI,MAAM;CAC9B;;CAGA,cAAiC;EAC/B,OAAO,KAAK;CACd;;CAGA,SAAS,QAAwC;EAC/C,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM;EAClC,OAAO,OAAO,EAAE,GAAG,KAAK,IAAI,KAAA;CAC9B;;CAGA,YAAY,QAAoC;EAC9C,IAAI,WAAW,KAAA,GAAW,OAAO,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC;EACtD,OAAO,KAAK,MAAM,IAAI,MAAM,CAAC,EAAE,WAAW,CAAC;CAC7C;;CAGA,cAAc,aAAkD;EAC9D,MAAM,YAAY,KAAK,WAAW,IAAI,WAAW;EACjD,OAAO,YAAY,EAAE,GAAG,UAAU,IAAI,KAAA;CACxC;;CAGA,gBAAgB,QAAgB,OAAwC;EACtE,MAAM,SAA6B,CAAC;EACpC,KAAK,MAAM,UAAU,KAAK,MAAM,IAAI,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG;GAC1D,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM;GAClC,IAAI,KAAK,UAAU,SAAS,KAAK,UAAU,MACzC,OAAO,KAAK;IAAE;IAAQ,QAAQ,KAAK;IAAQ,SAAS,KAAK;IAAU,OAAO,KAAK;GAAM,CAAC;EAE1F;EACA,OAAO;CACT;AACF;;;;;;AAOA,IAAa,kBAAb,MAA6B;CAC3B;CACA;CACA;CACA;;CAEA;CACA;CACA;;;;;;;CAOA;CACA;CACA;CAEA,YAAY,OAAoB,SAAiB;EAC/C,KAAK,QAAQ;EACb,KAAK,UAAU;EACf,KAAK,WAAW,MAAM;EACtB,KAAK,SAAS,MAAM,WAAW;EAC/B,KAAK,SAAS,MAAM,WAAW;EAC/B,KAAK,OAAO,MAAM,SAAS;EAC3B,KAAK,iBAAiB,MAAM,mBAAmB;EAC/C,KAAK,QAAQ,MAAM,UAAU;EAC7B,KAAK,SAAS,MAAM,WAAW;EAC/B,MAAM,UAAU,MAAM,kBAAkB;EACxC,IAAI,CAAC,KAAK,QAAQ,QAAQ,QAAQ,gBAAgB;EAClD,KAAK,aAAa;GAAE,UAAU,KAAK,WAAW;GAAM;EAAQ;CAC9D;;CAGA,IAAI,aAA4B;EAC9B,OAAO,KAAK,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM;CACzC;CAEA,KAAK,QAAwC;EAC3C,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM;CACpC;CAEA,QAAQ,QAAyB;EAC/B,OAAO,KAAK,KAAK,CAAC,CAAC,YAAY,MAAM;CACvC;;CAGA,UAAoB;EAClB,OAAO,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,YAAY,CAAC;CACtC;;CAGA,QAAsB;EACpB,MAAM,QAAQ,KAAK,KAAK;EACxB,OAAO,MAAM,YAAY,CAAC,CAAC,KAAK,WAAW,MAAM,SAAS,MAAM,CAAE;CACpE;CAEA,gBAAgB,gBAA4C;EAC1D,OAAO,KAAK,KAAK,CAAC,CAAC,oBAAoB,cAAc;CACvD;CAEA,KAAK,QAAqD;EACxD,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM;CACpC;;CAGA,QAAmC;EACjC,MAAM,QAAQ,KAAK,KAAK;EACxB,OAAO,MAAM,YAAY,CAAC,CAAC,KAAK,WAAW,MAAM,SAAS,MAAM,CAAE;CACpE;CAEA,KAAK,QAAwC;EAC3C,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM;CACpC;;CAGA,MAAM,SAA8B,CAAC,GAAiB;EACpD,MAAM,QAAQ,KAAK,KAAK;EACxB,OAAO,MAAM,YAAY,OAAO,MAAM,CAAC,CAAC,KAAK,WAAW,MAAM,SAAS,MAAM,CAAE;CACjF;CAEA,UAAU,aAAkD;EAC1D,OAAO,KAAK,KAAK,CAAC,CAAC,cAAc,WAAW;CAC9C;;;CAIA,YAAY,QAAgB,OAAwC;EAClE,OAAO,KAAK,KAAK,CAAC,CAAC,gBAAgB,QAAQ,KAAK;CAClD;;CAGA,WAAW,QAAgB,OAAuC;EAChE,OAAO,iBAAiB,KAAK,YAAY,QAAQ,KAAK,CAAC;CACzD;;CAGA,QAAQ,aAAyD;EAC/D,MAAM,QAAQ,KAAK,KAAK;EACxB,IAAI,YAAY,aAAa,KAAK,UAChC,MAAM,IAAI,kBACR,2BAA2B,YAAY,SAAS,QAAQ,KAAK,UAC/D;EAEF,MAAM,OAAO,MAAM,SAAS,YAAY,MAAM;EAC9C,IAAI,CAAC,QAAQ,KAAK,WAAW,YAAY,QACvC,MAAM,IAAI,kBACR,QAAQ,YAAY,OAAO,WAAW,YAAY,OAAO,oBAAoB,KAAK,UACpF;EAEF,IAAI,YAAY,UAAU,KAAK,YAAY,UAAU,KAAK,UACxD,MAAM,IAAI,kBACR,QAAQ,YAAY,OAAO,OAAO,KAAK,SAAS,mCAAmC,YAAY,SACjG;EAEF,MAAM,OAAO,MAAM,SAAS,KAAK,MAAM;EACvC,IAAI,KAAK,UAAU,MACjB,MAAM,IAAI,kBACR,QAAQ,KAAK,OAAO,8CACtB;EAEF,MAAM,cAAc,KAAK,QAAQ,eAAe;EAChD,OAAO;GACL,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,KAAK,KAAK;GACV,iBAAiB,cACb,gBAAgB;IAAE,QAAQ,YAAY;IAAQ,SAAS,YAAY;GAAQ,CAAC,IAC5E;EACN;CACF;CAEA,OAA4B;EAC1B,IAAI,CAAC,KAAK,MAAM,KAAK,KAAK,OAAO,GAC/B,MAAM,IAAI,kBACR,yCAAyC,KAAK,MAAM,YAAY,GAAG,6DACrE;EAEF,OAAO,KAAK;CACd;AACF;AAEA,SAAS,SAAS,QAAgC;CAChD,MAAM,SAAS,OAAO,UAAU,GAAG,EAAE,CAAC,EAAE,YAAY;CACpD,OAAO;EACL,QAAQ,OAAO,MAAM;EACrB,SAAS,OAAO;EAChB,gBAAgB,OAAO,MAAM;EAC7B,UAAU,OAAO,MAAM;EACvB,UAAU,OAAO,MAAM;EACvB,iBAAiB,OAAO;EACxB,OAAO,OAAO;EACd,SAAS,CAAC,GAAG,OAAO,OAAO;EAC3B,UAAU,CAAC,GAAG,OAAO,QAAQ;EAC7B,SAAS,CAAC,GAAG,OAAO,OAAO;EAC3B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,WAAW,aAAa,OAAO,OAAO;EACpD,UAAU,OAAO;EACjB,WAAW,CAAC,GAAG,OAAO,SAAS;EAC/B,WAAW,OAAO,QAAQ;EAC1B,OAAO,EAAE,GAAG,OAAO,MAAM;EACzB,oBAAoB,OAAO;EAC3B,iBAAiB,OAAO;CAC1B;AACF;AAEA,SAAS,iBACP,QACA,OACA,OACA,QACM;CASN,IAAI,CAAC;EAPH,MAAM,CAAC,SAAS,WAAW;EAC3B,OAAO,CAAC,OAAO;EACf,QAAQ,CAAC,WAAW;EACpB,MAAM,CAAC,WAAW;EAClB,OAAO,CAAC,MAAM;EACd,UAAU,CAAC,SAAS,WAAW;CAEtB,EAAE,MAAM,CAAC,SAAS,KAAK,GAChC,MAAM,UAAU,QAAQ,OAAO,MAAM,MAAM,0BAA0B,MAAM,OAAO;CAEpF,IAAI,UAAU,UAAU,CAAC,QACvB,MAAM,UAAU,QAAQ,OAAO,qCAAqC;AAExE;AAEA,SAAS,aAAa,QAA2B,OAAe,SAAuB;CACrF,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,SAAS,OAAO,QAClC,MAAM,UAAU,SAAS,QAAQ,sBAAsB,MAAM,QAAQ;AAEzE;AAEA,SAAS,MAAM,OAAe,MAAc,WAA2B;CACrE,MAAM,OAAO,UAAU,QAAQ,eAAe,SAC5C,UAAU,IAAI,OAAO,SAAS,SAAS,UAAU,MACnD;CACA,OAAO,GAAG,MAAM,GAAG,UAAU,IAAI,OAAO,GAAG,KAAK,GAAG,GAAG;AACxD;AAEA,SAAS,MAAM,KAAqB;CAClC,OAAO,KAAK,MAAM,MAAM,GAAG,IAAI;AACjC;AAEA,SAAS,UAAU,SAA6C;CAC9D,OAAO,IAAI,2BAA2B,OAAO;AAC/C;;;;;;;;ACh0CA,MAAa,uBAAuB;;;;;;;;;;;;;;;;;;;;;;AC4CpC,MAAM,YAAY,EACf,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,QAAQ,UAAU,MAAM,KAAK,MAAM,OAAO,yCAAyC;AAEtF,MAAM,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,uBAAuB;AAErD,MAAM,qBAAqB,EACxB,OAAO,CAAC,CACR,MAAM,4EAA4E;AAErF,MAAM,gBAAgB,EACnB,OAAO,CAAC,CACR,MAAM,oDAAoD,CAAC,CAC3D,QAAQ,UAAU,OAAO,SAAS,KAAK,MAAM,KAAK,CAAC,GAAG,mBAAmB;AAE5E,MAAM,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK;AAC7D,MAAM,eAAe,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK;AACtD,MAAM,gBAAgB,EAAE,OAAO,CAAC,CAAC,OAAO;AACxC,MAAM,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY;AAE5C,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,MAAM,qBAAqB;AACtD,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,MAAM,qBAAqB;AAEtD,MAAM,oBAAoB,EACvB,OAAO;CAAE,MAAM;CAAW,KAAK;CAAW,QAAQ;CAAM,YAAY;AAAiB,CAAC,CAAC,CACvF,OAAO;AAEV,MAAM,kBAAkB,EAAE,OAAO;CAAE,KAAK;CAAW,UAAU;AAAmB,CAAC,CAAC,CAAC,OAAO;AAE1F,MAAM,mBAAmB,EAAE,OAAO,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO;AAEjE,MAAM,sBAAsB,EAAE,OAAO;CAAE,MAAM;CAAW,SAAS;AAAU,CAAC,CAAC,CAAC,OAAO;AAErF,MAAM,sBAAsB,EAAE,MAAM,CAClC,EACG,OAAO;CACN,UAAU;CACV,UAAU,UAAU,OAAO,kBAAkB,0CAA0C;AACzF,CAAC,CAAC,CACD,OAAO,GACV,EAAE,OAAO;CAAE,UAAU;CAAW,OAAO;CAAW,SAAS;AAAU,CAAC,CAAC,CAAC,OAAO,CACjF,CAAC;AAED,MAAM,0BAA0B,EAC7B,OAAO;CAAE,OAAO;CAAqB,OAAO;CAAiB,WAAW;AAAgB,CAAC,CAAC,CAC1F,OAAO;AAEV,MAAM,gBAAgB;CACpB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,QAAQ,EAAE,KAAK;CAAC;CAAS;CAAa;AAAM,CAAC;AAEnD,MAAM,oBAAoB,EAAE,OAAO;CAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,UAAU,CAAC;CAAG,KAAK;AAAI,CAAC,CAAC,CAAC,OAAO;AAE5F,MAAM,iBAAiB;CACrB,SAAS;CACT,YAAY;CACZ,WAAW,EAAE,MAAM,iBAAiB;AACtC;AAEA,MAAM,sBAAsB,EAAE,KAAK;CACjC;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,oBAAoB,EACvB,OAAO;CACN,QAAQ,EAAE,QAAQ,OAAO;CACzB,aAAa;CACb,cAAc;CACd,cAAc;AAChB,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,sBAAsB,EAAE,OAAO;CAAE,QAAQ,EAAE,QAAQ,SAAS;CAAG,QAAQ;AAAU,CAAC,CAAC,CAAC,OAAO;AAEjG,MAAM,kBAAkB,EACrB,OAAO;CACN,QAAQ,EAAE,QAAQ,OAAO;CACzB,KAAK;CACL,QAAQ,EAAE,KAAK;EAAC;EAAY;EAAiB;CAAM,CAAC;AACtD,CAAC,CAAC,CACD,OAAO,CAAC,CACR,aAAa,MAAM,QAAQ;CAC1B,IAAI,KAAK,WAAW,UAAU,KAAK,QAAQ,GACzC,IAAI,SAAS;EAAE,MAAM;EAAU,SAAS;CAAmC,CAAC;AAEhF,CAAC;AAEH,MAAM,oBAAoB,EACvB,OAAO;CAAE,QAAQ,EAAE,QAAQ,SAAS;CAAG,oBAAoB;CAAK,QAAQ;AAAU,CAAC,CAAC,CACpF,OAAO;AAEV,MAAM,mBAAmB,EACtB,OAAO;CACN,QAAQ,EAAE,mBAAmB,UAAU,CAAC,mBAAmB,mBAAmB,CAAC;CAC/E,MAAM,EAAE,mBAAmB,UAAU,CAAC,iBAAiB,iBAAiB,CAAC;AAC3E,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,gBAAgB,EAAE,OAAO,WAAW,aAAa,CAAC,CAAC,aAAa,SAAS,QAAQ;CACrF,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GACnC,IAAI,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ,aAC1D,IAAI,SAAS;EAAE,MAAM;EAAU,SAAS,qBAAqB;CAAM,CAAC;AAG1E,CAAC;AAED,MAAM,gBAAgB,EAAE,mBAAmB,UAAU;CACnD,EAAE,OAAO;EAAE,QAAQ,EAAE,QAAQ,QAAQ;EAAG,OAAO;EAAe,SAAS;CAAc,CAAC,CAAC,CAAC,OAAO;CAC/F,EACG,OAAO;EACN,QAAQ,EAAE,QAAQ,QAAQ;EAC1B,OAAO;EACP,SAAS;EACT,SAAS;CACX,CAAC,CAAC,CACD,OAAO;CACV,EACG,OAAO;EACN,QAAQ,EAAE,QAAQ,SAAS;EAC3B,SAAS;EACT,OAAO,oBAAoB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO;CACvE,CAAC,CAAC,CACD,OAAO;AACZ,CAAC;AAED,MAAM,eAAe,EAAE,mBAAmB,UAAU,CAClD,EACG,OAAO;CACN,QAAQ,EAAE,QAAQ,UAAU;CAC5B,QAAQ;CACR,eAAe;CACf,gBAAgB;CAChB,OAAO;AACT,CAAC,CAAC,CACD,OAAO,CAAC,CACR,aAAa,QAAQ,QAAQ;CAC5B,MAAM,WAAW,OAAO,iBAAiB,OAAO;CAChD,MAAM,YAAY,OAAO,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,GAAG,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI;CAC7F,IAAI,KAAK,IAAI,OAAO,QAAQ,QAAQ,IAAI,WACtC,IAAI,SAAS;EAAE,MAAM;EAAU,SAAS;CAAkD,CAAC;AAE/F,CAAC,GACH,EAAE,OAAO;CAAE,QAAQ,EAAE,QAAQ,cAAc;CAAG,QAAQ;AAAU,CAAC,CAAC,CAAC,OAAO,CAC5E,CAAC;AAED,MAAM,wBAAwB,EAC3B,OAAO;CACN,WAAW;CACX,OAAO,EAAE,QAAQ;CACjB,aAAa;CACb,QAAQ;CACR,UAAU,EAAE,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC,CAAC,CACD,OAAO,CAAC,CACR,aAAa,UAAU,QAAQ;CAC9B,IAAI,SAAS,UAAU,SAAS,cAAc,GAC5C,IAAI,SAAS;EAAE,MAAM;EAAU,SAAS;CAAmC,CAAC;CAE9E,IAAI,CAAC,SAAS,SAAS,SAAS,OAAO,WAAW,cAAc,SAAS,OAAO,UAAU,GACxF,IAAI,SAAS;EAAE,MAAM;EAAU,SAAS;CAA4C,CAAC;AAEzF,CAAC;AAEH,MAAM,aAAa,EAChB,OAAO;CAAE,QAAQ;CAAW,QAAQ;CAAW,QAAQ;AAAgB,CAAC,CAAC,CACzE,OAAO;AAEV,MAAM,mBAAmB,EAAE,OAAO;CAAE,eAAe;CAAM,OAAO,EAAE,MAAM,UAAU;AAAE,CAAC,CAAC,CAAC,OAAO;AAE9F,MAAM,qBAAqB,EACxB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,eAAe;CAC/B,SAAS;CACT,SAAS,EAAE,OAAO;EAAE,MAAM;EAAW,cAAc;CAAgB,CAAC,CAAC,CAAC,OAAO;CAC7E,cAAc,EAAE,KAAK,CAAC,GAAG,eAAe,QAAQ,CAAC;CACjD,WAAW,EACR,OAAO;EACN,QAAQ;EACR,WAAW,EAAE,KAAK,CAAC,YAAY,UAAU,CAAC;EAC1C,OAAO,EAAE,MAAM,CAAC,iBAAiB,gBAAgB,CAAC;EAClD,OAAO;CACT,CAAC,CAAC,CACD,OAAO;CACV,QAAQ,EACL,OAAO;EACN,OAAO;EACP,WAAW;EACX,MAAM;EACN,cAAc,EAAE,QAAQ;CAC1B,CAAC,CAAC,CACD,OAAO;CACV,QAAQ,EACL,OAAO;EAAE,WAAW;EAAW,YAAY;EAAW,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK;CAAE,CAAC,CAAC,CACtF,OAAO;CACV,QAAQ,EACL,OAAO;EACN,QAAQ,IAAI,SAAS;EACrB,UAAU,aAAa,SAAS;EAChC,UAAU,aAAa,SAAS;EAChC,UAAU,cAAc,SAAS;EACjC,gBAAgB,aAAa,SAAS;EACtC,kBAAkB;CACpB,CAAC,CAAC,CACD,OAAO;CACV,aAAa,EACV,OAAO;EAAE,UAAU;EAAW,QAAQ;EAAS,SAAS;CAAa,CAAC,CAAC,CACvE,OAAO,CAAC,CACR,SAAS;CACZ,aAAa,EACV,OAAO;EAAE,UAAU;EAAW,QAAQ;EAAS,UAAU;CAAK,CAAC,CAAC,CAChE,OAAO,CAAC,CACR,SAAS;CACZ,UAAU;AACZ,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,yBAAyB,EAC5B,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,mBAAmB;CACnC,aAAa;CACb,eAAe;CACf,aAAa,kBAAkB,SAAS;AAC1C,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,0BAA0B,EAC7B,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,oBAAoB;CACpC,aAAa;CACb,eAAe;CACf,WAAW,EAAE,mBAAmB,QAAQ,CACtC,EACG,OAAO;EAAE,MAAM,EAAE,QAAQ,OAAO;EAAG,OAAO;EAAqB,QAAQ;CAAgB,CAAC,CAAC,CACzF,OAAO,GACV,EAAE,OAAO;EAAE,MAAM,EAAE,QAAQ,eAAe;EAAG,QAAQ;CAAgB,CAAC,CAAC,CAAC,OAAO,CACjF,CAAC;CACD,SAAS,EAAE,mBAAmB,UAAU;EACtC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO;EACpD,EAAE,OAAO;GAAE,QAAQ,EAAE,QAAQ,SAAS;GAAG,SAAS;EAAoB,CAAC,CAAC,CAAC,OAAO;EAChF,EAAE,OAAO;GAAE,QAAQ,EAAE,QAAQ,QAAQ;GAAG,SAAS;EAAoB,CAAC,CAAC,CAAC,OAAO;CACjF,CAAC;CACD,YAAY;AACd,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,uBAAuB,EAC1B,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,iBAAiB;CACjC,QAAQ;CACR,gBAAgB;CAChB,UAAU;CACV,UAAU,EAAE,MACV,EACG,OAAO;EAAE,WAAW;EAAW,MAAM,EAAE,KAAK,aAAa;EAAG,UAAU;CAAkB,CAAC,CAAC,CAC1F,OAAO,CACZ;AACF,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,gBAAgB,EAAE,OAAO;CAAE,UAAU;CAAW,QAAQ;AAAQ,CAAC,CAAC,CAAC,OAAO;AAEhF,MAAM,0BAA0B,EAAE,MAAM,CAAC,mBAAmB,gBAAgB,CAAC;AAE7E,MAAM,qBAAqB,EACxB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,eAAe;CAC/B,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,qBAAqB;CAC9C,aAAa;CACb,SAAS,EAAE,MAAM,aAAa;CAC9B,UAAU,EAAE,KAAK;EAAC;EAAQ;EAAS;EAAW;EAAS;EAAS;CAAQ,CAAC;CACzE,aAAa,EAAE,KAAK;EAAC;EAAY;EAAc;CAAS,CAAC;CACzD,UAAU,EACP,OAAO;EACN,MAAM,EAAE,KAAK;GAAC;GAAS;GAAmB;GAAS;GAAa;EAAU,CAAC;EAC3E,MAAM;EACN,aAAa,UAAU,SAAS;EAChC,QAAQ;CACV,CAAC,CAAC,CACD,OAAO,CAAC,CACR,SAAS;CACZ,WAAW,EACR,OAAO;EAAE,MAAM;EAAW,UAAU,EAAE,OAAO,WAAW,aAAa;CAAE,CAAC,CAAC,CACzE,OAAO,CAAC,CACR,SAAS;CACZ,WAAW;CACX,OAAO,EAAE,MAAM,uBAAuB;CACtC,OAAO,EAAE,OAAO;AAClB,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,sBAAsB,EACzB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,gBAAgB;CAChC,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,KAAK;CACL,OAAO,EAAE,KAAK;EAAC;EAAQ;EAAS;EAAU;EAAQ;EAAS;CAAU,CAAC;CACtE,MAAM,UAAU,SAAS;CACzB,aAAa,kBAAkB,SAAS;AAC1C,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,iBAAiB,EAAE,MAAM,CAC7B,EACG,OAAO;CACN,SAAS;CACT,WAAW,UAAU,SAAS;CAC9B,cAAc,iBAAiB,SAAS;CACxC,cAAc,iBAAiB,SAAS;AAC1C,CAAC,CAAC,CACD,OAAO,GACV,gBACF,CAAC;AAED,MAAM,eAAe,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY;AAErD,MAAM,oBAAoB,EACvB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,cAAc;CAC9B,QAAQ;CACR,SAAS;CACT,OAAO;CACP,SAAS;CACT,YAAY;CACZ,YAAY,aAAa,SAAS;CAClC,QAAQ,aAAa,SAAS;CAC9B,SAAS,aAAa,SAAS;CAC/B,WAAW,EAAE,OAAO;EAAE,MAAM;EAAW,OAAO,UAAU,SAAS;CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS;CACxF,UAAU;CACV,iBAAiB,EAAE,MAAM,qBAAqB;CAC9C,UAAU;AACZ,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,sBAAsB,EACzB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,gBAAgB;CAChC,QAAQ;CACR,QAAQ,EAAE,KAAK;EAAC;EAAU;EAAU;EAAY;CAAS,CAAC;AAC5D,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,qBAAqB,EACxB,OAAO;CACN,SAAS;CACT,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO,cAAc,SAAS;CAC9B,UAAU,EAAE,MAAM,CAAC,eAAe,aAAa,CAAC,CAAC,CAAC,SAAS;CAC3D,QAAQ,EAAE,KAAK;EAAC;EAAQ;EAAgB;EAAe;CAAW,CAAC;CACnE,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC9C,eAAe,EAAE,QAAQ;CACzB,eAAe;CACf,WAAW;AACb,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,oBAAoB,EACvB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,cAAc;CAC9B,QAAQ;CACR,UAAU,EAAE,mBAAmB,UAAU;EACvC,EAAE,OAAO;GAAE,QAAQ,EAAE,QAAQ,UAAU;GAAG,MAAM;EAAiB,CAAC,CAAC,CAAC,OAAO;EAC3E,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO;EACjD,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO;EAClD,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO;EACnD,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO;EACnD,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO;CACrD,CAAC;CACD,OAAO,mBAAmB,SAAS;CACnC,MAAM;CACN,QAAQ;AACV,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAExC,MAAM,uBAAuB,EAAE,mBAAmB,QAAQ,CACxD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO,GACnD,EAAE,OAAO;CAAE,MAAM,EAAE,QAAQ,QAAQ;CAAG,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS;AAAE,CAAC,CAAC,CAAC,OAAO,CACxF,CAAC;AAED,MAAM,cAAc,EACjB,OAAO;CACN,MAAM;CACN,YAAY;CACZ,OAAO,EAAE,MAAM,CACb,EACG,OAAO;EACN,UAAU,EAAE,QAAQ;EACpB,eAAe,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS;EAC5C,sBAAsB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;EAC7C,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;EACnC,OAAO;EACP,WAAW;EACX,gBAAgB,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY;EAChD,WAAW;CACb,CAAC,CAAC,CACD,OAAO,GACV,gBACF,CAAC;CACD,WAAW,EAAE,MACX,EACG,OAAO;EACN,QAAQ;EACR,UAAU,mBAAmB,SAAS;EACtC,MAAM,EACH,OAAO;GACN,OAAO;GACP,YAAY;GACZ,QAAQ,EAAE,KAAK;IAAC;IAAkB;IAAgB;GAAY,CAAC;GAC/D,OAAO;GACP,UAAU,EAAE,MAAM,CAAC,eAAe,aAAa,CAAC;EAClD,CAAC,CAAC,CACD,OAAO,CAAC,CACR,SAAS;EACZ,SAAS,EAAE,QAAQ;CACrB,CAAC,CAAC,CACD,OAAO,CACZ;CACA,UAAU,QAAQ,SAAS;CAC3B,UAAU,EAAE,KAAK;EAAC;EAAQ;EAAQ;CAAqB,CAAC;CACxD,QAAQ;AACV,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,qBAAqB,EACxB,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,eAAe;CAC/B,QAAQ,EAAE,KAAK;EAAC;EAAU;EAAY;EAAa;EAAY;EAAa;CAAS,CAAC;CACtF,OAAO,YAAY,SAAS;AAC9B,CAAC,CAAC,CACD,OAAO;AAEV,MAAM,cAAc,EAAE,mBAAmB,QAAQ;CAC/C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,cAAc,EACjB,OAAO;CACN,QAAQ,EAAE,QAAQ,oBAAoB;CACtC,UAAU;CACV,UAAU;CACV,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CACtC,OAAO;CACP,WAAW;AACb,CAAC,CAAC,CACD,OAAO;;;AAIV,SAAgB,0BAA0B,OAAmC;CAC3E,MAAM,SAAS,YAAY,UAAU,KAAK;CAC1C,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,kBAAkB,gCAAgC,eAAe,OAAO,KAAK,GAAG;CAE5F,OAAO,eAAe,OAAO,IAAyB;AACxD;;;AAwDA,SAAgB,iBAAiB,SAAgD;CAC/E,IAAI,QAAQ,OAAO,OAAO,IAAI,mBAAmB,QAAQ,MAAM,QAAQ,UAAU,QAAQ,KAAK;CAC9F,OAAO,IAAI,iBAAiB,QAAQ,MAAM,QAAQ,UAAU,QAAQ,WAAW;AACjF;;;AAIA,SAAgB,uBACd,MACA,UACA,QACiB;CACjB,OAAO,iBAAiB,MAAM,QAAQ,kBAAkB,QAAQ,CAAC;AACnE;;;;;;;;AASA,SAAgB,sBACd,MACA,UACA,SACmB;CACnB,IAAI;CACJ,IAAI;EACF,MAAM,KAAK,MAAM,IAAI;CACvB,SAAS,OAAO;EACd,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,4BAA4B,QAAQ,QAClE,EAAE,OAAO,MAAM,CACjB;CACF;CACA,MAAM,QAAQ,uBAAuB,KAAK,OAAO;CACjD,IAAI,MAAM,aAAa,UACrB,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,QAAQ,QAAQ,KAAK,qBAAqB,MAAM,SAAS,aAAa,UACtG;CAEF,IAAI,gBAAgB,KAAK,MAAM,MAC7B,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,mCAAmC,QAAQ,MAC3E;CAEF,MAAM,EAAE,WAAW,GAAG,aAAa;CACnC,MAAM,WAAW,cAAc,QAAQ;CACvC,IAAI,cAAc,UAChB,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,QAAQ,QAAQ,KAAK,2BAA2B,SAAS,QAAQ,WACjG;CAEF,OAAO;AACT;AAOA,SAAS,kBACP,UAC4E;CAC5E,OAAO;EACL,GAAG;EACH,QAAQ;GAAE,QAAQ;GAAsB;EAAS;EACjD,gBAAgB,YAAY,IAAI,0BAA0B,OAAO;EACjE,YAAY;EACZ,mBAAmB,OAAO,UAAU;GAClC,IAAI,MAAM,aAAa,UACrB,MAAM,IAAI,2BACR,SAAS,MAAM,qBAAqB,MAAM,SAAS,aAAa,UAClE;EAEJ;EACA,uBAAuB,IAAI,YAAY,QAAQ;CACjD;AACF;;AAGA,IAAa,mBAAb,MAAsD;CACpD;CACA;CACA;CACA;CACA;CAMA,YAAY,MAAc,UAAkB,cAA2C,OAAO;EAC5F,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG,MAAM,IAAI,kBAAkB,sBAAsB;EAChF,IAAI,SAAS,WAAW,KAAK,SAAS,KAAK,MAAM,UAC/C,MAAM,IAAI,kBAAkB,2DAA2D;EAEzF,KAAK,WAAW;EAChB,KAAK,kBAAkB;EACvB,KAAK,UAAU,IAAI,kBAAkB,MAAM,kBAAkB,QAAQ,GAAG,EACtE,oBAAoB,gBAAgB,UACtC,CAAC;EACD,KAAK,OAAO,KAAK,QAAQ;EACzB,KAAK,kBAAkB,KAAK,QAAQ;CACtC;CAEA,MAAM,QAAkC;EACtC,OAAO,KAAK,QAAQ,OAAO;CAC7B;CAEA,MAAM,OAAO,OAA6D;EAGxE,MAAM,QAAQ,0BAA0B,KAAK;EAC7C,MAAM,EAAE,OAAO,UAAU,eAAe,MAAM,KAAK,QAAQ,OAAO,OAAO,EACvE,SAAS,KAAK,oBAAoB,MACpC,CAAC;EACD,OAAO;GAAE;GAAO;GAAU,OAAO;EAAW;CAC9C;CAEA,MAAM,cAAiD;EACrD,OAAO,KAAK,QAAQ,YAAY;CAClC;CAEA,MAAM,iBAA6C;EACjD,OAAO,KAAK,QAAQ,eAAe;CACrC;CAEA,MAAM,mBAAsD;EAC1D,OAAO,KAAK,QAAQ,iBAAiB;CACvC;AACF;;AAGA,IAAM,qBAAN,MAAiD;CAC/C;CACA;CACA;CACA;CAMA,YAAY,MAAc,UAAkB,OAAwB;EAClE,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG,MAAM,IAAI,kBAAkB,sBAAsB;EAChF,IAAI,SAAS,WAAW,KAAK,SAAS,KAAK,MAAM,UAC/C,MAAM,IAAI,kBAAkB,2DAA2D;EAEzF,KAAK,OAAO;EACZ,KAAK,WAAW;EAChB,KAAK,kBAAkB,GAAG,KAAK;EAC/B,KAAK,UAAU,IAAI,oBAAoB,MAAM,kBAAkB,QAAQ,GAAG,KAAK;CACjF;CAEA,MAAM,QAAkC;EACtC,OAAO,KAAK,QAAQ,OAAO;CAC7B;CAEA,MAAM,OAAO,OAA6D;EACxE,MAAM,EAAE,OAAO,UAAU,eAAe,MAAM,KAAK,QAAQ,OACzD,0BAA0B,KAAK,CACjC;EACA,OAAO;GAAE;GAAO;GAAU,OAAO;EAAW;CAC9C;CAEA,MAAM,cAAiD;EACrD,OAAO;CACT;CAEA,MAAM,iBAA6C;EACjD,MAAM,IAAI,kBACR,iBAAiB,KAAK,KAAK,wDAC7B;CACF;CAEA,MAAM,mBAAsD;EAC1D,OAAO,EAAE,SAAS,MAAM;CAC1B;AACF;AAEA,SAAS,uBAAuB,KAAc,SAA+C;CAC3F,MAAM,SAAU,KAAqC;CACrD,IAAI,WAAA,gCACF,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,QAAQ,QAAQ,KAAK,4BAA4B,KAAK,UAAU,MAAM,EAAE,4BAA4B,qBAAqB,sCACzJ;CAEF,MAAM,SAAS,YAAY,UAAU,GAAG;CACxC,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,iCAAiC,QAAQ,KAAK,IAAI,eAAe,OAAO,KAAK,GAC7G;CAEF,MAAM,QAAQ,OAAO;CACrB,MAAM,kBAAkB,0BAA0B,MAAM,KAAK;CAC7D,IAAI,gBAAgB,eAAe,MAAM,gBAAgB,MAAM,KAAK,GAClE,MAAM,IAAI,2BACR,iBAAiB,QAAQ,KAAK,4CAA4C,QAAQ,MACpF;CAEF,OAAO;AACT;AAEA,SAAS,eAAe,OAA6C;CACnE,MAAM,YAAY,cAAc,MAAM,SAAS;CAC/C,QAAQ,MAAM,MAAd;EACE,KAAK,iBACH,OAAO;GACL,GAAG;GACH;GACA,QAAQ;IACN,GAAG,MAAM;IACT,OAAO;KAAE,GAAG,MAAM,OAAO;KAAO,OAAO,UAAU,MAAM,OAAO,MAAM,KAAK;IAAE;IAC3E,WAAW;KAAE,GAAG,MAAM,OAAO;KAAW,OAAO,UAAU,MAAM,OAAO,UAAU,KAAK;IAAE;IACvF,MAAM;KAAE,GAAG,MAAM,OAAO;KAAM,OAAO,UAAU,MAAM,OAAO,KAAK,KAAK;IAAE;GAC1E;EACF;EACF,KAAK,mBACH,OAAO;GACL,GAAG;GACH;GACA,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,eAAe,EAAE,WAAW,EAAE,SAAS,CAAC;EACvF;EACF,KAAK,gBACH,OAAO;GACL,GAAG;GACH;GACA,iBAAiB,CAAC,GAAG,MAAM,eAAe,CAAC,CACxC,KAAK,cAAc;IAAE,GAAG;IAAU,UAAU,cAAc,SAAS,QAAQ;GAAE,EAAE,CAAC,CAChF,MAAM,GAAG,MAAM,eAAe,EAAE,WAAW,EAAE,SAAS,CAAC;EAC5D;EACF,SACE,OAAO;GAAE,GAAG;GAAO;EAAU;CACjC;AACF;AAEA,SAAS,UAAU,OAAmC;CACpD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC;AACrE;AAEA,SAAS,cAAc,WAAqD;CAC1E,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,MAAM,GAAG,MAAM,eAAe,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;AACrF;AAEA,SAAS,eAAe,OAA2B;CACjD,OAAO,MAAM,OACV,KAAK,UAAU,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,GAAG,IAAI,SAAS,IAAI,MAAM,SAAS,CAAC,CAC9F,KAAK,IAAI;AACd"}
|