@tangle-network/agent-knowledge 20.0.1 → 22.0.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.
@@ -1,9 +1,10 @@
1
1
  import { i as textSourceId, n as slugify, r as stableId, t as sha256 } from "./ids-Bevz_pXV.js";
2
+ import { r as searchKnowledge } from "./search-BBr5eUyT.js";
2
3
  import { canonicalCandidateBytes, canonicalCandidateDigest, sha256Bytes, sha256DigestSchema } from "@tangle-network/agent-interface";
3
4
  import { contentHash } from "@tangle-network/agent-eval";
4
5
  import { z } from "zod";
5
6
  import { createHash, randomUUID } from "node:crypto";
6
- import { constants, lstatSync } from "node:fs";
7
+ import { closeSync, constants, fstatSync, lstatSync, openSync, readFileSync } from "node:fs";
7
8
  import { lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm } from "node:fs/promises";
8
9
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
9
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -399,6 +400,19 @@ function normalizePagesDirectory(value = DEFAULT_PAGES_DIRECTORY) {
399
400
  return normalized;
400
401
  }
401
402
  //#endregion
403
+ //#region src/bounded-file-io.ts
404
+ /** Keep filesystem descriptors bounded and drain a failed batch before its owner releases handles. */
405
+ async function mapFileIo(values, operation) {
406
+ const results = [];
407
+ for (let start = 0; start < values.length; start += 8) {
408
+ const batch = await Promise.allSettled(values.slice(start, start + 8).map((value, offset) => Promise.resolve().then(() => operation(value, start + offset))));
409
+ const failed = batch.find((result) => result.status === "rejected");
410
+ if (failed?.status === "rejected") throw failed.reason;
411
+ for (const result of batch) if (result.status === "fulfilled") results.push(result.value);
412
+ }
413
+ return results;
414
+ }
415
+ //#endregion
402
416
  //#region src/file-transaction.ts
403
417
  const digestSchema = z.string().regex(/^[a-f0-9]{64}$/);
404
418
  const fileModeSchema = z.number().int().min(0).max(511);
@@ -460,7 +474,7 @@ async function prepareKnowledgeFileTransaction(input) {
460
474
  const activeTransactions = await activeTransactionDirectoryNames(transactionRoot);
461
475
  if (activeTransactions.length > 0) throw new Error(`knowledge file transaction is already active: ${activeTransactions.join(", ")}`);
462
476
  const paths = /* @__PURE__ */ new Set();
463
- const changed = (await Promise.all(input.mutations.map(async (mutation, index) => {
477
+ const changed = (await mapFileIo(input.mutations, async (mutation, index) => {
464
478
  const path = assertKnowledgeMutationPath(mutation.path, boundPagesDirectory, input.researchState);
465
479
  if (paths.has(path)) throw new Error(`knowledge file transaction repeats path: ${path}`);
466
480
  if (mutation.content === null && mutation.mode !== void 0) throw new Error(`deleted knowledge file cannot declare a mode: ${path}`);
@@ -485,7 +499,7 @@ async function prepareKnowledgeFileTransaction(input) {
485
499
  before: before?.bytes ?? null,
486
500
  after
487
501
  };
488
- }))).filter((entry) => entry !== null);
502
+ })).filter((entry) => entry !== null);
489
503
  if (changed.length === 0) return null;
490
504
  const preparationDir = await mkdtemp(join(transactionRoot, "prepare-"));
491
505
  let activated = false;
@@ -504,10 +518,14 @@ async function prepareKnowledgeFileTransaction(input) {
504
518
  entries: changed.map((item) => item.entry)
505
519
  });
506
520
  for (const side of ["before", "after"]) if (changed.some((item) => item[side])) await mkdir(join(preparationDir, side));
507
- await Promise.all([...changed.flatMap((item) => ["before", "after"].flatMap((side) => {
521
+ await mapFileIo(changed.flatMap((item) => ["before", "after"].flatMap((side) => {
508
522
  const bytes = item[side];
509
- return bytes ? [writeFileDurable(snapshotPath(preparationDir, side, item.entry.index), bytes)] : [];
510
- })), writeJsonDurable(join(preparationDir, "transaction.json"), transaction)]);
523
+ return bytes ? [{
524
+ path: snapshotPath(preparationDir, side, item.entry.index),
525
+ bytes
526
+ }] : [];
527
+ })), (item) => writeFileDurable(item.path, item.bytes));
528
+ await writeJsonDurable(join(preparationDir, "transaction.json"), transaction);
511
529
  const activeDir = join(transactionRoot, activeTransactionDirectoryName(transaction.transactionId));
512
530
  await renameDurable(preparationDir, activeDir);
513
531
  activated = true;
@@ -621,8 +639,10 @@ async function applyKnowledgeFileTransaction(input) {
621
639
  });
622
640
  }
