@tangle-network/agent-knowledge 8.0.9 → 10.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/AGENTS.md +14 -2
  2. package/CHANGELOG.md +99 -0
  3. package/README.md +127 -5
  4. package/dist/benchmarks/index.d.ts +1 -1
  5. package/dist/benchmarks/index.js +1 -1
  6. package/dist/{benchmarks-B_07vX0Q.js → benchmarks-B6fCb6AD.js} +2 -2
  7. package/dist/{benchmarks-B_07vX0Q.js.map → benchmarks-B6fCb6AD.js.map} +1 -1
  8. package/dist/cli.js +53 -21
  9. package/dist/cli.js.map +1 -1
  10. package/dist/{index-DypNCZtP.d.ts → index-DZeFm-BP.d.ts} +2 -2
  11. package/dist/{index-DypNCZtP.d.ts.map → index-DZeFm-BP.d.ts.map} +1 -1
  12. package/dist/{index-Ij4giqqj.d.ts → index-eDsIXWyM.d.ts} +3 -3
  13. package/dist/{index-Ij4giqqj.d.ts.map → index-eDsIXWyM.d.ts.map} +1 -1
  14. package/dist/index.d.ts +910 -290
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1009 -382
  17. package/dist/index.js.map +1 -1
  18. package/dist/{inspect-0tmv3xV8.js → inspect-DALsvG10.js} +680 -108
  19. package/dist/inspect-DALsvG10.js.map +1 -0
  20. package/dist/memory/index.d.ts +2 -2
  21. package/dist/memory/index.js +2 -2
  22. package/dist/{memory-BPgPIEhj.js → memory-BRGsy2QN.js} +2 -2
  23. package/dist/{memory-BPgPIEhj.js.map → memory-BRGsy2QN.js.map} +1 -1
  24. package/dist/search-Cw6eYfSd.js +258 -0
  25. package/dist/search-Cw6eYfSd.js.map +1 -0
  26. package/dist/{types-CTT16XnO.d.ts → types-m2QB86fF.d.ts} +17 -3
  27. package/dist/types-m2QB86fF.d.ts.map +1 -0
  28. package/dist/viz/index.d.ts +1 -1
  29. package/docs/architecture.md +1 -0
  30. package/docs/knowledge-use-receipts.md +50 -12
  31. package/package.json +3 -3
  32. package/dist/inspect-0tmv3xV8.js.map +0 -1
  33. package/dist/search-CtVJ0PKX.js +0 -132
  34. package/dist/search-CtVJ0PKX.js.map +0 -1
  35. package/dist/types-CTT16XnO.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { $ as WIKILINK_REGEX, $t as syncDirectory, A as MemoryKbStore, At as mergeTrackedClaims, B as auditKnowledgeCitations, Bt as applyKnowledgeFileTransaction, C as writeSourceRegistry, Ct as claimId, D as KB_EVENTS_PATH, Dt as linkClaimContradictions, E as KB_CLAIM_LEDGER_DIR, Et as emptyClaimLedger, F as assertCurrentRunCitationsResolved, Ft as acquireDurableFileLock, G as resolveRunScopedCitation, Gt as rollbackKnowledgeFileTransaction, H as parseKnowledgeCitationReference, Ht as finishKnowledgeFileTransaction, I as assertKnowledgeCitationAudit, It as inspectPendingKnowledgeMutation, J as initKnowledgeBase, Jt as listRegularFilesWithinRoot, K as resolveRunScopedCitations, Kt as isKernelAnchoredPath, L as assertKnowledgeCitationsResolved, Lt as recoverPendingKnowledgeMutation, M as buildKnowledgeGraph, Mt as researchSourceVersionKey, N as KnowledgeCitationAuditError, Nt as formatFrontmatter, O as KB_INDEX_PATH, Ot as materializeRegisteredClaimEvidence, P as KnowledgeCitationResolutionError, Pt as parseFrontmatter, Q as writeJson, Qt as renameDurable, R as assertRunScopedCitationsResolved, Rt as withKnowledgeMutation, S as sourceRegistryPath, St as claimEvidenceId, T as FileSystemKbStore, Tt as deepQuestionId, U as resolveKnowledgeCitation, Ut as knowledgeFileTransactionPlanHash, V as formatKnowledgeCitationReference, Vt as assertKnowledgeMutationPath, W as resolveKnowledgeCitations, Wt as prepareKnowledgeFileTransaction, X as layoutFor, Xt as readRegularFileWithinRoot, Y as isScaffoldPath, Yt as readRegularFileNoFollow, Z as loadKnowledgePages, Zt as removeDurable, _ as writeKnowledgeIndex, _t as ClaimLedgerGoalConflictError, a as applyKnowledgeWriteBlocksFile, an as writeJsonDurableWithinRoot, at as KnowledgeGraphEdgeSchema, b as loadSourceRegistry, bt as assertResearchClaimLedgerIntegrity, c as validateKnowledgeIndex, ct as KnowledgePageInvalidationSchema, d as UncheckableClaimError, dt as ResearchClaimLedgerSchema, en as withSafeDescendant, et as extractWikilinks, f as assertGradeableEvidence, ft as ResearchClaimRecordSchema, g as buildKnowledgeIndex, gt as KNOWLEDGE_EVENT_TYPES, h as verifyGradeableEvidence, ht as SourceRecordSchema, i as applyKnowledgeWriteBlocks, in as writeJsonDurable, it as KnowledgeEventSchema, j as assertClaimLedgerId, jt as normalizeClaimText, k as KB_STORE_DIR, kt as mergeClaimLedgers, l as lintKnowledgeIndex, lt as KnowledgePageSchema, m as verdictFor, mt as SourceAnchorSchema, n as inspectKnowledgeIndex, nn as writeFileDurable, nt as DeepQuestionSchema, o as isSafeKnowledgePath, on as mediaTypeFor, ot as KnowledgeGraphNodeSchema, p as gradeFor, pt as ResearchSourceVersionSchema, q as SCAFFOLD_PAGE_BASENAMES, qt as isMissingFile, r as stringMetadata, rn as writeFileDurableWithinRoot, rt as KnowledgeBaseCandidateSchema, s as parseKnowledgeWriteBlocks, sn as textSourceAdapter, st as KnowledgeIndexSchema, t as explainKnowledgeTarget, tn as withSafeDirectory, tt as normalizeLinkTarget, u as CHECKABLE_RUNG_THRESHOLD, ut as ResearchClaimEvidenceSchema, v as addSourcePath, vt as assertDeepQuestionIntegrity, w as ClaimLedgerMigrationRequiredError, wt as claimSourceHost, x as snapshotSourceTextInput, xt as assertTrackedClaimIntegrity, y as addSourceText, yt as assertResearchClaimEvidenceIntegrity, z as auditCurrentRunCitations, zt as withKnowledgeRead } from "./inspect-0tmv3xV8.js";
1
+ import { $ as resolveKnowledgeCitations, $t as withKnowledgeRead, A as sourceRegistryPath, At as KNOWLEDGE_EVENT_TYPES, B as buildKnowledgeGraph, Bt as emptyClaimLedger, C as verifyGradeableEvidence, Cn as mediaTypeFor, Ct as KnowledgeRelationSchema, D as addSourceText, Dt as ResearchSourceVersionSchema, E as addSourcePath, Et as ResearchClaimRecordSchema, F as KB_EVENTS_PATH, Ft as assertTrackedClaimIntegrity, G as assertKnowledgeCitationAudit, Gt as normalizeClaimText, H as KnowledgeCitationAuditError, Ht as materializeRegisteredClaimEvidence, I as KB_INDEX_PATH, It as claimEvidenceId, J as auditCurrentRunCitations, Jt as parseFrontmatter, K as assertKnowledgeCitationsResolved, Kt as researchSourceVersionKey, L as KB_STORE_DIR, Lt as claimId, M as ClaimLedgerMigrationRequiredError, Mt as assertDeepQuestionIntegrity, N as FileSystemKbStore, Nt as assertResearchClaimEvidenceIntegrity, O as loadSourceRegistry, Ot as SourceAnchorSchema, P as KB_CLAIM_LEDGER_DIR, Pt as assertResearchClaimLedgerIntegrity, Q as resolveKnowledgeCitation, Qt as withKnowledgeMutation, R as MemoryKbStore, Rt as claimSourceHost, S as verdictFor, Sn as writeJsonDurableWithinRoot, St as KnowledgeRelationNodeSchema, T as writeKnowledgeIndex, Tt as ResearchClaimLedgerSchema, U as KnowledgeCitationResolutionError, Ut as mergeClaimLedgers, V as knowledgePageRelations, Vt as linkClaimContradictions, W as assertCurrentRunCitationsResolved, Wt as mergeTrackedClaims, X as formatKnowledgeCitationReference, Xt as inspectPendingKnowledgeMutation, Y as auditKnowledgeCitations, Yt as acquireDurableFileLock, Z as parseKnowledgeCitationReference, Zt as recoverPendingKnowledgeMutation, _ as lintKnowledgeIndex, _n as withSafeDescendant, _t as KnowledgeGraphNodeSchema, a as applyKnowledgeWriteBlocksFile, an as prepareKnowledgeFileTransaction, at as isScaffoldPath, b as assertGradeableEvidence, bn as writeFileDurableWithinRoot, bt as KnowledgePageSchema, c as KnowledgeDuplicateIntakeError, cn as normalizePagesDirectory, ct as loadKnowledgePages, d as createFileRunLineageAuthority, dn as listRegularFilesWithinRoot, dt as extractWikilinks, en as applyKnowledgeFileTransaction, et as resolveRunScopedCitation, f as createRunScopedStores, fn as readRegularFileNoFollow, ft as normalizeLinkTarget, g as validateKnowledgeIndex, gn as syncDirectory, gt as KnowledgeGraphEdgeSchema, h as normalizePageText, hn as renameDurable, ht as KnowledgeEventSchema, i as applyKnowledgeWriteBlocks, in as knowledgeFileTransactionPlanHash, it as isKnowledgePagePath, j as writeSourceRegistry, jt as ClaimLedgerGoalConflictError, k as snapshotSourceTextInput, kt as SourceRecordSchema, l as assertKnowledgeWriteIntake, ln as isKernelAnchoredPath, lt as writeJson, m as detectNearDuplicatePages, mn as removeDurable, mt as KnowledgeBaseCandidateSchema, n as inspectKnowledgeIndex, nn as commitKnowledgeFileMutations, nt as SCAFFOLD_PAGE_BASENAMES, o as isSafeKnowledgePath, on as rollbackKnowledgeFileTransaction, ot as knowledgePageFromMarkdown, p as originatedPages, pn as readRegularFileWithinRoot, pt as DeepQuestionSchema, q as assertRunScopedCitationsResolved, qt as formatFrontmatter, r as stringMetadata, rn as finishKnowledgeFileTransaction, rt as initKnowledgeBase, s as parseKnowledgeWriteBlocks, sn as DEFAULT_PAGES_DIRECTORY, st as layoutFor, t as explainKnowledgeTarget, tn as assertKnowledgeMutationPath, tt as resolveRunScopedCitations, u as RUN_LINEAGE_BASENAME, un as isMissingFile, ut as WIKILINK_REGEX, v as CHECKABLE_RUNG_THRESHOLD, vn as withSafeDirectory, vt as KnowledgeIndexSchema, w as buildKnowledgeIndex, wn as textSourceAdapter, wt as ResearchClaimEvidenceSchema, x as gradeFor, xn as writeJsonDurable, xt as KnowledgeRelationGraphSchema, y as UncheckableClaimError, yn as writeFileDurable, yt as KnowledgePageInvalidationSchema, z as assertClaimLedgerId, zt as deepQuestionId } from "./inspect-DALsvG10.js";
2
2
  import { i as textSourceId, n as slugify, r as stableId, t as sha256 } from "./ids-Bevz_pXV.js";
3
- import { A as runSerializedKnowledgeOptimization, C as deterministicRng, D as toOffPolicyTrajectory, E as retrievalHoldoutConfigHash, M as assertImmutableRef, O as jsonCandidateCodec, S as applySessionStickyRetrievalHoldout, T as resetRetrievalHoldoutRegistry, _ as createAgentMemoryBranch, a as createNeo4jAgentMemoryAdapter, b as renderMemoryContext, c as runAgentMemoryImprovement, d as compareAgentMemoryLearning, f as runAgentMemoryLearningExperiment, g as buildAgentMemorySequencesFromBenchmarkCases, h as buildAgentMemorySequenceScenarios, i as AgentMemoryWriteInputSchema, j as scenarioContentFingerprint, k as jsonObjectCandidateCodec, l as createGraphitiMemoryAdapter, m as agentMemorySequenceJudge, n as AgentMemoryKindSchema, o as createMem0MemoryAdapter, p as runAgentMemoryExperiment, r as AgentMemoryScopeSchema, s as mem0MemoryAdapterIdentity, t as AgentMemoryHitSchema, u as graphitiMemoryAdapterIdentity, v as forkAgentMemoryBranchSnapshot, w as emitRetrievalHoldoutBypass, x as applyRetrievalHoldout, y as defaultGetMemoryContext } from "./memory-BPgPIEhj.js";
4
- import { n as searchKnowledge, r as tokenizeQuery, t as reciprocalRankFusion } from "./search-CtVJ0PKX.js";
5
- import { B as createNoopMemoryBenchmarkAdapter, C as sleepForMemoryRecovery, F as buildIndustryRagBenchmarkSmokeCases, G as retrievalConfigFromSurface, H as memoryWriteResultToSourceRecord, I as respondToIndustryMemoryBenchmarkSmokeCase, J as scoreRetrievalArtifact, K as retrievalConfigSurface, L as respondToIndustryRagBenchmarkSmokeCase, M as INDUSTRY_RAG_BENCHMARKS, N as buildFirstPartyMemoryLifecycleBenchmarkCases, P as buildIndustryMemoryBenchmarkSmokeCases, R as isKnowledgeMemoryBenchmarkCase, S as runBoundedMemoryLifecycle, U as buildRetrievalEvalDispatch, V as memoryHitToSourceRecord, W as partitionRetrievalScenarios, a as buildKnowledgeBenchmarkScenarios, b as memoryRecoveryDelayMs, c as runKnowledgeBenchmarkSuite, d as summarizeKnowledgeBenchmarkCampaign, f as acquireAgentMemoryRunLease, h as DEFAULT_MEMORY_CLEANUP_TIMEOUT_MS, i as runMemoryAdapterBenchmark, j as INDUSTRY_MEMORY_BENCHMARKS, l as scoreKnowledgeBenchmarkArtifact, m as AgentMemoryLifecycleUnsafeError, n as parseKnowledgeBenchmarkJsonl, o as knowledgeBenchmarkJudge, p as AgentMemoryLifecycleTimeoutError, q as retrievalRecallJudge, r as parseKnowledgeBenchmarkQrels, s as renderKnowledgeBenchmarkReportMarkdown, t as buildRetrievalBenchmarkCasesFromQrels, u as scoreMemoryBenchmarkArtifact, x as resolveMemoryCleanupTimeoutMs, y as createMemoryExecutionPool, z as createInMemoryBenchmarkAdapter } from "./benchmarks-B_07vX0Q.js";
3
+ import { A as runSerializedKnowledgeOptimization, C as deterministicRng, D as toOffPolicyTrajectory, E as retrievalHoldoutConfigHash, M as assertImmutableRef, O as jsonCandidateCodec, S as applySessionStickyRetrievalHoldout, T as resetRetrievalHoldoutRegistry, _ as createAgentMemoryBranch, a as createNeo4jAgentMemoryAdapter, b as renderMemoryContext, c as runAgentMemoryImprovement, d as compareAgentMemoryLearning, f as runAgentMemoryLearningExperiment, g as buildAgentMemorySequencesFromBenchmarkCases, h as buildAgentMemorySequenceScenarios, i as AgentMemoryWriteInputSchema, j as scenarioContentFingerprint, k as jsonObjectCandidateCodec, l as createGraphitiMemoryAdapter, m as agentMemorySequenceJudge, n as AgentMemoryKindSchema, o as createMem0MemoryAdapter, p as runAgentMemoryExperiment, r as AgentMemoryScopeSchema, s as mem0MemoryAdapterIdentity, t as AgentMemoryHitSchema, u as graphitiMemoryAdapterIdentity, v as forkAgentMemoryBranchSnapshot, w as emitRetrievalHoldoutBypass, x as applyRetrievalHoldout, y as defaultGetMemoryContext } from "./memory-BRGsy2QN.js";
4
+ import { a as buildKnowledgeLexicalIndex, c as tokenizeText, i as searchKnowledgePages, n as reciprocalRankFusion, o as scoreBm25, r as searchKnowledge, s as tokenizeQuery, t as KNOWLEDGE_SEARCH_RETRIEVER_ID } from "./search-Cw6eYfSd.js";
5
+ import { B as createNoopMemoryBenchmarkAdapter, C as sleepForMemoryRecovery, F as buildIndustryRagBenchmarkSmokeCases, G as retrievalConfigFromSurface, H as memoryWriteResultToSourceRecord, I as respondToIndustryMemoryBenchmarkSmokeCase, J as scoreRetrievalArtifact, K as retrievalConfigSurface, L as respondToIndustryRagBenchmarkSmokeCase, M as INDUSTRY_RAG_BENCHMARKS, N as buildFirstPartyMemoryLifecycleBenchmarkCases, P as buildIndustryMemoryBenchmarkSmokeCases, R as isKnowledgeMemoryBenchmarkCase, S as runBoundedMemoryLifecycle, U as buildRetrievalEvalDispatch, V as memoryHitToSourceRecord, W as partitionRetrievalScenarios, a as buildKnowledgeBenchmarkScenarios, b as memoryRecoveryDelayMs, c as runKnowledgeBenchmarkSuite, d as summarizeKnowledgeBenchmarkCampaign, f as acquireAgentMemoryRunLease, h as DEFAULT_MEMORY_CLEANUP_TIMEOUT_MS, i as runMemoryAdapterBenchmark, j as INDUSTRY_MEMORY_BENCHMARKS, l as scoreKnowledgeBenchmarkArtifact, m as AgentMemoryLifecycleUnsafeError, n as parseKnowledgeBenchmarkJsonl, o as knowledgeBenchmarkJudge, p as AgentMemoryLifecycleTimeoutError, q as retrievalRecallJudge, r as parseKnowledgeBenchmarkQrels, s as renderKnowledgeBenchmarkReportMarkdown, t as buildRetrievalBenchmarkCasesFromQrels, u as scoreMemoryBenchmarkArtifact, x as resolveMemoryCleanupTimeoutMs, y as createMemoryExecutionPool, z as createInMemoryBenchmarkAdapter } from "./benchmarks-B6fCb6AD.js";
6
6
  import { IRS_DIMENSION_HINTS, MAX_RESPONSE_BYTES, MIN_REQUEST_GAP_MS, POLITE_USER_AGENT, __resetHttpThrottle, createCornellLiiSource, createIrsPublicationsSource, createStateSosSource, extractLinks, firstMatch, htmlToText, innerHtmlById, looksLikeBlockPage, politeFetch } from "./sources/index.js";
