@hraness/kb 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/DISCLOSURE +43 -0
  2. package/LICENSE +21 -0
  3. package/README.md +545 -0
  4. package/dist/agent-context.js +35 -0
  5. package/dist/agent-guide-audit.js +18 -0
  6. package/dist/attachments.js +19 -0
  7. package/dist/authoring.js +33 -0
  8. package/dist/benchmark.js +19 -0
  9. package/dist/capture.js +49 -0
  10. package/dist/cli.js +3646 -0
  11. package/dist/clip/acquire.js +57 -0
  12. package/dist/clip/args.js +21 -0
  13. package/dist/clip/bounded-byte-buffer.js +9 -0
  14. package/dist/clip/browser-profiles.js +17 -0
  15. package/dist/clip/bundle-reader.js +11 -0
  16. package/dist/clip/cli.js +27 -0
  17. package/dist/clip/cookies.js +21 -0
  18. package/dist/clip/defuddle-worker.js +84 -0
  19. package/dist/clip/doctor.js +32 -0
  20. package/dist/clip/jobs.js +784 -0
  21. package/dist/clip/network-proxy.js +9 -0
  22. package/dist/clip/network.js +28 -0
  23. package/dist/clip/persist.js +30 -0
  24. package/dist/clip/refresh.js +11 -0
  25. package/dist/clip/terminal.js +11 -0
  26. package/dist/evaluation-builder.js +12238 -0
  27. package/dist/evaluation-kb.js +26 -0
  28. package/dist/evaluation.js +35 -0
  29. package/dist/git.js +39 -0
  30. package/dist/graph.js +39 -0
  31. package/dist/index-01jj6rbv.js +1103 -0
  32. package/dist/index-06c9ctr6.js +738 -0
  33. package/dist/index-0kavxzqj.js +2480 -0
  34. package/dist/index-1gwbassd.js +743 -0
  35. package/dist/index-1n418kb9.js +827 -0
  36. package/dist/index-1vrd1rmn.js +56 -0
  37. package/dist/index-1xxnjn0d.js +171 -0
  38. package/dist/index-3rm7cz6h.js +373 -0
  39. package/dist/index-3v2z4f0q.js +328 -0
  40. package/dist/index-48pz4jpc.js +392 -0
  41. package/dist/index-4j3tt0c3.js +234 -0
  42. package/dist/index-5n05se68.js +307 -0
  43. package/dist/index-5vwpzb5a.js +764 -0
  44. package/dist/index-6g2pv9d2.js +370 -0
  45. package/dist/index-7fzc32gf.js +712 -0
  46. package/dist/index-84x0vjjp.js +432 -0
  47. package/dist/index-adx6khj5.js +488 -0
  48. package/dist/index-b88v3vtm.js +805 -0
  49. package/dist/index-cv6fh7z5.js +462 -0
  50. package/dist/index-cxfrakt7.js +1067 -0
  51. package/dist/index-d13v9ckt.js +150 -0
  52. package/dist/index-dycjbhw2.js +1943 -0
  53. package/dist/index-dyqwejk5.js +531 -0
  54. package/dist/index-e5fbsywq.js +658 -0
  55. package/dist/index-f984hw45.js +927 -0
  56. package/dist/index-gh719d91.js +63 -0
  57. package/dist/index-hgve9rh2.js +2046 -0
  58. package/dist/index-hya40gb2.js +474 -0
  59. package/dist/index-j4zgmzjr.js +152 -0
  60. package/dist/index-jsmvyyvf.js +1166 -0
  61. package/dist/index-kh0pwvdd.js +1974 -0
  62. package/dist/index-mqx4nd6v.js +119 -0
  63. package/dist/index-mxxxytys.js +1254 -0
  64. package/dist/index-n5dd7r0v.js +711 -0
  65. package/dist/index-npg9z1a4.js +431 -0
  66. package/dist/index-pj501bh1.js +140 -0
  67. package/dist/index-qry4vhxk.js +1041 -0
  68. package/dist/index-s2gw5aw9.js +199 -0
  69. package/dist/index-vvdj6kca.js +70 -0
  70. package/dist/index-w2zc0vwa.js +571 -0
  71. package/dist/index-x3fthpsc.js +585 -0
  72. package/dist/index-zr53sf63.js +44 -0
  73. package/dist/index-zxdy5pby.js +2728 -0
  74. package/dist/index-zzhgcwyt.js +966 -0
  75. package/dist/index.js +453 -0
  76. package/dist/navigation.js +13 -0
  77. package/dist/pdf.js +85 -0
  78. package/dist/percolate.js +24 -0
  79. package/dist/portfolio.js +77 -0
  80. package/dist/query.js +29 -0
  81. package/dist/repository-memory.js +60 -0
  82. package/dist/sdk.js +36 -0
  83. package/dist/search-rules.js +34 -0
  84. package/dist/search.js +22 -0
  85. package/dist/semantic.js +39 -0
  86. package/dist/source-inbox.js +17 -0
  87. package/dist/untrusted-content.js +32 -0
  88. package/dist/url-intelligence.js +74 -0
  89. package/dist/workflow.js +23 -0
  90. package/dist/workflows/decision-context.js +20 -0
  91. package/dist/workflows/explain-change.js +8 -0
  92. package/dist/workflows/index.js +28 -0
  93. package/dist/workflows/plan-radar.js +10 -0
  94. package/package.json +409 -0
  95. package/skills/kb/AGENTS.md +19 -0
  96. package/skills/kb/SKILL.md +82 -0
  97. package/skills/kb/agents/openai.yaml +4 -0
  98. package/skills/kb/references/pdf-review.md +51 -0
  99. package/skills/kb/references/percolate.md +144 -0
  100. package/skills/kb/references/plan-structure.md +105 -0
  101. package/skills/kb/references/plan.md +115 -0
  102. package/skills/kb/references/query.md +231 -0
  103. package/skills/kb/references/refresh.md +133 -0
  104. package/skills/kb/references/save-pdf.md +125 -0
  105. package/skills/kb/references/save-url.md +178 -0
  106. package/skills/kb/references/url-authentication.md +75 -0
  107. package/skills/kb/references/url-platforms.md +25 -0
  108. package/src/agent-context.ts +1241 -0
  109. package/src/agent-guide-audit.ts +750 -0
  110. package/src/attachments.ts +723 -0
  111. package/src/authoring.ts +1725 -0
  112. package/src/benchmark.ts +362 -0
  113. package/src/capture.ts +68 -0
  114. package/src/cli.ts +3660 -0
  115. package/src/clip/acquire.ts +1273 -0
  116. package/src/clip/archive-today.ts +402 -0
  117. package/src/clip/args.ts +423 -0
  118. package/src/clip/assets.ts +262 -0
  119. package/src/clip/bounded-byte-buffer.ts +75 -0
  120. package/src/clip/browser-profiles.ts +372 -0
  121. package/src/clip/bundle-reader.ts +608 -0
  122. package/src/clip/capture.ts +1054 -0
  123. package/src/clip/cli.ts +181 -0
  124. package/src/clip/cookies.ts +512 -0
  125. package/src/clip/doctor.ts +1110 -0
  126. package/src/clip/extract.ts +868 -0
  127. package/src/clip/jobs.ts +959 -0
  128. package/src/clip/lib.ts +861 -0
  129. package/src/clip/media.ts +1474 -0
  130. package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
  131. package/src/clip/metadata-search-tool/Cargo.toml +18 -0
  132. package/src/clip/metadata-search-tool/runner.ts +685 -0
  133. package/src/clip/metadata-search-tool/src/main.rs +389 -0
  134. package/src/clip/metadata-search.ts +687 -0
  135. package/src/clip/network-proxy.ts +627 -0
  136. package/src/clip/network.ts +950 -0
  137. package/src/clip/package-root.ts +54 -0
  138. package/src/clip/persist.ts +1472 -0
  139. package/src/clip/platforms.ts +1824 -0
  140. package/src/clip/refresh.ts +197 -0
  141. package/src/clip/structured.ts +432 -0
  142. package/src/clip/terminal.ts +197 -0
  143. package/src/clip/url-intelligence.ts +581 -0
  144. package/src/clip/url-metadata-backfill.ts +616 -0
  145. package/src/clip/url-metadata-cli.ts +251 -0
  146. package/src/clip/url-metadata.ts +1397 -0
  147. package/src/evaluation-analysis-v2.ts +1440 -0
  148. package/src/evaluation-builder.ts +2539 -0
  149. package/src/evaluation-corpus-authoring.ts +2052 -0
  150. package/src/evaluation-evidence.ts +1147 -0
  151. package/src/evaluation-execution-v2.ts +426 -0
  152. package/src/evaluation-implementation.ts +131 -0
  153. package/src/evaluation-kb-closure.ts +1430 -0
  154. package/src/evaluation-kb-runner-v2.ts +735 -0
  155. package/src/evaluation-kb-v2.ts +2567 -0
  156. package/src/evaluation-kb.ts +1018 -0
  157. package/src/evaluation-measurement-v2.ts +1462 -0
  158. package/src/evaluation-packing-v2.ts +452 -0
  159. package/src/evaluation-redaction.ts +28 -0
  160. package/src/evaluation-v2.ts +3857 -0
  161. package/src/evaluation.ts +1220 -0
  162. package/src/git.ts +1276 -0
  163. package/src/graph.ts +1487 -0
  164. package/src/index.ts +20 -0
  165. package/src/init.ts +123 -0
  166. package/src/navigation.ts +277 -0
  167. package/src/note-lock.ts +529 -0
  168. package/src/pdf/args.ts +202 -0
  169. package/src/pdf/capture.ts +298 -0
  170. package/src/pdf/cli.ts +159 -0
  171. package/src/pdf/extract.ts +303 -0
  172. package/src/pdf/layout.ts +618 -0
  173. package/src/pdf/markdown.ts +154 -0
  174. package/src/pdf/model.ts +234 -0
  175. package/src/pdf/ocr.ts +190 -0
  176. package/src/pdf/persist.ts +314 -0
  177. package/src/pdf/source.ts +135 -0
  178. package/src/pdf/tools.ts +146 -0
  179. package/src/pdf.ts +92 -0
  180. package/src/percolate.ts +877 -0
  181. package/src/portfolio-audit.ts +574 -0
  182. package/src/portfolio-identity.ts +162 -0
  183. package/src/portfolio-registry.ts +473 -0
  184. package/src/portfolio.ts +765 -0
  185. package/src/query.ts +646 -0
  186. package/src/repository-memory.ts +1150 -0
  187. package/src/sdk.ts +1452 -0
  188. package/src/search-rules.ts +712 -0
  189. package/src/search.ts +710 -0
  190. package/src/semantic-runtime.ts +1139 -0
  191. package/src/semantic.ts +2480 -0
  192. package/src/source-inbox.ts +232 -0
  193. package/src/untrusted-content.ts +401 -0
  194. package/src/url-intelligence.ts +104 -0
  195. package/src/vault.ts +636 -0
  196. package/src/workflow.ts +653 -0
  197. package/src/workflows/decision-context.ts +81 -0
  198. package/src/workflows/explain-change.ts +73 -0
  199. package/src/workflows/index.ts +3 -0
  200. package/src/workflows/plan-radar.ts +101 -0
