@equationalapplications/core-llm-wiki 4.22.0 → 4.23.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 +10 -6
- package/dist/{chunk-LCAU6NYC.mjs → chunk-MYZJLVX4.mjs} +311 -45
- package/dist/chunk-MYZJLVX4.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +348 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +41 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-Bk8J6QLX.d.mts → testing-CBjAuTSl.d.mts} +72 -0
- package/dist/{testing-Bk8J6QLX.d.ts → testing-CBjAuTSl.d.ts} +72 -0
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +309 -43
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +6 -6
- package/dist/chunk-LCAU6NYC.mjs.map +0 -1
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/utils/pure.ts","../src/services/EmbeddingService.ts","../src/utils/ontology.ts","../src/repositories/MetadataRepository.ts","../src/services/ImportExportService.ts","../src/utils/ids.ts","../src/prompts.ts","../src/services/PromptService.ts","../src/services/IngestionService.ts","../src/utils/embedding.ts","../src/services/MaintenanceService.ts","../src/readOptions.ts","../src/services/RetrievalService.ts","../src/utils/cosine.ts","../src/services/SearchService.ts","../src/services/JobManager.ts","../src/services/WriteService.ts"],"names":["counts","MiniSearch","rows","documents"],"mappings":"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","file":"testing.js","sourcesContent":["import { extractSqliteCode } from './db/sqliteCodes';\n\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 /**\n * Runs `fn` inside a transaction. A bare adapter implementation is not required to\n * serialize concurrent calls itself — `WikiMemory` wraps every adapter it's given in\n * `withSerializedTransactions` (see `db/serializedAdapter.ts`), which is what makes\n * transactions serialize in practice. Once wrapped, inside the callback use ONLY the\n * provided `tx` handle — never the outer database handle (captured via closure or\n * `this.db`). Calling the outer handle deadlocks against the transaction mutex;\n * calling `tx.withTransactionAsync` throws (nested transactions are unsupported).\n */\n withTransactionAsync<T>(fn: (tx: SQLiteAdapter) => Promise<T>): Promise<T>;\n closeAsync(): Promise<void>;\n}\n\nexport interface PromptOverrides {\n ingestSystemPrompt?: string;\n librarianSystemPrompt?: string;\n healSystemPrompt?: string;\n ontologyBackfillSystemPrompt?: string;\n}\n\nexport type OntologyMode = 'strict' | 'emergent' | 'off';\n\nexport interface OntologyNodeType {\n type: string;\n description: string;\n}\n\nexport interface OntologyEdgeType {\n type: string;\n source_type: string;\n target_type: string;\n description: string;\n}\n\n/**\n * Allowed node and edge types for an entity's ontology graph.\n * Persisted per entity and injected into librarian/ingest prompts when mode ≠ `off`.\n */\nexport interface OntologyManifest {\n node_types: OntologyNodeType[];\n edge_types: OntologyEdgeType[];\n}\n\n/**\n * Global ontology defaults and bootstrap manifests for known entities.\n * Per-entity mode and manifest overrides are stored in SQLite and managed via\n * `WikiMemory.getOntologyManifest` / `setOntologyManifest`.\n */\nexport interface OntologyConfig {\n /** Global default mode. Default: `'off'` (backward compatible — no typed extraction). */\n mode?: OntologyMode;\n /**\n * Bootstrap manifests for known entities at construction time.\n * Written to the database on first access if no row exists for that entity.\n */\n seedManifests?: Record<string, {\n manifest: OntologyManifest;\n mode?: OntologyMode;\n }>;\n}\n\nexport interface ExtractedFactEdge {\n edge_type: string;\n target_title: string;\n}\n\nexport interface OntologyUpdates {\n node_types?: OntologyNodeType[];\n edge_types?: OntologyEdgeType[];\n}\n\nexport interface OntologyPromptContext {\n ontologyManifest: string;\n ontologyModeInstructions: string;\n}\n\n/** Result of a single ontology backfill run. Omissions (facts the model declined\n * to classify) are derivable as scanned − typed − failedValidation. */\nexport interface OntologyBackfillResult {\n /** Untyped facts sent to the model this run. */\n scanned: number;\n /** Facts that received an okf_type. */\n typed: number;\n /** Model classifications rejected (unknown/duplicate id, non-manifest type). */\n failedValidation: number;\n /** Edges persisted. */\n edgesAdded: number;\n /** Untyped facts still eligible after this run — safe host convergence signal: loop while > 0.\n * Always 0 when ontology mode is 'off' (nothing is eligible for typing while\n * disabled), so 0 does not imply queue exhaustion in that mode. */\n remaining: number;\n /** Untyped facts inside the recheck cooldown. */\n deferred: number;\n}\n\nexport interface WikiConfig {\n /**\n * Prefix applied to every SQL table/index/trigger name. Must match\n * `^[A-Za-z][A-Za-z0-9_]{0,30}_$` (letter, then alphanumeric/underscore,\n * ending in `_`, max 32 chars total) — enforced in the `WikiMemory` constructor.\n * Default: `'llm_wiki_'`.\n */\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 /** Global prompt overrides for text generation calls (`ingestDocument`, `runLibrarian`, `runHeal`). Does not affect embedding generation. Runtime overrides on individual method calls take precedence. */\n prompts?: PromptOverrides;\n /**\n * When true, entry and task mutations append an event to the internal outbox table.\n * The table is always created; this flag only controls whether writes occur.\n * @default false\n */\n enableOutbox?: boolean;\n ontology?: OntologyConfig;\n /** Default node cap for traverseGraph(), unless overridden per-call. Default 20. */\n maxTraversalNodes?: number;\n /** Default minimum confidence tier for discovered traversal nodes. Default 'tentative'. */\n minTraversalConfidence?: 'certain' | 'inferred' | 'tentative';\n /** Default traversal direction. Default 'both'. */\n traversalDirection?: 'inbound' | 'outbound' | 'both';\n /** Default source_type dead-end list for discovered traversal nodes. Default []. */\n excludeSourceTypes?: Array<WikiFact['source_type']>;\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> | null;\n last_accessed_at: number | null;\n access_count: number;\n deleted_at: number | null;\n /**\n * Verbatim OKF `type:` frontmatter value when this fact originated from (or was\n * re-imported via) an OKF bundle. `null`/`undefined` for facts never touched by\n * OKF import. Distinct from `source_type`, which governs immutability rules.\n */\n okf_type?: string | 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 /** Verbatim OKF `type:` frontmatter value when this task originated from an OKF bundle. */\n okf_type?: string | 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 WikiEdge {\n id: string;\n entity_id: string;\n source_id: string;\n target_id: string;\n edge_type: string;\n created_at: number;\n}\n\nexport interface GraphTraversalOptions {\n sourceId: string;\n /** Hop count. Default 1. Clamped to [1, 3] regardless of input. */\n maxDepth?: number;\n /** Default 'both'. Falls back to WikiConfig.traversalDirection, then 'both'. */\n direction?: 'inbound' | 'outbound' | 'both';\n /**\n * Allowed edge types. `undefined` = no filter (all types).\n * `[]` (explicit empty array) = match nothing — distinct from `undefined`.\n */\n edgeTypes?: string[];\n /** Total node cap (anchor + neighbors). Default 20 via WikiConfig.maxTraversalNodes. */\n maxTraversalNodes?: number;\n /** Minimum confidence tier for *discovered* nodes. Does not gate the anchor. Default 'tentative'. */\n minTraversalConfidence?: 'certain' | 'inferred' | 'tentative';\n /** source_type values to dead-end on for *discovered* nodes. Does not gate the anchor. Default []. */\n excludeSourceTypes?: Array<WikiFact['source_type']>;\n}\n\nexport interface GraphNeighborhood {\n /** Anchor node first, then discovered neighbors ordered by depth ASC, then updated_at DESC. */\n nodes: WikiFact[];\n /** Only edges where both endpoints are present in `nodes`. */\n edges: WikiEdge[];\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 ExtractedFactWithOntology extends ExtractedFact {\n okf_type?: string;\n edges?: ExtractedFactEdge[];\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 edges?: WikiEdge[];\n /** Entity summary prose for OKF profile ≥ 1 round-trip. Omitted = no summary (Clanker default). */\n summary?: string;\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. `'ontologyBackfill'` was added afterward.\n * Exhaustive `switch` / narrowing on this type must be updated (or given a\n * `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 | 'ontologyBackfill';\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\n/**\n * Thrown by the serialized transaction wrapper when a SQLite driver error\n * escapes a transaction callback (nested BEGIN, SQLITE_BUSY, constraint\n * violation). Domain errors thrown from callback logic pass through unwrapped.\n * Stable `instanceof` target for observability, mirroring {@link WikiBusyError}.\n */\nexport class WikiTransactionError extends Error {\n /** Best-effort SQLite code lifted from the driver error, e.g. 'SQLITE_BUSY'. */\n readonly sqliteErrorCode?: string;\n\n constructor(message: string, options: { cause: unknown }) {\n super(message, options);\n this.name = 'WikiTransactionError';\n this.sqliteErrorCode = extractSqliteCode(options.cause);\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\nexport const HOOK_TIMEOUT_MARKER = Symbol('WikiMemoryHookTimeout');\n\n","import type { ExtractedFact, ExtractedTask } from '../types';\n\nexport function 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 const useBrace =\n firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket);\n\n if (useBrace) {\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 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\nexport function sanitizeRankerError(err: unknown, sanitizeRankerErrors: boolean | undefined): Error {\n if (sanitizeRankerErrors === false) {\n return err instanceof Error ? err : new Error(String(err));\n }\n const typeName = err instanceof Error ? (err.constructor?.name ?? 'Error') : typeof err;\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 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\nexport function 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\nexport function 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\nexport async 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\nexport function 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\nexport function 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\nexport function 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\nexport function 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 // Clamp priority to valid range 0-10 as documented in the prompt contract\n priority = Math.max(0, Math.min(10, Math.round(priority)));\n\n return {\n ...task,\n description,\n priority\n };\n}\n\nexport function 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\nexport function 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\nexport function 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\nexport function 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","import type { SQLiteAdapter, WikiOptions } from '../types';\nimport { HOOK_TIMEOUT_MARKER } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport { clip } from '../utils/pure';\n\nexport class EmbeddingService {\n constructor(\n private db: SQLiteAdapter,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private metadataRepo: MetadataRepository,\n ) {}\n\n async storeEmbeddingDimension(dim: number): Promise<void> {\n const existing = await this.metadataRepo.getMeta('embedding_dimension');\n if (existing) {\n const storedDim = parseInt(existing, 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.metadataRepo.setMeta('embedding_dimension_mismatch', String(dim), this.db);\n }\n // Do not clear embedding_dimension_mismatch here; only reconcileEmbeddingDimension()\n // may clear it after a full runReembed confirms all blobs match.\n } else {\n await this.metadataRepo.setMeta('embedding_dimension', String(dim), this.db);\n }\n }\n\n /** Promotes embedding_dimension_mismatch to canonical embedding_dimension when safe. */\n async reconcileEmbeddingDimension(): Promise<void> {\n const mismatchValue = await this.metadataRepo.getMeta('embedding_dimension_mismatch');\n if (!mismatchValue) return;\n\n const newDim = parseInt(mismatchValue, 10);\n const residualCount = await this.entryRepo.countStaleEmbeddings(newDim);\n if (residualCount === 0) {\n await this.metadataRepo.setMeta('embedding_dimension', mismatchValue, this.db);\n await this.metadataRepo.clearDimensionMismatch(this.db);\n }\n }\n\n async embedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }): 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 = clip(`${fact.title} ${fact.body} ${tagsStr}`.trim(), 16_000);\n try {\n const vector = await embedFn(text);\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])) {\n hasNonFinite = true;\n break;\n }\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.entryRepo.updateEmbeddingBlob(fact.id, blob);\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 async notifyEmbeddingPersisted(entityId: string, factId: string, vector: Float32Array | null): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n const vectorCopy = vector ? vector.slice() : null;\n await this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n });\n }\n\n 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 const timeoutError = new Error(`onEmbeddingPersisted timed out after ${timeoutMs}ms`);\n (timeoutError as any)[HOOK_TIMEOUT_MARKER] = true;\n reject(timeoutError);\n }, timeoutMs);\n });\n\n const hookPromise = Promise.resolve().then(() =>\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 hookPromise.catch(() => {});\n throw err;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n}\n","import type {\n OntologyManifest,\n OntologyUpdates,\n ExtractedFactEdge,\n} from '../types';\n\nexport function emptyManifest(): OntologyManifest {\n return { node_types: [], edge_types: [] };\n}\n\nexport function normalizeTitleKey(title: string): string {\n return title.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nexport function resolveNodeType(raw: string, manifest: OntologyManifest): string | null {\n const slug = raw.trim();\n if (!slug) return null;\n const hit = manifest.node_types.find(n => n.type.toLowerCase() === slug.toLowerCase());\n return hit?.type ?? null;\n}\n\nexport function resolveEdgeDefinitions(\n rawEdgeType: string,\n manifest: OntologyManifest,\n): OntologyManifest['edge_types'][number][] {\n const slug = rawEdgeType.trim();\n if (!slug) return [];\n return manifest.edge_types.filter(e => e.type.toLowerCase() === slug.toLowerCase());\n}\n\nfunction edgeTripleKey(type: string, sourceType: string, targetType: string): string {\n return `${type.trim().toLowerCase()}|${sourceType.trim().toLowerCase()}|${targetType.trim().toLowerCase()}`;\n}\n\nexport function validateManifest(manifest: OntologyManifest): void {\n const nodeSlugs = new Set<string>();\n for (const node of manifest.node_types ?? []) {\n const type = node.type?.trim();\n if (!type) throw new Error('Ontology node type slug must be non-empty');\n const key = type.toLowerCase();\n if (nodeSlugs.has(key)) throw new Error(`Duplicate node type: ${type}`);\n nodeSlugs.add(key);\n }\n const edgeKeys = new Set<string>();\n const edgeNames = new Map<string, string>();\n for (const edge of manifest.edge_types ?? []) {\n const edgeType = edge.type?.trim();\n const sourceType = edge.source_type?.trim();\n const targetType = edge.target_type?.trim();\n if (!edgeType) throw new Error('Ontology edge type slug must be non-empty');\n if (!sourceType || !targetType || !nodeSlugs.has(sourceType.toLowerCase()) || !nodeSlugs.has(targetType.toLowerCase())) {\n throw new Error(`Edge type ${edgeType} references unknown node type`);\n }\n const edgeKey = edgeTripleKey(edgeType, sourceType, targetType);\n if (edgeKeys.has(edgeKey)) {\n throw new Error(`Duplicate edge definition: ${edgeType} (${sourceType} → ${targetType})`);\n }\n edgeKeys.add(edgeKey);\n // Persisted edge_type values come from def.type verbatim, so every triple\n // sharing a name must agree on casing or storage ends up mixed.\n const canonical = edgeNames.get(edgeType.toLowerCase());\n if (canonical === undefined) {\n edgeNames.set(edgeType.toLowerCase(), edgeType);\n } else if (canonical !== edgeType) {\n throw new Error(`Inconsistent casing for edge type: ${edgeType} conflicts with ${canonical}`);\n }\n }\n}\n\nexport function mergeOntologyUpdates(\n current: OntologyManifest,\n updates: OntologyUpdates,\n): OntologyManifest {\n const node_types = [...current.node_types];\n const edge_types = [...current.edge_types];\n const nodeSlugs = new Set(node_types.map(n => n.type.trim().toLowerCase()));\n const edgeKeys = new Set(edge_types.map(e => edgeTripleKey(e.type, e.source_type, e.target_type)));\n const edgeNames = new Map(edge_types.map(e => [e.type.trim().toLowerCase(), e.type.trim()]));\n\n for (const node of updates.node_types ?? []) {\n const type = node?.type?.trim();\n if (!type) continue;\n const key = type.toLowerCase();\n if (nodeSlugs.has(key)) continue;\n node_types.push({ type, description: String(node.description ?? '') });\n nodeSlugs.add(key);\n }\n for (const edge of updates.edge_types ?? []) {\n const rawEdgeType = edge?.type?.trim();\n const sourceType = edge?.source_type?.trim();\n const targetType = edge?.target_type?.trim();\n if (!rawEdgeType || !sourceType || !targetType) continue;\n // First-seen casing wins for a given edge name, as with node types, so a\n // later triple spelled differently cannot make the manifest fail validation.\n const edgeType = edgeNames.get(rawEdgeType.toLowerCase()) ?? rawEdgeType;\n const edgeKey = edgeTripleKey(edgeType, sourceType, targetType);\n if (edgeKeys.has(edgeKey)) continue;\n if (!nodeSlugs.has(sourceType.toLowerCase()) || !nodeSlugs.has(targetType.toLowerCase())) continue;\n edgeNames.set(edgeType.toLowerCase(), edgeType);\n edge_types.push({\n type: edgeType,\n source_type: sourceType,\n target_type: targetType,\n description: String(edge.description ?? ''),\n });\n edgeKeys.add(edgeKey);\n }\n return { node_types, edge_types };\n}\n\nexport function validateInlineEdges(\n sourceType: string,\n _targetType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n): ExtractedFactEdge[] {\n if (!Array.isArray(edges)) return [];\n const valid: ExtractedFactEdge[] = [];\n for (const edge of edges) {\n if (typeof edge?.edge_type !== 'string' || typeof edge?.target_title !== 'string') continue;\n const defs = resolveEdgeDefinitions(edge.edge_type, manifest);\n const match = defs.find(d => d.source_type.toLowerCase() === sourceType.toLowerCase());\n if (!match) continue;\n valid.push({ edge_type: match.type, target_title: edge.target_title });\n }\n return valid;\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { SQLiteAdapter, OntologyManifest, OntologyMode, OntologyUpdates } from '../types';\nimport { emptyManifest, mergeOntologyUpdates, validateManifest } from '../utils/ontology';\n\n/** Meta-table key for an entity's OKF summary prose (profile v1 round-trip). */\nexport function entitySummaryMetaKey(entityId: string): string {\n return `entity_summary:${entityId}`;\n}\n\nexport class MetadataRepository extends BaseRepository {\n // CHECKPOINTS TABLE METHODS\n\n async getCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<{ memory?: number; heal?: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{\n memory_checkpoint: number | null;\n heal_checkpoint: number | null;\n }>(\n `SELECT memory_checkpoint, heal_checkpoint FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId],\n );\n if (!row) return {};\n return {\n memory: row.memory_checkpoint ?? undefined,\n heal: row.heal_checkpoint ?? undefined,\n };\n }\n\n async updateCheckpoint(\n entityId: string,\n updates: { memory?: number; heal?: number },\n tx: SQLiteAdapter,\n ): Promise<void> {\n const fields: string[] = [];\n const values: number[] = [];\n\n if (updates.memory !== undefined) {\n fields.push('memory_checkpoint = ?');\n values.push(updates.memory);\n }\n if (updates.heal !== undefined) {\n fields.push('heal_checkpoint = ?');\n values.push(updates.heal);\n }\n if (fields.length === 0) return;\n\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}checkpoints (entity_id, memory_checkpoint, heal_checkpoint)\n VALUES (?, ?, ?)\n ON CONFLICT(entity_id) DO UPDATE SET ${fields.join(', ')}`,\n [entityId, updates.memory ?? 0, updates.heal ?? 0, ...values],\n );\n }\n\n async deleteCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId],\n );\n }\n\n // META TABLE METHODS\n\n async getMeta(key: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = ?`,\n [key],\n );\n return row ? row.value : null;\n }\n\n async setMeta(key: string, value: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}meta (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value`,\n [key, value],\n );\n }\n\n async deleteMeta(key: string, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = ?`,\n [key],\n );\n }\n\n async clearDimensionMismatch(tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`,\n );\n }\n\n async tableExists(tableName: string, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ name: string }>(\n `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,\n [tableName],\n );\n return row != null;\n }\n\n async getTableDdl(tableName: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ sql: string | null }>(\n `SELECT sql FROM sqlite_master WHERE type='table' AND name=?`,\n [tableName],\n );\n return row?.sql ?? null;\n }\n\n async vacuum(): Promise<void> {\n await this.db.execAsync(`PRAGMA wal_checkpoint(TRUNCATE)`);\n await this.db.execAsync(`VACUUM`);\n }\n\n async getDistinctEntityIds(tx?: SQLiteAdapter): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.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 return rows.map(r => r.entity_id);\n }\n\n async getManifest(entityId: string, tx?: SQLiteAdapter): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n } | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{\n mode: string;\n manifest_json: string;\n }>(`SELECT mode, manifest_json FROM ${this.prefix}entity_manifests WHERE entity_id = ?`, [entityId]);\n if (!row) return null;\n if (row.mode !== 'off' && row.mode !== 'strict' && row.mode !== 'emergent') {\n throw new Error(`Invalid ontology mode for entity ${entityId}: ${JSON.stringify(row.mode)}`);\n }\n let manifest: OntologyManifest;\n try {\n manifest = JSON.parse(row.manifest_json) as OntologyManifest;\n } catch (error) {\n throw new Error(`Invalid manifest_json for entity ${entityId}: ${(error as Error).message}`);\n }\n validateManifest(manifest);\n return {\n mode: row.mode,\n manifest,\n };\n }\n\n async setManifest(\n entityId: string,\n data: { mode: OntologyMode; manifest: OntologyManifest },\n tx: SQLiteAdapter,\n ): Promise<void> {\n validateManifest(data.manifest);\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(entity_id) DO UPDATE SET mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`,\n [entityId, data.mode, JSON.stringify(data.manifest), Date.now()],\n );\n }\n\n async mergeManifestUpdates(\n entityId: string,\n updates: OntologyUpdates,\n tx: SQLiteAdapter,\n ): Promise<OntologyManifest> {\n const current = (await this.getManifest(entityId, tx)) ?? {\n mode: 'emergent' as OntologyMode,\n manifest: emptyManifest(),\n };\n const merged = mergeOntologyUpdates(current.manifest, updates);\n await this.setManifest(entityId, { mode: current.mode, manifest: merged }, tx);\n return merged;\n }\n}\n","import type { SQLiteAdapter, MemoryBundle, MemoryDump, WikiFact } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\nimport { entitySummaryMetaKey, type MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\nimport { clip } from '../utils/pure';\n\nconst MAX_EMBEDDING_BLOB_BYTES = 32 * 1024; // 8192-dim float32 ceiling\nconst IMPORT_TITLE_MAX = 500;\nconst IMPORT_BODY_MAX = 8000;\n\nexport class ImportExportService {\n constructor(\n private db: SQLiteAdapter,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private edgeRepo: EdgeRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\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 ids = await this.metadataRepo.getDistinctEntityIds();\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(\n async (id): Promise<[string, MemoryBundle]> => [\n id,\n await this.getFullBundle(id, { includeBlobs: true }),\n ],\n ),\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(\n dump: MemoryDump,\n opts?: { merge?: boolean },\n ): Promise<void> {\n const merge = opts?.merge ?? false;\n const entityIds = Object.keys(dump.entities);\n\n this.jobManager.acquireImportLocks(entityIds);\n try {\n await this.assertNoLegacySourceTypes();\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n await this.doImportEntity(entityId, bundle, merge);\n }\n } finally {\n this.jobManager.releaseImportLocks(entityIds);\n }\n }\n\n async getFullBundle(\n entityId: string,\n opts?: { maxEvents?: number; includeBlobs?: boolean },\n ): Promise<MemoryBundle> {\n const [factsRaw, tasks, events, edges, summaryValue] = await Promise.all([\n opts?.includeBlobs\n ? this.entryRepo.findAllByEntityIdWithBlobs(entityId)\n : this.entryRepo.findAllByEntityId(entityId),\n this.taskRepo.findAllByEntityId(entityId),\n this.eventRepo.getByEntityId(entityId, opts?.maxEvents),\n this.edgeRepo.getByEntityId(entityId),\n this.metadataRepo.getMeta(entitySummaryMetaKey(entityId)),\n ]);\n\n const facts = factsRaw.map((f) => {\n const {\n embedding: _embedding,\n embedding_blob,\n ...rest\n } = f as WikiFact & { embedding?: unknown; embedding_blob?: Uint8Array };\n const safeBlobCopy =\n opts?.includeBlobs && embedding_blob\n ? (() => {\n const c = new ArrayBuffer(embedding_blob.byteLength);\n new Uint8Array(c).set(embedding_blob);\n return new Uint8Array(c);\n })()\n : undefined;\n\n const factBase = safeBlobCopy\n ? { ...rest, embedding_blob: safeBlobCopy }\n : rest;\n return {\n ...factBase,\n tags:\n typeof factBase.tags === 'string'\n ? JSON.parse(factBase.tags)\n : factBase.tags,\n };\n });\n\n return {\n facts,\n tasks,\n events,\n edges,\n ...(summaryValue != null ? { summary: summaryValue } : {}),\n };\n }\n\n /** Single-entity import transaction + post-processing; package-internal hook for tests. */\n async doImportEntity(\n entityId: string,\n bundle: MemoryBundle,\n merge: boolean,\n ): Promise<void> {\n const upsertedFactIds = new Set<string>();\n const upsertedDeletedFactIds = new Set<string>();\n const factsWithPreservedBlob = new Map<string, Uint8Array>();\n const preservedBlobDims = new Set<number>();\n const softDeletedFactIds: string[] = [];\n const clippedTextByFactId = new Map<string, { title: string; body: string }>();\n\n await this.db.withTransactionAsync(async (tx) => {\n if (!merge) {\n const deletedLiveFactIds = await this.entryRepo.findIdsBySource(\n entityId,\n null,\n null,\n tx,\n false,\n );\n softDeletedFactIds.push(...deletedLiveFactIds);\n await this.entryRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.taskRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.edgeRepo.bulkDeleteByEntityId(entityId, tx);\n await this.metadataRepo.deleteCheckpoint(entityId, tx);\n }\n\n if (bundle.summary !== undefined) {\n await this.metadataRepo.setMeta(entitySummaryMetaKey(entityId), bundle.summary, tx);\n } else if (!merge) {\n await this.metadataRepo.deleteMeta(entitySummaryMetaKey(entityId), tx);\n }\n\n const factIds = bundle.facts.map((fact) => fact.id);\n const existingFactsById = new Map<\n string,\n { id: string; entity_id: string; updated_at: number }\n >();\n const existingFacts = await this.entryRepo.findExistingMetadataByIds(\n factIds,\n tx,\n );\n for (const existingFact of existingFacts) {\n existingFactsById.set(existingFact.id, existingFact);\n }\n\n for (const fact of bundle.facts) {\n const sourceType = this._normalizeImportedSourceType(\n String(fact.source_type),\n {\n entityId,\n factId: fact.id,\n },\n );\n\n const safeUpdatedAt = Number.isFinite(fact.updated_at)\n ? fact.updated_at\n : 0;\n const existing = existingFactsById.get(fact.id);\n\n const rawBlobRaw = (fact as WikiFact & { embedding_blob?: unknown })\n .embedding_blob;\n let rawBlob: Uint8Array | null = null;\n\n if (rawBlobRaw instanceof Uint8Array) {\n if (rawBlobRaw.byteLength <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = rawBlobRaw;\n }\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 const data = obj['data'] as number[];\n if (data.length <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = new Uint8Array(data);\n }\n } else if (!Array.isArray(rawBlobRaw)) {\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every((k) => /^\\d+$/.test(k))) {\n const len = entries.length;\n if (len <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n rawBlob[i] = (obj[String(i)] as number) ?? 0;\n }\n }\n }\n }\n }\n\n if (rawBlob !== null && rawBlob.byteLength > MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = null; // Oversized blob — drop and let the fact re-embed normally.\n }\n\n let blobData: Uint8Array | null = null;\n if (\n rawBlob !== null &&\n rawBlob.byteLength > 0 &&\n rawBlob.byteLength % 4 === 0\n ) {\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\n let allFinite = true;\n for (let i = 0; i < floats.length; i++) {\n if (!isFinite(floats[i])) {\n allFinite = false;\n break;\n }\n }\n if (allFinite) {\n blobData = alignedBlob;\n }\n }\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision(\n 'entry',\n fact.id,\n existing.entity_id,\n entityId,\n );\n continue;\n }\n if (merge && safeUpdatedAt <= existing.updated_at) continue;\n }\n\n const safeTitle = clip(String(fact.title ?? ''), IMPORT_TITLE_MAX);\n const safeBody = clip(String(fact.body ?? ''), IMPORT_BODY_MAX);\n clippedTextByFactId.set(fact.id, { title: safeTitle, body: safeBody });\n\n const factObj: WikiFact = {\n id: fact.id,\n entity_id: entityId,\n title: safeTitle,\n body: safeBody,\n tags: Array.isArray(fact.tags) ? fact.tags : [],\n confidence: fact.confidence,\n source_type: sourceType,\n source_hash: fact.source_hash,\n source_ref: fact.source_ref,\n created_at: fact.created_at,\n updated_at: safeUpdatedAt,\n last_accessed_at: fact.last_accessed_at,\n access_count: fact.access_count,\n deleted_at: fact.deleted_at,\n embedding_blob: blobData ?? undefined,\n okf_type: fact.okf_type ?? null,\n };\n\n await this.entryRepo.upsertForImport(factObj, tx);\n\n if (blobData != null) {\n factsWithPreservedBlob.set(fact.id, blobData);\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n }\n\n existingFactsById.set(fact.id, {\n id: fact.id,\n entity_id: entityId,\n updated_at: safeUpdatedAt,\n });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n }\n\n const taskIds = bundle.tasks.map((task) => task.id);\n const existingTasksById = new Map<\n string,\n { id: string; entity_id: string; updated_at: number }\n >();\n const existingTasks = await this.taskRepo.findExistingMetadataByIds(\n taskIds,\n tx,\n );\n\n for (const existingTask of existingTasks) {\n existingTasksById.set(existingTask.id, existingTask);\n }\n\n for (const task of bundle.tasks) {\n const safeUpdatedAt = Number.isFinite(task.updated_at)\n ? task.updated_at\n : 0;\n const existing = existingTasksById.get(task.id);\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision(\n 'task',\n task.id,\n existing.entity_id,\n entityId,\n );\n continue;\n }\n if (merge && safeUpdatedAt <= existing.updated_at) continue;\n }\n\n await this.taskRepo.upsertForImport(\n {\n id: task.id,\n entity_id: entityId,\n description: task.description,\n status: task.status,\n priority: task.priority,\n created_at: task.created_at,\n updated_at: safeUpdatedAt,\n resolved_at: task.resolved_at,\n deleted_at: task.deleted_at,\n okf_type: task.okf_type ?? null,\n },\n tx,\n safeUpdatedAt,\n );\n\n existingTasksById.set(task.id, {\n id: task.id,\n entity_id: entityId,\n updated_at: safeUpdatedAt,\n });\n }\n\n for (const event of bundle.events) {\n await this.eventRepo.addIgnoreDuplicate(\n {\n id: event.id,\n entity_id: entityId,\n event_type: event.event_type,\n summary: event.summary,\n related_entry_id: event.related_entry_id ?? null,\n created_at: event.created_at,\n },\n tx,\n );\n }\n\n for (const edge of bundle.edges ?? []) {\n await this.edgeRepo.addIgnoreDuplicate(\n {\n id: edge.id,\n entity_id: entityId,\n source_id: edge.source_id,\n target_id: edge.target_id,\n edge_type: edge.edge_type,\n created_at: edge.created_at,\n },\n tx,\n );\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const fact of bundle.facts) {\n if (\n !fact.deleted_at &&\n upsertedFactIds.has(fact.id) &&\n !factsWithPreservedBlob.has(fact.id)\n ) {\n const clipped = clippedTextByFactId.get(fact.id);\n const embedded = await this.embeddingService.embedFact({\n id: fact.id,\n entity_id: entityId,\n title: clipped?.title ?? fact.title,\n body: clipped?.body ?? fact.body,\n tags:\n Array.isArray(fact.tags) || typeof fact.tags === 'string'\n ? fact.tags\n : [],\n });\n if (!embedded) {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, fact.id, null);\n }\n }\n }\n\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(\n blobData.buffer,\n blobData.byteOffset,\n blobData.byteLength / 4,\n );\n await this.embeddingService.notifyEmbeddingPersisted(\n entityId,\n fact.id,\n float32Vector,\n );\n } catch (hookErr) {\n console.warn(\n `[WikiMemory] onEmbeddingPersisted hook failed for preserved-blob fact ${fact.id}:`,\n hookErr,\n );\n }\n }\n }\n\n for (const factId of softDeletedFactIds) {\n if (!upsertedFactIds.has(factId) || upsertedDeletedFactIds.has(factId)) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(\n entityId,\n factId,\n null,\n );\n } catch (hookErr) {\n console.warn(\n `[WikiMemory] onEmbeddingPersisted(vector=null) hook failed for soft-deleted fact ${factId}:`,\n hookErr,\n );\n }\n }\n }\n\n try {\n const canonicalDimValue = await this.metadataRepo.getMeta(\n 'embedding_dimension',\n );\n const canonicalDim = canonicalDimValue\n ? parseInt(canonicalDimValue, 10)\n : null;\n\n if (preservedBlobDims.size === 1) {\n const preservedDim = [...preservedBlobDims][0];\n if (canonicalDim === null || canonicalDim === preservedDim) {\n await this.embeddingService.storeEmbeddingDimension(preservedDim);\n const staleMismatchValue = await this.metadataRepo.getMeta(\n 'embedding_dimension_mismatch',\n );\n if (\n staleMismatchValue &&\n parseInt(staleMismatchValue, 10) !== preservedDim\n ) {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(preservedDim),\n this.db,\n );\n }\n await this.embeddingService.reconcileEmbeddingDimension();\n } else {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(canonicalDim),\n this.db,\n );\n }\n } else if (preservedBlobDims.size > 1) {\n if (canonicalDim === null) {\n const sortedPreservedBlobDims = [...preservedBlobDims].sort(\n (a, b) => a - b,\n );\n await this.embeddingService.storeEmbeddingDimension(\n sortedPreservedBlobDims[0],\n );\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(sortedPreservedBlobDims[0]),\n this.db,\n );\n } else {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(canonicalDim),\n this.db,\n );\n }\n }\n } finally {\n this.searchService.evictCache(entityId);\n }\n }\n\n private _warnCrossEntityCollision(\n type: 'entry' | 'task',\n id: string,\n existingEntityId: string,\n targetEntityId: string,\n ): void {\n console.warn(\n `[WikiMemory] importDump: ${type} id ${JSON.stringify(id)} already belongs to entity ` +\n `${JSON.stringify(existingEntityId)}; skipping for entity ${JSON.stringify(targetEntityId)}`,\n );\n }\n\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\n const allowed: WikiFact['source_type'][] = [\n 'user_stated',\n 'librarian_inferred',\n 'user_confirmed',\n 'immutable_document',\n ];\n if ((allowed as string[]).includes(raw))\n return raw as WikiFact['source_type'];\n\n const where =\n ctx !== undefined\n ? ` for entity \"${ctx.entityId}\" fact \"${ctx.factId}\"`\n : '';\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 public async assertNoLegacySourceTypes(): Promise<void> {\n if (!(await this.entryRepo.hasLegacySourceTypes())) return;\n\n const count = await this.entryRepo.countLegacySourceTypes();\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${this.entryRepo.getLegacyMigrationSQL()}\\n\\n` +\n `After running the migration SQL, restart your application.`,\n );\n }\n}\n","type GetRandomValues = (bytes: Uint8Array) => void;\n\nlet _injectedGetRandomValues: GetRandomValues | null = null;\n\n/**\n * Inject a platform-specific `getRandomValues` implementation.\n * Call this once at module load time from the platform adapter\n * (e.g. expo-crypto's getRandomValues) when the global `crypto` API is\n * absent — Hermes / React Native being the primary case.\n * Pass `null` to clear a previously injected source.\n */\nexport function configureRandomSource(fn: GetRandomValues | null): void {\n _injectedGetRandomValues = fn;\n}\n\n/**\n * Generate a random ID with an optional prefix.\n * Resolution order:\n * 1. crypto.randomUUID (Web / Node 19+)\n * 2. crypto.getRandomValues (Web / Node / polyfilled global)\n * 3. injected source via configureRandomSource (e.g. expo-crypto in RN)\n * Throws if none is available — record IDs must always be cryptographically random.\n */\nexport function generateId(prefix: string = ''): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return prefix + crypto.randomUUID().replace(/-/g, '').substring(0, 24);\n }\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return prefix + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('').substring(0, 24);\n }\n if (_injectedGetRandomValues) {\n const bytes = new Uint8Array(16);\n _injectedGetRandomValues(bytes);\n return prefix + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('').substring(0, 24);\n }\n throw new Error(\n 'generateId: no cryptographically secure random source available ' +\n '(crypto.randomUUID and crypto.getRandomValues are both missing, and no configureRandomSource() injection was provided).',\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\nexport const ONTOLOGY_BACKFILL_SYSTEM_PROMPT = `You are a knowledge classification agent. You will receive existing memory facts that currently have no ontology type. For each input fact { \"id\", \"title\", \"body\", \"tags\" }, assign the best matching okf_type from the ontology manifest and optionally propose edges to related facts by title.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"classifications\": [\n { \"id\": \"string (input fact id, copied verbatim)\", \"okf_type\": \"string (manifest node type slug)\", \"edges\": [{ \"edge_type\": \"string\", \"target_title\": \"string\" }] }\n ]\n}\nIf no manifest type fits a fact, omit that fact from \"classifications\" entirely — do not guess.\nDo not return markdown, just raw JSON.`;\n","import {\n INGEST_SYSTEM_PROMPT,\n LIBRARIAN_SYSTEM_PROMPT,\n HEAL_SYSTEM_PROMPT,\n ONTOLOGY_BACKFILL_SYSTEM_PROMPT,\n} from '../prompts';\nimport type { PromptOverrides, OntologyPromptContext } from '../types';\n\nexport class PromptService {\n constructor(private globalOverrides?: PromptOverrides) {}\n\n private hydrate(template: string, variables: Record<string, unknown>): string {\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_match, key) => {\n const value = variables[key];\n if (value === undefined) return _match;\n return typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n });\n }\n\n private hasOntologyPlaceholders(template: string): boolean {\n return /\\{\\{\\s*ontology(?:Manifest|ModeInstructions)\\s*\\}\\}/.test(template);\n }\n\n private buildSystemPrompt(\n template: string,\n variables: Record<string, unknown>,\n ontologyContext: OntologyPromptContext | null | undefined,\n ): string {\n const shouldHydrate = Object.keys(variables).some((key) =>\n new RegExp(`\\\\{\\\\{\\\\s*${key}\\\\s*\\\\}\\\\}`).test(template),\n ) || (ontologyContext != null && this.hasOntologyPlaceholders(template));\n\n const hydrated = shouldHydrate\n ? this.hydrate(template, { ...variables, ...(ontologyContext ?? {}) })\n : template;\n\n return this.hasOntologyPlaceholders(template)\n ? (ontologyContext != null\n ? hydrated\n : hydrated.replace(/\\{\\{\\s*ontology(?:Manifest|ModeInstructions)\\s*\\}\\}/g, ''))\n : this.appendOntology(hydrated, ontologyContext);\n }\n\n private appendOntology(systemPrompt: string, ctx: OntologyPromptContext | null | undefined): string {\n if (!ctx) return systemPrompt;\n return `${systemPrompt}\\n\\n${ctx.ontologyModeInstructions}`;\n }\n\n buildIngestPrompt(\n documentChunk: string,\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.ingestSystemPrompt ?? INGEST_SYSTEM_PROMPT;\n const hasDocumentChunk = /\\{\\{\\s*documentChunk\\s*\\}\\}/.test(template);\n if (hasDocumentChunk || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { documentChunk }, ontologyContext),\n userPrompt: hasDocumentChunk ? 'Please extract the facts.' : `Document Chunk:\\n${documentChunk}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Document Chunk:\\n${documentChunk}`,\n };\n }\n\n buildLibrarianPrompt(\n events: unknown[],\n currentFacts: unknown[],\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.librarianSystemPrompt ?? LIBRARIAN_SYSTEM_PROMPT;\n const hasEvents = /\\{\\{\\s*events\\s*\\}\\}/.test(template);\n const hasCurrentFacts = /\\{\\{\\s*currentFacts\\s*\\}\\}/.test(template);\n if (hasEvents || hasCurrentFacts || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { events, currentFacts }, ontologyContext),\n userPrompt: (hasEvents || hasCurrentFacts)\n ? 'Please synthesize the context.'\n : `Events:\\n${JSON.stringify(events, null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Events:\\n${JSON.stringify(events, null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`,\n };\n }\n\n buildHealPrompt(\n healCandidates: unknown[],\n documentAnchors: unknown[],\n allTasks: unknown[],\n recentEvents: unknown[],\n runtimeOverride?: string,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.healSystemPrompt ?? HEAL_SYSTEM_PROMPT;\n if (\n /\\{\\{\\s*healCandidates\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*documentAnchors\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*allTasks\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*recentEvents\\s*\\}\\}/.test(template)\n ) {\n return {\n systemPrompt: this.hydrate(template, { healCandidates, documentAnchors, allTasks, recentEvents }),\n userPrompt: 'Please heal the memory graph.',\n };\n }\n return {\n systemPrompt: template,\n userPrompt: `Heal Candidates:\\n${JSON.stringify(healCandidates, null, 2)}\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(documentAnchors, null, 2)}\\nAll Tasks:\\n${JSON.stringify(allTasks, null, 2)}\\nRecent Events:\\n${JSON.stringify(recentEvents, null, 2)}\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`,\n };\n }\n\n buildOntologyBackfillPrompt(\n facts: unknown[],\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.ontologyBackfillSystemPrompt ?? ONTOLOGY_BACKFILL_SYSTEM_PROMPT;\n const hasFacts = /\\{\\{\\s*facts\\s*\\}\\}/.test(template);\n if (hasFacts || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { facts }, ontologyContext),\n userPrompt: hasFacts ? 'Please classify the facts.' : `Facts:\\n${JSON.stringify(facts, null, 2)}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Facts:\\n${JSON.stringify(facts, null, 2)}`,\n };\n }\n}\n","import { chunkText, withConcurrency, validateFact, parseJsonResponse, normalizeSourceRef, normalizeSourceHash } from '../utils/pure';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { generateId } from '../utils/ids';\nimport type { WikiOptions, ExtractedFact, ExtractedFactWithOntology, WikiFact, OntologyUpdates } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\nimport type { OntologyService, TitleIndexEntry } from './OntologyService';\nimport { PromptService } from './PromptService';\n\nexport class IngestionService {\n private promptService: PromptService;\n\n constructor(\n private db: SQLiteAdapter,\n private prefix: string,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\n promptService?: PromptService,\n private ontologyService?: OntologyService,\n ) {\n // Fallback for direct instantiation outside WikiMemory facade (e.g. isolated tests).\n this.promptService = promptService ?? new PromptService(this.options.config?.prompts);\n }\n\n async ingestDocument(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n documentChunk: string;\n maxChunkLength?: number;\n chunkOverlap?: number;\n chunkConcurrency?: number;\n promptOverride?: string;\n }\n ): Promise<{ truncated: boolean; chunks: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n\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\n const rawConcurrency = params.chunkConcurrency ?? this.options.config?.chunkConcurrency ?? 1;\n const chunkConcurrency = Number.isFinite(rawConcurrency) && rawConcurrency >= 1 ? Math.floor(rawConcurrency) : 1;\n\n if (typeof params.documentChunk !== 'string') {\n throw new Error(`documentChunk must be a string, received ${typeof params.documentChunk}`);\n }\n\n this.jobManager.acquireLock('ingest', entityId, sourceRef);\n\n try {\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n if (chunks.length === 0) return { truncated: false, chunks: 0 };\n\n const chunkResults = await withConcurrency(\n chunks.map((chunk) => async () => {\n const ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n const { systemPrompt, userPrompt } = this.promptService.buildIngestPrompt(\n chunk,\n params.promptOverride,\n ontologyContext,\n );\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n const result = parseJsonResponse<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>(responseText);\n return {\n facts: (Array.isArray(result.facts) ? result.facts : [])\n .map(validateFact)\n .filter((f): f is ExtractedFact => f !== null),\n ontology_updates: result.ontology_updates,\n };\n }),\n chunkConcurrency\n );\n\n const seen = new Set<string>();\n const orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }> = [];\n for (const chunkResult of chunkResults) {\n const dedupedFacts: ExtractedFact[] = [];\n for (const fact of chunkResult.facts) {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (!seen.has(normalizedTitle)) {\n seen.add(normalizedTitle);\n dedupedFacts.push(fact);\n }\n }\n orderedChunkFacts.push({ facts: dedupedFacts, ontology_updates: chunkResult.ontology_updates });\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 (tx) => {\n deletedSourceFactIds.push(...(await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false)));\n await this.entryRepo.softDeleteBySource(entityId, tx, sourceRef, null);\n\n const titleIndex = new Map<string, TitleIndexEntry>();\n const pendingEdges: Array<{\n sourceId: string;\n sourceType: string | null;\n edges: ExtractedFactWithOntology['edges'];\n }> = [];\n\n const existingFacts = await this.entryRepo.findRecentByEntityId(entityId, 500, tx);\n for (const existing of existingFacts) {\n titleIndex.set(normalizeTitleKey(existing.title), {\n id: existing.id,\n okf_type: existing.okf_type ?? null,\n });\n }\n\n let ontologyState = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n let { mode, manifest } = ontologyState;\n\n for (const { facts, ontology_updates } of orderedChunkFacts) {\n if (mode === 'emergent' && ontology_updates && this.ontologyService) {\n manifest = await this.ontologyService.mergeEmergentUpdates(entityId, ontology_updates, tx);\n ontologyState = await this.ontologyService.getEffectiveState(entityId, tx);\n mode = ontologyState.mode;\n }\n\n for (const fact of facts) {\n const ontologyFact = fact as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest)\n ?? { okf_type: null, edges: [] };\n\n const id = generateId('fact_');\n const wikiFact: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'immutable_document', source_hash: sourceHash, source_ref: sourceRef,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n okf_type: normalized.okf_type,\n };\n await this.entryRepo.upsert(wikiFact, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n\n titleIndex.set(normalizeTitleKey(fact.title), { id, okf_type: normalized.okf_type });\n\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n }\n\n for (const item of pendingEdges) {\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now,\n );\n }\n });\n\n await this.searchService.sync(entityId);\n\n const uniqueDeletedSourceFactIds = Array.from(new Set(deletedSourceFactIds));\n for (const factId of uniqueDeletedSourceFactIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during ingest for ${factId}:`, hookErr);\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n return { truncated, chunks: chunks.length };\n\n } finally {\n this.jobManager.releaseLock('ingest', entityId, sourceRef);\n }\n }\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","import { parseJsonResponse, validateFact, validateTask, titleTokens, jaccardScore, normalizeSourceRef, normalizeSourceHash, sanitizeRankerError } from '../utils/pure';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { PromptService } from './PromptService';\nimport type { OntologyService, TitleIndexEntry } from './OntologyService';\nimport { generateId } from '../utils/ids';\nimport { parseEmbedding } from '../utils/embedding';\nimport { PrunePartialFailureError } from '../types';\nimport { HOOK_TIMEOUT_MARKER } from '../types';\nimport type { WikiOptions, ExtractedFact, ExtractedFactEdge, ExtractedTask, ExtractedFactWithOntology, WikiFact, WikiTask, OntologyUpdates, OntologyBackfillResult } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport { entitySummaryMetaKey, type MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\n\nconst FUZZY_THRESHOLD = 0.5;\nconst MIN_TOKENS_TO_QUALIFY = 3;\n\nexport const ONTOLOGY_BACKFILL_BATCH_SIZE = 25;\nexport const ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS = 40_000;\nexport const ONTOLOGY_BACKFILL_RECHECK_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport class MaintenanceService {\n private promptService: PromptService;\n\n constructor(\n private db: SQLiteAdapter,\n private prefix: string,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\n promptService?: PromptService,\n private ontologyService?: OntologyService,\n ) {\n // Fallback for direct instantiation outside WikiMemory facade (e.g. isolated tests).\n this.promptService = promptService ?? new PromptService(this.options.config?.prompts);\n }\n\n async runPrune(entityId: string, options?: { retainSoftDeletedFor?: number | null; retainEventsFor?: number | null; vacuum?: boolean }): Promise<{ entries: number; tasks: number; events: number }> {\n this.jobManager.acquireLock('prune', entityId);\n\n try {\n const retainSoftDeletedFor = options?.retainSoftDeletedFor !== undefined ? options.retainSoftDeletedFor : (this.options.config?.pruneRetainSoftDeletedFor ?? 7);\n const retainEventsFor = options?.retainEventsFor !== undefined ? options.retainEventsFor : (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 const entriesToDelete = await this.entryRepo.getPrunableMetadata(entityId, cutoff);\n\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.embeddingService.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 const succeededIds = succeeded.map(r => r.id);\n\n await this.db.withTransactionAsync(async (tx) => {\n if (succeededIds.length > 0) {\n deletedEntries = await this.entryRepo.bulkDeletePruned(entityId, cutoff, succeededIds, tx);\n }\n deletedTasks = await this.taskRepo.bulkDeletePruned(entityId, cutoff, tx);\n });\n\n if (failure) {\n await this.searchService.sync(entityId);\n const remaining = entriesToDelete.length - succeeded.length - 1;\n const isTimeout = (failure.cause as any)?.[HOOK_TIMEOUT_MARKER] === true;\n\n if (isTimeout) {\n throw new PrunePartialFailureError(\n succeeded.length, failure.factId, remaining, new Error('Deletion hook timed out'), deletedTasks, 0\n );\n }\n\n const errMsg = (failure.cause as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n const sanitizedCause = isValidationError ? failure.cause as Error : this._sanitizeRankerError(failure.cause);\n\n throw new PrunePartialFailureError(\n succeeded.length, failure.factId, remaining, sanitizedCause, deletedTasks, 0\n );\n }\n }\n\n if (retainEventsFor !== null) {\n const cutoff = now - retainEventsFor * 86400000;\n const eventResult = await this.eventRepo.prune(entityId, cutoff);\n deletedEvents = eventResult.changes;\n }\n\n if (vacuum) {\n await this.metadataRepo.vacuum();\n }\n\n await this.searchService.sync(entityId);\n return { entries: deletedEntries, tasks: deletedTasks, events: deletedEvents };\n } finally {\n this.jobManager.releaseLock('prune', entityId);\n }\n }\n\n async runLibrarian(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n this.jobManager.acquireLock('librarian', entityId);\n try {\n await this.doRunLibrarian(entityId, options?.promptOverride);\n } finally {\n this.jobManager.releaseLock('librarian', entityId);\n }\n }\n\n async runHeal(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n this.jobManager.acquireLock('heal', entityId);\n try {\n await this.doRunHeal(entityId, options?.promptOverride);\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n\n async runOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<OntologyBackfillResult> {\n this.jobManager.acquireLock('ontologyBackfill', entityId);\n try {\n return await this.doRunOntologyBackfill(entityId, options);\n } finally {\n this.jobManager.releaseLock('ontologyBackfill', 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 op = entityId ? 'reembed' : 'global_reembed';\n this.jobManager.acquireLock(op, entityId ?? '*');\n\n try {\n\n const rows = await this.entryRepo.findAllForReembed(entityId);\n this.searchService.evictCache(entityId);\n\n const skipExisting = opts?.skipExisting ?? false;\n let effectiveSkip = skipExisting;\n\n if (skipExisting) {\n const mismatchValue = await this.metadataRepo.getMeta('embedding_dimension_mismatch');\n if (mismatchValue) {\n if (entityId) {\n const mismatchDim = parseInt(mismatchValue, 10);\n const staleCount = await this.entryRepo.countStaleForEntity(entityId, mismatchDim);\n if (staleCount > 0) effectiveSkip = false;\n } else {\n effectiveSkip = false;\n }\n }\n }\n\n let embedded = 0;\n let skipped = 0;\n let failed = 0;\n\n try {\n for (const row of rows) {\n const existingBlob = (row as WikiFact & { embedding_blob?: Uint8Array | null }).embedding_blob;\n const blobIsValid = !!existingBlob && existingBlob.byteLength > 0 && existingBlob.byteLength % 4 === 0;\n\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\n const success = await this.embeddingService.embedFact(row);\n if (success) embedded++;\n else failed++;\n }\n\n if (embedded > 0) {\n await this.embeddingService.reconcileEmbeddingDimension();\n }\n } finally {\n this.searchService.evictCache(entityId);\n }\n\n return { embedded, skipped, failed };\n } finally {\n this.jobManager.releaseLock(op, 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 if (params.clearAll && (params.entryId !== undefined || params.taskId !== undefined || params.sourceRef !== undefined || params.sourceHash !== undefined)) {\n throw new Error('forget() clearAll is mutually exclusive with entryId, taskId, sourceRef, and sourceHash');\n }\n\n this.jobManager.acquireLock('forget', entityId);\n\n try {\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n const deletedEntryIds: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n if (params.clearAll) {\n deletedEntryIds.push(...await this.entryRepo.findIdsBySource(entityId, null, null, tx, true));\n deletedEntries = await this.entryRepo.bulkSoftDeleteByEntityId(entityId, tx);\n deletedTasks = await this.taskRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.metadataRepo.updateCheckpoint(entityId, { memory: 0, heal: 0 }, tx);\n await this.metadataRepo.deleteMeta(entitySummaryMetaKey(entityId), tx);\n } else {\n const hasIdSelectors = params.entryId !== undefined || params.taskId !== undefined;\n const hasSourceSelectors = params.sourceRef !== undefined || params.sourceHash !== undefined;\n\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\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 const entryId = await this.entryRepo.findIdById(params.entryId, entityId, tx);\n if (entryId) deletedEntryIds.push(entryId);\n }\n\n if (sourceRef || sourceHash) {\n deletedEntryIds.push(...await this.entryRepo.findIdsBySource(entityId, sourceRef, sourceHash, tx, true));\n }\n\n const entryPromise = params.entryId ? this.entryRepo.softDelete(params.entryId, entityId, tx).then(r => r.changes > 0) : null;\n const taskDeletedPromise = params.taskId ? this.taskRepo.softDeleteById(params.taskId, entityId, tx).then(r => r.changes > 0) : null;\n const refPromise = (sourceRef || sourceHash) ? this.entryRepo.softDeleteBySource(entityId, tx, sourceRef, sourceHash) : null;\n\n const [entryResult, taskResult, refResult] = await Promise.all([\n entryPromise ?? Promise.resolve(false),\n taskDeletedPromise ?? Promise.resolve(false),\n refPromise ?? Promise.resolve(0),\n ]);\n\n if (entryResult) deletedEntries++;\n if (taskResult) deletedTasks++;\n deletedEntries += refResult;\n }\n });\n\n await this.searchService.sync(entityId);\n\n const uniqueDeletedIds = Array.from(new Set(deletedEntryIds));\n for (const factId of uniqueDeletedIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersistedOrThrow(entityId, factId, null);\n } catch (hookErr) {\n const isTimeout = (hookErr as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new Error(`forget(${entityId}/${factId}) failed: ${(hookErr as Error).message}`);\n }\n const errMsg = (hookErr as Error)?.message ?? '';\n if (errMsg.startsWith('Invalid deletionHookTimeoutMs')) {\n throw new Error(`forget(${entityId}/${factId}) failed: ${errMsg}`, { cause: hookErr });\n }\n throw new Error(`forget(${entityId}/${factId}) failed: ANN cleanup hook rejected`, { cause: this._sanitizeRankerError(hookErr) });\n }\n }\n\n return { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.jobManager.releaseLock('forget', entityId);\n }\n }\n\n /** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */\n async doRunLibrarian(entityId: string, promptOverride?: string): Promise<void> {\n const events = await this.eventRepo.getRecent(entityId, 50);\n const currentFactsRows = await this.entryRepo.findRecentByEntityId(entityId, 100);\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 ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n\n const { systemPrompt, userPrompt } = this.promptService.buildLibrarianPrompt(\n events.reverse(),\n currentFacts,\n promptOverride,\n ontologyContext,\n );\n\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n\n const result = parseJsonResponse<{\n facts: ExtractedFact[];\n tasks: ExtractedTask[];\n ontology_updates?: OntologyUpdates;\n }>(responseText);\n const facts = Array.isArray(result.facts) ? result.facts : [];\n const tasks = Array.isArray(result.tasks) ? result.tasks : [];\n const ontologyUpdates = result.ontology_updates;\n\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 const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n let { mode, manifest } = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n\n if (mode === 'emergent' && ontologyUpdates && this.ontologyService) {\n manifest = await this.ontologyService.mergeEmergentUpdates(entityId, ontologyUpdates, tx);\n }\n\n const titleIndex = new Map<string, TitleIndexEntry>();\n for (const existing of currentFactsRows) {\n titleIndex.set(normalizeTitleKey(existing.title), {\n id: existing.id,\n okf_type: existing.okf_type ?? null,\n });\n }\n\n const factsForDedupe = await this.entryRepo.findRecentByEntityId(entityId, 100, tx);\n\n const pendingEdges: Array<{\n sourceId: string;\n sourceType: string | null;\n edges: ExtractedFactWithOntology['edges'];\n }> = [];\n\n for (const fact of validFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of factsForDedupe) {\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\n if (skip) continue;\n\n const ontologyFact = fact as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest)\n ?? { okf_type: null, edges: [] };\n\n const id = generateId('fact_');\n const factObj: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'librarian_inferred', source_hash: null, source_ref: null,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n okf_type: normalized.okf_type,\n };\n\n await this.entryRepo.upsert(factObj, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n factsForDedupe.push(factObj);\n\n titleIndex.set(normalizeTitleKey(fact.title), { id, okf_type: normalized.okf_type });\n\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n\n for (const item of pendingEdges) {\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now,\n );\n }\n\n for (const task of validTasks) {\n const id = generateId('task_');\n const taskObj: WikiTask = {\n id, entity_id: entityId, description: task.description, status: 'pending', priority: task.priority,\n created_at: now, updated_at: now, resolved_at: null, deleted_at: null\n };\n await this.taskRepo.upsert(taskObj, tx);\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /** Core heal pass (locks handled by {@link runHeal}). Package-internal orchestration hook. */\n async doRunHeal(entityId: string, promptOverride?: 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 const orphanedIds: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n if (orphanAfterDays !== null) {\n const orphanThreshold = now - (orphanAfterDays * MS_PER_DAY);\n orphanedIds.push(...await this.entryRepo.markOrphaned(entityId, orphanThreshold, tx));\n }\n if (staleInferredAfterDays !== null) {\n const staleThreshold = now - (staleInferredAfterDays * MS_PER_DAY);\n await this.entryRepo.downgradeStaleInferred(entityId, staleThreshold, tx);\n }\n });\n\n for (const factId of orphanedIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal orphan pass for ${factId}:`, hookErr);\n }\n }\n\n const allFactsRows = await this.entryRepo.findAllByEntityId(entityId);\n const allTasks = await this.taskRepo.findAllPending([entityId]);\n const recentEvents = await this.eventRepo.getRecent(entityId, 20);\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 healCandidatesForPrompt = 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 });\n\n const { systemPrompt, userPrompt } = this.promptService.buildHealPrompt(\n healCandidatesForPrompt,\n documentAnchors,\n allTasks,\n recentEvents,\n promptOverride,\n );\n\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\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\n const safeDowngraded = Array.from(new Set(downgraded.filter(id => mutableIds.has(id))));\n const safeDeleted = Array.from(new Set(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 const healFactsForDedupe = [...healCandidates];\n\n await this.db.withTransactionAsync(async (tx) => {\n await this.entryRepo.downgradeByIds(safeDowngraded, entityId, tx);\n await this.entryRepo.softDeleteByIds(safeDeleted, entityId, tx);\n\n for (const fact of validNewFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of healFactsForDedupe) {\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\n if (skip) continue;\n\n const id = generateId('fact_');\n const factObj: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'librarian_inferred', source_hash: null, source_ref: null,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n };\n\n await this.entryRepo.upsert(factObj, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n healFactsForDedupe.push(factObj);\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const factId of uniqueDeletedFactIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal for ${factId}:`, hookErr);\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /** Core ontology backfill pass (locks handled by {@link runOntologyBackfill}). Package-internal orchestration hook. */\n async doRunOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<OntologyBackfillResult> {\n const batchSize = options?.batchSize ?? ONTOLOGY_BACKFILL_BATCH_SIZE;\n if (!Number.isInteger(batchSize) || batchSize < 1) {\n throw new Error('Invalid batchSize: must be an integer >= 1');\n }\n\n const now = Date.now();\n const recheckCutoff = now - ONTOLOGY_BACKFILL_RECHECK_MS;\n const zeroed = { scanned: 0, typed: 0, failedValidation: 0, edgesAdded: 0 };\n\n const ontologyService = this.ontologyService;\n if (!ontologyService) {\n return { ...zeroed, remaining: 0, deferred: 0 };\n }\n\n const { mode } = await ontologyService.getEffectiveState(entityId);\n if (mode === 'off') {\n // remaining stays 0: with ontology off nothing is eligible for typing, and\n // a host convergence loop (while remaining > 0) must terminate.\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { ...zeroed, remaining: 0, deferred: counts.deferred };\n }\n\n const candidates = await this.entryRepo.findUntypedByEntityId(entityId, batchSize, recheckCutoff);\n if (candidates.length === 0) {\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { ...zeroed, remaining: counts.eligible, deferred: counts.deferred };\n }\n\n const ontologyContext = await ontologyService.buildPromptContext(entityId);\n\n // Payload guard: cap the full serialized prompt (system + user — manifest,\n // ids, tags, JSON syntax, overrides all counted) so dense facts cannot blow\n // a provider's context window. A single fact whose prompt alone exceeds the\n // cap is still sent by itself: deferring it would just re-defer forever and\n // starve it (spec Decision 2).\n const toPromptShape = (f: WikiFact) => ({ id: f.id, title: f.title, body: f.body, tags: f.tags });\n const buildPrompt = (facts: WikiFact[]) => this.promptService.buildOntologyBackfillPrompt(\n facts.map(toPromptShape),\n options?.promptOverride,\n ontologyContext,\n );\n\n const batch: WikiFact[] = [candidates[0]];\n let built = buildPrompt(batch);\n for (let i = 1; i < candidates.length; i++) {\n const next = buildPrompt([...batch, candidates[i]]);\n if (next.systemPrompt.length + next.userPrompt.length > ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS) break;\n batch.push(candidates[i]);\n built = next;\n }\n\n const { systemPrompt, userPrompt } = built;\n\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n\n const parsed = parseJsonResponse<{\n classifications?: Array<{ id?: unknown; okf_type?: unknown; edges?: unknown }>;\n ontology_updates?: OntologyUpdates;\n }>(responseText);\n const classifications = Array.isArray(parsed.classifications) ? parsed.classifications : [];\n\n let typed = 0;\n let failedValidation = 0;\n let edgesAdded = 0;\n\n let abortedOntologyOff = false;\n\n await this.db.withTransactionAsync(async (tx) => {\n let { mode: txMode, manifest } = await ontologyService.getEffectiveState(entityId, tx);\n\n // setOntologyManifest is not under this job lock, so ontology can be\n // disabled while generateText was in flight. Abort without typing facts\n // or stamping cooldowns.\n if (txMode === 'off') {\n abortedOntologyOff = true;\n return;\n }\n\n if (txMode === 'emergent' && parsed.ontology_updates) {\n manifest = await ontologyService.mergeEmergentUpdates(entityId, parsed.ontology_updates, tx);\n }\n\n // Full breadth, three columns only: an old fact's edge targets are its\n // contemporaries, which a recent-100 window would silently miss.\n const titleRows = await this.entryRepo.findTitleIndexByEntityId(entityId, tx);\n const titleIndex = new Map<string, TitleIndexEntry>();\n for (const row of titleRows) {\n titleIndex.set(normalizeTitleKey(row.title), { id: row.id, okf_type: row.okf_type });\n }\n\n const batchById = new Map(batch.map(f => [f.id, f]));\n const applied = new Set<string>();\n const pendingEdges: Array<{ sourceId: string; sourceType: string; edges: ExtractedFactEdge[] }> = [];\n\n for (const classification of classifications) {\n const fact = typeof classification.id === 'string' ? batchById.get(classification.id) : undefined;\n if (!fact || applied.has(fact.id)) {\n failedValidation++;\n continue;\n }\n applied.add(fact.id);\n\n const normalized = ontologyService.validateAndNormalizeFact(\n {\n title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n okf_type: classification.okf_type as string | undefined, edges: classification.edges as ExtractedFactEdge[] | undefined,\n } as ExtractedFactWithOntology,\n manifest,\n );\n if (!normalized.okf_type) {\n failedValidation++;\n continue;\n }\n\n const result = await this.entryRepo.updateOkfType(fact.id, entityId, normalized.okf_type, tx);\n // changes === 0 → typed concurrently between select and update; the\n // okf_type IS NULL guard left it untouched. Counted as an omission.\n if (result.changes === 0) continue;\n\n typed++;\n titleIndex.set(normalizeTitleKey(fact.title), { id: fact.id, okf_type: normalized.okf_type });\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: fact.id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n\n // Two-phase: edges resolve only after every batch fact has its new type,\n // so intra-batch targets pass the target-type check.\n for (const item of pendingEdges) {\n edgesAdded += await ontologyService.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges, manifest, titleIndex, tx, now,\n );\n }\n\n await this.entryRepo.markOntologyChecked(batch.map(f => f.id), entityId, now, tx);\n });\n\n if (abortedOntologyOff) {\n // Mirror the mode === 'off' early path: remaining stays 0 so a host\n // convergence loop (while remaining > 0) still terminates.\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { ...zeroed, remaining: 0, deferred: counts.deferred };\n }\n\n this.searchService.evictCache(entityId);\n\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { scanned: batch.length, typed, failedValidation, edgesAdded, remaining: counts.eligible, deferred: counts.deferred };\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 private _sanitizeRankerError(err: unknown): Error {\n return sanitizeRankerError(err, this.options.sanitizeRankerErrors);\n }\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 type { WikiOptions, MemoryBundle, WikiFact, ReadOptions } from '../types';\nimport { EntryRepository, EntryRowMetadata, EntryRowWithEmbeddings } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport { applyTierWeight, normalizeEntityIds, sanitizeTierWeights, shouldExposeReadMetadata } from '../readOptions';\nimport { sanitizeRankerError } from '../utils/pure';\n\ntype ReadCandidateRowMetadata = EntryRowMetadata;\ntype ReadCandidateRowWithEmbeddings = EntryRowWithEmbeddings;\n\nexport class RetrievalService {\n constructor(\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\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 = shouldExposeReadMetadata(entityId)\n ? sanitizeTierWeights(entityIds, options?.tierWeights)\n : undefined;\n const exposeMetadata = shouldExposeReadMetadata(entityId);\n\n if (entityIds.length === 0) {\n const empty: MemoryBundle = { facts: [], tasks: [], events: [], edges: [] };\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 storedDimValue = await this.metadataRepo.getMeta('embedding_dimension');\n if (storedDimValue) {\n const storedDim = parseInt(storedDimValue, 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 scored entity has a blob whose\n // dimension differs from the query vector. Uses scoredEntityIds so zero-weight\n // (skipped) entities with stale embeddings do not force keyword fallback.\n const mismatchedCount = await this.entryRepo.countDimensionMismatched(scoredEntityIds, queryVec.length);\n if (mismatchedCount > 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 preResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, Number.MAX_SAFE_INTEGER);\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 if (useRanker) {\n candidateRows = await this.entryRepo.findMetadataByIds(topKIds);\n } else {\n candidateRows = await this.entryRepo.findWithEmbeddingsByIds(topKIds);\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 candidateRows = await this.entryRepo.findMetadataByEntityIds(scoredEntityIds);\n } else {\n candidateRows = await this.entryRepo.findWithEmbeddingsByEntityIds(scoredEntityIds);\n }\n // Collect MiniSearch scores for hybrid blend if weight is set and <1\n if (weight !== undefined && weight < 1) {\n miniSearchScores = this.searchService.getMiniSearchScores(trimmedQuery, scoredEntityIds);\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 embeddingRows = await this.entryRepo.findEmbeddingsByIds(rowIds);\n const embeddingsMap = new Map(embeddingRows.map(row => [row.id, row]));\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.searchService.rankSemantic({\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 keywordOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const topResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, 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.searchService.rankSemantic({\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 fallbackOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const results = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, fallbackOversampledLimit);\n const candidates = results.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 await this.entryRepo.trackAccess(ids, now);\n }\n } else {\n // Empty query: use global recency ordering, ignore tier weights.\n facts = await this.entryRepo.findRecentByEntityIds(entityIds, maxResults);\n }\n\n const eventsLimit = Math.min(10 * entityIds.length, 100);\n const [tasks, events] = await Promise.all([\n this.taskRepo.findAllPending(entityIds as string[], entityIds.length === 1 ? undefined : Math.min(20 * entityIds.length, 200)),\n entityIds.length === 1\n ? this.eventRepo.getRecent(entityIds[0], eventsLimit)\n : this.eventRepo.getRecentForEntities(entityIds as string[], eventsLimit),\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(), edges: [] };\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 * 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[], tx?: SQLiteAdapter): Promise<WikiFact[]> {\n return this.entryRepo.findByIds(ids, scopedEntityIds, tx);\n }\n\n private _sanitizeRankerError(err: unknown): Error {\n return sanitizeRankerError(err, this.options.sanitizeRankerErrors);\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","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","import MiniSearch, { SearchResult } from 'minisearch';\nimport { EntryRepository } from '../repositories/EntryRepository';\nimport { cosineSimilarity } from '../utils/cosine';\nimport { parseEmbedding } from '../utils/embedding';\n\nexport interface ScoredRow {\n id: string;\n entity_id: string;\n score: number;\n updated_at: number | null;\n access_count: number | null;\n}\n\nexport interface RankSemanticArgs {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateRows: Array<{\n id: string;\n entity_id: string;\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n updated_at: number | null;\n access_count: number | null;\n }>;\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n populateCache: boolean;\n limit: number;\n skipSort?: boolean;\n}\n\nexport class SearchService {\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 /**\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\n private miniSearch: MiniSearch<{ id: string; entity_id: string; title: string; body: string; tags: string }>;\n private miniSearchEntryIdsByEntity = new Map<string, Set<string>>();\n private vectorCache: Map<string, Map<string, Float32Array>> = new Map();\n\n constructor(private entryRepo: EntryRepository) {\n this.miniSearch = new MiniSearch({\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 }\n\n /**\n * Rebuilds the search index and clears the vector cache for a given entity.\n * A direct replacement for manually syncing state after a DB transaction.\n */\n async sync(entityId?: string): Promise<void> {\n await this.rebuildIndex(entityId);\n this.evictCache(entityId);\n }\n\n /**\n * Clears the parsed vector cache. Useful for mid-loop flush guarantees\n * or memory pressure evictions.\n */\n evictCache(entityId?: string): void {\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n }\n\n /**\n * Fully resets the search service.\n */\n clearAll(): void {\n this.vectorCache.clear();\n this.miniSearch.removeAll();\n this.miniSearchEntryIdsByEntity.clear();\n }\n\n /**\n * Executes a keyword search against the active MiniSearch index.\n */\n searchKeyword(query: string, entityIds: string[], limit: number): SearchResult[] {\n const entityIdSet = new Set(entityIds);\n const results = this.miniSearch.search(query, {\n filter: (r) => entityIdSet.has(r.entity_id as string),\n combineWith: 'OR',\n });\n return results.slice(0, limit);\n }\n\n /**\n * Pre-fetches MiniSearch scores for candidate hydration, used during hybrid weighting.\n */\n getMiniSearchScores(query: string, entityIds: string[], preFilterLimit?: number): Map<string, number> {\n const entityIdSet = new Set(entityIds);\n let results = this.miniSearch.search(query, {\n filter: (r) => entityIdSet.has(r.entity_id as string),\n combineWith: 'OR',\n });\n\n if (preFilterLimit !== undefined) {\n results = results.slice(0, preFilterLimit);\n }\n\n if (results.length === 0) return new Map();\n\n const maxMsScore = Math.max(1, results[0]?.score ?? 1);\n return new Map(results.map((r) => [r.id, r.score / maxMsScore]));\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 async rankSemantic(args: RankSemanticArgs): Promise<ScoredRow[]> {\n const queryVec = args.queryVec instanceof Float32Array ? args.queryVec.slice() : Array.from(args.queryVec);\n const { entityId, candidateRows, weight, miniSearchScores, populateCache, limit, skipSort } = args;\n\n let entityCache = this.vectorCache.get(entityId);\n const tooLarge = populateCache && candidateRows.length > SearchService.MAX_VECTOR_CACHE_FACTS_PER_ENTITY;\n\n if (tooLarge && entityCache) {\n this.vectorCache.delete(entityId);\n entityCache = undefined;\n }\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\n if (vector && canCache && entityCache && !entityCache.has(row.id)) {\n entityCache.set(row.id, vector);\n }\n\n let score = 0;\n if (vector && vector.length === queryVec.length) {\n const cosSim = cosineSimilarity(queryVec, vector);\n if (weight !== undefined) {\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 const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = (1 - weight) * kwScore;\n } else {\n score = -2;\n }\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 if (this.vectorCache.size >= SearchService.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 if (!skipSort) {\n this._tieBreakSort(scored);\n }\n\n return scored.slice(0, limit);\n }\n\n // --- Internal Index Management ---\n\n private async rebuildIndex(entityId?: string): Promise<void> {\n if (entityId) {\n const rows = await this.entryRepo.findMiniSearchRows(entityId);\n const previousIds = this.miniSearchEntryIdsByEntity.get(entityId);\n\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(\n entityId,\n new Set(documents.map((document) => document.id))\n );\n return;\n }\n\n const rows = await this.entryRepo.findMiniSearchRows();\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 normalizeMiniSearchRow(row: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n 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 _tieBreakSort(items: ScoredRow[]): void {\n items.sort((a, b) => this._compareScoredRows(a, b));\n }\n\n private _compareScoredRows(a: ScoredRow, b: ScoredRow): number {\n const scoreDiff = b.score - a.score;\n if (!Number.isNaN(scoreDiff) && scoreDiff !== 0) return scoreDiff;\n\n const accessCountDiff = (b.access_count ?? 0) - (a.access_count ?? 0);\n if (accessCountDiff !== 0) return accessCountDiff;\n\n const updatedAtDiff = (b.updated_at ?? 0) - (a.updated_at ?? 0);\n if (updatedAtDiff !== 0) return updatedAtDiff;\n\n return a.id.localeCompare(b.id);\n }\n}\n","import { EntityStatus, WikiBusyError, WikiBusyOperation } from '../types';\n\nexport type OperationType =\n | 'prune'\n | 'librarian'\n | 'heal'\n | 'ingest'\n | 'reembed'\n | 'global_reembed'\n | 'import'\n | 'global_import'\n | 'forget'\n | 'ontologyBackfill';\n\nexport class JobManager {\n private activeMaintenanceJobs = new Set<string>();\n private activeIngestJobs = new Map<string, Set<string>>();\n private statusSubscribers = new Map<\n string,\n Set<{ callback: (s: EntityStatus) => void; last: EntityStatus }>\n >();\n\n constructor(private prefix: string) {}\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 _librarianKey(entityId: string) { return `${this.prefix}:${entityId}:librarian`; }\n private _healKey(entityId: string) { return `${this.prefix}:${entityId}:heal`; }\n private _ontologyBackfillKey(entityId: string) { return `${this.prefix}:${entityId}:ontologyBackfill`; }\n\n /**\n * Lookup table for acquireLock/releaseLock's dynamic-dispatch branch.\n * Excludes 'ingest' | 'global_reembed' | 'global_import', which those\n * methods already handle via explicit if/else branches before reaching\n * this table.\n */\n private readonly lockKeyFns: Record<\n Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>,\n (entityId: string) => string\n > = {\n prune: (id) => this._pruneKey(id),\n librarian: (id) => this._librarianKey(id),\n heal: (id) => this._healKey(id),\n reembed: (id) => this._reembedKey(id),\n import: (id) => this._importKey(id),\n forget: (id) => this._forgetKey(id),\n ontologyBackfill: (id) => this._ontologyBackfillKey(id),\n };\n\n private _isReembedActive(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalReembedKey());\n }\n\n private _isImportActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._importKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalImportKey());\n }\n\n private _isForgetActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._forgetKey(entityId));\n }\n\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\n private _hasIngestJob(entityId: string, sourceRef?: string): boolean {\n return this.activeIngestJobs.get(entityId)?.has(sourceRef ?? '') ?? false;\n }\n\n private _addIngestJob(entityId: string, sourceRef?: string): void {\n const sourceKey = sourceRef ?? '';\n let refs = this.activeIngestJobs.get(entityId);\n if (!refs) {\n refs = new Set<string>();\n this.activeIngestJobs.set(entityId, refs);\n }\n refs.add(sourceKey);\n }\n\n private _removeIngestJob(entityId: string, sourceRef?: string): void {\n const sourceKey = sourceRef ?? '';\n const refs = this.activeIngestJobs.get(entityId);\n if (!refs) return;\n refs.delete(sourceKey);\n if (refs.size === 0) {\n this.activeIngestJobs.delete(entityId);\n }\n }\n\n private _isIngestActiveFor(entityId: string): boolean {\n return this.activeIngestJobs.has(entityId);\n }\n\n acquireLock(operation: OperationType, entityId: string, sourceRef?: string): void {\n let blockingOperation: WikiBusyOperation | null = null;\n\n if (operation !== 'global_import' && this.activeMaintenanceJobs.has(this._globalImportKey())) {\n throw new WikiBusyError('import', '*');\n }\n\n switch (operation) {\n case 'prune':\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n\n case 'librarian':\n case 'heal':\n case 'ontologyBackfill': {\n const opKey = this.lockKeyFns[operation](entityId);\n if (this.activeMaintenanceJobs.has(opKey)) blockingOperation = operation;\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n\n case 'reembed':\n if (this.activeMaintenanceJobs.has(this._reembedKey(entityId))) blockingOperation = 'reembed';\n else if (this.activeMaintenanceJobs.has(this._globalReembedKey())) blockingOperation = 'reembed';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n\n case 'global_reembed':\n if (this.activeMaintenanceJobs.has(this._globalReembedKey())) blockingOperation = 'reembed';\n else if (this._isAnyMaintenanceActiveWithSuffix(':reembed')) blockingOperation = 'reembed';\n else if (this._isAnyMaintenanceActiveWithSuffix(':prune')) blockingOperation = 'prune';\n else if (this._isAnyMaintenanceActiveWithSuffix(':librarian')) blockingOperation = 'librarian';\n else if (this._isAnyMaintenanceActiveWithSuffix(':heal')) blockingOperation = 'heal';\n else if (this._isAnyMaintenanceActiveWithSuffix(':ontologyBackfill')) blockingOperation = 'ontologyBackfill';\n else if (this.activeIngestJobs.size > 0) blockingOperation = 'ingest';\n else if (this._isAnyMaintenanceActiveWithSuffix(':import')) blockingOperation = 'import';\n else if (this._isAnyMaintenanceActiveWithSuffix(':forget')) blockingOperation = 'forget';\n break;\n\n case 'import':\n case 'forget': {\n const selfKey = operation === 'import' ? this._importKey(entityId) : this._forgetKey(entityId);\n if (this.activeMaintenanceJobs.has(selfKey)) blockingOperation = operation;\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n\n case 'global_import':\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) blockingOperation = 'import';\n break;\n\n case 'ingest': {\n const sourceKey = sourceRef ?? '';\n if (this._hasIngestJob(entityId, sourceKey)) blockingOperation = 'ingest';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n }\n\n if (blockingOperation) {\n throw new WikiBusyError(\n blockingOperation,\n operation === 'global_reembed' || operation === 'global_import' ? '*' : entityId\n );\n }\n\n if (operation === 'ingest') {\n this._addIngestJob(entityId, sourceRef);\n } else if (operation === 'global_reembed') {\n this.activeMaintenanceJobs.add(this._globalReembedKey());\n } else if (operation === 'global_import') {\n this.activeMaintenanceJobs.add(this._globalImportKey());\n } else {\n this.activeMaintenanceJobs.add(this.lockKeyFns[operation as Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>](entityId));\n }\n\n this._notifyStatusSubscribers(entityId);\n }\n\n releaseLock(operation: OperationType, entityId: string, sourceRef?: string): void {\n if (operation === 'ingest') {\n this._removeIngestJob(entityId, sourceRef);\n } else if (operation === 'global_reembed') {\n this.activeMaintenanceJobs.delete(this._globalReembedKey());\n } else if (operation === 'global_import') {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n } else {\n this.activeMaintenanceJobs.delete(this.lockKeyFns[operation as Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>](entityId));\n }\n\n this._notifyStatusSubscribers(entityId);\n }\n\n /**\n * Returns true if acquireLock(operation, entityId) would throw WikiBusyError.\n * Use for non-throwing conflict checks (e.g. auto-trigger gating in write()).\n */\n isBlocked(operation: OperationType, entityId: string): boolean {\n if (operation !== 'global_import' && this.activeMaintenanceJobs.has(this._globalImportKey())) return true;\n\n switch (operation) {\n case 'librarian':\n case 'heal':\n case 'ontologyBackfill':\n return this.activeMaintenanceJobs.has(this.lockKeyFns[operation](entityId)) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n case 'prune':\n return this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._librarianKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._healKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n default:\n return false;\n }\n }\n\n /**\n * Auto-heal historically only gated on the heal self-key. Keep that behavior\n * for write() auto-trigger paths while preserving stricter checks in acquireLock().\n */\n tryAcquireAutoHealLock(entityId: string): boolean {\n const healKey = this._healKey(entityId);\n if (this.activeMaintenanceJobs.has(healKey)) return false;\n this.activeMaintenanceJobs.add(healKey);\n this._notifyStatusSubscribers(entityId);\n return true;\n }\n\n /**\n * Validates then acquires global + per-entity import locks atomically.\n * Validates all entities before acquiring any lock (same as current importDump semantics).\n */\n acquireImportLocks(entityIds: string[]): void {\n for (const entityId of entityIds) {\n if (this.activeMaintenanceJobs.has(this._importKey(entityId))) throw new WikiBusyError('import', entityId);\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) throw new WikiBusyError('librarian', entityId);\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) throw new WikiBusyError('heal', entityId);\n if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) throw new WikiBusyError('ontologyBackfill', entityId);\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) throw new WikiBusyError('prune', entityId);\n if (this._isReembedActive(entityId)) throw new WikiBusyError('reembed', entityId);\n if (this._isIngestActiveFor(entityId)) throw new WikiBusyError('ingest', entityId);\n if (this._isForgetActiveFor(entityId)) throw new WikiBusyError('forget', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) throw new WikiBusyError('import', '*');\n\n this.activeMaintenanceJobs.add(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.add(this._importKey(entityId));\n }\n }\n\n releaseImportLocks(entityIds: string[]): void {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.delete(this._importKey(entityId));\n }\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n return {\n ingesting: this._isIngestActiveFor(entityId),\n librarian: this.activeMaintenanceJobs.has(this._librarianKey(entityId)),\n heal: this.activeMaintenanceJobs.has(this._healKey(entityId)),\n };\n }\n\n subscribeEntityStatus(entityId: string, callback: (status: EntityStatus) => void): () => 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\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(`[JobManager] 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 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 if (entityId === '*') return;\n\n const set = this.statusSubscribers.get(entityId);\n if (!set || set.size === 0) return;\n\n for (const entry of Array.from(set)) {\n if (!set.has(entry)) continue;\n const next = this.getEntityStatus(entityId);\n\n if (entry.last.ingesting === next.ingesting &&\n entry.last.librarian === next.librarian &&\n entry.last.heal === next.heal) {\n continue;\n }\n\n entry.last = this._copyEntityStatus(next);\n try {\n entry.callback(this._copyEntityStatus(next));\n } catch (err) {\n console.error(`[JobManager] callback error for entityId=\"${entityId}\" during transition emission`, err);\n }\n }\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport type { WikiOptions, WikiEvent } from '../types';\nimport { WikiBusyError } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { JobManager } from './JobManager';\nimport type { MaintenanceService } from './MaintenanceService';\nimport { generateId } from '../utils/ids';\nimport { clip } from '../utils/pure';\n\nexport class WriteService {\n constructor(\n private db: SQLiteAdapter,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private jobManager: JobManager,\n private maintenanceService: MaintenanceService,\n ) {}\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n if (typeof entityId !== 'string' || entityId.length === 0 || entityId.length > 200 || entityId.includes('\\0')) {\n throw new TypeError(\n `Invalid entityId: must be a non-empty string at most 200 chars with no null bytes; got ${JSON.stringify(entityId)}.`,\n );\n }\n if (event === null || typeof event !== 'object' || Array.isArray(event)) {\n throw new TypeError('Invalid event: must be a non-null object.');\n }\n if (typeof event.summary !== 'string') {\n throw new TypeError('Invalid event.summary: must be a string.');\n }\n const summary = clip(event.summary, 4000);\n\n let relatedEntryId: string | null = null;\n const rawRelatedEntryId = event.related_entry_id;\n if (rawRelatedEntryId != null && rawRelatedEntryId !== '') {\n if (\n typeof rawRelatedEntryId !== 'string' ||\n rawRelatedEntryId.length > 200 ||\n rawRelatedEntryId.includes('\\0')\n ) {\n relatedEntryId = null;\n } else {\n const existing = await this.entryRepo.findByIds([rawRelatedEntryId], [entityId]);\n relatedEntryId = existing.length > 0 ? rawRelatedEntryId : null;\n }\n }\n\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 const newEvent: WikiEvent = {\n id,\n entity_id: entityId,\n event_type: eventType,\n summary,\n related_entry_id: relatedEntryId,\n created_at: now,\n };\n\n let shouldRunLibrarian = false;\n let librarianCount = 0;\n let prevMemoryCheckpoint = 0;\n\n await this.db.withTransactionAsync(async (tx) => {\n await this.eventRepo.add(newEvent, tx);\n\n const threshold = this.options.config?.autoLibrarianThreshold || 20;\n\n const [count, cp] = await Promise.all([\n this.eventRepo.count(entityId, tx),\n this.metadataRepo.getCheckpoint(entityId, tx),\n ]);\n\n let memoryCheckpoint = cp.memory ?? 0;\n if (memoryCheckpoint > count) memoryCheckpoint = 0;\n\n if (count - memoryCheckpoint >= threshold) {\n if (!this.jobManager.isBlocked('librarian', entityId)) {\n shouldRunLibrarian = true;\n librarianCount = count;\n prevMemoryCheckpoint = memoryCheckpoint;\n await this.metadataRepo.updateCheckpoint(entityId, { memory: count }, tx);\n }\n }\n });\n\n if (shouldRunLibrarian) {\n try {\n this.jobManager.acquireLock('librarian', entityId);\n this.runLibrarianThenMaybeHeal(entityId, librarianCount, prevMemoryCheckpoint)\n .catch(console.error)\n .finally(() => {\n this.jobManager.releaseLock('librarian', entityId);\n });\n } catch (e) {\n if (!(e instanceof WikiBusyError)) throw e;\n await this.metadataRepo.updateCheckpoint(entityId, { memory: prevMemoryCheckpoint }, this.db);\n }\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number, prevCheckpoint: number): Promise<void> {\n try {\n await this.maintenanceService.doRunLibrarian(entityId);\n // Only advance checkpoint after successful librarian run\n await this.metadataRepo.updateCheckpoint(entityId, { memory: currentEventCount }, this.db);\n } catch (e) {\n // Rollback checkpoint on failure so events can be retried\n await this.metadataRepo.updateCheckpoint(entityId, { memory: prevCheckpoint }, this.db);\n throw e;\n }\n\n const autoHealThreshold = this.options.config?.autoHealThreshold || 100;\n\n const cp = await this.metadataRepo.getCheckpoint(entityId, this.db);\n let healCheckpoint = cp.heal ?? 0;\n if (healCheckpoint > currentEventCount) healCheckpoint = 0;\n\n const shouldRunHeal = currentEventCount - healCheckpoint >= autoHealThreshold;\n\n if (shouldRunHeal && this.jobManager.tryAcquireAutoHealLock(entityId)) {\n try {\n await this.maintenanceService.doRunHeal(entityId);\n await this.metadataRepo.updateCheckpoint(entityId, { heal: currentEventCount }, this.db);\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/utils/pure.ts","../src/services/EmbeddingService.ts","../src/utils/ontology.ts","../src/repositories/MetadataRepository.ts","../src/services/ImportExportService.ts","../src/utils/ids.ts","../src/prompts.ts","../src/services/PromptService.ts","../src/services/IngestionService.ts","../src/utils/embedding.ts","../src/services/BoundedLlmCall.ts","../src/services/MaintenanceService.ts","../src/readOptions.ts","../src/services/RetrievalService.ts","../src/utils/cosine.ts","../src/services/SearchService.ts","../src/services/JobManager.ts","../src/services/WriteService.ts"],"names":["counts","MiniSearch","rows","documents"],"mappings":"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","file":"testing.js","sourcesContent":["import { extractSqliteCode } from './db/sqliteCodes';\n\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 /**\n * Runs `fn` inside a transaction. A bare adapter implementation is not required to\n * serialize concurrent calls itself — `WikiMemory` wraps every adapter it's given in\n * `withSerializedTransactions` (see `db/serializedAdapter.ts`), which is what makes\n * transactions serialize in practice. Once wrapped, inside the callback use ONLY the\n * provided `tx` handle — never the outer database handle (captured via closure or\n * `this.db`). Calling the outer handle deadlocks against the transaction mutex;\n * calling `tx.withTransactionAsync` throws (nested transactions are unsupported).\n */\n withTransactionAsync<T>(fn: (tx: SQLiteAdapter) => Promise<T>): Promise<T>;\n closeAsync(): Promise<void>;\n}\n\nexport interface PromptOverrides {\n ingestSystemPrompt?: string;\n librarianSystemPrompt?: string;\n healSystemPrompt?: string;\n ontologyBackfillSystemPrompt?: string;\n}\n\nexport type OntologyMode = 'strict' | 'emergent' | 'off';\n\nexport interface OntologyNodeType {\n type: string;\n description: string;\n}\n\nexport interface OntologyEdgeType {\n type: string;\n source_type: string;\n target_type: string;\n description: string;\n}\n\n/**\n * Allowed node and edge types for an entity's ontology graph.\n * Persisted per entity and injected into librarian/ingest prompts when mode ≠ `off`.\n */\nexport interface OntologyManifest {\n node_types: OntologyNodeType[];\n edge_types: OntologyEdgeType[];\n}\n\n/**\n * Global ontology defaults and bootstrap manifests for known entities.\n * Per-entity mode and manifest overrides are stored in SQLite and managed via\n * `WikiMemory.getOntologyManifest` / `setOntologyManifest`.\n */\nexport interface OntologyConfig {\n /** Global default mode. Default: `'off'` (backward compatible — no typed extraction). */\n mode?: OntologyMode;\n /**\n * Bootstrap manifests for known entities at construction time.\n * Written to the database on first access if no row exists for that entity.\n */\n seedManifests?: Record<string, {\n manifest: OntologyManifest;\n mode?: OntologyMode;\n }>;\n}\n\nexport interface ExtractedFactEdge {\n edge_type: string;\n target_title: string;\n}\n\nexport interface OntologyUpdates {\n node_types?: OntologyNodeType[];\n edge_types?: OntologyEdgeType[];\n}\n\nexport interface OntologyPromptContext {\n ontologyManifest: string;\n ontologyModeInstructions: string;\n}\n\n/** Result of a single ontology backfill run. Omissions (facts the model declined\n * to classify) are derivable as scanned − typed − failedValidation. */\nexport interface OntologyBackfillResult {\n /** Untyped facts sent to the model this run. */\n scanned: number;\n /** Facts that received an okf_type. */\n typed: number;\n /** Model classifications rejected (unknown/duplicate id, non-manifest type). */\n failedValidation: number;\n /** Edges persisted. */\n edgesAdded: number;\n /** Untyped facts still eligible after this run — safe host convergence signal: loop while > 0.\n * Always 0 when ontology mode is 'off' (nothing is eligible for typing while\n * disabled), so 0 does not imply queue exhaustion in that mode. */\n remaining: number;\n /** Untyped facts inside the recheck cooldown. */\n deferred: number;\n /** Facts a batch could not process even alone, skipped so the pass could finish.\n * Stamped with the recheck cooldown, so they reappear as `deferred` next pass. */\n skipped: number;\n}\n\nexport interface WikiConfig {\n /**\n * Prefix applied to every SQL table/index/trigger name. Must match\n * `^[A-Za-z][A-Za-z0-9_]{0,30}_$` (letter, then alphanumeric/underscore,\n * ending in `_`, max 32 chars total) — enforced in the `WikiMemory` constructor.\n * Default: `'llm_wiki_'`.\n */\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 /** Global prompt overrides for text generation calls (`ingestDocument`, `runLibrarian`, `runHeal`). Does not affect embedding generation. Runtime overrides on individual method calls take precedence. */\n prompts?: PromptOverrides;\n /**\n * When true, entry and task mutations append an event to the internal outbox table.\n * The table is always created; this flag only controls whether writes occur.\n * @default false\n */\n enableOutbox?: boolean;\n ontology?: OntologyConfig;\n /** Default node cap for traverseGraph(), unless overridden per-call. Default 20. */\n maxTraversalNodes?: number;\n /** Default minimum confidence tier for discovered traversal nodes. Default 'tentative'. */\n minTraversalConfidence?: 'certain' | 'inferred' | 'tentative';\n /** Default traversal direction. Default 'both'. */\n traversalDirection?: 'inbound' | 'outbound' | 'both';\n /** Default source_type dead-end list for discovered traversal nodes. Default []. */\n excludeSourceTypes?: Array<WikiFact['source_type']>;\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> | null;\n last_accessed_at: number | null;\n access_count: number;\n deleted_at: number | null;\n /**\n * Verbatim OKF `type:` frontmatter value when this fact originated from (or was\n * re-imported via) an OKF bundle. `null`/`undefined` for facts never touched by\n * OKF import. Distinct from `source_type`, which governs immutability rules.\n */\n okf_type?: string | 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 /** Verbatim OKF `type:` frontmatter value when this task originated from an OKF bundle. */\n okf_type?: string | 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 WikiEdge {\n id: string;\n entity_id: string;\n source_id: string;\n target_id: string;\n edge_type: string;\n created_at: number;\n}\n\nexport interface GraphTraversalOptions {\n sourceId: string;\n /** Hop count. Default 1. Clamped to [1, 3] regardless of input. */\n maxDepth?: number;\n /** Default 'both'. Falls back to WikiConfig.traversalDirection, then 'both'. */\n direction?: 'inbound' | 'outbound' | 'both';\n /**\n * Allowed edge types. `undefined` = no filter (all types).\n * `[]` (explicit empty array) = match nothing — distinct from `undefined`.\n */\n edgeTypes?: string[];\n /** Total node cap (anchor + neighbors). Default 20 via WikiConfig.maxTraversalNodes. */\n maxTraversalNodes?: number;\n /** Minimum confidence tier for *discovered* nodes. Does not gate the anchor. Default 'tentative'. */\n minTraversalConfidence?: 'certain' | 'inferred' | 'tentative';\n /** source_type values to dead-end on for *discovered* nodes. Does not gate the anchor. Default []. */\n excludeSourceTypes?: Array<WikiFact['source_type']>;\n}\n\nexport interface GraphNeighborhood {\n /** Anchor node first, then discovered neighbors ordered by depth ASC, then updated_at DESC. */\n nodes: WikiFact[];\n /** Only edges where both endpoints are present in `nodes`. */\n edges: WikiEdge[];\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 ExtractedFactWithOntology extends ExtractedFact {\n okf_type?: string;\n edges?: ExtractedFactEdge[];\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 * Optional. The provider's hard output-token ceiling for `generateText`.\n * Core cannot observe it — the token budget lives entirely in the host's\n * adapter — so maintenance passes that generate response-size-proportional\n * output size their batches blind unless this is declared.\n *\n * When absent, batching falls back to a conservative default and adapts\n * downward on failure. When present, it is used as a sizing hint only and is\n * never trusted as a guarantee.\n */\n maxOutputTokens?: 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 edges?: WikiEdge[];\n /** Entity summary prose for OKF profile ≥ 1 round-trip. Omitted = no summary (Clanker default). */\n summary?: string;\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. `'ontologyBackfill'` was added afterward.\n * Exhaustive `switch` / narrowing on this type must be updated (or given a\n * `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 | 'ontologyBackfill';\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\n/**\n * Thrown by the serialized transaction wrapper when a SQLite driver error\n * escapes a transaction callback (nested BEGIN, SQLITE_BUSY, constraint\n * violation). Domain errors thrown from callback logic pass through unwrapped.\n * Stable `instanceof` target for observability, mirroring {@link WikiBusyError}.\n */\nexport class WikiTransactionError extends Error {\n /** Best-effort SQLite code lifted from the driver error, e.g. 'SQLITE_BUSY'. */\n readonly sqliteErrorCode?: string;\n\n constructor(message: string, options: { cause: unknown }) {\n super(message, options);\n this.name = 'WikiTransactionError';\n this.sqliteErrorCode = extractSqliteCode(options.cause);\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\nexport const HOOK_TIMEOUT_MARKER = Symbol('WikiMemoryHookTimeout');\n\n","import type { ExtractedFact, ExtractedTask } from '../types';\n\nexport function 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 const useBrace =\n firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket);\n\n if (useBrace) {\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 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\nexport function sanitizeRankerError(err: unknown, sanitizeRankerErrors: boolean | undefined): Error {\n if (sanitizeRankerErrors === false) {\n return err instanceof Error ? err : new Error(String(err));\n }\n const typeName = err instanceof Error ? (err.constructor?.name ?? 'Error') : typeof err;\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 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\nexport function 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\nexport function 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\nexport async 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\nexport function 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\nexport function 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\nexport function 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\nexport function 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 // Clamp priority to valid range 0-10 as documented in the prompt contract\n priority = Math.max(0, Math.min(10, Math.round(priority)));\n\n return {\n ...task,\n description,\n priority\n };\n}\n\nexport function 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\nexport function 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\nexport function 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\nexport function 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","import type { SQLiteAdapter, WikiOptions } from '../types';\nimport { HOOK_TIMEOUT_MARKER } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport { clip } from '../utils/pure';\n\nexport class EmbeddingService {\n constructor(\n private db: SQLiteAdapter,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private metadataRepo: MetadataRepository,\n ) {}\n\n async storeEmbeddingDimension(dim: number): Promise<void> {\n const existing = await this.metadataRepo.getMeta('embedding_dimension');\n if (existing) {\n const storedDim = parseInt(existing, 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.metadataRepo.setMeta('embedding_dimension_mismatch', String(dim), this.db);\n }\n // Do not clear embedding_dimension_mismatch here; only reconcileEmbeddingDimension()\n // may clear it after a full runReembed confirms all blobs match.\n } else {\n await this.metadataRepo.setMeta('embedding_dimension', String(dim), this.db);\n }\n }\n\n /** Promotes embedding_dimension_mismatch to canonical embedding_dimension when safe. */\n async reconcileEmbeddingDimension(): Promise<void> {\n const mismatchValue = await this.metadataRepo.getMeta('embedding_dimension_mismatch');\n if (!mismatchValue) return;\n\n const newDim = parseInt(mismatchValue, 10);\n const residualCount = await this.entryRepo.countStaleEmbeddings(newDim);\n if (residualCount === 0) {\n await this.metadataRepo.setMeta('embedding_dimension', mismatchValue, this.db);\n await this.metadataRepo.clearDimensionMismatch(this.db);\n }\n }\n\n async embedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }): 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 = clip(`${fact.title} ${fact.body} ${tagsStr}`.trim(), 16_000);\n try {\n const vector = await embedFn(text);\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])) {\n hasNonFinite = true;\n break;\n }\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.entryRepo.updateEmbeddingBlob(fact.id, blob);\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 async notifyEmbeddingPersisted(entityId: string, factId: string, vector: Float32Array | null): Promise<void> {\n if (!this.options.vectorRanker?.onEmbeddingPersisted) return;\n const vectorCopy = vector ? vector.slice() : null;\n await this.options.vectorRanker.onEmbeddingPersisted({\n entityId,\n factId,\n vector: vectorCopy,\n });\n }\n\n 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 const timeoutError = new Error(`onEmbeddingPersisted timed out after ${timeoutMs}ms`);\n (timeoutError as any)[HOOK_TIMEOUT_MARKER] = true;\n reject(timeoutError);\n }, timeoutMs);\n });\n\n const hookPromise = Promise.resolve().then(() =>\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 hookPromise.catch(() => {});\n throw err;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n}\n","import type {\n OntologyManifest,\n OntologyUpdates,\n ExtractedFactEdge,\n} from '../types';\n\nexport function emptyManifest(): OntologyManifest {\n return { node_types: [], edge_types: [] };\n}\n\nexport function normalizeTitleKey(title: string): string {\n return title.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nexport function resolveNodeType(raw: string, manifest: OntologyManifest): string | null {\n const slug = raw.trim();\n if (!slug) return null;\n const hit = manifest.node_types.find(n => n.type.toLowerCase() === slug.toLowerCase());\n return hit?.type ?? null;\n}\n\nexport function resolveEdgeDefinitions(\n rawEdgeType: string,\n manifest: OntologyManifest,\n): OntologyManifest['edge_types'][number][] {\n const slug = rawEdgeType.trim();\n if (!slug) return [];\n return manifest.edge_types.filter(e => e.type.toLowerCase() === slug.toLowerCase());\n}\n\nfunction edgeTripleKey(type: string, sourceType: string, targetType: string): string {\n return `${type.trim().toLowerCase()}|${sourceType.trim().toLowerCase()}|${targetType.trim().toLowerCase()}`;\n}\n\nexport function validateManifest(manifest: OntologyManifest): void {\n const nodeSlugs = new Set<string>();\n for (const node of manifest.node_types ?? []) {\n const type = node.type?.trim();\n if (!type) throw new Error('Ontology node type slug must be non-empty');\n const key = type.toLowerCase();\n if (nodeSlugs.has(key)) throw new Error(`Duplicate node type: ${type}`);\n nodeSlugs.add(key);\n }\n const edgeKeys = new Set<string>();\n const edgeNames = new Map<string, string>();\n for (const edge of manifest.edge_types ?? []) {\n const edgeType = edge.type?.trim();\n const sourceType = edge.source_type?.trim();\n const targetType = edge.target_type?.trim();\n if (!edgeType) throw new Error('Ontology edge type slug must be non-empty');\n if (!sourceType || !targetType || !nodeSlugs.has(sourceType.toLowerCase()) || !nodeSlugs.has(targetType.toLowerCase())) {\n throw new Error(`Edge type ${edgeType} references unknown node type`);\n }\n const edgeKey = edgeTripleKey(edgeType, sourceType, targetType);\n if (edgeKeys.has(edgeKey)) {\n throw new Error(`Duplicate edge definition: ${edgeType} (${sourceType} → ${targetType})`);\n }\n edgeKeys.add(edgeKey);\n // Persisted edge_type values come from def.type verbatim, so every triple\n // sharing a name must agree on casing or storage ends up mixed.\n const canonical = edgeNames.get(edgeType.toLowerCase());\n if (canonical === undefined) {\n edgeNames.set(edgeType.toLowerCase(), edgeType);\n } else if (canonical !== edgeType) {\n throw new Error(`Inconsistent casing for edge type: ${edgeType} conflicts with ${canonical}`);\n }\n }\n}\n\nexport function mergeOntologyUpdates(\n current: OntologyManifest,\n updates: OntologyUpdates,\n): OntologyManifest {\n const node_types = [...current.node_types];\n const edge_types = [...current.edge_types];\n const nodeSlugs = new Set(node_types.map(n => n.type.trim().toLowerCase()));\n const edgeKeys = new Set(edge_types.map(e => edgeTripleKey(e.type, e.source_type, e.target_type)));\n const edgeNames = new Map(edge_types.map(e => [e.type.trim().toLowerCase(), e.type.trim()]));\n\n for (const node of updates.node_types ?? []) {\n const type = node?.type?.trim();\n if (!type) continue;\n const key = type.toLowerCase();\n if (nodeSlugs.has(key)) continue;\n node_types.push({ type, description: String(node.description ?? '') });\n nodeSlugs.add(key);\n }\n for (const edge of updates.edge_types ?? []) {\n const rawEdgeType = edge?.type?.trim();\n const sourceType = edge?.source_type?.trim();\n const targetType = edge?.target_type?.trim();\n if (!rawEdgeType || !sourceType || !targetType) continue;\n // First-seen casing wins for a given edge name, as with node types, so a\n // later triple spelled differently cannot make the manifest fail validation.\n const edgeType = edgeNames.get(rawEdgeType.toLowerCase()) ?? rawEdgeType;\n const edgeKey = edgeTripleKey(edgeType, sourceType, targetType);\n if (edgeKeys.has(edgeKey)) continue;\n if (!nodeSlugs.has(sourceType.toLowerCase()) || !nodeSlugs.has(targetType.toLowerCase())) continue;\n edgeNames.set(edgeType.toLowerCase(), edgeType);\n edge_types.push({\n type: edgeType,\n source_type: sourceType,\n target_type: targetType,\n description: String(edge.description ?? ''),\n });\n edgeKeys.add(edgeKey);\n }\n return { node_types, edge_types };\n}\n\nexport function validateInlineEdges(\n sourceType: string,\n _targetType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n): ExtractedFactEdge[] {\n if (!Array.isArray(edges)) return [];\n const valid: ExtractedFactEdge[] = [];\n for (const edge of edges) {\n if (typeof edge?.edge_type !== 'string' || typeof edge?.target_title !== 'string') continue;\n const defs = resolveEdgeDefinitions(edge.edge_type, manifest);\n const match = defs.find(d => d.source_type.toLowerCase() === sourceType.toLowerCase());\n if (!match) continue;\n valid.push({ edge_type: match.type, target_title: edge.target_title });\n }\n return valid;\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { SQLiteAdapter, OntologyManifest, OntologyMode, OntologyUpdates } from '../types';\nimport { emptyManifest, mergeOntologyUpdates, validateManifest } from '../utils/ontology';\n\n/** Meta-table key for an entity's OKF summary prose (profile v1 round-trip). */\nexport function entitySummaryMetaKey(entityId: string): string {\n return `entity_summary:${entityId}`;\n}\n\nexport class MetadataRepository extends BaseRepository {\n // CHECKPOINTS TABLE METHODS\n\n async getCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<{ memory?: number; heal?: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{\n memory_checkpoint: number | null;\n heal_checkpoint: number | null;\n }>(\n `SELECT memory_checkpoint, heal_checkpoint FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId],\n );\n if (!row) return {};\n return {\n memory: row.memory_checkpoint ?? undefined,\n heal: row.heal_checkpoint ?? undefined,\n };\n }\n\n async updateCheckpoint(\n entityId: string,\n updates: { memory?: number; heal?: number },\n tx: SQLiteAdapter,\n ): Promise<void> {\n const fields: string[] = [];\n const values: number[] = [];\n\n if (updates.memory !== undefined) {\n fields.push('memory_checkpoint = ?');\n values.push(updates.memory);\n }\n if (updates.heal !== undefined) {\n fields.push('heal_checkpoint = ?');\n values.push(updates.heal);\n }\n if (fields.length === 0) return;\n\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}checkpoints (entity_id, memory_checkpoint, heal_checkpoint)\n VALUES (?, ?, ?)\n ON CONFLICT(entity_id) DO UPDATE SET ${fields.join(', ')}`,\n [entityId, updates.memory ?? 0, updates.heal ?? 0, ...values],\n );\n }\n\n async deleteCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}checkpoints WHERE entity_id = ?`,\n [entityId],\n );\n }\n\n // META TABLE METHODS\n\n async getMeta(key: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ value: string }>(\n `SELECT value FROM ${this.prefix}meta WHERE key = ?`,\n [key],\n );\n return row ? row.value : null;\n }\n\n async setMeta(key: string, value: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}meta (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value`,\n [key, value],\n );\n }\n\n async deleteMeta(key: string, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = ?`,\n [key],\n );\n }\n\n async clearDimensionMismatch(tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `DELETE FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`,\n );\n }\n\n async tableExists(tableName: string, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ name: string }>(\n `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,\n [tableName],\n );\n return row != null;\n }\n\n async getTableDdl(tableName: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ sql: string | null }>(\n `SELECT sql FROM sqlite_master WHERE type='table' AND name=?`,\n [tableName],\n );\n return row?.sql ?? null;\n }\n\n async vacuum(): Promise<void> {\n await this.db.execAsync(`PRAGMA wal_checkpoint(TRUNCATE)`);\n await this.db.execAsync(`VACUUM`);\n }\n\n async getDistinctEntityIds(tx?: SQLiteAdapter): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.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 return rows.map(r => r.entity_id);\n }\n\n async getManifest(entityId: string, tx?: SQLiteAdapter): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n } | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{\n mode: string;\n manifest_json: string;\n }>(`SELECT mode, manifest_json FROM ${this.prefix}entity_manifests WHERE entity_id = ?`, [entityId]);\n if (!row) return null;\n if (row.mode !== 'off' && row.mode !== 'strict' && row.mode !== 'emergent') {\n throw new Error(`Invalid ontology mode for entity ${entityId}: ${JSON.stringify(row.mode)}`);\n }\n let manifest: OntologyManifest;\n try {\n manifest = JSON.parse(row.manifest_json) as OntologyManifest;\n } catch (error) {\n throw new Error(`Invalid manifest_json for entity ${entityId}: ${(error as Error).message}`);\n }\n validateManifest(manifest);\n return {\n mode: row.mode,\n manifest,\n };\n }\n\n async setManifest(\n entityId: string,\n data: { mode: OntologyMode; manifest: OntologyManifest },\n tx: SQLiteAdapter,\n ): Promise<void> {\n validateManifest(data.manifest);\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(entity_id) DO UPDATE SET mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`,\n [entityId, data.mode, JSON.stringify(data.manifest), Date.now()],\n );\n }\n\n async mergeManifestUpdates(\n entityId: string,\n updates: OntologyUpdates,\n tx: SQLiteAdapter,\n ): Promise<OntologyManifest> {\n const current = (await this.getManifest(entityId, tx)) ?? {\n mode: 'emergent' as OntologyMode,\n manifest: emptyManifest(),\n };\n const merged = mergeOntologyUpdates(current.manifest, updates);\n await this.setManifest(entityId, { mode: current.mode, manifest: merged }, tx);\n return merged;\n }\n}\n","import type { SQLiteAdapter, MemoryBundle, MemoryDump, WikiFact } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\nimport { entitySummaryMetaKey, type MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\nimport { clip } from '../utils/pure';\n\nconst MAX_EMBEDDING_BLOB_BYTES = 32 * 1024; // 8192-dim float32 ceiling\nconst IMPORT_TITLE_MAX = 500;\nconst IMPORT_BODY_MAX = 8000;\n\nexport class ImportExportService {\n constructor(\n private db: SQLiteAdapter,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private edgeRepo: EdgeRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\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 ids = await this.metadataRepo.getDistinctEntityIds();\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(\n async (id): Promise<[string, MemoryBundle]> => [\n id,\n await this.getFullBundle(id, { includeBlobs: true }),\n ],\n ),\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(\n dump: MemoryDump,\n opts?: { merge?: boolean },\n ): Promise<void> {\n const merge = opts?.merge ?? false;\n const entityIds = Object.keys(dump.entities);\n\n this.jobManager.acquireImportLocks(entityIds);\n try {\n await this.assertNoLegacySourceTypes();\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n await this.doImportEntity(entityId, bundle, merge);\n }\n } finally {\n this.jobManager.releaseImportLocks(entityIds);\n }\n }\n\n async getFullBundle(\n entityId: string,\n opts?: { maxEvents?: number; includeBlobs?: boolean },\n ): Promise<MemoryBundle> {\n const [factsRaw, tasks, events, edges, summaryValue] = await Promise.all([\n opts?.includeBlobs\n ? this.entryRepo.findAllByEntityIdWithBlobs(entityId)\n : this.entryRepo.findAllByEntityId(entityId),\n this.taskRepo.findAllByEntityId(entityId),\n this.eventRepo.getByEntityId(entityId, opts?.maxEvents),\n this.edgeRepo.getByEntityId(entityId),\n this.metadataRepo.getMeta(entitySummaryMetaKey(entityId)),\n ]);\n\n const facts = factsRaw.map((f) => {\n const {\n embedding: _embedding,\n embedding_blob,\n ...rest\n } = f as WikiFact & { embedding?: unknown; embedding_blob?: Uint8Array };\n const safeBlobCopy =\n opts?.includeBlobs && embedding_blob\n ? (() => {\n const c = new ArrayBuffer(embedding_blob.byteLength);\n new Uint8Array(c).set(embedding_blob);\n return new Uint8Array(c);\n })()\n : undefined;\n\n const factBase = safeBlobCopy\n ? { ...rest, embedding_blob: safeBlobCopy }\n : rest;\n return {\n ...factBase,\n tags:\n typeof factBase.tags === 'string'\n ? JSON.parse(factBase.tags)\n : factBase.tags,\n };\n });\n\n return {\n facts,\n tasks,\n events,\n edges,\n ...(summaryValue != null ? { summary: summaryValue } : {}),\n };\n }\n\n /** Single-entity import transaction + post-processing; package-internal hook for tests. */\n async doImportEntity(\n entityId: string,\n bundle: MemoryBundle,\n merge: boolean,\n ): Promise<void> {\n const upsertedFactIds = new Set<string>();\n const upsertedDeletedFactIds = new Set<string>();\n const factsWithPreservedBlob = new Map<string, Uint8Array>();\n const preservedBlobDims = new Set<number>();\n const softDeletedFactIds: string[] = [];\n const clippedTextByFactId = new Map<string, { title: string; body: string }>();\n\n await this.db.withTransactionAsync(async (tx) => {\n if (!merge) {\n const deletedLiveFactIds = await this.entryRepo.findIdsBySource(\n entityId,\n null,\n null,\n tx,\n false,\n );\n softDeletedFactIds.push(...deletedLiveFactIds);\n await this.entryRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.taskRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.edgeRepo.bulkDeleteByEntityId(entityId, tx);\n await this.metadataRepo.deleteCheckpoint(entityId, tx);\n }\n\n if (bundle.summary !== undefined) {\n await this.metadataRepo.setMeta(entitySummaryMetaKey(entityId), bundle.summary, tx);\n } else if (!merge) {\n await this.metadataRepo.deleteMeta(entitySummaryMetaKey(entityId), tx);\n }\n\n const factIds = bundle.facts.map((fact) => fact.id);\n const existingFactsById = new Map<\n string,\n { id: string; entity_id: string; updated_at: number }\n >();\n const existingFacts = await this.entryRepo.findExistingMetadataByIds(\n factIds,\n tx,\n );\n for (const existingFact of existingFacts) {\n existingFactsById.set(existingFact.id, existingFact);\n }\n\n for (const fact of bundle.facts) {\n const sourceType = this._normalizeImportedSourceType(\n String(fact.source_type),\n {\n entityId,\n factId: fact.id,\n },\n );\n\n const safeUpdatedAt = Number.isFinite(fact.updated_at)\n ? fact.updated_at\n : 0;\n const existing = existingFactsById.get(fact.id);\n\n const rawBlobRaw = (fact as WikiFact & { embedding_blob?: unknown })\n .embedding_blob;\n let rawBlob: Uint8Array | null = null;\n\n if (rawBlobRaw instanceof Uint8Array) {\n if (rawBlobRaw.byteLength <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = rawBlobRaw;\n }\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 const data = obj['data'] as number[];\n if (data.length <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = new Uint8Array(data);\n }\n } else if (!Array.isArray(rawBlobRaw)) {\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every((k) => /^\\d+$/.test(k))) {\n const len = entries.length;\n if (len <= MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n rawBlob[i] = (obj[String(i)] as number) ?? 0;\n }\n }\n }\n }\n }\n\n if (rawBlob !== null && rawBlob.byteLength > MAX_EMBEDDING_BLOB_BYTES) {\n rawBlob = null; // Oversized blob — drop and let the fact re-embed normally.\n }\n\n let blobData: Uint8Array | null = null;\n if (\n rawBlob !== null &&\n rawBlob.byteLength > 0 &&\n rawBlob.byteLength % 4 === 0\n ) {\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\n let allFinite = true;\n for (let i = 0; i < floats.length; i++) {\n if (!isFinite(floats[i])) {\n allFinite = false;\n break;\n }\n }\n if (allFinite) {\n blobData = alignedBlob;\n }\n }\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision(\n 'entry',\n fact.id,\n existing.entity_id,\n entityId,\n );\n continue;\n }\n if (merge && safeUpdatedAt <= existing.updated_at) continue;\n }\n\n const safeTitle = clip(String(fact.title ?? ''), IMPORT_TITLE_MAX);\n const safeBody = clip(String(fact.body ?? ''), IMPORT_BODY_MAX);\n clippedTextByFactId.set(fact.id, { title: safeTitle, body: safeBody });\n\n const factObj: WikiFact = {\n id: fact.id,\n entity_id: entityId,\n title: safeTitle,\n body: safeBody,\n tags: Array.isArray(fact.tags) ? fact.tags : [],\n confidence: fact.confidence,\n source_type: sourceType,\n source_hash: fact.source_hash,\n source_ref: fact.source_ref,\n created_at: fact.created_at,\n updated_at: safeUpdatedAt,\n last_accessed_at: fact.last_accessed_at,\n access_count: fact.access_count,\n deleted_at: fact.deleted_at,\n embedding_blob: blobData ?? undefined,\n okf_type: fact.okf_type ?? null,\n };\n\n await this.entryRepo.upsertForImport(factObj, tx);\n\n if (blobData != null) {\n factsWithPreservedBlob.set(fact.id, blobData);\n if (!fact.deleted_at) preservedBlobDims.add(blobData.byteLength / 4);\n }\n\n existingFactsById.set(fact.id, {\n id: fact.id,\n entity_id: entityId,\n updated_at: safeUpdatedAt,\n });\n upsertedFactIds.add(fact.id);\n if (fact.deleted_at) upsertedDeletedFactIds.add(fact.id);\n }\n\n const taskIds = bundle.tasks.map((task) => task.id);\n const existingTasksById = new Map<\n string,\n { id: string; entity_id: string; updated_at: number }\n >();\n const existingTasks = await this.taskRepo.findExistingMetadataByIds(\n taskIds,\n tx,\n );\n\n for (const existingTask of existingTasks) {\n existingTasksById.set(existingTask.id, existingTask);\n }\n\n for (const task of bundle.tasks) {\n const safeUpdatedAt = Number.isFinite(task.updated_at)\n ? task.updated_at\n : 0;\n const existing = existingTasksById.get(task.id);\n\n if (existing) {\n if (existing.entity_id !== entityId) {\n this._warnCrossEntityCollision(\n 'task',\n task.id,\n existing.entity_id,\n entityId,\n );\n continue;\n }\n if (merge && safeUpdatedAt <= existing.updated_at) continue;\n }\n\n await this.taskRepo.upsertForImport(\n {\n id: task.id,\n entity_id: entityId,\n description: task.description,\n status: task.status,\n priority: task.priority,\n created_at: task.created_at,\n updated_at: safeUpdatedAt,\n resolved_at: task.resolved_at,\n deleted_at: task.deleted_at,\n okf_type: task.okf_type ?? null,\n },\n tx,\n safeUpdatedAt,\n );\n\n existingTasksById.set(task.id, {\n id: task.id,\n entity_id: entityId,\n updated_at: safeUpdatedAt,\n });\n }\n\n for (const event of bundle.events) {\n await this.eventRepo.addIgnoreDuplicate(\n {\n id: event.id,\n entity_id: entityId,\n event_type: event.event_type,\n summary: event.summary,\n related_entry_id: event.related_entry_id ?? null,\n created_at: event.created_at,\n },\n tx,\n );\n }\n\n for (const edge of bundle.edges ?? []) {\n await this.edgeRepo.addIgnoreDuplicate(\n {\n id: edge.id,\n entity_id: entityId,\n source_id: edge.source_id,\n target_id: edge.target_id,\n edge_type: edge.edge_type,\n created_at: edge.created_at,\n },\n tx,\n );\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const fact of bundle.facts) {\n if (\n !fact.deleted_at &&\n upsertedFactIds.has(fact.id) &&\n !factsWithPreservedBlob.has(fact.id)\n ) {\n const clipped = clippedTextByFactId.get(fact.id);\n const embedded = await this.embeddingService.embedFact({\n id: fact.id,\n entity_id: entityId,\n title: clipped?.title ?? fact.title,\n body: clipped?.body ?? fact.body,\n tags:\n Array.isArray(fact.tags) || typeof fact.tags === 'string'\n ? fact.tags\n : [],\n });\n if (!embedded) {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, fact.id, null);\n }\n }\n }\n\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(\n blobData.buffer,\n blobData.byteOffset,\n blobData.byteLength / 4,\n );\n await this.embeddingService.notifyEmbeddingPersisted(\n entityId,\n fact.id,\n float32Vector,\n );\n } catch (hookErr) {\n console.warn(\n `[WikiMemory] onEmbeddingPersisted hook failed for preserved-blob fact ${fact.id}:`,\n hookErr,\n );\n }\n }\n }\n\n for (const factId of softDeletedFactIds) {\n if (!upsertedFactIds.has(factId) || upsertedDeletedFactIds.has(factId)) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(\n entityId,\n factId,\n null,\n );\n } catch (hookErr) {\n console.warn(\n `[WikiMemory] onEmbeddingPersisted(vector=null) hook failed for soft-deleted fact ${factId}:`,\n hookErr,\n );\n }\n }\n }\n\n try {\n const canonicalDimValue = await this.metadataRepo.getMeta(\n 'embedding_dimension',\n );\n const canonicalDim = canonicalDimValue\n ? parseInt(canonicalDimValue, 10)\n : null;\n\n if (preservedBlobDims.size === 1) {\n const preservedDim = [...preservedBlobDims][0];\n if (canonicalDim === null || canonicalDim === preservedDim) {\n await this.embeddingService.storeEmbeddingDimension(preservedDim);\n const staleMismatchValue = await this.metadataRepo.getMeta(\n 'embedding_dimension_mismatch',\n );\n if (\n staleMismatchValue &&\n parseInt(staleMismatchValue, 10) !== preservedDim\n ) {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(preservedDim),\n this.db,\n );\n }\n await this.embeddingService.reconcileEmbeddingDimension();\n } else {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(canonicalDim),\n this.db,\n );\n }\n } else if (preservedBlobDims.size > 1) {\n if (canonicalDim === null) {\n const sortedPreservedBlobDims = [...preservedBlobDims].sort(\n (a, b) => a - b,\n );\n await this.embeddingService.storeEmbeddingDimension(\n sortedPreservedBlobDims[0],\n );\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(sortedPreservedBlobDims[0]),\n this.db,\n );\n } else {\n await this.metadataRepo.setMeta(\n 'embedding_dimension_mismatch',\n String(canonicalDim),\n this.db,\n );\n }\n }\n } finally {\n this.searchService.evictCache(entityId);\n }\n }\n\n private _warnCrossEntityCollision(\n type: 'entry' | 'task',\n id: string,\n existingEntityId: string,\n targetEntityId: string,\n ): void {\n console.warn(\n `[WikiMemory] importDump: ${type} id ${JSON.stringify(id)} already belongs to entity ` +\n `${JSON.stringify(existingEntityId)}; skipping for entity ${JSON.stringify(targetEntityId)}`,\n );\n }\n\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\n const allowed: WikiFact['source_type'][] = [\n 'user_stated',\n 'librarian_inferred',\n 'user_confirmed',\n 'immutable_document',\n ];\n if ((allowed as string[]).includes(raw))\n return raw as WikiFact['source_type'];\n\n const where =\n ctx !== undefined\n ? ` for entity \"${ctx.entityId}\" fact \"${ctx.factId}\"`\n : '';\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 public async assertNoLegacySourceTypes(): Promise<void> {\n if (!(await this.entryRepo.hasLegacySourceTypes())) return;\n\n const count = await this.entryRepo.countLegacySourceTypes();\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${this.entryRepo.getLegacyMigrationSQL()}\\n\\n` +\n `After running the migration SQL, restart your application.`,\n );\n }\n}\n","type GetRandomValues = (bytes: Uint8Array) => void;\n\nlet _injectedGetRandomValues: GetRandomValues | null = null;\n\n/**\n * Inject a platform-specific `getRandomValues` implementation.\n * Call this once at module load time from the platform adapter\n * (e.g. expo-crypto's getRandomValues) when the global `crypto` API is\n * absent — Hermes / React Native being the primary case.\n * Pass `null` to clear a previously injected source.\n */\nexport function configureRandomSource(fn: GetRandomValues | null): void {\n _injectedGetRandomValues = fn;\n}\n\n/**\n * Generate a random ID with an optional prefix.\n * Resolution order:\n * 1. crypto.randomUUID (Web / Node 19+)\n * 2. crypto.getRandomValues (Web / Node / polyfilled global)\n * 3. injected source via configureRandomSource (e.g. expo-crypto in RN)\n * Throws if none is available — record IDs must always be cryptographically random.\n */\nexport function generateId(prefix: string = ''): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return prefix + crypto.randomUUID().replace(/-/g, '').substring(0, 24);\n }\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return prefix + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('').substring(0, 24);\n }\n if (_injectedGetRandomValues) {\n const bytes = new Uint8Array(16);\n _injectedGetRandomValues(bytes);\n return prefix + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('').substring(0, 24);\n }\n throw new Error(\n 'generateId: no cryptographically secure random source available ' +\n '(crypto.randomUUID and crypto.getRandomValues are both missing, and no configureRandomSource() injection was provided).',\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\nexport const ONTOLOGY_BACKFILL_SYSTEM_PROMPT = `You are a knowledge classification agent. You will receive existing memory facts that currently have no ontology type. For each input fact { \"id\", \"title\", \"body\", \"tags\" }, assign the best matching okf_type from the ontology manifest and optionally propose edges to related facts by title.\nReturn ONLY a valid JSON object matching this schema:\n{\n \"classifications\": [\n { \"id\": \"string (input fact id, copied verbatim)\", \"okf_type\": \"string (manifest node type slug)\", \"edges\": [{ \"edge_type\": \"string\", \"target_title\": \"string\" }] }\n ]\n}\nIf no manifest type fits a fact, omit that fact from \"classifications\" entirely — do not guess.\nDo not return markdown, just raw JSON.`;\n","import {\n INGEST_SYSTEM_PROMPT,\n LIBRARIAN_SYSTEM_PROMPT,\n HEAL_SYSTEM_PROMPT,\n ONTOLOGY_BACKFILL_SYSTEM_PROMPT,\n} from '../prompts';\nimport type { PromptOverrides, OntologyPromptContext } from '../types';\n\nexport class PromptService {\n constructor(private globalOverrides?: PromptOverrides) {}\n\n private hydrate(template: string, variables: Record<string, unknown>): string {\n return template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_match, key) => {\n const value = variables[key];\n if (value === undefined) return _match;\n return typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n });\n }\n\n private hasOntologyPlaceholders(template: string): boolean {\n return /\\{\\{\\s*ontology(?:Manifest|ModeInstructions)\\s*\\}\\}/.test(template);\n }\n\n private buildSystemPrompt(\n template: string,\n variables: Record<string, unknown>,\n ontologyContext: OntologyPromptContext | null | undefined,\n ): string {\n const shouldHydrate = Object.keys(variables).some((key) =>\n new RegExp(`\\\\{\\\\{\\\\s*${key}\\\\s*\\\\}\\\\}`).test(template),\n ) || (ontologyContext != null && this.hasOntologyPlaceholders(template));\n\n const hydrated = shouldHydrate\n ? this.hydrate(template, { ...variables, ...(ontologyContext ?? {}) })\n : template;\n\n return this.hasOntologyPlaceholders(template)\n ? (ontologyContext != null\n ? hydrated\n : hydrated.replace(/\\{\\{\\s*ontology(?:Manifest|ModeInstructions)\\s*\\}\\}/g, ''))\n : this.appendOntology(hydrated, ontologyContext);\n }\n\n private appendOntology(systemPrompt: string, ctx: OntologyPromptContext | null | undefined): string {\n if (!ctx) return systemPrompt;\n return `${systemPrompt}\\n\\n${ctx.ontologyModeInstructions}`;\n }\n\n buildIngestPrompt(\n documentChunk: string,\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.ingestSystemPrompt ?? INGEST_SYSTEM_PROMPT;\n const hasDocumentChunk = /\\{\\{\\s*documentChunk\\s*\\}\\}/.test(template);\n if (hasDocumentChunk || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { documentChunk }, ontologyContext),\n userPrompt: hasDocumentChunk ? 'Please extract the facts.' : `Document Chunk:\\n${documentChunk}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Document Chunk:\\n${documentChunk}`,\n };\n }\n\n buildLibrarianPrompt(\n events: unknown[],\n currentFacts: unknown[],\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.librarianSystemPrompt ?? LIBRARIAN_SYSTEM_PROMPT;\n const hasEvents = /\\{\\{\\s*events\\s*\\}\\}/.test(template);\n const hasCurrentFacts = /\\{\\{\\s*currentFacts\\s*\\}\\}/.test(template);\n if (hasEvents || hasCurrentFacts || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { events, currentFacts }, ontologyContext),\n userPrompt: (hasEvents || hasCurrentFacts)\n ? 'Please synthesize the context.'\n : `Events:\\n${JSON.stringify(events, null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Events:\\n${JSON.stringify(events, null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`,\n };\n }\n\n buildHealPrompt(\n healCandidates: unknown[],\n documentAnchors: unknown[],\n allTasks: unknown[],\n recentEvents: unknown[],\n runtimeOverride?: string,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.healSystemPrompt ?? HEAL_SYSTEM_PROMPT;\n if (\n /\\{\\{\\s*healCandidates\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*documentAnchors\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*allTasks\\s*\\}\\}/.test(template) ||\n /\\{\\{\\s*recentEvents\\s*\\}\\}/.test(template)\n ) {\n return {\n systemPrompt: this.hydrate(template, { healCandidates, documentAnchors, allTasks, recentEvents }),\n userPrompt: 'Please heal the memory graph.',\n };\n }\n return {\n systemPrompt: template,\n userPrompt: `Heal Candidates:\\n${JSON.stringify(healCandidates, null, 2)}\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(documentAnchors, null, 2)}\\nAll Tasks:\\n${JSON.stringify(allTasks, null, 2)}\\nRecent Events:\\n${JSON.stringify(recentEvents, null, 2)}\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`,\n };\n }\n\n buildOntologyBackfillPrompt(\n facts: unknown[],\n runtimeOverride?: string,\n ontologyContext?: OntologyPromptContext | null,\n ): { systemPrompt: string; userPrompt: string } {\n const template = runtimeOverride ?? this.globalOverrides?.ontologyBackfillSystemPrompt ?? ONTOLOGY_BACKFILL_SYSTEM_PROMPT;\n const hasFacts = /\\{\\{\\s*facts\\s*\\}\\}/.test(template);\n if (hasFacts || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.buildSystemPrompt(template, { facts }, ontologyContext),\n userPrompt: hasFacts ? 'Please classify the facts.' : `Facts:\\n${JSON.stringify(facts, null, 2)}`,\n };\n }\n return {\n systemPrompt: this.appendOntology(template, ontologyContext),\n userPrompt: `Facts:\\n${JSON.stringify(facts, null, 2)}`,\n };\n }\n}\n","import { chunkText, withConcurrency, validateFact, parseJsonResponse, normalizeSourceRef, normalizeSourceHash } from '../utils/pure';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { generateId } from '../utils/ids';\nimport type { WikiOptions, ExtractedFact, ExtractedFactWithOntology, WikiFact, OntologyUpdates } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\nimport type { OntologyService, TitleIndexEntry } from './OntologyService';\nimport { PromptService } from './PromptService';\n\nexport class IngestionService {\n private promptService: PromptService;\n\n constructor(\n private db: SQLiteAdapter,\n private prefix: string,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\n promptService?: PromptService,\n private ontologyService?: OntologyService,\n ) {\n // Fallback for direct instantiation outside WikiMemory facade (e.g. isolated tests).\n this.promptService = promptService ?? new PromptService(this.options.config?.prompts);\n }\n\n async ingestDocument(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n documentChunk: string;\n maxChunkLength?: number;\n chunkOverlap?: number;\n chunkConcurrency?: number;\n promptOverride?: string;\n }\n ): Promise<{ truncated: boolean; chunks: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n\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\n const rawConcurrency = params.chunkConcurrency ?? this.options.config?.chunkConcurrency ?? 1;\n const chunkConcurrency = Number.isFinite(rawConcurrency) && rawConcurrency >= 1 ? Math.floor(rawConcurrency) : 1;\n\n if (typeof params.documentChunk !== 'string') {\n throw new Error(`documentChunk must be a string, received ${typeof params.documentChunk}`);\n }\n\n this.jobManager.acquireLock('ingest', entityId, sourceRef);\n\n try {\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n if (chunks.length === 0) return { truncated: false, chunks: 0 };\n\n const chunkResults = await withConcurrency(\n chunks.map((chunk) => async () => {\n const ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n const { systemPrompt, userPrompt } = this.promptService.buildIngestPrompt(\n chunk,\n params.promptOverride,\n ontologyContext,\n );\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n const result = parseJsonResponse<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>(responseText);\n return {\n facts: (Array.isArray(result.facts) ? result.facts : [])\n .map(validateFact)\n .filter((f): f is ExtractedFact => f !== null),\n ontology_updates: result.ontology_updates,\n };\n }),\n chunkConcurrency\n );\n\n const seen = new Set<string>();\n const orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }> = [];\n for (const chunkResult of chunkResults) {\n const dedupedFacts: ExtractedFact[] = [];\n for (const fact of chunkResult.facts) {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (!seen.has(normalizedTitle)) {\n seen.add(normalizedTitle);\n dedupedFacts.push(fact);\n }\n }\n orderedChunkFacts.push({ facts: dedupedFacts, ontology_updates: chunkResult.ontology_updates });\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 (tx) => {\n deletedSourceFactIds.push(...(await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false)));\n await this.entryRepo.softDeleteBySource(entityId, tx, sourceRef, null);\n\n const titleIndex = new Map<string, TitleIndexEntry>();\n const pendingEdges: Array<{\n sourceId: string;\n sourceType: string | null;\n edges: ExtractedFactWithOntology['edges'];\n }> = [];\n\n const existingFacts = await this.entryRepo.findRecentByEntityId(entityId, 500, tx);\n for (const existing of existingFacts) {\n titleIndex.set(normalizeTitleKey(existing.title), {\n id: existing.id,\n okf_type: existing.okf_type ?? null,\n });\n }\n\n let ontologyState = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n let { mode, manifest } = ontologyState;\n\n for (const { facts, ontology_updates } of orderedChunkFacts) {\n if (mode === 'emergent' && ontology_updates && this.ontologyService) {\n manifest = await this.ontologyService.mergeEmergentUpdates(entityId, ontology_updates, tx);\n ontologyState = await this.ontologyService.getEffectiveState(entityId, tx);\n mode = ontologyState.mode;\n }\n\n for (const fact of facts) {\n const ontologyFact = fact as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest)\n ?? { okf_type: null, edges: [] };\n\n const id = generateId('fact_');\n const wikiFact: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'immutable_document', source_hash: sourceHash, source_ref: sourceRef,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n okf_type: normalized.okf_type,\n };\n await this.entryRepo.upsert(wikiFact, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n\n titleIndex.set(normalizeTitleKey(fact.title), { id, okf_type: normalized.okf_type });\n\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n }\n\n for (const item of pendingEdges) {\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now,\n );\n }\n });\n\n await this.searchService.sync(entityId);\n\n const uniqueDeletedSourceFactIds = Array.from(new Set(deletedSourceFactIds));\n for (const factId of uniqueDeletedSourceFactIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during ingest for ${factId}:`, hookErr);\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n return { truncated, chunks: chunks.length };\n\n } finally {\n this.jobManager.releaseLock('ingest', entityId, sourceRef);\n }\n }\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","/**\n * Bounded LLM calls.\n *\n * Maintenance passes build prompts whose *response* size grows with corpus\n * size. Past a threshold the call fails permanently: every retry re-sends the\n * same oversized request, so there is no partial progress and no self-recovery.\n * Raising the host's token budget only postpones this — providers enforce a\n * hard output ceiling, and core cannot see it (`LLMProvider.generateText`\n * returns a bare string).\n *\n * `runBatched` owns batch sizing, failure detection, halve-and-retry splitting\n * and the skip decision. It knows nothing about facts, heal, or ontology — the\n * caller supplies the domain callbacks — so it is testable against a fake\n * `call` with no LLM and no database.\n */\n\n/**\n * Batch size when the provider declares no ceiling.\n *\n * Deliberately below ONTOLOGY_BACKFILL_BATCH_SIZE (25), a size already\n * observed to fail at a 9999-token ceiling. The absence of a hint must never\n * size *up*: starting large would make the split path do all the work, burning\n * API time and tokens on first attempts guaranteed to fail.\n */\nexport const DEFAULT_BATCH_SIZE = 10;\n\n/** Crude per-item output estimate. Its only job is to make the common case one\n * call rather than three; it is never trusted — the split path is always armed. */\nconst ESTIMATED_OUTPUT_TOKENS_PER_ITEM = 150;\n\n/** Headroom against the declared ceiling for preamble, JSON syntax, and the\n * estimate simply being wrong. */\nconst OUTPUT_BUDGET_FRACTION = 0.8;\n\nconst TRUNCATION_PATTERNS: RegExp[] = [\n /truncat/i,\n /token limit/i,\n /max(imum)?[ _-]?tokens?/i,\n /output limit/i,\n /length limit/i,\n /finish[_ ]?reason/i,\n];\n\n// A \"max tokens\" match paired with \"exceed(s)\" is a request-configuration\n// error (the caller asked for more than the model allows), not the provider\n// cutting a response short. Splitting the batch cannot fix it — the adapter\n// keeps requesting the same max tokens — so it must propagate instead of\n// being absorbed into a pile of skipped items.\nconst EXCEEDS_LIMIT_PATTERN = /exceed[a-z]*[^.]{0,40}\\b(model|context)?[ _-]?limit/i;\n\n/**\n * Whether a thrown error looks like the provider cut the response short.\n *\n * Core only sees a string or an Error, so this is string matching by\n * necessity. A false positive costs one wasted split; a false negative\n * propagates the error, which is the right outcome for a network or auth\n * failure that must not be silently absorbed into a pile of skipped items.\n */\nexport function isTruncationError(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err ?? '');\n if (EXCEEDS_LIMIT_PATTERN.test(message)) return false;\n return TRUNCATION_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport interface BuiltPrompt {\n systemPrompt: string;\n userPrompt: string;\n}\n\nexport interface RunBatchedArgs<TItem, TResult> {\n items: TItem[];\n /** May be async: heal selects anchors per batch via a search + repository read. */\n buildPrompt: (batch: TItem[]) => BuiltPrompt | Promise<BuiltPrompt>;\n call: (prompts: BuiltPrompt) => Promise<string>;\n /** Receives the batch so the caller can pair a response with the exact items\n * that produced it without this module knowing any domain shape. Throwing is\n * the signal that the response was unusable. */\n parse: (responseText: string, batch: TItem[]) => TResult;\n /** Provider output ceiling, when the host declares one. Sizing hint only. */\n maxOutputTokens?: number;\n /** Input bound, applied independently of output sizing. */\n maxPromptChars: number;\n /** Called once per skipped item, for operator-legible logging. */\n onSkip?: (item: TItem, err: unknown) => void;\n}\n\nexport interface RunBatchedOutcome<TItem, TResult> {\n results: TResult[];\n /** Items that failed even alone. Returned, never thrown. */\n skipped: TItem[];\n /** Number of `call` attempts made, including failed ones. */\n batches: number;\n}\n\nexport function initialBatchSize(maxOutputTokens?: number): number {\n if (!maxOutputTokens || !Number.isFinite(maxOutputTokens) || maxOutputTokens <= 0) {\n return DEFAULT_BATCH_SIZE;\n }\n const estimate = Math.floor(\n (maxOutputTokens * OUTPUT_BUDGET_FRACTION) / ESTIMATED_OUTPUT_TOKENS_PER_ITEM,\n );\n // Only ever sizes up. Sizing down from a declared ceiling is left to the\n // split path, which measures reality instead of guessing.\n return Math.max(DEFAULT_BATCH_SIZE, estimate);\n}\n\nconst promptLength = (prompts: BuiltPrompt): number =>\n prompts.systemPrompt.length + prompts.userPrompt.length;\n\nexport async function runBatched<TItem, TResult>(\n args: RunBatchedArgs<TItem, TResult>,\n): Promise<RunBatchedOutcome<TItem, TResult>> {\n const { items, buildPrompt, call, parse, maxPromptChars, maxOutputTokens, onSkip } = args;\n\n const results: TResult[] = [];\n const skipped: TItem[] = [];\n let batches = 0;\n\n /**\n * Sticky downward adaptation. Ratchets down on failure and never climbs back\n * up within a run: without it, a 1177-fact backlog rediscovers the same\n * ceiling on every batch. Deliberately *not* touched by maxPromptChars\n * trimming — one dense batch should not shrink every later batch.\n */\n let batchSize = initialBatchSize(maxOutputTokens);\n\n /**\n * Longest prefix of `candidate` whose built prompt fits `maxPromptChars`. A\n * single item that exceeds the cap alone is still sent: deferring it would\n * starve it forever.\n *\n * `buildPrompt` is not assumed cheap — heal runs a keyword search and a\n * repository read on every call — so the overflow path binary-searches the\n * prefix length instead of dropping one item at a time. The whole batch is\n * tried first, which keeps the common case (it fits) at exactly one call and\n * bounds the overflow case at ~log2(n) + 1 instead of n.\n *\n * Prompt length is treated as non-decreasing in prefix length. That is the\n * same assumption the one-at-a-time walk made by stopping at the first fit;\n * if it is ever violated the result is a slightly different batch size, never\n * a lost item, and the split path stays armed either way.\n */\n const trim = async (candidate: TItem[]): Promise<{ batch: TItem[]; prompts: BuiltPrompt }> => {\n const whole = await buildPrompt(candidate);\n if (candidate.length <= 1 || promptLength(whole) <= maxPromptChars) {\n return { batch: candidate, prompts: whole };\n }\n\n let low = 2;\n let high = candidate.length - 1; // the full length is known not to fit\n let best: TItem[] | undefined;\n let bestPrompts: BuiltPrompt | undefined;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const batch = candidate.slice(0, mid);\n const prompts = await buildPrompt(batch);\n if (promptLength(prompts) <= maxPromptChars) {\n best = batch;\n bestPrompts = prompts;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n if (best && bestPrompts) return { batch: best, prompts: bestPrompts };\n\n const single = candidate.slice(0, 1);\n return { batch: single, prompts: await buildPrompt(single) };\n };\n\n const onFailure = async (batch: TItem[], err: unknown): Promise<void> => {\n if (batch.length <= 1) {\n if (batch.length === 1) {\n skipped.push(batch[0]);\n onSkip?.(batch[0], err);\n }\n return;\n }\n const mid = Math.ceil(batch.length / 2);\n if (mid < batchSize) batchSize = mid;\n // Re-reads batchSize on every chunk rather than fixing it once: a nested\n // failure inside the first chunk can shrink batchSize further, and a later\n // chunk of this same batch must honor that smaller size too, not the size\n // this batch was split at before the shrink was discovered.\n //\n // Chunks go through `trim` rather than straight to `attempt`: a subset of a\n // trimmed batch is not automatically under maxPromptChars, because\n // buildPrompt is not required to be monotonic in batch size. Heal's is not\n // — it re-selects up to HEAL_MAX_ANCHORS anchors per batch, so a sub-batch\n // can match anchors the parent did not. Without this, the input bound held\n // only on first attempts.\n let i = 0;\n while (i < batch.length) {\n const size = Math.min(batchSize, batch.length - i);\n const trimmed = await trim(batch.slice(i, i + size));\n await attempt(trimmed.batch, trimmed.prompts);\n // trim always returns at least one item, so this advances.\n i += trimmed.batch.length;\n }\n };\n\n const attempt = async (batch: TItem[], prebuilt?: BuiltPrompt): Promise<void> => {\n if (batch.length === 0) return;\n const prompts = prebuilt ?? (await buildPrompt(batch));\n\n batches++;\n let responseText: string;\n try {\n responseText = await call(prompts);\n } catch (err) {\n // Only truncation-shaped failures are retryable by splitting. Anything\n // else (network, auth) is a real error and must surface.\n if (!isTruncationError(err)) throw err;\n await onFailure(batch, err);\n return;\n }\n\n let result: TResult;\n try {\n result = parse(responseText, batch);\n } catch (err) {\n // A response truncated mid-JSON surfaces here rather than as a thrown\n // call error, depending on where the cut landed in the grammar.\n await onFailure(batch, err);\n return;\n }\n\n results.push(result);\n };\n\n let index = 0;\n while (index < items.length) {\n const { batch, prompts } = await trim(items.slice(index, index + batchSize));\n index += batch.length;\n await attempt(batch, prompts);\n }\n\n return { results, skipped, batches };\n}\n","import { parseJsonResponse, validateFact, validateTask, titleTokens, jaccardScore, normalizeSourceRef, normalizeSourceHash, sanitizeRankerError } from '../utils/pure';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { PromptService } from './PromptService';\nimport type { OntologyService, TitleIndexEntry } from './OntologyService';\nimport { generateId } from '../utils/ids';\nimport { parseEmbedding } from '../utils/embedding';\nimport { PrunePartialFailureError } from '../types';\nimport { HOOK_TIMEOUT_MARKER } from '../types';\nimport type { WikiOptions, ExtractedFact, ExtractedFactEdge, ExtractedTask, ExtractedFactWithOntology, WikiFact, WikiTask, OntologyUpdates, OntologyBackfillResult } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport { entitySummaryMetaKey, type MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport type { JobManager } from './JobManager';\nimport type { EmbeddingService } from './EmbeddingService';\nimport { runBatched } from './BoundedLlmCall';\n\nconst FUZZY_THRESHOLD = 0.5;\nconst MIN_TOKENS_TO_QUALIFY = 3;\n\nexport const ONTOLOGY_BACKFILL_BATCH_SIZE = 25;\nexport const ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS = 40_000;\nexport const ONTOLOGY_BACKFILL_RECHECK_MS = 7 * 24 * 60 * 60 * 1000;\n\n/**\n * Anchors offered per heal call. Anchors exist only for contradiction\n * detection; on a document-heavy corpus they outnumbered the candidates the\n * model actually reasons about by ~80x and were the direct cause of #63.\n */\nexport const HEAL_MAX_ANCHORS = 50;\n\n/** Search hits requested before the immutable_document filter is applied.\n * Overfetched because the index holds every fact, not only anchors. */\nconst HEAL_ANCHOR_SEARCH_OVERFETCH = 4;\n\n/** Input bound for heal, mirroring ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS.\n * Independent of output batching: a small number of dense facts is still trimmed. */\nexport const HEAL_MAX_PROMPT_CHARS = 40_000;\n\n/** One parsed ontology-backfill response, paired with the facts that produced it. */\ninterface OntologyBackfillBatch {\n batch: WikiFact[];\n classifications: Array<{ id?: unknown; okf_type?: unknown; edges?: unknown }>;\n ontologyUpdates?: OntologyUpdates;\n}\n\n/** An immutable_document fact offered to heal purely for contradiction detection. */\ntype HealAnchor = { id: string; title: string; source_ref: string | null };\n\n/** One parsed heal response, paired with the candidates that produced it. */\ninterface HealBatch {\n batch: WikiFact[];\n downgraded: string[];\n deleted: string[];\n newFacts: ExtractedFact[];\n}\n\nexport class MaintenanceService {\n private promptService: PromptService;\n\n constructor(\n private db: SQLiteAdapter,\n private prefix: string,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\n private jobManager: JobManager,\n private embeddingService: EmbeddingService,\n promptService?: PromptService,\n private ontologyService?: OntologyService,\n ) {\n // Fallback for direct instantiation outside WikiMemory facade (e.g. isolated tests).\n this.promptService = promptService ?? new PromptService(this.options.config?.prompts);\n }\n\n async runPrune(entityId: string, options?: { retainSoftDeletedFor?: number | null; retainEventsFor?: number | null; vacuum?: boolean }): Promise<{ entries: number; tasks: number; events: number }> {\n this.jobManager.acquireLock('prune', entityId);\n\n try {\n const retainSoftDeletedFor = options?.retainSoftDeletedFor !== undefined ? options.retainSoftDeletedFor : (this.options.config?.pruneRetainSoftDeletedFor ?? 7);\n const retainEventsFor = options?.retainEventsFor !== undefined ? options.retainEventsFor : (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 const entriesToDelete = await this.entryRepo.getPrunableMetadata(entityId, cutoff);\n\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.embeddingService.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 const succeededIds = succeeded.map(r => r.id);\n\n await this.db.withTransactionAsync(async (tx) => {\n if (succeededIds.length > 0) {\n deletedEntries = await this.entryRepo.bulkDeletePruned(entityId, cutoff, succeededIds, tx);\n }\n deletedTasks = await this.taskRepo.bulkDeletePruned(entityId, cutoff, tx);\n });\n\n if (failure) {\n await this.searchService.sync(entityId);\n const remaining = entriesToDelete.length - succeeded.length - 1;\n const isTimeout = (failure.cause as any)?.[HOOK_TIMEOUT_MARKER] === true;\n\n if (isTimeout) {\n throw new PrunePartialFailureError(\n succeeded.length, failure.factId, remaining, new Error('Deletion hook timed out'), deletedTasks, 0\n );\n }\n\n const errMsg = (failure.cause as Error)?.message ?? '';\n const isValidationError = errMsg.startsWith('Invalid deletionHookTimeoutMs');\n const sanitizedCause = isValidationError ? failure.cause as Error : this._sanitizeRankerError(failure.cause);\n\n throw new PrunePartialFailureError(\n succeeded.length, failure.factId, remaining, sanitizedCause, deletedTasks, 0\n );\n }\n }\n\n if (retainEventsFor !== null) {\n const cutoff = now - retainEventsFor * 86400000;\n const eventResult = await this.eventRepo.prune(entityId, cutoff);\n deletedEvents = eventResult.changes;\n }\n\n if (vacuum) {\n await this.metadataRepo.vacuum();\n }\n\n await this.searchService.sync(entityId);\n return { entries: deletedEntries, tasks: deletedTasks, events: deletedEvents };\n } finally {\n this.jobManager.releaseLock('prune', entityId);\n }\n }\n\n async runLibrarian(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n this.jobManager.acquireLock('librarian', entityId);\n try {\n await this.doRunLibrarian(entityId, options?.promptOverride);\n } finally {\n this.jobManager.releaseLock('librarian', entityId);\n }\n }\n\n async runHeal(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n this.jobManager.acquireLock('heal', entityId);\n try {\n await this.doRunHeal(entityId, options?.promptOverride);\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n\n async runOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<OntologyBackfillResult> {\n this.jobManager.acquireLock('ontologyBackfill', entityId);\n try {\n return await this.doRunOntologyBackfill(entityId, options);\n } finally {\n this.jobManager.releaseLock('ontologyBackfill', 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 op = entityId ? 'reembed' : 'global_reembed';\n this.jobManager.acquireLock(op, entityId ?? '*');\n\n try {\n\n const rows = await this.entryRepo.findAllForReembed(entityId);\n this.searchService.evictCache(entityId);\n\n const skipExisting = opts?.skipExisting ?? false;\n let effectiveSkip = skipExisting;\n\n if (skipExisting) {\n const mismatchValue = await this.metadataRepo.getMeta('embedding_dimension_mismatch');\n if (mismatchValue) {\n if (entityId) {\n const mismatchDim = parseInt(mismatchValue, 10);\n const staleCount = await this.entryRepo.countStaleForEntity(entityId, mismatchDim);\n if (staleCount > 0) effectiveSkip = false;\n } else {\n effectiveSkip = false;\n }\n }\n }\n\n let embedded = 0;\n let skipped = 0;\n let failed = 0;\n\n try {\n for (const row of rows) {\n const existingBlob = (row as WikiFact & { embedding_blob?: Uint8Array | null }).embedding_blob;\n const blobIsValid = !!existingBlob && existingBlob.byteLength > 0 && existingBlob.byteLength % 4 === 0;\n\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\n const success = await this.embeddingService.embedFact(row);\n if (success) embedded++;\n else failed++;\n }\n\n if (embedded > 0) {\n await this.embeddingService.reconcileEmbeddingDimension();\n }\n } finally {\n this.searchService.evictCache(entityId);\n }\n\n return { embedded, skipped, failed };\n } finally {\n this.jobManager.releaseLock(op, 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 if (params.clearAll && (params.entryId !== undefined || params.taskId !== undefined || params.sourceRef !== undefined || params.sourceHash !== undefined)) {\n throw new Error('forget() clearAll is mutually exclusive with entryId, taskId, sourceRef, and sourceHash');\n }\n\n this.jobManager.acquireLock('forget', entityId);\n\n try {\n const now = Date.now();\n let deletedEntries = 0;\n let deletedTasks = 0;\n const deletedEntryIds: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n if (params.clearAll) {\n deletedEntryIds.push(...await this.entryRepo.findIdsBySource(entityId, null, null, tx, true));\n deletedEntries = await this.entryRepo.bulkSoftDeleteByEntityId(entityId, tx);\n deletedTasks = await this.taskRepo.bulkSoftDeleteByEntityId(entityId, tx);\n await this.metadataRepo.updateCheckpoint(entityId, { memory: 0, heal: 0 }, tx);\n await this.metadataRepo.deleteMeta(entitySummaryMetaKey(entityId), tx);\n } else {\n const hasIdSelectors = params.entryId !== undefined || params.taskId !== undefined;\n const hasSourceSelectors = params.sourceRef !== undefined || params.sourceHash !== undefined;\n\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\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 const entryId = await this.entryRepo.findIdById(params.entryId, entityId, tx);\n if (entryId) deletedEntryIds.push(entryId);\n }\n\n if (sourceRef || sourceHash) {\n deletedEntryIds.push(...await this.entryRepo.findIdsBySource(entityId, sourceRef, sourceHash, tx, true));\n }\n\n const entryPromise = params.entryId ? this.entryRepo.softDelete(params.entryId, entityId, tx).then(r => r.changes > 0) : null;\n const taskDeletedPromise = params.taskId ? this.taskRepo.softDeleteById(params.taskId, entityId, tx).then(r => r.changes > 0) : null;\n const refPromise = (sourceRef || sourceHash) ? this.entryRepo.softDeleteBySource(entityId, tx, sourceRef, sourceHash) : null;\n\n const [entryResult, taskResult, refResult] = await Promise.all([\n entryPromise ?? Promise.resolve(false),\n taskDeletedPromise ?? Promise.resolve(false),\n refPromise ?? Promise.resolve(0),\n ]);\n\n if (entryResult) deletedEntries++;\n if (taskResult) deletedTasks++;\n deletedEntries += refResult;\n }\n });\n\n await this.searchService.sync(entityId);\n\n const uniqueDeletedIds = Array.from(new Set(deletedEntryIds));\n for (const factId of uniqueDeletedIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersistedOrThrow(entityId, factId, null);\n } catch (hookErr) {\n const isTimeout = (hookErr as any)?.[HOOK_TIMEOUT_MARKER] === true;\n if (isTimeout) {\n throw new Error(`forget(${entityId}/${factId}) failed: ${(hookErr as Error).message}`);\n }\n const errMsg = (hookErr as Error)?.message ?? '';\n if (errMsg.startsWith('Invalid deletionHookTimeoutMs')) {\n throw new Error(`forget(${entityId}/${factId}) failed: ${errMsg}`, { cause: hookErr });\n }\n throw new Error(`forget(${entityId}/${factId}) failed: ANN cleanup hook rejected`, { cause: this._sanitizeRankerError(hookErr) });\n }\n }\n\n return { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.jobManager.releaseLock('forget', entityId);\n }\n }\n\n /** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */\n async doRunLibrarian(entityId: string, promptOverride?: string): Promise<void> {\n const events = await this.eventRepo.getRecent(entityId, 50);\n const currentFactsRows = await this.entryRepo.findRecentByEntityId(entityId, 100);\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 ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n\n const { systemPrompt, userPrompt } = this.promptService.buildLibrarianPrompt(\n events.reverse(),\n currentFacts,\n promptOverride,\n ontologyContext,\n );\n\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n\n const result = parseJsonResponse<{\n facts: ExtractedFact[];\n tasks: ExtractedTask[];\n ontology_updates?: OntologyUpdates;\n }>(responseText);\n const facts = Array.isArray(result.facts) ? result.facts : [];\n const tasks = Array.isArray(result.tasks) ? result.tasks : [];\n const ontologyUpdates = result.ontology_updates;\n\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 const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n let { mode, manifest } = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n\n if (mode === 'emergent' && ontologyUpdates && this.ontologyService) {\n manifest = await this.ontologyService.mergeEmergentUpdates(entityId, ontologyUpdates, tx);\n }\n\n const titleIndex = new Map<string, TitleIndexEntry>();\n for (const existing of currentFactsRows) {\n titleIndex.set(normalizeTitleKey(existing.title), {\n id: existing.id,\n okf_type: existing.okf_type ?? null,\n });\n }\n\n const factsForDedupe = await this.entryRepo.findRecentByEntityId(entityId, 100, tx);\n\n const pendingEdges: Array<{\n sourceId: string;\n sourceType: string | null;\n edges: ExtractedFactWithOntology['edges'];\n }> = [];\n\n for (const fact of validFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of factsForDedupe) {\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\n if (skip) continue;\n\n const ontologyFact = fact as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest)\n ?? { okf_type: null, edges: [] };\n\n const id = generateId('fact_');\n const factObj: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'librarian_inferred', source_hash: null, source_ref: null,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n okf_type: normalized.okf_type,\n };\n\n await this.entryRepo.upsert(factObj, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n factsForDedupe.push(factObj);\n\n titleIndex.set(normalizeTitleKey(fact.title), { id, okf_type: normalized.okf_type });\n\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n\n for (const item of pendingEdges) {\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now,\n );\n }\n\n for (const task of validTasks) {\n const id = generateId('task_');\n const taskObj: WikiTask = {\n id, entity_id: entityId, description: task.description, status: 'pending', priority: task.priority,\n created_at: now, updated_at: now, resolved_at: null, deleted_at: null\n };\n await this.taskRepo.upsert(taskObj, tx);\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /** Core heal pass (locks handled by {@link runHeal}). Package-internal orchestration hook. */\n async doRunHeal(entityId: string, promptOverride?: 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 const orphanedIds: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n if (orphanAfterDays !== null) {\n const orphanThreshold = now - (orphanAfterDays * MS_PER_DAY);\n orphanedIds.push(...await this.entryRepo.markOrphaned(entityId, orphanThreshold, tx));\n }\n if (staleInferredAfterDays !== null) {\n const staleThreshold = now - (staleInferredAfterDays * MS_PER_DAY);\n await this.entryRepo.downgradeStaleInferred(entityId, staleThreshold, tx);\n }\n });\n\n for (const factId of orphanedIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal orphan pass for ${factId}:`, hookErr);\n }\n }\n\n const healCandidates = await this.entryRepo.findHealCandidatesByEntityId(entityId);\n const allTasks = await this.taskRepo.findAllPending([entityId]);\n const recentEvents = await this.eventRepo.getRecent(entityId, 20);\n\n const toPromptShape = (f: WikiFact) => {\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 };\n\n // Anchor selection costs a keyword search plus a repository read, and\n // runBatched calls buildPrompt more than once per batch it actually sends —\n // while trimming to maxPromptChars, and again for each half when a batch is\n // split. Prefixes recur heavily across those paths, so memoizing by the\n // query the batch produces collapses the repeats. Scoped to this pass: the\n // index and the anchor rows can both change between heal runs.\n const anchorCache = new Map<string, HealAnchor[]>();\n\n const outcome = await runBatched<WikiFact, HealBatch>({\n items: healCandidates,\n buildPrompt: async (batch) => {\n const documentAnchors = await this._selectHealAnchors(entityId, batch, anchorCache);\n return this.promptService.buildHealPrompt(\n batch.map(toPromptShape),\n documentAnchors,\n allTasks,\n recentEvents,\n promptOverride,\n );\n },\n call: (prompts) => this.options.llmProvider.generateText(prompts),\n parse: (responseText, batch) => {\n const result = parseJsonResponse<{ downgraded: string[], deleted: string[], newFacts: ExtractedFact[] }>(responseText);\n return {\n batch,\n downgraded: Array.isArray(result.downgraded) ? result.downgraded : [],\n deleted: Array.isArray(result.deleted) ? result.deleted : [],\n newFacts: Array.isArray(result.newFacts) ? result.newFacts : [],\n };\n },\n maxOutputTokens: this.options.llmProvider.maxOutputTokens,\n maxPromptChars: HEAL_MAX_PROMPT_CHARS,\n onSkip: (fact, err) => {\n console.warn(\n `[WikiMemory] heal skipped ${entityId}/${fact.id}: response could not be bounded`,\n err,\n );\n },\n });\n\n // The mutable-ids guard is per batch: the model may only act on the\n // candidates it was actually offered in the call that produced the output.\n const safeDowngradedSet = new Set<string>();\n const safeDeletedSet = new Set<string>();\n const newFacts: ExtractedFact[] = [];\n\n for (const batchResult of outcome.results) {\n const mutableIds = new Set(batchResult.batch.map(f => f.id));\n for (const id of batchResult.downgraded) if (mutableIds.has(id)) safeDowngradedSet.add(id);\n for (const id of batchResult.deleted) if (mutableIds.has(id)) safeDeletedSet.add(id);\n newFacts.push(...batchResult.newFacts);\n }\n\n const safeDowngraded = Array.from(safeDowngradedSet);\n const safeDeleted = Array.from(safeDeletedSet);\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 const healFactsForDedupe = [...healCandidates];\n\n await this.db.withTransactionAsync(async (tx) => {\n await this.entryRepo.downgradeByIds(safeDowngraded, entityId, tx);\n await this.entryRepo.softDeleteByIds(safeDeleted, entityId, tx);\n\n for (const fact of validNewFacts) {\n const newTokens = titleTokens(fact.title);\n let skip = false;\n\n if (newTokens.size >= MIN_TOKENS_TO_QUALIFY) {\n for (const existing of healFactsForDedupe) {\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\n if (skip) continue;\n\n const id = generateId('fact_');\n const factObj: WikiFact = {\n id, entity_id: entityId, title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n source_type: 'librarian_inferred', source_hash: null, source_ref: null,\n created_at: now, updated_at: now, last_accessed_at: null, access_count: 0, deleted_at: null,\n };\n\n await this.entryRepo.upsert(factObj, tx);\n insertedFacts.push({ id, entity_id: entityId, title: fact.title, body: fact.body, tags: JSON.stringify(fact.tags) });\n healFactsForDedupe.push(factObj);\n }\n });\n\n await this.searchService.sync(entityId);\n\n for (const factId of uniqueDeletedFactIds) {\n try {\n await this.embeddingService.notifyEmbeddingPersisted(entityId, factId, null);\n } catch (hookErr) {\n console.warn(`[WikiMemory] onEmbeddingPersisted hook failed during heal for ${factId}:`, hookErr);\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact);\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /** Core ontology backfill pass (locks handled by {@link runOntologyBackfill}). Package-internal orchestration hook. */\n async doRunOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<OntologyBackfillResult> {\n const batchSize = options?.batchSize ?? ONTOLOGY_BACKFILL_BATCH_SIZE;\n if (!Number.isInteger(batchSize) || batchSize < 1) {\n throw new Error('Invalid batchSize: must be an integer >= 1');\n }\n\n const now = Date.now();\n const recheckCutoff = now - ONTOLOGY_BACKFILL_RECHECK_MS;\n const zeroed = { scanned: 0, typed: 0, failedValidation: 0, edgesAdded: 0, skipped: 0 };\n\n const ontologyService = this.ontologyService;\n if (!ontologyService) {\n return { ...zeroed, remaining: 0, deferred: 0 };\n }\n\n const { mode } = await ontologyService.getEffectiveState(entityId);\n if (mode === 'off') {\n // remaining stays 0: with ontology off nothing is eligible for typing, and\n // a host convergence loop (while remaining > 0) must terminate.\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { ...zeroed, remaining: 0, deferred: counts.deferred };\n }\n\n const candidates = await this.entryRepo.findUntypedByEntityId(entityId, batchSize, recheckCutoff);\n if (candidates.length === 0) {\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return { ...zeroed, remaining: counts.eligible, deferred: counts.deferred };\n }\n\n const ontologyContext = await ontologyService.buildPromptContext(entityId);\n\n // Payload guard: cap the full serialized prompt (system + user — manifest,\n // ids, tags, JSON syntax, overrides all counted) so dense facts cannot blow\n // a provider's context window. A single fact whose prompt alone exceeds the\n // cap is still sent by itself: deferring it would just re-defer forever and\n // starve it (spec Decision 2). Output size is bounded separately, by\n // runBatched — the two bounds are independent and both enforced.\n const toPromptShape = (f: WikiFact) => ({ id: f.id, title: f.title, body: f.body, tags: f.tags });\n const buildPrompt = (facts: WikiFact[]) => this.promptService.buildOntologyBackfillPrompt(\n facts.map(toPromptShape),\n options?.promptOverride,\n ontologyContext,\n );\n\n const outcome = await runBatched<WikiFact, OntologyBackfillBatch>({\n items: candidates,\n buildPrompt,\n call: (prompts) => this.options.llmProvider.generateText(prompts),\n parse: (responseText, batch) => {\n const parsed = parseJsonResponse<{\n classifications?: Array<{ id?: unknown; okf_type?: unknown; edges?: unknown }>;\n ontology_updates?: OntologyUpdates;\n }>(responseText);\n return {\n batch,\n classifications: Array.isArray(parsed.classifications) ? parsed.classifications : [],\n ontologyUpdates: parsed.ontology_updates,\n };\n },\n maxOutputTokens: this.options.llmProvider.maxOutputTokens,\n maxPromptChars: ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS,\n onSkip: (fact, err) => {\n console.warn(\n `[WikiMemory] ontology backfill skipped ${entityId}/${fact.id}: response could not be bounded`,\n err,\n );\n },\n });\n\n let typed = 0;\n let failedValidation = 0;\n let edgesAdded = 0;\n let scanned = 0;\n let abortedOntologyOff = false;\n\n for (const batchResult of outcome.results) {\n const applied = await this._applyOntologyBackfillBatch(entityId, batchResult, now);\n if (applied.abortedOntologyOff) {\n abortedOntologyOff = true;\n break;\n }\n typed += applied.typed;\n failedValidation += applied.failedValidation;\n edgesAdded += applied.edgesAdded;\n scanned += batchResult.batch.length;\n }\n\n if (abortedOntologyOff) {\n // remaining stays 0 so a host convergence loop (while remaining > 0)\n // still terminates, mirroring the mode === 'off' early path.\n //\n // The counters are NOT zeroed. A pass is now many transactions, so\n // batches applied before the flip are already committed — facts typed,\n // edges persisted, cooldowns stamped. Reporting zeros here would tell the\n // caller nothing happened while the database says otherwise. Only the\n // aborting batch and everything after it are dropped, and those wrote\n // nothing: the abort check runs before any write in the batch's\n // transaction.\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return {\n scanned,\n typed,\n failedValidation,\n edgesAdded,\n skipped: outcome.skipped.length,\n remaining: 0,\n deferred: counts.deferred,\n };\n }\n\n // Skipped facts get the same cooldown stamp as processed ones. Without it\n // they stay at the head of the updated_at ASC queue and every later pass\n // re-attempts them first, starving everything behind them.\n if (outcome.skipped.length > 0) {\n await this.entryRepo.markOntologyChecked(outcome.skipped.map(f => f.id), entityId, now, this.db);\n }\n\n this.searchService.evictCache(entityId);\n\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n return {\n scanned,\n typed,\n failedValidation,\n edgesAdded,\n skipped: outcome.skipped.length,\n remaining: counts.eligible,\n deferred: counts.deferred,\n };\n }\n\n /**\n * Applies one parsed backfill batch in its own transaction. Per-batch rather\n * than one transaction for the pass, so mergeEmergentUpdates semantics and\n * the mid-flight `mode === 'off'` abort check keep the shape they had when a\n * pass was a single call.\n */\n private async _applyOntologyBackfillBatch(\n entityId: string,\n batchResult: OntologyBackfillBatch,\n now: number,\n ): Promise<{ typed: number; failedValidation: number; edgesAdded: number; abortedOntologyOff: boolean }> {\n const ontologyService = this.ontologyService!;\n const { batch, classifications, ontologyUpdates } = batchResult;\n\n let typed = 0;\n let failedValidation = 0;\n let edgesAdded = 0;\n let abortedOntologyOff = false;\n\n await this.db.withTransactionAsync(async (tx) => {\n let { mode: txMode, manifest } = await ontologyService.getEffectiveState(entityId, tx);\n\n // setOntologyManifest is not under this job lock, so ontology can be\n // disabled while generateText was in flight. Abort without typing facts\n // or stamping cooldowns.\n if (txMode === 'off') {\n abortedOntologyOff = true;\n return;\n }\n\n if (txMode === 'emergent' && ontologyUpdates) {\n manifest = await ontologyService.mergeEmergentUpdates(entityId, ontologyUpdates, tx);\n }\n\n // Full breadth, three columns only: an old fact's edge targets are its\n // contemporaries, which a recent-100 window would silently miss.\n const titleRows = await this.entryRepo.findTitleIndexByEntityId(entityId, tx);\n const titleIndex = new Map<string, TitleIndexEntry>();\n for (const row of titleRows) {\n titleIndex.set(normalizeTitleKey(row.title), { id: row.id, okf_type: row.okf_type });\n }\n\n const batchById = new Map(batch.map(f => [f.id, f]));\n const applied = new Set<string>();\n const pendingEdges: Array<{ sourceId: string; sourceType: string; edges: ExtractedFactEdge[] }> = [];\n\n for (const classification of classifications) {\n const fact = typeof classification.id === 'string' ? batchById.get(classification.id) : undefined;\n if (!fact || applied.has(fact.id)) {\n failedValidation++;\n continue;\n }\n applied.add(fact.id);\n\n const normalized = ontologyService.validateAndNormalizeFact(\n {\n title: fact.title, body: fact.body, tags: fact.tags, confidence: fact.confidence,\n okf_type: classification.okf_type as string | undefined, edges: classification.edges as ExtractedFactEdge[] | undefined,\n } as ExtractedFactWithOntology,\n manifest,\n );\n if (!normalized.okf_type) {\n failedValidation++;\n continue;\n }\n\n const result = await this.entryRepo.updateOkfType(fact.id, entityId, normalized.okf_type, tx);\n // changes === 0 → typed concurrently between select and update; the\n // okf_type IS NULL guard left it untouched. Counted as an omission.\n if (result.changes === 0) continue;\n\n typed++;\n titleIndex.set(normalizeTitleKey(fact.title), { id: fact.id, okf_type: normalized.okf_type });\n if (normalized.edges.length > 0) {\n pendingEdges.push({ sourceId: fact.id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n\n // Two-phase: edges resolve only after every batch fact has its new type,\n // so intra-batch targets pass the target-type check.\n for (const item of pendingEdges) {\n edgesAdded += await ontologyService.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges, manifest, titleIndex, tx, now,\n );\n }\n\n await this.entryRepo.markOntologyChecked(batch.map(f => f.id), entityId, now, tx);\n });\n\n return { typed, failedValidation, edgesAdded, abortedOntologyOff };\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 /**\n * Anchors relevant to one batch of heal candidates.\n *\n * Heal used to pass every immutable_document fact for the entity — 2560 rows\n * against 31 candidates on the corpus behind #63 — which is what blew the\n * output ceiling. Anchors are now retrieved by keyword relevance to the batch\n * and capped.\n *\n * The MiniSearch index holds all facts, not only anchors, so hits are\n * overfetched and the source_type restriction is applied after retrieval, in\n * SQL. Search rank order is preserved through the filter.\n *\n * Accepted tradeoff: an anchor that contradicts a candidate while sharing no\n * vocabulary with it is now missed. Exhaustive-but-broken traded for\n * relevance-scoped-and-working.\n *\n * `cache` is keyed by the derived query rather than by the batch, so two\n * batches that reduce to the same query share one lookup. Caller-owned and\n * per-pass — see the call site in doRunHeal.\n */\n private async _selectHealAnchors(\n entityId: string,\n batch: WikiFact[],\n cache?: Map<string, HealAnchor[]>,\n ): Promise<HealAnchor[]> {\n const query = batch.map(f => f.title).join(' ').trim();\n if (!query) return [];\n\n const cached = cache?.get(query);\n if (cached) return cached;\n\n const hits = this.searchService.searchKeyword(\n query,\n [entityId],\n HEAL_MAX_ANCHORS * HEAL_ANCHOR_SEARCH_OVERFETCH,\n );\n const hitIds = hits.map(h => h.id as string);\n\n const anchors: HealAnchor[] = [];\n if (hitIds.length > 0) {\n const rows = await this.entryRepo.findAnchorRowsByIds(entityId, hitIds);\n const byId = new Map(rows.map(r => [r.id, r]));\n\n for (const id of hitIds) {\n const row = byId.get(id);\n if (!row) continue;\n anchors.push(row);\n if (anchors.length >= HEAL_MAX_ANCHORS) break;\n }\n }\n\n // Cached even when empty: a query that matched nothing still cost a search,\n // and the trim and split paths will ask for it again.\n cache?.set(query, anchors);\n return anchors;\n }\n\n private _sanitizeRankerError(err: unknown): Error {\n return sanitizeRankerError(err, this.options.sanitizeRankerErrors);\n }\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 type { WikiOptions, MemoryBundle, WikiFact, ReadOptions } from '../types';\nimport { EntryRepository, EntryRowMetadata, EntryRowWithEmbeddings } from '../repositories/EntryRepository';\nimport type { TaskRepository } from '../repositories/TaskRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { SearchService } from './SearchService';\nimport { applyTierWeight, normalizeEntityIds, sanitizeTierWeights, shouldExposeReadMetadata } from '../readOptions';\nimport { sanitizeRankerError } from '../utils/pure';\n\ntype ReadCandidateRowMetadata = EntryRowMetadata;\ntype ReadCandidateRowWithEmbeddings = EntryRowWithEmbeddings;\n\nexport class RetrievalService {\n constructor(\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private taskRepo: TaskRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private searchService: SearchService,\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 = shouldExposeReadMetadata(entityId)\n ? sanitizeTierWeights(entityIds, options?.tierWeights)\n : undefined;\n const exposeMetadata = shouldExposeReadMetadata(entityId);\n\n if (entityIds.length === 0) {\n const empty: MemoryBundle = { facts: [], tasks: [], events: [], edges: [] };\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 storedDimValue = await this.metadataRepo.getMeta('embedding_dimension');\n if (storedDimValue) {\n const storedDim = parseInt(storedDimValue, 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 scored entity has a blob whose\n // dimension differs from the query vector. Uses scoredEntityIds so zero-weight\n // (skipped) entities with stale embeddings do not force keyword fallback.\n const mismatchedCount = await this.entryRepo.countDimensionMismatched(scoredEntityIds, queryVec.length);\n if (mismatchedCount > 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 preResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, Number.MAX_SAFE_INTEGER);\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 if (useRanker) {\n candidateRows = await this.entryRepo.findMetadataByIds(topKIds);\n } else {\n candidateRows = await this.entryRepo.findWithEmbeddingsByIds(topKIds);\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 candidateRows = await this.entryRepo.findMetadataByEntityIds(scoredEntityIds);\n } else {\n candidateRows = await this.entryRepo.findWithEmbeddingsByEntityIds(scoredEntityIds);\n }\n // Collect MiniSearch scores for hybrid blend if weight is set and <1\n if (weight !== undefined && weight < 1) {\n miniSearchScores = this.searchService.getMiniSearchScores(trimmedQuery, scoredEntityIds);\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 embeddingRows = await this.entryRepo.findEmbeddingsByIds(rowIds);\n const embeddingsMap = new Map(embeddingRows.map(row => [row.id, row]));\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.searchService.rankSemantic({\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 keywordOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const topResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, 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.searchService.rankSemantic({\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 fallbackOversampledLimit = Math.max(maxResults * 2, maxResults + 50);\n const results = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, fallbackOversampledLimit);\n const candidates = results.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 await this.entryRepo.trackAccess(ids, now);\n }\n } else {\n // Empty query: use global recency ordering, ignore tier weights.\n facts = await this.entryRepo.findRecentByEntityIds(entityIds, maxResults);\n }\n\n const eventsLimit = Math.min(10 * entityIds.length, 100);\n const [tasks, events] = await Promise.all([\n this.taskRepo.findAllPending(entityIds as string[], entityIds.length === 1 ? undefined : Math.min(20 * entityIds.length, 200)),\n entityIds.length === 1\n ? this.eventRepo.getRecent(entityIds[0], eventsLimit)\n : this.eventRepo.getRecentForEntities(entityIds as string[], eventsLimit),\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(), edges: [] };\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 * 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[], tx?: SQLiteAdapter): Promise<WikiFact[]> {\n return this.entryRepo.findByIds(ids, scopedEntityIds, tx);\n }\n\n private _sanitizeRankerError(err: unknown): Error {\n return sanitizeRankerError(err, this.options.sanitizeRankerErrors);\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","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","import MiniSearch, { SearchResult } from 'minisearch';\nimport { EntryRepository } from '../repositories/EntryRepository';\nimport { cosineSimilarity } from '../utils/cosine';\nimport { parseEmbedding } from '../utils/embedding';\n\nexport interface ScoredRow {\n id: string;\n entity_id: string;\n score: number;\n updated_at: number | null;\n access_count: number | null;\n}\n\nexport interface RankSemanticArgs {\n entityId: string;\n queryVec: Float32Array | number[];\n candidateRows: Array<{\n id: string;\n entity_id: string;\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n updated_at: number | null;\n access_count: number | null;\n }>;\n weight: number | undefined;\n miniSearchScores: Map<string, number> | undefined;\n populateCache: boolean;\n limit: number;\n skipSort?: boolean;\n}\n\nexport class SearchService {\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 /**\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\n private miniSearch: MiniSearch<{ id: string; entity_id: string; title: string; body: string; tags: string }>;\n private miniSearchEntryIdsByEntity = new Map<string, Set<string>>();\n private vectorCache: Map<string, Map<string, Float32Array>> = new Map();\n\n /**\n * Serializes rebuilds. `rebuildIndex` awaits a repository read between\n * snapshotting the previous id set and discarding it, so two concurrent\n * sync() calls for one entity can interleave: a slow, stale read lands last\n * and discards documents the fresh read just added. Chaining also keeps\n * discard()/addAll() out of each other's way, which is what accrued the\n * auto-vacuum debt behind the TypeError in #64.\n */\n private syncChain: Promise<void> = Promise.resolve();\n\n constructor(private entryRepo: EntryRepository) {\n this.miniSearch = new MiniSearch({\n fields: ['title', 'body', 'tags'],\n storeFields: ['entity_id'],\n // Vacuuming is driven explicitly at the end of each serialized rebuild\n // (see sync). Auto-vacuum fires on its own schedule, asynchronously with\n // respect to the caller, and traversing the tree mid-rebuild is what\n // threw the uncaught TypeError in MiniSearch.performVacuuming (#64).\n autoVacuum: false,\n searchOptions: {\n boost: { title: 2 },\n fuzzy: 0.2,\n prefix: true,\n },\n });\n }\n\n /**\n * Rebuilds the search index and clears the vector cache for a given entity.\n * A direct replacement for manually syncing state after a DB transaction.\n *\n * Rebuilds are serialized per instance and never reject: the MiniSearch index\n * is a rebuildable cache over SQLite, so degraded keyword search is the\n * correct failure mode and killing the host process is not.\n */\n async sync(entityId?: string): Promise<void> {\n const work = this.syncChain.then(async () => {\n try {\n // evictCache is inside the guard, not after it: a throw escaping here\n // would reject `work`, and since the next sync() chains off `work`,\n // every later rebuild would reject too — the poisoned-chain form of\n // exactly the unhandled rejection this method exists to prevent. The\n // inner finally keeps eviction unconditional, as it was before.\n try {\n await this.rebuildIndex(entityId);\n await this.miniSearch.vacuum();\n } finally {\n this.evictCache(entityId);\n }\n } catch (err) {\n console.warn(`[WikiMemory] search index rebuild failed for ${entityId ?? '*'}:`, err);\n }\n });\n this.syncChain = work;\n return work;\n }\n\n /**\n * Clears the parsed vector cache. Useful for mid-loop flush guarantees\n * or memory pressure evictions.\n */\n evictCache(entityId?: string): void {\n if (entityId) {\n this.vectorCache.delete(entityId);\n } else {\n this.vectorCache.clear();\n }\n }\n\n /**\n * Fully resets the search service.\n */\n clearAll(): void {\n this.vectorCache.clear();\n this.miniSearch.removeAll();\n this.miniSearchEntryIdsByEntity.clear();\n }\n\n /**\n * Executes a keyword search against the active MiniSearch index.\n */\n searchKeyword(query: string, entityIds: string[], limit: number): SearchResult[] {\n const entityIdSet = new Set(entityIds);\n const results = this.miniSearch.search(query, {\n filter: (r) => entityIdSet.has(r.entity_id as string),\n combineWith: 'OR',\n });\n return results.slice(0, limit);\n }\n\n /**\n * Pre-fetches MiniSearch scores for candidate hydration, used during hybrid weighting.\n */\n getMiniSearchScores(query: string, entityIds: string[], preFilterLimit?: number): Map<string, number> {\n const entityIdSet = new Set(entityIds);\n let results = this.miniSearch.search(query, {\n filter: (r) => entityIdSet.has(r.entity_id as string),\n combineWith: 'OR',\n });\n\n if (preFilterLimit !== undefined) {\n results = results.slice(0, preFilterLimit);\n }\n\n if (results.length === 0) return new Map();\n\n const maxMsScore = Math.max(1, results[0]?.score ?? 1);\n return new Map(results.map((r) => [r.id, r.score / maxMsScore]));\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 async rankSemantic(args: RankSemanticArgs): Promise<ScoredRow[]> {\n const queryVec = args.queryVec instanceof Float32Array ? args.queryVec.slice() : Array.from(args.queryVec);\n const { entityId, candidateRows, weight, miniSearchScores, populateCache, limit, skipSort } = args;\n\n let entityCache = this.vectorCache.get(entityId);\n const tooLarge = populateCache && candidateRows.length > SearchService.MAX_VECTOR_CACHE_FACTS_PER_ENTITY;\n\n if (tooLarge && entityCache) {\n this.vectorCache.delete(entityId);\n entityCache = undefined;\n }\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\n if (vector && canCache && entityCache && !entityCache.has(row.id)) {\n entityCache.set(row.id, vector);\n }\n\n let score = 0;\n if (vector && vector.length === queryVec.length) {\n const cosSim = cosineSimilarity(queryVec, vector);\n if (weight !== undefined) {\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 const kwScore = miniSearchScores?.get(row.id) ?? 0;\n score = (1 - weight) * kwScore;\n } else {\n score = -2;\n }\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 if (this.vectorCache.size >= SearchService.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 if (!skipSort) {\n this._tieBreakSort(scored);\n }\n\n return scored.slice(0, limit);\n }\n\n // --- Internal Index Management ---\n\n private async rebuildIndex(entityId?: string): Promise<void> {\n if (entityId) {\n const rows = await this.entryRepo.findMiniSearchRows(entityId);\n const previousIds = this.miniSearchEntryIdsByEntity.get(entityId);\n\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(\n entityId,\n new Set(documents.map((document) => document.id))\n );\n return;\n }\n\n const rows = await this.entryRepo.findMiniSearchRows();\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 normalizeMiniSearchRow(row: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n 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 _tieBreakSort(items: ScoredRow[]): void {\n items.sort((a, b) => this._compareScoredRows(a, b));\n }\n\n private _compareScoredRows(a: ScoredRow, b: ScoredRow): number {\n const scoreDiff = b.score - a.score;\n if (!Number.isNaN(scoreDiff) && scoreDiff !== 0) return scoreDiff;\n\n const accessCountDiff = (b.access_count ?? 0) - (a.access_count ?? 0);\n if (accessCountDiff !== 0) return accessCountDiff;\n\n const updatedAtDiff = (b.updated_at ?? 0) - (a.updated_at ?? 0);\n if (updatedAtDiff !== 0) return updatedAtDiff;\n\n return a.id.localeCompare(b.id);\n }\n}\n","import { EntityStatus, WikiBusyError, WikiBusyOperation } from '../types';\n\nexport type OperationType =\n | 'prune'\n | 'librarian'\n | 'heal'\n | 'ingest'\n | 'reembed'\n | 'global_reembed'\n | 'import'\n | 'global_import'\n | 'forget'\n | 'ontologyBackfill';\n\nexport class JobManager {\n private activeMaintenanceJobs = new Set<string>();\n private activeIngestJobs = new Map<string, Set<string>>();\n private statusSubscribers = new Map<\n string,\n Set<{ callback: (s: EntityStatus) => void; last: EntityStatus }>\n >();\n\n constructor(private prefix: string) {}\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 _librarianKey(entityId: string) { return `${this.prefix}:${entityId}:librarian`; }\n private _healKey(entityId: string) { return `${this.prefix}:${entityId}:heal`; }\n private _ontologyBackfillKey(entityId: string) { return `${this.prefix}:${entityId}:ontologyBackfill`; }\n\n /**\n * Lookup table for acquireLock/releaseLock's dynamic-dispatch branch.\n * Excludes 'ingest' | 'global_reembed' | 'global_import', which those\n * methods already handle via explicit if/else branches before reaching\n * this table.\n */\n private readonly lockKeyFns: Record<\n Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>,\n (entityId: string) => string\n > = {\n prune: (id) => this._pruneKey(id),\n librarian: (id) => this._librarianKey(id),\n heal: (id) => this._healKey(id),\n reembed: (id) => this._reembedKey(id),\n import: (id) => this._importKey(id),\n forget: (id) => this._forgetKey(id),\n ontologyBackfill: (id) => this._ontologyBackfillKey(id),\n };\n\n private _isReembedActive(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalReembedKey());\n }\n\n private _isImportActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._importKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalImportKey());\n }\n\n private _isForgetActiveFor(entityId: string): boolean {\n return this.activeMaintenanceJobs.has(this._forgetKey(entityId));\n }\n\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\n private _hasIngestJob(entityId: string, sourceRef?: string): boolean {\n return this.activeIngestJobs.get(entityId)?.has(sourceRef ?? '') ?? false;\n }\n\n private _addIngestJob(entityId: string, sourceRef?: string): void {\n const sourceKey = sourceRef ?? '';\n let refs = this.activeIngestJobs.get(entityId);\n if (!refs) {\n refs = new Set<string>();\n this.activeIngestJobs.set(entityId, refs);\n }\n refs.add(sourceKey);\n }\n\n private _removeIngestJob(entityId: string, sourceRef?: string): void {\n const sourceKey = sourceRef ?? '';\n const refs = this.activeIngestJobs.get(entityId);\n if (!refs) return;\n refs.delete(sourceKey);\n if (refs.size === 0) {\n this.activeIngestJobs.delete(entityId);\n }\n }\n\n private _isIngestActiveFor(entityId: string): boolean {\n return this.activeIngestJobs.has(entityId);\n }\n\n acquireLock(operation: OperationType, entityId: string, sourceRef?: string): void {\n let blockingOperation: WikiBusyOperation | null = null;\n\n if (operation !== 'global_import' && this.activeMaintenanceJobs.has(this._globalImportKey())) {\n throw new WikiBusyError('import', '*');\n }\n\n switch (operation) {\n case 'prune':\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n\n case 'librarian':\n case 'heal':\n case 'ontologyBackfill': {\n const opKey = this.lockKeyFns[operation](entityId);\n if (this.activeMaintenanceJobs.has(opKey)) blockingOperation = operation;\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n\n case 'reembed':\n if (this.activeMaintenanceJobs.has(this._reembedKey(entityId))) blockingOperation = 'reembed';\n else if (this.activeMaintenanceJobs.has(this._globalReembedKey())) blockingOperation = 'reembed';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n\n case 'global_reembed':\n if (this.activeMaintenanceJobs.has(this._globalReembedKey())) blockingOperation = 'reembed';\n else if (this._isAnyMaintenanceActiveWithSuffix(':reembed')) blockingOperation = 'reembed';\n else if (this._isAnyMaintenanceActiveWithSuffix(':prune')) blockingOperation = 'prune';\n else if (this._isAnyMaintenanceActiveWithSuffix(':librarian')) blockingOperation = 'librarian';\n else if (this._isAnyMaintenanceActiveWithSuffix(':heal')) blockingOperation = 'heal';\n else if (this._isAnyMaintenanceActiveWithSuffix(':ontologyBackfill')) blockingOperation = 'ontologyBackfill';\n else if (this.activeIngestJobs.size > 0) blockingOperation = 'ingest';\n else if (this._isAnyMaintenanceActiveWithSuffix(':import')) blockingOperation = 'import';\n else if (this._isAnyMaintenanceActiveWithSuffix(':forget')) blockingOperation = 'forget';\n break;\n\n case 'import':\n case 'forget': {\n const selfKey = operation === 'import' ? this._importKey(entityId) : this._forgetKey(entityId);\n if (this.activeMaintenanceJobs.has(selfKey)) blockingOperation = operation;\n else if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) blockingOperation = 'librarian';\n else if (this.activeMaintenanceJobs.has(this._healKey(entityId))) blockingOperation = 'heal';\n else if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) blockingOperation = 'ontologyBackfill';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isIngestActiveFor(entityId)) blockingOperation = 'ingest';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n\n case 'global_import':\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) blockingOperation = 'import';\n break;\n\n case 'ingest': {\n const sourceKey = sourceRef ?? '';\n if (this._hasIngestJob(entityId, sourceKey)) blockingOperation = 'ingest';\n else if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) blockingOperation = 'prune';\n else if (this._isReembedActive(entityId)) blockingOperation = 'reembed';\n else if (this._isImportActiveFor(entityId)) blockingOperation = 'import';\n else if (this._isForgetActiveFor(entityId)) blockingOperation = 'forget';\n break;\n }\n }\n\n if (blockingOperation) {\n throw new WikiBusyError(\n blockingOperation,\n operation === 'global_reembed' || operation === 'global_import' ? '*' : entityId\n );\n }\n\n if (operation === 'ingest') {\n this._addIngestJob(entityId, sourceRef);\n } else if (operation === 'global_reembed') {\n this.activeMaintenanceJobs.add(this._globalReembedKey());\n } else if (operation === 'global_import') {\n this.activeMaintenanceJobs.add(this._globalImportKey());\n } else {\n this.activeMaintenanceJobs.add(this.lockKeyFns[operation as Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>](entityId));\n }\n\n this._notifyStatusSubscribers(entityId);\n }\n\n releaseLock(operation: OperationType, entityId: string, sourceRef?: string): void {\n if (operation === 'ingest') {\n this._removeIngestJob(entityId, sourceRef);\n } else if (operation === 'global_reembed') {\n this.activeMaintenanceJobs.delete(this._globalReembedKey());\n } else if (operation === 'global_import') {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n } else {\n this.activeMaintenanceJobs.delete(this.lockKeyFns[operation as Exclude<OperationType, 'ingest' | 'global_reembed' | 'global_import'>](entityId));\n }\n\n this._notifyStatusSubscribers(entityId);\n }\n\n /**\n * Returns true if acquireLock(operation, entityId) would throw WikiBusyError.\n * Use for non-throwing conflict checks (e.g. auto-trigger gating in write()).\n */\n isBlocked(operation: OperationType, entityId: string): boolean {\n if (operation !== 'global_import' && this.activeMaintenanceJobs.has(this._globalImportKey())) return true;\n\n switch (operation) {\n case 'librarian':\n case 'heal':\n case 'ontologyBackfill':\n return this.activeMaintenanceJobs.has(this.lockKeyFns[operation](entityId)) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n case 'prune':\n return this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._librarianKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._healKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n default:\n return false;\n }\n }\n\n /**\n * Auto-heal historically only gated on the heal self-key. Keep that behavior\n * for write() auto-trigger paths while preserving stricter checks in acquireLock().\n */\n tryAcquireAutoHealLock(entityId: string): boolean {\n const healKey = this._healKey(entityId);\n if (this.activeMaintenanceJobs.has(healKey)) return false;\n this.activeMaintenanceJobs.add(healKey);\n this._notifyStatusSubscribers(entityId);\n return true;\n }\n\n /**\n * Validates then acquires global + per-entity import locks atomically.\n * Validates all entities before acquiring any lock (same as current importDump semantics).\n */\n acquireImportLocks(entityIds: string[]): void {\n for (const entityId of entityIds) {\n if (this.activeMaintenanceJobs.has(this._importKey(entityId))) throw new WikiBusyError('import', entityId);\n if (this.activeMaintenanceJobs.has(this._librarianKey(entityId))) throw new WikiBusyError('librarian', entityId);\n if (this.activeMaintenanceJobs.has(this._healKey(entityId))) throw new WikiBusyError('heal', entityId);\n if (this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId))) throw new WikiBusyError('ontologyBackfill', entityId);\n if (this.activeMaintenanceJobs.has(this._pruneKey(entityId))) throw new WikiBusyError('prune', entityId);\n if (this._isReembedActive(entityId)) throw new WikiBusyError('reembed', entityId);\n if (this._isIngestActiveFor(entityId)) throw new WikiBusyError('ingest', entityId);\n if (this._isForgetActiveFor(entityId)) throw new WikiBusyError('forget', entityId);\n }\n if (this.activeMaintenanceJobs.has(this._globalImportKey())) throw new WikiBusyError('import', '*');\n\n this.activeMaintenanceJobs.add(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.add(this._importKey(entityId));\n }\n }\n\n releaseImportLocks(entityIds: string[]): void {\n this.activeMaintenanceJobs.delete(this._globalImportKey());\n for (const entityId of entityIds) {\n this.activeMaintenanceJobs.delete(this._importKey(entityId));\n }\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n return {\n ingesting: this._isIngestActiveFor(entityId),\n librarian: this.activeMaintenanceJobs.has(this._librarianKey(entityId)),\n heal: this.activeMaintenanceJobs.has(this._healKey(entityId)),\n };\n }\n\n subscribeEntityStatus(entityId: string, callback: (status: EntityStatus) => void): () => 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\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(`[JobManager] 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 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 if (entityId === '*') return;\n\n const set = this.statusSubscribers.get(entityId);\n if (!set || set.size === 0) return;\n\n for (const entry of Array.from(set)) {\n if (!set.has(entry)) continue;\n const next = this.getEntityStatus(entityId);\n\n if (entry.last.ingesting === next.ingesting &&\n entry.last.librarian === next.librarian &&\n entry.last.heal === next.heal) {\n continue;\n }\n\n entry.last = this._copyEntityStatus(next);\n try {\n entry.callback(this._copyEntityStatus(next));\n } catch (err) {\n console.error(`[JobManager] callback error for entityId=\"${entityId}\" during transition emission`, err);\n }\n }\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport type { WikiOptions, WikiEvent } from '../types';\nimport { WikiBusyError } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { EventRepository } from '../repositories/EventRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { JobManager } from './JobManager';\nimport type { MaintenanceService } from './MaintenanceService';\nimport { generateId } from '../utils/ids';\nimport { clip } from '../utils/pure';\n\nexport class WriteService {\n constructor(\n private db: SQLiteAdapter,\n private options: WikiOptions,\n private entryRepo: EntryRepository,\n private eventRepo: EventRepository,\n private metadataRepo: MetadataRepository,\n private jobManager: JobManager,\n private maintenanceService: MaintenanceService,\n ) {}\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n if (typeof entityId !== 'string' || entityId.length === 0 || entityId.length > 200 || entityId.includes('\\0')) {\n throw new TypeError(\n `Invalid entityId: must be a non-empty string at most 200 chars with no null bytes; got ${JSON.stringify(entityId)}.`,\n );\n }\n if (event === null || typeof event !== 'object' || Array.isArray(event)) {\n throw new TypeError('Invalid event: must be a non-null object.');\n }\n if (typeof event.summary !== 'string') {\n throw new TypeError('Invalid event.summary: must be a string.');\n }\n const summary = clip(event.summary, 4000);\n\n let relatedEntryId: string | null = null;\n const rawRelatedEntryId = event.related_entry_id;\n if (rawRelatedEntryId != null && rawRelatedEntryId !== '') {\n if (\n typeof rawRelatedEntryId !== 'string' ||\n rawRelatedEntryId.length > 200 ||\n rawRelatedEntryId.includes('\\0')\n ) {\n relatedEntryId = null;\n } else {\n const existing = await this.entryRepo.findByIds([rawRelatedEntryId], [entityId]);\n relatedEntryId = existing.length > 0 ? rawRelatedEntryId : null;\n }\n }\n\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 const newEvent: WikiEvent = {\n id,\n entity_id: entityId,\n event_type: eventType,\n summary,\n related_entry_id: relatedEntryId,\n created_at: now,\n };\n\n let shouldRunLibrarian = false;\n let librarianCount = 0;\n let prevMemoryCheckpoint = 0;\n\n await this.db.withTransactionAsync(async (tx) => {\n await this.eventRepo.add(newEvent, tx);\n\n const threshold = this.options.config?.autoLibrarianThreshold || 20;\n\n const [count, cp] = await Promise.all([\n this.eventRepo.count(entityId, tx),\n this.metadataRepo.getCheckpoint(entityId, tx),\n ]);\n\n let memoryCheckpoint = cp.memory ?? 0;\n if (memoryCheckpoint > count) memoryCheckpoint = 0;\n\n if (count - memoryCheckpoint >= threshold) {\n if (!this.jobManager.isBlocked('librarian', entityId)) {\n shouldRunLibrarian = true;\n librarianCount = count;\n prevMemoryCheckpoint = memoryCheckpoint;\n await this.metadataRepo.updateCheckpoint(entityId, { memory: count }, tx);\n }\n }\n });\n\n if (shouldRunLibrarian) {\n try {\n this.jobManager.acquireLock('librarian', entityId);\n this.runLibrarianThenMaybeHeal(entityId, librarianCount, prevMemoryCheckpoint)\n .catch(console.error)\n .finally(() => {\n this.jobManager.releaseLock('librarian', entityId);\n });\n } catch (e) {\n if (!(e instanceof WikiBusyError)) throw e;\n await this.metadataRepo.updateCheckpoint(entityId, { memory: prevMemoryCheckpoint }, this.db);\n }\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number, prevCheckpoint: number): Promise<void> {\n try {\n await this.maintenanceService.doRunLibrarian(entityId);\n // Only advance checkpoint after successful librarian run\n await this.metadataRepo.updateCheckpoint(entityId, { memory: currentEventCount }, this.db);\n } catch (e) {\n // Rollback checkpoint on failure so events can be retried\n await this.metadataRepo.updateCheckpoint(entityId, { memory: prevCheckpoint }, this.db);\n throw e;\n }\n\n const autoHealThreshold = this.options.config?.autoHealThreshold || 100;\n\n const cp = await this.metadataRepo.getCheckpoint(entityId, this.db);\n let healCheckpoint = cp.heal ?? 0;\n if (healCheckpoint > currentEventCount) healCheckpoint = 0;\n\n const shouldRunHeal = currentEventCount - healCheckpoint >= autoHealThreshold;\n\n if (shouldRunHeal && this.jobManager.tryAcquireAutoHealLock(entityId)) {\n try {\n await this.maintenanceService.doRunHeal(entityId);\n await this.metadataRepo.updateCheckpoint(entityId, { heal: currentEventCount }, this.db);\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n }\n}\n"]}
|