7
7
  import { createHash } from "node:crypto";
8
8
  import { cp, lstat, mkdir, mkdtemp, readFile, rm, stat } from "node:fs/promises";
9
9
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
10
- import { agentImprovementActivationResultSchema, agentImprovementActivationSchema, canonicalCandidateDigest, omitTopLevelDigest, sha256DigestSchema } from "@tangle-network/agent-interface";
10
+ import { agentImprovementActivationResultSchema, agentImprovementActivationSchema, canonicalCandidateBytes, canonicalCandidateDigest, canonicalCandidateJson, omitTopLevelDigest, sha256Bytes, sha256DigestSchema } from "@tangle-network/agent-interface";
11
11
  import { acquisitionPlansForKnowledgeGaps, blockingKnowledgeEval, canonicalJson, contentHash, evaluateReleaseConfidence, objectiveEval, scoreKnowledgeReadiness, userQuestionsForKnowledgeGaps, validateRunRecord } from "@tangle-network/agent-eval";
12
12
  import { z } from "zod";
13
13
  import { surfaceHash } from "@tangle-network/agent-eval/campaign";
@@ -1931,168 +1931,6 @@ async function calibrateRagAnswerJudge(options) {
1931
1931
  };
1932
1932
  }
1933
1933
  //#endregion
1934
- //#region src/rag-eval/near-duplicates.ts
1935
- /**
1936
- * Detect exact and near-duplicate pages without a model, embedding service, or clock.
1937
- *
1938
- * The detector uses word shingles when prose has enough tokens and Unicode
1939
- * character shingles otherwise. An inverted index proposes candidate pairs;
1940
- * high-document-frequency shingles are ignored so common boilerplate cannot
1941
- * make candidate generation quadratic. Exact normalized copies are always
1942
- * proposed before ordinary shingle candidates, even when every shingle is
1943
- * common. Every limit and sort order is explicit so the same corpus produces
1944
- * the same report on every run.
1945
- */
1946
- function detectNearDuplicatePages(pages, options = {}) {
1947
- const threshold = finiteUnitInterval(options.threshold ?? .82, "threshold");
1948
- const minCharacters = nonNegativeInteger(options.minCharacters ?? 80, "minCharacters");
1949
- const wordShingleSize = positiveInteger$1(options.wordShingleSize ?? 5, "wordShingleSize");
1950
- const characterShingleSize = positiveInteger$1(options.characterShingleSize ?? 16, "characterShingleSize");
1951
- const maxDocumentFrequency = positiveInteger$1(options.maxDocumentFrequency ?? 64, "maxDocumentFrequency");
1952
- const maxCandidatePairs = positiveInteger$1(options.maxCandidatePairs ?? 25e4, "maxCandidatePairs");
1953
- const maxReportedPairs = nonNegativeInteger(options.maxReportedPairs ?? 1e3, "maxReportedPairs");
1954
- const prepared = pages.map((page) => preparePage(page, wordShingleSize, characterShingleSize)).filter((item) => item !== null && item.normalized.length >= minCharacters).sort((left, right) => left.page.path.localeCompare(right.page.path));
1955
- const candidateKeys = /* @__PURE__ */ new Set();
1956
- const exactGroups = /* @__PURE__ */ new Map();
1957
- const byShingle = /* @__PURE__ */ new Map();
1958
- for (const [index, item] of prepared.entries()) {
1959
- exactGroups.set(item.normalized, [...exactGroups.get(item.normalized) ?? [], index]);
1960
- for (const shingle of item.shingles) byShingle.set(shingle, [...byShingle.get(shingle) ?? [], index]);
1961
- }
1962
- let truncated = false;
1963
- const addPair = (left, right) => {
1964
- if (left === right) return true;
1965
- const key = pairKey(Math.min(left, right), Math.max(left, right));
1966
- if (candidateKeys.has(key)) return true;
1967
- if (candidateKeys.size >= maxCandidatePairs) {
1968
- truncated = true;
1969
- return false;
1970
- }
1971
- candidateKeys.add(key);
1972
- return true;
1973
- };
1974
- for (const normalized of [...exactGroups.keys()].sort()) if (!addGroupPairs(exactGroups.get(normalized), addPair)) break;
1975
- if (!truncated) for (const shingle of [...byShingle.keys()].sort()) {
1976
- const group = byShingle.get(shingle);
1977
- if (group.length > maxDocumentFrequency) continue;
1978
- if (!addGroupPairs(group, addPair)) break;
1979
- }
1980
- const duplicatePageIndices = /* @__PURE__ */ new Set();
1981
- const pairs = [];
1982
- let duplicatePairCount = 0;
1983
- let comparedPairCount = 0;
1984
- for (const key of [...candidateKeys].sort(pairKeyOrder)) {
1985
- const [leftIndex, rightIndex] = parsePairKey(key);
1986
- const left = prepared[leftIndex];
1987
- const right = prepared[rightIndex];
1988
- comparedPairCount += 1;
1989
- const exact = left.normalized === right.normalized;
1990
- const overlap = jaccard(left.shingles, right.shingles);
1991
- if (!exact && overlap.similarity < threshold) continue;
1992
- duplicatePairCount += 1;
1993
- duplicatePageIndices.add(leftIndex);
1994
- duplicatePageIndices.add(rightIndex);
1995
- if (pairs.length >= maxReportedPairs) {
1996
- truncated = true;
1997
- continue;
1998
- }
1999
- pairs.push({
2000
- leftPageId: left.page.id,
2001
- leftPath: left.page.path,
2002
- rightPageId: right.page.id,
2003
- rightPath: right.page.path,
2004
- similarity: exact ? 1 : round$1(overlap.similarity),
2005
- intersectionSize: overlap.intersectionSize,
2006
- unionSize: overlap.unionSize,
2007
- exact
2008
- });
2009
- }
2010
- pairs.sort((left, right) => right.similarity - left.similarity || left.leftPath.localeCompare(right.leftPath) || left.rightPath.localeCompare(right.rightPath));
2011
- return {
2012
- algorithm: "deterministic-shingle-jaccard-v1",
2013
- threshold,
2014
- pageCount: pages.length,
2015
- eligiblePageCount: prepared.length,
2016
- candidatePairCount: candidateKeys.size,
2017
- comparedPairCount,
2018
- duplicatePairCount,
2019
- duplicatePageCount: duplicatePageIndices.size,
2020
- duplicatePageRate: prepared.length === 0 ? 0 : round$1(duplicatePageIndices.size / prepared.length),
2021
- truncated,
2022
- pairs
2023
- };
2024
- }
2025
- function preparePage(page, wordShingleSize, characterShingleSize) {
2026
- const normalized = normalizePageText(`${page.title}\n${page.text}`);
2027
- if (normalized.length === 0) return null;
2028
- const words = normalized.match(/[\p{L}\p{N}]+/gu) ?? [];
2029
- const shingles = words.length >= wordShingleSize + 2 ? sequenceShingles(words, wordShingleSize) : characterShingles(normalized.replace(/\s+/g, ""), characterShingleSize);
2030
- if (shingles.size === 0) shingles.add(normalized);
2031
- return {
2032
- page,
2033
- normalized,
2034
- shingles
2035
- };
2036
- }
2037
- function normalizePageText(value) {
2038
- return value.normalize("NFKC").toLowerCase().replace(/https?:\/\/\S+/g, "<url>").replace(/\s+/g, " ").trim();
2039
- }
2040
- function sequenceShingles(items, width) {
2041
- const out = /* @__PURE__ */ new Set();
2042
- if (items.length < width) return out;
2043
- for (let index = 0; index <= items.length - width; index += 1) out.add(items.slice(index, index + width).join(""));
2044
- return out;
2045
- }
2046
- function characterShingles(value, width) {
2047
- const chars = [...value];
2048
- const out = /* @__PURE__ */ new Set();
2049
- if (chars.length < width) return out;
2050
- for (let index = 0; index <= chars.length - width; index += 1) out.add(chars.slice(index, index + width).join(""));
2051
- return out;
2052
- }
2053
- function addGroupPairs(group, add) {
2054
- for (let left = 0; left < group.length; left += 1) for (let right = left + 1; right < group.length; right += 1) if (!add(group[left], group[right])) return false;
2055
- return true;
2056
- }
2057
- function jaccard(left, right) {
2058
- const [small, large] = left.size <= right.size ? [left, right] : [right, left];
2059
- let intersectionSize = 0;
2060
- for (const item of small) if (large.has(item)) intersectionSize += 1;
2061
- const unionSize = left.size + right.size - intersectionSize;
2062
- return {
2063
- similarity: unionSize === 0 ? 1 : intersectionSize / unionSize,
2064
- intersectionSize,
2065
- unionSize
2066
- };
2067
- }
2068
- function pairKey(left, right) {
2069
- return `${left}:${right}`;
2070
- }
2071
- function parsePairKey(value) {
2072
- const [left, right] = value.split(":");
2073
- return [Number(left), Number(right)];
2074
- }
2075
- function pairKeyOrder(left, right) {
2076
- const [leftA, leftB] = parsePairKey(left);
2077
- const [rightA, rightB] = parsePairKey(right);
2078
- return leftA - rightA || leftB - rightB;
2079
- }
2080
- function finiteUnitInterval(value, name) {
2081
- if (!Number.isFinite(value) || value < 0 || value > 1) throw new Error(`${name} must be a finite number in [0, 1]`);
2082
- return value;
2083
- }
2084
- function positiveInteger$1(value, name) {
2085
- if (!Number.isInteger(value) || value < 1) throw new Error(`${name} must be a positive integer`);
2086
- return value;
2087
- }
2088
- function nonNegativeInteger(value, name) {
2089
- if (!Number.isInteger(value) || value < 0) throw new Error(`${name} must be a non-negative integer`);
2090
- return value;
2091
- }
2092
- function round$1(value) {
2093
- return Math.round(value * 1e6) / 1e6;
2094
- }
2095
- //#endregion
2096
1934
  //#region src/rag-eval/knowledge-base.ts