623
641
  async function assertKnowledgeFileTransactionApplied(root, transaction) {
624
- for (const entry of transaction.entries) await withSafeDescendant(root, entry.path, async (target) => {
625
- if (!fileMatches(await readRegularFile(target), entry.afterHash, entry.afterMode)) throw new Error(`knowledge file transaction did not commit: ${entry.path}`);
642
+ await mapFileIo(transaction.entries, async (entry) => {
643
+ await withSafeDescendant(root, entry.path, async (target) => {
644
+ if (!fileMatches(await readRegularFile(target), entry.afterHash, entry.afterMode)) throw new Error(`knowledge file transaction did not commit: ${entry.path}`);
645
+ });
626
646
  });
627
647
  }
628
648
  async function finishKnowledgeFileTransaction(input) {
@@ -774,8 +794,10 @@ async function assertKnowledgeFileTransactionTerminal(root, transaction, directi
774
794
  await assertKnowledgeFileTransactionApplied(root, transaction);
775
795
  return;
776
796
  }
777
- for (const entry of transaction.entries) await withSafeDescendant(root, entry.path, async (target) => {
778
- if (!fileMatches(await readRegularFile(target), entry.beforeHash, entry.beforeMode)) throw new Error(`knowledge file transaction did not roll back: ${entry.path}`);
797
+ await mapFileIo(transaction.entries, async (entry) => {
798
+ await withSafeDescendant(root, entry.path, async (target) => {
799
+ if (!fileMatches(await readRegularFile(target), entry.beforeHash, entry.beforeMode)) throw new Error(`knowledge file transaction did not roll back: ${entry.path}`);
800
+ });
779
801
  });
780
802
  }
781
803
  async function withTransactionRoot(root, transactionRoot, create, use) {
@@ -833,7 +855,7 @@ function knowledgeMutationPathPrefixes(pagesDirectory) {
833
855
  }
834
856
  function assertKnowledgeMutationPath(path, pagesDirectory, researchState = false) {
835
857
  const normalized = normalizeTransactionPath(path);
836
- if (normalized === SOURCE_REGISTRY_PATH || researchState && (normalized === ".agent-knowledge/events.json" || /^\.agent-knowledge\/claim-ledgers\/[^/]+\.json$/.test(normalized)) || knowledgeMutationPathPrefixes(pagesDirectory).some((prefix) => normalized.startsWith(prefix))) return normalized;
858
+ if (normalized === SOURCE_REGISTRY_PATH || researchState && (normalized === ".agent-knowledge/events.json" || normalized === "events.json" || /^(?:\.agent-knowledge\/)?event-log\/(?:state\.json|(?:records\/[a-f0-9]{64}|index\/[a-f0-9]{2,64})\.json)$/.test(normalized) || /^\.agent-knowledge\/claim-ledgers\/[^/]+\.json$/.test(normalized)) || knowledgeMutationPathPrefixes(pagesDirectory).some((prefix) => normalized.startsWith(prefix))) return normalized;
837
859
  throw new Error(`knowledge transaction contains an unsupported path: ${path}`);
838
860
  }
839
861
  function normalizeTransactionPath(path) {
@@ -2448,6 +2470,249 @@ function citedPageId(persisted) {
2448
2470
  }
2449
2471
  }
2450
2472
  //#endregion
2473
+ //#region src/event-store.ts
2474
+ /** Durable immutable event payloads with bounded, hash-partitioned metadata buckets. */
2475
+ const stateSchema = z.object({
2476
+ version: z.literal(1),
2477
+ sequence: z.number().int().nonnegative().safe(),
2478
+ count: z.number().int().nonnegative().safe()
2479
+ }).strict();
2480
+ const entrySchema = z.object({
2481
+ id: z.string().min(1),
2482
+ createdAt: z.string().min(1),
2483
+ type: KnowledgeEventSchema.shape.type,
2484
+ target: z.string().optional(),
2485
+ sequence: z.number().int().nonnegative().safe(),
2486
+ digest: z.string().regex(/^[a-f0-9]{64}$/)
2487
+ }).strict();
2488
+ const MAX_BUCKET_ENTRIES = 256;
2489
+ const bucketSchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("branch") }).strict(), z.object({
2490
+ kind: z.literal("leaf"),
2491
+ entries: z.array(entrySchema).max(MAX_BUCKET_ENTRIES)
2492
+ }).strict()]);
2493
+ const encode = (value) => `${JSON.stringify(value)}\n`;
2494
+ const recordPath = (directory, digest) => `${directory}/records/${digest}.json`;
2495
+ const bucketPath = (directory, prefix) => `${directory}/index/${prefix}.json`;
2496
+ async function readOptional(root, path) {
2497
+ try {
2498
+ return (await readRegularFileWithinRoot(root, path)).bytes;
2499
+ } catch (error) {
2500
+ if (isMissingFile(error)) return void 0;
2501
+ throw error;
2502
+ }
2503
+ }
2504
+ async function assertNoLegacy(root, path) {
2505
+ if (await withSafeDescendant(root, path, async (target) => {
2506
+ try {
2507
+ await lstat(target);
2508
+ return true;
2509
+ } catch (error) {
2510
+ if (isMissingFile(error)) return false;
2511
+ throw error;
2512
+ }
2513
+ })) throw new Error("legacy event history reappeared after migration; reconcile the older writer before proceeding");
2514
+ }
2515
+ function ordered(entries) {
2516
+ return entries.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.sequence - b.sequence);
2517
+ }
2518
+ async function putStoredEvent(root, legacyPath, event) {
2519
+ const directory = legacyPath === "events.json" ? "event-log" : ".agent-knowledge/event-log";
2520
+ const statePath = `${directory}/state.json`;
2521
+ const parsed = KnowledgeEventSchema.parse(structuredClone(event));
2522
+ const purpose = `event-put:${sha256(encode({
2523
+ legacyPath,
2524
+ event: parsed
2525
+ }))}`;
2526
+ await withKnowledgeMutation(root, async (lock) => {
2527
+ const saved = await readOptional(root, statePath);
2528
+ let sequence = 0;
2529
+ let count = 0;
2530
+ const mutations = /* @__PURE__ */ new Map();
2531
+ const add = (path, content) => mutations.set(path, {
2532
+ path,
2533
+ content
2534
+ });
2535
+ const bucketCache = /* @__PURE__ */ new Map();
2536
+ const writeBucket = (prefix, entries) => {
2537
+ const writeTree = (prefix, entries) => {
2538
+ if (entries.length <= MAX_BUCKET_ENTRIES) {
2539
+ const bucket = {
2540
+ kind: "leaf",
2541
+ entries: entries.sort((a, b) => a.id.localeCompare(b.id))
2542
+ };
2543
+ bucketCache.set(prefix, bucket);
2544
+ add(bucketPath(directory, prefix), encode(bucket));
2545
+ return;
2546
+ }
2547
+ if (prefix.length >= 64) throw new Error("event id hash collision");
2548
+ const branch = { kind: "branch" };
2549
+ bucketCache.set(prefix, branch);
2550
+ add(bucketPath(directory, prefix), encode(branch));
2551
+ const groups = /* @__PURE__ */ new Map();
2552
+ for (const entry of entries) {
2553
+ const child = sha256(entry.id).slice(0, prefix.length + 1);
2554
+ const group = groups.get(child) ?? [];
2555
+ group.push(entry);
2556
+ groups.set(child, group);
2557
+ }
2558
+ for (const [child, group] of groups) writeTree(child, group);
2559
+ };
2560
+ writeTree(prefix, entries);
2561
+ };
2562
+ const putIndexEntry = async (entry) => {
2563
+ const idHash = sha256(entry.id);
2564
+ for (let length = 2; length <= 64; length++) {
2565
+ const prefix = idHash.slice(0, length);
2566
+ let bucket = bucketCache.get(prefix);
2567
+ if (!bucket) {
2568
+ const bytes = await readOptional(root, bucketPath(directory, prefix));
2569
+ bucket = bytes ? parseBucket(prefix, bytes, sequence) : {
2570
+ kind: "leaf",
2571
+ entries: []
2572
+ };
2573
+ bucketCache.set(prefix, bucket);
2574
+ }
2575
+ if (bucket.kind === "branch") continue;
2576
+ if (!bucket.entries.some((value) => value.id === entry.id)) count += 1;
2577
+ writeBucket(prefix, [...bucket.entries.filter((value) => value.id !== entry.id), entry]);
2578
+ return;
2579
+ }
2580
+ throw new Error("event index has an invalid terminal branch");
2581
+ };
2582
+ const append = async (value) => {
2583
+ if (sequence >= Number.MAX_SAFE_INTEGER) throw new Error("event sequence exhausted");
2584
+ sequence += 1;
2585
+ const content = encode(value);
2586
+ const digest = sha256(content);
2587
+ add(recordPath(directory, digest), content);
2588
+ await putIndexEntry({
2589
+ id: value.id,
2590
+ createdAt: value.createdAt,
2591
+ type: value.type,
2592
+ ...value.target === void 0 ? {} : { target: value.target },
2593
+ sequence,
2594
+ digest
2595
+ });
2596
+ };
2597
+ if (saved) {
2598
+ const state = stateSchema.parse(JSON.parse(saved.toString("utf8")));
2599
+ sequence = state.sequence;
2600
+ count = state.count;
2601
+ await assertNoLegacy(root, legacyPath);
2602
+ } else {
2603
+ await assertEmptyLog(root, directory);
2604
+ const legacy = await readOptional(root, legacyPath);
2605
+ if (legacy) {
2606
+ const events = z.array(KnowledgeEventSchema).parse(JSON.parse(legacy.toString("utf8")));
2607
+ for (const value of events) await append(value);
2608
+ add(legacyPath, null);
2609
+ }
2610
+ }
2611
+ await append(parsed);
2612
+ add(statePath, encode({
2613
+ version: 1,
2614
+ sequence,
2615
+ count
2616
+ }));
2617
+ await commitKnowledgeFileMutations({
2618
+ root,
2619
+ transactionRoot: lock.transactionRoot,
2620
+ purpose,
2621
+ researchState: true,
2622
+ mutations: [...mutations.values()],
2623
+ assertOwned: lock.assertOwned
2624
+ });
2625
+ }, { resumeTransaction: { purpose } });
2626
+ }
2627
+ async function listStoredEvents(root, legacyPath, query) {
2628
+ const directory = legacyPath === "events.json" ? "event-log" : ".agent-knowledge/event-log";
2629
+ const statePath = `${directory}/state.json`;
2630
+ return withKnowledgeRead(root, async () => {
2631
+ const saved = await readOptional(root, statePath);
2632
+ if (!saved) {
2633
+ await assertEmptyLog(root, directory);
2634
+ const bytes = await readOptional(root, legacyPath);
2635
+ let events = bytes ? z.array(KnowledgeEventSchema).parse(JSON.parse(bytes.toString("utf8"))) : [];
2636
+ if (query.type) events = events.filter((event) => event.type === query.type);
2637
+ if (query.target) events = events.filter((event) => event.target === query.target);
2638
+ return events.slice(-(query.limit ?? events.length));
2639
+ }
2640
+ const state = stateSchema.parse(JSON.parse(saved.toString("utf8")));
2641
+ await assertNoLegacy(root, legacyPath);
2642
+ const entries = [];
2643
+ const buckets = /* @__PURE__ */ new Map();
2644
+ for (const file of await readEventIndex(root, `${directory}/index`)) {
2645
+ const prefix = file.path.slice(`${directory}/index/`.length, -5);
2646
+ buckets.set(prefix, parseBucket(prefix, file.bytes, state.sequence));
2647
+ }
2648
+ let count = 0;
2649
+ for (const [prefix, bucket] of buckets) {
2650
+ for (let length = 2; length < prefix.length; length++) if (buckets.get(prefix.slice(0, length))?.kind !== "branch") throw new Error("event index has an orphaned bucket");
2651
+ if (bucket.kind === "branch") {
2652
+ if (![...buckets.keys()].some((child) => child.length === prefix.length + 1 && child.startsWith(prefix))) throw new Error("event index branch has no children");
2653
+ continue;
2654
+ }
2655
+ count += bucket.entries.length;
2656
+ for (const entry of bucket.entries) {
2657
+ if (query.type && entry.type !== query.type) continue;
2658
+ if (query.target && entry.target !== query.target) continue;
2659
+ entries.push(entry);
2660
+ }
2661
+ }
2662
+ if (count !== state.count) throw new Error("event index entry count mismatch");
2663
+ return mapFileIo(ordered(entries).slice(-(query.limit ?? entries.length)), async (entry) => {
2664
+ const bytes = (await readRegularFileWithinRoot(root, recordPath(directory, entry.digest))).bytes;
2665
+ if (createHash("sha256").update(bytes).digest("hex") !== entry.digest) throw new Error("event payload digest mismatch");
2666
+ const event = KnowledgeEventSchema.parse(JSON.parse(bytes.toString("utf8")));
2667
+ if (event.id !== entry.id || event.createdAt !== entry.createdAt || event.type !== entry.type || event.target !== entry.target) throw new Error("event payload index mismatch");
2668
+ return event;
2669
+ });
2670
+ });
2671
+ }
2672
+ async function assertEmptyLog(root, directory) {
2673
+ try {
2674
+ if ((await listRegularFilesWithinRoot(root, directory)).length) throw new Error("event log state is missing; recover the log before proceeding");
2675
+ } catch (error) {
2676
+ if (!isMissingFile(error)) throw error;
2677
+ }
2678
+ }
2679
+ async function readEventIndex(root, relativeDirectory) {
2680
+ return withSafeDirectory(root, relativeDirectory, false, async (directory) => {
2681
+ const entries = await readdir(directory, { withFileTypes: true });
2682
+ const files = [];
2683
+ for (let start = 0; start < entries.length; start += 64) {
2684
+ if (start > 0) await new Promise((resolve) => setImmediate(resolve));
2685
+ for (const entry of entries.slice(start, start + 64)) {
2686
+ if (!entry.isFile() || !/^[a-f0-9]{2,64}\.json$/.test(entry.name)) throw new Error("event index contains an unsupported entry");
2687
+ const fd = openSync(join(directory, entry.name), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
2688
+ try {
2689
+ if (!fstatSync(fd).isFile()) throw new Error("event index contains an unsupported entry");
2690
+ files.push({
2691
+ path: `${relativeDirectory}/${entry.name}`,
2692
+ bytes: readFileSync(fd)
2693
+ });
2694
+ } finally {
2695
+ closeSync(fd);
2696
+ }
2697
+ }
2698
+ }
2699
+ return files;
2700
+ });
2701
+ }
2702
+ function parseBucket(prefix, bytes, sequence) {
2703
+ const bucket = bucketSchema.parse(JSON.parse(bytes.toString("utf8")));
2704
+ if (bucket.kind === "branch") {
2705
+ if (prefix.length >= 64) throw new Error("event index has an invalid terminal branch");
2706
+ return bucket;
2707
+ }
2708
+ const ids = /* @__PURE__ */ new Set();
2709
+ for (const entry of bucket.entries) {
2710
+ if (!sha256(entry.id).startsWith(prefix) || entry.sequence > sequence || ids.has(entry.id)) throw new Error("event index identity mismatch");
2711
+ ids.add(entry.id);
2712
+ }
2713
+ return bucket;
2714
+ }
2715
+ //#endregion
2451
2716
  //#region src/kb-store.ts
2452
2717
  /**
2453
2718
  * Where a filesystem knowledge base keeps its machine-written records, relative
@@ -2462,6 +2727,7 @@ function citedPageId(persisted) {
2462
2727
  */
2463
2728
  const KB_STORE_DIR = ".agent-knowledge";
2464
2729
  const KB_INDEX_PATH = `${KB_STORE_DIR}/index.json`;
2730
+ /** Legacy array import path; new events live in the adjacent event-log directory. */
2465
2731
  const KB_EVENTS_PATH = `${KB_STORE_DIR}/events.json`;
2466
2732
  const KB_CLAIM_LEDGER_DIR = `${KB_STORE_DIR}/claim-ledgers`;
2467
2733
  /**
@@ -2525,6 +2791,8 @@ var MemoryKbStore = class {
2525
2791
  };
2526
2792
  }
2527
2793
  async putEvent(event) {
2794
+ const position = this.events.findIndex((entry) => entry.id === event.id);
2795
+ if (position !== -1) this.events.splice(position, 1);
2528
2796
  this.events.push(clone(event));
2529
2797
  }
2530
2798
  async listEvents(query = {}) {
@@ -2551,7 +2819,6 @@ var MemoryKbStore = class {
2551
2819
  return clone(next);
2552
2820
  }
2553
2821
  };
2554
- const knowledgeEventsSchema = z.array(KnowledgeEventSchema);
2555
2822
  var FileSystemKbStore = class {
2556
2823
  root;
2557
2824
  indexPath;
@@ -2616,19 +2883,10 @@ var FileSystemKbStore = class {
2616
2883
  return withKnowledgeRead(this.root, () => this.readIndex());
2617
2884
  }
2618
2885
  async putEvent(event) {
2619
- const parsed = KnowledgeEventSchema.parse(event);
2620
- await withKnowledgeMutation(this.root, async () => {
2621
- const next = [...(await this.readEvents()).filter((entry) => entry.id !== parsed.id), parsed].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
2622
- await writeJsonDurableWithinRoot(this.root, this.eventsPath, next);
2623
- });
2886
+ await putStoredEvent(this.root, this.eventsPath, event);
2624
2887
  }
2625
2888
  async listEvents(query = {}) {
2626
- return withKnowledgeRead(this.root, async () => {
2627
- let events = await this.readEvents();
2628
- if (query.type) events = events.filter((event) => event.type === query.type);
2629
- if (query.target) events = events.filter((event) => event.target === query.target);
2630
- return clone(events.slice(-(query.limit ?? events.length)));
2631
- });
2889
+ return this.readEvents(query);
2632
2890
  }
2633
2891
  async putClaimLedger(ledger) {
2634
2892
  const parsed = parseResearchClaimLedger(ledger);
@@ -2678,8 +2936,8 @@ var FileSystemKbStore = class {
2678
2936
  async readIndex() {
2679
2937
  return readJsonFile(this.root, this.indexPath, KnowledgeIndexSchema);
2680
2938
  }
2681
- async readEvents() {
2682
- return await readJsonFile(this.root, this.eventsPath, knowledgeEventsSchema) ?? [];
2939
+ async readEvents(query = {}) {
2940
+ return listStoredEvents(this.root, this.eventsPath, query);
2683
2941
  }
2684
2942
  claimLedgerPath(id) {
2685
2943
  return `${this.claimLedgerDir}/${assertClaimLedgerId(id)}.json`;
@@ -4556,278 +4814,6 @@ function stringMetadata(metadata, key) {
4556
4814
  return typeof value === "string" ? value : void 0;
4557
4815
  }
4558
4816
  //#endregion
4559
- //#region src/lexical-postings.ts
4560
- const DEFAULT_FIELD_BOOSTS = Object.freeze({
4561
- title: 3,
4562
- path: 2,
4563
- text: 1
4564
- });
4565
- function lexicalPageTerms(page, tokenize, fieldBoosts) {
4566
- const frequencies = /* @__PURE__ */ new Map();
4567
- let length = 0;
4568
- for (const [text, boost] of [
4569
- [page.title, fieldBoosts.title],
4570
- [page.path.replace(/\.md$/, ""), fieldBoosts.path],
4571
- [page.text, fieldBoosts.text]
4572
- ]) {
4573
- if (boost === 0) continue;
4574
- for (const token of tokenize(text)) {
4575
- frequencies.set(token, (frequencies.get(token) ?? 0) + boost);
4576
- length += boost;
4577
- }
4578
- }
4579
- return {
4580
- frequencies,
4581
- length
4582
- };
4583
- }
4584
- /** Inverted index from per-page terms already computed with `tokenize` and `fieldBoosts`. */
4585
- function assembleLexicalIndex(pages, terms, tokenize, fieldBoosts) {
4586
- const postings = /* @__PURE__ */ new Map();
4587
- const documentLengths = [];
4588
- let totalLength = 0;
4589
- terms.forEach(({ frequencies, length }, ordinal) => {
4590
- documentLengths.push(length);
4591
- totalLength += length;
4592
- for (const [term, tf] of frequencies) {
4593
- let list = postings.get(term);
4594
- if (!list) {
4595
- list = [];
4596
- postings.set(term, list);
4597
- }
4598
- list.push({
4599
- ordinal,
4600
- tf
4601
- });
4602
- }
4603
- });
4604
- return {
4605
- pages,
4606
- postings,
4607
- documentLengths,
4608
- averageDocumentLength: pages.length > 0 ? totalLength / pages.length : 0,
4609
- documentCount: pages.length,
4610
- tokenize,
4611
- fieldBoosts
4612
- };
4613
- }
4614
- //#endregion
4615
- //#region src/lexical-index.ts
4616
- const STOP_WORDS = /* @__PURE__ */ new Set([
4617
- "the",
4618
- "is",
4619
- "a",
4620
- "an",
4621
- "what",
4622
- "how",
4623
- "are",
4624
- "was",
4625
- "were",
4626
- "to",
4627
- "for",
4628
- "of",
4629
- "with",
4630
- "by",
4631
- "in",
4632
- "on",
4633
- "and"
4634
- ]);
4635
- /**
4636
- * The token stream of one text: lower-cased, split on whitespace and
4637
- * punctuation, single characters and stop words removed, and a CJK run
4638
- * expanded into its bigrams and characters. Repeats are kept so a term
4639
- * frequency can be counted. Indexing and querying share this function, so the
4640
- * two vocabularies cannot drift.
4641
- */
4642
- function tokenizeText(text) {
4643
- const raw = text.toLowerCase().split(/[\s,,。!?、;:""''()()\-_/\\·~~…]+/).filter((token) => token.length > 1 && !STOP_WORDS.has(token));
4644
- const tokens = [];
4645
- for (const token of raw) {
4646
- if (/[\u4e00-\u9fff\u3400-\u4dbf]/.test(token) && token.length > 2) {
4647
- const chars = [...token];
4648
- for (let i = 0; i < chars.length - 1; i++) tokens.push(chars[i] + chars[i + 1]);
4649
- tokens.push(...chars);
4650
- }
4651
- tokens.push(token);
4652
- }
4653
- return tokens;
4654
- }
4655
- /** The distinct query terms, in first-occurrence order. */
4656
- function tokenizeQuery(query) {
4657
- return [...new Set(tokenizeText(query))];
4658
- }
4659
- function buildKnowledgeLexicalIndex(pages, options = {}) {
4660
- const tokenize = options.tokenize ?? tokenizeText;
4661
- const fieldBoosts = resolveFieldBoosts(options.fieldBoosts);
4662
- return assembleLexicalIndex(pages, pages.map((page) => lexicalPageTerms(page, tokenize, fieldBoosts)), tokenize, fieldBoosts);
4663
- }
4664
- /**
4665
- * Okapi BM25 over the distinct query terms, with the Lucene inverse document
4666
- * frequency `ln(1 + (N - df + 0.5) / (df + 0.5))`, which is positive for every
4667
- * indexed term. Pages with no matching term are absent. The result is ordered
4668
- * by score, then by path, so it does not depend on page order.
4669
- */
4670
- function scoreBm25(index, tokens, options = {}) {
4671
- const k1 = options.k1 ?? 1.2;
4672
- const b = options.b ?? .75;
4673
- if (!Number.isFinite(k1) || k1 < 0) throw new Error(`bm25 k1 must be >= 0, got ${String(k1)}`);
4674
- if (!Number.isFinite(b) || b < 0 || b > 1) throw new Error(`bm25 b must lie in [0, 1], got ${String(b)}`);
4675
- const scores = /* @__PURE__ */ new Map();
4676
- const { documentCount, averageDocumentLength, documentLengths } = index;
4677
- for (const term of new Set(tokens)) {
4678
- const list = index.postings.get(term);
4679
- if (!list) continue;
4680
- const df = list.length;
4681
- const idf = Math.log(1 + (documentCount - df + .5) / (df + .5));
4682
- for (const { ordinal, tf } of list) {
4683
- const lengthRatio = averageDocumentLength > 0 ? documentLengths[ordinal] / averageDocumentLength : 1;
4684
- const saturated = tf * (k1 + 1) / (tf + k1 * (1 - b + b * lengthRatio));
4685
- scores.set(ordinal, (scores.get(ordinal) ?? 0) + idf * saturated);
4686
- }
4687
- }
4688
- return [...scores.entries()].map(([ordinal, score]) => ({
4689
- page: index.pages[ordinal],
4690
- score
4691
- })).sort((left, right) => right.score - left.score || left.page.path.localeCompare(right.page.path));
4692
- }
4693
- function resolveFieldBoosts(boosts) {
4694
- const resolved = {
4695
- ...DEFAULT_FIELD_BOOSTS,
4696
- ...boosts
4697
- };
4698
- for (const [field, boost] of Object.entries(resolved)) if (!Number.isFinite(boost) || boost < 0) throw new Error(`lexical field boost ${field} must be >= 0, got ${String(boost)}`);
4699
- return Object.freeze(resolved);
4700
- }
4701
- //#endregion
4702
- //#region src/search.ts
4703
- const RRF_K = 60;
4704
- /**
4705
- * Identity of the ranking `searchKnowledge` performs: BM25 over title, path,
4706
- * and body, exact-title and phrase matches ahead of bag-of-words matches, and
4707
- * reciprocal rank fusion with link and shared-source structure. Declare it as
4708
- * the retriever id of a retrieval receipt minted from these results.
4709
- */
4710
- const KNOWLEDGE_SEARCH_RETRIEVER_ID = "bm25-rrf-v1";
4711
- function searchKnowledge(index, query, limitOrOptions = 10) {
4712
- return searchKnowledgePages(index.pages, query, limitOrOptions);
4713
- }
4714
- /**
4715
- * Rank a page set that is not a built index, such as the chain a run can see.
4716
- *
4717
- * `searchKnowledge` is this function over `index.pages`, so both entry points
4718
- * rank identically and neither can drift from the other.
4719
- */
4720
- function searchKnowledgePages(pages, query, limitOrOptions = 10) {
4721
- const trimmed = query.trim();
4722
- if (trimmed === "") return [];
4723
- const options = typeof limitOrOptions === "number" ? { limit: limitOrOptions } : { ...limitOrOptions };
4724
- const limit = options.limit ?? 10;
4725
- if (!Number.isInteger(limit) || limit < 0) throw new Error(`search limit must be a non-negative integer, got ${String(limit)}`);
4726
- const matched = filterPages(pages, options);
4727
- const lexicalRanked = rankLexical(matched, trimmed, options.lexicalIndex ? assertLexicalIndexMatches(options.lexicalIndex, pages) : buildKnowledgeLexicalIndex(pages));
4728
- const ranked = [...fuseRanks([lexicalRanked, rankByGraph(matched, lexicalRanked, pages)]).entries()].map(([page, score]) => ({
4729
- page,
4730
- score
4731
- })).sort((a, b) => b.score - a.score || comparePages(a.page, b.page)).slice(0, limit);
4732
- const topScore = ranked[0]?.score ?? 0;
4733
- return ranked.map((item, i) => ({
4734
- citationId: item.page.id,
4735
- page: item.page,
4736
- score: item.score,
4737
- rrfScore: item.score,
4738
- normalizedScore: topScore > 0 ? item.score / topScore : 0,
4739
- rank: i + 1,
4740
- snippet: buildSnippet(item.page.text, trimmed),
4741
- reasons: reasonsFor(item.page, trimmed)
4742
- }));
4743
- }
4744
- function reciprocalRankFusion(rankLists, k = RRF_K) {
4745
- return fuseRanks(rankLists, k);
4746
- }
4747
- function fuseRanks(rankLists, k = RRF_K) {
4748
- const scores = /* @__PURE__ */ new Map();
4749
- for (const list of rankLists) list.forEach((id, idx) => {
4750
- scores.set(id, (scores.get(id) ?? 0) + 1 / (k + idx + 1));
4751
- });
4752
- return scores;
4753
- }
4754
- function filterPages(pages, options) {
4755
- const pageIds = options.pageIds ? new Set(options.pageIds) : null;
4756
- const tags = options.tags ? new Set(options.tags) : null;
4757
- const kinds = options.kinds ? new Set(options.kinds) : null;
4758
- return pages.filter((page) => {
4759
- if (options.excludeInvalidated && page.invalidation !== void 0) return false;
4760
- if (pageIds && !pageIds.has(page.id)) return false;
4761
- if (tags && !page.tags.some((tag) => tags.has(tag))) return false;
4762
- if (kinds) {
4763
- const kind = page.frontmatter.kind;
4764
- if (typeof kind !== "string" || !kinds.has(kind)) return false;
4765
- }
4766
- return options.predicate?.(page) ?? true;
4767
- });
4768
- }
4769
- function assertLexicalIndexMatches(lexicalIndex, pages) {
4770
- if (lexicalIndex.pages.length !== pages.length || lexicalIndex.pages.some((page, ordinal) => page !== pages[ordinal])) throw new Error("lexical index was not built from the searched pages");
4771
- return lexicalIndex;
4772
- }
4773
- /**
4774
- * The lexical rank list. An exact title or path match outranks a title that
4775
- * contains the query, which outranks a body that contains the query, which
4776
- * outranks a bag-of-words match; BM25 orders pages inside each of those tiers.
4777
- * The tiers are an ordering, not a score, so a strong bag-of-words page cannot
4778
- * overtake an exact match by term repetition alone.
4779
- */
4780
- function rankLexical(pages, query, lexicalIndex) {
4781
- const tokens = [...new Set(lexicalIndex.tokenize(query))];
4782
- const bm25 = new Map(scoreBm25(lexicalIndex, tokens).map((hit) => [hit.page, hit.score]));
4783
- const phrase = query.toLowerCase();
4784
- return pages.flatMap((page) => {
4785
- const score = bm25.get(page) ?? 0;
4786
- if (score === 0 && tokens.length > 0) return [];
4787
- const tier = phraseTier(page, phrase);
4788
- if (score === 0 && tier === 0) return [];
4789
- return [{
4790
- page,
4791
- tier,
4792
- score
4793
- }];
4794
- }).sort((a, b) => b.tier - a.tier || b.score - a.score || comparePages(a.page, b.page)).map((item) => item.page);
4795
- }
4796
- function phraseTier(page, phrase) {
4797
- const title = page.title.toLowerCase();
4798
- if (title === phrase || page.path.toLowerCase().endsWith(`${phrase}.md`)) return 3;
4799
- if (title.includes(phrase)) return 2;
4800
- if (page.text.toLowerCase().includes(phrase)) return 1;
4801
- return 0;
4802
- }
4803
- function rankByGraph(pages, lexicalRanked, visiblePages) {
4804
- if (lexicalRanked.length === 0) return [];
4805
- const counts = /* @__PURE__ */ new Map();
4806
- for (const page of visiblePages) counts.set(page.id, (counts.get(page.id) ?? 0) + 1);
4807
- const seeds = new Set(lexicalRanked.slice(0, 5).filter((page) => counts.get(page.id) === 1).map((page) => page.id));
4808
- return pages.map((page) => ({
4809
- page,
4810
- score: page.outLinks.filter((link) => seeds.has(link)).length + page.sourceIds.filter((source) => lexicalRanked.some((seed) => seed.sourceIds.includes(source))).length
4811
- })).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || comparePages(a.page, b.page)).map((item) => item.page);
4812
- }
4813
- function comparePages(a, b) {
4814
- return a.path.localeCompare(b.path) || a.id.localeCompare(b.id);
4815
- }
4816
- function buildSnippet(text, query) {
4817
- const compact = text.replace(/\s+/g, " ").trim();
4818
- const idx = compact.toLowerCase().indexOf(query.toLowerCase());
4819
- if (idx < 0) return compact.slice(0, 180);
4820
- return compact.slice(Math.max(0, idx - 80), Math.min(compact.length, idx + query.length + 100));
4821
- }
4822
- function reasonsFor(page, query) {
4823
- const lower = `${page.title}\n${page.text}`.toLowerCase();
4824
- const reasons = [];
4825
- if (lower.includes(query.toLowerCase())) reasons.push("phrase");
4826
- if (page.sourceIds.length > 0) reasons.push("sourced");
4827
- if (page.outLinks.length > 0) reasons.push("linked");
4828
- return reasons;
4829
- }
4830
- //#endregion
4831
4817
  //#region src/inspect.ts