@@ -0,0 +1,2567 @@
1
+ import {
2
+ MAX_EVALUATION_DIAGNOSTICS,
3
+ MAX_EVALUATION_EVIDENCE_BYTES,
4
+ MAX_EVALUATION_RESULTS_PER_QUERY,
5
+ type EvaluationDiagnostic,
6
+ type EvaluationRetriever,
7
+ type EvaluationRetrieverResult,
8
+ type RetrievalEvaluationCorpus,
9
+ } from "./evaluation.js";
10
+ import {
11
+ validateEvaluationEvidenceRegistry,
12
+ type EvaluationEvidenceRegistry,
13
+ type EvaluationEvidenceUnit,
14
+ } from "./evaluation-evidence.js";
15
+ import {
16
+ assertEvaluationImplementationArtifactV2,
17
+ type VerifiedEvaluationImplementationArtifactV2,
18
+ } from "./evaluation-implementation.js";
19
+ import {
20
+ EXISTING_LANE_CLOSURE_FUSION,
21
+ freezeExistingLaneClosureVariant,
22
+ runExistingLaneClosure,
23
+ type ExistingLaneClosureAccounting,
24
+ type ExistingLaneClosureBackend,
25
+ type ExistingLaneClosureBackends,
26
+ type ExistingLaneClosureDiagnostic,
27
+ type ExistingLaneClosureEvidenceLocator,
28
+ type ExistingLaneClosureEvidenceRegistry,
29
+ type ExistingLaneClosureExecutableInputs,
30
+ type ExistingLaneClosureGitInput,
31
+ type ExistingLaneClosureGraphInput,
32
+ type ExistingLaneClosureHit,
33
+ type ExistingLaneClosureHybridInput,
34
+ type ExistingLaneClosureLaneId,
35
+ type ExistingLaneClosureLaneResult,
36
+ type ExistingLaneClosureMetadataInput,
37
+ type ExistingLaneClosurePathContextInput,
38
+ type ExistingLaneClosureResult,
39
+ type ExistingLaneClosureVariant,
40
+ } from "./evaluation-kb-closure.js";
41
+ import {
42
+ knowledgeBaseEvaluationRetrieverIds,
43
+ openKnowledgeBaseEvaluation,
44
+ type KnowledgeBaseEvaluation,
45
+ type KnowledgeBaseEvaluationRetrieverId,
46
+ type OpenKnowledgeBaseEvaluationOptions,
47
+ } from "./evaluation-kb.js";
48
+ import {
49
+ MAX_EVALUATION_V2_RESULTS_PER_LANE,
50
+ evaluationRetrieverDescriptorDigestV2,
51
+ type EvaluationCandidateLockV2,
52
+ type EvaluationCandidateDecisionV2,
53
+ type EvaluationCandidateReasonV2,
54
+ type EvaluationEvidenceLocatorV2,
55
+ type EvaluationExecutionRequestV2,
56
+ type EvaluationLaneIdV2,
57
+ type EvaluationLaneOutcomeV2,
58
+ type EvaluationRankedCandidateV2,
59
+ type EvaluationRepeatedSampleV2,
60
+ type EvaluationResourceAccountingV2,
61
+ type EvaluationSourceClassV2,
62
+ type EvaluationTrustClassV2,
63
+ type EvaluationRetrieverDescriptorV2,
64
+ type EvaluationRetrieverTraceV2,
65
+ type EvaluationRetrieverV2,
66
+ type RetrievalEvaluationCorpusV2,
67
+ } from "./evaluation-v2.js";
68
+
69
+ const SHA256 = /^[0-9a-f]{64}$/u;
70
+ const CANONICAL_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
71
+ const WINDOWS_ABSOLUTE_PATH = /^[a-z]:[\\/]/iu;
72
+ const MAX_DESCRIPTOR_TEXT_BYTES = 16 * 1_024;
73
+ const MAX_DIAGNOSTIC_MESSAGE_BYTES = 16 * 1_024;
74
+
75
+ export const KNOWLEDGE_BASE_EVALUATION_ADAPTER_V2 = "evaluation-kb-v2";
76
+ export const KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 = 10;
77
+ export const KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2 = 5;
78
+ export const KNOWLEDGE_BASE_EVALUATION_EMBEDDING_NOT_INVOKED_V2 = Object.freeze({
79
+ calls: 0,
80
+ inputTokens: 0,
81
+ durationMs: 0,
82
+ } as const);
83
+
84
+ export type KnowledgeBaseEvaluationDescriptorDefinitionV2 = Readonly<{
85
+ readonly id: string;
86
+ readonly role: EvaluationRetrieverDescriptorV2["role"];
87
+ /** Authored, immutable implementation version. Never inferred from the ID or CLI state. */
88
+ readonly version: string;
89
+ /** Digest supplied by the corpus author for the exact implementation under evaluation. */
90
+ readonly implementationSha256: string;
91
+ readonly retrieveLimit: number;
92
+ }>;
93
+
94
+ export type KnowledgeBaseEvaluationDescriptorDefinitionsV2 = Readonly<{
95
+ readonly [Lane in KnowledgeBaseEvaluationRetrieverId]: KnowledgeBaseEvaluationDescriptorDefinitionV2;
96
+ }>;
97
+
98
+ export type KnowledgeBaseEvaluationLaneDescriptorsV2 = Readonly<{
99
+ readonly [Lane in KnowledgeBaseEvaluationRetrieverId]: EvaluationRetrieverDescriptorV2;
100
+ }>;
101
+
102
+ export type KnowledgeBaseExistingLaneClosureDescriptorV2 = Readonly<{
103
+ readonly descriptor: EvaluationRetrieverDescriptorV2;
104
+ readonly variant: ExistingLaneClosureVariant;
105
+ }>;
106
+
107
+ export type KnowledgeBaseEvaluationDiagnosticV2 = Readonly<{
108
+ readonly code: string;
109
+ readonly lane: string;
110
+ readonly status: "degraded" | "ready" | "unavailable";
111
+ readonly message?: string;
112
+ }>;
113
+
114
+ export type KnowledgeBaseEvaluationRawEvidenceV2 = Readonly<{
115
+ readonly laneId: EvaluationLaneIdV2;
116
+ readonly documentId: string;
117
+ readonly rank: number;
118
+ readonly evidence?: unknown;
119
+ readonly provenance?: readonly KnowledgeBaseEvaluationEvidenceUnitV2[];
120
+ }>;
121
+
122
+ export type KnowledgeBaseEvaluationEvidenceUnitV2 = Readonly<{
123
+ readonly evidenceUnitId: string;
124
+ readonly registryUnitId: string;
125
+ readonly documentId: string;
126
+ readonly sourceFamilyId: string;
127
+ readonly sourceClass: EvaluationSourceClassV2;
128
+ readonly trustClass: EvaluationTrustClassV2;
129
+ readonly locator: EvaluationEvidenceLocatorV2;
130
+ }>;
131
+
132
+ export type KnowledgeBaseEvaluationRetrieverResultV2 = Readonly<{
133
+ readonly retrieverId: string;
134
+ readonly status: "degraded" | "ready" | "unavailable";
135
+ readonly candidates: readonly EvaluationRankedCandidateV2[];
136
+ readonly trace: EvaluationRetrieverTraceV2;
137
+ readonly diagnostics: readonly KnowledgeBaseEvaluationDiagnosticV2[];
138
+ readonly rawEvidence: readonly KnowledgeBaseEvaluationRawEvidenceV2[];
139
+ readonly evidenceUnits: readonly KnowledgeBaseEvaluationEvidenceUnitV2[];
140
+ readonly timings: Readonly<Record<string, number>>;
141
+ readonly rawResources: Readonly<Record<string, number>>;
142
+ readonly resources: EvaluationResourceAccountingV2;
143
+ readonly elapsedMs: number;
144
+ }>;
145
+
146
+ export type KnowledgeBaseEvaluationRetrieverV2 = Omit<EvaluationRetrieverV2, "retrieve"> & Readonly<{
147
+ readonly retrieve: (
148
+ request: EvaluationExecutionRequestV2,
149
+ ) => Promise<KnowledgeBaseEvaluationRetrieverResultV2>;
150
+ }>;
151
+
152
+ export type KnowledgeBaseEvaluationAccountingProviderV2 = (
153
+ input: Readonly<{
154
+ readonly lane: KnowledgeBaseEvaluationRetrieverId;
155
+ readonly status: EvaluationRetrieverResult["status"];
156
+ readonly timings: Readonly<Record<string, number>>;
157
+ readonly resources: Readonly<Record<string, number>>;
158
+ }>,
159
+ ) => EvaluationResourceAccountingV2 | Promise<EvaluationResourceAccountingV2>;
160
+
161
+ export type KnowledgeBaseEvaluationV2 = Readonly<{
162
+ readonly retrievers: readonly KnowledgeBaseEvaluationRetrieverV2[];
163
+ readonly close: () => Promise<void>;
164
+ }>;
165
+
166
+ type VerifiedKnowledgeBaseEvaluationBindingV2 = Readonly<{
167
+ readonly suiteSha256: string | undefined;
168
+ readonly candidateLockSha256: string | undefined;
169
+ readonly buildContractSha256: string | undefined;
170
+ readonly repositoryCommit: string;
171
+ readonly vaultTree: string;
172
+ }>;
173
+
174
+ const verifiedKnowledgeBaseEvaluationsV2 = new WeakMap<
175
+ KnowledgeBaseEvaluationV2,
176
+ VerifiedKnowledgeBaseEvaluationBindingV2
177
+ >();
178
+
179
+ /**
180
+ * Reject structurally compatible or copied evaluators that did not pass the
181
+ * frozen snapshot, descriptor, evidence, and implementation-artifact adapter.
182
+ */
183
+ export function assertVerifiedKnowledgeBaseEvaluationV2(
184
+ evaluation: KnowledgeBaseEvaluationV2,
185
+ corpus: RetrievalEvaluationCorpusV2,
186
+ ): void {
187
+ const binding = verifiedKnowledgeBaseEvaluationsV2.get(evaluation);
188
+ if (
189
+ binding === undefined
190
+ || binding.suiteSha256 !== corpus.manifest.corpusSha256
191
+ || binding.candidateLockSha256 !== corpus.manifest.candidateLockSha256
192
+ || binding.buildContractSha256 !== corpus.manifest.buildContractSha256
193
+ || binding.repositoryCommit !== corpus.frozen.repositoryCommit
194
+ || binding.vaultTree !== corpus.frozen.vaultTree
195
+ ) {
196
+ throw new TypeError(
197
+ "Evaluation runtime is not the implementation-bound adapter for this sealed corpus.",
198
+ );
199
+ }
200
+ }
201
+
202
+ export type AdaptVerifiedKnowledgeBaseEvaluationV2Options = Readonly<{
203
+ readonly corpus: RetrievalEvaluationCorpusV2;
204
+ readonly evidenceRegistry: EvaluationEvidenceRegistry;
205
+ /** Required measurement boundary. Omission is never interpreted as zero work. */
206
+ readonly accounting: KnowledgeBaseEvaluationAccountingProviderV2;
207
+ /** The already-open legacy session must have passed its immutable snapshot verification. */
208
+ readonly evaluation: KnowledgeBaseEvaluation;
209
+ readonly laneDescriptors: KnowledgeBaseEvaluationLaneDescriptorsV2;
210
+ readonly closureDescriptors?: readonly KnowledgeBaseExistingLaneClosureDescriptorV2[];
211
+ readonly implementationArtifacts: readonly VerifiedEvaluationImplementationArtifactV2[];
212
+ readonly now?: () => number;
213
+ }>;
214
+
215
+ export type OpenKnowledgeBaseEvaluationV2Options = Omit<
216
+ OpenKnowledgeBaseEvaluationOptions,
217
+ "corpus" | "now"
218
+ > & Readonly<{
219
+ readonly corpus: RetrievalEvaluationCorpusV2;
220
+ readonly evidenceRegistry: EvaluationEvidenceRegistry;
221
+ /** Required measurement boundary. Omission is never interpreted as zero work. */
222
+ readonly accounting: KnowledgeBaseEvaluationAccountingProviderV2;
223
+ readonly laneDescriptors: KnowledgeBaseEvaluationLaneDescriptorsV2;
224
+ readonly closureDescriptors?: readonly KnowledgeBaseExistingLaneClosureDescriptorV2[];
225
+ readonly implementationArtifacts: readonly VerifiedEvaluationImplementationArtifactV2[];
226
+ readonly now?: () => number;
227
+ readonly openEvaluation?: (
228
+ options: OpenKnowledgeBaseEvaluationOptions,
229
+ ) => Promise<KnowledgeBaseEvaluation>;
230
+ }>;
231
+
232
+ export const knowledgeBaseExistingLaneClosureVariantsV2 = Object.freeze({
233
+ "primary-only": freezeExistingLaneClosureVariant({
234
+ primary: {
235
+ lane: "hybrid",
236
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
237
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
238
+ },
239
+ structuralLanes: [],
240
+ git: { mode: "off" },
241
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
242
+ }),
243
+ "metadata-closure": freezeExistingLaneClosureVariant({
244
+ primary: {
245
+ lane: "hybrid",
246
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
247
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2,
248
+ },
249
+ structuralLanes: [{
250
+ lane: "metadata",
251
+ limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
252
+ }],
253
+ git: { mode: "off" },
254
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
255
+ }),
256
+ "graph-closure": freezeExistingLaneClosureVariant({
257
+ primary: {
258
+ lane: "hybrid",
259
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
260
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2,
261
+ },
262
+ structuralLanes: [{
263
+ lane: "graph",
264
+ limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
265
+ }],
266
+ git: { mode: "off" },
267
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
268
+ }),
269
+ "path-context-closure": freezeExistingLaneClosureVariant({
270
+ primary: {
271
+ lane: "hybrid",
272
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
273
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2,
274
+ },
275
+ structuralLanes: [{
276
+ lane: "path-context",
277
+ limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
278
+ }],
279
+ git: { mode: "off" },
280
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
281
+ }),
282
+ "structural-closure": freezeExistingLaneClosureVariant({
283
+ primary: {
284
+ lane: "hybrid",
285
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
286
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2,
287
+ },
288
+ structuralLanes: [
289
+ { lane: "metadata", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
290
+ { lane: "graph", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
291
+ { lane: "path-context", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
292
+ ],
293
+ git: { mode: "off" },
294
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
295
+ }),
296
+ "structural-git-closure": freezeExistingLaneClosureVariant({
297
+ primary: {
298
+ lane: "hybrid",
299
+ retrieveLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
300
+ retainLimit: KNOWLEDGE_BASE_EXISTING_LANE_PRIMARY_RETAIN_V2,
301
+ },
302
+ structuralLanes: [
303
+ { lane: "metadata", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
304
+ { lane: "graph", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
305
+ { lane: "path-context", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
306
+ ],
307
+ git: {
308
+ mode: "explicit-input",
309
+ limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
310
+ },
311
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
312
+ }),
313
+ "structural-only": freezeExistingLaneClosureVariant({
314
+ primary: null,
315
+ structuralLanes: [
316
+ { lane: "metadata", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
317
+ { lane: "graph", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
318
+ { lane: "path-context", limit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2 },
319
+ ],
320
+ git: { mode: "off" },
321
+ outputLimit: KNOWLEDGE_BASE_EXISTING_LANE_CLOSURE_BUDGET_V2,
322
+ }),
323
+ } as const);
324
+
325
+ const laneInput = Object.freeze({
326
+ exact: "text",
327
+ keyword: "text",
328
+ semantic: "text",
329
+ hybrid: "text",
330
+ metadata: "metadata",
331
+ graph: "graph",
332
+ "path-context": "context",
333
+ git: "history",
334
+ } satisfies Readonly<Record<KnowledgeBaseEvaluationRetrieverId, string>>);
335
+
336
+ function record(value: unknown, label: string): Readonly<Record<string, unknown>> {
337
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
338
+ throw new TypeError(`${label} must be an object.`);
339
+ }
340
+ return value as Readonly<Record<string, unknown>>;
341
+ }
342
+
343
+ function ownData(value: Readonly<Record<string, unknown>>, key: string, label: string): unknown {
344
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
345
+ if (descriptor === undefined) return undefined;
346
+ if (!("value" in descriptor)) throw new TypeError(`${label}.${key} must be a data property.`);
347
+ return descriptor.value;
348
+ }
349
+
350
+ function boundedText(value: unknown, label: string, maximumBytes = MAX_DESCRIPTOR_TEXT_BYTES): string {
351
+ if (
352
+ typeof value !== "string"
353
+ || value.trim() === ""
354
+ || /[\0\r\n]/u.test(value)
355
+ || value.normalize("NFC") !== value
356
+ || Buffer.byteLength(value, "utf8") > maximumBytes
357
+ ) {
358
+ throw new TypeError(`${label} must be a non-empty NFC single-line bounded string.`);
359
+ }
360
+ return value;
361
+ }
362
+
363
+ function canonicalId(value: unknown, label: string): string {
364
+ const id = boundedText(value, label, 256);
365
+ if (!CANONICAL_ID.test(id)) throw new TypeError(`${label} must be a canonical lowercase ID.`);
366
+ return id;
367
+ }
368
+
369
+ function positiveLimit(value: unknown, label: string): number {
370
+ if (
371
+ !Number.isSafeInteger(value)
372
+ || (value as number) < 1
373
+ || (value as number) > MAX_EVALUATION_V2_RESULTS_PER_LANE
374
+ ) throw new TypeError(`${label} must be an integer from 1 through ${MAX_EVALUATION_V2_RESULTS_PER_LANE}.`);
375
+ return value as number;
376
+ }
377
+
378
+ function definition(
379
+ value: KnowledgeBaseEvaluationDescriptorDefinitionV2,
380
+ lane: KnowledgeBaseEvaluationRetrieverId,
381
+ ): KnowledgeBaseEvaluationDescriptorDefinitionV2 {
382
+ const input = record(value, `descriptor definition ${lane}`);
383
+ const keys = Object.keys(input).toSorted();
384
+ const expected = ["id", "implementationSha256", "retrieveLimit", "role", "version"];
385
+ if (keys.length !== expected.length || keys.some((key, index) => key !== expected[index])) {
386
+ throw new TypeError(`descriptor definition ${lane} must declare exactly ${expected.join(", ")}.`);
387
+ }
388
+ if (input.role !== "ablation" && input.role !== "baseline" && input.role !== "candidate") {
389
+ throw new TypeError(`descriptor definition ${lane}.role is invalid.`);
390
+ }
391
+ const implementationSha256 = boundedText(
392
+ input.implementationSha256,
393
+ `descriptor definition ${lane}.implementationSha256`,
394
+ 64,
395
+ );
396
+ if (!SHA256.test(implementationSha256)) {
397
+ throw new TypeError(`descriptor definition ${lane}.implementationSha256 must be lowercase SHA-256.`);
398
+ }
399
+ return Object.freeze({
400
+ id: canonicalId(input.id, `descriptor definition ${lane}.id`),
401
+ role: input.role,
402
+ version: boundedText(input.version, `descriptor definition ${lane}.version`, 512),
403
+ implementationSha256,
404
+ retrieveLimit: positiveLimit(input.retrieveLimit, `descriptor definition ${lane}.retrieveLimit`),
405
+ });
406
+ }
407
+
408
+ function laneConfiguration(
409
+ lane: KnowledgeBaseEvaluationRetrieverId,
410
+ retrieveLimit: number,
411
+ ): EvaluationRetrieverDescriptorV2["configuration"] {
412
+ return Object.freeze({
413
+ "adapter-schema": KNOWLEDGE_BASE_EVALUATION_ADAPTER_V2,
414
+ "execution-input": laneInput[lane],
415
+ "generative-llm-call-limit": 0,
416
+ "generative-llm-input-token-limit": 0,
417
+ "generative-llm-output-token-limit": 0,
418
+ "lane-order": knowledgeBaseEvaluationRetrieverIds.indexOf(lane) + 1,
419
+ "provenance-source": "live-lane-evidence",
420
+ "result-order": "raw-rank-ascending",
421
+ "retrieve-limit": retrieveLimit,
422
+ });
423
+ }
424
+
425
+ /** Build the eight immutable built-in lane descriptors from authored version metadata. */
426
+ export function createKnowledgeBaseEvaluationLaneDescriptorsV2(
427
+ definitions: KnowledgeBaseEvaluationDescriptorDefinitionsV2,
428
+ ): KnowledgeBaseEvaluationLaneDescriptorsV2 {
429
+ const output = new Map<KnowledgeBaseEvaluationRetrieverId, EvaluationRetrieverDescriptorV2>();
430
+ const ids = new Set<string>();
431
+ for (const lane of knowledgeBaseEvaluationRetrieverIds) {
432
+ const parsed = definition(definitions[lane], lane);
433
+ if (ids.has(parsed.id)) throw new TypeError(`Retriever descriptor ID ${parsed.id} is repeated.`);
434
+ ids.add(parsed.id);
435
+ output.set(lane, Object.freeze({
436
+ id: parsed.id,
437
+ role: parsed.role,
438
+ version: parsed.version,
439
+ implementationSha256: parsed.implementationSha256,
440
+ lanes: Object.freeze([lane] as const),
441
+ configuration: laneConfiguration(lane, parsed.retrieveLimit),
442
+ }));
443
+ }
444
+ const required = (lane: KnowledgeBaseEvaluationRetrieverId): EvaluationRetrieverDescriptorV2 => {
445
+ const descriptor = output.get(lane);
446
+ if (descriptor === undefined) throw new Error(`Missing authored descriptor for ${lane}.`);
447
+ return descriptor;
448
+ };
449
+ return Object.freeze({
450
+ exact: required("exact"),
451
+ keyword: required("keyword"),
452
+ semantic: required("semantic"),
453
+ hybrid: required("hybrid"),
454
+ metadata: required("metadata"),
455
+ graph: required("graph"),
456
+ "path-context": required("path-context"),
457
+ git: required("git"),
458
+ });
459
+ }
460
+
461
+ function closureConfiguration(
462
+ variant: ExistingLaneClosureVariant,
463
+ ): EvaluationRetrieverDescriptorV2["configuration"] {
464
+ const structural = new Map(variant.structuralLanes.map(({ lane, limit }, index) =>
465
+ [lane, { limit, order: index + 1 }] as const));
466
+ const executionOrder = [
467
+ ...(variant.primary === null ? [] : ["hybrid"]),
468
+ ...variant.structuralLanes.map(({ lane }) => lane),
469
+ ...(variant.git.mode === "explicit-input" ? ["git"] : []),
470
+ ].join(",") || "none";
471
+ return Object.freeze({
472
+ "adapter-schema": KNOWLEDGE_BASE_EVALUATION_ADAPTER_V2,
473
+ "execution-order": executionOrder,
474
+ "fusion-rule": EXISTING_LANE_CLOSURE_FUSION,
475
+ "generative-llm-call-limit": 0,
476
+ "generative-llm-input-token-limit": 0,
477
+ "generative-llm-output-token-limit": 0,
478
+ "git-limit": variant.git.mode === "explicit-input" ? variant.git.limit : null,
479
+ "git-mode": variant.git.mode,
480
+ "graph-limit": structural.get("graph")?.limit ?? null,
481
+ "graph-order": structural.get("graph")?.order ?? null,
482
+ "metadata-limit": structural.get("metadata")?.limit ?? null,
483
+ "metadata-order": structural.get("metadata")?.order ?? null,
484
+ "output-limit": variant.outputLimit,
485
+ "path-context-limit": structural.get("path-context")?.limit ?? null,
486
+ "path-context-order": structural.get("path-context")?.order ?? null,
487
+ "primary-lane": variant.primary?.lane ?? null,
488
+ "primary-retain-limit": variant.primary?.retainLimit ?? null,
489
+ "primary-retrieve-limit": variant.primary?.retrieveLimit ?? null,
490
+ "provenance-source": "live-lane-evidence",
491
+ "result-order": "primary-prefix-then-declared-lane-round-robin-by-source-rank",
492
+ });
493
+ }
494
+
495
+ function closureDescriptorLanes(
496
+ variant: ExistingLaneClosureVariant,
497
+ ): readonly EvaluationLaneIdV2[] {
498
+ return Object.freeze([
499
+ ...(variant.primary === null ? [] : ["hybrid" as const]),
500
+ ...variant.structuralLanes.map(({ lane }) => lane),
501
+ ...(variant.git.mode === "explicit-input" ? ["git" as const] : []),
502
+ ].toSorted());
503
+ }
504
+
505
+ /** Bind one deeply frozen closure variant to explicit authored implementation metadata. */
506
+ export function createKnowledgeBaseExistingLaneClosureDescriptorV2(options: Readonly<{
507
+ readonly id: string;
508
+ readonly role: EvaluationRetrieverDescriptorV2["role"];
509
+ readonly version: string;
510
+ readonly implementationSha256: string;
511
+ readonly variant: ExistingLaneClosureVariant;
512
+ }>): KnowledgeBaseExistingLaneClosureDescriptorV2 {
513
+ const variant = freezeExistingLaneClosureVariant(options.variant);
514
+ const parsed = definition({
515
+ id: options.id,
516
+ role: options.role,
517
+ version: options.version,
518
+ implementationSha256: options.implementationSha256,
519
+ retrieveLimit: variant.outputLimit,
520
+ }, "hybrid");
521
+ return Object.freeze({
522
+ descriptor: Object.freeze({
523
+ id: parsed.id,
524
+ role: parsed.role,
525
+ version: parsed.version,
526
+ implementationSha256: parsed.implementationSha256,
527
+ lanes: closureDescriptorLanes(variant),
528
+ configuration: closureConfiguration(variant),
529
+ }),
530
+ variant,
531
+ });
532
+ }
533
+
534
+ function assertFrozenSnapshot(
535
+ expected: RetrievalEvaluationCorpusV2["frozen"],
536
+ actual: RetrievalEvaluationCorpusV2["frozen"],
537
+ ): void {
538
+ if (
539
+ actual.repositoryCommit !== expected.repositoryCommit
540
+ || actual.vaultTree !== expected.vaultTree
541
+ || actual.vaultRoot !== expected.vaultRoot
542
+ ) throw new TypeError("Evaluation request does not name the adapter's locked frozen snapshot.");
543
+ }
544
+
545
+ function assertRequestLimit(descriptor: EvaluationRetrieverDescriptorV2, requestLimit: number): void {
546
+ const configured = descriptor.configuration["retrieve-limit"]
547
+ ?? descriptor.configuration["output-limit"];
548
+ if (requestLimit !== configured) {
549
+ throw new TypeError(
550
+ `Retriever ${descriptor.id} requires locked limit ${String(configured)}, received ${requestLimit}.`,
551
+ );
552
+ }
553
+ }
554
+
555
+ const forbiddenLegacyQueryFields = Object.freeze([
556
+ "adjudication",
557
+ "answer",
558
+ "assessments",
559
+ "assessorIds",
560
+ "class",
561
+ "cohort",
562
+ "expectedSupport",
563
+ "gold",
564
+ "id",
565
+ "inputOrigins",
566
+ "labels",
567
+ "negativeSubtype",
568
+ "nuggets",
569
+ "primaryLane",
570
+ "qrels",
571
+ "rawAssessments",
572
+ "split",
573
+ "strata",
574
+ "supportState",
575
+ "text",
576
+ "trust",
577
+ ] as const);
578
+
579
+ /** Private bridge. A legacy lane can observe only `inputs`; every other field is poison. */
580
+ function legacyQueryBridge(
581
+ inputs: RetrievalEvaluationCorpusV2["queries"][number]["inputs"] | Readonly<Record<string, unknown>>,
582
+ ): RetrievalEvaluationCorpus["queries"][number] {
583
+ const target: Record<string, unknown> = {};
584
+ Object.defineProperty(target, "inputs", {
585
+ configurable: false,
586
+ enumerable: true,
587
+ value: Object.freeze(inputs),
588
+ writable: false,
589
+ });
590
+ for (const field of forbiddenLegacyQueryFields) {
591
+ Object.defineProperty(target, field, {
592
+ configurable: false,
593
+ enumerable: false,
594
+ get(): never {
595
+ throw new Error(`Legacy evaluation lane attempted to read forbidden query field ${field}.`);
596
+ },
597
+ });
598
+ }
599
+ Object.preventExtensions(target);
600
+ return new Proxy(target, {
601
+ get(object, property, receiver): unknown {
602
+ if (typeof property === "symbol" || property === "inputs" || forbiddenLegacyQueryFields.includes(
603
+ property as typeof forbiddenLegacyQueryFields[number],
604
+ )) return Reflect.get(object, property, receiver);
605
+ throw new Error(`Legacy evaluation lane attempted to read forbidden query field ${property}.`);
606
+ },
607
+ }) as unknown as RetrievalEvaluationCorpus["queries"][number];
608
+ }
609
+
610
+ /** Private bridge. Snapshot verification can observe only the frozen commit/tree/root. */
611
+ function legacyCorpusBridge(
612
+ frozen: RetrievalEvaluationCorpusV2["frozen"],
613
+ ): RetrievalEvaluationCorpus {
614
+ const target: Record<string, unknown> = {};
615
+ Object.defineProperty(target, "frozen", {
616
+ configurable: false,
617
+ enumerable: true,
618
+ value: frozen,
619
+ writable: false,
620
+ });
621
+ for (const field of ["assessment", "description", "id", "queries", "schemaVersion"] as const) {
622
+ Object.defineProperty(target, field, {
623
+ configurable: false,
624
+ enumerable: false,
625
+ get(): never {
626
+ throw new Error(`Legacy evaluation opener attempted to read forbidden corpus field ${field}.`);
627
+ },
628
+ });
629
+ }
630
+ Object.preventExtensions(target);
631
+ return new Proxy(target, {
632
+ get(object, property, receiver): unknown {
633
+ if (typeof property === "symbol" || property === "frozen") {
634
+ return Reflect.get(object, property, receiver);
635
+ }
636
+ if (typeof property === "string" && Object.hasOwn(object, property)) {
637
+ return Reflect.get(object, property, receiver);
638
+ }
639
+ throw new Error(`Legacy evaluation opener attempted to read forbidden corpus field ${String(property)}.`);
640
+ },
641
+ }) as unknown as RetrievalEvaluationCorpus;
642
+ }
643
+
644
+ function executionInputs(request: EvaluationExecutionRequestV2): RetrievalEvaluationCorpusV2["queries"][number]["inputs"] {
645
+ const query = record(request.query, "evaluation v2 execution query");
646
+ const keys = Object.keys(query);
647
+ if (keys.length !== 1 || keys[0] !== "inputs") {
648
+ throw new TypeError("Evaluation v2 execution query may expose only inputs.");
649
+ }
650
+ return record(
651
+ ownData(query, "inputs", "evaluation v2 execution query"),
652
+ "evaluation v2 execution query.inputs",
653
+ ) as RetrievalEvaluationCorpusV2["queries"][number]["inputs"];
654
+ }
655
+
656
+ function inputForLegacyLane(
657
+ lane: KnowledgeBaseEvaluationRetrieverId,
658
+ inputs: RetrievalEvaluationCorpusV2["queries"][number]["inputs"],
659
+ ): Readonly<Record<string, unknown>> {
660
+ if (lane === "exact" || lane === "keyword" || lane === "semantic" || lane === "hybrid") {
661
+ return Object.freeze({ text: inputs.text });
662
+ }
663
+ if (lane === "metadata") {
664
+ return Object.freeze(inputs.metadata === undefined ? {} : { metadata: inputs.metadata });
665
+ }
666
+ if (lane === "graph") {
667
+ return Object.freeze(inputs.graph === undefined ? {} : { graph: inputs.graph });
668
+ }
669
+ if (lane === "path-context") {
670
+ return Object.freeze(inputs.context === undefined ? {} : { context: inputs.context });
671
+ }
672
+ return Object.freeze(inputs.history === undefined ? {} : { history: inputs.history });
673
+ }
674
+
675
+ function laneIsApplicable(
676
+ lane: KnowledgeBaseEvaluationRetrieverId,
677
+ inputs: RetrievalEvaluationCorpusV2["queries"][number]["inputs"],
678
+ ): boolean {
679
+ if (lane === "exact" || lane === "keyword" || lane === "semantic" || lane === "hybrid") return true;
680
+ if (lane === "metadata") return inputs.metadata !== undefined;
681
+ if (lane === "graph") return inputs.graph !== undefined;
682
+ if (lane === "path-context") return inputs.context !== undefined;
683
+ return inputs.history !== undefined;
684
+ }
685
+
686
+ function finiteMetricMap(value: unknown, label: string): Readonly<Record<string, number>> {
687
+ if (value === undefined) return Object.freeze({});
688
+ const input = record(value, label);
689
+ if (Object.keys(input).length > 32) throw new TypeError(`${label} may have at most 32 entries.`);
690
+ const output: Record<string, number> = {};
691
+ for (const key of Object.keys(input).toSorted()) {
692
+ const candidate = ownData(input, key, label);
693
+ if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0) {
694
+ throw new TypeError(`${label}.${key} must be a non-negative finite number.`);
695
+ }
696
+ output[boundedText(key, `${label} key`, 128)] = candidate;
697
+ }
698
+ return Object.freeze(output);
699
+ }
700
+
701
+ function diagnosticCode(lane: string, status: EvaluationDiagnostic["status"]): string {
702
+ const normalized = `${lane}-${status}`.normalize("NFKD").toLowerCase()
703
+ .replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 120);
704
+ return CANONICAL_ID.test(normalized) ? normalized : `diagnostic-${status}`;
705
+ }
706
+
707
+ function copyDiagnostics(value: unknown, label: string): readonly KnowledgeBaseEvaluationDiagnosticV2[] {
708
+ if (value === undefined) return Object.freeze([]);
709
+ if (!Array.isArray(value) || value.length > MAX_EVALUATION_DIAGNOSTICS) {
710
+ throw new TypeError(`${label} must contain at most ${MAX_EVALUATION_DIAGNOSTICS} entries.`);
711
+ }
712
+ return Object.freeze(value.map((candidate, index) => {
713
+ const input = record(candidate, `${label}[${index}]`);
714
+ const lane = boundedText(ownData(input, "lane", `${label}[${index}]`), `${label}[${index}].lane`, 256);
715
+ const status = ownData(input, "status", `${label}[${index}]`);
716
+ if (status !== "ready" && status !== "degraded" && status !== "unavailable") {
717
+ throw new TypeError(`${label}[${index}].status is invalid.`);
718
+ }
719
+ const rawMessage = ownData(input, "message", `${label}[${index}]`);
720
+ const message = rawMessage === undefined
721
+ ? undefined
722
+ : boundedText(rawMessage, `${label}[${index}].message`, MAX_DIAGNOSTIC_MESSAGE_BYTES);
723
+ return Object.freeze({
724
+ code: diagnosticCode(lane, status),
725
+ lane,
726
+ status,
727
+ ...(message === undefined ? {} : { message }),
728
+ });
729
+ }));
730
+ }
731
+
732
+ type ValidatedLegacyHit = Readonly<{
733
+ readonly documentId: string;
734
+ readonly rank: number;
735
+ readonly score?: number;
736
+ readonly evidence?: unknown;
737
+ }>;
738
+
739
+ type ValidatedLegacyResult = Readonly<{
740
+ readonly status: EvaluationRetrieverResult["status"];
741
+ readonly hits: readonly ValidatedLegacyHit[];
742
+ readonly diagnostics: readonly KnowledgeBaseEvaluationDiagnosticV2[];
743
+ readonly timings: Readonly<Record<string, number>>;
744
+ readonly resources: Readonly<Record<string, number>>;
745
+ }>;
746
+
747
+ function immutableEvidenceCopy(value: unknown): unknown {
748
+ let nodes = 0;
749
+ const seen = new Set<object>();
750
+ const copy = (candidate: unknown, depth: number): unknown => {
751
+ if (candidate === null || typeof candidate === "string" || typeof candidate === "boolean") {
752
+ return candidate;
753
+ }
754
+ if (typeof candidate === "number") {
755
+ if (!Number.isFinite(candidate)) throw new TypeError("legacy lane evidence numbers must be finite.");
756
+ return candidate;
757
+ }
758
+ if (candidate === undefined) return undefined;
759
+ if (typeof candidate !== "object") {
760
+ throw new TypeError("legacy lane evidence must contain only JSON-compatible values.");
761
+ }
762
+ if (depth > 32 || (nodes += 1) > 10_000) {
763
+ throw new TypeError("legacy lane evidence exceeds its structural bound.");
764
+ }
765
+ if (seen.has(candidate)) throw new TypeError("legacy lane evidence must not contain cycles.");
766
+ seen.add(candidate);
767
+ let output: unknown;
768
+ if (Array.isArray(candidate)) {
769
+ if (candidate.length > 10_000) throw new TypeError("legacy lane evidence array is too large.");
770
+ output = Object.freeze(candidate.map((entry) => {
771
+ const copied = copy(entry, depth + 1);
772
+ return copied === undefined ? null : copied;
773
+ }));
774
+ } else {
775
+ const input = candidate as Readonly<Record<string, unknown>>;
776
+ if (Object.keys(input).length > 10_000) throw new TypeError("legacy lane evidence object is too large.");
777
+ const object: Record<string, unknown> = {};
778
+ for (const key of Object.keys(input).toSorted()) {
779
+ const copied = copy(ownData(input, key, "legacy lane evidence"), depth + 1);
780
+ if (copied !== undefined) object[key] = copied;
781
+ }
782
+ output = Object.freeze(object);
783
+ }
784
+ seen.delete(candidate);
785
+ return output;
786
+ };
787
+ const copied = copy(value, 0);
788
+ const serialized = JSON.stringify(copied);
789
+ if (serialized === undefined || Buffer.byteLength(serialized, "utf8") > MAX_EVALUATION_EVIDENCE_BYTES) {
790
+ throw new TypeError("legacy lane evidence exceeds its serialized byte bound.");
791
+ }
792
+ return copied;
793
+ }
794
+
795
+ function confinedPath(value: unknown, label: string): string {
796
+ const path = boundedText(value, label, 4_096);
797
+ if (
798
+ path.startsWith("/")
799
+ || path.startsWith("./")
800
+ || path.includes("\\")
801
+ || WINDOWS_ABSOLUTE_PATH.test(path)
802
+ || path.split("/").some((part) => part === "" || part === "." || part === "..")
803
+ ) throw new TypeError(`${label} must be a canonical confined path.`);
804
+ return path;
805
+ }
806
+
807
+ function validateLegacyResult(
808
+ value: unknown,
809
+ lane: KnowledgeBaseEvaluationRetrieverId,
810
+ limit: number,
811
+ ): ValidatedLegacyResult {
812
+ const input = record(value, `legacy ${lane} result`);
813
+ const status = ownData(input, "status", `legacy ${lane} result`);
814
+ if (status !== "ready" && status !== "degraded" && status !== "unavailable") {
815
+ throw new TypeError(`legacy ${lane} result.status is invalid.`);
816
+ }
817
+ const rawHits = ownData(input, "hits", `legacy ${lane} result`);
818
+ if (!Array.isArray(rawHits) || rawHits.length > limit || rawHits.length > MAX_EVALUATION_RESULTS_PER_QUERY) {
819
+ throw new TypeError(`legacy ${lane} result.hits exceeds its locked result bound.`);
820
+ }
821
+ const hits = rawHits.map((candidate, index): ValidatedLegacyHit => {
822
+ const hit = record(candidate, `legacy ${lane} result.hits[${index}]`);
823
+ const rank = ownData(hit, "rank", `legacy ${lane} result.hits[${index}]`);
824
+ if (!Number.isSafeInteger(rank) || rank !== index + 1) {
825
+ throw new TypeError(`legacy ${lane} hit ranks must be contiguous source ranks.`);
826
+ }
827
+ const score = ownData(hit, "score", `legacy ${lane} result.hits[${index}]`);
828
+ if (score !== undefined && (typeof score !== "number" || !Number.isFinite(score))) {
829
+ throw new TypeError(`legacy ${lane} result.hits[${index}].score must be finite.`);
830
+ }
831
+ const rawEvidence = ownData(hit, "evidence", `legacy ${lane} result.hits[${index}]`);
832
+ const evidence = rawEvidence === undefined ? undefined : immutableEvidenceCopy(rawEvidence);
833
+ return Object.freeze({
834
+ documentId: confinedPath(
835
+ ownData(hit, "documentId", `legacy ${lane} result.hits[${index}]`),
836
+ `legacy ${lane} result.hits[${index}].documentId`,
837
+ ),
838
+ rank,
839
+ ...(score === undefined ? {} : { score }),
840
+ ...(evidence === undefined ? {} : { evidence }),
841
+ });
842
+ });
843
+ if (new Set(hits.map(({ documentId }) => documentId)).size !== hits.length) {
844
+ throw new TypeError(`legacy ${lane} result.hits must not repeat a document.`);
845
+ }
846
+ if (status === "unavailable" && hits.length > 0) {
847
+ throw new TypeError(`legacy ${lane} unavailable result may not contain hits.`);
848
+ }
849
+ return Object.freeze({
850
+ status,
851
+ hits: Object.freeze(hits),
852
+ diagnostics: copyDiagnostics(
853
+ ownData(input, "diagnostics", `legacy ${lane} result`),
854
+ `legacy ${lane} result.diagnostics`,
855
+ ),
856
+ timings: finiteMetricMap(
857
+ ownData(input, "timings", `legacy ${lane} result`),
858
+ `legacy ${lane} result.timings`,
859
+ ),
860
+ resources: finiteMetricMap(
861
+ ownData(input, "resources", `legacy ${lane} result`),
862
+ `legacy ${lane} result.resources`,
863
+ ),
864
+ });
865
+ }
866
+
867
+ type BoundEvidenceUnit = KnowledgeBaseEvaluationEvidenceUnitV2 & Readonly<{
868
+ readonly kind: EvaluationEvidenceUnit["kind"];
869
+ readonly frontmatterField?: string;
870
+ readonly text: string;
871
+ }>;
872
+
873
+ type EvidenceBindings = Readonly<{
874
+ readonly byCorpusUnitId: Readonly<Record<string, BoundEvidenceUnit>>;
875
+ readonly byRegistryUnitId: Readonly<Record<string, BoundEvidenceUnit>>;
876
+ readonly byDocumentId: Readonly<Record<string, readonly BoundEvidenceUnit[]>>;
877
+ readonly units: readonly BoundEvidenceUnit[];
878
+ }>;
879
+
880
+ type LegacyRetrieverBindings = Readonly<Record<
881
+ KnowledgeBaseEvaluationRetrieverId,
882
+ EvaluationRetriever
883
+ >>;
884
+
885
+ type KnowledgeBaseEvaluationExecutionContractV2 = Readonly<{
886
+ readonly frozen: RetrievalEvaluationCorpusV2["frozen"];
887
+ readonly manifest: Readonly<{
888
+ readonly corpusSha256: string;
889
+ readonly candidateLockSha256: string;
890
+ readonly buildContractSha256: string;
891
+ }>;
892
+ readonly candidateLock: EvaluationCandidateLockV2;
893
+ readonly descriptors: readonly EvaluationRetrieverDescriptorV2[];
894
+ readonly descriptorsById: Readonly<Record<string, EvaluationRetrieverDescriptorV2>>;
895
+ readonly evidenceBindings: EvidenceBindings;
896
+ readonly closureEvidenceRegistry: ExistingLaneClosureEvidenceRegistry;
897
+ readonly legacyRetrievers: LegacyRetrieverBindings;
898
+ }>;
899
+
900
+ function copyRetrieverDescriptor(
901
+ descriptor: EvaluationRetrieverDescriptorV2,
902
+ ): EvaluationRetrieverDescriptorV2 {
903
+ const configuration = Object.freeze(Object.fromEntries(
904
+ Object.entries(descriptor.configuration).toSorted(([left], [right]) => left.localeCompare(right)),
905
+ ));
906
+ return Object.freeze({
907
+ id: descriptor.id,
908
+ role: descriptor.role,
909
+ version: descriptor.version,
910
+ implementationSha256: descriptor.implementationSha256,
911
+ lanes: Object.freeze([...descriptor.lanes]),
912
+ configuration,
913
+ });
914
+ }
915
+
916
+ function copyCandidateLock(
917
+ candidateLock: EvaluationCandidateLockV2,
918
+ ): EvaluationCandidateLockV2 {
919
+ return Object.freeze({
920
+ baselineRetrieverId: candidateLock.baselineRetrieverId,
921
+ candidateRetrieverIds: Object.freeze([...candidateLock.candidateRetrieverIds]),
922
+ descriptorDigests: Object.freeze(candidateLock.descriptorDigests.map((binding) => Object.freeze({
923
+ retrieverId: binding.retrieverId,
924
+ sha256: binding.sha256,
925
+ }))),
926
+ });
927
+ }
928
+
929
+ function bindLegacyRetrievers(evaluation: KnowledgeBaseEvaluation): LegacyRetrieverBindings {
930
+ const byId: Partial<Record<KnowledgeBaseEvaluationRetrieverId, EvaluationRetriever>> =
931
+ Object.create(null) as Partial<Record<KnowledgeBaseEvaluationRetrieverId, EvaluationRetriever>>;
932
+ for (const retriever of evaluation.retrievers) {
933
+ if (!knowledgeBaseEvaluationRetrieverIds.includes(retriever.id as KnowledgeBaseEvaluationRetrieverId)) {
934
+ throw new TypeError(`Verified evaluation exposed unknown lane ${retriever.id}.`);
935
+ }
936
+ const lane = retriever.id as KnowledgeBaseEvaluationRetrieverId;
937
+ if (byId[lane] !== undefined) throw new TypeError(`Verified evaluation repeats ${lane} lane.`);
938
+ byId[lane] = Object.freeze({ id: retriever.id, retrieve: retriever.retrieve });
939
+ }
940
+ if (knowledgeBaseEvaluationRetrieverIds.some((lane) => byId[lane] === undefined)) {
941
+ throw new TypeError("Verified evaluation must expose all eight immutable built-in lanes.");
942
+ }
943
+ return Object.freeze(byId) as LegacyRetrieverBindings;
944
+ }
945
+
946
+ function createExecutionContract(options: Readonly<{
947
+ readonly corpus: RetrievalEvaluationCorpusV2;
948
+ readonly descriptors: readonly EvaluationRetrieverDescriptorV2[];
949
+ readonly evidenceBindings: EvidenceBindings;
950
+ readonly legacyRetrievers: LegacyRetrieverBindings;
951
+ }>): KnowledgeBaseEvaluationExecutionContractV2 {
952
+ const frozen = Object.freeze({
953
+ repositoryCommit: options.corpus.frozen.repositoryCommit,
954
+ vaultTree: options.corpus.frozen.vaultTree,
955
+ vaultRoot: options.corpus.frozen.vaultRoot,
956
+ });
957
+ const descriptors = Object.freeze(options.descriptors.map(copyRetrieverDescriptor));
958
+ const descriptorsById = Object.freeze(Object.assign(
959
+ Object.create(null) as Record<string, EvaluationRetrieverDescriptorV2>,
960
+ Object.fromEntries(descriptors.map((descriptor) => [descriptor.id, descriptor])),
961
+ ));
962
+ const candidateLock = copyCandidateLock(options.corpus.candidateLock);
963
+ for (const descriptor of descriptors) {
964
+ const lock = candidateLock.descriptorDigests.find(({ retrieverId }) =>
965
+ retrieverId === descriptor.id);
966
+ if (lock?.sha256 !== evaluationRetrieverDescriptorDigestV2(descriptor)) {
967
+ throw new TypeError(`Retriever descriptor ${descriptor.id} drifted while deriving its execution contract.`);
968
+ }
969
+ }
970
+ const closureRegistry = closureEvidenceRegistry(options.evidenceBindings);
971
+ return Object.freeze({
972
+ frozen,
973
+ manifest: Object.freeze({
974
+ corpusSha256: options.corpus.manifest.corpusSha256,
975
+ candidateLockSha256: options.corpus.manifest.candidateLockSha256,
976
+ buildContractSha256: options.corpus.manifest.buildContractSha256,
977
+ }),
978
+ candidateLock,
979
+ descriptors,
980
+ descriptorsById,
981
+ evidenceBindings: options.evidenceBindings,
982
+ closureEvidenceRegistry: closureRegistry,
983
+ legacyRetrievers: options.legacyRetrievers,
984
+ });
985
+ }
986
+
987
+ function evidenceBindingKey(value: Readonly<{
988
+ readonly documentId: string;
989
+ readonly sourcePath: string;
990
+ readonly lineRange: { readonly start: number; readonly end: number };
991
+ readonly headingPath: readonly string[];
992
+ readonly sourcePage?: number;
993
+ readonly trustClass: string;
994
+ }>): string {
995
+ return JSON.stringify([
996
+ value.documentId,
997
+ value.sourcePath,
998
+ value.lineRange.start,
999
+ value.lineRange.end,
1000
+ value.headingPath,
1001
+ value.sourcePage ?? null,
1002
+ value.trustClass,
1003
+ ]);
1004
+ }
1005
+
1006
+ function buildEvidenceBindings(
1007
+ registry: EvaluationEvidenceRegistry,
1008
+ corpus: RetrievalEvaluationCorpusV2,
1009
+ ): EvidenceBindings {
1010
+ validateEvaluationEvidenceRegistry(registry);
1011
+ const familyById = new Map(corpus.sourceFamilies.map((family) => [family.id, family]));
1012
+ const documentById = new Map(corpus.documents.map((document) => [document.id, document]));
1013
+ const registryById = new Map<string, EvaluationEvidenceUnit>();
1014
+ for (const unit of registry.units) {
1015
+ if (registryById.has(unit.id)) {
1016
+ throw new TypeError(`Live registry unit ${unit.id} is duplicated.`);
1017
+ }
1018
+ registryById.set(unit.id, unit);
1019
+ }
1020
+
1021
+ const byCorpusUnitId = new Map<string, BoundEvidenceUnit>();
1022
+ const byRegistryUnitId = new Map<string, BoundEvidenceUnit>();
1023
+ const mutableByDocumentId = new Map<string, BoundEvidenceUnit[]>();
1024
+ for (const corpusUnit of corpus.evidenceUnits) {
1025
+ const document = documentById.get(corpusUnit.documentId);
1026
+ const family = familyById.get(corpusUnit.sourceFamilyId);
1027
+ if (document === undefined || family === undefined) {
1028
+ throw new TypeError(`Corpus evidence unit ${corpusUnit.id} has an unresolved document or source family.`);
1029
+ }
1030
+ const key = evidenceBindingKey({
1031
+ documentId: corpusUnit.documentId,
1032
+ sourcePath: corpusUnit.sourcePath,
1033
+ lineRange: corpusUnit.lineRange,
1034
+ headingPath: corpusUnit.headingPath,
1035
+ ...(corpusUnit.sourcePage === undefined ? {} : { sourcePage: corpusUnit.sourcePage }),
1036
+ trustClass: corpusUnit.trustClass,
1037
+ });
1038
+ const registryUnit = registryById.get(corpusUnit.id);
1039
+ if (registryUnit === undefined) {
1040
+ throw new TypeError(
1041
+ `Corpus evidence unit ${corpusUnit.id} does not preserve an exact live registry unit identity.`,
1042
+ );
1043
+ }
1044
+ const registryKey = evidenceBindingKey({
1045
+ documentId: registryUnit.documentId,
1046
+ sourcePath: registryUnit.sourcePath,
1047
+ lineRange: registryUnit.lineRange,
1048
+ headingPath: registryUnit.headingAncestry,
1049
+ ...(registryUnit.pdfPage === undefined ? {} : { sourcePage: registryUnit.pdfPage }),
1050
+ trustClass: registryUnit.trustClass,
1051
+ });
1052
+ if (key !== registryKey) {
1053
+ throw new TypeError(
1054
+ `Corpus evidence unit ${corpusUnit.id} metadata does not match its exact live registry unit.`,
1055
+ );
1056
+ }
1057
+ if (byRegistryUnitId.has(registryUnit.id)) {
1058
+ throw new TypeError(`Live registry unit ${registryUnit.id} is bound to more than one corpus unit.`);
1059
+ }
1060
+ const bound: BoundEvidenceUnit = Object.freeze({
1061
+ evidenceUnitId: corpusUnit.id,
1062
+ registryUnitId: registryUnit.id,
1063
+ documentId: corpusUnit.documentId,
1064
+ sourceFamilyId: corpusUnit.sourceFamilyId,
1065
+ sourceClass: family.sourceClass,
1066
+ trustClass: corpusUnit.trustClass,
1067
+ locator: Object.freeze({
1068
+ evidenceUnitId: corpusUnit.id,
1069
+ sourceFamilyId: corpusUnit.sourceFamilyId,
1070
+ sourceClass: family.sourceClass,
1071
+ trustClass: corpusUnit.trustClass,
1072
+ sourcePath: corpusUnit.sourcePath,
1073
+ lineRange: Object.freeze({
1074
+ start: corpusUnit.lineRange.start,
1075
+ end: corpusUnit.lineRange.end,
1076
+ }),
1077
+ headingPath: Object.freeze([...corpusUnit.headingPath]),
1078
+ ...(corpusUnit.sourcePage === undefined ? {} : { sourcePage: corpusUnit.sourcePage }),
1079
+ }),
1080
+ kind: registryUnit.kind,
1081
+ ...(registryUnit.frontmatterField === undefined
1082
+ ? {}
1083
+ : { frontmatterField: registryUnit.frontmatterField }),
1084
+ text: registryUnit.text,
1085
+ });
1086
+ byCorpusUnitId.set(bound.evidenceUnitId, bound);
1087
+ byRegistryUnitId.set(bound.registryUnitId, bound);
1088
+ const documentUnits = mutableByDocumentId.get(bound.documentId) ?? [];
1089
+ documentUnits.push(bound);
1090
+ mutableByDocumentId.set(bound.documentId, documentUnits);
1091
+ }
1092
+ const kindOrder: Readonly<Record<EvaluationEvidenceUnit["kind"], number>> = Object.freeze({
1093
+ heading: 0,
1094
+ paragraph: 1,
1095
+ list: 2,
1096
+ table: 3,
1097
+ "code-block": 4,
1098
+ "pdf-page-span": 5,
1099
+ "frontmatter-field": 6,
1100
+ });
1101
+ const byDocumentId = new Map<string, readonly BoundEvidenceUnit[]>();
1102
+ for (const [documentId, units] of mutableByDocumentId) {
1103
+ byDocumentId.set(documentId, Object.freeze(units.toSorted((left, right) =>
1104
+ left.locator.lineRange.start - right.locator.lineRange.start
1105
+ || kindOrder[left.kind] - kindOrder[right.kind]
1106
+ || left.locator.lineRange.end - right.locator.lineRange.end
1107
+ || left.evidenceUnitId.localeCompare(right.evidenceUnitId))));
1108
+ }
1109
+ const allUnits = Object.freeze([...byCorpusUnitId.values()]
1110
+ .toSorted((left, right) => left.evidenceUnitId.localeCompare(right.evidenceUnitId)));
1111
+ return Object.freeze({
1112
+ byCorpusUnitId: Object.freeze(Object.assign(
1113
+ Object.create(null) as Record<string, BoundEvidenceUnit>,
1114
+ Object.fromEntries(byCorpusUnitId),
1115
+ )),
1116
+ byRegistryUnitId: Object.freeze(Object.assign(
1117
+ Object.create(null) as Record<string, BoundEvidenceUnit>,
1118
+ Object.fromEntries(byRegistryUnitId),
1119
+ )),
1120
+ byDocumentId: Object.freeze(Object.assign(
1121
+ Object.create(null) as Record<string, readonly BoundEvidenceUnit[]>,
1122
+ Object.fromEntries(byDocumentId),
1123
+ )),
1124
+ units: allUnits,
1125
+ });
1126
+ }
1127
+
1128
+ type HitEvidenceLocator =
1129
+ | Readonly<{ readonly kind: "evidence-unit"; readonly evidenceUnitId: string }>
1130
+ | Readonly<{ readonly kind: "frontmatter-field"; readonly field: string }>
1131
+ | Readonly<{ readonly kind: "frontmatter-field-any"; readonly fields: readonly string[] }>
1132
+ | Readonly<{ readonly kind: "frontmatter-value"; readonly value: string }>
1133
+ | Readonly<{ readonly kind: "line"; readonly line: number }>
1134
+ | Readonly<{
1135
+ readonly kind: "line-range";
1136
+ readonly start: number;
1137
+ readonly end: number;
1138
+ }>
1139
+ | Readonly<{ readonly kind: "source-page"; readonly sourcePage: number }>
1140
+ | Readonly<{ readonly kind: "source-path"; readonly sourcePath: string }>
1141
+ | Readonly<{ readonly kind: "title"; readonly title: string }>;
1142
+
1143
+ type HitEvidenceProvenance = Readonly<{
1144
+ readonly targetDocumentId: string;
1145
+ readonly evidenceDocumentId: string;
1146
+ readonly sourcePath: string;
1147
+ readonly locator: HitEvidenceLocator;
1148
+ }>;
1149
+
1150
+ function positiveSourcePosition(value: unknown): value is number {
1151
+ return Number.isSafeInteger(value) && (value as number) >= 1 && (value as number) <= 10_000_000;
1152
+ }
1153
+
1154
+ function hitEvidenceProvenance(
1155
+ hit: ValidatedLegacyHit,
1156
+ ): readonly HitEvidenceProvenance[] | undefined {
1157
+ if (hit.evidence === null || typeof hit.evidence !== "object" || Array.isArray(hit.evidence)) {
1158
+ return undefined;
1159
+ }
1160
+ const evidence = hit.evidence as Readonly<Record<string, unknown>>;
1161
+ if (!Object.prototype.hasOwnProperty.call(evidence, "provenance")) return undefined;
1162
+ try {
1163
+ const rawProvenance = ownData(evidence, "provenance", "lane evidence");
1164
+ if (!Array.isArray(rawProvenance) || rawProvenance.length === 0 || rawProvenance.length > 64) {
1165
+ return undefined;
1166
+ }
1167
+ const parseText = (value: unknown): string | undefined => {
1168
+ if (typeof value !== "string" || value === "" || /[\0\r\n]/u.test(value)) return undefined;
1169
+ if (value.normalize("NFC") !== value || Buffer.byteLength(value, "utf8") > 4_096) return undefined;
1170
+ return value;
1171
+ };
1172
+ const parsed = rawProvenance.map((candidate, index): HitEvidenceProvenance | undefined => {
1173
+ const provenance = record(candidate, `lane evidence.provenance[${index}]`);
1174
+ if (
1175
+ Object.keys(provenance).toSorted().join("\0")
1176
+ !== "evidenceDocumentId\0locator\0sourcePath\0targetDocumentId"
1177
+ ) {
1178
+ return undefined;
1179
+ }
1180
+ const targetDocumentId = confinedPath(
1181
+ ownData(provenance, "targetDocumentId", "lane evidence.provenance"),
1182
+ "lane evidence.provenance.targetDocumentId",
1183
+ );
1184
+ if (targetDocumentId !== hit.documentId) return undefined;
1185
+ const evidenceDocumentId = confinedPath(
1186
+ ownData(provenance, "evidenceDocumentId", "lane evidence.provenance"),
1187
+ "lane evidence.provenance.evidenceDocumentId",
1188
+ );
1189
+ const sourcePath = confinedPath(
1190
+ ownData(provenance, "sourcePath", "lane evidence.provenance"),
1191
+ "lane evidence.provenance.sourcePath",
1192
+ );
1193
+ const locator = record(
1194
+ ownData(provenance, "locator", "lane evidence.provenance"),
1195
+ "lane evidence.provenance.locator",
1196
+ );
1197
+ const kind = ownData(locator, "kind", "lane evidence.provenance.locator");
1198
+ if (kind === "evidence-unit") {
1199
+ if (Object.keys(locator).toSorted().join("\0") !== "evidenceUnitId\0kind") return undefined;
1200
+ const evidenceUnitId = ownData(locator, "evidenceUnitId", "lane evidence.provenance.locator");
1201
+ if (typeof evidenceUnitId !== "string") return undefined;
1202
+ return Object.freeze({
1203
+ targetDocumentId,
1204
+ evidenceDocumentId,
1205
+ sourcePath,
1206
+ locator: Object.freeze({ kind, evidenceUnitId }),
1207
+ });
1208
+ }
1209
+ if (kind === "frontmatter-field") {
1210
+ if (Object.keys(locator).toSorted().join("\0") !== "field\0kind") return undefined;
1211
+ const field = ownData(locator, "field", "lane evidence.provenance.locator");
1212
+ const parsedField = parseText(field);
1213
+ if (parsedField === undefined) return undefined;
1214
+ return Object.freeze({
1215
+ targetDocumentId,
1216
+ evidenceDocumentId,
1217
+ sourcePath,
1218
+ locator: Object.freeze({ kind, field: parsedField }),
1219
+ });
1220
+ }
1221
+ if (kind === "frontmatter-field-any") {
1222
+ if (Object.keys(locator).toSorted().join("\0") !== "fields\0kind") return undefined;
1223
+ const fields = ownData(locator, "fields", "lane evidence.provenance.locator");
1224
+ if (!Array.isArray(fields) || fields.length === 0 || fields.length > 32) return undefined;
1225
+ const parsedFields = fields.map(parseText);
1226
+ if (parsedFields.some((field) => field === undefined)) return undefined;
1227
+ const canonicalFields = [...new Set(parsedFields as string[])].toSorted();
1228
+ if (canonicalFields.length !== fields.length) return undefined;
1229
+ return Object.freeze({
1230
+ targetDocumentId,
1231
+ evidenceDocumentId,
1232
+ sourcePath,
1233
+ locator: Object.freeze({ kind, fields: Object.freeze(canonicalFields) }),
1234
+ });
1235
+ }
1236
+ if (kind === "frontmatter-value") {
1237
+ if (Object.keys(locator).toSorted().join("\0") !== "kind\0value") return undefined;
1238
+ const value = parseText(ownData(locator, "value", "lane evidence.provenance.locator"));
1239
+ if (value === undefined) return undefined;
1240
+ return Object.freeze({
1241
+ targetDocumentId,
1242
+ evidenceDocumentId,
1243
+ sourcePath,
1244
+ locator: Object.freeze({ kind, value }),
1245
+ });
1246
+ }
1247
+ if (kind === "line") {
1248
+ if (Object.keys(locator).toSorted().join("\0") !== "kind\0line") return undefined;
1249
+ const line = ownData(locator, "line", "lane evidence.provenance.locator");
1250
+ if (!positiveSourcePosition(line)) return undefined;
1251
+ return Object.freeze({
1252
+ targetDocumentId,
1253
+ evidenceDocumentId,
1254
+ sourcePath,
1255
+ locator: Object.freeze({ kind, line }),
1256
+ });
1257
+ }
1258
+ if (kind === "line-range") {
1259
+ if (Object.keys(locator).toSorted().join("\0") !== "end\0kind\0start") return undefined;
1260
+ const start = ownData(locator, "start", "lane evidence.provenance.locator");
1261
+ const end = ownData(locator, "end", "lane evidence.provenance.locator");
1262
+ if (!positiveSourcePosition(start) || !positiveSourcePosition(end) || end < start) return undefined;
1263
+ return Object.freeze({
1264
+ targetDocumentId,
1265
+ evidenceDocumentId,
1266
+ sourcePath,
1267
+ locator: Object.freeze({ kind, start, end }),
1268
+ });
1269
+ }
1270
+ if (kind === "source-page") {
1271
+ if (Object.keys(locator).toSorted().join("\0") !== "kind\0sourcePage") return undefined;
1272
+ const sourcePage = ownData(locator, "sourcePage", "lane evidence.provenance.locator");
1273
+ if (!Number.isSafeInteger(sourcePage) || (sourcePage as number) < 1 || (sourcePage as number) > 1_000_000) {
1274
+ return undefined;
1275
+ }
1276
+ return Object.freeze({
1277
+ targetDocumentId,
1278
+ evidenceDocumentId,
1279
+ sourcePath,
1280
+ locator: Object.freeze({ kind, sourcePage: sourcePage as number }),
1281
+ });
1282
+ }
1283
+ if (kind === "source-path") {
1284
+ if (Object.keys(locator).toSorted().join("\0") !== "kind\0sourcePath") return undefined;
1285
+ const locatorSourcePath = confinedPath(
1286
+ ownData(locator, "sourcePath", "lane evidence.provenance.locator"),
1287
+ "lane evidence.provenance.locator.sourcePath",
1288
+ );
1289
+ if (locatorSourcePath !== sourcePath) return undefined;
1290
+ return Object.freeze({
1291
+ targetDocumentId,
1292
+ evidenceDocumentId,
1293
+ sourcePath,
1294
+ locator: Object.freeze({ kind, sourcePath: locatorSourcePath }),
1295
+ });
1296
+ }
1297
+ if (kind === "title") {
1298
+ if (Object.keys(locator).toSorted().join("\0") !== "kind\0title") return undefined;
1299
+ const title = parseText(ownData(locator, "title", "lane evidence.provenance.locator"));
1300
+ if (title === undefined) return undefined;
1301
+ return Object.freeze({
1302
+ targetDocumentId,
1303
+ evidenceDocumentId,
1304
+ sourcePath,
1305
+ locator: Object.freeze({ kind, title }),
1306
+ });
1307
+ }
1308
+ return undefined;
1309
+ });
1310
+ if (parsed.some((candidate) => candidate === undefined)) return undefined;
1311
+ const provenance = parsed as HitEvidenceProvenance[];
1312
+ if (new Set(provenance.map((candidate) => JSON.stringify(candidate))).size !== provenance.length) {
1313
+ return undefined;
1314
+ }
1315
+ return Object.freeze(provenance);
1316
+ } catch {
1317
+ return undefined;
1318
+ }
1319
+ }
1320
+
1321
+ function normalizeEvidenceText(value: string): string {
1322
+ return value.normalize("NFC").toLocaleLowerCase("en-US");
1323
+ }
1324
+
1325
+ function resolveEvidenceContribution(
1326
+ provenance: HitEvidenceProvenance,
1327
+ bindings: EvidenceBindings,
1328
+ ): readonly BoundEvidenceUnit[] {
1329
+ if (provenance.locator.kind === "evidence-unit") {
1330
+ const binding = bindings.byCorpusUnitId[provenance.locator.evidenceUnitId]
1331
+ ?? bindings.byRegistryUnitId[provenance.locator.evidenceUnitId];
1332
+ return binding?.documentId === provenance.evidenceDocumentId
1333
+ && binding.locator.sourcePath === provenance.sourcePath
1334
+ ? Object.freeze([binding])
1335
+ : Object.freeze([]);
1336
+ }
1337
+ let candidates = [...(bindings.byDocumentId[provenance.evidenceDocumentId] ?? [])]
1338
+ .filter((candidate) => candidate.locator.sourcePath === provenance.sourcePath);
1339
+ if (candidates.length === 0) return Object.freeze([]);
1340
+
1341
+ if (provenance.locator.kind === "frontmatter-field") {
1342
+ const field = provenance.locator.field;
1343
+ candidates = candidates.filter(({ kind, frontmatterField }) =>
1344
+ kind === "frontmatter-field" && frontmatterField === field);
1345
+ } else if (provenance.locator.kind === "frontmatter-field-any") {
1346
+ const fields = provenance.locator.fields;
1347
+ candidates = candidates.filter(({ kind, frontmatterField }) =>
1348
+ kind === "frontmatter-field"
1349
+ && frontmatterField !== undefined
1350
+ && fields.includes(frontmatterField));
1351
+ } else if (provenance.locator.kind === "frontmatter-value") {
1352
+ const value = normalizeEvidenceText(provenance.locator.value);
1353
+ candidates = candidates.filter(({ kind, text }) =>
1354
+ kind === "frontmatter-field" && normalizeEvidenceText(text).includes(value));
1355
+ } else if (provenance.locator.kind === "title") {
1356
+ const title = provenance.locator.title;
1357
+ const frontmatter = candidates.filter(({ kind, frontmatterField }) =>
1358
+ kind === "frontmatter-field" && frontmatterField === "title");
1359
+ candidates = frontmatter.length > 0
1360
+ ? frontmatter
1361
+ : candidates.filter(({ kind, locator }) =>
1362
+ kind === "heading"
1363
+ && normalizeEvidenceText(locator.headingPath.at(-1) ?? "")
1364
+ === normalizeEvidenceText(title));
1365
+ } else if (provenance.locator.kind === "line" || provenance.locator.kind === "line-range") {
1366
+ const lineRange = provenance.locator.kind === "line"
1367
+ ? Object.freeze({ start: provenance.locator.line, end: provenance.locator.line })
1368
+ : Object.freeze({ start: provenance.locator.start, end: provenance.locator.end });
1369
+ const containing = candidates.filter(({ locator }) =>
1370
+ locator.lineRange.start <= lineRange.start && locator.lineRange.end >= lineRange.end);
1371
+ if (containing.length === 0) return Object.freeze([]);
1372
+ const nonPage = containing.filter(({ kind }) => kind !== "pdf-page-span");
1373
+ candidates = nonPage.length > 0 ? nonPage : containing;
1374
+ const narrowestSpan = Math.min(...candidates.map(({ locator }) =>
1375
+ locator.lineRange.end - locator.lineRange.start));
1376
+ candidates = candidates.filter(({ locator }) =>
1377
+ locator.lineRange.end - locator.lineRange.start === narrowestSpan);
1378
+ } else if (provenance.locator.kind === "source-path") {
1379
+ // A path is retrieval identity, not a Markdown slice that may earn nugget credit.
1380
+ return Object.freeze([]);
1381
+ } else {
1382
+ const sourcePage = provenance.locator.sourcePage;
1383
+ candidates = candidates.filter(({ kind, locator }) =>
1384
+ kind === "pdf-page-span" && locator.sourcePage === sourcePage);
1385
+ }
1386
+ return Object.freeze(candidates);
1387
+ }
1388
+
1389
+ function resolveHitEvidence(
1390
+ hit: ValidatedLegacyHit,
1391
+ bindings: EvidenceBindings,
1392
+ lane: KnowledgeBaseEvaluationRetrieverId,
1393
+ ): readonly BoundEvidenceUnit[] | undefined {
1394
+ const provenance = hitEvidenceProvenance(hit);
1395
+ if (provenance === undefined) return undefined;
1396
+ const resolved = provenance.map((candidate) => resolveEvidenceContribution(candidate, bindings));
1397
+ const requiresEveryContribution = lane === "metadata" || lane === "graph" || lane === "path-context";
1398
+ if (requiresEveryContribution && resolved.some((candidates) => candidates.length === 0)) {
1399
+ return undefined;
1400
+ }
1401
+ const unique = [...new Map(resolved.flat()
1402
+ .map((candidate) => [candidate.evidenceUnitId, candidate] as const)).values()]
1403
+ .toSorted((left, right) => left.evidenceUnitId.localeCompare(right.evidenceUnitId));
1404
+ return unique.length === 0 ? undefined : Object.freeze(unique);
1405
+ }
1406
+
1407
+ function publicEvidenceUnit(unit: BoundEvidenceUnit): KnowledgeBaseEvaluationEvidenceUnitV2 {
1408
+ return Object.freeze({
1409
+ evidenceUnitId: unit.evidenceUnitId,
1410
+ registryUnitId: unit.registryUnitId,
1411
+ documentId: unit.documentId,
1412
+ sourceFamilyId: unit.sourceFamilyId,
1413
+ sourceClass: unit.sourceClass,
1414
+ trustClass: unit.trustClass,
1415
+ locator: unit.locator,
1416
+ });
1417
+ }
1418
+
1419
+ function closureEvidenceLocator(unit: BoundEvidenceUnit): ExistingLaneClosureEvidenceLocator {
1420
+ return Object.freeze({
1421
+ evidenceUnitId: unit.evidenceUnitId,
1422
+ documentId: unit.documentId,
1423
+ sourceFamilyId: unit.sourceFamilyId,
1424
+ sourceClass: unit.sourceClass,
1425
+ trustClass: unit.trustClass,
1426
+ sourcePath: unit.locator.sourcePath,
1427
+ lineRange: Object.freeze({
1428
+ start: unit.locator.lineRange.start,
1429
+ end: unit.locator.lineRange.end,
1430
+ }),
1431
+ headingPath: Object.freeze([...unit.locator.headingPath]),
1432
+ ...(unit.locator.sourcePage === undefined ? {} : { sourcePage: unit.locator.sourcePage }),
1433
+ });
1434
+ }
1435
+
1436
+ function closureEvidenceRegistry(bindings: EvidenceBindings): ExistingLaneClosureEvidenceRegistry {
1437
+ return Object.freeze({
1438
+ units: Object.freeze(bindings.units
1439
+ .map(closureEvidenceLocator)),
1440
+ });
1441
+ }
1442
+
1443
+ function closureLocatorKey(locator: ExistingLaneClosureEvidenceLocator): string {
1444
+ return JSON.stringify([
1445
+ locator.evidenceUnitId,
1446
+ locator.documentId,
1447
+ locator.sourceFamilyId,
1448
+ locator.sourceClass,
1449
+ locator.trustClass,
1450
+ locator.sourcePath,
1451
+ locator.lineRange.start,
1452
+ locator.lineRange.end,
1453
+ locator.headingPath,
1454
+ locator.sourcePage ?? null,
1455
+ ]);
1456
+ }
1457
+
1458
+ function bindingFromClosureLocator(
1459
+ locator: ExistingLaneClosureEvidenceLocator,
1460
+ bindings: EvidenceBindings,
1461
+ ): BoundEvidenceUnit {
1462
+ const binding = bindings.byCorpusUnitId[locator.evidenceUnitId];
1463
+ if (
1464
+ binding === undefined
1465
+ || closureLocatorKey(closureEvidenceLocator(binding)) !== closureLocatorKey(locator)
1466
+ ) {
1467
+ throw new TypeError(
1468
+ `Closure provenance ${locator.evidenceUnitId} does not match the adapter evidence binding.`,
1469
+ );
1470
+ }
1471
+ return binding;
1472
+ }
1473
+
1474
+ function bindingsFromClosureProvenance(
1475
+ provenance: readonly ExistingLaneClosureEvidenceLocator[],
1476
+ bindings: EvidenceBindings,
1477
+ ): readonly BoundEvidenceUnit[] {
1478
+ return Object.freeze(provenance.map((locator) => bindingFromClosureLocator(locator, bindings)));
1479
+ }
1480
+
1481
+ function uniqueBindingsFromClosureProvenance(
1482
+ provenance: readonly ExistingLaneClosureEvidenceLocator[],
1483
+ bindings: EvidenceBindings,
1484
+ ): readonly BoundEvidenceUnit[] {
1485
+ return Object.freeze([...new Map(bindingsFromClosureProvenance(provenance, bindings)
1486
+ .map((binding) => [binding.evidenceUnitId, binding] as const)).values()]);
1487
+ }
1488
+
1489
+ function reasonCodes(
1490
+ diagnostics: readonly KnowledgeBaseEvaluationDiagnosticV2[],
1491
+ applicable: boolean,
1492
+ status: ValidatedLegacyResult["status"],
1493
+ ): readonly string[] {
1494
+ return Object.freeze([
1495
+ ...new Set([
1496
+ ...diagnostics.map(({ code }) => code),
1497
+ ...(!applicable ? ["missing-input"] : []),
1498
+ ...(applicable && status === "degraded" && diagnostics.length === 0 ? ["degraded"] : []),
1499
+ ...(applicable && status === "unavailable" && diagnostics.length === 0 ? ["unavailable"] : []),
1500
+ ]),
1501
+ ].toSorted());
1502
+ }
1503
+
1504
+ function exactKeys(
1505
+ input: Readonly<Record<string, unknown>>,
1506
+ expected: readonly string[],
1507
+ label: string,
1508
+ ): void {
1509
+ const actual = Object.keys(input).toSorted();
1510
+ const canonical = [...expected].toSorted();
1511
+ if (actual.length !== canonical.length || actual.some((key, index) => key !== canonical[index])) {
1512
+ throw new TypeError(`${label} must declare exactly ${canonical.join(", ")}.`);
1513
+ }
1514
+ }
1515
+
1516
+ function accountingInteger(value: unknown, label: string): number {
1517
+ if (!Number.isSafeInteger(value) || (value as number) < 0) {
1518
+ throw new TypeError(`${label} must be a non-negative safe integer.`);
1519
+ }
1520
+ return value as number;
1521
+ }
1522
+
1523
+ function accountingDuration(value: unknown, label: string): number {
1524
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
1525
+ throw new TypeError(`${label} must be a non-negative finite number.`);
1526
+ }
1527
+ return value;
1528
+ }
1529
+
1530
+ function copyEmbeddingAccounting(
1531
+ value: unknown,
1532
+ label: string,
1533
+ ): EvaluationResourceAccountingV2["embedding"] {
1534
+ const input = record(value, label);
1535
+ const optionalKeys = ["inputTokensMeasured", "durationScope"]
1536
+ .filter((key) => Object.hasOwn(input, key));
1537
+ exactKeys(input, ["calls", "durationMs", "inputTokens", ...optionalKeys], label);
1538
+ const calls = accountingInteger(ownData(input, "calls", label), `${label}.calls`);
1539
+ const inputTokens = accountingInteger(
1540
+ ownData(input, "inputTokens", label),
1541
+ `${label}.inputTokens`,
1542
+ );
1543
+ const durationMs = accountingDuration(
1544
+ ownData(input, "durationMs", label),
1545
+ `${label}.durationMs`,
1546
+ );
1547
+ const inputTokensMeasured = ownData(input, "inputTokensMeasured", label);
1548
+ if (Object.hasOwn(input, "inputTokensMeasured") && inputTokensMeasured !== false) {
1549
+ throw new TypeError(`${label}.inputTokensMeasured must be literal false when present.`);
1550
+ }
1551
+ const durationScopeValue = ownData(input, "durationScope", label);
1552
+ if (
1553
+ Object.hasOwn(input, "durationScope")
1554
+ && durationScopeValue !== "embedding-backed-search-upper-bound"
1555
+ ) {
1556
+ throw new TypeError(
1557
+ `${label}.durationScope must be embedding-backed-search-upper-bound when present.`,
1558
+ );
1559
+ }
1560
+ const durationScope: EvaluationResourceAccountingV2["embedding"]["durationScope"] =
1561
+ durationScopeValue === "embedding-backed-search-upper-bound"
1562
+ ? durationScopeValue
1563
+ : undefined;
1564
+ if (calls === 0) {
1565
+ if (
1566
+ inputTokens !== 0
1567
+ || durationMs !== 0
1568
+ || inputTokensMeasured !== undefined
1569
+ || durationScope !== undefined
1570
+ ) throw new TypeError(`${label} zero-call accounting must be the exact unannotated zero record.`);
1571
+ } else if (inputTokensMeasured === false && inputTokens !== 0) {
1572
+ throw new TypeError(`${label} unmeasured input tokens must use zero only as an explicit placeholder.`);
1573
+ }
1574
+ return Object.freeze({
1575
+ calls,
1576
+ inputTokens,
1577
+ ...(inputTokensMeasured === false ? { inputTokensMeasured: false as const } : {}),
1578
+ durationMs,
1579
+ ...(durationScope === undefined ? {} : { durationScope }),
1580
+ });
1581
+ }
1582
+
1583
+ function parseChildAccounting(
1584
+ value: unknown,
1585
+ lane: KnowledgeBaseEvaluationRetrieverId,
1586
+ ): EvaluationResourceAccountingV2 {
1587
+ const input = record(value, `${lane} child accounting`);
1588
+ exactKeys(input, ["cacheBytes", "embedding", "llm", "packedContext", "peakRssBytes"], `${lane} child accounting`);
1589
+ const llm = record(ownData(input, "llm", `${lane} child accounting`), `${lane} child accounting.llm`);
1590
+ exactKeys(llm, ["calls", "inputTokens", "outputTokens"], `${lane} child accounting.llm`);
1591
+ if (
1592
+ ownData(llm, "calls", `${lane} child accounting.llm`) !== 0
1593
+ || ownData(llm, "inputTokens", `${lane} child accounting.llm`) !== 0
1594
+ || ownData(llm, "outputTokens", `${lane} child accounting.llm`) !== 0
1595
+ ) throw new TypeError(`${lane} child accounting requires literal-zero generative LLM counters.`);
1596
+
1597
+ const embeddingCopy = copyEmbeddingAccounting(
1598
+ ownData(input, "embedding", `${lane} child accounting`),
1599
+ `${lane} child accounting.embedding`,
1600
+ );
1601
+ if (
1602
+ lane !== "semantic" && lane !== "hybrid"
1603
+ && (
1604
+ embeddingCopy.calls !== KNOWLEDGE_BASE_EVALUATION_EMBEDDING_NOT_INVOKED_V2.calls
1605
+ || embeddingCopy.inputTokens !== KNOWLEDGE_BASE_EVALUATION_EMBEDDING_NOT_INVOKED_V2.inputTokens
1606
+ || embeddingCopy.durationMs !== KNOWLEDGE_BASE_EVALUATION_EMBEDDING_NOT_INVOKED_V2.durationMs
1607
+ )
1608
+ ) throw new TypeError(`${lane} must use the fixed not-invoked embedding accounting record.`);
1609
+
1610
+ const packedContext = record(
1611
+ ownData(input, "packedContext", `${lane} child accounting`),
1612
+ `${lane} child accounting.packedContext`,
1613
+ );
1614
+ exactKeys(packedContext, ["readerTokens", "utf8Bytes"], `${lane} child accounting.packedContext`);
1615
+ const packedContextCopy = Object.freeze({
1616
+ utf8Bytes: accountingInteger(
1617
+ ownData(packedContext, "utf8Bytes", `${lane} child accounting.packedContext`),
1618
+ `${lane} child accounting.packedContext.utf8Bytes`,
1619
+ ),
1620
+ readerTokens: accountingInteger(
1621
+ ownData(packedContext, "readerTokens", `${lane} child accounting.packedContext`),
1622
+ `${lane} child accounting.packedContext.readerTokens`,
1623
+ ),
1624
+ });
1625
+ if (packedContextCopy.utf8Bytes !== 0 || packedContextCopy.readerTokens !== 0) {
1626
+ throw new TypeError(`${lane} child retrieval may not include packed-context accounting.`);
1627
+ }
1628
+ return Object.freeze({
1629
+ llm: Object.freeze({ calls: 0, inputTokens: 0, outputTokens: 0 }),
1630
+ embedding: embeddingCopy,
1631
+ packedContext: packedContextCopy,
1632
+ peakRssBytes: accountingInteger(
1633
+ ownData(input, "peakRssBytes", `${lane} child accounting`),
1634
+ `${lane} child accounting.peakRssBytes`,
1635
+ ),
1636
+ cacheBytes: accountingInteger(
1637
+ ownData(input, "cacheBytes", `${lane} child accounting`),
1638
+ `${lane} child accounting.cacheBytes`,
1639
+ ),
1640
+ });
1641
+ }
1642
+
1643
+ async function childAccounting(
1644
+ provider: KnowledgeBaseEvaluationAccountingProviderV2,
1645
+ lane: KnowledgeBaseEvaluationRetrieverId,
1646
+ result: ValidatedLegacyResult,
1647
+ ): Promise<EvaluationResourceAccountingV2> {
1648
+ if (typeof provider !== "function") {
1649
+ throw new TypeError("Knowledge-base evaluation v2 requires a per-lane accounting provider.");
1650
+ }
1651
+ return parseChildAccounting(await provider(Object.freeze({
1652
+ lane,
1653
+ status: result.status,
1654
+ timings: result.timings,
1655
+ resources: result.resources,
1656
+ })), lane);
1657
+ }
1658
+
1659
+ function aggregateChildAccounting(
1660
+ values: readonly EvaluationResourceAccountingV2[],
1661
+ ): EvaluationResourceAccountingV2 {
1662
+ const safeSum = (numbers: readonly number[], label: string): number => {
1663
+ const value = numbers.reduce((total, candidate) => total + candidate, 0);
1664
+ if (!Number.isSafeInteger(value)) throw new TypeError(`${label} exceeds the safe integer bound.`);
1665
+ return value;
1666
+ };
1667
+ const inputTokensMeasured = values.some(({ embedding }) => embedding.inputTokensMeasured === false)
1668
+ ? false as const
1669
+ : undefined;
1670
+ const durationScope = values.some(
1671
+ ({ embedding }) => embedding.durationScope === "embedding-backed-search-upper-bound",
1672
+ ) ? "embedding-backed-search-upper-bound" as const : undefined;
1673
+ const durationMs = values.reduce((total, { embedding }) => total + embedding.durationMs, 0);
1674
+ if (!Number.isFinite(durationMs)) throw new TypeError("embedding duration exceeds the finite bound.");
1675
+ const cacheValues = new Set(values.map(({ cacheBytes }) => cacheBytes));
1676
+ if (cacheValues.size > 1) {
1677
+ throw new TypeError("Closure lanes must report one identical shared-cache byte count.");
1678
+ }
1679
+ return Object.freeze({
1680
+ llm: Object.freeze({ calls: 0, inputTokens: 0, outputTokens: 0 }),
1681
+ embedding: Object.freeze({
1682
+ calls: safeSum(values.map(({ embedding }) => embedding.calls), "embedding calls"),
1683
+ inputTokens: inputTokensMeasured === false
1684
+ ? 0
1685
+ : safeSum(values.map(({ embedding }) => embedding.inputTokens), "embedding input tokens"),
1686
+ ...(inputTokensMeasured === false ? { inputTokensMeasured } : {}),
1687
+ durationMs,
1688
+ ...(durationScope === undefined ? {} : { durationScope }),
1689
+ }),
1690
+ packedContext: Object.freeze({ utf8Bytes: 0, readerTokens: 0 }),
1691
+ peakRssBytes: Math.max(0, ...values.map(({ peakRssBytes }) => peakRssBytes)),
1692
+ cacheBytes: values[0]?.cacheBytes ?? 0,
1693
+ });
1694
+ }
1695
+
1696
+ function evaluationAccountingFromClosure(
1697
+ value: ExistingLaneClosureAccounting,
1698
+ ): EvaluationResourceAccountingV2 {
1699
+ return Object.freeze({
1700
+ llm: Object.freeze({ calls: 0, inputTokens: 0, outputTokens: 0 }),
1701
+ embedding: Object.freeze({
1702
+ calls: value.embedding.calls,
1703
+ inputTokens: value.embedding.inputTokens,
1704
+ ...(value.embedding.inputTokensMeasured === false
1705
+ ? { inputTokensMeasured: false as const }
1706
+ : {}),
1707
+ durationMs: value.embedding.durationMs,
1708
+ ...(value.embedding.durationScope === undefined
1709
+ ? {}
1710
+ : { durationScope: value.embedding.durationScope }),
1711
+ }),
1712
+ packedContext: Object.freeze({
1713
+ utf8Bytes: value.packedContext.utf8Bytes,
1714
+ readerTokens: value.packedContext.readerTokens,
1715
+ }),
1716
+ peakRssBytes: value.peakRssBytes,
1717
+ cacheBytes: value.cacheBytes,
1718
+ });
1719
+ }
1720
+
1721
+ function accountingKey(value: EvaluationResourceAccountingV2): string {
1722
+ return JSON.stringify([
1723
+ value.llm.calls,
1724
+ value.llm.inputTokens,
1725
+ value.llm.outputTokens,
1726
+ value.embedding.calls,
1727
+ value.embedding.inputTokens,
1728
+ value.embedding.inputTokensMeasured,
1729
+ value.embedding.durationMs,
1730
+ value.embedding.durationScope,
1731
+ value.packedContext.utf8Bytes,
1732
+ value.packedContext.readerTokens,
1733
+ value.peakRssBytes,
1734
+ value.cacheBytes,
1735
+ ]);
1736
+ }
1737
+
1738
+ function assertClosureAccountingMatchesInvocations(
1739
+ closure: EvaluationResourceAccountingV2,
1740
+ invoked: EvaluationResourceAccountingV2,
1741
+ ): void {
1742
+ if (accountingKey(closure) !== accountingKey(invoked)) {
1743
+ throw new TypeError("Closure aggregate accounting does not match its invoked lane accounting.");
1744
+ }
1745
+ }
1746
+
1747
+ function singleLaneResult(options: Readonly<{
1748
+ readonly descriptor: EvaluationRetrieverDescriptorV2;
1749
+ readonly lane: KnowledgeBaseEvaluationRetrieverId;
1750
+ readonly applicable: boolean;
1751
+ readonly legacy: ValidatedLegacyResult;
1752
+ readonly bindings: EvidenceBindings;
1753
+ readonly accounting: EvaluationResourceAccountingV2;
1754
+ readonly elapsedMs: number;
1755
+ }>): KnowledgeBaseEvaluationRetrieverResultV2 {
1756
+ const rows = options.legacy.hits.map((hit) => Object.freeze({
1757
+ hit,
1758
+ evidence: resolveHitEvidence(hit, options.bindings, options.lane),
1759
+ }));
1760
+ const resolved = rows.filter((row): row is typeof row & Readonly<{
1761
+ readonly evidence: readonly BoundEvidenceUnit[];
1762
+ }> => row.evidence !== undefined);
1763
+ const missingProvenanceCount = rows.length - resolved.length;
1764
+ const status = missingProvenanceCount > 0 && options.legacy.status === "ready"
1765
+ ? "degraded" as const
1766
+ : options.legacy.status;
1767
+ const diagnostics = Object.freeze([
1768
+ ...options.legacy.diagnostics,
1769
+ ...(missingProvenanceCount === 0
1770
+ ? []
1771
+ : [Object.freeze({
1772
+ code: "missing-provenance",
1773
+ lane: options.lane,
1774
+ status: "degraded" as const,
1775
+ message: `${missingProvenanceCount} ${options.lane} hit(s) lacked a lane-associated frozen source slice.`,
1776
+ })]),
1777
+ ]);
1778
+ const candidates = Object.freeze(resolved.map(({ hit, evidence }, index): EvaluationRankedCandidateV2 =>
1779
+ Object.freeze({
1780
+ documentId: hit.documentId,
1781
+ evidenceUnitIds: Object.freeze(evidence.map(({ evidenceUnitId }) => evidenceUnitId)),
1782
+ rank: index + 1,
1783
+ ...(hit.score === undefined ? {} : { score: hit.score }),
1784
+ provenance: Object.freeze(evidence.map(({ locator }) => locator)),
1785
+ })));
1786
+ const laneOutcome: EvaluationLaneOutcomeV2 = Object.freeze({
1787
+ laneId: options.lane,
1788
+ applicability: options.applicable ? "applied" : "skipped",
1789
+ status,
1790
+ reasonCodes: reasonCodes(diagnostics, options.applicable, status),
1791
+ rawRanking: options.applicable
1792
+ ? Object.freeze(rows.map(({ hit, evidence }): EvaluationRankedCandidateV2 => Object.freeze({
1793
+ documentId: hit.documentId,
1794
+ evidenceUnitIds: Object.freeze(evidence?.map(({ evidenceUnitId }) => evidenceUnitId) ?? []),
1795
+ rank: hit.rank,
1796
+ ...(hit.score === undefined ? {} : { score: hit.score }),
1797
+ provenance: Object.freeze(evidence?.map(({ locator }) => locator) ?? []),
1798
+ })))
1799
+ : Object.freeze([]),
1800
+ });
1801
+ if (!options.applicable && options.legacy.hits.length > 0) {
1802
+ throw new TypeError(`Legacy ${options.lane} lane returned hits without executable input.`);
1803
+ }
1804
+ const trace: EvaluationRetrieverTraceV2 = Object.freeze({
1805
+ laneOutcomes: Object.freeze([laneOutcome]),
1806
+ candidateDecisions: Object.freeze(rows.map(({ hit, evidence }): EvaluationCandidateDecisionV2 =>
1807
+ Object.freeze({
1808
+ documentId: hit.documentId,
1809
+ evidenceUnitIds: Object.freeze(evidence?.map(({ evidenceUnitId }) => evidenceUnitId) ?? []),
1810
+ laneId: options.lane,
1811
+ sourceRank: hit.rank,
1812
+ disposition: evidence === undefined ? "excluded" : "accepted",
1813
+ reasonCodes: Object.freeze([
1814
+ evidence === undefined ? "missing-provenance" as const : "primary" as const,
1815
+ ]),
1816
+ provenance: Object.freeze(evidence?.map(({ locator }) => locator) ?? []),
1817
+ ...(evidence === undefined
1818
+ ? {}
1819
+ : { outputRank: resolved.findIndex((candidate) => candidate.hit === hit) + 1 }),
1820
+ }))),
1821
+ });
1822
+ const evidenceUnits = Object.freeze([...new Map(resolved.flatMap(({ evidence }) =>
1823
+ evidence.map((candidate) => [candidate.evidenceUnitId, candidate] as const))).values()]
1824
+ .map(publicEvidenceUnit));
1825
+ return Object.freeze({
1826
+ retrieverId: options.descriptor.id,
1827
+ status,
1828
+ candidates,
1829
+ trace,
1830
+ diagnostics,
1831
+ rawEvidence: Object.freeze(rows.map(({ hit, evidence }) => Object.freeze({
1832
+ laneId: options.lane,
1833
+ documentId: hit.documentId,
1834
+ rank: hit.rank,
1835
+ ...(hit.evidence === undefined ? {} : { evidence: hit.evidence }),
1836
+ ...(evidence === undefined
1837
+ ? {}
1838
+ : { provenance: Object.freeze(evidence.map(publicEvidenceUnit)) }),
1839
+ }))),
1840
+ evidenceUnits,
1841
+ timings: options.legacy.timings,
1842
+ rawResources: options.legacy.resources,
1843
+ resources: options.accounting,
1844
+ elapsedMs: options.elapsedMs,
1845
+ });
1846
+ }
1847
+
1848
+ function closureHit(
1849
+ hit: ValidatedLegacyHit,
1850
+ bindings: EvidenceBindings,
1851
+ lane: KnowledgeBaseEvaluationRetrieverId,
1852
+ ): ExistingLaneClosureHit {
1853
+ const evidence = resolveHitEvidence(hit, bindings, lane);
1854
+ return Object.freeze({
1855
+ documentId: hit.documentId,
1856
+ canonicalDocumentId: hit.documentId.normalize("NFC"),
1857
+ rank: hit.rank,
1858
+ ...(hit.score === undefined ? {} : { score: hit.score }),
1859
+ evidenceUnits: Object.freeze(evidence === undefined
1860
+ ? []
1861
+ : evidence.map((candidate) => Object.freeze({
1862
+ id: candidate.evidenceUnitId,
1863
+ locator: closureEvidenceLocator(candidate),
1864
+ }))),
1865
+ ...(hit.evidence === undefined ? {} : { evidence: hit.evidence }),
1866
+ });
1867
+ }
1868
+
1869
+ function closureDiagnostic(
1870
+ diagnostic: KnowledgeBaseEvaluationDiagnosticV2,
1871
+ ): ExistingLaneClosureDiagnostic {
1872
+ return Object.freeze({
1873
+ code: diagnostic.code,
1874
+ status: diagnostic.status,
1875
+ ...(diagnostic.message === undefined ? {} : { message: diagnostic.message }),
1876
+ details: Object.freeze({ lane: diagnostic.lane }),
1877
+ });
1878
+ }
1879
+
1880
+ function closureBackend<Input>(options: Readonly<{
1881
+ readonly lane: KnowledgeBaseEvaluationRetrieverId;
1882
+ readonly retriever: EvaluationRetriever;
1883
+ readonly corpus: RetrievalEvaluationCorpusV2["frozen"];
1884
+ readonly bindings: EvidenceBindings;
1885
+ readonly accounting: KnowledgeBaseEvaluationAccountingProviderV2;
1886
+ readonly recordAccounting: (
1887
+ lane: KnowledgeBaseEvaluationRetrieverId,
1888
+ accounting: EvaluationResourceAccountingV2,
1889
+ ) => void;
1890
+ readonly toInputs: (input: Input) => Readonly<Record<string, unknown>>;
1891
+ }>): ExistingLaneClosureBackend<Input> {
1892
+ return Object.freeze({
1893
+ retrieve: async ({ input, limit, signal }): Promise<ExistingLaneClosureLaneResult> => {
1894
+ throwIfAborted(signal);
1895
+ const raw = await options.retriever.retrieve({
1896
+ corpus: options.corpus,
1897
+ query: legacyQueryBridge(options.toInputs(input)),
1898
+ limit,
1899
+ signal,
1900
+ });
1901
+ throwIfAborted(signal);
1902
+ const result = validateLegacyResult(raw, options.lane, limit);
1903
+ const accounting = await childAccounting(options.accounting, options.lane, result);
1904
+ options.recordAccounting(options.lane, accounting);
1905
+ return Object.freeze({
1906
+ status: result.status,
1907
+ hits: Object.freeze(result.hits.map((hit) =>
1908
+ closureHit(hit, options.bindings, options.lane))),
1909
+ diagnostics: Object.freeze(result.diagnostics.map(closureDiagnostic)),
1910
+ timings: result.timings,
1911
+ resources: result.resources,
1912
+ accounting,
1913
+ });
1914
+ },
1915
+ });
1916
+ }
1917
+
1918
+ function closureBackends(
1919
+ retrievers: LegacyRetrieverBindings,
1920
+ corpus: RetrievalEvaluationCorpusV2["frozen"],
1921
+ bindings: EvidenceBindings,
1922
+ accounting: KnowledgeBaseEvaluationAccountingProviderV2,
1923
+ recordAccounting: (
1924
+ lane: KnowledgeBaseEvaluationRetrieverId,
1925
+ accounting: EvaluationResourceAccountingV2,
1926
+ ) => void,
1927
+ ): ExistingLaneClosureBackends {
1928
+ return Object.freeze({
1929
+ hybrid: closureBackend<ExistingLaneClosureHybridInput>({
1930
+ lane: "hybrid",
1931
+ retriever: retrievers.hybrid,
1932
+ corpus,
1933
+ bindings,
1934
+ accounting,
1935
+ recordAccounting,
1936
+ toInputs: (input) => Object.freeze({ text: input.text }),
1937
+ }),
1938
+ metadata: closureBackend<ExistingLaneClosureMetadataInput>({
1939
+ lane: "metadata",
1940
+ retriever: retrievers.metadata,
1941
+ corpus,
1942
+ bindings,
1943
+ accounting,
1944
+ recordAccounting,
1945
+ toInputs: (input) => Object.freeze({ metadata: input }),
1946
+ }),
1947
+ graph: closureBackend<ExistingLaneClosureGraphInput>({
1948
+ lane: "graph",
1949
+ retriever: retrievers.graph,
1950
+ corpus,
1951
+ bindings,
1952
+ accounting,
1953
+ recordAccounting,
1954
+ toInputs: (input) => Object.freeze({ graph: input }),
1955
+ }),
1956
+ pathContext: closureBackend<ExistingLaneClosurePathContextInput>({
1957
+ lane: "path-context",
1958
+ retriever: retrievers["path-context"],
1959
+ corpus,
1960
+ bindings,
1961
+ accounting,
1962
+ recordAccounting,
1963
+ toInputs: (input) => Object.freeze({ context: input }),
1964
+ }),
1965
+ git: closureBackend<ExistingLaneClosureGitInput>({
1966
+ lane: "git",
1967
+ retriever: retrievers.git,
1968
+ corpus,
1969
+ bindings,
1970
+ accounting,
1971
+ recordAccounting,
1972
+ toInputs: (input) => Object.freeze({ history: input }),
1973
+ }),
1974
+ });
1975
+ }
1976
+
1977
+ function closureInputs(
1978
+ inputs: RetrievalEvaluationCorpusV2["queries"][number]["inputs"],
1979
+ ): ExistingLaneClosureExecutableInputs {
1980
+ return Object.freeze({
1981
+ hybrid: Object.freeze({ text: inputs.text }),
1982
+ ...(inputs.metadata === undefined ? {} : { metadata: inputs.metadata }),
1983
+ ...(inputs.graph === undefined ? {} : { graph: inputs.graph }),
1984
+ ...(inputs.context === undefined ? {} : { pathContext: inputs.context }),
1985
+ ...(inputs.history === undefined ? {} : { history: inputs.history }),
1986
+ });
1987
+ }
1988
+
1989
+ function mapClosureLaneOutcome(
1990
+ lane: ExistingLaneClosureResult["trace"]["lanes"][number],
1991
+ bindings: EvidenceBindings,
1992
+ ): EvaluationLaneOutcomeV2 {
1993
+ const rawRanking = Object.freeze(lane.candidates.map((candidate): EvaluationRankedCandidateV2 => {
1994
+ const provenance = bindingsFromClosureProvenance(candidate.provenance, bindings);
1995
+ return Object.freeze({
1996
+ documentId: candidate.canonicalDocumentId,
1997
+ evidenceUnitIds: Object.freeze(provenance.map(({ evidenceUnitId }) => evidenceUnitId)),
1998
+ rank: candidate.sourceRank,
1999
+ provenance: Object.freeze(provenance.map(({ locator }) => locator)),
2000
+ });
2001
+ }));
2002
+ if (lane.invocation === "invoked") {
2003
+ if (rawRanking.some(({ rank }, index) => rank !== index + 1)) {
2004
+ throw new TypeError(`Closure ${lane.lane} did not preserve contiguous source ranks.`);
2005
+ }
2006
+ if (new Set(rawRanking.map(({ documentId }) => documentId)).size !== rawRanking.length) {
2007
+ throw new TypeError(`Closure ${lane.lane} raw ranking repeats a canonical document.`);
2008
+ }
2009
+ }
2010
+ const status = lane.invocation === "disabled"
2011
+ ? "ready"
2012
+ : lane.invocation === "skipped-missing-input"
2013
+ ? "unavailable"
2014
+ : lane.status as "degraded" | "ready" | "unavailable";
2015
+ const codes = [
2016
+ ...lane.diagnostics.map(({ code }) => canonicalId(code, `closure ${lane.lane} diagnostic code`)),
2017
+ ...(lane.invocation === "disabled" ? ["disabled"] : []),
2018
+ ...(lane.invocation === "skipped-missing-input" ? ["missing-input"] : []),
2019
+ ];
2020
+ return Object.freeze({
2021
+ laneId: lane.lane,
2022
+ applicability: lane.invocation === "invoked" ? "applied" : "skipped",
2023
+ status,
2024
+ reasonCodes: Object.freeze([...new Set(codes)].toSorted()),
2025
+ rawRanking: lane.invocation === "invoked" && status !== "unavailable"
2026
+ ? rawRanking
2027
+ : Object.freeze([]),
2028
+ });
2029
+ }
2030
+
2031
+ function mapClosureResult(options: Readonly<{
2032
+ readonly descriptor: EvaluationRetrieverDescriptorV2;
2033
+ readonly result: ExistingLaneClosureResult;
2034
+ readonly bindings: EvidenceBindings;
2035
+ readonly accounting: EvaluationResourceAccountingV2;
2036
+ readonly elapsedMs: number;
2037
+ }>): KnowledgeBaseEvaluationRetrieverResultV2 {
2038
+ const laneOrder = new Map(options.descriptor.lanes.map((lane, index) => [lane, index]));
2039
+ const outcomesByLane = new Map(options.result.trace.lanes.map((lane) => [lane.lane, lane]));
2040
+ const laneOutcomes = Object.freeze(options.descriptor.lanes.map((lane) => {
2041
+ const outcome = outcomesByLane.get(lane as ExistingLaneClosureLaneId);
2042
+ if (outcome === undefined) throw new TypeError(`Closure trace is missing locked lane ${lane}.`);
2043
+ return mapClosureLaneOutcome(outcome, options.bindings);
2044
+ }));
2045
+ const candidateDecisions = Object.freeze(options.result.trace.lanes
2046
+ .flatMap((lane) => lane.candidates.map((candidate): EvaluationCandidateDecisionV2 => {
2047
+ const provenance = bindingsFromClosureProvenance(candidate.provenance, options.bindings);
2048
+ return Object.freeze({
2049
+ documentId: candidate.canonicalDocumentId,
2050
+ evidenceUnitIds: Object.freeze(provenance.map(({ evidenceUnitId }) => evidenceUnitId)),
2051
+ laneId: candidate.lane,
2052
+ sourceRank: candidate.sourceRank,
2053
+ disposition: candidate.decision,
2054
+ reasonCodes: Object.freeze([candidate.reasonCode as EvaluationCandidateReasonV2]),
2055
+ ...(candidate.decision === "accepted" && candidate.outputRank !== undefined
2056
+ ? { outputRank: candidate.outputRank }
2057
+ : {}),
2058
+ provenance: Object.freeze(provenance.map(({ locator }) => locator)),
2059
+ });
2060
+ }))
2061
+ .toSorted((left, right) =>
2062
+ (laneOrder.get(left.laneId) ?? Number.MAX_SAFE_INTEGER)
2063
+ - (laneOrder.get(right.laneId) ?? Number.MAX_SAFE_INTEGER)
2064
+ || left.sourceRank - right.sourceRank
2065
+ || left.documentId.localeCompare(right.documentId)));
2066
+ const candidates = Object.freeze(options.result.hits.map((hit, index): EvaluationRankedCandidateV2 => {
2067
+ const document = options.result.trace.documents[index];
2068
+ const provenance = document === undefined
2069
+ ? Object.freeze([])
2070
+ : uniqueBindingsFromClosureProvenance(
2071
+ document.sources.flatMap(({ provenance }) => provenance),
2072
+ options.bindings,
2073
+ );
2074
+ if (provenance.length === 0) {
2075
+ throw new TypeError(`Accepted closure candidate ${hit.canonicalDocumentId} lacks exact unit provenance.`);
2076
+ }
2077
+ return Object.freeze({
2078
+ documentId: hit.canonicalDocumentId,
2079
+ evidenceUnitIds: Object.freeze(provenance.map(({ evidenceUnitId }) => evidenceUnitId)),
2080
+ rank: index + 1,
2081
+ ...(hit.score === undefined ? {} : { score: hit.score }),
2082
+ provenance: Object.freeze(provenance.map(({ locator }) => locator)),
2083
+ });
2084
+ }));
2085
+ const diagnostics = Object.freeze(options.result.trace.lanes.flatMap((lane) =>
2086
+ lane.diagnostics.map((diagnostic) => Object.freeze({
2087
+ code: diagnostic.code,
2088
+ lane: lane.lane,
2089
+ status: diagnostic.status,
2090
+ ...(diagnostic.message === undefined ? {} : { message: diagnostic.message }),
2091
+ }))));
2092
+ const evidenceUnits = Object.freeze([...new Map(options.result.trace.lanes.flatMap((lane) =>
2093
+ lane.candidates.flatMap((candidate) => bindingsFromClosureProvenance(
2094
+ candidate.provenance,
2095
+ options.bindings,
2096
+ ).map((evidence) => [evidence.evidenceUnitId, evidence] as const)))).values()]
2097
+ .map(publicEvidenceUnit));
2098
+ const rawEvidence = Object.freeze(laneOutcomes.flatMap((outcome) => {
2099
+ const lane = outcomesByLane.get(outcome.laneId as ExistingLaneClosureLaneId);
2100
+ if (lane === undefined) {
2101
+ throw new TypeError(`Closure trace is missing locked lane ${outcome.laneId}.`);
2102
+ }
2103
+ return outcome.rawRanking.map((ranking) => {
2104
+ const matching = lane.candidates.filter((candidate) =>
2105
+ candidate.canonicalDocumentId === ranking.documentId
2106
+ && candidate.sourceRank === ranking.rank);
2107
+ if (matching.length !== 1) {
2108
+ throw new TypeError(
2109
+ `Closure raw evidence cannot join ${outcome.laneId} rank ${ranking.rank} exactly once.`,
2110
+ );
2111
+ }
2112
+ const candidate = matching[0]!;
2113
+ const evidence = bindingsFromClosureProvenance(candidate.provenance, options.bindings);
2114
+ return Object.freeze({
2115
+ laneId: outcome.laneId,
2116
+ documentId: ranking.documentId,
2117
+ rank: ranking.rank,
2118
+ ...(candidate.evidence === undefined ? {} : { evidence: candidate.evidence }),
2119
+ ...(evidence.length === 0
2120
+ ? {}
2121
+ : { provenance: Object.freeze(evidence.map(publicEvidenceUnit)) }),
2122
+ });
2123
+ });
2124
+ }));
2125
+ return Object.freeze({
2126
+ retrieverId: options.descriptor.id,
2127
+ status: options.result.status,
2128
+ candidates,
2129
+ trace: Object.freeze({ laneOutcomes, candidateDecisions }),
2130
+ diagnostics,
2131
+ rawEvidence,
2132
+ evidenceUnits,
2133
+ timings: options.result.timings,
2134
+ rawResources: options.result.resources,
2135
+ resources: options.accounting,
2136
+ elapsedMs: options.elapsedMs,
2137
+ });
2138
+ }
2139
+
2140
+ function throwIfAborted(signal: AbortSignal): void {
2141
+ if (!signal.aborted) return;
2142
+ if (signal.reason instanceof Error) throw signal.reason;
2143
+ throw new Error("Knowledge-base evaluation v2 retrieval was aborted.");
2144
+ }
2145
+
2146
+ function elapsed(startedAt: number, now: () => number): number {
2147
+ const duration = now() - startedAt;
2148
+ return Number.isFinite(duration) && duration >= 0 ? duration : 0;
2149
+ }
2150
+
2151
+ function validateLaneDescriptor(
2152
+ lane: KnowledgeBaseEvaluationRetrieverId,
2153
+ descriptor: EvaluationRetrieverDescriptorV2,
2154
+ ): number {
2155
+ if (descriptor.lanes.length !== 1 || descriptor.lanes[0] !== lane) {
2156
+ throw new TypeError(`Descriptor ${descriptor.id} must expose only ${lane} lane.`);
2157
+ }
2158
+ const retrieveLimit = positiveLimit(
2159
+ descriptor.configuration["retrieve-limit"],
2160
+ `descriptor ${descriptor.id} retrieve-limit`,
2161
+ );
2162
+ const expected = laneConfiguration(lane, retrieveLimit);
2163
+ if (JSON.stringify(descriptor.configuration) !== JSON.stringify(expected)) {
2164
+ throw new TypeError(`Descriptor ${descriptor.id} configuration does not match the executable lane contract.`);
2165
+ }
2166
+ return retrieveLimit;
2167
+ }
2168
+
2169
+ function validateClosureDescriptor(pair: KnowledgeBaseExistingLaneClosureDescriptorV2): void {
2170
+ const frozen = freezeExistingLaneClosureVariant(pair.variant);
2171
+ if (JSON.stringify(pair.descriptor.configuration) !== JSON.stringify(closureConfiguration(frozen))) {
2172
+ throw new TypeError(`Closure descriptor ${pair.descriptor.id} does not bind its complete variant.`);
2173
+ }
2174
+ if (JSON.stringify(pair.descriptor.lanes) !== JSON.stringify(closureDescriptorLanes(frozen))) {
2175
+ throw new TypeError(`Closure descriptor ${pair.descriptor.id} lanes do not match its variant.`);
2176
+ }
2177
+ }
2178
+
2179
+ function implementationArtifactsByRetrieverId(
2180
+ artifacts: readonly VerifiedEvaluationImplementationArtifactV2[],
2181
+ descriptors: readonly EvaluationRetrieverDescriptorV2[],
2182
+ ): ReadonlyMap<string, VerifiedEvaluationImplementationArtifactV2> {
2183
+ const artifactArrayIsValid: boolean = Array.isArray(artifacts);
2184
+ if (!artifactArrayIsValid) {
2185
+ throw new TypeError("implementationArtifacts must be an exact one-per-descriptor array.");
2186
+ }
2187
+ const expectedIds = new Set(descriptors.map(({ id }) => id));
2188
+ const byRetrieverId = new Map<string, VerifiedEvaluationImplementationArtifactV2>();
2189
+ for (const artifact of artifacts) {
2190
+ const retrieverId = artifact?.retrieverId;
2191
+ if (typeof retrieverId !== "string") {
2192
+ throw new TypeError("implementationArtifacts contains an invalid artifact entry.");
2193
+ }
2194
+ if (byRetrieverId.has(retrieverId)) {
2195
+ throw new TypeError(`Implementation artifact for retriever ${retrieverId} is duplicated.`);
2196
+ }
2197
+ if (!expectedIds.has(retrieverId)) {
2198
+ throw new TypeError(`Implementation artifact for retriever ${retrieverId} is extra.`);
2199
+ }
2200
+ byRetrieverId.set(retrieverId, artifact);
2201
+ }
2202
+ for (const descriptor of descriptors) {
2203
+ if (!byRetrieverId.has(descriptor.id)) {
2204
+ throw new TypeError(`Implementation artifact for retriever ${descriptor.id} is missing.`);
2205
+ }
2206
+ }
2207
+ return byRetrieverId;
2208
+ }
2209
+
2210
+ function createSingleLaneExecutionRetriever(options: Readonly<{
2211
+ readonly contract: KnowledgeBaseEvaluationExecutionContractV2;
2212
+ readonly descriptorId: string;
2213
+ readonly lane: KnowledgeBaseEvaluationRetrieverId;
2214
+ readonly accounting: KnowledgeBaseEvaluationAccountingProviderV2;
2215
+ readonly now: () => number;
2216
+ }>): KnowledgeBaseEvaluationRetrieverV2 {
2217
+ const descriptor = options.contract.descriptorsById[options.descriptorId];
2218
+ if (descriptor === undefined) {
2219
+ throw new TypeError(`Execution contract is missing descriptor ${options.descriptorId}.`);
2220
+ }
2221
+ const legacy = options.contract.legacyRetrievers[options.lane];
2222
+ return Object.freeze({
2223
+ descriptor,
2224
+ retrieve: async (request): Promise<KnowledgeBaseEvaluationRetrieverResultV2> => {
2225
+ assertFrozenSnapshot(options.contract.frozen, request.corpus);
2226
+ assertRequestLimit(descriptor, request.limit);
2227
+ throwIfAborted(request.signal);
2228
+ const inputs = executionInputs(request);
2229
+ const applicable = laneIsApplicable(options.lane, inputs);
2230
+ if (!applicable) {
2231
+ return singleLaneResult({
2232
+ descriptor,
2233
+ lane: options.lane,
2234
+ applicable: false,
2235
+ legacy: Object.freeze({
2236
+ status: "unavailable",
2237
+ hits: Object.freeze([]),
2238
+ diagnostics: Object.freeze([]),
2239
+ timings: Object.freeze({}),
2240
+ resources: Object.freeze({}),
2241
+ }),
2242
+ bindings: options.contract.evidenceBindings,
2243
+ accounting: aggregateChildAccounting([]),
2244
+ elapsedMs: 0,
2245
+ });
2246
+ }
2247
+ const startedAt = options.now();
2248
+ const raw = await legacy.retrieve({
2249
+ corpus: options.contract.frozen,
2250
+ query: legacyQueryBridge(inputForLegacyLane(options.lane, inputs)),
2251
+ limit: request.limit,
2252
+ signal: request.signal,
2253
+ });
2254
+ throwIfAborted(request.signal);
2255
+ const legacyResult = validateLegacyResult(raw, options.lane, request.limit);
2256
+ const accounting = await childAccounting(options.accounting, options.lane, legacyResult);
2257
+ throwIfAborted(request.signal);
2258
+ return singleLaneResult({
2259
+ descriptor,
2260
+ lane: options.lane,
2261
+ applicable,
2262
+ legacy: legacyResult,
2263
+ bindings: options.contract.evidenceBindings,
2264
+ accounting,
2265
+ elapsedMs: elapsed(startedAt, options.now),
2266
+ });
2267
+ },
2268
+ });
2269
+ }
2270
+
2271
+ function createClosureExecutionRetriever(options: Readonly<{
2272
+ readonly contract: KnowledgeBaseEvaluationExecutionContractV2;
2273
+ readonly descriptorId: string;
2274
+ readonly variant: ExistingLaneClosureVariant;
2275
+ readonly accounting: KnowledgeBaseEvaluationAccountingProviderV2;
2276
+ readonly now: () => number;
2277
+ }>): KnowledgeBaseEvaluationRetrieverV2 {
2278
+ const descriptor = options.contract.descriptorsById[options.descriptorId];
2279
+ if (descriptor === undefined) {
2280
+ throw new TypeError(`Execution contract is missing descriptor ${options.descriptorId}.`);
2281
+ }
2282
+ const variant = freezeExistingLaneClosureVariant(options.variant);
2283
+ return Object.freeze({
2284
+ descriptor,
2285
+ retrieve: async (request): Promise<KnowledgeBaseEvaluationRetrieverResultV2> => {
2286
+ assertFrozenSnapshot(options.contract.frozen, request.corpus);
2287
+ assertRequestLimit(descriptor, request.limit);
2288
+ throwIfAborted(request.signal);
2289
+ const inputs = executionInputs(request);
2290
+ const startedAt = options.now();
2291
+ const childAccountingByLane = new Map<
2292
+ KnowledgeBaseEvaluationRetrieverId,
2293
+ EvaluationResourceAccountingV2
2294
+ >();
2295
+ const backends = closureBackends(
2296
+ options.contract.legacyRetrievers,
2297
+ options.contract.frozen,
2298
+ options.contract.evidenceBindings,
2299
+ options.accounting,
2300
+ (lane, accounting) => {
2301
+ if (childAccountingByLane.has(lane)) {
2302
+ throw new TypeError(`Closure invoked ${lane} accounting more than once.`);
2303
+ }
2304
+ childAccountingByLane.set(lane, accounting);
2305
+ },
2306
+ );
2307
+ const result = await runExistingLaneClosure({
2308
+ variant,
2309
+ query: Object.freeze({ inputs: closureInputs(inputs) }),
2310
+ backends,
2311
+ evidenceRegistry: options.contract.closureEvidenceRegistry,
2312
+ signal: request.signal,
2313
+ });
2314
+ throwIfAborted(request.signal);
2315
+ const invokedAccounting = aggregateChildAccounting([...childAccountingByLane.values()]);
2316
+ const closureAccounting = evaluationAccountingFromClosure(result.accounting);
2317
+ assertClosureAccountingMatchesInvocations(closureAccounting, invokedAccounting);
2318
+ return mapClosureResult({
2319
+ descriptor,
2320
+ result,
2321
+ bindings: options.contract.evidenceBindings,
2322
+ accounting: closureAccounting,
2323
+ elapsedMs: elapsed(startedAt, options.now),
2324
+ });
2325
+ },
2326
+ });
2327
+ }
2328
+
2329
+ /** Adapt one verified immutable legacy session without changing production search. */
2330
+ export function adaptVerifiedKnowledgeBaseEvaluationV2(
2331
+ options: AdaptVerifiedKnowledgeBaseEvaluationV2Options,
2332
+ ): KnowledgeBaseEvaluationV2 {
2333
+ const clock = options.now ?? performance.now.bind(performance);
2334
+ const accounting = options.accounting;
2335
+ const close = options.evaluation.close;
2336
+ if (typeof accounting !== "function") {
2337
+ throw new TypeError("Knowledge-base evaluation v2 requires a per-lane accounting provider.");
2338
+ }
2339
+ const closureDescriptors = options.closureDescriptors ?? Object.freeze([]);
2340
+ const descriptors: EvaluationRetrieverDescriptorV2[] = [];
2341
+ const laneDescriptorIds = new Map<KnowledgeBaseEvaluationRetrieverId, string>();
2342
+ for (const lane of knowledgeBaseEvaluationRetrieverIds) {
2343
+ const descriptor = options.laneDescriptors[lane];
2344
+ validateLaneDescriptor(lane, descriptor);
2345
+ descriptors.push(descriptor);
2346
+ laneDescriptorIds.set(lane, descriptor.id);
2347
+ }
2348
+ const closureIds = new Set<string>();
2349
+ const lockedClosures: Readonly<{
2350
+ readonly descriptorId: string;
2351
+ readonly variant: ExistingLaneClosureVariant;
2352
+ }>[] = [];
2353
+ for (const pair of closureDescriptors) {
2354
+ validateClosureDescriptor(pair);
2355
+ if (closureIds.has(pair.descriptor.id)) {
2356
+ throw new TypeError(`Closure descriptor ID ${pair.descriptor.id} is repeated.`);
2357
+ }
2358
+ closureIds.add(pair.descriptor.id);
2359
+ descriptors.push(pair.descriptor);
2360
+ lockedClosures.push(Object.freeze({
2361
+ descriptorId: pair.descriptor.id,
2362
+ variant: freezeExistingLaneClosureVariant(pair.variant),
2363
+ }));
2364
+ }
2365
+ if (new Set(descriptors.map(({ id }) => id)).size !== descriptors.length) {
2366
+ throw new TypeError("Knowledge-base evaluation v2 descriptor IDs must be unique.");
2367
+ }
2368
+ const implementationArtifacts = implementationArtifactsByRetrieverId(
2369
+ options.implementationArtifacts,
2370
+ descriptors,
2371
+ );
2372
+ for (const descriptor of descriptors) {
2373
+ const artifact = implementationArtifacts.get(descriptor.id);
2374
+ if (artifact === undefined) {
2375
+ throw new TypeError(`Implementation artifact for retriever ${descriptor.id} is missing.`);
2376
+ }
2377
+ assertEvaluationImplementationArtifactV2(artifact, options.corpus, descriptor);
2378
+ }
2379
+ const evidenceBindings = buildEvidenceBindings(options.evidenceRegistry, options.corpus);
2380
+ const legacyRetrievers = bindLegacyRetrievers(options.evaluation);
2381
+ const contract = createExecutionContract({
2382
+ corpus: options.corpus,
2383
+ descriptors,
2384
+ evidenceBindings,
2385
+ legacyRetrievers,
2386
+ });
2387
+
2388
+ const retrievers: KnowledgeBaseEvaluationRetrieverV2[] = [];
2389
+ for (const lane of knowledgeBaseEvaluationRetrieverIds) {
2390
+ const descriptorId = laneDescriptorIds.get(lane);
2391
+ if (descriptorId === undefined) throw new TypeError(`Execution contract is missing ${lane} lane.`);
2392
+ retrievers.push(createSingleLaneExecutionRetriever({
2393
+ contract,
2394
+ descriptorId,
2395
+ lane,
2396
+ accounting,
2397
+ now: clock,
2398
+ }));
2399
+ }
2400
+
2401
+ for (const closure of lockedClosures) {
2402
+ retrievers.push(createClosureExecutionRetriever({
2403
+ contract,
2404
+ descriptorId: closure.descriptorId,
2405
+ variant: closure.variant,
2406
+ accounting,
2407
+ now: clock,
2408
+ }));
2409
+ }
2410
+ if (new Set(retrievers.map(({ descriptor }) => descriptor.id)).size !== retrievers.length) {
2411
+ throw new TypeError("Knowledge-base evaluation v2 descriptor IDs must be unique.");
2412
+ }
2413
+ const evaluationV2: KnowledgeBaseEvaluationV2 = Object.freeze({
2414
+ retrievers: Object.freeze(retrievers),
2415
+ close,
2416
+ });
2417
+ verifiedKnowledgeBaseEvaluationsV2.set(evaluationV2, Object.freeze({
2418
+ suiteSha256: contract.manifest.corpusSha256,
2419
+ candidateLockSha256: contract.manifest.candidateLockSha256,
2420
+ buildContractSha256: contract.manifest.buildContractSha256,
2421
+ repositoryCommit: contract.frozen.repositoryCommit,
2422
+ vaultTree: contract.frozen.vaultTree,
2423
+ }));
2424
+ return evaluationV2;
2425
+ }
2426
+
2427
+ /** Open the existing verified immutable scan/session, then adapt its lanes to v2. */
2428
+ export async function openKnowledgeBaseEvaluationV2(
2429
+ options: OpenKnowledgeBaseEvaluationV2Options,
2430
+ ): Promise<KnowledgeBaseEvaluationV2> {
2431
+ const {
2432
+ corpus,
2433
+ evidenceRegistry,
2434
+ accounting,
2435
+ laneDescriptors,
2436
+ closureDescriptors,
2437
+ implementationArtifacts,
2438
+ now,
2439
+ openEvaluation = openKnowledgeBaseEvaluation,
2440
+ ...legacyOptions
2441
+ } = options;
2442
+ const evaluation = await openEvaluation({
2443
+ ...legacyOptions,
2444
+ corpus: legacyCorpusBridge(corpus.frozen),
2445
+ ...(now === undefined ? {} : { now }),
2446
+ });
2447
+ try {
2448
+ return adaptVerifiedKnowledgeBaseEvaluationV2({
2449
+ corpus,
2450
+ evidenceRegistry,
2451
+ accounting,
2452
+ evaluation,
2453
+ laneDescriptors,
2454
+ implementationArtifacts,
2455
+ ...(closureDescriptors === undefined ? {} : { closureDescriptors }),
2456
+ ...(now === undefined ? {} : { now }),
2457
+ });
2458
+ } catch (error) {
2459
+ await evaluation.close();
2460
+ throw error;
2461
+ }
2462
+ }
2463
+
2464
+ /** Convert a successful adapter result into the strict repeated-sample schema. */
2465
+ export function createKnowledgeBaseEvaluationRepeatedSampleV2(options: Readonly<{
2466
+ readonly result: KnowledgeBaseEvaluationRetrieverResultV2;
2467
+ readonly profileId: string;
2468
+ readonly queryId?: string;
2469
+ readonly repetition: number;
2470
+ readonly concurrencyBatchIdentity?: string;
2471
+ readonly timings?: Partial<EvaluationRepeatedSampleV2["timings"]>;
2472
+ readonly embedding?: EvaluationResourceAccountingV2["embedding"];
2473
+ readonly packedContext?: EvaluationResourceAccountingV2["packedContext"];
2474
+ readonly packedContextTrace?: NonNullable<EvaluationRepeatedSampleV2["packedContextTrace"]>;
2475
+ readonly peakRssBytes?: number;
2476
+ readonly cacheBytes?: number;
2477
+ }>): EvaluationRepeatedSampleV2 {
2478
+ const finite = (value: number, label: string): number => {
2479
+ if (!Number.isFinite(value) || value < 0) throw new TypeError(`${label} must be non-negative and finite.`);
2480
+ return value;
2481
+ };
2482
+ const integer = (value: number, label: string): number => {
2483
+ if (!Number.isSafeInteger(value) || value < 0) throw new TypeError(`${label} must be a non-negative integer.`);
2484
+ return value;
2485
+ };
2486
+ if (!Number.isSafeInteger(options.repetition) || options.repetition < 1) {
2487
+ throw new TypeError("sample repetition must be a positive integer.");
2488
+ }
2489
+ const concurrencyBatchIdentity = options.concurrencyBatchIdentity === undefined
2490
+ ? undefined
2491
+ : boundedText(
2492
+ options.concurrencyBatchIdentity,
2493
+ "sample concurrencyBatchIdentity",
2494
+ 512,
2495
+ );
2496
+ const timings = Object.freeze({
2497
+ elapsedMs: finite(options.timings?.elapsedMs ?? options.result.elapsedMs, "sample elapsedMs"),
2498
+ indexMs: finite(options.timings?.indexMs ?? 0, "sample indexMs"),
2499
+ updateMs: finite(options.timings?.updateMs ?? 0, "sample updateMs"),
2500
+ queryMs: finite(options.timings?.queryMs ?? options.result.elapsedMs, "sample queryMs"),
2501
+ packingMs: finite(options.timings?.packingMs ?? 0, "sample packingMs"),
2502
+ });
2503
+ const embedding = copyEmbeddingAccounting(
2504
+ options.embedding ?? options.result.resources.embedding,
2505
+ "sample embedding",
2506
+ );
2507
+ const packedContext = options.packedContext ?? options.result.resources.packedContext;
2508
+ const packedContextTrace = options.packedContextTrace === undefined
2509
+ ? undefined
2510
+ : Object.freeze({
2511
+ evidenceUnitIds: Object.freeze(options.packedContextTrace.evidenceUnitIds.map((id, index) =>
2512
+ boundedText(id, `sample packedContextTrace.evidenceUnitIds[${index}]`, 512))),
2513
+ truncated: options.packedContextTrace.truncated,
2514
+ packedBytesSha256: boundedText(
2515
+ options.packedContextTrace.packedBytesSha256,
2516
+ "sample packedContextTrace.packedBytesSha256",
2517
+ 64,
2518
+ ),
2519
+ });
2520
+ return Object.freeze({
2521
+ retrieverId: options.result.retrieverId,
2522
+ profileId: canonicalId(options.profileId, "sample profileId"),
2523
+ ...(options.queryId === undefined
2524
+ ? {}
2525
+ : { queryId: boundedText(options.queryId, "sample queryId", 256) }),
2526
+ repetition: options.repetition,
2527
+ ...(concurrencyBatchIdentity === undefined ? {} : { concurrencyBatchIdentity }),
2528
+ status: options.result.status,
2529
+ timings,
2530
+ resources: Object.freeze({
2531
+ llm: Object.freeze({ calls: 0, inputTokens: 0, outputTokens: 0 }),
2532
+ embedding: Object.freeze({
2533
+ calls: embedding.calls,
2534
+ inputTokens: embedding.inputTokens,
2535
+ ...(embedding.inputTokensMeasured === false
2536
+ ? { inputTokensMeasured: false as const }
2537
+ : {}),
2538
+ durationMs: embedding.durationMs,
2539
+ ...(embedding.durationScope === undefined
2540
+ ? {}
2541
+ : { durationScope: embedding.durationScope }),
2542
+ }),
2543
+ packedContext: Object.freeze({
2544
+ utf8Bytes: integer(packedContext.utf8Bytes, "sample packedContext.utf8Bytes"),
2545
+ readerTokens: integer(packedContext.readerTokens, "sample packedContext.readerTokens"),
2546
+ }),
2547
+ peakRssBytes: integer(
2548
+ options.peakRssBytes ?? options.result.resources.peakRssBytes,
2549
+ "sample peakRssBytes",
2550
+ ),
2551
+ cacheBytes: integer(
2552
+ options.cacheBytes ?? options.result.resources.cacheBytes,
2553
+ "sample cacheBytes",
2554
+ ),
2555
+ }),
2556
+ trace: options.result.trace,
2557
+ rawEvidence: Object.freeze(options.result.rawEvidence.map((row) => Object.freeze({
2558
+ laneId: row.laneId,
2559
+ documentId: row.documentId,
2560
+ rank: row.rank,
2561
+ ...(row.evidence === undefined
2562
+ ? {}
2563
+ : { evidence: immutableEvidenceCopy(row.evidence) }),
2564
+ }))),
2565
+ ...(packedContextTrace === undefined ? {} : { packedContextTrace }),
2566
+ });
2567
+ }