@equationalapplications/core-llm-wiki 4.4.0 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -2
- package/dist/index.d.mts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +56 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/db/schema.ts","../src/db/migrations.ts","../src/types.ts","../src/prompts.ts","../src/utils/cosine.ts","../src/utils/embedding.ts","../src/readOptions.ts","../src/WikiMemory.ts","../src/utils/formatContext.ts","../src/utils/formatMemoryDump.ts","../src/index.ts"],"names":["MiniSearch","rows","documents"],"mappings":"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","file":"index.js","sourcesContent":["import type { SQLiteAdapter } from '../types';\n\nexport async function setupDatabase(db: SQLiteAdapter, prefix: string) {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entries (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n title TEXT NOT NULL,\n body TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n confidence TEXT NOT NULL DEFAULT 'inferred',\n source_type TEXT NOT NULL DEFAULT 'librarian_inferred',\n source_hash TEXT,\n source_ref TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n last_accessed_at INTEGER,\n access_count INTEGER NOT NULL DEFAULT 0,\n deleted_at INTEGER,\n embedding TEXT,\n embedding_blob BLOB\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}entries_entity_idx ON ${prefix}entries(entity_id);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_ref_idx ON ${prefix}entries(entity_id, source_ref);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_hash_idx ON ${prefix}entries(entity_id, source_hash) WHERE source_hash IS NOT NULL;\n CREATE INDEX IF NOT EXISTS ${prefix}entries_updated_idx ON ${prefix}entries(updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}tasks (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n description TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n priority INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n resolved_at INTEGER,\n deleted_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_entity_idx ON ${prefix}tasks(entity_id, status);\n\n CREATE TABLE IF NOT EXISTS ${prefix}events (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n summary TEXT NOT NULL,\n related_entry_id TEXT,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}events_entity_idx ON ${prefix}events(entity_id, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}checkpoints (\n entity_id TEXT PRIMARY KEY,\n heal_checkpoint INTEGER NOT NULL DEFAULT 0,\n memory_checkpoint INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n}\n","import type { SQLiteAdapter } from '../types';\n\nexport interface Migration {\n version: number;\n description: string;\n run: (db: SQLiteAdapter, prefix: string) => Promise<void>;\n}\n\nexport const MIGRATIONS: Migration[] = [\n {\n version: 1,\n description: 'Rebuild FTS5 with porter unicode61 tokenizer (superseded by v2)',\n run: async (_db, _prefix) => {\n // This migration is superseded by v2 which drops FTS5 entirely.\n // It is kept as a no-op so upgrade paths from v0 do not require FTS5 support.\n },\n },\n {\n version: 2,\n description: 'Remove FTS5; add embedding column for semantic retrieval',\n run: async (db, prefix) => {\n // Drop FTS5 artifacts in a transaction.\n await db.withTransactionAsync(async () => {\n await db.execAsync(`\n DROP TRIGGER IF EXISTS ${prefix}entries_ai;\n DROP TRIGGER IF EXISTS ${prefix}entries_ad;\n DROP TRIGGER IF EXISTS ${prefix}entries_au;\n DROP TABLE IF EXISTS ${prefix}entries_fts;\n `);\n });\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding')) {\n await db.execAsync(`ALTER TABLE ${prefix}entries ADD COLUMN embedding TEXT`);\n }\n },\n },\n {\n version: 3,\n description: 'Add embedding_blob BLOB column for Float32Array vector storage',\n run: async (db, prefix) => {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding_blob')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN embedding_blob BLOB`\n );\n }\n },\n },\n];\n\n// Verify MIGRATIONS are in strictly ascending version order at module load time.\n// This prevents skipped or repeated migrations caused by out-of-order entries.\nfor (let i = 1; i < MIGRATIONS.length; i++) {\n if (MIGRATIONS[i].version <= MIGRATIONS[i - 1].version) {\n throw new Error(\n `migrations.ts: MIGRATIONS must be in strictly ascending version order. ` +\n `Found version ${MIGRATIONS[i].version} after ${MIGRATIONS[i - 1].version} at index ${i}.`\n );\n }\n}\n\n// Derived from the last (highest) migration version so it never drifts out of sync.\nexport const CURRENT_SCHEMA_VERSION =\n MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].version : 0;\n","/**\n * Platform-agnostic SQLite driver interface.\n * Each platform package (wiki-expo, wiki-react) provides an adapter\n * that wraps its native driver behind this interface.\n */\nexport interface SQLiteAdapter {\n execAsync(sql: string): Promise<void>;\n runAsync(sql: string, params?: unknown[]): Promise<{ changes: number; lastInsertRowId: number }>;\n getAllAsync<T>(sql: string, params?: unknown[]): Promise<T[]>;\n getFirstAsync<T>(sql: string, params?: unknown[]): Promise<T | null>;\n withTransactionAsync<T>(fn: () => Promise<T>): Promise<T>;\n closeAsync(): Promise<void>;\n}\n\nexport interface WikiConfig {\n tablePrefix?: string;\n maxResults?: number;\n /** @deprecated Use maxResults */\n maxFtsResults?: number;\n pruneEventsAfter?: number;\n pruneRetainSoftDeletedFor?: number;\n autoLibrarianThreshold?: number;\n autoHealThreshold?: number;\n orphanAfterDays?: number | null;\n staleInferredAfterDays?: number | null;\n maxChunkLength?: number;\n chunkOverlap?: number;\n chunkConcurrency?: number;\n /**\n * Max MiniSearch candidates passed to cosine scoring.\n * When set, MiniSearch pre-filters before the cosine scan.\n * Only applies when embed is provided and succeeds.\n * Default: undefined (full scan).\n */\n preFilterLimit?: number;\n /**\n * Hybrid blend weight (0.0–1.0).\n * 0.0 = pure keyword (skips embed() entirely).\n * 1.0 = pure semantic.\n * Values outside [0,1] are clamped. Ignored when embed is absent or throws.\n * Default: undefined (pure semantic when embed provided).\n */\n hybridWeight?: number;\n}\n\nexport interface ReadOptions {\n maxResults?: number;\n /**\n * undefined → use WikiConfig.preFilterLimit (or no pre-filter if also unset).\n * null → explicitly disable a config-level preFilterLimit for this call.\n */\n preFilterLimit?: number | null;\n hybridWeight?: number;\n /**\n * Per-entity score multiplier for multi-entity reads. Missing entries default to 1.0.\n * Entities with weight 0 are skipped during scored retrieval unless\n * `includeZeroWeightEntities` is true; in that case they rank below all finite scores.\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n */\n tierWeights?: Record<string, number>;\n /**\n * When true, entities with a tier weight of 0 are included in scored retrieval\n * as bottom fillers (ranked below every finite-scored candidate).\n * When false (default), zero-weight entities are skipped entirely.\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n */\n includeZeroWeightEntities?: boolean;\n}\n\nexport interface WikiFact {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string[];\n confidence: 'certain' | 'inferred' | 'tentative';\n /**\n * Source type of this fact.\n * - 'immutable_document': From ingestDocument(), cannot be modified by system (librarian/heal).\n * Only removable via forget() or replaced via re-ingest.\n * - 'librarian_inferred': Created by runLibrarian() from events, or by runHeal() when synthesizing new inferred facts.\n * - 'user_stated': Direct user statement.\n * - 'user_confirmed': User-confirmed fact.\n */\n source_type: 'user_stated' | 'librarian_inferred' | 'user_confirmed' | 'immutable_document';\n source_hash: string | null;\n source_ref: string | null;\n created_at: number;\n updated_at: number;\n /**\n * Raw Float32Array bytes for the fact's embedding vector.\n * Set when the fact was fetched via exportDump() with blob preservation.\n * Accepted in importDump() as a real Uint8Array (in-memory round-trip),\n * a Node.js Buffer JSON shape `{ type: 'Buffer', data: number[] }`,\n * or a numeric-keyed plain object `{ 0: byte, 1: byte, ... }` produced\n * by JSON.stringify(Uint8Array).\n */\n embedding_blob?: Uint8Array | { type: 'Buffer'; data: number[] } | Record<string, number>;\n last_accessed_at: number | null;\n access_count: number;\n deleted_at: number | null;\n}\n\nexport interface WikiTask {\n id: string;\n entity_id: string;\n description: string;\n status: 'pending' | 'in_progress' | 'done' | 'abandoned';\n priority: number;\n created_at: number;\n updated_at: number;\n resolved_at: number | null;\n deleted_at: number | null;\n}\n\nexport interface WikiEvent {\n id: string;\n entity_id: string;\n event_type: 'observation' | 'decision' | 'action' | 'outcome';\n summary: string;\n related_entry_id?: string | null;\n created_at: number;\n}\n\nexport interface WikiCheckpoint {\n entity_id: string;\n heal_checkpoint: number;\n memory_checkpoint: number;\n}\n\nexport interface ExtractedFact {\n title: string;\n body: string;\n tags: string[];\n confidence: 'certain' | 'inferred' | 'tentative';\n}\n\nexport interface ExtractedTask {\n description: string;\n priority: number;\n}\n\nexport interface LLMProvider {\n /**\n * Generates text using the developer's LLM of choice.\n * Expected to return the raw text response (typically a JSON string).\n */\n generateText: (params: { systemPrompt: string; userPrompt: string }) => Promise<string>;\n /**\n * Optional. When provided, enables semantic similarity search in `read()`.\n * Must return a stable-dimension float array for any input text.\n * Called once per fact on creation/update, and once per `read()` query.\n * When absent or throws, `read()` falls back to MiniSearch.\n */\n embed?: (text: string) => Promise<number[]>;\n}\n\n/**\n * Result of semantic ranking for a single fact.\n */\nexport interface VectorRankerSemanticResult {\n id: string;\n /** Cosine similarity in [-1, 1] when exact; implementations MAY document other monotonic scales. */\n semanticScore: number;\n}\n\n/**\n * Arguments passed to VectorRanker.rankBySimilarity.\n */\nexport interface VectorRankerRankArgs {\n entityId: string;\n /**\n * Query embedding. Treat as readonly — core provides a defensive copy,\n * but adapters MUST NOT mutate this array. Mutation can corrupt\n * WikiMemory's internal vector cache and JS-cosine fallback path.\n */\n queryVec: Float32Array | number[];\n /**\n * When set (MiniSearch pre-filter path): ranker MUST only produce results for ids in this set.\n * When omitted (full-entity semantic path): ranker scopes by entityId per its backing store contract.\n */\n candidateIds?: readonly string[];\n /**\n * Upper bound on how many distinct fact ids should receive a semanticScore in this call.\n * WikiMemory derives this from maxResults / candidate cardinality / documented oversampling policy.\n */\n limit: number;\n}\n\n/**\n * Optional backend for semantic candidate scoring / top-k retrieval.\n * When omitted, WikiMemory scores rows with embedding_blob / embedding TEXT in JS (cosine).\n */\nexport interface VectorRanker {\n /**\n * Return semantic scores for facts in scope, sorted descending by semanticScore (stable tie-breaking\n * not required — WikiMemory reapplies existing tie-breakers after blending).\n * Implementations SHOULD omit facts with no usable vector; callers treat missing ids like today's\n * \"no embedding\" rows (pure semantic: -2; hybrid: keyword-only portion).\n */\n rankBySimilarity(args: VectorRankerRankArgs): Promise<VectorRankerSemanticResult[]>;\n\n /**\n * Called after a fact's embedding is successfully persisted to embedding_blob (or cleared).\n * Hosts use this to keep sqlite-vec / external indexes consistent with SQLite as source of truth.\n *\n * On deletion paths (forget, prune, hard-delete), core awaits this hook to ensure ANN cleanup\n * completes before the deletion call resolves (GDPR compliance). Hook failures or timeouts on\n * those paths reject the deletion call.\n *\n * Treat `vector` as readonly — core provides a defensive copy, but adapters MUST NOT mutate.\n *\n * Optional: if omitted, hosts MUST document \"index rebuilt separately\" and accept stale ANN until rebuild.\n */\n onEmbeddingPersisted?(event: {\n entityId: string;\n factId: string;\n vector: Float32Array | null; // null = embedding removed / unusable\n }): void | Promise<void>;\n}\n\n/**\n * Fallback policy when rankBySimilarity rejects.\n */\nexport type VectorRankerFallback = 'js-cosine' | 'keyword' | 'empty' | 'throw';\n\nexport interface WikiOptions {\n config?: WikiConfig;\n llmProvider: LLMProvider;\n /**\n * Called when embedding-based retrieval is degraded or unavailable during `read()`.\n * This can happen when:\n * - `embed()` throws (e.g. network error, model unavailable) → falls back to keyword search\n * - `embed()` returns a vector with non-finite values (NaN / Infinity) → falls back to keyword search\n * - The query vector's dimension doesn't match stored embeddings (model switch;\n * resolve by calling `runReembed()`) → falls back to keyword search\n * - `vectorRanker` returns IDs that don't belong to the requested entity or don't exist\n * (ranker integrity issue; returned rows will be filtered out, reducing result count) →\n * may still use semantic ranking, but with degraded quality\n *\n * `read()` returns results (keyword fallback or degraded semantic) — this is a notification, not an error path.\n */\n onRetrievalFallback?: (error: Error) => void;\n\n /**\n * Optional backend for semantic candidate scoring / top-k retrieval.\n * When omitted, WikiMemory scores rows with embedding_blob / embedding TEXT in JS (cosine).\n */\n vectorRanker?: VectorRanker;\n\n /**\n * When rankBySimilarity throws. Default `'js-cosine'`.\n * Ignored when vectorRanker is undefined.\n */\n vectorRankerFallback?: VectorRankerFallback;\n\n /**\n * Called only when rankBySimilarity rejects (after embeddings path succeeded).\n * Invoked before applying vectorRankerFallback when that policy recovers or before rejecting when policy is 'throw'.\n */\n onVectorRankerFallback?: (info: {\n error: Error;\n /** Effective policy core will apply for this read (same as WikiOptions.vectorRankerFallback, default js-cosine). */\n policy: VectorRankerFallback;\n }) => void;\n\n /**\n * When true: after rankBySimilarity failure, once the recoverable fallback has finished\n * and read() will resolve, invoke onRetrievalFallback — after onVectorRankerFallback if set.\n * Ignored when vectorRankerFallback is 'throw'. Default false.\n */\n propagateRankerFailureToRetrievalFallback?: boolean;\n\n /**\n * When true (default), sanitize ranker errors before exposing via error.cause\n * to prevent credential leakage in host telemetry. Disable only when you\n * control the ranker implementation.\n *\n * Sanitization replaces error message/stack with a generic message preserving\n * only the error type (constructor name).\n */\n sanitizeRankerErrors?: boolean;\n\n /**\n * Timeout (ms) for onEmbeddingPersisted hook on GDPR deletion paths\n * (forget, _doPrune). Hook must complete within this window or the\n * deletion operation rejects. Default 30000.\n * Lower for interactive deletes; raise for slow remote ANN backends.\n */\n deletionHookTimeoutMs?: number;\n\n /**\n * Escape hatch: skip onEmbeddingPersisted on deletion paths entirely.\n * Use ONLY when the ANN backend is permanently decommissioned. Vectors\n * orphaned in the (unreachable) external index are accepted as a tradeoff.\n * NOT GDPR-safe for live indexes. Default false.\n */\n forceDeleteIgnoreRankerHook?: boolean;\n}\n\nexport interface MemoryBundle {\n facts: WikiFact[];\n tasks: WikiTask[];\n events: WikiEvent[];\n factScores?: Record<string, number>;\n metadata?: {\n query: string;\n entityIds: string[];\n tierWeights?: Record<string, number>;\n };\n}\n\nexport interface MemoryDump {\n generatedAt: number;\n entities: Record<string, MemoryBundle>;\n}\n\nexport interface FormattedMemoryDump {\n manifest: string;\n files: Array<{ name: string; content: string }>;\n}\n\nexport interface FormatContextOptions {\n format?: 'markdown' | 'plain';\n maxFacts?: number;\n maxTasks?: number;\n maxEvents?: number;\n includeConfidence?: boolean;\n includeTags?: boolean;\n factWeights?: {\n confidence?: number;\n accessCount?: number;\n recency?: number;\n };\n}\n\nexport interface EntityStatus {\n ingesting: boolean;\n librarian: boolean;\n heal: boolean;\n}\n\n/**\n * All operations that can appear in a {@link WikiBusyError}.\n *\n * @remarks **Breaking change from v2.x** — the union previously only contained\n * `'ingest' | 'librarian' | 'heal' | 'prune' | 'reembed'`. The values `'import'`\n * and `'forget'` were added in v3.0. Exhaustive `switch` / narrowing on this type\n * must be updated (or given a `default` arm) to compile without errors.\n */\nexport type WikiBusyOperation =\n | 'ingest'\n | 'librarian'\n | 'heal'\n | 'prune'\n | 'reembed'\n | 'import'\n | 'forget';\n\n/**\n * Thrown when a background mutator is already running for the requested entity.\n */\nexport class WikiBusyError extends Error {\n readonly operation: WikiBusyOperation;\n readonly entityId: string;\n\n constructor(operation: WikiBusyOperation, entityId: string) {\n super(`${operation} already running for entity ${entityId}`);\n this.name = 'WikiBusyError';\n this.operation = operation;\n this.entityId = entityId;\n }\n}\n\nexport class PrunePartialFailureError extends Error {\n readonly deleted: number;\n readonly failedAt: string;\n readonly remaining: number;\n readonly deletedTasks: number;\n readonly deletedEvents: number;\n override readonly cause: Error;\n\n constructor(\n deleted: number,\n failedAt: string,\n remaining: number,\n cause: Error,\n deletedTasks: number = 0,\n deletedEvents: number = 0,\n ) {\n super(`Prune partially failed: deleted ${deleted}, failed at ${failedAt}, ${remaining} remaining`);\n this.name = 'PrunePartialFailureError';\n this.deleted = deleted;\n this.failedAt = failedAt;\n this.remaining = remaining;\n this.deletedTasks = deletedTasks;\n this.deletedEvents = deletedEvents;\n this.cause = cause;\n }\n}\n\n","export const LIBRARIAN_SYSTEM_PROMPT = `You are a knowledge extraction agent. Your job is to analyze recent episodic events and extract stable facts and actionable tasks about the user or entity.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"facts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }],\n \"tasks\": [{ \"description\": \"string\", \"priority\": \"number (0-10)\" }]\n}\nKeep facts concise. Do not return markdown, just raw JSON.`;\n\nexport const HEAL_SYSTEM_PROMPT = `You are a memory grooming agent. Your job is to review a full dump of facts and recent events to resolve contradictions, downgrade stale claims, and flag obsolete facts for deletion.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"downgraded\": [\"string (fact IDs)\"],\n \"deleted\": [\"string (fact IDs)\"],\n \"newFacts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }]\n}\nDo not return markdown, just raw JSON.`;\n\nexport const INGEST_SYSTEM_PROMPT = `You are a document ingestion agent. Your job is to extract factual knowledge from the provided document chunk.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"facts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }]\n}\nExtract verbatim factual content. Do not return markdown, just raw JSON.`;\n","export function cosineSimilarity(a: ArrayLike<number>, b: ArrayLike<number>): number {\n let dot = 0, normA = 0, normB = 0;\n const len = Math.min(a.length, b.length);\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n","export function parseEmbedding(\n blob: Uint8Array | null | undefined,\n text: string | null | undefined\n): Float32Array | null {\n if (blob && blob.byteLength > 0) {\n if (blob.byteLength % 4 !== 0) return null;\n // Copy into fresh ArrayBuffer — SQLite drivers may return pooled Buffer\n // objects that get reused across queries, silently corrupting cached vectors.\n const copy = new ArrayBuffer(blob.byteLength);\n new Uint8Array(copy).set(blob);\n const vector = new Float32Array(copy);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n }\n if (text) {\n try {\n const arr: unknown = JSON.parse(text);\n if (!Array.isArray(arr) || !arr.every((v: unknown) => typeof v === 'number' && isFinite(v))) return null;\n const vector = new Float32Array(arr as number[]);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n } catch { return null; }\n }\n return null;\n}\n","export function normalizeEntityIds(entityId: string | string[]): string[] {\n const input = Array.isArray(entityId) ? entityId : [entityId];\n const seen = new Set<string>();\n const normalized: string[] = [];\n\n for (const id of input) {\n if (seen.has(id)) continue;\n seen.add(id);\n normalized.push(id);\n }\n\n return normalized;\n}\n\nexport function sanitizeTierWeights(\n entityIds: readonly string[],\n tierWeights: Record<string, number> | undefined,\n): Record<string, number> | undefined {\n if (tierWeights === undefined) return undefined;\n\n const sanitized = Object.create(null) as Record<string, number>;\n for (const entityId of entityIds) {\n const raw = tierWeights[entityId];\n if (raw === undefined || !Number.isFinite(raw)) {\n sanitized[entityId] = 1;\n } else {\n sanitized[entityId] = Math.max(0, raw);\n }\n }\n return sanitized;\n}\n\nexport function applyTierWeight(\n score: number,\n entityId: string,\n sanitizedTierWeights: Record<string, number> | undefined,\n): number {\n const weight = sanitizedTierWeights?.[entityId] ?? 1;\n // Weight=0 → sentinel -Infinity so zero-weight entities always sort below any\n // finite score, including negative cosine values from the pure-semantic path.\n if (weight === 0) return -Infinity;\n return score * weight;\n}\n\nexport function shouldExposeReadMetadata(\n entityId: string | string[],\n): boolean {\n return Array.isArray(entityId);\n}\n","import type { SQLiteAdapter } from './types';\nimport { setupDatabase } from './db/schema';\nimport { MIGRATIONS, CURRENT_SCHEMA_VERSION } from './db/migrations';\nimport { WikiOptions, MemoryBundle, MemoryDump, WikiEvent, WikiFact, WikiTask, WikiCheckpoint, ExtractedFact, ExtractedTask, WikiBusyError, PrunePartialFailureError, EntityStatus, ReadOptions } from './types';\nimport { LIBRARIAN_SYSTEM_PROMPT, HEAL_SYSTEM_PROMPT, INGEST_SYSTEM_PROMPT } from './prompts';\nimport MiniSearch from 'minisearch';\nimport { cosineSimilarity } from './utils/cosine';\nimport { parseEmbedding } from './utils/embedding';\nimport { applyTierWeight, normalizeEntityIds, sanitizeTierWeights, shouldExposeReadMetadata } from './readOptions';\n\nexport { WikiBusyError, PrunePartialFailureError } from './types';\n\n/**\n * Private symbol to mark timeout errors thrown by WikiMemory (not from ranker).\n * Used to distinguish WikiMemory's own timeout errors from ranker errors that might contain \"timed out\" in message.\n */\nconst HOOK_TIMEOUT_MARKER = Symbol('WikiMemoryHookTimeout');\n\ntype ReadCandidateRowMetadata = {\n id: string;\n entity_id: string;\n updated_at: number | null;\n access_count: number | null;\n};\n\ntype ReadCandidateRowWithEmbeddings = ReadCandidateRowMetadata & {\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n};\n\n\nfunction parseJsonResponse<T>(text: string): T {\n const firstBrace = text.indexOf('{');\n const firstBracket = text.indexOf('[');\n\n let start: number;\n let openChar: string;\n let closeChar: string;\n\n if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n openChar = '{';\n closeChar = '}';\n } else if (firstBracket !== -1) {\n start = firstBracket;\n openChar = '[';\n closeChar = ']';\n } else {\n throw new SyntaxError('No JSON object/array found in LLM response');\n }\n\n // Walk from `start`, tracking nesting depth and skipping strings/escapes,\n // so we stop at the true matching close bracket rather than the last one.\n let depth = 0;\n let inString = false;\n let escape = false;\n let end = -1;\n for (let i = start; i < text.length; i++) {\n const ch = text[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === openChar) { depth++; continue; }\n if (ch === closeChar) {\n depth--;\n if (depth === 0) { end = i; break; }\n }\n }\n\n if (end === -1) throw new SyntaxError('No JSON object/array found in LLM response');\n return JSON.parse(text.slice(start, end + 1)) as T;\n}\n\nfunction generateId(prefix: string = '') {\n return prefix + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n}\n\nfunction safeSlice(value: string, start: number, end?: number): string {\n const length = value.length;\n let safeStart = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);\n let safeEnd = end === undefined\n ? length\n : end < 0\n ? Math.max(length + end, 0)\n : Math.min(end, length);\n\n if (safeStart > safeEnd) {\n [safeStart, safeEnd] = [safeEnd, safeStart];\n }\n\n if (\n safeStart > 0 &&\n safeStart < length &&\n value.charCodeAt(safeStart) >= 0xDC00 &&\n value.charCodeAt(safeStart) <= 0xDFFF &&\n value.charCodeAt(safeStart - 1) >= 0xD800 &&\n value.charCodeAt(safeStart - 1) <= 0xDBFF\n ) {\n safeStart--;\n }\n\n if (\n safeEnd > 0 &&\n safeEnd < length &&\n value.charCodeAt(safeEnd - 1) >= 0xD800 &&\n value.charCodeAt(safeEnd - 1) <= 0xDBFF &&\n value.charCodeAt(safeEnd) >= 0xDC00 &&\n value.charCodeAt(safeEnd) <= 0xDFFF\n ) {\n safeEnd--;\n }\n\n return value.slice(safeStart, safeEnd);\n}\n\nfunction chunkText(\n input: string,\n maxChunkLength: number,\n overlap: number\n): { chunks: string[]; truncated: boolean } {\n const text = input.trim();\n if (text.length === 0) return { chunks: [], truncated: false };\n if (!Number.isInteger(maxChunkLength) || maxChunkLength < 2) {\n throw new Error('maxChunkLength must be an integer >= 2');\n }\n if (!Number.isInteger(overlap) || overlap < 0 || overlap >= maxChunkLength) {\n throw new Error('overlap must be a non-negative integer < maxChunkLength');\n }\n\n const chunks: string[] = [];\n let truncated = false;\n let cursor = 0;\n const halfMax = Math.floor(maxChunkLength / 2);\n\n while (cursor < text.length) {\n const remaining = text.length - cursor;\n if (remaining <= maxChunkLength) {\n chunks.push(safeSlice(text, cursor, text.length));\n break;\n }\n\n const windowEnd = cursor + maxChunkLength;\n const minSplit = cursor + halfMax;\n\n // 1. paragraph break\n let splitPoint = -1;\n const paraIdx = text.lastIndexOf('\\n\\n', windowEnd);\n if (paraIdx >= minSplit && paraIdx + 2 <= windowEnd) {\n splitPoint = paraIdx + 2;\n }\n\n // 2. sentence terminator (single left-to-right pass, no lookahead regex)\n if (splitPoint === -1) {\n let lastTerm = -1;\n for (let i = minSplit; i < windowEnd - 1; i++) {\n const ch = text[i];\n if ((ch === '.' || ch === '!' || ch === '?') && /\\s/.test(text[i + 1])) {\n lastTerm = i + 2; // include the terminator + whitespace\n }\n }\n if (lastTerm !== -1 && lastTerm <= windowEnd) splitPoint = lastTerm;\n }\n\n // 3. whitespace\n if (splitPoint === -1) {\n for (let i = windowEnd - 1; i >= minSplit; i--) {\n if (/\\s/.test(text[i])) {\n splitPoint = i + 1;\n break;\n }\n }\n }\n\n // 4. hard cut\n if (splitPoint === -1) {\n truncated = true;\n splitPoint = windowEnd;\n }\n\n chunks.push(safeSlice(text, cursor, splitPoint));\n const next = Math.max(splitPoint - overlap, cursor + 1);\n cursor = next;\n }\n\n return { chunks, truncated };\n}\n\nasync function withConcurrency<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<T[]> {\n const results: T[] = new Array(tasks.length);\n let index = 0;\n let failed = false;\n let firstError: unknown;\n async function worker() {\n while (index < tasks.length && !failed) {\n const i = index++;\n try {\n results[i] = await tasks[i]();\n } catch (e) {\n if (!failed) { failed = true; firstError = e; }\n return;\n }\n }\n }\n const workerCount = tasks.length === 0 ? 0 : Math.min(Math.max(limit, 1), tasks.length);\n await Promise.allSettled(Array.from({ length: workerCount }, worker));\n if (failed) throw firstError;\n return results;\n}\n\nfunction clip(value: string, max: number): string {\n if (typeof value !== 'string') return '';\n const s = value.trim();\n return s.length <= max ? s : safeSlice(s, 0, max).trimEnd();\n}\n\nfunction validateTags(tags: any[]): string[] {\n if (!Array.isArray(tags)) return [];\n return tags\n .filter(t => typeof t === 'string')\n .map(t => t.trim().toLowerCase())\n .filter(t => t.length > 0 && t.length <= 40)\n .slice(0, 6);\n}\n\nfunction validateFact(fact: any): ExtractedFact | null {\n if (typeof fact?.title !== 'string' || typeof fact?.body !== 'string') return null;\n const title = clip(fact.title, 80);\n const body = clip(fact.body, 800);\n if (!title || !body) return null;\n \n let confidence = fact.confidence;\n if (confidence !== 'certain' && confidence !== 'tentative') confidence = 'inferred';\n \n return {\n ...fact,\n title,\n body,\n confidence,\n tags: validateTags(fact.tags)\n };\n}\n\nfunction validateTask(task: any): ExtractedTask | null {\n if (typeof task?.description !== 'string') return null;\n const description = clip(task.description, 200);\n if (!description) return null;\n \n let priority = task.priority;\n if (typeof priority !== 'number' || !isFinite(priority)) priority = 0;\n \n return {\n ...task,\n description,\n priority\n };\n}\n\nfunction normalizeSourceRef(value: string): string | null {\n if (typeof value !== 'string') return null;\n const cleaned = value.replace(/[^A-Za-z0-9._\\- ]/g, '').trim().slice(0, 255);\n return cleaned.length > 0 ? cleaned : null;\n}\n\nfunction normalizeSourceHash(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n return /^[0-9a-f]{64}$/i.test(value) ? value.toLowerCase() : null;\n}\n\n\nfunction titleTokens(title: string): Set<string> {\n return new Set(title.toLowerCase().replace(/[^a-z0-9\\s]/g, '').split(/\\s+/).filter(t => t.length >= 3));\n}\n\nfunction jaccardScore(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n const intersection = new Set([...a].filter(x => b.has(x)));\n const union = new Set([...a, ...b]);\n return intersection.size / union.size;\n}\n\nconst FUZZY_THRESHOLD = 0.5;\nconst MIN_TOKENS_TO_QUALIFY = 3;\n\nexport class WikiMemory {\n private db: SQLiteAdapter;\n private prefix: string;\n private options: WikiOptions;\n private activeMaintenanceJobs = new Set<string>();\n private activeIngestJobs = new Set<string>();\n private statusSubscribers = new Map<\n string,\n Set<{ callback: (s: EntityStatus) => void; last: EntityStatus }>\n >();\n private miniSearch = new MiniSearch<{ id: string; entity_id: string; title: string; body: string; tags: string }>({\n fields: ['title', 'body', 'tags'],\n storeFields: ['entity_id'],\n searchOptions: {\n boost: { title: 2 },\n fuzzy: 0.2,\n prefix: true,\n },\n });\n private miniSearchEntryIdsByEntity = new Map<string, Set<string>>();\n /**\n * Maximum number of entities whose parsed embedding vectors are held in\n * memory. This cap is intentionally conservative so the cache remains safe\n * on memory-constrained runtimes (e.g., mobile/Expo).\n */\n private static readonly MAX_VECTOR_CACHE_ENTITIES = 16;\n /**\n * Maximum number of fact vectors cached per entity. Keep this high enough to\n * preserve the parsed-embedding reuse optimization for common mid-sized\n * entities while still maintaining a bounded memory footprint.\n */\n private static readonly MAX_VECTOR_CACHE_FACTS_PER_ENTITY = 500;\n private vectorCache: Map<string, Map<string, Float32Array>> = new Map();\n\n private normalizeMiniSearchRow(row: {\n id: string; entity_id: string; title: string; body: string; tags: string;\n }): { id: string; entity_id: string; title: string; body: string; tags: string } {\n return {\n id: row.id,\n entity_id: row.entity_id,\n title: row.title,\n body: row.body,\n tags: (() => {\n try {\n const parsed = JSON.parse(row.tags);\n return Array.isArray(parsed) ? parsed.join(' ') : row.tags;\n } catch {\n return row.tags;\n }\n })(),\n };\n }\n\n private async rebuildMiniSearchIndex(entityId?: string): Promise<void> {\n if (entityId) {\n const rows = await this.db.getAllAsync<{\n id: string; entity_id: string; title: string; body: string; tags: string;\n }>(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL AND entity_id = ?`,\n [entityId],\n );\n\n const previousIds = this.miniSearchEntryIdsByEntity.get(entityId);\n if (previousIds) {\n for (const id of previousIds) {\n this.miniSearch.discard(id);\n }\n }\n\n const documents = rows.map(row => this.normalizeMiniSearchRow(row));\n if (documents.length > 0) {\n this.miniSearch.addAll(documents);\n }\n\n this.miniSearchEntryIdsByEntity.set(entityId, new Set(documents.map(document => document.id)));\n return;\n }\n\n const rows = await this.db.getAllAsync<{\n id: string; entity_id: string; title: string; body: string; tags: string;\n }>(`SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL`);\n\n this.miniSearch.removeAll();\n this.miniSearchEntryIdsByEntity.clear();\n\n const documents = rows.map(row => this.normalizeMiniSearchRow(row));\n if (documents.length > 0) {\n this.miniSearch.addAll(documents);\n }\n\n for (const document of documents) {\n const ids = this.miniSearchEntryIdsByEntity.get(document.entity_id) ?? new Set<string>();\n ids.add(document.id);\n this.miniSearchEntryIdsByEntity.set(document.entity_id, ids);\n }\n }\n\n private async storeEmbeddingDimension(dim: number): Promise<void> {\n const existing = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n if (existing) {\n const storedDim = parseInt(existing.value, 10);\n if (storedDim !== dim) {\n console.warn(\n `[WikiMemory] Embedding dimension mismatch: stored ${storedDim}, got ${dim}. ` +\n `Call runReembed() to rebuild embeddings with the new model.`\n );\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(dim)]\n );\n }\n // Do NOT clear 'embedding_dimension_mismatch' here: other facts may still hold\n // old-dimension blobs written during a previous model. Only _reconcileEmbeddingDimension()\n // (called after a full runReembed) may clear the flag once it confirms all stored\n // blobs match the new canonical dimension.\n } else {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension', ?)`,\n [String(dim)]\n );\n }\n }\n\n /**\n * After a successful runReembed(), promote the pending `embedding_dimension_mismatch`\n * value to the canonical `embedding_dimension` key and clear the mismatch flag.\n * This ensures future read() calls use embedding-based retrieval rather than staying\n * stuck on the MiniSearch fallback.\n */\n private async _reconcileEmbeddingDimension(): Promise<void> {\n const mismatch = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (!mismatch) return;\n\n const newDim = parseInt(mismatch.value, 10);\n // Check whether any non-deleted fact still stores a blob with a different byte\n // length. If so, those facts haven't been re-embedded yet and the mismatch flag\n // must stay in place so read() keeps falling back to MiniSearch for them.\n // A row blocks mismatch-flag removal if:\n // (a) it has a BLOB whose dimension differs from the new model, OR\n // (b) it has only a TEXT vector (embedding_blob IS NULL) — TEXT rows were\n // written by an older model and must be converted by runReembed() before\n // they are safe to score against the new query dimension.\n const residual = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE deleted_at IS NULL\n AND (\n (embedding_blob IS NOT NULL AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?)\n OR (embedding_blob IS NULL AND embedding IS NOT NULL)\n )`,\n [newDim]\n );\n // Only promote and clear once every stored vector uses the new dimension.\n // Promoting before all rows are converted would leave read() in an inconsistent\n // state: the canonical dim would point at the new model while TEXT-only or\n // wrong-dim blobs still exist, causing those rows to score silently as 0.\n if (!residual || residual.cnt === 0) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension', ?)`,\n [mismatch.value]\n );\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n }\n }\n\n private async embedFact(fact: { id: string; entity_id: string; title: string; body: string; tags: string | string[] }): Promise<boolean> {\n const embedFn = this.options.llmProvider.embed;\n if (!embedFn) return false;\n let tagsStr: string;\n if (Array.isArray(fact.tags)) {\n tagsStr = fact.tags.join(' ');\n } else {\n try {\n const parsed = JSON.parse(fact.tags);\n tagsStr = Array.isArray(parsed) ? parsed.join(' ') : fact.tags;\n } catch {\n tagsStr = fact.tags;\n }\n }\n const text = `${fact.title} ${fact.body} ${tagsStr}`.trim();\n try {\n const vector = await embedFn(text);\n // Validate before persisting: an empty or non-finite vector would poison\n // embedding_dimension and write unusable data to embedding_blob.\n if (vector.length === 0 || !vector.every(v => typeof v === 'number' && isFinite(v))) {\n console.warn(`[WikiMemory] embedFact: embed() returned an invalid vector for ${fact.id}; skipping.`);\n return false;\n }\n const float32Vector = new Float32Array(vector);\n let hasNonFinite = false;\n for (let i = 0; i < float32Vector.length; i++) {\n if (!isFinite(float32Vector[i])) { hasNonFinite = true; break; }\n }\n if (hasNonFinite) {\n console.warn(`[WikiMemory] embedFact: embed() returned values that overflow float32 for ${fact.id}; skipping.`);\n return false;\n }\n await this.storeEmbeddingDimension(float32Vector.length);\n const blob = new Uint8Array(float32Vector.buffer);\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET embedding_blob = ?, embedding = NULL WHERE id = ?`,\n [blob, fact.id]\n );\n // Isolate hook failure: embedding was persisted successfully even if external index sync fails\n try {\n await this._notifyEmbeddingPersisted(fact.entity_id, fact.id, float32Vector);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed for ${fact.id}:`, hookErr);\n }\n return true;\n } catch (err) {\n console.warn(`[WikiMemory] embedFact failed for ${fact.id}:`, err);\n return false;\n }\n }\n\n private _librarianKey(entityId: string) { return `${this.prefix}:${entityId}:librarian`; }\n private _healKey(entityId: string) { return `${this.prefix}:${entityId}:heal`; }\n private _warnCrossEntityCollision(type: 'entry' | 'task', id: string, existingEntityId: string, targetEntityId: string): void {\n console.warn(`[WikiMemory] importDump: ${type} id \"${id}\" already belongs to entity \"${existingEntityId}\"; skipping for entity \"${targetEntityId}\"`);\n }\n\n /** Maps pre-rename enum strings from older dumps to current source_type values. */\n private _normalizeImportedSourceType(\n raw: string,\n ctx?: { entityId: string; factId: string },\n ): WikiFact['source_type'] {\n if (raw === 'user_document') return 'immutable_document';\n if (raw === 'agent_inferred') return 'librarian_inferred';\n const allowed: WikiFact['source_type'][] = ['user_stated', 'librarian_inferred', 'user_confirmed', 'immutable_document'];\n if ((allowed as string[]).includes(raw)) return raw as WikiFact['source_type'];\n const where =\n ctx !== undefined ? ` for entity \"${ctx.entityId}\" fact \"${ctx.factId}\"` : '';\n throw new Error(\n `importDump: invalid source_type \"${raw}\"${where} (expected one of: ${allowed.join(', ')}, or legacy aliases user_document / agent_inferred)`\n );\n }\n\n private async assertNoLegacySourceTypes(): Promise<void> {\n const legacyProbe = await this.db.getFirstAsync<{ one: number }>(\n `SELECT 1 AS one FROM ${this.prefix}entries\n WHERE source_type IN ('user_document', 'agent_inferred')\n LIMIT 1`,\n []\n );\n\n if (!legacyProbe) return;\n\n const legacyCount = await this.db.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}entries\n WHERE source_type IN ('user_document', 'agent_inferred')`,\n []\n );\n\n const count = legacyCount?.count ?? 0;\n const migrationSQL = `\n-- Migrate legacy source_type values (targets your WikiMemory prefix: ${this.prefix})\nUPDATE ${this.prefix}entries SET source_type = 'immutable_document' WHERE source_type = 'user_document';\nUPDATE ${this.prefix}entries SET source_type = 'librarian_inferred' WHERE source_type = 'agent_inferred';\n `.trim();\n\n throw new Error(\n `Database contains ${count} entries with legacy source_type values ('user_document' or 'agent_inferred'). ` +\n `These enum values were renamed in this release. Running without migration would allow legacy 'user_document' facts to bypass ` +\n `immutability guards, causing data corruption.\\n\\n${migrationSQL}\\n\\n` +\n `After running the migration SQL, restart your application.`\n );\n }\n\n private async _notifyEmbeddingPersisted(\n entityId: string,\n factId: string,\n vector: Float32Array | null,\n ): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n // Defensive copy prevents hooks from mutating cache/fallback/persisted-blob vectors.\n // .slice() on Float32Array allocates a fresh ArrayBuffer (not a view).\n const vectorCopy = vector ? vector.slice() : null;\n await this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n });\n }\n\n /**\n * GDPR-critical variant: awaits the hook with a timeout and rethrows failures.\n * Use ONLY on deletion paths. forget() calls after soft-delete UPDATE; runPrune()\n * calls before hard DELETE. For best-effort sync, use _notifyEmbeddingPersisted.\n */\n private async _notifyEmbeddingPersistedOrThrow(\n entityId: string,\n factId: string,\n vector: Float32Array | null,\n ): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n if (this.options.forceDeleteIgnoreRankerHook === true) return;\n\n const vectorCopy = vector ? vector.slice() : null;\n const rawTimeout = this.options.deletionHookTimeoutMs ?? 30_000;\n if (typeof rawTimeout !== 'number' || !Number.isFinite(rawTimeout) || rawTimeout <= 0) {\n throw new Error('Invalid deletionHookTimeoutMs: must be a positive finite number');\n }\n const timeoutMs = rawTimeout;\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(\n () => {\n const timeoutError = new Error(`onEmbeddingPersisted timed out after ${timeoutMs}ms`);\n (timeoutError as any)[HOOK_TIMEOUT_MARKER] = true;\n reject(timeoutError);\n },\n timeoutMs,\n );\n });\n\n const hookPromise = Promise.resolve(\n this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n }),\n );\n\n try {\n await Promise.race([hookPromise, timeoutPromise]);\n } catch (err) {\n // Suppress late rejections from hook if timeout won\n hookPromise.catch(() => {});\n throw err;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n\n constructor(db: SQLiteAdapter, options: WikiOptions) {\n this.db = db;\n this.options = options;\n this.prefix = options.config?.tablePrefix || 'llm_wiki_';\n }\n\n async setup() {\n // Probe entries-table existence BEFORE creating any tables. setupDatabase()\n // uses IF NOT EXISTS throughout, so once it has run the entries table always\n // exists and the fresh-install branch would be unreachable. Future migrations\n // that ALTER TABLE would also fail if run against a schema already at the\n // target version but inferred as legacy because the probe ran too late.\n const entriesExistedBeforeSetup = await this.db.getFirstAsync<{ name: string }>(\n `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,\n [`${this.prefix}entries`]\n );\n\n await setupDatabase(this.db, this.prefix);\n\n let currentVersion: number;\n\n if (!entriesExistedBeforeSetup) {\n // Fresh install — all tables just created at current schema; no migrations needed.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(CURRENT_SCHEMA_VERSION)]\n );\n currentVersion = CURRENT_SCHEMA_VERSION;\n } else {\n // Existing install — check meta for schema version.\n const metaRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'schema_version'`\n );\n\n if (metaRow) {\n currentVersion = parseInt(metaRow.value, 10);\n if (!Number.isFinite(currentVersion)) currentVersion = 0;\n } else {\n // Legacy install without meta row — infer version from porter probe.\n const ftsMeta = await this.db.getFirstAsync<{ sql: string | null }>(\n `SELECT sql FROM sqlite_master WHERE type='table' AND name=?`,\n [`${this.prefix}entries_fts`]\n );\n const hasPorter = /tokenize\\s*=\\s*['\"]porter\\s+unicode61['\"]/i.test(ftsMeta?.sql ?? '');\n currentVersion = hasPorter ? 1 : 0;\n }\n }\n\n // Run pending migrations in order.\n for (const migration of MIGRATIONS) {\n if (migration.version > currentVersion) {\n await migration.run(this.db, this.prefix);\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(migration.version)]\n );\n currentVersion = migration.version;\n }\n }\n\n // Ensure meta row exists for legacy installs already at current version\n // (porter present, no meta row) — the migration loop may not have written it.\n if (entriesExistedBeforeSetup) {\n const metaCheck = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'schema_version'`\n );\n if (!metaCheck) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(currentVersion)]\n );\n }\n }\n\n // Fail before any other mutating passes (e.g. source_ref normalization) so we never\n // partially \"repair\" a DB that is still on legacy source_type strings.\n if (entriesExistedBeforeSetup) {\n await this.assertNoLegacySourceTypes();\n }\n\n // Migration: normalize any existing source_ref values that were stored before the\n // allowlist rule ([^A-Za-z0-9._\\- ] → strip) was introduced. Read-then-update in\n // JS so the normalization is guaranteed to match what normalizeSourceRef() produces,\n // regardless of which characters the old normalization left behind.\n // The WHERE clause pre-filters to rows that contain any character outside the\n // allowlist (checking leading/trailing whitespace, slashes, backslashes, NUL, and\n // the full ASCII non-allowlist range via GLOB) so that already-normalized\n // rows are never fetched. Idempotent: after the first run no rows match the filter.\n type Row = { rowid: number; source_ref: string };\n const rows = await this.db.getAllAsync<Row>(`\n SELECT rowid, source_ref FROM ${this.prefix}entries\n WHERE source_ref IS NOT NULL\n AND (\n TRIM(source_ref) != source_ref\n OR INSTR(source_ref, '/') > 0\n OR INSTR(source_ref, '\\\\') > 0\n OR INSTR(source_ref, CHAR(0)) > 0\n OR source_ref GLOB '*[^-A-Za-z0-9._ ]*'\n )\n `);\n await this.db.withTransactionAsync(async () => {\n for (const row of rows) {\n const normalized = normalizeSourceRef(row.source_ref);\n if (normalized !== row.source_ref) {\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET source_ref = ? WHERE rowid = ?`,\n [normalized, row.rowid]\n );\n }\n }\n });\n\n await this.rebuildMiniSearchIndex();\n }\n\n async hasChanged(entityId: string, sourceRef: string, sourceHash: string): Promise<boolean> {\n const normalizedRef = normalizeSourceRef(sourceRef);\n if (!normalizedRef) {\n throw new Error(`Invalid sourceRef: \"${sourceRef}\"`);\n }\n const normalizedHash = normalizeSourceHash(sourceHash);\n if (!normalizedHash) {\n throw new Error(`Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)`);\n }\n const row = await this.db.getFirstAsync<{ source_hash: string | null }>(\n `SELECT source_hash FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT 1`,\n [entityId, normalizedRef]\n );\n if (!row) return true;\n const normalizedStoredHash = row.source_hash ? normalizeSourceHash(row.source_hash) : null;\n return normalizedStoredHash !== normalizedHash;\n }\n\n private _pruneKey(entityId: string) { return `${this.prefix}:${entityId}:prune`; }\n private _reembedKey(entityId: string) { return `${this.prefix}:${entityId}:reembed`; }\n private _globalReembedKey() { return `${this.prefix}:reembed`; }\n private _importKey(entityId: string) { return `${this.prefix}:${entityId}:import`; }\n private _globalImportKey() { return `${this.prefix}:import`; }\n private _forgetKey(entityId: string) { return `${this.prefix}:${entityId}:forget`; }\n private _isReembedActive(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId))\n || this.activeMaintenanceJobs.has(this._globalReembedKey());\n }\n private _isImportActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._importKey(entityId))\n || this.activeMaintenanceJobs.has(this._globalImportKey());\n }\n private _isForgetActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._forgetKey(entityId));\n }\n /** Returns true if any maintenance job has the given operation suffix (e.g. ':prune'). */\n private _isAnyMaintenanceActiveWithSuffix(suffix: string): boolean {\n const entityKeyPrefix = `${this.prefix}:`;\n for (const k of this.activeMaintenanceJobs) {\n if (k.startsWith(entityKeyPrefix) && k.endsWith(suffix)) return true;\n }\n return false;\n }\n /** Returns true if any ingest job is active for the given entity. */\n private _isIngestActiveFor(entityId: string): boolean {\n const entityKeyPrefix = `${this.prefix}:${entityId}:`;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(entityKeyPrefix)) return true;\n }\n return false;\n }\n\n private _copyEntityStatus(s: EntityStatus): EntityStatus {\n return { ingesting: s.ingesting, librarian: s.librarian, heal: s.heal };\n }\n\n private _notifyStatusSubscribers(entityId: string): void {\n const set = this.statusSubscribers.get(entityId);\n if (!set || set.size === 0) return;\n // Snapshot for safe iteration if a callback unsubscribes or subscribes.\n // Re-read status each iteration so re-entrant mutations cannot leave stale\n // snapshots for remaining subscribers.\n for (const entry of Array.from(set)) {\n if (!set.has(entry)) continue; // unsubscribed during this emission\n const next = this.getEntityStatus(entityId);\n if (\n entry.last.ingesting === next.ingesting &&\n entry.last.librarian === next.librarian &&\n entry.last.heal === next.heal\n ) continue;\n entry.last = this._copyEntityStatus(next);\n try {\n entry.callback(this._copyEntityStatus(next));\n } catch (err) {\n console.error(`[WikiMemory.subscribeEntityStatus] callback error for entityId=\"${entityId}\" during transition emission`, err);\n }\n }\n }\n\n private _validatePruneDuration(value: number | null | undefined, name: string): void {\n if (value !== null && value !== undefined && (typeof value !== 'number' || !isFinite(value) || value < 0)) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number or null`);\n }\n }\n\n async runPrune(\n entityId: string,\n options?: {\n retainSoftDeletedFor?: number | null;\n retainEventsFor?: number | null;\n vacuum?: boolean;\n }\n ): Promise<{ entries: number; tasks: number; events: number }> {\n const pruneKey = this._pruneKey(entityId);\n // Prune must not run concurrently with librarian, heal, ingest, import, or another\n // prune for the same entity.\n const ingestPrefix = `${this.prefix}:${entityId}:`;\n let isIngestRunning = false;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(ingestPrefix)) { isIngestRunning = true; break; }\n }\n let blockingOperation: 'prune' | 'librarian' | 'heal' | 'ingest' | 'reembed' | 'import' | 'forget' | null = null;\n if (this.activeMaintenanceJobs.has(pruneKey)) {\n blockingOperation = 'prune';\n } else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n blockingOperation = 'librarian';\n } else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n blockingOperation = 'heal';\n } else if (this._isReembedActive(entityId)) {\n blockingOperation = 'reembed';\n } else if (isIngestRunning) {\n blockingOperation = 'ingest';\n } else if (this._isImportActiveFor(entityId)) {\n blockingOperation = 'import';\n } else if (this._isForgetActiveFor(entityId)) {\n blockingOperation = 'forget';\n }\n if (blockingOperation !== null) {\n throw new WikiBusyError(blockingOperation, entityId);\n }\n this.activeMaintenanceJobs.add(pruneKey);\n try {\n const retainSoftDeletedFor = options?.retainSoftDeletedFor !== undefined\n ? options.retainSoftDeletedFor\n : (this.options.config?.pruneRetainSoftDeletedFor ?? 7);\n const retainEventsFor = options?.retainEventsFor !== undefined\n ? options.retainEventsFor\n : (this.options.config?.pruneEventsAfter ?? 30);\n const vacuum = options?.vacuum ?? false;\n\n this._validatePruneDuration(retainSoftDeletedFor, 'retainSoftDeletedFor');\n this._validatePruneDuration(retainEventsFor, 'retainEventsFor');\n\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n let deletedEvents = 0;\n\n if (retainSoftDeletedFor !== null) {\n const cutoff = now - retainSoftDeletedFor * 86400000;\n\n const entriesToDelete = await this.db.getAllAsync<{ id: string; entity_id: string }>(\n `SELECT id, entity_id FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff]\n );\n\n // Hook-before-delete: await hook for each row, accumulate successes, commit partial on failure\n const succeeded: Array<{ entity_id: string; id: string }> = [];\n let failure: { factId: string; cause: unknown } | null = null;\n\n for (const row of entriesToDelete) {\n try {\n await this._notifyEmbeddingPersistedOrThrow(row.entity_id, row.id, null);\n succeeded.push({ entity_id: row.entity_id, id: row.id });\n } catch (err) {\n failure = { factId: row.id, cause: err };\n break;\n }\n }\n\n if (succeeded.length > 0) {\n // Delete in chunks to avoid SQLite bind-parameter limit (typically 999)\n const chunkSize = 500;\n for (let i = 0; i < succeeded.length; i += chunkSize) {\n const chunk = succeeded.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const entryResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ? AND id IN (${placeholders})`,\n [entityId, cutoff, ...chunk.map((r) => r.id)],\n );\n deletedEntries += entryResult.changes;\n }\n }\n\n // Delete tasks (independent of entry hook success/failure)\n const taskResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}tasks\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff]\n );\n deletedTasks = taskResult.changes;\n\n if (failure) {\n // Rebuild index and clear cache to reflect successful partial deletions\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n const remaining = entriesToDelete.length - succeeded.length - 1;\n\n // Preserve timeout errors (thrown by WikiMemory, not the ranker)\n const isTimeout = (failure.cause as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new PrunePartialFailureError(\n succeeded.length,\n failure.factId,\n remaining,\n new Error('Deletion hook timed out'),\n deletedTasks,\n 0, // events not yet deleted at this point\n );\n }\n\n // Preserve WikiMemory validation errors (not from the adapter hook)\n const errMsg = (failure.cause as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n const sanitizedCause = isValidationError\n ? failure.cause as Error\n : this._sanitizeRankerError(failure.cause);\n\n throw new PrunePartialFailureError(\n succeeded.length,\n failure.factId,\n remaining,\n sanitizedCause,\n deletedTasks,\n 0, // events not yet deleted at this point\n );\n }\n }\n\n if (retainEventsFor !== null) {\n const cutoff = now - retainEventsFor * 86400000;\n const eventResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}events\n WHERE entity_id = ? AND created_at <= ?`,\n [entityId, cutoff]\n );\n deletedEvents = eventResult.changes;\n }\n\n if (vacuum) {\n await this.db.execAsync(`PRAGMA wal_checkpoint(TRUNCATE)`);\n await this.db.execAsync(`VACUUM`);\n }\n\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n return { entries: deletedEntries, tasks: deletedTasks, events: deletedEvents };\n } finally {\n this.activeMaintenanceJobs.delete(pruneKey);\n }\n }\n\n async read(entityId: string | string[], query: string, options?: ReadOptions): Promise<MemoryBundle> {\n const config = this.options.config;\n const entityIds = normalizeEntityIds(entityId);\n const sanitizedTierWeights = sanitizeTierWeights(entityIds, options?.tierWeights);\n const exposeMetadata = shouldExposeReadMetadata(entityId);\n\n if (entityIds.length === 0) {\n const empty: MemoryBundle = { facts: [], tasks: [], events: [] };\n if (exposeMetadata) {\n empty.metadata = { query, entityIds: [] };\n if (sanitizedTierWeights && Object.keys(sanitizedTierWeights).length > 0) empty.metadata.tierWeights = sanitizedTierWeights;\n }\n return empty;\n }\n\n const MAX_ENTITY_IDS = 100;\n if (entityIds.length > MAX_ENTITY_IDS) {\n throw new RangeError(`read() accepts at most ${MAX_ENTITY_IDS} entity IDs; received ${entityIds.length}`);\n }\n const nullByteId = entityIds.find(id => id.includes('\\x00'));\n if (nullByteId !== undefined) {\n throw new TypeError(`entity_id values must not contain the null byte (\\\\x00); got \"${nullByteId}\"`);\n }\n\n const rawMaxResults = options?.maxResults ?? config?.maxResults ?? config?.maxFtsResults ?? 10;\n const maxResults = Number.isFinite(rawMaxResults)\n ? Math.max(0, Math.trunc(rawMaxResults))\n : 10;\n const rawPreFilterLimit =\n options?.preFilterLimit === null\n ? undefined\n : (options?.preFilterLimit ?? config?.preFilterLimit);\n const effectivePreFilterLimit =\n rawPreFilterLimit === undefined\n ? undefined\n : Number.isFinite(rawPreFilterLimit)\n ? Math.max(0, Math.trunc(rawPreFilterLimit))\n : undefined;\n const hybridWeight = options?.hybridWeight ?? config?.hybridWeight;\n const weight = hybridWeight !== undefined && !Number.isNaN(hybridWeight)\n ? Math.max(0, Math.min(1, hybridWeight))\n : undefined;\n const skipEmbed = weight === 0;\n const embedFn = this.options.llmProvider.embed;\n const trimmedQuery = query.trim();\n\n let facts: WikiFact[] = [];\n let scoreByFactId: Map<string, number> | undefined;\n\n if (maxResults === 0) {\n // Fast-path: a zero-capacity result window can never return any facts.\n // Skip embed(), DB scan, and sort — fall through to tasks/events fetch below.\n } else if (trimmedQuery) {\n let usedEmbed = false;\n const scoredEntityIds = this._filterScoredEntities(entityIds, sanitizedTierWeights, options?.includeZeroWeightEntities);\n\n // Fast-path: all entities zero-weight — skip embedFn, DB mismatch query, and\n // cosine work entirely. usedEmbed=true suppresses the keyword fallback below.\n if (scoredEntityIds.length === 0) {\n usedEmbed = true;\n } else if (!skipEmbed && embedFn) {\n let rankerShouldRethrow = false;\n let pendingRankerFallbackError: Error | undefined;\n try {\n const queryVec = await embedFn(trimmedQuery);\n\n // Validate that the provider returned a well-formed vector. An empty vector\n // would cause all facts to score 0 (silently bypassing the fallback), and\n // non-finite values (NaN, Infinity) make the sort comparator unstable.\n if (queryVec.length === 0 || !queryVec.every(v => typeof v === 'number' && isFinite(v))) {\n throw new Error(\n 'embed() returned an empty or non-finite vector. Falling back to keyword search.'\n );\n }\n\n // Detect embedding dimension mismatch: if stored dimension differs from the\n // query vector, existing fact embeddings were built with a different model and\n // cosine scoring would silently produce misleading rankings. Fall back to\n // MiniSearch until the caller runs runReembed().\n const storedDimRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n if (storedDimRow) {\n const storedDim = parseInt(storedDimRow.value, 10);\n if (storedDim !== queryVec.length) {\n throw new Error(\n `Embedding dimension mismatch: stored ${storedDim}, query has ${queryVec.length}. ` +\n `Call runReembed() to rebuild embeddings with the new model.`\n );\n }\n }\n\n // Check whether any non-deleted fact for any requested entity has a blob whose\n // dimension differs from the query vector. Uses all entityIds (not just\n // scoredEntityIds) so a caller requesting a namespace always gets fail-safe scoring.\n const mismatchScope = this._entityInClause(entityIds);\n const mismatchedCount = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE ${mismatchScope.clause} AND deleted_at IS NULL\n AND embedding_blob IS NOT NULL\n AND (CAST(length(embedding_blob) AS INTEGER) % 4 = 0)\n AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?`,\n [...mismatchScope.params, queryVec.length]\n );\n if (mismatchedCount && mismatchedCount.cnt > 0) {\n throw new Error(\n `Some facts have embeddings that do not match the current model dimension. ` +\n `Call runReembed() to rebuild all embeddings consistently.`\n );\n }\n\n const useRanker = Boolean(this.options.vectorRanker);\n let candidateRows: ReadCandidateRowMetadata[] | ReadCandidateRowWithEmbeddings[] | null; // null = pre-filter returned 0 results\n // Composite cache keys (multi-entity join strings) are never invalidated by write/reembed paths.\n let populateCache = entityIds.length === 1;\n let miniSearchScores: Map<string, number> | undefined;\n\n if (effectivePreFilterLimit !== undefined) {\n populateCache = false; // partial scan — do not populate cache\n const entityIdSet = new Set(scoredEntityIds);\n const preResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => entityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n if (preResults.length === 0) {\n candidateRows = null; // empty pre-filter\n } else {\n const topKResults = preResults.slice(0, effectivePreFilterLimit);\n if (topKResults.length === 0) {\n // effectivePreFilterLimit is 0 — treat the same as no candidates\n // (avoids constructing an invalid \"WHERE id IN ()\" SQL clause)\n candidateRows = null;\n } else {\n const topKIds = topKResults.map(r => r.id);\n const inClauseChunkSize = 500;\n if (useRanker) {\n const rows: ReadCandidateRowMetadata[] = [];\n for (let i = 0; i < topKIds.length; i += inClauseChunkSize) {\n const idChunk = topKIds.slice(i, i + inClauseChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<ReadCandidateRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n rows.push(...chunkRows);\n }\n candidateRows = rows;\n } else {\n const rows: ReadCandidateRowWithEmbeddings[] = [];\n for (let i = 0; i < topKIds.length; i += inClauseChunkSize) {\n const idChunk = topKIds.slice(i, i + inClauseChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<ReadCandidateRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n rows.push(...chunkRows);\n }\n candidateRows = rows;\n }\n if (weight !== undefined && weight < 1) {\n const maxMsScore = Math.max(1, topKResults[0]?.score ?? 1);\n miniSearchScores = new Map(topKResults.map(r => [r.id, r.score / maxMsScore]));\n }\n }\n }\n } else {\n // Full scan of scored entities\n // If vectorRanker is configured, skip embedding load for now (ranker will provide ranking)\n // Otherwise fetch embeddings for JS cosine ranking\n if (useRanker) {\n const entityScope = this._entityInClause(scoredEntityIds);\n candidateRows = await this.db.getAllAsync<ReadCandidateRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,\n entityScope.params\n );\n } else {\n const entityScope = this._entityInClause(scoredEntityIds);\n candidateRows = await this.db.getAllAsync<ReadCandidateRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,\n entityScope.params\n );\n }\n // Collect MiniSearch scores for hybrid blend if weight is set and <1\n if (weight !== undefined && weight < 1) {\n const entityIdSet = new Set(scoredEntityIds);\n const msResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => entityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n const maxMsScore = Math.max(1, msResults[0]?.score ?? 1);\n miniSearchScores = new Map(msResults.map(r => [r.id, r.score / maxMsScore]));\n }\n }\n\n if (candidateRows === null) {\n // pre-filter returned 0 candidates — facts = [], skip phase 2, skip access tracking\n usedEmbed = true;\n } else {\n // Rank candidates: use vectorRanker if present, otherwise use JS cosine\n const entityCacheKey = entityIds.length === 1 ? entityIds[0] : entityIds.join('\\x00');\n let scored: Array<{ id: string; entity_id: string; score: number; updated_at?: number | null; access_count?: number | null }>;\n\n if (useRanker) {\n // Build per-entity candidate maps so each ranker call receives one entityId.\n const candidateRowsByEntity = new Map<string, ReadCandidateRowMetadata[]>();\n for (const row of candidateRows as ReadCandidateRowMetadata[]) {\n const rows = candidateRowsByEntity.get(row.entity_id) ?? [];\n rows.push(row);\n candidateRowsByEntity.set(row.entity_id, rows);\n }\n\n try {\n const rankerResultsByEntity = await Promise.all(\n scoredEntityIds.filter(id => (candidateRowsByEntity.get(id)?.length ?? 0) > 0).map(async scopedEntityId => {\n const rowsForEntity = candidateRowsByEntity.get(scopedEntityId) ?? [];\n const candidateIds = effectivePreFilterLimit !== undefined\n ? rowsForEntity.map(row => row.id)\n : undefined;\n const ranked = await this._rankWithVectorRanker({\n entityId: scopedEntityId,\n queryVec,\n candidateIds,\n candidateRows: rowsForEntity,\n weight,\n miniSearchScores,\n limit: Math.max(maxResults * 2, maxResults + 50),\n });\n return ranked.map(row => ({ ...row, entity_id: scopedEntityId }));\n }),\n );\n\n scored = rankerResultsByEntity.flat();\n\n // Build metadata map only for IDs returned by the ranker (not all candidates)\n // to keep memory proportional to the oversampled result size on constrained runtimes.\n const scoredIds = new Set(scored.map(s => s.id));\n const metadataById = new Map(\n (candidateRows as ReadCandidateRowMetadata[])\n .filter(row => scoredIds.has(row.id))\n .map(row => [row.id, row])\n );\n scored = scored.map(row => {\n const metadata = metadataById.get(row.id);\n return {\n ...row,\n updated_at: metadata?.updated_at ?? null,\n access_count: metadata?.access_count ?? null,\n };\n });\n\n // Backfill ranker-omitted rows per VectorRanker contract:\n // treat missing ids as \"no embedding\" (pure semantic: -2, hybrid: keyword-only)\n\n // Compute backfill budget up-front.\n // Hybrid mode: allow up to maxResults keyword-only rows to compete.\n // Pure semantic: only fill the remaining result slots.\n const isHybrid = weight !== undefined && weight < 1;\n const maxBackfill = isHybrid\n ? maxResults\n : Math.max(0, maxResults - scored.length);\n\n if (maxBackfill > 0) {\n if (isHybrid) {\n // Hybrid mode: prioritize by keyword score using O(N log K) top-K selection\n // instead of O(N log N) full sort, since K (maxBackfill) is typically << N.\n type CandidateRow = typeof candidateRows[number];\n const topK: Array<{ row: CandidateRow; kwScore: number }> = [];\n\n for (const row of candidateRows) {\n if (scoredIds.has(row.id)) continue;\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n const candidate = { row, kwScore };\n\n if (topK.length < maxBackfill) {\n // Array not full yet - insert in sorted position (descending order)\n let insertIdx = topK.length;\n for (let i = 0; i < topK.length; i++) {\n const cmp = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[i].row.id,\n score: topK[i].kwScore,\n updated_at: topK[i].row.updated_at,\n access_count: topK[i].row.access_count,\n }\n );\n if (cmp < 0) {\n insertIdx = i;\n break;\n }\n }\n topK.splice(insertIdx, 0, candidate);\n } else {\n const cmpWorst = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[maxBackfill - 1].row.id,\n score: topK[maxBackfill - 1].kwScore,\n updated_at: topK[maxBackfill - 1].row.updated_at,\n access_count: topK[maxBackfill - 1].row.access_count,\n }\n );\n if (cmpWorst < 0) {\n // Found better candidate than current worst - replace worst and re-insert\n let insertIdx = maxBackfill - 1;\n for (let i = 0; i < topK.length; i++) {\n const cmp = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[i].row.id,\n score: topK[i].kwScore,\n updated_at: topK[i].row.updated_at,\n access_count: topK[i].row.access_count,\n }\n );\n if (cmp < 0) {\n insertIdx = i;\n break;\n }\n }\n topK.splice(insertIdx, 0, candidate);\n topK.pop(); // Remove worst element\n }\n }\n }\n\n for (const { row, kwScore } of topK) {\n scored.push({\n id: row.id,\n entity_id: row.entity_id,\n score: (1 - weight) * kwScore,\n updated_at: row.updated_at,\n access_count: row.access_count,\n });\n }\n } else {\n // Pure semantic: all omitted rows share score -2.\n // Tie-break omitted rows deterministically before truncating.\n const omitted: Array<{ id: string; entity_id: string; score: number; updated_at: number | null; access_count: number | null }> = [];\n for (const row of candidateRows) {\n if (scoredIds.has(row.id)) continue;\n omitted.push({ id: row.id, entity_id: row.entity_id, score: -2, updated_at: row.updated_at, access_count: row.access_count });\n }\n if (omitted.length > 0) {\n this._tieBreakSort(omitted);\n scored.push(...omitted.slice(0, maxBackfill));\n }\n }\n }\n } catch (rankerErr) {\n const rankerError = rankerErr instanceof Error ? rankerErr : new Error(String(rankerErr));\n const policy = this.options.vectorRankerFallback ?? 'js-cosine';\n\n this.options.onVectorRankerFallback?.({\n error: this._sanitizeRankerError(rankerError),\n policy,\n });\n\n if (policy === 'throw') {\n rankerShouldRethrow = true;\n throw rankerError;\n } else if (policy === 'js-cosine') {\n // If embeddings were skipped (vectorRanker was configured), fetch them now for fallback\n let fallbackRows = candidateRows;\n if (fallbackRows && fallbackRows.length > 0 && !('embedding_blob' in fallbackRows[0])) {\n const rowIds = fallbackRows.map(r => r.id);\n const embeddingsMap = new Map<string, { embedding_blob: Uint8Array | null; embedding: string | null }>();\n const chunkSize = 500;\n for (let i = 0; i < rowIds.length; i += chunkSize) {\n const idChunk = rowIds.slice(i, i + chunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const embeddingRows = await this.db.getAllAsync<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>(\n `SELECT id, embedding_blob, embedding FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n for (const row of embeddingRows) {\n embeddingsMap.set(row.id, { embedding_blob: row.embedding_blob, embedding: row.embedding });\n }\n }\n fallbackRows = fallbackRows.map(r => ({\n ...r,\n embedding_blob: embeddingsMap.get(r.id)?.embedding_blob ?? null,\n embedding: embeddingsMap.get(r.id)?.embedding ?? null,\n })) as ReadCandidateRowWithEmbeddings[];\n }\n scored = await this._rankWithJsCosine({\n entityId: entityCacheKey,\n queryVec,\n candidateRows: fallbackRows as ReadCandidateRowWithEmbeddings[],\n weight,\n miniSearchScores,\n populateCache,\n limit: fallbackRows.length,\n skipSort: true, // read() re-sorts after applying tier weights\n });\n } else if (policy === 'keyword') {\n // Fall back to keyword-only results from MiniSearch\n const scoredEntityIdSet = new Set(scoredEntityIds);\n const msResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => scoredEntityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n // Oversample so tier weights can re-rank before the global slice\n const keywordOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const topResults = msResults.slice(0, keywordOversampledLimit);\n const topResultIds = new Set(topResults.map(r => r.id));\n const candidateMap = new Map(candidateRows.filter(r => topResultIds.has(r.id)).map(row => [row.id, row]));\n scored = topResults.map(result => {\n const metadata = candidateMap.get(result.id);\n const entityForScore = metadata?.entity_id\n ?? (result as unknown as { entity_id: string }).entity_id\n ?? '';\n return {\n id: result.id,\n entity_id: entityForScore,\n score: result.score ?? 0,\n access_count: metadata?.access_count ?? null,\n updated_at: metadata?.updated_at ?? null,\n };\n });\n } else {\n // policy === 'empty'\n scored = [];\n }\n\n if (this.options.propagateRankerFailureToRetrievalFallback) {\n const mirrored = new Error('Vector ranker failed, falling back', {\n cause: this._sanitizeRankerError(rankerErr),\n });\n pendingRankerFallbackError = mirrored;\n }\n }\n } else {\n // Use in-process JS cosine similarity\n // At this point candidateRows must have embeddings (we fetched them because vectorRanker is not configured)\n // Materialize all candidates only when tier weights will actually change ranking —\n // i.e., at least one entity has a weight other than 1. A no-op weights object\n // (all values === 1, or empty after sanitization) preserves the hot-path behavior.\n const jsCosineNeedsTierSort = sanitizedTierWeights !== undefined &&\n Object.values(sanitizedTierWeights).some(w => w !== 1);\n scored = await this._rankWithJsCosine({\n entityId: entityCacheKey,\n queryVec,\n candidateRows: candidateRows as ReadCandidateRowWithEmbeddings[],\n weight,\n miniSearchScores,\n populateCache,\n limit: jsCosineNeedsTierSort ? candidateRows.length : maxResults,\n skipSort: jsCosineNeedsTierSort, // read() re-sorts after applying tier weights\n });\n }\n\n if (scored.length > 0) {\n // Apply tier weights before global sort and slice\n scored = scored.map(row => ({\n ...row,\n score: applyTierWeight(row.score, row.entity_id, sanitizedTierWeights),\n }));\n\n // Re-apply tie-break sorting after tier-weight application (applies to all paths including\n // vectorRankerFallback='keyword': applyTierWeight mutates scores so MiniSearch ordering is no longer valid)\n this._tieBreakSort(scored);\n\n // Phase 2: fetch full rows only for the top results\n const selectedScored = scored.slice(0, maxResults);\n const topIds = selectedScored.map(s => s.id);\n\n // Capture scores for exposure in metadata\n if (exposeMetadata && trimmedQuery) {\n scoreByFactId = new Map(selectedScored.map(s => [s.id, Number.isFinite(s.score) ? s.score : 0]));\n }\n\n if (topIds.length > 0) {\n const facts2 = await this._hydrateFactsByIds(topIds, entityIds);\n\n // Hydration can return fewer rows than ranked IDs when rows were concurrently\n // soft-deleted or filtered by deleted_at before phase 2 hydration completes.\n if (facts2.length < topIds.length) {\n const hydrationById = new Set(facts2.map(f => f.id));\n const missingIds = topIds.filter(id => !hydrationById.has(id));\n const missingCount = missingIds.length;\n const sample = missingIds.slice(0, 5);\n const sampleSuffix = sample.length > 0\n ? ` Missing ID sample: ${sample.join(', ')}${missingIds.length > sample.length ? ', ...' : ''}.`\n : '';\n const error = new Error(\n `Phase 2 fact hydration returned ${missingCount} fewer row(s) than ranked IDs. ` +\n `Rows may have been concurrently soft-deleted or filtered by deleted_at during hydration, ` +\n `or vector ranker output may include IDs that do not exist in requested entities.` +\n sampleSuffix\n );\n this.options.onRetrievalFallback?.(error);\n }\n facts = facts2;\n }\n // Ranker path completed — notify of any prior fallback now that hydration is done.\n // Fires outside the topIds.length>0 guard since scored.length>0 && maxResults>0\n // means topIds is always non-empty here, but the notification is harmless either way.\n if (pendingRankerFallbackError) {\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n pendingRankerFallbackError = undefined;\n }\n usedEmbed = true;\n } else {\n // Empty scored results (ranker returned no matches)\n if (pendingRankerFallbackError) {\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n pendingRankerFallbackError = undefined;\n }\n usedEmbed = true;\n }\n } // closes the candidateRows !== null else block\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (rankerShouldRethrow) {\n throw error;\n }\n // If Phase 2 failed and there's a pending ranker error, include it as cause\n if (pendingRankerFallbackError) {\n (error as any).cause = pendingRankerFallbackError;\n pendingRankerFallbackError = undefined;\n }\n // Always notify of Phase 2 errors (ranker error attached as cause if present)\n this.options.onRetrievalFallback?.(error);\n }\n }\n\n if (!usedEmbed && scoredEntityIds.length > 0) {\n // embed absent or threw — fall back to MiniSearch with tier weight application\n const fallbackEntityIdSet = new Set(scoredEntityIds);\n const fallbackOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const results = this.miniSearch.search(trimmedQuery, {\n filter: (r) => fallbackEntityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n const candidates = results.slice(0, fallbackOversampledLimit).map(r => ({\n id: r.id as string,\n entity_id: (r as unknown as { entity_id: string }).entity_id,\n score: applyTierWeight(r.score ?? 0, (r as unknown as { entity_id: string }).entity_id, sanitizedTierWeights),\n updated_at: null as number | null,\n access_count: null as number | null,\n }));\n this._tieBreakSort(candidates);\n const topCandidates = candidates.slice(0, maxResults);\n const topIds = topCandidates.map(c => c.id);\n if (topIds.length > 0) {\n facts = await this._hydrateFactsByIds(topIds, entityIds);\n if (exposeMetadata) {\n scoreByFactId = new Map(topCandidates.map(c => [c.id, Number.isFinite(c.score) ? c.score : 0]));\n }\n }\n }\n\n if (facts.length > 0) {\n const ids = facts.map(f => f.id);\n const now = Date.now();\n const accessChunkSize = 500;\n for (let i = 0; i < ids.length; i += accessChunkSize) {\n const idChunk = ids.slice(i, i + accessChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries\n SET access_count = access_count + 1, last_accessed_at = ?\n WHERE id IN (${placeholders})`,\n [now, ...idChunk]\n );\n }\n }\n } else {\n // Empty query: use global recency ordering, ignore tier weights.\n // Raw SELECT * — normalize here since _hydrateFactsByIds is not used.\n const entityScope = this._entityInClause(entityIds);\n const rawFacts = await this.db.getAllAsync<WikiFact & { embedding?: unknown; embedding_blob?: unknown }>(\n `SELECT * FROM ${this.prefix}entries\n WHERE ${entityScope.clause} AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT ?`,\n [...entityScope.params, maxResults]\n );\n facts = rawFacts.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f;\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n } as WikiFact;\n });\n }\n\n const [tasks, events] = await Promise.all([\n (async () => {\n const entityScope = this._entityInClause(entityIds);\n // Single-entity reads preserve the pre-Phase-2 unbounded behavior.\n // Multi-entity reads cap at 20× entity count (max 200) to bound result size.\n const tasksLimit = entityIds.length === 1 ? undefined : Math.min(20 * entityIds.length, 200);\n return this.db.getAllAsync<WikiTask>(\n `SELECT * FROM ${this.prefix}tasks\n WHERE ${entityScope.clause} AND status IN ('pending', 'in_progress') AND deleted_at IS NULL\n ORDER BY priority DESC, created_at ASC${tasksLimit !== undefined ? '\\n LIMIT ?' : ''}`,\n tasksLimit !== undefined ? [...entityScope.params, tasksLimit] : entityScope.params\n );\n })(),\n (async () => {\n const entityScope = this._entityInClause(entityIds);\n // Scaled global cap: 10× entity count, max 100. Not a per-entity guarantee —\n // a single high-volume entity can fill the entire budget.\n const eventsLimit = Math.min(10 * entityIds.length, 100);\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events\n WHERE ${entityScope.clause}\n ORDER BY created_at DESC\n LIMIT ?`,\n [...entityScope.params, eventsLimit]\n );\n })(),\n ]);\n\n // Build factScores from captured scores\n let factScores: Record<string, number> | undefined;\n if (exposeMetadata && trimmedQuery && scoreByFactId) {\n factScores = Object.fromEntries(facts.map(fact => [fact.id, scoreByFactId!.get(fact.id) ?? 0]));\n }\n\n const bundle: MemoryBundle = { facts, tasks, events: events.reverse() };\n\n if (exposeMetadata) {\n bundle.metadata = { query, entityIds };\n if (sanitizedTierWeights && Object.keys(sanitizedTierWeights).length > 0) bundle.metadata.tierWeights = sanitizedTierWeights;\n if (factScores && Object.keys(factScores).length > 0) bundle.factScores = factScores;\n }\n\n return bundle;\n }\n\n /**\n * Returns entity IDs that will participate in scored retrieval.\n * Excludes zero-weight entities unless includeZeroWeightEntities is true.\n */\n private _filterScoredEntities(\n entityIds: readonly string[],\n sanitizedTierWeights: Record<string, number> | undefined,\n includeZeroWeightEntities?: boolean,\n ): string[] {\n return entityIds.filter(id => {\n const w = sanitizedTierWeights?.[id] ?? 1;\n return includeZeroWeightEntities === true || w !== 0;\n });\n }\n\n /**\n * Stable tie-break sort: score desc → access_count desc → updated_at desc → id asc.\n */\n private _tieBreakSort<T extends { id: string; score: number; updated_at?: number | null; access_count?: number | null }>(items: T[]): void {\n items.sort((a, b) => this._compareScoredRows(a, b));\n }\n\n /**\n * Comparator for score + deterministic tie-break fields.\n * Negative return means \"a ranks ahead of b\" for descending score order.\n */\n private _compareScoredRows(\n a: { id: string; score: number; updated_at?: number | null; access_count?: number | null },\n b: { id: string; score: number; updated_at?: number | null; access_count?: number | null },\n ): number {\n const scoreDiff = b.score - a.score;\n // isNaN guard: -Infinity - (-Infinity) = NaN; fall through to tie-break\n if (!Number.isNaN(scoreDiff) && scoreDiff !== 0) return scoreDiff;\n const accessCountDiff = (b.access_count ?? 0) - (a.access_count ?? 0);\n if (accessCountDiff !== 0) return accessCountDiff;\n const updatedAtDiff = (b.updated_at ?? 0) - (a.updated_at ?? 0);\n if (updatedAtDiff !== 0) return updatedAtDiff;\n return a.id.localeCompare(b.id);\n }\n\n /**\n * Build SQL IN clause with placeholders for multiple entity IDs.\n */\n private _entityInClause(entityIds: readonly string[]): { clause: string; params: string[] } {\n if (entityIds.length === 0) return { clause: '1=0', params: [] };\n const placeholders = entityIds.map(() => '?').join(',');\n return { clause: `entity_id IN (${placeholders})`, params: [...entityIds] };\n }\n\n /**\n * Hydrate full facts by ID. Pass scopedEntityIds to restrict to requested namespaces in SQL\n * (defense-in-depth against a rogue VectorRanker returning cross-entity IDs).\n */\n private async _hydrateFactsByIds(ids: readonly string[], scopedEntityIds?: readonly string[]): Promise<WikiFact[]> {\n const fullRows: Array<WikiFact & { embedding?: unknown; embedding_blob?: unknown }> = [];\n const chunkSize = 500;\n const entityClause = scopedEntityIds && scopedEntityIds.length > 0\n ? ` AND entity_id IN (${scopedEntityIds.map(() => '?').join(',')})`\n : '';\n const entityParams = scopedEntityIds && scopedEntityIds.length > 0 ? [...scopedEntityIds] : [];\n\n for (let i = 0; i < ids.length; i += chunkSize) {\n const idChunk = ids.slice(i, i + chunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<WikiFact & { embedding?: unknown; embedding_blob?: unknown }>(\n `SELECT * FROM ${this.prefix}entries WHERE id IN (${placeholders})${entityClause} AND deleted_at IS NULL`,\n [...idChunk, ...entityParams],\n );\n fullRows.push(...chunkRows);\n }\n\n const byId = new Map(fullRows.map(row => [row.id, row]));\n return ids\n .map(id => byId.get(id))\n .filter((fact): fact is WikiFact & { embedding?: unknown; embedding_blob?: unknown } => fact !== undefined)\n .map(fact => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = fact;\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n };\n });\n }\n\n /**\n * Strip potentially sensitive data from ranker errors before exposing to host callbacks.\n * Preserves error type for debugging but removes message/stack that may contain credentials.\n * Recursively sanitizes one level of .cause; deeper chains collapse to type only.\n */\n private _sanitizeRankerError(err: unknown): Error {\n if (this.options.sanitizeRankerErrors === false) {\n return err instanceof Error ? err : new Error(String(err));\n }\n\n const typeName =\n err instanceof Error\n ? (err.constructor?.name ?? 'Error')\n : typeof err;\n\n const innerCause =\n err instanceof Error && err.cause !== undefined\n ? new Error(`Caused by: ${(err.cause as Error)?.constructor?.name ?? typeof err.cause}`)\n : undefined;\n\n const sanitized = new Error(\n `VectorRanker ${typeName} (message scrubbed for security)`,\n innerCause ? { cause: innerCause } : undefined,\n );\n sanitized.name = typeName;\n return sanitized;\n }\n\n /**\n * Score candidate rows using in-process JS cosine similarity.\n * Applies hybrid blending (if weight set) and tie-break sorting before returning.\n */\n private async _rankWithJsCosine(args: {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateRows: Array<{ id: string; entity_id: string; embedding_blob: Uint8Array | null; embedding: string | null; updated_at: number | null; access_count: number | null }>;\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n populateCache: boolean;\n limit: number;\n skipSort?: boolean;\n }): Promise<Array<{ id: string; entity_id: string; score: number; updated_at: number | null; access_count: number | null }>> {\n const queryVec = args.queryVec instanceof Float32Array\n ? args.queryVec.slice()\n : Array.from(args.queryVec);\n const { entityId, candidateRows, weight, miniSearchScores, populateCache, limit, skipSort } = args;\n\n // Cache: reuse parsed vectors from prior full-scan reads\n let entityCache = this.vectorCache.get(entityId);\n const tooLarge = populateCache && candidateRows.length > WikiMemory.MAX_VECTOR_CACHE_FACTS_PER_ENTITY;\n if (tooLarge && entityCache) {\n this.vectorCache.delete(entityId);\n entityCache = undefined;\n }\n const canCache = populateCache && !tooLarge;\n if (canCache && !entityCache) {\n entityCache = new Map<string, Float32Array>();\n }\n\n const scored = candidateRows.map(row => {\n let vector = entityCache?.get(row.id) ?? parseEmbedding(row.embedding_blob, row.embedding);\n if (vector && canCache && entityCache && !entityCache.has(row.id)) {\n entityCache.set(row.id, vector);\n }\n let score = 0;\n if (vector && vector.length === queryVec.length) {\n const cosSim = cosineSimilarity(queryVec, vector);\n if (weight !== undefined) {\n // Clamp to [0,1] only for hybrid blending so the weighted sum stays\n // in a predictable range. Pure-semantic ranking preserves the full\n // [-1,1] cosine range so the least-dissimilar facts always rank above\n // unembedded rows (which score 0) even when all scores are negative.\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = weight * Math.max(0, cosSim) + (1 - weight) * kwScore;\n } else {\n score = cosSim;\n }\n } else if (weight !== undefined && weight < 1) {\n // No usable embedding — still apply the keyword portion of the hybrid score.\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = (1 - weight) * kwScore;\n } else {\n // Pure-semantic path with no usable vector. Use -2 (below the minimum\n // valid cosine of -1) so embedded facts always rank above unembedded rows\n // even when every cosine score is negative.\n score = -2;\n }\n return {\n id: row.id,\n entity_id: row.entity_id,\n score,\n updated_at: row.updated_at,\n access_count: row.access_count,\n };\n });\n\n if (canCache && entityCache && entityCache.size > 0) {\n if (!this.vectorCache.has(entityId)) {\n // Evict the oldest entity when at the per-process cap to prevent unbounded growth\n // on long-lived instances serving many distinct entities.\n if (this.vectorCache.size >= WikiMemory.MAX_VECTOR_CACHE_ENTITIES) {\n const oldestKey = this.vectorCache.keys().next().value as string | undefined;\n if (oldestKey !== undefined) this.vectorCache.delete(oldestKey);\n }\n this.vectorCache.set(entityId, entityCache);\n }\n }\n\n // Apply tie-break sorting unless caller will re-sort after applying tier weights.\n if (!skipSort) this._tieBreakSort(scored);\n\n return scored.slice(0, limit);\n }\n\n /**\n * Delegate semantic ranking to the injected VectorRanker.\n * Caller should pass an oversampledLimit to preserve recall after re-ranking.\n * Returns scored results ready for hybrid blending and tie-break sorting.\n */\n private async _rankWithVectorRanker(args: {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateIds: readonly string[] | undefined;\n candidateRows: ReadCandidateRowMetadata[];\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n limit: number;\n }): Promise<Array<{ id: string; entity_id: string; score: number }>> {\n const { entityId, candidateIds, candidateRows, weight, miniSearchScores, limit } = args;\n\n const ranker = this.options.vectorRanker;\n if (!ranker) {\n throw new Error('vectorRanker not configured');\n }\n\n const queryVecCopy = args.queryVec instanceof Float32Array\n ? args.queryVec.slice()\n : Array.from(args.queryVec);\n\n const rankerResults = await ranker.rankBySimilarity({\n entityId,\n queryVec: queryVecCopy,\n candidateIds,\n limit,\n });\n\n // Normalize ranker output: filter to allowed ids, drop non-finite scores, deduplicate\n // Stop collecting once limit valid results are found to protect against huge result sets\n const allowedIds = new Set(candidateRows.map(row => row.id));\n const seen = new Set<string>();\n const normalized: typeof rankerResults = [];\n\n for (const r of rankerResults) {\n if (normalized.length >= limit) break; // Early termination once limit reached\n if (seen.has(r.id)) continue;\n if (allowedIds && !allowedIds.has(r.id)) continue;\n if (!Number.isFinite(r.semanticScore)) continue;\n seen.add(r.id);\n normalized.push(r);\n }\n\n const entityIdByCandidateId = new Map(candidateRows.map(row => [row.id, row.entity_id]));\n\n // Convert ranker results to scored format, applying hybrid blending if weight is set\n const scored = normalized.map(r => {\n let score = r.semanticScore;\n if (weight !== undefined) {\n // Hybrid blending: floor semantic score at 0 for predictable weighted sum (no upper clamp)\n const kwScore = miniSearchScores?.get(r.id) ?? 0;\n score = weight * Math.max(0, r.semanticScore) + (1 - weight) * kwScore;\n }\n return {\n id: r.id,\n entity_id: entityIdByCandidateId.get(r.id)!, // allowedIds filter above guarantees membership\n score,\n };\n });\n\n // Caller handles backfill, metadata attachment, tie-break sorting, and final slice\n return scored;\n }\n\n async getMemoryBundle(entityId: string): Promise<MemoryBundle> {\n return this._getFullBundle(entityId, { maxEvents: 10 });\n }\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n const id = generateId('evt_');\n const now = Date.now();\n \n let eventType = event.event_type;\n if (!['observation', 'decision', 'action', 'outcome'].includes(eventType)) {\n eventType = 'observation';\n }\n\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `, [id, entityId, eventType, event.summary, event.related_entry_id || null, now]);\n\n const threshold = this.options.config?.autoLibrarianThreshold || 20;\n \n const [row, cp] = await Promise.all([\n this.db.getFirstAsync<{ count: number }>(`SELECT COUNT(*) as count FROM ${this.prefix}events WHERE entity_id = ?`, [entityId]),\n this.db.getFirstAsync<WikiCheckpoint>(`SELECT * FROM ${this.prefix}checkpoints WHERE entity_id = ?`, [entityId])\n ]);\n \n const count = row?.count || 0;\n let memoryCheckpoint = cp?.memory_checkpoint || 0;\n if (memoryCheckpoint > count) memoryCheckpoint = 0;\n\n if (count - memoryCheckpoint >= threshold) {\n const jobKey = this._librarianKey(entityId);\n if (\n !this.activeMaintenanceJobs.has(jobKey) &&\n !this.activeMaintenanceJobs.has(this._pruneKey(entityId)) &&\n !this._isReembedActive(entityId) &&\n !this._isImportActiveFor(entityId) &&\n !this._isForgetActiveFor(entityId)\n ) {\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n this.runLibrarianThenMaybeHeal(entityId, count)\n .catch(console.error)\n .finally(() => {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n });\n }\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number) {\n await this._doRunLibrarian(entityId);\n \n await this.db.runAsync(`\n INSERT INTO ${this.prefix}checkpoints (entity_id, memory_checkpoint) \n VALUES (?, ?) \n ON CONFLICT(entity_id) DO UPDATE SET memory_checkpoint = ?\n `, [entityId, currentEventCount, currentEventCount]);\n \n const autoHealThreshold = this.options.config?.autoHealThreshold || 100;\n const cp = await this.db.getFirstAsync<WikiCheckpoint>(`SELECT * FROM ${this.prefix}checkpoints WHERE entity_id = ?`, [entityId]);\n let healCheckpoint = cp?.heal_checkpoint || 0;\n if (healCheckpoint > currentEventCount) healCheckpoint = 0;\n \n if (currentEventCount - healCheckpoint >= autoHealThreshold) {\n const healKey = this._healKey(entityId);\n if (!this.activeMaintenanceJobs.has(healKey)) {\n this.activeMaintenanceJobs.add(healKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunHeal(entityId);\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}checkpoints (entity_id, heal_checkpoint) \n VALUES (?, ?) \n ON CONFLICT(entity_id) DO UPDATE SET heal_checkpoint = ?\n `, [entityId, currentEventCount, currentEventCount]);\n } finally {\n this.activeMaintenanceJobs.delete(healKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n }\n }\n\n private async _doRunLibrarian(entityId: string): Promise<void> {\n const events = await this.db.getAllAsync<WikiEvent>(`\n SELECT * FROM ${this.prefix}events\n WHERE entity_id = ?\n ORDER BY created_at DESC\n LIMIT 50\n `, [entityId]);\n\n const currentFactsRows = await this.db.getAllAsync<WikiFact>(`\n SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT 100\n `, [entityId]);\n\n const currentFacts = currentFactsRows.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f as WikiFact & { embedding?: unknown; embedding_blob?: unknown };\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n };\n });\n\n const userPrompt = `Events:\\n${JSON.stringify(events.reverse(), null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`;\n \n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: LIBRARIAN_SYSTEM_PROMPT,\n userPrompt,\n });\n\n const result = parseJsonResponse<{ facts: ExtractedFact[], tasks: ExtractedTask[] }>(responseText);\n const facts = Array.isArray(result.facts) ? result.facts : [];\n const tasks = Array.isArray(result.tasks) ? result.tasks : [];\n const validFacts = facts.map(validateFact).filter((f): f is ExtractedFact => f !== null);\n const validTasks = tasks.map(validateTask).filter((t): t is ExtractedTask => t !== null);\n\n const now = Date.now();\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n\n await this.db.withTransactionAsync(async () => {\n for (const fact of validFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of currentFactsRows) {\n if (existing.source_type !== 'librarian_inferred') continue;\n const existingTokens = titleTokens(existing.title);\n if (existingTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n if (jaccardScore(newTokens, existingTokens) >= FUZZY_THRESHOLD) {\n skip = true;\n break;\n }\n }\n }\n }\n if (skip) continue;\n\n const id = generateId('fact_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'librarian_inferred', now, now]);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n\n for (const task of validTasks) {\n const id = generateId('task_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}tasks (id, entity_id, description, status, priority, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, task.description, 'pending', task.priority, now, now]);\n }\n });\n\n // Rebuild the text index before the (potentially slow) embedding loop so\n // concurrent reads using MiniSearch (preFilter, keyword fallback) see the\n // new fact content immediately after the DB transaction commits.\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Second vector cache flush: a concurrent read() may have repopulated it\n // during the embed loop; flush so subsequent reads see the new BLOBs.\n this.vectorCache.delete(entityId);\n }\n\n private async _doRunHeal(entityId: string): Promise<void> {\n const now = Date.now();\n const orphanAfterDays = this.options.config?.orphanAfterDays !== undefined ? this.options.config.orphanAfterDays : 30;\n const staleInferredAfterDays = this.options.config?.staleInferredAfterDays !== undefined ? this.options.config.staleInferredAfterDays : 60;\n const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n if (orphanAfterDays !== null && (typeof orphanAfterDays !== 'number' || !Number.isFinite(orphanAfterDays) || orphanAfterDays < 0)) {\n throw new Error('Invalid orphanAfterDays: must be a finite number >= 0 or null');\n }\n if (staleInferredAfterDays !== null && (typeof staleInferredAfterDays !== 'number' || !Number.isFinite(staleInferredAfterDays) || staleInferredAfterDays < 0)) {\n throw new Error('Invalid staleInferredAfterDays: must be a finite number >= 0 or null');\n }\n\n await this.db.withTransactionAsync(async () => {\n if (orphanAfterDays !== null) {\n const orphanThreshold = now - (orphanAfterDays * MS_PER_DAY);\n await this.db.runAsync(`\n UPDATE ${this.prefix}entries\n SET deleted_at = ?, updated_at = ?\n WHERE entity_id = ? AND access_count = 0 AND created_at <= ? AND source_type != 'immutable_document' AND deleted_at IS NULL\n `, [now, now, entityId, orphanThreshold]);\n }\n\n if (staleInferredAfterDays !== null) {\n const staleThreshold = now - (staleInferredAfterDays * MS_PER_DAY);\n await this.db.runAsync(`\n UPDATE ${this.prefix}entries\n SET confidence = 'tentative', updated_at = ?\n WHERE entity_id = ? AND confidence = 'inferred' AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?)) AND source_type != 'immutable_document' AND deleted_at IS NULL\n `, [now, entityId, staleThreshold, staleThreshold]);\n }\n });\n\n const allFactsRows = await this.db.getAllAsync<WikiFact>(`SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`, [entityId]);\n const allTasks = await this.db.getAllAsync<WikiTask>(`SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND status IN ('pending', 'in_progress') AND deleted_at IS NULL`, [entityId]);\n const recentEvents = await this.db.getAllAsync<WikiEvent>(`SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT 20`, [entityId]);\n\n const healCandidates = allFactsRows.filter(f => f.source_type !== 'immutable_document');\n const documentAnchors = allFactsRows\n .filter(f => f.source_type === 'immutable_document')\n .map(({ id, title, source_ref }) => ({ id, title, source_ref }));\n\n const userPrompt = `Heal Candidates:\\n${JSON.stringify(healCandidates.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f as WikiFact & { embedding?: unknown; embedding_blob?: unknown };\n return { ...rest, tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags };\n }), null, 2)}\n\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(documentAnchors, null, 2)}\n\\nAll Tasks:\\n${JSON.stringify(allTasks, null, 2)}\n\\nRecent Events:\\n${JSON.stringify(recentEvents, null, 2)}\n\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`;\n \n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: HEAL_SYSTEM_PROMPT,\n userPrompt,\n });\n\n const result = parseJsonResponse<{ downgraded: string[], deleted: string[], newFacts: ExtractedFact[] }>(responseText);\n\n const mutableIds = new Set(healCandidates.map(f => f.id));\n const downgraded = Array.isArray(result.downgraded) ? result.downgraded : [];\n const deleted = Array.isArray(result.deleted) ? result.deleted : [];\n const newFacts = Array.isArray(result.newFacts) ? result.newFacts : [];\n const safeDowngraded = downgraded.filter(id => mutableIds.has(id));\n const safeDeleted = deleted.filter(id => mutableIds.has(id));\n const validNewFacts = newFacts.map(validateFact).filter((f): f is ExtractedFact => f !== null);\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const uniqueDeletedFactIds = Array.from(new Set(safeDeleted));\n\n await this.db.withTransactionAsync(async () => {\n for (const id of safeDowngraded) {\n await this.db.runAsync(`UPDATE ${this.prefix}entries SET confidence = 'tentative', updated_at = ? WHERE id = ? AND entity_id = ?`, [now, id, entityId]);\n }\n for (const id of safeDeleted) {\n await this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ?`, [now, now, id, entityId]);\n }\n for (const fact of validNewFacts) {\n const id = generateId('fact_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'librarian_inferred', now, now]);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n });\n\n // Pre-flush: evict stale cached vectors before writing new embeddings so a\n // concurrent read() during the embed loop doesn't rank deleted/downgraded\n // facts from the cache. Post-flush below handles vectors repopulated during\n // the loop.\n this.vectorCache.delete(entityId);\n // Rebuild MiniSearch before the embedding loop so concurrent reads using\n // preFilterLimit, hybrid scoring, or keyword fallback see the new/deleted\n // facts immediately rather than waiting for every embed call to finish.\n await this.rebuildMiniSearchIndex(entityId);\n for (const factId of uniqueDeletedFactIds) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal for ${factId}:`, hookErr);\n }\n }\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Post-flush: evict any cache entries a concurrent read() repopulated while\n // the embedding loop was running.\n this.vectorCache.delete(entityId);\n }\n\n async runLibrarian(entityId: string): Promise<void> {\n const jobKey = this._librarianKey(entityId);\n if (this.activeMaintenanceJobs.has(jobKey)) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunLibrarian(entityId);\n } finally {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n\n async runHeal(entityId: string): Promise<void> {\n const jobKey = this._healKey(entityId);\n if (this.activeMaintenanceJobs.has(jobKey)) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunHeal(entityId);\n } finally {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n\n async runReembed(entityId?: string, opts?: { force?: boolean; skipExisting?: boolean }): Promise<{ embedded: number; skipped: number; failed: number }> {\n const embedFn = this.options.llmProvider.embed;\n if (!embedFn) return { embedded: 0, skipped: 0, failed: 0 };\n\n const reembedKey = entityId ? this._reembedKey(entityId) : this._globalReembedKey();\n if (this.activeMaintenanceJobs.has(reembedKey)) {\n throw new WikiBusyError('reembed', entityId ?? '*');\n }\n if (entityId) {\n // Cross-check: fail if global reembed is in-flight (it covers this entity too)\n if (this.activeMaintenanceJobs.has(this._globalReembedKey())) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this._isIngestActiveFor(entityId)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n } else {\n // Cross-check: fail if any per-entity reembed is in-flight (global covers all entities)\n if (this._isAnyMaintenanceActiveWithSuffix(':reembed')) {\n throw new WikiBusyError('reembed', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':prune')) {\n throw new WikiBusyError('prune', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':librarian')) {\n throw new WikiBusyError('librarian', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':heal')) {\n throw new WikiBusyError('heal', '*');\n }\n if (this.activeIngestJobs.size > 0) {\n throw new WikiBusyError('ingest', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':import')) {\n throw new WikiBusyError('import', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':forget')) {\n throw new WikiBusyError('forget', '*');\n }\n }\n this.activeMaintenanceJobs.add(reembedKey);\n\n try {\n const where = entityId ? `entity_id = ? AND deleted_at IS NULL` : `deleted_at IS NULL`;\n const params = entityId ? [entityId] : [];\n const rows = await this.db.getAllAsync<WikiFact>(\n `SELECT * FROM ${this.prefix}entries WHERE ${where}`,\n params\n );\n\n // Invalidate before the embedding loop so any concurrent read() fetches fresh\n // vectors from the database rather than stale pre-reembed cached ones.\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n\n // skipExisting is an explicit opt-in for round-trip import scenarios where\n // the caller knows every blob is already fresh and wants to avoid paying the\n // full embedding cost again (e.g. after exportDump → importDump on the same\n // model). By default runReembed() re-embeds every selected fact so that a\n // model switch always works correctly — a dimension-only probe cannot detect\n // same-dimension provider changes, so unconditional re-embedding is the only\n // safe default.\n // { force: true } is kept as a no-op alias so existing call sites that pass\n // it explicitly continue to work without change.\n // skipExisting skips facts that already have a structurally valid BLOB.\n // WARNING: this is only safe when the caller can guarantee the stored BLOBs\n // were produced by the *same* embedding model that is currently configured.\n // It cannot detect same-dimension model/provider switches (e.g. two providers\n // that both produce 1536-dim vectors). After any provider change, always call\n // runReembed() without { skipExisting: true } to force full re-embedding.\n const skipExisting = opts?.skipExisting ?? false;\n // Never skip when a dimension mismatch is pending: blobs on disk are stale\n // regardless of what the caller requested.\n // For per-entity reembed, only disable skipExisting when THIS entity actually\n // has stale blobs — the global mismatch flag may reflect a different entity's\n // state and should not force unnecessary re-embedding of entity A's valid blobs.\n let effectiveSkip = skipExisting;\n if (skipExisting) {\n const mismatchRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (mismatchRow) {\n if (entityId) {\n // Per-entity: check whether this entity has any blobs at the wrong dimension\n // (i.e., the old canonical dim, not the pending new mismatch dim) or TEXT-only rows.\n const mismatchDim = parseInt(mismatchRow.value, 10);\n const staleForEntity = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND (\n embedding_blob IS NULL\n OR (CAST(length(embedding_blob) AS INTEGER) / 4) != ?\n )`,\n [entityId, mismatchDim]\n );\n if (staleForEntity && staleForEntity.cnt > 0) effectiveSkip = false;\n } else {\n // Global reembed: any pending mismatch means blobs are stale somewhere.\n effectiveSkip = false;\n }\n }\n }\n let embedded = 0;\n let skipped = 0;\n let failed = 0;\n try {\n for (const row of rows) {\n // Skip facts with existing BLOBs only when the caller opts in via\n // { skipExisting: true } AND no dimension mismatch is active.\n // The default always re-embeds, ensuring correctness after model switches.\n // Only skip if the BLOB is structurally valid (non-zero length, divisible\n // by 4) and contains entirely finite values. A BLOB full of NaN/Infinity\n // passes the byte-length check but would silently score 0 in read() —\n // let embedFact() repair it instead of leaving the fact permanently unsearchable.\n const existingBlob = (row as WikiFact & { embedding_blob?: Uint8Array | null }).embedding_blob;\n const blobIsValid = !!existingBlob && existingBlob.byteLength > 0 && existingBlob.byteLength % 4 === 0;\n if (effectiveSkip && blobIsValid) {\n const vec = parseEmbedding(existingBlob, null);\n if (vec !== null && vec.every(v => Number.isFinite(v))) {\n skipped++;\n continue;\n }\n }\n const success = await this.embedFact(row);\n if (success) embedded++;\n else failed++;\n }\n // If any fact was successfully re-embedded, promote the pending dimension to\n // canonical and clear the mismatch flag so read() uses embeddings from here on.\n if (embedded > 0) {\n await this._reconcileEmbeddingDimension();\n }\n } finally {\n // Invalidate again after the loop: a concurrent read() might have re-populated\n // the cache with pre-reembed vectors while the loop was running, so flush any\n // such stale entries to ensure subsequent reads see the freshly written data,\n // even if the loop or dimension reconciliation threw.\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n }\n\n return { embedded, skipped, failed };\n } finally {\n this.activeMaintenanceJobs.delete(reembedKey);\n }\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n const ingestPrefix = `${this.prefix}:${entityId}:`;\n let ingesting = false;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(ingestPrefix)) { ingesting = true; break; }\n }\n\n return {\n ingesting,\n librarian: this.activeMaintenanceJobs.has(this._librarianKey(entityId)),\n heal: this.activeMaintenanceJobs.has(this._healKey(entityId)),\n };\n }\n\n /**\n * Subscribe to {@link EntityStatus} changes for a single entity. The callback\n * is invoked synchronously once with the current status before this method\n * returns, then again on every transition where any of `ingesting`,\n * `librarian`, or `heal` flips. No polling, no duplicate snapshots.\n *\n * Returns an idempotent unsubscribe function.\n *\n * See also {@link getEntityStatus} for a synchronous point-in-time read.\n */\n subscribeEntityStatus(\n entityId: string,\n callback: (status: EntityStatus) => void\n ): () => void {\n const initial = this.getEntityStatus(entityId);\n let set = this.statusSubscribers.get(entityId);\n if (!set) {\n set = new Set();\n this.statusSubscribers.set(entityId, set);\n }\n const entry = { callback, last: this._copyEntityStatus(initial) };\n set.add(entry);\n\n try {\n callback(this._copyEntityStatus(initial));\n } catch (err) {\n console.error(`[WikiMemory.subscribeEntityStatus] callback error for entityId=\"${entityId}\" during initial emission`, err);\n }\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n const s = this.statusSubscribers.get(entityId);\n if (!s) return;\n s.delete(entry);\n if (s.size === 0) this.statusSubscribers.delete(entityId);\n };\n }\n\n public clearVectorCache(): void {\n this.vectorCache.clear();\n }\n\n private async _getFullBundle(entityId: string, opts?: { maxEvents?: number; includeBlobs?: boolean }): Promise<MemoryBundle> {\n const maxEvents = opts?.maxEvents;\n const eventsQuery = maxEvents != null\n ? `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`\n : `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at ASC`;\n const eventsParams: (string | number)[] = maxEvents != null ? [entityId, maxEvents] : [entityId];\n\n const [factsRaw, tasks, eventsRaw] = await Promise.all([\n this.db.getAllAsync<WikiFact>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId]\n ),\n this.db.getAllAsync<WikiTask>(\n `SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL ORDER BY priority DESC, created_at ASC`,\n [entityId]\n ),\n this.db.getAllAsync<WikiEvent>(eventsQuery, eventsParams),\n ]);\n const facts = factsRaw.map(f => {\n // Always strip the legacy text embedding column — never useful to callers.\n const { embedding: _embedding, embedding_blob, ...rest } =\n f as WikiFact & { embedding?: unknown; embedding_blob?: Uint8Array };\n // Include the BLOB only on the export path so importDump() can round-trip\n // embeddings without re-calling the embed provider. Strip it on the LLM\n // prompt / formatMemoryDump paths to keep payloads small.\n // Copy blob bytes before returning: some SQLite drivers (better-sqlite3)\n // back Buffer objects with pooled native memory that can be reused by a\n // subsequent query, silently corrupting the already-returned MemoryDump.\n const safeBlobCopy = opts?.includeBlobs && embedding_blob\n ? (() => { const c = new ArrayBuffer(embedding_blob.byteLength); new Uint8Array(c).set(embedding_blob); return new Uint8Array(c); })()\n : undefined;\n const factBase = safeBlobCopy\n ? { ...rest, embedding_blob: safeBlobCopy }\n : rest;\n return {\n ...factBase,\n tags: typeof factBase.tags === 'string' ? JSON.parse(factBase.tags) : factBase.tags,\n };\n });\n // When limited, results arrive newest-first; reverse to chronological order.\n const events = maxEvents != null ? eventsRaw.slice().reverse() : eventsRaw;\n return { facts, tasks, events };\n }\n\n async exportDump(entityIds?: string[]): Promise<MemoryDump> {\n let ids: string[];\n if (entityIds && entityIds.length > 0) {\n ids = Array.from(new Set(entityIds));\n } else {\n // Collect all distinct entity_ids across entries, tasks, events\n const rows = await this.db.getAllAsync<{ entity_id: string }>(`\n SELECT DISTINCT entity_id FROM (\n SELECT entity_id FROM ${this.prefix}entries WHERE deleted_at IS NULL\n UNION\n SELECT entity_id FROM ${this.prefix}tasks WHERE deleted_at IS NULL\n UNION\n SELECT entity_id FROM ${this.prefix}events\n ) ORDER BY entity_id\n `);\n ids = rows.map(r => r.entity_id);\n }\n\n const entities: Record<string, MemoryBundle> = {};\n const BATCH = 3;\n for (let i = 0; i < ids.length; i += BATCH) {\n const batch = ids.slice(i, i + BATCH);\n const batchResults = await Promise.all(\n batch.map(async (id): Promise<[string, MemoryBundle]> => [id, await this._getFullBundle(id, { includeBlobs: true })])\n );\n for (const [id, bundle] of batchResults) {\n entities[id] = bundle;\n }\n }\n\n return { generatedAt: Date.now(), entities };\n }\n\n async importDump(dump: MemoryDump, opts?: { merge?: boolean }): Promise<void> {\n const merge = opts?.merge ?? false;\n const entityIds = Object.keys(dump.entities);\n\n // Pre-validate all locks before writing anything. This makes the operation\n // atomic with respect to busy-error rejection: either every entity passes the\n // lock check and we proceed, or we reject before mutating any entity.\n // Per-entity checks first: surface the specific conflicting entity in the error.\n for (const entityId of entityIds) {\n if (this.activeMaintenanceJobs.has(this._importKey(entityId))) {\n throw new WikiBusyError('import', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isIngestActiveFor(entityId)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n }\n // Global import lock check after per-entity checks: serializes concurrent\n // importDump() calls for *different* entities so they cannot race on the shared\n // embedding_dimension / embedding_dimension_mismatch meta keys.\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) {\n throw new WikiBusyError('import', '*');\n }\n\n // Acquire global + per-entity import locks before any await so the lock check and\n // lock acquisition remain race-free across concurrent importDump() calls.\n this.activeMaintenanceJobs.add(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.add(this._importKey(entityId));\n }\n try {\n // Fail before any writes so we never partially commit an import and then reject\n // with a migration error — same probe as setup().\n await this.assertNoLegacySourceTypes();\n\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n await this._doImportEntity(entityId, bundle, merge);\n }\n } finally {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.delete(this._importKey(entityId));\n }\n }\n }\n\n private async _doImportEntity(entityId: string, bundle: MemoryBundle, merge: boolean): Promise<void> {\n // Track which fact IDs were actually inserted/updated inside the transaction.\n // Skipped rows (cross-entity collisions or merge LWW losers) must not be\n // re-embedded — doing so would corrupt the winning row's vector with the\n // losing fact's title/body.\n const upsertedFactIds = new Set<string>();\n // Track upserted facts whose incoming row is soft-deleted. In replace mode,\n // these IDs still need vector=null notifications because they remain deleted.\n const upsertedDeletedFactIds = new Set<string>();\n // Track which upserted facts already carry a valid BLOB so we can skip\n // embedFact() for them. BLOBs are reconstructed from three serialization\n // forms: in-memory Uint8Array/Buffer, Node.js Buffer JSON shape, and\n // numeric-keyed plain objects produced by JSON.stringify(Uint8Array).\n // Store the blob data so we can notify the external vector index after the transaction.\n const factsWithPreservedBlob = new Map<string, Uint8Array>();\n // Track every unique dimension seen in preserved BLOBs. A dump may contain\n // blobs from multiple models (e.g. an intermediate mixed-model migration),\n // so we call storeEmbeddingDimension() for each unique dimension found to\n // ensure the mismatch flag is set whenever any two stored blobs disagree.\n const preservedBlobDims = new Set<number>();\n // In replace mode, collect IDs of facts that will be soft-deleted so we can\n // notify the external vector index with vector=null after the transaction.\n // Without this, external indexes retain stale embeddings and keep returning\n // deleted fact IDs in ranking results.\n const softDeletedFactIds: string[] = [];\n await this.db.withTransactionAsync(async () => {\n if (!merge) {\n // Collect IDs of live facts that will be soft-deleted\n const toDelete = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId]\n );\n softDeletedFactIds.push(...toDelete.map(r => r.id));\n const now = Date.now();\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId]\n );\n await this.db.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId]\n );\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId]\n );\n }\n\n const factIds = bundle.facts.map((fact) => fact.id);\n const existingFactsById = new Map<string, { id: string; entity_id: string; updated_at: number }>();\n const factLookupChunkSize = 500;\n for (let i = 0; i < factIds.length; i += factLookupChunkSize) {\n const factIdChunk = factIds.slice(i, i + factLookupChunkSize);\n if (factIdChunk.length === 0) continue;\n const placeholders = factIdChunk.map(() => '?').join(', ');\n const existingFacts = await this.db.getAllAsync<{ id: string; entity_id: string; updated_at: number }>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}entries WHERE id IN (${placeholders})`,\n factIdChunk\n );\n for (const existingFact of existingFacts) {\n existingFactsById.set(existingFact.id, existingFact);\n }\n }\n\n for (const fact of bundle.facts) {\n const sourceType = this._normalizeImportedSourceType(String(fact.source_type), {\n entityId,\n factId: fact.id,\n });\n const tagsJson = JSON.stringify(Array.isArray(fact.tags) ? fact.tags : []);\n // Normalize once: non-finite (undefined/null/NaN) → 0 so we never persist an\n // invalid value to the DB and ORDER BY updated_at remains meaningful.\n const safeUpdatedAt = Number.isFinite(fact.updated_at) ? fact.updated_at : 0;\n const existing = existingFactsById.get(fact.id);\n\n // Extract a valid BLOB from the incoming fact.\n // Three serialization forms are normalised to Uint8Array:\n // 1. Real Uint8Array / Buffer (in-memory dump)\n // 2. Node.js Buffer JSON shape { type:'Buffer', data:[...] }\n // (produced by JSON.stringify(buffer))\n // 3. Numeric-keyed plain object {0:byte, 1:byte, ...}\n // (produced by JSON.stringify(Uint8Array))\n const rawBlobRaw = (fact as WikiFact & { embedding_blob?: unknown }).embedding_blob;\n let rawBlob: Uint8Array | null = null;\n if (rawBlobRaw instanceof Uint8Array) {\n rawBlob = rawBlobRaw;\n } else if (\n rawBlobRaw !== null &&\n rawBlobRaw !== undefined &&\n typeof rawBlobRaw === 'object'\n ) {\n const obj = rawBlobRaw as Record<string, unknown>;\n if (obj['type'] === 'Buffer' && Array.isArray(obj['data'])) {\n // Node.js Buffer serialized via JSON.stringify(buffer)\n rawBlob = new Uint8Array(obj['data'] as number[]);\n } else if (!Array.isArray(rawBlobRaw)) {\n // Numeric-keyed plain object from JSON.stringify(Uint8Array)\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every(k => /^\\d+$/.test(k))) {\n const len = entries.length;\n rawBlob = new Uint8Array(len);\n for (let i = 0; i < len; i++) rawBlob[i] = (obj[String(i)] as number) ?? 0;\n }\n }\n }\n let blobData: Uint8Array | null = null;\n if (\n rawBlob !== null &&\n rawBlob.byteLength > 0 &&\n rawBlob.byteLength % 4 === 0\n ) {\n // Also validate that every float32 value is finite: a blob with the right\n // byte length but NaN/Inf values would be preserved, skip embedFact(), and\n // then be silently dropped by read(), making the fact permanently unsearchable.\n // Copy into a fresh ArrayBuffer so the Float32Array view is guaranteed to\n // start at offset 0 of its own buffer. Buffer.slice(0) in Node.js does NOT\n // copy — it returns a view into the parent buffer, which can have a non-zero\n // byteOffset and corrupt the Float32Array interpretation.\n const copy = new ArrayBuffer(rawBlob.byteLength);\n const alignedBlob = new Uint8Array(copy);\n alignedBlob.set(rawBlob);\n const floats = new Float32Array(copy, 0, rawBlob.byteLength / 4);\n let allFinite = true;\n for (let i = 0; i < floats.length; i++) {\n if (!isFinite(floats[i])) { allFinite = false; break; }\n }\n if (allFinite) {\n // Preserve this blob regardless of its dimension. Mixed-dimension\n // blobs are a real intermediate state during model migration and\n // silently discarding valid vectors is worse than importing them;\n // storeEmbeddingDimension() and read()'s mismatch-check handle\n // the case where stored blobs disagree on size.\n // Note: same-dimension model changes (e.g. two different providers\n // that happen to produce 1536-dim vectors) are undetectable here —\n // there is no model fingerprint in the blob. Callers importing from\n // a different provider should call runReembed() after importDump()\n // rather than relying on { skipExisting: true }.\n // Store aligned copy (not rawBlob) to avoid Float32Array alignment errors in notification.\n blobData = alignedBlob;\n }\n }\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision('entry', fact.id, existing.entity_id, entityId);\n continue;\n }\n if (merge) {\n // LWW: incoming wins only if its updated_at is strictly newer than local.\n // 0 (epoch) never beats a real timestamp, so invalid incoming rows are skipped.\n if (safeUpdatedAt <= existing.updated_at) continue;\n }\n if (blobData != null) {\n // Incoming fact carries a valid BLOB (in-memory dump): persist it directly\n // and skip embedFact() — no embedding API call required.\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET entity_id = ?, title = ?, body = ?, tags = ?, confidence = ?, source_type = ?, source_hash = ?, source_ref = ?, created_at = ?, updated_at = ?, last_accessed_at = ?, access_count = ?, deleted_at = ?, embedding_blob = ?, embedding = NULL WHERE id = ?`,\n [entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, blobData, fact.id]\n );\n factsWithPreservedBlob.set(fact.id, blobData);\n // Only track dimensions for live facts: read() and _reconcileEmbeddingDimension()\n // both filter by deleted_at IS NULL, so a soft-deleted stale blob must not\n // set embedding_dimension_mismatch and block retrieval on healthy live facts.\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n } else {\n // read() never ranks the new title/body against the old vector;\n // the post-transaction embedding loop will re-embed.\n // If embedFact() fails (provider absent or throws), the NULL vector\n // remains, which is correct: new content with no valid embedding\n // falls back to keyword-only retrieval.\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET entity_id = ?, title = ?, body = ?, tags = ?, confidence = ?, source_type = ?, source_hash = ?, source_ref = ?, created_at = ?, updated_at = ?, last_accessed_at = ?, access_count = ?, deleted_at = ?, embedding_blob = NULL, embedding = NULL WHERE id = ?`,\n [entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, fact.id]\n );\n }\n existingFactsById.set(fact.id, { id: fact.id, entity_id: entityId, updated_at: safeUpdatedAt });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n } else {\n if (blobData != null) {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count, deleted_at, embedding_blob) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [fact.id, entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, blobData]\n );\n factsWithPreservedBlob.set(fact.id, blobData);\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n } else {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count, deleted_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [fact.id, entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at]\n );\n }\n existingFactsById.set(fact.id, { id: fact.id, entity_id: entityId, updated_at: safeUpdatedAt });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n }\n }\n\n const taskIds = bundle.tasks.map((task) => task.id);\n const existingTasksById = new Map<string, { id: string; entity_id: string; updated_at: number }>();\n const taskLookupChunkSize = 500;\n\n for (let i = 0; i < taskIds.length; i += taskLookupChunkSize) {\n const taskIdChunk = taskIds.slice(i, i + taskLookupChunkSize);\n if (taskIdChunk.length === 0) continue;\n\n const placeholders = taskIdChunk.map(() => '?').join(', ');\n const existingTasks = await this.db.getAllAsync<{ id: string; entity_id: string; updated_at: number }>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}tasks WHERE id IN (${placeholders})`,\n taskIdChunk\n );\n\n for (const existingTask of existingTasks) {\n existingTasksById.set(existingTask.id, existingTask);\n }\n }\n\n for (const task of bundle.tasks) {\n // Normalize once: non-finite (undefined/null/NaN) → 0 so we never persist an\n // invalid value to the DB and ORDER BY updated_at remains meaningful.\n const safeUpdatedAt = Number.isFinite(task.updated_at) ? task.updated_at : 0;\n const existing = existingTasksById.get(task.id);\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision('task', task.id, existing.entity_id, entityId);\n continue;\n }\n if (merge) {\n // LWW: incoming wins only if its updated_at is strictly newer than local.\n // 0 (epoch) never beats a real timestamp, so invalid incoming rows are skipped.\n if (safeUpdatedAt <= existing.updated_at) continue;\n }\n // replace mode (or merge LWW winner): update the existing row (restores if soft-deleted)\n await this.db.runAsync(\n `UPDATE ${this.prefix}tasks SET entity_id = ?, description = ?, status = ?, priority = ?, created_at = ?, updated_at = ?, resolved_at = ?, deleted_at = ? WHERE id = ?`,\n [entityId, task.description, task.status, task.priority, task.created_at, safeUpdatedAt, task.resolved_at, task.deleted_at, task.id]\n );\n existingTasksById.set(task.id, { id: task.id, entity_id: entityId, updated_at: safeUpdatedAt });\n } else {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}tasks (id, entity_id, description, status, priority, created_at, updated_at, resolved_at, deleted_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [task.id, entityId, task.description, task.status, task.priority, task.created_at, safeUpdatedAt, task.resolved_at, task.deleted_at]\n );\n existingTasksById.set(task.id, { id: task.id, entity_id: entityId, updated_at: safeUpdatedAt });\n }\n }\n\n for (const event of bundle.events) {\n await this.db.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [event.id, entityId, event.event_type, event.summary, event.related_entry_id ?? null, event.created_at]\n );\n }\n });\n // Invalidate cache before rebuilding the text index so concurrent reads\n // see consistent data: all use the post-transaction DB state.\n this.vectorCache.delete(entityId);\n // Rebuild the MiniSearch index immediately after the transaction commits\n // so concurrent read() calls using preFilterLimit or hybrid scoring get\n // the updated text rather than waiting for the (potentially slow) embedding loop.\n await this.rebuildMiniSearchIndex(entityId);\n // Embed only facts that were actually inserted/updated in the transaction.\n // Skipped rows (cross-entity collisions or merge LWW losers) must not be\n // re-embedded — they were not written and their existing row must not be\n // overwritten with the incoming fact's content.\n // Facts with preserved BLOBs (from an in-memory dump) already have valid\n // embeddings; skip embedFact() for those to avoid redundant API calls.\n // For facts without a BLOB, the UPDATE/INSERT already left embedding_blob = NULL,\n // so if embedFact() fails here the row correctly has a NULL vector.\n for (const fact of bundle.facts) {\n if (!fact.deleted_at && upsertedFactIds.has(fact.id) && !factsWithPreservedBlob.has(fact.id)) {\n await this.embedFact({\n id: fact.id,\n entity_id: entityId, // Use authoritative entityId from dump key, not fact.entity_id\n title: fact.title,\n body: fact.body,\n tags: Array.isArray(fact.tags) || typeof fact.tags === 'string' ? fact.tags : [],\n });\n }\n }\n // Notify external vector index about preserved-blob facts.\n // These skipped embedFact(), so _notifyEmbeddingPersisted was never called.\n // Only notify for live facts (skip soft-deleted) to avoid polluting external index.\n for (const fact of bundle.facts) {\n const blobData = factsWithPreservedBlob.get(fact.id);\n if (blobData && !fact.deleted_at && upsertedFactIds.has(fact.id)) {\n try {\n const float32Vector = new Float32Array(blobData.buffer, blobData.byteOffset, blobData.byteLength / 4);\n await this._notifyEmbeddingPersisted(entityId, fact.id, float32Vector);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed for preserved-blob fact ${fact.id}:`, hookErr);\n }\n }\n }\n // In replace mode, notify external vector index that soft-deleted facts should be removed.\n // Re-upserted facts are usually restores, except when the incoming row is still\n // soft-deleted (deleted_at set). Those must also receive vector=null.\n for (const factId of softDeletedFactIds) {\n if (!upsertedFactIds.has(factId) || upsertedDeletedFactIds.has(factId)) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted(vector=null) hook failed for soft-deleted fact ${factId}:`, hookErr);\n }\n }\n }\n // If any facts carried preserved BLOBs, record the vector dimension in the\n // meta table now (embedFact() was skipped for those rows, so it didn't happen\n // automatically). This ensures read() can detect model-dimension mismatches\n // after importing into a fresh DB that has never seen an embedding.\n // However, if the preserved BLOBs have a *different* dimension than the\n // current canonical dimension, skip bookkeeping entirely. Calling\n // storeEmbeddingDimension() with the imported dimension would set\n // embedding_dimension_mismatch, which _reconcileEmbeddingDimension() would\n // interpret as the target dimension. After runReembed() rewrites everything\n // to the canonical dimension, the mismatch flag would never clear (all facts\n // now differ from the old imported dimension, so residual count > 0 forever).\n // Instead, let runReembed() reconcile all vectors without pre-seeding metadata.\n try {\n // Query the current canonical embedding dimension, if any.\n const canonicalRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n const canonicalDim = canonicalRow ? parseInt(canonicalRow.value, 10) : null;\n\n if (preservedBlobDims.size === 1) {\n const preservedDim = [...preservedBlobDims][0];\n if (canonicalDim === null || canonicalDim === preservedDim) {\n // Fresh DB: record the imported dimension as canonical.\n // Matching canonical: storeEmbeddingDimension is a no-op for equal dims,\n // but a stale embedding_dimension_mismatch flag may still be present from\n // a previous import. Run reconciliation so the flag is cleared if all live\n // facts now agree on the canonical dimension.\n await this.storeEmbeddingDimension(preservedDim);\n // If a stale embedding_dimension_mismatch flag exists from a prior failed\n // model switch it may target a different dimension. _reconcileEmbeddingDimension()\n // checks residuals against whatever value the flag holds; a wrong value keeps\n // the flag stuck even though all imported blobs now match preservedDim.\n // Overwrite the flag to preservedDim before reconciling so the check is correct.\n const staleMismatch = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (staleMismatch && parseInt(staleMismatch.value, 10) !== preservedDim) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(preservedDim)]\n );\n }\n await this._reconcileEmbeddingDimension();\n } else {\n // Imported blobs differ from the canonical model dimension. Set\n // embedding_dimension_mismatch = canonicalDim so that:\n // (a) read() detects the mismatch and falls back to MiniSearch, and\n // (b) _reconcileEmbeddingDimension() can clear the flag after\n // runReembed() rewrites all blobs to canonicalDim.\n // Using the imported dim as the mismatch value would deadlock:\n // after runReembed(), all blobs have canonicalDim ≠ importedDim, so\n // the residual count never reaches 0 and the flag is never cleared.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(canonicalDim)]\n );\n }\n } else if (preservedBlobDims.size > 1) {\n if (canonicalDim === null) {\n // Fresh import with mixed BLOBs: seed canonical with the smallest imported\n // dimension, then write embedding_dimension_mismatch = that same canonical\n // value. Seeding mismatch = canonical (not dim[1]) ensures\n // _reconcileEmbeddingDimension() can always clear the flag:\n // - If runReembed() uses the same dim as canonical: storeEmbeddingDimension\n // is a no-op, mismatch stays = canonical, residual = 0 → clears. ✓\n // - If runReembed() uses a different dim: storeEmbeddingDimension overwrites\n // mismatch = currentDim, residual = 0 after full reembed → clears. ✓\n // Seeding mismatch = dim[1] instead would deadlock the second case: after\n // runReembed(), all blobs have currentDim ≠ dim[1] → residual > 0 forever.\n const sortedPreservedBlobDims = [...preservedBlobDims].sort((a, b) => a - b);\n await this.storeEmbeddingDimension(sortedPreservedBlobDims[0]);\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(sortedPreservedBlobDims[0])]\n );\n } else {\n // Import into an existing wiki with mixed-dimension blobs. Set\n // mismatch = canonicalDim so the flag clears correctly after runReembed()\n // rewrites everything to the canonical model.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(canonicalDim)]\n );\n }\n }\n } finally {\n // Second flush: evict any cache entries a concurrent read() repopulated\n // from old DB vectors while the embedding loop was running. Runs even if\n // storeEmbeddingDimension() throws so stale entries cannot survive an error.\n this.vectorCache.delete(entityId);\n }\n }\n\n async forget(entityId: string, params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean }): Promise<{ deleted: { entries: number; tasks: number } }> {\n let blockingOperation: \"librarian\" | \"heal\" | \"prune\" | \"reembed\" | \"ingest\" | \"forget\" | \"import\" | null = null;\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n blockingOperation = 'librarian';\n } else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n blockingOperation = 'heal';\n } else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n blockingOperation = 'prune';\n } else if (this._isReembedActive(entityId)) {\n blockingOperation = 'reembed';\n } else if (this._isIngestActiveFor(entityId)) {\n blockingOperation = 'ingest';\n } else if (this._isImportActiveFor(entityId)) {\n blockingOperation = 'import';\n } else if (this._isForgetActiveFor(entityId)) {\n blockingOperation = 'forget';\n }\n if (blockingOperation !== null) {\n throw new WikiBusyError(blockingOperation, entityId);\n }\n const forgetKey = this._forgetKey(entityId);\n this.activeMaintenanceJobs.add(forgetKey);\n try {\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n const deletedEntryIds: string[] = [];\n\n if (params.clearAll) {\n // Select both new deletions and already-soft-deleted (for hook retry on failure)\n const newDeletions = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId]\n );\n const alreadySoftDeleted = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL`,\n [entityId]\n );\n deletedEntryIds.push(...newDeletions.map(e => e.id), ...alreadySoftDeleted.map(e => e.id));\n\n const [entriesRes, tasksRes] = await Promise.all([\n this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`, [now, now, entityId]),\n this.db.runAsync(`UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`, [now, now, entityId]),\n ]);\n await this.db.runAsync(`UPDATE ${this.prefix}checkpoints SET memory_checkpoint = 0, heal_checkpoint = 0 WHERE entity_id = ?`, [entityId]);\n deletedEntries = entriesRes.changes;\n deletedTasks = tasksRes.changes;\n } else {\n const hasIdSelectors = params.entryId !== undefined || params.taskId !== undefined;\n const hasSourceSelectors = params.sourceRef !== undefined || params.sourceHash !== undefined;\n if (hasIdSelectors && hasSourceSelectors) {\n throw new Error('forget() params are mutually exclusive: use entryId/taskId together, or sourceRef/sourceHash together, but not both in the same call');\n }\n\n const sourceRef = params.sourceRef !== undefined ? normalizeSourceRef(params.sourceRef) : null;\n if (params.sourceRef !== undefined && !sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = params.sourceHash !== undefined ? normalizeSourceHash(params.sourceHash) : null;\n if (params.sourceHash !== undefined && !sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n if (params.entryId) {\n // Select entry regardless of deleted_at to allow hook retry on already-soft-deleted rows\n const entry = await this.db.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ?`,\n [params.entryId, entityId]\n );\n if (entry) deletedEntryIds.push(entry.id);\n }\n\n if (sourceRef || sourceHash) {\n // Select entries regardless of deleted_at to allow hook retry on already-soft-deleted rows\n let q = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ?`;\n const args: any[] = [entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n const entriesToDelete = await this.db.getAllAsync<{ id: string }>(q, args);\n deletedEntryIds.push(...entriesToDelete.map(e => e.id));\n }\n\n const entryPromise = params.entryId\n ? this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`, [now, now, params.entryId, entityId])\n : null;\n\n const taskPromise = params.taskId\n ? this.db.runAsync(`UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`, [now, now, params.taskId, entityId])\n : null;\n\n let refPromise: Promise<{ changes: number; lastInsertRowId: number }> | null = null;\n if (sourceRef || sourceHash) {\n let q = `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: any[] = [now, now, entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n refPromise = this.db.runAsync(q, args);\n }\n\n const [entryResult, taskResult, refResult] = await Promise.all([\n entryPromise ?? Promise.resolve(null),\n taskPromise ?? Promise.resolve(null),\n refPromise ?? Promise.resolve(null),\n ]);\n\n if (entryResult) deletedEntries += entryResult.changes;\n if (taskResult) deletedTasks += taskResult.changes;\n if (refResult) deletedEntries += refResult.changes;\n }\n\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n // Deduplicate to avoid redundant hook calls for the same fact\n const uniqueDeletedIds = Array.from(new Set(deletedEntryIds));\n for (const factId of uniqueDeletedIds) {\n try {\n await this._notifyEmbeddingPersistedOrThrow(entityId, factId, null);\n } catch (hookErr) {\n // Preserve timeout errors (thrown by WikiMemory, not the ranker)\n const isTimeout = (hookErr as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new Error(\n `forget(${entityId}/${factId}) failed: ${(hookErr as Error).message}`,\n );\n }\n // Preserve WikiMemory validation errors (not from the adapter hook)\n const errMsg = (hookErr as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n if (isValidationError) {\n throw new Error(\n `forget(${entityId}/${factId}) failed: ${errMsg}`,\n { cause: hookErr },\n );\n }\n // Actual hook rejection - sanitize error details\n throw new Error(\n `forget(${entityId}/${factId}) failed: ANN cleanup hook rejected`,\n { cause: this._sanitizeRankerError(hookErr) },\n );\n }\n }\n\n return { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.activeMaintenanceJobs.delete(forgetKey);\n }\n }\n\n async ingestDocument(entityId: string, params: { sourceRef: string; sourceHash: string; documentChunk: string; maxChunkLength?: number; chunkOverlap?: number; chunkConcurrency?: number }): Promise<{ truncated: boolean; chunks: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = normalizeSourceHash(params.sourceHash);\n if (!sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n const maxChunkLength = params.maxChunkLength ?? this.options.config?.maxChunkLength ?? 12000;\n const rawOverlap = params.chunkOverlap ?? this.options.config?.chunkOverlap ?? 400;\n const chunkOverlap = Math.min(\n Number.isFinite(rawOverlap) && rawOverlap >= 0 ? Math.floor(rawOverlap) : 400,\n maxChunkLength - 1\n );\n const rawConcurrency = params.chunkConcurrency ?? this.options.config?.chunkConcurrency ?? 1;\n const chunkConcurrency = Number.isFinite(rawConcurrency) && rawConcurrency >= 1\n ? Math.floor(rawConcurrency)\n : 1;\n\n if (typeof params.documentChunk !== 'string') {\n throw new Error(`documentChunk must be a string, received ${typeof params.documentChunk}`);\n }\n\n const jobKey = `${this.prefix}:${entityId}:${sourceRef}`;\n if (this.activeIngestJobs.has(jobKey)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeIngestJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n\n try {\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n\n if (chunks.length === 0) {\n return { truncated: false, chunks: 0 };\n }\n\n // Bounded-concurrency LLM calls — each chunk is independent\n const chunkResults = await withConcurrency(\n chunks.map((chunk) => async () => {\n const userPrompt = `Document Chunk:\\n${chunk}`;\n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: INGEST_SYSTEM_PROMPT,\n userPrompt,\n });\n const result = parseJsonResponse<{ facts: ExtractedFact[] }>(responseText);\n return (Array.isArray(result.facts) ? result.facts : [])\n .map(validateFact)\n .filter((f): f is ExtractedFact => f !== null);\n }),\n chunkConcurrency\n );\n\n // Flatten in chunk order, then dedup by normalized title (first-wins)\n const seen = new Set<string>();\n const allValidFacts: ExtractedFact[] = [];\n for (const facts of chunkResults) {\n for (const fact of facts) {\n const normalized = fact.title.trim().toLowerCase().replace(/\\s+/g, ' ');\n if (!seen.has(normalized)) {\n seen.add(normalized);\n allValidFacts.push(fact);\n }\n }\n }\n\n const now = Date.now();\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const deletedSourceFactIds: string[] = [];\n\n await this.db.withTransactionAsync(async () => {\n const existingSourceFacts = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE source_ref = ? AND entity_id = ? AND deleted_at IS NULL`,\n [sourceRef, entityId]\n );\n for (const row of existingSourceFacts) {\n deletedSourceFactIds.push(row.id);\n }\n\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE source_ref = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, sourceRef, entityId]\n );\n for (const fact of allValidFacts) {\n const id = generateId('fact_');\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'immutable_document', sourceHash, sourceRef, now, now]\n );\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n });\n\n // Rebuild text index before embedding so concurrent reads see new content.\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n const uniqueDeletedSourceFactIds = Array.from(new Set(deletedSourceFactIds));\n for (const factId of uniqueDeletedSourceFactIds) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during ingest for ${factId}:`, hookErr);\n }\n }\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Second flush after embed loop in case a concurrent read() repopulated cache.\n this.vectorCache.delete(entityId);\n\n return { truncated, chunks: chunks.length };\n } finally {\n this.activeIngestJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n}\n\nexport const __testables = { validateFact, validateTask, clip, chunkText };\n","import type { MemoryBundle, WikiFact, WikiTask, WikiEvent, FormatContextOptions } from '../types';\n\nfunction validateMaxOption(value: number, name: string): void {\n if (!isFinite(value) || value < 0) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number`);\n }\n}\n\nconst CONFIDENCE_WEIGHT: Record<string, number> = {\n certain: 1.0,\n inferred: 0.6,\n tentative: 0.3,\n};\n\nfunction scoreFactFor(\n fact: WikiFact,\n weights: Required<NonNullable<FormatContextOptions['factWeights']>>,\n now: number\n): number {\n const confW = CONFIDENCE_WEIGHT[fact.confidence] ?? 0.3;\n const ageDays = (now - fact.updated_at) / 86400000;\n const recencyDecay = Math.exp(-ageDays / 30);\n return (\n confW * weights.confidence +\n Math.log(1 + fact.access_count) * weights.accessCount +\n recencyDecay * weights.recency\n );\n}\n\nfunction renderFactMarkdown(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart =\n includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n return `- **${fact.title}**${confPart}${tagPart}\\n ${fact.body.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderFactPlain(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart =\n includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n return `${fact.title}${confPart}${tagPart}: ${fact.body}`;\n}\n\nfunction renderTaskMarkdown(task: WikiTask): string {\n return `- [P${task.priority}] ${task.description.replace(/\\n/g, '\\n ')} (${task.status})`;\n}\n\nfunction renderTaskPlain(task: WikiTask): string {\n return `[P${task.priority}] ${task.description} (${task.status})`;\n}\n\nfunction renderEventMarkdown(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `- [${event.event_type} @ ${ts}] ${event.summary.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderEventPlain(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `[${event.event_type} @ ${ts}] ${event.summary}`;\n}\n\nexport function formatContext(\n bundle: MemoryBundle,\n options?: FormatContextOptions\n): string {\n const opts: Required<FormatContextOptions> = {\n format: options?.format ?? 'markdown',\n maxFacts: options?.maxFacts ?? 10,\n maxTasks: options?.maxTasks ?? 10,\n maxEvents: options?.maxEvents ?? 10,\n includeConfidence: options?.includeConfidence ?? true,\n includeTags: options?.includeTags ?? true,\n factWeights: {\n confidence: options?.factWeights?.confidence ?? 1.0,\n accessCount: options?.factWeights?.accessCount ?? 0.3,\n recency: options?.factWeights?.recency ?? 0.5,\n },\n };\n\n validateMaxOption(opts.maxFacts, 'maxFacts');\n validateMaxOption(opts.maxTasks, 'maxTasks');\n validateMaxOption(opts.maxEvents, 'maxEvents');\n\n const weights = opts.factWeights as Required<NonNullable<FormatContextOptions['factWeights']>>;\n\n const now = Date.now();\n const sortedFacts = [...bundle.facts]\n .sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now))\n .slice(0, opts.maxFacts);\n\n const sortedTasks = [...bundle.tasks]\n .sort((a, b) => b.priority - a.priority || a.created_at - b.created_at)\n .slice(0, opts.maxTasks);\n\n const sortedEvents = [...bundle.events]\n .sort((a, b) => b.created_at - a.created_at)\n .slice(0, opts.maxEvents);\n\n if (sortedFacts.length === 0 && sortedTasks.length === 0 && sortedEvents.length === 0) {\n return '';\n }\n\n const isMarkdown = opts.format === 'markdown';\n const lines: string[] = [];\n\n if (isMarkdown) {\n lines.push('## Memory');\n\n if (sortedFacts.length > 0) {\n lines.push('');\n lines.push('### Known Facts');\n for (const fact of sortedFacts) {\n lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags));\n }\n }\n\n if (sortedTasks.length > 0) {\n lines.push('');\n lines.push('### Open Tasks');\n for (const task of sortedTasks) {\n lines.push(renderTaskMarkdown(task));\n }\n }\n\n if (sortedEvents.length > 0) {\n lines.push('');\n lines.push('### Recent Events');\n for (const event of sortedEvents) {\n lines.push(renderEventMarkdown(event));\n }\n }\n } else {\n if (sortedFacts.length > 0) {\n lines.push('KNOWN FACTS:');\n for (const fact of sortedFacts) {\n lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags));\n }\n }\n if (sortedTasks.length > 0) {\n lines.push('OPEN TASKS:');\n for (const task of sortedTasks) {\n lines.push(renderTaskPlain(task));\n }\n }\n if (sortedEvents.length > 0) {\n lines.push('RECENT EVENTS:');\n for (const event of sortedEvents) {\n lines.push(renderEventPlain(event));\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import type { MemoryDump, FormattedMemoryDump, MemoryBundle, WikiFact, WikiTask, WikiEvent } from '../types';\n\nfunction renderFact(f: WikiFact): string {\n const tags = (f.tags || []).join(', ');\n const source = f.source_ref ?? f.source_type;\n return `### ${f.title}\n**Tags:** ${tags}\n**Confidence:** ${f.confidence}\n**Source:** ${source}\n\n${f.body}\n\n---\n`;\n}\n\nfunction renderTask(t: WikiTask): string {\n const checked = t.status === 'done' ? 'x' : ' ';\n const note = t.status === 'done' ? ' (done)'\n : t.status === 'abandoned' ? ' (abandoned)'\n : t.status === 'in_progress' ? ' (in progress)'\n : '';\n return `- [${checked}] ${t.description}${note}\\n`;\n}\n\nfunction renderEvent(e: WikiEvent): string {\n const ts = new Date(e.created_at).toISOString();\n return `- [${ts}] (${e.event_type}) ${e.summary}\\n`;\n}\n\nfunction renderEntity(entityId: string, bundle: MemoryBundle, generatedAt: number): string {\n const lines: string[] = [];\n lines.push(`# Memory Dump: ${entityId}`);\n lines.push(`Generated: ${new Date(generatedAt).toISOString()}`);\n lines.push('');\n lines.push('## Facts');\n lines.push('');\n if (bundle.facts.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const f of bundle.facts) lines.push(renderFact(f));\n }\n lines.push('## Tasks');\n lines.push('');\n if (bundle.tasks.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const t of bundle.tasks) lines.push(renderTask(t));\n }\n lines.push('');\n lines.push('## Recent Events');\n lines.push('');\n if (bundle.events.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const e of bundle.events) lines.push(renderEvent(e));\n }\n return lines.join('\\n');\n}\n\nfunction shortHash(value: string): string {\n let h1 = 5381;\n let h2 = 52711;\n for (let i = 0; i < value.length; i += 1) {\n const c = value.charCodeAt(i);\n h1 = Math.imul(h1, 33) ^ c;\n h2 = Math.imul(h2, 31) ^ c;\n }\n return (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction formatEntityFileName(entityId: string): string {\n const normalized = entityId.normalize('NFKC');\n const sanitized = normalized\n .replace(/[^A-Za-z0-9._-]+/g, '_')\n .replace(/^\\.+/, '_')\n .replace(/_+/g, '_')\n .replace(/^[_-]+|[_-]+$/g, '');\n\n // Enforce a max base-name length so the final filename stays within typical\n // filesystem limits (~255 bytes). Reserve ~20 chars for `-<16hexchars>.md`.\n const MAX_BASE = 200;\n const trimmed = sanitized.length > MAX_BASE ? sanitized.slice(0, MAX_BASE) : sanitized;\n\n const baseName = trimmed && trimmed !== '.' && trimmed !== '..'\n ? trimmed\n : 'entity';\n const needsSuffix = baseName !== entityId || sanitized.length > MAX_BASE;\n const uniqueBaseName = needsSuffix ? `${baseName}-${shortHash(entityId)}` : baseName;\n\n return `${uniqueBaseName}.md`;\n}\n\nexport function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump {\n const files = Object.entries(dump.entities).map(([entityId, bundle]) => ({\n name: formatEntityFileName(entityId),\n content: renderEntity(entityId, bundle, dump.generatedAt),\n }));\n\n // Strip embedding_blob from each fact before JSON-serialising the manifest.\n // exportDump() now includes raw Uint8Array blobs for importDump() round-trips,\n // but those binaries serve no purpose in a human-readable manifest and can\n // massively inflate its size for non-trivial datasets.\n const manifestDump: MemoryDump = {\n generatedAt: dump.generatedAt,\n entities: Object.fromEntries(\n Object.entries(dump.entities).map(([entityId, bundle]) => [\n entityId,\n {\n ...bundle,\n facts: bundle.facts.map(f => {\n const { embedding_blob: _blob, ...rest } = f as WikiFact & { embedding_blob?: unknown };\n return rest as WikiFact;\n }),\n },\n ])\n ),\n };\n\n return {\n manifest: JSON.stringify(manifestDump, null, 2),\n files,\n };\n}\n","import { WikiMemory } from './WikiMemory';\nimport type { SQLiteAdapter, WikiOptions } from './types';\n\nexport * from './types';\nexport { WikiMemory } from './WikiMemory';\nexport { formatContext } from './utils/formatContext';\nexport { formatMemoryDump } from './utils/formatMemoryDump';\nexport { parseEmbedding } from './utils/embedding';\n\nexport function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory {\n return new WikiMemory(db, options);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/db/schema.ts","../src/db/migrations.ts","../src/types.ts","../src/prompts.ts","../src/utils/cosine.ts","../src/utils/embedding.ts","../src/readOptions.ts","../src/WikiMemory.ts","../src/utils/formatContext.ts","../src/utils/formatMemoryDump.ts","../src/librarianPrompt.ts","../src/index.ts"],"names":["MiniSearch","rows","documents"],"mappings":"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","file":"index.js","sourcesContent":["import type { SQLiteAdapter } from '../types';\n\nexport async function setupDatabase(db: SQLiteAdapter, prefix: string) {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entries (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n title TEXT NOT NULL,\n body TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n confidence TEXT NOT NULL DEFAULT 'inferred',\n source_type TEXT NOT NULL DEFAULT 'librarian_inferred',\n source_hash TEXT,\n source_ref TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n last_accessed_at INTEGER,\n access_count INTEGER NOT NULL DEFAULT 0,\n deleted_at INTEGER,\n embedding TEXT,\n embedding_blob BLOB\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}entries_entity_idx ON ${prefix}entries(entity_id);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_ref_idx ON ${prefix}entries(entity_id, source_ref);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_hash_idx ON ${prefix}entries(entity_id, source_hash) WHERE source_hash IS NOT NULL;\n CREATE INDEX IF NOT EXISTS ${prefix}entries_updated_idx ON ${prefix}entries(updated_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}tasks (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n description TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n priority INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n resolved_at INTEGER,\n deleted_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_entity_idx ON ${prefix}tasks(entity_id, status);\n\n CREATE TABLE IF NOT EXISTS ${prefix}events (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n summary TEXT NOT NULL,\n related_entry_id TEXT,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}events_entity_idx ON ${prefix}events(entity_id, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}checkpoints (\n entity_id TEXT PRIMARY KEY,\n heal_checkpoint INTEGER NOT NULL DEFAULT 0,\n memory_checkpoint INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n}\n","import type { SQLiteAdapter } from '../types';\n\nexport interface Migration {\n version: number;\n description: string;\n run: (db: SQLiteAdapter, prefix: string) => Promise<void>;\n}\n\nexport const MIGRATIONS: Migration[] = [\n {\n version: 1,\n description: 'Rebuild FTS5 with porter unicode61 tokenizer (superseded by v2)',\n run: async (_db, _prefix) => {\n // This migration is superseded by v2 which drops FTS5 entirely.\n // It is kept as a no-op so upgrade paths from v0 do not require FTS5 support.\n },\n },\n {\n version: 2,\n description: 'Remove FTS5; add embedding column for semantic retrieval',\n run: async (db, prefix) => {\n // Drop FTS5 artifacts in a transaction.\n await db.withTransactionAsync(async () => {\n await db.execAsync(`\n DROP TRIGGER IF EXISTS ${prefix}entries_ai;\n DROP TRIGGER IF EXISTS ${prefix}entries_ad;\n DROP TRIGGER IF EXISTS ${prefix}entries_au;\n DROP TABLE IF EXISTS ${prefix}entries_fts;\n `);\n });\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding')) {\n await db.execAsync(`ALTER TABLE ${prefix}entries ADD COLUMN embedding TEXT`);\n }\n },\n },\n {\n version: 3,\n description: 'Add embedding_blob BLOB column for Float32Array vector storage',\n run: async (db, prefix) => {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding_blob')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN embedding_blob BLOB`\n );\n }\n },\n },\n];\n\n// Verify MIGRATIONS are in strictly ascending version order at module load time.\n// This prevents skipped or repeated migrations caused by out-of-order entries.\nfor (let i = 1; i < MIGRATIONS.length; i++) {\n if (MIGRATIONS[i].version <= MIGRATIONS[i - 1].version) {\n throw new Error(\n `migrations.ts: MIGRATIONS must be in strictly ascending version order. ` +\n `Found version ${MIGRATIONS[i].version} after ${MIGRATIONS[i - 1].version} at index ${i}.`\n );\n }\n}\n\n// Derived from the last (highest) migration version so it never drifts out of sync.\nexport const CURRENT_SCHEMA_VERSION =\n MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].version : 0;\n","/**\n * Platform-agnostic SQLite driver interface.\n * Each platform package (wiki-expo, wiki-react) provides an adapter\n * that wraps its native driver behind this interface.\n */\nexport interface SQLiteAdapter {\n execAsync(sql: string): Promise<void>;\n runAsync(sql: string, params?: unknown[]): Promise<{ changes: number; lastInsertRowId: number }>;\n getAllAsync<T>(sql: string, params?: unknown[]): Promise<T[]>;\n getFirstAsync<T>(sql: string, params?: unknown[]): Promise<T | null>;\n withTransactionAsync<T>(fn: () => Promise<T>): Promise<T>;\n closeAsync(): Promise<void>;\n}\n\nexport interface WikiConfig {\n tablePrefix?: string;\n maxResults?: number;\n /** @deprecated Use maxResults */\n maxFtsResults?: number;\n pruneEventsAfter?: number;\n pruneRetainSoftDeletedFor?: number;\n autoLibrarianThreshold?: number;\n autoHealThreshold?: number;\n orphanAfterDays?: number | null;\n staleInferredAfterDays?: number | null;\n maxChunkLength?: number;\n chunkOverlap?: number;\n chunkConcurrency?: number;\n /**\n * Max MiniSearch candidates passed to cosine scoring.\n * When set, MiniSearch pre-filters before the cosine scan.\n * Only applies when embed is provided and succeeds.\n * Default: undefined (full scan).\n */\n preFilterLimit?: number;\n /**\n * Hybrid blend weight (0.0–1.0).\n * 0.0 = pure keyword (skips embed() entirely).\n * 1.0 = pure semantic.\n * Values outside [0,1] are clamped. Ignored when embed is absent or throws.\n * Default: undefined (pure semantic when embed provided).\n */\n hybridWeight?: number;\n}\n\nexport interface ReadOptions {\n maxResults?: number;\n /**\n * undefined → use WikiConfig.preFilterLimit (or no pre-filter if also unset).\n * null → explicitly disable a config-level preFilterLimit for this call.\n */\n preFilterLimit?: number | null;\n hybridWeight?: number;\n /**\n * Per-entity score multiplier for multi-entity reads. Missing entries default to 1.0.\n * Entities with weight 0 are skipped during scored retrieval unless\n * `includeZeroWeightEntities` is true; in that case they rank below all finite scores.\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n */\n tierWeights?: Record<string, number>;\n /**\n * When true, entities with a tier weight of 0 are included in scored retrieval\n * as bottom fillers (ranked below every finite-scored candidate).\n * When false (default), zero-weight entities are skipped entirely.\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n */\n includeZeroWeightEntities?: boolean;\n}\n\nexport interface WikiFact {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string[];\n confidence: 'certain' | 'inferred' | 'tentative';\n /**\n * Source type of this fact.\n * - 'immutable_document': From ingestDocument(), cannot be modified by system (librarian/heal).\n * Only removable via forget() or replaced via re-ingest.\n * - 'librarian_inferred': Created by runLibrarian() from events, or by runHeal() when synthesizing new inferred facts.\n * - 'user_stated': Direct user statement.\n * - 'user_confirmed': User-confirmed fact.\n */\n source_type: 'user_stated' | 'librarian_inferred' | 'user_confirmed' | 'immutable_document';\n source_hash: string | null;\n source_ref: string | null;\n created_at: number;\n updated_at: number;\n /**\n * Raw Float32Array bytes for the fact's embedding vector.\n * Set when the fact was fetched via exportDump() with blob preservation.\n * Accepted in importDump() as a real Uint8Array (in-memory round-trip),\n * a Node.js Buffer JSON shape `{ type: 'Buffer', data: number[] }`,\n * or a numeric-keyed plain object `{ 0: byte, 1: byte, ... }` produced\n * by JSON.stringify(Uint8Array).\n */\n embedding_blob?: Uint8Array | { type: 'Buffer'; data: number[] } | Record<string, number>;\n last_accessed_at: number | null;\n access_count: number;\n deleted_at: number | null;\n}\n\nexport interface WikiTask {\n id: string;\n entity_id: string;\n description: string;\n status: 'pending' | 'in_progress' | 'done' | 'abandoned';\n priority: number;\n created_at: number;\n updated_at: number;\n resolved_at: number | null;\n deleted_at: number | null;\n}\n\nexport interface WikiEvent {\n id: string;\n entity_id: string;\n event_type: 'observation' | 'decision' | 'action' | 'outcome';\n summary: string;\n related_entry_id?: string | null;\n created_at: number;\n}\n\nexport interface WikiCheckpoint {\n entity_id: string;\n heal_checkpoint: number;\n memory_checkpoint: number;\n}\n\nexport interface ExtractedFact {\n title: string;\n body: string;\n tags: string[];\n confidence: 'certain' | 'inferred' | 'tentative';\n}\n\nexport interface ExtractedTask {\n description: string;\n priority: number;\n}\n\nexport interface LLMProvider {\n /**\n * Generates text using the developer's LLM of choice.\n * Expected to return the raw text response (typically a JSON string).\n */\n generateText: (params: { systemPrompt: string; userPrompt: string }) => Promise<string>;\n /**\n * Optional. When provided, enables semantic similarity search in `read()`.\n * Must return a stable-dimension float array for any input text.\n * Called once per fact on creation/update, and once per `read()` query.\n * When absent or throws, `read()` falls back to MiniSearch.\n */\n embed?: (text: string) => Promise<number[]>;\n}\n\n/**\n * Result of semantic ranking for a single fact.\n */\nexport interface VectorRankerSemanticResult {\n id: string;\n /** Cosine similarity in [-1, 1] when exact; implementations MAY document other monotonic scales. */\n semanticScore: number;\n}\n\n/**\n * Arguments passed to VectorRanker.rankBySimilarity.\n */\nexport interface VectorRankerRankArgs {\n entityId: string;\n /**\n * Query embedding. Treat as readonly — core provides a defensive copy,\n * but adapters MUST NOT mutate this array. Mutation can corrupt\n * WikiMemory's internal vector cache and JS-cosine fallback path.\n */\n queryVec: Float32Array | number[];\n /**\n * When set (MiniSearch pre-filter path): ranker MUST only produce results for ids in this set.\n * When omitted (full-entity semantic path): ranker scopes by entityId per its backing store contract.\n */\n candidateIds?: readonly string[];\n /**\n * Upper bound on how many distinct fact ids should receive a semanticScore in this call.\n * WikiMemory derives this from maxResults / candidate cardinality / documented oversampling policy.\n */\n limit: number;\n}\n\n/**\n * Optional backend for semantic candidate scoring / top-k retrieval.\n * When omitted, WikiMemory scores rows with embedding_blob / embedding TEXT in JS (cosine).\n */\nexport interface VectorRanker {\n /**\n * Return semantic scores for facts in scope, sorted descending by semanticScore (stable tie-breaking\n * not required — WikiMemory reapplies existing tie-breakers after blending).\n * Implementations SHOULD omit facts with no usable vector; callers treat missing ids like today's\n * \"no embedding\" rows (pure semantic: -2; hybrid: keyword-only portion).\n */\n rankBySimilarity(args: VectorRankerRankArgs): Promise<VectorRankerSemanticResult[]>;\n\n /**\n * Called after a fact's embedding is successfully persisted to embedding_blob (or cleared).\n * Hosts use this to keep sqlite-vec / external indexes consistent with SQLite as source of truth.\n *\n * On deletion paths (forget, prune, hard-delete), core awaits this hook to ensure ANN cleanup\n * completes before the deletion call resolves (GDPR compliance). Hook failures or timeouts on\n * those paths reject the deletion call.\n *\n * Treat `vector` as readonly — core provides a defensive copy, but adapters MUST NOT mutate.\n *\n * Optional: if omitted, hosts MUST document \"index rebuilt separately\" and accept stale ANN until rebuild.\n */\n onEmbeddingPersisted?(event: {\n entityId: string;\n factId: string;\n vector: Float32Array | null; // null = embedding removed / unusable\n }): void | Promise<void>;\n}\n\n/**\n * Fallback policy when rankBySimilarity rejects.\n */\nexport type VectorRankerFallback = 'js-cosine' | 'keyword' | 'empty' | 'throw';\n\nexport interface WikiOptions {\n config?: WikiConfig;\n llmProvider: LLMProvider;\n /**\n * Called when embedding-based retrieval is degraded or unavailable during `read()`.\n * This can happen when:\n * - `embed()` throws (e.g. network error, model unavailable) → falls back to keyword search\n * - `embed()` returns a vector with non-finite values (NaN / Infinity) → falls back to keyword search\n * - The query vector's dimension doesn't match stored embeddings (model switch;\n * resolve by calling `runReembed()`) → falls back to keyword search\n * - `vectorRanker` returns IDs that don't belong to the requested entity or don't exist\n * (ranker integrity issue; returned rows will be filtered out, reducing result count) →\n * may still use semantic ranking, but with degraded quality\n *\n * `read()` returns results (keyword fallback or degraded semantic) — this is a notification, not an error path.\n */\n onRetrievalFallback?: (error: Error) => void;\n\n /**\n * Optional backend for semantic candidate scoring / top-k retrieval.\n * When omitted, WikiMemory scores rows with embedding_blob / embedding TEXT in JS (cosine).\n */\n vectorRanker?: VectorRanker;\n\n /**\n * When rankBySimilarity throws. Default `'js-cosine'`.\n * Ignored when vectorRanker is undefined.\n */\n vectorRankerFallback?: VectorRankerFallback;\n\n /**\n * Called only when rankBySimilarity rejects (after embeddings path succeeded).\n * Invoked before applying vectorRankerFallback when that policy recovers or before rejecting when policy is 'throw'.\n */\n onVectorRankerFallback?: (info: {\n error: Error;\n /** Effective policy core will apply for this read (same as WikiOptions.vectorRankerFallback, default js-cosine). */\n policy: VectorRankerFallback;\n }) => void;\n\n /**\n * When true: after rankBySimilarity failure, once the recoverable fallback has finished\n * and read() will resolve, invoke onRetrievalFallback — after onVectorRankerFallback if set.\n * Ignored when vectorRankerFallback is 'throw'. Default false.\n */\n propagateRankerFailureToRetrievalFallback?: boolean;\n\n /**\n * When true (default), sanitize ranker errors before exposing via error.cause\n * to prevent credential leakage in host telemetry. Disable only when you\n * control the ranker implementation.\n *\n * Sanitization replaces error message/stack with a generic message preserving\n * only the error type (constructor name).\n */\n sanitizeRankerErrors?: boolean;\n\n /**\n * Timeout (ms) for onEmbeddingPersisted hook on GDPR deletion paths\n * (forget, _doPrune). Hook must complete within this window or the\n * deletion operation rejects. Default 30000.\n * Lower for interactive deletes; raise for slow remote ANN backends.\n */\n deletionHookTimeoutMs?: number;\n\n /**\n * Escape hatch: skip onEmbeddingPersisted on deletion paths entirely.\n * Use ONLY when the ANN backend is permanently decommissioned. Vectors\n * orphaned in the (unreachable) external index are accepted as a tradeoff.\n * NOT GDPR-safe for live indexes. Default false.\n */\n forceDeleteIgnoreRankerHook?: boolean;\n}\n\nexport interface MemoryBundle {\n facts: WikiFact[];\n tasks: WikiTask[];\n events: WikiEvent[];\n factScores?: Record<string, number>;\n metadata?: {\n query: string;\n entityIds: string[];\n tierWeights?: Record<string, number>;\n };\n}\n\nexport interface MemoryDump {\n generatedAt: number;\n entities: Record<string, MemoryBundle>;\n}\n\nexport interface FormattedMemoryDump {\n manifest: string;\n files: Array<{ name: string; content: string }>;\n}\n\nexport interface FormatContextOptions {\n format?: 'markdown' | 'plain';\n maxFacts?: number;\n maxTasks?: number;\n maxEvents?: number;\n includeConfidence?: boolean;\n includeTags?: boolean;\n includeEntityIds?: boolean;\n includeFactScores?: boolean;\n factWeights?: {\n confidence?: number;\n accessCount?: number;\n recency?: number;\n };\n}\n\nexport interface EntityStatus {\n ingesting: boolean;\n librarian: boolean;\n heal: boolean;\n}\n\n/**\n * All operations that can appear in a {@link WikiBusyError}.\n *\n * @remarks **Breaking change from v2.x** — the union previously only contained\n * `'ingest' | 'librarian' | 'heal' | 'prune' | 'reembed'`. The values `'import'`\n * and `'forget'` were added in v3.0. Exhaustive `switch` / narrowing on this type\n * must be updated (or given a `default` arm) to compile without errors.\n */\nexport type WikiBusyOperation =\n | 'ingest'\n | 'librarian'\n | 'heal'\n | 'prune'\n | 'reembed'\n | 'import'\n | 'forget';\n\n/**\n * Thrown when a background mutator is already running for the requested entity.\n */\nexport class WikiBusyError extends Error {\n readonly operation: WikiBusyOperation;\n readonly entityId: string;\n\n constructor(operation: WikiBusyOperation, entityId: string) {\n super(`${operation} already running for entity ${entityId}`);\n this.name = 'WikiBusyError';\n this.operation = operation;\n this.entityId = entityId;\n }\n}\n\nexport class PrunePartialFailureError extends Error {\n readonly deleted: number;\n readonly failedAt: string;\n readonly remaining: number;\n readonly deletedTasks: number;\n readonly deletedEvents: number;\n override readonly cause: Error;\n\n constructor(\n deleted: number,\n failedAt: string,\n remaining: number,\n cause: Error,\n deletedTasks: number = 0,\n deletedEvents: number = 0,\n ) {\n super(`Prune partially failed: deleted ${deleted}, failed at ${failedAt}, ${remaining} remaining`);\n this.name = 'PrunePartialFailureError';\n this.deleted = deleted;\n this.failedAt = failedAt;\n this.remaining = remaining;\n this.deletedTasks = deletedTasks;\n this.deletedEvents = deletedEvents;\n this.cause = cause;\n }\n}\n\n","export const LIBRARIAN_SYSTEM_PROMPT = `You are a knowledge extraction agent. Your job is to analyze recent episodic events and extract stable facts and actionable tasks about the user or entity.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"facts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }],\n \"tasks\": [{ \"description\": \"string\", \"priority\": \"number (0-10)\" }]\n}\nKeep facts concise. Do not return markdown, just raw JSON.`;\n\nexport const HEAL_SYSTEM_PROMPT = `You are a memory grooming agent. Your job is to review a full dump of facts and recent events to resolve contradictions, downgrade stale claims, and flag obsolete facts for deletion.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"downgraded\": [\"string (fact IDs)\"],\n \"deleted\": [\"string (fact IDs)\"],\n \"newFacts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }]\n}\nDo not return markdown, just raw JSON.`;\n\nexport const INGEST_SYSTEM_PROMPT = `You are a document ingestion agent. Your job is to extract factual knowledge from the provided document chunk.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"facts\": [{ \"title\": \"string (max 80 chars)\", \"body\": \"string (max 800 chars)\", \"tags\": [\"string\"], \"confidence\": \"certain|inferred|tentative\" }]\n}\nExtract verbatim factual content. Do not return markdown, just raw JSON.`;\n","export function cosineSimilarity(a: ArrayLike<number>, b: ArrayLike<number>): number {\n let dot = 0, normA = 0, normB = 0;\n const len = Math.min(a.length, b.length);\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n","export function parseEmbedding(\n blob: Uint8Array | null | undefined,\n text: string | null | undefined\n): Float32Array | null {\n if (blob && blob.byteLength > 0) {\n if (blob.byteLength % 4 !== 0) return null;\n // Copy into fresh ArrayBuffer — SQLite drivers may return pooled Buffer\n // objects that get reused across queries, silently corrupting cached vectors.\n const copy = new ArrayBuffer(blob.byteLength);\n new Uint8Array(copy).set(blob);\n const vector = new Float32Array(copy);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n }\n if (text) {\n try {\n const arr: unknown = JSON.parse(text);\n if (!Array.isArray(arr) || !arr.every((v: unknown) => typeof v === 'number' && isFinite(v))) return null;\n const vector = new Float32Array(arr as number[]);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n } catch { return null; }\n }\n return null;\n}\n","export function normalizeEntityIds(entityId: string | string[]): string[] {\n const input = Array.isArray(entityId) ? entityId : [entityId];\n const seen = new Set<string>();\n const normalized: string[] = [];\n\n for (const id of input) {\n if (seen.has(id)) continue;\n seen.add(id);\n normalized.push(id);\n }\n\n return normalized;\n}\n\nexport function sanitizeTierWeights(\n entityIds: readonly string[],\n tierWeights: Record<string, number> | undefined,\n): Record<string, number> | undefined {\n if (tierWeights === undefined) return undefined;\n\n const sanitized = Object.create(null) as Record<string, number>;\n for (const entityId of entityIds) {\n const raw = tierWeights[entityId];\n if (raw === undefined || !Number.isFinite(raw)) {\n sanitized[entityId] = 1;\n } else {\n sanitized[entityId] = Math.max(0, raw);\n }\n }\n return sanitized;\n}\n\nexport function applyTierWeight(\n score: number,\n entityId: string,\n sanitizedTierWeights: Record<string, number> | undefined,\n): number {\n const weight = sanitizedTierWeights?.[entityId] ?? 1;\n // Weight=0 → sentinel -Infinity so zero-weight entities always sort below any\n // finite score, including negative cosine values from the pure-semantic path.\n if (weight === 0) return -Infinity;\n return score * weight;\n}\n\nexport function shouldExposeReadMetadata(\n entityId: string | string[],\n): boolean {\n return Array.isArray(entityId);\n}\n","import type { SQLiteAdapter } from './types';\nimport { setupDatabase } from './db/schema';\nimport { MIGRATIONS, CURRENT_SCHEMA_VERSION } from './db/migrations';\nimport { WikiOptions, MemoryBundle, MemoryDump, WikiEvent, WikiFact, WikiTask, WikiCheckpoint, ExtractedFact, ExtractedTask, WikiBusyError, PrunePartialFailureError, EntityStatus, ReadOptions } from './types';\nimport { LIBRARIAN_SYSTEM_PROMPT, HEAL_SYSTEM_PROMPT, INGEST_SYSTEM_PROMPT } from './prompts';\nimport MiniSearch from 'minisearch';\nimport { cosineSimilarity } from './utils/cosine';\nimport { parseEmbedding } from './utils/embedding';\nimport { applyTierWeight, normalizeEntityIds, sanitizeTierWeights, shouldExposeReadMetadata } from './readOptions';\n\nexport { WikiBusyError, PrunePartialFailureError } from './types';\n\n/**\n * Private symbol to mark timeout errors thrown by WikiMemory (not from ranker).\n * Used to distinguish WikiMemory's own timeout errors from ranker errors that might contain \"timed out\" in message.\n */\nconst HOOK_TIMEOUT_MARKER = Symbol('WikiMemoryHookTimeout');\n\ntype ReadCandidateRowMetadata = {\n id: string;\n entity_id: string;\n updated_at: number | null;\n access_count: number | null;\n};\n\ntype ReadCandidateRowWithEmbeddings = ReadCandidateRowMetadata & {\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n};\n\n\nfunction parseJsonResponse<T>(text: string): T {\n const firstBrace = text.indexOf('{');\n const firstBracket = text.indexOf('[');\n\n let start: number;\n let openChar: string;\n let closeChar: string;\n\n if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n openChar = '{';\n closeChar = '}';\n } else if (firstBracket !== -1) {\n start = firstBracket;\n openChar = '[';\n closeChar = ']';\n } else {\n throw new SyntaxError('No JSON object/array found in LLM response');\n }\n\n // Walk from `start`, tracking nesting depth and skipping strings/escapes,\n // so we stop at the true matching close bracket rather than the last one.\n let depth = 0;\n let inString = false;\n let escape = false;\n let end = -1;\n for (let i = start; i < text.length; i++) {\n const ch = text[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === openChar) { depth++; continue; }\n if (ch === closeChar) {\n depth--;\n if (depth === 0) { end = i; break; }\n }\n }\n\n if (end === -1) throw new SyntaxError('No JSON object/array found in LLM response');\n return JSON.parse(text.slice(start, end + 1)) as T;\n}\n\nfunction generateId(prefix: string = '') {\n return prefix + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n}\n\nfunction safeSlice(value: string, start: number, end?: number): string {\n const length = value.length;\n let safeStart = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);\n let safeEnd = end === undefined\n ? length\n : end < 0\n ? Math.max(length + end, 0)\n : Math.min(end, length);\n\n if (safeStart > safeEnd) {\n [safeStart, safeEnd] = [safeEnd, safeStart];\n }\n\n if (\n safeStart > 0 &&\n safeStart < length &&\n value.charCodeAt(safeStart) >= 0xDC00 &&\n value.charCodeAt(safeStart) <= 0xDFFF &&\n value.charCodeAt(safeStart - 1) >= 0xD800 &&\n value.charCodeAt(safeStart - 1) <= 0xDBFF\n ) {\n safeStart--;\n }\n\n if (\n safeEnd > 0 &&\n safeEnd < length &&\n value.charCodeAt(safeEnd - 1) >= 0xD800 &&\n value.charCodeAt(safeEnd - 1) <= 0xDBFF &&\n value.charCodeAt(safeEnd) >= 0xDC00 &&\n value.charCodeAt(safeEnd) <= 0xDFFF\n ) {\n safeEnd--;\n }\n\n return value.slice(safeStart, safeEnd);\n}\n\nfunction chunkText(\n input: string,\n maxChunkLength: number,\n overlap: number\n): { chunks: string[]; truncated: boolean } {\n const text = input.trim();\n if (text.length === 0) return { chunks: [], truncated: false };\n if (!Number.isInteger(maxChunkLength) || maxChunkLength < 2) {\n throw new Error('maxChunkLength must be an integer >= 2');\n }\n if (!Number.isInteger(overlap) || overlap < 0 || overlap >= maxChunkLength) {\n throw new Error('overlap must be a non-negative integer < maxChunkLength');\n }\n\n const chunks: string[] = [];\n let truncated = false;\n let cursor = 0;\n const halfMax = Math.floor(maxChunkLength / 2);\n\n while (cursor < text.length) {\n const remaining = text.length - cursor;\n if (remaining <= maxChunkLength) {\n chunks.push(safeSlice(text, cursor, text.length));\n break;\n }\n\n const windowEnd = cursor + maxChunkLength;\n const minSplit = cursor + halfMax;\n\n // 1. paragraph break\n let splitPoint = -1;\n const paraIdx = text.lastIndexOf('\\n\\n', windowEnd);\n if (paraIdx >= minSplit && paraIdx + 2 <= windowEnd) {\n splitPoint = paraIdx + 2;\n }\n\n // 2. sentence terminator (single left-to-right pass, no lookahead regex)\n if (splitPoint === -1) {\n let lastTerm = -1;\n for (let i = minSplit; i < windowEnd - 1; i++) {\n const ch = text[i];\n if ((ch === '.' || ch === '!' || ch === '?') && /\\s/.test(text[i + 1])) {\n lastTerm = i + 2; // include the terminator + whitespace\n }\n }\n if (lastTerm !== -1 && lastTerm <= windowEnd) splitPoint = lastTerm;\n }\n\n // 3. whitespace\n if (splitPoint === -1) {\n for (let i = windowEnd - 1; i >= minSplit; i--) {\n if (/\\s/.test(text[i])) {\n splitPoint = i + 1;\n break;\n }\n }\n }\n\n // 4. hard cut\n if (splitPoint === -1) {\n truncated = true;\n splitPoint = windowEnd;\n }\n\n chunks.push(safeSlice(text, cursor, splitPoint));\n const next = Math.max(splitPoint - overlap, cursor + 1);\n cursor = next;\n }\n\n return { chunks, truncated };\n}\n\nasync function withConcurrency<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<T[]> {\n const results: T[] = new Array(tasks.length);\n let index = 0;\n let failed = false;\n let firstError: unknown;\n async function worker() {\n while (index < tasks.length && !failed) {\n const i = index++;\n try {\n results[i] = await tasks[i]();\n } catch (e) {\n if (!failed) { failed = true; firstError = e; }\n return;\n }\n }\n }\n const workerCount = tasks.length === 0 ? 0 : Math.min(Math.max(limit, 1), tasks.length);\n await Promise.allSettled(Array.from({ length: workerCount }, worker));\n if (failed) throw firstError;\n return results;\n}\n\nfunction clip(value: string, max: number): string {\n if (typeof value !== 'string') return '';\n const s = value.trim();\n return s.length <= max ? s : safeSlice(s, 0, max).trimEnd();\n}\n\nfunction validateTags(tags: any[]): string[] {\n if (!Array.isArray(tags)) return [];\n return tags\n .filter(t => typeof t === 'string')\n .map(t => t.trim().toLowerCase())\n .filter(t => t.length > 0 && t.length <= 40)\n .slice(0, 6);\n}\n\nfunction validateFact(fact: any): ExtractedFact | null {\n if (typeof fact?.title !== 'string' || typeof fact?.body !== 'string') return null;\n const title = clip(fact.title, 80);\n const body = clip(fact.body, 800);\n if (!title || !body) return null;\n \n let confidence = fact.confidence;\n if (confidence !== 'certain' && confidence !== 'tentative') confidence = 'inferred';\n \n return {\n ...fact,\n title,\n body,\n confidence,\n tags: validateTags(fact.tags)\n };\n}\n\nfunction validateTask(task: any): ExtractedTask | null {\n if (typeof task?.description !== 'string') return null;\n const description = clip(task.description, 200);\n if (!description) return null;\n \n let priority = task.priority;\n if (typeof priority !== 'number' || !isFinite(priority)) priority = 0;\n \n return {\n ...task,\n description,\n priority\n };\n}\n\nfunction normalizeSourceRef(value: string): string | null {\n if (typeof value !== 'string') return null;\n const cleaned = value.replace(/[^A-Za-z0-9._\\- ]/g, '').trim().slice(0, 255);\n return cleaned.length > 0 ? cleaned : null;\n}\n\nfunction normalizeSourceHash(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n return /^[0-9a-f]{64}$/i.test(value) ? value.toLowerCase() : null;\n}\n\n\nfunction titleTokens(title: string): Set<string> {\n return new Set(title.toLowerCase().replace(/[^a-z0-9\\s]/g, '').split(/\\s+/).filter(t => t.length >= 3));\n}\n\nfunction jaccardScore(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n const intersection = new Set([...a].filter(x => b.has(x)));\n const union = new Set([...a, ...b]);\n return intersection.size / union.size;\n}\n\nconst FUZZY_THRESHOLD = 0.5;\nconst MIN_TOKENS_TO_QUALIFY = 3;\n\nexport class WikiMemory {\n private db: SQLiteAdapter;\n private prefix: string;\n private options: WikiOptions;\n private activeMaintenanceJobs = new Set<string>();\n private activeIngestJobs = new Set<string>();\n private statusSubscribers = new Map<\n string,\n Set<{ callback: (s: EntityStatus) => void; last: EntityStatus }>\n >();\n private miniSearch = new MiniSearch<{ id: string; entity_id: string; title: string; body: string; tags: string }>({\n fields: ['title', 'body', 'tags'],\n storeFields: ['entity_id'],\n searchOptions: {\n boost: { title: 2 },\n fuzzy: 0.2,\n prefix: true,\n },\n });\n private miniSearchEntryIdsByEntity = new Map<string, Set<string>>();\n /**\n * Maximum number of entities whose parsed embedding vectors are held in\n * memory. This cap is intentionally conservative so the cache remains safe\n * on memory-constrained runtimes (e.g., mobile/Expo).\n */\n private static readonly MAX_VECTOR_CACHE_ENTITIES = 16;\n /**\n * Maximum number of fact vectors cached per entity. Keep this high enough to\n * preserve the parsed-embedding reuse optimization for common mid-sized\n * entities while still maintaining a bounded memory footprint.\n */\n private static readonly MAX_VECTOR_CACHE_FACTS_PER_ENTITY = 500;\n private vectorCache: Map<string, Map<string, Float32Array>> = new Map();\n\n private normalizeMiniSearchRow(row: {\n id: string; entity_id: string; title: string; body: string; tags: string;\n }): { id: string; entity_id: string; title: string; body: string; tags: string } {\n return {\n id: row.id,\n entity_id: row.entity_id,\n title: row.title,\n body: row.body,\n tags: (() => {\n try {\n const parsed = JSON.parse(row.tags);\n return Array.isArray(parsed) ? parsed.join(' ') : row.tags;\n } catch {\n return row.tags;\n }\n })(),\n };\n }\n\n private async rebuildMiniSearchIndex(entityId?: string): Promise<void> {\n if (entityId) {\n const rows = await this.db.getAllAsync<{\n id: string; entity_id: string; title: string; body: string; tags: string;\n }>(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL AND entity_id = ?`,\n [entityId],\n );\n\n const previousIds = this.miniSearchEntryIdsByEntity.get(entityId);\n if (previousIds) {\n for (const id of previousIds) {\n this.miniSearch.discard(id);\n }\n }\n\n const documents = rows.map(row => this.normalizeMiniSearchRow(row));\n if (documents.length > 0) {\n this.miniSearch.addAll(documents);\n }\n\n this.miniSearchEntryIdsByEntity.set(entityId, new Set(documents.map(document => document.id)));\n return;\n }\n\n const rows = await this.db.getAllAsync<{\n id: string; entity_id: string; title: string; body: string; tags: string;\n }>(`SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL`);\n\n this.miniSearch.removeAll();\n this.miniSearchEntryIdsByEntity.clear();\n\n const documents = rows.map(row => this.normalizeMiniSearchRow(row));\n if (documents.length > 0) {\n this.miniSearch.addAll(documents);\n }\n\n for (const document of documents) {\n const ids = this.miniSearchEntryIdsByEntity.get(document.entity_id) ?? new Set<string>();\n ids.add(document.id);\n this.miniSearchEntryIdsByEntity.set(document.entity_id, ids);\n }\n }\n\n private async storeEmbeddingDimension(dim: number): Promise<void> {\n const existing = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n if (existing) {\n const storedDim = parseInt(existing.value, 10);\n if (storedDim !== dim) {\n console.warn(\n `[WikiMemory] Embedding dimension mismatch: stored ${storedDim}, got ${dim}. ` +\n `Call runReembed() to rebuild embeddings with the new model.`\n );\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(dim)]\n );\n }\n // Do NOT clear 'embedding_dimension_mismatch' here: other facts may still hold\n // old-dimension blobs written during a previous model. Only _reconcileEmbeddingDimension()\n // (called after a full runReembed) may clear the flag once it confirms all stored\n // blobs match the new canonical dimension.\n } else {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension', ?)`,\n [String(dim)]\n );\n }\n }\n\n /**\n * After a successful runReembed(), promote the pending `embedding_dimension_mismatch`\n * value to the canonical `embedding_dimension` key and clear the mismatch flag.\n * This ensures future read() calls use embedding-based retrieval rather than staying\n * stuck on the MiniSearch fallback.\n */\n private async _reconcileEmbeddingDimension(): Promise<void> {\n const mismatch = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (!mismatch) return;\n\n const newDim = parseInt(mismatch.value, 10);\n // Check whether any non-deleted fact still stores a blob with a different byte\n // length. If so, those facts haven't been re-embedded yet and the mismatch flag\n // must stay in place so read() keeps falling back to MiniSearch for them.\n // A row blocks mismatch-flag removal if:\n // (a) it has a BLOB whose dimension differs from the new model, OR\n // (b) it has only a TEXT vector (embedding_blob IS NULL) — TEXT rows were\n // written by an older model and must be converted by runReembed() before\n // they are safe to score against the new query dimension.\n const residual = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE deleted_at IS NULL\n AND (\n (embedding_blob IS NOT NULL AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?)\n OR (embedding_blob IS NULL AND embedding IS NOT NULL)\n )`,\n [newDim]\n );\n // Only promote and clear once every stored vector uses the new dimension.\n // Promoting before all rows are converted would leave read() in an inconsistent\n // state: the canonical dim would point at the new model while TEXT-only or\n // wrong-dim blobs still exist, causing those rows to score silently as 0.\n if (!residual || residual.cnt === 0) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension', ?)`,\n [mismatch.value]\n );\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n }\n }\n\n private async embedFact(fact: { id: string; entity_id: string; title: string; body: string; tags: string | string[] }): Promise<boolean> {\n const embedFn = this.options.llmProvider.embed;\n if (!embedFn) return false;\n let tagsStr: string;\n if (Array.isArray(fact.tags)) {\n tagsStr = fact.tags.join(' ');\n } else {\n try {\n const parsed = JSON.parse(fact.tags);\n tagsStr = Array.isArray(parsed) ? parsed.join(' ') : fact.tags;\n } catch {\n tagsStr = fact.tags;\n }\n }\n const text = `${fact.title} ${fact.body} ${tagsStr}`.trim();\n try {\n const vector = await embedFn(text);\n // Validate before persisting: an empty or non-finite vector would poison\n // embedding_dimension and write unusable data to embedding_blob.\n if (vector.length === 0 || !vector.every(v => typeof v === 'number' && isFinite(v))) {\n console.warn(`[WikiMemory] embedFact: embed() returned an invalid vector for ${fact.id}; skipping.`);\n return false;\n }\n const float32Vector = new Float32Array(vector);\n let hasNonFinite = false;\n for (let i = 0; i < float32Vector.length; i++) {\n if (!isFinite(float32Vector[i])) { hasNonFinite = true; break; }\n }\n if (hasNonFinite) {\n console.warn(`[WikiMemory] embedFact: embed() returned values that overflow float32 for ${fact.id}; skipping.`);\n return false;\n }\n await this.storeEmbeddingDimension(float32Vector.length);\n const blob = new Uint8Array(float32Vector.buffer);\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET embedding_blob = ?, embedding = NULL WHERE id = ?`,\n [blob, fact.id]\n );\n // Isolate hook failure: embedding was persisted successfully even if external index sync fails\n try {\n await this._notifyEmbeddingPersisted(fact.entity_id, fact.id, float32Vector);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed for ${fact.id}:`, hookErr);\n }\n return true;\n } catch (err) {\n console.warn(`[WikiMemory] embedFact failed for ${fact.id}:`, err);\n return false;\n }\n }\n\n private _librarianKey(entityId: string) { return `${this.prefix}:${entityId}:librarian`; }\n private _healKey(entityId: string) { return `${this.prefix}:${entityId}:heal`; }\n private _warnCrossEntityCollision(type: 'entry' | 'task', id: string, existingEntityId: string, targetEntityId: string): void {\n console.warn(`[WikiMemory] importDump: ${type} id \"${id}\" already belongs to entity \"${existingEntityId}\"; skipping for entity \"${targetEntityId}\"`);\n }\n\n /** Maps pre-rename enum strings from older dumps to current source_type values. */\n private _normalizeImportedSourceType(\n raw: string,\n ctx?: { entityId: string; factId: string },\n ): WikiFact['source_type'] {\n if (raw === 'user_document') return 'immutable_document';\n if (raw === 'agent_inferred') return 'librarian_inferred';\n const allowed: WikiFact['source_type'][] = ['user_stated', 'librarian_inferred', 'user_confirmed', 'immutable_document'];\n if ((allowed as string[]).includes(raw)) return raw as WikiFact['source_type'];\n const where =\n ctx !== undefined ? ` for entity \"${ctx.entityId}\" fact \"${ctx.factId}\"` : '';\n throw new Error(\n `importDump: invalid source_type \"${raw}\"${where} (expected one of: ${allowed.join(', ')}, or legacy aliases user_document / agent_inferred)`\n );\n }\n\n private async assertNoLegacySourceTypes(): Promise<void> {\n const legacyProbe = await this.db.getFirstAsync<{ one: number }>(\n `SELECT 1 AS one FROM ${this.prefix}entries\n WHERE source_type IN ('user_document', 'agent_inferred')\n LIMIT 1`,\n []\n );\n\n if (!legacyProbe) return;\n\n const legacyCount = await this.db.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}entries\n WHERE source_type IN ('user_document', 'agent_inferred')`,\n []\n );\n\n const count = legacyCount?.count ?? 0;\n const migrationSQL = `\n-- Migrate legacy source_type values (targets your WikiMemory prefix: ${this.prefix})\nUPDATE ${this.prefix}entries SET source_type = 'immutable_document' WHERE source_type = 'user_document';\nUPDATE ${this.prefix}entries SET source_type = 'librarian_inferred' WHERE source_type = 'agent_inferred';\n `.trim();\n\n throw new Error(\n `Database contains ${count} entries with legacy source_type values ('user_document' or 'agent_inferred'). ` +\n `These enum values were renamed in this release. Running without migration would allow legacy 'user_document' facts to bypass ` +\n `immutability guards, causing data corruption.\\n\\n${migrationSQL}\\n\\n` +\n `After running the migration SQL, restart your application.`\n );\n }\n\n private async _notifyEmbeddingPersisted(\n entityId: string,\n factId: string,\n vector: Float32Array | null,\n ): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n // Defensive copy prevents hooks from mutating cache/fallback/persisted-blob vectors.\n // .slice() on Float32Array allocates a fresh ArrayBuffer (not a view).\n const vectorCopy = vector ? vector.slice() : null;\n await this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n });\n }\n\n /**\n * GDPR-critical variant: awaits the hook with a timeout and rethrows failures.\n * Use ONLY on deletion paths. forget() calls after soft-delete UPDATE; runPrune()\n * calls before hard DELETE. For best-effort sync, use _notifyEmbeddingPersisted.\n */\n private async _notifyEmbeddingPersistedOrThrow(\n entityId: string,\n factId: string,\n vector: Float32Array | null,\n ): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n if (this.options.forceDeleteIgnoreRankerHook === true) return;\n\n const vectorCopy = vector ? vector.slice() : null;\n const rawTimeout = this.options.deletionHookTimeoutMs ?? 30_000;\n if (typeof rawTimeout !== 'number' || !Number.isFinite(rawTimeout) || rawTimeout <= 0) {\n throw new Error('Invalid deletionHookTimeoutMs: must be a positive finite number');\n }\n const timeoutMs = rawTimeout;\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(\n () => {\n const timeoutError = new Error(`onEmbeddingPersisted timed out after ${timeoutMs}ms`);\n (timeoutError as any)[HOOK_TIMEOUT_MARKER] = true;\n reject(timeoutError);\n },\n timeoutMs,\n );\n });\n\n const hookPromise = Promise.resolve(\n this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n }),\n );\n\n try {\n await Promise.race([hookPromise, timeoutPromise]);\n } catch (err) {\n // Suppress late rejections from hook if timeout won\n hookPromise.catch(() => {});\n throw err;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n\n constructor(db: SQLiteAdapter, options: WikiOptions) {\n this.db = db;\n this.options = options;\n this.prefix = options.config?.tablePrefix || 'llm_wiki_';\n }\n\n async setup() {\n // Probe entries-table existence BEFORE creating any tables. setupDatabase()\n // uses IF NOT EXISTS throughout, so once it has run the entries table always\n // exists and the fresh-install branch would be unreachable. Future migrations\n // that ALTER TABLE would also fail if run against a schema already at the\n // target version but inferred as legacy because the probe ran too late.\n const entriesExistedBeforeSetup = await this.db.getFirstAsync<{ name: string }>(\n `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,\n [`${this.prefix}entries`]\n );\n\n await setupDatabase(this.db, this.prefix);\n\n let currentVersion: number;\n\n if (!entriesExistedBeforeSetup) {\n // Fresh install — all tables just created at current schema; no migrations needed.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(CURRENT_SCHEMA_VERSION)]\n );\n currentVersion = CURRENT_SCHEMA_VERSION;\n } else {\n // Existing install — check meta for schema version.\n const metaRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'schema_version'`\n );\n\n if (metaRow) {\n currentVersion = parseInt(metaRow.value, 10);\n if (!Number.isFinite(currentVersion)) currentVersion = 0;\n } else {\n // Legacy install without meta row — infer version from porter probe.\n const ftsMeta = await this.db.getFirstAsync<{ sql: string | null }>(\n `SELECT sql FROM sqlite_master WHERE type='table' AND name=?`,\n [`${this.prefix}entries_fts`]\n );\n const hasPorter = /tokenize\\s*=\\s*['\"]porter\\s+unicode61['\"]/i.test(ftsMeta?.sql ?? '');\n currentVersion = hasPorter ? 1 : 0;\n }\n }\n\n // Run pending migrations in order.\n for (const migration of MIGRATIONS) {\n if (migration.version > currentVersion) {\n await migration.run(this.db, this.prefix);\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(migration.version)]\n );\n currentVersion = migration.version;\n }\n }\n\n // Ensure meta row exists for legacy installs already at current version\n // (porter present, no meta row) — the migration loop may not have written it.\n if (entriesExistedBeforeSetup) {\n const metaCheck = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'schema_version'`\n );\n if (!metaCheck) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('schema_version', ?)`,\n [String(currentVersion)]\n );\n }\n }\n\n // Fail before any other mutating passes (e.g. source_ref normalization) so we never\n // partially \"repair\" a DB that is still on legacy source_type strings.\n if (entriesExistedBeforeSetup) {\n await this.assertNoLegacySourceTypes();\n }\n\n // Migration: normalize any existing source_ref values that were stored before the\n // allowlist rule ([^A-Za-z0-9._\\- ] → strip) was introduced. Read-then-update in\n // JS so the normalization is guaranteed to match what normalizeSourceRef() produces,\n // regardless of which characters the old normalization left behind.\n // The WHERE clause pre-filters to rows that contain any character outside the\n // allowlist (checking leading/trailing whitespace, slashes, backslashes, NUL, and\n // the full ASCII non-allowlist range via GLOB) so that already-normalized\n // rows are never fetched. Idempotent: after the first run no rows match the filter.\n type Row = { rowid: number; source_ref: string };\n const rows = await this.db.getAllAsync<Row>(`\n SELECT rowid, source_ref FROM ${this.prefix}entries\n WHERE source_ref IS NOT NULL\n AND (\n TRIM(source_ref) != source_ref\n OR INSTR(source_ref, '/') > 0\n OR INSTR(source_ref, '\\\\') > 0\n OR INSTR(source_ref, CHAR(0)) > 0\n OR source_ref GLOB '*[^-A-Za-z0-9._ ]*'\n )\n `);\n await this.db.withTransactionAsync(async () => {\n for (const row of rows) {\n const normalized = normalizeSourceRef(row.source_ref);\n if (normalized !== row.source_ref) {\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET source_ref = ? WHERE rowid = ?`,\n [normalized, row.rowid]\n );\n }\n }\n });\n\n await this.rebuildMiniSearchIndex();\n }\n\n async hasChanged(entityId: string, sourceRef: string, sourceHash: string): Promise<boolean> {\n const normalizedRef = normalizeSourceRef(sourceRef);\n if (!normalizedRef) {\n throw new Error(`Invalid sourceRef: \"${sourceRef}\"`);\n }\n const normalizedHash = normalizeSourceHash(sourceHash);\n if (!normalizedHash) {\n throw new Error(`Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)`);\n }\n const row = await this.db.getFirstAsync<{ source_hash: string | null }>(\n `SELECT source_hash FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT 1`,\n [entityId, normalizedRef]\n );\n if (!row) return true;\n const normalizedStoredHash = row.source_hash ? normalizeSourceHash(row.source_hash) : null;\n return normalizedStoredHash !== normalizedHash;\n }\n\n private _pruneKey(entityId: string) { return `${this.prefix}:${entityId}:prune`; }\n private _reembedKey(entityId: string) { return `${this.prefix}:${entityId}:reembed`; }\n private _globalReembedKey() { return `${this.prefix}:reembed`; }\n private _importKey(entityId: string) { return `${this.prefix}:${entityId}:import`; }\n private _globalImportKey() { return `${this.prefix}:import`; }\n private _forgetKey(entityId: string) { return `${this.prefix}:${entityId}:forget`; }\n private _isReembedActive(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId))\n || this.activeMaintenanceJobs.has(this._globalReembedKey());\n }\n private _isImportActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._importKey(entityId))\n || this.activeMaintenanceJobs.has(this._globalImportKey());\n }\n private _isForgetActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._forgetKey(entityId));\n }\n /** Returns true if any maintenance job has the given operation suffix (e.g. ':prune'). */\n private _isAnyMaintenanceActiveWithSuffix(suffix: string): boolean {\n const entityKeyPrefix = `${this.prefix}:`;\n for (const k of this.activeMaintenanceJobs) {\n if (k.startsWith(entityKeyPrefix) && k.endsWith(suffix)) return true;\n }\n return false;\n }\n /** Returns true if any ingest job is active for the given entity. */\n private _isIngestActiveFor(entityId: string): boolean {\n const entityKeyPrefix = `${this.prefix}:${entityId}:`;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(entityKeyPrefix)) return true;\n }\n return false;\n }\n\n private _copyEntityStatus(s: EntityStatus): EntityStatus {\n return { ingesting: s.ingesting, librarian: s.librarian, heal: s.heal };\n }\n\n private _notifyStatusSubscribers(entityId: string): void {\n const set = this.statusSubscribers.get(entityId);\n if (!set || set.size === 0) return;\n // Snapshot for safe iteration if a callback unsubscribes or subscribes.\n // Re-read status each iteration so re-entrant mutations cannot leave stale\n // snapshots for remaining subscribers.\n for (const entry of Array.from(set)) {\n if (!set.has(entry)) continue; // unsubscribed during this emission\n const next = this.getEntityStatus(entityId);\n if (\n entry.last.ingesting === next.ingesting &&\n entry.last.librarian === next.librarian &&\n entry.last.heal === next.heal\n ) continue;\n entry.last = this._copyEntityStatus(next);\n try {\n entry.callback(this._copyEntityStatus(next));\n } catch (err) {\n console.error(`[WikiMemory.subscribeEntityStatus] callback error for entityId=\"${entityId}\" during transition emission`, err);\n }\n }\n }\n\n private _validatePruneDuration(value: number | null | undefined, name: string): void {\n if (value !== null && value !== undefined && (typeof value !== 'number' || !isFinite(value) || value < 0)) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number or null`);\n }\n }\n\n async runPrune(\n entityId: string,\n options?: {\n retainSoftDeletedFor?: number | null;\n retainEventsFor?: number | null;\n vacuum?: boolean;\n }\n ): Promise<{ entries: number; tasks: number; events: number }> {\n const pruneKey = this._pruneKey(entityId);\n // Prune must not run concurrently with librarian, heal, ingest, import, or another\n // prune for the same entity.\n const ingestPrefix = `${this.prefix}:${entityId}:`;\n let isIngestRunning = false;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(ingestPrefix)) { isIngestRunning = true; break; }\n }\n let blockingOperation: 'prune' | 'librarian' | 'heal' | 'ingest' | 'reembed' | 'import' | 'forget' | null = null;\n if (this.activeMaintenanceJobs.has(pruneKey)) {\n blockingOperation = 'prune';\n } else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n blockingOperation = 'librarian';\n } else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n blockingOperation = 'heal';\n } else if (this._isReembedActive(entityId)) {\n blockingOperation = 'reembed';\n } else if (isIngestRunning) {\n blockingOperation = 'ingest';\n } else if (this._isImportActiveFor(entityId)) {\n blockingOperation = 'import';\n } else if (this._isForgetActiveFor(entityId)) {\n blockingOperation = 'forget';\n }\n if (blockingOperation !== null) {\n throw new WikiBusyError(blockingOperation, entityId);\n }\n this.activeMaintenanceJobs.add(pruneKey);\n try {\n const retainSoftDeletedFor = options?.retainSoftDeletedFor !== undefined\n ? options.retainSoftDeletedFor\n : (this.options.config?.pruneRetainSoftDeletedFor ?? 7);\n const retainEventsFor = options?.retainEventsFor !== undefined\n ? options.retainEventsFor\n : (this.options.config?.pruneEventsAfter ?? 30);\n const vacuum = options?.vacuum ?? false;\n\n this._validatePruneDuration(retainSoftDeletedFor, 'retainSoftDeletedFor');\n this._validatePruneDuration(retainEventsFor, 'retainEventsFor');\n\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n let deletedEvents = 0;\n\n if (retainSoftDeletedFor !== null) {\n const cutoff = now - retainSoftDeletedFor * 86400000;\n\n const entriesToDelete = await this.db.getAllAsync<{ id: string; entity_id: string }>(\n `SELECT id, entity_id FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff]\n );\n\n // Hook-before-delete: await hook for each row, accumulate successes, commit partial on failure\n const succeeded: Array<{ entity_id: string; id: string }> = [];\n let failure: { factId: string; cause: unknown } | null = null;\n\n for (const row of entriesToDelete) {\n try {\n await this._notifyEmbeddingPersistedOrThrow(row.entity_id, row.id, null);\n succeeded.push({ entity_id: row.entity_id, id: row.id });\n } catch (err) {\n failure = { factId: row.id, cause: err };\n break;\n }\n }\n\n if (succeeded.length > 0) {\n // Delete in chunks to avoid SQLite bind-parameter limit (typically 999)\n const chunkSize = 500;\n for (let i = 0; i < succeeded.length; i += chunkSize) {\n const chunk = succeeded.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const entryResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ? AND id IN (${placeholders})`,\n [entityId, cutoff, ...chunk.map((r) => r.id)],\n );\n deletedEntries += entryResult.changes;\n }\n }\n\n // Delete tasks (independent of entry hook success/failure)\n const taskResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}tasks\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff]\n );\n deletedTasks = taskResult.changes;\n\n if (failure) {\n // Rebuild index and clear cache to reflect successful partial deletions\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n const remaining = entriesToDelete.length - succeeded.length - 1;\n\n // Preserve timeout errors (thrown by WikiMemory, not the ranker)\n const isTimeout = (failure.cause as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new PrunePartialFailureError(\n succeeded.length,\n failure.factId,\n remaining,\n new Error('Deletion hook timed out'),\n deletedTasks,\n 0, // events not yet deleted at this point\n );\n }\n\n // Preserve WikiMemory validation errors (not from the adapter hook)\n const errMsg = (failure.cause as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n const sanitizedCause = isValidationError\n ? failure.cause as Error\n : this._sanitizeRankerError(failure.cause);\n\n throw new PrunePartialFailureError(\n succeeded.length,\n failure.factId,\n remaining,\n sanitizedCause,\n deletedTasks,\n 0, // events not yet deleted at this point\n );\n }\n }\n\n if (retainEventsFor !== null) {\n const cutoff = now - retainEventsFor * 86400000;\n const eventResult = await this.db.runAsync(\n `DELETE FROM ${this.prefix}events\n WHERE entity_id = ? AND created_at <= ?`,\n [entityId, cutoff]\n );\n deletedEvents = eventResult.changes;\n }\n\n if (vacuum) {\n await this.db.execAsync(`PRAGMA wal_checkpoint(TRUNCATE)`);\n await this.db.execAsync(`VACUUM`);\n }\n\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n return { entries: deletedEntries, tasks: deletedTasks, events: deletedEvents };\n } finally {\n this.activeMaintenanceJobs.delete(pruneKey);\n }\n }\n\n async read(entityId: string | string[], query: string, options?: ReadOptions): Promise<MemoryBundle> {\n const config = this.options.config;\n const entityIds = normalizeEntityIds(entityId);\n const sanitizedTierWeights = sanitizeTierWeights(entityIds, options?.tierWeights);\n const exposeMetadata = shouldExposeReadMetadata(entityId);\n\n if (entityIds.length === 0) {\n const empty: MemoryBundle = { facts: [], tasks: [], events: [] };\n if (exposeMetadata) {\n empty.metadata = { query, entityIds: [] };\n if (sanitizedTierWeights && Object.keys(sanitizedTierWeights).length > 0) empty.metadata.tierWeights = sanitizedTierWeights;\n }\n return empty;\n }\n\n const MAX_ENTITY_IDS = 100;\n if (entityIds.length > MAX_ENTITY_IDS) {\n throw new RangeError(`read() accepts at most ${MAX_ENTITY_IDS} entity IDs; received ${entityIds.length}`);\n }\n const nullByteId = entityIds.find(id => id.includes('\\x00'));\n if (nullByteId !== undefined) {\n throw new TypeError(`entity_id values must not contain the null byte (\\\\x00); got \"${nullByteId}\"`);\n }\n\n const rawMaxResults = options?.maxResults ?? config?.maxResults ?? config?.maxFtsResults ?? 10;\n const maxResults = Number.isFinite(rawMaxResults)\n ? Math.max(0, Math.trunc(rawMaxResults))\n : 10;\n const rawPreFilterLimit =\n options?.preFilterLimit === null\n ? undefined\n : (options?.preFilterLimit ?? config?.preFilterLimit);\n const effectivePreFilterLimit =\n rawPreFilterLimit === undefined\n ? undefined\n : Number.isFinite(rawPreFilterLimit)\n ? Math.max(0, Math.trunc(rawPreFilterLimit))\n : undefined;\n const hybridWeight = options?.hybridWeight ?? config?.hybridWeight;\n const weight = hybridWeight !== undefined && !Number.isNaN(hybridWeight)\n ? Math.max(0, Math.min(1, hybridWeight))\n : undefined;\n const skipEmbed = weight === 0;\n const embedFn = this.options.llmProvider.embed;\n const trimmedQuery = query.trim();\n\n let facts: WikiFact[] = [];\n let scoreByFactId: Map<string, number> | undefined;\n\n if (maxResults === 0) {\n // Fast-path: a zero-capacity result window can never return any facts.\n // Skip embed(), DB scan, and sort — fall through to tasks/events fetch below.\n } else if (trimmedQuery) {\n let usedEmbed = false;\n const scoredEntityIds = this._filterScoredEntities(entityIds, sanitizedTierWeights, options?.includeZeroWeightEntities);\n\n // Fast-path: all entities zero-weight — skip embedFn, DB mismatch query, and\n // cosine work entirely. usedEmbed=true suppresses the keyword fallback below.\n if (scoredEntityIds.length === 0) {\n usedEmbed = true;\n } else if (!skipEmbed && embedFn) {\n let rankerShouldRethrow = false;\n let pendingRankerFallbackError: Error | undefined;\n try {\n const queryVec = await embedFn(trimmedQuery);\n\n // Validate that the provider returned a well-formed vector. An empty vector\n // would cause all facts to score 0 (silently bypassing the fallback), and\n // non-finite values (NaN, Infinity) make the sort comparator unstable.\n if (queryVec.length === 0 || !queryVec.every(v => typeof v === 'number' && isFinite(v))) {\n throw new Error(\n 'embed() returned an empty or non-finite vector. Falling back to keyword search.'\n );\n }\n\n // Detect embedding dimension mismatch: if stored dimension differs from the\n // query vector, existing fact embeddings were built with a different model and\n // cosine scoring would silently produce misleading rankings. Fall back to\n // MiniSearch until the caller runs runReembed().\n const storedDimRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n if (storedDimRow) {\n const storedDim = parseInt(storedDimRow.value, 10);\n if (storedDim !== queryVec.length) {\n throw new Error(\n `Embedding dimension mismatch: stored ${storedDim}, query has ${queryVec.length}. ` +\n `Call runReembed() to rebuild embeddings with the new model.`\n );\n }\n }\n\n // Check whether any non-deleted fact for any requested entity has a blob whose\n // dimension differs from the query vector. Uses all entityIds (not just\n // scoredEntityIds) so a caller requesting a namespace always gets fail-safe scoring.\n const mismatchScope = this._entityInClause(entityIds);\n const mismatchedCount = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE ${mismatchScope.clause} AND deleted_at IS NULL\n AND embedding_blob IS NOT NULL\n AND (CAST(length(embedding_blob) AS INTEGER) % 4 = 0)\n AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?`,\n [...mismatchScope.params, queryVec.length]\n );\n if (mismatchedCount && mismatchedCount.cnt > 0) {\n throw new Error(\n `Some facts have embeddings that do not match the current model dimension. ` +\n `Call runReembed() to rebuild all embeddings consistently.`\n );\n }\n\n const useRanker = Boolean(this.options.vectorRanker);\n let candidateRows: ReadCandidateRowMetadata[] | ReadCandidateRowWithEmbeddings[] | null; // null = pre-filter returned 0 results\n // Composite cache keys (multi-entity join strings) are never invalidated by write/reembed paths.\n let populateCache = entityIds.length === 1;\n let miniSearchScores: Map<string, number> | undefined;\n\n if (effectivePreFilterLimit !== undefined) {\n populateCache = false; // partial scan — do not populate cache\n const entityIdSet = new Set(scoredEntityIds);\n const preResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => entityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n if (preResults.length === 0) {\n candidateRows = null; // empty pre-filter\n } else {\n const topKResults = preResults.slice(0, effectivePreFilterLimit);\n if (topKResults.length === 0) {\n // effectivePreFilterLimit is 0 — treat the same as no candidates\n // (avoids constructing an invalid \"WHERE id IN ()\" SQL clause)\n candidateRows = null;\n } else {\n const topKIds = topKResults.map(r => r.id);\n const inClauseChunkSize = 500;\n if (useRanker) {\n const rows: ReadCandidateRowMetadata[] = [];\n for (let i = 0; i < topKIds.length; i += inClauseChunkSize) {\n const idChunk = topKIds.slice(i, i + inClauseChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<ReadCandidateRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n rows.push(...chunkRows);\n }\n candidateRows = rows;\n } else {\n const rows: ReadCandidateRowWithEmbeddings[] = [];\n for (let i = 0; i < topKIds.length; i += inClauseChunkSize) {\n const idChunk = topKIds.slice(i, i + inClauseChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<ReadCandidateRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n rows.push(...chunkRows);\n }\n candidateRows = rows;\n }\n if (weight !== undefined && weight < 1) {\n const maxMsScore = Math.max(1, topKResults[0]?.score ?? 1);\n miniSearchScores = new Map(topKResults.map(r => [r.id, r.score / maxMsScore]));\n }\n }\n }\n } else {\n // Full scan of scored entities\n // If vectorRanker is configured, skip embedding load for now (ranker will provide ranking)\n // Otherwise fetch embeddings for JS cosine ranking\n if (useRanker) {\n const entityScope = this._entityInClause(scoredEntityIds);\n candidateRows = await this.db.getAllAsync<ReadCandidateRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,\n entityScope.params\n );\n } else {\n const entityScope = this._entityInClause(scoredEntityIds);\n candidateRows = await this.db.getAllAsync<ReadCandidateRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,\n entityScope.params\n );\n }\n // Collect MiniSearch scores for hybrid blend if weight is set and <1\n if (weight !== undefined && weight < 1) {\n const entityIdSet = new Set(scoredEntityIds);\n const msResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => entityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n const maxMsScore = Math.max(1, msResults[0]?.score ?? 1);\n miniSearchScores = new Map(msResults.map(r => [r.id, r.score / maxMsScore]));\n }\n }\n\n if (candidateRows === null) {\n // pre-filter returned 0 candidates — facts = [], skip phase 2, skip access tracking\n usedEmbed = true;\n } else {\n // Rank candidates: use vectorRanker if present, otherwise use JS cosine\n const entityCacheKey = entityIds.length === 1 ? entityIds[0] : entityIds.join('\\x00');\n let scored: Array<{ id: string; entity_id: string; score: number; updated_at?: number | null; access_count?: number | null }>;\n\n if (useRanker) {\n // Build per-entity candidate maps so each ranker call receives one entityId.\n const candidateRowsByEntity = new Map<string, ReadCandidateRowMetadata[]>();\n for (const row of candidateRows as ReadCandidateRowMetadata[]) {\n const rows = candidateRowsByEntity.get(row.entity_id) ?? [];\n rows.push(row);\n candidateRowsByEntity.set(row.entity_id, rows);\n }\n\n try {\n const rankerResultsByEntity = await Promise.all(\n scoredEntityIds.filter(id => (candidateRowsByEntity.get(id)?.length ?? 0) > 0).map(async scopedEntityId => {\n const rowsForEntity = candidateRowsByEntity.get(scopedEntityId) ?? [];\n const candidateIds = effectivePreFilterLimit !== undefined\n ? rowsForEntity.map(row => row.id)\n : undefined;\n const ranked = await this._rankWithVectorRanker({\n entityId: scopedEntityId,\n queryVec,\n candidateIds,\n candidateRows: rowsForEntity,\n weight,\n miniSearchScores,\n limit: Math.max(maxResults * 2, maxResults + 50),\n });\n return ranked.map(row => ({ ...row, entity_id: scopedEntityId }));\n }),\n );\n\n scored = rankerResultsByEntity.flat();\n\n // Build metadata map only for IDs returned by the ranker (not all candidates)\n // to keep memory proportional to the oversampled result size on constrained runtimes.\n const scoredIds = new Set(scored.map(s => s.id));\n const metadataById = new Map(\n (candidateRows as ReadCandidateRowMetadata[])\n .filter(row => scoredIds.has(row.id))\n .map(row => [row.id, row])\n );\n scored = scored.map(row => {\n const metadata = metadataById.get(row.id);\n return {\n ...row,\n updated_at: metadata?.updated_at ?? null,\n access_count: metadata?.access_count ?? null,\n };\n });\n\n // Backfill ranker-omitted rows per VectorRanker contract:\n // treat missing ids as \"no embedding\" (pure semantic: -2, hybrid: keyword-only)\n\n // Compute backfill budget up-front.\n // Hybrid mode: allow up to maxResults keyword-only rows to compete.\n // Pure semantic: only fill the remaining result slots.\n const isHybrid = weight !== undefined && weight < 1;\n const maxBackfill = isHybrid\n ? maxResults\n : Math.max(0, maxResults - scored.length);\n\n if (maxBackfill > 0) {\n if (isHybrid) {\n // Hybrid mode: prioritize by keyword score using O(N log K) top-K selection\n // instead of O(N log N) full sort, since K (maxBackfill) is typically << N.\n type CandidateRow = typeof candidateRows[number];\n const topK: Array<{ row: CandidateRow; kwScore: number }> = [];\n\n for (const row of candidateRows) {\n if (scoredIds.has(row.id)) continue;\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n const candidate = { row, kwScore };\n\n if (topK.length < maxBackfill) {\n // Array not full yet - insert in sorted position (descending order)\n let insertIdx = topK.length;\n for (let i = 0; i < topK.length; i++) {\n const cmp = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[i].row.id,\n score: topK[i].kwScore,\n updated_at: topK[i].row.updated_at,\n access_count: topK[i].row.access_count,\n }\n );\n if (cmp < 0) {\n insertIdx = i;\n break;\n }\n }\n topK.splice(insertIdx, 0, candidate);\n } else {\n const cmpWorst = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[maxBackfill - 1].row.id,\n score: topK[maxBackfill - 1].kwScore,\n updated_at: topK[maxBackfill - 1].row.updated_at,\n access_count: topK[maxBackfill - 1].row.access_count,\n }\n );\n if (cmpWorst < 0) {\n // Found better candidate than current worst - replace worst and re-insert\n let insertIdx = maxBackfill - 1;\n for (let i = 0; i < topK.length; i++) {\n const cmp = this._compareScoredRows(\n {\n id: candidate.row.id,\n score: candidate.kwScore,\n updated_at: candidate.row.updated_at,\n access_count: candidate.row.access_count,\n },\n {\n id: topK[i].row.id,\n score: topK[i].kwScore,\n updated_at: topK[i].row.updated_at,\n access_count: topK[i].row.access_count,\n }\n );\n if (cmp < 0) {\n insertIdx = i;\n break;\n }\n }\n topK.splice(insertIdx, 0, candidate);\n topK.pop(); // Remove worst element\n }\n }\n }\n\n for (const { row, kwScore } of topK) {\n scored.push({\n id: row.id,\n entity_id: row.entity_id,\n score: (1 - weight) * kwScore,\n updated_at: row.updated_at,\n access_count: row.access_count,\n });\n }\n } else {\n // Pure semantic: all omitted rows share score -2.\n // Tie-break omitted rows deterministically before truncating.\n const omitted: Array<{ id: string; entity_id: string; score: number; updated_at: number | null; access_count: number | null }> = [];\n for (const row of candidateRows) {\n if (scoredIds.has(row.id)) continue;\n omitted.push({ id: row.id, entity_id: row.entity_id, score: -2, updated_at: row.updated_at, access_count: row.access_count });\n }\n if (omitted.length > 0) {\n this._tieBreakSort(omitted);\n scored.push(...omitted.slice(0, maxBackfill));\n }\n }\n }\n } catch (rankerErr) {\n const rankerError = rankerErr instanceof Error ? rankerErr : new Error(String(rankerErr));\n const policy = this.options.vectorRankerFallback ?? 'js-cosine';\n\n this.options.onVectorRankerFallback?.({\n error: this._sanitizeRankerError(rankerError),\n policy,\n });\n\n if (policy === 'throw') {\n rankerShouldRethrow = true;\n throw rankerError;\n } else if (policy === 'js-cosine') {\n // If embeddings were skipped (vectorRanker was configured), fetch them now for fallback\n let fallbackRows = candidateRows;\n if (fallbackRows && fallbackRows.length > 0 && !('embedding_blob' in fallbackRows[0])) {\n const rowIds = fallbackRows.map(r => r.id);\n const embeddingsMap = new Map<string, { embedding_blob: Uint8Array | null; embedding: string | null }>();\n const chunkSize = 500;\n for (let i = 0; i < rowIds.length; i += chunkSize) {\n const idChunk = rowIds.slice(i, i + chunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const embeddingRows = await this.db.getAllAsync<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>(\n `SELECT id, embedding_blob, embedding FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n idChunk\n );\n for (const row of embeddingRows) {\n embeddingsMap.set(row.id, { embedding_blob: row.embedding_blob, embedding: row.embedding });\n }\n }\n fallbackRows = fallbackRows.map(r => ({\n ...r,\n embedding_blob: embeddingsMap.get(r.id)?.embedding_blob ?? null,\n embedding: embeddingsMap.get(r.id)?.embedding ?? null,\n })) as ReadCandidateRowWithEmbeddings[];\n }\n scored = await this._rankWithJsCosine({\n entityId: entityCacheKey,\n queryVec,\n candidateRows: fallbackRows as ReadCandidateRowWithEmbeddings[],\n weight,\n miniSearchScores,\n populateCache,\n limit: fallbackRows.length,\n skipSort: true, // read() re-sorts after applying tier weights\n });\n } else if (policy === 'keyword') {\n // Fall back to keyword-only results from MiniSearch\n const scoredEntityIdSet = new Set(scoredEntityIds);\n const msResults = this.miniSearch.search(trimmedQuery, {\n filter: (r) => scoredEntityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n // Oversample so tier weights can re-rank before the global slice\n const keywordOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const topResults = msResults.slice(0, keywordOversampledLimit);\n const topResultIds = new Set(topResults.map(r => r.id));\n const candidateMap = new Map(candidateRows.filter(r => topResultIds.has(r.id)).map(row => [row.id, row]));\n scored = topResults.map(result => {\n const metadata = candidateMap.get(result.id);\n const entityForScore = metadata?.entity_id\n ?? (result as unknown as { entity_id: string }).entity_id\n ?? '';\n return {\n id: result.id,\n entity_id: entityForScore,\n score: result.score ?? 0,\n access_count: metadata?.access_count ?? null,\n updated_at: metadata?.updated_at ?? null,\n };\n });\n } else {\n // policy === 'empty'\n scored = [];\n }\n\n if (this.options.propagateRankerFailureToRetrievalFallback) {\n const mirrored = new Error('Vector ranker failed, falling back', {\n cause: this._sanitizeRankerError(rankerErr),\n });\n pendingRankerFallbackError = mirrored;\n }\n }\n } else {\n // Use in-process JS cosine similarity\n // At this point candidateRows must have embeddings (we fetched them because vectorRanker is not configured)\n // Materialize all candidates only when tier weights will actually change ranking —\n // i.e., at least one entity has a weight other than 1. A no-op weights object\n // (all values === 1, or empty after sanitization) preserves the hot-path behavior.\n const jsCosineNeedsTierSort = sanitizedTierWeights !== undefined &&\n Object.values(sanitizedTierWeights).some(w => w !== 1);\n scored = await this._rankWithJsCosine({\n entityId: entityCacheKey,\n queryVec,\n candidateRows: candidateRows as ReadCandidateRowWithEmbeddings[],\n weight,\n miniSearchScores,\n populateCache,\n limit: jsCosineNeedsTierSort ? candidateRows.length : maxResults,\n skipSort: jsCosineNeedsTierSort, // read() re-sorts after applying tier weights\n });\n }\n\n if (scored.length > 0) {\n // Apply tier weights before global sort and slice\n scored = scored.map(row => ({\n ...row,\n score: applyTierWeight(row.score, row.entity_id, sanitizedTierWeights),\n }));\n\n // Re-apply tie-break sorting after tier-weight application (applies to all paths including\n // vectorRankerFallback='keyword': applyTierWeight mutates scores so MiniSearch ordering is no longer valid)\n this._tieBreakSort(scored);\n\n // Phase 2: fetch full rows only for the top results\n const selectedScored = scored.slice(0, maxResults);\n const topIds = selectedScored.map(s => s.id);\n\n // Capture scores for exposure in metadata\n if (exposeMetadata && trimmedQuery) {\n scoreByFactId = new Map(selectedScored.map(s => [s.id, Number.isFinite(s.score) ? s.score : 0]));\n }\n\n if (topIds.length > 0) {\n const facts2 = await this._hydrateFactsByIds(topIds, entityIds);\n\n // Hydration can return fewer rows than ranked IDs when rows were concurrently\n // soft-deleted or filtered by deleted_at before phase 2 hydration completes.\n if (facts2.length < topIds.length) {\n const hydrationById = new Set(facts2.map(f => f.id));\n const missingIds = topIds.filter(id => !hydrationById.has(id));\n const missingCount = missingIds.length;\n const sample = missingIds.slice(0, 5);\n const sampleSuffix = sample.length > 0\n ? ` Missing ID sample: ${sample.join(', ')}${missingIds.length > sample.length ? ', ...' : ''}.`\n : '';\n const error = new Error(\n `Phase 2 fact hydration returned ${missingCount} fewer row(s) than ranked IDs. ` +\n `Rows may have been concurrently soft-deleted or filtered by deleted_at during hydration, ` +\n `or vector ranker output may include IDs that do not exist in requested entities.` +\n sampleSuffix\n );\n this.options.onRetrievalFallback?.(error);\n }\n facts = facts2;\n }\n // Ranker path completed — notify of any prior fallback now that hydration is done.\n // Fires outside the topIds.length>0 guard since scored.length>0 && maxResults>0\n // means topIds is always non-empty here, but the notification is harmless either way.\n if (pendingRankerFallbackError) {\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n pendingRankerFallbackError = undefined;\n }\n usedEmbed = true;\n } else {\n // Empty scored results (ranker returned no matches)\n if (pendingRankerFallbackError) {\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n pendingRankerFallbackError = undefined;\n }\n usedEmbed = true;\n }\n } // closes the candidateRows !== null else block\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (rankerShouldRethrow) {\n throw error;\n }\n // If Phase 2 failed and there's a pending ranker error, include it as cause\n if (pendingRankerFallbackError) {\n (error as any).cause = pendingRankerFallbackError;\n pendingRankerFallbackError = undefined;\n }\n // Always notify of Phase 2 errors (ranker error attached as cause if present)\n this.options.onRetrievalFallback?.(error);\n }\n }\n\n if (!usedEmbed && scoredEntityIds.length > 0) {\n // embed absent or threw — fall back to MiniSearch with tier weight application\n const fallbackEntityIdSet = new Set(scoredEntityIds);\n const fallbackOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const results = this.miniSearch.search(trimmedQuery, {\n filter: (r) => fallbackEntityIdSet.has((r as unknown as { entity_id: string }).entity_id),\n combineWith: 'OR',\n });\n const candidates = results.slice(0, fallbackOversampledLimit).map(r => ({\n id: r.id as string,\n entity_id: (r as unknown as { entity_id: string }).entity_id,\n score: applyTierWeight(r.score ?? 0, (r as unknown as { entity_id: string }).entity_id, sanitizedTierWeights),\n updated_at: null as number | null,\n access_count: null as number | null,\n }));\n this._tieBreakSort(candidates);\n const topCandidates = candidates.slice(0, maxResults);\n const topIds = topCandidates.map(c => c.id);\n if (topIds.length > 0) {\n facts = await this._hydrateFactsByIds(topIds, entityIds);\n if (exposeMetadata) {\n scoreByFactId = new Map(topCandidates.map(c => [c.id, Number.isFinite(c.score) ? c.score : 0]));\n }\n }\n }\n\n if (facts.length > 0) {\n const ids = facts.map(f => f.id);\n const now = Date.now();\n const accessChunkSize = 500;\n for (let i = 0; i < ids.length; i += accessChunkSize) {\n const idChunk = ids.slice(i, i + accessChunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries\n SET access_count = access_count + 1, last_accessed_at = ?\n WHERE id IN (${placeholders})`,\n [now, ...idChunk]\n );\n }\n }\n } else {\n // Empty query: use global recency ordering, ignore tier weights.\n // Raw SELECT * — normalize here since _hydrateFactsByIds is not used.\n const entityScope = this._entityInClause(entityIds);\n const rawFacts = await this.db.getAllAsync<WikiFact & { embedding?: unknown; embedding_blob?: unknown }>(\n `SELECT * FROM ${this.prefix}entries\n WHERE ${entityScope.clause} AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT ?`,\n [...entityScope.params, maxResults]\n );\n facts = rawFacts.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f;\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n } as WikiFact;\n });\n }\n\n const [tasks, events] = await Promise.all([\n (async () => {\n const entityScope = this._entityInClause(entityIds);\n // Single-entity reads preserve the pre-Phase-2 unbounded behavior.\n // Multi-entity reads cap at 20× entity count (max 200) to bound result size.\n const tasksLimit = entityIds.length === 1 ? undefined : Math.min(20 * entityIds.length, 200);\n return this.db.getAllAsync<WikiTask>(\n `SELECT * FROM ${this.prefix}tasks\n WHERE ${entityScope.clause} AND status IN ('pending', 'in_progress') AND deleted_at IS NULL\n ORDER BY priority DESC, created_at ASC${tasksLimit !== undefined ? '\\n LIMIT ?' : ''}`,\n tasksLimit !== undefined ? [...entityScope.params, tasksLimit] : entityScope.params\n );\n })(),\n (async () => {\n const entityScope = this._entityInClause(entityIds);\n // Scaled global cap: 10× entity count, max 100. Not a per-entity guarantee —\n // a single high-volume entity can fill the entire budget.\n const eventsLimit = Math.min(10 * entityIds.length, 100);\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events\n WHERE ${entityScope.clause}\n ORDER BY created_at DESC\n LIMIT ?`,\n [...entityScope.params, eventsLimit]\n );\n })(),\n ]);\n\n // Build factScores from captured scores\n let factScores: Record<string, number> | undefined;\n if (exposeMetadata && trimmedQuery && scoreByFactId) {\n factScores = Object.fromEntries(facts.map(fact => [fact.id, scoreByFactId!.get(fact.id) ?? 0]));\n }\n\n const bundle: MemoryBundle = { facts, tasks, events: events.reverse() };\n\n if (exposeMetadata) {\n bundle.metadata = { query, entityIds };\n if (sanitizedTierWeights && Object.keys(sanitizedTierWeights).length > 0) bundle.metadata.tierWeights = sanitizedTierWeights;\n if (factScores && Object.keys(factScores).length > 0) bundle.factScores = factScores;\n }\n\n return bundle;\n }\n\n /**\n * Returns entity IDs that will participate in scored retrieval.\n * Excludes zero-weight entities unless includeZeroWeightEntities is true.\n */\n private _filterScoredEntities(\n entityIds: readonly string[],\n sanitizedTierWeights: Record<string, number> | undefined,\n includeZeroWeightEntities?: boolean,\n ): string[] {\n return entityIds.filter(id => {\n const w = sanitizedTierWeights?.[id] ?? 1;\n return includeZeroWeightEntities === true || w !== 0;\n });\n }\n\n /**\n * Stable tie-break sort: score desc → access_count desc → updated_at desc → id asc.\n */\n private _tieBreakSort<T extends { id: string; score: number; updated_at?: number | null; access_count?: number | null }>(items: T[]): void {\n items.sort((a, b) => this._compareScoredRows(a, b));\n }\n\n /**\n * Comparator for score + deterministic tie-break fields.\n * Negative return means \"a ranks ahead of b\" for descending score order.\n */\n private _compareScoredRows(\n a: { id: string; score: number; updated_at?: number | null; access_count?: number | null },\n b: { id: string; score: number; updated_at?: number | null; access_count?: number | null },\n ): number {\n const scoreDiff = b.score - a.score;\n // isNaN guard: -Infinity - (-Infinity) = NaN; fall through to tie-break\n if (!Number.isNaN(scoreDiff) && scoreDiff !== 0) return scoreDiff;\n const accessCountDiff = (b.access_count ?? 0) - (a.access_count ?? 0);\n if (accessCountDiff !== 0) return accessCountDiff;\n const updatedAtDiff = (b.updated_at ?? 0) - (a.updated_at ?? 0);\n if (updatedAtDiff !== 0) return updatedAtDiff;\n return a.id.localeCompare(b.id);\n }\n\n /**\n * Build SQL IN clause with placeholders for multiple entity IDs.\n */\n private _entityInClause(entityIds: readonly string[]): { clause: string; params: string[] } {\n if (entityIds.length === 0) return { clause: '1=0', params: [] };\n const placeholders = entityIds.map(() => '?').join(',');\n return { clause: `entity_id IN (${placeholders})`, params: [...entityIds] };\n }\n\n /**\n * Hydrate full facts by ID. Pass scopedEntityIds to restrict to requested namespaces in SQL\n * (defense-in-depth against a rogue VectorRanker returning cross-entity IDs).\n */\n private async _hydrateFactsByIds(ids: readonly string[], scopedEntityIds?: readonly string[]): Promise<WikiFact[]> {\n const fullRows: Array<WikiFact & { embedding?: unknown; embedding_blob?: unknown }> = [];\n const chunkSize = 500;\n const entityClause = scopedEntityIds && scopedEntityIds.length > 0\n ? ` AND entity_id IN (${scopedEntityIds.map(() => '?').join(',')})`\n : '';\n const entityParams = scopedEntityIds && scopedEntityIds.length > 0 ? [...scopedEntityIds] : [];\n\n for (let i = 0; i < ids.length; i += chunkSize) {\n const idChunk = ids.slice(i, i + chunkSize);\n const placeholders = idChunk.map(() => '?').join(',');\n const chunkRows = await this.db.getAllAsync<WikiFact & { embedding?: unknown; embedding_blob?: unknown }>(\n `SELECT * FROM ${this.prefix}entries WHERE id IN (${placeholders})${entityClause} AND deleted_at IS NULL`,\n [...idChunk, ...entityParams],\n );\n fullRows.push(...chunkRows);\n }\n\n const byId = new Map(fullRows.map(row => [row.id, row]));\n return ids\n .map(id => byId.get(id))\n .filter((fact): fact is WikiFact & { embedding?: unknown; embedding_blob?: unknown } => fact !== undefined)\n .map(fact => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = fact;\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n };\n });\n }\n\n /**\n * Strip potentially sensitive data from ranker errors before exposing to host callbacks.\n * Preserves error type for debugging but removes message/stack that may contain credentials.\n * Recursively sanitizes one level of .cause; deeper chains collapse to type only.\n */\n private _sanitizeRankerError(err: unknown): Error {\n if (this.options.sanitizeRankerErrors === false) {\n return err instanceof Error ? err : new Error(String(err));\n }\n\n const typeName =\n err instanceof Error\n ? (err.constructor?.name ?? 'Error')\n : typeof err;\n\n const innerCause =\n err instanceof Error && err.cause !== undefined\n ? new Error(`Caused by: ${(err.cause as Error)?.constructor?.name ?? typeof err.cause}`)\n : undefined;\n\n const sanitized = new Error(\n `VectorRanker ${typeName} (message scrubbed for security)`,\n innerCause ? { cause: innerCause } : undefined,\n );\n sanitized.name = typeName;\n return sanitized;\n }\n\n /**\n * Score candidate rows using in-process JS cosine similarity.\n * Applies hybrid blending (if weight set) and tie-break sorting before returning.\n */\n private async _rankWithJsCosine(args: {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateRows: Array<{ id: string; entity_id: string; embedding_blob: Uint8Array | null; embedding: string | null; updated_at: number | null; access_count: number | null }>;\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n populateCache: boolean;\n limit: number;\n skipSort?: boolean;\n }): Promise<Array<{ id: string; entity_id: string; score: number; updated_at: number | null; access_count: number | null }>> {\n const queryVec = args.queryVec instanceof Float32Array\n ? args.queryVec.slice()\n : Array.from(args.queryVec);\n const { entityId, candidateRows, weight, miniSearchScores, populateCache, limit, skipSort } = args;\n\n // Cache: reuse parsed vectors from prior full-scan reads\n let entityCache = this.vectorCache.get(entityId);\n const tooLarge = populateCache && candidateRows.length > WikiMemory.MAX_VECTOR_CACHE_FACTS_PER_ENTITY;\n if (tooLarge && entityCache) {\n this.vectorCache.delete(entityId);\n entityCache = undefined;\n }\n const canCache = populateCache && !tooLarge;\n if (canCache && !entityCache) {\n entityCache = new Map<string, Float32Array>();\n }\n\n const scored = candidateRows.map(row => {\n let vector = entityCache?.get(row.id) ?? parseEmbedding(row.embedding_blob, row.embedding);\n if (vector && canCache && entityCache && !entityCache.has(row.id)) {\n entityCache.set(row.id, vector);\n }\n let score = 0;\n if (vector && vector.length === queryVec.length) {\n const cosSim = cosineSimilarity(queryVec, vector);\n if (weight !== undefined) {\n // Clamp to [0,1] only for hybrid blending so the weighted sum stays\n // in a predictable range. Pure-semantic ranking preserves the full\n // [-1,1] cosine range so the least-dissimilar facts always rank above\n // unembedded rows (which score 0) even when all scores are negative.\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = weight * Math.max(0, cosSim) + (1 - weight) * kwScore;\n } else {\n score = cosSim;\n }\n } else if (weight !== undefined && weight < 1) {\n // No usable embedding — still apply the keyword portion of the hybrid score.\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = (1 - weight) * kwScore;\n } else {\n // Pure-semantic path with no usable vector. Use -2 (below the minimum\n // valid cosine of -1) so embedded facts always rank above unembedded rows\n // even when every cosine score is negative.\n score = -2;\n }\n return {\n id: row.id,\n entity_id: row.entity_id,\n score,\n updated_at: row.updated_at,\n access_count: row.access_count,\n };\n });\n\n if (canCache && entityCache && entityCache.size > 0) {\n if (!this.vectorCache.has(entityId)) {\n // Evict the oldest entity when at the per-process cap to prevent unbounded growth\n // on long-lived instances serving many distinct entities.\n if (this.vectorCache.size >= WikiMemory.MAX_VECTOR_CACHE_ENTITIES) {\n const oldestKey = this.vectorCache.keys().next().value as string | undefined;\n if (oldestKey !== undefined) this.vectorCache.delete(oldestKey);\n }\n this.vectorCache.set(entityId, entityCache);\n }\n }\n\n // Apply tie-break sorting unless caller will re-sort after applying tier weights.\n if (!skipSort) this._tieBreakSort(scored);\n\n return scored.slice(0, limit);\n }\n\n /**\n * Delegate semantic ranking to the injected VectorRanker.\n * Caller should pass an oversampledLimit to preserve recall after re-ranking.\n * Returns scored results ready for hybrid blending and tie-break sorting.\n */\n private async _rankWithVectorRanker(args: {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateIds: readonly string[] | undefined;\n candidateRows: ReadCandidateRowMetadata[];\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n limit: number;\n }): Promise<Array<{ id: string; entity_id: string; score: number }>> {\n const { entityId, candidateIds, candidateRows, weight, miniSearchScores, limit } = args;\n\n const ranker = this.options.vectorRanker;\n if (!ranker) {\n throw new Error('vectorRanker not configured');\n }\n\n const queryVecCopy = args.queryVec instanceof Float32Array\n ? args.queryVec.slice()\n : Array.from(args.queryVec);\n\n const rankerResults = await ranker.rankBySimilarity({\n entityId,\n queryVec: queryVecCopy,\n candidateIds,\n limit,\n });\n\n // Normalize ranker output: filter to allowed ids, drop non-finite scores, deduplicate\n // Stop collecting once limit valid results are found to protect against huge result sets\n const allowedIds = new Set(candidateRows.map(row => row.id));\n const seen = new Set<string>();\n const normalized: typeof rankerResults = [];\n\n for (const r of rankerResults) {\n if (normalized.length >= limit) break; // Early termination once limit reached\n if (seen.has(r.id)) continue;\n if (allowedIds && !allowedIds.has(r.id)) continue;\n if (!Number.isFinite(r.semanticScore)) continue;\n seen.add(r.id);\n normalized.push(r);\n }\n\n const entityIdByCandidateId = new Map(candidateRows.map(row => [row.id, row.entity_id]));\n\n // Convert ranker results to scored format, applying hybrid blending if weight is set\n const scored = normalized.map(r => {\n let score = r.semanticScore;\n if (weight !== undefined) {\n // Hybrid blending: floor semantic score at 0 for predictable weighted sum (no upper clamp)\n const kwScore = miniSearchScores?.get(r.id) ?? 0;\n score = weight * Math.max(0, r.semanticScore) + (1 - weight) * kwScore;\n }\n return {\n id: r.id,\n entity_id: entityIdByCandidateId.get(r.id)!, // allowedIds filter above guarantees membership\n score,\n };\n });\n\n // Caller handles backfill, metadata attachment, tie-break sorting, and final slice\n return scored;\n }\n\n async getMemoryBundle(entityId: string): Promise<MemoryBundle> {\n return this._getFullBundle(entityId, { maxEvents: 10 });\n }\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n const id = generateId('evt_');\n const now = Date.now();\n \n let eventType = event.event_type;\n if (!['observation', 'decision', 'action', 'outcome'].includes(eventType)) {\n eventType = 'observation';\n }\n\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `, [id, entityId, eventType, event.summary, event.related_entry_id || null, now]);\n\n const threshold = this.options.config?.autoLibrarianThreshold || 20;\n \n const [row, cp] = await Promise.all([\n this.db.getFirstAsync<{ count: number }>(`SELECT COUNT(*) as count FROM ${this.prefix}events WHERE entity_id = ?`, [entityId]),\n this.db.getFirstAsync<WikiCheckpoint>(`SELECT * FROM ${this.prefix}checkpoints WHERE entity_id = ?`, [entityId])\n ]);\n \n const count = row?.count || 0;\n let memoryCheckpoint = cp?.memory_checkpoint || 0;\n if (memoryCheckpoint > count) memoryCheckpoint = 0;\n\n if (count - memoryCheckpoint >= threshold) {\n const jobKey = this._librarianKey(entityId);\n if (\n !this.activeMaintenanceJobs.has(jobKey) &&\n !this.activeMaintenanceJobs.has(this._pruneKey(entityId)) &&\n !this._isReembedActive(entityId) &&\n !this._isImportActiveFor(entityId) &&\n !this._isForgetActiveFor(entityId)\n ) {\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n this.runLibrarianThenMaybeHeal(entityId, count)\n .catch(console.error)\n .finally(() => {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n });\n }\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number) {\n await this._doRunLibrarian(entityId);\n \n await this.db.runAsync(`\n INSERT INTO ${this.prefix}checkpoints (entity_id, memory_checkpoint) \n VALUES (?, ?) \n ON CONFLICT(entity_id) DO UPDATE SET memory_checkpoint = ?\n `, [entityId, currentEventCount, currentEventCount]);\n \n const autoHealThreshold = this.options.config?.autoHealThreshold || 100;\n const cp = await this.db.getFirstAsync<WikiCheckpoint>(`SELECT * FROM ${this.prefix}checkpoints WHERE entity_id = ?`, [entityId]);\n let healCheckpoint = cp?.heal_checkpoint || 0;\n if (healCheckpoint > currentEventCount) healCheckpoint = 0;\n \n if (currentEventCount - healCheckpoint >= autoHealThreshold) {\n const healKey = this._healKey(entityId);\n if (!this.activeMaintenanceJobs.has(healKey)) {\n this.activeMaintenanceJobs.add(healKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunHeal(entityId);\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}checkpoints (entity_id, heal_checkpoint) \n VALUES (?, ?) \n ON CONFLICT(entity_id) DO UPDATE SET heal_checkpoint = ?\n `, [entityId, currentEventCount, currentEventCount]);\n } finally {\n this.activeMaintenanceJobs.delete(healKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n }\n }\n\n private async _doRunLibrarian(entityId: string): Promise<void> {\n const events = await this.db.getAllAsync<WikiEvent>(`\n SELECT * FROM ${this.prefix}events\n WHERE entity_id = ?\n ORDER BY created_at DESC\n LIMIT 50\n `, [entityId]);\n\n const currentFactsRows = await this.db.getAllAsync<WikiFact>(`\n SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC\n LIMIT 100\n `, [entityId]);\n\n const currentFacts = currentFactsRows.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f as WikiFact & { embedding?: unknown; embedding_blob?: unknown };\n return {\n ...rest,\n tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags,\n };\n });\n\n const userPrompt = `Events:\\n${JSON.stringify(events.reverse(), null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`;\n \n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: LIBRARIAN_SYSTEM_PROMPT,\n userPrompt,\n });\n\n const result = parseJsonResponse<{ facts: ExtractedFact[], tasks: ExtractedTask[] }>(responseText);\n const facts = Array.isArray(result.facts) ? result.facts : [];\n const tasks = Array.isArray(result.tasks) ? result.tasks : [];\n const validFacts = facts.map(validateFact).filter((f): f is ExtractedFact => f !== null);\n const validTasks = tasks.map(validateTask).filter((t): t is ExtractedTask => t !== null);\n\n const now = Date.now();\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n\n await this.db.withTransactionAsync(async () => {\n for (const fact of validFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of currentFactsRows) {\n if (existing.source_type !== 'librarian_inferred') continue;\n const existingTokens = titleTokens(existing.title);\n if (existingTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n if (jaccardScore(newTokens, existingTokens) >= FUZZY_THRESHOLD) {\n skip = true;\n break;\n }\n }\n }\n }\n if (skip) continue;\n\n const id = generateId('fact_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'librarian_inferred', now, now]);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n\n for (const task of validTasks) {\n const id = generateId('task_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}tasks (id, entity_id, description, status, priority, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, task.description, 'pending', task.priority, now, now]);\n }\n });\n\n // Rebuild the text index before the (potentially slow) embedding loop so\n // concurrent reads using MiniSearch (preFilter, keyword fallback) see the\n // new fact content immediately after the DB transaction commits.\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Second vector cache flush: a concurrent read() may have repopulated it\n // during the embed loop; flush so subsequent reads see the new BLOBs.\n this.vectorCache.delete(entityId);\n }\n\n private async _doRunHeal(entityId: string): Promise<void> {\n const now = Date.now();\n const orphanAfterDays = this.options.config?.orphanAfterDays !== undefined ? this.options.config.orphanAfterDays : 30;\n const staleInferredAfterDays = this.options.config?.staleInferredAfterDays !== undefined ? this.options.config.staleInferredAfterDays : 60;\n const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n if (orphanAfterDays !== null && (typeof orphanAfterDays !== 'number' || !Number.isFinite(orphanAfterDays) || orphanAfterDays < 0)) {\n throw new Error('Invalid orphanAfterDays: must be a finite number >= 0 or null');\n }\n if (staleInferredAfterDays !== null && (typeof staleInferredAfterDays !== 'number' || !Number.isFinite(staleInferredAfterDays) || staleInferredAfterDays < 0)) {\n throw new Error('Invalid staleInferredAfterDays: must be a finite number >= 0 or null');\n }\n\n await this.db.withTransactionAsync(async () => {\n if (orphanAfterDays !== null) {\n const orphanThreshold = now - (orphanAfterDays * MS_PER_DAY);\n await this.db.runAsync(`\n UPDATE ${this.prefix}entries\n SET deleted_at = ?, updated_at = ?\n WHERE entity_id = ? AND access_count = 0 AND created_at <= ? AND source_type != 'immutable_document' AND deleted_at IS NULL\n `, [now, now, entityId, orphanThreshold]);\n }\n\n if (staleInferredAfterDays !== null) {\n const staleThreshold = now - (staleInferredAfterDays * MS_PER_DAY);\n await this.db.runAsync(`\n UPDATE ${this.prefix}entries\n SET confidence = 'tentative', updated_at = ?\n WHERE entity_id = ? AND confidence = 'inferred' AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?)) AND source_type != 'immutable_document' AND deleted_at IS NULL\n `, [now, entityId, staleThreshold, staleThreshold]);\n }\n });\n\n const allFactsRows = await this.db.getAllAsync<WikiFact>(`SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`, [entityId]);\n const allTasks = await this.db.getAllAsync<WikiTask>(`SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND status IN ('pending', 'in_progress') AND deleted_at IS NULL`, [entityId]);\n const recentEvents = await this.db.getAllAsync<WikiEvent>(`SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT 20`, [entityId]);\n\n const healCandidates = allFactsRows.filter(f => f.source_type !== 'immutable_document');\n const documentAnchors = allFactsRows\n .filter(f => f.source_type === 'immutable_document')\n .map(({ id, title, source_ref }) => ({ id, title, source_ref }));\n\n const userPrompt = `Heal Candidates:\\n${JSON.stringify(healCandidates.map(f => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f as WikiFact & { embedding?: unknown; embedding_blob?: unknown };\n return { ...rest, tags: typeof rest.tags === 'string' ? JSON.parse(rest.tags) : rest.tags };\n }), null, 2)}\n\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(documentAnchors, null, 2)}\n\\nAll Tasks:\\n${JSON.stringify(allTasks, null, 2)}\n\\nRecent Events:\\n${JSON.stringify(recentEvents, null, 2)}\n\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`;\n \n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: HEAL_SYSTEM_PROMPT,\n userPrompt,\n });\n\n const result = parseJsonResponse<{ downgraded: string[], deleted: string[], newFacts: ExtractedFact[] }>(responseText);\n\n const mutableIds = new Set(healCandidates.map(f => f.id));\n const downgraded = Array.isArray(result.downgraded) ? result.downgraded : [];\n const deleted = Array.isArray(result.deleted) ? result.deleted : [];\n const newFacts = Array.isArray(result.newFacts) ? result.newFacts : [];\n const safeDowngraded = downgraded.filter(id => mutableIds.has(id));\n const safeDeleted = deleted.filter(id => mutableIds.has(id));\n const validNewFacts = newFacts.map(validateFact).filter((f): f is ExtractedFact => f !== null);\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const uniqueDeletedFactIds = Array.from(new Set(safeDeleted));\n\n await this.db.withTransactionAsync(async () => {\n for (const id of safeDowngraded) {\n await this.db.runAsync(`UPDATE ${this.prefix}entries SET confidence = 'tentative', updated_at = ? WHERE id = ? AND entity_id = ?`, [now, id, entityId]);\n }\n for (const id of safeDeleted) {\n await this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ?`, [now, now, id, entityId]);\n }\n for (const fact of validNewFacts) {\n const id = generateId('fact_');\n await this.db.runAsync(`\n INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'librarian_inferred', now, now]);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n });\n\n // Pre-flush: evict stale cached vectors before writing new embeddings so a\n // concurrent read() during the embed loop doesn't rank deleted/downgraded\n // facts from the cache. Post-flush below handles vectors repopulated during\n // the loop.\n this.vectorCache.delete(entityId);\n // Rebuild MiniSearch before the embedding loop so concurrent reads using\n // preFilterLimit, hybrid scoring, or keyword fallback see the new/deleted\n // facts immediately rather than waiting for every embed call to finish.\n await this.rebuildMiniSearchIndex(entityId);\n for (const factId of uniqueDeletedFactIds) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal for ${factId}:`, hookErr);\n }\n }\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Post-flush: evict any cache entries a concurrent read() repopulated while\n // the embedding loop was running.\n this.vectorCache.delete(entityId);\n }\n\n async runLibrarian(entityId: string): Promise<void> {\n const jobKey = this._librarianKey(entityId);\n if (this.activeMaintenanceJobs.has(jobKey)) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunLibrarian(entityId);\n } finally {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n\n async runHeal(entityId: string): Promise<void> {\n const jobKey = this._healKey(entityId);\n if (this.activeMaintenanceJobs.has(jobKey)) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeMaintenanceJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n try {\n await this._doRunHeal(entityId);\n } finally {\n this.activeMaintenanceJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n\n async runReembed(entityId?: string, opts?: { force?: boolean; skipExisting?: boolean }): Promise<{ embedded: number; skipped: number; failed: number }> {\n const embedFn = this.options.llmProvider.embed;\n if (!embedFn) return { embedded: 0, skipped: 0, failed: 0 };\n\n const reembedKey = entityId ? this._reembedKey(entityId) : this._globalReembedKey();\n if (this.activeMaintenanceJobs.has(reembedKey)) {\n throw new WikiBusyError('reembed', entityId ?? '*');\n }\n if (entityId) {\n // Cross-check: fail if global reembed is in-flight (it covers this entity too)\n if (this.activeMaintenanceJobs.has(this._globalReembedKey())) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this._isIngestActiveFor(entityId)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n } else {\n // Cross-check: fail if any per-entity reembed is in-flight (global covers all entities)\n if (this._isAnyMaintenanceActiveWithSuffix(':reembed')) {\n throw new WikiBusyError('reembed', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':prune')) {\n throw new WikiBusyError('prune', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':librarian')) {\n throw new WikiBusyError('librarian', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':heal')) {\n throw new WikiBusyError('heal', '*');\n }\n if (this.activeIngestJobs.size > 0) {\n throw new WikiBusyError('ingest', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':import')) {\n throw new WikiBusyError('import', '*');\n }\n if (this._isAnyMaintenanceActiveWithSuffix(':forget')) {\n throw new WikiBusyError('forget', '*');\n }\n }\n this.activeMaintenanceJobs.add(reembedKey);\n\n try {\n const where = entityId ? `entity_id = ? AND deleted_at IS NULL` : `deleted_at IS NULL`;\n const params = entityId ? [entityId] : [];\n const rows = await this.db.getAllAsync<WikiFact>(\n `SELECT * FROM ${this.prefix}entries WHERE ${where}`,\n params\n );\n\n // Invalidate before the embedding loop so any concurrent read() fetches fresh\n // vectors from the database rather than stale pre-reembed cached ones.\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n\n // skipExisting is an explicit opt-in for round-trip import scenarios where\n // the caller knows every blob is already fresh and wants to avoid paying the\n // full embedding cost again (e.g. after exportDump → importDump on the same\n // model). By default runReembed() re-embeds every selected fact so that a\n // model switch always works correctly — a dimension-only probe cannot detect\n // same-dimension provider changes, so unconditional re-embedding is the only\n // safe default.\n // { force: true } is kept as a no-op alias so existing call sites that pass\n // it explicitly continue to work without change.\n // skipExisting skips facts that already have a structurally valid BLOB.\n // WARNING: this is only safe when the caller can guarantee the stored BLOBs\n // were produced by the *same* embedding model that is currently configured.\n // It cannot detect same-dimension model/provider switches (e.g. two providers\n // that both produce 1536-dim vectors). After any provider change, always call\n // runReembed() without { skipExisting: true } to force full re-embedding.\n const skipExisting = opts?.skipExisting ?? false;\n // Never skip when a dimension mismatch is pending: blobs on disk are stale\n // regardless of what the caller requested.\n // For per-entity reembed, only disable skipExisting when THIS entity actually\n // has stale blobs — the global mismatch flag may reflect a different entity's\n // state and should not force unnecessary re-embedding of entity A's valid blobs.\n let effectiveSkip = skipExisting;\n if (skipExisting) {\n const mismatchRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (mismatchRow) {\n if (entityId) {\n // Per-entity: check whether this entity has any blobs at the wrong dimension\n // (i.e., the old canonical dim, not the pending new mismatch dim) or TEXT-only rows.\n const mismatchDim = parseInt(mismatchRow.value, 10);\n const staleForEntity = await this.db.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND (\n embedding_blob IS NULL\n OR (CAST(length(embedding_blob) AS INTEGER) / 4) != ?\n )`,\n [entityId, mismatchDim]\n );\n if (staleForEntity && staleForEntity.cnt > 0) effectiveSkip = false;\n } else {\n // Global reembed: any pending mismatch means blobs are stale somewhere.\n effectiveSkip = false;\n }\n }\n }\n let embedded = 0;\n let skipped = 0;\n let failed = 0;\n try {\n for (const row of rows) {\n // Skip facts with existing BLOBs only when the caller opts in via\n // { skipExisting: true } AND no dimension mismatch is active.\n // The default always re-embeds, ensuring correctness after model switches.\n // Only skip if the BLOB is structurally valid (non-zero length, divisible\n // by 4) and contains entirely finite values. A BLOB full of NaN/Infinity\n // passes the byte-length check but would silently score 0 in read() —\n // let embedFact() repair it instead of leaving the fact permanently unsearchable.\n const existingBlob = (row as WikiFact & { embedding_blob?: Uint8Array | null }).embedding_blob;\n const blobIsValid = !!existingBlob && existingBlob.byteLength > 0 && existingBlob.byteLength % 4 === 0;\n if (effectiveSkip && blobIsValid) {\n const vec = parseEmbedding(existingBlob, null);\n if (vec !== null && vec.every(v => Number.isFinite(v))) {\n skipped++;\n continue;\n }\n }\n const success = await this.embedFact(row);\n if (success) embedded++;\n else failed++;\n }\n // If any fact was successfully re-embedded, promote the pending dimension to\n // canonical and clear the mismatch flag so read() uses embeddings from here on.\n if (embedded > 0) {\n await this._reconcileEmbeddingDimension();\n }\n } finally {\n // Invalidate again after the loop: a concurrent read() might have re-populated\n // the cache with pre-reembed vectors while the loop was running, so flush any\n // such stale entries to ensure subsequent reads see the freshly written data,\n // even if the loop or dimension reconciliation threw.\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n }\n\n return { embedded, skipped, failed };\n } finally {\n this.activeMaintenanceJobs.delete(reembedKey);\n }\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n const ingestPrefix = `${this.prefix}:${entityId}:`;\n let ingesting = false;\n for (const k of this.activeIngestJobs) {\n if (k.startsWith(ingestPrefix)) { ingesting = true; break; }\n }\n\n return {\n ingesting,\n librarian: this.activeMaintenanceJobs.has(this._librarianKey(entityId)),\n heal: this.activeMaintenanceJobs.has(this._healKey(entityId)),\n };\n }\n\n /**\n * Subscribe to {@link EntityStatus} changes for a single entity. The callback\n * is invoked synchronously once with the current status before this method\n * returns, then again on every transition where any of `ingesting`,\n * `librarian`, or `heal` flips. No polling, no duplicate snapshots.\n *\n * Returns an idempotent unsubscribe function.\n *\n * See also {@link getEntityStatus} for a synchronous point-in-time read.\n */\n subscribeEntityStatus(\n entityId: string,\n callback: (status: EntityStatus) => void\n ): () => void {\n const initial = this.getEntityStatus(entityId);\n let set = this.statusSubscribers.get(entityId);\n if (!set) {\n set = new Set();\n this.statusSubscribers.set(entityId, set);\n }\n const entry = { callback, last: this._copyEntityStatus(initial) };\n set.add(entry);\n\n try {\n callback(this._copyEntityStatus(initial));\n } catch (err) {\n console.error(`[WikiMemory.subscribeEntityStatus] callback error for entityId=\"${entityId}\" during initial emission`, err);\n }\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n const s = this.statusSubscribers.get(entityId);\n if (!s) return;\n s.delete(entry);\n if (s.size === 0) this.statusSubscribers.delete(entityId);\n };\n }\n\n public clearVectorCache(): void {\n this.vectorCache.clear();\n }\n\n private async _getFullBundle(entityId: string, opts?: { maxEvents?: number; includeBlobs?: boolean }): Promise<MemoryBundle> {\n const maxEvents = opts?.maxEvents;\n const eventsQuery = maxEvents != null\n ? `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`\n : `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at ASC`;\n const eventsParams: (string | number)[] = maxEvents != null ? [entityId, maxEvents] : [entityId];\n\n const [factsRaw, tasks, eventsRaw] = await Promise.all([\n this.db.getAllAsync<WikiFact>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId]\n ),\n this.db.getAllAsync<WikiTask>(\n `SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL ORDER BY priority DESC, created_at ASC`,\n [entityId]\n ),\n this.db.getAllAsync<WikiEvent>(eventsQuery, eventsParams),\n ]);\n const facts = factsRaw.map(f => {\n // Always strip the legacy text embedding column — never useful to callers.\n const { embedding: _embedding, embedding_blob, ...rest } =\n f as WikiFact & { embedding?: unknown; embedding_blob?: Uint8Array };\n // Include the BLOB only on the export path so importDump() can round-trip\n // embeddings without re-calling the embed provider. Strip it on the LLM\n // prompt / formatMemoryDump paths to keep payloads small.\n // Copy blob bytes before returning: some SQLite drivers (better-sqlite3)\n // back Buffer objects with pooled native memory that can be reused by a\n // subsequent query, silently corrupting the already-returned MemoryDump.\n const safeBlobCopy = opts?.includeBlobs && embedding_blob\n ? (() => { const c = new ArrayBuffer(embedding_blob.byteLength); new Uint8Array(c).set(embedding_blob); return new Uint8Array(c); })()\n : undefined;\n const factBase = safeBlobCopy\n ? { ...rest, embedding_blob: safeBlobCopy }\n : rest;\n return {\n ...factBase,\n tags: typeof factBase.tags === 'string' ? JSON.parse(factBase.tags) : factBase.tags,\n };\n });\n // When limited, results arrive newest-first; reverse to chronological order.\n const events = maxEvents != null ? eventsRaw.slice().reverse() : eventsRaw;\n return { facts, tasks, events };\n }\n\n async exportDump(entityIds?: string[]): Promise<MemoryDump> {\n let ids: string[];\n if (entityIds && entityIds.length > 0) {\n ids = Array.from(new Set(entityIds));\n } else {\n // Collect all distinct entity_ids across entries, tasks, events\n const rows = await this.db.getAllAsync<{ entity_id: string }>(`\n SELECT DISTINCT entity_id FROM (\n SELECT entity_id FROM ${this.prefix}entries WHERE deleted_at IS NULL\n UNION\n SELECT entity_id FROM ${this.prefix}tasks WHERE deleted_at IS NULL\n UNION\n SELECT entity_id FROM ${this.prefix}events\n ) ORDER BY entity_id\n `);\n ids = rows.map(r => r.entity_id);\n }\n\n const entities: Record<string, MemoryBundle> = {};\n const BATCH = 3;\n for (let i = 0; i < ids.length; i += BATCH) {\n const batch = ids.slice(i, i + BATCH);\n const batchResults = await Promise.all(\n batch.map(async (id): Promise<[string, MemoryBundle]> => [id, await this._getFullBundle(id, { includeBlobs: true })])\n );\n for (const [id, bundle] of batchResults) {\n entities[id] = bundle;\n }\n }\n\n return { generatedAt: Date.now(), entities };\n }\n\n async importDump(dump: MemoryDump, opts?: { merge?: boolean }): Promise<void> {\n const merge = opts?.merge ?? false;\n const entityIds = Object.keys(dump.entities);\n\n // Pre-validate all locks before writing anything. This makes the operation\n // atomic with respect to busy-error rejection: either every entity passes the\n // lock check and we proceed, or we reject before mutating any entity.\n // Per-entity checks first: surface the specific conflicting entity in the error.\n for (const entityId of entityIds) {\n if (this.activeMaintenanceJobs.has(this._importKey(entityId))) {\n throw new WikiBusyError('import', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n throw new WikiBusyError('librarian', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n throw new WikiBusyError('heal', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isIngestActiveFor(entityId)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n }\n // Global import lock check after per-entity checks: serializes concurrent\n // importDump() calls for *different* entities so they cannot race on the shared\n // embedding_dimension / embedding_dimension_mismatch meta keys.\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) {\n throw new WikiBusyError('import', '*');\n }\n\n // Acquire global + per-entity import locks before any await so the lock check and\n // lock acquisition remain race-free across concurrent importDump() calls.\n this.activeMaintenanceJobs.add(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.add(this._importKey(entityId));\n }\n try {\n // Fail before any writes so we never partially commit an import and then reject\n // with a migration error — same probe as setup().\n await this.assertNoLegacySourceTypes();\n\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n await this._doImportEntity(entityId, bundle, merge);\n }\n } finally {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.delete(this._importKey(entityId));\n }\n }\n }\n\n private async _doImportEntity(entityId: string, bundle: MemoryBundle, merge: boolean): Promise<void> {\n // Track which fact IDs were actually inserted/updated inside the transaction.\n // Skipped rows (cross-entity collisions or merge LWW losers) must not be\n // re-embedded — doing so would corrupt the winning row's vector with the\n // losing fact's title/body.\n const upsertedFactIds = new Set<string>();\n // Track upserted facts whose incoming row is soft-deleted. In replace mode,\n // these IDs still need vector=null notifications because they remain deleted.\n const upsertedDeletedFactIds = new Set<string>();\n // Track which upserted facts already carry a valid BLOB so we can skip\n // embedFact() for them. BLOBs are reconstructed from three serialization\n // forms: in-memory Uint8Array/Buffer, Node.js Buffer JSON shape, and\n // numeric-keyed plain objects produced by JSON.stringify(Uint8Array).\n // Store the blob data so we can notify the external vector index after the transaction.\n const factsWithPreservedBlob = new Map<string, Uint8Array>();\n // Track every unique dimension seen in preserved BLOBs. A dump may contain\n // blobs from multiple models (e.g. an intermediate mixed-model migration),\n // so we call storeEmbeddingDimension() for each unique dimension found to\n // ensure the mismatch flag is set whenever any two stored blobs disagree.\n const preservedBlobDims = new Set<number>();\n // In replace mode, collect IDs of facts that will be soft-deleted so we can\n // notify the external vector index with vector=null after the transaction.\n // Without this, external indexes retain stale embeddings and keep returning\n // deleted fact IDs in ranking results.\n const softDeletedFactIds: string[] = [];\n await this.db.withTransactionAsync(async () => {\n if (!merge) {\n // Collect IDs of live facts that will be soft-deleted\n const toDelete = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId]\n );\n softDeletedFactIds.push(...toDelete.map(r => r.id));\n const now = Date.now();\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId]\n );\n await this.db.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId]\n );\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId]\n );\n }\n\n const factIds = bundle.facts.map((fact) => fact.id);\n const existingFactsById = new Map<string, { id: string; entity_id: string; updated_at: number }>();\n const factLookupChunkSize = 500;\n for (let i = 0; i < factIds.length; i += factLookupChunkSize) {\n const factIdChunk = factIds.slice(i, i + factLookupChunkSize);\n if (factIdChunk.length === 0) continue;\n const placeholders = factIdChunk.map(() => '?').join(', ');\n const existingFacts = await this.db.getAllAsync<{ id: string; entity_id: string; updated_at: number }>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}entries WHERE id IN (${placeholders})`,\n factIdChunk\n );\n for (const existingFact of existingFacts) {\n existingFactsById.set(existingFact.id, existingFact);\n }\n }\n\n for (const fact of bundle.facts) {\n const sourceType = this._normalizeImportedSourceType(String(fact.source_type), {\n entityId,\n factId: fact.id,\n });\n const tagsJson = JSON.stringify(Array.isArray(fact.tags) ? fact.tags : []);\n // Normalize once: non-finite (undefined/null/NaN) → 0 so we never persist an\n // invalid value to the DB and ORDER BY updated_at remains meaningful.\n const safeUpdatedAt = Number.isFinite(fact.updated_at) ? fact.updated_at : 0;\n const existing = existingFactsById.get(fact.id);\n\n // Extract a valid BLOB from the incoming fact.\n // Three serialization forms are normalised to Uint8Array:\n // 1. Real Uint8Array / Buffer (in-memory dump)\n // 2. Node.js Buffer JSON shape { type:'Buffer', data:[...] }\n // (produced by JSON.stringify(buffer))\n // 3. Numeric-keyed plain object {0:byte, 1:byte, ...}\n // (produced by JSON.stringify(Uint8Array))\n const rawBlobRaw = (fact as WikiFact & { embedding_blob?: unknown }).embedding_blob;\n let rawBlob: Uint8Array | null = null;\n if (rawBlobRaw instanceof Uint8Array) {\n rawBlob = rawBlobRaw;\n } else if (\n rawBlobRaw !== null &&\n rawBlobRaw !== undefined &&\n typeof rawBlobRaw === 'object'\n ) {\n const obj = rawBlobRaw as Record<string, unknown>;\n if (obj['type'] === 'Buffer' && Array.isArray(obj['data'])) {\n // Node.js Buffer serialized via JSON.stringify(buffer)\n rawBlob = new Uint8Array(obj['data'] as number[]);\n } else if (!Array.isArray(rawBlobRaw)) {\n // Numeric-keyed plain object from JSON.stringify(Uint8Array)\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every(k => /^\\d+$/.test(k))) {\n const len = entries.length;\n rawBlob = new Uint8Array(len);\n for (let i = 0; i < len; i++) rawBlob[i] = (obj[String(i)] as number) ?? 0;\n }\n }\n }\n let blobData: Uint8Array | null = null;\n if (\n rawBlob !== null &&\n rawBlob.byteLength > 0 &&\n rawBlob.byteLength % 4 === 0\n ) {\n // Also validate that every float32 value is finite: a blob with the right\n // byte length but NaN/Inf values would be preserved, skip embedFact(), and\n // then be silently dropped by read(), making the fact permanently unsearchable.\n // Copy into a fresh ArrayBuffer so the Float32Array view is guaranteed to\n // start at offset 0 of its own buffer. Buffer.slice(0) in Node.js does NOT\n // copy — it returns a view into the parent buffer, which can have a non-zero\n // byteOffset and corrupt the Float32Array interpretation.\n const copy = new ArrayBuffer(rawBlob.byteLength);\n const alignedBlob = new Uint8Array(copy);\n alignedBlob.set(rawBlob);\n const floats = new Float32Array(copy, 0, rawBlob.byteLength / 4);\n let allFinite = true;\n for (let i = 0; i < floats.length; i++) {\n if (!isFinite(floats[i])) { allFinite = false; break; }\n }\n if (allFinite) {\n // Preserve this blob regardless of its dimension. Mixed-dimension\n // blobs are a real intermediate state during model migration and\n // silently discarding valid vectors is worse than importing them;\n // storeEmbeddingDimension() and read()'s mismatch-check handle\n // the case where stored blobs disagree on size.\n // Note: same-dimension model changes (e.g. two different providers\n // that happen to produce 1536-dim vectors) are undetectable here —\n // there is no model fingerprint in the blob. Callers importing from\n // a different provider should call runReembed() after importDump()\n // rather than relying on { skipExisting: true }.\n // Store aligned copy (not rawBlob) to avoid Float32Array alignment errors in notification.\n blobData = alignedBlob;\n }\n }\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision('entry', fact.id, existing.entity_id, entityId);\n continue;\n }\n if (merge) {\n // LWW: incoming wins only if its updated_at is strictly newer than local.\n // 0 (epoch) never beats a real timestamp, so invalid incoming rows are skipped.\n if (safeUpdatedAt <= existing.updated_at) continue;\n }\n if (blobData != null) {\n // Incoming fact carries a valid BLOB (in-memory dump): persist it directly\n // and skip embedFact() — no embedding API call required.\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET entity_id = ?, title = ?, body = ?, tags = ?, confidence = ?, source_type = ?, source_hash = ?, source_ref = ?, created_at = ?, updated_at = ?, last_accessed_at = ?, access_count = ?, deleted_at = ?, embedding_blob = ?, embedding = NULL WHERE id = ?`,\n [entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, blobData, fact.id]\n );\n factsWithPreservedBlob.set(fact.id, blobData);\n // Only track dimensions for live facts: read() and _reconcileEmbeddingDimension()\n // both filter by deleted_at IS NULL, so a soft-deleted stale blob must not\n // set embedding_dimension_mismatch and block retrieval on healthy live facts.\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n } else {\n // read() never ranks the new title/body against the old vector;\n // the post-transaction embedding loop will re-embed.\n // If embedFact() fails (provider absent or throws), the NULL vector\n // remains, which is correct: new content with no valid embedding\n // falls back to keyword-only retrieval.\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET entity_id = ?, title = ?, body = ?, tags = ?, confidence = ?, source_type = ?, source_hash = ?, source_ref = ?, created_at = ?, updated_at = ?, last_accessed_at = ?, access_count = ?, deleted_at = ?, embedding_blob = NULL, embedding = NULL WHERE id = ?`,\n [entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, fact.id]\n );\n }\n existingFactsById.set(fact.id, { id: fact.id, entity_id: entityId, updated_at: safeUpdatedAt });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n } else {\n if (blobData != null) {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count, deleted_at, embedding_blob) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [fact.id, entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at, blobData]\n );\n factsWithPreservedBlob.set(fact.id, blobData);\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n } else {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count, deleted_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [fact.id, entityId, fact.title, fact.body, tagsJson, fact.confidence, sourceType, fact.source_hash, fact.source_ref, fact.created_at, safeUpdatedAt, fact.last_accessed_at, fact.access_count, fact.deleted_at]\n );\n }\n existingFactsById.set(fact.id, { id: fact.id, entity_id: entityId, updated_at: safeUpdatedAt });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n }\n }\n\n const taskIds = bundle.tasks.map((task) => task.id);\n const existingTasksById = new Map<string, { id: string; entity_id: string; updated_at: number }>();\n const taskLookupChunkSize = 500;\n\n for (let i = 0; i < taskIds.length; i += taskLookupChunkSize) {\n const taskIdChunk = taskIds.slice(i, i + taskLookupChunkSize);\n if (taskIdChunk.length === 0) continue;\n\n const placeholders = taskIdChunk.map(() => '?').join(', ');\n const existingTasks = await this.db.getAllAsync<{ id: string; entity_id: string; updated_at: number }>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}tasks WHERE id IN (${placeholders})`,\n taskIdChunk\n );\n\n for (const existingTask of existingTasks) {\n existingTasksById.set(existingTask.id, existingTask);\n }\n }\n\n for (const task of bundle.tasks) {\n // Normalize once: non-finite (undefined/null/NaN) → 0 so we never persist an\n // invalid value to the DB and ORDER BY updated_at remains meaningful.\n const safeUpdatedAt = Number.isFinite(task.updated_at) ? task.updated_at : 0;\n const existing = existingTasksById.get(task.id);\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision('task', task.id, existing.entity_id, entityId);\n continue;\n }\n if (merge) {\n // LWW: incoming wins only if its updated_at is strictly newer than local.\n // 0 (epoch) never beats a real timestamp, so invalid incoming rows are skipped.\n if (safeUpdatedAt <= existing.updated_at) continue;\n }\n // replace mode (or merge LWW winner): update the existing row (restores if soft-deleted)\n await this.db.runAsync(\n `UPDATE ${this.prefix}tasks SET entity_id = ?, description = ?, status = ?, priority = ?, created_at = ?, updated_at = ?, resolved_at = ?, deleted_at = ? WHERE id = ?`,\n [entityId, task.description, task.status, task.priority, task.created_at, safeUpdatedAt, task.resolved_at, task.deleted_at, task.id]\n );\n existingTasksById.set(task.id, { id: task.id, entity_id: entityId, updated_at: safeUpdatedAt });\n } else {\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}tasks (id, entity_id, description, status, priority, created_at, updated_at, resolved_at, deleted_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [task.id, entityId, task.description, task.status, task.priority, task.created_at, safeUpdatedAt, task.resolved_at, task.deleted_at]\n );\n existingTasksById.set(task.id, { id: task.id, entity_id: entityId, updated_at: safeUpdatedAt });\n }\n }\n\n for (const event of bundle.events) {\n await this.db.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [event.id, entityId, event.event_type, event.summary, event.related_entry_id ?? null, event.created_at]\n );\n }\n });\n // Invalidate cache before rebuilding the text index so concurrent reads\n // see consistent data: all use the post-transaction DB state.\n this.vectorCache.delete(entityId);\n // Rebuild the MiniSearch index immediately after the transaction commits\n // so concurrent read() calls using preFilterLimit or hybrid scoring get\n // the updated text rather than waiting for the (potentially slow) embedding loop.\n await this.rebuildMiniSearchIndex(entityId);\n // Embed only facts that were actually inserted/updated in the transaction.\n // Skipped rows (cross-entity collisions or merge LWW losers) must not be\n // re-embedded — they were not written and their existing row must not be\n // overwritten with the incoming fact's content.\n // Facts with preserved BLOBs (from an in-memory dump) already have valid\n // embeddings; skip embedFact() for those to avoid redundant API calls.\n // For facts without a BLOB, the UPDATE/INSERT already left embedding_blob = NULL,\n // so if embedFact() fails here the row correctly has a NULL vector.\n for (const fact of bundle.facts) {\n if (!fact.deleted_at && upsertedFactIds.has(fact.id) && !factsWithPreservedBlob.has(fact.id)) {\n await this.embedFact({\n id: fact.id,\n entity_id: entityId, // Use authoritative entityId from dump key, not fact.entity_id\n title: fact.title,\n body: fact.body,\n tags: Array.isArray(fact.tags) || typeof fact.tags === 'string' ? fact.tags : [],\n });\n }\n }\n // Notify external vector index about preserved-blob facts.\n // These skipped embedFact(), so _notifyEmbeddingPersisted was never called.\n // Only notify for live facts (skip soft-deleted) to avoid polluting external index.\n for (const fact of bundle.facts) {\n const blobData = factsWithPreservedBlob.get(fact.id);\n if (blobData && !fact.deleted_at && upsertedFactIds.has(fact.id)) {\n try {\n const float32Vector = new Float32Array(blobData.buffer, blobData.byteOffset, blobData.byteLength / 4);\n await this._notifyEmbeddingPersisted(entityId, fact.id, float32Vector);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed for preserved-blob fact ${fact.id}:`, hookErr);\n }\n }\n }\n // In replace mode, notify external vector index that soft-deleted facts should be removed.\n // Re-upserted facts are usually restores, except when the incoming row is still\n // soft-deleted (deleted_at set). Those must also receive vector=null.\n for (const factId of softDeletedFactIds) {\n if (!upsertedFactIds.has(factId) || upsertedDeletedFactIds.has(factId)) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted(vector=null) hook failed for soft-deleted fact ${factId}:`, hookErr);\n }\n }\n }\n // If any facts carried preserved BLOBs, record the vector dimension in the\n // meta table now (embedFact() was skipped for those rows, so it didn't happen\n // automatically). This ensures read() can detect model-dimension mismatches\n // after importing into a fresh DB that has never seen an embedding.\n // However, if the preserved BLOBs have a *different* dimension than the\n // current canonical dimension, skip bookkeeping entirely. Calling\n // storeEmbeddingDimension() with the imported dimension would set\n // embedding_dimension_mismatch, which _reconcileEmbeddingDimension() would\n // interpret as the target dimension. After runReembed() rewrites everything\n // to the canonical dimension, the mismatch flag would never clear (all facts\n // now differ from the old imported dimension, so residual count > 0 forever).\n // Instead, let runReembed() reconcile all vectors without pre-seeding metadata.\n try {\n // Query the current canonical embedding dimension, if any.\n const canonicalRow = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension'`\n );\n const canonicalDim = canonicalRow ? parseInt(canonicalRow.value, 10) : null;\n\n if (preservedBlobDims.size === 1) {\n const preservedDim = [...preservedBlobDims][0];\n if (canonicalDim === null || canonicalDim === preservedDim) {\n // Fresh DB: record the imported dimension as canonical.\n // Matching canonical: storeEmbeddingDimension is a no-op for equal dims,\n // but a stale embedding_dimension_mismatch flag may still be present from\n // a previous import. Run reconciliation so the flag is cleared if all live\n // facts now agree on the canonical dimension.\n await this.storeEmbeddingDimension(preservedDim);\n // If a stale embedding_dimension_mismatch flag exists from a prior failed\n // model switch it may target a different dimension. _reconcileEmbeddingDimension()\n // checks residuals against whatever value the flag holds; a wrong value keeps\n // the flag stuck even though all imported blobs now match preservedDim.\n // Overwrite the flag to preservedDim before reconciling so the check is correct.\n const staleMismatch = await this.db.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`\n );\n if (staleMismatch && parseInt(staleMismatch.value, 10) !== preservedDim) {\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(preservedDim)]\n );\n }\n await this._reconcileEmbeddingDimension();\n } else {\n // Imported blobs differ from the canonical model dimension. Set\n // embedding_dimension_mismatch = canonicalDim so that:\n // (a) read() detects the mismatch and falls back to MiniSearch, and\n // (b) _reconcileEmbeddingDimension() can clear the flag after\n // runReembed() rewrites all blobs to canonicalDim.\n // Using the imported dim as the mismatch value would deadlock:\n // after runReembed(), all blobs have canonicalDim ≠ importedDim, so\n // the residual count never reaches 0 and the flag is never cleared.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(canonicalDim)]\n );\n }\n } else if (preservedBlobDims.size > 1) {\n if (canonicalDim === null) {\n // Fresh import with mixed BLOBs: seed canonical with the smallest imported\n // dimension, then write embedding_dimension_mismatch = that same canonical\n // value. Seeding mismatch = canonical (not dim[1]) ensures\n // _reconcileEmbeddingDimension() can always clear the flag:\n // - If runReembed() uses the same dim as canonical: storeEmbeddingDimension\n // is a no-op, mismatch stays = canonical, residual = 0 → clears. ✓\n // - If runReembed() uses a different dim: storeEmbeddingDimension overwrites\n // mismatch = currentDim, residual = 0 after full reembed → clears. ✓\n // Seeding mismatch = dim[1] instead would deadlock the second case: after\n // runReembed(), all blobs have currentDim ≠ dim[1] → residual > 0 forever.\n const sortedPreservedBlobDims = [...preservedBlobDims].sort((a, b) => a - b);\n await this.storeEmbeddingDimension(sortedPreservedBlobDims[0]);\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(sortedPreservedBlobDims[0])]\n );\n } else {\n // Import into an existing wiki with mixed-dimension blobs. Set\n // mismatch = canonicalDim so the flag clears correctly after runReembed()\n // rewrites everything to the canonical model.\n await this.db.runAsync(\n `INSERT OR REPLACE INTO ${this.prefix}meta (key, value) VALUES ('embedding_dimension_mismatch', ?)`,\n [String(canonicalDim)]\n );\n }\n }\n } finally {\n // Second flush: evict any cache entries a concurrent read() repopulated\n // from old DB vectors while the embedding loop was running. Runs even if\n // storeEmbeddingDimension() throws so stale entries cannot survive an error.\n this.vectorCache.delete(entityId);\n }\n }\n\n async forget(entityId: string, params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean }): Promise<{ deleted: { entries: number; tasks: number } }> {\n let blockingOperation: \"librarian\" | \"heal\" | \"prune\" | \"reembed\" | \"ingest\" | \"forget\" | \"import\" | null = null;\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) {\n blockingOperation = 'librarian';\n } else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) {\n blockingOperation = 'heal';\n } else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n blockingOperation = 'prune';\n } else if (this._isReembedActive(entityId)) {\n blockingOperation = 'reembed';\n } else if (this._isIngestActiveFor(entityId)) {\n blockingOperation = 'ingest';\n } else if (this._isImportActiveFor(entityId)) {\n blockingOperation = 'import';\n } else if (this._isForgetActiveFor(entityId)) {\n blockingOperation = 'forget';\n }\n if (blockingOperation !== null) {\n throw new WikiBusyError(blockingOperation, entityId);\n }\n const forgetKey = this._forgetKey(entityId);\n this.activeMaintenanceJobs.add(forgetKey);\n try {\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n const deletedEntryIds: string[] = [];\n\n if (params.clearAll) {\n // Select both new deletions and already-soft-deleted (for hook retry on failure)\n const newDeletions = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId]\n );\n const alreadySoftDeleted = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL`,\n [entityId]\n );\n deletedEntryIds.push(...newDeletions.map(e => e.id), ...alreadySoftDeleted.map(e => e.id));\n\n const [entriesRes, tasksRes] = await Promise.all([\n this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`, [now, now, entityId]),\n this.db.runAsync(`UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`, [now, now, entityId]),\n ]);\n await this.db.runAsync(`UPDATE ${this.prefix}checkpoints SET memory_checkpoint = 0, heal_checkpoint = 0 WHERE entity_id = ?`, [entityId]);\n deletedEntries = entriesRes.changes;\n deletedTasks = tasksRes.changes;\n } else {\n const hasIdSelectors = params.entryId !== undefined || params.taskId !== undefined;\n const hasSourceSelectors = params.sourceRef !== undefined || params.sourceHash !== undefined;\n if (hasIdSelectors && hasSourceSelectors) {\n throw new Error('forget() params are mutually exclusive: use entryId/taskId together, or sourceRef/sourceHash together, but not both in the same call');\n }\n\n const sourceRef = params.sourceRef !== undefined ? normalizeSourceRef(params.sourceRef) : null;\n if (params.sourceRef !== undefined && !sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = params.sourceHash !== undefined ? normalizeSourceHash(params.sourceHash) : null;\n if (params.sourceHash !== undefined && !sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n if (params.entryId) {\n // Select entry regardless of deleted_at to allow hook retry on already-soft-deleted rows\n const entry = await this.db.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ?`,\n [params.entryId, entityId]\n );\n if (entry) deletedEntryIds.push(entry.id);\n }\n\n if (sourceRef || sourceHash) {\n // Select entries regardless of deleted_at to allow hook retry on already-soft-deleted rows\n let q = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ?`;\n const args: any[] = [entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n const entriesToDelete = await this.db.getAllAsync<{ id: string }>(q, args);\n deletedEntryIds.push(...entriesToDelete.map(e => e.id));\n }\n\n const entryPromise = params.entryId\n ? this.db.runAsync(`UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`, [now, now, params.entryId, entityId])\n : null;\n\n const taskPromise = params.taskId\n ? this.db.runAsync(`UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`, [now, now, params.taskId, entityId])\n : null;\n\n let refPromise: Promise<{ changes: number; lastInsertRowId: number }> | null = null;\n if (sourceRef || sourceHash) {\n let q = `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: any[] = [now, now, entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n refPromise = this.db.runAsync(q, args);\n }\n\n const [entryResult, taskResult, refResult] = await Promise.all([\n entryPromise ?? Promise.resolve(null),\n taskPromise ?? Promise.resolve(null),\n refPromise ?? Promise.resolve(null),\n ]);\n\n if (entryResult) deletedEntries += entryResult.changes;\n if (taskResult) deletedTasks += taskResult.changes;\n if (refResult) deletedEntries += refResult.changes;\n }\n\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n\n // Deduplicate to avoid redundant hook calls for the same fact\n const uniqueDeletedIds = Array.from(new Set(deletedEntryIds));\n for (const factId of uniqueDeletedIds) {\n try {\n await this._notifyEmbeddingPersistedOrThrow(entityId, factId, null);\n } catch (hookErr) {\n // Preserve timeout errors (thrown by WikiMemory, not the ranker)\n const isTimeout = (hookErr as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new Error(\n `forget(${entityId}/${factId}) failed: ${(hookErr as Error).message}`,\n );\n }\n // Preserve WikiMemory validation errors (not from the adapter hook)\n const errMsg = (hookErr as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n if (isValidationError) {\n throw new Error(\n `forget(${entityId}/${factId}) failed: ${errMsg}`,\n { cause: hookErr },\n );\n }\n // Actual hook rejection - sanitize error details\n throw new Error(\n `forget(${entityId}/${factId}) failed: ANN cleanup hook rejected`,\n { cause: this._sanitizeRankerError(hookErr) },\n );\n }\n }\n\n return { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.activeMaintenanceJobs.delete(forgetKey);\n }\n }\n\n async ingestDocument(entityId: string, params: { sourceRef: string; sourceHash: string; documentChunk: string; maxChunkLength?: number; chunkOverlap?: number; chunkConcurrency?: number }): Promise<{ truncated: boolean; chunks: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = normalizeSourceHash(params.sourceHash);\n if (!sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n const maxChunkLength = params.maxChunkLength ?? this.options.config?.maxChunkLength ?? 12000;\n const rawOverlap = params.chunkOverlap ?? this.options.config?.chunkOverlap ?? 400;\n const chunkOverlap = Math.min(\n Number.isFinite(rawOverlap) && rawOverlap >= 0 ? Math.floor(rawOverlap) : 400,\n maxChunkLength - 1\n );\n const rawConcurrency = params.chunkConcurrency ?? this.options.config?.chunkConcurrency ?? 1;\n const chunkConcurrency = Number.isFinite(rawConcurrency) && rawConcurrency >= 1\n ? Math.floor(rawConcurrency)\n : 1;\n\n if (typeof params.documentChunk !== 'string') {\n throw new Error(`documentChunk must be a string, received ${typeof params.documentChunk}`);\n }\n\n const jobKey = `${this.prefix}:${entityId}:${sourceRef}`;\n if (this.activeIngestJobs.has(jobKey)) {\n throw new WikiBusyError('ingest', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) {\n throw new WikiBusyError('prune', entityId);\n }\n if (this._isReembedActive(entityId)) {\n throw new WikiBusyError('reembed', entityId);\n }\n if (this._isImportActiveFor(entityId)) {\n throw new WikiBusyError('import', entityId);\n }\n if (this._isForgetActiveFor(entityId)) {\n throw new WikiBusyError('forget', entityId);\n }\n this.activeIngestJobs.add(jobKey);\n this._notifyStatusSubscribers(entityId);\n\n try {\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n\n if (chunks.length === 0) {\n return { truncated: false, chunks: 0 };\n }\n\n // Bounded-concurrency LLM calls — each chunk is independent\n const chunkResults = await withConcurrency(\n chunks.map((chunk) => async () => {\n const userPrompt = `Document Chunk:\\n${chunk}`;\n const responseText = await this.options.llmProvider.generateText({\n systemPrompt: INGEST_SYSTEM_PROMPT,\n userPrompt,\n });\n const result = parseJsonResponse<{ facts: ExtractedFact[] }>(responseText);\n return (Array.isArray(result.facts) ? result.facts : [])\n .map(validateFact)\n .filter((f): f is ExtractedFact => f !== null);\n }),\n chunkConcurrency\n );\n\n // Flatten in chunk order, then dedup by normalized title (first-wins)\n const seen = new Set<string>();\n const allValidFacts: ExtractedFact[] = [];\n for (const facts of chunkResults) {\n for (const fact of facts) {\n const normalized = fact.title.trim().toLowerCase().replace(/\\s+/g, ' ');\n if (!seen.has(normalized)) {\n seen.add(normalized);\n allValidFacts.push(fact);\n }\n }\n }\n\n const now = Date.now();\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const deletedSourceFactIds: string[] = [];\n\n await this.db.withTransactionAsync(async () => {\n const existingSourceFacts = await this.db.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE source_ref = ? AND entity_id = ? AND deleted_at IS NULL`,\n [sourceRef, entityId]\n );\n for (const row of existingSourceFacts) {\n deletedSourceFactIds.push(row.id);\n }\n\n await this.db.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE source_ref = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, sourceRef, entityId]\n );\n for (const fact of allValidFacts) {\n const id = generateId('fact_');\n await this.db.runAsync(\n `INSERT INTO ${this.prefix}entries (id, entity_id, title, body, tags, confidence, source_type, source_hash, source_ref, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [id, entityId, fact.title, fact.body, JSON.stringify(fact.tags), fact.confidence, 'immutable_document', sourceHash, sourceRef, now, now]\n );\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n }\n });\n\n // Rebuild text index before embedding so concurrent reads see new content.\n await this.rebuildMiniSearchIndex(entityId);\n this.vectorCache.delete(entityId);\n const uniqueDeletedSourceFactIds = Array.from(new Set(deletedSourceFactIds));\n for (const factId of uniqueDeletedSourceFactIds) {\n try {\n await this._notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during ingest for ${factId}:`, hookErr);\n }\n }\n for (const fact of insertedFacts) {\n await this.embedFact(fact);\n }\n // Second flush after embed loop in case a concurrent read() repopulated cache.\n this.vectorCache.delete(entityId);\n\n return { truncated, chunks: chunks.length };\n } finally {\n this.activeIngestJobs.delete(jobKey);\n this._notifyStatusSubscribers(entityId);\n }\n }\n}\n\nexport const __testables = { validateFact, validateTask, clip, chunkText };\n","import type { MemoryBundle, WikiFact, WikiTask, WikiEvent, FormatContextOptions } from '../types';\n\nfunction validateMaxOption(value: number, name: string): void {\n if (!isFinite(value) || value < 0) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number`);\n }\n}\n\nconst CONFIDENCE_WEIGHT: Record<string, number> = {\n certain: 1.0,\n inferred: 0.6,\n tentative: 0.3,\n};\n\nfunction scoreFactFor(\n fact: WikiFact,\n weights: Required<NonNullable<FormatContextOptions['factWeights']>>,\n now: number\n): number {\n const confW = CONFIDENCE_WEIGHT[fact.confidence] ?? 0.3;\n const ageDays = (now - fact.updated_at) / 86400000;\n const recencyDecay = Math.exp(-ageDays / 30);\n return (\n confW * weights.confidence +\n Math.log(1 + fact.access_count) * weights.accessCount +\n recencyDecay * weights.recency\n );\n}\n\nfunction renderFactMarkdown(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `- **${fact.title}**${confPart}${tagPart}${sourcePart}${scorePart}\\n ${fact.body.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderFactPlain(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `${fact.title}${confPart}${tagPart}${sourcePart}${scorePart}: ${fact.body}`;\n}\n\nfunction renderTaskMarkdown(task: WikiTask): string {\n return `- [P${task.priority}] ${task.description.replace(/\\n/g, '\\n ')} (${task.status})`;\n}\n\nfunction renderTaskPlain(task: WikiTask): string {\n return `[P${task.priority}] ${task.description} (${task.status})`;\n}\n\nfunction renderEventMarkdown(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `- [${event.event_type} @ ${ts}] ${event.summary.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderEventPlain(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `[${event.event_type} @ ${ts}] ${event.summary}`;\n}\n\nexport function formatContext(\n bundle: MemoryBundle,\n options?: FormatContextOptions\n): string {\n const opts: Required<FormatContextOptions> = {\n format: options?.format ?? 'markdown',\n maxFacts: options?.maxFacts ?? 10,\n maxTasks: options?.maxTasks ?? 10,\n maxEvents: options?.maxEvents ?? 10,\n includeConfidence: options?.includeConfidence ?? true,\n includeTags: options?.includeTags ?? true,\n includeEntityIds: options?.includeEntityIds ?? false,\n includeFactScores: options?.includeFactScores ?? false,\n factWeights: {\n confidence: options?.factWeights?.confidence ?? 1.0,\n accessCount: options?.factWeights?.accessCount ?? 0.3,\n recency: options?.factWeights?.recency ?? 0.5,\n },\n };\n\n validateMaxOption(opts.maxFacts, 'maxFacts');\n validateMaxOption(opts.maxTasks, 'maxTasks');\n validateMaxOption(opts.maxEvents, 'maxEvents');\n\n const weights = opts.factWeights as Required<NonNullable<FormatContextOptions['factWeights']>>;\n\n const now = Date.now();\n const sortedFacts = bundle.factScores\n ? [...bundle.facts].slice(0, opts.maxFacts)\n : [...bundle.facts]\n .sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now))\n .slice(0, opts.maxFacts);\n\n const sortedTasks = [...bundle.tasks]\n .sort((a, b) => b.priority - a.priority || a.created_at - b.created_at)\n .slice(0, opts.maxTasks);\n\n const sortedEvents = [...bundle.events]\n .sort((a, b) => b.created_at - a.created_at)\n .slice(0, opts.maxEvents);\n\n if (sortedFacts.length === 0 && sortedTasks.length === 0 && sortedEvents.length === 0) {\n return '';\n }\n\n const isMarkdown = opts.format === 'markdown';\n const lines: string[] = [];\n\n if (isMarkdown) {\n lines.push('## Memory');\n\n if (sortedFacts.length > 0) {\n lines.push('');\n lines.push('### Known Facts');\n for (const fact of sortedFacts) {\n lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n\n if (sortedTasks.length > 0) {\n lines.push('');\n lines.push('### Open Tasks');\n for (const task of sortedTasks) {\n lines.push(renderTaskMarkdown(task));\n }\n }\n\n if (sortedEvents.length > 0) {\n lines.push('');\n lines.push('### Recent Events');\n for (const event of sortedEvents) {\n lines.push(renderEventMarkdown(event));\n }\n }\n } else {\n if (sortedFacts.length > 0) {\n lines.push('KNOWN FACTS:');\n for (const fact of sortedFacts) {\n lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n if (sortedTasks.length > 0) {\n lines.push('OPEN TASKS:');\n for (const task of sortedTasks) {\n lines.push(renderTaskPlain(task));\n }\n }\n if (sortedEvents.length > 0) {\n lines.push('RECENT EVENTS:');\n for (const event of sortedEvents) {\n lines.push(renderEventPlain(event));\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import type { MemoryDump, FormattedMemoryDump, MemoryBundle, WikiFact, WikiTask, WikiEvent } from '../types';\n\nfunction renderFact(f: WikiFact): string {\n const tags = (f.tags || []).join(', ');\n const source = f.source_ref ?? f.source_type;\n return `### ${f.title}\n**Tags:** ${tags}\n**Confidence:** ${f.confidence}\n**Source:** ${source}\n\n${f.body}\n\n---\n`;\n}\n\nfunction renderTask(t: WikiTask): string {\n const checked = t.status === 'done' ? 'x' : ' ';\n const note = t.status === 'done' ? ' (done)'\n : t.status === 'abandoned' ? ' (abandoned)'\n : t.status === 'in_progress' ? ' (in progress)'\n : '';\n return `- [${checked}] ${t.description}${note}\\n`;\n}\n\nfunction renderEvent(e: WikiEvent): string {\n const ts = new Date(e.created_at).toISOString();\n return `- [${ts}] (${e.event_type}) ${e.summary}\\n`;\n}\n\nfunction renderEntity(entityId: string, bundle: MemoryBundle, generatedAt: number): string {\n const lines: string[] = [];\n lines.push(`# Memory Dump: ${entityId}`);\n lines.push(`Generated: ${new Date(generatedAt).toISOString()}`);\n lines.push('');\n lines.push('## Facts');\n lines.push('');\n if (bundle.facts.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const f of bundle.facts) lines.push(renderFact(f));\n }\n lines.push('## Tasks');\n lines.push('');\n if (bundle.tasks.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const t of bundle.tasks) lines.push(renderTask(t));\n }\n lines.push('');\n lines.push('## Recent Events');\n lines.push('');\n if (bundle.events.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const e of bundle.events) lines.push(renderEvent(e));\n }\n return lines.join('\\n');\n}\n\nfunction shortHash(value: string): string {\n let h1 = 5381;\n let h2 = 52711;\n for (let i = 0; i < value.length; i += 1) {\n const c = value.charCodeAt(i);\n h1 = Math.imul(h1, 33) ^ c;\n h2 = Math.imul(h2, 31) ^ c;\n }\n return (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction formatEntityFileName(entityId: string): string {\n const normalized = entityId.normalize('NFKC');\n const sanitized = normalized\n .replace(/[^A-Za-z0-9._-]+/g, '_')\n .replace(/^\\.+/, '_')\n .replace(/_+/g, '_')\n .replace(/^[_-]+|[_-]+$/g, '');\n\n // Enforce a max base-name length so the final filename stays within typical\n // filesystem limits (~255 bytes). Reserve ~20 chars for `-<16hexchars>.md`.\n const MAX_BASE = 200;\n const trimmed = sanitized.length > MAX_BASE ? sanitized.slice(0, MAX_BASE) : sanitized;\n\n const baseName = trimmed && trimmed !== '.' && trimmed !== '..'\n ? trimmed\n : 'entity';\n const needsSuffix = baseName !== entityId || sanitized.length > MAX_BASE;\n const uniqueBaseName = needsSuffix ? `${baseName}-${shortHash(entityId)}` : baseName;\n\n return `${uniqueBaseName}.md`;\n}\n\nexport function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump {\n const files = Object.entries(dump.entities).map(([entityId, bundle]) => ({\n name: formatEntityFileName(entityId),\n content: renderEntity(entityId, bundle, dump.generatedAt),\n }));\n\n // Strip embedding_blob from each fact before JSON-serialising the manifest.\n // exportDump() now includes raw Uint8Array blobs for importDump() round-trips,\n // but those binaries serve no purpose in a human-readable manifest and can\n // massively inflate its size for non-trivial datasets.\n const manifestDump: MemoryDump = {\n generatedAt: dump.generatedAt,\n entities: Object.fromEntries(\n Object.entries(dump.entities).map(([entityId, bundle]) => [\n entityId,\n {\n ...bundle,\n facts: bundle.facts.map(f => {\n const { embedding_blob: _blob, ...rest } = f as WikiFact & { embedding_blob?: unknown };\n return rest as WikiFact;\n }),\n },\n ])\n ),\n };\n\n return {\n manifest: JSON.stringify(manifestDump, null, 2),\n files,\n };\n}\n","import type { ReadOptions } from './types';\n\nexport interface LibrarianOptions {\n /** If provided, replaces the default Librarian system instructions. */\n systemPrompt?: string;\n /** entity_id -> score multiplier, forwarded to WikiMemory.read() as tierWeights. */\n entityWeights?: Record<string, number>;\n /** Forwarded to WikiMemory.read() for zero-weight filler context. */\n includeZeroWeightEntities?: boolean;\n temperature?: number;\n}\n\nexport interface LibrarianPromptVariables {\n context: string;\n tasks: string;\n query: string;\n}\n\nexport const DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = `You are a careful memory synthesis assistant.\nUse only the retrieved context when answering the request.\nPreserve source provenance when facts come from different entity namespaces.\n\nRequest:\n{{query}}\n\nRetrieved context:\n{{context}}\n\nOpen tasks:\n{{tasks}}`;\n\nexport function hydrateLibrarianPrompt(\n template: string,\n variables: LibrarianPromptVariables,\n): string {\n return template.replace(/\\{\\{(context|tasks|query)\\}\\}/g, (_, key) => variables[key as keyof LibrarianPromptVariables]);\n}\n\nexport function validateLibrarianPromptTemplate(\n template: string,\n options: { custom: boolean; taskCount: number },\n): string[] {\n if (!options.custom) return [];\n\n const warnings: string[] = [];\n if (!template.includes('{{context}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{context}}; retrieved memory will not be injected.');\n }\n if (!template.includes('{{query}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{query}}; the original request will not be injected.');\n }\n if (options.taskCount > 0 && !template.includes('{{tasks}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{tasks}} while retrieved tasks are available.');\n }\n return warnings;\n}\n\nexport function mapLibrarianOptionsToReadOptions(\n options: LibrarianOptions,\n): Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> {\n const readOptions: Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> = {};\n if (options.entityWeights !== undefined) readOptions.tierWeights = options.entityWeights;\n if (options.includeZeroWeightEntities !== undefined) {\n readOptions.includeZeroWeightEntities = options.includeZeroWeightEntities;\n }\n return readOptions;\n}\n","import { WikiMemory } from './WikiMemory';\nimport type { SQLiteAdapter, WikiOptions } from './types';\n\nexport * from './types';\nexport { WikiMemory } from './WikiMemory';\nexport { formatContext } from './utils/formatContext';\nexport { formatMemoryDump } from './utils/formatMemoryDump';\nexport { parseEmbedding } from './utils/embedding';\nexport * from './librarianPrompt';\n\nexport function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory {\n return new WikiMemory(db, options);\n}\n"]}
|