4832
4818
  function inspectKnowledgeIndex(index, options = {}) {
4833
4819
  const now = options.now ?? /* @__PURE__ */ new Date();
@@ -4891,6 +4877,6 @@ function explainKnowledgeTarget(index, target) {
4891
4877
  };
4892
4878
  }
4893
4879
  //#endregion
4894
- export { assertGradeableEvidence as $, removeDurable as $n, KnowledgeIndexSchema as $t, createKnowledgeVisibilitySnapshot as A, isKnowledgeMutationHeld as An, auditKnowledgeCitations as At, snapshotImmutableVisibility as B, knowledgeFileTransactionPlanHash as Bn, isScaffoldPath as Bt, createRunScopedStores as C, mergeTrackedClaims as Cn, KnowledgeCitationAuditError as Ct, KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM as D, parseFrontmatter as Dn, assertKnowledgeCitationsResolved as Dt, originatedPages as E, formatFrontmatter as En, assertKnowledgeCitationAudit as Et, knowledgePageDigest as F, withKnowledgeRead as Fn, resolveRunScopedCitation as Ft, visibilityIndexOf as G, canonicalPathsEqual as Gn, WIKILINK_REGEX as Gt, validateOrigin as H, rollbackKnowledgeFileTransaction as Hn, layoutFor as Ht, knowledgeVisibilityArtifactRef as I, applyKnowledgeFileTransaction as In, resolveRunScopedCitations as It, validateKnowledgeIndex as J, isMissingFile as Jn, DeepQuestionSchema as Jt, detectNearDuplicatePages as K, canonicalRelativeWithinRoot as Kn, extractWikilinks as Kt, nonEmpty as L, assertKnowledgeMutationPath as Ln, SCAFFOLD_PAGE_BASENAMES as Lt, digest as M, recoverPendingKnowledgeMutation as Mn, parseKnowledgeCitationReference as Mt, encodeKnowledgeVisibilitySnapshot as N, runInKnowledgeMutationScope as Nn, resolveKnowledgeCitation as Nt, KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION as O, acquireDurableFileLock as On, assertRunScopedCitationsResolved as Ot, immutablePageDigest as P, withKnowledgeMutation as Pn, resolveKnowledgeCitations as Pt, UncheckableClaimError as Q, relativeWithinRoot as Qn, KnowledgeGraphNodeSchema as Qt, normalizeVisibilityArtifact as R, commitKnowledgeFileMutations as Rn, initKnowledgeBase as Rt, createFileRunLineageAuthority as S, mergeClaimLedgers as Sn, knowledgePageRelations as St, loadKnowledgeToolChain as T, researchSourceVersionKey as Tn, assertCurrentRunCitationsResolved as Tt, verifyKnowledgeVisibilitySnapshot as U, DEFAULT_PAGES_DIRECTORY as Un, loadKnowledgePages as Ut, validateKnowledgePage as V, prepareKnowledgeFileTransaction as Vn, knowledgePageFromMarkdown as Vt, visibilityIdentity as W, normalizePagesDirectory as Wn, writeJson as Wt, CHECKABLE_RUNG_THRESHOLD as X, readRegularFileNoFollow as Xn, KnowledgeEventSchema as Xt, lintKnowledgeIndex as Y, listRegularFilesWithinRoot as Yn, KnowledgeBaseCandidateSchema as Yt, DEADLINE_EXIT_CODE as Z, readRegularFileWithinRoot as Zn, KnowledgeGraphEdgeSchema as Zt, isSafeKnowledgePath as _, claimSourceHost as _n, KB_INDEX_PATH as _t, searchKnowledge as a, ResearchClaimRecordSchema as an, writeFileDurableWithinRoot as ar, buildKnowledgeIndex as at, assertKnowledgeWriteIntake as b, linkClaimContradictions as bn, assertClaimLedgerId as bt, scoreBm25 as c, SourceRecordSchema as cn, mediaTypeFor$1 as cr, addSourceText as ct, DEFAULT_FIELD_BOOSTS as d, assertDeepQuestionIntegrity as dn, sourceRegistryPath as dt, KnowledgePageInvalidationSchema as en, renameDurable as er, claimCheckKey as et, assembleLexicalIndex as f, assertResearchClaimEvidenceIntegrity as fn, writeSourceRegistry as ft, applyKnowledgeWriteBlocksFile as g, claimId as gn, KB_EVENTS_PATH as gt, applyKnowledgeWriteBlocks as h, claimEvidenceId as hn, KB_CLAIM_LEDGER_DIR as ht, reciprocalRankFusion as i, ResearchClaimLedgerSchema as in, writeFileDurable as ir, verifyGradeableEvidence as it, decodeKnowledgeVisibilitySnapshot as j, measureKnowledgeMutation as jn, formatKnowledgeCitationReference as jt, assertSchemaVersion as k, inspectPendingKnowledgeMutation as kn, auditCurrentRunCitations as kt, tokenizeQuery as l, KNOWLEDGE_EVENT_TYPES as ln, textSourceAdapter as lr, loadSourceRegistry as lt, stringMetadata as m, assertTrackedClaimIntegrity as mn, FileSystemKbStore as mt, inspectKnowledgeIndex as n, KnowledgeRelationSchema as nn, withSafeDescendant as nr, gradeFor as nt, searchKnowledgePages as o, ResearchSourceVersionSchema as on, writeJsonDurable as or, writeKnowledgeIndex as ot, lexicalPageTerms as p, assertResearchClaimLedgerIntegrity as pn, ClaimLedgerMigrationRequiredError as pt, normalizePageText as q, isKernelAnchoredPath as qn, normalizeLinkTarget as qt, KNOWLEDGE_SEARCH_RETRIEVER_ID as r, ResearchClaimEvidenceSchema as rn, withSafeDirectory as rr, verdictFor as rt, buildKnowledgeLexicalIndex as s, SourceAnchorSchema as sn, writeJsonDurableWithinRoot as sr, addSourcePath as st, explainKnowledgeTarget as t, KnowledgePageSchema as tn, syncDirectory as tr, gradeClaims as tt, tokenizeText as u, ClaimLedgerGoalConflictError as un, snapshotSourceTextInput as ut, parseKnowledgeWriteBlocks as v, deepQuestionId as vn, KB_STORE_DIR as vt, isKnowledgeToolChain as w, normalizeClaimText as wn, KnowledgeCitationResolutionError as wt, RUN_LINEAGE_BASENAME as x, materializeRegisteredClaimEvidence as xn, buildKnowledgeGraph as xt, KnowledgeDuplicateIntakeError as y, emptyClaimLedger as yn, MemoryKbStore as yt, normalizeVisibilityRef as z, finishKnowledgeFileTransaction as zn, isKnowledgePagePath as zt };
4880
+ export { snapshotSourceTextInput as $, ClaimLedgerGoalConflictError as $t, validateKnowledgePage as A, prepareKnowledgeFileTransaction as An, knowledgePageFromMarkdown as At, DEADLINE_EXIT_CODE as B, readRegularFileWithinRoot as Bn, KnowledgeGraphEdgeSchema as Bt, immutablePageDigest as C, withKnowledgeMutation as Cn, resolveKnowledgeCitations as Ct, normalizeVisibilityArtifact as D, commitKnowledgeFileMutations as Dn, initKnowledgeBase as Dt, nonEmpty as E, assertKnowledgeMutationPath as En, SCAFFOLD_PAGE_BASENAMES as Et, detectNearDuplicatePages as F, canonicalRelativeWithinRoot as Fn, extractWikilinks as Ft, gradeFor as G, withSafeDescendant as Gn, KnowledgeRelationSchema as Gt, assertGradeableEvidence as H, removeDurable as Hn, KnowledgeIndexSchema as Ht, normalizePageText as I, isKernelAnchoredPath as In, normalizeLinkTarget as It, buildKnowledgeIndex as J, writeFileDurableWithinRoot as Jn, ResearchClaimRecordSchema as Jt, verdictFor as K, withSafeDirectory as Kn, ResearchClaimEvidenceSchema as Kt, validateKnowledgeIndex as L, isMissingFile as Ln, DeepQuestionSchema as Lt, verifyKnowledgeVisibilitySnapshot as M, DEFAULT_PAGES_DIRECTORY as Mn, loadKnowledgePages as Mt, visibilityIdentity as N, normalizePagesDirectory as Nn, writeJson as Nt, normalizeVisibilityRef as O, finishKnowledgeFileTransaction as On, isKnowledgePagePath as Ot, visibilityIndexOf as P, canonicalPathsEqual as Pn, WIKILINK_REGEX as Pt, loadSourceRegistry as Q, textSourceAdapter as Qn, KNOWLEDGE_EVENT_TYPES as Qt, lintKnowledgeIndex as R, listRegularFilesWithinRoot as Rn, KnowledgeBaseCandidateSchema as Rt, encodeKnowledgeVisibilitySnapshot as S, runInKnowledgeMutationScope as Sn, resolveKnowledgeCitation as St, knowledgeVisibilityArtifactRef as T, applyKnowledgeFileTransaction as Tn, resolveRunScopedCitations as Tt, claimCheckKey as U, renameDurable as Un, KnowledgePageInvalidationSchema as Ut, UncheckableClaimError as V, relativeWithinRoot as Vn, KnowledgeGraphNodeSchema as Vt, gradeClaims as W, syncDirectory as Wn, KnowledgePageSchema as Wt, addSourcePath as X, writeJsonDurableWithinRoot as Xn, SourceAnchorSchema as Xt, writeKnowledgeIndex as Y, writeJsonDurable as Yn, ResearchSourceVersionSchema as Yt, addSourceText as Z, mediaTypeFor$1 as Zn, SourceRecordSchema as Zt, KNOWLEDGE_USE_RECEIPT_SCHEMA_VERSION as _, acquireDurableFileLock as _n, assertRunScopedCitationsResolved as _t, applyKnowledgeWriteBlocksFile as a, claimId as an, KB_EVENTS_PATH as at, decodeKnowledgeVisibilitySnapshot as b, measureKnowledgeMutation as bn, formatKnowledgeCitationReference as bt, KnowledgeDuplicateIntakeError as c, emptyClaimLedger as cn, MemoryKbStore as ct, createFileRunLineageAuthority as d, mergeClaimLedgers as dn, knowledgePageRelations as dt, assertDeepQuestionIntegrity as en, sourceRegistryPath as et, createRunScopedStores as f, mergeTrackedClaims as fn, KnowledgeCitationAuditError as ft, KNOWLEDGE_RECEIPT_DIGEST_ALGORITHM as g, parseFrontmatter as gn, assertKnowledgeCitationsResolved as gt, originatedPages as h, formatFrontmatter as hn, assertKnowledgeCitationAudit as ht, applyKnowledgeWriteBlocks as i, claimEvidenceId as in, KB_CLAIM_LEDGER_DIR as it, validateOrigin as j, rollbackKnowledgeFileTransaction as jn, layoutFor as jt, snapshotImmutableVisibility as k, knowledgeFileTransactionPlanHash as kn, isScaffoldPath as kt, assertKnowledgeWriteIntake as l, linkClaimContradictions as ln, assertClaimLedgerId as lt, loadKnowledgeToolChain as m, researchSourceVersionKey as mn, assertCurrentRunCitationsResolved as mt, inspectKnowledgeIndex as n, assertResearchClaimLedgerIntegrity as nn, ClaimLedgerMigrationRequiredError as nt, isSafeKnowledgePath as o, claimSourceHost as on, KB_INDEX_PATH as ot, isKnowledgeToolChain as p, normalizeClaimText as pn, KnowledgeCitationResolutionError as pt, verifyGradeableEvidence as q, writeFileDurable as qn, ResearchClaimLedgerSchema as qt, stringMetadata as r, assertTrackedClaimIntegrity as rn, FileSystemKbStore as rt, parseKnowledgeWriteBlocks as s, deepQuestionId as sn, KB_STORE_DIR as st, explainKnowledgeTarget as t, assertResearchClaimEvidenceIntegrity as tn, writeSourceRegistry as tt, RUN_LINEAGE_BASENAME as u, materializeRegisteredClaimEvidence as un, buildKnowledgeGraph as ut, assertSchemaVersion as v, inspectPendingKnowledgeMutation as vn, auditCurrentRunCitations as vt, knowledgePageDigest as w, withKnowledgeRead as wn, resolveRunScopedCitation as wt, digest as x, recoverPendingKnowledgeMutation as xn, parseKnowledgeCitationReference as xt, createKnowledgeVisibilitySnapshot as y, isKnowledgeMutationHeld as yn, auditKnowledgeCitations as yt, CHECKABLE_RUNG_THRESHOLD as z, readRegularFileNoFollow as zn, KnowledgeEventSchema as zt };
4895
4881
 
4896
- //# sourceMappingURL=inspect-CMigdsD5.js.map
4882
+ //# sourceMappingURL=inspect-B1VI49Y9.js.map