@tangle-network/agent-eval 0.191.0 → 0.192.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/analyst/index.d.ts +6 -6
- package/dist/analyst/index.js +3 -3
- package/dist/{benchmark-command-3tZJnD82.js → benchmark-command-C458yEFK.js} +7 -7
- package/dist/{benchmark-command-3tZJnD82.js.map → benchmark-command-C458yEFK.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +3 -3
- package/dist/benchmarks/index.js +3 -3
- package/dist/campaign/index.d.ts +4 -4
- package/dist/campaign/index.js +8 -9
- package/dist/{campaign-C8iWEF0M.js → campaign-BVQVBEfH.js} +12 -326
- package/dist/campaign-BVQVBEfH.js.map +1 -0
- package/dist/{campaign-evidence-BqjlTM3P.js → campaign-evidence-DcQiYhJI.js} +10 -45
- package/dist/campaign-evidence-DcQiYhJI.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/contract/index.d.ts +6 -6
- package/dist/contract/index.js +6 -6
- package/dist/{default-registry-DK_9aVJf.d.ts → default-registry-DdqA_-_o.d.ts} +3 -3
- package/dist/{default-registry-DK_9aVJf.d.ts.map → default-registry-DdqA_-_o.d.ts.map} +1 -1
- package/dist/{define-agent-eval-BE43YTm4.js → define-agent-eval-DQuos3Aw.js} +8 -9
- package/dist/define-agent-eval-DQuos3Aw.js.map +1 -0
- package/dist/{define-agent-eval-P28y7mI1.d.ts → define-agent-eval-DcludNJS.d.ts} +13 -22
- package/dist/{define-agent-eval-P28y7mI1.d.ts.map → define-agent-eval-DcludNJS.d.ts.map} +1 -1
- package/dist/{dspy-rlm-engine-MfpwoEaj.js → dspy-rlm-engine-BX34vPVY.js} +2 -2
- package/dist/{dspy-rlm-engine-MfpwoEaj.js.map → dspy-rlm-engine-BX34vPVY.js.map} +1 -1
- package/dist/{engine-vNiM02Ub.d.ts → engine-C1DIAEpn.d.ts} +2 -2
- package/dist/{engine-vNiM02Ub.d.ts.map → engine-C1DIAEpn.d.ts.map} +1 -1
- package/dist/evaluation.d.ts +1 -1
- package/dist/experiment/index.d.ts +1 -1
- package/dist/experiment/index.js +1 -1
- package/dist/{external-optimizer-process-xFTliuiK.js → external-optimizer-process-D-Sab4v3.js} +3 -62
- package/dist/external-optimizer-process-D-Sab4v3.js.map +1 -0
- package/dist/{external-optimizer-subprocess-B234V9V0.js → external-optimizer-subprocess-kbqC-iWf.js} +64 -3
- package/dist/external-optimizer-subprocess-kbqC-iWf.js.map +1 -0
- package/dist/hosted/index.js +1 -1
- package/dist/{index-I4UJGRno.d.ts → index-Bj96W0jZ.d.ts} +28 -2
- package/dist/{index-I4UJGRno.d.ts.map → index-Bj96W0jZ.d.ts.map} +1 -1
- package/dist/{index-D-TN7ZRM.d.ts → index-DBoXFaz0.d.ts} +3 -3
- package/dist/{index-D-TN7ZRM.d.ts.map → index-DBoXFaz0.d.ts.map} +1 -1
- package/dist/{index-DH-MWH5f.d.ts → index-DNVzu9Vv.d.ts} +6 -6
- package/dist/{index-DH-MWH5f.d.ts.map → index-DNVzu9Vv.d.ts.map} +1 -1
- package/dist/{index-CzfnASj_.d.ts → index-DwQxdWve.d.ts} +338 -129
- package/dist/index-DwQxdWve.d.ts.map +1 -0
- package/dist/index.d.ts +9 -9
- package/dist/index.js +6 -6
- package/dist/jev.d.ts +1 -1
- package/dist/{journal-c3qY0SDP.js → journal-DvKCvjty.js} +94 -2
- package/dist/{journal-c3qY0SDP.js.map → journal-DvKCvjty.js.map} +1 -1
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +2 -2
- package/dist/{llm-judge-NJOHM0iA.js → llm-judge-Z6MkTkd0.js} +1819 -609
- package/dist/llm-judge-Z6MkTkd0.js.map +1 -0
- package/dist/{matrix-CgqdFm5N.d.ts → matrix-CQMMrEQ5.d.ts} +2 -2
- package/dist/{matrix-CgqdFm5N.d.ts.map → matrix-CQMMrEQ5.d.ts.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/{produced-state-CY-L7CqS.js → produced-state-CVmCPQDJ.js} +3 -3
- package/dist/{produced-state-CY-L7CqS.js.map → produced-state-CVmCPQDJ.js.map} +1 -1
- package/dist/rl.d.ts +1 -1
- package/dist/{search-ledger-CQ8Uy4FK.js → search-ledger-Ck7tok0h.js} +78 -12
- package/dist/search-ledger-Ck7tok0h.js.map +1 -0
- package/dist/{search-ledger-file-EvdDZRhv.js → search-ledger-file-DY0AXX3W.js} +2 -2
- package/dist/{search-ledger-file-EvdDZRhv.js.map → search-ledger-file-DY0AXX3W.js.map} +1 -1
- package/dist/{search-shipper-C55V7HE3.js → search-shipper-BG182p-U.js} +3 -3
- package/dist/{search-shipper-C55V7HE3.js.map → search-shipper-BG182p-U.js.map} +1 -1
- package/dist/{semantic-concept-judge-Bt7bXAAo.js → semantic-concept-judge-Bg-560H0.js} +3 -3
- package/dist/{semantic-concept-judge-Bt7bXAAo.js.map → semantic-concept-judge-Bg-560H0.js.map} +1 -1
- package/dist/{skillopt-optimization-method-DwO3TOAV.js → skillopt-optimization-method-DoayuM6D.js} +6 -6
- package/dist/{skillopt-optimization-method-DwO3TOAV.js.map → skillopt-optimization-method-DoayuM6D.js.map} +1 -1
- package/dist/{statistical-heldout-BED3wBtX.d.ts → statistical-heldout-C1Ej5Ce8.d.ts} +2 -2
- package/dist/{statistical-heldout-BED3wBtX.d.ts.map → statistical-heldout-C1Ej5Ce8.d.ts.map} +1 -1
- package/dist/{store-tool-spans-Cfh9XUCm.d.ts → store-tool-spans-ByLdU26j.d.ts} +3 -3
- package/dist/{store-tool-spans-Cfh9XUCm.d.ts.map → store-tool-spans-ByLdU26j.d.ts.map} +1 -1
- package/dist/{tool-groups-D-mkeN0N.d.ts → tool-groups-DiBi16ns.d.ts} +2 -2
- package/dist/tool-groups-DiBi16ns.d.ts.map +1 -0
- package/dist/trace-repair/index.d.ts +1 -1
- package/dist/traces.d.ts +2 -2
- package/dist/{types-ClK-sHs8.d.ts → types-ByZslIlr.d.ts} +2 -2
- package/dist/{types-ClK-sHs8.d.ts.map → types-ByZslIlr.d.ts.map} +1 -1
- package/dist/{types-BmQRs661.d.ts → types-C1CAD70_.d.ts} +14 -15
- package/dist/types-C1CAD70_.d.ts.map +1 -0
- package/docs/campaign-proposers.md +14 -16
- package/docs/search-ledger.md +62 -1
- package/package.json +1 -1
- package/dist/campaign-C8iWEF0M.js.map +0 -1
- package/dist/campaign-evidence-BqjlTM3P.js.map +0 -1
- package/dist/define-agent-eval-BE43YTm4.js.map +0 -1
- package/dist/external-optimizer-process-xFTliuiK.js.map +0 -1
- package/dist/external-optimizer-subprocess-B234V9V0.js.map +0 -1
- package/dist/index-CzfnASj_.d.ts.map +0 -1
- package/dist/llm-judge-NJOHM0iA.js.map +0 -1
- package/dist/search-ledger-CQ8Uy4FK.js.map +0 -1
- package/dist/tool-groups-D-mkeN0N.d.ts.map +0 -1
- package/dist/types-BmQRs661.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-ledger-Ck7tok0h.js","names":[],"sources":["../src/campaign/search-ledger-ordering.ts","../src/campaign/search-state.ts","../src/campaign/search-ledger-types.ts","../src/campaign/search-ledger.ts"],"sourcesContent":["import { canonicalString } from '../ledger-core'\nimport type { SearchArtifactRef } from './search-ledger-types'\n\nexport function artifactKey(artifact: SearchArtifactRef): string {\n return canonicalString(artifact)\n}\n\nexport function compareStrings(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n","/**\n * `SearchState`: the one projection of a search ledger.\n *\n * The same code checks every invariant for the producer's journal, the kernel,\n * and the Intelligence verifier, and builds the read model they share. It keeps\n * compact indexes (nodes, edges, cells, per-unit score sums, running audit\n * totals), not the raw event list, and applies each entry in time proportional\n * to that entry, so a search of any length appends at a constant cost.\n *\n * The journal asks for a snapshot after every append. A snapshot is a\n * `SearchStateView` that reads the live indexes, so taking one costs nothing.\n * The view is valid until the state applies its next entry; a read after that\n * throws rather than returning numbers from a later ledger position. Read the\n * ledger's state again to see newer entries. The audit, header, head and claim\n * on a view are plain values and stay readable.\n */\n\nimport { createHash } from 'node:crypto'\nimport type { LedgerProjector } from '../ledger-core'\nimport { canonicalString, compareCodeUnits, hashCanonical } from '../ledger-core/canonical'\nimport type { RolloutSearchLineage } from '../rollout/mint'\nimport { type RunSearchCoordinates, searchCellRunId } from '../run-record'\nimport { SearchLedgerError, SearchLedgerIntegrityError } from './search-ledger-errors'\nimport { artifactKey } from './search-ledger-ordering'\nimport type {\n NodeEstimate,\n SearchArtifactRef,\n SearchAttemptAccounting,\n SearchAudit,\n SearchCandidateSurface,\n SearchCellAllocatedEvent,\n SearchCellCancelledEvent,\n SearchCellSettledEvent,\n SearchCellStage,\n SearchClaim,\n SearchClosedEvent,\n SearchEdgeRecordedEvent,\n SearchLedgerEntry,\n SearchLedgerEvent,\n SearchLedgerHash,\n SearchNodeDecidedEvent,\n SearchNodeDecision,\n SearchNodeRef,\n SearchNodeRegisteredEvent,\n SearchNodeStatus,\n SearchOpenedEvent,\n SearchOperationKind,\n SearchOperationRecordedEvent,\n SearchOperationStartedEvent,\n SearchReservation,\n SearchSplit,\n SearchTask,\n SearchTaskOutcome,\n} from './search-ledger-types'\n\n/** Deterministic node id: identical content in one search is one node. */\nexport function searchNodeId(searchId: string, artifactDigest: string): string {\n return `node_${shortDigest([searchId, artifactDigest])}`\n}\n\n/** Deterministic cell id: one node on one task in one split at one repeat. */\nexport function searchCellId(\n searchId: string,\n nodeId: string,\n taskId: string,\n split: SearchSplit,\n rep: number,\n): string {\n return `cell_${shortDigest([searchId, nodeId, taskId, split, rep])}`\n}\n\n/** Digest a split's task list in taskId order. */\nexport function searchTaskSetDigest(tasks: readonly SearchTask[]): SearchLedgerHash {\n return hashCanonical(\n [...tasks].sort((left, right) => compareCodeUnits(left.taskId, right.taskId)),\n )\n}\n\n/** 128 bits of SHA-256 over the canonical encoding: collision-safe and short\n * enough for directory names. */\nfunction shortDigest(value: unknown): string {\n return createHash('sha256').update(canonicalString(value)).digest('hex').slice(0, 32)\n}\n\nconst MAX_LABEL_CHARS = 200\nconst USD_TOLERANCE = 1e-9\nconst SPLITS: readonly SearchSplit[] = ['train', 'selection', 'test']\n\nexport interface SearchDecisionRecord {\n sequence: number\n decision: SearchNodeDecision\n basis: NodeEstimate | null\n rule: string\n reason: string\n}\n\nexport interface SearchSpend {\n knownUsd: number\n floorUsd: number\n unknownCostCells: number\n boxMinutes: number\n}\n\n/** Scores of one node on one unit of one split: the sum and count of its\n * scored cells. Repeats and sibling tasks of the unit average inside it. */\nexport interface SearchUnitScore {\n unitId: string\n sum: number\n count: number\n mean: number\n}\n\n/** A cell's scored attempt: the inputs of every per-unit statistic. */\nexport interface SearchScoredCell {\n cellId: string\n unitId: string\n /** The attempt that produced the score, which is the cell's last. */\n attempt: number\n score: number\n}\n\n/**\n * Per-unit means of scored cells, in unitId order. Each unit sums its cells in\n * cellId order, so the result depends on the set of cells alone, never on the\n * order they settled in: a verifier that reads the same cells from a database\n * gets the same bits.\n */\nexport function searchUnitScores(cells: readonly SearchScoredCell[]): SearchUnitScore[] {\n const byUnit = new Map<string, SearchScoredCell[]>()\n for (const cell of cells) {\n const unit = byUnit.get(cell.unitId)\n if (unit) unit.push(cell)\n else byUnit.set(cell.unitId, [cell])\n }\n return [...byUnit.entries()]\n .sort(([left], [right]) => compareCodeUnits(left, right))\n .map(([unitId, unitCells]) => {\n let sum = 0\n for (const cell of unitCells.sort((left, right) =>\n compareCodeUnits(left.cellId, right.cellId),\n )) {\n sum += cell.score\n }\n return { unitId, sum, count: unitCells.length, mean: sum / unitCells.length }\n })\n}\n\nexport interface SearchNode {\n nodeId: string\n /** Registration order; the root is 0. */\n ordinal: number\n artifactDigest: SearchLedgerHash\n artifact: SearchArtifactRef\n surfaces: readonly SearchCandidateSurface[]\n /** First in-search parent of the node's first edge; null for the root, a\n * derived root, or a node whose parents are unknown. */\n primaryParentId: string | null\n /** Edges from the root along primary parents; null while unknown. */\n depth: number | null\n /** Every parent named by any edge into the node, in edge order. */\n parents: readonly SearchNodeRef[]\n children: readonly string[]\n edgeIds: readonly string[]\n status: SearchNodeStatus | null\n rung: number | null\n /** The node was decided `finalist` at some point, so its test cells are legal. */\n finalist: boolean\n decisions: readonly SearchDecisionRecord[]\n cellCount: number\n spend: SearchSpend\n registeredSequence: number\n updatedSequence: number\n}\n\nexport interface SearchCell {\n cellId: string\n nodeId: string\n taskId: string\n unitId: string\n split: SearchSplit\n rep: number\n stage: SearchCellStage\n lane: string | null\n reservation: SearchReservation | null\n attempts: number\n lastRunId: string | null\n outcome: SearchTaskOutcome['status'] | null\n /** Score of the scored attempt; null when no attempt was scored. */\n score: number | null\n /** No further attempt is legal: a scored or non-retryable outcome. */\n final: boolean\n cancelled: SearchCellCancelledEvent['reason'] | null\n /** Known cost plus proven floors across attempts. */\n spentUsd: number\n /** Every attempt's cost is known. */\n costKnown: boolean\n traceId: string | null\n allocatedSequence: number\n updatedSequence: number\n}\n\nexport interface SearchOperation {\n operationId: string\n operationKind: SearchOperationKind\n reservation: SearchReservation | null\n recorded: boolean\n /** The recorded outcome; null until the operation is recorded. */\n outcome: SearchOperationRecordedEvent['outcome']['status'] | null\n /** Artifacts the recorded event bound, for example a proposal's output. */\n artifacts: readonly SearchArtifactRef[]\n spentUsd: number\n}\n\nexport interface SearchCompletion {\n complete: boolean\n reasons: string[]\n}\n\ninterface NodeRecord {\n event: SearchNodeRegisteredEvent\n ordinal: number\n registeredSequence: number\n updatedSequence: number\n edgeIds: string[]\n parents: SearchNodeRef[]\n parentKeys: Set<string>\n primaryParentId: string | null\n depth: number | null\n children: string[]\n decisions: SearchDecisionRecord[]\n finalist: boolean\n cellIds: string[]\n scoredCells: number\n spend: SearchSpend\n}\n\ntype CellRecord = SearchCell\ntype OperationRecord = SearchOperation\n\n/**\n * The pure, incremental projection of one search ledger. `apply` refuses any\n * entry that breaks an invariant; the journal then discards this instance and\n * replays into a new one, so a refused entry leaves no partial state behind.\n */\nexport class SearchState implements LedgerProjector<SearchLedgerEntry, SearchStateView> {\n readonly searchId: string\n private version = 0\n private header: SearchOpenedEvent | null = null\n private closed: SearchClosedEvent | null = null\n private head: { sequence: number; entryHash: SearchLedgerHash } | null = null\n private lastOccurredAt = Number.NEGATIVE_INFINITY\n private lastOccurredAtText: string | null = null\n private readonly tasks = new Map<string, { split: SearchSplit; unitId: string }>()\n private readonly nodes = new Map<string, NodeRecord>()\n private readonly nodeOrder: string[] = []\n private readonly nodeByDigest = new Map<string, string>()\n private readonly edges = new Map<string, SearchEdgeRecordedEvent>()\n private readonly edgeOrder: string[] = []\n private readonly cells = new Map<string, CellRecord>()\n private readonly operations = new Map<string, OperationRecord>()\n private selectedNodeId: string | null = null\n private claimUsedUsd = 0\n private readonly audit: SearchAudit\n\n constructor(searchId: string) {\n this.searchId = searchId\n this.audit = {\n searchId,\n eventCount: 0,\n headHash: null,\n status: 'open',\n closeReason: null,\n nodes: 0,\n nodesWithoutEdge: 0,\n undecidedNodes: 0,\n selectedNodeId: null,\n edges: { explicit: 0, correlated: 0, unknown: 0, reproposals: 0 },\n cells: { allocated: 0, settled: 0, cancelled: 0, open: 0 },\n attempts: 0,\n outcomes: { passed: 0, failed: 0, errored: 0 },\n operations: { started: 0, recorded: 0, open: 0 },\n spend: {\n knownUsd: 0,\n floorUsd: 0,\n unknownCostCells: 0,\n unknownCostOperations: 0,\n committedUsd: 0,\n openReservationUsd: 0,\n overspendUsd: 0,\n unreservedCells: 0,\n boxMinutes: 0,\n },\n tokens: { inputTokens: 0, outputTokens: 0, cachedTokens: 0, unknownTokenAttempts: 0 },\n }\n }\n\n apply(entry: SearchLedgerEntry, index: number): void {\n const event = entry.event\n if (this.closed) {\n throw integrity(`event ${event.eventId} follows search-closed ${this.closed.eventId}`)\n }\n const occurredAt = Date.parse(event.occurredAt)\n if (occurredAt < this.lastOccurredAt) {\n throw integrity(`event ${event.eventId} occurred before the preceding event`)\n }\n assertUnique(event.artifacts.map(artifactKey), 'artifact receipt', event.eventId)\n if (event.kind === 'search-opened') {\n if (index !== 0 || this.header) {\n throw integrity('search-opened must be the first and only opening event')\n }\n this.open(event)\n } else {\n if (!this.header) {\n throw integrity(`event ${event.eventId} appears before search-opened`)\n }\n this.applyEvent(event, index)\n }\n this.lastOccurredAt = occurredAt\n this.lastOccurredAtText = event.occurredAt\n this.head = { sequence: index, entryHash: entry.entryHash }\n this.audit.eventCount = index + 1\n this.audit.headHash = entry.entryHash\n this.version += 1\n }\n\n snapshot(): SearchStateView {\n return new SearchStateView(this, this.version)\n }\n\n /** @internal Views check this before every read of the live indexes. */\n isAt(version: number): boolean {\n return this.version === version\n }\n\n private applyEvent(event: Exclude<SearchLedgerEvent, SearchOpenedEvent>, index: number): void {\n switch (event.kind) {\n case 'operation-started':\n this.startOperation(event)\n return\n case 'operation-recorded':\n this.recordOperation(event)\n return\n case 'node-registered':\n this.registerNode(event, index)\n return\n case 'edge-recorded':\n this.recordEdge(event, index)\n return\n case 'cell-allocated':\n this.allocateCell(event, index)\n return\n case 'cell-settled':\n this.settleCell(event, index)\n return\n case 'cell-cancelled':\n this.cancelCell(event, index)\n return\n case 'node-decided':\n this.decideNode(event, index)\n return\n case 'search-closed':\n this.close(event)\n return\n }\n }\n\n private open(event: SearchOpenedEvent): void {\n if (event.containment?.searchId === this.searchId) {\n throw integrity('a search cannot contain itself')\n }\n if (event.derivedFrom?.searchId === this.searchId) {\n throw integrity('a search cannot derive from itself')\n }\n const units: Record<SearchSplit, Set<string>> = {\n train: new Set(),\n selection: new Set(),\n test: new Set(),\n }\n for (const split of SPLITS) {\n const { tasks, taskSetDigest } = event.splits[split]\n if (searchTaskSetDigest(tasks) !== taskSetDigest) {\n throw integrity(`the ${split} split's taskSetDigest does not match its tasks`)\n }\n for (const task of tasks) {\n const owner = this.tasks.get(task.taskId)\n if (owner) {\n throw integrity(`task ${task.taskId} is in both the ${owner.split} and ${split} splits`)\n }\n this.tasks.set(task.taskId, { split, unitId: task.unitId })\n units[split].add(task.unitId)\n }\n }\n if (event.splits.heldOutUnits) {\n const seen = [...units.test].filter(\n (unit) => units.train.has(unit) || units.selection.has(unit),\n )\n if (seen.length > 0) {\n throw integrity(\n `test units ${seen.join(', ')} also appear in train or selection, but the splits declare heldOutUnits`,\n )\n }\n }\n const { budget } = event\n if (budget.maxUsd !== null && budget.reservedClaimUsd > budget.maxUsd + USD_TOLERANCE) {\n throw integrity(\n `the claim reserve $${budget.reservedClaimUsd} exceeds the search cap $${budget.maxUsd}`,\n )\n }\n this.header = event\n }\n\n private startOperation(event: SearchOperationStartedEvent): void {\n if (this.operations.has(event.operationId)) {\n throw integrity(`operation ${event.operationId} was started twice`)\n }\n this.admit(event.reservation, false, `operation ${event.operationId}`)\n this.operations.set(event.operationId, {\n operationId: event.operationId,\n operationKind: event.operationKind,\n reservation: event.reservation,\n recorded: false,\n outcome: null,\n artifacts: [],\n spentUsd: 0,\n })\n this.audit.operations.started += 1\n this.audit.operations.open += 1\n this.audit.spend.openReservationUsd += event.reservation?.usd ?? 0\n }\n\n private recordOperation(event: SearchOperationRecordedEvent): void {\n const operation = this.operations.get(event.operationId)\n if (!operation) {\n throw integrity(`operation ${event.operationId} was recorded before it started`)\n }\n if (operation.recorded) {\n throw integrity(`operation ${event.operationId} was recorded twice`)\n }\n if (operation.operationKind !== event.operationKind) {\n throw integrity(\n `operation ${event.operationId} started as ${operation.operationKind} but recorded as ${event.operationKind}`,\n )\n }\n const cost = this.book(event.accounting)\n if (cost.unknown) this.audit.spend.unknownCostOperations += 1\n const reserved = operation.reservation?.usd ?? 0\n this.audit.spend.openReservationUsd -= reserved\n if (operation.reservation) {\n this.audit.spend.overspendUsd += Math.max(0, cost.usd - reserved)\n }\n operation.recorded = true\n operation.outcome = event.outcome.status\n operation.artifacts = event.artifacts\n operation.spentUsd = cost.usd\n this.audit.operations.recorded += 1\n this.audit.operations.open -= 1\n }\n\n private registerNode(event: SearchNodeRegisteredEvent, index: number): void {\n const expected = searchNodeId(this.searchId, event.artifactDigest)\n if (event.nodeId !== expected) {\n throw integrity(\n `node ${event.nodeId} does not match its artifact digest (expected ${expected})`,\n )\n }\n if (this.nodes.has(event.nodeId)) {\n throw integrity(\n `node ${event.nodeId} was registered twice; a re-proposal is a second edge into it`,\n )\n }\n assertUnique(\n event.surfaces.map((surface) => surface.surfaceId),\n 'surfaceId',\n event.eventId,\n )\n const maxNodes = this.header!.budget.maxNodes\n if (maxNodes !== null && this.nodes.size + 1 > maxNodes) {\n throw integrity(`node ${event.nodeId} exceeds the search's maxNodes ${maxNodes}`)\n }\n this.nodes.set(event.nodeId, {\n event,\n ordinal: this.nodeOrder.length,\n registeredSequence: index,\n updatedSequence: index,\n edgeIds: [],\n parents: [],\n parentKeys: new Set(),\n primaryParentId: null,\n depth: null,\n children: [],\n decisions: [],\n finalist: false,\n cellIds: [],\n scoredCells: 0,\n spend: { knownUsd: 0, floorUsd: 0, unknownCostCells: 0, boxMinutes: 0 },\n })\n this.nodeOrder.push(event.nodeId)\n this.nodeByDigest.set(event.artifactDigest, event.nodeId)\n this.audit.nodes += 1\n this.audit.nodesWithoutEdge += 1\n this.audit.undecidedNodes += 1\n }\n\n private recordEdge(event: SearchEdgeRecordedEvent, index: number): void {\n if (this.edges.has(event.edgeId)) {\n throw integrity(`edge ${event.edgeId} was recorded twice`)\n }\n const child = this.nodes.get(event.childNodeId)\n if (!child) {\n throw integrity(`edge ${event.edgeId} names unregistered child ${event.childNodeId}`)\n }\n if (event.label.length > MAX_LABEL_CHARS) {\n throw integrity(`edge ${event.edgeId} label exceeds ${MAX_LABEL_CHARS} characters`)\n }\n if (event.diffs.length !== event.parents.length) {\n throw integrity(`edge ${event.edgeId} needs one diff per parent`)\n }\n assertUnique(\n event.parents.map((parent) => canonicalString(parent)),\n 'parent',\n event.eventId,\n )\n const { operator, attribution, parents } = event\n if ((operator === 'seed') !== (event.proposer === null)) {\n throw integrity(`edge ${event.edgeId}: exactly the seed edge has no proposer`)\n }\n if (operator === 'seed' && (parents.length > 0 || attribution === 'unknown')) {\n throw integrity(`seed edge ${event.edgeId} must have no parents and a known attribution`)\n }\n if (attribution === 'unknown' && parents.length > 0) {\n throw integrity(`edge ${event.edgeId} has unknown attribution but names parents`)\n }\n if (operator !== 'seed' && attribution !== 'unknown' && parents.length === 0) {\n throw integrity(`${operator} edge ${event.edgeId} names no parent`)\n }\n if (operator === 'merge' && attribution !== 'unknown' && parents.length < 2) {\n throw integrity(`merge edge ${event.edgeId} needs at least two parents`)\n }\n const operationId = event.proposer?.operationId ?? null\n if (operationId !== null && !this.operations.has(operationId)) {\n throw integrity(`edge ${event.edgeId} names operation ${operationId}, which never started`)\n }\n const inSearch: NodeRecord[] = []\n for (const parent of parents) {\n if (parent.searchId !== this.searchId) {\n const from = this.header!.derivedFrom\n if (\n operator !== 'derive' ||\n parents.length !== 1 ||\n !from ||\n from.searchId !== parent.searchId ||\n from.nodeId !== parent.nodeId\n ) {\n throw integrity(\n `edge ${event.edgeId} names a parent in search ${parent.searchId}; only a derive edge matching derivedFrom may`,\n )\n }\n continue\n }\n if (operator === 'derive') {\n throw integrity(`derive edge ${event.edgeId} must name the parent in derivedFrom`)\n }\n const record = this.nodes.get(parent.nodeId)\n if (!record) {\n throw integrity(`edge ${event.edgeId} names unregistered parent ${parent.nodeId}`)\n }\n if (record.ordinal >= child.ordinal) {\n throw integrity(\n `edge ${event.edgeId}: parent ${parent.nodeId} registered after child ${child.event.nodeId}`,\n )\n }\n if (record.edgeIds.length === 0) {\n throw integrity(`edge ${event.edgeId}: parent ${parent.nodeId} has no edge of its own yet`)\n }\n inSearch.push(record)\n }\n\n if (child.edgeIds.length === 0) {\n const primary = inSearch[0]\n child.primaryParentId = primary?.event.nodeId ?? null\n child.depth =\n operator === 'seed' || operator === 'derive'\n ? 0\n : primary && primary.depth !== null\n ? primary.depth + 1\n : null\n this.audit.nodesWithoutEdge -= 1\n } else {\n this.audit.edges.reproposals += 1\n }\n child.edgeIds.push(event.edgeId)\n for (const parent of parents) {\n const key = canonicalString(parent)\n if (child.parentKeys.has(key)) continue\n child.parentKeys.add(key)\n child.parents.push(parent)\n }\n for (const parent of inSearch) {\n if (!parent.children.includes(child.event.nodeId)) parent.children.push(child.event.nodeId)\n }\n child.updatedSequence = index\n this.edges.set(event.edgeId, event)\n this.edgeOrder.push(event.edgeId)\n this.audit.edges[attribution] += 1\n }\n\n private allocateCell(event: SearchCellAllocatedEvent, index: number): void {\n const expected = searchCellId(this.searchId, event.nodeId, event.taskId, event.split, event.rep)\n if (event.cellId !== expected) {\n throw integrity(`cell ${event.cellId} does not match its coordinates (expected ${expected})`)\n }\n if (this.cells.has(event.cellId)) {\n throw integrity(`cell ${event.cellId} was allocated twice`)\n }\n const node = this.nodes.get(event.nodeId)\n if (!node) throw integrity(`cell ${event.cellId} names unregistered node ${event.nodeId}`)\n if (node.edgeIds.length === 0) {\n throw integrity(`cell ${event.cellId}: node ${event.nodeId} has no edge yet`)\n }\n const task = this.tasks.get(event.taskId)\n if (!task || task.split !== event.split) {\n throw integrity(\n `cell ${event.cellId}: task ${event.taskId} is not in the ${event.split} split`,\n )\n }\n if (task.unitId !== event.unitId) {\n throw integrity(`cell ${event.cellId}: task ${event.taskId} samples unit ${task.unitId}`)\n }\n assertStageSplit(event.cellId, event.stage, event.split, node.ordinal === 0)\n if (event.split === 'test' && node.ordinal !== 0 && !node.finalist) {\n throw integrity(\n `cell ${event.cellId}: the test split is sealed; only the root and finalists run on it`,\n )\n }\n const maxCells = this.header!.budget.maxCells\n if (maxCells !== null && this.audit.cells.allocated + 1 > maxCells) {\n throw integrity(`cell ${event.cellId} exceeds the search's maxCells ${maxCells}`)\n }\n this.admit(event.reservation, event.stage === 'claim', `cell ${event.cellId}`)\n this.cells.set(event.cellId, {\n cellId: event.cellId,\n nodeId: event.nodeId,\n taskId: event.taskId,\n unitId: event.unitId,\n split: event.split,\n rep: event.rep,\n stage: event.stage,\n lane: event.lane,\n reservation: event.reservation,\n attempts: 0,\n lastRunId: null,\n outcome: null,\n score: null,\n final: false,\n cancelled: null,\n spentUsd: 0,\n costKnown: true,\n traceId: null,\n allocatedSequence: index,\n updatedSequence: index,\n })\n node.cellIds.push(event.cellId)\n node.updatedSequence = index\n this.audit.cells.allocated += 1\n this.audit.cells.open += 1\n this.audit.spend.openReservationUsd += event.reservation?.usd ?? 0\n if (event.stage === 'claim') this.claimUsedUsd += event.reservation?.usd ?? 0\n }\n\n private settleCell(event: SearchCellSettledEvent, index: number): void {\n const cell = this.cells.get(event.cellId)\n if (!cell) throw integrity(`attempt ${event.eventId} names unallocated cell ${event.cellId}`)\n if (cell.cancelled) throw integrity(`cell ${event.cellId} was settled after it was cancelled`)\n if (cell.final) {\n throw integrity(\n `cell ${event.cellId} was attempted again after a final ${cell.outcome} outcome; only a retryable error admits another attempt`,\n )\n }\n if (event.attempt !== cell.attempts + 1) {\n throw integrity(\n `cell ${event.cellId} attempt ${event.attempt} is not contiguous (expected ${cell.attempts + 1})`,\n )\n }\n const runId = searchCellRunId({ cellId: event.cellId, attempt: event.attempt })\n if (event.runId !== runId) {\n throw integrity(`cell ${event.cellId} attempt ${event.attempt} must have runId ${runId}`)\n }\n const node = this.nodes.get(cell.nodeId)!\n const declared = new Set(node.event.surfaces.map((surface) => surface.surfaceId))\n assertUnique(\n event.surfaceEvidence.map((evidence) => evidence.surfaceId),\n 'surface evidence',\n event.eventId,\n )\n for (const evidence of event.surfaceEvidence) {\n if (!declared.has(evidence.surfaceId)) {\n throw integrity(\n `attempt ${event.eventId} reports surface ${evidence.surfaceId}, which node ${cell.nodeId} does not declare`,\n )\n }\n }\n if (event.artifacts.filter((artifact) => artifact.role === 'run-record').length > 1) {\n throw integrity(`attempt ${event.eventId} binds more than one RunRecord`)\n }\n\n const before = this.reservationParts(cell)\n const cost = this.book(event.accounting)\n if (cell.attempts === 0) {\n this.audit.cells.settled += 1\n this.audit.cells.open -= 1\n if (cell.reservation === null) this.audit.spend.unreservedCells += 1\n }\n if (cost.unknown && cell.costKnown) {\n cell.costKnown = false\n this.audit.spend.unknownCostCells += 1\n node.spend.unknownCostCells += 1\n }\n cell.attempts = event.attempt\n cell.lastRunId = runId\n cell.outcome = event.outcome.status\n cell.spentUsd += cost.usd\n cell.updatedSequence = index\n if ('traceId' in event.traceRef) cell.traceId = event.traceRef.traceId\n if (event.outcome.status === 'errored') {\n cell.final = !event.outcome.error.retryable\n } else {\n cell.final = true\n cell.score = event.outcome.score\n node.scoredCells += 1\n }\n const after = this.reservationParts(cell)\n this.audit.spend.openReservationUsd += after.open - before.open\n this.audit.spend.overspendUsd += after.over - before.over\n if (cell.stage === 'claim') this.claimUsedUsd += after.used - before.used\n\n if (cost.unknown) node.spend.floorUsd += cost.usd\n else node.spend.knownUsd += cost.usd\n const boxMinutes = event.boxMinutes ?? 0\n node.spend.boxMinutes += boxMinutes\n this.audit.spend.boxMinutes += boxMinutes\n node.updatedSequence = index\n this.audit.attempts += 1\n this.audit.outcomes[event.outcome.status] += 1\n }\n\n private cancelCell(event: SearchCellCancelledEvent, index: number): void {\n const cell = this.cells.get(event.cellId)\n if (!cell)\n throw integrity(`cancellation ${event.eventId} names unallocated cell ${event.cellId}`)\n if (cell.cancelled) throw integrity(`cell ${event.cellId} was cancelled twice`)\n if (cell.final) throw integrity(`cell ${event.cellId} was cancelled after a final outcome`)\n const before = this.reservationParts(cell)\n cell.cancelled = event.reason\n cell.updatedSequence = index\n const after = this.reservationParts(cell)\n this.audit.spend.openReservationUsd += after.open - before.open\n this.audit.spend.overspendUsd += after.over - before.over\n if (cell.stage === 'claim') this.claimUsedUsd += after.used - before.used\n if (cell.attempts === 0) {\n this.audit.cells.cancelled += 1\n this.audit.cells.open -= 1\n }\n this.nodes.get(cell.nodeId)!.updatedSequence = index\n }\n\n private decideNode(event: SearchNodeDecidedEvent, index: number): void {\n const node = this.nodes.get(event.nodeId)\n if (!node) throw integrity(`decision ${event.eventId} names unregistered node ${event.nodeId}`)\n if (node.edgeIds.length === 0) {\n throw integrity(`decision ${event.eventId}: node ${event.nodeId} has no edge yet`)\n }\n const status = event.decision.status\n if (status === 'selected') {\n if (this.selectedNodeId !== null && this.selectedNodeId !== event.nodeId) {\n throw integrity(\n `node ${event.nodeId} was selected while ${this.selectedNodeId} is still selected`,\n )\n }\n if (node.scoredCells === 0) {\n throw integrity(`node ${event.nodeId} cannot be selected without a scored cell`)\n }\n }\n const previous = node.decisions.at(-1)?.decision.status ?? null\n const wasUndecided = previous === null || previous === 'advanced'\n const isUndecided = status === 'advanced'\n this.audit.undecidedNodes += (isUndecided ? 1 : 0) - (wasUndecided ? 1 : 0)\n if (previous === 'selected' && status !== 'selected') this.selectedNodeId = null\n if (status === 'selected') this.selectedNodeId = event.nodeId\n if (status === 'finalist') node.finalist = true\n node.decisions.push({\n sequence: index,\n decision: event.decision,\n basis: event.basis,\n rule: event.rule,\n reason: event.reason,\n })\n node.updatedSequence = index\n this.audit.selectedNodeId = this.selectedNodeId\n }\n\n private close(event: SearchClosedEvent): void {\n const reasons = this.incompleteReasons()\n if (reasons.length > 0) {\n throw integrity(`search-closed while incomplete: ${reasons.join('; ')}`)\n }\n if (event.claim) this.checkClaim(event.claim)\n this.closed = event\n this.audit.status = 'closed'\n this.audit.closeReason = event.reason\n // Nothing runs after the close, so every hold is released.\n this.audit.spend.openReservationUsd = 0\n }\n\n private checkClaim(claim: SearchClaim): void {\n if (claim.finalists.length > 3) {\n throw integrity(`the claim names ${claim.finalists.length} finalists; at most 3 are allowed`)\n }\n assertUnique(\n claim.finalists.map((finalist) => finalist.nodeId),\n 'claim finalist',\n 'search-closed',\n )\n for (const finalist of claim.finalists) {\n if (!this.nodes.get(finalist.nodeId)?.finalist) {\n throw integrity(`claim finalist ${finalist.nodeId} was never decided finalist`)\n }\n }\n if (claim.selected !== this.selectedNodeId) {\n throw integrity(\n `the claim selects ${claim.selected ?? 'nothing'} but the selected node is ${this.selectedNodeId ?? 'none'}`,\n )\n }\n const root = this.nodeOrder[0] ?? null\n if (claim.decision === 'ship') {\n const shipped = claim.finalists.find((finalist) => finalist.nodeId === claim.selected)\n if (claim.selected === null || claim.selected === root || !shipped?.promote) {\n throw integrity('a ship claim must select a finalist that the paired test promoted')\n }\n if (!this.header!.splits.heldOutUnits) {\n throw integrity('a ship claim needs test units held out from train and selection')\n }\n } else if (claim.selected !== null && claim.selected !== root) {\n throw integrity(`a ${claim.decision} claim keeps the root; it cannot select another node`)\n }\n if (claim.decision === 'test-cannot-resolve') {\n for (const cell of this.cells.values()) {\n if (cell.split === 'test' && cell.attempts > 0) {\n throw integrity('a test-cannot-resolve claim spends nothing on test cells')\n }\n }\n }\n }\n\n /** @internal */\n incompleteReasons(): string[] {\n const reasons: string[] = []\n if (!this.header) reasons.push('search-opened is missing')\n if (this.audit.cells.open > 0)\n reasons.push(count(this.audit.cells.open, 'cell', 'has no outcome'))\n if (this.audit.operations.open > 0) {\n reasons.push(count(this.audit.operations.open, 'operation', 'is unrecorded'))\n }\n if (this.audit.nodesWithoutEdge > 0) {\n reasons.push(count(this.audit.nodesWithoutEdge, 'node', 'has no edge'))\n }\n if (this.audit.undecidedNodes > 0) {\n reasons.push(count(this.audit.undecidedNodes, 'node', 'has no terminal decision'))\n }\n return reasons\n }\n\n /** Book an attempt's or operation's accounting into the running totals. An\n * unknown cost counts as its proven floor. */\n private book(accounting: SearchAttemptAccounting): { usd: number; unknown: boolean } {\n const { tokens, cost } = accounting\n if (tokens.status === 'known') {\n this.audit.tokens.inputTokens += tokens.inputTokens\n this.audit.tokens.outputTokens += tokens.outputTokens\n this.audit.tokens.cachedTokens += tokens.cachedTokens\n } else {\n this.audit.tokens.unknownTokenAttempts += 1\n }\n const usd = cost.status === 'known' ? cost.usd : cost.knownLowerBoundUsd\n if (cost.status === 'known') this.audit.spend.knownUsd += usd\n else this.audit.spend.floorUsd += usd\n this.audit.spend.committedUsd += usd\n return { usd, unknown: cost.status === 'unknown' }\n }\n\n /** A cell's share of the open reservations, its overspend, and what it draws\n * from the claim reserve: the larger of its hold and its spend. */\n private reservationParts(cell: CellRecord): { open: number; over: number; used: number } {\n const reserved = cell.reservation?.usd ?? 0\n const holding = !cell.final && cell.cancelled === null\n return {\n open: holding ? Math.max(0, reserved - cell.spentUsd) : 0,\n over: cell.reservation ? Math.max(0, cell.spentUsd - reserved) : 0,\n used: holding ? Math.max(reserved, cell.spentUsd) : cell.spentUsd,\n }\n }\n\n /** The admission rule: committed spend, open holds, the unspent claim\n * reserve and the new hold stay within the cap. A claim cell draws on the\n * claim reserve instead of adding to it. */\n private admit(reservation: SearchReservation | null, claim: boolean, subject: string): void {\n const { maxUsd, reservedClaimUsd } = this.header!.budget\n if (maxUsd === null) return\n const hold = reservation?.usd ?? 0\n const remainingClaim = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n const total =\n this.audit.spend.committedUsd +\n this.audit.spend.openReservationUsd +\n (claim ? Math.max(0, remainingClaim - hold) : remainingClaim) +\n hold\n if (total > maxUsd + USD_TOLERANCE) {\n throw integrity(\n `${subject} is not admissible: committed $${round(this.audit.spend.committedUsd)} + open $${round(this.audit.spend.openReservationUsd)} + claim reserve $${round(remainingClaim)} + hold $${round(hold)} exceeds the cap $${maxUsd}`,\n )\n }\n }\n\n // ── Reads, for SearchStateView ─────────────────────────────────────────\n\n /** @internal The largest hold a new non-claim cell or operation may take,\n * and the claim reserve still unspent. */\n readBudget(): { headroomUsd: number | null; claimReserveUsd: number } {\n const { maxUsd, reservedClaimUsd } = this.header?.budget ?? {\n maxUsd: null,\n reservedClaimUsd: 0,\n }\n const claimReserveUsd = Math.max(0, reservedClaimUsd - this.claimUsedUsd)\n if (maxUsd === null) return { headroomUsd: null, claimReserveUsd }\n const used =\n this.audit.spend.committedUsd + this.audit.spend.openReservationUsd + claimReserveUsd\n return { headroomUsd: Math.max(0, maxUsd - used), claimReserveUsd }\n }\n\n /** @internal */\n readHeader(): SearchOpenedEvent | null {\n return this.header\n }\n\n /** @internal */\n readClosed(): SearchClosedEvent | null {\n return this.closed\n }\n\n /** @internal */\n readHead(): { sequence: number; entryHash: SearchLedgerHash } | null {\n return this.head\n }\n\n /** @internal */\n readLastOccurredAt(): string | null {\n return this.lastOccurredAtText\n }\n\n /** @internal */\n readAudit(): SearchAudit {\n const audit = this.audit\n return {\n ...audit,\n edges: { ...audit.edges },\n cells: { ...audit.cells },\n outcomes: { ...audit.outcomes },\n operations: { ...audit.operations },\n spend: { ...audit.spend },\n tokens: { ...audit.tokens },\n }\n }\n\n /** @internal */\n readNode(nodeId: string): SearchNode | undefined {\n const record = this.nodes.get(nodeId)\n return record ? nodeView(record) : undefined\n }\n\n /** @internal */\n readNodeIds(): readonly string[] {\n return this.nodeOrder\n }\n\n /** @internal */\n readHasNode(nodeId: string): boolean {\n return this.nodes.has(nodeId)\n }\n\n /** @internal */\n readNodeIdForDigest(artifactDigest: string): string | undefined {\n return this.nodeByDigest.get(artifactDigest)\n }\n\n /** @internal */\n readEdge(edgeId: string): SearchEdgeRecordedEvent | undefined {\n return this.edges.get(edgeId)\n }\n\n /** @internal */\n readEdgeIds(): readonly string[] {\n return this.edgeOrder\n }\n\n /** @internal */\n readCell(cellId: string): SearchCell | undefined {\n const cell = this.cells.get(cellId)\n return cell ? { ...cell } : undefined\n }\n\n /** @internal */\n readCellIds(nodeId?: string): readonly string[] {\n if (nodeId === undefined) return [...this.cells.keys()]\n return this.nodes.get(nodeId)?.cellIds ?? []\n }\n\n /** @internal */\n readOperation(operationId: string): SearchOperation | undefined {\n const operation = this.operations.get(operationId)\n return operation ? { ...operation } : undefined\n }\n\n /** @internal */\n readScoredCells(nodeId: string, split: SearchSplit): SearchScoredCell[] {\n const scored: SearchScoredCell[] = []\n for (const cellId of this.nodes.get(nodeId)?.cellIds ?? []) {\n const cell = this.cells.get(cellId)!\n if (cell.split === split && cell.score !== null) {\n scored.push({ cellId, unitId: cell.unitId, attempt: cell.attempts, score: cell.score })\n }\n }\n return scored\n }\n}\n\n/**\n * A read of `SearchState` at one ledger position. Header, head, audit and\n * claim are values. Node, edge, cell and score reads go to the live indexes and\n * throw once the state has applied a later entry.\n */\nexport class SearchStateView {\n readonly searchId: string\n readonly header: SearchOpenedEvent | null\n readonly closed: SearchClosedEvent | null\n readonly head: { sequence: number; entryHash: SearchLedgerHash } | null\n /** `occurredAt` of the head entry; a writer stamps later events at or after it. */\n readonly lastOccurredAt: string | null\n readonly audit: SearchAudit\n readonly completion: SearchCompletion\n /**\n * The admission rule's room: `headroomUsd` is the largest reservation a new\n * non-claim cell or operation may hold (committed spend, open holds and the\n * unspent claim reserve all count against the cap), or null when the search\n * declares no cap. `claimReserveUsd` is what claim cells may still draw.\n */\n readonly budget: { headroomUsd: number | null; claimReserveUsd: number }\n private readonly state: SearchState\n private readonly version: number\n\n constructor(state: SearchState, version: number) {\n this.state = state\n this.version = version\n this.searchId = state.searchId\n this.header = state.readHeader()\n this.closed = state.readClosed()\n this.head = state.readHead()\n this.lastOccurredAt = state.readLastOccurredAt()\n this.audit = state.readAudit()\n this.budget = state.readBudget()\n const reasons = state.incompleteReasons()\n if (!this.closed) reasons.unshift('search is open')\n this.completion = { complete: this.closed !== null, reasons }\n }\n\n /** The node the search started from: the first registered. */\n get rootNodeId(): string | null {\n return this.live().readNodeIds()[0] ?? null\n }\n\n node(nodeId: string): SearchNode | undefined {\n return this.live().readNode(nodeId)\n }\n\n hasNode(nodeId: string): boolean {\n return this.live().readHasNode(nodeId)\n }\n\n /** Node ids in registration order. */\n nodeIds(): string[] {\n return [...this.live().readNodeIds()]\n }\n\n /** Nodes in registration order. */\n nodes(): SearchNode[] {\n const state = this.live()\n return state.readNodeIds().map((nodeId) => state.readNode(nodeId)!)\n }\n\n nodeIdForDigest(artifactDigest: string): string | undefined {\n return this.live().readNodeIdForDigest(artifactDigest)\n }\n\n edge(edgeId: string): SearchEdgeRecordedEvent | undefined {\n return this.live().readEdge(edgeId)\n }\n\n /** Edges in ledger order. */\n edges(): SearchEdgeRecordedEvent[] {\n const state = this.live()\n return state.readEdgeIds().map((edgeId) => state.readEdge(edgeId)!)\n }\n\n cell(cellId: string): SearchCell | undefined {\n return this.live().readCell(cellId)\n }\n\n /** Cells in allocation order, optionally of one node. */\n cells(filter: { nodeId?: string } = {}): SearchCell[] {\n const state = this.live()\n return state.readCellIds(filter.nodeId).map((cellId) => state.readCell(cellId)!)\n }\n\n operation(operationId: string): SearchOperation | undefined {\n return this.live().readOperation(operationId)\n }\n\n /** A node's scored cells on one split, in allocation order. Unscored cells\n * (errored, cancelled or in flight) are absent, never zero. */\n scoredCells(nodeId: string, split: SearchSplit): SearchScoredCell[] {\n return this.live().readScoredCells(nodeId, split)\n }\n\n /** Per-unit score means of a node on one split, in unitId order. */\n unitScores(nodeId: string, split: SearchSplit): SearchUnitScore[] {\n return searchUnitScores(this.scoredCells(nodeId, split))\n }\n\n /** The lineage a RunRecord mint needs for one cell attempt. */\n lineage(coordinates: RunSearchCoordinates): RolloutSearchLineage {\n const state = this.live()\n if (coordinates.searchId !== this.searchId) {\n throw new SearchLedgerError(\n `coordinates name search ${coordinates.searchId}, not ${this.searchId}`,\n )\n }\n const cell = state.readCell(coordinates.cellId)\n if (!cell || cell.nodeId !== coordinates.nodeId) {\n throw new SearchLedgerError(\n `cell ${coordinates.cellId} of node ${coordinates.nodeId} is not in search ${this.searchId}`,\n )\n }\n if (coordinates.attempt < 1 || coordinates.attempt > cell.attempts) {\n throw new SearchLedgerError(\n `cell ${coordinates.cellId} has ${cell.attempts} settled attempt(s), not attempt ${coordinates.attempt}`,\n )\n }\n const node = state.readNode(cell.nodeId)!\n if (node.depth === null) {\n throw new SearchLedgerError(\n `node ${node.nodeId} has unknown lineage, so its depth is unknown`,\n )\n }\n const containment = this.header?.containment ?? null\n return {\n depth: node.depth,\n ordinal: node.ordinal,\n rep: cell.rep,\n containingRunId: containment\n ? searchCellRunId({ cellId: containment.cellId, attempt: containment.attempt })\n : null,\n }\n }\n\n private live(): SearchState {\n if (!this.state.isAt(this.version)) {\n throw new SearchLedgerError(\n `this SearchStateView is from sequence ${this.head?.sequence ?? -1}, and the ledger has moved on; read the ledger's state again`,\n )\n }\n return this.state\n }\n}\n\nfunction nodeView(record: NodeRecord): SearchNode {\n const latest = record.decisions.at(-1)?.decision ?? null\n return {\n nodeId: record.event.nodeId,\n ordinal: record.ordinal,\n artifactDigest: record.event.artifactDigest,\n artifact: record.event.artifact,\n surfaces: record.event.surfaces,\n primaryParentId: record.primaryParentId,\n depth: record.depth,\n parents: [...record.parents],\n children: [...record.children],\n edgeIds: [...record.edgeIds],\n status: latest?.status ?? null,\n rung: latest?.status === 'advanced' ? latest.rung : null,\n finalist: record.finalist,\n decisions: [...record.decisions],\n cellCount: record.cellIds.length,\n spend: { ...record.spend },\n registeredSequence: record.registeredSequence,\n updatedSequence: record.updatedSequence,\n }\n}\n\nfunction assertStageSplit(\n cellId: string,\n stage: SearchCellStage,\n split: SearchSplit,\n isRoot: boolean,\n): void {\n const allowed: Record<SearchCellStage, readonly SearchSplit[]> = {\n root: ['train', 'selection'],\n train: ['train'],\n screen: ['selection'],\n rung: ['selection'],\n claim: ['test'],\n external: ['train', 'selection'],\n }\n if (!allowed[stage].includes(split)) {\n throw integrity(`cell ${cellId}: a ${stage} cell cannot run on the ${split} split`)\n }\n if (stage === 'root' && !isRoot) {\n throw integrity(`cell ${cellId}: only the root node runs root cells`)\n }\n}\n\nfunction assertUnique(values: readonly string[], label: string, eventId: string): void {\n if (new Set(values).size !== values.length) {\n throw integrity(`event ${eventId} contains duplicate ${label} values`)\n }\n}\n\nfunction count(value: number, noun: string, predicate: string): string {\n const verb = predicate.replace(/^(has|is) /, (word) =>\n value === 1 ? word : word === 'has ' ? 'have ' : 'are ',\n )\n return `${value} ${value === 1 ? noun : `${noun}s`} ${verb}`\n}\n\nfunction round(usd: number): number {\n return Math.round(usd * 1e6) / 1e6\n}\n\nfunction integrity(message: string): SearchLedgerIntegrityError {\n return new SearchLedgerIntegrityError(message)\n}\n","import type { AgentProfileDiff } from '@tangle-network/agent-interface'\nimport type { EvaluationClaim } from '../experiment/claim'\nimport type { LedgerHash } from '../ledger-core'\n\n/**\n * Schema tag every search-ledger entry carries. A ledger written under another\n * tag, such as the retired `tangle.search-ledger.v1` candidate-slot format, is\n * refused with its tag named; it is never translated.\n */\nexport const SEARCH_LEDGER_SCHEMA = 'tangle.search-ledger.2026-09' as const\n\nexport type SearchLedgerHash = LedgerHash\n\nexport type SearchSurfaceKind =\n | 'prompt'\n | 'tool-contract'\n | 'runtime-config'\n | 'memory'\n | 'knowledge'\n | 'agent-profile'\n | 'code'\n | 'deployment'\n\n/** What a search's nodes are: a mutable agent surface, or an output artifact. */\nexport type SearchArtifactKind = SearchSurfaceKind | 'output'\n\n/** Content-addressed artifact or receipt. Mutable paths are locators only; the\n * digest and byte length bind the exact bytes. */\nexport interface SearchArtifactRef {\n role: string\n uri: string\n sha256: SearchLedgerHash\n byteLength: number\n}\n\n/** Repository, dataset, or package source pinned to an immutable commit or\n * content digest. Branches, tags, and bare package versions are rejected. */\nexport interface SearchSourceRef {\n uri: string\n revision: string\n}\n\n/** A fact the producer does not have, with the reason. Unknown is never 0. */\nexport interface SearchUnknown {\n unknown: string\n}\n\n/** The model an attempt ran: an immutable snapshot, or a moving alias whose\n * served snapshot the producer could not observe. */\nexport type SearchModelIdentity =\n | { provider: string; snapshot: string }\n | { provider: string; alias: string; unknown: string }\n\nexport interface SearchCandidateSurface {\n surfaceId: string\n kind: SearchSurfaceKind\n artifact: SearchArtifactRef\n}\n\nexport type SearchOperationKind =\n | 'candidate-generation'\n | 'analysis'\n | 'selection'\n | 'judge'\n | 'other'\n\n/** train is the proposer's feedback, selection is private to the policy and\n * allocator, and test is sealed for the claim. */\nexport type SearchSplit = 'train' | 'selection' | 'test'\n\nexport interface SearchTask {\n taskId: string\n /** The claim's independent unit this task samples. Repeats and sibling\n * tasks of one unit average inside it before any statistic. */\n unitId: string\n source: SearchSourceRef\n}\n\nexport interface SearchSplitTasks {\n /** `hashCanonical` of `tasks` in taskId order. */\n taskSetDigest: SearchLedgerHash\n tasks: SearchTask[]\n}\n\nexport interface SearchSplits {\n train: SearchSplitTasks\n selection: SearchSplitTasks\n test: SearchSplitTasks\n /**\n * True when no test unit is a train or selection unit. A search that ran\n * with shared units records false, and then its claim cannot ship: a test\n * run of a seen unit measures a fresh run of a seen task, not an\n * improvement on unseen ones.\n */\n heldOutUnits: boolean\n}\n\nexport interface SearchBudget {\n /** Hard dollar cap on committed spend plus open reservations; null = none declared. */\n maxUsd: number | null\n maxCells: number | null\n maxNodes: number | null\n /** ISO time after which the policy stops expanding. */\n deadline: string | null\n maxConcurrency: number | null\n /** Held back at start for the root's and finalists' test cells. */\n reservedClaimUsd: number\n}\n\n/** Where a cell ran relative to the search's decisions. */\nexport type SearchCellStage = 'root' | 'train' | 'screen' | 'rung' | 'claim' | 'external'\n\nexport type SearchEdgeOperator = 'seed' | 'draft' | 'improve' | 'debug' | 'merge' | 'derive'\n\n/**\n * How an edge's parents are known. `explicit`: the proposer that created the\n * child emitted the edge. `correlated`: an importer joined an optimizer's own\n * parent record by content digest. `unknown`: no parent record exists, and the\n * edge has no parents. Nothing is inferred from timing or order.\n */\nexport type SearchEdgeAttribution = 'explicit' | 'correlated' | 'unknown'\n\nexport type SearchProposerKind = NonNullable<AgentProfileDiff['source']>['kind']\n\nexport interface SearchProposer {\n kind: SearchProposerKind\n name: string\n /** The candidate-generation operation that produced the child, when one was recorded. */\n operationId: string | null\n source: SearchSourceRef\n}\n\nexport interface SearchNodeRef {\n searchId: string\n nodeId: string\n}\n\n/** Dollars held for a cell or operation before it runs. `hard`: the lane\n * enforces the maximum. `estimate`: the lane cannot, and overshoot is recorded. */\nexport interface SearchReservation {\n kind: 'hard' | 'estimate'\n usd: number\n}\n\nexport type SearchTokenAccounting =\n | {\n status: 'known'\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n }\n | {\n status: 'unknown'\n reason: string\n }\n\nexport type SearchCostAccounting =\n | {\n status: 'known'\n usd: number\n source: 'provider' | 'pricing-table' | 'free'\n }\n | {\n status: 'unknown'\n /** Proven part of the spend; the total may be higher. */\n knownLowerBoundUsd: number\n reason: string\n }\n\nexport interface SearchAttemptAccounting {\n tokens: SearchTokenAccounting\n cost: SearchCostAccounting\n}\n\nexport interface SearchFailureReason {\n code: string\n message: string\n}\n\n/** `failed` is the agent's defect and carries a score; `errored` is the\n * environment's fault, carries none, and may be retried. */\nexport type SearchTaskOutcome =\n | {\n status: 'passed'\n score: number\n metrics: Record<string, number>\n }\n | {\n status: 'failed'\n score: number\n metrics: Record<string, number>\n failure: SearchFailureReason\n }\n | {\n status: 'errored'\n metrics: Record<string, number>\n error: SearchFailureReason & { retryable: boolean }\n }\n\nexport type SearchSurfaceEffect =\n | {\n status: 'measured'\n metric: string\n baselineValue: number\n candidateValue: number\n delta: number\n }\n | {\n status: 'not-measured'\n reason: string\n }\n\n/** Per-attempt proof that a declared node surface did or did not fire. A\n * surface without evidence is unobserved, not fired. */\nexport interface SearchSurfaceEvidence {\n surfaceId: string\n fired: boolean\n firingCount: number\n effect: SearchSurfaceEffect\n evidence: SearchArtifactRef[]\n}\n\nexport type SearchTraceRef =\n | {\n traceId: string\n execRunId: string | null\n spansWritten: number | null\n spansDropped: number | null\n }\n | SearchUnknown\n\nexport interface SearchExecutionIdentity {\n model: SearchModelIdentity\n agent: SearchSourceRef\n benchmark: SearchSourceRef\n}\n\nexport type SearchEstimateMethod = 'none' | 'insufficient' | 'descriptive' | 'bootstrap'\n\n/**\n * A paired contrast of one node against another on shared units. `none` below\n * 2 pairs, `insufficient` below 6, `descriptive` below 20, `bootstrap` from 20.\n * `estimateNode` computes it; the ledger records the estimate a decision used.\n */\nexport interface NodeEstimate {\n against: string\n split: SearchSplit\n /** Units the node scored on the split. */\n units: number\n /** Units both nodes scored: the paired sample. */\n pairs: number\n /** Mean per-unit difference, node minus `against`, in the metric's units.\n * Null for `none`. */\n delta: number | null\n /** Bootstrap interval on `delta`: spread for `descriptive`, decision grade\n * for `bootstrap`. Null for `none`, `insufficient` and an indeterminate sample. */\n interval: [number, number] | null\n method: SearchEstimateMethod\n /** Exact one-sided sign-test p toward improvement; `descriptive` only. */\n exactSignP: number | null\n /** Every paired delta is equal, so an interval would have zero width and\n * carries no evidence either way. */\n indeterminate: boolean\n /** Digest of the cells read, which also seeds the bootstrap. */\n cellSetDigest: SearchLedgerHash\n estimator: SearchSourceRef\n}\n\nexport type SearchNodeDecision =\n | { status: 'advanced'; rung: number }\n | { status: 'pruned' }\n | { status: 'invalid' }\n | { status: 'finalist' }\n | { status: 'selected' }\n | { status: 'rejected' }\n\nexport type SearchNodeStatus = SearchNodeDecision['status']\n\nexport type SearchCloseReason =\n | 'budget'\n | 'deadline'\n | 'max-nodes'\n | 'patience'\n | 'converged'\n | 'aborted'\n\nexport type SearchCancelReason = 'pruned' | 'budget' | 'deadline' | 'aborted'\n\nexport type SearchClaimPower =\n | {\n adequate: boolean\n minimumEffect: number\n powerAtMinimumEffect: number\n units: number\n }\n | SearchUnknown\n\n/** The claim made once, on the sealed test split. `selected` names the node the\n * search keeps: a finalist on `ship`, the root otherwise (or null when the\n * search keeps nothing). */\nexport interface SearchClaim {\n power: SearchClaimPower\n finalists: Array<{ nodeId: string; estimate: NodeEstimate | null; promote: boolean }>\n selected: string | null\n decision: 'ship' | 'hold' | 'test-cannot-resolve'\n}\n\ninterface SearchLedgerEventBase {\n eventId: string\n occurredAt: string\n artifacts: SearchArtifactRef[]\n}\n\n/** First event, once: what is searched, against what, on which tasks, under which budget. */\nexport interface SearchOpenedEvent extends SearchLedgerEventBase {\n kind: 'search-opened'\n /** What the search improves, for example `vb/coder`. */\n subject: string\n process: { name: string; executionRef: SearchSourceRef }\n artifactKind: SearchArtifactKind\n objective: {\n metric: string\n direction: 'maximize' | 'minimize'\n judge: SearchSourceRef | SearchUnknown\n claim: EvaluationClaim\n }\n splits: SearchSplits\n policy: { expansion: string; allocation: string; seed: number }\n budget: SearchBudget\n /** The cell attempt of another search whose execution runs this one. */\n containment: { searchId: string; cellId: string; attempt: number } | null\n /** The node of another search this one starts from. */\n derivedFrom: { searchId: string; nodeId: string; headHash: SearchLedgerHash } | null\n identity: SearchExecutionIdentity\n}\n\nexport interface SearchOperationStartedEvent extends SearchLedgerEventBase {\n kind: 'operation-started'\n operationId: string\n operationKind: SearchOperationKind\n reservation: SearchReservation | null\n}\n\nexport interface SearchOperationRecordedEvent extends SearchLedgerEventBase {\n kind: 'operation-recorded'\n operationId: string\n operationKind: SearchOperationKind\n execution:\n | {\n kind: 'model'\n model: SearchModelIdentity\n source: SearchSourceRef\n }\n | {\n kind: 'deterministic'\n source: SearchSourceRef\n }\n outcome:\n | { status: 'completed' }\n | { status: 'partial'; failure: SearchFailureReason }\n | { status: 'failed'; failure: SearchFailureReason }\n accounting: SearchAttemptAccounting\n}\n\n/** A content-addressed artifact enters the search. `nodeId` is\n * `searchNodeId(searchId, artifactDigest)`, so a re-proposal of identical\n * content is a second edge into this node, never a second node. */\nexport interface SearchNodeRegisteredEvent extends SearchLedgerEventBase {\n kind: 'node-registered'\n nodeId: string\n artifactDigest: SearchLedgerHash\n artifact: SearchArtifactRef\n surfaces: SearchCandidateSurface[]\n}\n\n/** The proposal that derived a node from its parents. */\nexport interface SearchEdgeRecordedEvent extends SearchLedgerEventBase {\n kind: 'edge-recorded'\n edgeId: string\n childNodeId: string\n /** Primary parent first. Empty for `seed` and for `unknown` attribution; a\n * parent in another search appears only on a `derive` edge. */\n parents: SearchNodeRef[]\n operator: SearchEdgeOperator\n attribution: SearchEdgeAttribution\n /** Null only on a `seed` edge: the search's starting artifact was not proposed. */\n proposer: SearchProposer | null\n /** Why the policy chose these parents. */\n selection: { rule: string; evidence: Record<string, number> } | null\n /** The proposer's redacted rationale. */\n rationale: SearchArtifactRef | SearchUnknown\n /** One diff per parent, parent to child. */\n diffs: Array<SearchArtifactRef | SearchUnknown>\n /** At most 200 characters, redacted. */\n label: string\n}\n\n/** One node on one task in one split at one repeat is planned. `cellId` is\n * `searchCellId(searchId, nodeId, taskId, split, rep)`. */\nexport interface SearchCellAllocatedEvent extends SearchLedgerEventBase {\n kind: 'cell-allocated'\n cellId: string\n nodeId: string\n taskId: string\n unitId: string\n split: SearchSplit\n rep: number\n stage: SearchCellStage\n lane: string | null\n /** Null when no reservation was made: an external optimizer dispatched the cell. */\n reservation: SearchReservation | null\n}\n\n/** One attempt at a cell finished. Its RunRecord, when the producer minted one,\n * is an artifact with role `run-record`. */\nexport interface SearchCellSettledEvent extends SearchLedgerEventBase {\n kind: 'cell-settled'\n cellId: string\n /** Counted from 1 without gaps. */\n attempt: number\n /** `searchCellRunId({ cellId, attempt })`. */\n runId: string\n outcome: SearchTaskOutcome\n accounting: SearchAttemptAccounting\n boxMinutes: number | null\n wallMs: number | null\n queueMs: number | null\n placement: { lane: string; boxId: string | null } | null\n identity: SearchExecutionIdentity\n surfaceEvidence: SearchSurfaceEvidence[]\n traceRef: SearchTraceRef\n}\n\nexport interface SearchCellCancelledEvent extends SearchLedgerEventBase {\n kind: 'cell-cancelled'\n cellId: string\n reason: SearchCancelReason\n}\n\n/** A policy, allocator or claim decision about a node. May repeat; the latest wins. */\nexport interface SearchNodeDecidedEvent extends SearchLedgerEventBase {\n kind: 'node-decided'\n nodeId: string\n decision: SearchNodeDecision\n basis: NodeEstimate | null\n rule: string\n reason: string\n}\n\n/** Last event, once. More work on a closed search is a derived search. */\nexport interface SearchClosedEvent extends SearchLedgerEventBase {\n kind: 'search-closed'\n reason: SearchCloseReason\n claim: SearchClaim | null\n}\n\nexport type SearchLedgerEvent =\n | SearchOpenedEvent\n | SearchOperationStartedEvent\n | SearchOperationRecordedEvent\n | SearchNodeRegisteredEvent\n | SearchEdgeRecordedEvent\n | SearchCellAllocatedEvent\n | SearchCellSettledEvent\n | SearchCellCancelledEvent\n | SearchNodeDecidedEvent\n | SearchClosedEvent\n\nexport interface SearchLedgerEntry {\n schema: typeof SEARCH_LEDGER_SCHEMA\n searchId: string\n sequence: number\n previousHash: SearchLedgerHash | null\n event: SearchLedgerEvent\n entryHash: SearchLedgerHash\n}\n\n/** Counts and sums over the whole search. Every field is a number or a short\n * scalar, so reading the audit costs the same at any search size. */\nexport interface SearchAudit {\n searchId: string\n eventCount: number\n headHash: SearchLedgerHash | null\n status: 'open' | 'closed'\n closeReason: SearchCloseReason | null\n nodes: number\n /** Nodes with no edge yet: not placed in the tree. */\n nodesWithoutEdge: number\n /** Nodes whose latest decision is missing or `advanced`. */\n undecidedNodes: number\n selectedNodeId: string | null\n edges: { explicit: number; correlated: number; unknown: number; reproposals: number }\n cells: { allocated: number; settled: number; cancelled: number; open: number }\n attempts: number\n outcomes: { passed: number; failed: number; errored: number }\n operations: { started: number; recorded: number; open: number }\n spend: {\n /** Sum of known cell and operation costs. */\n knownUsd: number\n /** Sum of the proven lower bounds of unknown costs. */\n floorUsd: number\n unknownCostCells: number\n unknownCostOperations: number\n /** knownUsd + floorUsd. */\n committedUsd: number\n /** Reservations of unsettled cells and unrecorded operations, net of their spend so far. */\n openReservationUsd: number\n /** Spend above reservations. */\n overspendUsd: number\n /** Settled cells that ran without a reservation. */\n unreservedCells: number\n boxMinutes: number\n }\n tokens: {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n unknownTokenAttempts: number\n }\n}\n","/**\n * Durable, append-only event log of one search: nodes (content-addressed\n * artifacts), edges (the proposals that derived them), cells (one run of one\n * node on one task), operations, decisions, and the claim.\n *\n * The ledger is the search's only lineage record and its only resume\n * checkpoint. A RunRecord owns one measured run and `CostLedger` owns per-call\n * accounting; this ledger binds them by digest instead of copying them.\n *\n * The file format is canonical JSONL with a SHA-256 hash chain. Every append is\n * serialized across processes, fsynced before acknowledgement, and idempotent\n * by `eventId`. A malformed, non-canonical, truncated, reordered, or conflicting\n * log fails loudly; a bad row is never skipped. A ledger written under another\n * schema tag is refused with that tag named, never translated.\n *\n * The journal machinery is the generic `ledger-core` journal. This module is\n * the search codec: event schemas and canonical ordering. `SearchState` is the\n * state machine and read model.\n */\n\nimport { z } from 'zod'\nimport { evaluationClaimSchema } from '../experiment/claim'\nimport {\n canonicalString,\n FileLedgerJournal,\n hashCanonical,\n type LedgerJournalCodec,\n type LedgerLineContext,\n type LedgerTextStore,\n type LedgerTrustedHead,\n type LedgerTrustedHeadRemoval,\n MemoryLedgerJournal,\n replayLedgerText,\n} from '../ledger-core'\nimport { modelHasSnapshot } from '../run-record'\nimport {\n SearchLedgerConflictError,\n SearchLedgerError,\n SearchLedgerIntegrityError,\n} from './search-ledger-errors'\nimport { SEARCH_LEDGER_FILE_CONTEXT } from './search-ledger-file'\nimport { artifactKey, compareStrings } from './search-ledger-ordering'\nimport {\n SEARCH_LEDGER_SCHEMA,\n type SearchArtifactRef,\n type SearchLedgerEntry,\n type SearchLedgerEvent,\n type SearchTask,\n} from './search-ledger-types'\nimport { SearchState, type SearchStateView } from './search-state'\n\nexport { SearchLedgerConflictError, SearchLedgerError, SearchLedgerIntegrityError }\n\nconst NON_EMPTY = z\n .string()\n .min(1)\n .refine((value) => value.trim() === value, 'must not contain surrounding whitespace')\n\nconst HASH = z.string().regex(/^sha256:[a-f0-9]{64}$/)\n\nconst IMMUTABLE_REVISION = z\n .string()\n .regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64}|sha256:[a-f0-9]{64}|sha512:[A-Za-z0-9+/=]+)$/)\n\nconst ISO_TIMESTAMP = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/)\n .refine((value) => Number.isFinite(Date.parse(value)), 'invalid timestamp')\n\nconst NON_NEGATIVE_INT = z.number().int().nonnegative().safe()\nconst POSITIVE_INT = z.number().int().positive().safe()\nconst FINITE_NUMBER = z.number().finite()\nconst USD = z.number().finite().nonnegative()\n\nconst NODE_ID = z.string().regex(/^node_[a-f0-9]{32}$/)\nconst CELL_ID = z.string().regex(/^cell_[a-f0-9]{32}$/)\n\nconst ArtifactRefSchema = z\n .object({ role: NON_EMPTY, uri: NON_EMPTY, sha256: HASH, byteLength: NON_NEGATIVE_INT })\n .strict()\n\nconst SourceRefSchema = z.object({ uri: NON_EMPTY, revision: IMMUTABLE_REVISION }).strict()\n\nconst UnknownRefSchema = z.object({ unknown: NON_EMPTY }).strict()\n\nconst FailureReasonSchema = z.object({ code: NON_EMPTY, message: NON_EMPTY }).strict()\n\nconst ModelIdentitySchema = z.union([\n z\n .object({\n provider: NON_EMPTY,\n snapshot: NON_EMPTY.refine(modelHasSnapshot, 'model must include an immutable snapshot'),\n })\n .strict(),\n z.object({ provider: NON_EMPTY, alias: NON_EMPTY, unknown: NON_EMPTY }).strict(),\n])\n\nconst ExecutionIdentitySchema = z\n .object({ model: ModelIdentitySchema, agent: SourceRefSchema, benchmark: SourceRefSchema })\n .strict()\n\nconst SURFACE_KINDS = [\n 'prompt',\n 'tool-contract',\n 'runtime-config',\n 'memory',\n 'knowledge',\n 'agent-profile',\n 'code',\n 'deployment',\n] as const\n\nconst SPLIT = z.enum(['train', 'selection', 'test'])\n\nconst ReservationSchema = z.object({ kind: z.enum(['hard', 'estimate']), usd: USD }).strict()\n\nconst EventBaseShape = {\n eventId: NON_EMPTY,\n occurredAt: ISO_TIMESTAMP,\n artifacts: z.array(ArtifactRefSchema),\n}\n\nconst OperationKindSchema = z.enum([\n 'candidate-generation',\n 'analysis',\n 'selection',\n 'judge',\n 'other',\n])\n\nconst KnownTokensSchema = z\n .object({\n status: z.literal('known'),\n inputTokens: NON_NEGATIVE_INT,\n outputTokens: NON_NEGATIVE_INT,\n cachedTokens: NON_NEGATIVE_INT,\n })\n .strict()\n\nconst UnknownTokensSchema = z.object({ status: z.literal('unknown'), reason: NON_EMPTY }).strict()\n\nconst KnownCostSchema = z\n .object({\n status: z.literal('known'),\n usd: USD,\n source: z.enum(['provider', 'pricing-table', 'free']),\n })\n .strict()\n .superRefine((cost, ctx) => {\n if (cost.source === 'free' && cost.usd !== 0) {\n ctx.addIssue({ code: 'custom', message: 'free cost source must have usd 0' })\n }\n })\n\nconst UnknownCostSchema = z\n .object({ status: z.literal('unknown'), knownLowerBoundUsd: USD, reason: NON_EMPTY })\n .strict()\n\nconst AccountingSchema = z\n .object({\n tokens: z.discriminatedUnion('status', [KnownTokensSchema, UnknownTokensSchema]),\n cost: z.discriminatedUnion('status', [KnownCostSchema, UnknownCostSchema]),\n })\n .strict()\n\nconst MetricsSchema = z.record(NON_EMPTY, FINITE_NUMBER).superRefine((metrics, ctx) => {\n for (const key of Object.keys(metrics)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n ctx.addIssue({ code: 'custom', message: `unsafe metric key ${key}` })\n }\n }\n})\n\nconst OutcomeSchema = z.discriminatedUnion('status', [\n z.object({ status: z.literal('passed'), score: FINITE_NUMBER, metrics: MetricsSchema }).strict(),\n z\n .object({\n status: z.literal('failed'),\n score: FINITE_NUMBER,\n metrics: MetricsSchema,\n failure: FailureReasonSchema,\n })\n .strict(),\n z\n .object({\n status: z.literal('errored'),\n metrics: MetricsSchema,\n error: FailureReasonSchema.extend({ retryable: z.boolean() }).strict(),\n })\n .strict(),\n])\n\nconst EffectSchema = z.discriminatedUnion('status', [\n z\n .object({\n status: z.literal('measured'),\n metric: NON_EMPTY,\n baselineValue: FINITE_NUMBER,\n candidateValue: FINITE_NUMBER,\n delta: FINITE_NUMBER,\n })\n .strict()\n .superRefine((effect, ctx) => {\n const expected = effect.candidateValue - effect.baselineValue\n const tolerance = Number.EPSILON * Math.max(1, Math.abs(expected), Math.abs(effect.delta)) * 8\n if (Math.abs(effect.delta - expected) > tolerance) {\n ctx.addIssue({ code: 'custom', message: 'delta must equal candidateValue - baselineValue' })\n }\n }),\n z.object({ status: z.literal('not-measured'), reason: NON_EMPTY }).strict(),\n])\n\nconst SurfaceEvidenceSchema = z\n .object({\n surfaceId: NON_EMPTY,\n fired: z.boolean(),\n firingCount: NON_NEGATIVE_INT,\n effect: EffectSchema,\n evidence: z.array(ArtifactRefSchema).min(1),\n })\n .strict()\n .superRefine((evidence, ctx) => {\n if (evidence.fired !== evidence.firingCount > 0) {\n ctx.addIssue({ code: 'custom', message: 'fired must equal firingCount > 0' })\n }\n if (!evidence.fired && evidence.effect.status === 'measured' && evidence.effect.delta !== 0) {\n ctx.addIssue({ code: 'custom', message: 'a surface that did not fire has no effect' })\n }\n })\n\nconst TaskSchema = z\n .object({ taskId: NON_EMPTY, unitId: NON_EMPTY, source: SourceRefSchema })\n .strict()\n\nconst SplitTasksSchema = z.object({ taskSetDigest: HASH, tasks: z.array(TaskSchema) }).strict()\n\nconst SearchOpenedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('search-opened'),\n subject: NON_EMPTY,\n process: z.object({ name: NON_EMPTY, executionRef: SourceRefSchema }).strict(),\n artifactKind: z.enum([...SURFACE_KINDS, 'output']),\n objective: z\n .object({\n metric: NON_EMPTY,\n direction: z.enum(['maximize', 'minimize']),\n judge: z.union([SourceRefSchema, UnknownRefSchema]),\n claim: evaluationClaimSchema,\n })\n .strict(),\n splits: z\n .object({\n train: SplitTasksSchema,\n selection: SplitTasksSchema,\n test: SplitTasksSchema,\n heldOutUnits: z.boolean(),\n })\n .strict(),\n policy: z\n .object({ expansion: NON_EMPTY, allocation: NON_EMPTY, seed: z.number().int().safe() })\n .strict(),\n budget: z\n .object({\n maxUsd: USD.nullable(),\n maxCells: POSITIVE_INT.nullable(),\n maxNodes: POSITIVE_INT.nullable(),\n deadline: ISO_TIMESTAMP.nullable(),\n maxConcurrency: POSITIVE_INT.nullable(),\n reservedClaimUsd: USD,\n })\n .strict(),\n containment: z\n .object({ searchId: NON_EMPTY, cellId: CELL_ID, attempt: POSITIVE_INT })\n .strict()\n .nullable(),\n derivedFrom: z\n .object({ searchId: NON_EMPTY, nodeId: NODE_ID, headHash: HASH })\n .strict()\n .nullable(),\n identity: ExecutionIdentitySchema,\n })\n .strict()\n\nconst OperationStartedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('operation-started'),\n operationId: NON_EMPTY,\n operationKind: OperationKindSchema,\n reservation: ReservationSchema.nullable(),\n })\n .strict()\n\nconst OperationRecordedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('operation-recorded'),\n operationId: NON_EMPTY,\n operationKind: OperationKindSchema,\n execution: z.discriminatedUnion('kind', [\n z\n .object({ kind: z.literal('model'), model: ModelIdentitySchema, source: SourceRefSchema })\n .strict(),\n z.object({ kind: z.literal('deterministic'), source: SourceRefSchema }).strict(),\n ]),\n outcome: z.discriminatedUnion('status', [\n z.object({ status: z.literal('completed') }).strict(),\n z.object({ status: z.literal('partial'), failure: FailureReasonSchema }).strict(),\n z.object({ status: z.literal('failed'), failure: FailureReasonSchema }).strict(),\n ]),\n accounting: AccountingSchema,\n })\n .strict()\n\nconst NodeRegisteredSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('node-registered'),\n nodeId: NODE_ID,\n artifactDigest: HASH,\n artifact: ArtifactRefSchema,\n surfaces: z.array(\n z\n .object({ surfaceId: NON_EMPTY, kind: z.enum(SURFACE_KINDS), artifact: ArtifactRefSchema })\n .strict(),\n ),\n })\n .strict()\n\nconst NodeRefSchema = z.object({ searchId: NON_EMPTY, nodeId: NODE_ID }).strict()\n\nconst ArtifactOrUnknownSchema = z.union([ArtifactRefSchema, UnknownRefSchema])\n\nconst EdgeRecordedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('edge-recorded'),\n edgeId: z.string().regex(/^edge_[a-f0-9]{32}$/),\n childNodeId: NODE_ID,\n parents: z.array(NodeRefSchema),\n operator: z.enum(['seed', 'draft', 'improve', 'debug', 'merge', 'derive']),\n attribution: z.enum(['explicit', 'correlated', 'unknown']),\n proposer: z\n .object({\n kind: z.enum(['trace', 'frontier-author', 'human', 'optimizer', 'compound']),\n name: NON_EMPTY,\n operationId: NON_EMPTY.nullable(),\n source: SourceRefSchema,\n })\n .strict()\n .nullable(),\n selection: z\n .object({ rule: NON_EMPTY, evidence: z.record(NON_EMPTY, FINITE_NUMBER) })\n .strict()\n .nullable(),\n rationale: ArtifactOrUnknownSchema,\n diffs: z.array(ArtifactOrUnknownSchema),\n label: z.string(),\n })\n .strict()\n\nconst CellAllocatedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-allocated'),\n cellId: CELL_ID,\n nodeId: NODE_ID,\n taskId: NON_EMPTY,\n unitId: NON_EMPTY,\n split: SPLIT,\n rep: NON_NEGATIVE_INT,\n stage: z.enum(['root', 'train', 'screen', 'rung', 'claim', 'external']),\n lane: NON_EMPTY.nullable(),\n reservation: ReservationSchema.nullable(),\n })\n .strict()\n\nconst TraceRefSchema = z.union([\n z\n .object({\n traceId: NON_EMPTY,\n execRunId: NON_EMPTY.nullable(),\n spansWritten: NON_NEGATIVE_INT.nullable(),\n spansDropped: NON_NEGATIVE_INT.nullable(),\n })\n .strict(),\n UnknownRefSchema,\n])\n\nconst NON_NEGATIVE = z.number().finite().nonnegative()\n\nconst CellSettledSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-settled'),\n cellId: CELL_ID,\n attempt: POSITIVE_INT,\n runId: NON_EMPTY,\n outcome: OutcomeSchema,\n accounting: AccountingSchema,\n boxMinutes: NON_NEGATIVE.nullable(),\n wallMs: NON_NEGATIVE.nullable(),\n queueMs: NON_NEGATIVE.nullable(),\n placement: z.object({ lane: NON_EMPTY, boxId: NON_EMPTY.nullable() }).strict().nullable(),\n identity: ExecutionIdentitySchema,\n surfaceEvidence: z.array(SurfaceEvidenceSchema),\n traceRef: TraceRefSchema,\n })\n .strict()\n\nconst CellCancelledSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('cell-cancelled'),\n cellId: CELL_ID,\n reason: z.enum(['pruned', 'budget', 'deadline', 'aborted']),\n })\n .strict()\n\nconst NodeEstimateSchema = z\n .object({\n against: NODE_ID,\n split: SPLIT,\n units: NON_NEGATIVE_INT,\n pairs: NON_NEGATIVE_INT,\n delta: FINITE_NUMBER.nullable(),\n interval: z.tuple([FINITE_NUMBER, FINITE_NUMBER]).nullable(),\n method: z.enum(['none', 'insufficient', 'descriptive', 'bootstrap']),\n exactSignP: z.number().min(0).max(1).nullable(),\n indeterminate: z.boolean(),\n cellSetDigest: HASH,\n estimator: SourceRefSchema,\n })\n .strict()\n\nconst NodeDecidedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('node-decided'),\n nodeId: NODE_ID,\n decision: z.discriminatedUnion('status', [\n z.object({ status: z.literal('advanced'), rung: NON_NEGATIVE_INT }).strict(),\n z.object({ status: z.literal('pruned') }).strict(),\n z.object({ status: z.literal('invalid') }).strict(),\n z.object({ status: z.literal('finalist') }).strict(),\n z.object({ status: z.literal('selected') }).strict(),\n z.object({ status: z.literal('rejected') }).strict(),\n ]),\n basis: NodeEstimateSchema.nullable(),\n rule: NON_EMPTY,\n reason: NON_EMPTY,\n })\n .strict()\n\nconst SearchClosedSchema = z\n .object({\n ...EventBaseShape,\n kind: z.literal('search-closed'),\n reason: z.enum(['budget', 'deadline', 'max-nodes', 'patience', 'converged', 'aborted']),\n claim: z\n .object({\n power: z.union([\n z\n .object({\n adequate: z.boolean(),\n minimumEffect: z.number().finite().positive(),\n powerAtMinimumEffect: z.number().min(0).max(1),\n units: NON_NEGATIVE_INT,\n })\n .strict(),\n UnknownRefSchema,\n ]),\n finalists: z.array(\n z\n .object({\n nodeId: NODE_ID,\n estimate: NodeEstimateSchema.nullable(),\n promote: z.boolean(),\n })\n .strict(),\n ),\n selected: NODE_ID.nullable(),\n decision: z.enum(['ship', 'hold', 'test-cannot-resolve']),\n })\n .strict()\n .nullable(),\n })\n .strict()\n\nconst EventSchema = z.discriminatedUnion('kind', [\n SearchOpenedSchema,\n OperationStartedSchema,\n OperationRecordedSchema,\n NodeRegisteredSchema,\n EdgeRecordedSchema,\n CellAllocatedSchema,\n CellSettledSchema,\n CellCancelledSchema,\n NodeDecidedSchema,\n SearchClosedSchema,\n])\n\nconst EntrySchema = z\n .object({\n schema: z.literal(SEARCH_LEDGER_SCHEMA),\n searchId: NON_EMPTY,\n sequence: NON_NEGATIVE_INT,\n previousHash: z.union([HASH, z.null()]),\n event: EventSchema,\n entryHash: HASH,\n })\n .strict()\n\n/** Validate and return a canonical copy. Arrays whose order carries no meaning\n * are sorted, so retries from different processes produce identical bytes. */\nexport function validateSearchLedgerEvent(input: unknown): SearchLedgerEvent {\n const parsed = EventSchema.safeParse(input)\n if (!parsed.success) {\n throw new SearchLedgerError(`invalid search ledger event: ${formatZodError(parsed.error)}`)\n }\n return normalizeEvent(parsed.data as SearchLedgerEvent)\n}\n\n/**\n * How this ledger uses its trusted head — the `(sequence, entryHash)` pin kept\n * in the sibling `<path>.head` file that a hash chain needs to prove entries\n * were not deleted from the end. `ledger-core/trusted-head.ts` holds the threat\n * model.\n *\n * - `pin` (default): every append records the new head, and a pin that is\n * present is verified on every read.\n * - `require`: additionally refuses to read a non-empty ledger whose pin is\n * gone, so deleting the sibling file cannot downgrade the guarantee.\n * - `off`: chain verification only. Truncation to a valid shorter prefix is\n * undetectable.\n */\nexport type SearchLedgerTrustedHeadMode = 'pin' | 'require' | 'off'\n\nexport interface OpenSearchLedgerOptions {\n path: string\n searchId: string\n trustedHead?: SearchLedgerTrustedHeadMode\n /**\n * Keep the ledger's text in this in-process store instead of a file, for a\n * run without a filesystem (an in-memory `CampaignStorage`, keyed by `path`).\n * The chain, parse and state rules are the file ledger's; there is no lock,\n * fsync or trusted head, and the ledger lives as long as the store.\n */\n store?: LedgerTextStore\n}\n\nexport interface SearchLedgerAppendResult {\n entry: SearchLedgerEntry\n /** False when the exact event was already durably present. */\n appended: boolean\n state: SearchStateView\n}\n\nexport interface SearchLedger {\n readonly path: string\n readonly searchId: string\n /** Sibling file holding this ledger's trusted head. */\n readonly trustedHeadPath: string\n append(event: SearchLedgerEvent): Promise<SearchLedgerAppendResult>\n /** The verified state at the file's current head. */\n state(): Promise<SearchStateView>\n /** The pinned head, or null when this ledger has never been pinned. */\n trustedHead(): Promise<LedgerTrustedHead | null>\n /** Pin the current verified head without rewriting a byte. */\n pinTrustedHead(): Promise<LedgerTrustedHead>\n /** Discard this ledger's pin, reporting what was discarded. It gives up the\n * deletion guarantee for every entry the pin covered. */\n clearTrustedHead(): Promise<LedgerTrustedHeadRemoval>\n}\n\n/** Open a durable filesystem search ledger. Construction performs no I/O; the\n * first `append` or `state` verifies the whole existing file. */\nexport function openSearchLedger(options: OpenSearchLedgerOptions): SearchLedger {\n if (options.store) return new MemorySearchLedger(options.path, options.searchId, options.store)\n return new FileSearchLedger(options.path, options.searchId, options.trustedHead)\n}\n\n/** Verify and project immutable search-ledger JSONL through the same codec as\n * `FileSearchLedger`. */\nexport function replaySearchLedgerText(\n text: string,\n searchId: string,\n source: string,\n): SearchStateView {\n return replayLedgerText(text, source, searchLedgerCodec(searchId))\n}\n\n/**\n * Verify one stored ledger line in isolation: the schema tag, the entry and\n * event schemas, canonical bytes, the entry's own hash, and its search. The\n * chain (sequence and previous hash) and the state machine are the caller's,\n * because they need the lines before this one. An ingest server runs this on\n * every received line, so it hashes exactly the bytes the producer hashed.\n */\nexport function parseSearchLedgerLine(\n line: string,\n searchId: string,\n context: LedgerLineContext,\n): SearchLedgerEntry {\n let raw: unknown\n try {\n raw = JSON.parse(line)\n } catch (error) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has invalid JSON at line ${context.line}`,\n { cause: error },\n )\n }\n const entry = parseSearchLedgerEntry(raw, context)\n if (entry.searchId !== searchId) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} belongs to search ${entry.searchId}, expected ${searchId}`,\n )\n }\n if (canonicalString(entry) !== line) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has non-canonical bytes at line ${context.line}`,\n )\n }\n const { entryHash, ...material } = entry\n const expected = hashCanonical(material)\n if (entryHash !== expected) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} hash mismatch: expected ${expected}, got ${entryHash}`,\n )\n }\n return entry\n}\n\ninterface SearchLedgerHeader {\n schema: typeof SEARCH_LEDGER_SCHEMA\n searchId: string\n}\n\nfunction searchLedgerCodec(\n searchId: string,\n): LedgerJournalCodec<SearchLedgerHeader, SearchLedgerEvent, SearchStateView> {\n return {\n ...SEARCH_LEDGER_FILE_CONTEXT,\n header: { schema: SEARCH_LEDGER_SCHEMA, searchId },\n conflictError: (message) => new SearchLedgerConflictError(message),\n parseEntry: parseSearchLedgerEntry,\n checkEntryHeader: (entry, index) => {\n if (entry.searchId !== searchId) {\n throw new SearchLedgerIntegrityError(\n `entry ${index} belongs to search ${entry.searchId}, expected ${searchId}`,\n )\n }\n },\n createProjector: () => new SearchState(searchId),\n }\n}\n\n/** Append-only file-backed search ledger with idempotent writes. */\nexport class FileSearchLedger implements SearchLedger {\n readonly path: string\n readonly searchId: string\n readonly trustedHeadPath: string\n private readonly trustedHeadMode: SearchLedgerTrustedHeadMode\n private readonly journal: FileLedgerJournal<\n SearchLedgerHeader,\n SearchLedgerEvent,\n SearchStateView\n >\n\n constructor(path: string, searchId: string, trustedHead: SearchLedgerTrustedHeadMode = 'pin') {\n if (path.trim().length === 0) throw new SearchLedgerError('ledger path is empty')\n if (searchId.length === 0 || searchId.trim() !== searchId) {\n throw new SearchLedgerError('searchId must be non-empty without surrounding whitespace')\n }\n this.searchId = searchId\n this.trustedHeadMode = trustedHead\n this.journal = new FileLedgerJournal(path, searchLedgerCodec(searchId), {\n requireTrustedHead: trustedHead === 'require',\n })\n this.path = this.journal.path\n this.trustedHeadPath = this.journal.trustedHeadPath\n }\n\n async state(): Promise<SearchStateView> {\n return this.journal.replay()\n }\n\n async append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult> {\n // Normalize before the journal hashes the event so retries from different\n // processes produce byte-identical entries.\n const event = validateSearchLedgerEvent(input)\n const { entry, appended, projection } = await this.journal.append(event, {\n pinHead: this.trustedHeadMode !== 'off',\n })\n return { entry, appended, state: projection }\n }\n\n async trustedHead(): Promise<LedgerTrustedHead | null> {\n return this.journal.trustedHead()\n }\n\n async pinTrustedHead(): Promise<LedgerTrustedHead> {\n return this.journal.pinTrustedHead()\n }\n\n async clearTrustedHead(): Promise<LedgerTrustedHeadRemoval> {\n return this.journal.clearTrustedHead()\n }\n}\n\n/** A search ledger held in an in-process text store. */\nclass MemorySearchLedger implements SearchLedger {\n readonly path: string\n readonly searchId: string\n readonly trustedHeadPath: string\n private readonly journal: MemoryLedgerJournal<\n SearchLedgerHeader,\n SearchLedgerEvent,\n SearchStateView\n >\n\n constructor(path: string, searchId: string, store: LedgerTextStore) {\n if (path.trim().length === 0) throw new SearchLedgerError('ledger path is empty')\n if (searchId.length === 0 || searchId.trim() !== searchId) {\n throw new SearchLedgerError('searchId must be non-empty without surrounding whitespace')\n }\n this.path = path\n this.searchId = searchId\n this.trustedHeadPath = `${path}.head`\n this.journal = new MemoryLedgerJournal(path, searchLedgerCodec(searchId), store)\n }\n\n async state(): Promise<SearchStateView> {\n return this.journal.replay()\n }\n\n async append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult> {\n const { entry, appended, projection } = await this.journal.append(\n validateSearchLedgerEvent(input),\n )\n return { entry, appended, state: projection }\n }\n\n async trustedHead(): Promise<LedgerTrustedHead | null> {\n return null\n }\n\n async pinTrustedHead(): Promise<LedgerTrustedHead> {\n throw new SearchLedgerError(\n `search ledger ${this.path} is held in memory; a trusted head protects only a file`,\n )\n }\n\n async clearTrustedHead(): Promise<LedgerTrustedHeadRemoval> {\n return { removed: false }\n }\n}\n\nfunction parseSearchLedgerEntry(raw: unknown, context: LedgerLineContext): SearchLedgerEntry {\n const schema = (raw as { schema?: unknown } | null)?.schema\n if (schema !== SEARCH_LEDGER_SCHEMA) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} line ${context.line} was written under schema ${JSON.stringify(schema)}; this version reads only ${SEARCH_LEDGER_SCHEMA} and does not translate other formats`,\n )\n }\n const parsed = EntrySchema.safeParse(raw)\n if (!parsed.success) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has a malformed entry at line ${context.line}: ${formatZodError(parsed.error)}`,\n )\n }\n const entry = parsed.data as SearchLedgerEntry\n const normalizedEvent = validateSearchLedgerEvent(entry.event)\n if (canonicalString(normalizedEvent) !== canonicalString(entry.event)) {\n throw new SearchLedgerIntegrityError(\n `search ledger ${context.path} has non-canonical event ordering at line ${context.line}`,\n )\n }\n return entry\n}\n\nfunction normalizeEvent(event: SearchLedgerEvent): SearchLedgerEvent {\n const artifacts = sortArtifacts(event.artifacts)\n switch (event.kind) {\n case 'search-opened':\n return {\n ...event,\n artifacts,\n splits: {\n ...event.splits,\n train: { ...event.splits.train, tasks: sortTasks(event.splits.train.tasks) },\n selection: { ...event.splits.selection, tasks: sortTasks(event.splits.selection.tasks) },\n test: { ...event.splits.test, tasks: sortTasks(event.splits.test.tasks) },\n },\n }\n case 'node-registered':\n return {\n ...event,\n artifacts,\n surfaces: [...event.surfaces].sort((a, b) => compareStrings(a.surfaceId, b.surfaceId)),\n }\n case 'cell-settled':\n return {\n ...event,\n artifacts,\n surfaceEvidence: [...event.surfaceEvidence]\n .map((evidence) => ({ ...evidence, evidence: sortArtifacts(evidence.evidence) }))\n .sort((a, b) => compareStrings(a.surfaceId, b.surfaceId)),\n }\n default:\n return { ...event, artifacts }\n }\n}\n\nfunction sortTasks(tasks: SearchTask[]): SearchTask[] {\n return [...tasks].sort((a, b) => compareStrings(a.taskId, b.taskId))\n}\n\nfunction sortArtifacts(artifacts: SearchArtifactRef[]): SearchArtifactRef[] {\n return [...artifacts].sort((a, b) => compareStrings(artifactKey(a), artifactKey(b)))\n}\n\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => `${issue.path.length > 0 ? issue.path.join('.') : '<root>'}: ${issue.message}`)\n .join('; ')\n}\n\nexport type * from './search-ledger-types'\nexport { SEARCH_LEDGER_SCHEMA }\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { s as ValidationError } from "./errors-Dngq5h35.js";
|
|
2
|
-
import {
|
|
2
|
+
import { l as appendLedgerLine, u as tryWithLedgerFileLock } from "./journal-DvKCvjty.js";
|
|
3
3
|
import "./ledger-core/index.js";
|
|
4
4
|
//#region src/campaign/search-ledger-errors.ts
|
|
5
5
|
/** Base error for invalid search-ledger input or operations. */
|
|
@@ -24,4 +24,4 @@ function tryWithSearchLedgerFileLock(ledgerPath, run) {
|
|
|
24
24
|
//#endregion
|
|
25
25
|
export { SearchLedgerError as a, SearchLedgerConflictError as i, appendSearchLedgerLine as n, SearchLedgerIntegrityError as o, tryWithSearchLedgerFileLock as r, SEARCH_LEDGER_FILE_CONTEXT as t };
|
|
26
26
|
|
|
27
|
-
//# sourceMappingURL=search-ledger-file-
|
|
27
|
+
//# sourceMappingURL=search-ledger-file-DY0AXX3W.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-ledger-file-
|
|
1
|
+
{"version":3,"file":"search-ledger-file-DY0AXX3W.js","names":[],"sources":["../src/campaign/search-ledger-errors.ts","../src/campaign/search-ledger-file.ts"],"sourcesContent":["import { ValidationError } from '../errors'\n\n/** Base error for invalid search-ledger input or operations. */\nexport class SearchLedgerError extends ValidationError {}\n\n/** Error raised when durable search-ledger data fails an integrity check. */\nexport class SearchLedgerIntegrityError extends SearchLedgerError {}\n\n/** Error raised when an event identifier is reused with different content. */\nexport class SearchLedgerConflictError extends SearchLedgerError {}\n","/** Campaign binding of the generic journal file layer to search-ledger errors. */\n\nimport {\n appendLedgerLine,\n type FileLockResult,\n type LedgerFileContext,\n tryWithLedgerFileLock,\n withLedgerFileLock,\n} from '../ledger-core'\nimport { SearchLedgerIntegrityError } from './search-ledger-errors'\n\nexport const SEARCH_LEDGER_FILE_CONTEXT: LedgerFileContext = {\n subject: 'search ledger',\n integrityError: (message, options) => new SearchLedgerIntegrityError(message, options),\n}\n\nexport function appendSearchLedgerLine(path: string, line: string): void {\n appendLedgerLine(path, line, SEARCH_LEDGER_FILE_CONTEXT)\n}\n\nexport function withSearchLedgerFileLock<T>(ledgerPath: string, run: () => T): T {\n return withLedgerFileLock(ledgerPath, SEARCH_LEDGER_FILE_CONTEXT, run)\n}\n\nexport type { FileLockResult }\n\nexport function tryWithSearchLedgerFileLock<T>(\n ledgerPath: string,\n run: () => T,\n): FileLockResult<T> {\n return tryWithLedgerFileLock(ledgerPath, SEARCH_LEDGER_FILE_CONTEXT, run)\n}\n"],"mappings":";;;;;AAGA,IAAa,oBAAb,cAAuC,gBAAgB,CAAC;;AAGxD,IAAa,6BAAb,cAAgD,kBAAkB,CAAC;;AAGnE,IAAa,4BAAb,cAA+C,kBAAkB,CAAC;;;;ACElE,MAAa,6BAAgD;CAC3D,SAAS;CACT,iBAAiB,SAAS,YAAY,IAAI,2BAA2B,SAAS,OAAO;AACvF;AAEA,SAAgB,uBAAuB,MAAc,MAAoB;CACvE,iBAAiB,MAAM,MAAM,0BAA0B;AACzD;AAQA,SAAgB,4BACd,YACA,KACmB;CACnB,OAAO,sBAAsB,YAAY,4BAA4B,GAAG;AAC1E"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as SearchLedgerIntegrityError } from "./search-ledger-file-
|
|
2
|
-
import { r as parseSearchLedgerLine } from "./search-ledger-
|
|
1
|
+
import { o as SearchLedgerIntegrityError } from "./search-ledger-file-DY0AXX3W.js";
|
|
2
|
+
import { r as parseSearchLedgerLine } from "./search-ledger-Ck7tok0h.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -778,4 +778,4 @@ async function shipBestEffort(ship, ledgerPath) {
|
|
|
778
778
|
//#endregion
|
|
779
779
|
export { TraceSpanEventSchema as C, IngestTracesRequestSchema as S, HOSTED_WIRE_VERSION as T, admitSearchLedgerBatch as _, HostedRequestError as a, searchLedgerHeadPath as b, hostedTenantFromEnv as c, SEARCH_LEDGER_BATCH_MAX_LINES as d, SEARCH_LEDGER_INGEST_PATH as f, SearchRunKindSchema as g, SearchLedgerHeadSchema as h, startSearchShipper as i, IngestSearchLedgerRequestSchema as l, SearchLedgerConflictSchema as m, shipBestEffort as n, createHostedClient as o, SearchBlobPutResponseSchema as p, shipSearchLedger as r, hostedClientFromEnv as s, SearchShipConflictError as t, SEARCH_LEDGER_BATCH_MAX_BYTES as u, searchBlobPath as v, UnixNanoTimestampSchema as w, IngestResponseSchema as x, searchLedgerArtifactRefs as y };
|
|
780
780
|
|
|
781
|
-
//# sourceMappingURL=search-shipper-
|
|
781
|
+
//# sourceMappingURL=search-shipper-BG182p-U.js.map
|