2097
1935
  function scoreKnowledgeBaseIndex(index, options = {}) {
2098
1936
  const validation = validateKnowledgeIndex(index, { strict: options.strict });
@@ -4698,21 +4536,33 @@ function positiveInteger(value, name) {
4698
4536
  */
4699
4537
  var FileSystemSearchProvider = class {
4700
4538
  root;
4539
+ /** Root-relative directory the provider indexes. */
4540
+ pagesDirectory;
4701
4541
  index;
4542
+ lexicalIndex;
4702
4543
  defaultLimit;
4703
4544
  refreshMode;
4704
4545
  constructor(options) {
4705
4546
  this.root = options.root;
4547
+ this.pagesDirectory = normalizePagesDirectory(options.pagesDirectory);
4706
4548
  this.index = options.index;
4707
4549
  this.defaultLimit = options.defaultLimit ?? 10;
4708
4550
  this.refreshMode = options.refresh ?? "manual";
4709
4551
  }
4710
4552
  async getIndex(options = {}) {
4711
- if (this.refreshMode === "always" || options.refresh || !this.index) this.index = await buildKnowledgeIndex(this.root);
4553
+ if (this.refreshMode === "always" || options.refresh || !this.index) {
4554
+ this.index = await buildKnowledgeIndex(this.root, { pagesDirectory: this.pagesDirectory });
4555
+ this.lexicalIndex = void 0;
4556
+ }
4712
4557
  return this.index;
4713
4558
  }
4714
4559
  async search(query, options = {}) {
4715
- return searchKnowledge(await this.getIndex(options), query, options.limit ?? this.defaultLimit);
4560
+ const index = await this.getIndex(options);
4561
+ if (!this.lexicalIndex) this.lexicalIndex = buildKnowledgeLexicalIndex(index.pages);
4562
+ return searchKnowledge(index, query, {
4563
+ limit: options.limit ?? this.defaultLimit,
4564
+ lexicalIndex: this.lexicalIndex
4565
+ });
4716
4566
  }
4717
4567
  async retrieve(query, options = {}) {
4718
4568
  return (await this.search(query, options)).map(hitFromSearchResult);
@@ -4725,6 +4575,7 @@ var FileSystemSearchProvider = class {
4725
4575
  }
4726
4576
  invalidate() {
4727
4577
  this.index = void 0;
4578
+ this.lexicalIndex = void 0;
4728
4579
  }
4729
4580
  };
4730
4581
  function createFileSystemSearchProvider(options) {
@@ -4830,6 +4681,77 @@ function buildKey(key) {
4830
4681
  return `${key.workspaceId}::${key.sourceId}`;
4831
4682
  }
4832
4683
  //#endregion
4684
+ //#region src/invalidation-propagation.ts
4685
+ /**
4686
+ * Invalidation propagation.
4687
+ *
4688
+ * A page whose own evidence refuted it carries an `invalidation`. That verdict
4689
+ * is invisible to a reader who arrives through a citation, so a page that cites
4690
+ * a refuted page records which of its citations are refuted. The pass is
4691
+ * planned as a diff, so a store already stamped produces no mutation and the
4692
+ * pass can run after every grading round.
4693
+ */
4694
+ /** Frontmatter field naming the cited pages whose evidence refuted them. */
4695
+ const CITES_INVALIDATED_FIELD = "citesInvalidated";
4696
+ /**
4697
+ * Plan the `citesInvalidated` stamp for every page authored in the target
4698
+ * store.
4699
+ *
4700
+ * Citations resolve over the whole chain, so a page here may be stamped for
4701
+ * citing a refuted inherited or shared page. Only `here` pages are stamped: a
4702
+ * run does not write the stores it inherits or shares.
4703
+ */
4704
+ function planInvalidationPropagation(visiblePages) {
4705
+ if (!Array.isArray(visiblePages)) throw new TypeError("knowledge invalidation propagation requires the visible pages");
4706
+ const invalidatedPageIds = [...new Set(visiblePages.filter((entry) => entry.page.invalidation !== void 0).map((entry) => entry.page.id))].sort();
4707
+ const stamps = [];
4708
+ for (const entry of visiblePages) {
4709
+ if (entry.origin !== "here") continue;
4710
+ const page = entry.page;
4711
+ const refuted = /* @__PURE__ */ new Set();
4712
+ for (const persisted of page.cites ?? []) {
4713
+ const resolution = resolveKnowledgeCitation(visiblePages, parseKnowledgeCitationReference(persisted));
4714
+ if (resolution.resolved?.page.invalidation !== void 0) refuted.add(resolution.resolved.page.id);
4715
+ }
4716
+ const citesInvalidated = [...refuted].sort();
4717
+ const current = idList(page.frontmatter[CITES_INVALIDATED_FIELD]);
4718
+ if (sameOrder(current, citesInvalidated)) continue;
4719
+ stamps.push({
4720
+ page,
4721
+ citesInvalidated,
4722
+ current
4723
+ });
4724
+ }
4725
+ stamps.sort((left, right) => left.page.path.localeCompare(right.page.path));
4726
+ return {
4727
+ invalidatedPageIds,
4728
+ stamps
4729
+ };
4730
+ }
4731
+ /**
4732
+ * Render one plan as a write-block proposal for `applyKnowledgeWriteBlocks`.
4733
+ *
4734
+ * Only the stamped field changes. The page is rendered through
4735
+ * `formatFrontmatter`, so its frontmatter is written in that writer's
4736
+ * normalized form.
4737
+ */
4738
+ function formatKnowledgeInvalidationProposal(plan) {
4739
+ return plan.stamps.map((stamp) => renderStampedBlock(stamp)).join("\n");
4740
+ }
4741
+ function renderStampedBlock(stamp) {
4742
+ const frontmatter = { ...stamp.page.frontmatter };
4743
+ if (stamp.citesInvalidated.length === 0) delete frontmatter[CITES_INVALIDATED_FIELD];
4744
+ else frontmatter[CITES_INVALIDATED_FIELD] = [...stamp.citesInvalidated];
4745
+ const content = formatFrontmatter(frontmatter, stamp.page.text);
4746
+ return `---FILE: ${stamp.page.path}---\n${content.replace(/\n+$/, "")}\n---END FILE---`;
4747
+ }
4748
+ function idList(value) {
4749
+ return (typeof value === "string" ? [value] : Array.isArray(value) ? value : []).filter((item) => typeof item === "string" && item.trim() !== "");
4750
+ }
4751
+ function sameOrder(left, right) {
4752
+ return left.length === right.length && left.every((item, index) => item === right[index]);
4753
+ }
4754
+ //#endregion
4833
4755
  //#region src/investment-thesis-set.ts
4834
4756
  /**
4835
4757
  * The eval set. 5 public companies, 5-8 held-out material facts each, every fact
@@ -5954,9 +5876,107 @@ async function runInvestmentThesisTask(input, options) {
5954
5876
  };
5955
5877
  }
5956
5878
  //#endregion
5879
+ //#region src/knowledge-brief.ts
5880
+ /**
5881
+ * Retrieval briefing.
5882
+ *
5883
+ * A brief turns "retrieved" from something a run claims into something the
5884
+ * infrastructure can prove. It ranks the knowledge visible to a question,
5885
+ * renders it with the ids a later write must cite, and returns the ranked
5886
+ * results in the shape a retrieval receipt takes, so what an actor was given
5887
+ * is recorded rather than asserted.
5888
+ *
5889
+ * Pure: no clock, no filesystem, no network.
5890
+ */
5891
+ /** Pages in a brief when the caller names no limit. */
5892
+ const DEFAULT_KNOWLEDGE_BRIEF_LIMIT = 5;
5893
+ /**
5894
+ * Rank the knowledge one question can see and render it for injection.
5895
+ *
5896
+ * The same page set produces the same brief on every run: ranking, ordering,
5897
+ * and rendering are deterministic, and no field carries a timestamp.
5898
+ */
5899
+ function buildKnowledgeBrief(visiblePages, question, options = {}) {
5900
+ if (!Array.isArray(visiblePages)) throw new TypeError("knowledge brief requires the visible pages");
5901
+ if (typeof question !== "string" || question.trim().length === 0) throw new TypeError("knowledge brief question must be a non-empty string");
5902
+ const limit = options.limit ?? 5;
5903
+ const excludeInvalidated = options.excludeInvalidated ?? true;
5904
+ const maxChars = options.maxChars;
5905
+ if (maxChars !== void 0 && (!Number.isInteger(maxChars) || maxChars < 0)) throw new Error(`knowledge brief maxChars must be a non-negative integer, got ${maxChars}`);
5906
+ const originByPage = /* @__PURE__ */ new Map();
5907
+ for (const entry of visiblePages) originByPage.set(entry.page, entry.origin);
5908
+ const ranked = searchKnowledgePages(visiblePages.map((entry) => entry.page), question, {
5909
+ limit,
5910
+ excludeInvalidated,
5911
+ ...options.tags === void 0 ? {} : { tags: options.tags },
5912
+ ...options.kinds === void 0 ? {} : { kinds: options.kinds }
5913
+ });
5914
+ const hits = [];
5915
+ const lines = [];
5916
+ let length = 0;
5917
+ for (const hit of ranked) {
5918
+ const line = briefLine(hit);
5919
+ const next = length === 0 ? line.length : length + 1 + line.length;
5920
+ if (maxChars !== void 0 && next > maxChars) break;
5921
+ hits.push(hit);
5922
+ lines.push(line);
5923
+ length = next;
5924
+ }
5925
+ return Object.freeze({
5926
+ question: question.trim(),
5927
+ retrieverId: KNOWLEDGE_SEARCH_RETRIEVER_ID,
5928
+ retrieverConfigDigest: canonicalCandidateDigest({
5929
+ limit,
5930
+ excludeInvalidated,
5931
+ tags: options.tags === void 0 ? null : [...options.tags],
5932
+ kinds: options.kinds === void 0 ? null : [...options.kinds],
5933
+ maxChars: maxChars ?? null
5934
+ }),
5935
+ hits: Object.freeze(hits),
5936
+ citationIds: Object.freeze(hits.map((hit) => hit.citationId)),
5937
+ results: Object.freeze(hits.map((hit) => Object.freeze({
5938
+ ...hit,
5939
+ origin: originOf(originByPage, hit)
5940
+ }))),
5941
+ text: lines.join("\n")
5942
+ });
5943
+ }
5944
+ function briefLine(hit) {
5945
+ const snippet = hit.snippet.replace(/\s+/g, " ").trim();
5946
+ return snippet === "" ? `- [${hit.citationId}] ${hit.page.title}` : `- [${hit.citationId}] ${hit.page.title} — ${snippet}`;
5947
+ }
5948
+ function originOf(originByPage, hit) {
5949
+ const origin = originByPage.get(hit.page);
5950
+ if (origin === void 0) throw new Error(`knowledge brief ranked a page outside the visible chain: ${hit.page.path}`);
5951
+ return origin;
5952
+ }
5953
+ //#endregion
5957
5954
  //#region src/knowledge-use-receipts.ts
5958
- const KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION = "1.0.0";
5955
+ const KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION = "2.0.0";
5959
5956
  const KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM = "rfc8785-sha256";
5957
+ /**
5958
+ * The visibility snapshot a receipt references could not be obtained, so the
5959
+ * result-to-visibility join cannot be proven. This is distinct from a snapshot
5960
+ * that loads and fails to match.
5961
+ */
5962
+ var KnowledgeVisibilityUnavailableError = class extends Error {
5963
+ reason;
5964
+ snapshotDigest;
5965
+ uri;
5966
+ constructor(input) {
5967
+ const where = input.uri === void 0 ? "" : ` at '${input.uri}'`;
5968
+ const detail = {
5969
+ "no-artifact-reference": "the receipt carries no artifact reference",
5970
+ missing: `no artifact is stored${where}`,
5971
+ "load-failed": `the artifact${where} could not be loaded`
5972
+ }[input.reason];
5973
+ super(`knowledge visibility snapshot ${input.snapshotDigest} is unavailable: ${detail}`, input.cause === void 0 ? void 0 : { cause: input.cause });
5974
+ this.name = "KnowledgeVisibilityUnavailableError";
5975
+ this.reason = input.reason;
5976
+ this.snapshotDigest = input.snapshotDigest;
5977
+ if (input.uri !== void 0) this.uri = input.uri;
5978
+ }
5979
+ };
5960
5980
  /** Stable content identity for one exact knowledge page. */
5961
5981
  function knowledgePageDigest(page) {
5962
5982
  validateKnowledgePage(page);
@@ -5981,7 +6001,7 @@ function createKnowledgeVisibilitySnapshot(visiblePages) {
5981
6001
  if (!entry || typeof entry !== "object") throw new TypeError(`knowledge visibility[${position}] must be an originated page`);
5982
6002
  const origin = validateOrigin(entry.origin, `knowledge visibility[${position}].origin`);
5983
6003
  validateKnowledgePage(entry.page);
5984
- const identity = `${origin}\u0000${entry.page.path}`;
6004
+ const identity = visibilityIdentity(origin, entry.page.path);
5985
6005
  if (identities.has(identity)) throw new Error(`knowledge visibility repeats path '${entry.page.path}' at origin '${origin}'`);
5986
6006
  identities.add(identity);
5987
6007
  return Object.freeze({
@@ -5995,23 +6015,94 @@ function createKnowledgeVisibilitySnapshot(visiblePages) {
5995
6015
  });
5996
6016
  });
5997
6017
  const material = visibilityMaterial(entries);
5998
- return Object.freeze({
6018
+ const snapshot = Object.freeze({
5999
6019
  ...material,
6000
6020
  snapshotDigest: canonicalCandidateDigest(material),
6001
6021
  entries: Object.freeze(entries)
6002
6022
  });
6023
+ visibilityIndexes.set(snapshot, indexVisibility(snapshot));
6024
+ return snapshot;
6003
6025
  }
6004
- /** Create a retrieval receipt and refuse results that were not in the view. */
6026
+ /**
6027
+ * Verify a snapshot's schema and canonical digest. The check runs once per
6028
+ * snapshot object; later calls with the same object are free.
6029
+ */
6030
+ function verifyKnowledgeVisibilitySnapshot(snapshot) {
6031
+ return visibilityIndexOf(snapshot).snapshot;
6032
+ }
6033
+ /** Canonical bytes of a verified snapshot, for durable storage. */
6034
+ function encodeKnowledgeVisibilitySnapshot(snapshot) {
6035
+ const verified = verifyKnowledgeVisibilitySnapshot(snapshot);
6036
+ return canonicalCandidateBytes({
6037
+ schemaVersion: verified.schemaVersion,
6038
+ digestAlgorithm: verified.digestAlgorithm,
6039
+ snapshotDigest: verified.snapshotDigest,
6040
+ entries: visibilityMaterial(verified.entries).entries
6041
+ });
6042
+ }
6043
+ /** Parse stored snapshot bytes and verify their schema and digest. */
6044
+ function decodeKnowledgeVisibilitySnapshot(bytes) {
6045
+ if (!(bytes instanceof Uint8Array)) throw new TypeError("knowledge visibility snapshot bytes must be a Uint8Array");
6046
+ let parsed;
6047
+ try {
6048
+ parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
6049
+ } catch (error) {
6050
+ throw new Error(`knowledge visibility snapshot bytes are not JSON: ${error instanceof Error ? error.message : String(error)}`);
6051
+ }
6052
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new TypeError("knowledge visibility snapshot must be an object");
6053
+ const candidate = parsed;
6054
+ if (!Array.isArray(candidate.entries)) throw new TypeError("knowledge visibility snapshot entries must be an array");
6055
+ return verifyKnowledgeVisibilitySnapshot(Object.freeze({
6056
+ schemaVersion: candidate.schemaVersion,
6057
+ digestAlgorithm: candidate.digestAlgorithm,
6058
+ snapshotDigest: digest(candidate.snapshotDigest, "knowledge visibility snapshotDigest"),
6059
+ entries: Object.freeze(candidate.entries.map((entry, position) => {
6060
+ if (!entry || typeof entry !== "object") throw new TypeError(`knowledge visibility[${position}] must be an object`);
6061
+ const value = entry;
6062
+ if (!Array.isArray(value.sourceIds)) throw new TypeError(`knowledge visibility[${position}].sourceIds must be an array`);
6063
+ return Object.freeze({
6064
+ position: value.position,
6065
+ pageId: value.pageId,
6066
+ origin: value.origin,
6067
+ path: value.path,
6068
+ pageDigest: value.pageDigest,
6069
+ sourceIds: Object.freeze([...value.sourceIds]),
6070
+ invalidated: value.invalidated
6071
+ });
6072
+ }))
6073
+ }));
6074
+ }
6075
+ /** Locator for snapshot bytes stored at `uri`. */
6076
+ function knowledgeVisibilityArtifactRef(input) {
6077
+ if (!input || typeof input !== "object" || !(input.bytes instanceof Uint8Array)) throw new TypeError("knowledge visibility artifact bytes must be a Uint8Array");
6078
+ if (input.bytes.byteLength === 0) throw new TypeError("knowledge visibility artifact bytes must not be empty");
6079
+ return Object.freeze({
6080
+ uri: nonEmpty$1(input.uri, "knowledge visibility artifact uri"),
6081
+ digest: sha256Bytes(input.bytes),
6082
+ byteLength: input.bytes.byteLength
6083
+ });
6084
+ }
6085
+ /**
6086
+ * Create a retrieval receipt over a precomputed snapshot. Every result must
6087
+ * occur in the snapshot with the same page id and bytes; the receipt stores the
6088
+ * snapshot's reference, not its entries.
6089
+ */
6005
6090
  function createKnowledgeRetrievalReceipt(input) {
6006
6091
  if (!input || typeof input !== "object") throw new TypeError("knowledge retrieval receipt input is required");
6007
- const runId = nonEmpty(input.runId, "knowledge retrieval runId");
6092
+ const runId = nonEmpty$1(input.runId, "knowledge retrieval runId");
6008
6093
  const actorId = optionalText(input.actorId, "knowledge retrieval actorId");
6009
6094
  const profileDigest = optionalDigest(input.profileDigest, "knowledge retrieval profileDigest");
6010
6095
  const executionRef = optionalDigest(input.executionRef, "knowledge retrieval executionRef");
6011
- const query = nonEmpty(input.query, "knowledge retrieval query");
6096
+ const query = nonEmpty$1(input.query, "knowledge retrieval query");
6012
6097
  const retriever = normalizeRetriever(input.retriever);
6013
- const visibility = createKnowledgeVisibilitySnapshot(input.visiblePages);
6014
- const results = normalizeRetrievalResults(input.results, visibility);
6098
+ const index = visibilityIndexOf(input.visibility);
6099
+ const artifact = input.visibilityArtifact === void 0 ? void 0 : normalizeVisibilityArtifact(input.visibilityArtifact, "knowledge retrieval visibilityArtifact");
6100
+ const visibility = Object.freeze({
6101
+ snapshotDigest: index.snapshot.snapshotDigest,
6102
+ pageCount: index.snapshot.entries.length,
6103
+ ...artifact === void 0 ? {} : { artifact }
6104
+ });
6105
+ const results = normalizeRetrievalResults(input.results, index);
6015
6106
  const evidenceRefs = normalizeEvidenceRefs(input.evidenceRefs ?? []);
6016
6107
  const attributes = normalizeAttributes(input.attributes ?? {});
6017
6108
  const material = retrievalMaterial({
@@ -6032,33 +6123,82 @@ function createKnowledgeRetrievalReceipt(input) {
6032
6123
  receiptDigest: canonicalCandidateDigest(material)
6033
6124
  });
6034
6125
  }
6035
- /** Verify the receipt's schema, internal joins, and canonical digest. */
6126
+ /**
6127
+ * Verify the receipt's schema, canonical digest, rank continuity, finite
6128
+ * scores, and well-formed visibility reference. This proves what the receipt
6129
+ * says; it does not prove that the results occur in the referenced snapshot.
6130
+ * Use `assertKnowledgeRetrievalMatchesVisibility` or
6131
+ * `assertKnowledgeRetrievalMatchesVisibilityArtifact` for that join.
6132
+ */
6036
6133
  function verifyKnowledgeRetrievalReceipt(receipt) {
6037
6134
  if (!receipt || typeof receipt !== "object") throw new TypeError("knowledge retrieval receipt is required");
6038
- if (receipt.schemaVersion !== "1.0.0") throw new Error(`unsupported knowledge retrieval schemaVersion '${receipt.schemaVersion}'`);
6135
+ assertSchemaVersion(receipt.schemaVersion, "knowledge retrieval");
6039
6136
  if (receipt.kind !== "knowledge-retrieval") throw new Error(`knowledge retrieval receipt kind must be 'knowledge-retrieval'`);
6040
6137
  if (receipt.digestAlgorithm !== "rfc8785-sha256") throw new Error(`unsupported knowledge retrieval digestAlgorithm '${receipt.digestAlgorithm}'`);
6041
- if (canonicalCandidateDigest(visibilityMaterial(receipt.visibility.entries)) !== receipt.visibility.snapshotDigest) throw new Error("knowledge retrieval visibility snapshot digest mismatch");
6042
- validateReceiptResults(receipt.results, receipt.visibility);
6138
+ const visibility = normalizeVisibilityRef(receipt.visibility);
6139
+ validateReceiptResultShape(receipt.results, visibility.pageCount);
6043
6140
  if (canonicalCandidateDigest(retrievalMaterial({
6044
6141
  createdAt: isoTimestamp(receipt.createdAt, "knowledge retrieval createdAt"),
6045
- runId: nonEmpty(receipt.runId, "knowledge retrieval runId"),
6142
+ runId: nonEmpty$1(receipt.runId, "knowledge retrieval runId"),
6046
6143
  actorId: optionalText(receipt.actorId, "knowledge retrieval actorId"),
6047
6144
  profileDigest: optionalDigest(receipt.profileDigest, "knowledge retrieval profileDigest"),
6048
6145
  executionRef: optionalDigest(receipt.executionRef, "knowledge retrieval executionRef"),
6049
- query: nonEmpty(receipt.query, "knowledge retrieval query"),
6146
+ query: nonEmpty$1(receipt.query, "knowledge retrieval query"),
6050
6147
  retriever: normalizeRetriever(receipt.retriever),
6051
- visibility: receipt.visibility,
6148
+ visibility,
6052
6149
  results: receipt.results,
6053
6150
  evidenceRefs: normalizeEvidenceRefs(receipt.evidenceRefs),
6054
6151
  attributes: normalizeAttributes(receipt.attributes)
6055
6152
  })) !== receipt.receiptDigest) throw new Error("knowledge retrieval receipt digest mismatch");
6056
6153
  return receipt;
6057
6154
  }
6058
- /** Prove that a receipt still describes the supplied visibility bytes. */
6059
- function assertKnowledgeRetrievalMatchesVisibility(receipt, visiblePages) {
6155
+ /**
6156
+ * Prove that the receipt references exactly this snapshot and that every
6157
+ * returned result occurs in it with the same page id and bytes. Pass the
6158
+ * snapshot itself, or the originated pages to snapshot them first.
6159
+ */
6160
+ function assertKnowledgeRetrievalMatchesVisibility(receipt, visibility) {
6161
+ verifyKnowledgeRetrievalReceipt(receipt);
6162
+ assertReceiptJoinsVisibility(receipt, visibilityIndexOf(Array.isArray(visibility) ? createKnowledgeVisibilitySnapshot(visibility) : visibility));
6163
+ }
6164
+ /**
6165
+ * Load the snapshot artifact the receipt references, prove the stored bytes
6166
+ * match the reference, and prove every returned result occurs in the decoded
6167
+ * snapshot. A snapshot that cannot be obtained raises
6168
+ * `KnowledgeVisibilityUnavailableError`; it is never treated as empty.
6169
+ */
6170
+ async function assertKnowledgeRetrievalMatchesVisibilityArtifact(receipt, loadArtifact) {
6060
6171
  verifyKnowledgeRetrievalReceipt(receipt);
6061
- if (createKnowledgeVisibilitySnapshot(visiblePages).snapshotDigest !== receipt.visibility.snapshotDigest) throw new Error("knowledge retrieval receipt does not match the supplied visibility snapshot");
6172
+ if (typeof loadArtifact !== "function") throw new TypeError("knowledge visibility artifact loader must be a function");
6173
+ const reference = receipt.visibility;
6174
+ if (reference.artifact === void 0) throw new KnowledgeVisibilityUnavailableError({
6175
+ reason: "no-artifact-reference",
6176
+ snapshotDigest: reference.snapshotDigest
6177
+ });
6178
+ const artifact = reference.artifact;
6179
+ let bytes;
6180
+ try {
6181
+ bytes = await loadArtifact(artifact);
6182
+ } catch (error) {
6183
+ throw new KnowledgeVisibilityUnavailableError({
6184
+ reason: "load-failed",
6185
+ snapshotDigest: reference.snapshotDigest,
6186
+ uri: artifact.uri,
6187
+ cause: error
6188
+ });
6189
+ }
6190
+ if (bytes === void 0) throw new KnowledgeVisibilityUnavailableError({
6191
+ reason: "missing",
6192
+ snapshotDigest: reference.snapshotDigest,
6193
+ uri: artifact.uri
6194
+ });
6195
+ if (!(bytes instanceof Uint8Array)) throw new TypeError(`knowledge visibility artifact '${artifact.uri}' loaded a non-byte value`);
6196
+ if (bytes.byteLength !== artifact.byteLength) throw new Error(`knowledge visibility artifact '${artifact.uri}' byteLength mismatch: expected ${artifact.byteLength}, observed ${bytes.byteLength}`);
6197
+ if (sha256Bytes(bytes) !== artifact.digest) throw new Error(`knowledge visibility artifact '${artifact.uri}' digest mismatch`);
6198
+ const snapshot = decodeKnowledgeVisibilitySnapshot(bytes);
6199
+ if (snapshot.snapshotDigest !== reference.snapshotDigest) throw new Error(`knowledge visibility artifact '${artifact.uri}' holds snapshot ${snapshot.snapshotDigest}, not ${reference.snapshotDigest}`);
6200
+ assertReceiptJoinsVisibility(receipt, visibilityIndexOf(snapshot));
6201
+ return snapshot;
6062
6202
  }
6063
6203
  /** Create a downstream-use receipt for one exact ranked result. */
6064
6204
  function createKnowledgeUseReceipt(input) {
@@ -6095,7 +6235,7 @@ function createKnowledgeUseReceipt(input) {
6095
6235
  function verifyKnowledgeUseReceipt(receipt, retrieval) {
6096
6236
  if (!receipt || typeof receipt !== "object") throw new TypeError("knowledge use receipt is required");
6097
6237
  const verifiedRetrieval = verifyKnowledgeRetrievalReceipt(retrieval);
6098
- if (receipt.schemaVersion !== "1.0.0") throw new Error(`unsupported knowledge use schemaVersion '${receipt.schemaVersion}'`);
6238
+ assertSchemaVersion(receipt.schemaVersion, "knowledge use");
6099
6239
  if (receipt.kind !== "knowledge-use") throw new Error(`knowledge use receipt kind must be 'knowledge-use'`);
6100
6240
  if (receipt.digestAlgorithm !== "rfc8785-sha256") throw new Error(`unsupported knowledge use digestAlgorithm '${receipt.digestAlgorithm}'`);
6101
6241
  if (receipt.retrievalReceiptDigest !== verifiedRetrieval.receiptDigest) throw new Error("knowledge use receipt references a different retrieval receipt");
@@ -6112,19 +6252,94 @@ function verifyKnowledgeUseReceipt(receipt, retrieval) {
6112
6252
  })) !== receipt.receiptDigest) throw new Error("knowledge use receipt digest mismatch");
6113
6253
  return receipt;
6114
6254
  }
6255
+ /** Record that one retrieval led to no use, with no rank to select. */
6256
+ function createKnowledgeRetrievalDisposition(input) {
6257
+ if (!input || typeof input !== "object") throw new TypeError("knowledge retrieval disposition input is required");
6258
+ const material = dispositionMaterial({
6259
+ createdAt: isoTimestamp(input.createdAt, "knowledge retrieval disposition createdAt"),
6260
+ retrieval: verifyKnowledgeRetrievalReceipt(input.retrieval),
6261
+ relation: validateDispositionRelation(input.relation),
6262
+ consumer: normalizeConsumer(input.consumer),
6263
+ evidenceRefs: normalizeEvidenceRefs(input.evidenceRefs ?? []),
6264
+ attributes: normalizeAttributes(input.attributes ?? {})
6265
+ });
6266
+ return Object.freeze({
6267
+ ...material,
6268
+ receiptDigest: canonicalCandidateDigest(material)
6269
+ });
6270
+ }
6271
+ /** Verify one disposition against the exact retrieval that authorized it. */
6272
+ function verifyKnowledgeRetrievalDisposition(disposition, retrieval) {
6273
+ if (!disposition || typeof disposition !== "object") throw new TypeError("knowledge retrieval disposition is required");
6274
+ const verifiedRetrieval = verifyKnowledgeRetrievalReceipt(retrieval);
6275
+ assertSchemaVersion(disposition.schemaVersion, "knowledge retrieval disposition");
6276
+ if (disposition.kind !== "knowledge-retrieval-disposition") throw new Error(`knowledge retrieval disposition kind must be 'knowledge-retrieval-disposition'`);
6277
+ if (disposition.digestAlgorithm !== "rfc8785-sha256") throw new Error(`unsupported knowledge retrieval disposition digestAlgorithm '${disposition.digestAlgorithm}'`);
6278
+ if (disposition.retrievalReceiptDigest !== verifiedRetrieval.receiptDigest) throw new Error("knowledge retrieval disposition references a different retrieval receipt");
6279
+ if (canonicalCandidateDigest(dispositionMaterial({
6280
+ createdAt: isoTimestamp(disposition.createdAt, "knowledge retrieval disposition createdAt"),
6281
+ retrieval: verifiedRetrieval,
6282
+ relation: validateDispositionRelation(disposition.relation),
6283
+ consumer: normalizeConsumer(disposition.consumer),
6284
+ evidenceRefs: normalizeEvidenceRefs(disposition.evidenceRefs),
6285
+ attributes: normalizeAttributes(disposition.attributes)
6286
+ })) !== disposition.receiptDigest) throw new Error("knowledge retrieval disposition digest mismatch");
6287
+ return disposition;
6288
+ }
6289
+ const visibilityIndexes = /* @__PURE__ */ new WeakMap();
6290
+ function visibilityIndexOf(snapshot) {
6291
+ if (!snapshot || typeof snapshot !== "object") throw new TypeError("knowledge visibility snapshot is required");
6292
+ const cached = visibilityIndexes.get(snapshot);
6293
+ if (cached !== void 0) return cached;
6294
+ assertSchemaVersion(snapshot.schemaVersion, "knowledge visibility");
6295
+ if (snapshot.digestAlgorithm !== "rfc8785-sha256") throw new Error(`unsupported knowledge visibility digestAlgorithm '${snapshot.digestAlgorithm}'`);
6296
+ if (!Array.isArray(snapshot.entries)) throw new TypeError("knowledge visibility snapshot entries must be an array");
6297
+ if (canonicalCandidateDigest(visibilityMaterial(snapshot.entries)) !== digest(snapshot.snapshotDigest, "knowledge visibility snapshotDigest")) throw new Error("knowledge visibility snapshot digest mismatch");
6298
+ const index = indexVisibility(snapshot);
6299
+ visibilityIndexes.set(snapshot, index);
6300
+ return index;
6301
+ }
6302
+ function indexVisibility(snapshot) {
6303
+ const byIdentity = /* @__PURE__ */ new Map();
6304
+ for (const entry of snapshot.entries) {
6305
+ const identity = visibilityIdentity(entry.origin, entry.path);
6306
+ if (byIdentity.has(identity)) throw new Error(`knowledge visibility repeats path '${entry.path}' at origin '${entry.origin}'`);
6307
+ byIdentity.set(identity, entry);
6308
+ }
6309
+ return {
6310
+ snapshot,
6311
+ byIdentity
6312
+ };
6313
+ }
6314
+ function visibilityIdentity(origin, path) {
6315
+ return `${origin}\u0000${path}`;
6316
+ }
6317
+ function assertReceiptJoinsVisibility(receipt, index) {
6318
+ if (index.snapshot.snapshotDigest !== receipt.visibility.snapshotDigest || index.snapshot.entries.length !== receipt.visibility.pageCount) throw new Error("knowledge retrieval receipt does not match the supplied visibility snapshot");
6319
+ for (const result of receipt.results) {
6320
+ const entry = index.byIdentity.get(visibilityIdentity(result.origin, result.path));
6321
+ if (!entry || entry.pageId !== result.pageId || entry.pageDigest !== result.pageDigest) throw new Error(`knowledge retrieval result rank ${result.rank} is not in the visibility snapshot`);
6322
+ }
6323
+ }
6324
+ function assertSchemaVersion(value, label) {
6325
+ if (value === "2.0.0") return;
6326
+ throw new Error(`unsupported ${label} schemaVersion '${String(value)}'${value === "1.0.0" ? "; 1.0.0 records embed the visibility snapshot and have no reader, create a 2.0.0 record from the snapshot" : ""}`);
6327
+ }
6115
6328
  function visibilityMaterial(entries) {
6116
6329
  return {
6117
6330
  schemaVersion: KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION,
6118
6331
  digestAlgorithm: KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM,
6119
6332
  entries: entries.map((entry, position) => {
6333
+ if (!entry || typeof entry !== "object") throw new TypeError(`knowledge visibility[${position}] must be an object`);
6120
6334
  if (entry.position !== position) throw new Error(`knowledge visibility position mismatch: expected ${position}, observed ${entry.position}`);
6335
+ if (!Array.isArray(entry.sourceIds)) throw new TypeError(`knowledge visibility[${position}].sourceIds must be an array`);
6121
6336
  return {
6122
6337
  position,
6123
- pageId: nonEmpty(entry.pageId, `knowledge visibility[${position}].pageId`),
6338
+ pageId: nonEmpty$1(entry.pageId, `knowledge visibility[${position}].pageId`),
6124
6339
  origin: validateOrigin(entry.origin, `knowledge visibility[${position}].origin`),
6125
- path: nonEmpty(entry.path, `knowledge visibility[${position}].path`),
6340
+ path: nonEmpty$1(entry.path, `knowledge visibility[${position}].path`),
6126
6341
  pageDigest: digest(entry.pageDigest, `knowledge visibility[${position}].pageDigest`),
6127
- sourceIds: entry.sourceIds.map((sourceId, sourceIndex) => nonEmpty(sourceId, `knowledge visibility[${position}].sourceIds[${sourceIndex}]`)),
6342
+ sourceIds: entry.sourceIds.map((sourceId, sourceIndex) => nonEmpty$1(sourceId, `knowledge visibility[${position}].sourceIds[${sourceIndex}]`)),
6128
6343
  invalidated: Boolean(entry.invalidated)
6129
6344
  };
6130
6345
  })
@@ -6148,17 +6363,27 @@ function retrievalMaterial(input) {
6148
6363
  attributes: input.attributes
6149
6364
  };
6150
6365
  }
6366
+ /**
6367
+ * The actor identity a downstream record inherits from the retrieval that
6368
+ * authorized it. A record that re-declared these could disagree with the
6369
+ * receipt it references.
6370
+ */
6371
+ function retrievalIdentity(retrieval) {
6372
+ return {
6373
+ runId: retrieval.runId,
6374
+ ...retrieval.actorId === void 0 ? {} : { actorId: retrieval.actorId },
6375
+ ...retrieval.profileDigest === void 0 ? {} : { profileDigest: retrieval.profileDigest },
6376
+ ...retrieval.executionRef === void 0 ? {} : { executionRef: retrieval.executionRef },
6377
+ retrievalReceiptDigest: retrieval.receiptDigest
6378
+ };
6379
+ }
6151
6380
  function useMaterial(input) {
6152
6381
  return {
6153
6382
  schemaVersion: KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION,
6154
6383
  kind: "knowledge-use",
6155
6384
  digestAlgorithm: KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM,
6156
6385
  createdAt: input.createdAt,
6157
- runId: input.retrieval.runId,
6158
- ...input.retrieval.actorId === void 0 ? {} : { actorId: input.retrieval.actorId },
6159
- ...input.retrieval.profileDigest === void 0 ? {} : { profileDigest: input.retrieval.profileDigest },
6160
- ...input.retrieval.executionRef === void 0 ? {} : { executionRef: input.retrieval.executionRef },
6161
- retrievalReceiptDigest: input.retrieval.receiptDigest,
6386
+ ...retrievalIdentity(input.retrieval),
6162
6387
  used: input.used,
6163
6388
  relation: input.relation,
6164
6389
  consumer: input.consumer,
@@ -6166,28 +6391,42 @@ function useMaterial(input) {
6166
6391
  attributes: input.attributes
6167
6392
  };
6168
6393
  }
6169
- function normalizeRetrievalResults(results, visibility) {
6394
+ function dispositionMaterial(input) {
6395
+ return {
6396
+ schemaVersion: KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION,
6397
+ kind: "knowledge-retrieval-disposition",
6398
+ digestAlgorithm: KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM,
6399
+ createdAt: input.createdAt,
6400
+ ...retrievalIdentity(input.retrieval),
6401
+ relation: input.relation,
6402
+ consumer: input.consumer,
6403
+ evidenceRefs: input.evidenceRefs,
6404
+ attributes: input.attributes
6405
+ };
6406
+ }
6407
+ function validateDispositionRelation(value) {
6408
+ if (value !== "irrelevant" && value !== "no-use") throw new TypeError(`knowledge retrieval disposition relation is invalid: ${String(value)}`);
6409
+ return value;
6410
+ }
6411
+ function normalizeRetrievalResults(results, index) {
6170
6412
  if (!Array.isArray(results)) throw new TypeError("knowledge retrieval results must be an array");
6171
- const visible = new Map(visibility.entries.map((entry) => [`${entry.origin}\u0000${entry.path}`, entry]));
6172
6413
  const seenRanks = /* @__PURE__ */ new Set();
6173
6414
  const seenPages = /* @__PURE__ */ new Set();
6174
- const normalized = results.map((result, index) => {
6175
- if (!result || typeof result !== "object") throw new TypeError(`knowledge retrieval results[${index}] must be an object`);
6176
- if (!Number.isSafeInteger(result.rank) || result.rank < 1) throw new TypeError(`knowledge retrieval results[${index}].rank must be positive`);
6415
+ const normalized = results.map((result, position) => {
6416
+ if (!result || typeof result !== "object") throw new TypeError(`knowledge retrieval results[${position}] must be an object`);
6417
+ if (!Number.isSafeInteger(result.rank) || result.rank < 1) throw new TypeError(`knowledge retrieval results[${position}].rank must be positive`);
6177
6418
  if (seenRanks.has(result.rank)) throw new Error(`knowledge retrieval repeats rank ${result.rank}`);
6178
6419
  seenRanks.add(result.rank);
6179
- const origin = validateOrigin(result.origin, `knowledge retrieval results[${index}].origin`);
6420
+ const origin = validateOrigin(result.origin, `knowledge retrieval results[${position}].origin`);
6180
6421
  validateKnowledgePage(result.page);
6181
- const key = `${origin}\u0000${result.page.path}`;
6182
- if (seenPages.has(key)) throw new Error(`knowledge retrieval repeats page '${result.page.path}' at origin '${origin}'`);
6183
- seenPages.add(key);
6184
- const visibleEntry = visible.get(key);
6422
+ const identity = visibilityIdentity(origin, result.page.path);
6423
+ if (seenPages.has(identity)) throw new Error(`knowledge retrieval repeats page '${result.page.path}' at origin '${origin}'`);
6424
+ seenPages.add(identity);
6425
+ const visibleEntry = index.byIdentity.get(identity);
6185
6426
  if (!visibleEntry) throw new Error(`knowledge retrieval result '${result.page.path}' at origin '${origin}' was not visible`);
6186
6427
  const pageDigest = knowledgePageDigest(result.page);
6187
6428
  if (visibleEntry.pageId !== result.page.id || visibleEntry.pageDigest !== pageDigest) throw new Error(`knowledge retrieval result '${result.page.path}' does not match its visibility snapshot`);
6188
- finite(result.rrfScore, `knowledge retrieval results[${index}].rrfScore`);
6189
- finite(result.normalizedScore, `knowledge retrieval results[${index}].normalizedScore`);
6190
- if (result.normalizedScore < 0 || result.normalizedScore > 1) throw new TypeError(`knowledge retrieval results[${index}].normalizedScore must be in [0,1]`);
6429
+ assertResultScores(result, position);
6191
6430
  return Object.freeze({
6192
6431
  rank: result.rank,
6193
6432
  pageId: result.page.id,
@@ -6197,36 +6436,68 @@ function normalizeRetrievalResults(results, visibility) {
6197
6436
  rrfScore: result.rrfScore,
6198
6437
  normalizedScore: result.normalizedScore,
6199
6438
  snippet: typeof result.snippet === "string" ? result.snippet : "",
6200
- reasons: Object.freeze(result.reasons.map((reason, reasonIndex) => nonEmpty(reason, `knowledge retrieval results[${index}].reasons[${reasonIndex}]`)))
6439
+ reasons: Object.freeze(result.reasons.map((reason, reasonIndex) => nonEmpty$1(reason, `knowledge retrieval results[${position}].reasons[${reasonIndex}]`)))
6201
6440
  });
6202
6441
  });
6203
6442
  normalized.sort((left, right) => left.rank - right.rank);
6204
- normalized.forEach((result, index) => {
6205
- if (result.rank !== index + 1) throw new Error(`knowledge retrieval ranks must be contiguous from 1; expected ${index + 1}, observed ${result.rank}`);
6206
- });
6443
+ assertContiguousRanks(normalized);
6207
6444
  return Object.freeze(normalized);
6208
6445
  }
6209
- function validateReceiptResults(results, visibility) {
6210
- const visible = new Map(visibility.entries.map((entry) => [`${entry.origin}\u0000${entry.path}`, entry]));
6446
+ function validateReceiptResultShape(results, pageCount) {
6447
+ if (!Array.isArray(results)) throw new TypeError("knowledge retrieval results must be an array");
6448
+ if (results.length > pageCount) throw new Error(`knowledge retrieval returns ${results.length} results from ${pageCount} visible pages`);
6449
+ assertContiguousRanks(results);
6211
6450
  const seen = /* @__PURE__ */ new Set();
6212
- results.forEach((result, index) => {
6213
- if (result.rank !== index + 1) throw new Error(`knowledge retrieval ranks must be contiguous from 1; expected ${index + 1}, observed ${result.rank}`);
6214
- const key = `${validateOrigin(result.origin, `knowledge retrieval results[${index}].origin`)}\u0000${nonEmpty(result.path, `knowledge retrieval results[${index}].path`)}`;
6215
- if (seen.has(key)) throw new Error(`knowledge retrieval repeats visible page '${result.path}'`);
6216
- seen.add(key);
6217
- const entry = visible.get(key);
6218
- if (!entry || entry.pageId !== result.pageId || entry.pageDigest !== result.pageDigest) throw new Error(`knowledge retrieval result rank ${result.rank} is not in the visibility snapshot`);
6219
- finite(result.rrfScore, `knowledge retrieval results[${index}].rrfScore`);
6220
- finite(result.normalizedScore, `knowledge retrieval results[${index}].normalizedScore`);
6221
- if (result.normalizedScore < 0 || result.normalizedScore > 1) throw new TypeError(`knowledge retrieval results[${index}].normalizedScore must be in [0,1]`);
6222
- if (!Array.isArray(result.reasons)) throw new TypeError(`knowledge retrieval results[${index}].reasons must be an array`);
6451
+ results.forEach((result, position) => {
6452
+ if (!result || typeof result !== "object") throw new TypeError(`knowledge retrieval results[${position}] must be an object`);
6453
+ const identity = visibilityIdentity(validateOrigin(result.origin, `knowledge retrieval results[${position}].origin`), nonEmpty$1(result.path, `knowledge retrieval results[${position}].path`));
6454
+ if (seen.has(identity)) throw new Error(`knowledge retrieval repeats visible page '${result.path}'`);
6455
+ seen.add(identity);
6456
+ nonEmpty$1(result.pageId, `knowledge retrieval results[${position}].pageId`);
6457
+ digest(result.pageDigest, `knowledge retrieval results[${position}].pageDigest`);
6458
+ assertResultScores(result, position);
6459
+ if (typeof result.snippet !== "string") throw new TypeError(`knowledge retrieval results[${position}].snippet must be a string`);
6460
+ if (!Array.isArray(result.reasons)) throw new TypeError(`knowledge retrieval results[${position}].reasons must be an array`);
6461
+ });
6462
+ }
6463
+ /**
6464
+ * Ranks a retriever returned: one-based, unique, and contiguous, so a receipt
6465
+ * cannot hide a result by omitting its rank.
6466
+ */
6467
+ function assertContiguousRanks(results) {
6468
+ results.forEach((result, position) => {
6469
+ if (result.rank !== position + 1) throw new Error(`knowledge retrieval ranks must be contiguous from 1; expected ${position + 1}, observed ${result.rank}`);
6470
+ });
6471
+ }
6472
+ /** Scores a receipt may carry: finite, with the normalized score inside [0,1]. */
6473
+ function assertResultScores(result, position) {
6474
+ finite(result.rrfScore, `knowledge retrieval results[${position}].rrfScore`);
6475
+ finite(result.normalizedScore, `knowledge retrieval results[${position}].normalizedScore`);
6476
+ if (result.normalizedScore < 0 || result.normalizedScore > 1) throw new TypeError(`knowledge retrieval results[${position}].normalizedScore must be in [0,1]`);
6477
+ }
6478
+ function normalizeVisibilityRef(input) {
6479
+ if (!input || typeof input !== "object") throw new TypeError("knowledge retrieval visibility reference is required");
6480
+ if (!Number.isSafeInteger(input.pageCount) || input.pageCount < 0) throw new TypeError("knowledge retrieval visibility pageCount must be a non-negative integer");
6481
+ return Object.freeze({
6482
+ snapshotDigest: digest(input.snapshotDigest, "knowledge retrieval visibility snapshotDigest"),
6483
+ pageCount: input.pageCount,
6484
+ ...input.artifact === void 0 ? {} : { artifact: normalizeVisibilityArtifact(input.artifact, "knowledge retrieval visibility artifact") }
6485
+ });
6486
+ }
6487
+ function normalizeVisibilityArtifact(input, label) {
6488
+ if (!input || typeof input !== "object") throw new TypeError(`${label} must be an object`);
6489
+ if (!Number.isSafeInteger(input.byteLength) || input.byteLength < 1) throw new TypeError(`${label} byteLength must be a positive integer`);
6490
+ return Object.freeze({
6491
+ uri: nonEmpty$1(input.uri, `${label} uri`),
6492
+ digest: digest(input.digest, `${label} digest`),
6493
+ byteLength: input.byteLength
6223
6494
  });
6224
6495
  }
6225
6496
  function normalizeRetriever(input) {
6226
6497
  if (!input || typeof input !== "object") throw new TypeError("knowledge retriever identity is required");
6227
6498
  return Object.freeze({
6228
- id: nonEmpty(input.id, "knowledge retriever id"),
6229
- version: nonEmpty(input.version, "knowledge retriever version"),
6499
+ id: nonEmpty$1(input.id, "knowledge retriever id"),
6500
+ version: nonEmpty$1(input.version, "knowledge retriever version"),
6230
6501
  configDigest: digest(input.configDigest, "knowledge retriever configDigest")
6231
6502
  });
6232
6503
  }
@@ -6242,7 +6513,7 @@ function normalizeConsumer(input) {
6242
6513
  ].includes(input.kind)) throw new TypeError(`knowledge consumer kind is invalid: ${String(input.kind)}`);
6243
6514
  return Object.freeze({
6244
6515
  kind: input.kind,
6245
- uri: nonEmpty(input.uri, "knowledge consumer uri"),
6516
+ uri: nonEmpty$1(input.uri, "knowledge consumer uri"),
6246
6517
  ...input.digest === void 0 ? {} : { digest: digest(input.digest, "knowledge consumer digest") }
6247
6518
  });
6248
6519
  }
@@ -6259,8 +6530,8 @@ function normalizeEvidenceRefs(values) {
6259
6530
  if (!value || typeof value !== "object" || !allowed.includes(value.kind)) throw new TypeError(`knowledge evidenceRefs[${index}].kind is invalid`);
6260
6531
  return Object.freeze({
6261
6532
  kind: value.kind,
6262
- uri: nonEmpty(value.uri, `knowledge evidenceRefs[${index}].uri`),
6263
- ...value.excerpt === void 0 ? {} : { excerpt: nonEmpty(value.excerpt, `knowledge evidenceRefs[${index}].excerpt`) }
6533
+ uri: nonEmpty$1(value.uri, `knowledge evidenceRefs[${index}].uri`),
6534
+ ...value.excerpt === void 0 ? {} : { excerpt: nonEmpty$1(value.excerpt, `knowledge evidenceRefs[${index}].excerpt`) }
6264
6535
  });
6265
6536
  }));
6266
6537
  }
@@ -6268,7 +6539,7 @@ function normalizeAttributes(input) {
6268
6539
  if (!input || typeof input !== "object" || Array.isArray(input)) throw new TypeError("knowledge receipt attributes must be an object");
6269
6540
  const normalized = {};
6270
6541
  for (const [key, value] of Object.entries(input)) {
6271
- const name = nonEmpty(key, "knowledge receipt attribute key");
6542
+ const name = nonEmpty$1(key, "knowledge receipt attribute key");
6272
6543
  if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") throw new TypeError(`knowledge receipt attribute '${name}' has an unsupported value`);
6273
6544
  if (typeof value === "number") finite(value, `knowledge receipt attribute '${name}'`);
6274
6545
  normalized[name] = value;
@@ -6287,9 +6558,9 @@ function validateUseRelation(value) {
6287
6558
  }
6288
6559
  function validateKnowledgePage(page) {
6289
6560
  if (!page || typeof page !== "object") throw new TypeError("knowledge page must be an object");
6290
- nonEmpty(page.id, "knowledge page id");
6291
- nonEmpty(page.path, "knowledge page path");
6292
- nonEmpty(page.title, "knowledge page title");
6561
+ nonEmpty$1(page.id, "knowledge page id");
6562
+ nonEmpty$1(page.path, "knowledge page path");
6563
+ nonEmpty$1(page.title, "knowledge page title");
6293
6564
  if (typeof page.text !== "string") throw new TypeError("knowledge page text must be a string");
6294
6565
  if (!page.frontmatter || typeof page.frontmatter !== "object" || Array.isArray(page.frontmatter)) throw new TypeError("knowledge page frontmatter must be an object");
6295
6566
  for (const [name, values] of [
@@ -6311,12 +6582,12 @@ function digest(value, label) {
6311
6582
  function optionalDigest(value, label) {
6312
6583
  return value === void 0 ? void 0 : digest(value, label);
6313
6584
  }
6314
- function nonEmpty(value, label) {
6585
+ function nonEmpty$1(value, label) {
6315
6586
  if (typeof value !== "string" || value.trim().length === 0) throw new TypeError(`${label} must be a non-empty string`);
6316
6587
  return value.trim();
6317
6588
  }
6318
6589
  function optionalText(value, label) {
6319
- return value === void 0 ? void 0 : nonEmpty(value, label);
6590
+ return value === void 0 ? void 0 : nonEmpty$1(value, label);
6320
6591
  }
6321
6592
  function finite(value, label) {
6322
6593
  if (typeof value !== "number" || !Number.isFinite(value)) throw new TypeError(`${label} must be a finite number`);
@@ -6327,6 +6598,285 @@ function isoTimestamp(value, label) {
6327
6598
  return date.toISOString();
6328
6599
  }
6329
6600
  //#endregion
6601
+ //#region src/knowledge-tools.ts
6602
+ const searchInput = z.object({
6603
+ question: z.string().min(1),
6604
+ limit: z.int().min(1).max(50).optional()
6605
+ });
6606
+ const readInput = z.object({ pageId: z.string().min(1) });
6607
+ const recordInput = z.object({ proposal: z.string().min(1) });
6608
+ const resolveInput = z.object({ references: z.array(z.string().min(1)).min(1) });
6609
+ /**
6610
+ * The four tools an agent needs to use a knowledge store: search, read, record,
6611
+ * resolve.
6612
+ */
6613
+ function createKnowledgeTools(options) {
6614
+ const { stores, runId } = options;
6615
+ if (!stores || typeof stores.loadChain !== "function") throw new TypeError("knowledge tools require run-scoped stores");
6616
+ if (typeof runId !== "string" || runId.trim().length === 0) throw new TypeError("knowledge tools require a runId");
6617
+ if (typeof options.retrieverVersion !== "string" || options.retrieverVersion.trim() === "") throw new TypeError("knowledge tools require the running retrieverVersion");
6618
+ const pages = options.pagesDirectory === void 0 ? {} : { pagesDirectory: options.pagesDirectory };
6619
+ return [
6620
+ tool("knowledge_search", "Search the knowledge this run can see and return a brief with the ids to cite.", searchInput, async (input) => {
6621
+ const chain = await stores.loadChain(runId);
6622
+ const brief = buildKnowledgeBrief(chain, input.question, {
6623
+ ...options.brief,
6624
+ ...input.limit === void 0 ? {} : { limit: input.limit }
6625
+ });
6626
+ const receipt = createKnowledgeRetrievalReceipt({
6627
+ runId,
6628
+ ...options.actorId === void 0 ? {} : { actorId: options.actorId },
6629
+ query: brief.question,
6630
+ retriever: {
6631
+ id: brief.retrieverId,
6632
+ version: options.retrieverVersion,
6633
+ configDigest: brief.retrieverConfigDigest
6634
+ },
6635
+ visibility: createKnowledgeVisibilitySnapshot(chain),
6636
+ results: brief.results,
6637
+ createdAt: options.now?.()
6638
+ });
6639
+ await options.recordRetrieval?.(receipt);
6640
+ return {
6641
+ text: brief.text,
6642
+ citationIds: brief.citationIds,
6643
+ retrievalReceiptDigest: receipt.receiptDigest,
6644
+ receipt
6645
+ };
6646
+ }),
6647
+ tool("knowledge_read", "Read one page by its id, optionally qualified with here::, shared:: or inherited:<runId>::.", readInput, async (input) => {
6648
+ const resolution = resolveKnowledgeCitation(await stores.loadChain(runId), parseKnowledgeCitationReference(input.pageId));
6649
+ return {
6650
+ status: resolution.status,
6651
+ page: resolution.resolved === void 0 ? null : {
6652
+ pageId: resolution.resolved.page.id,
6653
+ origin: resolution.resolved.origin,
6654
+ path: resolution.resolved.page.path,
6655
+ title: resolution.resolved.page.title,
6656
+ text: resolution.resolved.page.text
6657
+ },
6658
+ candidates: resolution.candidates.map((candidate) => ({
6659
+ pageId: candidate.pageId,
6660
+ origin: candidate.origin,
6661
+ path: candidate.page.path
6662
+ }))
6663
+ };
6664
+ }),
6665
+ tool("knowledge_record", "Write pages into the store of this run from ---FILE: ...--- blocks.", recordInput, async (input) => {
6666
+ const intake = options.intake;
6667
+ return applyKnowledgeWriteBlocks(stores.storePath(runId), input.proposal, {
6668
+ ...pages,
6669
+ ...intake === void 0 ? {} : { intake: {
6670
+ ...intake,
6671
+ inheritedPages: await inheritedOf(stores, runId)
6672
+ } }
6673
+ });
6674
+ }),
6675
+ tool("knowledge_resolve", "Resolve page ids against everything this run can see, without hiding an ambiguity.", resolveInput, async (input) => ({ resolutions: (await resolveRunScopedCitations(stores, runId, input.references.map((reference) => parseKnowledgeCitationReference(reference)))).map((resolution) => ({
6676
+ pageId: resolution.reference.pageId,
6677
+ ...resolution.reference.origin === void 0 ? {} : { origin: resolution.reference.origin },
6678
+ status: resolution.status,
6679
+ candidates: resolution.candidates.map((candidate) => ({
6680
+ pageId: candidate.pageId,
6681
+ origin: candidate.origin,
6682
+ path: candidate.page.path
6683
+ }))
6684
+ })) }))
6685
+ ];
6686
+ }
6687
+ /** Everything the run can see except what it wrote, which the write path reads itself. */
6688
+ async function inheritedOf(stores, runId) {
6689
+ return (await stores.loadChain(runId)).filter((entry) => entry.origin !== "here");
6690
+ }
6691
+ function tool(name, description, inputSchema, handler) {
6692
+ return {
6693
+ name,
6694
+ description,
6695
+ inputSchema,
6696
+ inputSchemaJson: z.toJSONSchema(inputSchema),
6697
+ handler: (input) => handler(inputSchema.parse(input))
6698
+ };
6699
+ }
6700
+ //#endregion
6701
+ //#region src/promotion.ts
6702
+ /**
6703
+ * Run-scope to shared-scope promotion.
6704
+ *
6705
+ * A run writes only its own store. Knowledge reaches the curated shared store
6706
+ * through this call and no other, and every promotion leaves a record naming
6707
+ * the source run, the promoted bytes, the support carried with them, the actor,
6708
+ * and the reason.
6709
+ *
6710
+ * A claim's cited support travels with it. Promoting a claim while leaving the
6711
+ * run-local pages it cites behind is what turns a resolved citation into a
6712
+ * dangling one, so the closure of cited pages is carried and the promotion is
6713
+ * refused when any citation would not resolve in the target.
6714
+ */
6715
+ const KNOWLEDGE_PROMOTION_SCHEMA_VERSION = "1.0.0";
6716
+ const KNOWLEDGE_PROMOTION_DIGEST_ALGORITHM = "rfc8785-sha256";
6717
+ /** Root-relative directory holding one JSON record per promotion. */
6718
+ const KNOWLEDGE_PROMOTIONS_DIRECTORY = ".agent-knowledge/promotions";
6719
+ /** A promotion that cannot be performed exactly as asked. */
6720
+ var KnowledgePromotionError = class extends Error {
6721
+ code;
6722
+ constructor(code, message) {
6723
+ super(message);
6724
+ this.name = "KnowledgePromotionError";
6725
+ this.code = code;
6726
+ }
6727
+ };
6728
+ /**
6729
+ * Promote pages a run authored into the shared store, with their cited support.
6730
+ *
6731
+ * Support keeps its own evidence fields exactly as written, so a promoted claim
6732
+ * cannot inherit a confidence its support does not carry. Pages travel as the
6733
+ * bytes their store holds.
6734
+ *
6735
+ * Re-running the same promotion is safe: unchanged pages produce no file
6736
+ * mutation and the record is content-addressed, so it lands at the same path
6737
+ * with the same bytes.
6738
+ */
6739
+ async function promoteRunScopedPages(stores, runId, options) {
6740
+ const pagesDirectory = normalizePagesDirectory(options.pagesDirectory);
6741
+ const sharedRoot = nonEmpty(options.sharedRoot, "promotion sharedRoot");
6742
+ const actor = nonEmpty(options.actor, "promotion actor");
6743
+ const reason = nonEmpty(options.reason, "promotion reason");
6744
+ if (!Array.isArray(options.pageIds) || options.pageIds.length === 0) throw new TypeError("promotion pageIds must name at least one page");
6745
+ const travellers = collectTravellers(await stores.loadChain(runId), options.pageIds);
6746
+ await initKnowledgeBase(sharedRoot);
6747
+ return withKnowledgeMutation(sharedRoot, async (lock) => {
6748
+ const existing = await loadKnowledgePages(sharedRoot, { pagesDirectory });
6749
+ assertNoIdentityConflict(travellers, existing);
6750
+ const promotedPaths = new Set(travellers.map((traveller) => traveller.entry.page.path));
6751
+ assertKnowledgeCitationsResolved(originatedPages([...existing.filter((page) => !promotedPaths.has(page.path)), ...travellers.map((traveller) => traveller.entry.page)], "shared"), travellers.flatMap((traveller) => (traveller.entry.page.cites ?? []).map((persisted) => parseKnowledgeCitationReference(persisted))));
6752
+ const mutations = await Promise.all(travellers.map(async (traveller) => ({
6753
+ path: traveller.entry.page.path,
6754
+ content: await readPageBytes(stores, runId, traveller.entry)
6755
+ })));
6756
+ await commitKnowledgeFileMutations({
6757
+ root: sharedRoot,
6758
+ transactionRoot: lock.transactionRoot,
6759
+ purpose: `knowledge-promotion:${runId}`,
6760
+ mutations,
6761
+ pagesDirectory,
6762
+ assertOwned: lock.assertOwned
6763
+ });
6764
+ const record = buildRecord({
6765
+ runId,
6766
+ actor,
6767
+ reason,
6768
+ travellers,
6769
+ createdAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString()
6770
+ });
6771
+ await writeJsonDurableWithinRoot(sharedRoot, `${KNOWLEDGE_PROMOTIONS_DIRECTORY}/${record.recordDigest}.json`, record);
6772
+ return record;
6773
+ });
6774
+ }
6775
+ /** Read one promotion record written by `promoteRunScopedPages`. */
6776
+ async function loadKnowledgePromotionRecord(sharedRoot, recordDigest) {
6777
+ try {
6778
+ const snapshot = await readRegularFileWithinRoot(sharedRoot, `${KNOWLEDGE_PROMOTIONS_DIRECTORY}/${recordDigest}.json`);
6779
+ return JSON.parse(snapshot.bytes.toString("utf8"));
6780
+ } catch (error) {
6781
+ if (isMissingFile(error)) return null;
6782
+ throw error;
6783
+ }
6784
+ }
6785
+ /**
6786
+ * The requested pages plus the closure of the run-local pages they cite.
6787
+ *
6788
+ * A citation into the shared store needs no carrying, and an unresolved
6789
+ * citation is left to the target-side check, which reports every one of them
6790
+ * together rather than failing on the first.
6791
+ */
6792
+ function collectTravellers(chain, pageIds) {
6793
+ const byId = /* @__PURE__ */ new Map();
6794
+ const queue = [];
6795
+ for (const pageId of pageIds) {
6796
+ const authored = chain.filter((entry) => entry.origin === "here" && entry.page.id === pageId);
6797
+ if (authored.length === 0) throw new KnowledgePromotionError("unknown-page", `promotion page "${pageId}" was not authored by this run`);
6798
+ if (authored.length > 1) throw new KnowledgePromotionError("ambiguous-support", `promotion page "${pageId}" names ${authored.length} pages in this run`);
6799
+ queue.push({
6800
+ entry: authored[0],
6801
+ requested: true
6802
+ });
6803
+ }
6804
+ while (queue.length > 0) {
6805
+ const next = queue.shift();
6806
+ const seen = byId.get(next.entry.page.id);
6807
+ if (seen) {
6808
+ if (next.requested) seen.requested = true;
6809
+ if (seen.entry.page.path !== next.entry.page.path) throw new KnowledgePromotionError("ambiguous-support", `promotion support "${next.entry.page.id}" names more than one visible page`);
6810
+ continue;
6811
+ }
6812
+ byId.set(next.entry.page.id, {
6813
+ entry: next.entry,
6814
+ requested: next.requested
6815
+ });
6816
+ for (const persisted of next.entry.page.cites ?? []) {
6817
+ const target = resolveKnowledgeCitation(chain, parseKnowledgeCitationReference(persisted)).resolved;
6818
+ if (target === void 0 || target.origin === "shared") continue;
6819
+ queue.push({
6820
+ entry: {
6821
+ page: target.page,
6822
+ origin: target.origin
6823
+ },
6824
+ requested: false
6825
+ });
6826
+ }
6827
+ }
6828
+ return [...byId.values()].sort((left, right) => Number(right.requested) - Number(left.requested) || left.entry.page.path.localeCompare(right.entry.page.path));
6829
+ }
6830
+ function assertNoIdentityConflict(travellers, existing) {
6831
+ for (const traveller of travellers) {
6832
+ const page = traveller.entry.page;
6833
+ const idClash = existing.find((other) => other.id === page.id && other.path !== page.path);
6834
+ if (idClash) throw new KnowledgePromotionError("id-conflict", `shared page "${idClash.path}" already holds id "${page.id}"; promoting "${page.path}" would create two`);
6835
+ const pathClash = existing.find((other) => other.path === page.path && other.id !== page.id);
6836
+ if (pathClash) throw new KnowledgePromotionError("path-conflict", `shared page "${page.path}" holds id "${pathClash.id}", not "${page.id}"`);
6837
+ }
6838
+ }
6839
+ /**
6840
+ * The page as its own store holds it. A promoted page must be the same bytes
6841
+ * in both scopes, so the record's digest describes what a reader will load.
6842
+ */
6843
+ async function readPageBytes(stores, runId, entry) {
6844
+ const sourceRunId = sourceRunOf(entry.origin, runId);
6845
+ return (await readRegularFileWithinRoot(stores.storePath(sourceRunId), entry.page.path)).bytes.toString("utf8");
6846
+ }
6847
+ function sourceRunOf(origin, runId) {
6848
+ if (origin === "here") return runId;
6849
+ if (origin.startsWith("inherited:")) return origin.slice(10);
6850
+ throw new Error(`promotion cannot read the bytes of a ${origin} page`);
6851
+ }
6852
+ function buildRecord(input) {
6853
+ const entries = input.travellers.map((traveller) => Object.freeze({
6854
+ pageId: traveller.entry.page.id,
6855
+ path: traveller.entry.page.path,
6856
+ sourceOrigin: traveller.entry.origin,
6857
+ pageDigest: knowledgePageDigest(traveller.entry.page),
6858
+ requested: traveller.requested
6859
+ }));
6860
+ const material = {
6861
+ schemaVersion: KNOWLEDGE_PROMOTION_SCHEMA_VERSION,
6862
+ kind: "knowledge-promotion",
6863
+ digestAlgorithm: KNOWLEDGE_PROMOTION_DIGEST_ALGORITHM,
6864
+ createdAt: input.createdAt,
6865
+ runId: input.runId,
6866
+ actor: input.actor,
6867
+ reason: input.reason,
6868
+ entries
6869
+ };
6870
+ return Object.freeze({
6871
+ ...material,
6872
+ recordDigest: canonicalCandidateDigest(material)
6873
+ });
6874
+ }
6875
+ function nonEmpty(value, label) {
6876
+ if (typeof value !== "string" || value.trim().length === 0) throw new TypeError(`${label} must be a non-empty string`);
6877
+ return value.trim();
6878
+ }
6879
+ //#endregion
6330
6880
  //#region src/propose-from-finding.ts
6331
6881
  var KnowledgeProposalParseError = class extends Error {
6332
6882
  findingId;
@@ -6602,6 +7152,227 @@ async function evaluateKnowledgeBaseReadiness(options) {
6602
7152
  };
6603
7153
  }
6604
7154
  //#endregion
7155
+ //#region src/relation-graph.ts
7156
+ /** A relation graph input or query that cannot be honored exactly. */
7157
+ var KnowledgeRelationGraphError = class extends Error {
7158
+ code;
7159
+ constructor(code, message) {
7160
+ super(message);
7161
+ this.name = "KnowledgeRelationGraphError";
7162
+ this.code = code;
7163
+ }
7164
+ };
7165
+ /**
7166
+ * Build a labeled multi-edge graph from caller relations.
7167
+ *
7168
+ * The graph keeps one edge per `(sourceId, targetId, predicate)`, in first-seen
7169
+ * order. A repeated triple is accepted only when its weight and metadata are
7170
+ * identical in canonical JSON; any other repeat is a conflict and is refused.
7171
+ * Node and relation metadata must be finite, acyclic JSON so the graph
7172
+ * round-trips through `KnowledgeRelationGraphSchema` unchanged.
7173
+ */
7174
+ function buildKnowledgeRelationGraph(input) {
7175
+ const declared = input.nodes === void 0 ? void 0 : /* @__PURE__ */ new Map();
7176
+ const nodes = [];
7177
+ if (declared !== void 0) for (const [position, node] of input.nodes.entries()) {
7178
+ const normalized = normalizeNode(node, position);
7179
+ if (declared.has(normalized.id)) throw new KnowledgeRelationGraphError("duplicate-node", `node "${normalized.id}" is declared more than once`);
7180
+ declared.set(normalized.id, normalized);
7181
+ nodes.push(normalized);
7182
+ }
7183
+ const edges = [];
7184
+ const canonicalByTriple = /* @__PURE__ */ new Map();
7185
+ for (const [position, relation] of input.relations.entries()) {
7186
+ const normalized = normalizeRelation(relation, position);
7187
+ if (declared !== void 0) {
7188
+ for (const endpoint of [normalized.sourceId, normalized.targetId]) if (!declared.has(endpoint)) throw new KnowledgeRelationGraphError("undeclared-endpoint", `relation ${describeTriple(normalized)} names undeclared node "${endpoint}"`);
7189
+ }
7190
+ const canonical = canonicalRelationJson(normalized);
7191
+ const key = tripleKey(normalized);
7192
+ const prior = canonicalByTriple.get(key);
7193
+ if (prior !== void 0) {
7194
+ if (prior === canonical) continue;
7195
+ throw new KnowledgeRelationGraphError("duplicate-relation", `relation ${describeTriple(normalized)} is repeated with different weight or metadata`);
7196
+ }
7197
+ canonicalByTriple.set(key, canonical);
7198
+ edges.push(normalized);
7199
+ }
7200
+ return {
7201
+ nodes,
7202
+ edges
7203
+ };
7204
+ }
7205
+ /** Relations touching `id`, each with the node at the other end, in graph order. */
7206
+ function neighbors(graph, id, query) {
7207
+ const index = indexOf(graph);
7208
+ validateQuery(query);
7209
+ assertKnownNode(index, id);
7210
+ return neighborsOf(index, id, query);
7211
+ }
7212
+ /**
7213
+ * Breadth-first traversal from `id` over matching relations. Each reachable
7214
+ * node is reported once, at the depth where the search first reached it; the
7215
+ * start node is never reported, so a cycle back to it adds no step.
7216
+ */
7217
+ function walk(graph, id, options) {
7218
+ const index = indexOf(graph);
7219
+ validateQuery(options);
7220
+ validateMaxDepth(options.maxDepth);
7221
+ assertKnownNode(index, id);
7222
+ const steps = [];
7223
+ for (const step of traverse(index, id, options, options.maxDepth)) steps.push(step);
7224
+ return steps;
7225
+ }
7226
+ /**
7227
+ * Whether `to` is `from` or lies on a path of matching relations out of `from`.
7228
+ */
7229
+ function isReachable(graph, from, to, query) {
7230
+ const index = indexOf(graph);
7231
+ validateQuery(query);
7232
+ assertKnownNode(index, from);
7233
+ assertKnownNode(index, to);
7234
+ if (from === to) return true;
7235
+ for (const step of traverse(index, from, query, void 0)) if (step.nodeId === to) return true;
7236
+ return false;
7237
+ }
7238
+ const indexes = /* @__PURE__ */ new WeakMap();
7239
+ function indexOf(graph) {
7240
+ const cached = indexes.get(graph);
7241
+ if (cached !== void 0) return cached;
7242
+ const outgoing = /* @__PURE__ */ new Map();
7243
+ const incoming = /* @__PURE__ */ new Map();
7244
+ const known = /* @__PURE__ */ new Set();
7245
+ for (const node of graph.nodes) known.add(node.id);
7246
+ for (const relation of graph.edges) {
7247
+ known.add(relation.sourceId);
7248
+ known.add(relation.targetId);
7249
+ push(outgoing, relation.sourceId, relation);
7250
+ push(incoming, relation.targetId, relation);
7251
+ }
7252
+ const index = {
7253
+ outgoing,
7254
+ incoming,
7255
+ known
7256
+ };
7257
+ indexes.set(graph, index);
7258
+ return index;
7259
+ }
7260
+ function push(map, key, relation) {
7261
+ const list = map.get(key);
7262
+ if (list === void 0) map.set(key, [relation]);
7263
+ else list.push(relation);
7264
+ }
7265
+ function neighborsOf(index, id, query) {
7266
+ const matches = (relation) => query.predicate === void 0 || relation.predicate === query.predicate;
7267
+ const result = [];
7268
+ if (query.direction !== "in") {
7269
+ for (const relation of index.outgoing.get(id) ?? []) if (matches(relation)) result.push({
7270
+ nodeId: relation.targetId,
7271
+ relation
7272
+ });
7273
+ }
7274
+ if (query.direction !== "out") for (const relation of index.incoming.get(id) ?? []) {
7275
+ if (query.direction === "both" && relation.sourceId === id) continue;
7276
+ if (matches(relation)) result.push({
7277
+ nodeId: relation.sourceId,
7278
+ relation
7279
+ });
7280
+ }
7281
+ return result;
7282
+ }
7283
+ function* traverse(index, start, query, maxDepth) {
7284
+ const visited = /* @__PURE__ */ new Set([start]);
7285
+ const queue = [{
7286
+ nodeId: start,
7287
+ depth: 0
7288
+ }];
7289
+ for (let head = 0; head < queue.length; head++) {
7290
+ const current = queue[head];
7291
+ if (maxDepth !== void 0 && current.depth >= maxDepth) continue;
7292
+ for (const neighbor of neighborsOf(index, current.nodeId, query)) {
7293
+ if (visited.has(neighbor.nodeId)) continue;
7294
+ visited.add(neighbor.nodeId);
7295
+ const depth = current.depth + 1;
7296
+ yield {
7297
+ nodeId: neighbor.nodeId,
7298
+ depth,
7299
+ from: current.nodeId,
7300
+ relation: neighbor.relation
7301
+ };
7302
+ queue.push({
7303
+ nodeId: neighbor.nodeId,
7304
+ depth
7305
+ });
7306
+ }
7307
+ }
7308
+ }
7309
+ function assertKnownNode(index, id) {
7310
+ if (!index.known.has(id)) throw new KnowledgeRelationGraphError("unknown-node", `node "${id}" is not in the graph`);
7311
+ }
7312
+ function validateQuery(query) {
7313
+ if (query.direction !== "out" && query.direction !== "in" && query.direction !== "both") throw new KnowledgeRelationGraphError("invalid-query", `direction must be "out", "in", or "both", got ${JSON.stringify(query.direction)}`);
7314
+ if (query.predicate !== void 0 && !isNonEmptyString(query.predicate)) throw new KnowledgeRelationGraphError("invalid-query", "predicate must be a non-empty string");
7315
+ }
7316
+ function validateMaxDepth(maxDepth) {
7317
+ if (maxDepth === void 0) return;
7318
+ if (!Number.isInteger(maxDepth) || maxDepth < 0) throw new KnowledgeRelationGraphError("invalid-query", `maxDepth must be a non-negative integer, got ${JSON.stringify(maxDepth)}`);
7319
+ }
7320
+ function normalizeNode(node, position) {
7321
+ if (!isNonEmptyString(node.id)) throw new KnowledgeRelationGraphError("invalid-node", `node at ${position} has no id`);
7322
+ if (!isNonEmptyString(node.kind)) throw new KnowledgeRelationGraphError("invalid-node", `node "${node.id}" has no kind`);
7323
+ if (node.label !== void 0 && typeof node.label !== "string") throw new KnowledgeRelationGraphError("invalid-node", `node "${node.id}" label is not a string`);
7324
+ if (node.metadata !== void 0) assertCanonicalMetadata(node.metadata, `node "${node.id}"`, "invalid-node");
7325
+ return {
7326
+ id: node.id,
7327
+ kind: node.kind,
7328
+ ...node.label !== void 0 ? { label: node.label } : {},
7329
+ ...node.metadata !== void 0 ? { metadata: node.metadata } : {}
7330
+ };
7331
+ }
7332
+ function normalizeRelation(relation, position) {
7333
+ for (const field of [
7334
+ "sourceId",
7335
+ "targetId",
7336
+ "predicate"
7337
+ ]) if (!isNonEmptyString(relation[field])) throw new KnowledgeRelationGraphError("invalid-relation", `relation at ${position} has no ${field}`);
7338
+ if (relation.weight !== void 0 && !Number.isFinite(relation.weight)) throw new KnowledgeRelationGraphError("invalid-relation", `relation ${describeTriple(relation)} weight must be a finite number`);
7339
+ return {
7340
+ sourceId: relation.sourceId,
7341
+ targetId: relation.targetId,
7342
+ predicate: relation.predicate,
7343
+ ...relation.weight !== void 0 ? { weight: relation.weight } : {},
7344
+ ...relation.metadata !== void 0 ? { metadata: relation.metadata } : {}
7345
+ };
7346
+ }
7347
+ function canonicalRelationJson(relation) {
7348
+ if (relation.metadata !== void 0) assertCanonicalMetadata(relation.metadata, `relation ${describeTriple(relation)}`, "invalid-relation");
7349
+ return canonicalCandidateJson({
7350
+ ...relation.weight !== void 0 ? { weight: relation.weight } : {},
7351
+ ...relation.metadata !== void 0 ? { metadata: relation.metadata } : {}
7352
+ });
7353
+ }
7354
+ function assertCanonicalMetadata(metadata, subject, code) {
7355
+ if (metadata === null || typeof metadata !== "object" || Array.isArray(metadata)) throw new KnowledgeRelationGraphError(code, `${subject} metadata must be an object`);
7356
+ try {
7357
+ canonicalCandidateJson(metadata);
7358
+ } catch (error) {
7359
+ throw new KnowledgeRelationGraphError(code, `${subject} metadata must be finite, acyclic JSON: ${error instanceof Error ? error.message : String(error)}`);
7360
+ }
7361
+ }
7362
+ function tripleKey(relation) {
7363
+ return JSON.stringify([
7364
+ relation.sourceId,
7365
+ relation.targetId,
7366
+ relation.predicate
7367
+ ]);
7368
+ }
7369
+ function describeTriple(relation) {
7370
+ return `${relation.sourceId} -[${relation.predicate}]-> ${relation.targetId}`;
7371
+ }
7372
+ function isNonEmptyString(value) {
7373
+ return typeof value === "string" && value.length > 0;
7374
+ }
7375
+ //#endregion
6605
7376
  //#region src/release.ts
6606
7377
  function knowledgeReleaseReport(input) {
6607
7378
  const baselineRuns = input.baselineRuns ?? [];
@@ -7293,150 +8064,6 @@ function buildSteerText(gaps, deepQuestions, invalidationTargets, minIndependent
7293
8064
  return lines.join("\n");
7294
8065
  }
7295
8066
  //#endregion
7296
- //#region src/run-scoped.ts
7297
- /**
7298
- * Run-scoped knowledge stores with lineage-chain reads.
7299
- *
7300
- * One store exists per run, physically isolated, with inheritance only through
7301
- * declared ancestry. Reads expose the current store, every declared ancestor,
7302
- * and an optional curated shared store with an explicit origin label.
7303
- */
7304
- const RUN_LINEAGE_BASENAME = "lineage.json";
7305
- /** Ancestry beyond this bound is invalid durable state. */
7306
- const MAX_LINEAGE_HOPS = 64;
7307
- function createRunScopedStores(options) {
7308
- if (!options || typeof options !== "object") throw new TypeError("createRunScopedStores options are required");
7309
- if (typeof options.root !== "string" || options.root.trim().length === 0) throw new TypeError("createRunScopedStores root must be a non-empty string");
7310
- if (options.runStorePath !== void 0 && typeof options.runStorePath !== "function") throw new TypeError("createRunScopedStores runStorePath must be a function when present");
7311
- if (options.lineageAuthority !== void 0) validateLineageAuthority(options.lineageAuthority);
7312
- const storePath = options.runStorePath ?? ((runId) => join(options.root, runId, "knowledge-base"));
7313
- const internalAuthority = createFileRunLineageAuthority(storePath);
7314
- const authority = options.lineageAuthority ?? internalAuthority;
7315
- const resolveLineage = async (runId) => {
7316
- assertRunId(runId);
7317
- const chain = [];
7318
- const seen = /* @__PURE__ */ new Set([runId]);
7319
- let current = runId;
7320
- for (let hop = 0; hop <= MAX_LINEAGE_HOPS; hop += 1) {
7321
- const parent = await authority.parentOf(current);
7322
- if (parent === null) return chain;
7323
- assertRunId(parent, `parent of '${current}'`);
7324
- if (seen.has(parent)) throw new Error(`run lineage cycle: ${parent} is its own ancestor (via ${runId})`);
7325
- seen.add(parent);
7326
- chain.push(parent);
7327
- current = parent;
7328
- }
7329
- throw new Error(`run lineage for '${runId}' exceeds ${MAX_LINEAGE_HOPS} ancestors`);
7330
- };
7331
- return {
7332
- async init(runId, initOptions = {}) {
7333
- assertRunId(runId);
7334
- const parentRunId = initOptions.parentRunId ?? null;
7335
- if (parentRunId !== null) assertRunId(parentRunId, `parent of '${runId}'`);
7336
- if (!authority.record) {
7337
- const existingParent = await authority.parentOf(runId);
7338
- if (existingParent !== parentRunId) throw new Error(`external lineage authority disagrees for '${runId}': expected ${renderParent(parentRunId)}, observed ${renderParent(existingParent)}`);
7339
- }
7340
- const layout = await initKnowledgeBase(storePath(runId));
7341
- if (authority.record) await authority.record(Object.freeze({
7342
- runId,
7343
- parentRunId,
7344
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
7345
- }));
7346
- return layout;
7347
- },
7348
- lineage: resolveLineage,
7349
- async loadChain(runId) {
7350
- assertRunId(runId);
7351
- const out = [];
7352
- const readInto = async (root, origin) => {
7353
- let pages;
7354
- try {
7355
- pages = await loadKnowledgePages(root);
7356
- } catch (error) {
7357
- if (isMissingFile(error)) return;
7358
- throw error;
7359
- }
7360
- for (const page of pages) out.push({
7361
- page,
7362
- origin
7363
- });
7364
- };
7365
- await readInto(storePath(runId), "here");
7366
- for (const ancestor of await resolveLineage(runId)) await readInto(storePath(ancestor), `inherited:${ancestor}`);
7367
- if (options.sharedRoot) await readInto(options.sharedRoot, "shared");
7368
- return out;
7369
- }
7370
- };
7371
- }
7372
- /** File-backed authority used when the product has no separate run manifest. */
7373
- function createFileRunLineageAuthority(runStorePath) {
7374
- if (typeof runStorePath !== "function") throw new TypeError("createFileRunLineageAuthority requires a runStorePath function");
7375
- const readRecord = async (runId) => {
7376
- assertRunId(runId);
7377
- const root = runStorePath(runId);
7378
- try {
7379
- return parseLineageRecord((await readRegularFileWithinRoot(root, RUN_LINEAGE_BASENAME)).bytes.toString("utf8"), runId);
7380
- } catch (error) {
7381
- if (isMissingFile(error)) return null;
7382
- throw error;
7383
- }
7384
- };
7385
- return {
7386
- async parentOf(runId) {
7387
- return (await readRecord(runId))?.parentRunId ?? null;
7388
- },
7389
- async record(record) {
7390
- const validated = validateLineageRecord(record);
7391
- const root = runStorePath(validated.runId);
7392
- await withKnowledgeMutation(root, async () => {
7393
- const existing = await readRecord(validated.runId);
7394
- if (existing) {
7395
- if (existing.parentRunId !== validated.parentRunId) throw new Error(`run lineage conflict for '${validated.runId}': existing parent ${renderParent(existing.parentRunId)}, requested ${renderParent(validated.parentRunId)}`);
7396
- return;
7397
- }
7398
- await writeJson(join(root, RUN_LINEAGE_BASENAME), validated);
7399
- });
7400
- }
7401
- };
7402
- }
7403
- function validateLineageAuthority(authority) {
7404
- if (!authority || typeof authority !== "object") throw new TypeError("lineageAuthority must be an object");
7405
- if (typeof authority.parentOf !== "function") throw new TypeError("lineageAuthority.parentOf must be a function");
7406
- if (authority.record !== void 0 && typeof authority.record !== "function") throw new TypeError("lineageAuthority.record must be a function when present");
7407
- }
7408
- function parseLineageRecord(text, expectedRunId) {
7409
- let parsed;
7410
- try {
7411
- parsed = JSON.parse(text);
7412
- } catch (cause) {
7413
- throw new Error(`invalid lineage JSON for '${expectedRunId}'`, { cause });
7414
- }
7415
- const record = validateLineageRecord(parsed);
7416
- if (record.runId !== expectedRunId) throw new Error(`lineage record identity mismatch: expected '${expectedRunId}', found '${record.runId}'`);
7417
- return record;
7418
- }
7419
- function validateLineageRecord(value) {
7420
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("run lineage record must be an object");
7421
- const record = value;
7422
- assertRunId(record.runId, "lineage record runId");
7423
- if (record.parentRunId !== null) assertRunId(record.parentRunId, `parent of '${record.runId}'`);
7424
- if (typeof record.createdAt !== "string" || record.createdAt.trim().length === 0 || !Number.isFinite(Date.parse(record.createdAt))) throw new TypeError("run lineage record createdAt must be an ISO timestamp");
7425
- return {
7426
- runId: record.runId,
7427
- parentRunId: record.parentRunId,
7428
- createdAt: record.createdAt
7429
- };
7430
- }
7431
- function assertRunId(value, label = "runId") {
7432
- if (typeof value !== "string" || value.trim().length === 0) throw new TypeError(`${label} must be a non-empty string`);
7433
- const trimmed = value.trim();
7434
- if (trimmed === "." || trimmed === ".." || /[/\\\0]/.test(value)) throw new TypeError(`${label} must not contain path separators or dot segments`);
7435
- }
7436
- function renderParent(parentRunId) {
7437
- return parentRunId === null ? "none" : `'${parentRunId}'`;
7438
- }
7439
- //#endregion
7440
- export { AgentMemoryHitSchema, AgentMemoryKindSchema, AgentMemoryLifecycleTimeoutError, AgentMemoryLifecycleUnsafeError, AgentMemoryScopeSchema, AgentMemoryWriteInputSchema, CHECKABLE_RUNG_THRESHOLD, ClaimLedgerGoalConflictError, ClaimLedgerMigrationRequiredError, DEFAULT_MEMORY_CLEANUP_TIMEOUT_MS, DeepQuestionSchema, FileSystemKbStore, FileSystemSearchProvider, INDUSTRY_MEMORY_BENCHMARKS, INDUSTRY_RAG_BENCHMARKS, IRS_DIMENSION_HINTS, KB_CLAIM_LEDGER_DIR, KB_EVENTS_PATH, KB_INDEX_PATH, KB_STORE_DIR, KNOWLEDGE_EVENT_TYPES, KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM, KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION, KnowledgeBaseCandidateSchema, KnowledgeCitationAuditError, KnowledgeCitationResolutionError, KnowledgeEventSchema, KnowledgeGraphEdgeSchema, KnowledgeGraphNodeSchema, KnowledgeImprovementCandidateRefSchema, KnowledgeImprovementEvidenceSchema, KnowledgeImprovementRunStateSchema, KnowledgeIndexSchema, KnowledgePageInvalidationSchema, KnowledgePageSchema, KnowledgeProposalParseError, MAX_RESPONSE_BYTES, MIN_REQUEST_GAP_MS, MemoryKbStore, POLITE_USER_AGENT, READINESS_SPEC_DEFAULTS, RUN_LINEAGE_BASENAME, ResearchClaimEvidenceSchema, ResearchClaimLedgerSchema, ResearchClaimRecordSchema, ResearchSourceVersionSchema, RouterError, SCAFFOLD_PAGE_BASENAMES, SourceAnchorSchema, SourceRecordSchema, UncheckableClaimError, WIKILINK_REGEX, __resetHttpThrottle, acquireAgentMemoryRunLease, addSourcePath, addSourceText, agentMemorySequenceJudge, applyKnowledgeWriteBlocks, applyKnowledgeWriteBlocksFile, applyRetrievalHoldout, applySessionStickyRetrievalHoldout, assertClaimLedgerId, assertCurrentRunCitationsResolved, assertDeepQuestionIntegrity, assertGradeableEvidence, assertKnowledgeCitationAudit, assertKnowledgeCitationsResolved, assertKnowledgeRetrievalMatchesVisibility, assertResearchClaimEvidenceIntegrity, assertResearchClaimLedgerIntegrity, assertRunScopedCitationsResolved, assertTrackedClaimIntegrity, auditCurrentRunCitations, auditKnowledgeCitations, buildAgentMemorySequenceScenarios, buildAgentMemorySequencesFromBenchmarkCases, buildEvalKnowledgeBundle, buildFirstPartyMemoryLifecycleBenchmarkCases, buildIndustryMemoryBenchmarkSmokeCases, buildIndustryRagBenchmarkSmokeCases, buildKnowledgeBenchmarkScenarios, buildKnowledgeGraph, buildKnowledgeIndex, buildRetrievalBenchmarkCasesFromQrels, buildRetrievalEvalDispatch, calibrateRagAnswerJudge, canonicalizeUrl, chunkMarkdown, citedClaimKey, citedClaimOf, claimEvidenceId, claimId, claimSourceHost, compareAgentMemoryLearning, contentKey, createAdaptiveResearchDriver, createAgentMemoryBranch, createClaimDecorator, createClaimGroundingVerifier, createCollectionResearchDriver, createCornellLiiSource, createD1FreshnessStoreStub, createFileRunLineageAuthority, createFileSystemFreshnessStore, createFileSystemSearchProvider, createGraphitiMemoryAdapter, createInMemoryBenchmarkAdapter, createIrsPublicationsSource, createKnowledgeControlLoopAdapter, createKnowledgeEvent, createKnowledgeRetrievalReceipt, createKnowledgeUseReceipt, createKnowledgeVisibilitySnapshot, createLocalDiscoveryDispatcher, createMem0MemoryAdapter, createMemoryExecutionPool, createNeo4jAgentMemoryAdapter, createNoopMemoryBenchmarkAdapter, createPersistentResearchDrivingDriver, createRagAnswerQualityHook, createResearchDrivingDriver, createRunScopedStores, createStateSosSource, createTangleRouterClient, createVerifyingResearchDriver, createWebResearchWorker, deepQuestionId, defaultGetMemoryContext, defineReadinessSpec, detectChanges, detectNearDuplicatePages, deterministicRng, diagnoseRagAnswerFailure, emitRetrievalHoldoutBypass, emptyClaimLedger, evaluateKnowledgeBaseReadiness, explainKnowledgeTarget, extractLinks, extractWikilinks, firstMatch, forkAgentMemoryBranchSnapshot, formatFrontmatter, formatKnowledgeCitationReference, fromAgentCandidateKnowledgeRef, gradeCompanyAgainstText, gradeFactAgainstText, gradeFor, graphitiMemoryAdapterIdentity, groundClaimInText, hashKnowledgeBase, htmlToText, improveKnowledgeBase, improveSelectedKnowledgeCandidate, initKnowledgeBase, innerHtmlById, inspectKnowledgeIndex, inspectPendingKnowledgeMutation, investmentThesisSet, isKernelAnchoredPath, isKnowledgeMemoryBenchmarkCase, isMissingFile, isSafeKnowledgePath, isScaffoldPath, jsonCandidateCodec, jsonObjectCandidateCodec, kbIndexToText, knowledgeBenchmarkJudge, knowledgeCitationAuditFindings, knowledgeImprovementCandidateRef, knowledgeImprovementRunDir, knowledgeImprovementRunId, knowledgePageDigest, knowledgeReleaseReport, layoutFor, lensDistribution, linkClaimContradictions, lintCurrentRunCitations, lintKnowledgeIndex, listRegularFilesWithinRoot, loadKnowledgeImprovementActivationResult, loadKnowledgeImprovementEvents, loadKnowledgeImprovementState, loadKnowledgePages, loadSourceRegistry, looksLikeBlockPage, materialFactsSurfaced, materialFactsSurfacedInText, materializeRegisteredClaimEvidence, mediaTypeFor, mem0MemoryAdapterIdentity, memoryHitToSourceRecord, memoryRecoveryDelayMs, memoryWriteResultToSourceRecord, mergeClaimLedgers, mergeTrackedClaims, normalizeClaimText, normalizeExternalRagScores, normalizeLinkTarget, normalizePageText, optimizeKnowledgeBasePolicy, parseFrontmatter, parseKnowledgeBenchmarkJsonl, parseKnowledgeBenchmarkQrels, parseKnowledgeCitationReference, parseKnowledgeWriteBlocks, partitionRetrievalScenarios, politeFetch, promoteKnowledgeCandidate, proposeFromFinding, proposeFromFindings, ragAnswerQualityJudge, readRegularFileNoFollow, readRegularFileWithinRoot, reciprocalRankFusion, recoverPendingKnowledgeMutation, removeDurable, renameDurable, renderKnowledgeBenchmarkReportMarkdown, renderMemoryContext, researchSourceVersionKey, resetRetrievalHoldoutRegistry, resolveKnowledgeCitation, resolveKnowledgeCitations, resolveMemoryCleanupTimeoutMs, resolveRunScopedCitation, resolveRunScopedCitations, respondToIndustryMemoryBenchmarkSmokeCase, respondToIndustryRagBenchmarkSmokeCase, restoreKnowledgeCandidateBaseline, retrievalConfigFromSurface, retrievalConfigSurface, retrievalHoldoutConfigHash, retrievalRecallJudge, runAgentMemoryExperiment, runAgentMemoryImprovement, runAgentMemoryLearningExperiment, runBoundedMemoryLifecycle, runDiscoveryLoop, runInvestmentThesisTask, runKnowledgeBenchmarkSuite, runKnowledgeResearchLoop, runMemoryAdapterBenchmark, runRagKnowledgeImprovementLoop, runRagOptimization, runRetrievalImprovementLoop, runSerializedKnowledgeOptimization, runVerifiedResearchLoop, scenarioContentFingerprint, scoreKnowledgeBaseIndex, scoreKnowledgeBenchmarkArtifact, scoreMemoryBenchmarkArtifact, scoreRagAnswerArtifact, scoreRetrievalArtifact, searchKnowledge, sha256, sleepForMemoryRecovery, slugify, snapshotSourceTextInput, sourceMatchesGaps, sourceRegistryPath, stableId, stripFrontmatter, summarizeKnowledgeBenchmarkCampaign, syncDirectory, textSourceAdapter, textSourceId, thesisReadinessSpecs, toAgentCandidateKnowledgeRef, toDeepEvalTestCases, toOffPolicyTrajectory, toRagCheckerRecords, toRagasEvaluationRows, toTruLensRecords, tokenizeQuery, totalMaterialFacts, triageSource, validateKnowledgeIndex, verdictFor, verifyGradeableEvidence, verifyKnowledgeRetrievalReceipt, verifyKnowledgeUseReceipt, withCitedClaim, withKnowledgeImprovementCandidate, withKnowledgeImprovementComparison, withKnowledgeMutation, withKnowledgeRead, withSafeDescendant, withSafeDirectory, writeFileDurable, writeFileDurableWithinRoot, writeJson, writeJsonDurable, writeJsonDurableWithinRoot, writeKnowledgeIndex, writeSourceRegistry };
8067
+ export { AgentMemoryHitSchema, AgentMemoryKindSchema, AgentMemoryLifecycleTimeoutError, AgentMemoryLifecycleUnsafeError, AgentMemoryScopeSchema, AgentMemoryWriteInputSchema, CHECKABLE_RUNG_THRESHOLD, CITES_INVALIDATED_FIELD, ClaimLedgerGoalConflictError, ClaimLedgerMigrationRequiredError, DEFAULT_KNOWLEDGE_BRIEF_LIMIT, DEFAULT_MEMORY_CLEANUP_TIMEOUT_MS, DEFAULT_PAGES_DIRECTORY, DeepQuestionSchema, FileSystemKbStore, FileSystemSearchProvider, INDUSTRY_MEMORY_BENCHMARKS, INDUSTRY_RAG_BENCHMARKS, IRS_DIMENSION_HINTS, KB_CLAIM_LEDGER_DIR, KB_EVENTS_PATH, KB_INDEX_PATH, KB_STORE_DIR, KNOWLEDGE_EVENT_TYPES, KNOWLEDGE_PROMOTIONS_DIRECTORY, KNOWLEDGE_PROMOTION_DIGEST_ALGORITHM, KNOWLEDGE_PROMOTION_SCHEMA_VERSION, KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM, KNOWLEDGE_SEARCH_RETRIEVER_ID, KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION, KnowledgeBaseCandidateSchema, KnowledgeCitationAuditError, KnowledgeCitationResolutionError, KnowledgeDuplicateIntakeError, KnowledgeEventSchema, KnowledgeGraphEdgeSchema, KnowledgeGraphNodeSchema, KnowledgeImprovementCandidateRefSchema, KnowledgeImprovementEvidenceSchema, KnowledgeImprovementRunStateSchema, KnowledgeIndexSchema, KnowledgePageInvalidationSchema, KnowledgePageSchema, KnowledgePromotionError, KnowledgeProposalParseError, KnowledgeRelationGraphError, KnowledgeRelationGraphSchema, KnowledgeRelationNodeSchema, KnowledgeRelationSchema, KnowledgeVisibilityUnavailableError, MAX_RESPONSE_BYTES, MIN_REQUEST_GAP_MS, MemoryKbStore, POLITE_USER_AGENT, READINESS_SPEC_DEFAULTS, RUN_LINEAGE_BASENAME, ResearchClaimEvidenceSchema, ResearchClaimLedgerSchema, ResearchClaimRecordSchema, ResearchSourceVersionSchema, RouterError, SCAFFOLD_PAGE_BASENAMES, SourceAnchorSchema, SourceRecordSchema, UncheckableClaimError, WIKILINK_REGEX, __resetHttpThrottle, acquireAgentMemoryRunLease, addSourcePath, addSourceText, agentMemorySequenceJudge, applyKnowledgeWriteBlocks, applyKnowledgeWriteBlocksFile, applyRetrievalHoldout, applySessionStickyRetrievalHoldout, assertClaimLedgerId, assertCurrentRunCitationsResolved, assertDeepQuestionIntegrity, assertGradeableEvidence, assertKnowledgeCitationAudit, assertKnowledgeCitationsResolved, assertKnowledgeRetrievalMatchesVisibility, assertKnowledgeRetrievalMatchesVisibilityArtifact, assertKnowledgeWriteIntake, assertResearchClaimEvidenceIntegrity, assertResearchClaimLedgerIntegrity, assertRunScopedCitationsResolved, assertTrackedClaimIntegrity, auditCurrentRunCitations, auditKnowledgeCitations, buildAgentMemorySequenceScenarios, buildAgentMemorySequencesFromBenchmarkCases, buildEvalKnowledgeBundle, buildFirstPartyMemoryLifecycleBenchmarkCases, buildIndustryMemoryBenchmarkSmokeCases, buildIndustryRagBenchmarkSmokeCases, buildKnowledgeBenchmarkScenarios, buildKnowledgeBrief, buildKnowledgeGraph, buildKnowledgeIndex, buildKnowledgeLexicalIndex, buildKnowledgeRelationGraph, buildRetrievalBenchmarkCasesFromQrels, buildRetrievalEvalDispatch, calibrateRagAnswerJudge, canonicalizeUrl, chunkMarkdown, citedClaimKey, citedClaimOf, claimEvidenceId, claimId, claimSourceHost, compareAgentMemoryLearning, contentKey, createAdaptiveResearchDriver, createAgentMemoryBranch, createClaimDecorator, createClaimGroundingVerifier, createCollectionResearchDriver, createCornellLiiSource, createD1FreshnessStoreStub, createFileRunLineageAuthority, createFileSystemFreshnessStore, createFileSystemSearchProvider, createGraphitiMemoryAdapter, createInMemoryBenchmarkAdapter, createIrsPublicationsSource, createKnowledgeControlLoopAdapter, createKnowledgeEvent, createKnowledgeRetrievalDisposition, createKnowledgeRetrievalReceipt, createKnowledgeTools, createKnowledgeUseReceipt, createKnowledgeVisibilitySnapshot, createLocalDiscoveryDispatcher, createMem0MemoryAdapter, createMemoryExecutionPool, createNeo4jAgentMemoryAdapter, createNoopMemoryBenchmarkAdapter, createPersistentResearchDrivingDriver, createRagAnswerQualityHook, createResearchDrivingDriver, createRunScopedStores, createStateSosSource, createTangleRouterClient, createVerifyingResearchDriver, createWebResearchWorker, decodeKnowledgeVisibilitySnapshot, deepQuestionId, defaultGetMemoryContext, defineReadinessSpec, detectChanges, detectNearDuplicatePages, deterministicRng, diagnoseRagAnswerFailure, emitRetrievalHoldoutBypass, emptyClaimLedger, encodeKnowledgeVisibilitySnapshot, evaluateKnowledgeBaseReadiness, explainKnowledgeTarget, extractLinks, extractWikilinks, firstMatch, forkAgentMemoryBranchSnapshot, formatFrontmatter, formatKnowledgeCitationReference, formatKnowledgeInvalidationProposal, fromAgentCandidateKnowledgeRef, gradeCompanyAgainstText, gradeFactAgainstText, gradeFor, graphitiMemoryAdapterIdentity, groundClaimInText, hashKnowledgeBase, htmlToText, improveKnowledgeBase, improveSelectedKnowledgeCandidate, initKnowledgeBase, innerHtmlById, inspectKnowledgeIndex, inspectPendingKnowledgeMutation, investmentThesisSet, isKernelAnchoredPath, isKnowledgeMemoryBenchmarkCase, isKnowledgePagePath, isMissingFile, isReachable, isSafeKnowledgePath, isScaffoldPath, jsonCandidateCodec, jsonObjectCandidateCodec, kbIndexToText, knowledgeBenchmarkJudge, knowledgeCitationAuditFindings, knowledgeImprovementCandidateRef, knowledgeImprovementRunDir, knowledgeImprovementRunId, knowledgePageDigest, knowledgePageFromMarkdown, knowledgePageRelations, knowledgeReleaseReport, knowledgeVisibilityArtifactRef, layoutFor, lensDistribution, linkClaimContradictions, lintCurrentRunCitations, lintKnowledgeIndex, listRegularFilesWithinRoot, loadKnowledgeImprovementActivationResult, loadKnowledgeImprovementEvents, loadKnowledgeImprovementState, loadKnowledgePages, loadKnowledgePromotionRecord, loadSourceRegistry, looksLikeBlockPage, materialFactsSurfaced, materialFactsSurfacedInText, materializeRegisteredClaimEvidence, mediaTypeFor, mem0MemoryAdapterIdentity, memoryHitToSourceRecord, memoryRecoveryDelayMs, memoryWriteResultToSourceRecord, mergeClaimLedgers, mergeTrackedClaims, neighbors, normalizeClaimText, normalizeExternalRagScores, normalizeLinkTarget, normalizePageText, normalizePagesDirectory, optimizeKnowledgeBasePolicy, originatedPages, parseFrontmatter, parseKnowledgeBenchmarkJsonl, parseKnowledgeBenchmarkQrels, parseKnowledgeCitationReference, parseKnowledgeWriteBlocks, partitionRetrievalScenarios, planInvalidationPropagation, politeFetch, promoteKnowledgeCandidate, promoteRunScopedPages, proposeFromFinding, proposeFromFindings, ragAnswerQualityJudge, readRegularFileNoFollow, readRegularFileWithinRoot, reciprocalRankFusion, recoverPendingKnowledgeMutation, removeDurable, renameDurable, renderKnowledgeBenchmarkReportMarkdown, renderMemoryContext, researchSourceVersionKey, resetRetrievalHoldoutRegistry, resolveKnowledgeCitation, resolveKnowledgeCitations, resolveMemoryCleanupTimeoutMs, resolveRunScopedCitation, resolveRunScopedCitations, respondToIndustryMemoryBenchmarkSmokeCase, respondToIndustryRagBenchmarkSmokeCase, restoreKnowledgeCandidateBaseline, retrievalConfigFromSurface, retrievalConfigSurface, retrievalHoldoutConfigHash, retrievalRecallJudge, runAgentMemoryExperiment, runAgentMemoryImprovement, runAgentMemoryLearningExperiment, runBoundedMemoryLifecycle, runDiscoveryLoop, runInvestmentThesisTask, runKnowledgeBenchmarkSuite, runKnowledgeResearchLoop, runMemoryAdapterBenchmark, runRagKnowledgeImprovementLoop, runRagOptimization, runRetrievalImprovementLoop, runSerializedKnowledgeOptimization, runVerifiedResearchLoop, scenarioContentFingerprint, scoreBm25, scoreKnowledgeBaseIndex, scoreKnowledgeBenchmarkArtifact, scoreMemoryBenchmarkArtifact, scoreRagAnswerArtifact, scoreRetrievalArtifact, searchKnowledge, searchKnowledgePages, sha256, sleepForMemoryRecovery, slugify, snapshotSourceTextInput, sourceMatchesGaps, sourceRegistryPath, stableId, stripFrontmatter, summarizeKnowledgeBenchmarkCampaign, syncDirectory, textSourceAdapter, textSourceId, thesisReadinessSpecs, toAgentCandidateKnowledgeRef, toDeepEvalTestCases, toOffPolicyTrajectory, toRagCheckerRecords, toRagasEvaluationRows, toTruLensRecords, tokenizeQuery, tokenizeText, totalMaterialFacts, triageSource, validateKnowledgeIndex, verdictFor, verifyGradeableEvidence, verifyKnowledgeRetrievalDisposition, verifyKnowledgeRetrievalReceipt, verifyKnowledgeUseReceipt, verifyKnowledgeVisibilitySnapshot, walk, withCitedClaim, withKnowledgeImprovementCandidate, withKnowledgeImprovementComparison, withKnowledgeMutation, withKnowledgeRead, withSafeDescendant, withSafeDirectory, writeFileDurable, writeFileDurableWithinRoot, writeJson, writeJsonDurable, writeJsonDurableWithinRoot, writeKnowledgeIndex, writeSourceRegistry };
7441
8068
 
7442
8069
  //# sourceMappingURL=index.js.map