@fortemi/core 2026.9.5 → 2026.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { v7, v5 } from 'uuid';
2
2
  import { sha256 } from '@noble/hashes/sha256';
3
3
  import { blake3 } from '@noble/hashes/blake3';
4
- import { bytesToHex } from '@noble/hashes/utils';
5
- import Ajv20203 from 'ajv/dist/2020.js';
4
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
5
+ import Ajv20206 from 'ajv/dist/2020.js';
6
6
  import { gzipSync, gunzipSync } from 'fflate';
7
7
  import { z } from 'zod';
8
8
 
@@ -24,9 +24,9 @@ var __export = (target, all) => {
24
24
  };
25
25
  var __copyProps = (to, from, except, desc) => {
26
26
  if (from && typeof from === "object" || typeof from === "function") {
27
- for (let key2 of __getOwnPropNames(from))
28
- if (!__hasOwnProp.call(to, key2) && key2 !== except)
29
- __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
27
+ for (let key3 of __getOwnPropNames(from))
28
+ if (!__hasOwnProp.call(to, key3) && key3 !== except)
29
+ __defProp(to, key3, { get: () => from[key3], enumerable: !(desc = __getOwnPropDesc(from, key3)) || desc.enumerable });
30
30
  }
31
31
  return to;
32
32
  };
@@ -1991,19 +1991,19 @@ var require_point = __commonJS({
1991
1991
  var Types = require_types();
1992
1992
  var BinaryWriter = require_binarywriter();
1993
1993
  var ZigZag = require_zigzag();
1994
- function Point2(x, y, z12, m, srid) {
1994
+ function Point2(x, y, z13, m, srid) {
1995
1995
  Geometry2.call(this);
1996
1996
  this.x = x;
1997
1997
  this.y = y;
1998
- this.z = z12;
1998
+ this.z = z13;
1999
1999
  this.m = m;
2000
2000
  this.srid = srid;
2001
2001
  this.hasZ = typeof this.z !== "undefined";
2002
2002
  this.hasM = typeof this.m !== "undefined";
2003
2003
  }
2004
2004
  util.inherits(Point2, Geometry2);
2005
- Point2.Z = function(x, y, z12, srid) {
2006
- var point = new Point2(x, y, z12, void 0, srid);
2005
+ Point2.Z = function(x, y, z13, srid) {
2006
+ var point = new Point2(x, y, z13, void 0, srid);
2007
2007
  point.hasZ = true;
2008
2008
  return point;
2009
2009
  };
@@ -2012,8 +2012,8 @@ var require_point = __commonJS({
2012
2012
  point.hasM = true;
2013
2013
  return point;
2014
2014
  };
2015
- Point2.ZM = function(x, y, z12, m, srid) {
2016
- var point = new Point2(x, y, z12, m, srid);
2015
+ Point2.ZM = function(x, y, z13, m, srid) {
2016
+ var point = new Point2(x, y, z13, m, srid);
2017
2017
  point.hasZ = true;
2018
2018
  point.hasM = true;
2019
2019
  return point;
@@ -2119,17 +2119,17 @@ var require_point = __commonJS({
2119
2119
  Point2.prototype._writeTwkbPoint = function(twkb, precision, previousPoint) {
2120
2120
  var x = this.x * precision.xyFactor;
2121
2121
  var y = this.y * precision.xyFactor;
2122
- var z12 = this.z * precision.zFactor;
2122
+ var z13 = this.z * precision.zFactor;
2123
2123
  var m = this.m * precision.mFactor;
2124
2124
  twkb.writeVarInt(ZigZag.encode(x - previousPoint.x));
2125
2125
  twkb.writeVarInt(ZigZag.encode(y - previousPoint.y));
2126
2126
  if (this.hasZ)
2127
- twkb.writeVarInt(ZigZag.encode(z12 - previousPoint.z));
2127
+ twkb.writeVarInt(ZigZag.encode(z13 - previousPoint.z));
2128
2128
  if (this.hasM)
2129
2129
  twkb.writeVarInt(ZigZag.encode(m - previousPoint.m));
2130
2130
  previousPoint.x = x;
2131
2131
  previousPoint.y = y;
2132
- previousPoint.z = z12;
2132
+ previousPoint.z = z13;
2133
2133
  previousPoint.m = m;
2134
2134
  };
2135
2135
  Point2.prototype._getWkbSize = function() {
@@ -3615,14 +3615,14 @@ var MemoryDatasetIngestStore = class {
3615
3615
  receipts: /* @__PURE__ */ new Map()
3616
3616
  };
3617
3617
  const draft = {
3618
- records: new Map([...existing.records].map(([key2, value]) => [key2, clone(value)])),
3619
- receipts: new Map([...existing.receipts].map(([key2, value]) => [key2, clone(value)])),
3618
+ records: new Map([...existing.records].map(([key3, value]) => [key3, clone(value)])),
3619
+ receipts: new Map([...existing.receipts].map(([key3, value]) => [key3, clone(value)])),
3620
3620
  ...existing.checkpoint ? { checkpoint: clone(existing.checkpoint) } : {}
3621
3621
  };
3622
3622
  const transaction = {
3623
3623
  getRecord: (id) => draft.records.get(id),
3624
3624
  setRecord: (record) => draft.records.set(record.logicalId, clone(record)),
3625
- getReceipt: (key2) => draft.receipts.get(key2),
3625
+ getReceipt: (key3) => draft.receipts.get(key3),
3626
3626
  setReceipt: (receipt) => draft.receipts.set(receipt.idempotencyKey, clone(receipt)),
3627
3627
  getCheckpoint: () => draft.checkpoint,
3628
3628
  setCheckpoint: (checkpoint) => {
@@ -3650,7 +3650,7 @@ var MemoryDatasetIngestStore = class {
3650
3650
  function canonicalJson(value) {
3651
3651
  if (value === null || typeof value !== "object") return JSON.stringify(value);
3652
3652
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
3653
- return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key2, item]) => `${JSON.stringify(key2)}:${canonicalJson(item)}`).join(",")}}`;
3653
+ return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson(item)}`).join(",")}}`;
3654
3654
  }
3655
3655
  function digest(value) {
3656
3656
  return computeHash(new TextEncoder().encode(canonicalJson(value)));
@@ -3819,11 +3819,11 @@ var DatasetIngestExecutor = class {
3819
3819
  return this.store.getReceipt(datasetDestinationScopeKey(plan.destination), deriveDatasetIngestIdempotencyKey(plan, batch));
3820
3820
  }
3821
3821
  status(scope, expectedSourceRevision) {
3822
- const key2 = datasetDestinationScopeKey(scope);
3823
- const lastSuccessful = this.successes.get(key2);
3822
+ const key3 = datasetDestinationScopeKey(scope);
3823
+ const lastSuccessful = this.successes.get(key3);
3824
3824
  return {
3825
3825
  scope: clone(scope),
3826
- ...this.attempts.get(key2) ? { lastAttempt: clone(this.attempts.get(key2)) } : {},
3826
+ ...this.attempts.get(key3) ? { lastAttempt: clone(this.attempts.get(key3)) } : {},
3827
3827
  ...lastSuccessful ? { lastSuccessful: clone(lastSuccessful) } : {},
3828
3828
  freshness: lastSuccessful ? expectedSourceRevision && expectedSourceRevision !== lastSuccessful.sourceRevision ? "stale" : "current" : "never"
3829
3829
  };
@@ -3877,7 +3877,7 @@ function canonicalJson2(value) {
3877
3877
  if (value === null || typeof value !== "object") return JSON.stringify(value);
3878
3878
  if (Array.isArray(value)) return `[${value.map(canonicalJson2).join(",")}]`;
3879
3879
  const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
3880
- return `{${entries.map(([key2, item]) => `${JSON.stringify(key2)}:${canonicalJson2(item)}`).join(",")}}`;
3880
+ return `{${entries.map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson2(item)}`).join(",")}}`;
3881
3881
  }
3882
3882
  function computeLineageDigest(value) {
3883
3883
  return computeHash(new TextEncoder().encode(canonicalJson2(value)));
@@ -3957,9 +3957,9 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
3957
3957
  if (item.payload !== void 0 && computeLineageDigest(item.payload) !== item.digest) {
3958
3958
  throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence ${item.id} payload does not match ${item.digest}`);
3959
3959
  }
3960
- const key2 = `${item.id}@${item.revision}`;
3961
- this.ensureUnique(this.evidence, key2, "evidence revision");
3962
- return this.append(this.evidence, key2, item);
3960
+ const key3 = `${item.id}@${item.revision}`;
3961
+ this.ensureUnique(this.evidence, key3, "evidence revision");
3962
+ return this.append(this.evidence, key3, item);
3963
3963
  }
3964
3964
  appendAssertion(assertion) {
3965
3965
  requireIdentity(assertion.id, "assertion.id");
@@ -3995,13 +3995,13 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
3995
3995
  if (item.digest !== reference.digest) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence reference digest differs for ${reference.evidenceId}`);
3996
3996
  if (reference.locator && reference.locator !== item.locator) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence locator differs for ${reference.evidenceId}`);
3997
3997
  }
3998
- const key2 = `${assertion.id}@${assertion.revision}`;
3999
- if (this.assertions.has(key2)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate assertion revision ${key2}`);
3998
+ const key3 = `${assertion.id}@${assertion.revision}`;
3999
+ if (this.assertions.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate assertion revision ${key3}`);
4000
4000
  const prior = [...this.assertions.values()].some((entry) => entry.value.id === assertion.id);
4001
4001
  if (prior && !this.hasReplacementPermission(assertion.id, assertion.revision)) {
4002
4002
  throw new LineageValidationError("CORRECTION_INVALID", `Assertion ${assertion.id} can only receive revision ${assertion.revision} after an explicit correction`);
4003
4003
  }
4004
- return this.append(this.assertions, key2, assertion);
4004
+ return this.append(this.assertions, key3, assertion);
4005
4005
  }
4006
4006
  appendCorrection(correction) {
4007
4007
  requireIdentity(correction.id, "correction.id");
@@ -4116,10 +4116,10 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
4116
4116
  const correction = pending.splice(index, 1)[0];
4117
4117
  ledger.appendCorrection(correction);
4118
4118
  if (correction.replacementAssertionId && correction.replacementRevision) {
4119
- const key2 = `${correction.replacementAssertionId}@${correction.replacementRevision}`;
4120
- if (!ledger.assertions.has(key2)) {
4121
- const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` === key2);
4122
- if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${key2}`);
4119
+ const key3 = `${correction.replacementAssertionId}@${correction.replacementRevision}`;
4120
+ if (!ledger.assertions.has(key3)) {
4121
+ const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` === key3);
4122
+ if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${key3}`);
4123
4123
  ledger.appendAssertion(replacement);
4124
4124
  }
4125
4125
  }
@@ -4167,19 +4167,19 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
4167
4167
  }
4168
4168
  });
4169
4169
  }
4170
- append(map, key2, value) {
4170
+ append(map, key3, value) {
4171
4171
  this.sequence += 1;
4172
- map.set(key2, { sequence: this.sequence, value: clone2(value) });
4172
+ map.set(key3, { sequence: this.sequence, value: clone2(value) });
4173
4173
  return this.sequence;
4174
4174
  }
4175
- ensureUnique(map, key2, label) {
4176
- if (map.has(key2)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate ${label} identity ${key2}`);
4175
+ ensureUnique(map, key3, label) {
4176
+ if (map.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate ${label} identity ${key3}`);
4177
4177
  }
4178
4178
  visibleAt(map, snapshot) {
4179
- return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([key2, entry]) => [key2, clone2(entry.value)]));
4179
+ return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([key3, entry]) => [key3, clone2(entry.value)]));
4180
4180
  }
4181
- sorted(map, key2 = (item) => item.id) {
4182
- return [...map.values()].sort((left, right) => key2(left).localeCompare(key2(right))).map(clone2);
4181
+ sorted(map, key3 = (item) => item.id) {
4182
+ return [...map.values()].sort((left, right) => key3(left).localeCompare(key3(right))).map(clone2);
4183
4183
  }
4184
4184
  hasReplacementPermission(assertionId, revision) {
4185
4185
  return [...this.corrections.values()].some((entry) => entry.value.action === "correct" && entry.value.replacementAssertionId === assertionId && entry.value.replacementRevision === revision);
@@ -4724,7 +4724,7 @@ var DATASET_EXECUTION_CAPABILITY_IDS = [
4724
4724
  var ID_SET = new Set(DATASET_EXECUTION_CAPABILITY_IDS);
4725
4725
  var LIMIT_KEYS = ["maxInputBytes", "maxRecordBytes", "maxBatchRecords", "maxConcurrency", "maxPageSize", "maxTraversalDepth"];
4726
4726
  var versionPattern = new RegExp(schema_default.$defs.semver.pattern);
4727
- var ajv = new Ajv20203({ strict: true, allErrors: false });
4727
+ var ajv = new Ajv20206({ strict: true, allErrors: false });
4728
4728
  ajv.addSchema(schema_default);
4729
4729
  var descriptorStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/descriptor" });
4730
4730
  var requestStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/request" });
@@ -4767,8 +4767,8 @@ function compareVersions(left, right) {
4767
4767
  function isSupported(capability) {
4768
4768
  return capability !== void 0 && (capability.status === "supported" || capability.status === "experimental");
4769
4769
  }
4770
- function structuralDiagnostics(validate3, prefix = "") {
4771
- return (validate3.errors ?? []).slice(0, 8).map((error) => ({
4770
+ function structuralDiagnostics(validate4, prefix = "") {
4771
+ return (validate4.errors ?? []).slice(0, 8).map((error) => ({
4772
4772
  code: "DESCRIPTOR_INVALID",
4773
4773
  path: (prefix + error.instancePath).slice(0, 256),
4774
4774
  message: "Invalid capability wire structure: " + error.keyword
@@ -4801,10 +4801,10 @@ function validateDatasetExecutionDescriptor(descriptor) {
4801
4801
  diagnostics.push({ code: "CAPABILITY_DUPLICATE", capability: capability.id, path: `/capabilities/${index}/id`, message: `Capability ${capability.id} is declared more than once` });
4802
4802
  }
4803
4803
  capabilities.set(capability.id, capability);
4804
- for (const key2 of LIMIT_KEYS) {
4805
- const value = capability.limits?.[key2];
4804
+ for (const key3 of LIMIT_KEYS) {
4805
+ const value = capability.limits?.[key3];
4806
4806
  if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0)) {
4807
- diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${key2}`, message: `${key2} must be a non-negative safe integer` });
4807
+ diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${key3}`, message: `${key3} must be a non-negative safe integer` });
4808
4808
  }
4809
4809
  }
4810
4810
  if (capability.status !== "unsupported" && capability.evidence.length === 0) {
@@ -4875,10 +4875,10 @@ function assessRequirement(requirement, capabilities) {
4875
4875
  return { ok: false, reason: "version-insufficient", diagnostics: [{ code: "CAPABILITY_VERSION_INSUFFICIENT", capability: requirement.id, message: `${capability.version} does not satisfy ${requirement.minimumVersion}` }] };
4876
4876
  }
4877
4877
  }
4878
- for (const key2 of LIMIT_KEYS) {
4879
- const required = requirement.minimumLimits?.[key2];
4880
- if (required !== void 0 && (capability.limits?.[key2] ?? -1) < required) {
4881
- return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${key2}`, message: `${key2} does not satisfy ${required}` }] };
4878
+ for (const key3 of LIMIT_KEYS) {
4879
+ const required = requirement.minimumLimits?.[key3];
4880
+ if (required !== void 0 && (capability.limits?.[key3] ?? -1) < required) {
4881
+ return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${key3}`, message: `${key3} does not satisfy ${required}` }] };
4882
4882
  }
4883
4883
  }
4884
4884
  return { ok: true, diagnostics: [] };
@@ -4986,7 +4986,7 @@ var encoder = new TextEncoder();
4986
4986
  function canonicalJson3(value) {
4987
4987
  if (value === null || typeof value !== "object") return JSON.stringify(value);
4988
4988
  if (Array.isArray(value)) return `[${value.map(canonicalJson3).join(",")}]`;
4989
- return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key2, item]) => `${JSON.stringify(key2)}:${canonicalJson3(item)}`).join(",")}}`;
4989
+ return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson3(item)}`).join(",")}}`;
4990
4990
  }
4991
4991
  function digestDatasetMaterializationValue(value) {
4992
4992
  return computeHash(encoder.encode(canonicalJson3(value)));
@@ -5077,7 +5077,7 @@ async function executeDatasetMaterialization(request, runtime, adapter, authoriz
5077
5077
  }
5078
5078
  const selected = [request.profile, ...options.fallbackProfiles ?? []].find((item) => item.id === negotiation.selectedProfile);
5079
5079
  try {
5080
- const validateConfiguration = new Ajv20203({ strict: true, allErrors: true }).compile(selected.configurationSchema);
5080
+ const validateConfiguration = new Ajv20206({ strict: true, allErrors: true }).compile(selected.configurationSchema);
5081
5081
  if (!validateConfiguration(request.configuration)) {
5082
5082
  throw new DatasetMaterializationError("CONFIGURATION_INVALID", `Configuration does not satisfy ${selected.id}: ${JSON.stringify(validateConfiguration.errors)}`);
5083
5083
  }
@@ -6877,7 +6877,7 @@ function nativeIdentityKey(spec, row) {
6877
6877
  // src/migrations/0031_native_shard_lineage.ts
6878
6878
  var triggers = Object.entries(nativeIdentities).flatMap(([component, spec]) => (component === "links" ? ["link", "link_url_target"] : [spec.table]).map((table) => `
6879
6879
  CREATE TRIGGER native_lineage_delete AFTER DELETE ON ${table} FOR EACH ROW
6880
- EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((key2) => `'${key2}'`).join(", ")});`)).join("\n");
6880
+ EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((key3) => `'${key3}'`).join(", ")});`)).join("\n");
6881
6881
  var migration0031 = {
6882
6882
  version: 31,
6883
6883
  name: "0031_native_shard_lineage",
@@ -6923,6 +6923,58 @@ var migration0032 = {
6923
6923
  `
6924
6924
  };
6925
6925
 
6926
+ // src/migrations/0033_typed_metadata_search.ts
6927
+ init_geometry_buffer();
6928
+ var migration0033 = {
6929
+ version: 33,
6930
+ name: "0033_typed_metadata_search",
6931
+ sql: `
6932
+ CREATE FUNCTION public.metadata_search_order_key_v1(value jsonb)
6933
+ RETURNS numeric LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
6934
+ SET search_path = pg_catalog
6935
+ AS $function$
6936
+ SELECT CASE jsonb_typeof(value)
6937
+ WHEN 'number' THEN trunc(greatest(-1e16::numeric,
6938
+ least(1e16::numeric, (value #>> '{}')::numeric)), 18)
6939
+ WHEN 'boolean' THEN CASE WHEN value = 'true'::jsonb THEN 1::numeric ELSE 0::numeric END
6940
+ ELSE NULL::numeric
6941
+ END
6942
+ $function$;
6943
+
6944
+ CREATE FUNCTION public.metadata_search_text_key_v1(value jsonb)
6945
+ RETURNS text LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
6946
+ SET search_path = pg_catalog
6947
+ AS $function$
6948
+ SELECT CASE WHEN jsonb_typeof(value) = 'string'
6949
+ THEN left(value #>> '{}', 256) ELSE NULL::text END
6950
+ $function$;
6951
+
6952
+ DO $metadata_indexes$
6953
+ DECLARE metadata_path text;
6954
+ BEGIN
6955
+ FOREACH metadata_path IN ARRAY ARRAY['provider', 'model', 'role', 'event_kind', 'sensitivity']
6956
+ LOOP
6957
+ -- Superseded unbounded indexes can reject large values before query rechecks.
6958
+ EXECUTE format('DROP INDEX %I', 'idx_note_metadata_' || metadata_path);
6959
+ EXECUTE format('DROP INDEX %I', 'idx_note_native_metadata_' || metadata_path);
6960
+ EXECUTE format(
6961
+ 'CREATE INDEX %I ON note (
6962
+ (jsonb_typeof(metadata -> %L)),
6963
+ (public.metadata_search_order_key_v1(metadata -> %L)),
6964
+ (public.metadata_search_text_key_v1(metadata -> %L) COLLATE "C"))',
6965
+ 'idx_note_metadata_' || metadata_path || '_v1', metadata_path, metadata_path, metadata_path);
6966
+ END LOOP;
6967
+ END
6968
+ $metadata_indexes$;
6969
+
6970
+ CREATE INDEX idx_source_identity_metadata_run_v1 ON source_identity
6971
+ (tenant_id, import_run_id COLLATE "C", note_id);
6972
+ CREATE INDEX idx_source_identity_metadata_note_v1 ON source_identity (tenant_id, note_id);
6973
+ UPDATE metadata_index_path SET value_type = 'json-scalar-v1', indexed_at = now()
6974
+ WHERE path IN ('provider', 'model', 'role', 'event_kind', 'sensitivity');
6975
+ `
6976
+ };
6977
+
6926
6978
  // src/migrations/index.ts
6927
6979
  var allMigrations = [
6928
6980
  migration0001,
@@ -6956,7 +7008,8 @@ var allMigrations = [
6956
7008
  migration0029,
6957
7009
  migration0030,
6958
7010
  migration0031,
6959
- migration0032
7011
+ migration0032,
7012
+ migration0033
6960
7013
  ];
6961
7014
 
6962
7015
  // src/data-archive.ts
@@ -7558,6 +7611,137 @@ var NotesRepository = class {
7558
7611
  // src/repositories/search-repository.ts
7559
7612
  init_geometry_buffer();
7560
7613
 
7614
+ // src/repositories/search-evidence-repository.ts
7615
+ init_geometry_buffer();
7616
+
7617
+ // src/search-evidence.ts
7618
+ init_geometry_buffer();
7619
+
7620
+ // schemas/metadata-search/candidate/1.0.0/evidence-locator.schema.json
7621
+ var evidence_locator_schema_default = {
7622
+ $schema: "https://json-schema.org/draft/2020-12/schema",
7623
+ $id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-locator.schema.json",
7624
+ title: "Candidate search evidence locator",
7625
+ type: "object",
7626
+ additionalProperties: false,
7627
+ required: ["version", "note_id", "unit", "content_digest", "span"],
7628
+ properties: {
7629
+ version: { const: "1.0.0" },
7630
+ note_id: { $ref: "#/$defs/identifier" },
7631
+ unit: {
7632
+ type: "object",
7633
+ additionalProperties: false,
7634
+ required: ["kind", "id", "index"],
7635
+ properties: {
7636
+ kind: { enum: ["current", "title", "embedding", "attachment"] },
7637
+ id: { $ref: "#/$defs/identifier" },
7638
+ index: { type: "integer", minimum: 0, maximum: 2147483647 }
7639
+ },
7640
+ if: { properties: { kind: { enum: ["current", "title", "attachment"] } } },
7641
+ then: { properties: { index: { const: 0 } } }
7642
+ },
7643
+ content_digest: { $ref: "#/$defs/digest" },
7644
+ span: {
7645
+ type: "object",
7646
+ additionalProperties: false,
7647
+ required: ["unit", "start", "end"],
7648
+ properties: {
7649
+ unit: { const: "utf8-bytes" },
7650
+ start: { type: "integer", minimum: 0, maximum: 16777216 },
7651
+ end: { type: "integer", minimum: 0, maximum: 16777216 }
7652
+ }
7653
+ },
7654
+ source: {
7655
+ type: "object",
7656
+ additionalProperties: false,
7657
+ required: ["namespace", "external_id_hash", "import_run_id", "schema_version"],
7658
+ properties: {
7659
+ namespace: { $ref: "#/$defs/identifier" },
7660
+ external_id_hash: { $ref: "#/$defs/digest" },
7661
+ import_run_id: { $ref: "#/$defs/identifier" },
7662
+ schema_version: { $ref: "#/$defs/identifier" }
7663
+ }
7664
+ }
7665
+ },
7666
+ $defs: {
7667
+ identifier: { type: "string", minLength: 1, maxLength: 200, pattern: "^[^\\u0000]+$" },
7668
+ digest: { type: "string", pattern: "^sha256:[a-f0-9]{64}$" }
7669
+ }
7670
+ };
7671
+
7672
+ // src/search-evidence.ts
7673
+ var MAX_EVIDENCE_BYTES = 16 * 1024 * 1024;
7674
+ var validateSchema = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(evidence_locator_schema_default);
7675
+ var encoder2 = new TextEncoder();
7676
+ var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
7677
+ var invalid = () => new Error("SEARCH_EVIDENCE_INVALID");
7678
+ var unavailable = () => new Error("SEARCH_EVIDENCE_UNAVAILABLE");
7679
+ function wellFormed(value) {
7680
+ for (let i = 0; i < value.length; i++) {
7681
+ const code = value.charCodeAt(i);
7682
+ if (code >= 55296 && code <= 56319) {
7683
+ const next = value.charCodeAt(++i);
7684
+ if (!(next >= 56320 && next <= 57343)) return false;
7685
+ } else if (code >= 56320 && code <= 57343) return false;
7686
+ }
7687
+ return true;
7688
+ }
7689
+ function parseSearchEvidenceLocator(value) {
7690
+ if (!validateSchema(value)) throw invalid();
7691
+ const locator = value;
7692
+ const strings = [locator.note_id, locator.unit.id, ...Object.values(locator.source ?? {})];
7693
+ if (!strings.every(wellFormed) || locator.span.start > locator.span.end) throw invalid();
7694
+ if ((locator.unit.kind === "current" || locator.unit.kind === "title") && locator.unit.id !== locator.note_id) throw invalid();
7695
+ const copy = {
7696
+ version: locator.version,
7697
+ note_id: locator.note_id,
7698
+ unit: Object.freeze({ kind: locator.unit.kind, id: locator.unit.id, index: locator.unit.index }),
7699
+ content_digest: locator.content_digest,
7700
+ span: Object.freeze({ unit: locator.span.unit, start: locator.span.start, end: locator.span.end }),
7701
+ ...locator.source === void 0 ? {} : { source: Object.freeze({ ...locator.source }) }
7702
+ };
7703
+ return Object.freeze(copy);
7704
+ }
7705
+ function textBytes(content) {
7706
+ if (typeof content !== "string" || content.length > MAX_EVIDENCE_BYTES || !wellFormed(content)) return null;
7707
+ const bytes = encoder2.encode(content);
7708
+ return bytes.length <= MAX_EVIDENCE_BYTES ? bytes : null;
7709
+ }
7710
+ function spanText(bytes, start, end) {
7711
+ if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || start > end || end > bytes.length) return null;
7712
+ if (start < bytes.length && (bytes[start] & 192) === 128 || end < bytes.length && (bytes[end] & 192) === 128) return null;
7713
+ try {
7714
+ return decoder.decode(bytes.subarray(start, end));
7715
+ } catch {
7716
+ return null;
7717
+ }
7718
+ }
7719
+ function bindSearchEvidence(text, start, end) {
7720
+ const bytes = textBytes(text.content);
7721
+ if (!bytes || spanText(bytes, start, end) === null) throw invalid();
7722
+ return parseSearchEvidenceLocator({
7723
+ version: "1.0.0",
7724
+ note_id: text.note_id,
7725
+ unit: text.unit,
7726
+ content_digest: computeHash(bytes),
7727
+ span: { unit: "utf8-bytes", start, end },
7728
+ ...text.source === void 0 ? {} : { source: text.source }
7729
+ });
7730
+ }
7731
+ function sameSource(a, b) {
7732
+ if (!a || !b) return a === b;
7733
+ return a.namespace === b.namespace && a.external_id_hash === b.external_id_hash && a.import_run_id === b.import_run_id && a.schema_version === b.schema_version;
7734
+ }
7735
+ function resolveSearchEvidence(value, text) {
7736
+ const locator = parseSearchEvidenceLocator(value);
7737
+ if (!text || locator.note_id !== text.note_id || locator.unit.kind !== text.unit.kind || locator.unit.id !== text.unit.id || locator.unit.index !== text.unit.index || !sameSource(locator.source, text.source)) throw unavailable();
7738
+ const bytes = textBytes(text.content);
7739
+ if (!bytes || computeHash(bytes) !== locator.content_digest) throw unavailable();
7740
+ const result = spanText(bytes, locator.span.start, locator.span.end);
7741
+ if (result === null) throw unavailable();
7742
+ return result;
7743
+ }
7744
+
7561
7745
  // src/repositories/condition-builder.ts
7562
7746
  init_geometry_buffer();
7563
7747
  function buildNoteConditions(options, startIdx, includeDeleted = false) {
@@ -7573,6 +7757,11 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
7573
7757
  );
7574
7758
  params.push(options.tags);
7575
7759
  }
7760
+ if (options.tagsAll?.length) {
7761
+ conditions.push(`NOT EXISTS (SELECT 1 FROM unnest($${idx++}::text[]) wanted(tag)
7762
+ WHERE NOT EXISTS (SELECT 1 FROM note_tag nt WHERE nt.note_id = n.id AND nt.tag = wanted.tag))`);
7763
+ params.push(options.tagsAll);
7764
+ }
7576
7765
  if (options.collection_id) {
7577
7766
  conditions.push(
7578
7767
  `EXISTS (SELECT 1 FROM collection_note cn WHERE cn.note_id = n.id AND cn.collection_id = $${idx++})`
@@ -7603,6 +7792,10 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
7603
7792
  conditions.push(`n.source = $${idx++}`);
7604
7793
  params.push(options.source);
7605
7794
  }
7795
+ if (options.sources?.length) {
7796
+ conditions.push(`n.source = ANY($${idx++}::text[])`);
7797
+ params.push(options.sources);
7798
+ }
7606
7799
  if (options.visibility) {
7607
7800
  conditions.push(`n.visibility = $${idx++}`);
7608
7801
  params.push(options.visibility);
@@ -7610,6 +7803,657 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
7610
7803
  return { conditions, params, nextIdx: idx };
7611
7804
  }
7612
7805
 
7806
+ // src/repositories/metadata-predicates.ts
7807
+ init_geometry_buffer();
7808
+
7809
+ // schemas/metadata-search/candidate/1.0.0/predicates.schema.json
7810
+ var predicates_schema_default = {
7811
+ $schema: "https://json-schema.org/draft/2020-12/schema",
7812
+ $id: "https://fortemi.dev/schemas/metadata-search/candidate/1.0.0/predicates.schema.json",
7813
+ title: "Candidate typed metadata predicates",
7814
+ type: "array",
7815
+ maxItems: 8,
7816
+ items: {
7817
+ $ref: "#/$defs/predicate"
7818
+ },
7819
+ $defs: {
7820
+ scalar: {
7821
+ oneOf: [
7822
+ {
7823
+ type: "string",
7824
+ maxLength: 256,
7825
+ pattern: "^[^\\u0000]*$"
7826
+ },
7827
+ {
7828
+ type: "number",
7829
+ minimum: -9007199254740991,
7830
+ maximum: 9007199254740991
7831
+ },
7832
+ {
7833
+ type: "boolean"
7834
+ },
7835
+ {
7836
+ type: "null"
7837
+ }
7838
+ ]
7839
+ },
7840
+ bound: {
7841
+ oneOf: [
7842
+ {
7843
+ type: "string",
7844
+ maxLength: 256,
7845
+ pattern: "^[^\\u0000]*$"
7846
+ },
7847
+ {
7848
+ type: "number",
7849
+ minimum: -9007199254740991,
7850
+ maximum: 9007199254740991
7851
+ }
7852
+ ]
7853
+ },
7854
+ predicate: {
7855
+ oneOf: [
7856
+ {
7857
+ type: "object",
7858
+ additionalProperties: false,
7859
+ required: [
7860
+ "path",
7861
+ "op",
7862
+ "value"
7863
+ ],
7864
+ properties: {
7865
+ path: {
7866
+ enum: [
7867
+ "provider",
7868
+ "model",
7869
+ "role",
7870
+ "event_kind",
7871
+ "sensitivity",
7872
+ "import_run_id"
7873
+ ]
7874
+ },
7875
+ op: {
7876
+ const: "eq"
7877
+ },
7878
+ value: {
7879
+ $ref: "#/$defs/scalar"
7880
+ }
7881
+ },
7882
+ allOf: [
7883
+ {
7884
+ if: {
7885
+ properties: {
7886
+ path: {
7887
+ const: "import_run_id"
7888
+ }
7889
+ }
7890
+ },
7891
+ then: {
7892
+ properties: {
7893
+ value: {
7894
+ type: "string",
7895
+ maxLength: 200,
7896
+ pattern: "^[^\\u0000]*$",
7897
+ minLength: 1
7898
+ }
7899
+ }
7900
+ }
7901
+ }
7902
+ ]
7903
+ },
7904
+ {
7905
+ type: "object",
7906
+ additionalProperties: false,
7907
+ required: [
7908
+ "path",
7909
+ "op",
7910
+ "value"
7911
+ ],
7912
+ properties: {
7913
+ path: {
7914
+ enum: [
7915
+ "provider",
7916
+ "model",
7917
+ "role",
7918
+ "event_kind",
7919
+ "sensitivity",
7920
+ "import_run_id"
7921
+ ]
7922
+ },
7923
+ op: {
7924
+ const: "in"
7925
+ },
7926
+ value: {
7927
+ type: "array",
7928
+ maxItems: 32,
7929
+ items: {
7930
+ $ref: "#/$defs/scalar"
7931
+ }
7932
+ }
7933
+ },
7934
+ allOf: [
7935
+ {
7936
+ if: {
7937
+ properties: {
7938
+ path: {
7939
+ const: "import_run_id"
7940
+ }
7941
+ }
7942
+ },
7943
+ then: {
7944
+ properties: {
7945
+ value: {
7946
+ type: "array",
7947
+ items: {
7948
+ type: "string",
7949
+ maxLength: 200,
7950
+ pattern: "^[^\\u0000]*$",
7951
+ minLength: 1
7952
+ }
7953
+ }
7954
+ }
7955
+ }
7956
+ }
7957
+ ]
7958
+ },
7959
+ {
7960
+ type: "object",
7961
+ additionalProperties: false,
7962
+ required: [
7963
+ "path",
7964
+ "op"
7965
+ ],
7966
+ properties: {
7967
+ path: {
7968
+ enum: [
7969
+ "provider",
7970
+ "model",
7971
+ "role",
7972
+ "event_kind",
7973
+ "sensitivity",
7974
+ "import_run_id"
7975
+ ]
7976
+ },
7977
+ op: {
7978
+ const: "range"
7979
+ },
7980
+ gte: {
7981
+ $ref: "#/$defs/bound"
7982
+ },
7983
+ lte: {
7984
+ $ref: "#/$defs/bound"
7985
+ }
7986
+ },
7987
+ anyOf: [
7988
+ {
7989
+ properties: {
7990
+ gte: {
7991
+ $ref: "#/$defs/bound"
7992
+ }
7993
+ },
7994
+ required: [
7995
+ "gte"
7996
+ ]
7997
+ },
7998
+ {
7999
+ properties: {
8000
+ lte: {
8001
+ $ref: "#/$defs/bound"
8002
+ }
8003
+ },
8004
+ required: [
8005
+ "lte"
8006
+ ]
8007
+ }
8008
+ ],
8009
+ oneOf: [
8010
+ {
8011
+ properties: {
8012
+ gte: {
8013
+ type: "string",
8014
+ maxLength: 256,
8015
+ pattern: "^[^\\u0000]*$"
8016
+ },
8017
+ lte: {
8018
+ type: "string",
8019
+ maxLength: 256,
8020
+ pattern: "^[^\\u0000]*$"
8021
+ }
8022
+ }
8023
+ },
8024
+ {
8025
+ properties: {
8026
+ gte: {
8027
+ type: "number",
8028
+ minimum: -9007199254740991,
8029
+ maximum: 9007199254740991
8030
+ },
8031
+ lte: {
8032
+ type: "number",
8033
+ minimum: -9007199254740991,
8034
+ maximum: 9007199254740991
8035
+ }
8036
+ }
8037
+ }
8038
+ ],
8039
+ allOf: [
8040
+ {
8041
+ if: {
8042
+ properties: {
8043
+ path: {
8044
+ const: "import_run_id"
8045
+ }
8046
+ }
8047
+ },
8048
+ then: {
8049
+ properties: {
8050
+ gte: {
8051
+ type: "string",
8052
+ maxLength: 200,
8053
+ pattern: "^[^\\u0000]*$",
8054
+ minLength: 1
8055
+ },
8056
+ lte: {
8057
+ type: "string",
8058
+ maxLength: 200,
8059
+ pattern: "^[^\\u0000]*$",
8060
+ minLength: 1
8061
+ }
8062
+ }
8063
+ }
8064
+ }
8065
+ ]
8066
+ },
8067
+ {
8068
+ type: "object",
8069
+ additionalProperties: false,
8070
+ required: [
8071
+ "path",
8072
+ "op"
8073
+ ],
8074
+ properties: {
8075
+ path: {
8076
+ enum: [
8077
+ "provider",
8078
+ "model",
8079
+ "role",
8080
+ "event_kind",
8081
+ "sensitivity",
8082
+ "import_run_id"
8083
+ ]
8084
+ },
8085
+ op: {
8086
+ const: "exists"
8087
+ },
8088
+ value: {
8089
+ type: "boolean"
8090
+ }
8091
+ }
8092
+ }
8093
+ ]
8094
+ }
8095
+ }
8096
+ };
8097
+
8098
+ // src/repositories/metadata-predicates.ts
8099
+ var REGISTERED_METADATA_PATHS = [
8100
+ "provider",
8101
+ "model",
8102
+ "role",
8103
+ "event_kind",
8104
+ "sensitivity",
8105
+ "import_run_id"
8106
+ ];
8107
+ var validateSchema2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(predicates_schema_default);
8108
+ function compareStrings(left, right) {
8109
+ const a = Array.from(left, (char) => char.codePointAt(0));
8110
+ const b = Array.from(right, (char) => char.codePointAt(0));
8111
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
8112
+ if (a[i] !== b[i]) return a[i] - b[i];
8113
+ }
8114
+ return a.length - b.length;
8115
+ }
8116
+ function validateMetadataPredicates(value) {
8117
+ if (!validateSchema2(value)) throw new Error("METADATA_PREDICATES_INVALID");
8118
+ const predicates = value;
8119
+ for (const predicate of predicates) {
8120
+ const values = predicate.op === "range" ? [predicate.gte, predicate.lte] : predicate.op === "in" ? predicate.value : [predicate.value];
8121
+ for (const scalar of values) {
8122
+ if (typeof scalar === "string" && Array.from(scalar).some((char) => {
8123
+ const code = char.codePointAt(0);
8124
+ return code >= 55296 && code <= 57343;
8125
+ })) throw new Error("METADATA_PREDICATES_INVALID");
8126
+ }
8127
+ }
8128
+ for (const predicate of predicates) {
8129
+ if (predicate.op !== "range" || predicate.gte === void 0 || predicate.lte === void 0) continue;
8130
+ const reversed = typeof predicate.gte === "string" ? compareStrings(predicate.gte, predicate.lte) > 0 : predicate.gte > predicate.lte;
8131
+ if (reversed) throw new Error("METADATA_RANGE_INVALID");
8132
+ }
8133
+ }
8134
+ function predicateSql(predicate, compare, exists) {
8135
+ switch (predicate.op) {
8136
+ case "eq":
8137
+ return compare(predicate.value, "=");
8138
+ case "in":
8139
+ return predicate.value.length ? `(${predicate.value.map((value) => compare(value, "=")).join(" OR ")})` : "FALSE";
8140
+ case "range":
8141
+ return `(${[
8142
+ predicate.gte === void 0 ? null : compare(predicate.gte, ">="),
8143
+ predicate.lte === void 0 ? null : compare(predicate.lte, "<=")
8144
+ ].filter(Boolean).join(" AND ")})`;
8145
+ case "exists":
8146
+ return predicate.value === false ? `NOT (${exists})` : exists;
8147
+ }
8148
+ }
8149
+ function buildMetadataSourceConditions(options, startIdx) {
8150
+ const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
8151
+ validateMetadataPredicates(predicates);
8152
+ const params = [options.tenant_id ?? "default"];
8153
+ let idx = startIdx + 1;
8154
+ const conditions = [
8155
+ `si.note_id = n.id`,
8156
+ `si.tenant_id = $${startIdx}`,
8157
+ "si.archive_id IS NOT DISTINCT FROM n.archive_id",
8158
+ "si.import_run_id IS NOT NULL"
8159
+ ];
8160
+ for (const predicate of predicates.filter((p) => p.path === "import_run_id")) {
8161
+ conditions.push(predicateSql(predicate, (value, op) => {
8162
+ params.push(value);
8163
+ return `si.import_run_id COLLATE "C" ${op} $${idx++}::text COLLATE "C"`;
8164
+ }, "si.import_run_id IS NOT NULL"));
8165
+ }
8166
+ return { conditions, joins: [], params, nextIdx: idx };
8167
+ }
8168
+ function buildMetadataPredicateConditions(options, startIdx) {
8169
+ const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
8170
+ validateMetadataPredicates(predicates);
8171
+ const conditions = [];
8172
+ const params = [];
8173
+ const joins = [];
8174
+ let idx = startIdx;
8175
+ if (options.archive_id !== void 0) {
8176
+ conditions.push(`n.archive_id IS NOT DISTINCT FROM $${idx++}::text`);
8177
+ params.push(options.archive_id);
8178
+ }
8179
+ if (options.tenant_id !== void 0) {
8180
+ const source = buildMetadataSourceConditions({ ...options, metadataPredicates: [] }, idx);
8181
+ const native = options.tenant_id === "default" ? " OR NOT EXISTS (SELECT 1 FROM source_identity si WHERE si.note_id = n.id)" : "";
8182
+ conditions.push(`(EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})${native})`);
8183
+ params.push(...source.params);
8184
+ idx = source.nextIdx;
8185
+ }
8186
+ for (const predicate of predicates) {
8187
+ if (predicate.path === "import_run_id") continue;
8188
+ const lhs = `(n.metadata -> '${predicate.path}')`;
8189
+ conditions.push(predicateSql(predicate, (value, op) => {
8190
+ if (value === null) return `jsonb_typeof(${lhs}) = 'null'`;
8191
+ const rhs = `$${idx++}::jsonb`;
8192
+ params.push(JSON.stringify(value));
8193
+ const type = typeof value;
8194
+ if (type === "string") {
8195
+ return `(jsonb_typeof(${lhs}) = 'string'
8196
+ AND public.metadata_search_order_key_v1(${lhs}) IS NULL
8197
+ AND public.metadata_search_text_key_v1(${lhs}) COLLATE "C" ${op} public.metadata_search_text_key_v1(${rhs}) COLLATE "C"
8198
+ AND (${lhs} #>> '{}') COLLATE "C" ${op} (${rhs} #>> '{}') COLLATE "C")`;
8199
+ }
8200
+ return `(jsonb_typeof(${lhs}) = '${type}'
8201
+ AND public.metadata_search_order_key_v1(${lhs}) ${op} public.metadata_search_order_key_v1(${rhs})
8202
+ AND ${lhs} ${op} ${rhs})`;
8203
+ }, `jsonb_typeof(${lhs}) IS NOT NULL`));
8204
+ }
8205
+ const runs = predicates.filter((p) => p.path === "import_run_id");
8206
+ if (runs.length) {
8207
+ const positive = runs.filter((p) => !(p.op === "exists" && p.value === false));
8208
+ for (const [selected, negated] of [[positive, false], [[], true]]) {
8209
+ if (negated ? !runs.some((p) => p.op === "exists" && p.value === false) : !positive.length) continue;
8210
+ const source = buildMetadataSourceConditions({ ...options, metadataPredicates: selected }, idx);
8211
+ conditions.push(`${negated ? "NOT " : ""}EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})`);
8212
+ params.push(...source.params);
8213
+ idx = source.nextIdx;
8214
+ }
8215
+ }
8216
+ return { conditions, joins, params, nextIdx: idx };
8217
+ }
8218
+
8219
+ // src/repositories/search-evidence-repository.ts
8220
+ function validateScope(scope) {
8221
+ if (!scope || typeof scope !== "object" || Array.isArray(scope) || ![Object.prototype, null].includes(Object.getPrototypeOf(scope)) || Object.keys(scope).some((key3) => !["tenant_id", "archive_id", "visibility", "metadataPredicates"].includes(key3))) {
8222
+ throw new Error("SEARCH_EVIDENCE_INVALID");
8223
+ }
8224
+ for (const key3 of ["tenant_id", "archive_id", "visibility"]) {
8225
+ const value = scope[key3];
8226
+ if (value === void 0 || key3 === "archive_id" && value === null) continue;
8227
+ if (typeof value !== "string" || value.length === 0 || value.includes("\0") || Array.from(value).some((char) => {
8228
+ const code = char.codePointAt(0);
8229
+ return code >= 55296 && code <= 57343;
8230
+ })) throw new Error("SEARCH_EVIDENCE_INVALID");
8231
+ }
8232
+ }
8233
+ async function resolveStoredSearchEvidence(db, value, scope = {}) {
8234
+ const locator = parseSearchEvidenceLocator(value);
8235
+ validateScope(scope);
8236
+ const options = { ...scope, tenant_id: scope.tenant_id ?? "default" };
8237
+ const notes = buildNoteConditions(options, 5);
8238
+ const metadata2 = buildMetadataPredicateConditions(options, notes.nextIdx);
8239
+ const params = [
8240
+ locator.note_id,
8241
+ locator.unit.id,
8242
+ locator.unit.index,
8243
+ MAX_EVIDENCE_BYTES,
8244
+ ...notes.params,
8245
+ ...metadata2.params
8246
+ ];
8247
+ const conditions = ["n.id = $1", ...notes.conditions, ...metadata2.conditions];
8248
+ let joins;
8249
+ let content;
8250
+ switch (locator.unit.kind) {
8251
+ case "current":
8252
+ joins = "JOIN note_revised_current c ON c.note_id = n.id";
8253
+ content = "c.content";
8254
+ conditions.push("n.id = $2", "$3::integer = 0");
8255
+ break;
8256
+ case "title":
8257
+ joins = "";
8258
+ content = "n.title";
8259
+ conditions.push("n.id = $2", "$3::integer = 0");
8260
+ break;
8261
+ case "embedding":
8262
+ joins = "JOIN embedding e ON e.note_id = n.id";
8263
+ content = "e.text";
8264
+ conditions.push("e.id = $2", "e.chunk_index = $3");
8265
+ break;
8266
+ case "attachment":
8267
+ joins = "JOIN attachment a ON a.note_id = n.id";
8268
+ content = "a.extracted_text";
8269
+ conditions.push("a.id = $2", "$3::integer = 0", "a.status = 'completed'", "a.deleted_at IS NULL");
8270
+ break;
8271
+ }
8272
+ if (locator.source) {
8273
+ const source = buildMetadataSourceConditions(options, metadata2.nextIdx);
8274
+ let idx = source.nextIdx;
8275
+ conditions.push(`EXISTS (SELECT 1 FROM source_identity si
8276
+ WHERE ${source.conditions.join(" AND ")}
8277
+ AND si.namespace = $${idx++} AND si.external_id_hash = $${idx++}
8278
+ AND si.import_run_id = $${idx++} AND si.source_schema_version = $${idx++})`);
8279
+ params.push(
8280
+ ...source.params,
8281
+ locator.source.namespace,
8282
+ locator.source.external_id_hash,
8283
+ locator.source.import_run_id,
8284
+ locator.source.schema_version
8285
+ );
8286
+ }
8287
+ const result = await db.query(
8288
+ `SELECT CASE WHEN octet_length(${content}) <= $4
8289
+ THEN encode(convert_to(${content}, 'UTF8'), 'hex') ELSE NULL END AS content_hex
8290
+ FROM note n ${joins} ${metadata2.joins.join(" ")}
8291
+ WHERE ${conditions.join(" AND ")} LIMIT 1`,
8292
+ params
8293
+ );
8294
+ const row = result.rows[0];
8295
+ return resolveSearchEvidence(locator, row?.content_hex == null ? null : {
8296
+ note_id: locator.note_id,
8297
+ unit: locator.unit,
8298
+ content: new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(hexToBytes(row.content_hex)),
8299
+ ...locator.source === void 0 ? {} : { source: locator.source }
8300
+ });
8301
+ }
8302
+
8303
+ // src/repositories/search-evidence-projection.ts
8304
+ init_geometry_buffer();
8305
+
8306
+ // src/search-evidence-set.ts
8307
+ init_geometry_buffer();
8308
+
8309
+ // schemas/metadata-search/candidate/1.0.0/evidence-set.schema.json
8310
+ var evidence_set_schema_default = {
8311
+ $schema: "https://json-schema.org/draft/2020-12/schema",
8312
+ $id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-set.schema.json",
8313
+ title: "Candidate per-hit search evidence envelope",
8314
+ type: "object",
8315
+ additionalProperties: false,
8316
+ required: ["version", "locators", "omissions"],
8317
+ properties: {
8318
+ version: { const: "1.0.0" },
8319
+ locators: {
8320
+ type: "array",
8321
+ maxItems: 64,
8322
+ uniqueItems: true,
8323
+ items: { $ref: "evidence-locator.schema.json" }
8324
+ },
8325
+ omissions: {
8326
+ type: "array",
8327
+ maxItems: 2,
8328
+ uniqueItems: true,
8329
+ items: { enum: ["unavailable-unit", "locator-limit"] }
8330
+ }
8331
+ },
8332
+ if: { properties: { locators: { type: "array", maxItems: 0 } } },
8333
+ then: { properties: { omissions: { type: "array", minItems: 1 } } }
8334
+ };
8335
+
8336
+ // src/search-evidence-set.ts
8337
+ var MAX_SEARCH_LOCATORS = 64;
8338
+ var EVIDENCE_OMISSIONS = ["unavailable-unit", "locator-limit"];
8339
+ var validate = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addSchema(evidence_locator_schema_default).compile(evidence_set_schema_default);
8340
+ var invalid2 = () => new Error("SEARCH_EVIDENCE_INVALID");
8341
+ var priorities = { embedding: 0, title: 1, current: 2, attachment: 3 };
8342
+ function scalarCompare(left, right) {
8343
+ const a = Array.from(left, (char) => char.codePointAt(0));
8344
+ const b = Array.from(right, (char) => char.codePointAt(0));
8345
+ for (let i = 0; i < Math.min(a.length, b.length); i++) if (a[i] !== b[i]) return a[i] - b[i];
8346
+ return a.length - b.length;
8347
+ }
8348
+ function key(locator) {
8349
+ return [
8350
+ priorities[locator.unit.kind],
8351
+ locator.unit.id,
8352
+ locator.unit.index,
8353
+ locator.content_digest,
8354
+ locator.span.start,
8355
+ locator.span.end,
8356
+ locator.source ? 1 : 0,
8357
+ locator.source?.namespace ?? "",
8358
+ locator.source?.external_id_hash ?? "",
8359
+ locator.source?.import_run_id ?? "",
8360
+ locator.source?.schema_version ?? ""
8361
+ ];
8362
+ }
8363
+ function compareSearchEvidence(left, right) {
8364
+ const a = key(left), b = key(right);
8365
+ for (let i = 0; i < a.length; i++) {
8366
+ const cmp = typeof a[i] === "number" ? a[i] - b[i] : scalarCompare(a[i], b[i]);
8367
+ if (cmp !== 0) return cmp;
8368
+ }
8369
+ return 0;
8370
+ }
8371
+ function parseSearchEvidenceSet(value, noteId) {
8372
+ if (!validate(value)) throw invalid2();
8373
+ const locators = value.locators.map(parseSearchEvidenceLocator);
8374
+ if (locators.some((locator, i) => locator.note_id !== noteId || i > 0 && compareSearchEvidence(locators[i - 1], locator) >= 0)) throw invalid2();
8375
+ if (value.omissions.some((reason, i) => i > 0 && EVIDENCE_OMISSIONS.indexOf(value.omissions[i - 1]) >= EVIDENCE_OMISSIONS.indexOf(reason))) throw invalid2();
8376
+ return Object.freeze({ version: "1.0.0", locators: Object.freeze(locators), omissions: Object.freeze([...value.omissions]) });
8377
+ }
8378
+ function createSearchEvidenceSet(noteId, values, omissions = []) {
8379
+ const parsed = values.map(parseSearchEvidenceLocator);
8380
+ if (parsed.some((locator) => locator.note_id !== noteId) || omissions.some((reason) => !EVIDENCE_OMISSIONS.includes(reason))) throw invalid2();
8381
+ const locators = parsed.sort(compareSearchEvidence).filter((locator, i, all) => i === 0 || compareSearchEvidence(all[i - 1], locator) !== 0);
8382
+ const reasons = new Set(omissions);
8383
+ if (locators.length > MAX_SEARCH_LOCATORS) reasons.add("locator-limit");
8384
+ if (locators.length === 0) reasons.add("unavailable-unit");
8385
+ return parseSearchEvidenceSet({
8386
+ version: "1.0.0",
8387
+ locators: locators.slice(0, MAX_SEARCH_LOCATORS),
8388
+ omissions: EVIDENCE_OMISSIONS.filter((reason) => reasons.has(reason))
8389
+ }, noteId);
8390
+ }
8391
+ function mergeSearchEvidenceSets(noteId, sets) {
8392
+ const checked2 = sets.map((set) => parseSearchEvidenceSet(set, noteId));
8393
+ return createSearchEvidenceSet(noteId, checked2.flatMap((set) => [...set.locators]), checked2.flatMap((set) => [...set.omissions]));
8394
+ }
8395
+
8396
+ // src/repositories/search-evidence-projection.ts
8397
+ function buildSearchEvidenceProjection(options, startIdx, match) {
8398
+ const source = buildMetadataSourceConditions(options, startIdx);
8399
+ const scope = buildMetadataPredicateConditions({ tenant_id: options.tenant_id ?? "default", archive_id: options.archive_id }, source.nextIdx);
8400
+ const units = [];
8401
+ if (match.lexical) {
8402
+ const query = `${match.lexical.fn}('english', $${match.lexical.parameter})`;
8403
+ units.push(`SELECT 1 AS priority, 'title'::text AS kind, n.id AS id, 0 AS index, n.title AS content
8404
+ WHERE to_tsvector('english', n.title) @@ ${query}`);
8405
+ units.push(`SELECT 2, 'current', n.id, 0, c.content
8406
+ WHERE to_tsvector('english', c.content) @@ ${query}`);
8407
+ units.push(`SELECT 3, 'attachment', a.id, 0, a.extracted_text FROM attachment a
8408
+ WHERE a.note_id = n.id AND a.deleted_at IS NULL AND a.status = 'completed'
8409
+ AND to_tsvector('english', a.extracted_text) @@ ${query}`);
8410
+ }
8411
+ if (match.embedding) units.push("SELECT 0, 'embedding'::text, e.id, e.chunk_index, NULLIF(e.text, '')");
8412
+ if (units.length === 0) throw new Error("SEARCH_EVIDENCE_INVALID");
8413
+ return {
8414
+ params: [...source.params, ...scope.params],
8415
+ nextIdx: scope.nextIdx,
8416
+ sql: `(WITH units(priority, kind, id, index, content) AS (${units.join(" UNION ALL ")}),
8417
+ sources AS (
8418
+ SELECT DISTINCT si.namespace COLLATE "C" AS namespace, si.external_id_hash COLLATE "C" AS external_id_hash,
8419
+ si.import_run_id COLLATE "C" AS import_run_id, si.source_schema_version COLLATE "C" AS source_schema_version
8420
+ FROM source_identity si WHERE ${source.conditions.join(" AND ")}
8421
+ ORDER BY si.namespace COLLATE "C", si.external_id_hash COLLATE "C",
8422
+ si.import_run_id COLLATE "C", si.source_schema_version COLLATE "C"
8423
+ LIMIT ${MAX_SEARCH_LOCATORS + 1}
8424
+ ), candidates AS MATERIALIZED (
8425
+ SELECT u.*, s.namespace, s.external_id_hash, s.import_run_id, s.source_schema_version
8426
+ FROM units u LEFT JOIN sources s ON true
8427
+ ORDER BY u.priority, u.id COLLATE "C", u.index, s.namespace COLLATE "C",
8428
+ s.external_id_hash COLLATE "C", s.import_run_id COLLATE "C", s.source_schema_version COLLATE "C"
8429
+ LIMIT ${MAX_SEARCH_LOCATORS + 1}
8430
+ ), bound AS (
8431
+ SELECT CASE WHEN ${scope.conditions.join(" AND ")}
8432
+ AND char_length(n.id) BETWEEN 1 AND 200 AND char_length(id) BETWEEN 1 AND 200
8433
+ AND index BETWEEN 0 AND 2147483647 AND octet_length(content) <= ${MAX_EVIDENCE_BYTES}
8434
+ AND (namespace IS NULL OR (char_length(namespace) BETWEEN 1 AND 200
8435
+ AND external_id_hash ~ '^sha256:[a-f0-9]{64}$'
8436
+ AND char_length(import_run_id) BETWEEN 1 AND 200
8437
+ AND char_length(source_schema_version) BETWEEN 1 AND 200))
8438
+ THEN jsonb_build_object('version', '1.0.0', 'note_id', n.id,
8439
+ 'unit', jsonb_build_object('kind', kind, 'id', id, 'index', index),
8440
+ 'content_digest', 'sha256:' || encode(sha256(convert_to(content, 'UTF8')), 'hex'),
8441
+ 'span', jsonb_build_object('unit', 'utf8-bytes', 'start', 0, 'end', octet_length(content)))
8442
+ || CASE WHEN namespace IS NULL THEN '{}'::jsonb ELSE jsonb_build_object('source',
8443
+ jsonb_build_object('namespace', namespace, 'external_id_hash', external_id_hash,
8444
+ 'import_run_id', import_run_id, 'schema_version', source_schema_version)) END
8445
+ ELSE NULL END AS locator FROM candidates
8446
+ ) SELECT jsonb_build_object('locators', coalesce(jsonb_agg(locator), '[]'::jsonb),
8447
+ 'limited', count(*) > ${MAX_SEARCH_LOCATORS}) FROM bound)`
8448
+ };
8449
+ }
8450
+ function projectedSearchEvidence(noteId, value) {
8451
+ return createSearchEvidenceSet(noteId, value.locators.filter((locator) => locator !== null), [
8452
+ ...value.locators.some((locator) => locator === null) ? ["unavailable-unit"] : [],
8453
+ ...value.limited ? ["locator-limit"] : []
8454
+ ]);
8455
+ }
8456
+
7613
8457
  // src/repositories/embedding-sets-repository.ts
7614
8458
  init_geometry_buffer();
7615
8459
  var ATTACHMENT_TEXT_JOIN = `
@@ -8189,91 +9033,6 @@ var EmbeddingSetsRepository = class {
8189
9033
  }
8190
9034
  };
8191
9035
 
8192
- // src/repositories/metadata-predicates.ts
8193
- init_geometry_buffer();
8194
- var REGISTERED_METADATA_PATHS = [
8195
- "provider",
8196
- "model",
8197
- "role",
8198
- "event_kind",
8199
- "sensitivity",
8200
- "import_run_id"
8201
- ];
8202
- var REGISTERED_SET = new Set(REGISTERED_METADATA_PATHS);
8203
- var MAX_PREDICATES = 8;
8204
- var MAX_IN_VALUES = 32;
8205
- var MAX_VALUE_LENGTH = 256;
8206
- function assertRegisteredPath(path) {
8207
- if (!REGISTERED_SET.has(path) || path.includes(".") || path.includes("/")) {
8208
- throw new Error(`Unsupported metadata predicate path: ${path}`);
8209
- }
8210
- }
8211
- function assertBoundedValue(value) {
8212
- if (typeof value === "string" && value.length > MAX_VALUE_LENGTH) {
8213
- throw new Error("Metadata predicate value exceeds the 256 character bound");
8214
- }
8215
- }
8216
- function jsonAccessor(path) {
8217
- if (path === "import_run_id") return "si.import_run_id";
8218
- return `n.metadata ->> '${path}'`;
8219
- }
8220
- function buildMetadataPredicateConditions(options, startIdx) {
8221
- const predicates = options.metadataPredicates ?? [];
8222
- if (predicates.length > MAX_PREDICATES) {
8223
- throw new Error(`Metadata predicate count exceeds the ${MAX_PREDICATES} predicate bound`);
8224
- }
8225
- const conditions = [];
8226
- const params = [];
8227
- const joins = [];
8228
- let idx = startIdx;
8229
- let needsSourceJoin = options.tenant_id !== void 0 || options.archive_id !== void 0;
8230
- if (options.tenant_id !== void 0) {
8231
- conditions.push(`COALESCE(si.tenant_id, 'default') = $${idx++}`);
8232
- params.push(options.tenant_id);
8233
- }
8234
- if (options.archive_id !== void 0) {
8235
- conditions.push(`si.archive_id IS NOT DISTINCT FROM $${idx++}`);
8236
- params.push(options.archive_id);
8237
- }
8238
- for (const predicate of predicates) {
8239
- assertRegisteredPath(predicate.path);
8240
- const lhs = jsonAccessor(predicate.path);
8241
- if (predicate.path === "import_run_id") needsSourceJoin = true;
8242
- if (predicate.op === "eq") {
8243
- assertBoundedValue(predicate.value);
8244
- conditions.push(`${lhs} IS NOT DISTINCT FROM $${idx++}`);
8245
- params.push(predicate.value == null ? null : String(predicate.value));
8246
- } else if (predicate.op === "in") {
8247
- if (predicate.value.length > MAX_IN_VALUES) {
8248
- throw new Error(`Metadata predicate membership exceeds the ${MAX_IN_VALUES} value bound`);
8249
- }
8250
- for (const value of predicate.value) assertBoundedValue(value);
8251
- conditions.push(`${lhs} = ANY($${idx++})`);
8252
- params.push(predicate.value.map((value) => value == null ? null : String(value)));
8253
- } else if (predicate.op === "range") {
8254
- if (predicate.gte === void 0 && predicate.lte === void 0) {
8255
- throw new Error("Metadata range predicate requires gte or lte");
8256
- }
8257
- if (predicate.gte !== void 0) {
8258
- assertBoundedValue(predicate.gte);
8259
- conditions.push(`${lhs} >= $${idx++}`);
8260
- params.push(String(predicate.gte));
8261
- }
8262
- if (predicate.lte !== void 0) {
8263
- assertBoundedValue(predicate.lte);
8264
- conditions.push(`${lhs} <= $${idx++}`);
8265
- params.push(String(predicate.lte));
8266
- }
8267
- } else {
8268
- conditions.push(predicate.value === false ? `${lhs} IS NULL` : `${lhs} IS NOT NULL`);
8269
- }
8270
- }
8271
- if (needsSourceJoin) {
8272
- joins.push("LEFT JOIN source_identity si ON si.note_id = n.id");
8273
- }
8274
- return { conditions, joins, params, nextIdx: idx };
8275
- }
8276
-
8277
9036
  // src/repositories/search-repository.ts
8278
9037
  var ATTACHMENT_TEXT_JOIN2 = `
8279
9038
  LEFT JOIN (
@@ -8295,6 +9054,10 @@ var SearchRepository = class {
8295
9054
  this.db = db;
8296
9055
  this.semanticAvailable = semanticAvailable;
8297
9056
  }
9057
+ /** Candidate citation resolution with fresh local scope and content checks. */
9058
+ async resolveEvidence(locator, scope = {}) {
9059
+ return resolveStoredSearchEvidence(this.db, locator, scope);
9060
+ }
8298
9061
  tsqueryFn(query) {
8299
9062
  return query.includes('"') ? "phraseto_tsquery" : "plainto_tsquery";
8300
9063
  }
@@ -8304,7 +9067,7 @@ var SearchRepository = class {
8304
9067
  const setFilter = embeddingSetId ? " AND embedding_set_id = $2" : "";
8305
9068
  if (embeddingSetId) params.push(embeddingSetId);
8306
9069
  const result = await this.db.query(
8307
- "SELECT note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
9070
+ "SELECT to_jsonb(note_id) AS note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
8308
9071
  params
8309
9072
  );
8310
9073
  return new Set(result.rows.map((r) => r.note_id));
@@ -8348,15 +9111,17 @@ var SearchRepository = class {
8348
9111
  attachEmbeddingStatus(results, embeddingSet) {
8349
9112
  return results.map((r) => ({ ...r, has_embedding: embeddingSet.has(r.id) }));
8350
9113
  }
8351
- async fetchLocatorMap(noteIds, metadataPaths = []) {
9114
+ async fetchLocatorMap(noteIds, options) {
8352
9115
  const locators = /* @__PURE__ */ new Map();
8353
9116
  if (noteIds.length === 0) return locators;
9117
+ const metadataPaths = this.metadataPaths(options);
9118
+ const source = buildMetadataSourceConditions(options, 2);
8354
9119
  const result = await this.db.query(
8355
- `SELECT note_id, namespace, external_id_hash, import_run_id, source_schema_version
8356
- FROM source_identity
8357
- WHERE note_id = ANY($1)
8358
- ORDER BY created_at ASC`,
8359
- [noteIds]
9120
+ `SELECT to_jsonb(si.note_id) AS note_id, si.namespace, si.external_id_hash, si.import_run_id, si.source_schema_version
9121
+ FROM source_identity si JOIN note n ON n.id = si.note_id
9122
+ WHERE n.id = ANY($1) AND ${source.conditions.join(" AND ")}
9123
+ ORDER BY si.created_at ASC, si.id ASC`,
9124
+ [noteIds, ...source.params]
8360
9125
  );
8361
9126
  for (const row of result.rows) {
8362
9127
  const existing = locators.get(row.note_id) ?? [];
@@ -8384,6 +9149,7 @@ var SearchRepository = class {
8384
9149
  return [...new Set((options.metadataPredicates ?? []).map((predicate) => predicate.path))];
8385
9150
  }
8386
9151
  async search(query, options = {}, queryEmbedding) {
9152
+ validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
8387
9153
  const { limit = 20, offset = 0 } = options;
8388
9154
  const mode = options.mode ?? "auto";
8389
9155
  if (mode === "text") {
@@ -8429,9 +9195,11 @@ var SearchRepository = class {
8429
9195
  allParams
8430
9196
  );
8431
9197
  const total = parseInt(countResult.rows[0].count, 10);
8432
- const searchParams = [...allParams, limit, offset];
9198
+ const evidence = buildSearchEvidenceProjection(options, paramIdx, { lexical: { fn: tsqFn, parameter: 1 } });
9199
+ paramIdx = evidence.nextIdx;
9200
+ const searchParams = [...allParams, ...evidence.params, limit, offset];
8433
9201
  const result = await this.db.query(
8434
- `SELECT n.id, n.title, n.created_at, n.updated_at,
9202
+ `SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at, ${evidence.sql} AS evidence_projection,
8435
9203
  ts_rank(
8436
9204
  setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
8437
9205
  ${tsqFn}('english', $1)
@@ -8459,7 +9227,7 @@ var SearchRepository = class {
8459
9227
  let facets;
8460
9228
  if (options.include_facets) {
8461
9229
  const idsResult = await this.db.query(
8462
- `SELECT n.id FROM note n
9230
+ `SELECT to_jsonb(n.id) AS id FROM note n
8463
9231
  LEFT JOIN note_revised_current c ON c.note_id = n.id
8464
9232
  ${metadata2.joins.join("\n")}
8465
9233
  ${ATTACHMENT_TEXT_JOIN2}
@@ -8468,7 +9236,7 @@ var SearchRepository = class {
8468
9236
  );
8469
9237
  facets = await this.fetchFacets(idsResult.rows.map((r) => r.id));
8470
9238
  }
8471
- const locatorMap = await this.fetchLocatorMap(resultIds, this.metadataPaths(options));
9239
+ const locatorMap = await this.fetchLocatorMap(resultIds, options);
8472
9240
  const baseResults = result.rows.map((r) => ({
8473
9241
  id: r.id,
8474
9242
  title: r.title,
@@ -8477,7 +9245,8 @@ var SearchRepository = class {
8477
9245
  created_at: r.created_at,
8478
9246
  updated_at: r.updated_at,
8479
9247
  tags: tagMap.get(r.id) ?? [],
8480
- locators: locatorMap.get(r.id) ?? []
9248
+ locators: locatorMap.get(r.id) ?? [],
9249
+ evidence: projectedSearchEvidence(r.id, r.evidence_projection)
8481
9250
  }));
8482
9251
  return {
8483
9252
  results: this.attachEmbeddingStatus(baseResults, embeddingSet),
@@ -8491,6 +9260,7 @@ var SearchRepository = class {
8491
9260
  };
8492
9261
  }
8493
9262
  async semanticSearch(queryEmbedding, options = {}) {
9263
+ validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
8494
9264
  const { limit = 20, offset = 0 } = options;
8495
9265
  const vector = vectorColumn(queryEmbedding);
8496
9266
  const vectorStr = `[${queryEmbedding.join(",")}]`;
@@ -8512,11 +9282,14 @@ var SearchRepository = class {
8512
9282
  params
8513
9283
  );
8514
9284
  const total = parseInt(countResult.rows[0].count, 10);
9285
+ const evidence = buildSearchEvidenceProjection(options, paramIdx, { embedding: true });
9286
+ paramIdx = evidence.nextIdx;
8515
9287
  const vecIdx = paramIdx++;
8516
9288
  const limIdx = paramIdx++;
8517
9289
  const offIdx = paramIdx++;
8518
9290
  const result = await this.db.query(
8519
- `SELECT * FROM (SELECT DISTINCT ON (n.id) n.id, n.title, n.created_at, n.updated_at,
9291
+ `SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
9292
+ ${evidence.sql} AS evidence_projection,
8520
9293
  (${vector} <=> $${vecIdx}::vector) as distance,
8521
9294
  LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
8522
9295
  FROM embedding e
@@ -8528,11 +9301,11 @@ var SearchRepository = class {
8528
9301
  ORDER BY n.id, ${vector} <=> $${vecIdx}::vector ASC, e.id) AS best_chunks
8529
9302
  ORDER BY distance ASC, id
8530
9303
  LIMIT $${limIdx} OFFSET $${offIdx}`,
8531
- [...params, vectorStr, limit, offset]
9304
+ [...params, ...evidence.params, vectorStr, limit, offset]
8532
9305
  );
8533
9306
  const tagMap = await this.fetchTagMap(result.rows.map((r) => r.id));
8534
9307
  const facets = options.include_facets ? await this.fetchFacets((await this.db.query(
8535
- `SELECT n.id
9308
+ `SELECT to_jsonb(n.id) AS id
8536
9309
  FROM embedding e
8537
9310
  JOIN note n ON n.id = e.note_id
8538
9311
  LEFT JOIN note_revised_current c ON c.note_id = n.id
@@ -8540,7 +9313,7 @@ var SearchRepository = class {
8540
9313
  WHERE ${where}`,
8541
9314
  params
8542
9315
  )).rows.map((r) => r.id)) : void 0;
8543
- const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id), this.metadataPaths(options));
9316
+ const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id), options);
8544
9317
  return {
8545
9318
  results: result.rows.map((r) => ({
8546
9319
  id: r.id,
@@ -8551,7 +9324,8 @@ var SearchRepository = class {
8551
9324
  updated_at: r.updated_at,
8552
9325
  tags: tagMap.get(r.id) ?? [],
8553
9326
  has_embedding: true,
8554
- locators: locatorMap.get(r.id) ?? []
9327
+ locators: locatorMap.get(r.id) ?? [],
9328
+ evidence: projectedSearchEvidence(r.id, r.evidence_projection)
8555
9329
  })),
8556
9330
  total,
8557
9331
  query: "",
@@ -8563,6 +9337,7 @@ var SearchRepository = class {
8563
9337
  };
8564
9338
  }
8565
9339
  async hybridSearch(query, queryEmbedding, options = {}) {
9340
+ validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
8566
9341
  const { limit = 20, offset = 0 } = options;
8567
9342
  const vectorStr = `[${queryEmbedding.join(",")}]`;
8568
9343
  const k = 60;
@@ -8577,11 +9352,12 @@ var SearchRepository = class {
8577
9352
  ${COMBINED_TEXT_VECTOR_SQL2} @@ ${tsqFn}('english', $1))`
8578
9353
  ];
8579
9354
  textCond.params.push(...textMeta.params);
8580
- this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
9355
+ const textNextIdx = this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
8581
9356
  const textWhere = textConditions.join(" AND ");
8582
- const textParams = [query, ...textCond.params];
9357
+ const textEvidence = buildSearchEvidenceProjection(options, textNextIdx, { lexical: { fn: tsqFn, parameter: 1 } });
9358
+ const textParams = [query, ...textCond.params, ...textEvidence.params];
8583
9359
  const textResult = await this.db.query(
8584
- `SELECT n.id,
9360
+ `SELECT to_jsonb(n.id) AS id, ${textEvidence.sql} AS evidence_projection,
8585
9361
  ts_rank(
8586
9362
  setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
8587
9363
  ${tsqFn}('english', $1)
@@ -8603,9 +9379,11 @@ var SearchRepository = class {
8603
9379
  const vector = vectorColumn(queryEmbedding);
8604
9380
  vecCond.conditions.push(`vector_dims(e.vector) = ${queryEmbedding.length}`);
8605
9381
  const vecWhere = vecCond.conditions.join(" AND ");
8606
- const vecVecIdx = vecCond.nextIdx;
9382
+ const vectorEvidence = buildSearchEvidenceProjection(options, vecCond.nextIdx, { embedding: true });
9383
+ const vecVecIdx = vectorEvidence.nextIdx;
8607
9384
  const vectorResult = await this.db.query(
8608
- `SELECT * FROM (SELECT DISTINCT ON (n.id) n.id, (${vector} <=> $${vecVecIdx}::vector) as distance
9385
+ `SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, ${vectorEvidence.sql} AS evidence_projection,
9386
+ (${vector} <=> $${vecVecIdx}::vector) as distance
8609
9387
  FROM embedding e
8610
9388
  JOIN note n ON n.id = e.note_id
8611
9389
  LEFT JOIN note_revised_current c ON c.note_id = n.id
@@ -8614,9 +9392,15 @@ var SearchRepository = class {
8614
9392
  ORDER BY n.id, ${vector} <=> $${vecVecIdx}::vector ASC, e.id) AS best_chunks
8615
9393
  ORDER BY distance ASC, id
8616
9394
  LIMIT 100`,
8617
- [...vecCond.params, vectorStr]
9395
+ [...vecCond.params, ...vectorEvidence.params, vectorStr]
8618
9396
  );
8619
9397
  const rrfScores = /* @__PURE__ */ new Map();
9398
+ const evidenceMap = /* @__PURE__ */ new Map();
9399
+ for (const row of [...textResult.rows, ...vectorResult.rows]) {
9400
+ const existing = evidenceMap.get(row.id) ?? [];
9401
+ existing.push(projectedSearchEvidence(row.id, row.evidence_projection));
9402
+ evidenceMap.set(row.id, existing);
9403
+ }
8620
9404
  textResult.rows.forEach((row, idx) => {
8621
9405
  rrfScores.set(row.id, (rrfScores.get(row.id) ?? 0) + 1 / (k + idx + 1));
8622
9406
  });
@@ -8629,21 +9413,24 @@ var SearchRepository = class {
8629
9413
  if (pageIds.length === 0) {
8630
9414
  return { results: [], total, query, mode: "hybrid", semantic_available: this.semanticAvailable, limit, offset };
8631
9415
  }
9416
+ const displayConditions = buildNoteConditions(options, 2);
9417
+ const displayMetadata = buildMetadataPredicateConditions(options, displayConditions.nextIdx);
8632
9418
  const noteResult = await this.db.query(
8633
- `SELECT n.id, n.title, n.created_at, n.updated_at,
9419
+ `SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
8634
9420
  LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
8635
9421
  FROM note n
8636
9422
  LEFT JOIN note_revised_current c ON c.note_id = n.id
8637
9423
  ${ATTACHMENT_TEXT_JOIN2}
8638
- WHERE n.id = ANY($1)`,
8639
- [pageIds]
9424
+ ${displayMetadata.joins.join("\n")}
9425
+ WHERE n.id = ANY($1) AND ${[...displayConditions.conditions, ...displayMetadata.conditions].join(" AND ")}`,
9426
+ [pageIds, ...displayConditions.params, ...displayMetadata.params]
8640
9427
  );
8641
9428
  const noteMap = new Map(noteResult.rows.map((r) => [r.id, r]));
8642
9429
  const [tagMap, embeddingSet] = await Promise.all([
8643
9430
  this.fetchTagMap(pageIds),
8644
9431
  this.fetchEmbeddingStatus(pageIds, resolvedEmbeddingSet, options.embeddingSetId)
8645
9432
  ]);
8646
- const locatorMap = await this.fetchLocatorMap(pageIds, this.metadataPaths(options));
9433
+ const locatorMap = await this.fetchLocatorMap(pageIds, options);
8647
9434
  const facets = options.include_facets ? await this.fetchFacets(sortedIds) : void 0;
8648
9435
  return {
8649
9436
  results: pageIds.map((id) => {
@@ -8658,7 +9445,8 @@ var SearchRepository = class {
8658
9445
  updated_at: r.updated_at,
8659
9446
  tags: tagMap.get(id) ?? [],
8660
9447
  has_embedding: embeddingSet.has(id),
8661
- locators: locatorMap.get(id) ?? []
9448
+ locators: locatorMap.get(id) ?? [],
9449
+ evidence: mergeSearchEvidenceSets(id, evidenceMap.get(id) ?? [])
8662
9450
  };
8663
9451
  }).filter((r) => r !== null),
8664
9452
  total,
@@ -8690,7 +9478,7 @@ var SearchRepository = class {
8690
9478
  const total = parseInt(countResult.rows[0].count, 10);
8691
9479
  const listParams = [...params, limit, offset];
8692
9480
  const result = await this.db.query(
8693
- `SELECT n.id, n.title, n.created_at, n.updated_at,
9481
+ `SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
8694
9482
  LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
8695
9483
  FROM note n
8696
9484
  LEFT JOIN note_revised_current c ON c.note_id = n.id
@@ -8703,7 +9491,7 @@ var SearchRepository = class {
8703
9491
  );
8704
9492
  const resultIds = result.rows.map((r) => r.id);
8705
9493
  const embeddingSet = await this.fetchEmbeddingStatus(resultIds, resolvedEmbeddingSet, options.embeddingSetId);
8706
- const locatorMap = await this.fetchLocatorMap(resultIds, this.metadataPaths(options));
9494
+ const locatorMap = await this.fetchLocatorMap(resultIds, options);
8707
9495
  return {
8708
9496
  results: result.rows.map((r) => ({
8709
9497
  id: r.id,
@@ -8748,7 +9536,7 @@ var SearchRepository = class {
8748
9536
  const tagMap = /* @__PURE__ */ new Map();
8749
9537
  if (noteIds.length === 0) return tagMap;
8750
9538
  const tagsResult = await this.db.query(
8751
- `SELECT note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
9539
+ `SELECT to_jsonb(note_id) AS note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
8752
9540
  [noteIds]
8753
9541
  );
8754
9542
  for (const row of tagsResult.rows) {
@@ -8992,7 +9780,7 @@ init_geometry_buffer();
8992
9780
  // src/shard/full-v1-references.ts
8993
9781
  init_geometry_buffer();
8994
9782
  var uuid2 = (value) => typeof value === "string" ? value.toLowerCase() : value;
8995
- var key = (...values) => JSON.stringify(values);
9783
+ var key2 = (...values) => JSON.stringify(values);
8996
9784
  var present = (value) => value !== null && value !== void 0;
8997
9785
  function fullV1ReferenceErrors(records) {
8998
9786
  const errors = [];
@@ -9050,7 +9838,7 @@ function fullV1ReferenceErrors(records) {
9050
9838
  const id = uuid2(attachment.id);
9051
9839
  check(!attachmentIds.has(id), "notes", index, "duplicate attachment identity");
9052
9840
  attachmentIds.add(id);
9053
- const declaration = key(attachment.bytes, attachment.mime);
9841
+ const declaration = key2(attachment.bytes, attachment.mime);
9054
9842
  check(
9055
9843
  !digests.has(attachment.checksum) || digests.get(attachment.checksum) === declaration,
9056
9844
  "notes",
@@ -9076,7 +9864,7 @@ function fullV1ReferenceErrors(records) {
9076
9864
  }
9077
9865
  });
9078
9866
  ids2("note_original_history");
9079
- unique2("note_original_history", (row) => key(uuid2(row.note_id), row.version_number));
9867
+ unique2("note_original_history", (row) => key2(uuid2(row.note_id), row.version_number));
9080
9868
  rows("note_original_history").forEach((row, index) => {
9081
9869
  ref(row, "note_id", notes, "note_original_history", index);
9082
9870
  const current = originals.get(uuid2(row.note_id));
@@ -9088,7 +9876,7 @@ function fullV1ReferenceErrors(records) {
9088
9876
  );
9089
9877
  });
9090
9878
  const revisionIds = ids2("note_revisions");
9091
- unique2("note_revisions", (row) => key(uuid2(row.note_id), row.revision_number));
9879
+ unique2("note_revisions", (row) => key2(uuid2(row.note_id), row.revision_number));
9092
9880
  const revisions = new Map(rows("note_revisions").map((row) => [uuid2(row.id), row]));
9093
9881
  rows("note_revisions").forEach((row, index) => {
9094
9882
  ref(row, "note_id", notes, "note_revisions", index);
@@ -9143,7 +9931,7 @@ function fullV1ReferenceErrors(records) {
9143
9931
  ref(row, "named_location_id", namedLocations, "provenance_locations", index, true);
9144
9932
  });
9145
9933
  const devices = ids2("provenance_devices");
9146
- unique2("provenance_devices", (row) => key(row.device_make, row.device_model, uuid2(row.owner_id)));
9934
+ unique2("provenance_devices", (row) => key2(row.device_make, row.device_model, uuid2(row.owner_id)));
9147
9935
  ids2("provenance_records");
9148
9936
  unique2("provenance_records", (row) => uuid2(row.note_id));
9149
9937
  rows("provenance_records").forEach((row, index) => {
@@ -9175,13 +9963,13 @@ function fullV1ReferenceErrors(records) {
9175
9963
  const config = configRows.get(uuid2(row.embedding_config_id));
9176
9964
  if (config) dimensions.set(uuid2(row.id), Number(row.truncate_dim ?? config.dimension));
9177
9965
  });
9178
- unique2("embedding_set_members", (row) => key(uuid2(row.embedding_set_id), uuid2(row.note_id)));
9966
+ unique2("embedding_set_members", (row) => key2(uuid2(row.embedding_set_id), uuid2(row.note_id)));
9179
9967
  rows("embedding_set_members").forEach((row, index) => {
9180
9968
  ref(row, "embedding_set_id", sets, "embedding_set_members", index);
9181
9969
  ref(row, "note_id", notes, "embedding_set_members", index);
9182
9970
  });
9183
9971
  ids2("embeddings");
9184
- unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ? key(uuid2(row.note_id), uuid2(row.embedding_set_id), row.chunk_index) : null);
9972
+ unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ? key2(uuid2(row.note_id), uuid2(row.embedding_set_id), row.chunk_index) : null);
9185
9973
  rows("embeddings").forEach((row, index) => {
9186
9974
  ref(row, "note_id", notes, "embeddings", index, true);
9187
9975
  ref(row, "embedding_set_id", sets, "embeddings", index, true);
@@ -9199,34 +9987,34 @@ function fullV1ReferenceErrors(records) {
9199
9987
  unique2("skos_schemes", (row) => row.uri);
9200
9988
  const concepts = ids2("skos_concepts");
9201
9989
  unique2("skos_concepts", (row) => row.uri);
9202
- unique2("skos_concepts", (row) => present(row.notation) ? key(uuid2(row.primary_scheme_id), row.notation) : null);
9990
+ unique2("skos_concepts", (row) => present(row.notation) ? key2(uuid2(row.primary_scheme_id), row.notation) : null);
9203
9991
  rows("skos_concepts").forEach((row, index) => {
9204
9992
  ref(row, "primary_scheme_id", schemes, "skos_concepts", index);
9205
9993
  ref(row, "replaced_by_id", concepts, "skos_concepts", index, true);
9206
9994
  check(uuid2(row.replaced_by_id) !== uuid2(row.id), "skos_concepts", index, "concept replaces itself");
9207
9995
  });
9208
9996
  ids2("skos_labels");
9209
- unique2("skos_labels", (row) => key(uuid2(row.concept_id), row.label_type, row.language, row.value));
9210
- unique2("skos_labels", (row) => row.label_type === "pref_label" ? key(uuid2(row.concept_id), row.language) : null);
9997
+ unique2("skos_labels", (row) => key2(uuid2(row.concept_id), row.label_type, row.language, row.value));
9998
+ unique2("skos_labels", (row) => row.label_type === "pref_label" ? key2(uuid2(row.concept_id), row.language) : null);
9211
9999
  rows("skos_labels").forEach((row, index) => ref(row, "concept_id", concepts, "skos_labels", index));
9212
10000
  ids2("skos_notes");
9213
10001
  rows("skos_notes").forEach((row, index) => ref(row, "concept_id", concepts, "skos_notes", index));
9214
10002
  ids2("skos_relations");
9215
- unique2("skos_relations", (row) => key(uuid2(row.subject_id), uuid2(row.object_id), row.relation_type));
10003
+ unique2("skos_relations", (row) => key2(uuid2(row.subject_id), uuid2(row.object_id), row.relation_type));
9216
10004
  rows("skos_relations").forEach((row, index) => {
9217
10005
  ref(row, "subject_id", concepts, "skos_relations", index);
9218
10006
  ref(row, "object_id", concepts, "skos_relations", index);
9219
10007
  check(uuid2(row.subject_id) !== uuid2(row.object_id), "skos_relations", index, "self relation is invalid");
9220
10008
  });
9221
10009
  ids2("skos_mapping_relations");
9222
- unique2("skos_mapping_relations", (row) => key(uuid2(row.concept_id), row.target_uri, row.relation_type));
10010
+ unique2("skos_mapping_relations", (row) => key2(uuid2(row.concept_id), row.target_uri, row.relation_type));
9223
10011
  rows("skos_mapping_relations").forEach((row, index) => ref(row, "concept_id", concepts, "skos_mapping_relations", index));
9224
- unique2("skos_scheme_memberships", (row) => key(uuid2(row.concept_id), uuid2(row.scheme_id)));
10012
+ unique2("skos_scheme_memberships", (row) => key2(uuid2(row.concept_id), uuid2(row.scheme_id)));
9225
10013
  rows("skos_scheme_memberships").forEach((row, index) => {
9226
10014
  ref(row, "concept_id", concepts, "skos_scheme_memberships", index);
9227
10015
  ref(row, "scheme_id", schemes, "skos_scheme_memberships", index);
9228
10016
  });
9229
- unique2("note_skos_tags", (row) => key(uuid2(row.note_id), uuid2(row.concept_id)));
10017
+ unique2("note_skos_tags", (row) => key2(uuid2(row.note_id), uuid2(row.concept_id)));
9230
10018
  rows("note_skos_tags").forEach((row, index) => {
9231
10019
  ref(row, "note_id", notes, "note_skos_tags", index);
9232
10020
  ref(row, "concept_id", concepts, "note_skos_tags", index);
@@ -9234,7 +10022,7 @@ function fullV1ReferenceErrors(records) {
9234
10022
  const skosCollections = ids2("skos_collections");
9235
10023
  unique2("skos_collections", (row) => row.uri);
9236
10024
  rows("skos_collections").forEach((row, index) => ref(row, "scheme_id", schemes, "skos_collections", index, true));
9237
- unique2("skos_collection_members", (row) => key(uuid2(row.collection_id), uuid2(row.concept_id)));
10025
+ unique2("skos_collection_members", (row) => key2(uuid2(row.collection_id), uuid2(row.concept_id)));
9238
10026
  rows("skos_collection_members").forEach((row, index) => {
9239
10027
  ref(row, "collection_id", skosCollections, "skos_collection_members", index);
9240
10028
  ref(row, "concept_id", concepts, "skos_collection_members", index);
@@ -9250,7 +10038,7 @@ function fullV1ReferenceErrors(records) {
9250
10038
  );
9251
10039
  }
9252
10040
  });
9253
- unique2("graph_edges", (row) => key(row.graph_source_id, uuid2(row.from_note_id), uuid2(row.to_note_id), row.kind));
10041
+ unique2("graph_edges", (row) => key2(row.graph_source_id, uuid2(row.from_note_id), uuid2(row.to_note_id), row.kind));
9254
10042
  rows("graph_edges").forEach((row, index) => {
9255
10043
  ref(row, "graph_source_id", sources, "graph_edges", index, false, false);
9256
10044
  ref(row, "from_note_id", notes, "graph_edges", index);
@@ -9262,7 +10050,7 @@ function fullV1ReferenceErrors(records) {
9262
10050
  rows("communities").forEach((row, index) => {
9263
10051
  ref(row, "graph_source_id", sources, "communities", index, false, false);
9264
10052
  for (const community of row.communities) {
9265
- const id = key(row.id, community.id);
10053
+ const id = key2(row.id, community.id);
9266
10054
  check(!communities.has(id), "communities", index, "duplicate community identity within set");
9267
10055
  communities.add(id);
9268
10056
  const representatives = /* @__PURE__ */ new Set();
@@ -9277,10 +10065,10 @@ function fullV1ReferenceErrors(records) {
9277
10065
  }
9278
10066
  }
9279
10067
  });
9280
- unique2("community_assignments", (row) => key(row.community_set_id, uuid2(row.note_id)));
10068
+ unique2("community_assignments", (row) => key2(row.community_set_id, uuid2(row.note_id)));
9281
10069
  rows("community_assignments").forEach((row, index) => {
9282
10070
  check(
9283
- communities.has(key(row.community_set_id, row.community_id)),
10071
+ communities.has(key2(row.community_set_id, row.community_id)),
9284
10072
  "community_assignments",
9285
10073
  index,
9286
10074
  "community does not belong to the declared set"
@@ -19283,7 +20071,7 @@ function collectSidecarBlobs(files) {
19283
20071
  }
19284
20072
 
19285
20073
  // src/shard/schema-validator.ts
19286
- var decoder = new TextDecoder();
20074
+ var decoder2 = new TextDecoder();
19287
20075
  var LEGACY_COMPONENT_SCHEMA_DEFS = {
19288
20076
  notes: "note",
19289
20077
  collections: "collection",
@@ -19539,13 +20327,13 @@ function getKnowledgeShardSchema() {
19539
20327
  function getKnowledgeShardContractReceipt() {
19540
20328
  return knowledge_shard_schema_receipt_default;
19541
20329
  }
19542
- function addCanonicalFormats(ajv2) {
19543
- ajv2.addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
19544
- ajv2.addFormat("date-time", {
20330
+ function addCanonicalFormats(ajv3) {
20331
+ ajv3.addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
20332
+ ajv3.addFormat("date-time", {
19545
20333
  type: "string",
19546
20334
  validate: (value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && !Number.isNaN(Date.parse(value))
19547
20335
  });
19548
- ajv2.addFormat("uri", {
20336
+ ajv3.addFormat("uri", {
19549
20337
  type: "string",
19550
20338
  validate: (value) => {
19551
20339
  try {
@@ -19558,7 +20346,7 @@ function addCanonicalFormats(ajv2) {
19558
20346
  }
19559
20347
  function getLegacyAjv() {
19560
20348
  if (!legacyAjvInstance) {
19561
- legacyAjvInstance = new Ajv20203({
20349
+ legacyAjvInstance = new Ajv20206({
19562
20350
  allErrors: true,
19563
20351
  strict: true,
19564
20352
  validateFormats: false
@@ -19569,7 +20357,7 @@ function getLegacyAjv() {
19569
20357
  }
19570
20358
  function getCoreAjv() {
19571
20359
  if (!coreAjvInstance) {
19572
- coreAjvInstance = new Ajv20203({
20360
+ coreAjvInstance = new Ajv20206({
19573
20361
  allErrors: true,
19574
20362
  strict: true,
19575
20363
  validateFormats: true
@@ -19589,7 +20377,7 @@ function getCoreAjv() {
19589
20377
  }
19590
20378
  function getRecordAjv() {
19591
20379
  if (!recordAjvInstance) {
19592
- recordAjvInstance = new Ajv20203({
20380
+ recordAjvInstance = new Ajv20206({
19593
20381
  allErrors: true,
19594
20382
  strict: true,
19595
20383
  validateFormats: true
@@ -19609,7 +20397,7 @@ function getRecordAjv() {
19609
20397
  }
19610
20398
  function getFullAjv() {
19611
20399
  if (!fullAjvInstance) {
19612
- fullAjvInstance = new Ajv20203({
20400
+ fullAjvInstance = new Ajv20206({
19613
20401
  allErrors: true,
19614
20402
  strict: true,
19615
20403
  validateFormats: true
@@ -19644,30 +20432,30 @@ function fullSchemaVersion(value) {
19644
20432
  return value === "1.1.0" || value === "1.2.0" || value === "2.0.0" ? value : void 0;
19645
20433
  }
19646
20434
  function coreValidatorFor(name, version = CURRENT_SHARD_VERSION) {
19647
- const key2 = `${version}:${name}`;
19648
- const cached = coreValidators.get(key2);
20435
+ const key3 = `${version}:${name}`;
20436
+ const cached = coreValidators.get(key3);
19649
20437
  if (cached) return cached;
19650
20438
  const schema = CORE_V1_SCHEMAS[version][name];
19651
20439
  const validator = getCoreAjv().getSchema(schema.$id) ?? getCoreAjv().compile(schema);
19652
- coreValidators.set(key2, validator);
20440
+ coreValidators.set(key3, validator);
19653
20441
  return validator;
19654
20442
  }
19655
20443
  function recordValidatorFor(name, version = CURRENT_SHARD_VERSION) {
19656
- const key2 = `${version}:${name}`;
19657
- const cached = recordValidators.get(key2);
20444
+ const key3 = `${version}:${name}`;
20445
+ const cached = recordValidators.get(key3);
19658
20446
  if (cached) return cached;
19659
20447
  const schema = RECORD_V1_SCHEMAS[version][name];
19660
20448
  const validator = getRecordAjv().getSchema(schema.$id) ?? getRecordAjv().compile(schema);
19661
- recordValidators.set(key2, validator);
20449
+ recordValidators.set(key3, validator);
19662
20450
  return validator;
19663
20451
  }
19664
20452
  function fullValidatorFor(name, version = CURRENT_SHARD_VERSION) {
19665
- const key2 = `${version}:${name}`;
19666
- const cached = fullValidators.get(key2);
20453
+ const key3 = `${version}:${name}`;
20454
+ const cached = fullValidators.get(key3);
19667
20455
  if (cached) return cached;
19668
20456
  const schema = FULL_V1_SCHEMAS[version][name];
19669
20457
  const validator = getFullAjv().getSchema(schema.$id) ?? getFullAjv().compile(schema);
19670
- fullValidators.set(key2, validator);
20458
+ fullValidators.set(key3, validator);
19671
20459
  return validator;
19672
20460
  }
19673
20461
  function formatErrors(errors) {
@@ -19682,7 +20470,7 @@ function profileOf(value) {
19682
20470
  return typeof profile === "string" ? profile : void 0;
19683
20471
  }
19684
20472
  function validateShardManifest(value) {
19685
- let validate3;
20473
+ let validate4;
19686
20474
  const profile = profileOf(value);
19687
20475
  if (profile === "core-v1") {
19688
20476
  const version = value && typeof value === "object" && !Array.isArray(value) ? coreSchemaVersion(String(value.version ?? "")) : void 0;
@@ -19692,7 +20480,7 @@ function validateShardManifest(value) {
19692
20480
  errors: ["(root) uses an unsupported canonical core-v1 schema version"]
19693
20481
  };
19694
20482
  }
19695
- validate3 = coreValidatorFor("manifest", version);
20483
+ validate4 = coreValidatorFor("manifest", version);
19696
20484
  } else if (profile === "record-v1") {
19697
20485
  const version = value && typeof value === "object" && !Array.isArray(value) ? recordSchemaVersion(String(value.version ?? "")) : void 0;
19698
20486
  if (!version) {
@@ -19701,7 +20489,7 @@ function validateShardManifest(value) {
19701
20489
  errors: ["(root) uses an unsupported canonical record-v1 schema version"]
19702
20490
  };
19703
20491
  }
19704
- validate3 = recordValidatorFor("manifest", version);
20492
+ validate4 = recordValidatorFor("manifest", version);
19705
20493
  } else if (profile === "full-v1") {
19706
20494
  const version = value && typeof value === "object" && !Array.isArray(value) ? fullSchemaVersion(String(value.version ?? "")) : void 0;
19707
20495
  if (!version) {
@@ -19710,17 +20498,17 @@ function validateShardManifest(value) {
19710
20498
  errors: ["(root) uses an unsupported canonical full-v1 schema version"]
19711
20499
  };
19712
20500
  }
19713
- validate3 = fullValidatorFor("manifest", version);
20501
+ validate4 = fullValidatorFor("manifest", version);
19714
20502
  } else {
19715
- validate3 = legacyValidatorFor("manifest");
20503
+ validate4 = legacyValidatorFor("manifest");
19716
20504
  }
19717
- const valid = validate3(value);
19718
- return { valid, errors: formatErrors(validate3.errors) };
20505
+ const valid = validate4(value);
20506
+ return { valid, errors: formatErrors(validate4.errors) };
19719
20507
  }
19720
20508
  function parseJsonArray(bytes, path) {
19721
20509
  if (!bytes) return { records: [], errors: [] };
19722
20510
  try {
19723
- const value = JSON.parse(decoder.decode(bytes));
20511
+ const value = JSON.parse(decoder2.decode(bytes));
19724
20512
  if (!Array.isArray(value)) return { records: [], errors: [`${path} must be a JSON array`] };
19725
20513
  return { records: value, errors: [] };
19726
20514
  } catch {
@@ -19729,7 +20517,7 @@ function parseJsonArray(bytes, path) {
19729
20517
  }
19730
20518
  function parseJsonl(bytes, path) {
19731
20519
  if (!bytes) return { records: [], errors: [] };
19732
- const text = decoder.decode(bytes).trim();
20520
+ const text = decoder2.decode(bytes).trim();
19733
20521
  if (!text) return { records: [], errors: [] };
19734
20522
  const records = [];
19735
20523
  const errors = [];
@@ -19973,7 +20761,7 @@ function validateFullV1Structure(files, manifest) {
19973
20761
  const signatureBytes = files.get("signature.json");
19974
20762
  if (signatureBytes) {
19975
20763
  try {
19976
- const signature = JSON.parse(decoder.decode(signatureBytes));
20764
+ const signature = JSON.parse(decoder2.decode(signatureBytes));
19977
20765
  const signatureValidator = fullValidatorFor("signature", schemaVersion);
19978
20766
  if (!signatureValidator(signature)) {
19979
20767
  errors.push(
@@ -20069,7 +20857,7 @@ function validateShardArchive(input) {
20069
20857
  if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
20070
20858
  let manifest;
20071
20859
  try {
20072
- manifest = JSON.parse(decoder.decode(manifestBytes));
20860
+ manifest = JSON.parse(decoder2.decode(manifestBytes));
20073
20861
  } catch {
20074
20862
  return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
20075
20863
  }
@@ -20088,7 +20876,7 @@ async function validateCoreV1ShardArchive(input) {
20088
20876
  if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
20089
20877
  let manifest;
20090
20878
  try {
20091
- manifest = JSON.parse(decoder.decode(manifestBytes));
20879
+ manifest = JSON.parse(decoder2.decode(manifestBytes));
20092
20880
  } catch {
20093
20881
  return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
20094
20882
  }
@@ -20111,7 +20899,7 @@ async function validateRecordV1ShardArchive(input) {
20111
20899
  if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
20112
20900
  let manifest;
20113
20901
  try {
20114
- manifest = JSON.parse(decoder.decode(manifestBytes));
20902
+ manifest = JSON.parse(decoder2.decode(manifestBytes));
20115
20903
  } catch {
20116
20904
  return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
20117
20905
  }
@@ -20134,7 +20922,7 @@ async function validateFullV1ShardArchive(input) {
20134
20922
  if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
20135
20923
  let manifest;
20136
20924
  try {
20137
- manifest = JSON.parse(decoder.decode(manifestBytes));
20925
+ manifest = JSON.parse(decoder2.decode(manifestBytes));
20138
20926
  } catch {
20139
20927
  return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
20140
20928
  }
@@ -20163,9 +20951,9 @@ async function validateFullV1ShardArchive(input) {
20163
20951
  return { valid: errors.length === 0, errors };
20164
20952
  }
20165
20953
  function validateShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
20166
- let validate3;
20954
+ let validate4;
20167
20955
  if (profile === "core-v1" && component in CORE_V1_COMPONENT_FILES) {
20168
- validate3 = coreValidatorFor(component, version);
20956
+ validate4 = coreValidatorFor(component, version);
20169
20957
  } else if (profile === "record-v1" && component in RECORD_V1_COMPONENT_FILES) {
20170
20958
  const canonicalVersion = recordSchemaVersion(version);
20171
20959
  if (!canonicalVersion) {
@@ -20174,7 +20962,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
20174
20962
  errors: [`(root) uses an unsupported canonical record-v1 schema version ${version}`]
20175
20963
  };
20176
20964
  }
20177
- validate3 = recordValidatorFor(component, canonicalVersion);
20965
+ validate4 = recordValidatorFor(component, canonicalVersion);
20178
20966
  } else if (profile === "full-v1" && component in FULL_V1_COMPONENT_FILES) {
20179
20967
  const canonicalVersion = fullSchemaVersion(version);
20180
20968
  if (!canonicalVersion) {
@@ -20183,7 +20971,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
20183
20971
  errors: [`(root) uses an unsupported canonical full-v1 schema version ${version}`]
20184
20972
  };
20185
20973
  }
20186
- validate3 = fullValidatorFor(component, canonicalVersion);
20974
+ validate4 = fullValidatorFor(component, canonicalVersion);
20187
20975
  } else {
20188
20976
  const legacyDef = LEGACY_COMPONENT_SCHEMA_DEFS[component];
20189
20977
  if (!legacyDef) {
@@ -20192,10 +20980,10 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
20192
20980
  errors: [`(root) component '${component}' requires an explicit full-v1 profile`]
20193
20981
  };
20194
20982
  }
20195
- validate3 = legacyValidatorFor(legacyDef);
20983
+ validate4 = legacyValidatorFor(legacyDef);
20196
20984
  }
20197
- const valid = validate3(value);
20198
- return { valid, errors: formatErrors(validate3.errors) };
20985
+ const valid = validate4(value);
20986
+ return { valid, errors: formatErrors(validate4.errors) };
20199
20987
  }
20200
20988
  function assertShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
20201
20989
  const result = validateShardComponentRecord(component, value, profile, version);
@@ -20512,6 +21300,12 @@ var ManageNoteInputSchema = z.object({
20512
21300
  });
20513
21301
  var SearchInputSchema = z.object({
20514
21302
  query: z.string(),
21303
+ metadataPredicates: z.unknown().transform((value) => {
21304
+ validateMetadataPredicates(value);
21305
+ return value;
21306
+ }).optional(),
21307
+ tenant_id: z.string().min(1).optional(),
21308
+ archive_id: z.string().min(1).nullable().optional(),
20515
21309
  mode: z.enum(["text", "semantic", "hybrid", "auto"]).default("text"),
20516
21310
  query_embedding: z.array(z.number()).optional(),
20517
21311
  embeddingSetId: z.string().optional(),
@@ -20576,6 +21370,366 @@ async function manageNote(db, rawInput, events) {
20576
21370
 
20577
21371
  // src/remote-contract.ts
20578
21372
  init_geometry_buffer();
21373
+
21374
+ // src/remote-search-schema.ts
21375
+ init_geometry_buffer();
21376
+
21377
+ // schemas/metadata-search/candidate/1.0.0/search-rest.schema.json
21378
+ var search_rest_schema_default = {
21379
+ $schema: "https://json-schema.org/draft/2020-12/schema",
21380
+ $id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/search-rest.schema.json",
21381
+ title: "Candidate canonical GET search request and response",
21382
+ description: "Producer authority candidate. Schema validation is supplemented by same-note/canonical evidence binding, exact returned totals, strict-filter aggregate count and metadata range semantics. No auth grant or complete capability promotion.",
21383
+ $defs: {
21384
+ StrictSearchFilterInput: {
21385
+ type: "object",
21386
+ description: "Decoded strict_filter JSON. Unknown keys retain legacy ignored behavior. Sum of the five list lengths must not exceed 1000; name resolution still requires current authorized storage.",
21387
+ additionalProperties: true,
21388
+ properties: {
21389
+ required_tags: {
21390
+ type: "array",
21391
+ maxItems: 1e3,
21392
+ items: {
21393
+ type: "string"
21394
+ },
21395
+ default: []
21396
+ },
21397
+ any_tags: {
21398
+ type: "array",
21399
+ maxItems: 1e3,
21400
+ items: {
21401
+ type: "string"
21402
+ },
21403
+ default: []
21404
+ },
21405
+ excluded_tags: {
21406
+ type: "array",
21407
+ maxItems: 1e3,
21408
+ items: {
21409
+ type: "string"
21410
+ },
21411
+ default: []
21412
+ },
21413
+ required_schemes: {
21414
+ type: "array",
21415
+ maxItems: 1e3,
21416
+ items: {
21417
+ type: "string"
21418
+ },
21419
+ default: []
21420
+ },
21421
+ excluded_schemes: {
21422
+ type: "array",
21423
+ maxItems: 1e3,
21424
+ items: {
21425
+ type: "string"
21426
+ },
21427
+ default: []
21428
+ },
21429
+ min_tag_count: {
21430
+ type: ["integer", "null"],
21431
+ minimum: -2147483648,
21432
+ maximum: 2147483647
21433
+ },
21434
+ include_untagged: {
21435
+ type: "boolean",
21436
+ default: true
21437
+ }
21438
+ }
21439
+ },
21440
+ SearchRestRequest: {
21441
+ type: "object",
21442
+ description: "Decoded GET query parameters. JSON-content parameters are decoded to JSON values before this schema is applied. This is not a POST request body. Unknown query keys retain legacy ignored behavior and cannot grant tenant/archive authorization.",
21443
+ required: [
21444
+ "q"
21445
+ ],
21446
+ additionalProperties: true,
21447
+ properties: {
21448
+ q: {
21449
+ type: "string",
21450
+ description: "Search expression. Empty text remains accepted."
21451
+ },
21452
+ limit: {
21453
+ type: "integer",
21454
+ minimum: 0,
21455
+ maximum: 1e3,
21456
+ default: 20
21457
+ },
21458
+ filters: {
21459
+ type: "string",
21460
+ description: "Legacy filter expression; combined with comma-separated tags."
21461
+ },
21462
+ mode: {
21463
+ type: "string",
21464
+ default: "hybrid",
21465
+ description: "fts selects lexical search, semantic selects vector search. hybrid, absent and other legacy values select hybrid; failures have explicit FTS degradation."
21466
+ },
21467
+ set: {
21468
+ type: "string",
21469
+ description: "Embedding-set slug resolved within the authorized memory and tenant."
21470
+ },
21471
+ created_after: {
21472
+ type: "string",
21473
+ format: "date-time"
21474
+ },
21475
+ created_before: {
21476
+ type: "string",
21477
+ format: "date-time"
21478
+ },
21479
+ updated_after: {
21480
+ type: "string",
21481
+ format: "date-time"
21482
+ },
21483
+ updated_before: {
21484
+ type: "string",
21485
+ format: "date-time"
21486
+ },
21487
+ since: {
21488
+ type: "string",
21489
+ description: "Relative created-after time; explicit created_after wins. Unrecognized relative text retains legacy ignored behavior."
21490
+ },
21491
+ tags: {
21492
+ type: "string",
21493
+ description: "Comma-separated tags; trimmed nonempty entries are AND requirements."
21494
+ },
21495
+ strict_filter: {
21496
+ $ref: "#/$defs/StrictSearchFilterInput",
21497
+ "x-fortemi-query-content": "application/json"
21498
+ },
21499
+ metadata_predicates: {
21500
+ $ref: "predicates.schema.json",
21501
+ "x-fortemi-query-content": "application/json",
21502
+ "x-fortemi-max-encoded-utf8-bytes": 1048576
21503
+ },
21504
+ diversity: {
21505
+ type: "number",
21506
+ minimum: -34028234663852886e22,
21507
+ maximum: 34028234663852886e22,
21508
+ description: "Finite f32 input, clamped to [0,1] before MMR; zero is pure relevance."
21509
+ }
21510
+ }
21511
+ },
21512
+ SearchHitFields: {
21513
+ type: "object",
21514
+ required: [
21515
+ "note_id",
21516
+ "score",
21517
+ "snippet"
21518
+ ],
21519
+ properties: {
21520
+ note_id: {
21521
+ type: "string",
21522
+ format: "uuid"
21523
+ },
21524
+ score: {
21525
+ type: "number",
21526
+ description: "Finite retrieval/fusion score, not a probability."
21527
+ },
21528
+ snippet: {
21529
+ type: [
21530
+ "string",
21531
+ "null"
21532
+ ],
21533
+ description: "Display only; not citation text or coordinates."
21534
+ },
21535
+ title: {
21536
+ type: "string"
21537
+ },
21538
+ tags: {
21539
+ type: "array",
21540
+ items: {
21541
+ type: "string"
21542
+ }
21543
+ },
21544
+ embedding_status: {
21545
+ enum: [
21546
+ "ready",
21547
+ "pending",
21548
+ "failed",
21549
+ "none"
21550
+ ]
21551
+ },
21552
+ evidence: {
21553
+ $ref: "evidence-set.schema.json"
21554
+ }
21555
+ }
21556
+ },
21557
+ SearchHit: {
21558
+ type: "object",
21559
+ allOf: [
21560
+ {
21561
+ $ref: "#/$defs/SearchHitFields"
21562
+ }
21563
+ ],
21564
+ unevaluatedProperties: false
21565
+ },
21566
+ ChainSearchInfo: {
21567
+ type: "object",
21568
+ additionalProperties: false,
21569
+ required: [
21570
+ "chain_id",
21571
+ "original_title",
21572
+ "chunks_matched",
21573
+ "best_chunk_sequence",
21574
+ "total_chunks"
21575
+ ],
21576
+ description: "Legacy display aggregation. Index/count fields are currently heuristic, not native citation coordinates; use evidence for exact unit identity.",
21577
+ properties: {
21578
+ chain_id: {
21579
+ type: "string",
21580
+ format: "uuid"
21581
+ },
21582
+ original_title: {
21583
+ type: "string"
21584
+ },
21585
+ chunks_matched: {
21586
+ type: "integer",
21587
+ minimum: 0
21588
+ },
21589
+ best_chunk_sequence: {
21590
+ type: "integer",
21591
+ minimum: 0,
21592
+ maximum: 4294967295
21593
+ },
21594
+ total_chunks: {
21595
+ type: "integer",
21596
+ minimum: 0,
21597
+ maximum: 4294967295
21598
+ }
21599
+ }
21600
+ },
21601
+ EnhancedSearchHit: {
21602
+ type: "object",
21603
+ allOf: [
21604
+ {
21605
+ $ref: "#/$defs/SearchHitFields"
21606
+ },
21607
+ {
21608
+ type: "object",
21609
+ properties: {
21610
+ chain_info: {
21611
+ $ref: "#/$defs/ChainSearchInfo"
21612
+ }
21613
+ }
21614
+ }
21615
+ ],
21616
+ unevaluatedProperties: false
21617
+ },
21618
+ SearchDegradation: {
21619
+ type: "object",
21620
+ additionalProperties: false,
21621
+ required: [
21622
+ "code",
21623
+ "effective_mode"
21624
+ ],
21625
+ properties: {
21626
+ code: {
21627
+ type: "string",
21628
+ pattern: "^[a-z][a-z0-9_]{0,63}$"
21629
+ },
21630
+ effective_mode: {
21631
+ const: "fts"
21632
+ }
21633
+ }
21634
+ },
21635
+ SearchRestResponse: {
21636
+ type: "object",
21637
+ additionalProperties: false,
21638
+ required: [
21639
+ "results",
21640
+ "query",
21641
+ "total",
21642
+ "degraded"
21643
+ ],
21644
+ properties: {
21645
+ results: {
21646
+ type: "array",
21647
+ maxItems: 1e3,
21648
+ items: {
21649
+ $ref: "#/$defs/EnhancedSearchHit"
21650
+ }
21651
+ },
21652
+ query: {
21653
+ type: "string"
21654
+ },
21655
+ total: {
21656
+ type: "integer",
21657
+ minimum: 0,
21658
+ maximum: 1e3,
21659
+ description: "Returned hit count, exactly results.length; not total matches in storage."
21660
+ },
21661
+ degraded: {
21662
+ type: "boolean"
21663
+ },
21664
+ degradation: {
21665
+ $ref: "#/$defs/SearchDegradation"
21666
+ }
21667
+ },
21668
+ if: {
21669
+ properties: {
21670
+ degraded: {
21671
+ const: true
21672
+ }
21673
+ }
21674
+ },
21675
+ then: {
21676
+ properties: {
21677
+ degradation: {}
21678
+ },
21679
+ required: [
21680
+ "degradation"
21681
+ ]
21682
+ },
21683
+ else: {
21684
+ not: {
21685
+ properties: {
21686
+ degradation: {}
21687
+ },
21688
+ required: [
21689
+ "degradation"
21690
+ ]
21691
+ }
21692
+ }
21693
+ }
21694
+ }
21695
+ };
21696
+
21697
+ // schemas/metadata-search/candidate/1.0.0/evidence-resolution.schema.json
21698
+ var evidence_resolution_schema_default = {
21699
+ $schema: "https://json-schema.org/draft/2020-12/schema",
21700
+ $id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-resolution.schema.json",
21701
+ title: "Candidate current-storage evidence resolution",
21702
+ $defs: {
21703
+ SearchEvidenceResolveRequest: {
21704
+ type: "object",
21705
+ additionalProperties: false,
21706
+ required: ["locator"],
21707
+ properties: {
21708
+ locator: { $ref: "evidence-locator.schema.json" },
21709
+ metadata_predicates: { $ref: "predicates.schema.json" },
21710
+ include_archived: { type: "boolean", default: false }
21711
+ }
21712
+ },
21713
+ SearchEvidenceResolveResponse: {
21714
+ type: "object",
21715
+ additionalProperties: false,
21716
+ required: ["text"],
21717
+ properties: {
21718
+ text: { type: "string", maxLength: 16777216 }
21719
+ }
21720
+ }
21721
+ }
21722
+ };
21723
+
21724
+ // src/remote-search-schema.ts
21725
+ var timestamp = z.string().datetime({ offset: true });
21726
+ var ajv2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).addFormat("date-time", { type: "string", validate: (value) => timestamp.safeParse(value).success }).addKeyword({ keyword: "x-fortemi-query-content", schemaType: "string", valid: true }).addKeyword({ keyword: "x-fortemi-max-encoded-utf8-bytes", schemaType: "number", valid: true }).addSchema([search_rest_schema_default, evidence_locator_schema_default, evidence_set_schema_default, evidence_resolution_schema_default]).addSchema(predicates_schema_default, new URL("predicates.schema.json", search_rest_schema_default.$id).href);
21727
+ var isSearchRestRequest = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestRequest" });
21728
+ var isSearchRestResponse = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestResponse" });
21729
+ var isEvidenceResolveRequest = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveRequest" });
21730
+ var isEvidenceResolveResponse = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveResponse" });
21731
+
21732
+ // src/remote-contract.ts
20579
21733
  var uuid3 = z.string().uuid().transform((value) => value.toLowerCase());
20580
21734
  var metadata = z.object({
20581
21735
  id: uuid3,
@@ -20618,7 +21772,7 @@ function parseRemoteNoteDetail(value) {
20618
21772
  return { ...projectNote({ ...result.note, tags: result.tags }), content: result.revised.content };
20619
21773
  });
20620
21774
  }
20621
- var timestamp = z.string().datetime({ offset: true });
21775
+ var timestamp2 = z.string().datetime({ offset: true });
20622
21776
  function remoteNoteId(value) {
20623
21777
  const parsed = uuid3.safeParse(value);
20624
21778
  if (!parsed.success) throw new RemoteBackendError("invalid-request");
@@ -20631,7 +21785,7 @@ var link = z.object({
20631
21785
  to_url: z.string().nullable(),
20632
21786
  kind: z.string(),
20633
21787
  score: z.number().finite(),
20634
- created_at_utc: timestamp,
21788
+ created_at_utc: timestamp2,
20635
21789
  snippet: z.string().nullable(),
20636
21790
  metadata: z.unknown().refine((value) => value !== void 0)
20637
21791
  });
@@ -20670,7 +21824,7 @@ var conceptAssignment = z.tuple([
20670
21824
  source: z.string(),
20671
21825
  relevance_score: z.number().finite(),
20672
21826
  is_primary: z.boolean(),
20673
- created_at: timestamp,
21827
+ created_at: timestamp2,
20674
21828
  confidence: z.number().finite().optional(),
20675
21829
  created_by: z.string().optional()
20676
21830
  }),
@@ -20678,8 +21832,8 @@ var conceptAssignment = z.tuple([
20678
21832
  id: uuid3,
20679
21833
  primary_scheme_id: uuid3,
20680
21834
  pref_label: z.string(),
20681
- created_at: timestamp,
20682
- updated_at: timestamp
21835
+ created_at: timestamp2,
21836
+ updated_at: timestamp2
20683
21837
  })
20684
21838
  ]);
20685
21839
  function parseRemoteConcepts(value, noteId) {
@@ -20714,8 +21868,8 @@ var provenanceActivity = z.object({
20714
21868
  revision_id: uuid3.nullable(),
20715
21869
  activity_type: z.string(),
20716
21870
  model_name: z.string().nullable(),
20717
- started_at: timestamp,
20718
- ended_at: timestamp.nullable(),
21871
+ started_at: timestamp2,
21872
+ ended_at: timestamp2.nullable(),
20719
21873
  metadata: z.unknown().refine((value) => value !== void 0)
20720
21874
  });
20721
21875
  var provenanceEdge = z.object({
@@ -20724,7 +21878,7 @@ var provenanceEdge = z.object({
20724
21878
  source_note_id: uuid3.nullable(),
20725
21879
  source_url: z.string().nullable(),
20726
21880
  relation: z.string(),
20727
- created_at_utc: timestamp
21881
+ created_at_utc: timestamp2
20728
21882
  });
20729
21883
  var provenanceChain = z.object({
20730
21884
  note_id: uuid3,
@@ -20762,12 +21916,14 @@ function remoteSearchParameters(query, options) {
20762
21916
  if (typeof query !== "string" || !parsed.success) throw new RemoteBackendError("invalid-request");
20763
21917
  const value = parsed.data;
20764
21918
  if ((value.offset ?? 0) !== 0 || (value.source?.length ?? 0) > 0) throw new RemoteBackendError("unsupported-operation");
20765
- return {
21919
+ const parameters = {
20766
21920
  q: query,
20767
21921
  mode: value.mode,
20768
21922
  limit: value.limit,
20769
21923
  ...value.tags?.length ? { tags: value.tags.join(",") } : {}
20770
21924
  };
21925
+ if (!isSearchRestRequest(parameters)) throw new RemoteBackendError("invalid-request");
21926
+ return parameters;
20771
21927
  }
20772
21928
  var searchHit = z.object({
20773
21929
  note_id: uuid3,
@@ -20776,6 +21932,7 @@ var searchHit = z.object({
20776
21932
  title: z.string().optional(),
20777
21933
  tags: z.array(z.string()).optional(),
20778
21934
  embedding_status: z.enum(["ready", "pending", "failed", "none"]).optional(),
21935
+ evidence: z.unknown().optional(),
20779
21936
  chain_info: z.object({
20780
21937
  chain_id: uuid3,
20781
21938
  original_title: z.string(),
@@ -20783,10 +21940,13 @@ var searchHit = z.object({
20783
21940
  best_chunk_sequence: z.number().int().nonnegative(),
20784
21941
  total_chunks: z.number().int().nonnegative()
20785
21942
  }).optional()
20786
- });
21943
+ }).transform(({ evidence, ...hit }) => ({
21944
+ ...hit,
21945
+ ...evidence === void 0 ? {} : { evidence: parseSearchEvidenceSet(evidence, hit.note_id) }
21946
+ }));
20787
21947
  var searchDegradation = z.object({
20788
21948
  code: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
20789
- effective_mode: searchMode
21949
+ effective_mode: z.literal("fts")
20790
21950
  });
20791
21951
  var searchResponse = z.object({
20792
21952
  query: z.string(),
@@ -20797,8 +21957,10 @@ var searchResponse = z.object({
20797
21957
  });
20798
21958
  function parseRemoteSearch(value, query, limit) {
20799
21959
  return remoteProjection(() => {
21960
+ if (!isSearchRestResponse(value)) throw new Error("Invalid search schema");
20800
21961
  const result = searchResponse.parse(value);
20801
21962
  if (result.query !== query || result.total !== result.results.length || result.results.length > limit || result.degraded !== (result.degradation !== void 0)) throw new Error("Invalid search envelope");
21963
+ if (result.results.some((hit) => hit.chain_info && hit.chain_info.chain_id !== hit.note_id)) throw new Error("Invalid chain identity");
20802
21964
  return result;
20803
21965
  });
20804
21966
  }
@@ -20834,6 +21996,135 @@ function parseRemoteRestored(value, id) {
20834
21996
  });
20835
21997
  }
20836
21998
 
21999
+ // src/backend-search-options.ts
22000
+ init_geometry_buffer();
22001
+ function validateBackendSearchOptions(options, support) {
22002
+ if (options?.metadataPredicates !== void 0) {
22003
+ validateMetadataPredicates(options.metadataPredicates);
22004
+ if (!support.metadata) throw new Error("BACKEND_METADATA_PREDICATES_UNSUPPORTED");
22005
+ }
22006
+ if (options?.tenant_id !== void 0 || options?.archive_id !== void 0) {
22007
+ if (!support.scope) throw new Error("BACKEND_SEARCH_SCOPE_UNSUPPORTED");
22008
+ if (options.tenant_id !== void 0 && (typeof options.tenant_id !== "string" || !options.tenant_id.length) || options.archive_id !== void 0 && options.archive_id !== null && (typeof options.archive_id !== "string" || !options.archive_id.length)) {
22009
+ throw new Error("BACKEND_SEARCH_SCOPE_INVALID");
22010
+ }
22011
+ }
22012
+ if (options?.mode !== void 0 && support.modes && !support.modes.includes(options.mode)) {
22013
+ throw new Error("BACKEND_SEARCH_MODE_UNSUPPORTED");
22014
+ }
22015
+ }
22016
+
22017
+ // src/remote-evidence-resolution.ts
22018
+ init_geometry_buffer();
22019
+ var encoder3 = new TextEncoder();
22020
+ var decoder3 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
22021
+ var invalidRequest = () => new RemoteBackendError("invalid-request");
22022
+ var invalidResponse = () => new RemoteBackendError("invalid-response");
22023
+ function prepare(value, options = {}) {
22024
+ try {
22025
+ if (!options || typeof options !== "object" || Array.isArray(options) || ![Object.prototype, null].includes(Object.getPrototypeOf(options)) || Reflect.ownKeys(options).some((key3) => !["metadataPredicates", "includeArchived", "signal"].includes(String(key3)))) throw invalidRequest();
22026
+ const locator = parseSearchEvidenceLocator(value);
22027
+ if (locator.span.end > MAX_EVIDENCE_BYTES) throw invalidRequest();
22028
+ const metadata2 = Object.hasOwn(options, "metadataPredicates") ? options.metadataPredicates : void 0;
22029
+ const archived = Object.hasOwn(options, "includeArchived") ? options.includeArchived : void 0;
22030
+ const signal = Object.hasOwn(options, "signal") ? options.signal : void 0;
22031
+ if (signal !== void 0 && !(signal instanceof AbortSignal)) throw invalidRequest();
22032
+ if (metadata2 !== void 0) validateMetadataPredicates(metadata2);
22033
+ const request = {
22034
+ locator,
22035
+ ...metadata2 === void 0 ? {} : { metadata_predicates: metadata2 },
22036
+ ...archived === void 0 ? {} : { include_archived: archived }
22037
+ };
22038
+ if (!isEvidenceResolveRequest(request)) throw invalidRequest();
22039
+ const body = JSON.stringify(request);
22040
+ if (encoder3.encode(body).length > 65536) throw invalidRequest();
22041
+ const wire = JSON.parse(body);
22042
+ if (!isEvidenceResolveRequest(wire)) throw invalidRequest();
22043
+ const encoded = wire;
22044
+ parseSearchEvidenceLocator(encoded.locator);
22045
+ if (encoded.metadata_predicates !== void 0) validateMetadataPredicates(encoded.metadata_predicates);
22046
+ return { body, signal, length: locator.span.end - locator.span.start };
22047
+ } catch {
22048
+ throw invalidRequest();
22049
+ }
22050
+ }
22051
+ async function resolveRemoteEvidence(value, options, send) {
22052
+ const prepared = prepare(value, options);
22053
+ if (prepared.signal?.aborted) throw new RemoteBackendError("aborted");
22054
+ const controller = new AbortController();
22055
+ const abort = () => controller.abort();
22056
+ prepared.signal?.addEventListener("abort", abort, { once: true });
22057
+ const timer = setTimeout(abort, 3e4);
22058
+ let reader;
22059
+ let completed = false;
22060
+ let rejectAbort = () => {
22061
+ };
22062
+ const aborted = new Promise((_resolve, reject) => {
22063
+ rejectAbort = () => reject(new RemoteBackendError("aborted"));
22064
+ });
22065
+ controller.signal.addEventListener("abort", rejectAbort, { once: true });
22066
+ async function perform() {
22067
+ const response = await send(prepared.body, controller.signal);
22068
+ if (controller.signal.aborted) {
22069
+ void response.body?.cancel().catch(() => {
22070
+ });
22071
+ throw new RemoteBackendError("aborted");
22072
+ }
22073
+ reader = response.body?.getReader();
22074
+ if (!response.ok) throw new RemoteBackendError("http", response.status);
22075
+ if (response.status !== 200 || !reader || response.headers.get("content-type")?.split(";")[0].trim().toLowerCase() !== "application/json" || !response.headers.get("cache-control")?.split(",").some((part) => part.trim().toLowerCase() === "no-store")) throw invalidResponse();
22076
+ const maximum = prepared.length * 6 + 64;
22077
+ const advertised = response.headers.get("content-length");
22078
+ if (advertised !== null && (!/^\d+$/.test(advertised) || Number(advertised) > maximum)) throw invalidResponse();
22079
+ let bytes = new Uint8Array(Math.min(maximum, 4096));
22080
+ let length = 0;
22081
+ while (true) {
22082
+ const { done, value: chunk } = await reader.read();
22083
+ if (done) {
22084
+ completed = true;
22085
+ break;
22086
+ }
22087
+ const nextLength = length + chunk.byteLength;
22088
+ if (nextLength > maximum) throw invalidResponse();
22089
+ if (nextLength > bytes.length) {
22090
+ const grown = new Uint8Array(Math.min(maximum, Math.max(nextLength, bytes.length * 2)));
22091
+ grown.set(bytes.subarray(0, length));
22092
+ bytes = grown;
22093
+ }
22094
+ bytes.set(chunk, length);
22095
+ length = nextLength;
22096
+ }
22097
+ let data;
22098
+ try {
22099
+ data = JSON.parse(decoder3.decode(bytes.subarray(0, length)));
22100
+ } catch {
22101
+ throw invalidResponse();
22102
+ }
22103
+ if (!isEvidenceResolveResponse(data)) throw invalidResponse();
22104
+ const text = data.text;
22105
+ if (text.length > prepared.length) throw invalidResponse();
22106
+ const textBytes2 = encoder3.encode(text);
22107
+ if (textBytes2.length !== prepared.length || decoder3.decode(textBytes2) !== text) throw invalidResponse();
22108
+ return text;
22109
+ }
22110
+ try {
22111
+ return await Promise.race([perform(), aborted]);
22112
+ } catch (error) {
22113
+ if (error instanceof RemoteBackendError) throw error;
22114
+ throw new RemoteBackendError(controller.signal.aborted || error instanceof Error && error.name === "AbortError" ? "aborted" : "transport");
22115
+ } finally {
22116
+ clearTimeout(timer);
22117
+ prepared.signal?.removeEventListener("abort", abort);
22118
+ controller.signal.removeEventListener("abort", rejectAbort);
22119
+ controller.abort();
22120
+ if (reader) {
22121
+ if (!completed) void reader.cancel().catch(() => {
22122
+ });
22123
+ reader.releaseLock();
22124
+ }
22125
+ }
22126
+ }
22127
+
20837
22128
  // src/data-backend.ts
20838
22129
  var SEMANTIC_RANK = {
20839
22130
  none: 0,
@@ -20848,6 +22139,8 @@ var STARTUP_RANK = {
20848
22139
  };
20849
22140
  function missingFor(request, caps) {
20850
22141
  const missing = [];
22142
+ if (request.typedMetadataPredicates && !caps.typedMetadataPredicates) missing.push("typedMetadataPredicates");
22143
+ if (request.evidenceLocators && !caps.evidenceLocators) missing.push("evidenceLocators");
20851
22144
  if (request.read && !caps.read) missing.push("read");
20852
22145
  if (request.write && !caps.write) missing.push("write");
20853
22146
  if (request.merge && !caps.merge) missing.push("merge");
@@ -20971,9 +22264,45 @@ function shardProvenanceToBackend(edge) {
20971
22264
  }
20972
22265
  function createPGliteBackend(db, options = {}) {
20973
22266
  const semanticAvailable = options.semanticAvailable ?? false;
22267
+ const embedQuery = options.embedQuery;
22268
+ const canEmbed = semanticAvailable && typeof embedQuery === "function";
20974
22269
  const notes = new NotesRepository(db);
20975
22270
  const search = new SearchRepository(db, semanticAvailable);
20976
22271
  const links = new LinksRepository(db);
22272
+ async function searchNotes(query, o) {
22273
+ validateBackendSearchOptions(o, {
22274
+ metadata: true,
22275
+ scope: true,
22276
+ modes: canEmbed ? ["fts", "semantic", "hybrid"] : ["fts"]
22277
+ });
22278
+ const mode = o?.mode ?? "fts";
22279
+ const vector = mode === "fts" ? void 0 : await embedQuery(query);
22280
+ if (mode !== "fts" && (!Array.isArray(vector) || !vector.length || !Array.from(vector).every((value) => typeof value === "number" && Number.isFinite(value)))) {
22281
+ throw new Error("BACKEND_QUERY_EMBEDDING_INVALID");
22282
+ }
22283
+ const r = await search.search(query, {
22284
+ limit: o?.limit,
22285
+ offset: o?.offset,
22286
+ tagsAll: o?.tags,
22287
+ sources: o?.source,
22288
+ mode: mode === "fts" ? "text" : mode,
22289
+ metadataPredicates: o?.metadataPredicates,
22290
+ tenant_id: o?.tenant_id,
22291
+ archive_id: o?.archive_id,
22292
+ include_facets: true
22293
+ }, vector);
22294
+ return {
22295
+ hits: r.results.map((res) => ({
22296
+ note: searchResultToBackend(res),
22297
+ rank: res.rank,
22298
+ snippet: res.snippet,
22299
+ locators: res.locators,
22300
+ evidence: res.evidence
22301
+ })),
22302
+ total: r.total,
22303
+ facets: r.facets ? { tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count])) } : void 0
22304
+ };
22305
+ }
20977
22306
  async function linksOf(id) {
20978
22307
  const result = await links.listForNote(id);
20979
22308
  const urlLinks = await db.query(
@@ -21014,7 +22343,9 @@ function createPGliteBackend(db, options = {}) {
21014
22343
  write: true,
21015
22344
  merge: true,
21016
22345
  multiUser: false,
21017
- semantic: semanticAvailable ? "ann-full" : "none",
22346
+ typedMetadataPredicates: true,
22347
+ evidenceLocators: false,
22348
+ semantic: canEmbed ? "ann-full" : "none",
21018
22349
  startupCost: "index-build"
21019
22350
  },
21020
22351
  async listNotes(o) {
@@ -21029,24 +22360,8 @@ function createPGliteBackend(db, options = {}) {
21029
22360
  return null;
21030
22361
  }
21031
22362
  },
21032
- async search(query, o) {
21033
- const r = await search.search(query, {
21034
- limit: o?.limit,
21035
- offset: o?.offset,
21036
- tags: o?.tags,
21037
- source: o?.source?.[0],
21038
- include_facets: true
21039
- });
21040
- const hits = r.results.map((res) => ({
21041
- note: searchResultToBackend(res),
21042
- rank: res.rank,
21043
- snippet: res.snippet
21044
- }));
21045
- const facets = r.facets ? {
21046
- tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count]))
21047
- } : void 0;
21048
- return { hits, total: r.total, facets };
21049
- },
22363
+ search: searchNotes,
22364
+ ...canEmbed ? { semantic: async (query, k) => (await searchNotes(query, { mode: "semantic", limit: k })).hits } : {},
21050
22365
  async getNoteFull(id) {
21051
22366
  try {
21052
22367
  const f = await notes.get(id);
@@ -21072,6 +22387,7 @@ var DEFAULT_REMOTE_PATHS = {
21072
22387
  notes: "/api/v1/notes",
21073
22388
  note: "/api/v1/notes/:id",
21074
22389
  search: "/api/v1/search",
22390
+ resolveEvidence: "/api/v1/search/evidence/resolve",
21075
22391
  links: "/api/v1/notes/:id/links",
21076
22392
  concepts: "/api/v1/notes/:id/concepts",
21077
22393
  provenance: "/api/v1/notes/:id/provenance",
@@ -21082,12 +22398,12 @@ function remotePath(template, id) {
21082
22398
  }
21083
22399
  function remoteUrl(baseUrl, path, params) {
21084
22400
  const url = new URL(path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
21085
- for (const [key2, value] of Object.entries(params ?? {})) {
22401
+ for (const [key3, value] of Object.entries(params ?? {})) {
21086
22402
  if (value === void 0) continue;
21087
22403
  if (Array.isArray(value)) {
21088
- for (const item of value) url.searchParams.append(key2, String(item));
22404
+ for (const item of value) url.searchParams.append(key3, String(item));
21089
22405
  } else {
21090
- url.searchParams.set(key2, String(value));
22406
+ url.searchParams.set(key3, String(value));
21091
22407
  }
21092
22408
  }
21093
22409
  return url.toString();
@@ -21143,6 +22459,7 @@ function createRemoteBackend(config) {
21143
22459
  return note;
21144
22460
  }
21145
22461
  async function searchRemote(query, options, requireSemantic = false) {
22462
+ validateBackendSearchOptions(options, { metadata: false, scope: false });
21146
22463
  const params = remoteSearchParameters(query, options);
21147
22464
  const result = parseRemoteSearch(await getJson(paths.search, params), query, params.limit);
21148
22465
  if (requireSemantic && result.degraded) throw new RemoteBackendError("degraded-search");
@@ -21167,6 +22484,7 @@ function createRemoteBackend(config) {
21167
22484
  },
21168
22485
  rank: hit.score,
21169
22486
  ...hit.snippet === null ? {} : { snippet: hit.snippet },
22487
+ ...hit.evidence === void 0 ? {} : { evidence: hit.evidence },
21170
22488
  remoteSearch: {
21171
22489
  ...hit.title === void 0 ? {} : { title: hit.title },
21172
22490
  ...hit.tags === void 0 ? {} : { tags: hit.tags },
@@ -21223,6 +22541,8 @@ function createRemoteBackend(config) {
21223
22541
  merge: false,
21224
22542
  multiUser: true,
21225
22543
  semantic: "server",
22544
+ typedMetadataPredicates: false,
22545
+ evidenceLocators: false,
21226
22546
  startupCost: "network"
21227
22547
  },
21228
22548
  async listNotes(o) {
@@ -21250,6 +22570,20 @@ function createRemoteBackend(config) {
21250
22570
  }
21251
22571
  },
21252
22572
  search: searchRemote,
22573
+ async resolveEvidence(locator, options) {
22574
+ return resolveRemoteEvidence(locator, options, async (body, signal) => {
22575
+ const headers = await remoteHeaders(config, true);
22576
+ signal.throwIfAborted();
22577
+ return (config.fetchImpl ?? globalThis.fetch)(remoteUrl(config.baseUrl, paths.resolveEvidence ?? DEFAULT_REMOTE_PATHS.resolveEvidence), {
22578
+ method: "POST",
22579
+ headers,
22580
+ body,
22581
+ signal,
22582
+ cache: "no-store",
22583
+ redirect: "error"
22584
+ });
22585
+ });
22586
+ },
21253
22587
  getNoteFull,
21254
22588
  linksOf,
21255
22589
  conceptsOf,
@@ -21319,6 +22653,8 @@ function createShardBackend(reader, options = {}) {
21319
22653
  merge: false,
21320
22654
  multiUser: false,
21321
22655
  semantic,
22656
+ typedMetadataPredicates: false,
22657
+ evidenceLocators: false,
21322
22658
  startupCost: "instant"
21323
22659
  },
21324
22660
  async listNotes(o) {
@@ -21330,6 +22666,7 @@ function createShardBackend(reader, options = {}) {
21330
22666
  return n ? shardNoteToBackend(n) : null;
21331
22667
  },
21332
22668
  async search(query, o) {
22669
+ validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
21333
22670
  const r = await reader.search(query, { ...o, rank: true, snippets: true });
21334
22671
  const hits = r.rankedItems ? r.rankedItems.map((it) => ({
21335
22672
  note: shardNoteToBackend(it.note),
@@ -21873,26 +23210,26 @@ function isRecord(value) {
21873
23210
  function isSupportedState(value) {
21874
23211
  return typeof value === "string" && FORTEMI_COMPATIBILITY_STATES.includes(value);
21875
23212
  }
21876
- function requireRecord(parent, key2, errors) {
21877
- const value = parent[key2];
23213
+ function requireRecord(parent, key3, errors) {
23214
+ const value = parent[key3];
21878
23215
  if (!isRecord(value)) {
21879
- errors.push(`${key2} must be an object`);
23216
+ errors.push(`${key3} must be an object`);
21880
23217
  return null;
21881
23218
  }
21882
23219
  return value;
21883
23220
  }
21884
- function requireString(parent, key2, path, errors) {
21885
- const value = parent[key2];
23221
+ function requireString(parent, key3, path, errors) {
23222
+ const value = parent[key3];
21886
23223
  if (typeof value !== "string" || value.length === 0) {
21887
- errors.push(`${path}.${key2} must be a non-empty string`);
23224
+ errors.push(`${path}.${key3} must be a non-empty string`);
21888
23225
  return null;
21889
23226
  }
21890
23227
  return value;
21891
23228
  }
21892
- function requireBoolean(parent, key2, path, errors) {
21893
- const value = parent[key2];
23229
+ function requireBoolean(parent, key3, path, errors) {
23230
+ const value = parent[key3];
21894
23231
  if (typeof value !== "boolean") {
21895
- errors.push(`${path}.${key2} must be a boolean`);
23232
+ errors.push(`${path}.${key3} must be a boolean`);
21896
23233
  return null;
21897
23234
  }
21898
23235
  return value;
@@ -21942,24 +23279,24 @@ function validateFortemiCompatibilityResponse(raw) {
21942
23279
  }
21943
23280
  const capabilities = requireRecord(raw, "capabilities", errors);
21944
23281
  if (capabilities) {
21945
- for (const key2 of FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES) {
21946
- if (!isRecord(capabilities[key2])) {
21947
- errors.push(`capabilities.${key2} must be present as an object`);
23282
+ for (const key3 of FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES) {
23283
+ if (!isRecord(capabilities[key3])) {
23284
+ errors.push(`capabilities.${key3} must be present as an object`);
21948
23285
  }
21949
23286
  }
21950
- for (const [key2, value] of Object.entries(capabilities)) {
23287
+ for (const [key3, value] of Object.entries(capabilities)) {
21951
23288
  if (!isRecord(value)) {
21952
- errors.push(`capabilities.${key2} must be an object`);
23289
+ errors.push(`capabilities.${key3} must be an object`);
21953
23290
  continue;
21954
23291
  }
21955
23292
  if (!isSupportedState(value.state)) {
21956
- errors.push(`capabilities.${key2}.state must be one of ${FORTEMI_COMPATIBILITY_STATES.join(", ")}`);
23293
+ errors.push(`capabilities.${key3}.state must be one of ${FORTEMI_COMPATIBILITY_STATES.join(", ")}`);
21957
23294
  }
21958
23295
  if ("reason_code" in value && typeof value.reason_code !== "string") {
21959
- errors.push(`capabilities.${key2}.reason_code must be a string when present`);
23296
+ errors.push(`capabilities.${key3}.reason_code must be a string when present`);
21960
23297
  }
21961
23298
  if (value.state !== "available" && !value.reason_code) {
21962
- warnings.push(`capabilities.${key2} is ${String(value.state)} without reason_code`);
23299
+ warnings.push(`capabilities.${key3} is ${String(value.state)} without reason_code`);
21963
23300
  }
21964
23301
  }
21965
23302
  }
@@ -21978,7 +23315,7 @@ function validateFortemiCompatibilityResponse(raw) {
21978
23315
  };
21979
23316
  }
21980
23317
  function formatFortemiCompatibilitySummary(response) {
21981
- const capabilitySummary = Object.entries(response.capabilities).map(([key2, value]) => `${key2}=${value.state}`).sort().join(", ");
23318
+ const capabilitySummary = Object.entries(response.capabilities).map(([key3, value]) => `${key3}=${value.state}`).sort().join(", ");
21982
23319
  return [
21983
23320
  `Fortemi compatibility ${response.contract_revision}`,
21984
23321
  `api=${response.api.name}@${response.api.version}`,
@@ -24291,7 +25628,7 @@ var CollectionsRepository = class {
24291
25628
 
24292
25629
  // src/repositories/templates-repository.ts
24293
25630
  init_geometry_buffer();
24294
- function validate(record) {
25631
+ function validate2(record) {
24295
25632
  if (!validateShardComponentRecord("templates", record, "full-v1", "2.0.0").valid) throw new Error("Invalid native template");
24296
25633
  }
24297
25634
  var TemplatesRepository = class {
@@ -24309,7 +25646,7 @@ var TemplatesRepository = class {
24309
25646
  async create(input) {
24310
25647
  const id = generateId();
24311
25648
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
24312
- validate({
25649
+ validate2({
24313
25650
  id,
24314
25651
  name: input.name,
24315
25652
  content: input.content,
@@ -24329,13 +25666,13 @@ var TemplatesRepository = class {
24329
25666
  }
24330
25667
  async update(id, input) {
24331
25668
  const current = await this.get(id);
24332
- validate({ ...current, ...Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0)) });
25669
+ validate2({ ...current, ...Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0)) });
24333
25670
  const values = [];
24334
25671
  const assignments = ["updated_at = now()"];
24335
- for (const key2 of ["name", "content", "description", "format", "default_tags", "collection_id"]) {
24336
- if (input[key2] === void 0) continue;
24337
- values.push(key2 === "default_tags" ? JSON.stringify(input[key2]) : input[key2]);
24338
- assignments.push(`${key2} = $${values.length}${key2 === "default_tags" ? "::jsonb" : ""}`);
25672
+ for (const key3 of ["name", "content", "description", "format", "default_tags", "collection_id"]) {
25673
+ if (input[key3] === void 0) continue;
25674
+ values.push(key3 === "default_tags" ? JSON.stringify(input[key3]) : input[key3]);
25675
+ assignments.push(`${key3} = $${values.length}${key3 === "default_tags" ? "::jsonb" : ""}`);
24339
25676
  }
24340
25677
  values.push(id);
24341
25678
  await this.db.query(`UPDATE template SET ${assignments.join(", ")} WHERE id = $${values.length}`, values);
@@ -24496,8 +25833,8 @@ async function removeOmittedNativeSkos(tx, state, selectedNoteIds3) {
24496
25833
  await tx.query(
24497
25834
  `DELETE FROM ${table} existing WHERE existing.${owner} = ANY($1::text[])
24498
25835
  AND NOT EXISTS (SELECT 1 FROM UNNEST(${keys.map((_, index) => `$${index + 2}::text[]`).join(", ")}) incoming(${keys.join(", ")})
24499
- WHERE ${keys.map((key2) => `incoming.${key2} = existing.${key2}`).join(" AND ")})`,
24500
- [selected, ...keys.map((key2) => incoming.map((row) => nativeUuid(row[key2])))]
25836
+ WHERE ${keys.map((key3) => `incoming.${key3} = existing.${key3}`).join(" AND ")})`,
25837
+ [selected, ...keys.map((key3) => incoming.map((row) => nativeUuid(row[key3])))]
24501
25838
  );
24502
25839
  }
24503
25840
  }
@@ -25036,8 +26373,8 @@ async function captureKnowledge(db, rawInput, events) {
25036
26373
  if (!input.template) throw new Error("template is required for from_template action");
25037
26374
  let content = input.template;
25038
26375
  if (input.variables) {
25039
- for (const [key2, value] of Object.entries(input.variables)) {
25040
- content = content.replaceAll(`{{${key2}}}`, value);
26376
+ for (const [key3, value] of Object.entries(input.variables)) {
26377
+ content = content.replaceAll(`{{${key3}}}`, value);
25041
26378
  }
25042
26379
  }
25043
26380
  const note = await repo.create({
@@ -25063,6 +26400,9 @@ async function searchTool(db, rawInput) {
25063
26400
  }
25064
26401
  const repo = new SearchRepository(db, semanticAvailable);
25065
26402
  return repo.search(input.query, {
26403
+ metadataPredicates: input.metadataPredicates,
26404
+ tenant_id: input.tenant_id,
26405
+ archive_id: input.archive_id,
25066
26406
  limit: input.limit,
25067
26407
  offset: input.offset,
25068
26408
  mode: input.mode,
@@ -25087,10 +26427,10 @@ function zodToJsonSchema(schema) {
25087
26427
  const shape = schema.shape;
25088
26428
  const properties = {};
25089
26429
  const required = [];
25090
- for (const [key2, value] of Object.entries(shape)) {
25091
- properties[key2] = resolvePropertySchema(value);
26430
+ for (const [key3, value] of Object.entries(shape)) {
26431
+ properties[key3] = resolvePropertySchema(value);
25092
26432
  if (!(value instanceof z.ZodOptional) && !(value instanceof z.ZodDefault)) {
25093
- required.push(key2);
26433
+ required.push(key3);
25094
26434
  }
25095
26435
  }
25096
26436
  return {
@@ -27154,13 +28494,13 @@ var OpenAICompatibleProvider = class {
27154
28494
  throw new Error("Streaming not supported: response body is null");
27155
28495
  }
27156
28496
  const reader = response.body.getReader();
27157
- const decoder8 = new TextDecoder();
28497
+ const decoder10 = new TextDecoder();
27158
28498
  let buffer = "";
27159
28499
  try {
27160
28500
  while (true) {
27161
28501
  const { done, value } = await reader.read();
27162
28502
  if (done) break;
27163
- buffer += decoder8.decode(value, { stream: true });
28503
+ buffer += decoder10.decode(value, { stream: true });
27164
28504
  const lines = buffer.split("\n");
27165
28505
  buffer = lines.pop() ?? "";
27166
28506
  for (const line of lines) {
@@ -28221,8 +29561,8 @@ var AllowlistTrustStore = class {
28221
29561
  }
28222
29562
  /** Mark a key revoked without removing it (still resolvable, verdict `revoked`). */
28223
29563
  revoke(keyId) {
28224
- const key2 = this.keys.get(keyId);
28225
- if (key2) this.keys.set(keyId, { ...key2, revoked: true });
29564
+ const key3 = this.keys.get(keyId);
29565
+ if (key3) this.keys.set(keyId, { ...key3, revoked: true });
28226
29566
  }
28227
29567
  };
28228
29568
  function base64urlToBytes(s) {
@@ -28310,7 +29650,7 @@ async function verifyShardSignature(input) {
28310
29650
  };
28311
29651
  let signatureValid = false;
28312
29652
  try {
28313
- const key2 = await globalThis.crypto.subtle.importKey(
29653
+ const key3 = await globalThis.crypto.subtle.importKey(
28314
29654
  "raw",
28315
29655
  toBufferSource(base64urlToBytes(trusted.public_key)),
28316
29656
  { name: "Ed25519" },
@@ -28320,7 +29660,7 @@ async function verifyShardSignature(input) {
28320
29660
  const digest2 = await sha256Hex(canonicalPayloadBytes(payload));
28321
29661
  signatureValid = await globalThis.crypto.subtle.verify(
28322
29662
  "Ed25519",
28323
- key2,
29663
+ key3,
28324
29664
  toBufferSource(base64urlToBytes(envelope.signature)),
28325
29665
  toBufferSource(new TextEncoder().encode(digest2))
28326
29666
  );
@@ -36933,8 +38273,8 @@ function classifyPresenceValue(value) {
36933
38273
  function classifyOwnProperty(document2, pointer) {
36934
38274
  const resolved = parentAndKey(document2, pointer, false);
36935
38275
  if (!resolved) return "absent";
36936
- const { parent, key: key2 } = resolved;
36937
- return Object.hasOwn(parent, key2) ? classifyPresenceValue(parent[key2]) : "absent";
38276
+ const { parent, key: key3 } = resolved;
38277
+ return Object.hasOwn(parent, key3) ? classifyPresenceValue(parent[key3]) : "absent";
36938
38278
  }
36939
38279
  function capturePresence(document2, pointers) {
36940
38280
  return Object.fromEntries(pointers.flatMap(
@@ -36986,14 +38326,14 @@ function restoreStoredPresence(document2, presence) {
36986
38326
  for (const [pointer, stored] of Object.entries(presence)) {
36987
38327
  const resolved = parentAndKey(restored, pointer);
36988
38328
  if (!resolved) throw new Error(`JSON Pointer '${pointer}' parent is not an object`);
36989
- const { parent, key: key2 } = resolved;
38329
+ const { parent, key: key3 } = resolved;
36990
38330
  if (stored === "legacy-indeterminate") {
36991
38331
  throw new Error(`Cannot emit schema 2.0 with legacy-indeterminate state at ${pointer}`);
36992
38332
  }
36993
38333
  if (stored === "absent") {
36994
- delete parent[key2];
38334
+ delete parent[key3];
36995
38335
  } else if (stored === "null") {
36996
- parent[key2] = null;
38336
+ parent[key3] = null;
36997
38337
  } else if (classifyOwnProperty(restored, pointer) !== stored) {
36998
38338
  throw new Error(`Stored ${stored} state at ${pointer} does not match the persisted value`);
36999
38339
  }
@@ -37312,7 +38652,7 @@ var rowKey = (component, row) => nativeIdentityKey(nativeIdentities[component],
37312
38652
  function canonical(value) {
37313
38653
  if (Array.isArray(value)) return value.map(canonical);
37314
38654
  if (value !== null && typeof value === "object") return Object.fromEntries(
37315
- Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key2, item]) => [key2, canonical(item)])
38655
+ Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key3, item]) => [key3, canonical(item)])
37316
38656
  );
37317
38657
  return value;
37318
38658
  }
@@ -37374,7 +38714,7 @@ async function readNativeLineage(tx, state) {
37374
38714
 
37375
38715
  // src/shard/live-full-v1.ts
37376
38716
  var components2 = Object.keys(FULL_V1_COMPONENT_FILES);
37377
- var encoder2 = new TextEncoder();
38717
+ var encoder4 = new TextEncoder();
37378
38718
  var scoped = (values) => values ? [...values] : void 0;
37379
38719
  var ids = (rows) => new Set(rows.map((row) => row.id));
37380
38720
  var nullableIn = (set, value) => value === null || set.has(value);
@@ -37710,7 +39050,7 @@ async function exportLiveFullV1(db, options) {
37710
39050
  for (const component of components2) {
37711
39051
  const spec = FULL_V1_COMPONENT_FILES[component];
37712
39052
  const rows = state[component];
37713
- const bytes = encoder2.encode(spec.encoding === "json-array" ? JSON.stringify(rows) : rows.map((row) => JSON.stringify(row)).join("\n"));
39053
+ const bytes = encoder4.encode(spec.encoding === "json-array" ? JSON.stringify(rows) : rows.map((row) => JSON.stringify(row)).join("\n"));
37714
39054
  files.set(spec.file, bytes);
37715
39055
  counts[component] = rows.length;
37716
39056
  checksums[spec.file] = await sha256Hex(bytes);
@@ -37749,7 +39089,7 @@ async function exportLiveFullV1(db, options) {
37749
39089
  capability = { ...capability, losses: manifestLosses };
37750
39090
  return failure2("Generated live full-v1 manifest violates presence authority.");
37751
39091
  }
37752
- files.set("manifest.json", encoder2.encode(JSON.stringify(manifest, null, 2)));
39092
+ files.set("manifest.json", encoder4.encode(JSON.stringify(manifest, null, 2)));
37753
39093
  for (const note of state.notes) for (const { attachment } of note.attachments) {
37754
39094
  const path = sidecarEntryName(attachment.checksum);
37755
39095
  if (files.has(path)) continue;
@@ -37772,7 +39112,7 @@ async function exportLiveFullV1(db, options) {
37772
39112
  }
37773
39113
 
37774
39114
  // src/shard/shard-export.ts
37775
- var encoder3 = new TextEncoder();
39115
+ var encoder5 = new TextEncoder();
37776
39116
  var CORE_V1_FILES = /* @__PURE__ */ new Set([
37777
39117
  "notes.jsonl",
37778
39118
  "collections.json",
@@ -38178,11 +39518,11 @@ async function exportShardBytes(db, options, mode) {
38178
39518
  const slice = shardNotes.slice(offset, offset + clusterSize);
38179
39519
  const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
38180
39520
  clusters.push({ href, offset });
38181
- files.set(href, encoder3.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
39521
+ files.set(href, encoder5.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
38182
39522
  }
38183
39523
  layout = { clusters: { notes: clusters } };
38184
39524
  } else {
38185
- files.set("notes.jsonl", encoder3.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
39525
+ files.set("notes.jsonl", encoder5.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
38186
39526
  }
38187
39527
  components4.push("notes");
38188
39528
  counts.notes = notes.length;
@@ -38210,7 +39550,7 @@ async function exportShardBytes(db, options, mode) {
38210
39550
  mode?.nativeSchema2Presence
38211
39551
  );
38212
39552
  }
38213
- files.set("collections.json", encoder3.encode(JSON.stringify(shardCollections)));
39553
+ files.set("collections.json", encoder5.encode(JSON.stringify(shardCollections)));
38214
39554
  components4.push("collections");
38215
39555
  counts.collections = shardCollections.length;
38216
39556
  const allTagRows = await db.query(
@@ -38226,7 +39566,7 @@ async function exportShardBytes(db, options, mode) {
38226
39566
  const shardTags = tagsToShard(
38227
39567
  relevantTags.map((r) => ({ name: r.tag, created_at: r.created_at }))
38228
39568
  );
38229
- files.set("tags.json", encoder3.encode(JSON.stringify(shardTags)));
39569
+ files.set("tags.json", encoder5.encode(JSON.stringify(shardTags)));
38230
39570
  components4.push("tags");
38231
39571
  counts.tags = shardTags.length;
38232
39572
  const templateRows = await db.query(`SELECT * FROM template ORDER BY created_at, id`);
@@ -38242,7 +39582,7 @@ async function exportShardBytes(db, options, mode) {
38242
39582
  mode?.nativeSchema2Presence
38243
39583
  );
38244
39584
  }
38245
- files.set("templates.json", encoder3.encode(JSON.stringify(shardTemplates)));
39585
+ files.set("templates.json", encoder5.encode(JSON.stringify(shardTemplates)));
38246
39586
  components4.push("templates");
38247
39587
  counts.templates = shardTemplates.length;
38248
39588
  }
@@ -38267,7 +39607,7 @@ async function exportShardBytes(db, options, mode) {
38267
39607
  );
38268
39608
  }
38269
39609
  const linksJsonl = shardLinks.map((l) => JSON.stringify(l)).join("\n");
38270
- files.set("links.jsonl", encoder3.encode(linksJsonl));
39610
+ files.set("links.jsonl", encoder5.encode(linksJsonl));
38271
39611
  components4.push("links");
38272
39612
  counts.links = shardLinks.length;
38273
39613
  const allNoteSkosRows = await db.query(`SELECT * FROM note_skos_tag ORDER BY created_at`);
@@ -38284,25 +39624,25 @@ async function exportShardBytes(db, options, mode) {
38284
39624
  (row) => exportedConceptIds.has(row.source_concept_id) && exportedConceptIds.has(row.target_concept_id)
38285
39625
  ) : allRelationRows.rows;
38286
39626
  const shardSkosSchemes = filteredSchemeRows.map(skosSchemeToShard);
38287
- files.set("skos_schemes.json", encoder3.encode(JSON.stringify(shardSkosSchemes)));
39627
+ files.set("skos_schemes.json", encoder5.encode(JSON.stringify(shardSkosSchemes)));
38288
39628
  components4.push("skos_schemes");
38289
39629
  counts.skos_schemes = shardSkosSchemes.length;
38290
39630
  const shardSkosConcepts = filteredConceptRows.map(skosConceptToShard);
38291
- files.set("skos_concepts.json", encoder3.encode(JSON.stringify(shardSkosConcepts)));
39631
+ files.set("skos_concepts.json", encoder5.encode(JSON.stringify(shardSkosConcepts)));
38292
39632
  components4.push("skos_concepts");
38293
39633
  counts.skos_concepts = shardSkosConcepts.length;
38294
39634
  const skosRelationsJsonl = filteredRelationRows.map((row) => JSON.stringify(skosRelationToShard(row))).join("\n");
38295
- files.set("skos_relations.jsonl", encoder3.encode(skosRelationsJsonl));
39635
+ files.set("skos_relations.jsonl", encoder5.encode(skosRelationsJsonl));
38296
39636
  components4.push("skos_relations");
38297
39637
  counts.skos_relations = filteredRelationRows.length;
38298
39638
  const noteSkosJsonl = filteredNoteSkosRows.map((row) => JSON.stringify(noteSkosTagToShard(row))).join("\n");
38299
- files.set("note_skos_tags.jsonl", encoder3.encode(noteSkosJsonl));
39639
+ files.set("note_skos_tags.jsonl", encoder5.encode(noteSkosJsonl));
38300
39640
  components4.push("note_skos_tags");
38301
39641
  counts.note_skos_tags = filteredNoteSkosRows.length;
38302
39642
  const provenanceRows = await db.query(`SELECT * FROM provenance_edge ORDER BY started_at`);
38303
39643
  const filteredProvenanceRows = isFiltered ? provenanceRows.rows.filter((row) => row.entity_type !== "note" || exportedNoteIds.has(row.entity_id)) : provenanceRows.rows;
38304
39644
  const provenanceJsonl = filteredProvenanceRows.map((row) => JSON.stringify(provenanceEdgeToShard(row))).join("\n");
38305
- files.set("provenance_edges.jsonl", encoder3.encode(provenanceJsonl));
39645
+ files.set("provenance_edges.jsonl", encoder5.encode(provenanceJsonl));
38306
39646
  components4.push("provenance_edges");
38307
39647
  counts.provenance_edges = filteredProvenanceRows.length;
38308
39648
  if (options?.includeEmbeddings) {
@@ -38342,7 +39682,7 @@ async function exportShardBytes(db, options, mode) {
38342
39682
  freshness_json: { status: "unknown" }
38343
39683
  } : row
38344
39684
  ));
38345
- files.set("embedding_sets.json", encoder3.encode(JSON.stringify(shardEmbSets)));
39685
+ files.set("embedding_sets.json", encoder5.encode(JSON.stringify(shardEmbSets)));
38346
39686
  components4.push("embedding_sets");
38347
39687
  counts.embedding_sets = shardEmbSets.length;
38348
39688
  const embeddingConfigRows = await db.query(
@@ -38352,7 +39692,7 @@ async function exportShardBytes(db, options, mode) {
38352
39692
  );
38353
39693
  if (embeddingConfigRows.rows.length > 0) {
38354
39694
  const shardEmbeddingConfigs = embeddingConfigRows.rows.map((row) => embeddingConfigToShard(row));
38355
- files.set("embedding_configs.json", encoder3.encode(JSON.stringify(shardEmbeddingConfigs)));
39695
+ files.set("embedding_configs.json", encoder5.encode(JSON.stringify(shardEmbeddingConfigs)));
38356
39696
  components4.push("embedding_configs");
38357
39697
  counts.embedding_configs = shardEmbeddingConfigs.length;
38358
39698
  }
@@ -38365,7 +39705,7 @@ async function exportShardBytes(db, options, mode) {
38365
39705
  (member) => exportedSetIds.has(member.embedding_set_id) && exportedNoteIds.has(member.note_id) && (includeMaterializedSelectors || !virtualSetIds.has(member.embedding_set_id))
38366
39706
  );
38367
39707
  const membersJsonl = scopedEmbMemberRows.map((m) => JSON.stringify(embeddingSetMemberToShard(m))).join("\n");
38368
- files.set("embedding_set_members.jsonl", encoder3.encode(membersJsonl));
39708
+ files.set("embedding_set_members.jsonl", encoder5.encode(membersJsonl));
38369
39709
  components4.push("embedding_set_members");
38370
39710
  counts.embedding_set_members = scopedEmbMemberRows.length;
38371
39711
  const embRows = await db.query(
@@ -38391,7 +39731,7 @@ async function exportShardBytes(db, options, mode) {
38391
39731
  (embedding) => exportedSetIds.has(embedding.embedding_set_id) && exportedNoteIds.has(embedding.note_id) && (memberEmbeddingIds.size === 0 || memberEmbeddingIds.has(embedding.id))
38392
39732
  );
38393
39733
  const embJsonl = scopedEmbRows.map((e) => JSON.stringify(embeddingToShard(e))).join("\n");
38394
- files.set("embeddings.jsonl", encoder3.encode(embJsonl));
39734
+ files.set("embeddings.jsonl", encoder5.encode(embJsonl));
38395
39735
  components4.push("embeddings");
38396
39736
  counts.embeddings = scopedEmbRows.length;
38397
39737
  }
@@ -38417,7 +39757,7 @@ async function exportShardBytes(db, options, mode) {
38417
39757
  freshness: jsonObject3(row.freshness_json) ?? { status: "unknown" },
38418
39758
  created_at: iso2(row.created_at)
38419
39759
  }));
38420
- files.set("graph_sources.json", encoder3.encode(JSON.stringify(shardGraphSources)));
39760
+ files.set("graph_sources.json", encoder5.encode(JSON.stringify(shardGraphSources)));
38421
39761
  components4.push("graph_sources");
38422
39762
  counts.graph_sources = shardGraphSources.length;
38423
39763
  }
@@ -38433,7 +39773,7 @@ async function exportShardBytes(db, options, mode) {
38433
39773
  rank: row.rank,
38434
39774
  metadata: jsonObject3(row.metadata_json)
38435
39775
  })).join("\n");
38436
- files.set("graph_edges.jsonl", encoder3.encode(graphEdgesJsonl));
39776
+ files.set("graph_edges.jsonl", encoder5.encode(graphEdgesJsonl));
38437
39777
  components4.push("graph_edges");
38438
39778
  counts.graph_edges = scopedGraphEdgeRows.length;
38439
39779
  }
@@ -38469,7 +39809,7 @@ async function exportShardBytes(db, options, mode) {
38469
39809
  })),
38470
39810
  created_at: iso2(row.created_at)
38471
39811
  }));
38472
- files.set("communities.json", encoder3.encode(JSON.stringify(shardCommunitySets)));
39812
+ files.set("communities.json", encoder5.encode(JSON.stringify(shardCommunitySets)));
38473
39813
  components4.push("communities");
38474
39814
  counts.community_sets = shardCommunitySets.length;
38475
39815
  counts.communities = scopedCommunityRows.length;
@@ -38485,7 +39825,7 @@ async function exportShardBytes(db, options, mode) {
38485
39825
  source_type: row.source_type,
38486
39826
  metadata: jsonObject3(row.metadata_json)
38487
39827
  })).join("\n");
38488
- files.set("community_assignments.jsonl", encoder3.encode(assignmentsJsonl));
39828
+ files.set("community_assignments.jsonl", encoder5.encode(assignmentsJsonl));
38489
39829
  components4.push("community_assignments");
38490
39830
  counts.community_assignments = scopedAssignmentRows.length;
38491
39831
  }
@@ -38508,10 +39848,10 @@ async function exportShardBytes(db, options, mode) {
38508
39848
  const coreTags = [...tagsByName.values()].sort(
38509
39849
  (left, right) => left.name.localeCompare(right.name)
38510
39850
  );
38511
- files.set("tags.json", encoder3.encode(JSON.stringify(coreTags)));
39851
+ files.set("tags.json", encoder5.encode(JSON.stringify(coreTags)));
38512
39852
  components4.splice(0, components4.length, ...CORE_V1_COMPONENTS);
38513
- for (const key2 of Object.keys(counts)) {
38514
- if (!CORE_V1_COMPONENTS.includes(key2)) delete counts[key2];
39853
+ for (const key3 of Object.keys(counts)) {
39854
+ if (!CORE_V1_COMPONENTS.includes(key3)) delete counts[key3];
38515
39855
  }
38516
39856
  Object.assign(counts, {
38517
39857
  notes: shardNotes.length,
@@ -38548,7 +39888,7 @@ async function exportShardBytes(db, options, mode) {
38548
39888
  ...!coreV1 ? { migrated_from: null } : {},
38549
39889
  ...!coreV1 && layout ? { layout } : {}
38550
39890
  };
38551
- files.set("manifest.json", encoder3.encode(JSON.stringify(manifest, null, 2)));
39891
+ files.set("manifest.json", encoder5.encode(JSON.stringify(manifest, null, 2)));
38552
39892
  if (options?.includeBlobs && options.blobStore) {
38553
39893
  const packed = /* @__PURE__ */ new Set();
38554
39894
  for (const row of attachmentRows.rows) {
@@ -38573,14 +39913,14 @@ init_geometry_buffer();
38573
39913
 
38574
39914
  // src/shard/parse.ts
38575
39915
  init_geometry_buffer();
38576
- var decoder2 = new TextDecoder();
39916
+ var decoder4 = new TextDecoder();
38577
39917
  function parseJsonlBytes(data) {
38578
39918
  if (!data || data.byteLength === 0) return [];
38579
- return decoder2.decode(data).split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
39919
+ return decoder4.decode(data).split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
38580
39920
  }
38581
39921
  function parseJsonArrayBytes(data) {
38582
39922
  if (!data || data.byteLength === 0) return [];
38583
- return JSON.parse(decoder2.decode(data));
39923
+ return JSON.parse(decoder4.decode(data));
38584
39924
  }
38585
39925
 
38586
39926
  // src/shard/blob-staging.ts
@@ -38644,8 +39984,8 @@ async function promoteBlobs(blobStore, blobs) {
38644
39984
  init_geometry_buffer();
38645
39985
  function instant(value) {
38646
39986
  if (value === null || value === void 0) return Number.NEGATIVE_INFINITY;
38647
- const timestamp3 = value instanceof Date ? value.getTime() : Date.parse(value);
38648
- return Number.isNaN(timestamp3) ? Number.NEGATIVE_INFINITY : timestamp3;
39987
+ const timestamp4 = value instanceof Date ? value.getTime() : Date.parse(value);
39988
+ return Number.isNaN(timestamp4) ? Number.NEGATIVE_INFINITY : timestamp4;
38649
39989
  }
38650
39990
  function shouldApplyReplacement(existing, incoming) {
38651
39991
  const existingDeleted = instant(existing.deleted_at);
@@ -39005,7 +40345,7 @@ async function importNativeFullV1(db, data, options = {}) {
39005
40345
  }
39006
40346
 
39007
40347
  // src/shard/shard-import.ts
39008
- var decoder3 = new TextDecoder();
40348
+ var decoder5 = new TextDecoder();
39009
40349
  var DEFAULT_BATCH_SIZE = 250;
39010
40350
  function emptyCounts2() {
39011
40351
  return {
@@ -39142,7 +40482,7 @@ async function importShard(db, data, options) {
39142
40482
  }
39143
40483
  let manifest;
39144
40484
  try {
39145
- manifest = JSON.parse(decoder3.decode(manifestData));
40485
+ manifest = JSON.parse(decoder5.decode(manifestData));
39146
40486
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
39147
40487
  throw new Error("manifest must be a JSON object");
39148
40488
  }
@@ -39446,11 +40786,11 @@ async function importShard(db, data, options) {
39446
40786
  }
39447
40787
  }
39448
40788
  }
39449
- const skipExisting = async (key2, sql, params) => {
40789
+ const skipExisting = async (key3, sql, params) => {
39450
40790
  if (strategy !== "skip") return false;
39451
40791
  const existing = await tx.query(sql, params);
39452
40792
  if (existing.rows.length === 0) return false;
39453
- skipped[key2] = (skipped[key2] ?? 0) + 1;
40793
+ skipped[key3] = (skipped[key3] ?? 0) + 1;
39454
40794
  return true;
39455
40795
  };
39456
40796
  const storePresence = async (component, recordId, record) => {
@@ -40374,8 +41714,8 @@ function slugifyServerEmbeddingSet(value) {
40374
41714
 
40375
41715
  // src/shard/full-v1-store.ts
40376
41716
  init_geometry_buffer();
40377
- var decoder4 = new TextDecoder();
40378
- var encoder4 = new TextEncoder();
41717
+ var decoder6 = new TextDecoder();
41718
+ var encoder6 = new TextEncoder();
40379
41719
  function emptyCounts3() {
40380
41720
  return {
40381
41721
  notes: 0,
@@ -40429,12 +41769,12 @@ function componentRecords(component, bytes) {
40429
41769
  function canonicalJson4(value) {
40430
41770
  if (Array.isArray(value)) return `[${value.map(canonicalJson4).join(",")}]`;
40431
41771
  if (value && typeof value === "object") {
40432
- return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key2, item]) => `${JSON.stringify(key2)}:${canonicalJson4(item)}`).join(",")}}`;
41772
+ return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson4(item)}`).join(",")}}`;
40433
41773
  }
40434
41774
  return JSON.stringify(value);
40435
41775
  }
40436
41776
  function encodeComponentRecords(component, records) {
40437
- return encoder4.encode(FULL_V1_COMPONENT_FILES[component].encoding === "json-array" ? JSON.stringify(records) : records.map((record) => JSON.stringify(record)).join("\n"));
41777
+ return encoder6.encode(FULL_V1_COMPONENT_FILES[component].encoding === "json-array" ? JSON.stringify(records) : records.map((record) => JSON.stringify(record)).join("\n"));
40438
41778
  }
40439
41779
  function attachmentBlobReferences(files) {
40440
41780
  const refs = /* @__PURE__ */ new Map();
@@ -40471,7 +41811,7 @@ async function importFullV1Snapshot(db, data, options) {
40471
41811
  files = unpackTarGz(bytes);
40472
41812
  const manifestBytes = files.get("manifest.json");
40473
41813
  if (!manifestBytes) throw new Error("Missing manifest");
40474
- const parsed2 = JSON.parse(decoder4.decode(manifestBytes));
41814
+ const parsed2 = JSON.parse(decoder6.decode(manifestBytes));
40475
41815
  if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2)) {
40476
41816
  throw new Error("Manifest is not an object");
40477
41817
  }
@@ -40725,7 +42065,7 @@ async function exportFullV1Snapshot(db, blobStore) {
40725
42065
  name: "fortemi-react-full-v1-store",
40726
42066
  version: manifest.producer?.version ?? "unknown"
40727
42067
  };
40728
- files.set("manifest.json", encoder4.encode(JSON.stringify(manifest, null, 2)));
42068
+ files.set("manifest.json", encoder6.encode(JSON.stringify(manifest, null, 2)));
40729
42069
  files.delete("signature.json");
40730
42070
  blobRefs = attachmentBlobReferences(files);
40731
42071
  } else {
@@ -40752,7 +42092,7 @@ async function exportFullV1Snapshot(db, blobStore) {
40752
42092
 
40753
42093
  // src/shard/shard-reader.ts
40754
42094
  init_geometry_buffer();
40755
- var decoder5 = new TextDecoder();
42095
+ var decoder7 = new TextDecoder();
40756
42096
  function assertSafeComponentName(filename) {
40757
42097
  if (filename.length === 0 || filename.startsWith("/") || filename.includes("\\") || filename.includes("\0") || filename.includes(":") || filename.split("/").some((segment) => segment === "..")) {
40758
42098
  throw new Error(`Refusing to read unsafe shard component path: ${JSON.stringify(filename)}`);
@@ -40854,7 +42194,7 @@ async function resolveStore(source, maxComponentBytes) {
40854
42194
  const files = unpackTarGz(bytes);
40855
42195
  const manifestBytes = files.get("manifest.json");
40856
42196
  if (!manifestBytes) throw new Error("Missing manifest.json in shard archive");
40857
- const manifest = JSON.parse(decoder5.decode(manifestBytes));
42197
+ const manifest = JSON.parse(decoder7.decode(manifestBytes));
40858
42198
  return new PackedComponentStore(files, manifest);
40859
42199
  }
40860
42200
  function tokenize(query) {
@@ -40991,14 +42331,14 @@ var ShardReaderImpl = class {
40991
42331
  weights: { ...DEFAULT_WEIGHTS, ...options.weights }
40992
42332
  });
40993
42333
  }
40994
- cacheMatches(key2, notes) {
40995
- this.matchCache.delete(key2);
40996
- this.matchCache.set(key2, notes);
42334
+ cacheMatches(key3, notes) {
42335
+ this.matchCache.delete(key3);
42336
+ this.matchCache.set(key3, notes);
40997
42337
  let total = 0;
40998
42338
  for (const set of this.matchCache.values()) total += set.length;
40999
42339
  while (total > this.maxCachedMatches && this.matchCache.size > 1) {
41000
42340
  const oldest = this.matchCache.keys().next().value;
41001
- if (oldest === void 0 || oldest === key2) break;
42341
+ if (oldest === void 0 || oldest === key3) break;
41002
42342
  total -= this.matchCache.get(oldest)?.length ?? 0;
41003
42343
  this.matchCache.delete(oldest);
41004
42344
  }
@@ -41008,12 +42348,12 @@ var ShardReaderImpl = class {
41008
42348
  const weights = { ...DEFAULT_WEIGHTS, ...options.weights };
41009
42349
  const offset = options.offset ?? 0;
41010
42350
  const limit = options.limit ?? Number.MAX_SAFE_INTEGER;
41011
- const key2 = this.matchKey(query, options);
41012
- let matched = this.matchCache.get(key2);
42351
+ const key3 = this.matchKey(query, options);
42352
+ let matched = this.matchCache.get(key3);
41013
42353
  let fetchedClusters = 0;
41014
42354
  if (matched) {
41015
- this.matchCache.delete(key2);
41016
- this.matchCache.set(key2, matched);
42355
+ this.matchCache.delete(key3);
42356
+ this.matchCache.set(key3, matched);
41017
42357
  } else {
41018
42358
  const { notes, fetched } = await this.loadAllNotes();
41019
42359
  fetchedClusters = fetched;
@@ -41021,7 +42361,7 @@ var ShardReaderImpl = class {
41021
42361
  if (tokens.length > 0 && options.rank !== false) {
41022
42362
  matched = [...matched].sort((a, b) => rankNote(b, tokens, weights) - rankNote(a, tokens, weights));
41023
42363
  }
41024
- this.cacheMatches(key2, matched);
42364
+ this.cacheMatches(key3, matched);
41025
42365
  }
41026
42366
  const page = matched.slice(offset, offset + limit);
41027
42367
  const result = {
@@ -41140,7 +42480,7 @@ async function openShard(source, options = {}) {
41140
42480
 
41141
42481
  // src/shard/semantic-providers.ts
41142
42482
  init_geometry_buffer();
41143
- var decoder6 = new TextDecoder();
42483
+ var decoder8 = new TextDecoder();
41144
42484
  function cosine(a, b) {
41145
42485
  let dot = 0;
41146
42486
  let normA = 0;
@@ -41164,7 +42504,7 @@ function createCosineSemanticProvider(options) {
41164
42504
  vectors = [];
41165
42505
  return;
41166
42506
  }
41167
- vectors = decoder6.decode(bytes).split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
42507
+ vectors = decoder8.decode(bytes).split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
41168
42508
  },
41169
42509
  async search(query, k) {
41170
42510
  const queryVector = await options.embedQuery(query);
@@ -42700,14 +44040,14 @@ function matchSetCacheKey(q, options) {
42700
44040
  weights: { ...DEFAULT_QUERY_WEIGHTS, ...options.weights }
42701
44041
  });
42702
44042
  }
42703
- function cacheMatchEntries(runtime, key2, entries) {
42704
- runtime.matchCache.delete(key2);
42705
- runtime.matchCache.set(key2, entries);
44043
+ function cacheMatchEntries(runtime, key3, entries) {
44044
+ runtime.matchCache.delete(key3);
44045
+ runtime.matchCache.set(key3, entries);
42706
44046
  let total = 0;
42707
44047
  for (const set of runtime.matchCache.values()) total += set.length;
42708
44048
  while (total > runtime.maxCachedMatches && runtime.matchCache.size > 1) {
42709
44049
  const oldest = runtime.matchCache.keys().next().value;
42710
- if (oldest === void 0 || oldest === key2) break;
44050
+ if (oldest === void 0 || oldest === key3) break;
42711
44051
  total -= runtime.matchCache.get(oldest)?.length ?? 0;
42712
44052
  runtime.matchCache.delete(oldest);
42713
44053
  }
@@ -42720,15 +44060,15 @@ function getPartsForRange(manifest, offset, limit) {
42720
44060
  return manifest.parts.filter((part) => part.count > 0 && part.offset < end && part.offset + part.count > offset);
42721
44061
  }
42722
44062
  async function loadChunkPart(runtime, part) {
42723
- const key2 = chunkPartCacheKey(part);
42724
- const cached = runtime.partCache.get(key2);
44063
+ const key3 = chunkPartCacheKey(part);
44064
+ const cached = runtime.partCache.get(key3);
42725
44065
  if (cached) {
42726
- runtime.partCache.delete(key2);
42727
- runtime.partCache.set(key2, cached);
44066
+ runtime.partCache.delete(key3);
44067
+ runtime.partCache.set(key3, cached);
42728
44068
  return { part: cached, fetched: false };
42729
44069
  }
42730
44070
  const parsed = assertAiwgFortemiChunkPart(await runtime.loader(part, runtime.manifest), part, runtime.manifest);
42731
- runtime.partCache.set(key2, parsed);
44071
+ runtime.partCache.set(key3, parsed);
42732
44072
  while (runtime.partCache.size > runtime.maxCachedParts) {
42733
44073
  const oldest = runtime.partCache.keys().next().value;
42734
44074
  if (oldest === void 0) break;
@@ -43153,10 +44493,10 @@ function aiwgFortemiIndexToCommunityGraph(index, options = {}) {
43153
44493
  const kind = relationship.type;
43154
44494
  const configuredWeight = Object.prototype.hasOwnProperty.call(relationshipWeights, kind) ? relationshipWeights[kind] : void 0;
43155
44495
  const baseWeight = typeof configuredWeight === "number" && Number.isFinite(configuredWeight) ? configuredWeight : 1;
43156
- const key2 = `${item.id}\0${relationship.target_id}\0${kind}`;
43157
- const existing = edgeCounts.get(key2);
44496
+ const key3 = `${item.id}\0${relationship.target_id}\0${kind}`;
44497
+ const existing = edgeCounts.get(key3);
43158
44498
  if (existing) existing.weight += baseWeight;
43159
- else edgeCounts.set(key2, { source: item.id, target: relationship.target_id, kind, weight: baseWeight });
44499
+ else edgeCounts.set(key3, { source: item.id, target: relationship.target_id, kind, weight: baseWeight });
43160
44500
  }
43161
44501
  }
43162
44502
  const communities = /* @__PURE__ */ new Map();
@@ -43896,7 +45236,7 @@ function getAiwgFortemiIndexExportSchema() {
43896
45236
  }
43897
45237
  function getAjv() {
43898
45238
  if (!ajvInstance) {
43899
- ajvInstance = new Ajv20203({
45239
+ ajvInstance = new Ajv20206({
43900
45240
  allErrors: true,
43901
45241
  strict: false,
43902
45242
  validateFormats: false
@@ -43941,7 +45281,7 @@ function getProjectedRecordValidator() {
43941
45281
  return projectedRecordValidator;
43942
45282
  }
43943
45283
  function validateAiwgFortemiIndexExportSchema(value) {
43944
- const validate3 = getExportValidator();
45284
+ const validate4 = getExportValidator();
43945
45285
  const schemaValue = value && typeof value === "object" && Array.isArray(value.items) ? {
43946
45286
  ...value,
43947
45287
  items: value.items.map((item) => {
@@ -43951,18 +45291,18 @@ function validateAiwgFortemiIndexExportSchema(value) {
43951
45291
  return schemaRecord;
43952
45292
  })
43953
45293
  } : value;
43954
- const valid = validate3(schemaValue);
43955
- return { valid, errors: formatErrors2(validate3.errors) };
45294
+ const valid = validate4(schemaValue);
45295
+ return { valid, errors: formatErrors2(validate4.errors) };
43956
45296
  }
43957
45297
  function validateAiwgFortemiProjectedRecordSchema(value) {
43958
- const validate3 = getProjectedRecordValidator();
43959
- const valid = validate3(value);
43960
- return { valid, errors: formatErrors2(validate3.errors) };
45298
+ const validate4 = getProjectedRecordValidator();
45299
+ const valid = validate4(value);
45300
+ return { valid, errors: formatErrors2(validate4.errors) };
43961
45301
  }
43962
45302
 
43963
45303
  // src/aiwg-index-full-shard.ts
43964
45304
  init_geometry_buffer();
43965
- var encoder5 = new TextEncoder();
45305
+ var encoder7 = new TextEncoder();
43966
45306
  var UUID_NAMESPACE = "7ab5d1f8-29d2-5e35-9e2f-3a45de171a9e";
43967
45307
  function uuid5(kind, id) {
43968
45308
  return v5(`${kind}:${id}`, UUID_NAMESPACE);
@@ -43970,7 +45310,7 @@ function uuid5(kind, id) {
43970
45310
  function own(value, field) {
43971
45311
  return Object.prototype.hasOwnProperty.call(value, field);
43972
45312
  }
43973
- function timestamp2(value) {
45313
+ function timestamp3(value) {
43974
45314
  if (!value || Number.isNaN(Date.parse(value))) return void 0;
43975
45315
  return new Date(value).toISOString();
43976
45316
  }
@@ -43978,7 +45318,7 @@ function addLoss(losses, code, message, details = {}) {
43978
45318
  losses.push({ code, message, ...details });
43979
45319
  }
43980
45320
  function encode(values, encoding) {
43981
- return encoder5.encode(encoding === "json-array" ? JSON.stringify(values) : values.map((value) => JSON.stringify(value)).join("\n"));
45321
+ return encoder7.encode(encoding === "json-array" ? JSON.stringify(values) : values.map((value) => JSON.stringify(value)).join("\n"));
43982
45322
  }
43983
45323
  function noteTitle(record, losses) {
43984
45324
  if (own(record, "title")) return record.title ?? null;
@@ -44043,7 +45383,7 @@ function noteContent(record, losses) {
44043
45383
  return "";
44044
45384
  }
44045
45385
  function createdAt(record, losses) {
44046
- const source = timestamp2(record.source.updated_at);
45386
+ const source = timestamp3(record.source.updated_at);
44047
45387
  if (source) return source;
44048
45388
  addLoss(
44049
45389
  losses,
@@ -44073,7 +45413,7 @@ function schemeName(concept) {
44073
45413
  }
44074
45414
  async function convertAiwgIndexToFullV1(index, options = {}) {
44075
45415
  const losses = [];
44076
- const exportedAt = timestamp2(options.createdAt) ?? new Date(index.generated_at).toISOString();
45416
+ const exportedAt = timestamp3(options.createdAt) ?? new Date(index.generated_at).toISOString();
44077
45417
  const records = [...index.items].sort((a, b) => a.id.localeCompare(b.id));
44078
45418
  const noteIds = new Map(records.map((record) => [record.id, uuid5("record", record.id)]));
44079
45419
  const rows = /* @__PURE__ */ new Map();
@@ -44146,7 +45486,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44146
45486
  tags: recordTags,
44147
45487
  attachments: []
44148
45488
  });
44149
- const hash = await sha256Hex(encoder5.encode(content));
45489
+ const hash = await sha256Hex(encoder7.encode(content));
44150
45490
  rows.get("note_originals").push({
44151
45491
  id: uuid5("note-original", record.id),
44152
45492
  note_id: noteId,
@@ -44168,9 +45508,9 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44168
45508
  for (const record of records) {
44169
45509
  for (const [position, relationship] of record.relationships.entries()) {
44170
45510
  const target = noteIds.get(relationship.target_id) ?? null;
44171
- const key2 = `${record.id}\0${position}\0${relationship.type}\0${relationship.target_id}`;
45511
+ const key3 = `${record.id}\0${position}\0${relationship.type}\0${relationship.target_id}`;
44172
45512
  rows.get("links").push({
44173
- id: uuid5("relationship", key2),
45513
+ id: uuid5("relationship", key3),
44174
45514
  from_note_id: noteIds.get(record.id),
44175
45515
  to_note_id: target,
44176
45516
  to_url: target ? null : `aiwg://record/${encodeURIComponent(relationship.target_id)}`,
@@ -44238,7 +45578,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44238
45578
  metric: null,
44239
45579
  algorithm: null,
44240
45580
  parameters: null,
44241
- input_hash: `sha256:${await sha256Hex(encoder5.encode(JSON.stringify(relationshipInput)))}`,
45581
+ input_hash: `sha256:${await sha256Hex(encoder7.encode(JSON.stringify(relationshipInput)))}`,
44242
45582
  freshness: { status: "fresh", checked_at: exportedAt },
44243
45583
  created_at: exportedAt
44244
45584
  });
@@ -44327,7 +45667,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44327
45667
  action: "omit"
44328
45668
  }
44329
45669
  );
44330
- const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((key2) => key2 !== "domain");
45670
+ const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((key3) => key3 !== "domain");
44331
45671
  if (unmappedConceptMetadata.length > 0) addLoss(
44332
45672
  losses,
44333
45673
  "aiwg-skos-metadata-unmapped",
@@ -44470,7 +45810,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44470
45810
  }
44471
45811
  for (const record of records) {
44472
45812
  for (const [position, event] of (record.provenance_events ?? []).entries()) {
44473
- const start = timestamp2(event.started_at);
45813
+ const start = timestamp3(event.started_at);
44474
45814
  if (!start) addLoss(
44475
45815
  losses,
44476
45816
  "aiwg-provenance-start-unavailable",
@@ -44490,7 +45830,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44490
45830
  activity_type: event.activity,
44491
45831
  model_name: event.agent ?? null,
44492
45832
  started_at: start ?? new Date(record.updated_at).toISOString(),
44493
- ended_at: timestamp2(event.ended_at) ?? null,
45833
+ ended_at: timestamp3(event.ended_at) ?? null,
44494
45834
  metadata: {
44495
45835
  source: event.source ?? null,
44496
45836
  path: event.path ?? null,
@@ -44696,7 +46036,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
44696
46036
  checksums,
44697
46037
  min_reader_version: "2.0.0"
44698
46038
  };
44699
- const manifestBytes = encoder5.encode(JSON.stringify(manifest, null, 2));
46039
+ const manifestBytes = encoder7.encode(JSON.stringify(manifest, null, 2));
44700
46040
  files.set("manifest.json", manifestBytes);
44701
46041
  const validation = await validateFullV1ShardArchive(files);
44702
46042
  if (!validation.valid) {
@@ -44976,7 +46316,7 @@ var RECORD_STORE_CAPABILITIES = {
44976
46316
  sourceAddressedUpsert: true,
44977
46317
  deletionReceipts: true,
44978
46318
  typedMetadataPredicates: false,
44979
- evidenceLocators: true,
46319
+ evidenceLocators: false,
44980
46320
  fullTextSearch: false,
44981
46321
  vectorSearch: false,
44982
46322
  sqlJoins: false
@@ -45363,7 +46703,7 @@ var CanonicalNotesRepository = class {
45363
46703
  * Bounded substring scan over title + revised content (case-insensitive).
45364
46704
  * This is deliberately not ranked FTS — see `store.capabilities`.
45365
46705
  */
45366
- async searchText(query, limit = 20) {
46706
+ async searchText(query, limit = 20, accept) {
45367
46707
  const needle = query.toLowerCase();
45368
46708
  const revised = new Map(
45369
46709
  (await this.store.list("note_revised_current")).map((r) => [r.id, r.content])
@@ -45371,6 +46711,7 @@ var CanonicalNotesRepository = class {
45371
46711
  const hits = [];
45372
46712
  for (const note of await this.store.list("note")) {
45373
46713
  if (note.deleted_at !== null) continue;
46714
+ if (accept && !accept(note)) continue;
45374
46715
  const haystack = `${note.title ?? ""}
45375
46716
  ${revised.get(note.id) ?? ""}`.toLowerCase();
45376
46717
  if (haystack.includes(needle)) {
@@ -45886,6 +47227,8 @@ function createRecordBackend(store, options = {}) {
45886
47227
  // via importShardToRecords (record-shard.ts)
45887
47228
  multiUser: false,
45888
47229
  semantic: "none",
47230
+ typedMetadataPredicates: false,
47231
+ evidenceLocators: false,
45889
47232
  startupCost: "instant"
45890
47233
  },
45891
47234
  async listNotes(o) {
@@ -45905,17 +47248,11 @@ function createRecordBackend(store, options = {}) {
45905
47248
  return noteToBackend(view.note, view.tags);
45906
47249
  },
45907
47250
  async search(query, o) {
47251
+ validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
45908
47252
  const offset = o?.offset ?? 0;
45909
47253
  const limit = o?.limit ?? 20;
45910
- let matched = await notes.searchText(query, offset + limit);
45911
- if (o?.tags?.length) {
45912
- const tags2 = await tagsByNote();
45913
- matched = matched.filter((n) => o.tags.every((t) => (tags2.get(n.id) ?? []).includes(t)));
45914
- }
45915
- if (o?.source?.length) {
45916
- matched = matched.filter((n) => o.source.includes(n.source));
45917
- }
45918
47254
  const tags = await tagsByNote();
47255
+ const matched = await notes.searchText(query, offset + limit, (n) => (!o?.tags?.length || o.tags.every((t) => (tags.get(n.id) ?? []).includes(t))) && (!o?.source?.length || o.source.includes(n.source)));
45919
47256
  const hits = matched.slice(offset, offset + limit).map((n) => ({ note: noteToBackend(n, tags.get(n.id) ?? []) }));
45920
47257
  return { hits, total: matched.length };
45921
47258
  },
@@ -45973,8 +47310,8 @@ function createRecordBackend(store, options = {}) {
45973
47310
 
45974
47311
  // src/records/record-shard.ts
45975
47312
  init_geometry_buffer();
45976
- var encoder6 = new TextEncoder();
45977
- var decoder7 = new TextDecoder();
47313
+ var encoder8 = new TextEncoder();
47314
+ var decoder9 = new TextDecoder();
45978
47315
  function emptyCounts4() {
45979
47316
  return {
45980
47317
  notes: 0,
@@ -46231,11 +47568,11 @@ async function buildRecordShardArchive(store, options, profile) {
46231
47568
  const slice = shardNotes.slice(offset, offset + clusterSize);
46232
47569
  const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
46233
47570
  clusters.push({ href, offset });
46234
- files.set(href, encoder6.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
47571
+ files.set(href, encoder8.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
46235
47572
  }
46236
47573
  layout = { clusters: { notes: clusters } };
46237
47574
  } else {
46238
- files.set("notes.jsonl", encoder6.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
47575
+ files.set("notes.jsonl", encoder8.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
46239
47576
  }
46240
47577
  components4.push("notes");
46241
47578
  counts.notes = shardNotes.length;
@@ -46263,7 +47600,7 @@ async function buildRecordShardArchive(store, options, profile) {
46263
47600
  note_count: mapped.note_count ?? 0
46264
47601
  };
46265
47602
  });
46266
- files.set("collections.json", encoder6.encode(JSON.stringify(shardCollections)));
47603
+ files.set("collections.json", encoder8.encode(JSON.stringify(shardCollections)));
46267
47604
  components4.push("collections");
46268
47605
  counts.collections = shardCollections.length;
46269
47606
  const distinctTags = [...new Set(
@@ -46280,7 +47617,7 @@ async function buildRecordShardArchive(store, options, profile) {
46280
47617
  created_at: tagCreatedAt.get(name) ?? (/* @__PURE__ */ new Date(0)).toISOString()
46281
47618
  }))
46282
47619
  );
46283
- files.set("tags.json", encoder6.encode(JSON.stringify(shardTags)));
47620
+ files.set("tags.json", encoder8.encode(JSON.stringify(shardTags)));
46284
47621
  components4.push("tags");
46285
47622
  counts.tags = shardTags.length;
46286
47623
  const links = await store.list("link");
@@ -46302,7 +47639,7 @@ async function buildRecordShardArchive(store, options, profile) {
46302
47639
  }
46303
47640
  return shard;
46304
47641
  });
46305
- files.set("links.jsonl", encoder6.encode(shardLinks.map((l) => JSON.stringify(l)).join("\n")));
47642
+ files.set("links.jsonl", encoder8.encode(shardLinks.map((l) => JSON.stringify(l)).join("\n")));
46306
47643
  components4.push("links");
46307
47644
  counts.links = shardLinks.length;
46308
47645
  const checksums = {};
@@ -46432,7 +47769,7 @@ async function buildRecordShardArchive(store, options, profile) {
46432
47769
  );
46433
47770
  }
46434
47771
  }
46435
- files.set("manifest.json", encoder6.encode(JSON.stringify(manifest, null, 2)));
47772
+ files.set("manifest.json", encoder8.encode(JSON.stringify(manifest, null, 2)));
46436
47773
  if (options?.includeBlobs && options.blobStore) {
46437
47774
  const packed = /* @__PURE__ */ new Set();
46438
47775
  for (const checksum of exportedBlobChecksums) {
@@ -46512,7 +47849,7 @@ async function importShardToRecords(store, data, options) {
46512
47849
  }
46513
47850
  let manifest;
46514
47851
  try {
46515
- manifest = JSON.parse(decoder7.decode(manifestData));
47852
+ manifest = JSON.parse(decoder9.decode(manifestData));
46516
47853
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
46517
47854
  throw new Error("manifest must be a JSON object");
46518
47855
  }
@@ -46649,8 +47986,8 @@ async function importShardToRecords(store, data, options) {
46649
47986
  for (const component of manifest.components ?? []) {
46650
47987
  if (UNSUPPORTED_COMPONENTS.includes(component)) {
46651
47988
  const count2 = manifest.counts?.[component];
46652
- const key2 = component === "communities" ? "communities" : component;
46653
- skipped[key2] = (skipped[key2] ?? 0) + (typeof count2 === "number" ? count2 : 0);
47989
+ const key3 = component === "communities" ? "communities" : component;
47990
+ skipped[key3] = (skipped[key3] ?? 0) + (typeof count2 === "number" ? count2 : 0);
46654
47991
  warnings.push(
46655
47992
  `Shard component '${component}' is not supported by the canonical record tier and was skipped. Import into a PGlite-backed store to preserve it.`
46656
47993
  );
@@ -46818,7 +48155,7 @@ async function importShardToRecords(store, data, options) {
46818
48155
  id: existingOriginal?.id ?? generateId(),
46819
48156
  note_id: note.id,
46820
48157
  content: note.original_content,
46821
- content_hash: computeHash(encoder6.encode(note.original_content)),
48158
+ content_hash: computeHash(encoder8.encode(note.original_content)),
46822
48159
  created_at: createdAt2
46823
48160
  };
46824
48161
  mutations.push({ op: "put", collection: "note_original", record: originalRecord });
@@ -47125,7 +48462,7 @@ async function upsertRecordStoreSources(store, items, options = {}) {
47125
48462
  const requestDigest = sourceRequestDigest(items, options);
47126
48463
  const batchId = options.batchId ?? deriveSourceBatchId(requestDigest);
47127
48464
  const batchReason = batchId.length === 0 || batchId.length > 200 ? "invalid_batch_metadata" : JSON.stringify(options.checkpoint ?? {}).length > 65536 ? "checkpoint_too_large" : void 0;
47128
- const validation = validate2(items, options.maxItems ?? 500, batchReason);
48465
+ const validation = validate3(items, options.maxItems ?? 500, batchReason);
47129
48466
  if (validation) return finish2(importRunId, batchId, options.dryRun === true, "rejected", validation, options.checkpoint);
47130
48467
  const batches = await store.list("source_import_batch");
47131
48468
  const prior = batches.find((batch2) => batch2.tenant_id === (items[0].source.tenant_id ?? "default") && batch2.archive_id === (items[0].source.archive_id ?? null) && batch2.namespace === items[0].source.namespace && batch2.batch_id === batchId);
@@ -47309,7 +48646,7 @@ function addUpdateMutations(mutations, item, identity, note, current, original,
47309
48646
  mutations.push({ op: "put", collection: "note_revision", record: revision });
47310
48647
  }
47311
48648
  }
47312
- function validate2(items, maxItems, initialReason) {
48649
+ function validate3(items, maxItems, initialReason) {
47313
48650
  let reason = initialReason ?? (items.length === 0 || items.length > maxItems ? "batch_size_out_of_bounds" : null);
47314
48651
  const seen = /* @__PURE__ */ new Set();
47315
48652
  const stableIds = /* @__PURE__ */ new Set();
@@ -47318,9 +48655,9 @@ function validate2(items, maxItems, initialReason) {
47318
48655
  if ((item.source.source_id?.length ?? 0) > 500 || item.source.source_id === "" || (item.source.workspace_id?.length ?? 0) > 500 || item.source.workspace_id === "") reason ??= "invalid_batch_metadata";
47319
48656
  if ((item.format ?? "markdown").length > 100 || (item.title?.length ?? 0) > 2e3 || JSON.stringify(item.metadata ?? {}).length > 262144) reason ??= "invalid_item";
47320
48657
  if (item.content_digest && item.content_digest !== sourceContentDigest(item.content)) reason ??= "content_digest_mismatch";
47321
- const key2 = `${item.source.tenant_id}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
47322
- if (seen.has(key2)) reason ??= "duplicate_external_id_in_batch";
47323
- seen.add(key2);
48658
+ const key3 = `${item.source.tenant_id}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
48659
+ if (seen.has(key3)) reason ??= "duplicate_external_id_in_batch";
48660
+ seen.add(key3);
47324
48661
  if (item.source.caller_stable_id && stableIds.has(item.source.caller_stable_id)) reason ??= "caller_stable_id_conflict";
47325
48662
  if (item.source.caller_stable_id) stableIds.add(item.source.caller_stable_id);
47326
48663
  }
@@ -47452,7 +48789,7 @@ async function purgeRecordStoreGraph(store, selector, operationKey) {
47452
48789
  }
47453
48790
 
47454
48791
  // src/index.ts
47455
- var VERSION = "2026.9.5";
48792
+ var VERSION = "2026.9.6";
47456
48793
  /*! Bundled license information:
47457
48794
 
47458
48795
  ieee754/index.js:
@@ -47467,6 +48804,6 @@ buffer/index.js:
47467
48804
  *)
47468
48805
  */
47469
48806
 
47470
- export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportFullV1Snapshot, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetExecutionCapabilitiesFromWire, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreRequest, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateDatasetExecutionRequest, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
48807
+ export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, bindSearchEvidence, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createSearchEvidenceSet, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportFullV1Snapshot, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, mergeSearchEvidenceSets, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetExecutionCapabilitiesFromWire, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, parseSearchEvidenceLocator, parseSearchEvidenceSet, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, resolveSearchEvidence, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreRequest, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateDatasetExecutionRequest, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
47471
48808
  //# sourceMappingURL=index.js.map
47472
48809
  //# sourceMappingURL=index.js.map