@equationalapplications/core-llm-wiki 7.4.0 → 7.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/db/schema.ts","../src/db/sqliteCodes.ts","../src/types.ts","../src/db/serializedAdapter.ts","../src/db/migrations.ts","../src/repositories/BaseRepository.ts","../src/repositories/rowMappers.ts","../src/repositories/EntryRepository.ts","../src/utils/ids.ts","../src/repositories/OutboxRepository.ts","../src/repositories/SourceRefIndexRepository.ts","../src/repositories/TaskRepository.ts","../src/repositories/EventRepository.ts","../src/repositories/EdgeRepository.ts","../src/utils/ontology.ts","../src/repositories/MetadataRepository.ts","../src/utils/cosine.ts","../src/utils/embedding.ts","../src/services/SearchService.ts","../src/services/JobManager.ts","../src/utils/pure.ts","../src/utils/diagnostics.ts","../src/prompts.ts","../src/utils/healConstants.ts","../src/services/PromptService.ts","../src/utils/chunkingDefaults.ts","../src/services/IngestionService.ts","../src/services/BoundedLlmCall.ts","../src/services/MaintenanceService.ts","../src/services/ImportExportService.ts","../src/utils/embedDefaults.ts","../src/services/EmbeddingService.ts","../src/readOptions.ts","../src/services/RetrievalService.ts","../src/services/WriteService.ts","../src/prompts/ontology.ts","../src/services/OntologyService.ts","../src/services/GraphTraversalService.ts","../src/db/okf-trust-writes.ts","../src/WikiMemory.ts","../src/utils/formatContext.ts","../src/utils/formatGraphContext.ts","../src/utils/sanitizeForFilename.ts","../src/utils/formatMemoryDump.ts","../src/utils/formatOkfBundle.ts","../src/utils/parseOkfBundle.ts","../src/librarianPrompt.ts","../src/index.ts"],"names":["isStaleAfter","deriveTrustTier","MiniSearch","rows","documents","result","entries","counts","latestVerified","entityId","formatSourcesJson","appendEventIdComment","relatedLinksFor","appendRelatedSection","buildConceptDocument","buildLogMd","buildEntityIndexMd","buildRootIndexMd","parseVerifiedFlexible","parseCitationsList","isAllowedOkfPath","parseRootIndexMd","parseEntityIndexMd","parseConcept","splitRelatedSection","extractMarkdownLinks","parseLogMd","parseEventIdComment"],"mappings":"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","file":"index.js","sourcesContent":["import type { SQLiteAdapter } from '../types';\n\nexport async function setupDatabase(db: SQLiteAdapter, prefix: string) {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entries (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n title TEXT NOT NULL,\n body TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n confidence TEXT NOT NULL DEFAULT 'inferred',\n source_type TEXT NOT NULL DEFAULT 'librarian_inferred',\n source_hash TEXT,\n source_ref TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n last_accessed_at INTEGER,\n access_count INTEGER NOT NULL DEFAULT 0,\n deleted_at INTEGER,\n embedding TEXT,\n embedding_blob BLOB,\n okf_type TEXT,\n ontology_checked_at INTEGER,\n heal_checked_at INTEGER,\n lifecycle_status TEXT NOT NULL DEFAULT 'stable',\n stale_after INTEGER,\n generated_by TEXT,\n last_verified_at INTEGER,\n last_verified_by TEXT,\n okf_sources TEXT,\n okf_verified TEXT,\n okf_usage_window TEXT,\n embedding_failed_at INTEGER,\n embedding_failure_kind TEXT,\n embedding_attempts INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}entries_entity_idx ON ${prefix}entries(entity_id);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_ref_idx ON ${prefix}entries(entity_id, source_ref);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_hash_idx ON ${prefix}entries(entity_id, source_hash) WHERE source_hash IS NOT NULL;\n CREATE INDEX IF NOT EXISTS ${prefix}entries_updated_idx ON ${prefix}entries(updated_at DESC);\n\n -- source_ref_index: per-(entity, source_hash) record of the canonical sourceRef\n -- currently holding that hash. The partial UNIQUE index on (entity_id, source_hash)\n -- WHERE deleted_at IS NULL enforces the sourceRef-level TOCTOU-race invariant;\n -- entries-level uniqueness cannot express it because a single ingestDocument call\n -- writes N facts that all share (entity_id, source_ref, source_hash). See\n -- docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n CREATE TABLE IF NOT EXISTS ${prefix}source_ref_index (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_hash TEXT NOT NULL,\n source_ref TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n deleted_at INTEGER\n );\n CREATE UNIQUE INDEX IF NOT EXISTS ${prefix}idx_source_ref_hash\n ON ${prefix}source_ref_index (entity_id, source_hash)\n WHERE deleted_at IS NULL;\n\n CREATE TABLE IF NOT EXISTS ${prefix}tasks (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n description TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n priority INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n resolved_at INTEGER,\n deleted_at INTEGER,\n okf_type TEXT,\n lifecycle_status TEXT NOT NULL DEFAULT 'stable',\n stale_after INTEGER,\n generated_by TEXT,\n last_verified_at INTEGER,\n last_verified_by TEXT,\n okf_sources TEXT,\n okf_verified TEXT,\n okf_usage_window TEXT\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_entity_idx ON ${prefix}tasks(entity_id, status);\n\n CREATE TABLE IF NOT EXISTS ${prefix}edges (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n edge_type TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n UNIQUE(entity_id, source_id, target_id, edge_type)\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}edges_entity_idx ON ${prefix}edges(entity_id);\n\n CREATE TABLE IF NOT EXISTS ${prefix}events (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n summary TEXT NOT NULL,\n related_entry_id TEXT,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}events_entity_idx ON ${prefix}events(entity_id, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}checkpoints (\n entity_id TEXT PRIMARY KEY,\n heal_checkpoint INTEGER NOT NULL DEFAULT 0,\n memory_checkpoint INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}entity_manifests (\n entity_id TEXT PRIMARY KEY,\n mode TEXT NOT NULL DEFAULT 'off',\n manifest_json TEXT NOT NULL DEFAULT '{\"node_types\":[],\"edge_types\":[]}',\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}outbox (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n table_name TEXT NOT NULL,\n record_id TEXT NOT NULL,\n operation TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_entity_id_created_at\n ON ${prefix}outbox (entity_id, created_at);\n\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_created_at\n ON ${prefix}outbox (created_at);\n `);\n\n // OKF v0.2 indexes — gated on column existence so we never try to create an\n // index on a column that hasn't been added yet (upgrade-from-pre-v10 case).\n // The columns themselves are in the CREATE TABLE above (fresh installs get\n // them directly) and in migration v10 (upgrades get them via ALTER TABLE).\n // The migration also creates these same indexes, so the IF NOT EXISTS guard\n // makes either path safe.\n await createOkfV02IndexesIfColumnsExist(db, prefix);\n}\n\nasync function createOkfV02IndexesIfColumnsExist(db: SQLiteAdapter, prefix: string): Promise<void> {\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n const colNames = new Set(cols.map((c) => c.name));\n if (colNames.has('lifecycle_status')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_lifecycle_status_idx ON ${prefix}${table}(lifecycle_status);`);\n }\n if (colNames.has('stale_after')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_stale_after_idx ON ${prefix}${table}(stale_after);`);\n }\n if (colNames.has('last_verified_at')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_last_verified_at_idx ON ${prefix}${table}(last_verified_at);`);\n }\n }\n}\n","/**\n * SQLite primary result codes → symbolic name (https://sqlite.org/rescode.html),\n * so a numeric expo-sqlite code normalizes to the same shape as the string codes\n * better-sqlite3 / node:sqlite already report (e.g. both become 'SQLITE_BUSY').\n *\n * Dependency-free leaf module: shared by `db/serializedAdapter.ts` and `types.ts`\n * (via `WikiTransactionError`) so the mapping has a single source of truth.\n */\nconst SQLITE_RESULT_CODE_NAMES: Record<number, string> = {\n 1: 'SQLITE_ERROR', 2: 'SQLITE_INTERNAL', 3: 'SQLITE_PERM', 4: 'SQLITE_ABORT',\n 5: 'SQLITE_BUSY', 6: 'SQLITE_LOCKED', 7: 'SQLITE_NOMEM', 8: 'SQLITE_READONLY',\n 9: 'SQLITE_INTERRUPT', 10: 'SQLITE_IOERR', 11: 'SQLITE_CORRUPT', 12: 'SQLITE_NOTFOUND',\n 13: 'SQLITE_FULL', 14: 'SQLITE_CANTOPEN', 15: 'SQLITE_PROTOCOL', 16: 'SQLITE_EMPTY',\n 17: 'SQLITE_SCHEMA', 18: 'SQLITE_TOOBIG', 19: 'SQLITE_CONSTRAINT', 20: 'SQLITE_MISMATCH',\n 21: 'SQLITE_MISUSE', 22: 'SQLITE_NOLFS', 23: 'SQLITE_AUTH', 24: 'SQLITE_FORMAT',\n 25: 'SQLITE_RANGE', 26: 'SQLITE_NOTADB', 27: 'SQLITE_NOTICE', 28: 'SQLITE_WARNING',\n // Extended result codes (https://sqlite.org/rescode.html#extended_result_code_list).\n // 2067 = SQLITE_CONSTRAINT_UNIQUE — raised when a UNIQUE index/PRIMARY KEY\n // rejects an INSERT/UPDATE; expo-sqlite reports this as a numeric \"Error code N:\"\n // prefix and we normalize it back to the symbolic name so callers can branch on\n // the same string the rest of the ecosystem uses.\n 2067: 'SQLITE_CONSTRAINT_UNIQUE',\n 100: 'SQLITE_ROW', 101: 'SQLITE_DONE',\n};\n\n/** Falls back to `SQLITE_<n>` for a result code outside the known table. */\nexport function nameForSqliteResultCode(n: number): string {\n return SQLITE_RESULT_CODE_NAMES[n] ?? `SQLITE_${n}`;\n}\n\n/**\n * Best-effort SQLite code extraction. Driver-specific:\n * better-sqlite3 / node:sqlite: err.code === 'SQLITE_BUSY' (string, SQLITE_-prefixed)\n * expo-sqlite: err.message starts with 'Error code N: …' (numeric,\n * normalized here to the same symbolic name)\n */\nexport function extractSqliteCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const { code, message } = err as { code?: unknown; message?: unknown };\n if (typeof code === 'string' && code.startsWith('SQLITE_')) return code;\n if (typeof message === 'string') {\n const m = /^Error code (\\d+):/.exec(message);\n if (m) return nameForSqliteResultCode(Number(m[1]));\n }\n return undefined;\n}\n","import { extractSqliteCode } from './db/sqliteCodes';\nimport type {\n OkfSource,\n OkfSourceUsageWindow,\n OkfVerifiedEntry,\n} from '@equationalapplications/core-okf';\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 /**\n * `changes` must report the number of rows the statement actually wrote.\n * It must be 0 when a conflict clause suppresses a write (INSERT OR IGNORE,\n * or ON CONFLICT DO UPDATE ... WHERE), and must never be nonzero for a\n * suppressed write. A permitted write that modifies no column value still\n * counts the row, as SQLite does.\n *\n * This count is load-bearing beyond ownership checks: edge insertion\n * (and therefore upsertGraph's public edgesWritten), metadata compare-and-set,\n * soft-delete success reporting, and maintenance sweep counts all read it.\n * An adapter that under-reports silently corrupts those results.\n */\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 /** Optional parent type slug. One level only — the parent must exist in the\n * same manifest and must not itself declare a `parent_type`. */\n parent_type?: 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\n/** Result of a single `runReembed` sweep. */\nexport interface ReembedResult {\n /** Facts successfully (re-)embedded this sweep. */\n embedded: number;\n /** Facts with a valid existing embedding left untouched because\n * `skipExisting` was in effect (and no dimension mismatch forced a re-embed). */\n skipped: number;\n /** Facts whose embed attempt ran and failed this sweep. Includes\n * `storage_error` failures, which are not backoff-tracked (a marker is\n * itself a DB write — see the reembed README section). Convergence loops\n * should test this counter, never `deferred`. */\n failed: number;\n /** Previously failed facts still inside their exponential backoff window\n * (60s doubling, capped at 24h), not attempted this sweep. Not an error;\n * a later sweep retries them once the window elapses. */\n deferred: number;\n /** Facts excluded for good: a `float32_overflow` failure or 5 failed\n * lifetime attempts. `{ force: true }` retries these anyway. */\n permanentlyFailed: number;\n}\n\n/**\n * L3 heal-success record: a fact the model emitted a verdict for under a\n * truncated view of its own body. `originalBodyChars` lets an operator flag\n * the fact for re-inspection; `truncatedBodyChars` is the L3 cap actually\n * applied. Emitted by `PromptService.buildHealPrompt`, surfaced via\n * `HealResult.degraded`, mutually exclusive with `HealResult.skipped` on\n * `id` (a fact can be either healed-under-degradation or dropped — never\n * both).\n */\nexport interface DegradedRecord {\n id: string;\n originalBodyChars: number;\n truncatedBodyChars: number;\n}\n\n/** Result of a single heal run. */\nexport interface HealResult {\n /**\n * Heal candidates sent to the model this run. Counts candidates whose batch\n * came back unusable and landed in `skipped` as well — they reached the\n * provider too, so this is provider exposure, not successful throughput.\n */\n scanned: number;\n /**\n * Facts whose confidence was lowered to `tentative` — the stale-inferred SQL\n * pass (`inferred` → `tentative`) plus any model-directed downgrades, deduped.\n */\n downgraded: number;\n /** Facts soft-deleted — the orphan-marking SQL pass plus model-directed deletes, deduped. */\n deleted: number;\n /** New facts synthesized by heal. */\n newFactsCreated: number;\n /**\n * Candidates that could not converge after the helper's full escalation\n * path. `reason` distinguishes genuine non-convergence\n * (`'non_convergent'` — terminal give-up at attemptLevel 3, parse error,\n * or model-config error) from transient provider failures\n * (`'call_error'` — non-truncation error originating in `call()` at\n * `batch.length === 1`). `doRunHeal` excludes `'call_error'` ids from\n * `markHealChecked`'s cooldown stamp so a momentary provider hiccup does\n * not lock the fact out for `HEAL_RECHECK_MS`. Mutually exclusive with\n * `degraded` on `id`.\n */\n skipped: Array<{ id: string; reason: 'non_convergent' | 'call_error' }>;\n /**\n * L3 heal successes: facts the model emitted a verdict for under a\n * truncated view of their own body. Each entry carries the truncation\n * magnitude so an operator can flag the fact for re-inspection. The\n * corresponding log line `[WikiMemory] heal healed under degraded\n * context ...` fires for each entry. Mutually exclusive with `skipped`\n * on `id` — the reconciliation step in doRunHeal drops any record\n * whose id also appears in `skipped` (a contradiction: degraded means\n * healed, skipped means dropped).\n */\n degraded: Array<DegradedRecord>;\n /**\n * Heal candidates still eligible after this run — convergence signal: loop while > 0.\n *\n * This does NOT mean what it means for OntologyBackfillResult. Untyped facts are\n * a finite backlog that drains permanently; heal's candidates are the live mutable\n * corpus. `remaining === 0` means \"every mutable fact is inside the recheck\n * cooldown\", not \"there is no more work\" — it climbs back as the cooldown lapses\n * and as new facts are written. A host loop terminates, but it converges to\n * \"corpus swept once this cooldown window\", not to a drained queue.\n */\n remaining: number;\n /** Heal candidates 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 * Maximum characters of `title + body + tags` passed to `llmProvider.embed()`\n * when embedding a fact. Longer input is clipped, not rejected.\n *\n * Default 6000 (~1,500 tokens), which fits common embedding windows including\n * nomic-embed-text's 2,048 tokens with headroom. Values above the 16,000\n * hard ceiling are clamped to it; the ceiling is a security control and\n * configuration cannot raise it.\n */\n maxEmbedChars?: 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 * Engine default for `ReadOptions.excludeDrafts` and\n * `GraphTraversalOptions.excludeDrafts`. Default false (drafts visible).\n */\n excludeDrafts?: boolean;\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 * Minimum number of results to retain from each named entity before the global\n * `maxResults` cut. Applied after scoring: the top-N scored results from each\n * named entity are reserved, then remaining slots fill by score as usual.\n *\n * An entity with fewer than N matching results contributes what it has — this is\n * not an error. Floors cannot resurrect a result excluded by `preFilterLimit`.\n *\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n * Ignored when `query` is empty — that path uses recency ordering and ignores\n * `tierWeights` as well.\n *\n * Throws `WikiInvalidReadOptions` when a floor cannot be satisfied by\n * construction: floors summing above `maxResults`, a floor on an entity excluded\n * by `tierWeights: 0`, or a floor keyed to an entity not in `entityId`.\n */\n tierFloors?: Record<string, number>;\n /**\n * When true, facts whose `lifecycle_status` is `'draft'` are excluded before\n * `maxResults`, `tierFloors` and every other cut, on every read path.\n * Resolves call → `WikiConfig.excludeDrafts` → false.\n */\n excludeDrafts?: 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 // --- OKF v0.2 surface (additive; see spec §4.6) ---\n /** OKF v0.2 lifecycle state. Defaults to 'stable' on the SQL side. */\n lifecycle_status?: 'draft' | 'stable' | 'deprecated';\n /** Absolute YYYY-MM-DD cutoff for staleness. NULL = never stale. */\n stale_after?: number | null;\n /** Actor string per OKF v0.2 §7 (`<producer>/<version>`, `human:<id>`, `process:<id>`). */\n generated_by?: string | null;\n /** Full list of OKF v0.2 sources (provenance). */\n okf_sources?: OkfSource[];\n /** Chronological list of verification events. */\n okf_verified?: OkfVerifiedEntry[];\n /** Sibling-of-sources usage window object. */\n okf_usage_window?: OkfSourceUsageWindow | null;\n /** Convenience: epoch ms of the latest verifier. Derived; mirrored for query speed. */\n last_verified_at?: number | null;\n /** Convenience: actor string of the latest verifier. Derived; mirrored for query speed. */\n last_verified_by?: string | null;\n /**\n * Hydrated at read time: `isStaleAfter(stale_after, now)`. `true` once the\n * absolute stale_after cutoff has passed; `false` otherwise (including when\n * stale_after is null). Surfaced per spec §2.7 + §5.3 so hosts can render\n * staleness without recomputing. Always present on read paths that go\n * through `mapRowToFact` / `mapRowToTask`.\n */\n isStale?: boolean;\n /**\n * Hydrated at read time: `deriveTrustTier(okf_verified)`. `'human-reviewed'`\n * when any entry has `by: 'human:...'`, `'machine-confirmed'` when entries\n * exist without a human verifier, `'unverified'` when okf_verified is empty.\n * Surfaced per spec §2.7 + §5.3. Always present on read paths that go through\n * `mapRowToFact` / `mapRowToTask`.\n */\n trustTier?: 'unverified' | 'machine-confirmed' | 'human-reviewed';\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 // --- OKF v0.2 surface (additive; see spec §4.6) ---\n lifecycle_status?: 'draft' | 'stable' | 'deprecated';\n stale_after?: number | null;\n generated_by?: string | null;\n okf_sources?: OkfSource[];\n okf_verified?: OkfVerifiedEntry[];\n okf_usage_window?: OkfSourceUsageWindow | null;\n last_verified_at?: number | null;\n last_verified_by?: string | null;\n /**\n * Hydrated at read time: `isStaleAfter(stale_after, now)`. Mirrors\n * {@link WikiFact.isStale} (spec §2.5 + §5.3 treat stale_after symmetrically\n * for tasks and facts). Always present on read paths that go through\n * `mapRowToTask`.\n */\n isStale?: boolean;\n /**\n * Hydrated at read time: `deriveTrustTier(okf_verified)`. Mirrors\n * {@link WikiFact.trustTier}. Always present on read paths that go through\n * `mapRowToTask`.\n */\n trustTier?: 'unverified' | 'machine-confirmed' | 'human-reviewed';\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 * When true, draft facts are dead ends for *discovered* nodes (not\n * discovered, not traversed through). Does not gate the anchor.\n * Resolves call → `WikiConfig.excludeDrafts` → false.\n */\n excludeDrafts?: boolean;\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\n/** Severity is fixed per code (spec §4.2.6). */\nexport type WikiDiagnosticSeverity = 'info' | 'warn' | 'error';\n\n/**\n * Closed for this release series, but new codes are added in minor versions:\n * hosts must tolerate codes they do not recognize.\n */\nexport type WikiDiagnosticCode =\n | 'ingest_chunk_failed'\n | 'fact_rejected'\n | 'task_rejected'\n | 'fact_deduplicated'\n | 'edge_dropped'\n | 'embedding_failed'\n | 'hook_failed'\n | 'background_job_failed'\n | 'heal_skipped'\n | 'grounding_missing'\n | 'grounding_failed'\n | 'classification_low_confidence'\n | 'classification_invalid';\n\n/** The service run that emitted the diagnostic. */\nexport type WikiDiagnosticOperation =\n | 'ingest' | 'upsertGraph' | 'librarian' | 'heal' | 'ontologyBackfill' | 'reembed' | 'importDump' | 'write';\n\n/** `'auto'` when a write threshold started the run (auto-librarian / auto-heal); `'call'` when the host did. */\nexport type WikiDiagnosticTrigger = 'call' | 'auto';\n\n/** Identifiers only — never titles, bodies, quotes, LLM output, provider messages, or hashes of content. */\nexport interface WikiDiagnosticDetail {\n factId?: string;\n sourceRef?: string;\n chunkIndex?: number;\n edgeType?: string;\n /** Manifest slug of the edge source, when resolved. */\n sourceNodeType?: string;\n /** Manifest slug of the edge target, when resolved. */\n targetNodeType?: string;\n /** Position of a rejected item in the LLM response array. */\n itemIndex?: number;\n /** Machine-readable sub-reason, e.g. `'target_not_found'`. */\n reason?: string;\n /** Aggregated `ingest_chunk_failed` only; the first 20 failed chunk indexes. */\n chunkIndexes?: number[];\n /** Aggregated emissions only. */\n count?: number;\n}\n\nexport interface WikiDiagnostic {\n code: WikiDiagnosticCode;\n severity: WikiDiagnosticSeverity;\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n entityId: string;\n /** Epoch ms, sampled at emission. */\n at: number;\n /** Fixed template per code. Never contains content. */\n message: string;\n detail?: WikiDiagnosticDetail;\n}\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 /**\n * Receives typed, content-free diagnostics for events core previously\n * dropped silently or only logged (spec §4). Synchronous; a returned promise\n * is ignored. A throwing or rejecting hook never affects the operation that\n * emitted the diagnostic. Existing console output is unchanged whether or\n * not this is set.\n */\n onDiagnostic?: (diagnostic: WikiDiagnostic) => void;\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 /** Sanitized per-entity result floors, when `tierFloors` was supplied and non-empty. */\n tierFloors?: 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 `ingestDocument({ onDuplicateHash: 'throw' })` when a different\n * source_ref in the same entity already holds the supplied source_hash against\n * a live row. Mirrors {@link WikiBusyError}'s anchoring of canonical metadata\n * on the error instance for stable observability.\n */\nexport class WikiDuplicateHashError extends Error {\n readonly canonical: string;\n readonly sourceHash: string;\n readonly entityId: string;\n\n constructor(params: { canonical: string; sourceHash: string; entityId: string }) {\n super(`Duplicate source hash for entity ${params.entityId}; another ref already holds this content`);\n this.name = 'WikiDuplicateHashError';\n this.canonical = params.canonical;\n this.sourceHash = params.sourceHash;\n this.entityId = params.entityId;\n }\n}\n\n/**\n * Thrown by `WikiMemory.upsertGraph` when the persisted ontology mode for the\n * entity is `'strict'` and a caller-supplied node or edge `type` does not\n * resolve against the entity's manifest. Mirrors {@link WikiBusyError}'s\n * anchoring of canonical metadata on the error instance for stable\n * observability. Per C4, the check is pre-flight and all-or-nothing — the\n * first invalid item throws; NONE are written.\n */\nexport class WikiStrictOntologyViolation extends Error {\n readonly entityId: string;\n readonly kind: 'node' | 'edge';\n readonly type: string;\n readonly code = 'WIKI_STRICT_ONTOLOGY_VIOLATION' as const;\n\n constructor(entityId: string, kind: 'node' | 'edge', type: string) {\n super(\n `Out-of-manifest ${kind} type \"${type}\" for entity \"${entityId}\" under strict mode.`,\n );\n this.entityId = entityId;\n this.kind = kind;\n this.type = type;\n this.name = 'WikiStrictOntologyViolation';\n }\n}\n\n/**\n * Thrown by `WikiMemory.upsertGraph`'s C2 probe when the supplied\n * `sourceHash` is already mapped to a *different* `sourceRef` for the same\n * entity. Indicates either a caller-side id-derivation collision, a race with\n * another writer, or — per the C2 known-limitation note in the spec — two\n * source files with genuinely identical content (byte-identical barrel\n * re-exports, blank stubs, vendored boilerplate). In all cases: fail loud.\n */\nexport class WikiSourceRefHashCollision extends Error {\n readonly entityId: string;\n readonly sourceHash: string;\n readonly existingSourceRef: string;\n readonly attemptedSourceRef: string;\n readonly code = 'WIKI_SOURCE_REF_HASH_COLLISION' as const;\n\n constructor(params: {\n entityId: string;\n sourceHash: string;\n existingSourceRef: string;\n attemptedSourceRef: string;\n }) {\n super(\n `Source hash \"${params.sourceHash}\" for entity \"${params.entityId}\" ` +\n `is already mapped to sourceRef \"${params.existingSourceRef}\"; ` +\n `cannot remap to \"${params.attemptedSourceRef}\".`,\n );\n this.entityId = params.entityId;\n this.sourceHash = params.sourceHash;\n this.existingSourceRef = params.existingSourceRef;\n this.attemptedSourceRef = params.attemptedSourceRef;\n this.name = 'WikiSourceRefHashCollision';\n }\n}\n\n/**\n * Thrown when a graph node ID is already owned by another entity.\n *\n * Raised by `WikiMemory.upsertGraph`'s node-ownership pre-flight and,\n * independently, by `EntryRepository.upsert` for every caller — which is why\n * `ingestDocument` can surface it too (it shares `upsertGraphCore` on its full\n * path and `EntryRepository.upsert` on its partial path).\n *\n * Deliberately carries NO context: no owner entity, node ID, stored content,\n * provenance, or `cause`. A rejection is reachable by whatever supplies the\n * node IDs, so the error must not become a channel for reading another\n * entity's identifiers. The `WIKI_`-prefixed code and fixed message also keep\n * it clear of `extractSqliteCode`, so it passes through the serialized\n * transaction wrapper unwrapped.\n */\nexport class WikiGraphNodeOwnershipConflict extends Error {\n readonly code = 'WIKI_GRAPH_NODE_OWNERSHIP_CONFLICT' as const;\n\n /**\n * Privacy-preserving constructor: accepts no arguments, so neither the foreign\n * owner, the conflicting node ID, the stored content, nor any provenance can\n * leak through this error. The fixed message and `code` are the entire signal.\n *\n * @returns a contextless `WikiGraphNodeOwnershipConflict` instance. See the\n * class-level JSDoc for the privacy rationale.\n */\n\n constructor() {\n super('Graph write rejected because a node ID is unavailable for this entity.');\n this.name = 'WikiGraphNodeOwnershipConflict';\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/**\n * Failure kinds eligible for a persisted embedding failure marker (spec §3.3).\n * `no_provider` never marks (nothing to retry against), and `storage_error`\n * never marks (D3 — a marker is itself a DB write). Defined here, neutral\n * between repositories and services, so EntryRepository can type-narrow the\n * marker kind without importing from services.\n */\nexport type EmbeddingMarkerKind =\n | 'invalid_vector'\n | 'float32_overflow'\n | 'provider_error';\n\n/**\n * Failure record for a single chunk that could not be ingested. Produced by\n * `IngestionService.ingestDocument` and surfaced on the result's `parseFailures`\n * array. `source === 'parse'` for `WikiParseError`-shaped failures (then `tier`\n * is set); `source === 'llm'` for `generateText` rejections (no `tier`).\n *\n * Note: `'ontologyContext'` is reserved but NEVER produced. `buildPromptContext`\n * failures are DB-systemic and propagate as raw throws, not as `parseFailures`.\n */\nexport interface ChunkFailure {\n chunkIndex: number;\n sourceRef: string;\n source: 'parse' | 'llm';\n tier?: 'strict' | 'repair' | 'all';\n position: number | null;\n message: string;\n}\n\n/**\n * Result of `IngestionService.ingestDocument`. The shape WIDENS relative to\n * earlier versions: `ingestedChunks` and `failedChunks` are always present;\n * `parseFailures` is present iff at least one chunk failed.\n *\n * Hosts that destructure `{ truncated, chunks }` see no behavior change.\n * Hosts pattern-matching the entire shape must update to the new fields.\n */\nexport interface IngestDocumentResult {\n truncated: boolean;\n chunks: number;\n ingestedChunks: number;\n failedChunks: number;\n duplicateOf?: string;\n parseFailures?: ChunkFailure[];\n}\n\n/**\n * Thrown by `parseJsonResponse` when both the strict scanner pass and the\n * container-aware repair pass fail to produce a parsable candidate.\n *\n * - `tier: 'strict'` — the existing scanner produced no usable slice (no\n * `{`/`[` at all, or no balanced close). `slice` is the full input text;\n * `position` is the offset of the first `{`/`[`, or `null` when none found.\n * - `tier: 'repair'` — tier 1 found a slice but `JSON.parse` failed; tier 2\n * produced no parsable candidate within `MAX_REPAIR_CANDIDATES`. `slice` is\n * the largest balanced span the walker found; `position` is the offset of\n * the first parse failure within that candidate when known.\n * - `tier: 'all'` — generic catch-all.\n */\nexport class WikiParseError extends Error {\n readonly tier: 'strict' | 'repair' | 'all';\n readonly position: number | null;\n readonly slice: string;\n\n constructor(\n message: string,\n opts: { tier: WikiParseError['tier']; position?: number | null; slice?: string },\n ) {\n super(message);\n this.name = 'WikiParseError';\n this.tier = opts.tier;\n this.position = opts.position ?? null;\n this.slice = opts.slice ?? '';\n }\n}\n\n/**\n * Thrown by `IngestionService.ingestDocument` when every chunk of a document\n * failed (either `parseJsonResponse` or `generateText`). A silent zero-fact\n * ingest is a worse regression than a typed throw — matches existing host\n * semantics (`aws-cloud-agent` Writer Lambda today sees `ingestDocument`\n * throw on any failure).\n */\nexport class WikiIngestEmptyError extends Error {\n readonly parseFailures: ChunkFailure[];\n readonly sourceRef: string;\n readonly chunks: number;\n\n constructor(params: { parseFailures: ChunkFailure[]; sourceRef: string; chunks: number }) {\n const summary = `All ${params.chunks} chunks failed for sourceRef \"${params.sourceRef}\"; see parseFailures for per-chunk detail`;\n super(summary);\n this.name = 'WikiIngestEmptyError';\n this.parseFailures = params.parseFailures;\n this.sourceRef = params.sourceRef;\n this.chunks = params.chunks;\n }\n}\n\n/**\n * Thrown by `read()` when `ReadOptions` contains a request that cannot be\n * satisfied by construction — as opposed to one that merely finds no data.\n */\nexport class WikiInvalidReadOptions extends Error {\n readonly field: string;\n readonly reason: string;\n\n constructor(field: string, reason: string) {\n super(`Invalid ReadOptions.${field}: ${reason}`);\n this.name = 'WikiInvalidReadOptions';\n this.field = field;\n this.reason = reason;\n Object.setPrototypeOf(this, WikiInvalidReadOptions.prototype);\n }\n}\n\n/**\n * Thrown by `promoteDraft` when no live draft with that id exists for the\n * entity: missing, soft-deleted, owned by another entity, or not a draft.\n * Contextless for the same reason as {@link WikiGraphNodeOwnershipConflict}.\n * The `WIKI_` code keeps it clear of `extractSqliteCode`, so it passes through\n * the serialized transaction wrapper unwrapped.\n */\nexport class WikiDraftNotFound extends Error {\n readonly code = 'WIKI_DRAFT_NOT_FOUND' as const;\n\n constructor() {\n super('No draft fact with that id exists for this entity.');\n this.name = 'WikiDraftNotFound';\n Object.setPrototypeOf(this, WikiDraftNotFound.prototype);\n }\n}\n\n/** One page of `listDrafts`. `nextCursor` is opaque; pass it back unchanged. */\nexport interface DraftPage {\n facts: WikiFact[];\n nextCursor: string | null;\n}\n\n","import type { SQLiteAdapter } from '../types';\nimport { WikiTransactionError } from '../types';\nimport { extractSqliteCode } from './sqliteCodes';\n\nexport { extractSqliteCode };\n\n/** True when `err` carries a parseable SQLite code — gates whether the wrapper re-wraps. */\nexport function isDriverError(err: unknown): boolean {\n return extractSqliteCode(err) !== undefined;\n}\n\n/**\n * Returns an adapter with the given methods overridden, delegating everything else\n * (own or class-prototype methods) to `target`.\n *\n * Uses a `Proxy` rather than `Object.create`/object-spread: delegated methods are\n * bound to `target` before being returned, so their receiver (`this`) stays the\n * original adapter instance. That keeps ES `#private` fields and `instanceof`/identity\n * checks inside those methods working — `Object.create` would invoke them with the\n * wrapper as `this` and break both.\n */\nfunction withOverrides(target: SQLiteAdapter, overrides: Partial<SQLiteAdapter>): SQLiteAdapter {\n return new Proxy(target, {\n get(obj, prop, receiver) {\n if (prop in overrides) return Reflect.get(overrides, prop, receiver);\n const value = Reflect.get(obj, prop, obj);\n return typeof value === 'function' ? value.bind(obj) : value;\n },\n }) as SQLiteAdapter;\n}\n\n/**\n * Returns the same adapter with `withTransactionAsync` overridden to throw. Injected\n * by the serialized wrapper onto the `tx` handed to every callback so a *nested*\n * transaction fails loudly instead of deadlocking against the mutex.\n */\nexport function guardReentrancy(tx: SQLiteAdapter): SQLiteAdapter {\n return withOverrides(tx, {\n withTransactionAsync() {\n throw new Error(\n 'Nested withTransactionAsync is not supported: you are already ' +\n 'inside a transaction. Pass the current `tx` down instead of ' +\n 'opening a new transaction.'\n );\n },\n });\n}\n\nconst DEADLOCK_WARN_MS = 10_000;\n\n/**\n * Wraps `withTransactionAsync` in a promise-chain mutex so transactions on the\n * single shared connection run one at a time. Non-transactional reads/writes are\n * untouched. Applied once in the WikiMemory constructor before the adapter reaches\n * any repository or service.\n */\nexport function withSerializedTransactions(db: SQLiteAdapter): SQLiteAdapter {\n let queue: Promise<unknown> = Promise.resolve();\n return withOverrides(db, {\n withTransactionAsync<T>(fn: (tx: SQLiteAdapter) => Promise<T>): Promise<T> {\n // Warns if a call waits >10s for the lock — the signature of the closure-capture\n // deadlock (calling the outer `db` instead of `tx` inside a callback). Cleared the\n // instant the lock is acquired, so it measures queue wait only.\n const warn = setTimeout(() => {\n console.warn(\n '[core-llm-wiki] Transaction queued >10s — possible deadlock. ' +\n 'Inside a transaction callback, use the `tx` parameter, never the ' +\n 'outer database handle.'\n );\n }, DEADLOCK_WARN_MS);\n\n const run = queue\n .catch(() => undefined) // proceed from a settled state; swallow prior outcome\n .then(() => {\n clearTimeout(warn);\n // Re-wrap the tx so a nested withTransactionAsync throws synchronously.\n // Some adapters invoke the callback with no tx handle; fall back to the\n // outer db (same connection). The guard still blocks nested transactions.\n return db.withTransactionAsync((tx) => fn(guardReentrancy(tx ?? db)));\n })\n .catch((e) => {\n // Wrap only driver errors; domain errors reach the caller with instanceof intact.\n throw isDriverError(e)\n ? new WikiTransactionError('Transaction failed', { cause: e })\n : e;\n });\n\n queue = run; // advance the tail; next caller's leading .catch() absorbs this rejection\n return run as Promise<T>;\n },\n });\n}\n","import type { SQLiteAdapter } from '../types';\n\nexport interface Migration {\n version: number;\n description: string;\n run: (db: SQLiteAdapter, prefix: string) => Promise<void>;\n}\n\nexport const MIGRATIONS: Migration[] = [\n {\n version: 1,\n description: 'Rebuild FTS5 with porter unicode61 tokenizer (superseded by v2)',\n run: async (_db, _prefix) => {\n // This migration is superseded by v2 which drops FTS5 entirely.\n // It is kept as a no-op so upgrade paths from v0 do not require FTS5 support.\n },\n },\n {\n version: 2,\n description: 'Remove FTS5; add embedding column for semantic retrieval',\n run: async (db, prefix) => {\n // Drop FTS5 artifacts in a transaction.\n await db.withTransactionAsync(async (tx) => {\n await tx.execAsync(`\n DROP TRIGGER IF EXISTS ${prefix}entries_ai;\n DROP TRIGGER IF EXISTS ${prefix}entries_ad;\n DROP TRIGGER IF EXISTS ${prefix}entries_au;\n DROP TABLE IF EXISTS ${prefix}entries_fts;\n `);\n });\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding')) {\n await db.execAsync(`ALTER TABLE ${prefix}entries ADD COLUMN embedding TEXT`);\n }\n },\n },\n {\n version: 3,\n description: 'Add embedding_blob BLOB column for Float32Array vector storage',\n run: async (db, prefix) => {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding_blob')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN embedding_blob BLOB`\n );\n }\n },\n },\n {\n version: 4,\n description: 'Create outbox table for change data capture',\n run: async (db, prefix) => {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}outbox (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n table_name TEXT NOT NULL,\n record_id TEXT NOT NULL,\n operation TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_entity_id_created_at\n ON ${prefix}outbox (entity_id, created_at);\n `);\n },\n },\n {\n version: 5,\n description: 'Add okf_type to entries/tasks for OKF type fidelity; create edges table for OKF graph import',\n run: async (db, prefix) => {\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n if (!cols.some(c => c.name === 'okf_type')) {\n await db.execAsync(`ALTER TABLE ${prefix}${table} ADD COLUMN okf_type TEXT`);\n }\n }\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}edges (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n edge_type TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n UNIQUE(entity_id, source_id, target_id, edge_type)\n );\n CREATE INDEX IF NOT EXISTS ${prefix}edges_entity_idx ON ${prefix}edges (entity_id);\n `);\n },\n },\n {\n version: 6,\n description: 'Add entity_manifests table for per-entity ontology state',\n run: async (db, prefix) => {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entity_manifests (\n entity_id TEXT PRIMARY KEY,\n mode TEXT NOT NULL DEFAULT 'off',\n manifest_json TEXT NOT NULL DEFAULT '{\"node_types\":[],\"edge_types\":[]}',\n updated_at INTEGER NOT NULL\n );\n `);\n },\n },\n {\n version: 7,\n description: 'Add ontology_checked_at to entries for ontology backfill recheck cooldown',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'ontology_checked_at')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN ontology_checked_at INTEGER`\n );\n }\n },\n },\n {\n version: 8,\n description: 'Add heal_checked_at to entries for heal recheck cooldown',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5/v7.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'heal_checked_at')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN heal_checked_at INTEGER`\n );\n }\n },\n },\n {\n version: 9,\n description: 'add_source_ref_index',\n run: async (db, prefix) => {\n // Defense-in-depth safety net for the #79 TOCTOU race fix. The original\n // design put a UNIQUE index on `entries(entity_id, source_hash)`, but\n // that conflates per-fact and per-sourceRef granularity: a single\n // `ingestDocument` writes N facts that all share\n // (entity_id, source_ref, source_hash), and the 2nd–Nth inserts hit\n // SQLITE_CONSTRAINT_UNIQUE inside the normal multi-fact path. The\n // correct invariant is \"at most one sourceRef per (entity, hash)\", so\n // the constraint lives on a dedicated per-(entity, hash) table that\n // records the canonical sourceRef for each hash. See\n // docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n //\n // Abort path: if any (entity_id, source_hash) already has live rows\n // under multiple distinct source_refs, a previous race beat the new\n // app-level guard. The migration aborts with an actionable error\n // rather than auto-resolving — auto-resolving would either destroy\n // facts or pick a wrong canonical, both worse than failing safe. The\n // thrown error escapes setup() BEFORE the CREATE TABLE runs, so the\n // new table is never created and schema_version is never advanced.\n const duplicates = await db.getAllAsync<{ entity_id: string; source_hash: string; n_refs: number }>(\n `SELECT entity_id, source_hash, COUNT(DISTINCT source_ref) AS n_refs\n FROM ${prefix}entries\n WHERE deleted_at IS NULL AND source_hash IS NOT NULL\n GROUP BY entity_id, source_hash\n HAVING COUNT(DISTINCT source_ref) > 1`\n );\n if (duplicates.length > 0) {\n const sample = duplicates\n .slice(0, 5)\n .map(d => `(entity_id=${d.entity_id}, source_hash=${d.source_hash.slice(0, 12)}…, n_refs=${d.n_refs})`)\n .join(', ');\n throw new Error(\n `Migration v9 (add_source_ref_index) failed: existing live rows have multiple sourceRefs sharing a hash. ` +\n `Found ${duplicates.length} duplicate (entity_id, source_hash) groups. ` +\n `First ${Math.min(5, duplicates.length)}: ${sample}. ` +\n `Resolve each by calling forget({ sourceRef: <loser> }) for the offending sourceRef, then re-run setup.`\n );\n }\n await db.execAsync(\n `CREATE TABLE IF NOT EXISTS ${prefix}source_ref_index (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_hash TEXT NOT NULL,\n source_ref TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n deleted_at INTEGER\n );\n CREATE UNIQUE INDEX IF NOT EXISTS ${prefix}idx_source_ref_hash\n ON ${prefix}source_ref_index (entity_id, source_hash)\n WHERE deleted_at IS NULL;`\n );\n // Backfill: for each (entity_id, source_hash) group with live entries,\n // pick the sourceRef of the entry that wins\n // `ROW_NUMBER() OVER (PARTITION BY entity_id, source_hash ORDER BY updated_at ASC, id ASC) = 1`.\n // The tie-breaker `id ASC` matches `findLatestSourceHash` ordering so\n // the canonical row is deterministic. INSERT OR IGNORE with a\n // deterministic ID (`sri_<entity_id>:<source_hash>`) makes the backfill\n // idempotent — re-running v9 is a no-op.\n await db.execAsync(\n `INSERT OR IGNORE INTO ${prefix}source_ref_index (id, entity_id, source_hash, source_ref, created_at, deleted_at)\n SELECT\n 'sri:' || entity_id || ':' || source_hash,\n entity_id,\n source_hash,\n source_ref,\n updated_at,\n NULL\n FROM (\n SELECT\n entity_id, source_hash, source_ref, updated_at,\n ROW_NUMBER() OVER (\n PARTITION BY entity_id, source_hash\n ORDER BY updated_at ASC, id ASC\n ) AS rn\n FROM ${prefix}entries\n WHERE deleted_at IS NULL\n AND source_hash IS NOT NULL\n AND source_ref IS NOT NULL\n ) ranked\n WHERE rn = 1;`\n );\n },\n },\n {\n version: 10,\n description: 'OKF v0.2: add lifecycle_status, stale_after, generated_by, last_verified_*, okf_sources, okf_verified, okf_usage_window to entries and tasks',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction — same constraint\n // as v2/v3/v5/v7/v8. We do all eight columns per table, then indexes, inside\n // a single execAsync batch where possible. SQLite ALTER on the same table from\n // separate statements is fine; we just can't wrap it in BEGIN...COMMIT.\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n const existing = new Set(cols.map((c) => c.name));\n const adds: Array<[string, string]> = [\n ['lifecycle_status', `ALTER TABLE ${prefix}${table} ADD COLUMN lifecycle_status TEXT NOT NULL DEFAULT 'stable'`],\n ['stale_after', `ALTER TABLE ${prefix}${table} ADD COLUMN stale_after INTEGER`],\n ['generated_by', `ALTER TABLE ${prefix}${table} ADD COLUMN generated_by TEXT`],\n ['last_verified_at', `ALTER TABLE ${prefix}${table} ADD COLUMN last_verified_at INTEGER`],\n ['last_verified_by', `ALTER TABLE ${prefix}${table} ADD COLUMN last_verified_by TEXT`],\n ['okf_sources', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_sources TEXT`],\n ['okf_verified', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_verified TEXT`],\n ['okf_usage_window', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_usage_window TEXT`],\n ];\n for (const [name, sql] of adds) {\n if (!existing.has(name)) await db.execAsync(sql);\n }\n }\n await db.execAsync(`\n CREATE INDEX IF NOT EXISTS ${prefix}entries_lifecycle_status_idx ON ${prefix}entries(lifecycle_status);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_stale_after_idx ON ${prefix}entries(stale_after);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_last_verified_at_idx ON ${prefix}entries(last_verified_at);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_lifecycle_status_idx ON ${prefix}tasks(lifecycle_status);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_stale_after_idx ON ${prefix}tasks(stale_after);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_last_verified_at_idx ON ${prefix}tasks(last_verified_at);\n `);\n },\n },\n {\n version: 11,\n description: 'Add embedding_failed_at, embedding_failure_kind, embedding_attempts to entries for embed retry state',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5/v7/v8/v10.\n // Only the entries table gets these columns — tasks are never embedded.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n const existing = new Set(cols.map((c) => c.name));\n const adds: Array<[string, string]> = [\n ['embedding_failed_at', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_failed_at INTEGER`],\n ['embedding_failure_kind', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_failure_kind TEXT`],\n ['embedding_attempts', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_attempts INTEGER NOT NULL DEFAULT 0`],\n ];\n for (const [name, sql] of adds) {\n if (!existing.has(name)) await db.execAsync(sql);\n }\n },\n },\n];\n\n// Verify MIGRATIONS are in strictly ascending version order at module load time.\n// This prevents skipped or repeated migrations caused by out-of-order entries.\nfor (let i = 1; i < MIGRATIONS.length; i++) {\n if (MIGRATIONS[i].version <= MIGRATIONS[i - 1].version) {\n throw new Error(\n `migrations.ts: MIGRATIONS must be in strictly ascending version order. ` +\n `Found version ${MIGRATIONS[i].version} after ${MIGRATIONS[i - 1].version} at index ${i}.`\n );\n }\n}\n\n// Derived from the last (highest) migration version so it never drifts out of sync.\nexport const CURRENT_SCHEMA_VERSION =\n MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].version : 0;\n","/**\n * Abstract base for all repositories.\n * Provides db accessor + prefix-aware helpers.\n */\nexport abstract class BaseRepository {\n protected db: import('../types').SQLiteAdapter;\n protected prefix: string;\n\n constructor(db: import('../types').SQLiteAdapter, prefix: string) {\n this.db = db;\n this.prefix = prefix;\n }\n\n /**\n * Return the DB executor for a given transaction handle.\n * If tx is provided, use it; otherwise fall back to this.db.\n */\n protected getExecutor(tx?: import('../types').SQLiteAdapter): import('../types').SQLiteAdapter {\n return tx ?? this.db;\n }\n}\n","/**\n * Shared JSON column parsers for repository row mappers.\n *\n * SQLite JSON1 columns return a string when read; in-memory callers expect the\n * parsed value. The parsers tolerate both shapes so callers stay\n * implementation-agnostic (e.g. tests pass arrays directly, drivers return\n * strings). Hoisted to module scope so each row mapping doesn't reallocate\n * two closures (was the case before refactor — see #90 review).\n */\n\nexport function parseJsonArray<T>(s: unknown, fallback: T[]): T[] {\n if (Array.isArray(s)) return s as T[];\n if (typeof s === 'string' && s.length > 0) {\n try {\n const p = JSON.parse(s);\n if (Array.isArray(p)) return p as T[];\n } catch {\n // fall through to fallback\n }\n }\n return fallback;\n}\n\n/**\n * Arrays are rejected in both branches: `typeof [] === 'object'`, so a\n * malformed `okf_usage_window` of `[]` would otherwise be handed back as an\n * object and re-exported with an invalid shape (see #90 review).\n */\nexport function parseJsonObject<T>(s: unknown, fallback: T | null = null): T | null {\n if (s && typeof s === 'object' && !Array.isArray(s)) return s as T;\n if (typeof s === 'string' && s.length > 0) {\n try {\n const p = JSON.parse(s);\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as T;\n } catch {\n // fall through to fallback\n }\n }\n return fallback;\n}\n","import type { SQLiteAdapter, WikiFact, EmbeddingMarkerKind } from '../types';\nimport { WikiGraphNodeOwnershipConflict } from '../types';\nimport { BaseRepository } from './BaseRepository';\nimport { OutboxRepository } from './OutboxRepository';\nimport { parseJsonArray, parseJsonObject } from './rowMappers';\nimport { isStaleAfter, deriveTrustTier } from '@equationalapplications/core-okf';\n\nexport type EntryRowMetadata = {\n id: string;\n entity_id: string;\n updated_at: number | null;\n access_count: number | null;\n};\n\nexport type EntryRowWithEmbeddings = EntryRowMetadata & {\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n};\n\n/**\n * One row of the reembed candidate scan. `findAllForReembed` does `SELECT *`,\n * so the marker columns come back at runtime; naming them here makes that\n * dependency visible to the compiler instead of hiding it behind a cast in\n * MaintenanceService.runReembed (spec §4.4).\n */\nexport type ReembedCandidateRow = WikiFact & {\n embedding_blob?: Uint8Array | null;\n embedding_failed_at?: number | null;\n embedding_failure_kind?: string | null;\n embedding_attempts?: number | null;\n};\n\nfunction mapRowToFact(row: any): WikiFact {\n const tags: string[] = (() => {\n if (Array.isArray(row.tags)) return row.tags;\n try { const p = JSON.parse(row.tags as string); if (Array.isArray(p)) return p; } catch {}\n return [];\n })();\n\n const okf_verified = parseJsonArray<NonNullable<WikiFact['okf_verified']>[number]>(row.okf_verified, []);\n // Hydrate per spec §2.7 + §5.3: surface isStale/trustTier so hosts don't have to\n // re-call the core-okf helpers. Sampled once per row rather than once per call\n // because `now` here means \"as of this hydration\" — using a stable per-call\n // value would shift staleness while we're mapping sibling rows in the same\n // read. Date.now() is cheap enough that per-row sampling is fine.\n const now = Date.now();\n const staleAfterRaw = row.stale_after != null ? Number(row.stale_after) : null;\n\n return {\n id: row.id,\n entity_id: row.entity_id,\n title: row.title,\n body: row.body,\n tags,\n confidence: row.confidence,\n source_type: row.source_type,\n source_hash: row.source_hash ?? null,\n source_ref: row.source_ref ?? null,\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at),\n last_accessed_at: (row.last_accessed_at === null || row.last_accessed_at === undefined)\n ? null\n : Number(row.last_accessed_at),\n deleted_at: row.deleted_at != null ? Number(row.deleted_at) : null,\n access_count: Number(row.access_count ?? 0),\n okf_type: row.okf_type ?? null,\n // OKF v0.2\n lifecycle_status: (row.lifecycle_status ?? 'stable') as WikiFact['lifecycle_status'],\n stale_after: staleAfterRaw,\n generated_by: row.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiFact['okf_sources']>[number]>(row.okf_sources, []),\n okf_verified,\n okf_usage_window: parseJsonObject<NonNullable<WikiFact['okf_usage_window']>>(row.okf_usage_window),\n last_verified_at: row.last_verified_at != null ? Number(row.last_verified_at) : null,\n last_verified_by: row.last_verified_by ?? null,\n // Spec §2.7 + §5.3: hydrate so read() consumers don't re-call the helpers.\n isStale: isStaleAfter(staleAfterRaw, now),\n trustTier: deriveTrustTier(okf_verified),\n };\n}\n\nfunction normalizeEmbeddingBlobValue(blob: unknown): Uint8Array | null {\n if (blob instanceof Uint8Array) return blob;\n if (blob !== null && blob !== undefined && typeof blob === 'object') {\n const obj = blob as Record<string, unknown>;\n if (obj['type'] === 'Buffer' && Array.isArray(obj['data'])) {\n return new Uint8Array(obj['data'] as number[]);\n }\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every((k) => /^\\d+$/.test(k))) {\n const len = entries.length;\n const arr = new Uint8Array(len);\n for (let i = 0; i < len; i++) arr[i] = (obj[String(i)] as number) ?? 0;\n return arr;\n }\n }\n return null;\n}\n\n/** Mapper that preserves embedding_blob for export/import round-tripping. */\nfunction mapRowToFactWithBlobs(row: any): WikiFact {\n const base = mapRowToFact(row);\n const embeddingBlob = normalizeEmbeddingBlobValue(row.embedding_blob);\n return embeddingBlob ? { ...base, embedding_blob: embeddingBlob } : base;\n}\n\n\nexport class EntryRepository extends BaseRepository {\n private chunkSize = 500;\n\n constructor(db: SQLiteAdapter, prefix: string, private outbox: OutboxRepository) {\n super(db, prefix);\n }\n\n /**\n * Fetch facts by IDs, optionally scoped to entity IDs.\n * Returns facts in the order of the input IDs (first match wins).\n */\n async findByIds(\n ids: readonly string[],\n scopedEntityIds?: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows: any[] = [];\n const entityClause = scopedEntityIds && scopedEntityIds.length > 0\n ? ` AND entity_id IN (${scopedEntityIds.map(() => '?').join(',')})`\n : '';\n const entityParams = scopedEntityIds ?? [];\n\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE id IN (${placeholders})${entityClause} AND deleted_at IS NULL`,\n [...chunk, ...entityParams],\n );\n rows.push(...chunkRows);\n }\n\n const byId = new Map(rows.map(r => [r.id, r]));\n return ids\n .map(id => byId.get(id))\n .filter((r): r is any => r !== undefined)\n .map(mapRowToFact);\n }\n\n /**\n * Upsert a WikiFact. Nullable fields set to null when fact value is null.\n * Returns { changes, lastInsertRowId }.\n * `tx` is REQUIRED to ensure atomic outbox staging.\n *\n * OKF metadata discipline (spec §2.5 + DAO checklist §8): content writes\n * MUST NOT silently overwrite OKF metadata that a caller didn't supply. The\n * previous CASE WHEN IS NULL guards around `lifecycle_status`, etc. were\n * dead because the bind always supplied a non-null value (notably\n * `fact.lifecycle_status ?? 'stable'`), so excluded.X was never NULL and\n * an UPDATE rewrote an existing `deprecated` row to `stable`. We now omit\n * these columns from the SET clause entirely — SQLite's ON CONFLICT UPDATE\n * leaves untouched columns at their existing row value, which is exactly\n * the preservation semantics we want for content writes. Callers that\n * intentionally want to overwrite OKF metadata should use\n * {@link upsertForImport} (always-replace semantics for that path).\n * New-row INSERTs still bind a value so the column is populated; if the\n * caller supplied nothing, the schema DEFAULT 'stable' applies when the\n * bind is bound as 'stable' explicitly here.\n *\n * Marker discipline (spec §4.1): a conflict carrying a real\n * `embedding_blob` clears the embedding failure markers, because the row now\n * HAS a valid embedding and a surviving marker would be a self-contradictory\n * diagnostic that inflates runReembed's permanentlyFailed counter. A conflict\n * with no blob leaves marker state alone, matching the \"absent means don't\n * touch\" semantics used for embedding_blob itself.\n *\n * Graph node ownership (spec §2.4 + §3, REQ-OWN-01 + REQ-GRAPH-01): entry\n * IDs share one database-wide namespace, so an ID stays owned by its\n * existing entity for as long as the row exists — soft deletion included.\n * The pre-write lookup already reads the existing row for OKF metadata; we\n * project `entity_id` off that same SELECT and reject the write before\n * any outbox payload construction when the stored owner differs from\n * `fact.entity_id`. Soft-deleted foreign rows keep their IDs reserved;\n * permanent reservation is NOT introduced, so a physically absent ID may\n * still be inserted under the requested entity. The ON CONFLICT UPDATE SET\n * clause carries a final `WHERE entries.entity_id = excluded.entity_id`\n * guard so the database itself refuses a cross-owner row overwrite even if\n * a future caller bypasses the pre-write check. When `runAsync` reports\n * 0 changes (a legitimate conflict-suppressed write, OR an adapter that\n * under-reports a permitted write) we re-read the stored owner; only a\n * foreign owner throws — this is local defensive behavior, not permission\n * for adapters to under-report. The thrown error is\n * `WikiGraphNodeOwnershipConflict` (no owner, node ID, or stored content\n * is disclosed). Upserts that pass both gates retain existing same-entity\n * update + resurrection semantics.\n */\n async upsert(fact: WikiFact, tx: SQLiteAdapter): Promise<{ changes: number; lastInsertRowId: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const tagsJson = JSON.stringify(fact.tags);\n const embeddingBlob = this.normalizeEmbeddingBlob(fact.embedding_blob);\n\n const existingRow = await executor.getFirstAsync<{\n id: string;\n entity_id: string;\n lifecycle_status: string;\n stale_after: number | null;\n generated_by: string | null;\n okf_sources: string | null;\n okf_verified: string | null;\n okf_usage_window: string | null;\n last_verified_at: number | null;\n last_verified_by: string | null;\n }>(\n `SELECT id, entity_id, lifecycle_status, stale_after, generated_by,\n okf_sources, okf_verified, okf_usage_window,\n last_verified_at, last_verified_by\n FROM ${this.prefix}entries WHERE id = ?`,\n [fact.id],\n );\n\n // Entry IDs share one global namespace, so an ID stays owned by its\n // existing entity for as long as the row exists — soft deletion included.\n // Reject here, before any write or outbox payload construction. This costs\n // one extra column on a SELECT the method already ran, not a new query.\n if (existingRow && existingRow.entity_id !== fact.entity_id) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n\n const operation = fact.deleted_at ? 'DELETE' : (existingRow ? 'UPDATE' : 'INSERT');\n\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entries (\n id, entity_id, title, body, tags, confidence, source_type,\n source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count,\n deleted_at, embedding_blob, embedding, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n title = excluded.title,\n body = excluded.body,\n tags = excluded.tags,\n confidence = excluded.confidence,\n source_type = excluded.source_type,\n source_hash = excluded.source_hash,\n source_ref = excluded.source_ref,\n updated_at = excluded.updated_at,\n last_accessed_at = excluded.last_accessed_at,\n access_count = excluded.access_count,\n deleted_at = excluded.deleted_at,\n embedding_blob = CASE WHEN excluded.embedding_blob IS NULL THEN embedding_blob ELSE excluded.embedding_blob END,\n embedding = NULL,\n embedding_failed_at = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failed_at END,\n embedding_failure_kind = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failure_kind END,\n embedding_attempts = CASE WHEN excluded.embedding_blob IS NOT NULL THEN 0 ELSE embedding_attempts END,\n okf_type = excluded.okf_type\n WHERE ${this.prefix}entries.entity_id = excluded.entity_id`,\n [\n fact.id,\n fact.entity_id,\n fact.title,\n fact.body,\n tagsJson,\n fact.confidence,\n fact.source_type,\n fact.source_hash,\n fact.source_ref,\n fact.created_at,\n now,\n fact.last_accessed_at === null ? null : fact.last_accessed_at,\n fact.access_count,\n fact.deleted_at ?? null,\n embeddingBlob ?? null,\n null,\n fact.okf_type ?? null,\n // OKF v0.2 metadata — bound for INSERT only; ON CONFLICT UPDATE\n // preserves the existing row values (these columns are intentionally\n // absent from the SET clause above).\n fact.lifecycle_status ?? 'stable',\n fact.stale_after ?? null,\n fact.generated_by ?? null,\n fact.last_verified_at ?? null,\n fact.last_verified_by ?? null,\n fact.okf_sources ? JSON.stringify(fact.okf_sources) : null,\n fact.okf_verified ? JSON.stringify(fact.okf_verified) : null,\n fact.okf_usage_window ? JSON.stringify(fact.okf_usage_window) : null,\n ],\n );\n\n // A suppressed conflict-update reports 0 (see the SQLiteAdapter contract).\n // A permitted write that an adapter under-reports as 0 also lands here, so\n // confirm ownership from the stored row rather than inferring it from the\n // count. A foreign owner rejects; a missing row means the adapter dropped\n // the write (impossible under real SQLite), so fail rather than publish an\n // outbox event for state that does not exist.\n if (result.changes === 0) {\n const stored = await tx.getFirstAsync<{ entity_id: string }>(\n `SELECT entity_id FROM ${this.prefix}entries WHERE id = ?`,\n [fact.id],\n );\n if (!stored) {\n throw new Error('Entry upsert reported no change and stored no row; the SQLiteAdapter did not perform the write');\n }\n if (stored.entity_id !== fact.entity_id) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n }\n\n // Outbox payload mirrors what is actually persisted. On UPDATE, the SET\n // clause intentionally omits the OKF metadata columns so the prior row\n // values win — so `fact.X` here would describe state we did NOT write.\n // Re-read those columns from the stored row and overlay them onto the\n // caller-supplied payload before publishing (#90 review).\n const persistedOkf = existingRow\n ? {\n lifecycle_status: (existingRow.lifecycle_status ?? 'stable') as WikiFact['lifecycle_status'],\n stale_after: existingRow.stale_after != null ? Number(existingRow.stale_after) : null,\n generated_by: existingRow.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiFact['okf_sources']>[number]>(existingRow.okf_sources, []),\n okf_verified: parseJsonArray<NonNullable<WikiFact['okf_verified']>[number]>(existingRow.okf_verified, []),\n okf_usage_window: parseJsonObject<NonNullable<WikiFact['okf_usage_window']>>(existingRow.okf_usage_window),\n last_verified_at: existingRow.last_verified_at != null ? Number(existingRow.last_verified_at) : null,\n last_verified_by: existingRow.last_verified_by ?? null,\n }\n : null;\n await this.outbox.push({\n entityId: fact.entity_id,\n tableName: 'entries',\n recordId: fact.id,\n operation,\n payload: persistedOkf ? { ...fact, ...persistedOkf } : fact,\n }, tx);\n\n return result;\n }\n\n /**\n * Normalize an embedding blob value to Uint8Array or null.\n */\n private normalizeEmbeddingBlob(blob: unknown): Uint8Array | null {\n return normalizeEmbeddingBlobValue(blob);\n }\n\n /**\n * Fetch existing rows by IDs and return id/entity_id/updated_at for import collision resolution.\n */\n async findExistingMetadataByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; updated_at: number }>> {\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; entity_id: string; updated_at: number }> = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}entries WHERE id IN (${placeholders})`,\n chunk,\n );\n rows.push(...chunkRows.map((row) => ({ id: row.id, entity_id: row.entity_id, updated_at: Number(row.updated_at) })));\n }\n return rows;\n }\n\n async findIdById(id: string, entityId: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ?`,\n [id, entityId],\n );\n return row?.id ?? null;\n }\n\n async findIdsBySource(\n entityId: string,\n sourceRef: string | null,\n sourceHash: string | null,\n tx?: SQLiteAdapter,\n includeDeleted = false,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n let sql = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ?`;\n const args: unknown[] = [entityId];\n if (sourceRef !== null) {\n sql += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash !== null) {\n sql += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n if (!includeDeleted) {\n sql += ` AND deleted_at IS NULL`;\n }\n const rows = await executor.getAllAsync<{ id: string }>(sql, args);\n return rows.map((row) => row.id);\n }\n\n async upsertForImport(fact: WikiFact, tx: SQLiteAdapter): Promise<{ changes: number; lastInsertRowId: number }> {\n const executor = this.getExecutor(tx);\n const tagsJson = JSON.stringify(fact.tags);\n const embeddingBlob = this.normalizeEmbeddingBlob(fact.embedding_blob);\n\n // Import is replace semantics: a re-imported fact whose OKF metadata\n // cleared (stale_after removed, generated_by removed, etc.) MUST overwrite\n // the prior row's value. The previous CASE WHEN IS NULL guards preserved\n // the old database values instead, so an \"absent in dump\" never cleared.\n // Direct `= excluded.X` ensures the dump is authoritative.\n //\n // WARNING: unlike `upsert`, this SQL re-parents a conflicting row\n // (`entity_id = excluded.entity_id`, no owner predicate). It is safe only\n // because ImportExportService skips foreign-owned IDs before calling it.\n // Do not model a new write path on this method; use `upsert`.\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entries (\n id, entity_id, title, body, tags, confidence, source_type,\n source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count,\n deleted_at, embedding_blob, embedding, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n title = excluded.title,\n body = excluded.body,\n tags = excluded.tags,\n confidence = excluded.confidence,\n source_type = excluded.source_type,\n source_hash = excluded.source_hash,\n source_ref = excluded.source_ref,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at,\n last_accessed_at = excluded.last_accessed_at,\n access_count = excluded.access_count,\n deleted_at = excluded.deleted_at,\n embedding_blob = excluded.embedding_blob,\n embedding = NULL,\n embedding_failed_at = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failed_at END,\n embedding_failure_kind = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failure_kind END,\n embedding_attempts = CASE WHEN excluded.embedding_blob IS NOT NULL THEN 0 ELSE embedding_attempts END,\n okf_type = excluded.okf_type,\n lifecycle_status = excluded.lifecycle_status,\n stale_after = excluded.stale_after,\n generated_by = excluded.generated_by,\n last_verified_at = excluded.last_verified_at,\n last_verified_by = excluded.last_verified_by,\n okf_sources = excluded.okf_sources,\n okf_verified = excluded.okf_verified,\n okf_usage_window = excluded.okf_usage_window`,\n [\n fact.id,\n fact.entity_id,\n fact.title,\n fact.body,\n tagsJson,\n fact.confidence,\n fact.source_type,\n fact.source_hash,\n fact.source_ref,\n fact.created_at,\n fact.updated_at,\n fact.last_accessed_at === null ? null : fact.last_accessed_at,\n fact.access_count,\n fact.deleted_at ?? null,\n embeddingBlob ?? null,\n null,\n fact.okf_type ?? null,\n // Same NOT NULL DEFAULT note as in upsert above.\n fact.lifecycle_status ?? 'stable',\n fact.stale_after ?? null,\n fact.generated_by ?? null,\n fact.last_verified_at ?? null,\n fact.last_verified_by ?? null,\n fact.okf_sources ? JSON.stringify(fact.okf_sources) : null,\n fact.okf_verified ? JSON.stringify(fact.okf_verified) : null,\n fact.okf_usage_window ? JSON.stringify(fact.okf_usage_window) : null,\n ],\n );\n\n return result;\n }\n\n /**\n * Soft-delete a single entry by ID scoped to entityId. Sets deleted_at + updated_at.\n * `tx` is REQUIRED to ensure atomic outbox staging.\n */\n async softDelete(entryId: string, entityId: string, tx: SQLiteAdapter): Promise<{ changes: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, entryId, entityId],\n );\n\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: entryId,\n operation: 'DELETE',\n payload: { id: entryId, entity_id: entityId, deleted_at: now },\n }, tx);\n\n return result;\n }\n\n /**\n * Soft-delete entries by source_ref and/or source_hash within a transaction.\n * Stages a DELETE outbox entry for each row in the same transaction.\n * `tx` is REQUIRED.\n * Returns the number of rows deleted.\n */\n async softDeleteBySource(\n entityId: string,\n tx: SQLiteAdapter,\n sourceRef?: string | null,\n sourceHash?: string | null,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n\n let q = `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: any[] = [now, now, entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n\n // Build a separate SELECT query to get affected IDs before updating\n let selectQ = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`;\n const selectArgs: any[] = [entityId];\n if (sourceRef) {\n selectQ += ` AND source_ref = ?`;\n selectArgs.push(sourceRef);\n }\n if (sourceHash) {\n selectQ += ` AND source_hash = ?`;\n selectArgs.push(sourceHash);\n }\n\n const idsToDelete = await executor.getAllAsync<{ id: string }>(selectQ, selectArgs);\n\n const result = await executor.runAsync(q, args);\n\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n\n return result.changes;\n }\n\n /**\n * Fetch IDs + entity_ids of soft-deleted rows older than cutoff for a given entity.\n * Used by runPrune().\n */\n async getPrunableMetadata(\n entityId: string,\n cutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string }>> {\n const executor = this.getExecutor(tx);\n return executor.getAllAsync<{ id: string; entity_id: string }>(\n `SELECT id, entity_id FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n }\n\n /**\n * Fetch all non-deleted entries for an entity, ordered by updated_at DESC.\n * Used by _getFullBundle().\n */\n async findAllByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId],\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Fetch live, mutable entries for an entity — everything heal is allowed to\n * downgrade or delete — oldest first, capped at `limit`, skipping anything\n * stamped inside the recheck cooldown (heal_checked_at > recheckCutoff).\n *\n * Oldest-first rather than newest-first: with a cooldown in place, newest-first\n * would keep re-selecting recently-touched facts every pass while older ones\n * wait indefinitely to even enter a batch.\n */\n async findHealCandidatesByEntityId(\n entityId: string,\n limit: number,\n recheckCutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'\n AND (heal_checked_at IS NULL OR heal_checked_at <= ?)\n ORDER BY updated_at ASC LIMIT ?`,\n [entityId, recheckCutoff, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Resolve search hits to document anchors. The MiniSearch index holds every\n * fact, not only immutable_document rows, so the source-type restriction has\n * to be applied here, after retrieval.\n */\n async findAnchorRowsByIds(\n entityId: string,\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; title: string; source_ref: string | null }>> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; title: string; source_ref: string | null }> = [];\n // Chunked like every other multi-id read here. The current caller stays well\n // under SQLITE_MAX_VARIABLE_NUMBER, but that is a property of the caller,\n // not of this method.\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(', ');\n const chunkRows = await executor.getAllAsync<{ id: string; title: string; source_ref: string | null }>(\n `SELECT id, title, source_ref FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND source_type = 'immutable_document'\n AND id IN (${placeholders})`,\n [entityId, ...chunk],\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n /**\n * Fetch recent non-deleted entries for an entity (limited), ordered by updated_at DESC.\n * Used by MaintenanceService.doRunLibrarian().\n *\n * When `excludeSourceRef` is supplied, the WHERE clause filters out that\n * sourceRef BEFORE applying LIMIT. The caller in IngestionService is\n * `findRecentByEntityId(entityId, 500, tx)` — it discards same-sourceRef\n * rows after the read to build a cross-sourceRef title index. If those\n * rows are filtered out in SQL, the limit applies to usable rows only\n * and a re-ingest where the caller's sourceRef owns most recent facts\n * still leaves cross-sourceRef entries in the index.\n */\n async findRecentByEntityId(\n entityId: string,\n limit: number,\n tx?: SQLiteAdapter,\n excludeSourceRef?: string,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n // `IS NULL OR !=` keeps NULL-source_ref rows (e.g. librarian_inferred facts)\n // in the cross-sourceRef title index. The intent of `excludeSourceRef` is\n // \"drop THIS sourceRef's rows\"; NULL rows belong to neither the current\n // sourceRef nor the replacement set, and excluding them causes edges\n // targeting legacy/non-document facts to fail to resolve.\n const excludeClause = excludeSourceRef ? ` AND (source_ref IS NULL OR source_ref != ?)` : '';\n const args: unknown[] = excludeSourceRef ? [entityId, excludeSourceRef, limit] : [entityId, limit];\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL${excludeClause} ORDER BY updated_at DESC LIMIT ?`,\n args,\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Fetch all non-deleted entries for an entity with embedding blobs preserved.\n * Used by ImportExportService for export/import round-tripping.\n */\n async findAllByEntityIdWithBlobs(entityId: string, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId],\n );\n return rows.map(mapRowToFactWithBlobs);\n }\n\n /**\n * Count non-deleted entries for the given entities whose embedding_blob dimension\n * doesn't match queryVecLength. Used by read() to detect model-switch mismatches.\n */\n async countDimensionMismatched(\n entityIds: readonly string[],\n queryVecLength: number,\n tx?: SQLiteAdapter,\n ): Promise<number> {\n if (entityIds.length === 0) return 0;\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL\n AND embedding_blob IS NOT NULL\n AND (CAST(length(embedding_blob) AS INTEGER) % 4 = 0)\n AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?`,\n [...entityIds, queryVecLength],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count non-deleted entries for entityId that are stale relative to targetDim\n * (either no blob or wrong dimension). Used by runReembed() per-entity skip logic.\n */\n async countStaleForEntity(entityId: string, targetDim: number, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND (\n embedding_blob IS NULL\n OR (CAST(length(embedding_blob) AS INTEGER) / 4) != ?\n )`,\n [entityId, targetDim],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count non-deleted entries with stale or unconverted embeddings relative to `dim`.\n * Used by _reconcileEmbeddingDimension() to decide when to promote the pending\n * embedding_dimension value.\n */\n async countStaleEmbeddings(dim: number, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE deleted_at IS NULL\n AND (\n (embedding_blob IS NOT NULL AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?)\n OR (embedding_blob IS NULL AND embedding IS NOT NULL)\n )`,\n [dim],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Bulk delete pruned entries (already soft-deleted) by IDs.\n * Used by runPrune(). Returns total number of deleted rows.\n * `tx` is REQUIRED so outbox deletion events are staged atomically.\n */\n async bulkDeletePruned(\n entityId: string,\n cutoff: number,\n ids: string[],\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n let totalChanges = 0;\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ? AND id IN (${placeholders})`,\n [entityId, cutoff, ...chunk],\n );\n totalChanges += result.changes;\n // Stage outbox entries for permanently deleted records\n if (result.changes > 0) {\n for (const id of chunk) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: cutoff },\n }, tx);\n }\n }\n }\n return totalChanges;\n }\n\n /**\n * Mark orphaned entries (never accessed, old) as deleted.\n * Used by MaintenanceService.doRunHeal().\n */\n async markOrphaned(\n entityId: string,\n orphanThreshold: number,\n tx: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const updatedRows = await executor.getAllAsync<{ id: string }>(\n `UPDATE ${this.prefix}entries\n SET deleted_at = ?, updated_at = ?\n WHERE entity_id = ? AND access_count = 0 AND created_at <= ? AND source_type != 'immutable_document' AND deleted_at IS NULL\n RETURNING id`,\n [now, now, entityId, orphanThreshold],\n );\n for (const row of updatedRows) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return updatedRows.map(r => r.id);\n }\n\n /**\n * Downgrade stale inferred entries to 'tentative'.\n * Used by MaintenanceService.doRunHeal().\n *\n * Returns the ids it downgraded so the caller can fold them into\n * {@link HealResult.downgraded} without double-counting a fact the model also\n * downgraded in the same pass.\n */\n async downgradeStaleInferred(\n entityId: string,\n staleThreshold: number,\n tx: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const eligibleRows = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE entity_id = ? AND confidence = 'inferred'\n AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?))\n AND source_type != 'immutable_document' AND deleted_at IS NULL`,\n [entityId, staleThreshold, staleThreshold],\n );\n if (eligibleRows.length === 0) return [];\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET confidence = 'tentative', updated_at = ?\n WHERE entity_id = ? AND confidence = 'inferred' AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?)) AND source_type != 'immutable_document' AND deleted_at IS NULL`,\n [now, entityId, staleThreshold, staleThreshold],\n );\n for (const row of eligibleRows) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'UPDATE',\n payload: { id: row.id, entity_id: entityId, confidence: 'tentative', updated_at: now },\n }, tx);\n }\n return eligibleRows.map(r => r.id);\n }\n\n /**\n * Downgrade specific entries to 'tentative' by IDs.\n * Used by MaintenanceService.doRunHeal().\n */\n async downgradeByIds(\n ids: string[],\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const placeholders = ids.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET confidence = 'tentative', updated_at = ? WHERE id IN (${placeholders}) AND entity_id = ?`,\n [now, ...ids, entityId],\n );\n // Stage outbox entries for downgraded records\n for (const id of ids) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'UPDATE',\n payload: { id, entity_id: entityId, confidence: 'tentative', updated_at: now },\n }, tx);\n }\n }\n\n /**\n * Soft-delete specific entries by IDs.\n * Used by MaintenanceService.doRunHeal().\n */\n async softDeleteByIds(\n ids: string[],\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const placeholders = ids.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id IN (${placeholders}) AND entity_id = ?`,\n [now, now, ...ids, entityId],\n );\n // Stage outbox entries for soft-deleted records\n for (const id of ids) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n }\n\n /**\n * Bulk soft-delete all entries for an entity.\n * Stages DELETE outbox entries for each row in the same transaction.\n * `tx` is REQUIRED.\n */\n async bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n // Get IDs before updating for outbox staging\n const idsToDelete = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId],\n );\n // Stage outbox entries for each deleted record\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return result.changes;\n }\n\n async findMiniSearchRows(\n entityId?: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; title: string; body: string; tags: string }>> {\n const executor = this.getExecutor(tx);\n if (entityId !== undefined) {\n return executor.getAllAsync(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL AND entity_id = ?`,\n [entityId],\n );\n }\n return executor.getAllAsync(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL`,\n );\n }\n\n async updateEmbeddingBlob(id: string, blob: Uint8Array, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_blob = ?,\n embedding = NULL,\n embedding_failed_at = NULL,\n embedding_failure_kind = NULL,\n embedding_attempts = 0\n WHERE id = ?`,\n [blob, id],\n );\n }\n\n /**\n * Record a failed embedding attempt. Deliberately does NOT touch updated_at\n * (import merge is last-write-wins on it) and pushes no outbox event —\n * embedding lifecycle is local state, not replicated. Same discipline as\n * updateEmbeddingBlob. See spec §3.5.\n *\n * Only marker-eligible kinds (spec §3.3) are accepted: `no_provider` never\n * marks and `storage_error` never marks, so retry/permanent-failure policy\n * built on these rows only ever sees real embed failures.\n */\n async markEmbeddingFailure(\n id: string,\n kind: EmbeddingMarkerKind,\n now: number,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_failed_at = ?,\n embedding_failure_kind = ?,\n embedding_attempts = embedding_attempts + 1\n WHERE id = ?`,\n [now, kind, id],\n );\n }\n\n /**\n * Clear marker state for every marked row. Called when the embedding\n * dimension is promoted: a new model produces different vectors, so past\n * failures — including `float32_overflow`, which is otherwise terminal —\n * no longer predict future ones (spec §2.3).\n *\n * Same discipline as markEmbeddingFailure: no `updated_at` touch and no\n * outbox event, because embedding lifecycle is local state, not replicated.\n * Returns the number of rows cleared.\n */\n async clearEmbeddingFailureMarkers(tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_failed_at = NULL,\n embedding_failure_kind = NULL,\n embedding_attempts = 0\n WHERE embedding_failed_at IS NOT NULL`,\n );\n return result.changes;\n }\n\n async hasLegacySourceTypes(tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ one: number }>(\n `SELECT 1 AS one FROM ${this.prefix}entries WHERE source_type IN ('user_document', 'agent_inferred') LIMIT 1`,\n [],\n );\n return row != null;\n }\n\n async countLegacySourceTypes(tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}entries WHERE source_type IN ('user_document', 'agent_inferred')`,\n [],\n );\n return row?.count ?? 0;\n }\n\n async findAllForReembed(entityId?: string, tx?: SQLiteAdapter): Promise<ReembedCandidateRow[]> {\n const executor = this.getExecutor(tx);\n if (entityId !== undefined) {\n return executor.getAllAsync(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n }\n return executor.getAllAsync(\n `SELECT * FROM ${this.prefix}entries WHERE deleted_at IS NULL`,\n );\n }\n\n async findRowsForSourceRefMigration(tx?: SQLiteAdapter): Promise<Array<{ rowid: number; source_ref: string }>> {\n const executor = this.getExecutor(tx);\n return executor.getAllAsync(\n `SELECT rowid, source_ref FROM ${this.prefix}entries\n WHERE source_ref IS NOT NULL\n AND (\n TRIM(source_ref) != source_ref\n OR INSTR(source_ref, '/') > 0\n OR INSTR(source_ref, '\\\\') > 0\n OR INSTR(source_ref, CHAR(0)) > 0\n OR source_ref GLOB '*[^-A-Za-z0-9._ ]*'\n )`,\n );\n }\n\n async updateSourceRefByRowid(rowid: number, sourceRef: string | null, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET source_ref = ? WHERE rowid = ?`,\n [sourceRef, rowid],\n );\n }\n\n async findLatestSourceHash(entityId: string, sourceRef: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ source_hash: string | null }>(\n `SELECT source_hash FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC, id ASC\n LIMIT 1`,\n [entityId, sourceRef],\n );\n return row?.source_hash ?? null;\n }\n\n /**\n * Batch version of {@link findLatestSourceHash}. Returns a Map covering every\n * requested ref, where the value is the source_hash from the row with the\n * most-recently-updated live fact for that ref, or null when no live row exists.\n *\n * The SQL uses ROW_NUMBER() OVER (PARTITION BY source_ref ORDER BY updated_at\n * DESC, id ASC) — NOT MAX(source_hash). Aggregation with MAX(source_hash) is\n * wrong because MAX computes independently across grouped rows; the hash must\n * come from the exact row that wins MAX(updated_at). The `id ASC` tie-break\n * keeps selection deterministic when two live rows share `updated_at`.\n *\n * Source refs are de-duplicated and processed in chunks so the per-query bind\n * parameter count stays under SQLite's `SQLITE_MAX_VARIABLE_NUMBER` (default\n * 999, leaving one slot for `entity_id`).\n *\n * Empty input is a synchronous early return with zero SQL calls.\n */\n async findLatestSourceHashes(\n entityId: string,\n sourceRefs: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Map<string, string | null>> {\n const out = new Map<string, string | null>();\n if (sourceRefs.length === 0) return out;\n // Pre-populate with null for every requested ref so callers can distinguish\n // \"no live row\" (null) from \"row with a null source_hash\" (also null in this\n // shape, but at least the key is guaranteed present).\n const dedupedRefs = Array.from(new Set(sourceRefs));\n for (const ref of dedupedRefs) {\n out.set(ref, null);\n }\n const executor = this.getExecutor(tx);\n // 1 bind parameter for entity_id; remaining slots for source_ref placeholders.\n const chunkLimit = Math.max(1, this.chunkSize - 1);\n for (let i = 0; i < dedupedRefs.length; i += chunkLimit) {\n const chunk = dedupedRefs.slice(i, i + chunkLimit);\n const placeholders = chunk.map(() => '?').join(',');\n const rows = await executor.getAllAsync<{ source_ref: string; source_hash: string | null }>(\n `WITH ranked AS (\n SELECT source_ref, source_hash,\n ROW_NUMBER() OVER (\n PARTITION BY source_ref\n ORDER BY updated_at DESC, id ASC\n ) as rn\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref IN (${placeholders}) AND deleted_at IS NULL\n )\n SELECT source_ref, source_hash\n FROM ranked\n WHERE rn = 1`,\n [entityId, ...chunk],\n );\n for (const r of rows) {\n out.set(r.source_ref, r.source_hash);\n }\n }\n return out;\n }\n\n /**\n * Return the live source_refs for an entity that hold the given source_hash.\n * Used by the ingestDocument duplicate-hash guard and by hosts auditing\n * duplicate-content collisions. Sorted `COLLATE BINARY` so the canonical\n * ref (the code-unit-minimum of the set) is stable across deploys.\n */\n async findSourceRefsByHash(\n entityId: string,\n sourceHash: string,\n tx?: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ source_ref: string }>(\n `SELECT source_ref FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_hash = ? AND deleted_at IS NULL\n AND source_ref IS NOT NULL\n GROUP BY source_ref\n ORDER BY source_ref COLLATE BINARY`,\n [entityId, sourceHash],\n );\n return rows.map(r => r.source_ref);\n }\n\n /**\n * Per-sourceRef rollup for an entity: one row per live source_ref, with the\n * most-recently-updated live hash (NOT the lexically-max hash) and a live\n * fact count.\n *\n * The hash comes from the same row that wins ROW_NUMBER() over updated_at\n * DESC, so a ref with multiple live hashes (e.g. from import) reports the\n * latest one — matching single-doc `findLatestSourceHash` semantics.\n *\n * Sort is COLLATE BINARY: locale-dependent ordering re-mints identity on\n * every deploy, which is the bug this whole section exists to prevent.\n */\n async listSourceRefs(\n entityId: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{\n sourceRef: string;\n sourceHash: string | null;\n factCount: number;\n lastIngestedAt: number;\n }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{\n source_ref: string;\n source_hash: string | null;\n fact_count: number;\n last_ingested_at: number;\n }>(\n `WITH ranked AS (\n SELECT source_ref, source_hash, updated_at,\n ROW_NUMBER() OVER (\n PARTITION BY source_ref\n ORDER BY updated_at DESC, id ASC\n ) AS rn,\n COUNT(*) OVER (PARTITION BY source_ref) AS fact_count\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_ref IS NOT NULL\n )\n SELECT source_ref,\n source_hash AS source_hash,\n fact_count AS fact_count,\n updated_at AS last_ingested_at\n FROM ranked\n WHERE rn = 1\n ORDER BY source_ref COLLATE BINARY`,\n [entityId],\n );\n return rows.map(r => ({\n sourceRef: r.source_ref,\n sourceHash: r.source_hash,\n factCount: Number(r.fact_count),\n lastIngestedAt: Number(r.last_ingested_at),\n }));\n }\n\n /**\n * Count live entries for an entity across all source_refs/source_hashes.\n * Used by forget({ dryRun, clearAll: true }).\n */\n async countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count live entries matching a source filter (either or both may be null).\n * Used by forget({ dryRun: true }) with sourceRef/sourceHash.\n */\n async countLiveBySource(\n entityId: string,\n sourceRef: string | null,\n sourceHash: string | null,\n tx?: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n let q = `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: unknown[] = [entityId];\n if (sourceRef !== null) { q += ` AND source_ref = ?`; args.push(sourceRef); }\n if (sourceHash !== null) { q += ` AND source_hash = ?`; args.push(sourceHash); }\n const row = await executor.getFirstAsync<{ cnt: number }>(q, args);\n return row?.cnt ?? 0;\n }\n\n async findMetadataByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: EntryRowMetadata[] = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<EntryRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async findWithEmbeddingsByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: EntryRowWithEmbeddings[] = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<EntryRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async findMetadataByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n return executor.getAllAsync<EntryRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL`,\n [...entityIds],\n );\n }\n\n async findWithEmbeddingsByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n return executor.getAllAsync<EntryRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL`,\n [...entityIds],\n );\n }\n\n async findEmbeddingsByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }> = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>(\n `SELECT id, embedding_blob, embedding FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async trackAccess(ids: readonly string[], now: number, tx?: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET access_count = access_count + 1, last_accessed_at = ? WHERE id IN (${placeholders})`,\n [now, ...chunk],\n );\n }\n }\n\n getLegacyMigrationSQL(): string {\n return [\n `-- Migrate legacy source_type values (targets your WikiMemory prefix: ${this.prefix})`,\n `UPDATE ${this.prefix}entries SET source_type = 'immutable_document' WHERE source_type = 'user_document';`,\n `UPDATE ${this.prefix}entries SET source_type = 'librarian_inferred' WHERE source_type = 'agent_inferred';`,\n ].join('\\n');\n }\n\n async findRecentByEntityIds(\n entityIds: readonly string[],\n limit: number,\n tx?: SQLiteAdapter,\n opts?: { excludeDrafts?: boolean },\n ): Promise<WikiFact[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const draftClause = opts?.excludeDrafts === true ? ` AND lifecycle_status != 'draft'` : '';\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL${draftClause} ORDER BY updated_at DESC LIMIT ?`,\n [...entityIds, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /** IDs of live draft facts for the given entities (spec §5.1). Callers pass ≤ 100 entity ids. */\n async findDraftIdsByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<Set<string>> {\n if (entityIds.length === 0) return new Set();\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const rows = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL AND lifecycle_status = 'draft'`,\n [...entityIds],\n );\n return new Set(rows.map((r) => r.id));\n }\n\n /** Live drafts for one entity, newest first, keyset-paged by (created_at, id). */\n async listDraftsByEntityId(\n entityId: string,\n limit: number,\n after: { createdAt: number; id: string } | null,\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const afterClause = after ? ` AND (created_at < ? OR (created_at = ? AND id < ?))` : '';\n const args: unknown[] = after\n ? [entityId, after.createdAt, after.createdAt, after.id, limit]\n : [entityId, limit];\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND lifecycle_status = 'draft'${afterClause}\n ORDER BY created_at DESC, id DESC LIMIT ?`,\n args,\n );\n return rows.map(mapRowToFact);\n }\n\n /** True iff `entryId` is a live draft owned by `entityId`. */\n async isLiveDraft(entryId: string, entityId: string, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE id = ? AND entity_id = ? AND deleted_at IS NULL AND lifecycle_status = 'draft'`,\n [entryId, entityId],\n );\n return row != null;\n }\n\n /**\n * Live untyped facts eligible for ontology backfill, oldest first.\n * Skips facts checked within the recheck cooldown (ontology_checked_at > recheckCutoff).\n */\n async findUntypedByEntityId(entityId: string, limit: number, recheckCutoff: number, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL\n AND (ontology_checked_at IS NULL OR ontology_checked_at <= ?)\n ORDER BY updated_at ASC LIMIT ?`,\n [entityId, recheckCutoff, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /** Counts live untyped facts: eligible (past cooldown) vs deferred (in cooldown). */\n async countUntypedByEntityId(entityId: string, recheckCutoff: number, tx?: SQLiteAdapter): Promise<{ eligible: number; deferred: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ eligible: number | null; deferred: number | null }>(\n `SELECT\n SUM(CASE WHEN ontology_checked_at IS NULL OR ontology_checked_at <= ? THEN 1 ELSE 0 END) AS eligible,\n SUM(CASE WHEN ontology_checked_at IS NOT NULL AND ontology_checked_at > ? THEN 1 ELSE 0 END) AS deferred\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL`,\n [recheckCutoff, recheckCutoff, entityId],\n );\n return { eligible: Number(row?.eligible ?? 0), deferred: Number(row?.deferred ?? 0) };\n }\n\n /**\n * Sets okf_type only when currently NULL — additive by construction: a\n * concurrently-typed fact is never overwritten. Returns changes for the caller\n * to distinguish applied vs skipped.\n */\n async updateOkfType(id: string, entityId: string, okfType: string, tx: SQLiteAdapter): Promise<{ changes: number }> {\n const result = await tx.runAsync(\n `UPDATE ${this.prefix}entries SET okf_type = ?\n WHERE id = ? AND entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL`,\n [okfType, id, entityId],\n );\n return { changes: result.changes };\n }\n\n /**\n * Stamps the backfill recheck cooldown. NEVER touches updated_at — import\n * merge resolution is last-write-wins on updated_at and a bump here would\n * make an unchanged local fact beat a genuinely newer remote edit.\n */\n async markOntologyChecked(ids: string[], entityId: string, now: number, tx: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await tx.runAsync(\n `UPDATE ${this.prefix}entries SET ontology_checked_at = ?\n WHERE id IN (${placeholders}) AND entity_id = ? AND deleted_at IS NULL`,\n [now, ...chunk, entityId],\n );\n }\n }\n\n /**\n * Lightweight full-breadth title index (id, title, okf_type) over all live\n * typed facts. Used by ontology backfill edge resolution — a recent-N window\n * would miss an old fact's contemporaries. Untyped rows are excluded: they\n * can never pass the edge target-type check, and batch facts typed during\n * the run are re-added to the in-memory index by the caller.\n */\n async findTitleIndexByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<Array<{ id: string; title: string; okf_type: string | null }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ id: string; title: string; okf_type: string | null }>(\n `SELECT id, title, okf_type FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL AND okf_type IS NOT NULL`,\n [entityId],\n );\n return rows.map(r => ({ id: r.id, title: r.title, okf_type: r.okf_type ?? null }));\n }\n\n /** Counts live mutable facts: eligible (past cooldown) vs deferred (in cooldown). */\n async countHealCandidatesByEntityId(\n entityId: string,\n recheckCutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<{ eligible: number; deferred: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ eligible: number | null; deferred: number | null }>(\n `SELECT\n SUM(CASE WHEN heal_checked_at IS NULL OR heal_checked_at <= ? THEN 1 ELSE 0 END) AS eligible,\n SUM(CASE WHEN heal_checked_at IS NOT NULL AND heal_checked_at > ? THEN 1 ELSE 0 END) AS deferred\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'`,\n [recheckCutoff, recheckCutoff, entityId],\n );\n return { eligible: Number(row?.eligible ?? 0), deferred: Number(row?.deferred ?? 0) };\n }\n\n /**\n * Stamps the heal recheck cooldown. NEVER touches updated_at — import merge\n * resolution is last-write-wins on updated_at and a bump here would make an\n * unchanged local fact beat a genuinely newer remote edit.\n *\n * Soft-deleted rows are skipped: a candidate heal deleted earlier in the same\n * transaction is no longer a candidate under any future pass, so its cooldown\n * value is irrelevant. This means the stamped count can be lower than the\n * offered-candidate count.\n */\n async markHealChecked(ids: string[], entityId: string, now: number, tx: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await tx.runAsync(\n `UPDATE ${this.prefix}entries SET heal_checked_at = ?\n WHERE id IN (${placeholders}) AND entity_id = ? AND deleted_at IS NULL`,\n [now, ...chunk, entityId],\n );\n }\n }\n\n /**\n * Lightweight full-breadth index (id, title) over all live librarian_inferred\n * facts. This is heal's fuzzy-dedupe corpus, deliberately kept independent of\n * the bounded candidate window: seeding dedupe from a batchSize-limited read\n * would let a synthesized fact duplicating a fact outside the window pass the\n * Jaccard check, and a convergence loop would multiply those duplicates across\n * passes. Mirrors findTitleIndexByEntityId — full breadth, two columns, cheap.\n */\n async findInferredTitlesByEntityId(\n entityId: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; title: string }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ id: string; title: string }>(\n `SELECT id, title FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type = 'librarian_inferred'`,\n [entityId],\n );\n return rows.map(r => ({ id: r.id, title: r.title }));\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","import { BaseRepository } from './BaseRepository';\nimport type { SQLiteAdapter } from '../types';\nimport { generateId } from '../utils/ids';\n\nexport class OutboxRepository extends BaseRepository {\n private enableOutbox: boolean;\n\n constructor(db: SQLiteAdapter, prefix: string, enableOutbox = false) {\n super(db, prefix);\n this.enableOutbox = enableOutbox;\n }\n\n /**\n * Insert a new outbox event within the provided transaction.\n * No-op when enableOutbox is false.\n * `tx` is required — callers must always pass the active transaction\n * so the write is atomic with the main table mutation.\n */\n async push(\n params: {\n entityId: string;\n tableName: string;\n recordId: string;\n operation: 'INSERT' | 'UPDATE' | 'DELETE';\n payload: any;\n },\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (!this.enableOutbox) return;\n const executor = this.getExecutor(tx);\n const id = generateId('out_');\n const now = Date.now();\n await executor.runAsync(\n `INSERT INTO ${this.prefix}outbox (id, entity_id, table_name, record_id, operation, payload, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [id, params.entityId, params.tableName, params.recordId, params.operation, JSON.stringify(params.payload), now],\n );\n }\n\n /**\n * Fetch pending outbox rows ordered by created_at ASC, rowid ASC.\n * Reads directly from `this.db` (not a transaction).\n */\n async fetchPending(limit = 50): Promise<any[]> {\n return this.db.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}outbox ORDER BY created_at ASC, rowid ASC LIMIT ?`,\n [limit],\n );\n }\n\n /**\n * Delete acknowledged outbox rows by their IDs.\n * No-op when `ids` is empty.\n * Deletes directly from `this.db` (not a transaction).\n */\n async acknowledge(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(', ');\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}outbox WHERE id IN (${placeholders})`,\n chunk,\n );\n }\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport { BaseRepository } from './BaseRepository';\nimport { generateId } from '../utils/ids';\n\n/**\n * Per-(entity_id, source_hash) record of the canonical sourceRef currently\n * holding that hash. The partial UNIQUE index on (entity_id, source_hash)\n * WHERE deleted_at IS NULL enforces the sourceRef-level TOCTOU-race invariant\n * for the #79 fix. See\n * docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n *\n * The entries table cannot express this invariant directly because a single\n * `ingestDocument` call writes N facts that all share\n * (entity_id, source_ref, source_hash); a UNIQUE index on\n * `entries(entity_id, source_hash)` would block the 2nd–Nth fact inserts in\n * the normal multi-fact path. The per-(entity, hash) granularity of\n * source_ref_index matches the TOCTOU invariant exactly.\n *\n * No outbox events: this is an internal index table whose state is fully\n * derivable from `entries`. Hosts that need CDC continue to read `entries`\n * outbox events; the index is not part of the user-visible contract.\n */\nexport class SourceRefIndexRepository extends BaseRepository {\n /**\n * Idempotent insert: the partial UNIQUE index catches concurrent inserts for\n * the same (entity_id, source_hash). The caller (IngestionService) catches\n * the resulting SQLITE_CONSTRAINT_UNIQUE and translates it to the per-mode\n * duplicate-hash outcome. Runtime IDs use the `sri_` prefix to avoid\n * collision with the deterministic `sri:<entity>:<hash>` IDs used by the v9\n * backfill (the colon separator keeps the two ID spaces disjoint).\n */\n async upsert(\n entityId: string,\n sourceHash: string,\n sourceRef: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}source_ref_index (id, entity_id, source_hash, source_ref, created_at, deleted_at)\n VALUES (?, ?, ?, ?, ?, NULL)`,\n [generateId('sri_'), entityId, sourceHash, sourceRef, Date.now()],\n );\n }\n\n /**\n * Idempotent soft-delete of the live row for (entity_id, source_ref).\n * Called at the start of every ingestDocument to remove the prior run's\n * index row, so the new upsert doesn't collide with itself. No-op when the\n * row is already soft-deleted or never existed.\n */\n async softDeleteByEntityAndSourceRef(\n entityId: string,\n sourceRef: string,\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}source_ref_index\n SET deleted_at = ?, created_at = ?\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL`,\n [now, now, entityId, sourceRef],\n );\n return result.changes;\n }\n\n /**\n * Returns the live sourceRef holding the given hash, or null when no live\n * row exists. Used by the IngestionService pre-check (line 82) and the\n * catch-and-translate canonical lookup (line 212).\n */\n async findActiveByEntityAndHash(\n entityId: string,\n sourceHash: string,\n tx?: SQLiteAdapter,\n ): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ source_ref: string }>(\n `SELECT source_ref FROM ${this.prefix}source_ref_index\n WHERE entity_id = ? AND source_hash = ? AND deleted_at IS NULL`,\n [entityId, sourceHash],\n );\n return row?.source_ref ?? null;\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport { OutboxRepository } from './OutboxRepository';\nimport type { WikiTask, SQLiteAdapter } from '../types';\nimport { parseJsonArray, parseJsonObject } from './rowMappers';\nimport { isStaleAfter, deriveTrustTier } from '@equationalapplications/core-okf';\n\nfunction mapRowToTask(row: any): WikiTask {\n const okf_verified = parseJsonArray<NonNullable<WikiTask['okf_verified']>[number]>(row.okf_verified, []);\n // Mirror EntryRepository.mapRowToFact — see that file for the rationale on\n // per-row Date.now() sampling vs. a shared per-call value.\n const now = Date.now();\n const staleAfterRaw = row.stale_after != null ? Number(row.stale_after) : null;\n\n return {\n id: row.id,\n entity_id: row.entity_id,\n description: row.description,\n status: row.status,\n priority: Number(row.priority),\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at),\n resolved_at: row.resolved_at != null ? Number(row.resolved_at) : null,\n deleted_at: row.deleted_at != null ? Number(row.deleted_at) : null,\n okf_type: row.okf_type ?? null,\n // OKF v0.2\n lifecycle_status: (row.lifecycle_status ?? 'stable') as WikiTask['lifecycle_status'],\n stale_after: staleAfterRaw,\n generated_by: row.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiTask['okf_sources']>[number]>(row.okf_sources, []),\n okf_verified,\n okf_usage_window: parseJsonObject<NonNullable<WikiTask['okf_usage_window']>>(row.okf_usage_window),\n last_verified_at: row.last_verified_at != null ? Number(row.last_verified_at) : null,\n last_verified_by: row.last_verified_by ?? null,\n // Spec §2.7 + §5.3: hydrate so read() consumers don't re-call the helpers.\n isStale: isStaleAfter(staleAfterRaw, now),\n trustTier: deriveTrustTier(okf_verified),\n };\n}\n\nexport class TaskRepository extends BaseRepository {\n constructor(\n db: SQLiteAdapter,\n prefix: string,\n private outbox: OutboxRepository,\n ) {\n super(db, prefix);\n }\n\n /**\n * Fetch a single task by ID. Returns null if not found or soft-deleted.\n */\n async findById(id: string): Promise<WikiTask | null> {\n const row = await this.db.getFirstAsync<any>(\n `SELECT * FROM ${this.prefix}tasks WHERE id = ? AND deleted_at IS NULL`,\n [id],\n );\n return row ? mapRowToTask(row) : null;\n }\n\n /**\n * Fetch all pending/in_progress tasks for the given entity IDs.\n * Returns empty array when entityIds is empty.\n */\n async findAllPending(entityIds: string[], limit?: number): Promise<WikiTask[]> {\n if (entityIds.length === 0) return [];\n const placeholders = entityIds.map(() => '?').join(', ');\n const sql =\n `SELECT * FROM ${this.prefix}tasks ` +\n `WHERE entity_id IN (${placeholders}) AND status IN ('pending', 'in_progress') AND deleted_at IS NULL ` +\n `ORDER BY priority DESC, created_at ASC` +\n (limit != null ? ` LIMIT ?` : '');\n const params: unknown[] = limit != null ? [...entityIds, limit] : [...entityIds];\n const rows = await this.db.getAllAsync<any>(sql, params);\n return rows.map(mapRowToTask);\n }\n\n async findExistingMetadataByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; updated_at: number }>> {\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; entity_id: string; updated_at: number }> = [];\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}tasks WHERE id IN (${placeholders})`,\n chunk,\n );\n rows.push(...chunkRows.map((row) => ({ id: row.id, entity_id: row.entity_id, updated_at: Number(row.updated_at) })));\n }\n return rows;\n }\n\n /**\n * Upsert a WikiTask within the provided transaction.\n * Uses ON CONFLICT(id) DO UPDATE (not INSERT OR REPLACE).\n * Stages an outbox entry in the same transaction.\n * `tx` is REQUIRED.\n *\n * OKF metadata (lifecycle_status, sources, etc.) is intentionally excluded\n * from the SET clause so content writes preserve any existing row values.\n * See {@link EntryRepository.upsert} for the rationale — the same applies\n * symmetrically to tasks (spec §2.5). Callers that need to overwrite OKF\n * metadata should use {@link upsertForImport}.\n */\n async upsert(task: WikiTask, tx: SQLiteAdapter, updatedAt?: number): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Number.isFinite(updatedAt) ? updatedAt : Date.now();\n\n const existingRow = await executor.getFirstAsync<{\n id: string;\n lifecycle_status: string;\n stale_after: number | null;\n generated_by: string | null;\n okf_sources: string | null;\n okf_verified: string | null;\n okf_usage_window: string | null;\n last_verified_at: number | null;\n last_verified_by: string | null;\n }>(\n `SELECT id, lifecycle_status, stale_after, generated_by,\n okf_sources, okf_verified, okf_usage_window,\n last_verified_at, last_verified_by\n FROM ${this.prefix}tasks WHERE id = ?`,\n [task.id],\n );\n const operation = task.deleted_at != null ? 'DELETE' : (existingRow ? 'UPDATE' : 'INSERT');\n\n await executor.runAsync(\n `INSERT INTO ${this.prefix}tasks (\n id, entity_id, description, status, priority,\n created_at, updated_at, resolved_at, deleted_at,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n description = excluded.description,\n status = excluded.status,\n priority = excluded.priority,\n updated_at = excluded.updated_at,\n resolved_at = excluded.resolved_at,\n deleted_at = excluded.deleted_at`,\n [\n task.id,\n task.entity_id,\n task.description,\n task.status,\n task.priority,\n task.created_at,\n now, // updated_at set by repo or import override\n task.resolved_at ?? null,\n task.deleted_at ?? null,\n // OKF v0.2 metadata — bound for INSERT only; ON CONFLICT UPDATE\n // preserves the existing row values (these columns are intentionally\n // absent from the SET clause above).\n task.lifecycle_status ?? 'stable',\n task.stale_after ?? null,\n task.generated_by ?? null,\n task.last_verified_at ?? null,\n task.last_verified_by ?? null,\n task.okf_sources ? JSON.stringify(task.okf_sources) : null,\n task.okf_verified ? JSON.stringify(task.okf_verified) : null,\n task.okf_usage_window ? JSON.stringify(task.okf_usage_window) : null,\n ],\n );\n\n // Outbox payload mirrors what is actually persisted. On UPDATE, the SET\n // clause intentionally omits OKF metadata so prior row values win, but\n // the caller-supplied `task` would still describe state we did NOT write.\n // Re-read those columns from the stored row and overlay them onto the\n // caller-supplied payload before publishing (#90 review).\n const persistedOkf = existingRow\n ? {\n lifecycle_status: (existingRow.lifecycle_status ?? 'stable') as WikiTask['lifecycle_status'],\n stale_after: existingRow.stale_after != null ? Number(existingRow.stale_after) : null,\n generated_by: existingRow.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiTask['okf_sources']>[number]>(existingRow.okf_sources, []),\n okf_verified: parseJsonArray<NonNullable<WikiTask['okf_verified']>[number]>(existingRow.okf_verified, []),\n okf_usage_window: parseJsonObject<NonNullable<WikiTask['okf_usage_window']>>(existingRow.okf_usage_window),\n last_verified_at: existingRow.last_verified_at != null ? Number(existingRow.last_verified_at) : null,\n last_verified_by: existingRow.last_verified_by ?? null,\n }\n : null;\n await this.outbox.push(\n {\n entityId: task.entity_id,\n tableName: 'tasks',\n recordId: task.id,\n operation,\n payload: persistedOkf ? { ...task, ...persistedOkf } : task,\n },\n tx,\n );\n }\n\n async upsertForImport(task: WikiTask, tx: SQLiteAdapter, updatedAt?: number): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Number.isFinite(updatedAt) ? updatedAt : Date.now();\n\n // Import is replace semantics, mirroring EntryRepository.upsertForImport.\n // Dump is authoritative: a re-import that cleared stale_after, generated_by,\n // or verification mirrors must overwrite, not preserve.\n await executor.runAsync(\n `INSERT INTO ${this.prefix}tasks (\n id, entity_id, description, status, priority,\n created_at, updated_at, resolved_at, deleted_at, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n description = excluded.description,\n status = excluded.status,\n priority = excluded.priority,\n updated_at = excluded.updated_at,\n resolved_at = excluded.resolved_at,\n deleted_at = excluded.deleted_at,\n okf_type = excluded.okf_type,\n lifecycle_status = excluded.lifecycle_status,\n stale_after = excluded.stale_after,\n generated_by = excluded.generated_by,\n last_verified_at = excluded.last_verified_at,\n last_verified_by = excluded.last_verified_by,\n okf_sources = excluded.okf_sources,\n okf_verified = excluded.okf_verified,\n okf_usage_window = excluded.okf_usage_window`,\n [\n task.id,\n task.entity_id,\n task.description,\n task.status,\n task.priority,\n task.created_at,\n now,\n task.resolved_at ?? null,\n task.deleted_at ?? null,\n task.okf_type ?? null,\n task.lifecycle_status ?? 'stable',\n task.stale_after ?? null,\n task.generated_by ?? null,\n task.last_verified_at ?? null,\n task.last_verified_by ?? null,\n task.okf_sources ? JSON.stringify(task.okf_sources) : null,\n task.okf_verified ? JSON.stringify(task.okf_verified) : null,\n task.okf_usage_window ? JSON.stringify(task.okf_usage_window) : null,\n ],\n );\n }\n\n /**\n * Soft-delete a task by ID. Sets deleted_at and updated_at.\n * Stages a DELETE outbox entry in the same transaction.\n * `tx` is REQUIRED.\n */\n async softDelete(id: string, entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, id, entityId],\n );\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n },\n tx,\n );\n }\n\n /**\n * Fetch all non-deleted tasks for an entity, ordered by priority DESC, created_at ASC.\n * Used by _getFullBundle().\n */\n async findAllByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiTask[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL ORDER BY priority DESC, created_at ASC`,\n [entityId],\n );\n return rows.map(mapRowToTask);\n }\n\n /**\n * Bulk delete pruned tasks (already soft-deleted) by cutoff date.\n * Used by runPrune(). Returns number of deleted rows.\n */\n async bulkDeletePruned(\n entityId: string,\n cutoff: number,\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const rowsToDelete = await executor.getAllAsync<{ id: string; deleted_at: number }>(\n `SELECT id, deleted_at FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n if (rowsToDelete.length === 0) return 0;\n\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n\n for (const row of rowsToDelete) {\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: row.deleted_at },\n },\n tx,\n );\n }\n\n return result.changes;\n }\n\n /**\n * Soft-delete a task by ID within a transaction.\n * Stages a DELETE outbox entry in the same transaction.\n * `tx` is REQUIRED.\n */\n async softDeleteById(\n id: string,\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<{ changes: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, id, entityId],\n );\n if (result.changes > 0) {\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n },\n tx,\n );\n }\n return result;\n }\n\n /**\n * Bulk soft-delete all tasks for an entity.\n * Stages DELETE outbox entries for each row in the same transaction.\n * `tx` is REQUIRED.\n */\n async bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n // Get IDs before updating for outbox staging\n const idsToDelete = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId],\n );\n // Stage outbox entries for each deleted record\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'tasks',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return result.changes;\n }\n\n /**\n * Count live tasks for an entity. Used by forget({ dryRun, clearAll: true }).\n */\n async countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}tasks\n WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n return row?.cnt ?? 0;\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { WikiEvent, SQLiteAdapter } from '../types';\n\nexport class EventRepository extends BaseRepository {\n /**\n * Insert a new event row.\n * Pass `tx` to participate in a caller-owned transaction; omit to run against the default db.\n */\n async add(event: WikiEvent, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [\n event.id,\n event.entity_id,\n event.event_type,\n event.summary,\n event.related_entry_id ?? null,\n event.created_at,\n ],\n );\n }\n\n async addIgnoreDuplicate(event: WikiEvent, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [\n event.id,\n event.entity_id,\n event.event_type,\n event.summary,\n event.related_entry_id ?? null,\n event.created_at,\n ],\n );\n }\n\n /**\n * Return the most recent events for an entity, newest first.\n * Defaults to a limit of 50.\n */\n async getRecent(entityId: string, limit = 50): Promise<WikiEvent[]> {\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`,\n [entityId, limit],\n );\n }\n\n /**\n * Return the most recent events for the given entity IDs, newest first.\n * Defaults to a limit of 50.\n */\n async getRecentForEntities(entityIds: string[], limit = 50): Promise<WikiEvent[]> {\n if (entityIds.length === 0) return [];\n const placeholders = entityIds.map(() => '?').join(', ');\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id IN (${placeholders}) ORDER BY created_at DESC LIMIT ?`,\n [...entityIds, limit],\n );\n }\n\n /**\n * Delete events for an entity that were created at or before the given cutoff timestamp.\n * Returns the number of deleted rows.\n */\n async prune(entityId: string, cutoff: number): Promise<{ changes: number }> {\n return this.db.runAsync(\n `DELETE FROM ${this.prefix}events WHERE entity_id = ? AND created_at <= ?`,\n [entityId, cutoff],\n );\n }\n\n /**\n * Return the total number of events stored for an entity.\n * `tx` is optional — pass an active transaction handle for atomic reads.\n */\n async count(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = tx ?? this.db;\n const row = await executor.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}events WHERE entity_id = ?`,\n [entityId],\n );\n return row?.count ?? 0;\n }\n\n /**\n * Return all events for an entity in chronological (ASC) order.\n * When limit is provided, fetches newest-first then reverses to preserve chronological order.\n */\n async getByEntityId(entityId: string, limit?: number): Promise<WikiEvent[]> {\n if (limit != null) {\n const rows = await this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`,\n [entityId, limit],\n );\n return rows.slice().reverse();\n }\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at ASC`,\n [entityId],\n );\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { WikiEdge, SQLiteAdapter } from '../types';\n\nexport interface NeighborhoodQueryOptions {\n maxDepth: number; // already clamped to [1,3] by the caller (GraphTraversalService)\n direction: 'inbound' | 'outbound' | 'both';\n edgeTypes?: string[]; // undefined = no filter; [] = match nothing (short-circuits)\n minConfidence: 'certain' | 'inferred' | 'tentative';\n excludeSourceTypes: string[];\n maxNodes: number;\n /**\n * When true, draft facts are dead-ends for *discovered* nodes — the recursive\n * walk will not step onto a draft, and will not step *past* one either, since\n * a draft's neighbours are unreachable through it. The anchor node is exempt\n * (it is validated up-front and never gated by this flag), so callers can\n * intentionally start from a draft. Default false (drafts visible).\n */\n excludeDrafts?: boolean;\n}\n\nconst CONFIDENCE_RANK: Record<'tentative' | 'inferred' | 'certain', number> = {\n tentative: 0,\n inferred: 1,\n certain: 2,\n};\n\nexport class EdgeRepository extends BaseRepository {\n /**\n * Insert an edge, silently skipping on primary-key or uniqueness conflicts.\n * Returns true when a row was inserted, false when skipped as a duplicate.\n * Throws when the insert was skipped due to an id collision with a different edge tuple.\n */\n async addIgnoreDuplicate(edge: WikiEdge, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const result = await executor.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}edges (id, entity_id, source_id, target_id, edge_type, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [edge.id, edge.entity_id, edge.source_id, edge.target_id, edge.edge_type, edge.created_at],\n );\n\n if (result.changes > 0) return true;\n\n const existing = await executor.getFirstAsync<{\n entity_id: string;\n source_id: string;\n target_id: string;\n edge_type: string;\n }>(\n `SELECT entity_id, source_id, target_id, edge_type FROM ${this.prefix}edges WHERE id = ?`,\n [edge.id],\n );\n\n if (!existing) return false;\n\n if (\n String(existing.entity_id) !== edge.entity_id ||\n String(existing.source_id) !== edge.source_id ||\n String(existing.target_id) !== edge.target_id ||\n String(existing.edge_type) !== edge.edge_type\n ) {\n throw new Error(\n `Edge id collision: ${JSON.stringify(edge.id)} already exists with a different (entity_id, source_id, target_id, edge_type) tuple`,\n );\n }\n\n return false;\n }\n\n async getByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiEdge[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}edges WHERE entity_id = ? ORDER BY created_at ASC`,\n [entityId],\n );\n return rows.map(mapRowToEdge);\n }\n\n /** Hard delete — edges have no soft-delete concept, only presence/absence. `tx` is REQUIRED. */\n async bulkDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(`DELETE FROM ${this.prefix}edges WHERE entity_id = ?`, [entityId]);\n }\n\n /**\n * Hard-delete every edge whose `source_id` is in `sourceFactIds`, scoped to\n * `entityId`. Returns the number of rows deleted. Edges have no soft-delete\n * concept; this method is named `softDeleteBySourceFactIds` for symmetry with\n * `EntryRepository.softDeleteBySource` (which IS a soft delete), but its\n * semantics are immediate presence/absence removal. Use ONLY inside an open\n * transaction — the method requires `tx` and performs no autocommit.\n *\n * Used by `IngestionService.upsertGraphCore` to retire the prior parse's\n * edges whose source facts are being superseded by `softDeleteBySource`.\n */\n async softDeleteBySourceFactIds(\n entityId: string,\n sourceFactIds: readonly string[],\n tx: SQLiteAdapter,\n ): Promise<number> {\n if (sourceFactIds.length === 0) return 0;\n const executor = this.getExecutor(tx);\n // SQLite's SQLITE_MAX_VARIABLE_NUMBER defaults to 32,766; binding\n // `entityId` plus every ID in one statement would overflow once a\n // single sourceRef accumulates tens of thousands of facts. Chunk to\n // stay well under the limit, reusing the supplied tx executor.\n const chunkSize = 500;\n let totalChanges = 0;\n for (let i = 0; i < sourceFactIds.length; i += chunkSize) {\n const chunk = sourceFactIds.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}edges\n WHERE entity_id = ? AND source_id IN (${placeholders})`,\n [entityId, ...chunk],\n );\n totalChanges += result.changes;\n }\n return totalChanges;\n }\n\n /**\n * Multi-hop traversal from `sourceId` via SQLite `WITH RECURSIVE`. All filtering,\n * dead-ending, cycle-guarding, capping, and ordering happens in this one query.\n * The anchor is validated (exists, right entity, not soft-deleted) but never gated\n * by confidence/source_type — only nodes discovered beyond it are.\n */\n async getNeighborhood(\n entityId: string,\n sourceId: string,\n opts: NeighborhoodQueryOptions,\n tx?: SQLiteAdapter,\n ): Promise<{ nodeIds: string[]; edges: WikiEdge[] }> {\n const executor = this.getExecutor(tx);\n\n if (opts.edgeTypes && opts.edgeTypes.length === 0) {\n const anchor = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [sourceId, entityId],\n );\n return { nodeIds: anchor ? [anchor.id] : [], edges: [] };\n }\n\n const edgeTypesClause = opts.edgeTypes\n ? `e.edge_type IN (${opts.edgeTypes.map(() => '?').join(',')})`\n : '1=1';\n const excludeSourceTypesPlaceholders = opts.excludeSourceTypes.map(() => '?').join(',');\n const minConfidenceRank = CONFIDENCE_RANK[opts.minConfidence];\n\n const sql = `\n WITH RECURSIVE walk(node_id, depth, visited) AS (\n SELECT id, 0, ',' || id || ','\n FROM ${this.prefix}entries\n WHERE id = ? AND entity_id = ? AND deleted_at IS NULL\n\n UNION\n\n SELECT\n CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END,\n w.depth + 1,\n w.visited || (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END) || ','\n FROM walk w\n JOIN ${this.prefix}edges e\n ON e.entity_id = ?\n AND (\n (? != 'inbound' AND e.source_id = w.node_id) OR\n (? != 'outbound' AND e.target_id = w.node_id)\n )\n AND (${edgeTypesClause})\n JOIN ${this.prefix}entries n\n ON n.id = (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END)\n AND n.entity_id = ?\n AND n.deleted_at IS NULL\n AND (\n CASE n.confidence\n WHEN 'tentative' THEN 0\n WHEN 'inferred' THEN 1\n WHEN 'certain' THEN 2\n ELSE -1\n END\n ) >= ?\n AND n.source_type NOT IN (${excludeSourceTypesPlaceholders})\n AND (? = 0 OR n.lifecycle_status != 'draft')\n WHERE w.depth < ?\n AND instr(w.visited, ',' || (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END) || ',') = 0\n )\n SELECT node_id, MIN(depth) AS depth\n FROM walk\n GROUP BY node_id\n ORDER BY depth ASC, (SELECT updated_at FROM ${this.prefix}entries WHERE id = node_id) DESC\n LIMIT ?\n `;\n\n const params: unknown[] = [\n sourceId, entityId,\n entityId,\n opts.direction, opts.direction,\n ...(opts.edgeTypes ?? []),\n entityId,\n minConfidenceRank,\n ...opts.excludeSourceTypes,\n opts.excludeDrafts === true ? 1 : 0,\n opts.maxDepth,\n opts.maxNodes,\n ];\n\n const rows = await executor.getAllAsync<{ node_id: string; depth: number }>(sql, params);\n const nodeIds = rows.map((r) => r.node_id);\n if (nodeIds.length === 0) return { nodeIds: [], edges: [] };\n\n const valueRows = nodeIds.map(() => '(?)').join(', ');\n const edgeRows = await executor.getAllAsync<any>(\n `WITH neighborhood(node_id) AS (VALUES ${valueRows})\n SELECT e.* FROM ${this.prefix}edges e\n JOIN neighborhood ns ON e.source_id = ns.node_id\n JOIN neighborhood nt ON e.target_id = nt.node_id\n WHERE e.entity_id = ?`,\n [...nodeIds, entityId],\n );\n\n return { nodeIds, edges: edgeRows.map(mapRowToEdge) };\n }\n}\n\nfunction mapRowToEdge(row: any): WikiEdge {\n return {\n id: String(row.id),\n entity_id: String(row.entity_id),\n source_id: String(row.source_id),\n target_id: String(row.target_id),\n edge_type: String(row.edge_type),\n created_at: Number(row.created_at),\n };\n}\n","import type {\n OntologyManifest,\n OntologyNodeType,\n OntologyUpdates,\n ExtractedFactEdge,\n} from '../types';\nimport { WikiStrictOntologyViolation } 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\n/**\n * True when `concreteType` satisfies a declared type: an exact\n * (case-insensitive) match, or a one-hop parent match — the concrete type's\n * `parent_type` equals the declared type. Never recursive (D1). Exact matches\n * short-circuit before the node lookup, so manifests with no `parent_type`\n * behave bit-for-bit as before.\n */\nexport function typeSatisfies(\n declaredType: string,\n concreteType: string,\n manifest: OntologyManifest,\n): boolean {\n const concrete = concreteType.trim().toLowerCase();\n const declared = declaredType.trim().toLowerCase();\n if (!concrete || !declared) return false;\n if (declared === concrete) return true;\n // `node_types` is typed non-optional but arrives from JSON.parse of a DB row\n // at runtime, so guard it the way validateManifest already does — and for the\n // same reason, `typeof`-check the fields rather than calling .trim() on them.\n // This runs inside the caller's transaction, so a TypeError here aborts an\n // ingest exactly like one in the merge path. Manifests reaching this point\n // have already passed validateManifest (getManifest:164, and seeds via D11),\n // so this is defense in depth, not the primary guard.\n const def = (manifest.node_types ?? []).find(\n n => typeof n?.type === 'string' && n.type.trim().toLowerCase() === concrete,\n );\n const parent = typeof def?.parent_type === 'string'\n ? def.parent_type.trim().toLowerCase()\n : '';\n return parent !== '' && parent === declared;\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 // D1: optional one-level parent inheritance. A parent must be a real,\n // distinct node in the same manifest, and must not itself have a parent.\n // The chain check also rejects 2-cycles, which self-parent alone misses.\n const parentOf = new Map<string, string | undefined>();\n for (const node of manifest.node_types ?? []) {\n const parent = typeof node.parent_type === 'string'\n ? node.parent_type.trim().toLowerCase()\n : undefined;\n parentOf.set(node.type.trim().toLowerCase(), parent);\n }\n for (const node of manifest.node_types ?? []) {\n // D10: absent means \"no parent\"; present-but-unusable is malformed.\n if (node.parent_type === undefined) continue;\n // Typed `string | undefined`, but this runs on JSON.parse output from\n // `entity_manifests.manifest_json` on every read (MetadataRepository:164),\n // so a legacy or hand-edited row can carry a number or `null`. Unguarded,\n // `.trim()` on those raises a bare TypeError instead of this error.\n if (typeof node.parent_type !== 'string' || !node.parent_type.trim()) {\n throw new Error(`Ontology parent_type must be a non-empty string when present: ${node.type}`);\n }\n const parentSlug = node.parent_type.trim().toLowerCase();\n if (parentSlug === node.type.trim().toLowerCase()) {\n throw new Error(`Self-parent: ${node.type}`);\n }\n if (!nodeSlugs.has(parentSlug)) {\n throw new Error(`Parent type not found: ${node.parent_type}`);\n }\n const grandparent = parentOf.get(parentSlug);\n if (grandparent) {\n throw new Error(`Parent chain too deep: ${node.type} → ${node.parent_type} → ${grandparent}`);\n }\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\n// D6: emergent updates are untrusted. `updates` is JSON.parse output, so\n// every field is `unknown` at runtime whatever the TS types say — `.trim()`\n// on a number or an object throws a TypeError straight out of the caller's\n// transaction, which is the failure D6 exists to prevent. Guard every read.\n//\n// Exported so the test suite can exercise the index's untrusted-input\n// contract directly, without going through mergeOntologyUpdates — whose\n// pre-existing node loop (utils/ontology.ts:176) is unchanged by this work.\nexport function buildDeclaresParentIndex(\n nodes: ReadonlyArray<OntologyNodeType>,\n): Map<string, boolean> {\n const declaresParent = new Map<string, boolean>();\n for (const n of nodes) {\n const slug = typeof n?.type === 'string' ? n.type.trim().toLowerCase() : '';\n if (!slug || declaresParent.has(slug)) continue;\n declaresParent.set(slug, n?.parent_type !== undefined);\n }\n return declaresParent;\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 // Index over current + proposed nodes, first-seen wins (mirrors the dedup in\n // the loop below). Value: did this slug declare a `parent_type` key at all?\n // Presence, not usability — a node that declared one cannot serve as a\n // parent, whether it is a real child or a malformed proposal.\n const declaresParent = buildDeclaresParentIndex([\n ...current.node_types,\n ...(updates.node_types ?? []),\n ]);\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 // Drop a non-string, blank, unresolvable, self-referential, or two-deep\n // parent rather than letting it throw inside the caller's transaction (D6).\n // `declaresParent.get(...) === false` is the whole gate: `undefined` means\n // the slug is unknown, `true` means that node declared a parent of its own.\n const rawParent = typeof node?.parent_type === 'string' ? node.parent_type.trim() : '';\n const parentSlug = rawParent.toLowerCase();\n const keepParent = parentSlug !== ''\n && parentSlug !== key\n && declaresParent.get(parentSlug) === false;\n node_types.push({\n type,\n description: String(node.description ?? ''),\n ...(keepParent ? { parent_type: rawParent } : {}),\n });\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 type EdgeDropReason =\n | 'no_source_type'\n | 'invalid_shape'\n | 'type_not_in_manifest'\n | 'target_not_found'\n | 'target_type_mismatch';\n\n/** A dropped LLM-proposed edge. Slugs only — `target_title` is content and is never recorded. */\nexport interface EdgeDrop {\n reason: EdgeDropReason;\n /** Source fact id when known; null while validating before the fact has an id. */\n sourceId: string | null;\n edgeType: string | null;\n sourceNodeType: string | null;\n targetNodeType: string | null;\n}\n\nexport function validateInlineEdges(\n sourceType: string,\n _targetType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n opts?: { strict?: boolean; entityId?: string; drops?: EdgeDrop[] },\n): ExtractedFactEdge[] {\n const strict = opts?.strict === true;\n const entityId = opts?.entityId ?? '';\n const drops = opts?.drops;\n const drop = (reason: EdgeDropReason, edgeType: string | null): void => {\n drops?.push({ reason, sourceId: null, edgeType, sourceNodeType: sourceType, targetNodeType: null });\n };\n if (!Array.isArray(edges)) {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', '');\n drop('invalid_shape', null);\n return [];\n }\n const valid: ExtractedFactEdge[] = [];\n for (const edge of edges) {\n if (typeof edge?.edge_type !== 'string' || typeof edge?.target_title !== 'string') {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', String(edge?.edge_type ?? ''));\n drop('invalid_shape', typeof edge?.edge_type === 'string' ? edge.edge_type : null);\n continue;\n }\n const defs = resolveEdgeDefinitions(edge.edge_type, manifest);\n const match = defs.find(d => typeSatisfies(d.source_type, sourceType, manifest));\n if (!match) {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', edge.edge_type);\n drop('type_not_in_manifest', edge.edge_type);\n continue;\n }\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 /**\n * Returns the set of distinct `entity_id` values across entries/tasks/events.\n *\n * Deliberately widened from a prior `WHERE deleted_at IS NULL` form: the\n * returned set intentionally includes entities whose only rows are\n * soft-deleted, so the host's maintenance sweep can visit such\n * \"decommissioned-scope\" namespaces and reap the soft-deleted rows. Sorting\n * is `entity_id COLLATE BINARY` for stable, locale-independent ordering.\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\n UNION\n SELECT entity_id FROM ${this.prefix}tasks\n UNION\n SELECT entity_id FROM ${this.prefix}events\n ) ORDER BY entity_id COLLATE BINARY`,\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 /**\n * Write an entity's manifest.\n *\n * `opts.ifAbsent` selects the conflict behaviour:\n * - omitted / `false` — upsert. An existing row is replaced.\n * - `true` — create-if-absent. An existing row is left exactly as it is.\n *\n * Returns whether this call actually wrote a row. Under `ifAbsent` a `false`\n * result means another writer got there first; the check and the write are one\n * statement, so there is no window between them.\n */\n async setManifest(\n entityId: string,\n data: { mode: OntologyMode; manifest: OntologyManifest },\n tx: SQLiteAdapter,\n opts?: { ifAbsent?: boolean },\n ): Promise<boolean> {\n validateManifest(data.manifest);\n const executor = this.getExecutor(tx);\n const conflictClause = opts?.ifAbsent\n ? 'ON CONFLICT(entity_id) DO NOTHING'\n : `ON CONFLICT(entity_id) DO UPDATE SET\n mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`;\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)\n VALUES (?, ?, ?, ?)\n ${conflictClause}`,\n [entityId, data.mode, JSON.stringify(data.manifest), Date.now()],\n );\n return result.changes > 0;\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","export function cosineSimilarity(a: ArrayLike<number>, b: ArrayLike<number>): number {\n let dot = 0, normA = 0, normB = 0;\n const len = Math.min(a.length, b.length);\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n","export function parseEmbedding(\n blob: Uint8Array | null | undefined,\n text: string | null | undefined\n): Float32Array | null {\n if (blob && blob.byteLength > 0) {\n if (blob.byteLength % 4 !== 0) return null;\n // Copy into fresh ArrayBuffer — SQLite drivers may return pooled Buffer\n // objects that get reused across queries, silently corrupting cached vectors.\n const copy = new ArrayBuffer(blob.byteLength);\n new Uint8Array(copy).set(blob);\n const vector = new Float32Array(copy);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n }\n if (text) {\n try {\n const arr: unknown = JSON.parse(text);\n if (!Array.isArray(arr) || !arr.every((v: unknown) => typeof v === 'number' && isFinite(v))) return null;\n const vector = new Float32Array(arr as number[]);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n } catch { return null; }\n }\n return null;\n}\n","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 /**\n * Per-(entityId, sourceHash) promise-chain lock. Serializes ingest races\n * at the application level (the v9 partial UNIQUE index enforces it at\n * the DB level as defense-in-depth). Two callers holding the same hash\n * see FIFO order; different hashes never block one another.\n *\n * Keyed `${entityId}\\0${sourceHash}` so distinct (entityId, sourceHash)\n * pairs can never share a lock. A raw concatenation would let\n * (\"ab\", \"c…\") collide with (\"a\", \"bc…\"); the NUL separator makes that\n * impossible because neither component can contain NUL (entityIds are\n * user-supplied identifiers; sourceHashes are hex digests).\n */\n private hashLocks: Map<string, Promise<unknown>> = new Map();\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 _hashLockKey(entityId: string, sourceHash: string): string {\n return `${entityId}\\0${sourceHash}`;\n }\n\n /**\n * Acquire a promise-chain lock scoped to one `(entityId, sourceHash)` pair.\n * Returns a zero-argument release closure that removes the current tail\n * from the chain. Releasing is idempotent so a holder that double-fires\n * (e.g. on a finally that races an explicit release) cannot unblock\n * the next holder prematurely.\n *\n * Documented ordering: ingest acquires the hash lock FIRST, then the\n * synchronous sourceRef ingest lock, and the release closure unwinds in\n * the opposite order (sourceRef first, hash second). Hash-then-sourceRef\n * is required because the v9 partial UNIQUE index conflicts on the\n * (entity_id, source_hash) pair regardless of source_ref, so two callers\n * with DIFFERENT source_refs racing the same hash are the exact case the\n * TOCTOU race fix needs to serialize.\n *\n * Mechanics: each holder owns a private `released` promise that resolves\n * only when THIS holder calls release(). The map stores the holder's\n * `released` promise as the \"tail\" — the NEXT caller awaits that tail\n * via `previous = this.hashLocks.get(key)`. The current caller gets\n * their unique release function once `previous` (the prior holder's\n * release signal) settles, so each holder is guaranteed a UNIQUE release\n * closure bound to their own `released` promise.\n */\n acquireHashLock(entityId: string, sourceHash: string): Promise<() => void> {\n const key = this._hashLockKey(entityId, sourceHash);\n const previous = this.hashLocks.get(key) ?? Promise.resolve();\n let resolveReleased!: () => void;\n const released = new Promise<void>((resolve) => { resolveReleased = resolve; });\n let fired = false;\n const release = () => {\n if (fired) return;\n fired = true;\n // Unlink from the map ONLY if we are still the current tail; otherwise\n // a fresh holder has already chained a new tail and ours would race.\n if (this.hashLocks.get(key) === released) {\n this.hashLocks.delete(key);\n }\n resolveReleased();\n };\n this.hashLocks.set(key, released);\n // Wait for the prior holder to release, then hand back OUR unique closure.\n return previous.then(() => release);\n }\n\n private _pruneKey(entityId: string) { return `${this.prefix}:${entityId}:prune`; }\n private _reembedKey(entityId: string) { return `${this.prefix}:${entityId}:reembed`; }\n private _globalReembedKey() { return `${this.prefix}:reembed`; }\n private _importKey(entityId: string) { return `${this.prefix}:${entityId}:import`; }\n private _globalImportKey() { return `${this.prefix}:import`; }\n private _forgetKey(entityId: string) { return `${this.prefix}:${entityId}:forget`; }\n private _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 /**\n * True while any reembed sweep is in flight — per-entity or global.\n *\n * Read-only; acquires nothing. Callers that mutate embedding failure\n * markers across ALL entities (the dimension-promotion clear) must gate on\n * this and defer, rather than resurrect rows an in-flight sweep already\n * classified. See spec 2026-09-05-reembed-lock-scope-design.md §2.\n *\n * The global key `${prefix}:reembed` also ends in ':reembed', so the suffix\n * scan alone would already match it. The explicit check is kept because it\n * documents the intent and survives any future change to the global key's\n * format.\n */\n isAnyReembedActive(): boolean {\n return this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n this._isAnyMaintenanceActiveWithSuffix(':reembed');\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 case 'reembed':\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n 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._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n case 'global_reembed':\n return this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n this._isAnyMaintenanceActiveWithSuffix(':reembed') ||\n this._isAnyMaintenanceActiveWithSuffix(':prune') ||\n this._isAnyMaintenanceActiveWithSuffix(':librarian') ||\n this._isAnyMaintenanceActiveWithSuffix(':heal') ||\n this._isAnyMaintenanceActiveWithSuffix(':ontologyBackfill') ||\n this.activeIngestJobs.size > 0 ||\n this._isAnyMaintenanceActiveWithSuffix(':import') ||\n this._isAnyMaintenanceActiveWithSuffix(':forget');\n case 'import':\n case 'forget': {\n const selfKey = operation === 'import' ? this._importKey(entityId) : this._forgetKey(entityId);\n return this.activeMaintenanceJobs.has(selfKey) ||\n this.activeMaintenanceJobs.has(this._librarianKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._healKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n }\n case 'global_import':\n return this.activeMaintenanceJobs.has(this._globalImportKey());\n case 'ingest':\n return this._hasIngestJob(entityId) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(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\n * permissiveness for write() auto-trigger paths — stricter checks stay in\n * acquireLock() — with one exception: reembed sweeps, which are excluded\n * structurally rather than by accident (see below).\n */\n tryAcquireAutoHealLock(entityId: string): boolean {\n // Heal must not run during a sweep. It is safe today only because heal\n // upserts blob-less facts and the marker clear is guarded by\n // `CASE WHEN excluded.embedding_blob IS NOT NULL` — an accident of the\n // current SQL, not a stated rule. Make the exclusion structural so a\n // future heal that carries blobs cannot silently resurrect rows an\n // in-flight sweep classified. Spec 2026-09-05 §3.3.\n //\n // A refused pass is not lost work: WriteService.maybeRunHeal holds its\n // checkpoint back, so the next write retries.\n if (this.isAnyReembedActive()) return false;\n\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 * Centralized ingest lock acquisition. Acquires the hash lock FIRST\n * (FIFO across callers racing the same hash), then the synchronous\n * sourceRef ingest lock (rejects cross-entity conflicts and busy\n * operations). Returns a single zero-argument release closure that\n * unwinds in the opposite order — sourceRef first, hash second — so\n * the sourceRef lock is freed the instant its work is done and only\n * the hash lock keeps serializing the duplicate-content race window.\n *\n * On a sourceRef conflict (WikiBusyError thrown synchronously by the\n * underlying acquireLock) the hash lock is released BEFORE the error\n * propagates, so the next caller in the hash chain is not held up by\n * a request that never reached the DB.\n */\n async acquireIngestLocks(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n ): Promise<() => void> {\n const releaseHash = await this.acquireHashLock(entityId, sourceHash);\n let sourceLockAcquired = false;\n try {\n this.acquireLock('ingest', entityId, sourceRef);\n sourceLockAcquired = true;\n } catch (err) {\n releaseHash();\n throw err;\n }\n return () => {\n try {\n if (sourceLockAcquired) this.releaseLock('ingest', entityId, sourceRef);\n } finally {\n releaseHash();\n }\n };\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 { ExtractedFact, ExtractedTask } from '../types';\nimport { WikiParseError } from '../types';\n\n/**\n * Maximum number of candidate substrings the tier-2 walker will try before\n * throwing `WikiParseError`. 5 covers the realistic case (a few bare quotes\n * produce a few candidate spans) without unbounded retry on truly broken\n * inputs.\n */\nconst MAX_REPAIR_CANDIDATES = 5;\n\n/**\n * Throws {@link WikiParseError} for the \"no JSON object/array found\" case.\n * Used at the two strict-tier throw sites that differ only in whether a\n * `[`/`{` was located: when `start === null`, no open bracket was found;\n * when `start` is a number, an open bracket was found but no balanced\n * close existed. Both share the user-facing diagnostic.\n */\nfunction throwNoJsonFound(text: string, start: number | null): never {\n throw new WikiParseError(\n 'No JSON object/array found in LLM response',\n { tier: 'strict', position: start, slice: text },\n );\n}\n\n/**\n * Extract JSON from an LLM response.\n *\n * Tier 1 (strict): the existing hand-rolled brace-matching scanner. Walks\n * `text` from the first `{` or `[` to its matching close, respecting `\\\"` and\n * `\\\\`. Correct whenever the input contains no unescaped `\"` inside string\n * bodies. Returns the parsed value via `JSON.parse`.\n *\n * Tier 2 (repair): triggered only when tier 1 throws. Re-walks the raw text\n * from `start` (NOT from the scanner's possibly-truncated slice) with a\n * container-context stack that classifies every `\"` as **structural** (open\n * or close a string) or **content** (needs `\\` prefix). Produces candidate\n * substrings at every position the container stack returns to empty and\n * tries each largest-first; the first that `JSON.parse` accepts is returned.\n *\n * Throws {@link WikiParseError} when both tiers fail. The error's `tier`\n * field distinguishes 'strict' (no scanner slice found) from 'repair'\n * (scanner slice found but unparsable) from 'all' (catch-all).\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\n const useBrace =\n firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket);\n\n if (useBrace) {\n start = firstBrace;\n openChar = '{';\n } else if (firstBracket !== -1) {\n start = firstBracket;\n openChar = '[';\n } else {\n throwNoJsonFound(text, null);\n }\n\n // Tier 1: try the existing scanner first. If `JSON.parse` succeeds we're done.\n const slice = scanJsonSlice(text, start, openChar);\n if (slice !== null) {\n try {\n return JSON.parse(slice) as T;\n } catch {\n // fall through to tier 2\n }\n }\n\n // Tier 2: container-aware walker over the raw text. The scanner's slice may\n // be arbitrarily truncated by a bare quote mid-string — running the walker\n // on the raw text from `start` is the only way to get a complete container\n // span to repair against. The walker validates via `JSON.parse` itself and\n // returns the already-parsed value, so we don't re-parse on the hot path.\n //\n // The walker runs twice under opposing comma-ambiguity policies — see\n // `containerAwareRepair` docstring. Both passes can produce parseable\n // JSON for the SAME input but with different shapes — e.g. for\n // `{\"title\":\"He said \"hi\"\",\"body\":\"ok\"}` the odd-parity pass swallows\n // `,\"body\":\"ok\"` into the title (parseable but wrong), while for\n // `{\"title\":\"24\" monitor\",\"body\":\"ok\"}` the even-parity pass does the\n // swallowing. When both parse, we prefer the pass that mutated the input\n // LESS (fewer content-quote escapes): the correct interpretation escapes\n // exactly the true bare quotes, while the swallowing one escapes the\n // structural quotes it consumes too. When only the odd-parity pass parsed\n // AND it never hit a comma-ambiguity position, the even-parity pass is\n // guaranteed to make identical decisions, so we skip it entirely. Each\n // pass is bounded by MAX_REPAIR_CANDIDATES.\n const repairOdd = containerAwareRepair(text, start, false);\n if (repairOdd.success !== null && !repairOdd.ambiguous) {\n return repairOdd.success as T;\n }\n const repairEven = containerAwareRepair(text, start, true);\n if (repairOdd.success !== null && repairEven.success !== null) {\n // Both policies produced a parseable candidate. Prefer the minimal\n // repair; on a tie (identical walks) keep the odd-parity result, which\n // matches the historical single-pass behavior.\n const pick = repairEven.escapes < repairOdd.escapes ? repairEven : repairOdd;\n return pick.success as T;\n }\n if (repairOdd.success !== null) {\n return repairOdd.success as T;\n }\n if (repairEven.success !== null) {\n return repairEven.success as T;\n }\n // Both policies failed to parse. Prefer the even-parity failed candidate\n // as the diagnostic — it's the original walker behavior and its failure\n // message matches what callers (and existing tests) expect on\n // balanced-but-invalid payloads like `{\"facts\":}`.\n const repair = repairEven.failed !== null ? repairEven : repairOdd;\n if (repair.failed !== null) {\n throw new WikiParseError(\n `Repair produced a candidate but JSON.parse rejected it: ${repair.failed.message}`,\n { tier: 'repair', position: repair.failed.position, slice: repair.failed.candidate },\n );\n }\n\n // Per spec (WikiParseError `tier: 'strict'`): a scanner that produced NO\n // usable slice (no balanced close) is a strict failure even when the\n // container-aware walker also finds nothing — the input is structurally\n // incomplete, not just unparseable.\n if (slice === null) {\n throwNoJsonFound(text, start);\n }\n\n throw new WikiParseError(\n 'No parsable JSON candidate found',\n { tier: 'all', position: start, slice: text },\n );\n}\n\n/**\n * Tier-1 scanner: returns the substring from `start` to the matching close\n * of the container opened by `openChar` at `start`, or `null` if no balanced\n * close exists. Pure function — extracted so `parseJsonResponse` reads as\n * the two-tier flow it implements.\n */\nfunction scanJsonSlice(text: string, start: number, openChar: string): string | null {\n const closeChar = openChar === '{' ? '}' : ']';\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 if (end === -1) return null;\n // safeSlice lives in this same file and is the project's surrogate-pair-safe\n // string-slice helper (used by chunkText). Bare `text.slice(start, end + 1)`\n // can split a UTF-16 surrogate pair when `end` lands between the high and\n // low halves; the walker downstream then trips on a U+FFFD replacement char.\n return safeSlice(text, start, end + 1);\n}\n\n/**\n * Tier-2 walker: re-walks the raw text from `start` with a container-context\n * stack and a peek-ahead rule that classifies every `\"` as either structural\n * (opens/closes a string) or content (needs `\\` prefix). Produces candidate\n * substrings at every balanced container close and returns the first one\n * that `JSON.parse` would accept (largest balanced span first), or `null` if\n * no candidate parses.\n *\n * The walker tries two policies at comma-ambiguity positions (`\"X\"`,\n * `X` ends in a bare quote, peek-ahead is `,`):\n *\n * - `closeOnEvenParity=true` — treat the quote as STRUCTURAL CLOSE when the\n * bare-quote count is EVEN, content escape when ODD. This is the heuristic\n * that has historically matched LLM output (it works for `\"He said \"hi\", then left.\"`).\n * - `closeOnEvenParity=false` — the opposite flip. Required for inputs whose\n * real close is at an ODD count (e.g. `\"24\" monitor\",\"body\":\"ok\"}`), where\n * the model intended one literal `\"` inside the value string and the next\n * `\"` to be the structural close.\n *\n * `parseJsonResponse` runs both policies and accepts the first parse-success\n * from either; {@link MAX_REPAIR_CANDIDATES} bounds each policy's emissions\n * so the combined work stays small.\n */\ninterface ContainerFrame {\n container: 'object' | 'array';\n /**\n * For objects: `true` while the next string token starts a property NAME;\n * `false` while the next string token starts a property VALUE. Stays the\n * role through `,` (a `,` in an object leaves us expecting a key again) and\n * through `:` (a `:` leaves us expecting a value). Arrays always treat\n * every string as a value, so this flag is unused for arrays.\n */\n expectKey: boolean;\n}\n\ninterface RepairFailure {\n candidate: string;\n position: number | null;\n message: string;\n}\n\ninterface RepairResult {\n /** First candidate that JSON.parse accepted, or null if none parsed. */\n success: unknown | null;\n /** First candidate that JSON.parse rejected (best diagnostic), or null. */\n failed: RepairFailure | null;\n /** Number of content quotes this policy escaped (mutated) while walking.\n * Used to arbitrate when BOTH policies produce a parseable candidate:\n * the interpretation that mutated the input less is preferred. */\n escapes: number;\n /** True when the walk hit at least one comma-ambiguity position — the\n * only place the two policies' decisions can diverge. When false, the\n * opposing-policy pass is guaranteed to make identical decisions, so the\n * caller can skip it entirely. */\n ambiguous: boolean;\n}\n\nfunction containerAwareRepair(\n text: string,\n start: number,\n closeOnEvenParity: boolean,\n): RepairResult {\n // The walker produces a stream of balanced-span candidates in largest-first\n // order. We try each via `JSON.parse` at emission time so the success\n // path short-circuits without ever building the trailing-prefix out of\n // the walker; on a rejection we capture the first failure as the best\n // diagnostic and keep walking to find another candidate (bounded by\n // MAX_REPAIR_CANDIDATES). The `failed` slot is what callers use to\n // construct a `WikiParseError` with `tier: 'repair'` when nothing parses\n // — the public contract documents the slice + parse position in the\n // error.\n const stack: ContainerFrame[] = [];\n let inString = false;\n let stringRole: 'key' | 'value' | null = null;\n let escape = false;\n let i = start;\n // Output buffer; rebuilt as we walk, used to emit candidate substrings.\n let out = '';\n // Tracks bare quotes emitted as content so far inside the current string\n // token. Used to suppress a structural close on a `,` peek-ahead when the\n // body still has an open unescaped bare quote (`{\"body\":\"hi\", then...`}`);\n // closing prematurely puts the comma at structural level where JSON.parse\n // expects a property name. Reset on every structural close (or open).\n let bareQuoteCount = 0;\n // Best rejection seen so far — captured when JSON.parse rejects a\n // candidate so we can surface it on `WikiParseError(tier: 'repair')`.\n let bestFailed: RepairFailure | null = null;\n // Content quotes escaped so far this pass (see RepairResult.escapes).\n let escapes = 0;\n // Whether any comma-ambiguity position was reached (see\n // RepairResult.ambiguous).\n let ambiguous = false;\n // Captured successfully-parsed value of the first candidate that JSON.parse\n // accepted. Carried through the walker's short-circuit return so callers\n // can skip a second `JSON.parse` and `T`-cast on the hot success path.\n let bestSuccess: unknown = null;\n let attempts = 0;\n\n // Try `JSON.parse(candidate)` immediately on emission; capture the\n // failure as bestFailed (or the value as bestSuccess) and bump the\n // attempt counter. Returns true on success so the caller can short-circuit\n // out of the walk.\n //\n // `safeErrorToString` (defined in this same file) is the hardened\n // non-throwing coercion for the message field. `JSON.parse` always throws\n // a `SyntaxError`, but a hostile SyntaxError subclass with a throwing\n // `message` getter could still escape a raw `err.message` access —\n // delegating to `safeErrorToString` keeps the helper non-throwing.\n function tryEmitCandidate(candidate: string): boolean {\n attempts++;\n try {\n bestSuccess = JSON.parse(candidate);\n return true;\n } catch (err) {\n if (bestFailed === null) {\n bestFailed = {\n candidate,\n position: extractParsePosition(err),\n message: safeErrorToString(err),\n };\n }\n return false;\n }\n }\n\n while (i < text.length) {\n const ch = text[i];\n\n // Between top-level spans (stack empty after a failed candidate emit):\n // skip everything except a new container opener, and never accumulate\n // the inter-span text into `out` — sibling candidates must be\n // standalone spans, not span1 + prose + span2 concatenations that\n // JSON.parse can never accept.\n if (stack.length === 0 && !inString) {\n if (ch === '{' || ch === '[') {\n stack.push({ container: ch === '{' ? 'object' : 'array', expectKey: true });\n out += ch;\n }\n i++;\n continue;\n }\n\n if (escape) {\n out += ch;\n escape = false;\n i++;\n continue;\n }\n if (inString && ch === '\\\\') {\n out += ch;\n escape = true;\n i++;\n continue;\n }\n // Raw C0 control characters are invalid inside JSON strings, always.\n // Unlike the bare-quote case this repair is fully deterministic (no\n // comma-parity ambiguity — a control char inside a string body can\n // only be content), so both policy passes escape identically.\n if (inString) {\n const code = ch.charCodeAt(0);\n if (code < 0x20) {\n out += controlCharEscape(code);\n i++;\n continue;\n }\n }\n if (ch === '\"') {\n // Peek-ahead: skip whitespace, then look at the next non-whitespace char.\n let j = i + 1;\n while (j < text.length && (text[j] === ' ' || text[j] === '\\t' || text[j] === '\\n' || text[j] === '\\r')) {\n j++;\n }\n const next = j < text.length ? text[j] : '';\n\n if (!inString) {\n // A `\"` sitting at structural level right before a container close\n // is stray punctuation from a mis-tracked string boundary — emitting\n // it would open an unterminated string and guarantee JSON.parse\n // rejects the candidate. Skip the quote itself, preserve any\n // whitespace the peek-ahead skipped, emit the close, and pop.\n if (next === '}' || next === ']') {\n if (j > i + 1) out += text.slice(i + 1, j);\n out += next;\n i = j + 1;\n stack.pop();\n if (stack.length === 0) {\n if (tryEmitCandidate(out)) return { success: bestSuccess, failed: bestFailed, escapes, ambiguous };\n if (attempts >= MAX_REPAIR_CANDIDATES) break;\n out = '';\n }\n continue;\n }\n // Structural opening quote — always treated as opening (no escape).\n // Determine the string's role from the top frame: object + expectKey\n // → key, otherwise value. Arrays always treat strings as values.\n const top = stack[stack.length - 1];\n stringRole = top?.container === 'object' && top.expectKey ? 'key' : 'value';\n out += ch;\n inString = true;\n i++;\n continue;\n }\n\n // We're inside a string. Closing if next is one of , } ] : or another \" followed by :\n // Suppress the comma-only close when we have an open bare quote —\n // a `,` peek-ahead after an odd number of bare quotes means the\n // comma is body content, not a structural separator.\n //\n // Role-aware: `next === ':'` and `next === '\"' && text[j+1] === ':'`\n // are KEY-close signals (the `: ` is the JSON \"this string was a key\"\n // separator) and only fire for `stringRole === 'key'`. For value\n // strings, a `:` after the closing quote is body content (e.g.\n // `{\"body\":\"foo: \"bar\": baz\"}`) — closing prematurely there corrupts\n // the value. The `,` `}` `]` cases are value-close signals and always\n // apply.\n const commaOnly = next === ',';\n const isKeyClose = stringRole === 'key' && (\n next === ':' ||\n (next === '\"' && j + 1 < text.length && text[j + 1] === ':')\n );\n const isValueClose = !commaOnly && (\n next === ',' ||\n next === '}' ||\n next === ']'\n );\n // Comma-ambiguity: when the peek-ahead is `,` after at least one\n // bare-quote content escape, neither interpretation is structurally\n // implied — the comma is either a value separator OR content body.\n // The two passes diverge ONLY here (see the parameter docs on\n // `containerAwareRepair`): the `closeOnEvenParity=true` pass closes\n // on an even count (the legacy heuristic), the false pass on an odd\n // count. When `bareQuoteCount === 0` no ambiguity exists — the comma\n // must close — so both passes close and the caller can skip the\n // second pass entirely (see RepairResult.ambiguous).\n if (commaOnly && bareQuoteCount > 0) ambiguous = true;\n const shouldCommaClose =\n commaOnly && (\n bareQuoteCount === 0 ||\n (closeOnEvenParity\n ? bareQuoteCount % 2 === 0\n : bareQuoteCount % 2 === 1)\n );\n const isClosing =\n isKeyClose ||\n isValueClose ||\n shouldCommaClose;\n\n if (isClosing) {\n out += ch;\n inString = false;\n // Update the top frame's expectKey state. After closing a key, the\n // next string token is a value (separator is `:`) — expectKey=false.\n // After closing a value in an object, the next string token is a key\n // (separator is `,` or end-of-object) — expectKey=true. Array frames\n // ignore this flag (every string in an array is a value).\n const topFrame = stack[stack.length - 1];\n if (topFrame && topFrame.container === 'object') {\n topFrame.expectKey = stringRole === 'value';\n }\n stringRole = null;\n bareQuoteCount = 0;\n i++;\n continue;\n }\n\n // Content quote — escape it.\n out += '\\\\' + ch;\n bareQuoteCount++;\n escapes++;\n i++;\n continue;\n }\n if (!inString && (ch === '{' || ch === '[')) {\n // Push a new frame. Objects start expecting a key; arrays ignore the\n // flag (every string token is a value).\n stack.push({ container: ch === '{' ? 'object' : 'array', expectKey: true });\n out += ch;\n i++;\n continue;\n }\n if (!inString && ch === ',') {\n // A `,` in an object leaves us expecting a key. The string-close handler\n // already sets `expectKey=true` after a value close, so the only case\n // we need to handle here is the unit-structural case where the prior\n // element was a primitive (number, null, true, false, etc.) — its\n // position in the OUT stream is identical to a value close for the\n // purposes of the next string token.\n const topFrame = stack[stack.length - 1];\n if (topFrame && topFrame.container === 'object') {\n topFrame.expectKey = true;\n }\n out += ch;\n i++;\n continue;\n }\n if (!inString && (ch === '}' || ch === ']')) {\n out += ch;\n stack.pop();\n if (stack.length === 0) {\n // Balanced close at this position — try the candidate. The largest\n // outer span is the first one tried, so this short-circuits on the\n // success path. On a rejection, reset `out` so any trailing sibling\n // span is emitted standalone rather than concatenated onto the\n // already-rejected prefix.\n if (tryEmitCandidate(out)) return { success: bestSuccess, failed: bestFailed, escapes, ambiguous };\n if (attempts >= MAX_REPAIR_CANDIDATES) break;\n out = '';\n }\n i++;\n continue;\n }\n\n out += ch;\n i++;\n }\n\n return { success: null, failed: bestFailed, escapes, ambiguous };\n}\n\n/**\n * Maps a C0 control character's code point to its JSON string escape.\n * Uses the short forms JSON shares with JS (\\n, \\t, \\r, \\b, \\f) and\n * \\u00XX for everything else, exactly as JSON.stringify would.\n */\nfunction controlCharEscape(code: number): string {\n switch (code) {\n case 0x0A: return '\\\\n';\n case 0x09: return '\\\\t';\n case 0x0D: return '\\\\r';\n case 0x08: return '\\\\b';\n case 0x0C: return '\\\\f';\n default: return '\\\\u' + code.toString(16).padStart(4, '0');\n }\n}\n\n/**\n * Pulls the position offset out of a V8 `SyntaxError` message when present.\n * The V8 message format is `\"Unexpected token X in JSON at position N\"` (or\n * `\"Unexpected end of JSON input\"` with no position). We return `null` when\n * no position can be parsed — `WikiParseError.position` is `number | null`.\n *\n * Delegates the unknown→string coercion to `safeErrorToString` so a hostile\n * value (throwing toString, Proxy rejecting property access) can never throw\n * out of this helper and unwind the walker. JSON.parse always throws a\n * `SyntaxError`, so the defensive branch is rarely exercised in practice,\n * but the fallback is here to keep the walker non-throwing by construction.\n */\nfunction extractParsePosition(err: unknown): number | null {\n const match = /position\\s+(\\d+)/.exec(safeErrorToString(err));\n return match ? Number(match[1]) : null;\n}\n\n/**\n * Non-throwing coercion of an arbitrary JavaScript value to a string for\n * error-message reporting. JavaScript's `String(e)` returns `e.toString()`\n * for objects, which can throw if `toString` itself throws (e.g. an object\n * with a misbehaving prototype). Without this guard, a single provider-side\n * rejection can escape an `ingestDocument` per-chunk `catch` and tear down\n * `withConcurrency`, discarding every sibling chunk's results — the exact\n * silent-forever failure mode the partial-commit work exists to prevent.\n *\n * Falls back through:\n * - `Error.message` for `Error` instances (always available).\n * - `String(e)`, wrapped in try/catch.\n * - `Object.prototype.toString.call(e)` if `String(e)` threw (also wrapped).\n * - A static `[unstringifiable error]` marker as a final guarantee.\n */\nexport function safeErrorToString(e: unknown): string {\n // `e instanceof Error` invokes the `getPrototypeOf` trap on `e`. A Proxy\n // whose trap rejects turns the type-check itself into a throw point,\n // escaping every catch around this function body. Treat the trap throw\n // as \"not an Error\" and fall through to the String() / Object.prototype\n // paths, which themselves catch their own throws.\n let isErrorLike = false;\n try {\n isErrorLike = e instanceof Error;\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects — fall through\n }\n if (isErrorLike) {\n // Defensive: a hostile `Error` subclass or a tampered native Error could\n // set `message` to a non-string (e.g. `err.message = 42`) or make it a\n // throwing getter. `e.name` is similarly attacker-controllable. Coerce\n // both without unwinding so this helper is truly non-throwing.\n const msg = readErrorField(e, 'message');\n if (typeof msg === 'string' && msg.length > 0) return msg;\n const name = readErrorField(e, 'name');\n if (typeof name === 'string' && name.length > 0) return name;\n return '[Error]';\n }\n try {\n return String(e);\n } catch {\n try {\n return Object.prototype.toString.call(e);\n } catch {\n return '[unstringifiable error]';\n }\n }\n}\n\n/**\n * Read a fixed string-typed field off an `Error` instance without ever\n * throwing, even if a subclass installs a hostile getter. Internal helper\n * for `safeErrorToString`.\n */\nfunction readErrorField(e: unknown, key: 'message' | 'name'): unknown {\n try {\n return (e as Record<string, unknown>)[key];\n } catch {\n return undefined;\n }\n}\n\nexport function sanitizeRankerError(err: unknown, sanitizeRankerErrors: boolean | undefined): Error {\n // `err instanceof Error` invokes the `getPrototypeOf` trap on `err`. A\n // hostile Proxy (e.g. an injected VectorRanker returning one) whose trap\n // rejects would otherwise escape this \"sanitize\" function. Compute the\n // guard once — the property accesses below share the same hostile-input\n // surface and need their own guards.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n /* hostile Proxy — treat as non-Error */\n }\n if (sanitizeRankerErrors === false) {\n // `String(err)` invokes the `toString` / `Symbol.toPrimitive` trap on\n // `err`; a hostile Proxy whose trap rejects would throw out of this\n // function, defeating the non-throwing contract. Delegate to the\n // hardened `safeErrorToString` helper which converges all coercion\n // paths onto the static `[unstringifiable error]` marker on throw.\n return isErrorLike ? (err as Error) : new Error(safeErrorToString(err));\n }\n // `errLike.constructor?.name` and `.cause` access can also throw on a\n // hostile Error subclass with throwing getters (optional chaining `?.`\n // only short-circuits null/undefined, not trap throws). Wrap each access\n // so the function's documented non-throwing contract holds for all\n // attacker-controlled inputs.\n let errLike: Error | null = null;\n if (isErrorLike) errLike = err as Error;\n let typeName: string;\n try {\n if (errLike) {\n const rawName: unknown = errLike.constructor?.name;\n typeName = typeof rawName === 'string' ? rawName : 'Error';\n } else {\n typeName = typeof err;\n }\n } catch {\n typeName = isErrorLike ? 'Error' : typeof err;\n }\n let innerCause: Error | undefined;\n if (errLike) {\n let cause: unknown;\n try { cause = errLike.cause; } catch { cause = undefined; }\n if (cause !== undefined) {\n let causeName: string;\n try {\n const rawCauseName: unknown = (cause as Error)?.constructor?.name;\n causeName = typeof rawCauseName === 'string' ? rawCauseName : typeof cause;\n } catch {\n causeName = typeof cause;\n }\n innerCause = new Error(`Caused by: ${causeName}`);\n }\n }\n const sanitized = new Error(\n `VectorRanker ${typeName} (message scrubbed for security)`,\n innerCause ? { cause: innerCause } : undefined,\n );\n try { sanitized.name = typeName; } catch { /* hostile name setter — leave default */ }\n return sanitized;\n}\n\n/**\n * Slices a string like `String.prototype.slice`, but clamps out-of-range\n * indices instead of relying on JS's implicit clamping, normalizes a\n * start-after-end range by swapping the two bounds, and nudges either bound\n * off a UTF-16 surrogate pair boundary so slicing never splits one code\n * point in half.\n *\n * @param value - The source string to slice.\n * @param start - Start index; negative counts from the end, out-of-range\n * values are clamped to `[0, value.length]`.\n * @param end - End index (exclusive); defaults to `value.length` when\n * omitted. Same clamping/negative-index rules as `start`.\n * @returns The sliced substring, never splitting a surrogate pair.\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\n/**\n * Splits `input` into chunks of at most `maxChunkLength` characters,\n * preferring to split on a paragraph break, then a sentence terminator,\n * then whitespace, falling back to a hard cut only when none of those are\n * found within the window. Consecutive chunks overlap by up to `overlap`\n * characters so context isn't lost at a chunk boundary. This is the exact\n * chunking algorithm `IngestionService.ingestDocument` uses before\n * embedding, so callers can reproduce ingest-time chunk boundaries exactly\n * given the same `maxChunkLength`/`overlap` (see `DEFAULT_MAX_CHUNK_LENGTH`\n * and `DEFAULT_CHUNK_OVERLAP` for the defaults ingest uses).\n *\n * @param input - The text to chunk; leading/trailing whitespace is trimmed\n * before chunking. Empty/whitespace-only input returns the empty result\n * below without validating `maxChunkLength`/`overlap`.\n * @param maxChunkLength - For non-empty input, maximum characters per chunk;\n * must be an integer >= 2.\n * @param overlap - For non-empty input, maximum number of characters each\n * chunk repeats from the end of the previous chunk; must be a\n * non-negative integer less than `maxChunkLength`. A chunk repeats fewer\n * characters when the previous chunk was shorter than `overlap`.\n * @returns `chunks` — the resulting chunk strings (empty array for\n * empty/whitespace-only input); `truncated` — `true` if any split had to\n * fall back to a hard cut (no paragraph/sentence/whitespace boundary\n * found in the window).\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\n/** Why `validateFact` rejected `raw`. Only meaningful when `validateFact(raw)` returned null. */\nexport function factRejectionReason(raw: unknown): 'invalid_shape' | 'missing_title' | 'missing_body' {\n const fact = raw as { title?: unknown; body?: unknown } | null | undefined;\n if (typeof fact?.title !== 'string' || typeof fact?.body !== 'string') return 'invalid_shape';\n if (!clip(fact.title, 80)) return 'missing_title';\n return 'missing_body';\n}\n\n/** Why `validateTask` rejected `raw`. Only meaningful when `validateTask(raw)` returned null. */\nexport function taskRejectionReason(raw: unknown): 'invalid_shape' | 'missing_description' {\n const task = raw as { description?: unknown } | null | undefined;\n if (typeof task?.description !== 'string') return 'invalid_shape';\n return 'missing_description';\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 {\n WikiDiagnostic,\n WikiDiagnosticCode,\n WikiDiagnosticDetail,\n WikiDiagnosticOperation,\n WikiDiagnosticSeverity,\n WikiDiagnosticTrigger,\n WikiOptions,\n} from '../types';\nimport type { EdgeDrop } from './ontology';\n\n/** What a call site supplies; severity, message and timestamp are derived from `code`. */\nexport type WikiDiagnosticInput = Omit<WikiDiagnostic, 'severity' | 'message' | 'at'>;\n\ntype DiagnosticTarget = Pick<WikiOptions, 'onDiagnostic'>;\n\nconst SEVERITY: Record<WikiDiagnosticCode, WikiDiagnosticSeverity> = {\n ingest_chunk_failed: 'warn',\n fact_rejected: 'warn',\n task_rejected: 'warn',\n fact_deduplicated: 'info',\n edge_dropped: 'warn',\n embedding_failed: 'warn',\n hook_failed: 'warn',\n background_job_failed: 'error',\n heal_skipped: 'warn',\n grounding_missing: 'warn',\n grounding_failed: 'warn',\n classification_low_confidence: 'info',\n classification_invalid: 'warn',\n};\n\n// Fixed templates (REQ-DIAG-03): never interpolate content into these.\nconst MESSAGE: Record<WikiDiagnosticCode, string> = {\n ingest_chunk_failed: 'One or more document chunks failed to parse or generate.',\n fact_rejected: 'An extracted fact failed validation and was not written.',\n task_rejected: 'An extracted task failed validation and was not written.',\n fact_deduplicated: 'An extracted fact duplicated an existing fact and was not written.',\n edge_dropped: 'An extracted edge could not be resolved against the ontology and was not written.',\n embedding_failed: 'A fact could not be embedded.',\n hook_failed: 'A host hook threw or rejected.',\n background_job_failed: 'A background maintenance job failed.',\n heal_skipped: 'Heal skipped a candidate fact.',\n grounding_missing: 'A fact carried no qualifying evidence and was stored as a draft.',\n grounding_failed: 'A fact carried evidence not found in its source and was stored as a draft.',\n classification_low_confidence: 'A classifier answer was below the confidence threshold and was not applied.',\n classification_invalid: 'A classifier answer was invalid and was not applied.',\n};\n\nconst warnedNonFunction = new WeakSet<object>();\n\nfunction copyDetail(detail: WikiDiagnosticDetail): WikiDiagnosticDetail {\n const copy: WikiDiagnosticDetail = { ...detail };\n if (detail.chunkIndexes) copy.chunkIndexes = detail.chunkIndexes.slice();\n return copy;\n}\n\n/**\n * Deliver one diagnostic to the host hook. Never throws, never awaits, and\n * never writes to the console unless the hook itself misbehaves (REQ-DIAG-02).\n */\nexport function emitDiagnostic(options: DiagnosticTarget, input: WikiDiagnosticInput): void {\n const hook: unknown = options.onDiagnostic;\n if (hook === undefined || hook === null) return;\n if (typeof hook !== 'function') {\n if (!warnedNonFunction.has(options)) {\n warnedNonFunction.add(options);\n console.warn('[WikiMemory] onDiagnostic is not a function; diagnostics are disabled.');\n }\n return;\n }\n const diagnostic: WikiDiagnostic = {\n code: input.code,\n severity: SEVERITY[input.code],\n operation: input.operation,\n trigger: input.trigger,\n entityId: input.entityId,\n at: Date.now(),\n message: MESSAGE[input.code],\n ...(input.detail ? { detail: copyDetail(input.detail) } : {}),\n };\n try {\n const returned: unknown = (hook as (d: WikiDiagnostic) => unknown)(diagnostic);\n if (returned !== undefined) {\n // Promise.resolve never throws synchronously; a hostile thenable rejects instead.\n Promise.resolve(returned).catch((err: unknown) => {\n console.warn('[WikiMemory] onDiagnostic hook rejected:', err);\n });\n }\n } catch (err) {\n console.warn('[WikiMemory] onDiagnostic hook threw:', err);\n }\n}\n\n/**\n * Operation-scoped buffer (spec §4.2.4): push while the operation's\n * transaction is open, `flush` after it commits, `discard` (or simply drop the\n * buffer) when the operation throws.\n */\nexport class DiagnosticBuffer {\n private items: WikiDiagnosticInput[] = [];\n\n push(input: WikiDiagnosticInput): void {\n this.items.push(input);\n }\n\n get size(): number {\n return this.items.length;\n }\n\n flush(options: DiagnosticTarget): void {\n const pending = this.items;\n this.items = [];\n for (const input of pending) emitDiagnostic(options, input);\n }\n\n discard(): void {\n this.items = [];\n }\n}\n\n/** Map an `EdgeDrop` to an `edge_dropped` diagnostic input. Omits unknown locators instead of sending nulls. */\nexport function edgeDropDiagnostic(\n drop: EdgeDrop,\n ctx: {\n entityId: string;\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n sourceRef?: string;\n factId?: string;\n },\n): WikiDiagnosticInput {\n const detail: WikiDiagnosticDetail = { reason: drop.reason };\n const factId = ctx.factId ?? drop.sourceId;\n if (factId) detail.factId = factId;\n if (drop.edgeType) detail.edgeType = drop.edgeType;\n if (drop.sourceNodeType) detail.sourceNodeType = drop.sourceNodeType;\n if (drop.targetNodeType) detail.targetNodeType = drop.targetNodeType;\n if (ctx.sourceRef) detail.sourceRef = ctx.sourceRef;\n return { code: 'edge_dropped', operation: ctx.operation, trigger: ctx.trigger, entityId: ctx.entityId, detail };\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. JSON escaping rules: every literal \" character in the source must be escaped as \\\\\" inside any JSON string body, and every literal newline as \\\\n. Source prose containing quotes (e.g. a worked example with \"...\") must still be reproduced exactly — re-escape, do not omit. 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.\nWhen echoing an existing fact's title verbatim into \"target_title\", preserve every JSON escape sequence (\\\\\", \\\\n, \\\\\\\\, \\\\/) exactly as it appeared in the input body — do not strip backslashes, do not add unescaped quotes. Do not return markdown, just raw JSON.`;\n","/**\n * Shared constants for the heal pipeline.\n *\n * Both `PromptService.buildHealPrompt` (which applies the L0 anchor cap and\n * the L3 body truncation default) and `MaintenanceService.doRunHeal` (which\n * fetches tasks at the cap and looks up anchors with the overfetch sized off\n * it) read from this module. The spec (\"heal output-bounded convergence\n * ladder\") explicitly requires the values to match across the two callers —\n * if they drift, the L0 anchor slice and `_selectHealAnchors`'s overfetch\n * silently disagree with no test catching the gap.\n *\n * Lives in `utils/` rather than alongside `MaintenanceService` because\n * `PromptService` is constructed before `MaintenanceService` exists, and\n * importing from `MaintenanceService` would create a cycle at construction\n * time. A leaf constants module has no such risk.\n *\n * Heal-specific batch sizing, recheck cadence, and prompt char limits\n * (`HEAL_BATCH_SIZE`, `HEAL_RECHECK_MS`, `HEAL_MAX_PROMPT_CHARS`,\n * `HEAL_ANCHOR_SEARCH_OVERFETCH`) are not duplicated across files and stay\n * in `MaintenanceService.ts` — moving them here would expand this module's\n * surface without buying anything.\n */\n\n/** Cap on document anchors surfaced to the model at L0. */\nexport const HEAL_MAX_ANCHORS = 50;\n\n/** Per-candidate anchor ratio used at L0: `min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE)`. */\nexport const HEAL_ANCHORS_PER_CANDIDATE = 4;\n\n/**\n * Default body truncation cap applied at L3 only. A fact whose body is at or\n * below this cap passes through unchanged; a fact above it is sliced to this\n * length with a `...[truncated at N chars, original was M]` marker.\n */\nexport const HEAL_MAX_FACT_BODY_CHARS_L3 = 4_000;\n\n/**\n * Hard ceiling on the `allTasks` slice fed to the heal prompt at L0. Tasks\n * are entity-global (not batch-local), so this is a constant rather than a\n * function of batch length.\n */\nexport const HEAL_MAX_TASKS = 50;","import {\n INGEST_SYSTEM_PROMPT,\n LIBRARIAN_SYSTEM_PROMPT,\n HEAL_SYSTEM_PROMPT,\n ONTOLOGY_BACKFILL_SYSTEM_PROMPT,\n} from '../prompts';\nimport type { DegradedRecord, PromptOverrides, OntologyPromptContext } from '../types';\nimport {\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_MAX_ANCHORS,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n} from '../utils/healConstants';\nimport { safeSlice } from '../utils/pure';\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 /**\n * Heal-prompt level interpretation for the `attemptLevel` ladder.\n *\n * Caller contract: `documentAnchors` may be a slice sized for `batch.length`\n * or a larger set (e.g. a cache hit from `_selectHealAnchors`). This function\n * applies the prompt-side anchor cap `min(HEAL_MAX_ANCHORS=50, batch.length\n * * HEAL_ANCHORS_PER_CANDIDATE=4)` so the rendered prompt is bounded\n * regardless of caller input. `HEAL_MAX_ANCHORS` and\n * `HEAL_ANCHORS_PER_CANDIDATE` live here too — keeping the formula\n * co-located with its application avoids a \"MaintenanceService policy\"\n * import cycle (`PromptService` is constructed before `MaintenanceService`\n * exists) and makes the cap testable without a `MaintenanceService`\n * instance. Task 3 exports the same two constants from `MaintenanceService`\n * for caller-side overfetch sizing; the values must match.\n *\n * Level semantics:\n * - L0: allTasks + recentEvents + full candidate bodies; anchors re-capped\n * - L1: drop allTasks; recentEvents present; candidate bodies full\n * - L2: drop allTasks and recentEvents; candidate bodies full\n * - L3: drop allTasks and recentEvents; truncate each candidate body to\n * `bodyTruncationChars` and emit a `degraded` record per truncated fact\n */\n buildHealPrompt(\n healCandidates: unknown[],\n documentAnchors: unknown[],\n allTasks: unknown[],\n recentEvents: unknown[],\n runtimeOverride: string | undefined,\n attemptLevel: 0 | 1 | 2 | 3,\n bodyTruncationChars: number = HEAL_MAX_FACT_BODY_CHARS_L3,\n ): { prompts: { systemPrompt: string; userPrompt: string }; degraded: DegradedRecord[] } {\n // L0: all context. L1: drop allTasks. L2: also drop recentEvents.\n const effectiveTasks = attemptLevel >= 1 ? [] : allTasks;\n const effectiveEvents = attemptLevel >= 2 ? [] : recentEvents;\n\n // L0 anchor cap: min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE).\n // The caller is responsible for sizing the documentAnchors slice; we re-cap\n // here in case the caller passed a superset (e.g. from _selectHealAnchors\n // cache). Constants live in utils/healConstants so PromptService and\n // MaintenanceService cannot drift apart (spec: \"values must match\").\n const maxAnchors = Math.max(1, Math.min(HEAL_MAX_ANCHORS, healCandidates.length * HEAL_ANCHORS_PER_CANDIDATE));\n const effectiveAnchors = documentAnchors.slice(0, maxAnchors);\n\n // L3: truncate each candidate's body independently. A fact whose body\n // is already <= bodyTruncationChars passes through unchanged; the\n // caller sees that fact is absent from `degraded` and can treat the\n // result as if no truncation had occurred.\n const { shapedCandidates, degraded } = applyBodyTruncation(\n healCandidates,\n attemptLevel,\n bodyTruncationChars,\n );\n\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 prompts: {\n systemPrompt: this.hydrate(template, {\n healCandidates: shapedCandidates,\n documentAnchors: effectiveAnchors,\n allTasks: effectiveTasks,\n recentEvents: effectiveEvents,\n }),\n userPrompt: 'Please heal the memory graph.',\n },\n degraded,\n };\n }\n return {\n prompts: {\n systemPrompt: template,\n userPrompt: `Heal Candidates:\\n${JSON.stringify(shapedCandidates, null, 2)}\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(effectiveAnchors, null, 2)}\\nAll Tasks:\\n${JSON.stringify(effectiveTasks, null, 2)}\\nRecent Events:\\n${JSON.stringify(effectiveEvents, null, 2)}\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`,\n },\n degraded,\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\n/**\n * Truncate candidate bodies at L3 only. Each fact is sliced independently;\n * a fact whose body is at or below the cap passes through unchanged. The\n * trailing marker is what the post-reconcile log line references — an\n * operator scanning the log sees the truncation magnitude without\n * re-querying the fact.\n *\n * A candidate that needs truncation but lacks a string id passes through\n * untruncated: the upstream contract (`WikiFact.id` is a `TEXT PRIMARY KEY`)\n * guarantees string ids in practice, and truncating without an id would\n * emit a body the model can verdict under but with no DegradedRecord for\n * `MaintenanceService.doRunHeal` to reconcile — violating the\n * degraded ⊥ skipped invariant on id.\n */\nfunction applyBodyTruncation(\n candidates: unknown[],\n attemptLevel: 0 | 1 | 2 | 3,\n bodyTruncationChars: number,\n): { shapedCandidates: unknown[]; degraded: DegradedRecord[] } {\n if (attemptLevel < 3) {\n return { shapedCandidates: candidates, degraded: [] };\n }\n const shapedCandidates: unknown[] = [];\n const degraded: DegradedRecord[] = [];\n for (const c of candidates) {\n if (typeof c !== 'object' || c === null) {\n shapedCandidates.push(c);\n continue;\n }\n const fact = c as { id?: unknown; body?: unknown };\n const body = typeof fact.body === 'string' ? fact.body : '';\n if (body.length <= bodyTruncationChars) {\n shapedCandidates.push(c);\n continue;\n }\n // A candidate that needs L3 truncation must carry a string id so\n // doRunHeal can reconcile the truncation back to the source row\n // (`HealResult.degraded` is keyed by id, and degraded ⊥ skipped on id).\n // Without one the candidate passes through untruncated — the invariant\n // \"every truncated candidate has a DegradedRecord\" holds, and the\n // upstream contract (WikiFact.id is a TEXT PRIMARY KEY) means this\n // branch is defensive against future schema drift, not a happy path.\n if (typeof fact.id !== 'string') {\n shapedCandidates.push(c);\n continue;\n }\n const originalBodyChars = body.length;\n // `safeSlice` (utils/pure) keeps the boundary inside a UTF-16 surrogate\n // pair intact — a bare `String.prototype.slice` can land mid-codepoint and\n // emit a lone high surrogate that JSON.stringify turns into U+FFFD. The\n // same hazard is handled for `formatSkipError` log lines in\n // MaintenanceService. Bodies can be emoji-heavy. The returned prefix may\n // be one or two chars shorter than `bodyTruncationChars` when the cut\n // backs off the surrogate boundary, so `truncatedBodyChars` reads from\n // `prefix.length` rather than the requested limit.\n const prefix = safeSlice(body, 0, bodyTruncationChars);\n const truncatedBodyChars = prefix.length;\n const truncated = `${prefix}…[truncated at ${truncatedBodyChars} chars, original was ${originalBodyChars}]`;\n shapedCandidates.push({ ...fact, body: truncated });\n degraded.push({ id: fact.id, originalBodyChars, truncatedBodyChars });\n }\n return { shapedCandidates, degraded };\n}\n","/**\n * Default maximum characters per chunk that `ingestDocument` uses when a\n * caller doesn't override `maxChunkLength` (directly or via\n * `WikiOptions.config.maxChunkLength`).\n */\nexport const DEFAULT_MAX_CHUNK_LENGTH = 12000;\n\n/**\n * Default/fallback character overlap between consecutive chunks.\n * `ingestDocument` uses this when a caller doesn't override `chunkOverlap`\n * (directly or via `WikiOptions.config.chunkOverlap`), and clamps the\n * effective overlap (including this default) to `maxChunkLength - 1` when\n * needed. The clamp is a no-op for the shipped defaults; it can also apply\n * when a custom `maxChunkLength` makes the resolved overlap too large.\n */\nexport const DEFAULT_CHUNK_OVERLAP = 400;\n","import { chunkText, withConcurrency, validateFact, factRejectionReason, parseJsonResponse, normalizeSourceRef, normalizeSourceHash, safeErrorToString } from '../utils/pure';\nimport { normalizeTitleKey, typeSatisfies } from '../utils/ontology';\nimport { DiagnosticBuffer, emitDiagnostic, edgeDropDiagnostic } from '../utils/diagnostics';\nimport type { EdgeDrop } from '../utils/ontology';\nimport { generateId } from '../utils/ids';\nimport { WikiParseError, WikiIngestEmptyError, WikiDuplicateHashError, WikiTransactionError, WikiStrictOntologyViolation, WikiGraphNodeOwnershipConflict } from '../types';\nimport type { ChunkFailure, WikiOptions, ExtractedFact, ExtractedFactEdge, ExtractedFactWithOntology, WikiFact, OntologyUpdates, WikiEdge, IngestDocumentResult } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport { extractSqliteCode } from '../db/sqliteCodes';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SourceRefIndexRepository } from '../repositories/SourceRefIndexRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\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';\nimport { DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_CHUNK_OVERLAP } from '../utils/chunkingDefaults';\n\ntype ChunkResult =\n | { status: 'ok'; facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }\n | { status: 'failed'; error: ChunkFailure };\n\n/** Shape returned by {@link IngestionService.ingestDocument} when no chunks\n * ran — used for both the `chunks.length === 0` early-return and the\n * `onDuplicateHash: 'skip'` early-return. `duplicateOf` is present as an own\n * key ONLY when the skip is owed to a duplicate-hash collision — hosts using\n * `'duplicateOf' in result` to detect that case must not see the key on the\n * empty-document path (matching the pre-widening contract). */\nfunction zeroChunkResult(duplicateOf?: string): IngestDocumentResult {\n const result: IngestDocumentResult = {\n truncated: false,\n chunks: 0,\n ingestedChunks: 0,\n failedChunks: 0,\n };\n if (duplicateOf !== undefined) result.duplicateOf = duplicateOf;\n return result;\n}\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 sourceRefIndexRepo: SourceRefIndexRepository,\n private metadataRepo: MetadataRepository,\n private edgeRepo: EdgeRepository,\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 opts?: { onDuplicateHash?: 'ingest' | 'skip' | 'throw' },\n ): Promise<IngestDocumentResult> {\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 ?? DEFAULT_MAX_CHUNK_LENGTH;\n const rawOverlap = params.chunkOverlap ?? this.options.config?.chunkOverlap ?? DEFAULT_CHUNK_OVERLAP;\n const chunkOverlap = Math.min(\n Number.isFinite(rawOverlap) && rawOverlap >= 0 ? Math.floor(rawOverlap) : DEFAULT_CHUNK_OVERLAP,\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 // Acquire the hash + sourceRef ingest locks BEFORE the duplicate pre-check\n // so concurrent same-hash callers serialize here. Two callers that both\n // observe no duplicate at the pre-check can otherwise both reach the\n // INSERT and trip the v9 UNIQUE constraint — see\n // docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B.\n const releaseIngestLocks = await this.jobManager.acquireIngestLocks(entityId, sourceRef, sourceHash);\n\n try {\n // Duplicate-hash guard: runs AFTER acquireIngestLocks but BEFORE chunking\n // and any LLM call. With the per-hash lock held by the previous holder,\n // we are guaranteed to observe any committed write they made before\n // releasing. Early duplicate returns go through the `finally` block\n // below so both locks are released cleanly.\n const onDuplicateHash = opts?.onDuplicateHash ?? 'ingest';\n if (onDuplicateHash !== 'ingest') {\n // Source_ref_index is the source of truth for \"who currently holds\n // this hash\"; the pre-check queries it directly. At most one sourceRef\n // can hold a given hash, so the result is either null (no live ref)\n // or a single sourceRef (which cannot echo the incoming ref because\n // the source_ref_index row is the OTHER writer's).\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n if (canonical !== null && canonical !== sourceRef) {\n if (onDuplicateHash === 'throw') {\n throw new WikiDuplicateHashError({ canonical, sourceHash, entityId });\n }\n // 'skip'\n return zeroChunkResult(canonical);\n }\n }\n\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n if (chunks.length === 0) return zeroChunkResult();\n\n // Hoist the ontology prompt context out of the per-chunk closure:\n // `buildPromptContext(entityId)` depends only on entityId and reads\n // the manifest ONCE; running it per chunk is N-1 wasted DB reads.\n // Hoisting also makes its DB-systemic nature structural — a fault\n // surfaces before any LLM tokens are spent, not buried under\n // `WikiIngestEmptyError` after the first LLM call. See spec §3.\n const ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n\n const chunkResults = await withConcurrency(\n chunks.map((chunk, chunkIndex) => async () => {\n // Prompt building is INTENTIONALLY outside the try — it's a\n // template-driven step whose failures (malformatted\n // `promptOverride`, configured-template regression) are systemic\n // and identical for every chunk. Surfacing as a raw throw means\n // the host sees the real cause on the first chunk instead of\n // after `chunks.length` LLM calls under a `WikiIngestEmptyError`.\n // See spec §3.\n const { systemPrompt, userPrompt } = this.promptService.buildIngestPrompt(\n chunk,\n params.promptOverride,\n ontologyContext,\n );\n try {\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n const result = parseJsonResponse<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>(responseText);\n const rawFacts: unknown[] = Array.isArray(result.facts) ? result.facts : [];\n const facts: ExtractedFact[] = [];\n const itemIndexes: number[] = [];\n const rejected: Array<{ itemIndex: number; reason: ReturnType<typeof factRejectionReason> }> = [];\n rawFacts.forEach((raw, itemIndex) => {\n const valid = validateFact(raw);\n if (valid) {\n facts.push(valid);\n itemIndexes.push(itemIndex);\n } else {\n rejected.push({ itemIndex, reason: factRejectionReason(raw) });\n }\n });\n return {\n status: 'ok' as const,\n facts,\n itemIndexes,\n rejected,\n ontology_updates: result.ontology_updates,\n };\n } catch (e) {\n const failure: ChunkFailure = e instanceof WikiParseError\n ? {\n chunkIndex,\n sourceRef,\n source: 'parse',\n tier: e.tier,\n position: e.position,\n message: e.message,\n }\n : {\n chunkIndex,\n sourceRef,\n source: 'llm',\n // `safeErrorToString` is a non-throwing coercion: an LLM\n // provider may reject with a non-Error value, and even\n // `String(e)` itself can throw when `e.toString()` throws.\n // Letting such an exception escape this catch would cause\n // `withConcurrency` to reject, discarding every sibling\n // chunk's results — the exact failure mode this per-chunk\n // try/catch exists to prevent. Keeping the value in the\n // `ChunkFailure` preserves the typed diagnostic for\n // callers (see parseFailures) without unwinding the loop.\n position: null,\n message: safeErrorToString(e),\n };\n // Spec §2: log once per failure, NEVER include the raw response.\n // We deliberately omit `failure.message` here:\n // - For `source: 'parse'` the message is the parser's diagnostic\n // (safe) but in the interest of a single, narrow warn format we\n // surface only the tier (and position when known) on the log.\n // - For `source: 'llm'` the message is provider-controlled: an\n // LLM SDK commonly surfaces the raw response body, document\n // content, or a multi-megabyte HTTP error in `Error.message`.\n // Even a parser-diagnostic message that happens to share bytes\n // with a never-logged raw response would leak if we printed\n // it verbatim. The full message stays in `parseFailures` for\n // callers that want it; the warn line is intentionally narrow.\n const total = chunks.length;\n const tags: string[] = [];\n if (failure.tier) tags.push(`tier=${failure.tier}`);\n if (failure.position !== null) tags.push(`position=${failure.position}`);\n const tagsSuffix = tags.length > 0 ? `; ${tags.join(' ')}` : '';\n console.warn(\n `[WikiMemory] ingest chunk ${chunkIndex + 1}/${total} ${failure.source} failed (sourceRef=${sourceRef}${tagsSuffix})`,\n );\n return { status: 'failed' as const, error: failure };\n }\n }),\n chunkConcurrency\n );\n\n // Single pass: collect failures, dedup ok facts against the cross-chunk\n // `seen` set, and count `ingestedChunks` / `failedChunks` together.\n let ingestedChunks = 0;\n let failedChunks = 0;\n const failures: ChunkFailure[] = [];\n const seen = new Set<string>();\n const orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }> = [];\n const diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'ingest' as const, trigger: 'call' as const };\n for (const [chunkIndex, slot] of chunkResults.entries()) {\n if (slot.status === 'failed') {\n failedChunks++;\n failures.push(slot.error);\n continue;\n }\n ingestedChunks++;\n for (const r of slot.rejected) {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { sourceRef, chunkIndex, itemIndex: r.itemIndex, reason: r.reason } });\n }\n const dedupedFacts: ExtractedFact[] = [];\n slot.facts.forEach((fact, k) => {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (!seen.has(normalizedTitle)) {\n seen.add(normalizedTitle);\n dedupedFacts.push(fact);\n } else {\n diagBuffer.push({\n ...diagBase, code: 'fact_deduplicated',\n detail: { sourceRef, chunkIndex, itemIndex: slot.itemIndexes[k], reason: 'exact_title' },\n });\n }\n });\n orderedChunkFacts.push({ facts: dedupedFacts, ontology_updates: slot.ontology_updates });\n }\n\n for (const reason of ['parse', 'llm'] as const) {\n const ofReason = failures.filter((f) => f.source === reason);\n if (ofReason.length === 0) continue;\n diagBuffer.push({\n ...diagBase, code: 'ingest_chunk_failed',\n detail: {\n sourceRef, reason, count: ofReason.length,\n chunkIndexes: ofReason.map((f) => f.chunkIndex).sort((a, b) => a - b).slice(0, 20),\n },\n });\n }\n\n // Total failure: throw WikiIngestEmptyError before any persistence runs.\n // A silent zero-fact ingest is a worse regression than a typed throw.\n if (failedChunks === chunks.length) {\n throw new WikiIngestEmptyError({\n parseFailures: failures,\n sourceRef,\n chunks: chunks.length,\n });\n }\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const deletedSourceFactIds: string[] = [];\n\n try {\n if (failedChunks === 0) {\n // Happy path — full upsertGraphCore supersession + ownership.\n const fullResult = await this.db.withTransactionAsync(async (tx) => {\n return await this.runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer);\n });\n deletedSourceFactIds.push(...fullResult.deletedSourceFactIds);\n insertedFacts.push(...fullResult.insertedFacts);\n } else {\n // Partial path — append dedup-only, NO supersession, NO ownership update.\n // See spec §4.2. `insertedFacts` carries the per-fact descriptors\n // the post-commit hook loop needs to fire `embedFact` after the\n // partial transaction commits — without this, partial-row facts\n // would never reach the embedding service and the vector ranker\n // would never be notified for them (despite them being live in\n // the entries table). See the copilot review note on\n // `embeddingService.embedFact` vs. the partial-path gate.\n const partialResult = await this.db.withTransactionAsync(async (tx) => {\n const flat: ExtractedFact[] = [];\n for (const slot of orderedChunkFacts) flat.push(...slot.facts);\n return await this.appendPartialFacts(entityId, sourceRef, flat, tx, diagBuffer);\n });\n insertedFacts.push(...partialResult.insertedDescriptors);\n }\n } catch (err) {\n // A concurrent ingest for a DIFFERENT sourceRef beat us to the same\n // sourceHash between the pre-check above and this write — the\n // source_ref_index partial UNIQUE index (entity_id, source_hash)\n // rejected the upsert. Translate into the same duplicate-hash\n // outcome the pre-check would have produced, by mode. Any other\n // error re-throws unmodified. With the entries-level UNIQUE gone,\n // every UNIQUE violation inside this transaction originates from\n // source_ref_index, so the single check is sufficient.\n const sqliteCode = err instanceof WikiTransactionError\n ? err.sqliteErrorCode\n : extractSqliteCode(err);\n if (sqliteCode !== 'SQLITE_CONSTRAINT_UNIQUE') throw err;\n\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n // No other live ref holds this hash (e.g. a different constraint\n // fired, or the racing writer's row was itself rolled back) — the\n // UNIQUE violation isn't explained by a duplicate-hash race; surface\n // the original error rather than a misleading result.\n if (canonical === null) throw err;\n\n if (onDuplicateHash === 'throw' || onDuplicateHash === 'ingest') {\n throw new WikiDuplicateHashError({ canonical, sourceHash, entityId });\n }\n // 'skip'\n return zeroChunkResult(canonical);\n }\n\n // Post-commit (spec §4.2.4). The duplicate-hash `return zeroChunkResult(...)`\n // paths in the catch above leave without flushing: nothing was committed.\n diagBuffer.flush(this.options);\n\n await this.searchService.sync(entityId);\n\n // Post-commit hook loop. `notifyEmbeddingPersisted(entityId, factId, null)`\n // is the embedding-lifecycle retirement signal — only relevant on the\n // full path, which is the only path that calls `softDeleteBySource`.\n // `embedFact` runs for every newly-inserted fact on EITHER path: the\n // partial path appends live rows, and those rows must participate in\n // semantic retrieval just like full-path facts — otherwise a 6-of-7\n // partial commit would leave the embedded fields null until a later\n // full retry, and a vector ranker wouldn't be notified for them.\n // (The earlier gate `if (failedChunks === 0)` blocked both halves of\n // this block on the partial path and was the bug copilot flagged.)\n if (failedChunks === 0) {\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 emitDiagnostic(this.options, {\n entityId, operation: 'ingest', trigger: 'call', code: 'hook_failed',\n detail: { factId, reason: 'on_embedding_persisted' },\n });\n }\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'ingest', trigger: 'call' });\n }\n\n this.searchService.evictCache(entityId);\n\n const result: IngestDocumentResult = {\n truncated,\n chunks: chunks.length,\n ingestedChunks,\n failedChunks,\n };\n if (failedChunks > 0) result.parseFailures = failures;\n return result;\n\n } finally {\n releaseIngestLocks();\n }\n }\n\n /**\n * Reject the whole write when any incoming node ID is already owned by a\n * different entity. Runs entirely inside the supplied `tx`, through the\n * repository abstraction, and — being the first thing `upsertGraphCore`\n * does — before ontology resolution, which can itself persist a configured\n * seed manifest.\n *\n * The lookup has no deleted-row filter, so a soft-deleted foreign row keeps\n * its ID reserved. Only the lookup IDs are deduplicated; `params.nodes` and\n * the later write loops keep their ordering and counts.\n *\n * The error is deliberately contextless — see WikiGraphNodeOwnershipConflict.\n *\n * @param entityId - the entity the caller is writing on behalf of. Foreign\n * rows under a different entity trigger the rejection.\n * @param nodes - incoming node set; only the IDs are inspected, so callers\n * may pass the public `params.nodes` shape directly without slicing.\n * @param tx - the open transaction. Reuses the same handle every later\n * statement in `upsertGraphCore` runs against, so atomicity is enforced\n * by the host transaction's commit/rollback, not by this method.\n */\n private async assertGraphNodeOwnership(\n entityId: string,\n nodes: readonly { id: string }[],\n tx: SQLiteAdapter,\n ): Promise<void> {\n const ids = [...new Set(nodes.map(node => node.id))];\n const existing = await this.entryRepo.findExistingMetadataByIds(ids, tx);\n for (const row of existing) {\n if (row.entity_id !== entityId) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n }\n }\n\n /**\n * Implements spec §2 data flow steps a–j with the host-facing\n * `{sourceRef, sourceHash, nodes, edges}` parameter shape. Shared between\n * `ingestDocument` (with `{ strict: false }` to preserve current behavior)\n * and `WikiMemory.upsertGraph` (which lets the persisted ontology mode\n * decide strictness).\n *\n * Runs ENTIRELY inside the supplied `tx`. Does not acquire locks, does not\n * open a nested transaction, does not perform post-commit work (search\n * sync, embedding, cache eviction). Those concerns remain in `ingestDocument`.\n *\n * The pre-flight validation (steps a–c) lives INSIDE this method per the\n * spec, so the public `WikiMemory.upsertGraph` can be a thin wrapper that\n * performs only the C2 probe before delegating.\n *\n * @returns Counts: nodesWritten (validated nodes persisted), edgesWritten\n * (manifest-valid edges persisted), superseded (prior facts soft-deleted\n * plus prior source-ref edges hard-deleted).\n *\n * Node-ownership pre-flight (spec §3, REQ-GRAPH-01): the first statement\n * is `assertGraphNodeOwnership(entityId, params.nodes, tx)`, which runs\n * before ontology resolution, seed-manifest persistence, and every other\n * write. A foreign-owned ID throws `WikiGraphNodeOwnershipConflict` with\n * no disclosed owner, node ID, or content; the caller's transaction\n * remains open and must be rolled back by the host. Soft-deleted foreign\n * rows keep their IDs reserved. Duplicate incoming IDs are deduplicated\n * only for the lookup; `params.nodes` and the write loops keep their\n * ordering and counts so success counts match the pre-change contract.\n */\n async upsertGraphCore(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n nodes: readonly { id: string; type: string; title: string; body?: string; tags?: readonly string[]; confidence?: 'certain' | 'inferred' | 'tentative' }[];\n edges: readonly { type: string; sourceId: string; targetId: string; id?: string }[];\n },\n tx: SQLiteAdapter,\n opts?: { strict?: boolean; diag?: { buffer: DiagnosticBuffer; operation: 'ingest' | 'upsertGraph' } },\n ): Promise<{ nodesWritten: number; edgesWritten: number; superseded: number }> {\n // Node-ownership pre-flight FIRST — before ontology resolution and every\n // persistent mutation, so a rejected write leaves no seeded manifest\n // behind. Shared with ingestDocument's full path via runFullUpsertGraph;\n // that is intended. No bypass flag exists by design.\n await this.assertGraphNodeOwnership(entityId, params.nodes, tx);\n\n const now = Date.now();\n\n // (a) Resolve the effective ontology state through OntologyService rather\n // than reading metadataRepo.getManifest directly. OntologyService handles\n // the seedManifests contract (types.ts:65-66 — seeds are persisted on\n // first access when a tx is supplied, and cached otherwise) and the\n // ontologyConfig.mode fallback. Reading the repo directly here would\n // return null for an entity that has only a seedManifests entry, leaving\n // the strict mode silently unwritten and letting out-of-manifest data\n // through even when the host configured strict via the seed.\n const ontologyState = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n let { mode, manifest } = ontologyState;\n // `opts.strict === false` overrides the persisted mode (used by\n // ingestDocument to preserve its pre-strict-mode silent-drop behavior).\n // `opts.strict === true` forces strict. `opts.strict === undefined`\n // follows the persisted mode.\n const strictEffective = opts?.strict === false\n ? false\n : opts?.strict === true || mode === 'strict';\n\n // (b) Pre-flight node validation — all-or-nothing under strict mode.\n // Build WikiFacts ready for upsert, with canonical okf_type.\n const wikiFacts: WikiFact[] = [];\n for (const node of params.nodes) {\n const factLike = { okf_type: node.type, edges: [] } as unknown as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(factLike, manifest, {\n strict: strictEffective,\n entityId,\n }) ?? { okf_type: null, edges: [] };\n const wikiFact: WikiFact = {\n id: node.id,\n entity_id: entityId,\n title: node.title,\n body: node.body ?? '',\n // Public upsertGraph callers don't supply tags/confidence, so they\n // default to [] / 'certain' for deterministic AST-grade facts.\n // ingestDocument routes through this method for the LLM path and\n // forwards the LLM-supplied tags + confidence, preserving the prior\n // behavior (search filterability, heal-candidate selection, runReembed\n // embedding-text signal).\n tags: node.tags ? Array.from(node.tags) : [],\n confidence: node.confidence ?? 'certain',\n source_type: 'immutable_document',\n source_hash: params.sourceHash,\n source_ref: params.sourceRef,\n created_at: now,\n updated_at: now,\n last_accessed_at: null,\n access_count: 0,\n deleted_at: null,\n okf_type: normalized.okf_type,\n };\n wikiFacts.push(wikiFact);\n }\n\n // (c) Pre-flight edge validation, grouped by sourceId.\n // C3: dangling targetIds are stored verbatim. We only validate against\n // the manifest's (source_type, edge_type) lookup.\n const sourceIdToType = new Map<string, string | null>();\n for (const fact of wikiFacts) sourceIdToType.set(fact.id, fact.okf_type ?? null);\n\n // When the manifest is empty (no node_types AND no edge_types), the user\n // has expressed no constraints; edges pass through verbatim. This is\n // the documented \"no validation\" semantics — the host gets exactly the\n // edges it supplied, including dangling targetIds (C3).\n const hasConstraints = (manifest.node_types?.length ?? 0) > 0 || (manifest.edge_types?.length ?? 0) > 0;\n\n const validEdges: WikiEdge[] = [];\n for (const edge of params.edges) {\n if (!hasConstraints) {\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: edge.type,\n created_at: now,\n });\n continue;\n }\n // Per spec step (c): \"for each source node `n` in `params.nodes`, validate\n // that node's outgoing edges\". Edges whose sourceId references a node\n // OUTSIDE this call's nodes (a prior sourceRef's node) cannot have their\n // source type resolved without a DB lookup, so they pass through verbatim\n // — same lenient treatment C3 gives dangling targetIds.\n if (!sourceIdToType.has(edge.sourceId)) {\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: edge.type,\n created_at: now,\n });\n continue;\n }\n const sourceType = sourceIdToType.get(edge.sourceId);\n const candidates = (manifest.edge_types ?? []).filter(d =>\n d.type.toLowerCase() === edge.type.toLowerCase()\n && typeSatisfies(d.source_type, sourceType ?? '', manifest),\n );\n const match = candidates[0];\n if (!match) {\n if (strictEffective) throw new WikiStrictOntologyViolation(entityId, 'edge', edge.type);\n opts?.diag?.buffer.push({\n entityId, operation: opts.diag.operation, trigger: 'call', code: 'edge_dropped',\n detail: {\n reason: 'manifest_violation', factId: edge.sourceId, edgeType: edge.type,\n ...(sourceType ? { sourceNodeType: sourceType } : {}), sourceRef: params.sourceRef,\n },\n });\n continue;\n }\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: match.type,\n created_at: now,\n });\n }\n\n // (d) Supersede prior facts for sourceRef.\n const deletedFactIds = await this.entryRepo.findIdsBySource(entityId, params.sourceRef, null, tx, false);\n await this.entryRepo.softDeleteBySource(entityId, tx, params.sourceRef, null);\n\n // (e) Supersede prior edges whose source is in deletedFactIds.\n const deletedEdgeCount = await this.edgeRepo.softDeleteBySourceFactIds(entityId, deletedFactIds, tx);\n\n // (f) Clear prior source_ref_index row for (entity, sourceRef).\n await this.sourceRefIndexRepo.softDeleteByEntityAndSourceRef(entityId, params.sourceRef, tx);\n\n // (g) Take ownership of (entity, hash).\n await this.sourceRefIndexRepo.upsert(entityId, params.sourceHash, params.sourceRef, tx);\n\n // (h) Write nodes (per-row outbox INSERT via entryRepo.upsert).\n for (const wikiFact of wikiFacts) {\n await this.entryRepo.upsert(wikiFact, tx);\n }\n\n // (i) Write edges (C3: dangling targets stored verbatim, no FK, no title-index resolution).\n // Count actual inserts via addIgnoreDuplicate; an edge whose id already\n // exists with the same (entity_id, source_id, target_id, edge_type) tuple\n // — e.g. a deterministic edge id reused across two distinct sourceRefs —\n // is silently skipped (returns false) and must NOT be counted as written.\n // Counting `validEdges.length` over-reports when caller-supplied edge ids\n // collide across sourceRefs, breaking the spec's C3 invariant that the\n // caller can rely on `edgesWritten` to assert \"did you drop anything?\".\n let edgesInsertedCount = 0;\n for (const edge of validEdges) {\n const inserted = await this.edgeRepo.addIgnoreDuplicate(edge, tx);\n if (inserted) edgesInsertedCount++;\n }\n\n // (j) Return counts.\n return {\n nodesWritten: wikiFacts.length,\n edgesWritten: edgesInsertedCount,\n superseded: deletedFactIds.length + deletedEdgeCount,\n };\n }\n\n /**\n * Full supersession + ownership path: identical to the pre-issue-#92 behavior\n * for the happy path. Called from the `failedChunks === 0` branch of\n * `ingestDocument`. Runs INSIDE the caller's tx.\n *\n * Returns `{ deletedSourceFactIds, insertedFacts }` so the caller can fire\n * post-commit hooks (embedding lifecycle) AFTER the transaction commits.\n * On the partial path the caller never invokes this method; the empty\n * arrays stay empty.\n */\n private async runFullUpsertGraph(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>,\n tx: SQLiteAdapter,\n diagBuffer: DiagnosticBuffer,\n ): Promise<{ deletedSourceFactIds: string[]; insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> }> {\n const deletedSourceFactIds: string[] = [];\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n\n // Capture the IDs of facts about to be soft-deleted so we can fire\n // onEmbeddingPersisted hooks AFTER the transaction commits. The\n // capture happens BEFORE the softDelete, so even though\n // upsertGraphCore performs its own findIdsBySource for edge\n // supersession, the IDs here are the canonical \"what we retired\"\n // set for the embedding lifecycle.\n deletedSourceFactIds.push(...(await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false)));\n\n // Build title index from PRIOR facts EXCLUDING the current sourceRef.\n // Facts from this sourceRef are about to be superseded by\n // upsertGraphCore step (d); seeding them here would let resolveEdges\n // target a soon-to-be-retired fact and leave the new edge pointing\n // at a soft-deleted record (the new edge's source is fresh, so step\n // (e) only retires edges whose SOURCE is in the deleted-fact set).\n // The sourceRef exclusion is applied in SQL (via\n // findRecentByEntityId's excludeSourceRef param) so the 500-row\n // LIMIT applies to usable rows only — a re-ingest where the current\n // sourceRef owns most recent facts otherwise leaves the index empty\n // after the post-query filter, silently losing cross-sourceRef edges\n // that a first ingest would have resolved.\n const titleIndex = new Map<string, TitleIndexEntry>();\n const existingFacts = await this.entryRepo.findRecentByEntityId(entityId, 500, tx, sourceRef);\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 // Two-pass conversion of LLM extraction into host-facing shape.\n // Pass 1 (below) populates hostNodes and stages raw edge requests\n // for every replacement fact — facts from this ingest enter the\n // titleIndex as they're added, so forward references resolve in\n // pass 2 against the FINALIZED index. Pass 2 then resolves each\n // staged request into concrete hostEdges. upsertGraphCore owns the\n // persistence step.\n const hostNodes: { id: string; type: string; title: string; body: string; tags?: readonly string[]; confidence?: 'certain' | 'inferred' | 'tentative' }[] = [];\n const rawEdgeRequests: { sourceId: string; sourceType: string | null; edges: ExtractedFactEdge[] }[] = [];\n const now = Date.now();\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 id = generateId('fact_');\n const validationDrops: EdgeDrop[] = [];\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest, { strict: false, drops: validationDrops })\n ?? { okf_type: null, edges: [] };\n for (const drop of validationDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { entityId, operation: 'ingest', trigger: 'call', sourceRef, factId: id }));\n }\n\n hostNodes.push({\n id,\n type: ontologyFact.okf_type ?? '',\n title: fact.title,\n body: fact.body,\n // Forward the LLM-extracted tags/confidence through the\n // extracted-shape upsertGraphCore path so the entries row\n // stores them (search filterability, heal-candidate\n // selection, runReembed embedding-text signal). The public\n // WikiMemory.upsertGraph API doesn't accept tags/confidence\n // — host-supplied deterministic nodes default to [] and\n // 'certain' as documented.\n tags: fact.tags,\n confidence: fact.confidence,\n });\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 rawEdgeRequests.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n }\n\n // Pass 2: resolve every staged edge against the finalized title\n // index. By this point the index contains both surviving prior\n // facts (excluding this sourceRef) AND every replacement fact from\n // this ingest, so forward references resolve correctly and no\n // resolved edge points at a fact that's about to be soft-deleted.\n const hostEdges: { type: string; sourceId: string; targetId: string }[] = [];\n for (const req of rawEdgeRequests) {\n const resolveDrops: EdgeDrop[] = [];\n const resolved = this.ontologyService?.resolveEdges(\n entityId, req.sourceId, req.sourceType, req.edges, manifest, titleIndex, now, resolveDrops,\n ) ?? [];\n for (const drop of resolveDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { entityId, operation: 'ingest', trigger: 'call', sourceRef }));\n }\n for (const e of resolved) {\n hostEdges.push({ type: e.edge_type, sourceId: e.source_id, targetId: e.target_id });\n }\n }\n\n await this.upsertGraphCore(\n entityId,\n { sourceRef, sourceHash, nodes: hostNodes, edges: hostEdges },\n tx,\n { strict: false, diag: { buffer: diagBuffer, operation: 'ingest' } },\n );\n\n return { deletedSourceFactIds, insertedFacts };\n }\n\n /**\n * Partial-commit path for `ingestDocument`. Inserts ONLY facts whose\n * normalized title is not already in the live set for this (entityId,\n * sourceRef). Does NOT call `entryRepo.softDeleteBySource` (no\n * supersession) and does NOT call `sourceRefIndexRepo.upsert` (no\n * ownership). Edges are NOT resolved on this path (no ontology-context\n * build, no `resolveEdges`, no `mergeEmergentUpdates`). Stale edges from\n * prior attempts are recovered on the next full run's supersession.\n *\n * Source-hash is stored as NULL on partial rows. `findLatestSourceHash`\n * reads from the most recently updated live row for the sourceRef, so\n * storing the incoming hash here would cause `hasChanged` to return\n * `false` on a same-hash retry — the failed chunks would never get a\n * second chance. With NULL, a retry sees `storedHash === null`, `hasChanged`\n * returns `true`, and the partial commit's sibling rows remain live\n * (deduped, not superseded) for the next attempt to extend.\n *\n * Runs INSIDE the caller's `tx`. Does not open a nested transaction.\n * Returns `{ inserted, skippedDuplicate }` for observability.\n */\n private async appendPartialFacts(\n entityId: string,\n sourceRef: string,\n dedupedFacts: ExtractedFact[],\n tx: SQLiteAdapter,\n diagBuffer: DiagnosticBuffer,\n ): Promise<{\n inserted: number;\n skippedDuplicate: number;\n /** Descriptors for the rows this call actually inserted, in the same\n * shape `runFullUpsertGraph` returns — the post-commit hook loop\n * passes these to `embedFact`. Without them, partial-path inserts\n * would skip the embedding service entirely. */\n insertedDescriptors: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }>;\n }> {\n // Partial rows are intentionally stored with `source_hash: null` so\n // `hasChanged` keeps returning true on every retry of the same hash —\n // the failed chunks get a second chance. The full path stamps the actual\n // hash via `runFullUpsertGraph`; this helper deliberately does not.\n // Load the live (sourceRef, *) rows so we can dedup by title against prior\n // partial attempts AND prior full attempts. includeDeleted=false matches\n // the pre-supersession dedup semantics of the full path. Per spec §4.2:\n // `findIdsBySource` returns the ids (already scoped to `entityId` and\n // excluding deleted rows); `findByIds` resolves titles — no entity filter\n // needed because the ids carry that scope already.\n const liveIds = await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false);\n const liveFacts = liveIds.length === 0\n ? []\n : await this.entryRepo.findByIds(liveIds, undefined, tx);\n const liveTitles = new Set(liveFacts.map((f) => normalizeTitleKey(f.title)));\n\n let inserted = 0;\n let skippedDuplicate = 0;\n const now = Date.now();\n const insertedDescriptors: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n for (const fact of dedupedFacts) {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (liveTitles.has(normalizedTitle)) {\n diagBuffer.push({\n entityId, operation: 'ingest', trigger: 'call', code: 'fact_deduplicated',\n detail: { sourceRef, reason: 'exact_title' },\n });\n skippedDuplicate++;\n continue;\n }\n liveTitles.add(normalizedTitle);\n\n const id = generateId('fact_');\n const wikiFact: WikiFact = {\n id,\n entity_id: entityId,\n title: fact.title,\n body: fact.body,\n tags: fact.tags,\n confidence: fact.confidence,\n source_type: 'immutable_document',\n // source_hash: null on partial rows — see method docstring. The\n // full path stamps the actual hash; partial rows stay hash-less so\n // `hasChanged` keeps returning true for retries.\n source_hash: null,\n source_ref: sourceRef,\n created_at: now,\n updated_at: now,\n last_accessed_at: null,\n access_count: 0,\n deleted_at: null,\n okf_type: null,\n };\n await this.entryRepo.upsert(wikiFact, tx);\n // Mirror the shape `runFullUpsertGraph` returns so the caller's\n // post-commit `embedFact` loop is path-agnostic.\n insertedDescriptors.push({\n id,\n entity_id: entityId,\n title: fact.title,\n body: fact.body,\n tags: JSON.stringify(fact.tags),\n });\n inserted++;\n }\n return { inserted, skippedDuplicate, insertedDescriptors };\n }\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 *\n * The contract is explicit: this function must never throw. The\n * `err instanceof Error` check below invokes the `getPrototypeOf` trap on\n * `err`. A hostile Proxy whose trap rejects would otherwise throw out of\n * `runBatched` — and any throw inside `runBatched` is the silent-batch-\n * failure mode this whole helper exists to prevent. On a hostile trap, we\n * fall back to `false` (treat as not a truncation error): the consequence\n * is at most one wasted batch split, which is the correct trade-off.\n */\nfunction getErrorMessage(err: unknown): string | undefined {\n try {\n return err instanceof Error ? err.message : String(err ?? '');\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects\n return undefined;\n }\n}\n\nexport function isTruncationError(err: unknown): boolean {\n const message = getErrorMessage(err);\n if (message === undefined) return false;\n if (EXCEEDS_LIMIT_PATTERN.test(message)) return false;\n return TRUNCATION_PATTERNS.some((pattern) => pattern.test(message));\n}\n\n/**\n * Whether a thrown error looks like a model-config error — the caller\n * requested more output than the model allows, and re-running it in the\n * next pass produces the same failure. Distinguished from transient\n * provider failures (`ECONNRESET`, auth blip, 5xx) so the cooldown-stamp\n * filter in `doRunHeal` / `doRunOntologyBackfill` does not exclude these\n * facts from eligibility: a model-config bug is the host's problem to\n * fix, and a fact that errored this way can recover only when the host\n * does, so the cooldown stamp is the right behavior.\n *\n * Same Proxy-safety contract as `isTruncationError`: hostile\n * `getPrototypeOf` trap must not propagate out of this function.\n */\nexport function isConfigError(err: unknown): boolean {\n const message = getErrorMessage(err);\n if (message === undefined) return false;\n return EXCEEDS_LIMIT_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 /**\n * May be async: heal selects anchors per batch via a search + repository read.\n *\n * `attemptLevel` is the escalation level at which this build is being asked\n * to produce a prompt. trim()'s speculatives always pass `0` (they only\n * measure length). Real attempts pass the current escalation level: `0`\n * (normal), `1` (less shared context), `2` (less again), or `3` (last\n * resort — caller is expected to shrink or truncate the prompt itself).\n * Defaults to `0` so callers that don't care about the level are unchanged.\n */\n buildPrompt: (\n batch: TItem[],\n attemptLevel?: 0 | 1 | 2 | 3,\n ) => 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 /**\n * Items that could not converge after the helper's full escalation path.\n * The discriminator separates genuine non-convergence (`'non_convergent'`\n * — terminal give-up at L3, parse error, or a model-config error) from\n * transient provider failures (`'call_error'` — non-truncation error\n * originating in `call()` at `batch.length === 1`). Callers that stamp a\n * cooldown on skipped facts (e.g. `doRunHeal`) must filter out the\n * `'call_error'` ids so a momentary 5xx doesn't lock the fact out for a\n * week.\n */\n skipped: Array<{ item: TItem; reason: 'non_convergent' | 'call_error' }>;\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: Array<{ item: TItem; reason: 'non_convergent' | 'call_error' }> = [];\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 (\n batch: TItem[],\n err: unknown,\n attemptLevel: 0 | 1 | 2 | 3,\n fromCall: boolean,\n ): Promise<void> => {\n if (batch.length === 1) {\n // Gate: escalation only on a truncation-shaped error at the lowest batch\n // size, and only while the ladder has levels left. Anything else at this\n // point — parse error, exceeds-limit config error, or a non-truncation\n // call error — is a terminal give-up. A parse error is not retryable by\n // context-shedding (the JSON desync shape is the same at L1, L2, and L3);\n // escalating would burn three calls before reaching skip. The gate\n // prevents that.\n if (fromCall && isTruncationError(err) && attemptLevel < 3) {\n // Bypass trim: its prebuilt prompt is the L0 form, invalid at the new\n // level. attempt() will call buildPrompt(batch, attemptLevel + 1) to\n // produce the level-appropriate prompt.\n await attempt(batch, undefined, (attemptLevel + 1) as 0 | 1 | 2 | 3);\n } else {\n // Subreason: a non-truncation error originating in `call()` is a\n // transient provider failure (5xx, network reset, auth blip), not a\n // model capability failure or a model-config bug. Distinguishing it\n // lets orchestration callers (doRunHeal, doRunOntologyBackfill)\n // refuse to apply a recheck cooldown stamp to facts whose skip is\n // operationally reversible. EXCEEDS_LIMIT-shaped errors are\n // model-config bugs that retry identically every pass, so they stay\n // `'non_convergent'` and receive the cooldown stamp. See\n // docs/superpowers/specs/2026-08-17-...-design.md §\"Revision 1 —\n // call_error subreason\".\n const reason: 'non_convergent' | 'call_error' =\n fromCall && !isTruncationError(err) && !isConfigError(err) ? 'call_error' : 'non_convergent';\n skipped.push({ item: batch[0], reason });\n onSkip?.(batch[0], err);\n }\n return;\n }\n // Non-truncation call errors at batch.length > 1 are real errors (network,\n // auth) and must propagate rather than silently split/skip the corpus.\n // Parse errors always split — the JSON may parse after shedding context.\n if (fromCall && !isTruncationError(err)) throw err;\n // batch.length > 1: split path, unchanged. Sticky-down batchSize\n // adaptation and the inner trim/attempt loop at level 0 are preserved.\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 (\n batch: TItem[],\n prebuilt?: BuiltPrompt,\n attemptLevel: 0 | 1 | 2 | 3 = 0,\n ): Promise<void> => {\n if (batch.length === 0) return;\n // prebuilt is the L0 form from trim(); only valid at attemptLevel === 0.\n // The level-advance path in onFailure passes `undefined` to force a rebuild.\n const prompts =\n prebuilt && attemptLevel === 0\n ? prebuilt\n : (await buildPrompt(batch, attemptLevel));\n\n batches++;\n let responseText: string;\n try {\n responseText = await call(prompts);\n } catch (err) {\n // Non-truncation call errors: hand to onFailure (skips at batch.length===1,\n // throws at batch.length>1). Truncation errors also go to onFailure for\n // potential ladder escalation.\n await onFailure(batch, err, attemptLevel, true);\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 // Parse errors always split, never throw — the JSON may parse after\n // shedding context. The gate inside onFailure handles ladder escalation.\n await onFailure(batch, err, attemptLevel, false);\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, 0);\n }\n\n return { results, skipped, batches };\n}\n","import { parseJsonResponse, validateFact, validateTask, titleTokens, jaccardScore, normalizeSourceRef, normalizeSourceHash, sanitizeRankerError, safeErrorToString, safeSlice, factRejectionReason, taskRejectionReason } from '../utils/pure';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { DiagnosticBuffer, emitDiagnostic, edgeDropDiagnostic } from '../utils/diagnostics';\nimport type { EdgeDrop } 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, HealResult, DegradedRecord, ReembedResult, WikiDiagnosticTrigger } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SourceRefIndexRepository } from '../repositories/SourceRefIndexRepository';\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';\nimport {\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_MAX_ANCHORS,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n HEAL_MAX_TASKS,\n} from '../utils/healConstants';\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// Heal constants live in `utils/healConstants` so PromptService and\n// MaintenanceService cannot drift apart on the anchor cap formula\n// (spec: \"values must match\"). Re-exported here to preserve the existing\n// `MaintenanceService.HEAL_*` public surface that index.ts and other\n// downstream consumers already import.\nexport { HEAL_MAX_ANCHORS, HEAL_ANCHORS_PER_CANDIDATE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS } from '../utils/healConstants';\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/**\n * Heal candidates fetched per pass. Bounds the pool runBatched draws from, not\n * the size of an individual LLM call — runBatched still packs ~10 candidates per\n * request and splits further on failure. At this default one pass costs roughly\n * 2-3 provider calls instead of an unbounded count (#67).\n */\nexport const HEAL_BATCH_SIZE = 25;\n\n/** Cooldown before an already-healed fact is offered again. Matches ontology backfill. */\nexport const HEAL_RECHECK_MS = 7 * 24 * 60 * 60 * 1000;\n\n/** Attempts after which a fact is considered permanently un-embeddable. */\nexport const MAX_EMBED_ATTEMPTS = 5;\n/** First retry delay after a recoverable embedding failure. */\nexport const EMBED_RETRY_BASE_MS = 60_000;\n/** Upper bound on the exponential retry delay. */\nexport const EMBED_RETRY_CAP_MS = 24 * 60 * 60 * 1000;\n\n/** Exponential backoff: base * 2^(attempts-1), capped. */\nexport function embedRetryDelayMs(attempts: number): number {\n const n = Math.max(1, Math.trunc(attempts || 0));\n const delay = EMBED_RETRY_BASE_MS * Math.pow(2, n - 1);\n return Math.min(delay, EMBED_RETRY_CAP_MS);\n}\n\nexport type ReembedDisposition = 'attempt' | 'defer' | 'permanent';\n\n/**\n * Decide what to do with one candidate row. Pure: no DB, no clock.\n *\n * `float32_overflow` is terminal because it is deterministic arithmetic on the\n * same vector — retrying can only produce the same overflow.\n */\nexport function classifyReembedRow(\n row: {\n embedding_failed_at?: number | null;\n embedding_failure_kind?: string | null;\n embedding_attempts?: number | null;\n },\n now: number,\n force: boolean,\n): ReembedDisposition {\n if (force) return 'attempt';\n\n const failedAt = row.embedding_failed_at;\n if (failedAt === null || failedAt === undefined) return 'attempt';\n\n if (row.embedding_failure_kind === 'float32_overflow') return 'permanent';\n\n const attempts = row.embedding_attempts ?? 0;\n if (attempts >= MAX_EMBED_ATTEMPTS) return 'permanent';\n\n return now - failedAt >= embedRetryDelayMs(attempts) ? 'attempt' : 'defer';\n}\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\n/**\n * Hard cap on skipped-item error text in the log. A provider response or\n * prompt artifact can carry a multi-MB message; one unbounded failure must\n * not flood stderr (or any downstream log-shipping pipeline) by being logged\n * once per skipped item.\n */\nconst SKIP_ERROR_LOG_CHARS = 4096;\n\n/**\n * Stringify an unknown error from `RunBatchedArgs.onSkip` for the log.\n * Exported for unit testing only — callers must always treat the return\n * value as a bounded, log-safe string. Internal callers feed this through\n * `console.warn` from heal/ontology-backfill `onSkip` paths.\n *\n * The callback receives `unknown`, so the value is not guaranteed to be a\n * `WikiParseError` with a small `.message`; a raw provider stack, an HTTP\n * error object, or a `string` is all possible. `String(err)` on a plain object\n * uses `Object.prototype.toString` and stays small, but `JSON.stringify` is\n * needed to surface anything structured, and the output is bounded either\n * way so a degenerate payload cannot slip through.\n *\n * Implementation note: every coercion path delegates to `safeErrorToString`,\n * which guarantees a non-throwing string return via a static\n * `[unstringifiable error]` marker. The previous hand-rolled chain had a\n * hole — `JSON.stringify` throws and the `catch` then ran\n * `Object.prototype.toString.call(err)`, which itself can throw (a Proxy\n * whose `get` trap rejects every property access — including\n * `Symbol.toStringTag`). That throw escaped the function and rejected the\n * surrounding `runBatched` operation wholesale. `safeErrorToString` was\n * hardened against this exact path; reuse it.\n */\nexport const formatSkipError = (err: unknown): string => {\n // Two goals:\n // 1. Surface structured provider errors as JSON when present\n // (e.g. `{code: 500, msg: 'oops'}` -> `\"{\"code\":500,\"msg\":\"oops\"}\"`).\n // 2. Never throw, regardless of what hostile value reaches us via\n // `onSkip` (Symbol, function, throwing toString, Proxy rejecting\n // property access, Error with bad message, etc).\n //\n // `safeErrorToString` is the hardened non-throwing helper; every path\n // either uses it directly or falls back to it. JSON.stringify failure\n // paths (throwing toJSON, circular structure, Proxy) all converge on\n // `safeErrorToString`, which itself wraps String() and\n // Object.prototype.toString.call() in nested try/catch.\n let base: string;\n // `err instanceof Error` invokes the `getPrototypeOf` trap on `err`. A\n // hostile Proxy (e.g. one passed through `onSkip` from a misbehaving\n // provider plugin) whose trap rejects would throw out of this function —\n // defeating the documented \"never throw\" contract. Treat the trap throw\n // as \"not an Error\" and fall through to the JSON.stringify / safeErrorToString\n // branch below.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects — fall through\n }\n if (isErrorLike || (typeof err !== 'object' && typeof err !== 'function')) {\n // Errors -> safeErrorToString (returns err.message verbatim, or .name,\n // or '[Error]' for hostile Error subclasses)\n // Primitives (string, number, boolean, bigint, undefined, symbol) ->\n // safeErrorToString (String() handles them all)\n base = safeErrorToString(err);\n } else {\n // null + plain objects + arrays -> try JSON.stringify to surface\n // structure. `null` JSON-stringifies to 'null', `typeof null ===\n // 'object'` so it lands here safely.\n try {\n const json = JSON.stringify(err);\n base = typeof json === 'string' ? json : safeErrorToString(err);\n } catch {\n base = safeErrorToString(err);\n }\n }\n if (base.length > SKIP_ERROR_LOG_CHARS) {\n // safeSlice (from utils/pure) never splits a UTF-16 surrogate pair at the\n // cut boundary — a bare String.slice can, leaving a lone high surrogate\n // that renders as U+FFFD in the log line.\n const truncated = safeSlice(base, 0, SKIP_ERROR_LOG_CHARS);\n return `${truncated}…[+${base.length - SKIP_ERROR_LOG_CHARS} chars truncated]`;\n }\n return base;\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 sourceRefIndexRepo: SourceRefIndexRepository,\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(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number; bodyTruncationChars?: number },\n ): Promise<HealResult> {\n this.jobManager.acquireLock('heal', entityId);\n try {\n return await this.doRunHeal(entityId, options);\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 /**\n * Re-embed facts, honouring per-row failure markers and exponential backoff.\n *\n * Marker lifecycle (spec §2): markers are cleared by a successful embed, by\n * an upsert carrying a valid blob, and by an embedding-dimension promotion.\n * A promotion revives rows for the NEXT sweep, not this one — reconciliation\n * runs after candidates were already classified.\n *\n * Residual, by design: swapping to a provider with the SAME dimension never\n * sets embedding_dimension_mismatch, so promotion never fires and markers\n * survive the swap. Use `runReembed({ force: true })` to clear that state —\n * `force` bypasses classification entirely and retries every row.\n *\n * Lock scope (spec 2026-09-05 §2): a marker mutation is legal while a sweep\n * is in flight if and only if it cannot resurrect a row the sweep has\n * classified. Mutations scoped to entities not under an active sweep key are\n * legal — the entity-scoped ingest/import lock checks enforce that. The one\n * mutation that spans every entity, `reconcileEmbeddingDimension`'s marker\n * clear, is made legal by DEFERRING (importDump gates on\n * `JobManager.isAnyReembedActive()`), never by widening a lock. Auto-heal is\n * excluded from sweeps for the same reason.\n */\n async runReembed(\n entityId?: string,\n opts?: { force?: boolean; skipExisting?: boolean },\n ): Promise<ReembedResult> {\n const embedFn = this.options.llmProvider.embed;\n // Same callability guard as EmbeddingService.tryEmbedFact (spec §2.4): a\n // misconfigured provider short-circuits the sweep instead of iterating and\n // marking every row.\n if (typeof embedFn !== 'function') {\n return { embedded: 0, skipped: 0, failed: 0, deferred: 0, permanentlyFailed: 0 };\n }\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 let deferred = 0;\n let permanentlyFailed = 0;\n const force = opts?.force ?? false;\n // One clock snapshot for the whole sweep: backoff eligibility is decided\n // against sweep-start time, so rows whose window elapses mid-sweep stay\n // deferred until the next sweep. Keeps classifyReembedRow pure and the\n // sweep's deferral decisions deterministic for a single invocation.\n const now = Date.now();\n\n try {\n for (const row of rows) {\n const existingBlob = row.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 disposition = classifyReembedRow(row, now, force);\n if (disposition === 'defer') { deferred++; continue; }\n if (disposition === 'permanent') { permanentlyFailed++; continue; }\n\n const result = await this.embeddingService.tryEmbedFact(row, { operation: 'reembed', trigger: 'call' });\n if (result.ok) 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, deferred, permanentlyFailed };\n } finally {\n this.jobManager.releaseLock(op, entityId ?? '*');\n }\n }\n\n async forget(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n opts?: { dryRun?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\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 // Dry-run: read-only, no lock, no outbox events, no embedding hooks.\n if (opts?.dryRun === true) {\n return this.forgetDryRun(entityId, params);\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 // Mirror the clearAll to source_ref_index so the post-clearAll state\n // has no live index rows for the entity. Hard-delete via the soft-delete\n // path keeps the CDC contract identical to entries (outbox events are\n // not fired for source_ref_index, so this is purely an internal\n // invariant cleanup).\n // TODO: add a bulk source_ref_index soft-delete once the v9 backfill\n // gap is closed; for now, leaving the rows in place is safe because\n // the partial UNIQUE index excludes deleted_at != NULL rows from\n // re-ingest — a re-ingest would correctly take ownership.\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 // Soft-delete the source_ref_index row so a re-ingest of this\n // sourceRef+hash can take ownership. The pre-check at the start of\n // ingestDocument will now see no live ref and proceed. No-op when\n // the row is already soft-deleted or never existed.\n const sourceRefIndexPromise = sourceRef\n ? this.sourceRefIndexRepo.softDeleteByEntityAndSourceRef(entityId, sourceRef, tx).then(() => undefined)\n : 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 sourceRefIndexPromise ?? Promise.resolve(undefined),\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 params.clearAll\n ? { deleted: { entries: deletedEntries, tasks: deletedTasks }, metadataReset: true }\n : { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.jobManager.releaseLock('forget', entityId);\n }\n }\n\n /**\n * Read-only dry-run preview of {@link forget}. Returns the same shape as a\n * real call would, without acquiring the lock, opening a transaction, staging\n * outbox events, or firing embedding hooks. Counts may be off-by-N during a\n * concurrent real forget — this is accepted, not considered a bug.\n *\n * `metadataReset` mirrors the real call: only `clearAll: true` returns true,\n * because only `clearAll` actually resets the metadata checkpoint.\n * `standard` (sourceRef/sourceHash) returns no metadataReset field, just like\n * the real call. `entryId`/`taskId` selectors are rejected with a clear error\n * (the spec keeps dry-run narrow).\n */\n private async forgetDryRun(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\n // Note: the clearAll mutual-exclusion check is performed by the public\n // forget() before dispatching here. forgetDryRun is private and unreachable\n // for callers that violate that contract, so it does not re-validate.\n\n if (params.entryId !== undefined || params.taskId !== undefined) {\n throw new Error('forget({ dryRun: true }) does not support entryId/taskId selectors; use sourceRef/sourceHash or clearAll');\n }\n\n if (params.clearAll) {\n const entries = await this.entryRepo.countLiveByEntityId(entityId);\n const tasks = await this.taskRepo.countLiveByEntityId(entityId);\n return { deleted: { entries, tasks }, metadataReset: true };\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 // No source selectors supplied: the real call is a no-op (softDeleteBySource\n // is gated on `if (sourceRef || sourceHash)`). Mirror that — do NOT count all\n // live entries, which would silently mask a caller bug as a large blast radius.\n if (sourceRef === null && sourceHash === null) {\n return { deleted: { entries: 0, tasks: 0 } };\n }\n\n const entries = await this.entryRepo.countLiveBySource(entityId, sourceRef, sourceHash);\n return { deleted: { entries, tasks: 0 } };\n }\n\n /** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */\n async doRunLibrarian(entityId: string, promptOverride?: string, trigger: WikiDiagnosticTrigger = 'call'): 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 diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'librarian' as const, trigger };\n const validFacts: ExtractedFact[] = [];\n const validFactItemIndexes: number[] = [];\n facts.forEach((raw, itemIndex) => {\n const valid = validateFact(raw);\n if (valid) {\n validFacts.push(valid);\n validFactItemIndexes.push(itemIndex);\n } else {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { itemIndex, reason: factRejectionReason(raw) } });\n }\n });\n const validTasks: ExtractedTask[] = [];\n tasks.forEach((raw, itemIndex) => {\n const valid = validateTask(raw);\n if (valid) validTasks.push(valid);\n else diagBuffer.push({ ...diagBase, code: 'task_rejected', detail: { itemIndex, reason: taskRejectionReason(raw) } });\n });\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 [k, fact] of validFacts.entries()) {\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) {\n diagBuffer.push({ ...diagBase, code: 'fact_deduplicated', detail: { itemIndex: validFactItemIndexes[k], reason: 'fuzzy_title' } });\n continue;\n }\n\n const ontologyFact = fact as ExtractedFactWithOntology;\n const id = generateId('fact_');\n const validationDrops: EdgeDrop[] = [];\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest, { strict: false, drops: validationDrops })\n ?? { okf_type: null, edges: [] };\n for (const drop of validationDrops) diagBuffer.push(edgeDropDiagnostic(drop, { ...diagBase, factId: id }));\n\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 const resolveDrops: EdgeDrop[] = [];\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now, resolveDrops,\n );\n for (const drop of resolveDrops) diagBuffer.push(edgeDropDiagnostic(drop, diagBase));\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 diagBuffer.flush(this.options);\n\n await this.searchService.sync(entityId);\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'librarian', trigger });\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /**\n * Core heal pass (locks handled by {@link runHeal}). Package-internal orchestration hook.\n *\n * Bounded: at most `batchSize` candidates per pass (#67). Loop on\n * `result.remaining > 0` for convergence — see {@link HealResult.remaining}\n * for what convergence means here.\n */\n async doRunHeal(\n entityId: string,\n options?: {\n promptOverride?: string;\n batchSize?: number;\n bodyTruncationChars?: number;\n trigger?: WikiDiagnosticTrigger;\n },\n ): Promise<HealResult> {\n const promptOverride = options?.promptOverride;\n const batchSize = options?.batchSize ?? HEAL_BATCH_SIZE;\n const trigger: WikiDiagnosticTrigger = options?.trigger ?? 'call';\n const diagBase = { entityId, operation: 'heal' as const, trigger };\n if (!Number.isInteger(batchSize) || batchSize < 1) {\n throw new Error('Invalid batchSize: must be an integer >= 1');\n }\n\n const bodyTruncationChars = options?.bodyTruncationChars ?? HEAL_MAX_FACT_BODY_CHARS_L3;\n if (!Number.isInteger(bodyTruncationChars) || bodyTruncationChars < 1) {\n throw new Error('Invalid bodyTruncationChars: must be an integer >= 1');\n }\n\n const now = Date.now();\n const recheckCutoff = now - HEAL_RECHECK_MS;\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 // The SQL passes below mutate rows before candidates are even selected, so\n // their ids are folded into the HealResult counters — otherwise a pass that\n // soft-deletes 50 orphans but offers no candidates reports `deleted: 0`.\n const staleDowngradedIds: 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 staleDowngradedIds.push(...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 emitDiagnostic(this.options, { ...diagBase, code: 'hook_failed', detail: { factId, reason: 'on_embedding_persisted' } });\n }\n }\n\n const healCandidates = await this.entryRepo.findHealCandidatesByEntityId(entityId, batchSize, recheckCutoff);\n if (healCandidates.length === 0) {\n // The orphan/stale SQL passes above may still have mutated rows, so the\n // search index sync must happen before returning — it did today, after\n // runBatched no-oped on an empty candidate list.\n await this.searchService.sync(entityId);\n this.searchService.evictCache(entityId);\n const counts = await this.entryRepo.countHealCandidatesByEntityId(entityId, recheckCutoff);\n return {\n scanned: 0,\n downgraded: staleDowngradedIds.length,\n deleted: orphanedIds.length,\n newFactsCreated: 0,\n skipped: [], degraded: [], remaining: counts.eligible, deferred: counts.deferred,\n };\n }\n // Cap applied once at fetch time. The bound is the one remaining\n // unbounded input to the heal prompt (#101's L0 fix). AllTasks is\n // entity-global; we don't re-fetch per level. L1+ levels omit the\n // array via buildHealPrompt's level logic.\n const allTasks = await this.taskRepo.findAllPending([entityId], HEAL_MAX_TASKS);\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 // Captured in the doRunHeal scope so the buildPrompt lambda can push\n // L3 truncation records into it. Reconcile after runBatched returns:\n // any record whose id also ended up in outcome.skipped is a\n // contradiction (degraded = healed, skipped = dropped) and is dropped.\n // The post-reconcile log line fires for the survivors only.\n const degraded: DegradedRecord[] = [];\n\n const outcome = await runBatched<WikiFact, HealBatch>({\n items: healCandidates,\n buildPrompt: async (batch, attemptLevel = 0) => {\n const documentAnchors = await this._selectHealAnchors(\n entityId,\n batch,\n // Per-batch anchor cap: `batch.length * HEAL_ANCHORS_PER_CANDIDATE` (capped at\n // HEAL_MAX_ANCHORS) right-sizes the anchor lookup so a 1-fact batch does\n // not overfetch the same 200 keyword hits a 25-fact batch once did.\n // buildHealPrompt applies the matching cap on its side — values must match.\n Math.min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE),\n anchorCache,\n );\n const { prompts, degraded: batchDegraded } = await this.promptService.buildHealPrompt(\n batch.map(toPromptShape),\n documentAnchors,\n allTasks,\n recentEvents,\n promptOverride,\n attemptLevel,\n bodyTruncationChars,\n );\n // L0 calls (including trim's speculatives) return degraded: [].\n // Only L3 real attempts can push here.\n degraded.push(...batchDegraded);\n return prompts;\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: ${formatSkipError(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 // Position within the producing batch's response, not the merged list, so\n // a diagnostic's itemIndex points into an array the model actually returned.\n const newFactItemIndexes: number[] = [];\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 batchResult.newFacts.forEach((raw, itemIndex) => {\n newFacts.push(raw);\n newFactItemIndexes.push(itemIndex);\n });\n }\n\n const safeDowngraded = Array.from(safeDowngradedSet);\n const safeDeleted = Array.from(safeDeletedSet);\n const diagBuffer = new DiagnosticBuffer();\n const validNewFacts: ExtractedFact[] = [];\n const validNewFactItemIndexes: number[] = [];\n newFacts.forEach((raw, k) => {\n const itemIndex = newFactItemIndexes[k];\n const valid = validateFact(raw);\n if (valid) {\n validNewFacts.push(valid);\n validNewFactItemIndexes.push(itemIndex);\n } else {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { itemIndex, reason: factRejectionReason(raw) } });\n }\n });\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 // Full-breadth, independent of batchSize. Seeding from healCandidates would\n // shrink dedupe to a batchSize window, letting a synthesized fact that\n // duplicates a librarian_inferred fact outside the window pass the Jaccard\n // check — and a convergence loop would then multiply those duplicates.\n //\n // Read inside the transaction, after softDeleteByIds. The query filters\n // deleted_at IS NULL, so rows this pass retires leave the corpus naturally\n // — no explicit safeDeletedSet filter needed. Ordering is load-bearing:\n // the read must follow softDeleteByIds, or a delete-plus-restate (heal's\n // normal output shape) would match the replacement against the row it\n // replaces, drop the replacement, and leave the fact gone entirely (#68).\n // Reading inside the transaction also closes the race with concurrent\n // librarian passes (#69): withSerializedTransactions ensures a librarian\n // transaction either commits entirely before this transaction begins or\n // entirely after it ends, so there is no interleaving point at which a\n // librarian insert could land unseen.\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 const healFactsForDedupe: Array<{ id: string; title: string }> =\n await this.entryRepo.findInferredTitlesByEntityId(entityId, tx);\n\n for (const [k, fact] of validNewFacts.entries()) {\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 // The query already restricts to librarian_inferred, so the\n // projected { id, title } rows carry everything the check needs.\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) {\n diagBuffer.push({ ...diagBase, code: 'fact_deduplicated', detail: { itemIndex: validNewFactItemIndexes[k], reason: 'fuzzy_title' } });\n continue;\n }\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({ id, title: fact.title });\n }\n\n // Every candidate offered this pass is stamped, whether it landed in a\n // successful batch or in outcome.skipped: otherwise skipped facts stay at\n // the head of the updated_at ASC queue and starve everything behind them.\n // Facts heal just created are stamped too — without this each synthesized\n // fact is immediately an eligible candidate again and a host\n // `while (remaining > 0)` loop feeds on heal's own output.\n //\n // Transient-error ids (`reason: 'call_error'` from the runBatched helper,\n // added in Revision 1 of the ladder spec) are excluded from the stamp:\n // a momentary provider hiccup would otherwise lock a fact out of heals\n // for the full HEAL_RECHECK_MS window. The fact is reattempted as soon\n // as the host's scheduler runs heal again — `markHealChecked` skips\n // soft-deleted rows above, which is also correct (a deleted row is not\n // a candidate under any future pass).\n const callErrorIds = new Set(\n outcome.skipped.filter((s) => s.reason === 'call_error').map((s) => s.item.id),\n );\n await this.entryRepo.markHealChecked(\n [\n ...healCandidates.map((f) => f.id).filter((id) => !callErrorIds.has(id)),\n ...insertedFacts.map((f) => f.id),\n ],\n entityId,\n now,\n tx,\n );\n });\n\n for (const { item, reason } of outcome.skipped) {\n diagBuffer.push({ ...diagBase, code: 'heal_skipped', detail: { factId: item.id, reason } });\n }\n diagBuffer.flush(this.options);\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 emitDiagnostic(this.options, { ...diagBase, code: 'hook_failed', detail: { factId, reason: 'on_embedding_persisted' } });\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'heal', trigger });\n }\n\n this.searchService.evictCache(entityId);\n\n // Reconcile: a degraded record for an id in outcome.skipped is a\n // contradiction (degraded = healed, skipped = dropped). Drop the\n // contradiction. The reconciliation makes the two arrays mutually\n // exclusive on id, which is the contract HealResult promises.\n const skippedIds = new Set(outcome.skipped.map(({ item }) => item.id));\n const healedDegraded = degraded.filter((d) => !skippedIds.has(d.id));\n\n // Post-reconcile log. A naive implementation that logs inside the\n // buildPrompt lambda would emit this warning for facts whose L3\n // attempt still failed; that warning is a property of the log\n // stream, not just the data shape, and the test suite locks it.\n for (const d of healedDegraded) {\n console.warn(\n `[WikiMemory] heal healed under degraded context ${entityId}/${d.id}: ` +\n `body truncated from ${d.originalBodyChars} to ${d.truncatedBodyChars} chars`,\n );\n }\n\n // Skipped candidates were sent to the provider too — they just came back\n // unusable, possibly after being split down to a batch of one. Counting\n // only successful batches would under-report provider exposure, which is\n // the number this field exists to report.\n let scanned = outcome.skipped.length;\n for (const batchResult of outcome.results) scanned += batchResult.batch.length;\n\n // Union rather than sum: the orphan pass runs before candidate selection so\n // its ids cannot also be model-deleted, but a fact the stale pass downgraded\n // can be downgraded again by the model in the same pass.\n const allDowngraded = new Set([...staleDowngradedIds, ...safeDowngraded]);\n const allDeleted = new Set([...orphanedIds, ...uniqueDeletedFactIds]);\n\n const counts = await this.entryRepo.countHealCandidatesByEntityId(entityId, recheckCutoff);\n return {\n scanned,\n downgraded: allDowngraded.size,\n deleted: allDeleted.size,\n newFactsCreated: insertedFacts.length,\n skipped: outcome.skipped.map(({ item, reason }) => ({ id: item.id, reason })),\n degraded: healedDegraded,\n remaining: counts.eligible,\n deferred: counts.deferred,\n };\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: ${formatSkipError(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 — except\n // transient-error ids (`reason: 'call_error'` from the runBatched helper,\n // added in Revision 1 of the ladder spec), which are excluded so a\n // momentary provider hiccup doesn't lock them out of backfill for a full\n // ONTOLOGY_BACKFILL_RECHECK_MS window. Without the stamp on the non-\n // transient cases, those would stay at the head of the updated_at ASC\n // queue and every later pass would re-attempt them first, starving\n // everything behind them.\n if (outcome.skipped.length > 0) {\n const callErrorIds = new Set(\n outcome.skipped.filter((s) => s.reason === 'call_error').map((s) => s.item.id),\n );\n await this.entryRepo.markOntologyChecked(\n outcome.skipped\n .filter(({ item }) => !callErrorIds.has(item.id))\n .map(({ item }) => item.id),\n entityId,\n now,\n this.db,\n );\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 const diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'ontologyBackfill' as const, trigger: 'call' as const };\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 validationDrops: EdgeDrop[] = [];\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 { strict: false, drops: validationDrops },\n );\n for (const drop of validationDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { ...diagBase, factId: fact.id }));\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 const resolveDrops: EdgeDrop[] = [];\n const added = await ontologyService.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges, manifest, titleIndex, tx, now, resolveDrops,\n );\n edgesAdded += added;\n for (const drop of resolveDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, diagBase));\n }\n }\n\n await this.entryRepo.markOntologyChecked(batch.map(f => f.id), entityId, now, tx);\n });\n\n diagBuffer.flush(this.options);\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 cap: number = HEAL_MAX_ANCHORS,\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 // Overfetch is sized off the cap we were given, not the global max —\n // a single-candidate query asks for fewer search hits.\n const hits = this.searchService.searchKeyword(\n query,\n [entityId],\n cap * 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 >= cap) 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","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, normalizeSourceRef } from '../utils/pure';\nimport { latestVerified } from '@equationalapplications/core-okf';\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 // Normalize source_ref using the same rules as ingestDocument and the\n // startup migration. Persisting the raw value would let a later re-ingest\n // collide on shape mismatch (raw DB ref vs. normalized incoming ref) and\n // would skip soft-deletion on the default-path overwrite.\n // A non-null source_ref that normalizes to null (e.g. all-special-chars\n // or whitespace-only) is rejected to mirror ingestDocument — silently\n // coercing it to NULL would create a legacy row that many APIs\n // intentionally exclude.\n let normalizedSourceRef: string | null = null;\n if (fact.source_ref !== null && fact.source_ref !== undefined) {\n normalizedSourceRef = normalizeSourceRef(fact.source_ref);\n if (normalizedSourceRef === null) {\n throw new Error(\n `importDump: invalid source_ref ${JSON.stringify(fact.source_ref)} ` +\n `for entity \"${entityId}\" fact \"${fact.id}\" ` +\n `(must normalize to a non-empty string; see ingestDocument's sourceRef validation)`,\n );\n }\n }\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: normalizedSourceRef,\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 // OKF v0.2 — forwarded as-is; parseOkfBundle / the caller is responsible for\n // populating these per spec, importDump does not derive or validate them.\n lifecycle_status: fact.lifecycle_status ?? 'stable',\n stale_after: fact.stale_after ?? null,\n generated_by: fact.generated_by ?? null,\n okf_sources: fact.okf_sources ?? [],\n okf_verified: fact.okf_verified ?? [],\n okf_usage_window: fact.okf_usage_window ?? null,\n // last_verified_at/_by are DERIVED mirrors of `okf_verified` per spec\n // §5.3. Recomputing here (instead of trusting the payload field) closes\n // the invariant that a raw importDump cannot carry a\n // last_verified_by that contradicts its own okf_verified list.\n ...(() => {\n const latest = latestVerified(fact.okf_verified ?? [], Date.now());\n return { last_verified_at: latest?.at ?? null, last_verified_by: latest?.by ?? null };\n })(),\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 // OKF v0.2\n lifecycle_status: task.lifecycle_status ?? 'stable',\n stale_after: task.stale_after ?? null,\n generated_by: task.generated_by ?? null,\n okf_sources: task.okf_sources ?? [],\n okf_verified: task.okf_verified ?? [],\n okf_usage_window: task.okf_usage_window ?? null,\n // Derived mirrors — see fact branch above; same invariant.\n ...(() => {\n const latest = latestVerified(task.okf_verified ?? [], Date.now());\n return { last_verified_at: latest?.at ?? null, last_verified_by: latest?.by ?? null };\n })(),\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 }, { operation: 'importDump', trigger: 'call' });\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 this.embeddingService.reportHookFailed(\n { operation: 'importDump', trigger: 'call' },\n entityId,\n fact.id,\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 this.embeddingService.reportHookFailed(\n { operation: 'importDump', trigger: 'call' },\n entityId,\n factId,\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 // Dimension promotion clears embedding failure markers for EVERY\n // entity, but this import holds only entity-scoped locks — so it can\n // erase classifications a concurrent runReembed(otherEntity) just\n // made. Defer instead of widening the lock: the mismatch key is\n // sticky, so a later import or a productive sweep tail (one that\n // embeds > 0 rows — MaintenanceService runs the tail reconciliation\n // only `if (embedded > 0)`) completes the promotion.\n // Spec 2026-09-05-reembed-lock-scope-design.md §3.2.\n if (this.jobManager.isAnyReembedActive()) {\n console.info(\n '[WikiMemory] importDump: embedding-dimension promotion deferred; a reembed sweep is in flight',\n );\n } else {\n await this.embeddingService.reconcileEmbeddingDimension();\n }\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","/**\n * Default clamp on embed input length, in characters (~1,500 tokens).\n * Chosen to fit common embedding windows including nomic-embed-text's 2,048 tokens.\n */\nexport const DEFAULT_MAX_EMBED_CHARS = 6_000;\n\n/**\n * Hard upper bound on embed input length, in characters.\n * An unbounded-input guard from `5e04bad fix(core): security hardening phase 2`.\n * Configuration may lower the effective limit but must never raise it past this.\n */\nexport const EMBED_CHARS_CEILING = 16_000;\n","import type { SQLiteAdapter, WikiOptions, EmbeddingMarkerKind, WikiDiagnosticOperation, WikiDiagnosticTrigger } 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';\nimport { DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING } from '../utils/embedDefaults';\nimport { emitDiagnostic } from '../utils/diagnostics';\n\nexport type { EmbeddingMarkerKind };\n\nexport type EmbedFailureKind =\n | EmbeddingMarkerKind\n | 'no_provider'\n | 'storage_error';\n\nexport type EmbedFactResult =\n | { ok: true; dimension: number }\n | { ok: false; kind: EmbedFailureKind };\n\nexport interface EmbedDiagnosticContext {\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n}\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 /**\n * Promotes embedding_dimension_mismatch to canonical embedding_dimension when\n * safe, and clears embedding failure markers as part of the same event.\n *\n * Marker reset (spec §2.3): a promoted dimension means a different model is\n * producing the vectors, so prior failures no longer predict future ones.\n * `float32_overflow` is cleared too — it is terminal only because retrying is\n * the same arithmetic on the same vector, and after a model change it is not.\n *\n * All three writes commit atomically; see the transaction note inline.\n *\n * Revived rows are NOT embedded here. They become eligible and are picked up\n * by the NEXT sweep, because runReembed calls this after its candidates were\n * already classified; same-sweep revival would be re-entrant.\n *\n * Caller contract (spec 2026-09-05 §3.2): callers must not invoke this while\n * a reembed sweep is in flight unless they hold that sweep's lock, because\n * the marker clear spans every entity. `runReembed`'s tail call is exempt —\n * by the tail, the sweep's classification phase is complete, so the clear\n * cannot resurrect a row THIS sweep classified; any overlap with a\n * concurrent import's entity-scoped, blob-guarded writes (an importDump of a\n * different entity can run during a per-entity sweep) is bounded redundant\n * work. External callers\n * gate on `JobManager.isAnyReembedActive()` and defer. This service\n * deliberately holds no `JobManager` reference: gating here instead of at\n * the call site would make `runReembed`'s own tail call see its own lock and\n * defer forever.\n */\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 // One transaction for the whole promotion (spec §2.3): the three writes\n // are a single logical event. Committed separately, a failure after\n // clearDimensionMismatch would leave markers set with no mismatch key\n // left to re-trigger promotion, stranding those rows until `force: true`.\n // Safe to open here — both callers (runReembed, importDump's dimension\n // reconciliation) invoke this outside their own transactions, and the\n // adapter does not support nesting.\n await this.db.withTransactionAsync(async (tx) => {\n await this.metadataRepo.setMeta('embedding_dimension', mismatchValue, tx);\n await this.metadataRepo.clearDimensionMismatch(tx);\n await this.entryRepo.clearEmbeddingFailureMarkers(tx);\n });\n }\n }\n\n async tryEmbedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }, ctx?: EmbedDiagnosticContext): Promise<EmbedFactResult> {\n const embedFn = this.options.llmProvider.embed;\n // Callability, not truthiness: a truthy non-function would pass a `!embedFn`\n // guard, throw TypeError at the call, and be marked `provider_error` —\n // burning an attempt per sweep until a host config error permanently\n // excluded the fact. `no_provider` never marks. (spec §2.4)\n if (typeof embedFn !== 'function') return { ok: false, kind: 'no_provider' };\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 configuredMaxEmbedChars = this.options.config?.maxEmbedChars;\n const maxEmbedChars = Number.isFinite(configuredMaxEmbedChars)\n ? Math.min(Math.max(0, Math.trunc(configuredMaxEmbedChars as number)), EMBED_CHARS_CEILING)\n : DEFAULT_MAX_EMBED_CHARS;\n const text = clip(`${fact.title} ${fact.body} ${tagsStr}`.trim(), maxEmbedChars);\n let float32Vector: Float32Array;\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 this.reportEmbed(ctx, fact, 'embedding_failed', 'invalid_vector');\n await this.markFailure(fact.id, 'invalid_vector');\n return { ok: false, kind: 'invalid_vector' };\n }\n 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 this.reportEmbed(ctx, fact, 'embedding_failed', 'float32_overflow');\n await this.markFailure(fact.id, 'float32_overflow');\n return { ok: false, kind: 'float32_overflow' };\n }\n } catch (err) {\n console.warn(`[WikiMemory] embedFact failed for ${fact.id}:`, err);\n this.reportEmbed(ctx, fact, 'embedding_failed', 'embed_threw');\n await this.markFailure(fact.id, 'provider_error');\n return { ok: false, kind: 'provider_error' };\n }\n\n // Storage is a separate failure domain: a DB error here is NOT an\n // embedding failure and must not be marked as one (spec §3.2, D3).\n try {\n await this.storeEmbeddingDimension(float32Vector.length);\n const blob = new Uint8Array(float32Vector.buffer);\n await this.entryRepo.updateEmbeddingBlob(fact.id, blob);\n } catch (err) {\n console.warn(`[WikiMemory] embedFact: persisting embedding failed for ${fact.id}:`, err);\n this.reportEmbed(ctx, fact, 'embedding_failed', 'persist_failed');\n return { ok: false, kind: 'storage_error' };\n }\n\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 this.reportEmbed(ctx, fact, 'hook_failed', 'on_embedding_persisted');\n }\n return { ok: true, dimension: float32Vector.length };\n }\n\n private reportEmbed(\n ctx: EmbedDiagnosticContext | undefined,\n fact: { id: string; entity_id: string },\n code: 'embedding_failed' | 'hook_failed',\n reason: 'invalid_vector' | 'float32_overflow' | 'embed_threw' | 'persist_failed' | 'on_embedding_persisted',\n ): void {\n if (!ctx) return;\n emitDiagnostic(this.options, {\n code, operation: ctx.operation, trigger: ctx.trigger, entityId: fact.entity_id,\n detail: { factId: fact.id, reason },\n });\n }\n\n /** For callers that invoke `notifyEmbeddingPersisted` directly and catch its failure. */\n reportHookFailed(ctx: EmbedDiagnosticContext, entityId: string, factId: string): void {\n this.reportEmbed(ctx, { id: factId, entity_id: entityId }, 'hook_failed', 'on_embedding_persisted');\n }\n\n /** Marker writes must never fail the caller. Only marker-eligible kinds reach here. */\n private async markFailure(id: string, kind: EmbeddingMarkerKind): Promise<void> {\n try {\n await this.entryRepo.markEmbeddingFailure(id, kind, Date.now());\n } catch (err) {\n console.warn(`[WikiMemory] failed to record embedding failure for ${id}:`, err);\n }\n }\n\n /**\n * Back-compatible boolean form. Kept because callers such as\n * ImportExportService branch on `if (!embedded)`; a discriminated result\n * object is always truthy and would silently disable that branch.\n */\n async embedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }, ctx?: EmbedDiagnosticContext): Promise<boolean> {\n const result = await this.tryEmbedFact(fact, ctx);\n return result.ok;\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 { WikiInvalidReadOptions } from './types';\n\nexport 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\n/**\n * Validates and sanitizes `ReadOptions.tierFloors`.\n *\n * Throws `WikiInvalidReadOptions` for contradictions detectable without touching\n * data. Sanitizes value-shape noise. Never throws for data-dependent shortfalls —\n * an entity with fewer facts than its floor simply contributes what it has.\n */\nexport function validateTierFloors(\n entityIds: readonly string[],\n tierFloors: Record<string, number> | undefined,\n sanitizedTierWeights: Record<string, number> | undefined,\n includeZeroWeightEntities: boolean | undefined,\n maxResults: number,\n): Record<string, number> | undefined {\n if (tierFloors === undefined) return undefined;\n\n const known = new Set(entityIds);\n for (const key of Object.keys(tierFloors)) {\n // Per §4.2: non-finite values are sanitized away as absent. Filtering them\n // before key validation matches the documented rule and lets a typo like\n // { typo: NaN } fall through cleanly instead of tripping the \"key is not\n // one of the entity IDs\" check on a value the caller did not actually set.\n const raw = tierFloors[key];\n if (raw === undefined || !Number.isFinite(raw)) continue;\n if (!known.has(key)) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `\"${key}\" is not one of the entity IDs passed to read(); ` +\n `a floor on an unrequested entity can never be satisfied`,\n );\n }\n }\n\n const sanitized = Object.create(null) as Record<string, number>;\n let total = 0;\n for (const entityId of entityIds) {\n const raw = tierFloors[entityId];\n if (raw === undefined || !Number.isFinite(raw)) continue;\n const floor = Math.max(0, Math.trunc(raw));\n\n if (floor > 0 && includeZeroWeightEntities !== true && sanitizedTierWeights?.[entityId] === 0) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `\"${entityId}\" has tierWeight 0 and includeZeroWeightEntities is not set, ` +\n `so it is excluded from retrieval and its floor of ${floor} can never be met`,\n );\n }\n\n sanitized[entityId] = floor;\n total += floor;\n }\n\n if (total > maxResults) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `floors sum to ${total}, which exceeds maxResults (${maxResults})`,\n );\n }\n\n return sanitized;\n}\n\n/**\n * Selects up to `maxResults` rows, reserving each entity's top-N first.\n *\n * PRECONDITION: `sortedRows` must already be in final rank order (the caller's\n * tie-break sort). Selection order is restored from each row's position in the\n * input, so unsorted input yields silently wrong output rather than an error.\n *\n * Floors change which rows are selected, never the order they are returned in.\n */\nexport function selectWithFloors<T extends { id: string; entity_id: string }>(\n sortedRows: readonly T[],\n floors: Record<string, number> | undefined,\n maxResults: number,\n): T[] {\n if (maxResults <= 0) return [];\n if (floors === undefined || Object.keys(floors).length === 0) {\n return sortedRows.slice(0, maxResults);\n }\n\n const selected = new Set<number>();\n const taken = Object.create(null) as Record<string, number>;\n\n // Pass 1 — reserve each entity's top-N. Bounded by sum(floors) <= maxResults,\n // which validateTierFloors guarantees, so this cannot overflow the window.\n for (let i = 0; i < sortedRows.length; i++) {\n const entityId = sortedRows[i].entity_id;\n const floor = floors[entityId] ?? 0;\n if (floor <= 0) continue;\n const count = taken[entityId] ?? 0;\n if (count >= floor) continue;\n taken[entityId] = count + 1;\n selected.add(i);\n }\n\n // Pass 2 — fill the remaining slots in rank order.\n for (let i = 0; i < sortedRows.length && selected.size < maxResults; i++) {\n if (!selected.has(i)) selected.add(i);\n }\n\n // Restore global rank order: input was sorted, so index order is rank order.\n return Array.from(selected)\n .sort((a, b) => a - b)\n .map(i => sortedRows[i]);\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, selectWithFloors, shouldExposeReadMetadata, validateTierFloors } from '../readOptions';\nimport { sanitizeRankerError, safeErrorToString } from '../utils/pure';\n\ntype ReadCandidateRowMetadata = EntryRowMetadata;\ntype ReadCandidateRowWithEmbeddings = EntryRowWithEmbeddings;\n\nconst EMPTY_ID_SET: ReadonlySet<string> = new Set<string>();\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 excludeDrafts = (options?.excludeDrafts ?? config?.excludeDrafts ?? false) === true;\n const trimmedQuery = query.trim();\n // §3.3 — tierFloors is ignored on the empty-query recency path. Skipping\n // validation here keeps the public contract honest: an empty-query call\n // with floors that would otherwise be invalid must not throw, since the\n // floors are dropped before the cut anyway.\n const sanitizedTierFloors = trimmedQuery && exposeMetadata\n ? validateTierFloors(\n entityIds,\n options?.tierFloors,\n sanitizedTierWeights,\n options?.includeZeroWeightEntities,\n maxResults,\n )\n : undefined;\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\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 // Spec §5.1: one SQLite read per call; status is never taken from an index.\n const draftIds: ReadonlySet<string> = excludeDrafts && scoredEntityIds.length > 0\n ? await this.entryRepo.findDraftIdsByEntityIds(scoredEntityIds)\n : EMPTY_ID_SET;\n const draftPad = draftIds.size;\n const padLimit = (n: number): number => (n >= Number.MAX_SAFE_INTEGER ? n : n + draftPad);\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\n .searchKeyword(trimmedQuery, scoredEntityIds, Number.MAX_SAFE_INTEGER)\n .filter((r) => !draftIds.has(r.id));\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 = this._withoutDrafts(await this.entryRepo.findMetadataByEntityIds(scoredEntityIds), draftIds);\n } else {\n candidateRows = this._withoutDrafts(await this.entryRepo.findWithEmbeddingsByEntityIds(scoredEntityIds), draftIds);\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: padLimit(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 // Reserve per-entity floor shortfalls from omitted rows BEFORE\n // the global backfill pass. Without this reservation, the global\n // backfill budget caps at `maxResults - scored.length` (pure\n // semantic) or `maxResults` selected by kwScore (hybrid), and\n // either cap can silently drop every row from a floored entity\n // when the ranker returned no scores for it. selectWithFloors\n // cannot reserve a starved entity's floor from a `scored`\n // array that does not contain enough of its rows.\n type CandidateRow = typeof candidateRows[number];\n const floorShortfallByEntity: Record<string, number> = Object.create(null);\n let totalFloorShortfall = 0;\n if (sanitizedTierFloors) {\n const scoredCounts = new Map<string, number>();\n for (const s of scored) {\n scoredCounts.set(s.entity_id, (scoredCounts.get(s.entity_id) ?? 0) + 1);\n }\n for (const [entityId, floor] of Object.entries(sanitizedTierFloors)) {\n if (floor <= 0) continue;\n const currentCount = scoredCounts.get(entityId) ?? 0;\n const shortfall = Math.max(0, floor - currentCount);\n if (shortfall > 0) {\n floorShortfallByEntity[entityId] = shortfall;\n totalFloorShortfall += shortfall;\n }\n }\n }\n\n const reservedIds = new Set<string>();\n const reserved: Array<{ row: CandidateRow; kwScore: number }> = [];\n if (totalFloorShortfall > 0) {\n for (const [entityId, shortfall] of Object.entries(floorShortfallByEntity)) {\n const entityOmitted: Array<{ row: CandidateRow; kwScore: number }> = [];\n for (const row of candidateRows) {\n if (scoredIds.has(row.id) || reservedIds.has(row.id)) continue;\n if (row.entity_id !== entityId) continue;\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n entityOmitted.push({ row, kwScore });\n }\n // Sort within the floored entity by kwScore desc with the\n // shared tie-break. Within a single entity the kwScore\n // pool is small, so a full sort is fine here.\n entityOmitted.sort((a, b) => this._compareScoredRows(\n { id: a.row.id, score: a.kwScore, updated_at: a.row.updated_at, access_count: a.row.access_count },\n { id: b.row.id, score: b.kwScore, updated_at: b.row.updated_at, access_count: b.row.access_count },\n ));\n for (let i = 0; i < Math.min(shortfall, entityOmitted.length); i++) {\n reserved.push(entityOmitted[i]);\n reservedIds.add(entityOmitted[i].row.id);\n }\n }\n }\n\n const isHybrid = weight !== undefined && weight < 1;\n\n if (reserved.length > 0) {\n if (isHybrid) {\n for (const { row, kwScore } of reserved) {\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 for (const { row } of reserved) {\n scored.push({\n id: row.id,\n entity_id: row.entity_id,\n score: -2,\n updated_at: row.updated_at,\n access_count: row.access_count,\n });\n }\n }\n }\n\n // Compute the backfill budget AFTER the reserved rows have been\n // pushed into `scored`, so pure semantic fills only the slots the\n // reservation left over rather than over-materializing by\n // `reserved.length`. Hybrid keeps a global top-K of `maxResults`\n // selected by keyword score, unchanged.\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 const topK: Array<{ row: CandidateRow; kwScore: number }> = [];\n\n for (const row of candidateRows) {\n if (scoredIds.has(row.id) || reservedIds.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) || reservedIds.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 // `rankerErr instanceof Error` invokes the getPrototypeOf\n // trap on rankerErr. A hostile VectorRanker plugin could\n // return one whose trap rejects — treat as non-Error and\n // wrap in a synthetic Error so the fallback callback still\n // receives an Error instance.\n let isErrorLike = false;\n try {\n isErrorLike = rankerErr instanceof Error;\n } catch {\n // hostile Proxy — fall through\n }\n // `String(rankerErr)` invokes the `toString` /\n // `Symbol.toPrimitive` trap on rankerErr — a hostile Proxy\n // whose trap rejects would throw out of this catch and tear\n // down the retrieval. Delegate to the hardened\n // `safeErrorToString` helper (converges on the static\n // `[unstringifiable error]` marker on throw) to honor the\n // non-throwing contract this guard exists to provide.\n const rankerError = isErrorLike ? (rankerErr as Error) : new Error(safeErrorToString(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. When\n // preFilterLimit was active, candidateRows was already\n // narrowed to the pre-filtered IDs (§3.5); restrict this\n // keyword call to that same set so a floor cannot resurrect\n // a fact excluded by preFilterLimit.\n //\n // Active floors force full materialization here too, mirroring\n // the JS-cosine path's `jsCosineNeedsTierSort` widening and\n // the ordinary keyword fallback's `hasActiveFloors` widening:\n // selectWithFloors can only reserve a starved entity's rows\n // if they survive this keyword call's oversampling limit, and\n // a pre-truncated top-K is exactly the starved window the\n // floor exists to correct.\n const hasActiveFloorsKeywordFallback = sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0);\n const keywordOversampledLimit = hasActiveFloorsKeywordFallback\n ? Number.MAX_SAFE_INTEGER\n : padLimit(Math.max(maxResults * 2, maxResults + 50));\n const preFilteredIds = effectivePreFilterLimit !== undefined\n ? new Set((candidateRows as ReadCandidateRowMetadata[]).map(r => r.id))\n : undefined;\n const keywordResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, keywordOversampledLimit);\n const topResults = preFilteredIds === undefined\n ? keywordResults\n : keywordResults.filter(r => preFilteredIds.has(r.id));\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 // Active floors force materialization too: selectWithFloors can only reserve a\n // starved entity's rows if they survive the ranker's own limit, and a pre-truncated\n // top-K is exactly the starved window the floor exists to correct.\n const jsCosineNeedsTierSort = (sanitizedTierWeights !== undefined &&\n Object.values(sanitizedTierWeights).some(w => w !== 1)) ||\n (sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0));\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 (draftPad > 0) scored = scored.filter((s) => !draftIds.has(s.id));\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 = selectWithFloors(scored, sanitizedTierFloors, 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 // `err instanceof Error` invokes the getPrototypeOf trap on err.\n // A hostile Proxy (e.g. from a VectorRanker plugin or a wrapped\n // inner-call result) whose trap rejects must not throw out of\n // this catch — it would tear down the entire retrieval operation.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n // hostile Proxy — fall through\n }\n // Narrowed view: only valid when `isErrorLike` is true (guaranteed\n // by the try/catch above). Cast captures that runtime invariant\n // for the typechecker; the runtime is already proven correct.\n // `String(err)` invokes the `toString` / `Symbol.toPrimitive` trap\n // on err — delegate to the hardened `safeErrorToString` helper\n // so a hostile Proxy whose trap rejects cannot escape this catch.\n const error = isErrorLike ? (err as Error) : new Error(safeErrorToString(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 try {\n (error as any).cause = pendingRankerFallbackError;\n } catch {\n // Hostile or frozen error object — the assignment threw, so the\n // ranker diagnostic would otherwise be silently dropped. Surface\n // it as its own fallback notification instead of losing it.\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n }\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 // Active floors force full materialization: selectWithFloors can only\n // reserve a starved entity's rows if they survive the keyword\n // oversampling limit, and a pre-truncated top-K is exactly the starved\n // window the floor exists to correct. Mirrors the JS-cosine path's\n // `jsCosineNeedsTierSort` widening.\n const hasActiveFloors = sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0);\n const fallbackOversampledLimit = hasActiveFloors\n ? Number.MAX_SAFE_INTEGER\n : padLimit(Math.max(maxResults * 2, maxResults + 50));\n const results = this.searchService\n .searchKeyword(trimmedQuery, scoredEntityIds, fallbackOversampledLimit)\n .filter((r) => !draftIds.has(r.id as string));\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 = selectWithFloors(candidates, sanitizedTierFloors, 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 // Pass `excludeDrafts` opts only when true; the default path keeps its\n // 2-arg call signature for callers that prefer the strict form.\n facts = excludeDrafts\n ? await this.entryRepo.findRecentByEntityIds(entityIds, maxResults, undefined, { excludeDrafts: true })\n : 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 (sanitizedTierFloors && Object.keys(sanitizedTierFloors).length > 0) bundle.metadata.tierFloors = sanitizedTierFloors;\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 private _withoutDrafts<T extends { id: string }>(rows: T[], draftIds: ReadonlySet<string>): T[] {\n return draftIds.size === 0 ? rows : rows.filter((row) => !draftIds.has(row.id));\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","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';\nimport { emitDiagnostic } from '../utils/diagnostics';\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 let eventCount = 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 eventCount = count;\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 const stage: { job: 'librarian' | 'heal' } = { job: 'librarian' };\n this.runLibrarianThenMaybeHeal(entityId, librarianCount, prevMemoryCheckpoint, stage)\n .catch((err: unknown) => {\n console.error(err);\n this.reportBackgroundFailure(entityId, stage.job);\n })\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 } else if (!this.jobManager.isBlocked('librarian', entityId)) {\n // Auto-heal is evaluated on every write, not only on writes that also\n // trigger a librarian pass. doRunHeal is bounded to HEAL_BATCH_SIZE\n // candidates (#67) and a non-converged pass deliberately holds its\n // checkpoint back, so the gap stays above autoHealThreshold; gating the\n // retry on a librarian pass would stall a partial sweep until the next\n // librarian threshold crossing (another autoLibrarianThreshold events),\n // or forever if no further librarian pass runs.\n //\n // heal and librarian can overlap (deliberate mutex split in\n // JobManager.acquireLock). This check only reduces redundant passes — a\n // librarian pass already calls maybeRunHeal when it finishes, so losing\n // the race costs a duplicate pass, not correctness. Correctness rests on\n // heal's dedupe read being inside its transaction (#69).\n // tryAcquireAutoHealLock inside maybeRunHeal prevents a burst of writes\n // from stacking passes.\n this.maybeRunHeal(entityId, eventCount).catch((err: unknown) => {\n console.error(err);\n this.reportBackgroundFailure(entityId, 'heal');\n });\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number, prevCheckpoint: number, stage: { job: 'librarian' | 'heal' }): Promise<void> {\n try {\n await this.maintenanceService.doRunLibrarian(entityId, undefined, 'auto');\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 stage.job = 'heal';\n await this.maybeRunHeal(entityId, currentEventCount);\n }\n\n /**\n * Run one bounded auto-heal pass if the heal checkpoint has fallen\n * `autoHealThreshold` events behind. Called after every write (see\n * {@link write}) so a partial pass retries on the next write.\n */\n private async maybeRunHeal(entityId: string, currentEventCount: number): Promise<void> {\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 const result = await this.maintenanceService.doRunHeal(entityId, { trigger: 'auto' });\n // Advance only when the pass converged. doRunHeal is bounded to\n // HEAL_BATCH_SIZE candidates (#67); advancing unconditionally would cap\n // auto-heal at one batch per autoHealThreshold events and leave most of\n // a large corpus never auto-healed. Held back, the checkpoint gap stays\n // above the threshold, so the next write runs another bounded pass —\n // cost per write stays bounded while the corpus still converges.\n //\n // Sits inside the try, after the call: on a throw the checkpoint is not\n // advanced, exactly as before this change.\n if (result.remaining === 0) {\n await this.metadataRepo.updateCheckpoint(entityId, { heal: currentEventCount }, this.db);\n }\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n }\n\n private reportBackgroundFailure(entityId: string, job: 'librarian' | 'heal'): void {\n emitDiagnostic(this.options, {\n code: 'background_job_failed', operation: job, trigger: 'auto', entityId,\n detail: { reason: 'unhandled_rejection' },\n });\n }\n}\n","import type { OntologyMode } from '../types';\n\nconst FACT_ONTOLOGY_FIELDS = `\nEach fact may optionally include:\n- \"okf_type\": string — must be one of the node_types in the manifest\n- \"edges\": [{ \"edge_type\": string, \"target_title\": string }] — target_title must match another fact's title in this response or existing memory\n- An edge_type may appear in the manifest multiple times with different source_type/target_type; use the row whose types match your fact and target.`;\n\nconst EMERGENT_EXTRA = `\nYou may also return \"ontology_updates\" to propose new types:\n\"ontology_updates\": {\n \"node_types\": [{ \"type\": \"slug\", \"description\": \"...\", \"parent_type\": \"optional existing slug\" }],\n \"edge_types\": [{ \"type\": \"slug\", \"source_type\": \"...\", \"target_type\": \"...\", \"description\": \"...\" }]\n}\nOnly propose types not already in the manifest. Do not redefine existing types.`;\n\nexport function buildOntologyPromptAppendix(\n mode: OntologyMode,\n manifestJson: string,\n): { ontologyManifest: string; ontologyModeInstructions: string } {\n const strictRules = mode === 'strict'\n ? 'STRICT MODE: Use ONLY types defined in the manifest. If a fact does not fit any node_type, omit okf_type and edges entirely.'\n : 'EMERGENT MODE: Prefer manifest types. You may propose new types via ontology_updates when necessary.';\n\n const fallback = 'If okf_type or an edge is invalid, omit them rather than inventing unlisted types.';\n\n const ontologyModeInstructions = [\n '## Ontology constraints',\n strictRules,\n fallback,\n FACT_ONTOLOGY_FIELDS,\n mode === 'emergent' ? EMERGENT_EXTRA : '',\n 'Manifest:',\n manifestJson,\n ].filter(Boolean).join('\\n');\n\n return { ontologyManifest: manifestJson, ontologyModeInstructions };\n}\n","import type {\n OntologyConfig,\n OntologyManifest,\n OntologyMode,\n OntologyPromptContext,\n OntologyUpdates,\n ExtractedFactWithOntology,\n ExtractedFactEdge,\n SQLiteAdapter,\n WikiEdge,\n} from '../types';\nimport { WikiStrictOntologyViolation } from '../types';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\nimport { buildOntologyPromptAppendix } from '../prompts/ontology';\nimport {\n emptyManifest,\n normalizeTitleKey,\n resolveNodeType,\n resolveEdgeDefinitions,\n typeSatisfies,\n validateInlineEdges,\n validateManifest,\n type EdgeDrop,\n} from '../utils/ontology';\nimport { generateId } from '../utils/ids';\n\nexport type TitleIndexEntry = { id: string; okf_type: string | null };\n\n/**\n * Coordinates ontology mode resolution, manifest caching, LLM output validation, and edge persistence.\n * Cache is per WikiMemory instance (single-process); not shared across instances.\n */\nexport class OntologyService {\n private cache = new Map<string, { mode: OntologyMode; manifest: OntologyManifest }>();\n\n constructor(\n private metadataRepo: MetadataRepository,\n private edgeRepo: EdgeRepository,\n private ontologyConfig?: OntologyConfig,\n ) {}\n\n resolveMode(storedMode?: OntologyMode): OntologyMode {\n return storedMode ?? this.ontologyConfig?.mode ?? 'off';\n }\n\n invalidateCache(entityId: string): void {\n this.cache.delete(entityId);\n }\n\n async getEffectiveState(entityId: string, tx?: SQLiteAdapter): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n }> {\n if (!tx) {\n const cached = this.cache.get(entityId);\n if (cached) return cached;\n }\n\n const row = await this.metadataRepo.getManifest(entityId, tx);\n if (row) {\n const state = { mode: this.resolveMode(row.mode), manifest: row.manifest };\n if (!tx) this.cache.set(entityId, state);\n return state;\n }\n\n const seed = this.ontologyConfig?.seedManifests?.[entityId];\n if (seed) {\n // D11: the tx branch validates via setManifest; the cache branch did not.\n validateManifest(seed.manifest);\n const state = {\n mode: this.resolveMode(seed.mode),\n manifest: seed.manifest,\n };\n if (tx) {\n await this.metadataRepo.setManifest(entityId, state, tx);\n } else {\n this.cache.set(entityId, state);\n }\n return state;\n }\n\n return { mode: 'off', manifest: emptyManifest() };\n }\n\n async buildPromptContext(entityId: string): Promise<OntologyPromptContext | null> {\n const { mode, manifest } = await this.getEffectiveState(entityId);\n if (mode === 'off') return null;\n const manifestJson = JSON.stringify(manifest, null, 2);\n return buildOntologyPromptAppendix(mode, manifestJson);\n }\n\n async mergeEmergentUpdates(\n entityId: string,\n updates: OntologyUpdates,\n tx: SQLiteAdapter,\n ): Promise<OntologyManifest> {\n const merged = await this.metadataRepo.mergeManifestUpdates(entityId, updates, tx);\n this.invalidateCache(entityId);\n return merged;\n }\n\n validateAndNormalizeFact(\n fact: ExtractedFactWithOntology,\n manifest: OntologyManifest,\n opts?: { strict?: boolean; entityId?: string; drops?: EdgeDrop[] },\n ): { okf_type: string | null; edges: ExtractedFactEdge[] } {\n const rawType = typeof fact.okf_type === 'string' ? fact.okf_type : '';\n const strict = opts?.strict === true;\n const canonical = resolveNodeType(rawType, manifest);\n if (!canonical) {\n if (strict) throw new WikiStrictOntologyViolation(opts?.entityId ?? '', 'node', rawType);\n if (opts?.drops && Array.isArray(fact.edges)) {\n for (const edge of fact.edges) {\n opts.drops.push({\n reason: 'no_source_type',\n sourceId: null,\n edgeType: typeof edge?.edge_type === 'string' ? edge.edge_type : null,\n sourceNodeType: null,\n targetNodeType: null,\n });\n }\n }\n return { okf_type: null, edges: [] };\n }\n const edges = validateInlineEdges(canonical, null, fact.edges ?? [], manifest, opts);\n return { okf_type: canonical, edges };\n }\n\n /**\n * Pure resolver: given a source type, LLM-supplied edges, the manifest,\n * and a title index, return a list of concrete `WikiEdge` objects ready\n * for persistence. Performs no DB writes. Used by callers that batch edge\n * writes inside their own transaction (e.g. `IngestionService.ingestDocument`\n * when delegating to `upsertGraphCore`).\n */\n resolveEdges(\n entityId: string,\n sourceId: string,\n sourceType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n titleIndex: Map<string, TitleIndexEntry>,\n now: number,\n drops?: EdgeDrop[],\n ): WikiEdge[] {\n if (edges.length === 0) return [];\n if (!sourceType) {\n for (const edge of edges) {\n drops?.push({ reason: 'no_source_type', sourceId, edgeType: edge.edge_type, sourceNodeType: null, targetNodeType: null });\n }\n return [];\n }\n const out: WikiEdge[] = [];\n for (const edge of edges) {\n const candidates = resolveEdgeDefinitions(edge.edge_type, manifest)\n .filter(d => typeSatisfies(d.source_type, sourceType, manifest));\n if (candidates.length === 0) {\n drops?.push({ reason: 'type_not_in_manifest', sourceId, edgeType: edge.edge_type, sourceNodeType: sourceType, targetNodeType: null });\n continue;\n }\n\n const targetKey = normalizeTitleKey(edge.target_title);\n const target = titleIndex.get(targetKey);\n if (!target) {\n drops?.push({ reason: 'target_not_found', sourceId, edgeType: edge.edge_type, sourceNodeType: sourceType, targetNodeType: null });\n continue;\n }\n\n const targetType = (target.okf_type ?? '').trim().toLowerCase();\n const def = candidates.find(d => d.target_type.trim().toLowerCase() === targetType)\n ?? candidates.find(d => typeSatisfies(d.target_type, targetType, manifest));\n if (!def) {\n drops?.push({\n reason: 'target_type_mismatch', sourceId, edgeType: edge.edge_type,\n sourceNodeType: sourceType, targetNodeType: target.okf_type ?? null,\n });\n continue;\n }\n\n out.push({\n id: generateId(),\n entity_id: entityId,\n source_id: sourceId,\n target_id: target.id,\n edge_type: def.type,\n created_at: now,\n });\n }\n return out;\n }\n\n /**\n * Backwards-compatible wrapper: resolves edges via {@link resolveEdges},\n * then persists each via `edgeRepo.addIgnoreDuplicate` in the supplied\n * transaction. Returns the number of edges persisted. Used by paths that\n * want self-contained edge persistence (e.g. MaintenanceService heal /\n * backfill callers that do not have a separate edge-write step).\n */\n async resolveAndPersistEdges(\n entityId: string,\n sourceId: string,\n sourceType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n titleIndex: Map<string, TitleIndexEntry>,\n tx: SQLiteAdapter,\n now: number,\n drops?: EdgeDrop[],\n ): Promise<number> {\n const resolved = this.resolveEdges(entityId, sourceId, sourceType, edges, manifest, titleIndex, now, drops);\n let persisted = 0;\n for (const edge of resolved) {\n const inserted = await this.edgeRepo.addIgnoreDuplicate(edge, tx);\n if (inserted) persisted++;\n }\n return persisted;\n }\n}\n","import type { EdgeRepository, NeighborhoodQueryOptions } from '../repositories/EdgeRepository';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { GraphTraversalOptions, GraphNeighborhood, WikiConfig } from '../types';\n\n/**\n * Pure orchestrator — no SQL. Merges WikiConfig defaults with per-call options,\n * delegates the recursive walk to EdgeRepository, then hydrates node IDs into facts.\n */\nexport class GraphTraversalService {\n constructor(\n private edgeRepo: EdgeRepository,\n private entryRepo: EntryRepository,\n private config: WikiConfig,\n ) {}\n\n async traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood> {\n const fallbackMaxNodes = 20;\n const rawConfigDefault = this.config.maxTraversalNodes ?? fallbackMaxNodes;\n const defaultMaxNodes =\n Number.isFinite(rawConfigDefault) && rawConfigDefault >= 1\n ? Math.floor(rawConfigDefault)\n : fallbackMaxNodes;\n const rawMaxNodes = options.maxTraversalNodes ?? defaultMaxNodes;\n const maxNodes =\n Number.isFinite(rawMaxNodes) && rawMaxNodes >= 1 ? Math.floor(rawMaxNodes) : defaultMaxNodes;\n\n const opts: NeighborhoodQueryOptions = {\n maxDepth: Math.max(1, Math.min(options.maxDepth ?? 1, 3)),\n direction: options.direction ?? this.config.traversalDirection ?? 'both',\n edgeTypes: options.edgeTypes,\n minConfidence: options.minTraversalConfidence ?? this.config.minTraversalConfidence ?? 'tentative',\n excludeSourceTypes: options.excludeSourceTypes ?? this.config.excludeSourceTypes ?? [],\n excludeDrafts: options.excludeDrafts ?? this.config.excludeDrafts ?? false,\n maxNodes,\n };\n\n const { nodeIds, edges } = await this.edgeRepo.getNeighborhood(entityId, options.sourceId, opts);\n if (nodeIds.length === 0) return { nodes: [], edges: [] };\n\n // findByIds() returns facts in input-ID order (Map-based lookup,\n // see packages/core/src/repositories/EntryRepository.ts:104-108) — no re-sort needed.\n const nodes = await this.entryRepo.findByIds(nodeIds, [entityId]);\n const hydratedIds = new Set(nodes.map((node) => node.id));\n const filteredEdges = edges.filter(\n (edge) => hydratedIds.has(edge.source_id) && hydratedIds.has(edge.target_id),\n );\n return { nodes, edges: filteredEdges };\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport {\n formatSourcesJson,\n formatVerifiedJson,\n latestVerified,\n} from '@equationalapplications/core-okf';\n\nexport type OkfSource = {\n id?: string;\n resource: string;\n title?: string;\n author?: string;\n usage_count?: number;\n last_modified?: string;\n usage_window?: { from: string; to: string };\n};\nexport type OkfVerifiedEntry = { by: string; at: string };\n\n/**\n * DAO discipline (spec §8): only knowledge-content writes may bump `updated_at`.\n * Trust / provenance / lifecycle / freshness writes MUST NOT touch it. Every\n * `UPDATE` in this class is a non-content metadata write. Tests in\n * `__tests__/daoDiscipline.test.ts` and `__tests__/okfTrustWrites.test.ts`\n * snapshot the SQL via a logging adapter and assert the SET clause omits\n * `updated_at`.\n *\n * Deliberately does NOT push an outbox event, unlike `EntryRepository.upsert`\n * / `TaskRepository.upsert` (spec §8 \"Outbox/transaction scope\" note): outbox\n * delivery exists for *content* sync, and these writes are metadata, not\n * content, by the same reasoning that exempts them from `updated_at`. A\n * downstream sync consumer will not learn about a new verifier until the\n * next full re-export/re-import — accepted for v0.2.\n */\nexport class OkfTrustWritesRepository {\n constructor(private db: SQLiteAdapter, private prefix: string) {}\n\n private getExecutor(tx?: SQLiteAdapter): SQLiteAdapter {\n return tx ?? this.db;\n }\n\n /**\n * Append one or more verification events to a fact's `okf_verified` JSON\n * array, atomically, in a single SQL statement.\n *\n * The implementation uses json_each over the existing array UNION ALL'd\n * with json_each over the new events wrapped in json_group_array — a single\n * UPDATE expression. SQLite serializes this against concurrent writers on\n * the same row, so two callers appending simultaneously cannot lose each\n * other's events (the previous implementation serialized only the supplied\n * array and overwrote, dropping any pre-existing history).\n *\n * Sets the `last_verified_*` convenience columns from the latest event in\n * the union (computed in code; see {@link latestVerified}).\n */\n async writeOkfTrust(\n entryId: string,\n entityId: string,\n verified: OkfVerifiedEntry[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n if (verified.length === 0) return;\n const latest = latestVerified(verified, Date.now());\n const newEventsJson = JSON.stringify(verified);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET okf_verified = COALESCE(\n (SELECT json_group_array(json_object('by', s.by_val, 'at', s.at_val))\n FROM (\n SELECT json_extract(value, '$.by') AS by_val,\n json_extract(value, '$.at') AS at_val\n FROM json_each(okf_verified)\n UNION ALL\n SELECT json_extract(value, '$.by'),\n json_extract(value, '$.at')\n FROM json_each(?)\n ) AS s\n ORDER BY s.at_val),\n '[]'\n ),\n last_verified_by = ?,\n last_verified_at = ?\n WHERE id = ? AND entity_id = ?`,\n [newEventsJson, latest?.by ?? null, latest?.at ?? null, entryId, entityId],\n );\n }\n\n /** Replace the `sources` list (provenance). */\n async writeOkfSources(\n entryId: string,\n entityId: string,\n sources: OkfSource[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n const json = formatSourcesJson(sources);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET okf_sources = ?\n WHERE id = ? AND entity_id = ?`,\n [json, entryId, entityId],\n );\n }\n\n /** Set the OKF v0.2 lifecycle status. */\n async setLifecycleStatus(\n entryId: string,\n entityId: string,\n status: 'draft' | 'stable' | 'deprecated',\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET lifecycle_status = ?\n WHERE id = ? AND entity_id = ?`,\n [status, entryId, entityId],\n );\n }\n\n /** Set the absolute cutoff (epoch ms) for staleness, or NULL to clear. */\n async setStaleAfter(\n entryId: string,\n entityId: string,\n date: number | null,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET stale_after = ?\n WHERE id = ? AND entity_id = ?`,\n [date, entryId, entityId],\n );\n }\n\n /** Set the producer / verifier actor string. Rare. */\n async setGeneratedBy(\n entryId: string,\n entityId: string,\n actor: string,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET generated_by = ?\n WHERE id = ? AND entity_id = ?`,\n [actor, entryId, entityId],\n );\n }\n\n // The same five methods exist for tasks, with `tasks` instead of `entries`.\n // Tasks are symmetric per spec §2.5.\n\n /** Atomic append, task variant — mirrors {@link writeOkfTrust}. */\n async writeOkfTrustTask(\n taskId: string,\n entityId: string,\n verified: OkfVerifiedEntry[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n if (verified.length === 0) return;\n const latest = latestVerified(verified, Date.now());\n const newEventsJson = JSON.stringify(verified);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET okf_verified = COALESCE(\n (SELECT json_group_array(json_object('by', s.by_val, 'at', s.at_val))\n FROM (\n SELECT json_extract(value, '$.by') AS by_val,\n json_extract(value, '$.at') AS at_val\n FROM json_each(okf_verified)\n UNION ALL\n SELECT json_extract(value, '$.by'),\n json_extract(value, '$.at')\n FROM json_each(?)\n ) AS s\n ORDER BY s.at_val),\n '[]'\n ),\n last_verified_by = ?,\n last_verified_at = ?\n WHERE id = ? AND entity_id = ?`,\n [newEventsJson, latest?.by ?? null, latest?.at ?? null, taskId, entityId],\n );\n }\n\n async writeOkfSourcesTask(\n taskId: string,\n entityId: string,\n sources: OkfSource[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n const json = formatSourcesJson(sources);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET okf_sources = ?\n WHERE id = ? AND entity_id = ?`,\n [json, taskId, entityId],\n );\n }\n\n async setLifecycleStatusTask(\n taskId: string,\n entityId: string,\n status: 'draft' | 'stable' | 'deprecated',\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET lifecycle_status = ?\n WHERE id = ? AND entity_id = ?`,\n [status, taskId, entityId],\n );\n }\n\n async setStaleAfterTask(\n taskId: string,\n entityId: string,\n date: number | null,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET stale_after = ?\n WHERE id = ? AND entity_id = ?`,\n [date, taskId, entityId],\n );\n }\n\n async setGeneratedByTask(\n taskId: string,\n entityId: string,\n actor: string,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET generated_by = ?\n WHERE id = ? AND entity_id = ?`,\n [actor, taskId, entityId],\n );\n }\n}\n","import type { SQLiteAdapter } from './types';\nimport type { WikiOutboxEvent } from './outbox/types';\nimport { setupDatabase } from './db/schema';\nimport { withSerializedTransactions } from './db/serializedAdapter';\nimport { MIGRATIONS, CURRENT_SCHEMA_VERSION } from './db/migrations';\nimport {\n WikiOptions,\n MemoryBundle,\n MemoryDump,\n WikiEvent,\n EntityStatus,\n ReadOptions,\n WikiSourceRefHashCollision,\n WikiDraftNotFound,\n} from './types';\nimport type { DraftPage } from './types';\nimport { EntryRepository } from './repositories/EntryRepository';\nimport { OutboxRepository } from './repositories/OutboxRepository';\nimport { SourceRefIndexRepository } from './repositories/SourceRefIndexRepository';\nimport { TaskRepository } from './repositories/TaskRepository';\nimport { EventRepository } from './repositories/EventRepository';\nimport { EdgeRepository } from './repositories/EdgeRepository';\nimport { MetadataRepository, entitySummaryMetaKey } from './repositories/MetadataRepository';\nimport { SearchService } from './services/SearchService';\nimport { JobManager } from './services/JobManager';\nimport { normalizeSourceRef, normalizeSourceHash, validateFact, validateTask, clip, chunkText } from './utils/pure';\nimport { IngestionService } from './services/IngestionService';\nimport { MaintenanceService } from './services/MaintenanceService';\nimport { ImportExportService } from './services/ImportExportService';\nimport { EmbeddingService } from './services/EmbeddingService';\nimport { RetrievalService } from './services/RetrievalService';\nimport { WriteService } from './services/WriteService';\nimport { PromptService } from './services/PromptService';\nimport { OntologyService } from './services/OntologyService';\nimport { GraphTraversalService } from './services/GraphTraversalService';\nimport { OkfTrustWritesRepository } from './db/okf-trust-writes';\nimport { validateManifest } from './utils/ontology';\nimport { DiagnosticBuffer } from './utils/diagnostics';\nimport type { OntologyManifest, OntologyMode, GraphTraversalOptions, GraphNeighborhood, OntologyBackfillResult, HealResult, IngestDocumentResult, ReembedResult } from './types';\n\nexport { WikiBusyError, WikiTransactionError, PrunePartialFailureError, HOOK_TIMEOUT_MARKER, WikiStrictOntologyViolation, WikiSourceRefHashCollision, WikiParseError, WikiIngestEmptyError, WikiGraphNodeOwnershipConflict } from './types';\n\nconst TABLE_PREFIX_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,30}_$/;\n\n/** Typed escape hatch for tests — not part of the supported consumer API. */\nexport interface WikiMemoryTestAccess {\n embeddingService: EmbeddingService;\n importExportService: ImportExportService;\n ingestionService: IngestionService;\n maintenanceService: MaintenanceService;\n retrievalService: RetrievalService;\n searchService: SearchService;\n writeService: WriteService;\n promptService: PromptService;\n graphTraversalService: GraphTraversalService;\n entryRepo: EntryRepository;\n sourceRefIndexRepo: SourceRefIndexRepository;\n metadataRepo: MetadataRepository;\n jobManager: JobManager;\n}\n\n/** `listDrafts` cursors are `${created_at}:${id}`; opaque to callers. */\nfunction decodeDraftCursor(cursor: unknown): { createdAt: number; id: string } {\n const sep = typeof cursor === 'string' ? cursor.indexOf(':') : -1;\n const createdAt = sep > 0 ? Number((cursor as string).slice(0, sep)) : Number.NaN;\n const id = sep > 0 ? (cursor as string).slice(sep + 1) : '';\n if (!Number.isSafeInteger(createdAt) || id.length === 0) {\n throw new TypeError('Invalid listDrafts cursor.');\n }\n return { createdAt, id };\n}\n\nexport class WikiMemory {\n /** Emits `__testAccess` console warning at most once per instance when NODE_ENV ≠ \"test\". */\n #testAccessNonTestEnvWarned = false;\n\n private db: SQLiteAdapter;\n private prefix: string;\n private options: WikiOptions;\n private entryRepo: EntryRepository;\n private outboxRepo: OutboxRepository;\n private sourceRefIndexRepo: SourceRefIndexRepository;\n private taskRepo: TaskRepository;\n private eventRepo: EventRepository;\n private edgeRepo: EdgeRepository;\n private metadataRepo: MetadataRepository;\n private embeddingService: EmbeddingService;\n private searchService: SearchService;\n private jobManager: JobManager;\n private ingestionService: IngestionService;\n private maintenanceService: MaintenanceService;\n private importExportService: ImportExportService;\n private retrievalService: RetrievalService;\n private writeService: WriteService;\n private promptService: PromptService;\n private ontologyService: OntologyService;\n private graphTraversalService: GraphTraversalService;\n private readonly okfTrustWrites: OkfTrustWritesRepository;\n\n constructor(db: SQLiteAdapter, options: WikiOptions) {\n // Serialize transactions on the single shared connection before the adapter\n // reaches any repository or service. See docs/superpowers/specs/2026-07-09-transaction-serialization-spec.md.\n this.db = withSerializedTransactions(db);\n this.options = options;\n this.prefix = options.config?.tablePrefix ?? 'llm_wiki_';\n if (!TABLE_PREFIX_PATTERN.test(this.prefix)) {\n throw new Error(\n `Invalid tablePrefix: ${JSON.stringify(this.prefix)}. ` +\n `Must match ${TABLE_PREFIX_PATTERN} (letter, then alphanumeric/underscore, ending in \"_\", max 32 chars total).`,\n );\n }\n this.outboxRepo = new OutboxRepository(this.db, this.prefix, !!options.config?.enableOutbox);\n this.entryRepo = new EntryRepository(this.db, this.prefix, this.outboxRepo);\n this.sourceRefIndexRepo = new SourceRefIndexRepository(this.db, this.prefix);\n this.taskRepo = new TaskRepository(this.db, this.prefix, this.outboxRepo);\n this.eventRepo = new EventRepository(this.db, this.prefix);\n this.edgeRepo = new EdgeRepository(this.db, this.prefix);\n this.metadataRepo = new MetadataRepository(this.db, this.prefix);\n this.ontologyService = new OntologyService(\n this.metadataRepo,\n this.edgeRepo,\n options.config?.ontology,\n );\n this.embeddingService = new EmbeddingService(this.db, this.options, this.entryRepo, this.metadataRepo);\n this.searchService = new SearchService(this.entryRepo);\n this.jobManager = new JobManager(this.prefix);\n this.promptService = new PromptService(options.config?.prompts);\n this.ingestionService = new IngestionService(\n this.db,\n this.prefix,\n this.options,\n this.entryRepo,\n this.sourceRefIndexRepo,\n this.metadataRepo,\n this.edgeRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n this.promptService,\n this.ontologyService,\n );\n this.maintenanceService = new MaintenanceService(\n this.db,\n this.prefix,\n this.options,\n this.entryRepo,\n this.sourceRefIndexRepo,\n this.taskRepo,\n this.eventRepo,\n this.metadataRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n this.promptService,\n this.ontologyService,\n );\n this.importExportService = new ImportExportService(\n this.db,\n this.entryRepo,\n this.taskRepo,\n this.eventRepo,\n this.edgeRepo,\n this.metadataRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n );\n this.retrievalService = new RetrievalService(\n this.options,\n this.entryRepo,\n this.taskRepo,\n this.eventRepo,\n this.metadataRepo,\n this.searchService,\n );\n this.writeService = new WriteService(\n this.db,\n this.options,\n this.entryRepo,\n this.eventRepo,\n this.metadataRepo,\n this.jobManager,\n this.maintenanceService,\n );\n this.graphTraversalService = new GraphTraversalService(\n this.edgeRepo,\n this.entryRepo,\n this.options.config ?? {},\n );\n this.okfTrustWrites = new OkfTrustWritesRepository(this.db, this.prefix);\n }\n\n /**\n * Explicit escape hatch for test suites: typed access to composed services for mocks/spies.\n * If `NODE_ENV` is not `\"test\"`, emits a single `console.warn` per instance (skipped when `process` is undefined).\n */\n get __testAccess(): WikiMemoryTestAccess {\n const processEnv = typeof globalThis !== 'undefined'\n ? (globalThis as any).process?.env\n : undefined;\n\n if (\n processEnv !== undefined &&\n processEnv.NODE_ENV !== 'test' &&\n !this.#testAccessNonTestEnvWarned\n ) {\n this.#testAccessNonTestEnvWarned = true;\n console.warn('Warning: WikiMemory.__testAccess is intended for tests (NODE_ENV !== \"test\").');\n }\n return {\n embeddingService: this.embeddingService,\n importExportService: this.importExportService,\n ingestionService: this.ingestionService,\n maintenanceService: this.maintenanceService,\n retrievalService: this.retrievalService,\n searchService: this.searchService,\n writeService: this.writeService,\n promptService: this.promptService,\n graphTraversalService: this.graphTraversalService,\n entryRepo: this.entryRepo,\n sourceRefIndexRepo: this.sourceRefIndexRepo,\n metadataRepo: this.metadataRepo,\n jobManager: this.jobManager,\n };\n }\n\n async setup() {\n const entriesExistedBeforeSetup = await this.metadataRepo.tableExists(`${this.prefix}entries`);\n\n await setupDatabase(this.db, this.prefix);\n\n let currentVersion: number;\n\n if (!entriesExistedBeforeSetup) {\n await this.metadataRepo.setMeta('schema_version', String(CURRENT_SCHEMA_VERSION), this.db);\n currentVersion = CURRENT_SCHEMA_VERSION;\n } else {\n const schemaVersionValue = await this.metadataRepo.getMeta('schema_version');\n\n if (schemaVersionValue) {\n currentVersion = parseInt(schemaVersionValue, 10);\n if (!Number.isFinite(currentVersion)) currentVersion = 0;\n } else {\n const ftsDdl = await this.metadataRepo.getTableDdl(`${this.prefix}entries_fts`);\n const hasPorter = /tokenize\\s*=\\s*['\"]porter\\s+unicode61['\"]/i.test(ftsDdl ?? '');\n currentVersion = hasPorter ? 1 : 0;\n }\n }\n\n for (const migration of MIGRATIONS) {\n if (migration.version > currentVersion) {\n await migration.run(this.db, this.prefix);\n await this.metadataRepo.setMeta('schema_version', String(migration.version), this.db);\n currentVersion = migration.version;\n }\n }\n\n if (entriesExistedBeforeSetup) {\n const schemaVersionCheck = await this.metadataRepo.getMeta('schema_version');\n if (!schemaVersionCheck) {\n await this.metadataRepo.setMeta('schema_version', String(currentVersion), this.db);\n }\n }\n\n if (entriesExistedBeforeSetup) {\n await this.importExportService.assertNoLegacySourceTypes();\n }\n\n const rows = await this.entryRepo.findRowsForSourceRefMigration();\n await this.db.withTransactionAsync(async (tx) => {\n for (const row of rows) {\n const normalized = normalizeSourceRef(row.source_ref);\n if (normalized !== row.source_ref) {\n await this.entryRepo.updateSourceRefByRowid(row.rowid, normalized, tx);\n }\n }\n });\n\n await this.searchService.sync();\n }\n\n async hasChanged(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n ): Promise<boolean>;\n /**\n * Batched overload.\n *\n * `duplicateOf`, when present, is the canonical stored DIFFERENT `source_ref`\n * holding the same hash — never the incoming ref itself (the incoming ref is\n * excluded from the canonical-sort set so a self-reference is impossible).\n * `duplicateOf` reflects the *DB-side* normalized spelling; `sourceRef` in\n * each result echoes the raw caller value. Hosts should not compare these\n * two fields directly to infer canonical status.\n */\n async hasChanged(\n entityId: string,\n entries: Array<{ sourceRef: string; sourceHash: string }>,\n ): Promise<Array<{ sourceRef: string; changed: boolean; duplicateOf?: string }>>;\n async hasChanged(\n entityId: string,\n sourceRefOrEntries: string | Array<{ sourceRef: string; sourceHash: string }>,\n sourceHashArg?: string,\n ): Promise<boolean | Array<{ sourceRef: string; changed: boolean; duplicateOf?: string }>> {\n // Single-doc path: delegate to existing semantics.\n if (typeof sourceRefOrEntries === 'string') {\n const sourceRef = normalizeSourceRef(sourceRefOrEntries);\n if (!sourceRef) {\n throw new Error(`Invalid sourceRef: ${JSON.stringify(sourceRefOrEntries)}`);\n }\n const sourceHash = normalizeSourceHash(sourceHashArg!);\n if (!sourceHash) {\n throw new Error('Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)');\n }\n const storedHash = await this.entryRepo.findLatestSourceHash(entityId, sourceRef);\n if (storedHash === null) return true;\n const normalizedStoredHash = normalizeSourceHash(storedHash);\n return normalizedStoredHash !== sourceHash;\n }\n\n // Batched path: empty input -> empty result, zero SQL calls.\n const entries = sourceRefOrEntries;\n if (entries.length === 0) return [];\n\n // Normalize all inputs (validation up front). Preserve the raw ref so the\n // result echoes the caller's spelling (DB refs are normalized on setup,\n // but the caller hasn't seen that normalization yet).\n const normalized = entries.map(e => {\n const r = normalizeSourceRef(e.sourceRef);\n if (!r) throw new Error(`Invalid sourceRef: ${JSON.stringify(e.sourceRef)}`);\n const h = normalizeSourceHash(e.sourceHash);\n if (!h) throw new Error('Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)');\n return { rawSourceRef: e.sourceRef, sourceRef: r, sourceHash: h };\n });\n\n // 1 + H SQL queries: one batched latest-hash lookup, plus one source_ref_index\n // lookup per distinct input hash. Lookups are issued in parallel — the bound\n // is the SQL-query count, not the await count.\n const latestHashes = await this.entryRepo.findLatestSourceHashes(entityId, normalized.map(e => e.sourceRef));\n\n const distinctHashes = Array.from(new Set(normalized.map(e => e.sourceHash)));\n const dupRefs = await Promise.all(\n distinctHashes.map(h => this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, h)),\n );\n const dupMap = new Map<string, string | null>(); // hash -> canonical sourceRef (or null)\n for (let i = 0; i < distinctHashes.length; i++) {\n dupMap.set(distinctHashes[i], dupRefs[i]);\n }\n\n return normalized.map(e => {\n const stored = latestHashes.get(e.sourceRef);\n const changed = stored === undefined || stored === null || normalizeSourceHash(stored) !== e.sourceHash;\n const canonical = dupMap.get(e.sourceHash) ?? null;\n if (canonical === null || canonical === e.sourceRef) {\n return { sourceRef: e.rawSourceRef, changed };\n }\n // Canonical: the single sourceRef from source_ref_index that holds\n // this hash, if any. Because the partial UNIQUE index allows at most\n // one live row per (entity, hash), the canonical cannot be the\n // incoming ref (it would be the same sourceRef) — we filter that out\n // above. Non-ASCII sourceRefs are still compared by the DB's\n // source_ref index, so the canonical matches the DB ordering.\n return { sourceRef: e.rawSourceRef, changed, duplicateOf: canonical };\n });\n }\n\n /**\n * Returns the live source_refs for an entity, one row per ref, with the most\n * recently-updated live `source_hash` and a live fact count. Refs are sorted\n * `COLLATE BINARY` (no locale dependency). Used by hosts to reconcile stored\n * state against a live source, or audit duplicate-hash collisions via\n * `findSourceRefsByHash`.\n */\n async listSourceRefs(entityId: string): Promise<Array<{\n sourceRef: string;\n sourceHash: string | null;\n factCount: number;\n lastIngestedAt: number;\n }>> {\n return this.entryRepo.listSourceRefs(entityId);\n }\n\n /**\n * Returns the live source_refs for an entity that hold the given source_hash.\n * With v9, source_ref_index is the source of truth for the sourceRef-level\n * TOCTOU-race invariant: at most one sourceRef can hold a given\n * (entity_id, source_hash). The result is either a single-element array\n * (one canonical ref) or empty (no live ref holds the hash). Returned as\n * an array to preserve the existing public-API shape used by hosts\n * auditing duplicate-content collisions.\n */\n async findSourceRefsByHash(entityId: string, sourceHash: string): Promise<string[]> {\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n return canonical === null ? [] : [canonical];\n }\n\n /**\n * Returns the set of `entity_id` values with at least one row in this\n * database, INCLUDING entities whose only remaining rows are soft-deleted\n * — sorted ascending `entity_id COLLATE BINARY`. Empty array when the\n * database has no entities.\n *\n * The deliberate inclusion of soft-deleted-only entities closes the\n * decommissioned-scope leak: a scoped namespace whose documents have all\n * been forgotten or superseded must still appear so host maintenance\n * sweeps (`runLibrarian`, `runHeal`, `runOntologyBackfill`, `runPrune`)\n * can visit it and reap the soft-deleted rows.\n *\n * Read-only. Never acquires a lock. Never opens a transaction. Propagates\n * underlying read errors.\n *\n * @param options.prefix - Optional string filter applied as\n * `id.startsWith(prefix)`. O(n) over distinct ids because the\n * `(entity_id, source_ref)` index is not seekable on `entity_id`-only\n * prefix. Empty-string prefix matches every id.\n *\n * Note: this widens the coverage of `exportDump` (which delegates to\n * `MetadataRepository.getDistinctEntityIds`); exported dumps now include\n * orphaned entities. This is a deliberate widening for backup/migration\n * coverage, not a breaking change to `exportDump`'s return shape.\n */\n async listEntityIds(options?: { prefix?: string }): Promise<string[]> {\n const ids = await this.metadataRepo.getDistinctEntityIds();\n if (options?.prefix === undefined) return ids;\n return ids.filter(id => id.startsWith(options.prefix!));\n }\n\n async runPrune(\n entityId: string,\n options?: {\n retainSoftDeletedFor?: number | null;\n retainEventsFor?: number | null;\n vacuum?: boolean;\n },\n ): Promise<{ entries: number; tasks: number; events: number }> {\n return this.maintenanceService.runPrune(entityId, options);\n }\n\n async read(entityId: string | string[], query: string, options?: ReadOptions): Promise<MemoryBundle> {\n return this.retrievalService.read(entityId, query, options);\n }\n\n async traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood> {\n return this.graphTraversalService.traverseGraph(entityId, options);\n }\n\n async getMemoryBundle(entityId: string): Promise<MemoryBundle> {\n return this.importExportService.getFullBundle(entityId, { maxEvents: 10 });\n }\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n return this.writeService.write(entityId, event);\n }\n\n /**\n * @param options.promptOverride - Applies only to this manual call. Does NOT affect\n * WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,\n * set `options.config.prompts.librarianSystemPrompt` at WikiMemory construction time.\n */\n async runLibrarian(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n return this.maintenanceService.runLibrarian(entityId, options);\n }\n\n /**\n * Reviews stored facts with the LLM: removes orphans, downgrades stale\n * inferences, synthesizes corrections.\n *\n * Bounded per call: covers at most `batchSize` candidates (default 25), so\n * one call no longer sweeps the whole entity. Hosts own the cadence; loop\n * `while (result.remaining > 0)` for convergence.\n *\n * `remaining === 0` means \"every mutable fact is inside the 7-day recheck\n * cooldown\", not \"there is no more work\" — heal's candidate set is the live\n * mutable corpus, not a draining backlog, so it climbs back as the cooldown\n * lapses and as new facts are written. Do not write a loop expecting a drain.\n *\n * @param options.promptOverride - Applies only to this manual call. Does NOT affect\n * WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,\n * set `options.config.prompts.healSystemPrompt` at WikiMemory construction time.\n * @param options.batchSize - Candidates per run (default 25) for providers with\n * tighter context limits.\n */\n async runHeal(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<HealResult> {\n return this.maintenanceService.runHeal(entityId, options);\n }\n\n /**\n * Types already-persisted untyped facts (okf_type IS NULL) in place via one\n * librarian-style LLM call. Strictly additive: never creates, deletes, or\n * rewrites facts; never overwrites an existing okf_type. Free when there is\n * nothing to do (ontology off, or zero eligible untyped facts).\n *\n * Hosts own the trigger cadence (e.g. after each sync); loop `while\n * result.remaining > 0` for convergence. Throws WikiBusyError when another\n * backfill (or conflicting maintenance op) is running for the entity.\n *\n * @param options.promptOverride - Applies only to this call. For persistent\n * customization set `options.config.prompts.ontologyBackfillSystemPrompt`.\n * @param options.batchSize - Facts per run (default 25) for providers with\n * tighter context limits.\n */\n async runOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<OntologyBackfillResult> {\n return this.maintenanceService.runOntologyBackfill(entityId, options);\n }\n\n async runReembed(\n entityId?: string,\n opts?: { force?: boolean; skipExisting?: boolean },\n ): Promise<ReembedResult> {\n return this.maintenanceService.runReembed(entityId, opts);\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n return this.jobManager.getEntityStatus(entityId);\n }\n\n subscribeEntityStatus(\n entityId: string,\n callback: (status: EntityStatus) => void,\n ): () => void {\n return this.jobManager.subscribeEntityStatus(entityId, callback);\n }\n\n clearVectorCache(): void {\n this.searchService.evictCache();\n }\n\n async exportDump(entityIds?: string[]): Promise<MemoryDump> {\n return this.importExportService.exportDump(entityIds);\n }\n\n /** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */\n async getEntitySummary(entityId: string): Promise<string | null> {\n return this.metadataRepo.getMeta(entitySummaryMetaKey(entityId));\n }\n\n async importDump(dump: MemoryDump, opts?: { merge?: boolean }): Promise<void> {\n return this.importExportService.importDump(dump, opts);\n }\n\n async forget(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n opts?: { dryRun?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\n return this.maintenanceService.forget(entityId, params, opts);\n }\n\n /**\n * Full and partial ingestion both reject foreign-owned generated fact IDs with\n * `WikiGraphNodeOwnershipConflict`. Such collisions are unexpected. Ingestion\n * may already have persisted ontology or other state before rejection; unlike\n * direct graph preflight, it relies on transaction rollback for atomicity.\n *\n * @param params.promptOverride - Overrides the system prompt for this ingest call only.\n * For persistent customization, set `options.config.prompts.ingestSystemPrompt` at\n * WikiMemory construction time.\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 opts?: { onDuplicateHash?: 'ingest' | 'skip' | 'throw' },\n ): Promise<IngestDocumentResult> {\n return this.ingestionService.ingestDocument(entityId, params, opts);\n }\n\n /**\n * Deterministic write path into the graph. Accepts caller-supplied\n * `(nodes, edges)` and writes them under `(sourceRef, sourceHash)`\n * semantics identical to `ingestDocument`, minus the LLM extraction step.\n *\n * MUST be called from inside an open `db.withTransactionAsync` callback —\n * the third argument is the caller's `tx`. The method does not open a\n * nested transaction, does not acquire any lock, and does not perform\n * post-commit work (search sync, embedding, cache eviction). Hosts that\n * want embeddings synced should drive the existing maintenance sweep\n * (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,\n * scoped via `listEntityIds`).\n *\n * Contract (full pre-flight validation lives inside\n * `IngestionService.upsertGraphCore`, which this method delegates to):\n * - C2: no-op when `(entityId, sourceHash)` is already mapped to\n * `params.sourceRef`; throws `WikiSourceRefHashCollision` if mapped to\n * a different `sourceRef`.\n * - C3: edges with dangling `targetId` are stored verbatim (no FK, no\n * resolution).\n * - C4: under persisted ontology mode `'strict'`, an out-of-manifest node\n * or edge `type` throws `WikiStrictOntologyViolation` (pre-flight,\n * all-or-nothing — NONE written on failure).\n *\n * Entry IDs share one database-wide namespace. Existing rows, including\n * soft-deleted rows, reserve their IDs for their entity; same-entity updates\n * and resurrection remain supported. Hosts authenticate callers and select\n * the authorized entity ID; entity-qualified IDs are optional, not required.\n * After the live-only C2 probe above, a foreign node ID throws the fixed,\n * privacy-preserving `WikiGraphNodeOwnershipConflict` before persistent writes\n * (including seed manifests). Deleted source mappings do not trigger C2.\n *\n * Propagate later failures to roll back the host transaction. In particular,\n * foreign edge-ID collisions remain late bare `Error`s: the foreign edge is\n * not overwritten, but catching and committing can retain earlier writes.\n * This method neither commits nor rolls back the caller's transaction.\n *\n * @returns Counts: nodesWritten (validated nodes persisted), edgesWritten\n * (manifest-valid edges persisted), superseded (prior facts soft-deleted\n * plus prior source-ref edges hard-deleted).\n */\n async upsertGraph(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n nodes: readonly { id: string; type: string; title: string; body?: string }[];\n edges: readonly { type: string; sourceId: string; targetId: string; id?: string }[];\n },\n adapter: SQLiteAdapter,\n ): Promise<{ nodesWritten: number; edgesWritten: number; superseded: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = normalizeSourceHash(params.sourceHash);\n if (!sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n // C2 probe — runs inside the caller's tx so it sees the in-flight state.\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash, adapter);\n if (canonical !== null && canonical === sourceRef) {\n return { nodesWritten: 0, edgesWritten: 0, superseded: 0 };\n }\n if (canonical !== null && canonical !== sourceRef) {\n throw new WikiSourceRefHashCollision({\n entityId,\n sourceHash,\n existingSourceRef: canonical,\n attemptedSourceRef: sourceRef,\n });\n }\n\n // Delegate to upsertGraphCore for steps a–j (manifest read, validation,\n // supersession, writes, returns counts). No opts.strict override — let\n // the persisted ontology mode drive strictness per the spec.\n // The host owns this transaction and core never sees its commit, so\n // diagnostics are delivered when upsertGraph resolves (spec §4.2.4).\n // Hosts that roll back should disregard them.\n const diagBuffer = new DiagnosticBuffer();\n const result = await this.ingestionService.upsertGraphCore(\n entityId,\n { sourceRef, sourceHash, nodes: params.nodes, edges: params.edges },\n adapter,\n { diag: { buffer: diagBuffer, operation: 'upsertGraph' } },\n );\n diagBuffer.flush(this.options);\n return result;\n }\n\n /**\n * Returns up to `limit` unprocessed outbox events, oldest first.\n * Works regardless of enableOutbox value — allows draining after disabling.\n */\n async getUnprocessedOutboxEvents(limit = 100): Promise<WikiOutboxEvent[]> {\n if (Number.isFinite(limit) && limit <= 0) return [];\n const safeLimit = Number.isFinite(limit) && limit >= 1 ? Math.trunc(limit) : 100;\n const rows = await this.outboxRepo.fetchPending(safeLimit);\n return rows.map(row => {\n let payload: unknown = null;\n try {\n payload = JSON.parse(row.payload);\n } catch {\n // corrupted row — surface null payload rather than poisoning the batch\n }\n return { ...row, payload } as WikiOutboxEvent;\n });\n }\n\n /**\n * Deletes the given event IDs from the outbox table.\n * Call after successfully committing events to the external system.\n */\n async markOutboxEventsProcessed(eventIds: string[]): Promise<void> {\n await this.outboxRepo.acknowledge(eventIds);\n }\n\n /**\n * Returns the effective ontology mode and manifest for an entity.\n * Resolution order: persisted DB row → `WikiConfig.ontology.seedManifests[entityId]` → `null`.\n */\n async getOntologyManifest(entityId: string): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n } | null> {\n const row = await this.metadataRepo.getManifest(entityId);\n if (row) return { mode: this.ontologyService.resolveMode(row.mode), manifest: row.manifest };\n const seed = this.options.config?.ontology?.seedManifests?.[entityId];\n if (seed) {\n return {\n mode: this.ontologyService.resolveMode(seed.mode),\n manifest: seed.manifest,\n };\n }\n return null;\n }\n\n /**\n * Seeds or replaces an entity's ontology manifest and optional mode override.\n * Validates manifest invariants (unique type slugs, edge endpoints reference node types).\n * Invalidates the in-memory ontology cache for this entity.\n *\n * Delegates to `setOntologyManifests` so there is a single write path. The\n * observable contract is unchanged: same upsert semantics, same cache\n * invalidation, same `void` result.\n */\n async setOntologyManifest(\n entityId: string,\n manifest: OntologyManifest,\n options?: { mode?: OntologyMode },\n ): Promise<void> {\n await this.setOntologyManifests([{ entityId, manifest, mode: options?.mode }]);\n }\n\n /**\n * Write several entities' ontology manifests in a single transaction.\n *\n * All succeed or none do. The transaction is opened on this instance's\n * serialized adapter — callers pass data, never a transaction handle, because\n * a consumer holds the unwrapped adapter and a transaction opened on it would\n * bypass the serialization mutex applied in the constructor.\n *\n * Returns which entities were written. `skipped` is only ever non-empty under\n * `opts.ifAbsent`.\n *\n * Sharp edge: `ifAbsent` checks for a PERSISTED row, not for an effective\n * manifest. An entity whose manifest currently comes from\n * `WikiConfig.ontology.seedManifests` has no row until the seed is\n * materialized on first access that supplies a transaction (in practice, an\n * ingest). Until then `ifAbsent` treats the entity as absent, writes the new\n * manifest over the configured seed, and reports it in `written`; the same\n * call after the seed has been materialized reports it in `skipped`. See the\n * `ifAbsent` notes in the package README.\n */\n async setOntologyManifests(\n entries: Array<{\n entityId: string;\n manifest: OntologyManifest;\n mode?: OntologyMode;\n }>,\n opts?: { ifAbsent?: boolean },\n ): Promise<{ written: string[]; skipped: string[] }> {\n // Nothing to do — and deliberately no transaction, so an empty batch never\n // takes the serialization mutex.\n if (entries.length === 0) return { written: [], skipped: [] };\n\n // Two entries naming one entity express ambiguous intent. Applying the last\n // one silently would hide a caller bug whose symptom — a manifest that is\n // not the one the caller believed it wrote — surfaces far from its cause.\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.entityId)) {\n throw new Error(`Duplicate entityId in batch: ${entry.entityId}`);\n }\n seen.add(entry.entityId);\n }\n\n // Validate every manifest BEFORE opening the transaction, so a doomed batch\n // never reaches the database and never takes the mutex. `setManifest`\n // validates again inside the transaction; that is the invariant protecting\n // every other repository caller, and is not redundant with this gate.\n for (const entry of entries) {\n validateManifest(entry.manifest);\n }\n\n const written: string[] = [];\n const skipped: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n for (const entry of entries) {\n const mode = entry.mode ?? this.ontologyService.resolveMode();\n const wrote = await this.metadataRepo.setManifest(\n entry.entityId,\n { mode, manifest: entry.manifest },\n tx,\n { ifAbsent: opts?.ifAbsent === true },\n );\n (wrote ? written : skipped).push(entry.entityId);\n }\n });\n\n // After a successful commit, and for EVERY entry rather than just the\n // written ones: under `ifAbsent` a skipped entry means another writer won\n // the race, so this instance's cached copy may be stale and dropping it is\n // more correct than keeping it. A failed transaction throws above and never\n // reaches this loop, which is fine — a rolled-back batch changed nothing,\n // so the cache is still consistent with the database. Invalidating is cheap\n // either way: it only drops a cached copy, and the next read reloads from\n // the database.\n for (const entry of entries) {\n this.ontologyService.invalidateCache(entry.entityId);\n }\n\n return { written, skipped };\n }\n\n /** Append a verification event to a fact. Does NOT touch `updated_at`. */\n async writeOkfTrust(entryId: string, entityId: string, verified: { by: string; at: string }[]): Promise<void> {\n return this.okfTrustWrites.writeOkfTrust(entryId, entityId, verified);\n }\n\n /** Replace a fact's source list. Does NOT touch `updated_at`. */\n async writeOkfSources(entryId: string, entityId: string, sources: Array<{ resource: string; [k: string]: unknown }>): Promise<void> {\n return this.okfTrustWrites.writeOkfSources(entryId, entityId, sources as any);\n }\n\n /** Set a fact's OKF v0.2 lifecycle status. Does NOT touch `updated_at`. */\n async setLifecycleStatus(entryId: string, entityId: string, status: 'draft' | 'stable' | 'deprecated'): Promise<void> {\n return this.okfTrustWrites.setLifecycleStatus(entryId, entityId, status);\n }\n\n /**\n * Live draft facts for one entity, newest first (spec §5.2). Default page\n * size 50, clamped to [1, 500]. Pass `nextCursor` back unchanged for the next page.\n */\n async listDrafts(entityId: string, options?: { limit?: number; cursor?: string }): Promise<DraftPage> {\n const rawLimit = options?.limit;\n const limit = typeof rawLimit === 'number' && Number.isFinite(rawLimit)\n ? Math.min(500, Math.max(1, Math.floor(rawLimit)))\n : 50;\n const after = options?.cursor === undefined ? null : decodeDraftCursor(options.cursor);\n const rows = await this.entryRepo.listDraftsByEntityId(entityId, limit + 1, after);\n const facts = rows.slice(0, limit);\n const last = facts[facts.length - 1];\n return {\n facts,\n nextCursor: rows.length > limit && last ? `${last.created_at}:${last.id}` : null,\n };\n }\n\n /**\n * Promote a draft to `stable` and record who reviewed it, atomically\n * (spec §5.2). Metadata writes only: `updated_at` is not bumped and no\n * outbox event is pushed. Pass `by: 'human:<id>'` so `trustTier` becomes\n * `'human-reviewed'`.\n *\n * @throws WikiDraftNotFound when no live draft with that id exists for the entity.\n */\n async promoteDraft(entryId: string, entityId: string, reviewer: { by: string }): Promise<void> {\n const by = reviewer?.by;\n if (typeof by !== 'string' || by.trim().length === 0) {\n throw new TypeError('promoteDraft requires reviewer.by to be a non-empty string.');\n }\n await this.db.withTransactionAsync(async (tx) => {\n if (!(await this.entryRepo.isLiveDraft(entryId, entityId, tx))) {\n throw new WikiDraftNotFound();\n }\n await this.okfTrustWrites.setLifecycleStatus(entryId, entityId, 'stable', tx);\n await this.okfTrustWrites.writeOkfTrust(entryId, entityId, [{ by, at: new Date().toISOString() }], tx);\n });\n }\n\n /** Set a fact's stale_after (epoch ms) or clear it. Does NOT touch `updated_at`. */\n async setStaleAfter(entryId: string, entityId: string, date: number | null): Promise<void> {\n return this.okfTrustWrites.setStaleAfter(entryId, entityId, date);\n }\n\n /** Set a fact's generated_by actor string. Does NOT touch `updated_at`. */\n async setGeneratedBy(entryId: string, entityId: string, actor: string): Promise<void> {\n return this.okfTrustWrites.setGeneratedBy(entryId, entityId, actor);\n }\n\n /** Task variants of the same five DAO methods. Symmetric per spec §2.5. */\n async writeOkfTrustTask(taskId: string, entityId: string, verified: { by: string; at: string }[]): Promise<void> {\n return this.okfTrustWrites.writeOkfTrustTask(taskId, entityId, verified);\n }\n async writeOkfSourcesTask(taskId: string, entityId: string, sources: Array<{ resource: string; [k: string]: unknown }>): Promise<void> {\n return this.okfTrustWrites.writeOkfSourcesTask(taskId, entityId, sources as any);\n }\n async setLifecycleStatusTask(taskId: string, entityId: string, status: 'draft' | 'stable' | 'deprecated'): Promise<void> {\n return this.okfTrustWrites.setLifecycleStatusTask(taskId, entityId, status);\n }\n async setStaleAfterTask(taskId: string, entityId: string, date: number | null): Promise<void> {\n return this.okfTrustWrites.setStaleAfterTask(taskId, entityId, date);\n }\n async setGeneratedByTask(taskId: string, entityId: string, actor: string): Promise<void> {\n return this.okfTrustWrites.setGeneratedByTask(taskId, entityId, actor);\n }\n}\n\nexport const __testables = { validateFact, validateTask, clip, chunkText };\n","import type { MemoryBundle, WikiFact, WikiTask, WikiEvent, FormatContextOptions } from '../types';\n\nfunction validateMaxOption(value: number, name: string): void {\n if (!isFinite(value) || value < 0) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number`);\n }\n}\n\nconst CONFIDENCE_WEIGHT: Record<string, number> = {\n certain: 1.0,\n inferred: 0.6,\n tentative: 0.3,\n};\n\nfunction scoreFactFor(\n fact: WikiFact,\n weights: Required<NonNullable<FormatContextOptions['factWeights']>>,\n now: number\n): number {\n const confW = CONFIDENCE_WEIGHT[fact.confidence] ?? 0.3;\n const ageDays = (now - fact.updated_at) / 86400000;\n const recencyDecay = Math.exp(-ageDays / 30);\n return (\n confW * weights.confidence +\n Math.log(1 + fact.access_count) * weights.accessCount +\n recencyDecay * weights.recency\n );\n}\n\nfunction renderFactMarkdown(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `- **${fact.title}**${confPart}${tagPart}${sourcePart}${scorePart}\\n ${fact.body.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderFactPlain(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `${fact.title}${confPart}${tagPart}${sourcePart}${scorePart}: ${fact.body}`;\n}\n\nfunction renderTaskMarkdown(task: WikiTask): string {\n return `- [P${task.priority}] ${task.description.replace(/\\n/g, '\\n ')} (${task.status})`;\n}\n\nfunction renderTaskPlain(task: WikiTask): string {\n return `[P${task.priority}] ${task.description} (${task.status})`;\n}\n\nfunction renderEventMarkdown(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `- [${event.event_type} @ ${ts}] ${event.summary.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderEventPlain(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `[${event.event_type} @ ${ts}] ${event.summary}`;\n}\n\nexport function formatContext(\n bundle: MemoryBundle,\n options?: FormatContextOptions\n): string {\n const opts: Required<FormatContextOptions> = {\n format: options?.format ?? 'markdown',\n maxFacts: options?.maxFacts ?? 10,\n maxTasks: options?.maxTasks ?? 10,\n maxEvents: options?.maxEvents ?? 10,\n includeConfidence: options?.includeConfidence ?? true,\n includeTags: options?.includeTags ?? true,\n includeEntityIds: options?.includeEntityIds ?? false,\n includeFactScores: options?.includeFactScores ?? false,\n factWeights: {\n confidence: options?.factWeights?.confidence ?? 1.0,\n accessCount: options?.factWeights?.accessCount ?? 0.3,\n recency: options?.factWeights?.recency ?? 0.5,\n },\n };\n\n validateMaxOption(opts.maxFacts, 'maxFacts');\n validateMaxOption(opts.maxTasks, 'maxTasks');\n validateMaxOption(opts.maxEvents, 'maxEvents');\n\n const weights = opts.factWeights as Required<NonNullable<FormatContextOptions['factWeights']>>;\n\n const now = Date.now();\n const sortedFacts = bundle.factScores\n ? [...bundle.facts].slice(0, opts.maxFacts)\n : [...bundle.facts]\n .sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now))\n .slice(0, opts.maxFacts);\n\n const sortedTasks = [...bundle.tasks]\n .sort((a, b) => b.priority - a.priority || a.created_at - b.created_at)\n .slice(0, opts.maxTasks);\n\n const sortedEvents = [...bundle.events]\n .sort((a, b) => b.created_at - a.created_at)\n .slice(0, opts.maxEvents);\n\n if (sortedFacts.length === 0 && sortedTasks.length === 0 && sortedEvents.length === 0) {\n return '';\n }\n\n const isMarkdown = opts.format === 'markdown';\n const lines: string[] = [];\n\n if (isMarkdown) {\n lines.push('## Memory');\n\n if (sortedFacts.length > 0) {\n lines.push('');\n lines.push('### Known Facts');\n for (const fact of sortedFacts) {\n lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n\n if (sortedTasks.length > 0) {\n lines.push('');\n lines.push('### Open Tasks');\n for (const task of sortedTasks) {\n lines.push(renderTaskMarkdown(task));\n }\n }\n\n if (sortedEvents.length > 0) {\n lines.push('');\n lines.push('### Recent Events');\n for (const event of sortedEvents) {\n lines.push(renderEventMarkdown(event));\n }\n }\n } else {\n if (sortedFacts.length > 0) {\n lines.push('KNOWN FACTS:');\n for (const fact of sortedFacts) {\n lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n if (sortedTasks.length > 0) {\n lines.push('OPEN TASKS:');\n for (const task of sortedTasks) {\n lines.push(renderTaskPlain(task));\n }\n }\n if (sortedEvents.length > 0) {\n lines.push('RECENT EVENTS:');\n for (const event of sortedEvents) {\n lines.push(renderEventPlain(event));\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import type { GraphNeighborhood, WikiEdge } from '../types';\n\n/**\n * Pure presenter — dense text serialization of a GraphNeighborhood for LLM prompt\n * injection. Deterministic: same input always produces byte-identical output\n * (matters for prompt caching).\n */\nexport function formatGraphContext(neighborhood: GraphNeighborhood): string {\n const { nodes, edges } = neighborhood;\n if (nodes.length === 0) return '';\n\n const nodeById = new Map(nodes.map((n) => [n.id, n]));\n const nodeIndex = new Map(nodes.map((n, i) => [n.id, i]));\n const lines: string[] = [];\n\n for (const node of nodes) {\n lines.push(`[${node.okf_type ?? 'fact'}] ${node.title} (ID: ${node.id})`);\n\n const outbound = edgesByDirection(edges, node.id, 'source_id', nodeById, nodeIndex);\n const inbound = edgesByDirection(edges, node.id, 'target_id', nodeById, nodeIndex);\n\n for (const { edge, other } of outbound) {\n lines.push(` -[${edge.edge_type}]-> [${other.okf_type ?? 'fact'}] ${other.title}`);\n }\n for (const { edge, other } of inbound) {\n lines.push(` <-[${edge.edge_type}]- [${other.okf_type ?? 'fact'}] ${other.title}`);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction edgesByDirection(\n edges: WikiEdge[],\n nodeId: string,\n endpoint: 'source_id' | 'target_id',\n nodeById: Map<string, GraphNeighborhood['nodes'][number]>,\n nodeIndex: Map<string, number>,\n) {\n const otherEndpoint = endpoint === 'source_id' ? 'target_id' : 'source_id';\n return edges\n .filter((e) => e[endpoint] === nodeId)\n .filter((e) => {\n const otherId = e[otherEndpoint];\n const selfIdx = nodeIndex.get(nodeId)!;\n const otherIdx = nodeIndex.get(otherId);\n return otherIdx !== undefined && selfIdx < otherIdx;\n })\n .map((edge) => ({ edge, other: nodeById.get(edge[otherEndpoint])! }))\n .sort(\n (a, b) =>\n a.edge.edge_type.localeCompare(b.edge.edge_type) ||\n a.other.title.localeCompare(b.other.title) ||\n a.other.id.localeCompare(b.other.id) ||\n a.edge.id.localeCompare(b.edge.id),\n );\n}\n","function shortHash(value: string): string {\n let h1 = 5381;\n let h2 = 52711;\n for (let i = 0; i < value.length; i += 1) {\n const c = value.charCodeAt(i);\n h1 = Math.imul(h1, 33) ^ c;\n h2 = Math.imul(h2, 31) ^ c;\n }\n return (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0');\n}\n\nconst OKF_RESERVED_CONCEPT_NAMES = new Set(['index', 'log']);\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n 'con',\n 'prn',\n 'aux',\n 'nul',\n 'com1',\n 'com2',\n 'com3',\n 'com4',\n 'com5',\n 'com6',\n 'com7',\n 'com8',\n 'com9',\n 'lpt1',\n 'lpt2',\n 'lpt3',\n 'lpt4',\n 'lpt5',\n 'lpt6',\n 'lpt7',\n 'lpt8',\n 'lpt9',\n]);\n\nfunction isWindowsReservedName(name: string): boolean {\n const base = name.split('.')[0];\n return WINDOWS_RESERVED_NAMES.has(base.toLowerCase());\n}\n\nexport function sanitizeForFilename(value: string): string {\n const normalized = value.normalize('NFKC');\n const sanitized = normalized\n .replace(/[^A-Za-z0-9._-]+/g, '_')\n .replace(/^\\.+/, '_')\n .replace(/_+/g, '_')\n .replace(/^[_-]+|[_-]+$/g, '');\n\n // Enforce a max base-name length so the final filename stays within typical\n // filesystem limits (~255 bytes). Reserve ~20 chars for `-<16hexchars>`.\n const MAX_BASE = 200;\n const trimmed = sanitized.length > MAX_BASE ? sanitized.slice(0, MAX_BASE) : sanitized;\n\n let baseName = trimmed && trimmed !== '.' && trimmed !== '..' ? trimmed : 'entity';\n\n // Windows disallows trailing dots and spaces in filenames.\n const withoutTrailingDotSpace = baseName.replace(/[. ]+$/, '');\n const hadTrailingDotSpace = withoutTrailingDotSpace !== baseName;\n if (hadTrailingDotSpace) {\n baseName = withoutTrailingDotSpace || 'entity';\n }\n\n const windowsReserved = isWindowsReservedName(baseName);\n const needsSuffix =\n baseName !== value || sanitized.length > MAX_BASE || hadTrailingDotSpace || windowsReserved;\n\n if (!needsSuffix) return baseName;\n\n const suffix = `-${shortHash(value)}`;\n return `${baseName}${suffix}`;\n}\n\n/** Sanitize a fact/task id for use as a concept filename (without .md). */\nexport function sanitizeConceptId(id: string): string {\n const sanitized = sanitizeForFilename(id);\n if (OKF_RESERVED_CONCEPT_NAMES.has(sanitized.toLowerCase())) {\n return `${sanitized}-${shortHash(id)}`;\n }\n return sanitized;\n}\n","import type { MemoryDump, FormattedMemoryDump, MemoryBundle, WikiFact, WikiTask, WikiEvent } from '../types';\nimport { sanitizeForFilename } from './sanitizeForFilename';\n\nfunction renderFact(f: WikiFact): string {\n const tags = (f.tags || []).join(', ');\n const source = f.source_ref ?? f.source_type;\n return `### ${f.title}\n**Tags:** ${tags}\n**Confidence:** ${f.confidence}\n**Source:** ${source}\n\n${f.body}\n\n---\n`;\n}\n\nfunction renderTask(t: WikiTask): string {\n const checked = t.status === 'done' ? 'x' : ' ';\n const note = t.status === 'done' ? ' (done)'\n : t.status === 'abandoned' ? ' (abandoned)'\n : t.status === 'in_progress' ? ' (in progress)'\n : '';\n return `- [${checked}] ${t.description}${note}\\n`;\n}\n\nfunction renderEvent(e: WikiEvent): string {\n const ts = new Date(e.created_at).toISOString();\n return `- [${ts}] (${e.event_type}) ${e.summary}\\n`;\n}\n\nfunction renderEntity(entityId: string, bundle: MemoryBundle, generatedAt: number): string {\n const lines: string[] = [];\n lines.push(`# Memory Dump: ${entityId}`);\n lines.push(`Generated: ${new Date(generatedAt).toISOString()}`);\n lines.push('');\n lines.push('## Facts');\n lines.push('');\n if (bundle.facts.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const f of bundle.facts) lines.push(renderFact(f));\n }\n lines.push('## Tasks');\n lines.push('');\n if (bundle.tasks.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const t of bundle.tasks) lines.push(renderTask(t));\n }\n lines.push('');\n lines.push('## Recent Events');\n lines.push('');\n if (bundle.events.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const e of bundle.events) lines.push(renderEvent(e));\n }\n return lines.join('\\n');\n}\n\nfunction formatEntityFileName(entityId: string): string {\n return `${sanitizeForFilename(entityId)}.md`;\n}\n\nexport function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump {\n const files = Object.entries(dump.entities).map(([entityId, bundle]) => ({\n name: formatEntityFileName(entityId),\n content: renderEntity(entityId, bundle, dump.generatedAt),\n }));\n\n // Strip embedding_blob from each fact before JSON-serialising the manifest.\n // exportDump() now includes raw Uint8Array blobs for importDump() round-trips,\n // but those binaries serve no purpose in a human-readable manifest and can\n // massively inflate its size for non-trivial datasets.\n const manifestDump: MemoryDump = {\n generatedAt: dump.generatedAt,\n entities: Object.fromEntries(\n Object.entries(dump.entities).map(([entityId, bundle]) => [\n entityId,\n {\n ...bundle,\n facts: bundle.facts.map(f => {\n const { embedding_blob: _blob, ...rest } = f as WikiFact & { embedding_blob?: unknown };\n return rest as WikiFact;\n }),\n },\n ])\n ),\n };\n\n return {\n manifest: JSON.stringify(manifestDump, null, 2),\n files,\n };\n}\n","import type { MemoryDump, WikiEdge, WikiFact, WikiTask, WikiEvent } from '../types';\nimport {\n appendEventIdComment,\n appendRelatedSection,\n buildConceptDocument,\n buildEntityIndexMd,\n buildRootIndexMd,\n buildLogMd,\n serializeActorString,\n type OkfFile,\n type OkfFrontmatter,\n type OkfIndexEntry,\n type OkfIndexSection,\n type OkfLogEntry,\n} from '@equationalapplications/core-okf';\nimport { sanitizeConceptId, sanitizeForFilename } from './sanitizeForFilename';\n\nexport type OkfFormatProfile = 'llm-wiki/1' | 'llm-wiki/2';\n\nexport interface FormatOkfBundleOptions {\n /** Defaults to 'llm-wiki/2'. Pass 'llm-wiki/1' to force the v0.1 subset. */\n profile?: OkfFormatProfile;\n}\n\nconst DEFAULT_PROFILE: OkfFormatProfile = 'llm-wiki/2';\n\n/**\n * Format an epoch-ms timestamp as ISO 8601 with a double fallback:\n * 1. NaN / Infinity / non-finite -> epoch (0).\n * 2. Outside JS Date's representable range (e.g. 1e300) -> epoch.\n * `new Date(finite).toISOString()` throws RangeError only when the value is\n * outside the supported range; a finite but absurd number still throws. We\n * validate the constructed Date before calling toISOString so the helper\n * never aborts the bundle export.\n */\nfunction isoOrFallback(updatedAt: number): string {\n if (!Number.isFinite(updatedAt)) return new Date(0).toISOString();\n const d = new Date(updatedAt);\n if (!Number.isFinite(d.getTime())) return new Date(0).toISOString();\n return d.toISOString();\n}\n\nfunction isoDateOrOmit(ms: number | null | undefined): string | undefined {\n if (ms == null || !Number.isFinite(ms)) return undefined;\n const d = new Date(ms);\n if (!Number.isFinite(d.getTime())) return undefined;\n return d.toISOString().slice(0, 10);\n}\n\nfunction factFrontmatterV2(f: WikiFact): OkfFrontmatter {\n return {\n type: f.okf_type ?? 'fact',\n title: f.title,\n tags: f.tags,\n // `timestamp` rides along deliberately even on the v0.2 path — a naive\n // consumer that only understands the v0.1 key still gets a readable date\n // without needing flow-mapping support. `generated.at` is the canonical\n // v0.2 field and always wins on import when both are present (spec §2.4).\n timestamp: isoOrFallback(f.updated_at),\n resource: f.source_ref ?? undefined,\n id: f.id,\n entity_id: f.entity_id,\n confidence: f.confidence,\n source_type: f.source_type,\n source_hash: f.source_hash,\n created_at: f.created_at,\n access_count: f.access_count,\n last_accessed_at: f.last_accessed_at,\n deleted_at: f.deleted_at,\n // OKF v0.2\n status: f.lifecycle_status ?? 'stable',\n ...(isoDateOrOmit(f.stale_after) ? { stale_after: isoDateOrOmit(f.stale_after) } : {}),\n // Omit `generated` entirely when there's no actor on record — never\n // fabricate a `generated_by` (mirrors the import side's rule in §4.8:\n // it never invents one either, so export must not manufacture one that\n // would then round-trip back in as if it had always been asserted).\n ...(f.generated_by ? { generated: { by: f.generated_by, at: isoOrFallback(f.updated_at) } } : {}),\n // Omit `verified`/`sources` when empty — an emitted `[]` is not the same\n // shape as an absent key (spec §5.3 derives `unverified` from \"no\n // `verified` key\", not from \"empty `verified` list\").\n ...(f.okf_verified && f.okf_verified.length > 0 ? { verified: f.okf_verified } : {}),\n ...(f.okf_sources && f.okf_sources.length > 0 ? { sources: f.okf_sources } : {}),\n ...(f.okf_usage_window ? { usage_window: f.okf_usage_window } : {}),\n };\n}\n\nfunction taskFrontmatterV2(t: WikiTask): OkfFrontmatter {\n return {\n type: t.okf_type ?? 'task',\n title: t.description,\n timestamp: isoOrFallback(t.updated_at), // see factFrontmatterV2 comment — deliberate back-compat duplication\n id: t.id,\n entity_id: t.entity_id,\n status: t.lifecycle_status ?? 'stable', // OKF v0.2 lifecycle\n execution_status: t.status, // execution state under renamed key\n priority: t.priority,\n created_at: t.created_at,\n resolved_at: t.resolved_at,\n deleted_at: t.deleted_at,\n // OKF v0.2 — symmetric with facts (spec §2.5): stale_after applies to\n // tasks too (a hallucinated task needs a freshness signal as much as a\n // hallucinated fact does).\n ...(isoDateOrOmit(t.stale_after) ? { stale_after: isoDateOrOmit(t.stale_after) } : {}),\n ...(t.generated_by ? { generated: { by: t.generated_by, at: isoOrFallback(t.updated_at) } } : {}),\n ...(t.okf_verified && t.okf_verified.length > 0 ? { verified: t.okf_verified } : {}),\n ...(t.okf_sources && t.okf_sources.length > 0 ? { sources: t.okf_sources } : {}),\n ...(t.okf_usage_window ? { usage_window: t.okf_usage_window } : {}),\n };\n}\n\nfunction factFrontmatterV1(f: WikiFact): OkfFrontmatter {\n return {\n type: f.okf_type ?? 'fact',\n title: f.title,\n tags: f.tags,\n timestamp: isoOrFallback(f.updated_at),\n resource: f.source_ref ?? undefined,\n id: f.id,\n entity_id: f.entity_id,\n confidence: f.confidence,\n source_type: f.source_type,\n source_hash: f.source_hash,\n created_at: f.created_at,\n access_count: f.access_count,\n last_accessed_at: f.last_accessed_at,\n deleted_at: f.deleted_at,\n };\n}\n\nfunction taskFrontmatterV1(t: WikiTask): OkfFrontmatter {\n return {\n type: t.okf_type ?? 'task',\n title: t.description,\n timestamp: isoOrFallback(t.updated_at),\n id: t.id,\n entity_id: t.entity_id,\n status: t.status,\n priority: t.priority,\n created_at: t.created_at,\n resolved_at: t.resolved_at,\n deleted_at: t.deleted_at,\n };\n}\n\nfunction formatLogDate(timestampMs: number): string {\n return new Date(timestampMs).toISOString().slice(0, 10);\n}\n\nfunction conceptRelativePath(sourceFilePath: string, targetFilePath: string): string {\n const sourceDir = sourceFilePath.slice(0, sourceFilePath.lastIndexOf('/'));\n const targetDir = targetFilePath.slice(0, targetFilePath.lastIndexOf('/'));\n const targetName = targetFilePath.slice(targetFilePath.lastIndexOf('/') + 1);\n if (sourceDir === targetDir) return `./${targetName}`;\n if (sourceDir.endsWith('/facts') && targetDir.endsWith('/tasks')) return `../tasks/${targetName}`;\n if (sourceDir.endsWith('/tasks') && targetDir.endsWith('/facts')) return `../facts/${targetName}`;\n return targetFilePath.replace(/^entities\\/[^/]+\\//, '');\n}\n\nfunction buildEventLogEntries(\n events: WikiEvent[],\n factIdToFilename: Map<string, string>,\n): OkfLogEntry[] {\n return events.map(e => {\n const factFilename = e.related_entry_id ? factIdToFilename.get(e.related_entry_id) : undefined;\n const summary = e.summary\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\\r?\\n/g, ' ');\n\n const text = factFilename\n ? `(${e.event_type}) [${summary}](./facts/${factFilename}.md)`\n : `(${e.event_type}) ${summary}`;\n return { date: formatLogDate(e.created_at), text: appendEventIdComment(text, e.id) };\n });\n}\n\nexport function formatOkfBundle(\n dump: MemoryDump,\n options?: FormatOkfBundleOptions,\n): { files: OkfFile[] } {\n const profile: OkfFormatProfile = options?.profile ?? DEFAULT_PROFILE;\n const okfVersion = profile === 'llm-wiki/2' ? '0.2' : '0.1';\n const factFm = profile === 'llm-wiki/2' ? factFrontmatterV2 : factFrontmatterV1;\n const taskFm = profile === 'llm-wiki/2' ? taskFrontmatterV2 : taskFrontmatterV1;\n\n const files: OkfFile[] = [];\n const rootEntries: OkfIndexEntry[] = [];\n\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n const dir = sanitizeForFilename(entityId);\n const factIdToFilename = new Map(\n bundle.facts.map(f => [f.id, sanitizeConceptId(f.id)] as const),\n );\n\n const idToConceptPath = new Map<string, string>();\n for (const f of bundle.facts) {\n idToConceptPath.set(f.id, `entities/${dir}/facts/${factIdToFilename.get(f.id)!}.md`);\n }\n for (const t of bundle.tasks) {\n idToConceptPath.set(t.id, `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`);\n }\n\n const edgesBySource = new Map<string, WikiEdge[]>();\n for (const edge of bundle.edges ?? []) {\n const group = edgesBySource.get(edge.source_id) ?? [];\n group.push(edge);\n edgesBySource.set(edge.source_id, group);\n }\n\n function relatedLinksFor(sourcePath: string, sourceId: string) {\n return (edgesBySource.get(sourceId) ?? [])\n .map(edge => {\n const targetPath = idToConceptPath.get(edge.target_id);\n if (!targetPath) return null;\n return { edge_type: edge.edge_type, path: conceptRelativePath(sourcePath, targetPath) };\n })\n .filter((link): link is { edge_type: string; path: string } => link != null);\n }\n\n const factEntries: OkfIndexEntry[] = bundle.facts.map(f => ({\n path: `facts/${factIdToFilename.get(f.id)!}.md`,\n title: f.title,\n }));\n for (const f of bundle.facts) {\n const factPath = `entities/${dir}/facts/${factIdToFilename.get(f.id)!}.md`;\n const factBody = appendRelatedSection(f.body, relatedLinksFor(factPath, f.id));\n files.push({\n path: factPath,\n content: buildConceptDocument(factFm(f), factBody),\n });\n }\n\n const taskEntries: OkfIndexEntry[] = bundle.tasks.map(t => ({\n path: `tasks/${sanitizeConceptId(t.id)}.md`,\n title: t.description,\n }));\n for (const t of bundle.tasks) {\n const taskPath = `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`;\n const taskBody = appendRelatedSection('', relatedLinksFor(taskPath, t.id));\n files.push({\n path: taskPath,\n content: buildConceptDocument(taskFm(t), taskBody),\n });\n }\n\n files.push({\n path: `entities/${dir}/log.md`,\n content: buildLogMd(buildEventLogEntries(bundle.events, factIdToFilename)),\n });\n\n const entityIndexSections: OkfIndexSection[] = [\n { heading: 'Facts', entries: factEntries },\n { heading: 'Tasks', entries: taskEntries },\n ];\n files.push({\n path: `entities/${dir}/index.md`,\n content: buildEntityIndexMd({\n summary: bundle.summary,\n sections: entityIndexSections,\n }),\n });\n\n rootEntries.push({ path: `entities/${dir}/index.md`, title: entityId });\n }\n\n files.push({\n path: 'index.md',\n content: buildRootIndexMd(\n okfVersion,\n rootEntries.length > 0 ? [{ heading: 'Entities', entries: rootEntries }] : [],\n { profile },\n ),\n });\n\n return { files };\n}","import type { MemoryDump, WikiFact, WikiTask, WikiEvent, WikiEdge } from '../types';\nimport type { OkfFile, OkfFrontmatter, OkfFrontmatterValue } from '@equationalapplications/core-okf';\nimport {\n parseConcept,\n parseLogMd,\n parseRootIndexMd,\n parseEntityIndexMd,\n parseEventIdComment,\n splitRelatedSection,\n isAllowedOkfPath,\n extractMarkdownLinks,\n parseVerifiedFlexible,\n parseCitationsList,\n latestVerified,\n formatVerifiedJson,\n formatSourcesJson,\n type OkfSource,\n type OkfVerified,\n} from '@equationalapplications/core-okf';\nimport { generateId } from './ids';\n\nexport interface OkfImportOptions {\n typeMapping?: Record<string, 'fact' | 'task' | 'ignore'>;\n defaultSchema?: 'fact' | 'task' | 'ignore';\n}\n\ntype Route = 'fact' | 'task' | 'ignore';\n\nconst CONFIDENCE_VALUES = new Set(['certain', 'inferred', 'tentative']);\nconst SOURCE_TYPES = new Set([\n 'user_stated',\n 'librarian_inferred',\n 'user_confirmed',\n 'immutable_document',\n]);\nconst TASK_STATUSES = new Set(['pending', 'in_progress', 'done', 'abandoned']);\nconst EVENT_TYPES = new Set(['observation', 'decision', 'action', 'outcome']);\n\nfunction basenameMd(filePath: string): string {\n const name = filePath.slice(filePath.lastIndexOf('/') + 1);\n return name.endsWith('.md') ? name.slice(0, -3) : name;\n}\n\nfunction isConceptFile(filePath: string): boolean {\n if (!filePath.endsWith('.md')) return false;\n if (filePath.endsWith('/index.md') || filePath === 'index.md') return false;\n if (filePath.endsWith('/log.md') || filePath === 'log.md') return false;\n return true;\n}\n\nfunction isStructuralPath(filePath: string): boolean {\n return (\n filePath.endsWith('/index.md') ||\n filePath === 'index.md' ||\n filePath.endsWith('/log.md') ||\n filePath === 'log.md'\n );\n}\n\nfunction posixDirname(filePath: string): string {\n const idx = filePath.lastIndexOf('/');\n return idx === -1 ? '' : filePath.slice(0, idx);\n}\n\nfunction resolveRelativePath(fromFile: string, linkPath: string): string {\n const baseDir = posixDirname(fromFile);\n const segments = [...(baseDir ? baseDir.split('/') : []), ...linkPath.split('/')];\n const resolved: string[] = [];\n for (const seg of segments) {\n if (seg === '' || seg === '.') continue;\n if (seg === '..') {\n resolved.pop();\n continue;\n }\n resolved.push(seg);\n }\n return resolved.join('/');\n}\n\nfunction decodeLinkPath(path: string): string {\n if (!path.includes('%')) return path;\n try {\n return decodeURIComponent(path);\n } catch {\n return path;\n }\n}\n\nfunction addPathAliases(map: Map<string, string>, filePath: string, resolvedId: string): void {\n map.set(filePath, resolvedId);\n const withoutDot = filePath.replace(/^\\.\\//, '');\n if (withoutDot !== filePath) map.set(withoutDot, resolvedId);\n const entityRelative = filePath.replace(/^entities\\/[^/]+\\//, '');\n if (entityRelative !== filePath) {\n map.set(entityRelative, resolvedId);\n map.set(`./${entityRelative}`, resolvedId);\n }\n}\n\nfunction lookupResolvedId(map: Map<string, string>, path: string): string | undefined {\n const normalized = path.replace(/^\\.\\//, '');\n return map.get(path) ?? map.get(normalized) ?? map.get(`./${normalized}`);\n}\n\nfunction stripLinkSuffix(linkPath: string): string {\n const hashIdx = linkPath.indexOf('#');\n const queryIdx = linkPath.indexOf('?');\n if (hashIdx === -1 && queryIdx === -1) return linkPath;\n const cut =\n hashIdx === -1 ? queryIdx : queryIdx === -1 ? hashIdx : Math.min(hashIdx, queryIdx);\n return linkPath.slice(0, cut);\n}\n\nfunction resolveRoute(filePath: string, frontmatterType: string, options?: OkfImportOptions): Route {\n if (\n options?.typeMapping &&\n Object.prototype.hasOwnProperty.call(options.typeMapping, frontmatterType)\n ) {\n return options.typeMapping[frontmatterType]!;\n }\n if (filePath.includes('/facts/')) return 'fact';\n if (filePath.includes('/tasks/')) return 'task';\n return options?.defaultSchema ?? 'fact';\n}\n\nfunction parseFrontmatterTimestamp(value: OkfFrontmatterValue | undefined, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const parsed = Date.parse(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return fallback;\n}\n\n/**\n * Parse an OKF v0.2 `stale_after` YYYY-MM-DD wire string into an epoch ms\n * value. Returns null on non-string, regex mismatch, or a calendar-invalid\n * date — the previous inline regex accepted any three numeric components, so\n * `2026-13-45` would yield NaN and crash the SQLite bind downstream.\n */\nfunction parseStaleAfterRaw(raw: unknown): number | null {\n if (typeof raw !== 'string') return null;\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(raw);\n if (!m) return null;\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n const ms = Date.UTC(year, month - 1, day);\n if (!Number.isFinite(ms)) return null;\n // Reject calendar-invalid dates that Date.UTC silently normalizes (e.g.\n // 2025-02-29 → 2025-03-01). Compare the round-tripped components.\n const d = new Date(ms);\n if (\n d.getUTCFullYear() !== year ||\n d.getUTCMonth() + 1 !== month ||\n d.getUTCDate() !== day\n ) {\n return null;\n }\n return ms;\n}\n\nfunction unescapeLogSummary(summary: string): string {\n return summary.replace(/\\\\\\]/g, ']').replace(/\\\\\\[/g, '[').replace(/\\\\\\\\/g, '\\\\');\n}\n\nconst LOG_LINE_PATTERN = /^\\(([^)]+)\\)\\s*(?:\\[((?:\\\\.|[^\\]])*)\\]\\(([^)]+)\\)|(.+))$/;\n\nfunction parseLogEntryText(text: string): {\n event_type: WikiEvent['event_type'];\n summary: string;\n linkPath?: string;\n} | null {\n const match = LOG_LINE_PATTERN.exec(text.trim());\n if (!match) return null;\n const [, rawType, linkedSummary, linkPath, plainSummary] = match;\n const event_type = EVENT_TYPES.has(rawType) ? (rawType as WikiEvent['event_type']) : 'observation';\n if (linkPath) {\n return { event_type, summary: unescapeLogSummary(linkedSummary), linkPath };\n }\n return { event_type, summary: (plainSummary ?? '').trim() };\n}\n\nfunction frontmatterToFact(\n entityId: string,\n id: string,\n frontmatter: OkfFrontmatter,\n body: string,\n now: number,\n): WikiFact {\n const created_at = parseFrontmatterTimestamp(frontmatter.created_at, now);\n // Precedence (spec §2.4): v0.2 `generated.at` -> v0.1 `timestamp` -> legacy\n // `updated_at` -> `now`. The previous order swapped `updated_at` ahead of\n // the other two, so a present-but-finite `updated_at` clobbered\n // `generated.at`. We nest the fallbacks so the first finite wins.\n const updated_at = parseFrontmatterTimestamp(\n (frontmatter as any).generated?.at,\n parseFrontmatterTimestamp(\n frontmatter.timestamp,\n parseFrontmatterTimestamp(frontmatter.updated_at, now),\n ),\n );\n\n const verified: OkfVerified = parseVerifiedFlexible((frontmatter as any).verified);\n const rawSources = (frontmatter as any).sources;\n const hasSourcesKey = rawSources !== undefined;\n const sources: OkfSource[] = Array.isArray(rawSources) ? rawSources as OkfSource[] : [];\n const usageWindow = (frontmatter as any).usage_window && typeof (frontmatter as any).usage_window === 'object'\n ? (frontmatter as any).usage_window as { from: string; to: string }\n : null;\n const lastV = latestVerified(verified, now);\n const lifecycleRaw = (frontmatter as any).status;\n const lifecycle_status: 'draft' | 'stable' | 'deprecated' =\n lifecycleRaw === 'draft' || lifecycleRaw === 'stable' || lifecycleRaw === 'deprecated'\n ? lifecycleRaw : 'stable';\n const staleAfterRaw = (frontmatter as any).stale_after;\n const stale_after = parseStaleAfterRaw(staleAfterRaw);\n const generated_by = (frontmatter as any).generated?.by ?? null;\n\n // Spec §13.1 fallback (applies to v0.1, profile-0, AND v0.2 paths): body\n // `# Citations` -> synthetic sources, one entry per URL. The fallback only\n // fires when the `sources` key is ABSENT — a bundle that explicitly declares\n // `sources: []` (an author clearing provenance) MUST NOT have body citations\n // silently synthesized back into it. `hasSourcesKey` distinguishes absent\n // from explicitly-empty.\n if (!hasSourcesKey) {\n const urls = parseCitationsList(body);\n for (const url of urls) {\n sources.push({ resource: url });\n }\n }\n\n return {\n id,\n entity_id: entityId,\n title: typeof frontmatter.title === 'string' ? frontmatter.title : '',\n body,\n tags: Array.isArray(frontmatter.tags)\n ? frontmatter.tags.filter((t): t is string => typeof t === 'string')\n : [],\n confidence: CONFIDENCE_VALUES.has(String(frontmatter.confidence))\n ? (frontmatter.confidence as WikiFact['confidence'])\n : 'tentative',\n source_type: SOURCE_TYPES.has(String(frontmatter.source_type))\n ? (frontmatter.source_type as WikiFact['source_type'])\n : 'user_stated',\n source_hash: typeof frontmatter.source_hash === 'string' ? frontmatter.source_hash : null,\n source_ref: typeof frontmatter.resource === 'string' ? frontmatter.resource : null,\n created_at,\n updated_at,\n last_accessed_at:\n frontmatter.last_accessed_at != null\n ? parseFrontmatterTimestamp(frontmatter.last_accessed_at, now)\n : null,\n access_count: typeof frontmatter.access_count === 'number' ? frontmatter.access_count : 0,\n deleted_at:\n frontmatter.deleted_at != null ? parseFrontmatterTimestamp(frontmatter.deleted_at, 0) : null,\n okf_type: frontmatter.type,\n // OKF v0.2\n lifecycle_status,\n stale_after,\n generated_by,\n okf_sources: sources,\n okf_verified: verified,\n okf_usage_window: usageWindow,\n last_verified_at: lastV?.at ?? null,\n last_verified_by: lastV?.by ?? null,\n };\n}\n\nfunction frontmatterToTask(\n entityId: string,\n id: string,\n frontmatter: OkfFrontmatter,\n now: number,\n // Treat profile-1 explicit and version-only legacy the same: in both cases\n // `status` on the wire is the v0.1 execution state. Profile-2 (and unknown\n // profile with okf_version 0.2) uses the v0.2 rename rule.\n usesV1StatusRule: boolean,\n): WikiTask {\n const created_at = parseFrontmatterTimestamp(frontmatter.created_at, now);\n // Precedence (spec §2.4) — same nested-fallback chain as frontmatterToFact.\n const updated_at = parseFrontmatterTimestamp(\n (frontmatter as any).generated?.at,\n parseFrontmatterTimestamp(\n frontmatter.timestamp,\n parseFrontmatterTimestamp(frontmatter.updated_at, now),\n ),\n );\n\n const verified: OkfVerified = parseVerifiedFlexible((frontmatter as any).verified);\n const sources: OkfSource[] = Array.isArray((frontmatter as any).sources) ? (frontmatter as any).sources as OkfSource[] : [];\n const usageWindow = (frontmatter as any).usage_window && typeof (frontmatter as any).usage_window === 'object'\n ? (frontmatter as any).usage_window as { from: string; to: string }\n : null;\n const lastV = latestVerified(verified, now);\n const lifecycleRaw = (frontmatter as any).status;\n const lifecycle_status: 'draft' | 'stable' | 'deprecated' =\n lifecycleRaw === 'draft' || lifecycleRaw === 'stable' || lifecycleRaw === 'deprecated'\n ? lifecycleRaw : 'stable';\n // stale_after is symmetric with facts (spec §2.5) — parsed the same way,\n // not hardcoded to null.\n const staleAfterRaw = (frontmatter as any).stale_after;\n const stale_after = parseStaleAfterRaw(staleAfterRaw);\n\n // Status rename rule (spec §2.3):\n // - v0.2: wire `status` = lifecycle (already in lifecycle_status above);\n // wire `execution_status` = execution -> `task.status`.\n // - v0.1 / profile 0: wire `status` = execution -> `task.status`; lifecycle\n // is implicit 'stable'. Profile-1 bundles are explicit about being v0.1\n // (`profile: llm-wiki/1`); profile-0 (no profile key, `okf_version: 0.1`)\n // is the version-only fallback; both MUST use the v0.1 rule.\n const executionRaw = (frontmatter as any).execution_status;\n let executionState: WikiTask['status'];\n if (usesV1StatusRule) {\n executionState = TASK_STATUSES.has(String(frontmatter.status))\n ? (frontmatter.status as WikiTask['status']) : 'pending';\n } else {\n // v0.2 (or unknown profile — best-effort per spec §6 \"profile key unknown\").\n executionState = TASK_STATUSES.has(String(executionRaw))\n ? (executionRaw as WikiTask['status'])\n : TASK_STATUSES.has(String(frontmatter.status))\n ? (frontmatter.status as WikiTask['status'])\n : 'pending';\n }\n\n return {\n id,\n entity_id: entityId,\n description: typeof frontmatter.title === 'string' ? frontmatter.title : '',\n status: executionState,\n priority: typeof frontmatter.priority === 'number' ? frontmatter.priority : 0,\n created_at,\n updated_at,\n resolved_at:\n frontmatter.resolved_at != null\n ? parseFrontmatterTimestamp(frontmatter.resolved_at, now)\n : null,\n deleted_at:\n frontmatter.deleted_at != null ? parseFrontmatterTimestamp(frontmatter.deleted_at, 0) : null,\n okf_type: frontmatter.type,\n // OKF v0.2\n lifecycle_status,\n stale_after,\n generated_by: (frontmatter as any).generated?.by ?? null,\n okf_sources: sources,\n okf_verified: verified,\n okf_usage_window: usageWindow,\n last_verified_at: lastV?.at ?? null,\n last_verified_by: lastV?.by ?? null,\n };\n}\n\nfunction findLogMdPath(files: OkfFile[]): string | undefined {\n return files.find(f => f.path.endsWith('/log.md') || f.path === 'log.md')?.path;\n}\n\nfunction extractEdgesFromLinks(\n filePath: string,\n resolvedId: string,\n links: Array<{ text: string; path: string }>,\n pathToResolvedId: Map<string, string>,\n entityId: string,\n now: number,\n seenEdges: Set<string>,\n edges: WikiEdge[],\n): void {\n for (const link of links) {\n const strippedPath = stripLinkSuffix(decodeLinkPath(link.path));\n const directTargetId = lookupResolvedId(pathToResolvedId, strippedPath);\n const resolvedTargetPath = resolveRelativePath(filePath, strippedPath);\n if (isStructuralPath(strippedPath) || isStructuralPath(resolvedTargetPath)) continue;\n const targetId = directTargetId ?? lookupResolvedId(pathToResolvedId, resolvedTargetPath);\n if (!targetId) continue;\n const edgeKey = `${resolvedId}\\u0000${targetId}\\u0000${link.text}`;\n if (seenEdges.has(edgeKey)) continue;\n seenEdges.add(edgeKey);\n edges.push({\n id: generateId(),\n entity_id: entityId,\n source_id: resolvedId,\n target_id: targetId,\n edge_type: link.text,\n created_at: now,\n });\n }\n}\n\nexport function parseOkfBundle(\n entityId: string,\n files: OkfFile[],\n options?: OkfImportOptions,\n): MemoryDump {\n const now = Date.now();\n const normalizeOkfPath = (p: string) => p.replace(/^\\.\\//, '').replace(/\\\\/g, '/');\n\n const normalizedFiles = files.map(f => ({ ...f, path: normalizeOkfPath(f.path) }));\n\n const allowlistedFiles = normalizedFiles.filter(f => isAllowedOkfPath(f.path));\n\n const entityDirs = new Set(\n allowlistedFiles\n .map(f => /^entities\\/([^/]+)\\//.exec(f.path)?.[1])\n .filter((dir): dir is string => !!dir),\n );\n if (entityDirs.size > 1) {\n throw new Error(\n `parseOkfBundle: expected a single-entity bundle for \"${entityId}\", found entities: ${Array.from(entityDirs).join(', ')}`,\n );\n }\n const entityDir = entityDirs.values().next().value ?? entityId;\n const entityPrefix = `entities/${entityDir}/`;\n\n const allowedFiles = allowlistedFiles.filter(\n f => f.path === 'index.md' || f.path.startsWith(entityPrefix),\n );\n const rootIndex = allowedFiles.find(f => f.path === 'index.md');\n const profileMeta = rootIndex ? parseRootIndexMd(rootIndex.content) : {};\n const okfVersion = profileMeta.okf_version;\n const profile = profileMeta.profile;\n const isProfile1 = profile === 'llm-wiki/1';\n const isProfile2 = profile === 'llm-wiki/2';\n const isLegacyV1 = profile === undefined && okfVersion === '0.1';\n\n // Entity summary is a profile >= 1 feature (§4 of the profile doc). The\n // documented detection order (§4.8 detection plan) names four v0.1 and v0.2\n // entry points: explicit profile, version-only v0.1, version-only v0.2, and\n // unknown-profile v0.2 (best-effort). All four should pick up the summary.\n const isVersionOnlyV2 = profile === undefined && okfVersion === '0.2';\n const isUnknownProfileV2 = profile !== undefined && profile !== 'llm-wiki/1' && profile !== 'llm-wiki/2' && okfVersion === '0.2';\n const summaryEligible = isProfile1 || isProfile2 || isLegacyV1 || isVersionOnlyV2 || isUnknownProfileV2;\n let entitySummary: string | undefined;\n const entityIndex = allowedFiles.find(f => f.path === `${entityPrefix}index.md`);\n if (summaryEligible && entityIndex) {\n const summary = parseEntityIndexMd(entityIndex.content).summary;\n entitySummary = summary || undefined;\n }\n\n const pathToResolvedId = new Map<string, string>();\n\n for (const file of allowedFiles) {\n if (!isConceptFile(file.path)) continue;\n const { frontmatter } = parseConcept(file.content);\n const route = resolveRoute(file.path, frontmatter.type ?? '', options);\n if (route === 'ignore') continue;\n const resolvedId =\n typeof frontmatter.id === 'string' && frontmatter.id ? frontmatter.id : basenameMd(file.path);\n addPathAliases(pathToResolvedId, file.path, resolvedId);\n }\n\n const facts: WikiFact[] = [];\n const tasks: WikiTask[] = [];\n const edges: WikiEdge[] = [];\n let logContent: string | null = null;\n const logMdPath = findLogMdPath(allowedFiles);\n\n for (const file of allowedFiles) {\n if (file.path.endsWith('/log.md') || file.path === 'log.md') {\n logContent = file.content;\n continue;\n }\n if (!isConceptFile(file.path)) continue;\n\n const { frontmatter, body } = parseConcept(file.content);\n const route = resolveRoute(file.path, frontmatter.type ?? '', options);\n if (route === 'ignore') continue;\n\n const resolvedId =\n typeof frontmatter.id === 'string' && frontmatter.id ? frontmatter.id : basenameMd(file.path);\n\n const { body: storedBody, relatedLinks } = splitRelatedSection(body);\n const edgeLinks = (isProfile1 || isLegacyV1)\n ? relatedLinks\n : [...relatedLinks, ...extractMarkdownLinks(storedBody)];\n\n // Task status rename rule (spec §2.3) — v0.1 wire uses `status` as\n // execution state; v0.2 wire uses `status` as lifecycle and adds\n // `execution_status`. The flag we pass below is true when we are NOT\n // reading this task as a v0.2-style bundle.\n const usesV1StatusRule = isProfile1 || isLegacyV1 || (profile === undefined && okfVersion === undefined);\n\n if (route === 'fact') {\n facts.push(frontmatterToFact(entityId, resolvedId, frontmatter, storedBody, now));\n } else {\n tasks.push(frontmatterToTask(entityId, resolvedId, frontmatter, now, usesV1StatusRule));\n }\n\n const seenEdges = new Set<string>();\n extractEdgesFromLinks(\n file.path,\n resolvedId,\n edgeLinks,\n pathToResolvedId,\n entityId,\n now,\n seenEdges,\n edges,\n );\n }\n\n const events: WikiEvent[] = [];\n if (logContent != null) {\n const logPath = logMdPath ?? `entities/${entityId}/log.md`;\n for (const entry of parseLogMd(logContent)) {\n const { text, eventId } = parseEventIdComment(entry.text);\n const parsed = parseLogEntryText(text);\n if (!parsed) continue;\n let related_entry_id: string | null = null;\n if (parsed.linkPath) {\n const targetPath = resolveRelativePath(\n logPath,\n stripLinkSuffix(decodeLinkPath(parsed.linkPath)),\n );\n if (!isStructuralPath(targetPath) && targetPath.includes('/facts/')) {\n related_entry_id = lookupResolvedId(pathToResolvedId, targetPath) ?? null;\n }\n }\n const created_at = new Date(`${entry.date}T00:00:00.000Z`).getTime();\n if (!Number.isFinite(created_at)) continue;\n\n events.push({\n id: eventId ?? generateId('evt_'),\n entity_id: entityId,\n event_type: parsed.event_type,\n summary: parsed.summary,\n related_entry_id,\n created_at,\n });\n }\n }\n\n return {\n generatedAt: now,\n entities: {\n [entityId]: { facts, tasks, events, edges, summary: entitySummary },\n },\n };\n}\n","import type { ReadOptions } from './types';\n\nexport interface LibrarianOptions {\n /** If provided, replaces the default Librarian system instructions. */\n systemPrompt?: string;\n /** entity_id -> score multiplier, forwarded to WikiMemory.read() as tierWeights. */\n entityWeights?: Record<string, number>;\n /** Forwarded to WikiMemory.read() for zero-weight filler context. */\n includeZeroWeightEntities?: boolean;\n temperature?: number;\n}\n\nexport interface LibrarianPromptVariables {\n context: string;\n tasks: string;\n query: string;\n}\n\nexport const DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = `You are a careful memory synthesis assistant.\nUse only the retrieved context when answering the request.\nPreserve source provenance when facts come from different entity namespaces.\n\nRequest:\n{{query}}\n\nRetrieved context:\n{{context}}\n\nOpen tasks:\n{{tasks}}`;\n\nexport function hydrateLibrarianPrompt(\n template: string,\n variables: LibrarianPromptVariables,\n): string {\n return template.replace(/\\{\\{(context|tasks|query)\\}\\}/g, (_, key) => variables[key as keyof LibrarianPromptVariables]);\n}\n\nexport function validateLibrarianPromptTemplate(\n template: string,\n options: { custom: boolean; taskCount: number },\n): string[] {\n if (!options.custom) return [];\n\n const warnings: string[] = [];\n if (!template.includes('{{context}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{context}}; retrieved memory will not be injected.');\n }\n if (!template.includes('{{query}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{query}}; the original request will not be injected.');\n }\n if (options.taskCount > 0 && !template.includes('{{tasks}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{tasks}} while retrieved tasks are available.');\n }\n return warnings;\n}\n\nexport function mapLibrarianOptionsToReadOptions(\n options: LibrarianOptions,\n): Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> {\n const readOptions: Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> = {};\n if (options.entityWeights !== undefined) readOptions.tierWeights = options.entityWeights;\n if (options.includeZeroWeightEntities !== undefined) {\n readOptions.includeZeroWeightEntities = options.includeZeroWeightEntities;\n }\n return readOptions;\n}\n","import { WikiMemory } from './WikiMemory';\nimport type { SQLiteAdapter, WikiOptions } from './types';\n\nexport * from './types';\nexport type { WikiOutboxEvent } from './outbox/types';\nexport { WikiMemory } from './WikiMemory';\nexport type { WikiMemoryTestAccess } from './WikiMemory';\nexport { formatContext } from './utils/formatContext';\nexport { formatGraphContext } from './utils/formatGraphContext';\nexport { formatMemoryDump } from './utils/formatMemoryDump';\nexport { formatOkfBundle, type FormatOkfBundleOptions, type OkfFormatProfile } from './utils/formatOkfBundle';\nexport { parseOkfBundle, type OkfImportOptions } from './utils/parseOkfBundle';\nexport { parseEmbedding } from './utils/embedding';\nexport { validateManifest } from './utils/ontology';\nexport { configureRandomSource } from './utils/ids';\nexport { chunkText, safeSlice } from './utils/pure';\nexport { DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_CHUNK_OVERLAP } from './utils/chunkingDefaults';\nexport { DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING } from './utils/embedDefaults';\nexport * from './librarianPrompt';\nexport { PromptService } from './services/PromptService';\nexport type { EmbedFactResult, EmbedFailureKind } from './services/EmbeddingService';\nexport {\n ONTOLOGY_BACKFILL_BATCH_SIZE,\n ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS,\n ONTOLOGY_BACKFILL_RECHECK_MS,\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_BATCH_SIZE,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n HEAL_MAX_TASKS,\n HEAL_RECHECK_MS,\n} from './services/MaintenanceService';\nexport { ONTOLOGY_BACKFILL_SYSTEM_PROMPT } from './prompts';\n\nexport function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory {\n return new WikiMemory(db, options);\n}\n"]}
1
+ {"version":3,"sources":["../src/db/schema.ts","../src/db/sqliteCodes.ts","../src/types.ts","../src/db/serializedAdapter.ts","../src/db/migrations.ts","../src/repositories/BaseRepository.ts","../src/repositories/rowMappers.ts","../src/repositories/EntryRepository.ts","../src/utils/ids.ts","../src/repositories/OutboxRepository.ts","../src/repositories/SourceRefIndexRepository.ts","../src/repositories/TaskRepository.ts","../src/repositories/EventRepository.ts","../src/repositories/EdgeRepository.ts","../src/utils/ontology.ts","../src/repositories/MetadataRepository.ts","../src/utils/cosine.ts","../src/utils/embedding.ts","../src/services/SearchService.ts","../src/services/JobManager.ts","../src/utils/pure.ts","../src/utils/grounding.ts","../src/utils/diagnostics.ts","../src/prompts.ts","../src/utils/healConstants.ts","../src/services/PromptService.ts","../src/utils/chunkingDefaults.ts","../src/services/IngestionService.ts","../src/utils/classifier.ts","../src/services/BoundedLlmCall.ts","../src/services/MaintenanceService.ts","../src/services/ImportExportService.ts","../src/utils/embedDefaults.ts","../src/services/EmbeddingService.ts","../src/readOptions.ts","../src/services/RetrievalService.ts","../src/services/WriteService.ts","../src/prompts/ontology.ts","../src/services/OntologyService.ts","../src/services/GraphTraversalService.ts","../src/db/okf-trust-writes.ts","../src/WikiMemory.ts","../src/utils/formatContext.ts","../src/utils/formatGraphContext.ts","../src/utils/sanitizeForFilename.ts","../src/utils/formatMemoryDump.ts","../src/utils/formatOkfBundle.ts","../src/utils/parseOkfBundle.ts","../src/librarianPrompt.ts","../src/index.ts"],"names":["isStaleAfter","deriveTrustTier","MiniSearch","rows","documents","result","entries","counts","latestVerified","entityId","formatSourcesJson","appendEventIdComment","relatedLinksFor","appendRelatedSection","buildConceptDocument","buildLogMd","buildEntityIndexMd","buildRootIndexMd","parseVerifiedFlexible","parseCitationsList","isAllowedOkfPath","parseRootIndexMd","parseEntityIndexMd","parseConcept","splitRelatedSection","extractMarkdownLinks","parseLogMd","parseEventIdComment"],"mappings":"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","file":"index.js","sourcesContent":["import type { SQLiteAdapter } from '../types';\n\nexport async function setupDatabase(db: SQLiteAdapter, prefix: string) {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entries (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n title TEXT NOT NULL,\n body TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n confidence TEXT NOT NULL DEFAULT 'inferred',\n source_type TEXT NOT NULL DEFAULT 'librarian_inferred',\n source_hash TEXT,\n source_ref TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n last_accessed_at INTEGER,\n access_count INTEGER NOT NULL DEFAULT 0,\n deleted_at INTEGER,\n embedding TEXT,\n embedding_blob BLOB,\n okf_type TEXT,\n ontology_checked_at INTEGER,\n heal_checked_at INTEGER,\n lifecycle_status TEXT NOT NULL DEFAULT 'stable',\n stale_after INTEGER,\n generated_by TEXT,\n last_verified_at INTEGER,\n last_verified_by TEXT,\n okf_sources TEXT,\n okf_verified TEXT,\n okf_usage_window TEXT,\n embedding_failed_at INTEGER,\n embedding_failure_kind TEXT,\n embedding_attempts INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}entries_entity_idx ON ${prefix}entries(entity_id);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_ref_idx ON ${prefix}entries(entity_id, source_ref);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_source_hash_idx ON ${prefix}entries(entity_id, source_hash) WHERE source_hash IS NOT NULL;\n CREATE INDEX IF NOT EXISTS ${prefix}entries_updated_idx ON ${prefix}entries(updated_at DESC);\n\n -- source_ref_index: per-(entity, source_hash) record of the canonical sourceRef\n -- currently holding that hash. The partial UNIQUE index on (entity_id, source_hash)\n -- WHERE deleted_at IS NULL enforces the sourceRef-level TOCTOU-race invariant;\n -- entries-level uniqueness cannot express it because a single ingestDocument call\n -- writes N facts that all share (entity_id, source_ref, source_hash). See\n -- docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n CREATE TABLE IF NOT EXISTS ${prefix}source_ref_index (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_hash TEXT NOT NULL,\n source_ref TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n deleted_at INTEGER\n );\n CREATE UNIQUE INDEX IF NOT EXISTS ${prefix}idx_source_ref_hash\n ON ${prefix}source_ref_index (entity_id, source_hash)\n WHERE deleted_at IS NULL;\n\n CREATE TABLE IF NOT EXISTS ${prefix}tasks (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n description TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n priority INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n resolved_at INTEGER,\n deleted_at INTEGER,\n okf_type TEXT,\n lifecycle_status TEXT NOT NULL DEFAULT 'stable',\n stale_after INTEGER,\n generated_by TEXT,\n last_verified_at INTEGER,\n last_verified_by TEXT,\n okf_sources TEXT,\n okf_verified TEXT,\n okf_usage_window TEXT\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_entity_idx ON ${prefix}tasks(entity_id, status);\n\n CREATE TABLE IF NOT EXISTS ${prefix}edges (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n edge_type TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n UNIQUE(entity_id, source_id, target_id, edge_type)\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}edges_entity_idx ON ${prefix}edges(entity_id);\n\n CREATE TABLE IF NOT EXISTS ${prefix}events (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n event_type TEXT NOT NULL,\n summary TEXT NOT NULL,\n related_entry_id TEXT,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}events_entity_idx ON ${prefix}events(entity_id, created_at DESC);\n\n CREATE TABLE IF NOT EXISTS ${prefix}checkpoints (\n entity_id TEXT PRIMARY KEY,\n heal_checkpoint INTEGER NOT NULL DEFAULT 0,\n memory_checkpoint INTEGER NOT NULL DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}entity_manifests (\n entity_id TEXT PRIMARY KEY,\n mode TEXT NOT NULL DEFAULT 'off',\n manifest_json TEXT NOT NULL DEFAULT '{\"node_types\":[],\"edge_types\":[]}',\n updated_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS ${prefix}outbox (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n table_name TEXT NOT NULL,\n record_id TEXT NOT NULL,\n operation TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_entity_id_created_at\n ON ${prefix}outbox (entity_id, created_at);\n\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_created_at\n ON ${prefix}outbox (created_at);\n `);\n\n // OKF v0.2 indexes — gated on column existence so we never try to create an\n // index on a column that hasn't been added yet (upgrade-from-pre-v10 case).\n // The columns themselves are in the CREATE TABLE above (fresh installs get\n // them directly) and in migration v10 (upgrades get them via ALTER TABLE).\n // The migration also creates these same indexes, so the IF NOT EXISTS guard\n // makes either path safe.\n await createOkfV02IndexesIfColumnsExist(db, prefix);\n}\n\nasync function createOkfV02IndexesIfColumnsExist(db: SQLiteAdapter, prefix: string): Promise<void> {\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n const colNames = new Set(cols.map((c) => c.name));\n if (colNames.has('lifecycle_status')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_lifecycle_status_idx ON ${prefix}${table}(lifecycle_status);`);\n }\n if (colNames.has('stale_after')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_stale_after_idx ON ${prefix}${table}(stale_after);`);\n }\n if (colNames.has('last_verified_at')) {\n await db.execAsync(`CREATE INDEX IF NOT EXISTS ${prefix}${table}_last_verified_at_idx ON ${prefix}${table}(last_verified_at);`);\n }\n }\n}\n","/**\n * SQLite primary result codes → symbolic name (https://sqlite.org/rescode.html),\n * so a numeric expo-sqlite code normalizes to the same shape as the string codes\n * better-sqlite3 / node:sqlite already report (e.g. both become 'SQLITE_BUSY').\n *\n * Dependency-free leaf module: shared by `db/serializedAdapter.ts` and `types.ts`\n * (via `WikiTransactionError`) so the mapping has a single source of truth.\n */\nconst SQLITE_RESULT_CODE_NAMES: Record<number, string> = {\n 1: 'SQLITE_ERROR', 2: 'SQLITE_INTERNAL', 3: 'SQLITE_PERM', 4: 'SQLITE_ABORT',\n 5: 'SQLITE_BUSY', 6: 'SQLITE_LOCKED', 7: 'SQLITE_NOMEM', 8: 'SQLITE_READONLY',\n 9: 'SQLITE_INTERRUPT', 10: 'SQLITE_IOERR', 11: 'SQLITE_CORRUPT', 12: 'SQLITE_NOTFOUND',\n 13: 'SQLITE_FULL', 14: 'SQLITE_CANTOPEN', 15: 'SQLITE_PROTOCOL', 16: 'SQLITE_EMPTY',\n 17: 'SQLITE_SCHEMA', 18: 'SQLITE_TOOBIG', 19: 'SQLITE_CONSTRAINT', 20: 'SQLITE_MISMATCH',\n 21: 'SQLITE_MISUSE', 22: 'SQLITE_NOLFS', 23: 'SQLITE_AUTH', 24: 'SQLITE_FORMAT',\n 25: 'SQLITE_RANGE', 26: 'SQLITE_NOTADB', 27: 'SQLITE_NOTICE', 28: 'SQLITE_WARNING',\n // Extended result codes (https://sqlite.org/rescode.html#extended_result_code_list).\n // 2067 = SQLITE_CONSTRAINT_UNIQUE — raised when a UNIQUE index/PRIMARY KEY\n // rejects an INSERT/UPDATE; expo-sqlite reports this as a numeric \"Error code N:\"\n // prefix and we normalize it back to the symbolic name so callers can branch on\n // the same string the rest of the ecosystem uses.\n 2067: 'SQLITE_CONSTRAINT_UNIQUE',\n 100: 'SQLITE_ROW', 101: 'SQLITE_DONE',\n};\n\n/** Falls back to `SQLITE_<n>` for a result code outside the known table. */\nexport function nameForSqliteResultCode(n: number): string {\n return SQLITE_RESULT_CODE_NAMES[n] ?? `SQLITE_${n}`;\n}\n\n/**\n * Best-effort SQLite code extraction. Driver-specific:\n * better-sqlite3 / node:sqlite: err.code === 'SQLITE_BUSY' (string, SQLITE_-prefixed)\n * expo-sqlite: err.message starts with 'Error code N: …' (numeric,\n * normalized here to the same symbolic name)\n */\nexport function extractSqliteCode(err: unknown): string | undefined {\n if (typeof err !== 'object' || err === null) return undefined;\n const { code, message } = err as { code?: unknown; message?: unknown };\n if (typeof code === 'string' && code.startsWith('SQLITE_')) return code;\n if (typeof message === 'string') {\n const m = /^Error code (\\d+):/.exec(message);\n if (m) return nameForSqliteResultCode(Number(m[1]));\n }\n return undefined;\n}\n","import { extractSqliteCode } from './db/sqliteCodes';\nimport type {\n OkfSource,\n OkfSourceUsageWindow,\n OkfVerifiedEntry,\n} from '@equationalapplications/core-okf';\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 /**\n * `changes` must report the number of rows the statement actually wrote.\n * It must be 0 when a conflict clause suppresses a write (INSERT OR IGNORE,\n * or ON CONFLICT DO UPDATE ... WHERE), and must never be nonzero for a\n * suppressed write. A permitted write that modifies no column value still\n * counts the row, as SQLite does.\n *\n * This count is load-bearing beyond ownership checks: edge insertion\n * (and therefore upsertGraph's public edgesWritten), metadata compare-and-set,\n * soft-delete success reporting, and maintenance sweep counts all read it.\n * An adapter that under-reports silently corrupts those results.\n */\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 /** Optional parent type slug. One level only — the parent must exist in the\n * same manifest and must not itself declare a `parent_type`. */\n parent_type?: 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 * Engine default for `runOntologyBackfill`'s `classifier` option.\n * `'auto'` uses `llmProvider.classify` for node typing when present\n * (no edges are proposed); `'llm'` always uses `generateText`. Default `'llm'`.\n */\n backfillClassifier?: 'auto' | 'llm';\n /** Minimum classifier confidence to apply a node type. Finite, in [0, 1]. Default 0.5. */\n classifyMinConfidence?: number;\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\n/** Result of a single `runReembed` sweep. */\nexport interface ReembedResult {\n /** Facts successfully (re-)embedded this sweep. */\n embedded: number;\n /** Facts with a valid existing embedding left untouched because\n * `skipExisting` was in effect (and no dimension mismatch forced a re-embed). */\n skipped: number;\n /** Facts whose embed attempt ran and failed this sweep. Includes\n * `storage_error` failures, which are not backoff-tracked (a marker is\n * itself a DB write — see the reembed README section). Convergence loops\n * should test this counter, never `deferred`. */\n failed: number;\n /** Previously failed facts still inside their exponential backoff window\n * (60s doubling, capped at 24h), not attempted this sweep. Not an error;\n * a later sweep retries them once the window elapses. */\n deferred: number;\n /** Facts excluded for good: a `float32_overflow` failure or 5 failed\n * lifetime attempts. `{ force: true }` retries these anyway. */\n permanentlyFailed: number;\n}\n\n/**\n * L3 heal-success record: a fact the model emitted a verdict for under a\n * truncated view of its own body. `originalBodyChars` lets an operator flag\n * the fact for re-inspection; `truncatedBodyChars` is the L3 cap actually\n * applied. Emitted by `PromptService.buildHealPrompt`, surfaced via\n * `HealResult.degraded`, mutually exclusive with `HealResult.skipped` on\n * `id` (a fact can be either healed-under-degradation or dropped — never\n * both).\n */\nexport interface DegradedRecord {\n id: string;\n originalBodyChars: number;\n truncatedBodyChars: number;\n}\n\n/** Result of a single heal run. */\nexport interface HealResult {\n /**\n * Heal candidates sent to the model this run. Counts candidates whose batch\n * came back unusable and landed in `skipped` as well — they reached the\n * provider too, so this is provider exposure, not successful throughput.\n */\n scanned: number;\n /**\n * Facts whose confidence was lowered to `tentative` — the stale-inferred SQL\n * pass (`inferred` → `tentative`) plus any model-directed downgrades, deduped.\n */\n downgraded: number;\n /** Facts soft-deleted — the orphan-marking SQL pass plus model-directed deletes, deduped. */\n deleted: number;\n /** New facts synthesized by heal. */\n newFactsCreated: number;\n /**\n * Candidates that could not converge after the helper's full escalation\n * path. `reason` distinguishes genuine non-convergence\n * (`'non_convergent'` — terminal give-up at attemptLevel 3, parse error,\n * or model-config error) from transient provider failures\n * (`'call_error'` — non-truncation error originating in `call()` at\n * `batch.length === 1`). `doRunHeal` excludes `'call_error'` ids from\n * `markHealChecked`'s cooldown stamp so a momentary provider hiccup does\n * not lock the fact out for `HEAL_RECHECK_MS`. Mutually exclusive with\n * `degraded` on `id`.\n */\n skipped: Array<{ id: string; reason: 'non_convergent' | 'call_error' }>;\n /**\n * L3 heal successes: facts the model emitted a verdict for under a\n * truncated view of their own body. Each entry carries the truncation\n * magnitude so an operator can flag the fact for re-inspection. The\n * corresponding log line `[WikiMemory] heal healed under degraded\n * context ...` fires for each entry. Mutually exclusive with `skipped`\n * on `id` — the reconciliation step in doRunHeal drops any record\n * whose id also appears in `skipped` (a contradiction: degraded means\n * healed, skipped means dropped).\n */\n degraded: Array<DegradedRecord>;\n /**\n * Heal candidates still eligible after this run — convergence signal: loop while > 0.\n *\n * This does NOT mean what it means for OntologyBackfillResult. Untyped facts are\n * a finite backlog that drains permanently; heal's candidates are the live mutable\n * corpus. `remaining === 0` means \"every mutable fact is inside the recheck\n * cooldown\", not \"there is no more work\" — it climbs back as the cooldown lapses\n * and as new facts are written. A host loop terminates, but it converges to\n * \"corpus swept once this cooldown window\", not to a drained queue.\n */\n remaining: number;\n /** Heal candidates inside the recheck cooldown. */\n deferred: number;\n}\n\n/**\n * Opt-in evidence check for LLM-authored facts (spec §6). Default off: 7.x\n * write behavior is unchanged. In `'draft'` mode, writers in `writers` must\n * quote their source; a fact whose quotes are missing or not found is stored\n * as a `draft` instead of being rejected.\n */\nexport interface GroundingConfig {\n mode: 'off' | 'draft';\n /** Default `['ingest']`. The librarian and heal synthesize across events; measure their pass rates before opting them in. */\n writers?: Array<'ingest' | 'librarian' | 'heal'>;\n /** Quotes shorter than this (after whitespace normalization) count as absent. Default 20. */\n minEvidenceChars?: number;\n /** Quotes retained per fact. Retention only; every quote is checked. Default 3. */\n maxEvidence?: number;\n /** Characters retained per quote. Default 300. */\n maxEvidenceChars?: 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 * Maximum characters of `title + body + tags` passed to `llmProvider.embed()`\n * when embedding a fact. Longer input is clipped, not rejected.\n *\n * Default 6000 (~1,500 tokens), which fits common embedding windows including\n * nomic-embed-text's 2,048 tokens with headroom. Values above the 16,000\n * hard ceiling are clamped to it; the ceiling is a security control and\n * configuration cannot raise it.\n */\n maxEmbedChars?: 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 * Engine default for `ReadOptions.excludeDrafts` and\n * `GraphTraversalOptions.excludeDrafts`. Default false (drafts visible).\n */\n excludeDrafts?: boolean;\n /** Evidence check for LLM-authored facts (spec §6). Default off. */\n grounding?: GroundingConfig;\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 * Minimum number of results to retain from each named entity before the global\n * `maxResults` cut. Applied after scoring: the top-N scored results from each\n * named entity are reserved, then remaining slots fill by score as usual.\n *\n * An entity with fewer than N matching results contributes what it has — this is\n * not an error. Floors cannot resurrect a result excluded by `preFilterLimit`.\n *\n * Only meaningful when `entityId` is an array; ignored for single-string calls.\n * Ignored when `query` is empty — that path uses recency ordering and ignores\n * `tierWeights` as well.\n *\n * Throws `WikiInvalidReadOptions` when a floor cannot be satisfied by\n * construction: floors summing above `maxResults`, a floor on an entity excluded\n * by `tierWeights: 0`, or a floor keyed to an entity not in `entityId`.\n */\n tierFloors?: Record<string, number>;\n /**\n * When true, facts whose `lifecycle_status` is `'draft'` are excluded before\n * `maxResults`, `tierFloors` and every other cut, on every read path.\n * Resolves call → `WikiConfig.excludeDrafts` → false.\n */\n excludeDrafts?: 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 // --- OKF v0.2 surface (additive; see spec §4.6) ---\n /** OKF v0.2 lifecycle state. Defaults to 'stable' on the SQL side. */\n lifecycle_status?: 'draft' | 'stable' | 'deprecated';\n /** Absolute YYYY-MM-DD cutoff for staleness. NULL = never stale. */\n stale_after?: number | null;\n /** Actor string per OKF v0.2 §7 (`<producer>/<version>`, `human:<id>`, `process:<id>`). */\n generated_by?: string | null;\n /** Full list of OKF v0.2 sources (provenance). */\n okf_sources?: OkfSource[];\n /** Chronological list of verification events. */\n okf_verified?: OkfVerifiedEntry[];\n /** Sibling-of-sources usage window object. */\n okf_usage_window?: OkfSourceUsageWindow | null;\n /** Convenience: epoch ms of the latest verifier. Derived; mirrored for query speed. */\n last_verified_at?: number | null;\n /** Convenience: actor string of the latest verifier. Derived; mirrored for query speed. */\n last_verified_by?: string | null;\n /**\n * Hydrated at read time: `isStaleAfter(stale_after, now)`. `true` once the\n * absolute stale_after cutoff has passed; `false` otherwise (including when\n * stale_after is null). Surfaced per spec §2.7 + §5.3 so hosts can render\n * staleness without recomputing. Always present on read paths that go\n * through `mapRowToFact` / `mapRowToTask`.\n */\n isStale?: boolean;\n /**\n * Hydrated at read time: `deriveTrustTier(okf_verified)`. `'human-reviewed'`\n * when any entry has `by: 'human:...'`, `'machine-confirmed'` when entries\n * exist without a human verifier, `'unverified'` when okf_verified is empty.\n * Surfaced per spec §2.7 + §5.3. Always present on read paths that go through\n * `mapRowToFact` / `mapRowToTask`.\n */\n trustTier?: 'unverified' | 'machine-confirmed' | 'human-reviewed';\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 // --- OKF v0.2 surface (additive; see spec §4.6) ---\n lifecycle_status?: 'draft' | 'stable' | 'deprecated';\n stale_after?: number | null;\n generated_by?: string | null;\n okf_sources?: OkfSource[];\n okf_verified?: OkfVerifiedEntry[];\n okf_usage_window?: OkfSourceUsageWindow | null;\n last_verified_at?: number | null;\n last_verified_by?: string | null;\n /**\n * Hydrated at read time: `isStaleAfter(stale_after, now)`. Mirrors\n * {@link WikiFact.isStale} (spec §2.5 + §5.3 treat stale_after symmetrically\n * for tasks and facts). Always present on read paths that go through\n * `mapRowToTask`.\n */\n isStale?: boolean;\n /**\n * Hydrated at read time: `deriveTrustTier(okf_verified)`. Mirrors\n * {@link WikiFact.trustTier}. Always present on read paths that go through\n * `mapRowToTask`.\n */\n trustTier?: 'unverified' | 'machine-confirmed' | 'human-reviewed';\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 * When true, draft facts are dead ends for *discovered* nodes (not\n * discovered, not traversed through). Does not gate the anchor.\n * Resolves call → `WikiConfig.excludeDrafts` → false.\n */\n excludeDrafts?: boolean;\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 /** Quotes the model copied from its source; see `WikiConfig.grounding`. Never persisted. */\n evidence?: string[];\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 * Called with the provider as `this`, so class-based adapters may keep\n * SDK handles and config on the instance.\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 * Called with the provider as `this` (never detached), same as\n * `generateText`, so class-based adapters may read their own state.\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 * Optional non-generative classifier (System-One models such as Jev,\n * OpenJev, or a local ONNX classifier). Core never calls it unless the host\n * opts in (e.g. `WikiConfig.ontology.backfillClassifier: 'auto'`); merely\n * providing it changes nothing (REQ-COMPAT-01.5). Output is validated as\n * untrusted.\n */\n classify?: (request: ClassifyRequest) => Promise<ClassifyResponse>;\n}\n\n/** One typed question for a classifier. Vendor-neutral (Jev `noul` ↔ `binary`). */\nexport type ClassifierQuestion =\n | { kind: 'choice'; options: string[]; instructions?: string }\n | { kind: 'binary'; instructions: string }\n | { kind: 'score'; levels: string[]; instructions?: string };\n\n/** One state evaluated against a map of questions (many questions per state, one state per call). */\nexport interface ClassifyRequest {\n state: string;\n questions: Record<string, ClassifierQuestion>;\n}\n\nexport type ClassifierAnswer =\n | { kind: 'choice'; choice: string; confidence: number; probabilities: Record<string, number> }\n | { kind: 'binary'; probability: number }\n | { kind: 'score'; score: number; confidence: number; probabilities: number[] };\n\nexport interface ClassifyResponse {\n answers: Record<string, ClassifierAnswer>;\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\n/** Severity is fixed per code (spec §4.2.6). */\nexport type WikiDiagnosticSeverity = 'info' | 'warn' | 'error';\n\n/**\n * Closed for this release series, but new codes are added in minor versions:\n * hosts must tolerate codes they do not recognize.\n */\nexport type WikiDiagnosticCode =\n | 'ingest_chunk_failed'\n | 'fact_rejected'\n | 'task_rejected'\n | 'fact_deduplicated'\n | 'edge_dropped'\n | 'embedding_failed'\n | 'hook_failed'\n | 'background_job_failed'\n | 'heal_skipped'\n | 'grounding_missing'\n | 'grounding_failed'\n | 'classification_low_confidence'\n | 'classification_invalid';\n\n/** The service run that emitted the diagnostic. */\nexport type WikiDiagnosticOperation =\n | 'ingest' | 'upsertGraph' | 'librarian' | 'heal' | 'ontologyBackfill' | 'reembed' | 'importDump' | 'write';\n\n/** `'auto'` when a write threshold started the run (auto-librarian / auto-heal); `'call'` when the host did. */\nexport type WikiDiagnosticTrigger = 'call' | 'auto';\n\n/** Identifiers only — never titles, bodies, quotes, LLM output, provider messages, or hashes of content. */\nexport interface WikiDiagnosticDetail {\n factId?: string;\n sourceRef?: string;\n chunkIndex?: number;\n edgeType?: string;\n /** Manifest slug of the edge source, when resolved. */\n sourceNodeType?: string;\n /** Manifest slug of the edge target, when resolved. */\n targetNodeType?: string;\n /** Position of a rejected item in the LLM response array. */\n itemIndex?: number;\n /** Machine-readable sub-reason, e.g. `'target_not_found'`. */\n reason?: string;\n /** Aggregated `ingest_chunk_failed` only; the first 20 failed chunk indexes. */\n chunkIndexes?: number[];\n /** Aggregated emissions only. */\n count?: number;\n}\n\nexport interface WikiDiagnostic {\n code: WikiDiagnosticCode;\n severity: WikiDiagnosticSeverity;\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n entityId: string;\n /** Epoch ms, sampled at emission. */\n at: number;\n /** Fixed template per code. Never contains content. */\n message: string;\n detail?: WikiDiagnosticDetail;\n}\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 /**\n * Receives typed, content-free diagnostics for events core previously\n * dropped silently or only logged (spec §4). Synchronous; a returned promise\n * is ignored. A throwing or rejecting hook never affects the operation that\n * emitted the diagnostic. Existing console output is unchanged whether or\n * not this is set.\n */\n onDiagnostic?: (diagnostic: WikiDiagnostic) => void;\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 /** Sanitized per-entity result floors, when `tierFloors` was supplied and non-empty. */\n tierFloors?: 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 `ingestDocument({ onDuplicateHash: 'throw' })` when a different\n * source_ref in the same entity already holds the supplied source_hash against\n * a live row. Mirrors {@link WikiBusyError}'s anchoring of canonical metadata\n * on the error instance for stable observability.\n */\nexport class WikiDuplicateHashError extends Error {\n readonly canonical: string;\n readonly sourceHash: string;\n readonly entityId: string;\n\n constructor(params: { canonical: string; sourceHash: string; entityId: string }) {\n super(`Duplicate source hash for entity ${params.entityId}; another ref already holds this content`);\n this.name = 'WikiDuplicateHashError';\n this.canonical = params.canonical;\n this.sourceHash = params.sourceHash;\n this.entityId = params.entityId;\n }\n}\n\n/**\n * Thrown by `WikiMemory.upsertGraph` when the persisted ontology mode for the\n * entity is `'strict'` and a caller-supplied node or edge `type` does not\n * resolve against the entity's manifest. Mirrors {@link WikiBusyError}'s\n * anchoring of canonical metadata on the error instance for stable\n * observability. Per C4, the check is pre-flight and all-or-nothing — the\n * first invalid item throws; NONE are written.\n */\nexport class WikiStrictOntologyViolation extends Error {\n readonly entityId: string;\n readonly kind: 'node' | 'edge';\n readonly type: string;\n readonly code = 'WIKI_STRICT_ONTOLOGY_VIOLATION' as const;\n\n constructor(entityId: string, kind: 'node' | 'edge', type: string) {\n super(\n `Out-of-manifest ${kind} type \"${type}\" for entity \"${entityId}\" under strict mode.`,\n );\n this.entityId = entityId;\n this.kind = kind;\n this.type = type;\n this.name = 'WikiStrictOntologyViolation';\n }\n}\n\n/**\n * Thrown by `WikiMemory.upsertGraph`'s C2 probe when the supplied\n * `sourceHash` is already mapped to a *different* `sourceRef` for the same\n * entity. Indicates either a caller-side id-derivation collision, a race with\n * another writer, or — per the C2 known-limitation note in the spec — two\n * source files with genuinely identical content (byte-identical barrel\n * re-exports, blank stubs, vendored boilerplate). In all cases: fail loud.\n */\nexport class WikiSourceRefHashCollision extends Error {\n readonly entityId: string;\n readonly sourceHash: string;\n readonly existingSourceRef: string;\n readonly attemptedSourceRef: string;\n readonly code = 'WIKI_SOURCE_REF_HASH_COLLISION' as const;\n\n constructor(params: {\n entityId: string;\n sourceHash: string;\n existingSourceRef: string;\n attemptedSourceRef: string;\n }) {\n super(\n `Source hash \"${params.sourceHash}\" for entity \"${params.entityId}\" ` +\n `is already mapped to sourceRef \"${params.existingSourceRef}\"; ` +\n `cannot remap to \"${params.attemptedSourceRef}\".`,\n );\n this.entityId = params.entityId;\n this.sourceHash = params.sourceHash;\n this.existingSourceRef = params.existingSourceRef;\n this.attemptedSourceRef = params.attemptedSourceRef;\n this.name = 'WikiSourceRefHashCollision';\n }\n}\n\n/**\n * Thrown when a graph node ID is already owned by another entity.\n *\n * Raised by `WikiMemory.upsertGraph`'s node-ownership pre-flight and,\n * independently, by `EntryRepository.upsert` for every caller — which is why\n * `ingestDocument` can surface it too (it shares `upsertGraphCore` on its full\n * path and `EntryRepository.upsert` on its partial path).\n *\n * Deliberately carries NO context: no owner entity, node ID, stored content,\n * provenance, or `cause`. A rejection is reachable by whatever supplies the\n * node IDs, so the error must not become a channel for reading another\n * entity's identifiers. The `WIKI_`-prefixed code and fixed message also keep\n * it clear of `extractSqliteCode`, so it passes through the serialized\n * transaction wrapper unwrapped.\n */\nexport class WikiGraphNodeOwnershipConflict extends Error {\n readonly code = 'WIKI_GRAPH_NODE_OWNERSHIP_CONFLICT' as const;\n\n /**\n * Privacy-preserving constructor: accepts no arguments, so neither the foreign\n * owner, the conflicting node ID, the stored content, nor any provenance can\n * leak through this error. The fixed message and `code` are the entire signal.\n *\n * @returns a contextless `WikiGraphNodeOwnershipConflict` instance. See the\n * class-level JSDoc for the privacy rationale.\n */\n\n constructor() {\n super('Graph write rejected because a node ID is unavailable for this entity.');\n this.name = 'WikiGraphNodeOwnershipConflict';\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/**\n * Failure kinds eligible for a persisted embedding failure marker (spec §3.3).\n * `no_provider` never marks (nothing to retry against), and `storage_error`\n * never marks (D3 — a marker is itself a DB write). Defined here, neutral\n * between repositories and services, so EntryRepository can type-narrow the\n * marker kind without importing from services.\n */\nexport type EmbeddingMarkerKind =\n | 'invalid_vector'\n | 'float32_overflow'\n | 'provider_error';\n\n/**\n * Failure record for a single chunk that could not be ingested. Produced by\n * `IngestionService.ingestDocument` and surfaced on the result's `parseFailures`\n * array. `source === 'parse'` for `WikiParseError`-shaped failures (then `tier`\n * is set); `source === 'llm'` for `generateText` rejections (no `tier`).\n *\n * Note: `'ontologyContext'` is reserved but NEVER produced. `buildPromptContext`\n * failures are DB-systemic and propagate as raw throws, not as `parseFailures`.\n */\nexport interface ChunkFailure {\n chunkIndex: number;\n sourceRef: string;\n source: 'parse' | 'llm';\n tier?: 'strict' | 'repair' | 'all';\n position: number | null;\n message: string;\n}\n\n/**\n * Result of `IngestionService.ingestDocument`. The shape WIDENS relative to\n * earlier versions: `ingestedChunks` and `failedChunks` are always present;\n * `parseFailures` is present iff at least one chunk failed.\n *\n * Hosts that destructure `{ truncated, chunks }` see no behavior change.\n * Hosts pattern-matching the entire shape must update to the new fields.\n */\nexport interface IngestDocumentResult {\n truncated: boolean;\n chunks: number;\n ingestedChunks: number;\n failedChunks: number;\n duplicateOf?: string;\n parseFailures?: ChunkFailure[];\n}\n\n/**\n * Thrown by `parseJsonResponse` when both the strict scanner pass and the\n * container-aware repair pass fail to produce a parsable candidate.\n *\n * - `tier: 'strict'` — the existing scanner produced no usable slice (no\n * `{`/`[` at all, or no balanced close). `slice` is the full input text;\n * `position` is the offset of the first `{`/`[`, or `null` when none found.\n * - `tier: 'repair'` — tier 1 found a slice but `JSON.parse` failed; tier 2\n * produced no parsable candidate within `MAX_REPAIR_CANDIDATES`. `slice` is\n * the largest balanced span the walker found; `position` is the offset of\n * the first parse failure within that candidate when known.\n * - `tier: 'all'` — generic catch-all.\n */\nexport class WikiParseError extends Error {\n readonly tier: 'strict' | 'repair' | 'all';\n readonly position: number | null;\n readonly slice: string;\n\n constructor(\n message: string,\n opts: { tier: WikiParseError['tier']; position?: number | null; slice?: string },\n ) {\n super(message);\n this.name = 'WikiParseError';\n this.tier = opts.tier;\n this.position = opts.position ?? null;\n this.slice = opts.slice ?? '';\n }\n}\n\n/**\n * Thrown by `IngestionService.ingestDocument` when every chunk of a document\n * failed (either `parseJsonResponse` or `generateText`). A silent zero-fact\n * ingest is a worse regression than a typed throw — matches existing host\n * semantics (`aws-cloud-agent` Writer Lambda today sees `ingestDocument`\n * throw on any failure).\n */\nexport class WikiIngestEmptyError extends Error {\n readonly parseFailures: ChunkFailure[];\n readonly sourceRef: string;\n readonly chunks: number;\n\n constructor(params: { parseFailures: ChunkFailure[]; sourceRef: string; chunks: number }) {\n const summary = `All ${params.chunks} chunks failed for sourceRef \"${params.sourceRef}\"; see parseFailures for per-chunk detail`;\n super(summary);\n this.name = 'WikiIngestEmptyError';\n this.parseFailures = params.parseFailures;\n this.sourceRef = params.sourceRef;\n this.chunks = params.chunks;\n }\n}\n\n/**\n * Thrown by `read()` when `ReadOptions` contains a request that cannot be\n * satisfied by construction — as opposed to one that merely finds no data.\n */\nexport class WikiInvalidReadOptions extends Error {\n readonly field: string;\n readonly reason: string;\n\n constructor(field: string, reason: string) {\n super(`Invalid ReadOptions.${field}: ${reason}`);\n this.name = 'WikiInvalidReadOptions';\n this.field = field;\n this.reason = reason;\n Object.setPrototypeOf(this, WikiInvalidReadOptions.prototype);\n }\n}\n\n/**\n * Thrown by `promoteDraft` when no live draft with that id exists for the\n * entity: missing, soft-deleted, owned by another entity, or not a draft.\n * Contextless for the same reason as {@link WikiGraphNodeOwnershipConflict}.\n * The `WIKI_` code keeps it clear of `extractSqliteCode`, so it passes through\n * the serialized transaction wrapper unwrapped.\n */\nexport class WikiDraftNotFound extends Error {\n readonly code = 'WIKI_DRAFT_NOT_FOUND' as const;\n\n constructor() {\n super('No draft fact with that id exists for this entity.');\n this.name = 'WikiDraftNotFound';\n Object.setPrototypeOf(this, WikiDraftNotFound.prototype);\n }\n}\n\n/** One page of `listDrafts`. `nextCursor` is opaque; pass it back unchanged. */\nexport interface DraftPage {\n facts: WikiFact[];\n nextCursor: string | null;\n}\n\n","import type { SQLiteAdapter } from '../types';\nimport { WikiTransactionError } from '../types';\nimport { extractSqliteCode } from './sqliteCodes';\n\nexport { extractSqliteCode };\n\n/** True when `err` carries a parseable SQLite code — gates whether the wrapper re-wraps. */\nexport function isDriverError(err: unknown): boolean {\n return extractSqliteCode(err) !== undefined;\n}\n\n/**\n * Returns an adapter with the given methods overridden, delegating everything else\n * (own or class-prototype methods) to `target`.\n *\n * Uses a `Proxy` rather than `Object.create`/object-spread: delegated methods are\n * bound to `target` before being returned, so their receiver (`this`) stays the\n * original adapter instance. That keeps ES `#private` fields and `instanceof`/identity\n * checks inside those methods working — `Object.create` would invoke them with the\n * wrapper as `this` and break both.\n */\nfunction withOverrides(target: SQLiteAdapter, overrides: Partial<SQLiteAdapter>): SQLiteAdapter {\n return new Proxy(target, {\n get(obj, prop, receiver) {\n if (prop in overrides) return Reflect.get(overrides, prop, receiver);\n const value = Reflect.get(obj, prop, obj);\n return typeof value === 'function' ? value.bind(obj) : value;\n },\n }) as SQLiteAdapter;\n}\n\n/**\n * Returns the same adapter with `withTransactionAsync` overridden to throw. Injected\n * by the serialized wrapper onto the `tx` handed to every callback so a *nested*\n * transaction fails loudly instead of deadlocking against the mutex.\n */\nexport function guardReentrancy(tx: SQLiteAdapter): SQLiteAdapter {\n return withOverrides(tx, {\n withTransactionAsync() {\n throw new Error(\n 'Nested withTransactionAsync is not supported: you are already ' +\n 'inside a transaction. Pass the current `tx` down instead of ' +\n 'opening a new transaction.'\n );\n },\n });\n}\n\nconst DEADLOCK_WARN_MS = 10_000;\n\n/**\n * Wraps `withTransactionAsync` in a promise-chain mutex so transactions on the\n * single shared connection run one at a time. Non-transactional reads/writes are\n * untouched. Applied once in the WikiMemory constructor before the adapter reaches\n * any repository or service.\n */\nexport function withSerializedTransactions(db: SQLiteAdapter): SQLiteAdapter {\n let queue: Promise<unknown> = Promise.resolve();\n return withOverrides(db, {\n withTransactionAsync<T>(fn: (tx: SQLiteAdapter) => Promise<T>): Promise<T> {\n // Warns if a call waits >10s for the lock — the signature of the closure-capture\n // deadlock (calling the outer `db` instead of `tx` inside a callback). Cleared the\n // instant the lock is acquired, so it measures queue wait only.\n const warn = setTimeout(() => {\n console.warn(\n '[core-llm-wiki] Transaction queued >10s — possible deadlock. ' +\n 'Inside a transaction callback, use the `tx` parameter, never the ' +\n 'outer database handle.'\n );\n }, DEADLOCK_WARN_MS);\n\n const run = queue\n .catch(() => undefined) // proceed from a settled state; swallow prior outcome\n .then(() => {\n clearTimeout(warn);\n // Re-wrap the tx so a nested withTransactionAsync throws synchronously.\n // Some adapters invoke the callback with no tx handle; fall back to the\n // outer db (same connection). The guard still blocks nested transactions.\n return db.withTransactionAsync((tx) => fn(guardReentrancy(tx ?? db)));\n })\n .catch((e) => {\n // Wrap only driver errors; domain errors reach the caller with instanceof intact.\n throw isDriverError(e)\n ? new WikiTransactionError('Transaction failed', { cause: e })\n : e;\n });\n\n queue = run; // advance the tail; next caller's leading .catch() absorbs this rejection\n return run as Promise<T>;\n },\n });\n}\n","import type { SQLiteAdapter } from '../types';\n\nexport interface Migration {\n version: number;\n description: string;\n run: (db: SQLiteAdapter, prefix: string) => Promise<void>;\n}\n\nexport const MIGRATIONS: Migration[] = [\n {\n version: 1,\n description: 'Rebuild FTS5 with porter unicode61 tokenizer (superseded by v2)',\n run: async (_db, _prefix) => {\n // This migration is superseded by v2 which drops FTS5 entirely.\n // It is kept as a no-op so upgrade paths from v0 do not require FTS5 support.\n },\n },\n {\n version: 2,\n description: 'Remove FTS5; add embedding column for semantic retrieval',\n run: async (db, prefix) => {\n // Drop FTS5 artifacts in a transaction.\n await db.withTransactionAsync(async (tx) => {\n await tx.execAsync(`\n DROP TRIGGER IF EXISTS ${prefix}entries_ai;\n DROP TRIGGER IF EXISTS ${prefix}entries_ad;\n DROP TRIGGER IF EXISTS ${prefix}entries_au;\n DROP TABLE IF EXISTS ${prefix}entries_fts;\n `);\n });\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding')) {\n await db.execAsync(`ALTER TABLE ${prefix}entries ADD COLUMN embedding TEXT`);\n }\n },\n },\n {\n version: 3,\n description: 'Add embedding_blob BLOB column for Float32Array vector storage',\n run: async (db, prefix) => {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'embedding_blob')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN embedding_blob BLOB`\n );\n }\n },\n },\n {\n version: 4,\n description: 'Create outbox table for change data capture',\n run: async (db, prefix) => {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}outbox (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n table_name TEXT NOT NULL,\n record_id TEXT NOT NULL,\n operation TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n CREATE INDEX IF NOT EXISTS ${prefix}outbox_entity_id_created_at\n ON ${prefix}outbox (entity_id, created_at);\n `);\n },\n },\n {\n version: 5,\n description: 'Add okf_type to entries/tasks for OKF type fidelity; create edges table for OKF graph import',\n run: async (db, prefix) => {\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n if (!cols.some(c => c.name === 'okf_type')) {\n await db.execAsync(`ALTER TABLE ${prefix}${table} ADD COLUMN okf_type TEXT`);\n }\n }\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}edges (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n edge_type TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n UNIQUE(entity_id, source_id, target_id, edge_type)\n );\n CREATE INDEX IF NOT EXISTS ${prefix}edges_entity_idx ON ${prefix}edges (entity_id);\n `);\n },\n },\n {\n version: 6,\n description: 'Add entity_manifests table for per-entity ontology state',\n run: async (db, prefix) => {\n await db.execAsync(`\n CREATE TABLE IF NOT EXISTS ${prefix}entity_manifests (\n entity_id TEXT PRIMARY KEY,\n mode TEXT NOT NULL DEFAULT 'off',\n manifest_json TEXT NOT NULL DEFAULT '{\"node_types\":[],\"edge_types\":[]}',\n updated_at INTEGER NOT NULL\n );\n `);\n },\n },\n {\n version: 7,\n description: 'Add ontology_checked_at to entries for ontology backfill recheck cooldown',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'ontology_checked_at')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN ontology_checked_at INTEGER`\n );\n }\n },\n },\n {\n version: 8,\n description: 'Add heal_checked_at to entries for heal recheck cooldown',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5/v7.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n if (!cols.some(c => c.name === 'heal_checked_at')) {\n await db.execAsync(\n `ALTER TABLE ${prefix}entries ADD COLUMN heal_checked_at INTEGER`\n );\n }\n },\n },\n {\n version: 9,\n description: 'add_source_ref_index',\n run: async (db, prefix) => {\n // Defense-in-depth safety net for the #79 TOCTOU race fix. The original\n // design put a UNIQUE index on `entries(entity_id, source_hash)`, but\n // that conflates per-fact and per-sourceRef granularity: a single\n // `ingestDocument` writes N facts that all share\n // (entity_id, source_ref, source_hash), and the 2nd–Nth inserts hit\n // SQLITE_CONSTRAINT_UNIQUE inside the normal multi-fact path. The\n // correct invariant is \"at most one sourceRef per (entity, hash)\", so\n // the constraint lives on a dedicated per-(entity, hash) table that\n // records the canonical sourceRef for each hash. See\n // docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n //\n // Abort path: if any (entity_id, source_hash) already has live rows\n // under multiple distinct source_refs, a previous race beat the new\n // app-level guard. The migration aborts with an actionable error\n // rather than auto-resolving — auto-resolving would either destroy\n // facts or pick a wrong canonical, both worse than failing safe. The\n // thrown error escapes setup() BEFORE the CREATE TABLE runs, so the\n // new table is never created and schema_version is never advanced.\n const duplicates = await db.getAllAsync<{ entity_id: string; source_hash: string; n_refs: number }>(\n `SELECT entity_id, source_hash, COUNT(DISTINCT source_ref) AS n_refs\n FROM ${prefix}entries\n WHERE deleted_at IS NULL AND source_hash IS NOT NULL\n GROUP BY entity_id, source_hash\n HAVING COUNT(DISTINCT source_ref) > 1`\n );\n if (duplicates.length > 0) {\n const sample = duplicates\n .slice(0, 5)\n .map(d => `(entity_id=${d.entity_id}, source_hash=${d.source_hash.slice(0, 12)}…, n_refs=${d.n_refs})`)\n .join(', ');\n throw new Error(\n `Migration v9 (add_source_ref_index) failed: existing live rows have multiple sourceRefs sharing a hash. ` +\n `Found ${duplicates.length} duplicate (entity_id, source_hash) groups. ` +\n `First ${Math.min(5, duplicates.length)}: ${sample}. ` +\n `Resolve each by calling forget({ sourceRef: <loser> }) for the offending sourceRef, then re-run setup.`\n );\n }\n await db.execAsync(\n `CREATE TABLE IF NOT EXISTS ${prefix}source_ref_index (\n id TEXT PRIMARY KEY,\n entity_id TEXT NOT NULL,\n source_hash TEXT NOT NULL,\n source_ref TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n deleted_at INTEGER\n );\n CREATE UNIQUE INDEX IF NOT EXISTS ${prefix}idx_source_ref_hash\n ON ${prefix}source_ref_index (entity_id, source_hash)\n WHERE deleted_at IS NULL;`\n );\n // Backfill: for each (entity_id, source_hash) group with live entries,\n // pick the sourceRef of the entry that wins\n // `ROW_NUMBER() OVER (PARTITION BY entity_id, source_hash ORDER BY updated_at ASC, id ASC) = 1`.\n // The tie-breaker `id ASC` matches `findLatestSourceHash` ordering so\n // the canonical row is deterministic. INSERT OR IGNORE with a\n // deterministic ID (`sri_<entity_id>:<source_hash>`) makes the backfill\n // idempotent — re-running v9 is a no-op.\n await db.execAsync(\n `INSERT OR IGNORE INTO ${prefix}source_ref_index (id, entity_id, source_hash, source_ref, created_at, deleted_at)\n SELECT\n 'sri:' || entity_id || ':' || source_hash,\n entity_id,\n source_hash,\n source_ref,\n updated_at,\n NULL\n FROM (\n SELECT\n entity_id, source_hash, source_ref, updated_at,\n ROW_NUMBER() OVER (\n PARTITION BY entity_id, source_hash\n ORDER BY updated_at ASC, id ASC\n ) AS rn\n FROM ${prefix}entries\n WHERE deleted_at IS NULL\n AND source_hash IS NOT NULL\n AND source_ref IS NOT NULL\n ) ranked\n WHERE rn = 1;`\n );\n },\n },\n {\n version: 10,\n description: 'OKF v0.2: add lifecycle_status, stale_after, generated_by, last_verified_*, okf_sources, okf_verified, okf_usage_window to entries and tasks',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction — same constraint\n // as v2/v3/v5/v7/v8. We do all eight columns per table, then indexes, inside\n // a single execAsync batch where possible. SQLite ALTER on the same table from\n // separate statements is fine; we just can't wrap it in BEGIN...COMMIT.\n for (const table of ['entries', 'tasks'] as const) {\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}${table})`\n );\n const existing = new Set(cols.map((c) => c.name));\n const adds: Array<[string, string]> = [\n ['lifecycle_status', `ALTER TABLE ${prefix}${table} ADD COLUMN lifecycle_status TEXT NOT NULL DEFAULT 'stable'`],\n ['stale_after', `ALTER TABLE ${prefix}${table} ADD COLUMN stale_after INTEGER`],\n ['generated_by', `ALTER TABLE ${prefix}${table} ADD COLUMN generated_by TEXT`],\n ['last_verified_at', `ALTER TABLE ${prefix}${table} ADD COLUMN last_verified_at INTEGER`],\n ['last_verified_by', `ALTER TABLE ${prefix}${table} ADD COLUMN last_verified_by TEXT`],\n ['okf_sources', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_sources TEXT`],\n ['okf_verified', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_verified TEXT`],\n ['okf_usage_window', `ALTER TABLE ${prefix}${table} ADD COLUMN okf_usage_window TEXT`],\n ];\n for (const [name, sql] of adds) {\n if (!existing.has(name)) await db.execAsync(sql);\n }\n }\n await db.execAsync(`\n CREATE INDEX IF NOT EXISTS ${prefix}entries_lifecycle_status_idx ON ${prefix}entries(lifecycle_status);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_stale_after_idx ON ${prefix}entries(stale_after);\n CREATE INDEX IF NOT EXISTS ${prefix}entries_last_verified_at_idx ON ${prefix}entries(last_verified_at);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_lifecycle_status_idx ON ${prefix}tasks(lifecycle_status);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_stale_after_idx ON ${prefix}tasks(stale_after);\n CREATE INDEX IF NOT EXISTS ${prefix}tasks_last_verified_at_idx ON ${prefix}tasks(last_verified_at);\n `);\n },\n },\n {\n version: 11,\n description: 'Add embedding_failed_at, embedding_failure_kind, embedding_attempts to entries for embed retry state',\n run: async (db, prefix) => {\n // ALTER TABLE ADD COLUMN must run outside any explicit transaction —\n // SQLite (and expo-sqlite) do not permit schema alterations inside\n // a BEGIN...COMMIT block. Same pattern as v2/v3/v5/v7/v8/v10.\n // Only the entries table gets these columns — tasks are never embedded.\n const cols = await db.getAllAsync<{ name: string }>(\n `PRAGMA table_info(${prefix}entries)`\n );\n const existing = new Set(cols.map((c) => c.name));\n const adds: Array<[string, string]> = [\n ['embedding_failed_at', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_failed_at INTEGER`],\n ['embedding_failure_kind', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_failure_kind TEXT`],\n ['embedding_attempts', `ALTER TABLE ${prefix}entries ADD COLUMN embedding_attempts INTEGER NOT NULL DEFAULT 0`],\n ];\n for (const [name, sql] of adds) {\n if (!existing.has(name)) await db.execAsync(sql);\n }\n },\n },\n];\n\n// Verify MIGRATIONS are in strictly ascending version order at module load time.\n// This prevents skipped or repeated migrations caused by out-of-order entries.\nfor (let i = 1; i < MIGRATIONS.length; i++) {\n if (MIGRATIONS[i].version <= MIGRATIONS[i - 1].version) {\n throw new Error(\n `migrations.ts: MIGRATIONS must be in strictly ascending version order. ` +\n `Found version ${MIGRATIONS[i].version} after ${MIGRATIONS[i - 1].version} at index ${i}.`\n );\n }\n}\n\n// Derived from the last (highest) migration version so it never drifts out of sync.\nexport const CURRENT_SCHEMA_VERSION =\n MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].version : 0;\n","/**\n * Abstract base for all repositories.\n * Provides db accessor + prefix-aware helpers.\n */\nexport abstract class BaseRepository {\n protected db: import('../types').SQLiteAdapter;\n protected prefix: string;\n\n constructor(db: import('../types').SQLiteAdapter, prefix: string) {\n this.db = db;\n this.prefix = prefix;\n }\n\n /**\n * Return the DB executor for a given transaction handle.\n * If tx is provided, use it; otherwise fall back to this.db.\n */\n protected getExecutor(tx?: import('../types').SQLiteAdapter): import('../types').SQLiteAdapter {\n return tx ?? this.db;\n }\n}\n","/**\n * Shared JSON column parsers for repository row mappers.\n *\n * SQLite JSON1 columns return a string when read; in-memory callers expect the\n * parsed value. The parsers tolerate both shapes so callers stay\n * implementation-agnostic (e.g. tests pass arrays directly, drivers return\n * strings). Hoisted to module scope so each row mapping doesn't reallocate\n * two closures (was the case before refactor — see #90 review).\n */\n\nexport function parseJsonArray<T>(s: unknown, fallback: T[]): T[] {\n if (Array.isArray(s)) return s as T[];\n if (typeof s === 'string' && s.length > 0) {\n try {\n const p = JSON.parse(s);\n if (Array.isArray(p)) return p as T[];\n } catch {\n // fall through to fallback\n }\n }\n return fallback;\n}\n\n/**\n * Arrays are rejected in both branches: `typeof [] === 'object'`, so a\n * malformed `okf_usage_window` of `[]` would otherwise be handed back as an\n * object and re-exported with an invalid shape (see #90 review).\n */\nexport function parseJsonObject<T>(s: unknown, fallback: T | null = null): T | null {\n if (s && typeof s === 'object' && !Array.isArray(s)) return s as T;\n if (typeof s === 'string' && s.length > 0) {\n try {\n const p = JSON.parse(s);\n if (p && typeof p === 'object' && !Array.isArray(p)) return p as T;\n } catch {\n // fall through to fallback\n }\n }\n return fallback;\n}\n","import type { SQLiteAdapter, WikiFact, EmbeddingMarkerKind } from '../types';\nimport { WikiGraphNodeOwnershipConflict } from '../types';\nimport { BaseRepository } from './BaseRepository';\nimport { OutboxRepository } from './OutboxRepository';\nimport { parseJsonArray, parseJsonObject } from './rowMappers';\nimport { isStaleAfter, deriveTrustTier } from '@equationalapplications/core-okf';\n\nexport type EntryRowMetadata = {\n id: string;\n entity_id: string;\n updated_at: number | null;\n access_count: number | null;\n};\n\nexport type EntryRowWithEmbeddings = EntryRowMetadata & {\n embedding_blob: Uint8Array | null;\n embedding: string | null;\n};\n\n/**\n * One row of the reembed candidate scan. `findAllForReembed` does `SELECT *`,\n * so the marker columns come back at runtime; naming them here makes that\n * dependency visible to the compiler instead of hiding it behind a cast in\n * MaintenanceService.runReembed (spec §4.4).\n */\nexport type ReembedCandidateRow = WikiFact & {\n embedding_blob?: Uint8Array | null;\n embedding_failed_at?: number | null;\n embedding_failure_kind?: string | null;\n embedding_attempts?: number | null;\n};\n\nfunction mapRowToFact(row: any): WikiFact {\n const tags: string[] = (() => {\n if (Array.isArray(row.tags)) return row.tags;\n try { const p = JSON.parse(row.tags as string); if (Array.isArray(p)) return p; } catch {}\n return [];\n })();\n\n const okf_verified = parseJsonArray<NonNullable<WikiFact['okf_verified']>[number]>(row.okf_verified, []);\n // Hydrate per spec §2.7 + §5.3: surface isStale/trustTier so hosts don't have to\n // re-call the core-okf helpers. Sampled once per row rather than once per call\n // because `now` here means \"as of this hydration\" — using a stable per-call\n // value would shift staleness while we're mapping sibling rows in the same\n // read. Date.now() is cheap enough that per-row sampling is fine.\n const now = Date.now();\n const staleAfterRaw = row.stale_after != null ? Number(row.stale_after) : null;\n\n return {\n id: row.id,\n entity_id: row.entity_id,\n title: row.title,\n body: row.body,\n tags,\n confidence: row.confidence,\n source_type: row.source_type,\n source_hash: row.source_hash ?? null,\n source_ref: row.source_ref ?? null,\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at),\n last_accessed_at: (row.last_accessed_at === null || row.last_accessed_at === undefined)\n ? null\n : Number(row.last_accessed_at),\n deleted_at: row.deleted_at != null ? Number(row.deleted_at) : null,\n access_count: Number(row.access_count ?? 0),\n okf_type: row.okf_type ?? null,\n // OKF v0.2\n lifecycle_status: (row.lifecycle_status ?? 'stable') as WikiFact['lifecycle_status'],\n stale_after: staleAfterRaw,\n generated_by: row.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiFact['okf_sources']>[number]>(row.okf_sources, []),\n okf_verified,\n okf_usage_window: parseJsonObject<NonNullable<WikiFact['okf_usage_window']>>(row.okf_usage_window),\n last_verified_at: row.last_verified_at != null ? Number(row.last_verified_at) : null,\n last_verified_by: row.last_verified_by ?? null,\n // Spec §2.7 + §5.3: hydrate so read() consumers don't re-call the helpers.\n isStale: isStaleAfter(staleAfterRaw, now),\n trustTier: deriveTrustTier(okf_verified),\n };\n}\n\nfunction normalizeEmbeddingBlobValue(blob: unknown): Uint8Array | null {\n if (blob instanceof Uint8Array) return blob;\n if (blob !== null && blob !== undefined && typeof blob === 'object') {\n const obj = blob as Record<string, unknown>;\n if (obj['type'] === 'Buffer' && Array.isArray(obj['data'])) {\n return new Uint8Array(obj['data'] as number[]);\n }\n const entries = Object.keys(obj);\n if (entries.length > 0 && entries.every((k) => /^\\d+$/.test(k))) {\n const len = entries.length;\n const arr = new Uint8Array(len);\n for (let i = 0; i < len; i++) arr[i] = (obj[String(i)] as number) ?? 0;\n return arr;\n }\n }\n return null;\n}\n\n/** Mapper that preserves embedding_blob for export/import round-tripping. */\nfunction mapRowToFactWithBlobs(row: any): WikiFact {\n const base = mapRowToFact(row);\n const embeddingBlob = normalizeEmbeddingBlobValue(row.embedding_blob);\n return embeddingBlob ? { ...base, embedding_blob: embeddingBlob } : base;\n}\n\n\nexport class EntryRepository extends BaseRepository {\n private chunkSize = 500;\n\n constructor(db: SQLiteAdapter, prefix: string, private outbox: OutboxRepository) {\n super(db, prefix);\n }\n\n /**\n * Fetch facts by IDs, optionally scoped to entity IDs.\n * Returns facts in the order of the input IDs (first match wins).\n */\n async findByIds(\n ids: readonly string[],\n scopedEntityIds?: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows: any[] = [];\n const entityClause = scopedEntityIds && scopedEntityIds.length > 0\n ? ` AND entity_id IN (${scopedEntityIds.map(() => '?').join(',')})`\n : '';\n const entityParams = scopedEntityIds ?? [];\n\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE id IN (${placeholders})${entityClause} AND deleted_at IS NULL`,\n [...chunk, ...entityParams],\n );\n rows.push(...chunkRows);\n }\n\n const byId = new Map(rows.map(r => [r.id, r]));\n return ids\n .map(id => byId.get(id))\n .filter((r): r is any => r !== undefined)\n .map(mapRowToFact);\n }\n\n /**\n * Upsert a WikiFact. Nullable fields set to null when fact value is null.\n * Returns { changes, lastInsertRowId }.\n * `tx` is REQUIRED to ensure atomic outbox staging.\n *\n * OKF metadata discipline (spec §2.5 + DAO checklist §8): content writes\n * MUST NOT silently overwrite OKF metadata that a caller didn't supply. The\n * previous CASE WHEN IS NULL guards around `lifecycle_status`, etc. were\n * dead because the bind always supplied a non-null value (notably\n * `fact.lifecycle_status ?? 'stable'`), so excluded.X was never NULL and\n * an UPDATE rewrote an existing `deprecated` row to `stable`. We now omit\n * these columns from the SET clause entirely — SQLite's ON CONFLICT UPDATE\n * leaves untouched columns at their existing row value, which is exactly\n * the preservation semantics we want for content writes. Callers that\n * intentionally want to overwrite OKF metadata should use\n * {@link upsertForImport} (always-replace semantics for that path).\n * New-row INSERTs still bind a value so the column is populated; if the\n * caller supplied nothing, the schema DEFAULT 'stable' applies when the\n * bind is bound as 'stable' explicitly here.\n *\n * Marker discipline (spec §4.1): a conflict carrying a real\n * `embedding_blob` clears the embedding failure markers, because the row now\n * HAS a valid embedding and a surviving marker would be a self-contradictory\n * diagnostic that inflates runReembed's permanentlyFailed counter. A conflict\n * with no blob leaves marker state alone, matching the \"absent means don't\n * touch\" semantics used for embedding_blob itself.\n *\n * Graph node ownership (spec §2.4 + §3, REQ-OWN-01 + REQ-GRAPH-01): entry\n * IDs share one database-wide namespace, so an ID stays owned by its\n * existing entity for as long as the row exists — soft deletion included.\n * The pre-write lookup already reads the existing row for OKF metadata; we\n * project `entity_id` off that same SELECT and reject the write before\n * any outbox payload construction when the stored owner differs from\n * `fact.entity_id`. Soft-deleted foreign rows keep their IDs reserved;\n * permanent reservation is NOT introduced, so a physically absent ID may\n * still be inserted under the requested entity. The ON CONFLICT UPDATE SET\n * clause carries a final `WHERE entries.entity_id = excluded.entity_id`\n * guard so the database itself refuses a cross-owner row overwrite even if\n * a future caller bypasses the pre-write check. When `runAsync` reports\n * 0 changes (a legitimate conflict-suppressed write, OR an adapter that\n * under-reports a permitted write) we re-read the stored owner; only a\n * foreign owner throws — this is local defensive behavior, not permission\n * for adapters to under-report. The thrown error is\n * `WikiGraphNodeOwnershipConflict` (no owner, node ID, or stored content\n * is disclosed). Upserts that pass both gates retain existing same-entity\n * update + resurrection semantics.\n */\n async upsert(fact: WikiFact, tx: SQLiteAdapter): Promise<{ changes: number; lastInsertRowId: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const tagsJson = JSON.stringify(fact.tags);\n const embeddingBlob = this.normalizeEmbeddingBlob(fact.embedding_blob);\n\n const existingRow = await executor.getFirstAsync<{\n id: string;\n entity_id: string;\n lifecycle_status: string;\n stale_after: number | null;\n generated_by: string | null;\n okf_sources: string | null;\n okf_verified: string | null;\n okf_usage_window: string | null;\n last_verified_at: number | null;\n last_verified_by: string | null;\n }>(\n `SELECT id, entity_id, lifecycle_status, stale_after, generated_by,\n okf_sources, okf_verified, okf_usage_window,\n last_verified_at, last_verified_by\n FROM ${this.prefix}entries WHERE id = ?`,\n [fact.id],\n );\n\n // Entry IDs share one global namespace, so an ID stays owned by its\n // existing entity for as long as the row exists — soft deletion included.\n // Reject here, before any write or outbox payload construction. This costs\n // one extra column on a SELECT the method already ran, not a new query.\n if (existingRow && existingRow.entity_id !== fact.entity_id) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n\n const operation = fact.deleted_at ? 'DELETE' : (existingRow ? 'UPDATE' : 'INSERT');\n\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entries (\n id, entity_id, title, body, tags, confidence, source_type,\n source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count,\n deleted_at, embedding_blob, embedding, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n title = excluded.title,\n body = excluded.body,\n tags = excluded.tags,\n confidence = excluded.confidence,\n source_type = excluded.source_type,\n source_hash = excluded.source_hash,\n source_ref = excluded.source_ref,\n updated_at = excluded.updated_at,\n last_accessed_at = excluded.last_accessed_at,\n access_count = excluded.access_count,\n deleted_at = excluded.deleted_at,\n embedding_blob = CASE WHEN excluded.embedding_blob IS NULL THEN embedding_blob ELSE excluded.embedding_blob END,\n embedding = NULL,\n embedding_failed_at = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failed_at END,\n embedding_failure_kind = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failure_kind END,\n embedding_attempts = CASE WHEN excluded.embedding_blob IS NOT NULL THEN 0 ELSE embedding_attempts END,\n okf_type = excluded.okf_type\n WHERE ${this.prefix}entries.entity_id = excluded.entity_id`,\n [\n fact.id,\n fact.entity_id,\n fact.title,\n fact.body,\n tagsJson,\n fact.confidence,\n fact.source_type,\n fact.source_hash,\n fact.source_ref,\n fact.created_at,\n now,\n fact.last_accessed_at === null ? null : fact.last_accessed_at,\n fact.access_count,\n fact.deleted_at ?? null,\n embeddingBlob ?? null,\n null,\n fact.okf_type ?? null,\n // OKF v0.2 metadata — bound for INSERT only; ON CONFLICT UPDATE\n // preserves the existing row values (these columns are intentionally\n // absent from the SET clause above).\n fact.lifecycle_status ?? 'stable',\n fact.stale_after ?? null,\n fact.generated_by ?? null,\n fact.last_verified_at ?? null,\n fact.last_verified_by ?? null,\n fact.okf_sources ? JSON.stringify(fact.okf_sources) : null,\n fact.okf_verified ? JSON.stringify(fact.okf_verified) : null,\n fact.okf_usage_window ? JSON.stringify(fact.okf_usage_window) : null,\n ],\n );\n\n // A suppressed conflict-update reports 0 (see the SQLiteAdapter contract).\n // A permitted write that an adapter under-reports as 0 also lands here, so\n // confirm ownership from the stored row rather than inferring it from the\n // count. A foreign owner rejects; a missing row means the adapter dropped\n // the write (impossible under real SQLite), so fail rather than publish an\n // outbox event for state that does not exist.\n if (result.changes === 0) {\n const stored = await tx.getFirstAsync<{ entity_id: string }>(\n `SELECT entity_id FROM ${this.prefix}entries WHERE id = ?`,\n [fact.id],\n );\n if (!stored) {\n throw new Error('Entry upsert reported no change and stored no row; the SQLiteAdapter did not perform the write');\n }\n if (stored.entity_id !== fact.entity_id) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n }\n\n // Outbox payload mirrors what is actually persisted. On UPDATE, the SET\n // clause intentionally omits the OKF metadata columns so the prior row\n // values win — so `fact.X` here would describe state we did NOT write.\n // Re-read those columns from the stored row and overlay them onto the\n // caller-supplied payload before publishing (#90 review).\n const persistedOkf = existingRow\n ? {\n lifecycle_status: (existingRow.lifecycle_status ?? 'stable') as WikiFact['lifecycle_status'],\n stale_after: existingRow.stale_after != null ? Number(existingRow.stale_after) : null,\n generated_by: existingRow.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiFact['okf_sources']>[number]>(existingRow.okf_sources, []),\n okf_verified: parseJsonArray<NonNullable<WikiFact['okf_verified']>[number]>(existingRow.okf_verified, []),\n okf_usage_window: parseJsonObject<NonNullable<WikiFact['okf_usage_window']>>(existingRow.okf_usage_window),\n last_verified_at: existingRow.last_verified_at != null ? Number(existingRow.last_verified_at) : null,\n last_verified_by: existingRow.last_verified_by ?? null,\n }\n : null;\n await this.outbox.push({\n entityId: fact.entity_id,\n tableName: 'entries',\n recordId: fact.id,\n operation,\n payload: persistedOkf ? { ...fact, ...persistedOkf } : fact,\n }, tx);\n\n return result;\n }\n\n /**\n * Normalize an embedding blob value to Uint8Array or null.\n */\n private normalizeEmbeddingBlob(blob: unknown): Uint8Array | null {\n return normalizeEmbeddingBlobValue(blob);\n }\n\n /**\n * Fetch existing rows by IDs and return id/entity_id/updated_at for import collision resolution.\n */\n async findExistingMetadataByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; updated_at: number }>> {\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; entity_id: string; updated_at: number }> = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}entries WHERE id IN (${placeholders})`,\n chunk,\n );\n rows.push(...chunkRows.map((row) => ({ id: row.id, entity_id: row.entity_id, updated_at: Number(row.updated_at) })));\n }\n return rows;\n }\n\n async findIdById(id: string, entityId: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ?`,\n [id, entityId],\n );\n return row?.id ?? null;\n }\n\n async findIdsBySource(\n entityId: string,\n sourceRef: string | null,\n sourceHash: string | null,\n tx?: SQLiteAdapter,\n includeDeleted = false,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n let sql = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ?`;\n const args: unknown[] = [entityId];\n if (sourceRef !== null) {\n sql += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash !== null) {\n sql += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n if (!includeDeleted) {\n sql += ` AND deleted_at IS NULL`;\n }\n const rows = await executor.getAllAsync<{ id: string }>(sql, args);\n return rows.map((row) => row.id);\n }\n\n async upsertForImport(fact: WikiFact, tx: SQLiteAdapter): Promise<{ changes: number; lastInsertRowId: number }> {\n const executor = this.getExecutor(tx);\n const tagsJson = JSON.stringify(fact.tags);\n const embeddingBlob = this.normalizeEmbeddingBlob(fact.embedding_blob);\n\n // Import is replace semantics: a re-imported fact whose OKF metadata\n // cleared (stale_after removed, generated_by removed, etc.) MUST overwrite\n // the prior row's value. The previous CASE WHEN IS NULL guards preserved\n // the old database values instead, so an \"absent in dump\" never cleared.\n // Direct `= excluded.X` ensures the dump is authoritative.\n //\n // WARNING: unlike `upsert`, this SQL re-parents a conflicting row\n // (`entity_id = excluded.entity_id`, no owner predicate). It is safe only\n // because ImportExportService skips foreign-owned IDs before calling it.\n // Do not model a new write path on this method; use `upsert`.\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entries (\n id, entity_id, title, body, tags, confidence, source_type,\n source_hash, source_ref, created_at, updated_at, last_accessed_at, access_count,\n deleted_at, embedding_blob, embedding, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n title = excluded.title,\n body = excluded.body,\n tags = excluded.tags,\n confidence = excluded.confidence,\n source_type = excluded.source_type,\n source_hash = excluded.source_hash,\n source_ref = excluded.source_ref,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at,\n last_accessed_at = excluded.last_accessed_at,\n access_count = excluded.access_count,\n deleted_at = excluded.deleted_at,\n embedding_blob = excluded.embedding_blob,\n embedding = NULL,\n embedding_failed_at = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failed_at END,\n embedding_failure_kind = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failure_kind END,\n embedding_attempts = CASE WHEN excluded.embedding_blob IS NOT NULL THEN 0 ELSE embedding_attempts END,\n okf_type = excluded.okf_type,\n lifecycle_status = excluded.lifecycle_status,\n stale_after = excluded.stale_after,\n generated_by = excluded.generated_by,\n last_verified_at = excluded.last_verified_at,\n last_verified_by = excluded.last_verified_by,\n okf_sources = excluded.okf_sources,\n okf_verified = excluded.okf_verified,\n okf_usage_window = excluded.okf_usage_window`,\n [\n fact.id,\n fact.entity_id,\n fact.title,\n fact.body,\n tagsJson,\n fact.confidence,\n fact.source_type,\n fact.source_hash,\n fact.source_ref,\n fact.created_at,\n fact.updated_at,\n fact.last_accessed_at === null ? null : fact.last_accessed_at,\n fact.access_count,\n fact.deleted_at ?? null,\n embeddingBlob ?? null,\n null,\n fact.okf_type ?? null,\n // Same NOT NULL DEFAULT note as in upsert above.\n fact.lifecycle_status ?? 'stable',\n fact.stale_after ?? null,\n fact.generated_by ?? null,\n fact.last_verified_at ?? null,\n fact.last_verified_by ?? null,\n fact.okf_sources ? JSON.stringify(fact.okf_sources) : null,\n fact.okf_verified ? JSON.stringify(fact.okf_verified) : null,\n fact.okf_usage_window ? JSON.stringify(fact.okf_usage_window) : null,\n ],\n );\n\n return result;\n }\n\n /**\n * Soft-delete a single entry by ID scoped to entityId. Sets deleted_at + updated_at.\n * `tx` is REQUIRED to ensure atomic outbox staging.\n */\n async softDelete(entryId: string, entityId: string, tx: SQLiteAdapter): Promise<{ changes: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, entryId, entityId],\n );\n\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: entryId,\n operation: 'DELETE',\n payload: { id: entryId, entity_id: entityId, deleted_at: now },\n }, tx);\n\n return result;\n }\n\n /**\n * Soft-delete entries by source_ref and/or source_hash within a transaction.\n * Stages a DELETE outbox entry for each row in the same transaction.\n * `tx` is REQUIRED.\n * Returns the number of rows deleted.\n */\n async softDeleteBySource(\n entityId: string,\n tx: SQLiteAdapter,\n sourceRef?: string | null,\n sourceHash?: string | null,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n\n let q = `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: any[] = [now, now, entityId];\n if (sourceRef) {\n q += ` AND source_ref = ?`;\n args.push(sourceRef);\n }\n if (sourceHash) {\n q += ` AND source_hash = ?`;\n args.push(sourceHash);\n }\n\n // Build a separate SELECT query to get affected IDs before updating\n let selectQ = `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`;\n const selectArgs: any[] = [entityId];\n if (sourceRef) {\n selectQ += ` AND source_ref = ?`;\n selectArgs.push(sourceRef);\n }\n if (sourceHash) {\n selectQ += ` AND source_hash = ?`;\n selectArgs.push(sourceHash);\n }\n\n const idsToDelete = await executor.getAllAsync<{ id: string }>(selectQ, selectArgs);\n\n const result = await executor.runAsync(q, args);\n\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n\n return result.changes;\n }\n\n /**\n * Fetch IDs + entity_ids of soft-deleted rows older than cutoff for a given entity.\n * Used by runPrune().\n */\n async getPrunableMetadata(\n entityId: string,\n cutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string }>> {\n const executor = this.getExecutor(tx);\n return executor.getAllAsync<{ id: string; entity_id: string }>(\n `SELECT id, entity_id FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n }\n\n /**\n * Fetch all non-deleted entries for an entity, ordered by updated_at DESC.\n * Used by _getFullBundle().\n */\n async findAllByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId],\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Fetch live, mutable entries for an entity — everything heal is allowed to\n * downgrade or delete — oldest first, capped at `limit`, skipping anything\n * stamped inside the recheck cooldown (heal_checked_at > recheckCutoff).\n *\n * Oldest-first rather than newest-first: with a cooldown in place, newest-first\n * would keep re-selecting recently-touched facts every pass while older ones\n * wait indefinitely to even enter a batch.\n */\n async findHealCandidatesByEntityId(\n entityId: string,\n limit: number,\n recheckCutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'\n AND (heal_checked_at IS NULL OR heal_checked_at <= ?)\n ORDER BY updated_at ASC LIMIT ?`,\n [entityId, recheckCutoff, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Resolve search hits to document anchors. The MiniSearch index holds every\n * fact, not only immutable_document rows, so the source-type restriction has\n * to be applied here, after retrieval.\n */\n async findAnchorRowsByIds(\n entityId: string,\n ids: readonly string[],\n tx?: SQLiteAdapter,\n opts?: { withBody?: boolean },\n ): Promise<Array<{ id: string; title: string; source_ref: string | null; body?: string; lifecycle_status?: string }>> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n // Bodies and status are read only for heal grounding (spec §6.3, rev 7);\n // the default projection is unchanged.\n const columns = opts?.withBody ? 'id, title, source_ref, body, lifecycle_status' : 'id, title, source_ref';\n const rows: Array<{ id: string; title: string; source_ref: string | null; body?: string; lifecycle_status?: string }> = [];\n // Chunked like every other multi-id read here. The current caller stays well\n // under SQLITE_MAX_VARIABLE_NUMBER, but that is a property of the caller,\n // not of this method.\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(', ');\n const chunkRows = await executor.getAllAsync<{ id: string; title: string; source_ref: string | null; body?: string; lifecycle_status?: string }>(\n `SELECT ${columns} FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND source_type = 'immutable_document'\n AND id IN (${placeholders})`,\n [entityId, ...chunk],\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n /**\n * Fetch recent non-deleted entries for an entity (limited), ordered by updated_at DESC.\n * Used by MaintenanceService.doRunLibrarian().\n *\n * When `excludeSourceRef` is supplied, the WHERE clause filters out that\n * sourceRef BEFORE applying LIMIT. The caller in IngestionService is\n * `findRecentByEntityId(entityId, 500, tx)` — it discards same-sourceRef\n * rows after the read to build a cross-sourceRef title index. If those\n * rows are filtered out in SQL, the limit applies to usable rows only\n * and a re-ingest where the caller's sourceRef owns most recent facts\n * still leaves cross-sourceRef entries in the index.\n */\n async findRecentByEntityId(\n entityId: string,\n limit: number,\n tx?: SQLiteAdapter,\n excludeSourceRef?: string,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n // `IS NULL OR !=` keeps NULL-source_ref rows (e.g. librarian_inferred facts)\n // in the cross-sourceRef title index. The intent of `excludeSourceRef` is\n // \"drop THIS sourceRef's rows\"; NULL rows belong to neither the current\n // sourceRef nor the replacement set, and excluding them causes edges\n // targeting legacy/non-document facts to fail to resolve.\n const excludeClause = excludeSourceRef ? ` AND (source_ref IS NULL OR source_ref != ?)` : '';\n const args: unknown[] = excludeSourceRef ? [entityId, excludeSourceRef, limit] : [entityId, limit];\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL${excludeClause} ORDER BY updated_at DESC LIMIT ?`,\n args,\n );\n return rows.map(mapRowToFact);\n }\n\n /**\n * Fetch all non-deleted entries for an entity with embedding blobs preserved.\n * Used by ImportExportService for export/import round-tripping.\n */\n async findAllByEntityIdWithBlobs(entityId: string, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL ORDER BY updated_at DESC`,\n [entityId],\n );\n return rows.map(mapRowToFactWithBlobs);\n }\n\n /**\n * Count non-deleted entries for the given entities whose embedding_blob dimension\n * doesn't match queryVecLength. Used by read() to detect model-switch mismatches.\n */\n async countDimensionMismatched(\n entityIds: readonly string[],\n queryVecLength: number,\n tx?: SQLiteAdapter,\n ): Promise<number> {\n if (entityIds.length === 0) return 0;\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL\n AND embedding_blob IS NOT NULL\n AND (CAST(length(embedding_blob) AS INTEGER) % 4 = 0)\n AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?`,\n [...entityIds, queryVecLength],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count non-deleted entries for entityId that are stale relative to targetDim\n * (either no blob or wrong dimension). Used by runReembed() per-entity skip logic.\n */\n async countStaleForEntity(entityId: string, targetDim: number, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL\n AND (\n embedding_blob IS NULL\n OR (CAST(length(embedding_blob) AS INTEGER) / 4) != ?\n )`,\n [entityId, targetDim],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count non-deleted entries with stale or unconverted embeddings relative to `dim`.\n * Used by _reconcileEmbeddingDimension() to decide when to promote the pending\n * embedding_dimension value.\n */\n async countStaleEmbeddings(dim: number, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE deleted_at IS NULL\n AND (\n (embedding_blob IS NOT NULL AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?)\n OR (embedding_blob IS NULL AND embedding IS NOT NULL)\n )`,\n [dim],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Bulk delete pruned entries (already soft-deleted) by IDs.\n * Used by runPrune(). Returns total number of deleted rows.\n * `tx` is REQUIRED so outbox deletion events are staged atomically.\n */\n async bulkDeletePruned(\n entityId: string,\n cutoff: number,\n ids: string[],\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n let totalChanges = 0;\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ? AND id IN (${placeholders})`,\n [entityId, cutoff, ...chunk],\n );\n totalChanges += result.changes;\n // Stage outbox entries for permanently deleted records\n if (result.changes > 0) {\n for (const id of chunk) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: cutoff },\n }, tx);\n }\n }\n }\n return totalChanges;\n }\n\n /**\n * Mark orphaned entries (never accessed, old) as deleted.\n * Used by MaintenanceService.doRunHeal().\n */\n async markOrphaned(\n entityId: string,\n orphanThreshold: number,\n tx: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const updatedRows = await executor.getAllAsync<{ id: string }>(\n `UPDATE ${this.prefix}entries\n SET deleted_at = ?, updated_at = ?\n WHERE entity_id = ? AND access_count = 0 AND created_at <= ? AND source_type != 'immutable_document' AND deleted_at IS NULL\n RETURNING id`,\n [now, now, entityId, orphanThreshold],\n );\n for (const row of updatedRows) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return updatedRows.map(r => r.id);\n }\n\n /**\n * Downgrade stale inferred entries to 'tentative'.\n * Used by MaintenanceService.doRunHeal().\n *\n * Returns the ids it downgraded so the caller can fold them into\n * {@link HealResult.downgraded} without double-counting a fact the model also\n * downgraded in the same pass.\n */\n async downgradeStaleInferred(\n entityId: string,\n staleThreshold: number,\n tx: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const eligibleRows = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE entity_id = ? AND confidence = 'inferred'\n AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?))\n AND source_type != 'immutable_document' AND deleted_at IS NULL`,\n [entityId, staleThreshold, staleThreshold],\n );\n if (eligibleRows.length === 0) return [];\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET confidence = 'tentative', updated_at = ?\n WHERE entity_id = ? AND confidence = 'inferred' AND (last_accessed_at <= ? OR (last_accessed_at IS NULL AND created_at <= ?)) AND source_type != 'immutable_document' AND deleted_at IS NULL`,\n [now, entityId, staleThreshold, staleThreshold],\n );\n for (const row of eligibleRows) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'UPDATE',\n payload: { id: row.id, entity_id: entityId, confidence: 'tentative', updated_at: now },\n }, tx);\n }\n return eligibleRows.map(r => r.id);\n }\n\n /**\n * Downgrade specific entries to 'tentative' by IDs.\n * Used by MaintenanceService.doRunHeal().\n */\n async downgradeByIds(\n ids: string[],\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const placeholders = ids.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET confidence = 'tentative', updated_at = ? WHERE id IN (${placeholders}) AND entity_id = ?`,\n [now, ...ids, entityId],\n );\n // Stage outbox entries for downgraded records\n for (const id of ids) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'UPDATE',\n payload: { id, entity_id: entityId, confidence: 'tentative', updated_at: now },\n }, tx);\n }\n }\n\n /**\n * Soft-delete specific entries by IDs.\n * Used by MaintenanceService.doRunHeal().\n */\n async softDeleteByIds(\n ids: string[],\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const placeholders = ids.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE id IN (${placeholders}) AND entity_id = ?`,\n [now, now, ...ids, entityId],\n );\n // Stage outbox entries for soft-deleted records\n for (const id of ids) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n }\n\n /**\n * Bulk soft-delete all entries for an entity.\n * Stages DELETE outbox entries for each row in the same transaction.\n * `tx` is REQUIRED.\n */\n async bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n // Get IDs before updating for outbox staging\n const idsToDelete = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId],\n );\n // Stage outbox entries for each deleted record\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'entries',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return result.changes;\n }\n\n async findMiniSearchRows(\n entityId?: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; title: string; body: string; tags: string }>> {\n const executor = this.getExecutor(tx);\n if (entityId !== undefined) {\n return executor.getAllAsync(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL AND entity_id = ?`,\n [entityId],\n );\n }\n return executor.getAllAsync(\n `SELECT id, entity_id, title, body, tags FROM ${this.prefix}entries WHERE deleted_at IS NULL`,\n );\n }\n\n async updateEmbeddingBlob(id: string, blob: Uint8Array, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_blob = ?,\n embedding = NULL,\n embedding_failed_at = NULL,\n embedding_failure_kind = NULL,\n embedding_attempts = 0\n WHERE id = ?`,\n [blob, id],\n );\n }\n\n /**\n * Record a failed embedding attempt. Deliberately does NOT touch updated_at\n * (import merge is last-write-wins on it) and pushes no outbox event —\n * embedding lifecycle is local state, not replicated. Same discipline as\n * updateEmbeddingBlob. See spec §3.5.\n *\n * Only marker-eligible kinds (spec §3.3) are accepted: `no_provider` never\n * marks and `storage_error` never marks, so retry/permanent-failure policy\n * built on these rows only ever sees real embed failures.\n */\n async markEmbeddingFailure(\n id: string,\n kind: EmbeddingMarkerKind,\n now: number,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_failed_at = ?,\n embedding_failure_kind = ?,\n embedding_attempts = embedding_attempts + 1\n WHERE id = ?`,\n [now, kind, id],\n );\n }\n\n /**\n * Clear marker state for every marked row. Called when the embedding\n * dimension is promoted: a new model produces different vectors, so past\n * failures — including `float32_overflow`, which is otherwise terminal —\n * no longer predict future ones (spec §2.3).\n *\n * Same discipline as markEmbeddingFailure: no `updated_at` touch and no\n * outbox event, because embedding lifecycle is local state, not replicated.\n * Returns the number of rows cleared.\n */\n async clearEmbeddingFailureMarkers(tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET embedding_failed_at = NULL,\n embedding_failure_kind = NULL,\n embedding_attempts = 0\n WHERE embedding_failed_at IS NOT NULL`,\n );\n return result.changes;\n }\n\n async hasLegacySourceTypes(tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ one: number }>(\n `SELECT 1 AS one FROM ${this.prefix}entries WHERE source_type IN ('user_document', 'agent_inferred') LIMIT 1`,\n [],\n );\n return row != null;\n }\n\n async countLegacySourceTypes(tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}entries WHERE source_type IN ('user_document', 'agent_inferred')`,\n [],\n );\n return row?.count ?? 0;\n }\n\n async findAllForReembed(entityId?: string, tx?: SQLiteAdapter): Promise<ReembedCandidateRow[]> {\n const executor = this.getExecutor(tx);\n if (entityId !== undefined) {\n return executor.getAllAsync(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n }\n return executor.getAllAsync(\n `SELECT * FROM ${this.prefix}entries WHERE deleted_at IS NULL`,\n );\n }\n\n async findRowsForSourceRefMigration(tx?: SQLiteAdapter): Promise<Array<{ rowid: number; source_ref: string }>> {\n const executor = this.getExecutor(tx);\n return executor.getAllAsync(\n `SELECT rowid, source_ref FROM ${this.prefix}entries\n WHERE source_ref IS NOT NULL\n AND (\n TRIM(source_ref) != source_ref\n OR INSTR(source_ref, '/') > 0\n OR INSTR(source_ref, '\\\\') > 0\n OR INSTR(source_ref, CHAR(0)) > 0\n OR source_ref GLOB '*[^-A-Za-z0-9._ ]*'\n )`,\n );\n }\n\n async updateSourceRefByRowid(rowid: number, sourceRef: string | null, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET source_ref = ? WHERE rowid = ?`,\n [sourceRef, rowid],\n );\n }\n\n async findLatestSourceHash(entityId: string, sourceRef: string, tx?: SQLiteAdapter): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ source_hash: string | null }>(\n `SELECT source_hash FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL\n ORDER BY updated_at DESC, id ASC\n LIMIT 1`,\n [entityId, sourceRef],\n );\n return row?.source_hash ?? null;\n }\n\n /**\n * Batch version of {@link findLatestSourceHash}. Returns a Map covering every\n * requested ref, where the value is the source_hash from the row with the\n * most-recently-updated live fact for that ref, or null when no live row exists.\n *\n * The SQL uses ROW_NUMBER() OVER (PARTITION BY source_ref ORDER BY updated_at\n * DESC, id ASC) — NOT MAX(source_hash). Aggregation with MAX(source_hash) is\n * wrong because MAX computes independently across grouped rows; the hash must\n * come from the exact row that wins MAX(updated_at). The `id ASC` tie-break\n * keeps selection deterministic when two live rows share `updated_at`.\n *\n * Source refs are de-duplicated and processed in chunks so the per-query bind\n * parameter count stays under SQLite's `SQLITE_MAX_VARIABLE_NUMBER` (default\n * 999, leaving one slot for `entity_id`).\n *\n * Empty input is a synchronous early return with zero SQL calls.\n */\n async findLatestSourceHashes(\n entityId: string,\n sourceRefs: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Map<string, string | null>> {\n const out = new Map<string, string | null>();\n if (sourceRefs.length === 0) return out;\n // Pre-populate with null for every requested ref so callers can distinguish\n // \"no live row\" (null) from \"row with a null source_hash\" (also null in this\n // shape, but at least the key is guaranteed present).\n const dedupedRefs = Array.from(new Set(sourceRefs));\n for (const ref of dedupedRefs) {\n out.set(ref, null);\n }\n const executor = this.getExecutor(tx);\n // 1 bind parameter for entity_id; remaining slots for source_ref placeholders.\n const chunkLimit = Math.max(1, this.chunkSize - 1);\n for (let i = 0; i < dedupedRefs.length; i += chunkLimit) {\n const chunk = dedupedRefs.slice(i, i + chunkLimit);\n const placeholders = chunk.map(() => '?').join(',');\n const rows = await executor.getAllAsync<{ source_ref: string; source_hash: string | null }>(\n `WITH ranked AS (\n SELECT source_ref, source_hash,\n ROW_NUMBER() OVER (\n PARTITION BY source_ref\n ORDER BY updated_at DESC, id ASC\n ) as rn\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_ref IN (${placeholders}) AND deleted_at IS NULL\n )\n SELECT source_ref, source_hash\n FROM ranked\n WHERE rn = 1`,\n [entityId, ...chunk],\n );\n for (const r of rows) {\n out.set(r.source_ref, r.source_hash);\n }\n }\n return out;\n }\n\n /**\n * Return the live source_refs for an entity that hold the given source_hash.\n * Used by the ingestDocument duplicate-hash guard and by hosts auditing\n * duplicate-content collisions. Sorted `COLLATE BINARY` so the canonical\n * ref (the code-unit-minimum of the set) is stable across deploys.\n */\n async findSourceRefsByHash(\n entityId: string,\n sourceHash: string,\n tx?: SQLiteAdapter,\n ): Promise<string[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ source_ref: string }>(\n `SELECT source_ref FROM ${this.prefix}entries\n WHERE entity_id = ? AND source_hash = ? AND deleted_at IS NULL\n AND source_ref IS NOT NULL\n GROUP BY source_ref\n ORDER BY source_ref COLLATE BINARY`,\n [entityId, sourceHash],\n );\n return rows.map(r => r.source_ref);\n }\n\n /**\n * Per-sourceRef rollup for an entity: one row per live source_ref, with the\n * most-recently-updated live hash (NOT the lexically-max hash) and a live\n * fact count.\n *\n * The hash comes from the same row that wins ROW_NUMBER() over updated_at\n * DESC, so a ref with multiple live hashes (e.g. from import) reports the\n * latest one — matching single-doc `findLatestSourceHash` semantics.\n *\n * Sort is COLLATE BINARY: locale-dependent ordering re-mints identity on\n * every deploy, which is the bug this whole section exists to prevent.\n */\n async listSourceRefs(\n entityId: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{\n sourceRef: string;\n sourceHash: string | null;\n factCount: number;\n lastIngestedAt: number;\n }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{\n source_ref: string;\n source_hash: string | null;\n fact_count: number;\n last_ingested_at: number;\n }>(\n `WITH ranked AS (\n SELECT source_ref, source_hash, updated_at,\n ROW_NUMBER() OVER (\n PARTITION BY source_ref\n ORDER BY updated_at DESC, id ASC\n ) AS rn,\n COUNT(*) OVER (PARTITION BY source_ref) AS fact_count\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_ref IS NOT NULL\n )\n SELECT source_ref,\n source_hash AS source_hash,\n fact_count AS fact_count,\n updated_at AS last_ingested_at\n FROM ranked\n WHERE rn = 1\n ORDER BY source_ref COLLATE BINARY`,\n [entityId],\n );\n return rows.map(r => ({\n sourceRef: r.source_ref,\n sourceHash: r.source_hash,\n factCount: Number(r.fact_count),\n lastIngestedAt: Number(r.last_ingested_at),\n }));\n }\n\n /**\n * Count live entries for an entity across all source_refs/source_hashes.\n * Used by forget({ dryRun, clearAll: true }).\n */\n async countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n return row?.cnt ?? 0;\n }\n\n /**\n * Count live entries matching a source filter (either or both may be null).\n * Used by forget({ dryRun: true }) with sourceRef/sourceHash.\n */\n async countLiveBySource(\n entityId: string,\n sourceRef: string | null,\n sourceHash: string | null,\n tx?: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n let q = `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL`;\n const args: unknown[] = [entityId];\n if (sourceRef !== null) { q += ` AND source_ref = ?`; args.push(sourceRef); }\n if (sourceHash !== null) { q += ` AND source_hash = ?`; args.push(sourceHash); }\n const row = await executor.getFirstAsync<{ cnt: number }>(q, args);\n return row?.cnt ?? 0;\n }\n\n async findMetadataByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: EntryRowMetadata[] = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<EntryRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async findWithEmbeddingsByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: EntryRowWithEmbeddings[] = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<EntryRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async findMetadataByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n return executor.getAllAsync<EntryRowMetadata>(\n `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL`,\n [...entityIds],\n );\n }\n\n async findWithEmbeddingsByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n return executor.getAllAsync<EntryRowWithEmbeddings>(\n `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL`,\n [...entityIds],\n );\n }\n\n async findEmbeddingsByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>> {\n if (ids.length === 0) return [];\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }> = [];\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<{ id: string; embedding_blob: Uint8Array | null; embedding: string | null }>(\n `SELECT id, embedding_blob, embedding FROM ${this.prefix}entries WHERE id IN (${placeholders}) AND deleted_at IS NULL`,\n chunk,\n );\n rows.push(...chunkRows);\n }\n return rows;\n }\n\n async trackAccess(ids: readonly string[], now: number, tx?: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n const executor = this.getExecutor(tx);\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await executor.runAsync(\n `UPDATE ${this.prefix}entries SET access_count = access_count + 1, last_accessed_at = ? WHERE id IN (${placeholders})`,\n [now, ...chunk],\n );\n }\n }\n\n getLegacyMigrationSQL(): string {\n return [\n `-- Migrate legacy source_type values (targets your WikiMemory prefix: ${this.prefix})`,\n `UPDATE ${this.prefix}entries SET source_type = 'immutable_document' WHERE source_type = 'user_document';`,\n `UPDATE ${this.prefix}entries SET source_type = 'librarian_inferred' WHERE source_type = 'agent_inferred';`,\n ].join('\\n');\n }\n\n async findRecentByEntityIds(\n entityIds: readonly string[],\n limit: number,\n tx?: SQLiteAdapter,\n opts?: { excludeDrafts?: boolean },\n ): Promise<WikiFact[]> {\n if (entityIds.length === 0) return [];\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const draftClause = opts?.excludeDrafts === true ? ` AND lifecycle_status != 'draft'` : '';\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL${draftClause} ORDER BY updated_at DESC LIMIT ?`,\n [...entityIds, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /** IDs of live draft facts for the given entities (spec §5.1). Callers pass ≤ 100 entity ids. */\n async findDraftIdsByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<Set<string>> {\n if (entityIds.length === 0) return new Set();\n const executor = this.getExecutor(tx);\n const placeholders = entityIds.map(() => '?').join(',');\n const rows = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE entity_id IN (${placeholders}) AND deleted_at IS NULL AND lifecycle_status = 'draft'`,\n [...entityIds],\n );\n return new Set(rows.map((r) => r.id));\n }\n\n /** Live drafts for one entity, newest first, keyset-paged by (created_at, id). */\n async listDraftsByEntityId(\n entityId: string,\n limit: number,\n after: { createdAt: number; id: string } | null,\n tx?: SQLiteAdapter,\n ): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const afterClause = after ? ` AND (created_at < ? OR (created_at = ? AND id < ?))` : '';\n const args: unknown[] = after\n ? [entityId, after.createdAt, after.createdAt, after.id, limit]\n : [entityId, limit];\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND lifecycle_status = 'draft'${afterClause}\n ORDER BY created_at DESC, id DESC LIMIT ?`,\n args,\n );\n return rows.map(mapRowToFact);\n }\n\n /** True iff `entryId` is a live draft owned by `entityId`. */\n async isLiveDraft(entryId: string, entityId: string, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries\n WHERE id = ? AND entity_id = ? AND deleted_at IS NULL AND lifecycle_status = 'draft'`,\n [entryId, entityId],\n );\n return row != null;\n }\n\n /**\n * Live untyped facts eligible for ontology backfill, oldest first.\n * Skips facts checked within the recheck cooldown (ontology_checked_at > recheckCutoff).\n */\n async findUntypedByEntityId(entityId: string, limit: number, recheckCutoff: number, tx?: SQLiteAdapter): Promise<WikiFact[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}entries\n WHERE entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL\n AND (ontology_checked_at IS NULL OR ontology_checked_at <= ?)\n ORDER BY updated_at ASC LIMIT ?`,\n [entityId, recheckCutoff, limit],\n );\n return rows.map(mapRowToFact);\n }\n\n /** Counts live untyped facts: eligible (past cooldown) vs deferred (in cooldown). */\n async countUntypedByEntityId(entityId: string, recheckCutoff: number, tx?: SQLiteAdapter): Promise<{ eligible: number; deferred: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ eligible: number | null; deferred: number | null }>(\n `SELECT\n SUM(CASE WHEN ontology_checked_at IS NULL OR ontology_checked_at <= ? THEN 1 ELSE 0 END) AS eligible,\n SUM(CASE WHEN ontology_checked_at IS NOT NULL AND ontology_checked_at > ? THEN 1 ELSE 0 END) AS deferred\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL`,\n [recheckCutoff, recheckCutoff, entityId],\n );\n return { eligible: Number(row?.eligible ?? 0), deferred: Number(row?.deferred ?? 0) };\n }\n\n /**\n * Sets okf_type only when currently NULL — additive by construction: a\n * concurrently-typed fact is never overwritten. Returns changes for the caller\n * to distinguish applied vs skipped.\n */\n async updateOkfType(id: string, entityId: string, okfType: string, tx: SQLiteAdapter): Promise<{ changes: number }> {\n const result = await tx.runAsync(\n `UPDATE ${this.prefix}entries SET okf_type = ?\n WHERE id = ? AND entity_id = ? AND okf_type IS NULL AND deleted_at IS NULL`,\n [okfType, id, entityId],\n );\n return { changes: result.changes };\n }\n\n /**\n * Stamps the backfill recheck cooldown. NEVER touches updated_at — import\n * merge resolution is last-write-wins on updated_at and a bump here would\n * make an unchanged local fact beat a genuinely newer remote edit.\n */\n async markOntologyChecked(ids: string[], entityId: string, now: number, tx: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await tx.runAsync(\n `UPDATE ${this.prefix}entries SET ontology_checked_at = ?\n WHERE id IN (${placeholders}) AND entity_id = ? AND deleted_at IS NULL`,\n [now, ...chunk, entityId],\n );\n }\n }\n\n /**\n * Lightweight full-breadth title index (id, title, okf_type) over all live\n * typed facts. Used by ontology backfill edge resolution — a recent-N window\n * would miss an old fact's contemporaries. Untyped rows are excluded: they\n * can never pass the edge target-type check, and batch facts typed during\n * the run are re-added to the in-memory index by the caller.\n */\n async findTitleIndexByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<Array<{ id: string; title: string; okf_type: string | null }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ id: string; title: string; okf_type: string | null }>(\n `SELECT id, title, okf_type FROM ${this.prefix}entries WHERE entity_id = ? AND deleted_at IS NULL AND okf_type IS NOT NULL`,\n [entityId],\n );\n return rows.map(r => ({ id: r.id, title: r.title, okf_type: r.okf_type ?? null }));\n }\n\n /** Counts live mutable facts: eligible (past cooldown) vs deferred (in cooldown). */\n async countHealCandidatesByEntityId(\n entityId: string,\n recheckCutoff: number,\n tx?: SQLiteAdapter,\n ): Promise<{ eligible: number; deferred: number }> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ eligible: number | null; deferred: number | null }>(\n `SELECT\n SUM(CASE WHEN heal_checked_at IS NULL OR heal_checked_at <= ? THEN 1 ELSE 0 END) AS eligible,\n SUM(CASE WHEN heal_checked_at IS NOT NULL AND heal_checked_at > ? THEN 1 ELSE 0 END) AS deferred\n FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type != 'immutable_document'`,\n [recheckCutoff, recheckCutoff, entityId],\n );\n return { eligible: Number(row?.eligible ?? 0), deferred: Number(row?.deferred ?? 0) };\n }\n\n /**\n * Stamps the heal recheck cooldown. NEVER touches updated_at — import merge\n * resolution is last-write-wins on updated_at and a bump here would make an\n * unchanged local fact beat a genuinely newer remote edit.\n *\n * Soft-deleted rows are skipped: a candidate heal deleted earlier in the same\n * transaction is no longer a candidate under any future pass, so its cooldown\n * value is irrelevant. This means the stamped count can be lower than the\n * offered-candidate count.\n */\n async markHealChecked(ids: string[], entityId: string, now: number, tx: SQLiteAdapter): Promise<void> {\n if (ids.length === 0) return;\n for (let i = 0; i < ids.length; i += this.chunkSize) {\n const chunk = ids.slice(i, i + this.chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n await tx.runAsync(\n `UPDATE ${this.prefix}entries SET heal_checked_at = ?\n WHERE id IN (${placeholders}) AND entity_id = ? AND deleted_at IS NULL`,\n [now, ...chunk, entityId],\n );\n }\n }\n\n /**\n * Lightweight full-breadth index (id, title) over all live librarian_inferred\n * facts. This is heal's fuzzy-dedupe corpus, deliberately kept independent of\n * the bounded candidate window: seeding dedupe from a batchSize-limited read\n * would let a synthesized fact duplicating a fact outside the window pass the\n * Jaccard check, and a convergence loop would multiply those duplicates across\n * passes. Mirrors findTitleIndexByEntityId — full breadth, two columns, cheap.\n */\n async findInferredTitlesByEntityId(\n entityId: string,\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; title: string }>> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<{ id: string; title: string }>(\n `SELECT id, title FROM ${this.prefix}entries\n WHERE entity_id = ? AND deleted_at IS NULL AND source_type = 'librarian_inferred'`,\n [entityId],\n );\n return rows.map(r => ({ id: r.id, title: r.title }));\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","import { BaseRepository } from './BaseRepository';\nimport type { SQLiteAdapter } from '../types';\nimport { generateId } from '../utils/ids';\n\nexport class OutboxRepository extends BaseRepository {\n private enableOutbox: boolean;\n\n constructor(db: SQLiteAdapter, prefix: string, enableOutbox = false) {\n super(db, prefix);\n this.enableOutbox = enableOutbox;\n }\n\n /**\n * Insert a new outbox event within the provided transaction.\n * No-op when enableOutbox is false.\n * `tx` is required — callers must always pass the active transaction\n * so the write is atomic with the main table mutation.\n */\n async push(\n params: {\n entityId: string;\n tableName: string;\n recordId: string;\n operation: 'INSERT' | 'UPDATE' | 'DELETE';\n payload: any;\n },\n tx: SQLiteAdapter,\n ): Promise<void> {\n if (!this.enableOutbox) return;\n const executor = this.getExecutor(tx);\n const id = generateId('out_');\n const now = Date.now();\n await executor.runAsync(\n `INSERT INTO ${this.prefix}outbox (id, entity_id, table_name, record_id, operation, payload, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [id, params.entityId, params.tableName, params.recordId, params.operation, JSON.stringify(params.payload), now],\n );\n }\n\n /**\n * Fetch pending outbox rows ordered by created_at ASC, rowid ASC.\n * Reads directly from `this.db` (not a transaction).\n */\n async fetchPending(limit = 50): Promise<any[]> {\n return this.db.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}outbox ORDER BY created_at ASC, rowid ASC LIMIT ?`,\n [limit],\n );\n }\n\n /**\n * Delete acknowledged outbox rows by their IDs.\n * No-op when `ids` is empty.\n * Deletes directly from `this.db` (not a transaction).\n */\n async acknowledge(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(', ');\n await this.db.runAsync(\n `DELETE FROM ${this.prefix}outbox WHERE id IN (${placeholders})`,\n chunk,\n );\n }\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport { BaseRepository } from './BaseRepository';\nimport { generateId } from '../utils/ids';\n\n/**\n * Per-(entity_id, source_hash) record of the canonical sourceRef currently\n * holding that hash. The partial UNIQUE index on (entity_id, source_hash)\n * WHERE deleted_at IS NULL enforces the sourceRef-level TOCTOU-race invariant\n * for the #79 fix. See\n * docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B1.\n *\n * The entries table cannot express this invariant directly because a single\n * `ingestDocument` call writes N facts that all share\n * (entity_id, source_ref, source_hash); a UNIQUE index on\n * `entries(entity_id, source_hash)` would block the 2nd–Nth fact inserts in\n * the normal multi-fact path. The per-(entity, hash) granularity of\n * source_ref_index matches the TOCTOU invariant exactly.\n *\n * No outbox events: this is an internal index table whose state is fully\n * derivable from `entries`. Hosts that need CDC continue to read `entries`\n * outbox events; the index is not part of the user-visible contract.\n */\nexport class SourceRefIndexRepository extends BaseRepository {\n /**\n * Idempotent insert: the partial UNIQUE index catches concurrent inserts for\n * the same (entity_id, source_hash). The caller (IngestionService) catches\n * the resulting SQLITE_CONSTRAINT_UNIQUE and translates it to the per-mode\n * duplicate-hash outcome. Runtime IDs use the `sri_` prefix to avoid\n * collision with the deterministic `sri:<entity>:<hash>` IDs used by the v9\n * backfill (the colon separator keeps the two ID spaces disjoint).\n */\n async upsert(\n entityId: string,\n sourceHash: string,\n sourceRef: string,\n tx: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}source_ref_index (id, entity_id, source_hash, source_ref, created_at, deleted_at)\n VALUES (?, ?, ?, ?, ?, NULL)`,\n [generateId('sri_'), entityId, sourceHash, sourceRef, Date.now()],\n );\n }\n\n /**\n * Idempotent soft-delete of the live row for (entity_id, source_ref).\n * Called at the start of every ingestDocument to remove the prior run's\n * index row, so the new upsert doesn't collide with itself. No-op when the\n * row is already soft-deleted or never existed.\n */\n async softDeleteByEntityAndSourceRef(\n entityId: string,\n sourceRef: string,\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}source_ref_index\n SET deleted_at = ?, created_at = ?\n WHERE entity_id = ? AND source_ref = ? AND deleted_at IS NULL`,\n [now, now, entityId, sourceRef],\n );\n return result.changes;\n }\n\n /**\n * Returns the live sourceRef holding the given hash, or null when no live\n * row exists. Used by the IngestionService pre-check (line 82) and the\n * catch-and-translate canonical lookup (line 212).\n */\n async findActiveByEntityAndHash(\n entityId: string,\n sourceHash: string,\n tx?: SQLiteAdapter,\n ): Promise<string | null> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ source_ref: string }>(\n `SELECT source_ref FROM ${this.prefix}source_ref_index\n WHERE entity_id = ? AND source_hash = ? AND deleted_at IS NULL`,\n [entityId, sourceHash],\n );\n return row?.source_ref ?? null;\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport { OutboxRepository } from './OutboxRepository';\nimport type { WikiTask, SQLiteAdapter } from '../types';\nimport { parseJsonArray, parseJsonObject } from './rowMappers';\nimport { isStaleAfter, deriveTrustTier } from '@equationalapplications/core-okf';\n\nfunction mapRowToTask(row: any): WikiTask {\n const okf_verified = parseJsonArray<NonNullable<WikiTask['okf_verified']>[number]>(row.okf_verified, []);\n // Mirror EntryRepository.mapRowToFact — see that file for the rationale on\n // per-row Date.now() sampling vs. a shared per-call value.\n const now = Date.now();\n const staleAfterRaw = row.stale_after != null ? Number(row.stale_after) : null;\n\n return {\n id: row.id,\n entity_id: row.entity_id,\n description: row.description,\n status: row.status,\n priority: Number(row.priority),\n created_at: Number(row.created_at),\n updated_at: Number(row.updated_at),\n resolved_at: row.resolved_at != null ? Number(row.resolved_at) : null,\n deleted_at: row.deleted_at != null ? Number(row.deleted_at) : null,\n okf_type: row.okf_type ?? null,\n // OKF v0.2\n lifecycle_status: (row.lifecycle_status ?? 'stable') as WikiTask['lifecycle_status'],\n stale_after: staleAfterRaw,\n generated_by: row.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiTask['okf_sources']>[number]>(row.okf_sources, []),\n okf_verified,\n okf_usage_window: parseJsonObject<NonNullable<WikiTask['okf_usage_window']>>(row.okf_usage_window),\n last_verified_at: row.last_verified_at != null ? Number(row.last_verified_at) : null,\n last_verified_by: row.last_verified_by ?? null,\n // Spec §2.7 + §5.3: hydrate so read() consumers don't re-call the helpers.\n isStale: isStaleAfter(staleAfterRaw, now),\n trustTier: deriveTrustTier(okf_verified),\n };\n}\n\nexport class TaskRepository extends BaseRepository {\n constructor(\n db: SQLiteAdapter,\n prefix: string,\n private outbox: OutboxRepository,\n ) {\n super(db, prefix);\n }\n\n /**\n * Fetch a single task by ID. Returns null if not found or soft-deleted.\n */\n async findById(id: string): Promise<WikiTask | null> {\n const row = await this.db.getFirstAsync<any>(\n `SELECT * FROM ${this.prefix}tasks WHERE id = ? AND deleted_at IS NULL`,\n [id],\n );\n return row ? mapRowToTask(row) : null;\n }\n\n /**\n * Fetch all pending/in_progress tasks for the given entity IDs.\n * Returns empty array when entityIds is empty.\n */\n async findAllPending(entityIds: string[], limit?: number): Promise<WikiTask[]> {\n if (entityIds.length === 0) return [];\n const placeholders = entityIds.map(() => '?').join(', ');\n const sql =\n `SELECT * FROM ${this.prefix}tasks ` +\n `WHERE entity_id IN (${placeholders}) AND status IN ('pending', 'in_progress') AND deleted_at IS NULL ` +\n `ORDER BY priority DESC, created_at ASC` +\n (limit != null ? ` LIMIT ?` : '');\n const params: unknown[] = limit != null ? [...entityIds, limit] : [...entityIds];\n const rows = await this.db.getAllAsync<any>(sql, params);\n return rows.map(mapRowToTask);\n }\n\n async findExistingMetadataByIds(\n ids: readonly string[],\n tx?: SQLiteAdapter,\n ): Promise<Array<{ id: string; entity_id: string; updated_at: number }>> {\n const executor = this.getExecutor(tx);\n const rows: Array<{ id: string; entity_id: string; updated_at: number }> = [];\n const chunkSize = 500;\n for (let i = 0; i < ids.length; i += chunkSize) {\n const chunk = ids.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const chunkRows = await executor.getAllAsync<any>(\n `SELECT id, entity_id, updated_at FROM ${this.prefix}tasks WHERE id IN (${placeholders})`,\n chunk,\n );\n rows.push(...chunkRows.map((row) => ({ id: row.id, entity_id: row.entity_id, updated_at: Number(row.updated_at) })));\n }\n return rows;\n }\n\n /**\n * Upsert a WikiTask within the provided transaction.\n * Uses ON CONFLICT(id) DO UPDATE (not INSERT OR REPLACE).\n * Stages an outbox entry in the same transaction.\n * `tx` is REQUIRED.\n *\n * OKF metadata (lifecycle_status, sources, etc.) is intentionally excluded\n * from the SET clause so content writes preserve any existing row values.\n * See {@link EntryRepository.upsert} for the rationale — the same applies\n * symmetrically to tasks (spec §2.5). Callers that need to overwrite OKF\n * metadata should use {@link upsertForImport}.\n */\n async upsert(task: WikiTask, tx: SQLiteAdapter, updatedAt?: number): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Number.isFinite(updatedAt) ? updatedAt : Date.now();\n\n const existingRow = await executor.getFirstAsync<{\n id: string;\n lifecycle_status: string;\n stale_after: number | null;\n generated_by: string | null;\n okf_sources: string | null;\n okf_verified: string | null;\n okf_usage_window: string | null;\n last_verified_at: number | null;\n last_verified_by: string | null;\n }>(\n `SELECT id, lifecycle_status, stale_after, generated_by,\n okf_sources, okf_verified, okf_usage_window,\n last_verified_at, last_verified_by\n FROM ${this.prefix}tasks WHERE id = ?`,\n [task.id],\n );\n const operation = task.deleted_at != null ? 'DELETE' : (existingRow ? 'UPDATE' : 'INSERT');\n\n await executor.runAsync(\n `INSERT INTO ${this.prefix}tasks (\n id, entity_id, description, status, priority,\n created_at, updated_at, resolved_at, deleted_at,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n description = excluded.description,\n status = excluded.status,\n priority = excluded.priority,\n updated_at = excluded.updated_at,\n resolved_at = excluded.resolved_at,\n deleted_at = excluded.deleted_at`,\n [\n task.id,\n task.entity_id,\n task.description,\n task.status,\n task.priority,\n task.created_at,\n now, // updated_at set by repo or import override\n task.resolved_at ?? null,\n task.deleted_at ?? null,\n // OKF v0.2 metadata — bound for INSERT only; ON CONFLICT UPDATE\n // preserves the existing row values (these columns are intentionally\n // absent from the SET clause above).\n task.lifecycle_status ?? 'stable',\n task.stale_after ?? null,\n task.generated_by ?? null,\n task.last_verified_at ?? null,\n task.last_verified_by ?? null,\n task.okf_sources ? JSON.stringify(task.okf_sources) : null,\n task.okf_verified ? JSON.stringify(task.okf_verified) : null,\n task.okf_usage_window ? JSON.stringify(task.okf_usage_window) : null,\n ],\n );\n\n // Outbox payload mirrors what is actually persisted. On UPDATE, the SET\n // clause intentionally omits OKF metadata so prior row values win, but\n // the caller-supplied `task` would still describe state we did NOT write.\n // Re-read those columns from the stored row and overlay them onto the\n // caller-supplied payload before publishing (#90 review).\n const persistedOkf = existingRow\n ? {\n lifecycle_status: (existingRow.lifecycle_status ?? 'stable') as WikiTask['lifecycle_status'],\n stale_after: existingRow.stale_after != null ? Number(existingRow.stale_after) : null,\n generated_by: existingRow.generated_by ?? null,\n okf_sources: parseJsonArray<NonNullable<WikiTask['okf_sources']>[number]>(existingRow.okf_sources, []),\n okf_verified: parseJsonArray<NonNullable<WikiTask['okf_verified']>[number]>(existingRow.okf_verified, []),\n okf_usage_window: parseJsonObject<NonNullable<WikiTask['okf_usage_window']>>(existingRow.okf_usage_window),\n last_verified_at: existingRow.last_verified_at != null ? Number(existingRow.last_verified_at) : null,\n last_verified_by: existingRow.last_verified_by ?? null,\n }\n : null;\n await this.outbox.push(\n {\n entityId: task.entity_id,\n tableName: 'tasks',\n recordId: task.id,\n operation,\n payload: persistedOkf ? { ...task, ...persistedOkf } : task,\n },\n tx,\n );\n }\n\n async upsertForImport(task: WikiTask, tx: SQLiteAdapter, updatedAt?: number): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Number.isFinite(updatedAt) ? updatedAt : Date.now();\n\n // Import is replace semantics, mirroring EntryRepository.upsertForImport.\n // Dump is authoritative: a re-import that cleared stale_after, generated_by,\n // or verification mirrors must overwrite, not preserve.\n await executor.runAsync(\n `INSERT INTO ${this.prefix}tasks (\n id, entity_id, description, status, priority,\n created_at, updated_at, resolved_at, deleted_at, okf_type,\n lifecycle_status, stale_after, generated_by, last_verified_at, last_verified_by,\n okf_sources, okf_verified, okf_usage_window\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n entity_id = excluded.entity_id,\n description = excluded.description,\n status = excluded.status,\n priority = excluded.priority,\n updated_at = excluded.updated_at,\n resolved_at = excluded.resolved_at,\n deleted_at = excluded.deleted_at,\n okf_type = excluded.okf_type,\n lifecycle_status = excluded.lifecycle_status,\n stale_after = excluded.stale_after,\n generated_by = excluded.generated_by,\n last_verified_at = excluded.last_verified_at,\n last_verified_by = excluded.last_verified_by,\n okf_sources = excluded.okf_sources,\n okf_verified = excluded.okf_verified,\n okf_usage_window = excluded.okf_usage_window`,\n [\n task.id,\n task.entity_id,\n task.description,\n task.status,\n task.priority,\n task.created_at,\n now,\n task.resolved_at ?? null,\n task.deleted_at ?? null,\n task.okf_type ?? null,\n task.lifecycle_status ?? 'stable',\n task.stale_after ?? null,\n task.generated_by ?? null,\n task.last_verified_at ?? null,\n task.last_verified_by ?? null,\n task.okf_sources ? JSON.stringify(task.okf_sources) : null,\n task.okf_verified ? JSON.stringify(task.okf_verified) : null,\n task.okf_usage_window ? JSON.stringify(task.okf_usage_window) : null,\n ],\n );\n }\n\n /**\n * Soft-delete a task by ID. Sets deleted_at and updated_at.\n * Stages a DELETE outbox entry in the same transaction.\n * `tx` is REQUIRED.\n */\n async softDelete(id: string, entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, id, entityId],\n );\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n },\n tx,\n );\n }\n\n /**\n * Fetch all non-deleted tasks for an entity, ordered by priority DESC, created_at ASC.\n * Used by _getFullBundle().\n */\n async findAllByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiTask[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL ORDER BY priority DESC, created_at ASC`,\n [entityId],\n );\n return rows.map(mapRowToTask);\n }\n\n /**\n * Bulk delete pruned tasks (already soft-deleted) by cutoff date.\n * Used by runPrune(). Returns number of deleted rows.\n */\n async bulkDeletePruned(\n entityId: string,\n cutoff: number,\n tx: SQLiteAdapter,\n ): Promise<number> {\n const executor = this.getExecutor(tx);\n const rowsToDelete = await executor.getAllAsync<{ id: string; deleted_at: number }>(\n `SELECT id, deleted_at FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n if (rowsToDelete.length === 0) return 0;\n\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NOT NULL AND deleted_at <= ?`,\n [entityId, cutoff],\n );\n\n for (const row of rowsToDelete) {\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: row.deleted_at },\n },\n tx,\n );\n }\n\n return result.changes;\n }\n\n /**\n * Soft-delete a task by ID within a transaction.\n * Stages a DELETE outbox entry in the same transaction.\n * `tx` is REQUIRED.\n */\n async softDeleteById(\n id: string,\n entityId: string,\n tx: SQLiteAdapter,\n ): Promise<{ changes: number }> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [now, now, id, entityId],\n );\n if (result.changes > 0) {\n await this.outbox.push(\n {\n entityId,\n tableName: 'tasks',\n recordId: id,\n operation: 'DELETE',\n payload: { id, entity_id: entityId, deleted_at: now },\n },\n tx,\n );\n }\n return result;\n }\n\n /**\n * Bulk soft-delete all tasks for an entity.\n * Stages DELETE outbox entries for each row in the same transaction.\n * `tx` is REQUIRED.\n */\n async bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const now = Date.now();\n // Get IDs before updating for outbox staging\n const idsToDelete = await executor.getAllAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}tasks WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n const result = await executor.runAsync(\n `UPDATE ${this.prefix}tasks SET deleted_at = ?, updated_at = ? WHERE entity_id = ? AND deleted_at IS NULL`,\n [now, now, entityId],\n );\n // Stage outbox entries for each deleted record\n for (const row of idsToDelete) {\n await this.outbox.push({\n entityId,\n tableName: 'tasks',\n recordId: row.id,\n operation: 'DELETE',\n payload: { id: row.id, entity_id: entityId, deleted_at: now },\n }, tx);\n }\n return result.changes;\n }\n\n /**\n * Count live tasks for an entity. Used by forget({ dryRun, clearAll: true }).\n */\n async countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = this.getExecutor(tx);\n const row = await executor.getFirstAsync<{ cnt: number }>(\n `SELECT COUNT(*) AS cnt FROM ${this.prefix}tasks\n WHERE entity_id = ? AND deleted_at IS NULL`,\n [entityId],\n );\n return row?.cnt ?? 0;\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { WikiEvent, SQLiteAdapter } from '../types';\n\nexport class EventRepository extends BaseRepository {\n /**\n * Insert a new event row.\n * Pass `tx` to participate in a caller-owned transaction; omit to run against the default db.\n */\n async add(event: WikiEvent, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [\n event.id,\n event.entity_id,\n event.event_type,\n event.summary,\n event.related_entry_id ?? null,\n event.created_at,\n ],\n );\n }\n\n async addIgnoreDuplicate(event: WikiEvent, tx?: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}events (id, entity_id, event_type, summary, related_entry_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [\n event.id,\n event.entity_id,\n event.event_type,\n event.summary,\n event.related_entry_id ?? null,\n event.created_at,\n ],\n );\n }\n\n /**\n * Return the most recent events for an entity, newest first.\n * Defaults to a limit of 50.\n */\n async getRecent(entityId: string, limit = 50): Promise<WikiEvent[]> {\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`,\n [entityId, limit],\n );\n }\n\n /**\n * Return the most recent events for the given entity IDs, newest first.\n * Defaults to a limit of 50.\n */\n async getRecentForEntities(entityIds: string[], limit = 50): Promise<WikiEvent[]> {\n if (entityIds.length === 0) return [];\n const placeholders = entityIds.map(() => '?').join(', ');\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id IN (${placeholders}) ORDER BY created_at DESC LIMIT ?`,\n [...entityIds, limit],\n );\n }\n\n /**\n * Delete events for an entity that were created at or before the given cutoff timestamp.\n * Returns the number of deleted rows.\n */\n async prune(entityId: string, cutoff: number): Promise<{ changes: number }> {\n return this.db.runAsync(\n `DELETE FROM ${this.prefix}events WHERE entity_id = ? AND created_at <= ?`,\n [entityId, cutoff],\n );\n }\n\n /**\n * Return the total number of events stored for an entity.\n * `tx` is optional — pass an active transaction handle for atomic reads.\n */\n async count(entityId: string, tx?: SQLiteAdapter): Promise<number> {\n const executor = tx ?? this.db;\n const row = await executor.getFirstAsync<{ count: number }>(\n `SELECT COUNT(*) as count FROM ${this.prefix}events WHERE entity_id = ?`,\n [entityId],\n );\n return row?.count ?? 0;\n }\n\n /**\n * Return all events for an entity in chronological (ASC) order.\n * When limit is provided, fetches newest-first then reverses to preserve chronological order.\n */\n async getByEntityId(entityId: string, limit?: number): Promise<WikiEvent[]> {\n if (limit != null) {\n const rows = await this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at DESC LIMIT ?`,\n [entityId, limit],\n );\n return rows.slice().reverse();\n }\n return this.db.getAllAsync<WikiEvent>(\n `SELECT * FROM ${this.prefix}events WHERE entity_id = ? ORDER BY created_at ASC`,\n [entityId],\n );\n }\n}\n","import { BaseRepository } from './BaseRepository';\nimport type { WikiEdge, SQLiteAdapter } from '../types';\n\nexport interface NeighborhoodQueryOptions {\n maxDepth: number; // already clamped to [1,3] by the caller (GraphTraversalService)\n direction: 'inbound' | 'outbound' | 'both';\n edgeTypes?: string[]; // undefined = no filter; [] = match nothing (short-circuits)\n minConfidence: 'certain' | 'inferred' | 'tentative';\n excludeSourceTypes: string[];\n maxNodes: number;\n /**\n * When true, draft facts are dead-ends for *discovered* nodes — the recursive\n * walk will not step onto a draft, and will not step *past* one either, since\n * a draft's neighbours are unreachable through it. The anchor node is exempt\n * (it is validated up-front and never gated by this flag), so callers can\n * intentionally start from a draft. Default false (drafts visible).\n */\n excludeDrafts?: boolean;\n}\n\nconst CONFIDENCE_RANK: Record<'tentative' | 'inferred' | 'certain', number> = {\n tentative: 0,\n inferred: 1,\n certain: 2,\n};\n\nexport class EdgeRepository extends BaseRepository {\n /**\n * Insert an edge, silently skipping on primary-key or uniqueness conflicts.\n * Returns true when a row was inserted, false when skipped as a duplicate.\n * Throws when the insert was skipped due to an id collision with a different edge tuple.\n */\n async addIgnoreDuplicate(edge: WikiEdge, tx?: SQLiteAdapter): Promise<boolean> {\n const executor = this.getExecutor(tx);\n const result = await executor.runAsync(\n `INSERT OR IGNORE INTO ${this.prefix}edges (id, entity_id, source_id, target_id, edge_type, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [edge.id, edge.entity_id, edge.source_id, edge.target_id, edge.edge_type, edge.created_at],\n );\n\n if (result.changes > 0) return true;\n\n const existing = await executor.getFirstAsync<{\n entity_id: string;\n source_id: string;\n target_id: string;\n edge_type: string;\n }>(\n `SELECT entity_id, source_id, target_id, edge_type FROM ${this.prefix}edges WHERE id = ?`,\n [edge.id],\n );\n\n if (!existing) return false;\n\n if (\n String(existing.entity_id) !== edge.entity_id ||\n String(existing.source_id) !== edge.source_id ||\n String(existing.target_id) !== edge.target_id ||\n String(existing.edge_type) !== edge.edge_type\n ) {\n throw new Error(\n `Edge id collision: ${JSON.stringify(edge.id)} already exists with a different (entity_id, source_id, target_id, edge_type) tuple`,\n );\n }\n\n return false;\n }\n\n async getByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<WikiEdge[]> {\n const executor = this.getExecutor(tx);\n const rows = await executor.getAllAsync<any>(\n `SELECT * FROM ${this.prefix}edges WHERE entity_id = ? ORDER BY created_at ASC`,\n [entityId],\n );\n return rows.map(mapRowToEdge);\n }\n\n /** Hard delete — edges have no soft-delete concept, only presence/absence. `tx` is REQUIRED. */\n async bulkDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(`DELETE FROM ${this.prefix}edges WHERE entity_id = ?`, [entityId]);\n }\n\n /**\n * Hard-delete every edge whose `source_id` is in `sourceFactIds`, scoped to\n * `entityId`. Returns the number of rows deleted. Edges have no soft-delete\n * concept; this method is named `softDeleteBySourceFactIds` for symmetry with\n * `EntryRepository.softDeleteBySource` (which IS a soft delete), but its\n * semantics are immediate presence/absence removal. Use ONLY inside an open\n * transaction — the method requires `tx` and performs no autocommit.\n *\n * Used by `IngestionService.upsertGraphCore` to retire the prior parse's\n * edges whose source facts are being superseded by `softDeleteBySource`.\n */\n async softDeleteBySourceFactIds(\n entityId: string,\n sourceFactIds: readonly string[],\n tx: SQLiteAdapter,\n ): Promise<number> {\n if (sourceFactIds.length === 0) return 0;\n const executor = this.getExecutor(tx);\n // SQLite's SQLITE_MAX_VARIABLE_NUMBER defaults to 32,766; binding\n // `entityId` plus every ID in one statement would overflow once a\n // single sourceRef accumulates tens of thousands of facts. Chunk to\n // stay well under the limit, reusing the supplied tx executor.\n const chunkSize = 500;\n let totalChanges = 0;\n for (let i = 0; i < sourceFactIds.length; i += chunkSize) {\n const chunk = sourceFactIds.slice(i, i + chunkSize);\n const placeholders = chunk.map(() => '?').join(',');\n const result = await executor.runAsync(\n `DELETE FROM ${this.prefix}edges\n WHERE entity_id = ? AND source_id IN (${placeholders})`,\n [entityId, ...chunk],\n );\n totalChanges += result.changes;\n }\n return totalChanges;\n }\n\n /**\n * Multi-hop traversal from `sourceId` via SQLite `WITH RECURSIVE`. All filtering,\n * dead-ending, cycle-guarding, capping, and ordering happens in this one query.\n * The anchor is validated (exists, right entity, not soft-deleted) but never gated\n * by confidence/source_type — only nodes discovered beyond it are.\n */\n async getNeighborhood(\n entityId: string,\n sourceId: string,\n opts: NeighborhoodQueryOptions,\n tx?: SQLiteAdapter,\n ): Promise<{ nodeIds: string[]; edges: WikiEdge[] }> {\n const executor = this.getExecutor(tx);\n\n if (opts.edgeTypes && opts.edgeTypes.length === 0) {\n const anchor = await executor.getFirstAsync<{ id: string }>(\n `SELECT id FROM ${this.prefix}entries WHERE id = ? AND entity_id = ? AND deleted_at IS NULL`,\n [sourceId, entityId],\n );\n return { nodeIds: anchor ? [anchor.id] : [], edges: [] };\n }\n\n const edgeTypesClause = opts.edgeTypes\n ? `e.edge_type IN (${opts.edgeTypes.map(() => '?').join(',')})`\n : '1=1';\n const excludeSourceTypesPlaceholders = opts.excludeSourceTypes.map(() => '?').join(',');\n const minConfidenceRank = CONFIDENCE_RANK[opts.minConfidence];\n\n const sql = `\n WITH RECURSIVE walk(node_id, depth, visited) AS (\n SELECT id, 0, ',' || id || ','\n FROM ${this.prefix}entries\n WHERE id = ? AND entity_id = ? AND deleted_at IS NULL\n\n UNION\n\n SELECT\n CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END,\n w.depth + 1,\n w.visited || (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END) || ','\n FROM walk w\n JOIN ${this.prefix}edges e\n ON e.entity_id = ?\n AND (\n (? != 'inbound' AND e.source_id = w.node_id) OR\n (? != 'outbound' AND e.target_id = w.node_id)\n )\n AND (${edgeTypesClause})\n JOIN ${this.prefix}entries n\n ON n.id = (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END)\n AND n.entity_id = ?\n AND n.deleted_at IS NULL\n AND (\n CASE n.confidence\n WHEN 'tentative' THEN 0\n WHEN 'inferred' THEN 1\n WHEN 'certain' THEN 2\n ELSE -1\n END\n ) >= ?\n AND n.source_type NOT IN (${excludeSourceTypesPlaceholders})\n AND (? = 0 OR n.lifecycle_status != 'draft')\n WHERE w.depth < ?\n AND instr(w.visited, ',' || (CASE WHEN e.source_id = w.node_id THEN e.target_id ELSE e.source_id END) || ',') = 0\n )\n SELECT node_id, MIN(depth) AS depth\n FROM walk\n GROUP BY node_id\n ORDER BY depth ASC, (SELECT updated_at FROM ${this.prefix}entries WHERE id = node_id) DESC\n LIMIT ?\n `;\n\n const params: unknown[] = [\n sourceId, entityId,\n entityId,\n opts.direction, opts.direction,\n ...(opts.edgeTypes ?? []),\n entityId,\n minConfidenceRank,\n ...opts.excludeSourceTypes,\n opts.excludeDrafts === true ? 1 : 0,\n opts.maxDepth,\n opts.maxNodes,\n ];\n\n const rows = await executor.getAllAsync<{ node_id: string; depth: number }>(sql, params);\n const nodeIds = rows.map((r) => r.node_id);\n if (nodeIds.length === 0) return { nodeIds: [], edges: [] };\n\n const valueRows = nodeIds.map(() => '(?)').join(', ');\n const edgeRows = await executor.getAllAsync<any>(\n `WITH neighborhood(node_id) AS (VALUES ${valueRows})\n SELECT e.* FROM ${this.prefix}edges e\n JOIN neighborhood ns ON e.source_id = ns.node_id\n JOIN neighborhood nt ON e.target_id = nt.node_id\n WHERE e.entity_id = ?`,\n [...nodeIds, entityId],\n );\n\n return { nodeIds, edges: edgeRows.map(mapRowToEdge) };\n }\n}\n\nfunction mapRowToEdge(row: any): WikiEdge {\n return {\n id: String(row.id),\n entity_id: String(row.entity_id),\n source_id: String(row.source_id),\n target_id: String(row.target_id),\n edge_type: String(row.edge_type),\n created_at: Number(row.created_at),\n };\n}\n","import type {\n OntologyManifest,\n OntologyNodeType,\n OntologyUpdates,\n ExtractedFactEdge,\n} from '../types';\nimport { WikiStrictOntologyViolation } 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\n/**\n * True when `concreteType` satisfies a declared type: an exact\n * (case-insensitive) match, or a one-hop parent match — the concrete type's\n * `parent_type` equals the declared type. Never recursive (D1). Exact matches\n * short-circuit before the node lookup, so manifests with no `parent_type`\n * behave bit-for-bit as before.\n */\nexport function typeSatisfies(\n declaredType: string,\n concreteType: string,\n manifest: OntologyManifest,\n): boolean {\n const concrete = concreteType.trim().toLowerCase();\n const declared = declaredType.trim().toLowerCase();\n if (!concrete || !declared) return false;\n if (declared === concrete) return true;\n // `node_types` is typed non-optional but arrives from JSON.parse of a DB row\n // at runtime, so guard it the way validateManifest already does — and for the\n // same reason, `typeof`-check the fields rather than calling .trim() on them.\n // This runs inside the caller's transaction, so a TypeError here aborts an\n // ingest exactly like one in the merge path. Manifests reaching this point\n // have already passed validateManifest (getManifest:164, and seeds via D11),\n // so this is defense in depth, not the primary guard.\n const def = (manifest.node_types ?? []).find(\n n => typeof n?.type === 'string' && n.type.trim().toLowerCase() === concrete,\n );\n const parent = typeof def?.parent_type === 'string'\n ? def.parent_type.trim().toLowerCase()\n : '';\n return parent !== '' && parent === declared;\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 // D1: optional one-level parent inheritance. A parent must be a real,\n // distinct node in the same manifest, and must not itself have a parent.\n // The chain check also rejects 2-cycles, which self-parent alone misses.\n const parentOf = new Map<string, string | undefined>();\n for (const node of manifest.node_types ?? []) {\n const parent = typeof node.parent_type === 'string'\n ? node.parent_type.trim().toLowerCase()\n : undefined;\n parentOf.set(node.type.trim().toLowerCase(), parent);\n }\n for (const node of manifest.node_types ?? []) {\n // D10: absent means \"no parent\"; present-but-unusable is malformed.\n if (node.parent_type === undefined) continue;\n // Typed `string | undefined`, but this runs on JSON.parse output from\n // `entity_manifests.manifest_json` on every read (MetadataRepository:164),\n // so a legacy or hand-edited row can carry a number or `null`. Unguarded,\n // `.trim()` on those raises a bare TypeError instead of this error.\n if (typeof node.parent_type !== 'string' || !node.parent_type.trim()) {\n throw new Error(`Ontology parent_type must be a non-empty string when present: ${node.type}`);\n }\n const parentSlug = node.parent_type.trim().toLowerCase();\n if (parentSlug === node.type.trim().toLowerCase()) {\n throw new Error(`Self-parent: ${node.type}`);\n }\n if (!nodeSlugs.has(parentSlug)) {\n throw new Error(`Parent type not found: ${node.parent_type}`);\n }\n const grandparent = parentOf.get(parentSlug);\n if (grandparent) {\n throw new Error(`Parent chain too deep: ${node.type} → ${node.parent_type} → ${grandparent}`);\n }\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\n// D6: emergent updates are untrusted. `updates` is JSON.parse output, so\n// every field is `unknown` at runtime whatever the TS types say — `.trim()`\n// on a number or an object throws a TypeError straight out of the caller's\n// transaction, which is the failure D6 exists to prevent. Guard every read.\n//\n// Exported so the test suite can exercise the index's untrusted-input\n// contract directly, without going through mergeOntologyUpdates — whose\n// pre-existing node loop (utils/ontology.ts:176) is unchanged by this work.\nexport function buildDeclaresParentIndex(\n nodes: ReadonlyArray<OntologyNodeType>,\n): Map<string, boolean> {\n const declaresParent = new Map<string, boolean>();\n for (const n of nodes) {\n const slug = typeof n?.type === 'string' ? n.type.trim().toLowerCase() : '';\n if (!slug || declaresParent.has(slug)) continue;\n declaresParent.set(slug, n?.parent_type !== undefined);\n }\n return declaresParent;\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 // Index over current + proposed nodes, first-seen wins (mirrors the dedup in\n // the loop below). Value: did this slug declare a `parent_type` key at all?\n // Presence, not usability — a node that declared one cannot serve as a\n // parent, whether it is a real child or a malformed proposal.\n const declaresParent = buildDeclaresParentIndex([\n ...current.node_types,\n ...(updates.node_types ?? []),\n ]);\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 // Drop a non-string, blank, unresolvable, self-referential, or two-deep\n // parent rather than letting it throw inside the caller's transaction (D6).\n // `declaresParent.get(...) === false` is the whole gate: `undefined` means\n // the slug is unknown, `true` means that node declared a parent of its own.\n const rawParent = typeof node?.parent_type === 'string' ? node.parent_type.trim() : '';\n const parentSlug = rawParent.toLowerCase();\n const keepParent = parentSlug !== ''\n && parentSlug !== key\n && declaresParent.get(parentSlug) === false;\n node_types.push({\n type,\n description: String(node.description ?? ''),\n ...(keepParent ? { parent_type: rawParent } : {}),\n });\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 type EdgeDropReason =\n | 'no_source_type'\n | 'invalid_shape'\n | 'type_not_in_manifest'\n | 'target_not_found'\n | 'target_type_mismatch';\n\n/** A dropped LLM-proposed edge. Slugs only — `target_title` is content and is never recorded. */\nexport interface EdgeDrop {\n reason: EdgeDropReason;\n /** Source fact id when known; null while validating before the fact has an id. */\n sourceId: string | null;\n edgeType: string | null;\n sourceNodeType: string | null;\n targetNodeType: string | null;\n}\n\nexport function validateInlineEdges(\n sourceType: string,\n _targetType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n opts?: { strict?: boolean; entityId?: string; drops?: EdgeDrop[] },\n): ExtractedFactEdge[] {\n const strict = opts?.strict === true;\n const entityId = opts?.entityId ?? '';\n const drops = opts?.drops;\n const drop = (reason: EdgeDropReason, edgeType: string | null): void => {\n drops?.push({ reason, sourceId: null, edgeType, sourceNodeType: sourceType, targetNodeType: null });\n };\n if (!Array.isArray(edges)) {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', '');\n drop('invalid_shape', null);\n return [];\n }\n const valid: ExtractedFactEdge[] = [];\n for (const edge of edges) {\n if (typeof edge?.edge_type !== 'string' || typeof edge?.target_title !== 'string') {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', String(edge?.edge_type ?? ''));\n drop('invalid_shape', typeof edge?.edge_type === 'string' ? edge.edge_type : null);\n continue;\n }\n const defs = resolveEdgeDefinitions(edge.edge_type, manifest);\n const match = defs.find(d => typeSatisfies(d.source_type, sourceType, manifest));\n if (!match) {\n if (strict) throw new WikiStrictOntologyViolation(entityId, 'edge', edge.edge_type);\n drop('type_not_in_manifest', edge.edge_type);\n continue;\n }\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 /**\n * Returns the set of distinct `entity_id` values across entries/tasks/events.\n *\n * Deliberately widened from a prior `WHERE deleted_at IS NULL` form: the\n * returned set intentionally includes entities whose only rows are\n * soft-deleted, so the host's maintenance sweep can visit such\n * \"decommissioned-scope\" namespaces and reap the soft-deleted rows. Sorting\n * is `entity_id COLLATE BINARY` for stable, locale-independent ordering.\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\n UNION\n SELECT entity_id FROM ${this.prefix}tasks\n UNION\n SELECT entity_id FROM ${this.prefix}events\n ) ORDER BY entity_id COLLATE BINARY`,\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 /**\n * Write an entity's manifest.\n *\n * `opts.ifAbsent` selects the conflict behaviour:\n * - omitted / `false` — upsert. An existing row is replaced.\n * - `true` — create-if-absent. An existing row is left exactly as it is.\n *\n * Returns whether this call actually wrote a row. Under `ifAbsent` a `false`\n * result means another writer got there first; the check and the write are one\n * statement, so there is no window between them.\n */\n async setManifest(\n entityId: string,\n data: { mode: OntologyMode; manifest: OntologyManifest },\n tx: SQLiteAdapter,\n opts?: { ifAbsent?: boolean },\n ): Promise<boolean> {\n validateManifest(data.manifest);\n const executor = this.getExecutor(tx);\n const conflictClause = opts?.ifAbsent\n ? 'ON CONFLICT(entity_id) DO NOTHING'\n : `ON CONFLICT(entity_id) DO UPDATE SET\n mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`;\n const result = await executor.runAsync(\n `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)\n VALUES (?, ?, ?, ?)\n ${conflictClause}`,\n [entityId, data.mode, JSON.stringify(data.manifest), Date.now()],\n );\n return result.changes > 0;\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","export function cosineSimilarity(a: ArrayLike<number>, b: ArrayLike<number>): number {\n let dot = 0, normA = 0, normB = 0;\n const len = Math.min(a.length, b.length);\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n","export function parseEmbedding(\n blob: Uint8Array | null | undefined,\n text: string | null | undefined\n): Float32Array | null {\n if (blob && blob.byteLength > 0) {\n if (blob.byteLength % 4 !== 0) return null;\n // Copy into fresh ArrayBuffer — SQLite drivers may return pooled Buffer\n // objects that get reused across queries, silently corrupting cached vectors.\n const copy = new ArrayBuffer(blob.byteLength);\n new Uint8Array(copy).set(blob);\n const vector = new Float32Array(copy);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n }\n if (text) {\n try {\n const arr: unknown = JSON.parse(text);\n if (!Array.isArray(arr) || !arr.every((v: unknown) => typeof v === 'number' && isFinite(v))) return null;\n const vector = new Float32Array(arr as number[]);\n for (const value of vector) {\n if (!Number.isFinite(value)) return null;\n }\n return vector;\n } catch { return null; }\n }\n return null;\n}\n","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 /**\n * Per-(entityId, sourceHash) promise-chain lock. Serializes ingest races\n * at the application level (the v9 partial UNIQUE index enforces it at\n * the DB level as defense-in-depth). Two callers holding the same hash\n * see FIFO order; different hashes never block one another.\n *\n * Keyed `${entityId}\\0${sourceHash}` so distinct (entityId, sourceHash)\n * pairs can never share a lock. A raw concatenation would let\n * (\"ab\", \"c…\") collide with (\"a\", \"bc…\"); the NUL separator makes that\n * impossible because neither component can contain NUL (entityIds are\n * user-supplied identifiers; sourceHashes are hex digests).\n */\n private hashLocks: Map<string, Promise<unknown>> = new Map();\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 _hashLockKey(entityId: string, sourceHash: string): string {\n return `${entityId}\\0${sourceHash}`;\n }\n\n /**\n * Acquire a promise-chain lock scoped to one `(entityId, sourceHash)` pair.\n * Returns a zero-argument release closure that removes the current tail\n * from the chain. Releasing is idempotent so a holder that double-fires\n * (e.g. on a finally that races an explicit release) cannot unblock\n * the next holder prematurely.\n *\n * Documented ordering: ingest acquires the hash lock FIRST, then the\n * synchronous sourceRef ingest lock, and the release closure unwinds in\n * the opposite order (sourceRef first, hash second). Hash-then-sourceRef\n * is required because the v9 partial UNIQUE index conflicts on the\n * (entity_id, source_hash) pair regardless of source_ref, so two callers\n * with DIFFERENT source_refs racing the same hash are the exact case the\n * TOCTOU race fix needs to serialize.\n *\n * Mechanics: each holder owns a private `released` promise that resolves\n * only when THIS holder calls release(). The map stores the holder's\n * `released` promise as the \"tail\" — the NEXT caller awaits that tail\n * via `previous = this.hashLocks.get(key)`. The current caller gets\n * their unique release function once `previous` (the prior holder's\n * release signal) settles, so each holder is guaranteed a UNIQUE release\n * closure bound to their own `released` promise.\n */\n acquireHashLock(entityId: string, sourceHash: string): Promise<() => void> {\n const key = this._hashLockKey(entityId, sourceHash);\n const previous = this.hashLocks.get(key) ?? Promise.resolve();\n let resolveReleased!: () => void;\n const released = new Promise<void>((resolve) => { resolveReleased = resolve; });\n let fired = false;\n const release = () => {\n if (fired) return;\n fired = true;\n // Unlink from the map ONLY if we are still the current tail; otherwise\n // a fresh holder has already chained a new tail and ours would race.\n if (this.hashLocks.get(key) === released) {\n this.hashLocks.delete(key);\n }\n resolveReleased();\n };\n this.hashLocks.set(key, released);\n // Wait for the prior holder to release, then hand back OUR unique closure.\n return previous.then(() => release);\n }\n\n private _pruneKey(entityId: string) { return `${this.prefix}:${entityId}:prune`; }\n private _reembedKey(entityId: string) { return `${this.prefix}:${entityId}:reembed`; }\n private _globalReembedKey() { return `${this.prefix}:reembed`; }\n private _importKey(entityId: string) { return `${this.prefix}:${entityId}:import`; }\n private _globalImportKey() { return `${this.prefix}:import`; }\n private _forgetKey(entityId: string) { return `${this.prefix}:${entityId}:forget`; }\n private _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 /**\n * True while any reembed sweep is in flight — per-entity or global.\n *\n * Read-only; acquires nothing. Callers that mutate embedding failure\n * markers across ALL entities (the dimension-promotion clear) must gate on\n * this and defer, rather than resurrect rows an in-flight sweep already\n * classified. See spec 2026-09-05-reembed-lock-scope-design.md §2.\n *\n * The global key `${prefix}:reembed` also ends in ':reembed', so the suffix\n * scan alone would already match it. The explicit check is kept because it\n * documents the intent and survives any future change to the global key's\n * format.\n */\n isAnyReembedActive(): boolean {\n return this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n this._isAnyMaintenanceActiveWithSuffix(':reembed');\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 case 'reembed':\n return this.activeMaintenanceJobs.has(this._reembedKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n 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._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n case 'global_reembed':\n return this.activeMaintenanceJobs.has(this._globalReembedKey()) ||\n this._isAnyMaintenanceActiveWithSuffix(':reembed') ||\n this._isAnyMaintenanceActiveWithSuffix(':prune') ||\n this._isAnyMaintenanceActiveWithSuffix(':librarian') ||\n this._isAnyMaintenanceActiveWithSuffix(':heal') ||\n this._isAnyMaintenanceActiveWithSuffix(':ontologyBackfill') ||\n this.activeIngestJobs.size > 0 ||\n this._isAnyMaintenanceActiveWithSuffix(':import') ||\n this._isAnyMaintenanceActiveWithSuffix(':forget');\n case 'import':\n case 'forget': {\n const selfKey = operation === 'import' ? this._importKey(entityId) : this._forgetKey(entityId);\n return this.activeMaintenanceJobs.has(selfKey) ||\n this.activeMaintenanceJobs.has(this._librarianKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._healKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(entityId) ||\n this._isIngestActiveFor(entityId) ||\n this._isImportActiveFor(entityId) ||\n this._isForgetActiveFor(entityId);\n }\n case 'global_import':\n return this.activeMaintenanceJobs.has(this._globalImportKey());\n case 'ingest':\n return this._hasIngestJob(entityId) ||\n this.activeMaintenanceJobs.has(this._pruneKey(entityId)) ||\n this._isReembedActive(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\n * permissiveness for write() auto-trigger paths — stricter checks stay in\n * acquireLock() — with one exception: reembed sweeps, which are excluded\n * structurally rather than by accident (see below).\n */\n tryAcquireAutoHealLock(entityId: string): boolean {\n // Heal must not run during a sweep. It is safe today only because heal\n // upserts blob-less facts and the marker clear is guarded by\n // `CASE WHEN excluded.embedding_blob IS NOT NULL` — an accident of the\n // current SQL, not a stated rule. Make the exclusion structural so a\n // future heal that carries blobs cannot silently resurrect rows an\n // in-flight sweep classified. Spec 2026-09-05 §3.3.\n //\n // A refused pass is not lost work: WriteService.maybeRunHeal holds its\n // checkpoint back, so the next write retries.\n if (this.isAnyReembedActive()) return false;\n\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 * Centralized ingest lock acquisition. Acquires the hash lock FIRST\n * (FIFO across callers racing the same hash), then the synchronous\n * sourceRef ingest lock (rejects cross-entity conflicts and busy\n * operations). Returns a single zero-argument release closure that\n * unwinds in the opposite order — sourceRef first, hash second — so\n * the sourceRef lock is freed the instant its work is done and only\n * the hash lock keeps serializing the duplicate-content race window.\n *\n * On a sourceRef conflict (WikiBusyError thrown synchronously by the\n * underlying acquireLock) the hash lock is released BEFORE the error\n * propagates, so the next caller in the hash chain is not held up by\n * a request that never reached the DB.\n */\n async acquireIngestLocks(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n ): Promise<() => void> {\n const releaseHash = await this.acquireHashLock(entityId, sourceHash);\n let sourceLockAcquired = false;\n try {\n this.acquireLock('ingest', entityId, sourceRef);\n sourceLockAcquired = true;\n } catch (err) {\n releaseHash();\n throw err;\n }\n return () => {\n try {\n if (sourceLockAcquired) this.releaseLock('ingest', entityId, sourceRef);\n } finally {\n releaseHash();\n }\n };\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 { ExtractedFact, ExtractedTask } from '../types';\nimport { WikiParseError } from '../types';\n\n/**\n * Maximum number of candidate substrings the tier-2 walker will try before\n * throwing `WikiParseError`. 5 covers the realistic case (a few bare quotes\n * produce a few candidate spans) without unbounded retry on truly broken\n * inputs.\n */\nconst MAX_REPAIR_CANDIDATES = 5;\n\n/**\n * Throws {@link WikiParseError} for the \"no JSON object/array found\" case.\n * Used at the two strict-tier throw sites that differ only in whether a\n * `[`/`{` was located: when `start === null`, no open bracket was found;\n * when `start` is a number, an open bracket was found but no balanced\n * close existed. Both share the user-facing diagnostic.\n */\nfunction throwNoJsonFound(text: string, start: number | null): never {\n throw new WikiParseError(\n 'No JSON object/array found in LLM response',\n { tier: 'strict', position: start, slice: text },\n );\n}\n\n/**\n * Extract JSON from an LLM response.\n *\n * Tier 1 (strict): the existing hand-rolled brace-matching scanner. Walks\n * `text` from the first `{` or `[` to its matching close, respecting `\\\"` and\n * `\\\\`. Correct whenever the input contains no unescaped `\"` inside string\n * bodies. Returns the parsed value via `JSON.parse`.\n *\n * Tier 2 (repair): triggered only when tier 1 throws. Re-walks the raw text\n * from `start` (NOT from the scanner's possibly-truncated slice) with a\n * container-context stack that classifies every `\"` as **structural** (open\n * or close a string) or **content** (needs `\\` prefix). Produces candidate\n * substrings at every position the container stack returns to empty and\n * tries each largest-first; the first that `JSON.parse` accepts is returned.\n *\n * Throws {@link WikiParseError} when both tiers fail. The error's `tier`\n * field distinguishes 'strict' (no scanner slice found) from 'repair'\n * (scanner slice found but unparsable) from 'all' (catch-all).\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\n const useBrace =\n firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket);\n\n if (useBrace) {\n start = firstBrace;\n openChar = '{';\n } else if (firstBracket !== -1) {\n start = firstBracket;\n openChar = '[';\n } else {\n throwNoJsonFound(text, null);\n }\n\n // Tier 1: try the existing scanner first. If `JSON.parse` succeeds we're done.\n const slice = scanJsonSlice(text, start, openChar);\n if (slice !== null) {\n try {\n return JSON.parse(slice) as T;\n } catch {\n // fall through to tier 2\n }\n }\n\n // Tier 2: container-aware walker over the raw text. The scanner's slice may\n // be arbitrarily truncated by a bare quote mid-string — running the walker\n // on the raw text from `start` is the only way to get a complete container\n // span to repair against. The walker validates via `JSON.parse` itself and\n // returns the already-parsed value, so we don't re-parse on the hot path.\n //\n // The walker runs twice under opposing comma-ambiguity policies — see\n // `containerAwareRepair` docstring. Both passes can produce parseable\n // JSON for the SAME input but with different shapes — e.g. for\n // `{\"title\":\"He said \"hi\"\",\"body\":\"ok\"}` the odd-parity pass swallows\n // `,\"body\":\"ok\"` into the title (parseable but wrong), while for\n // `{\"title\":\"24\" monitor\",\"body\":\"ok\"}` the even-parity pass does the\n // swallowing. When both parse, we prefer the pass that mutated the input\n // LESS (fewer content-quote escapes): the correct interpretation escapes\n // exactly the true bare quotes, while the swallowing one escapes the\n // structural quotes it consumes too. When only the odd-parity pass parsed\n // AND it never hit a comma-ambiguity position, the even-parity pass is\n // guaranteed to make identical decisions, so we skip it entirely. Each\n // pass is bounded by MAX_REPAIR_CANDIDATES.\n const repairOdd = containerAwareRepair(text, start, false);\n if (repairOdd.success !== null && !repairOdd.ambiguous) {\n return repairOdd.success as T;\n }\n const repairEven = containerAwareRepair(text, start, true);\n if (repairOdd.success !== null && repairEven.success !== null) {\n // Both policies produced a parseable candidate. Prefer the minimal\n // repair; on a tie (identical walks) keep the odd-parity result, which\n // matches the historical single-pass behavior.\n const pick = repairEven.escapes < repairOdd.escapes ? repairEven : repairOdd;\n return pick.success as T;\n }\n if (repairOdd.success !== null) {\n return repairOdd.success as T;\n }\n if (repairEven.success !== null) {\n return repairEven.success as T;\n }\n // Both policies failed to parse. Prefer the even-parity failed candidate\n // as the diagnostic — it's the original walker behavior and its failure\n // message matches what callers (and existing tests) expect on\n // balanced-but-invalid payloads like `{\"facts\":}`.\n const repair = repairEven.failed !== null ? repairEven : repairOdd;\n if (repair.failed !== null) {\n throw new WikiParseError(\n `Repair produced a candidate but JSON.parse rejected it: ${repair.failed.message}`,\n { tier: 'repair', position: repair.failed.position, slice: repair.failed.candidate },\n );\n }\n\n // Per spec (WikiParseError `tier: 'strict'`): a scanner that produced NO\n // usable slice (no balanced close) is a strict failure even when the\n // container-aware walker also finds nothing — the input is structurally\n // incomplete, not just unparseable.\n if (slice === null) {\n throwNoJsonFound(text, start);\n }\n\n throw new WikiParseError(\n 'No parsable JSON candidate found',\n { tier: 'all', position: start, slice: text },\n );\n}\n\n/**\n * Tier-1 scanner: returns the substring from `start` to the matching close\n * of the container opened by `openChar` at `start`, or `null` if no balanced\n * close exists. Pure function — extracted so `parseJsonResponse` reads as\n * the two-tier flow it implements.\n */\nfunction scanJsonSlice(text: string, start: number, openChar: string): string | null {\n const closeChar = openChar === '{' ? '}' : ']';\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 if (end === -1) return null;\n // safeSlice lives in this same file and is the project's surrogate-pair-safe\n // string-slice helper (used by chunkText). Bare `text.slice(start, end + 1)`\n // can split a UTF-16 surrogate pair when `end` lands between the high and\n // low halves; the walker downstream then trips on a U+FFFD replacement char.\n return safeSlice(text, start, end + 1);\n}\n\n/**\n * Tier-2 walker: re-walks the raw text from `start` with a container-context\n * stack and a peek-ahead rule that classifies every `\"` as either structural\n * (opens/closes a string) or content (needs `\\` prefix). Produces candidate\n * substrings at every balanced container close and returns the first one\n * that `JSON.parse` would accept (largest balanced span first), or `null` if\n * no candidate parses.\n *\n * The walker tries two policies at comma-ambiguity positions (`\"X\"`,\n * `X` ends in a bare quote, peek-ahead is `,`):\n *\n * - `closeOnEvenParity=true` — treat the quote as STRUCTURAL CLOSE when the\n * bare-quote count is EVEN, content escape when ODD. This is the heuristic\n * that has historically matched LLM output (it works for `\"He said \"hi\", then left.\"`).\n * - `closeOnEvenParity=false` — the opposite flip. Required for inputs whose\n * real close is at an ODD count (e.g. `\"24\" monitor\",\"body\":\"ok\"}`), where\n * the model intended one literal `\"` inside the value string and the next\n * `\"` to be the structural close.\n *\n * `parseJsonResponse` runs both policies and accepts the first parse-success\n * from either; {@link MAX_REPAIR_CANDIDATES} bounds each policy's emissions\n * so the combined work stays small.\n */\ninterface ContainerFrame {\n container: 'object' | 'array';\n /**\n * For objects: `true` while the next string token starts a property NAME;\n * `false` while the next string token starts a property VALUE. Stays the\n * role through `,` (a `,` in an object leaves us expecting a key again) and\n * through `:` (a `:` leaves us expecting a value). Arrays always treat\n * every string as a value, so this flag is unused for arrays.\n */\n expectKey: boolean;\n}\n\ninterface RepairFailure {\n candidate: string;\n position: number | null;\n message: string;\n}\n\ninterface RepairResult {\n /** First candidate that JSON.parse accepted, or null if none parsed. */\n success: unknown | null;\n /** First candidate that JSON.parse rejected (best diagnostic), or null. */\n failed: RepairFailure | null;\n /** Number of content quotes this policy escaped (mutated) while walking.\n * Used to arbitrate when BOTH policies produce a parseable candidate:\n * the interpretation that mutated the input less is preferred. */\n escapes: number;\n /** True when the walk hit at least one comma-ambiguity position — the\n * only place the two policies' decisions can diverge. When false, the\n * opposing-policy pass is guaranteed to make identical decisions, so the\n * caller can skip it entirely. */\n ambiguous: boolean;\n}\n\nfunction containerAwareRepair(\n text: string,\n start: number,\n closeOnEvenParity: boolean,\n): RepairResult {\n // The walker produces a stream of balanced-span candidates in largest-first\n // order. We try each via `JSON.parse` at emission time so the success\n // path short-circuits without ever building the trailing-prefix out of\n // the walker; on a rejection we capture the first failure as the best\n // diagnostic and keep walking to find another candidate (bounded by\n // MAX_REPAIR_CANDIDATES). The `failed` slot is what callers use to\n // construct a `WikiParseError` with `tier: 'repair'` when nothing parses\n // — the public contract documents the slice + parse position in the\n // error.\n const stack: ContainerFrame[] = [];\n let inString = false;\n let stringRole: 'key' | 'value' | null = null;\n let escape = false;\n let i = start;\n // Output buffer; rebuilt as we walk, used to emit candidate substrings.\n let out = '';\n // Tracks bare quotes emitted as content so far inside the current string\n // token. Used to suppress a structural close on a `,` peek-ahead when the\n // body still has an open unescaped bare quote (`{\"body\":\"hi\", then...`}`);\n // closing prematurely puts the comma at structural level where JSON.parse\n // expects a property name. Reset on every structural close (or open).\n let bareQuoteCount = 0;\n // Best rejection seen so far — captured when JSON.parse rejects a\n // candidate so we can surface it on `WikiParseError(tier: 'repair')`.\n let bestFailed: RepairFailure | null = null;\n // Content quotes escaped so far this pass (see RepairResult.escapes).\n let escapes = 0;\n // Whether any comma-ambiguity position was reached (see\n // RepairResult.ambiguous).\n let ambiguous = false;\n // Captured successfully-parsed value of the first candidate that JSON.parse\n // accepted. Carried through the walker's short-circuit return so callers\n // can skip a second `JSON.parse` and `T`-cast on the hot success path.\n let bestSuccess: unknown = null;\n let attempts = 0;\n\n // Try `JSON.parse(candidate)` immediately on emission; capture the\n // failure as bestFailed (or the value as bestSuccess) and bump the\n // attempt counter. Returns true on success so the caller can short-circuit\n // out of the walk.\n //\n // `safeErrorToString` (defined in this same file) is the hardened\n // non-throwing coercion for the message field. `JSON.parse` always throws\n // a `SyntaxError`, but a hostile SyntaxError subclass with a throwing\n // `message` getter could still escape a raw `err.message` access —\n // delegating to `safeErrorToString` keeps the helper non-throwing.\n function tryEmitCandidate(candidate: string): boolean {\n attempts++;\n try {\n bestSuccess = JSON.parse(candidate);\n return true;\n } catch (err) {\n if (bestFailed === null) {\n bestFailed = {\n candidate,\n position: extractParsePosition(err),\n message: safeErrorToString(err),\n };\n }\n return false;\n }\n }\n\n while (i < text.length) {\n const ch = text[i];\n\n // Between top-level spans (stack empty after a failed candidate emit):\n // skip everything except a new container opener, and never accumulate\n // the inter-span text into `out` — sibling candidates must be\n // standalone spans, not span1 + prose + span2 concatenations that\n // JSON.parse can never accept.\n if (stack.length === 0 && !inString) {\n if (ch === '{' || ch === '[') {\n stack.push({ container: ch === '{' ? 'object' : 'array', expectKey: true });\n out += ch;\n }\n i++;\n continue;\n }\n\n if (escape) {\n out += ch;\n escape = false;\n i++;\n continue;\n }\n if (inString && ch === '\\\\') {\n out += ch;\n escape = true;\n i++;\n continue;\n }\n // Raw C0 control characters are invalid inside JSON strings, always.\n // Unlike the bare-quote case this repair is fully deterministic (no\n // comma-parity ambiguity — a control char inside a string body can\n // only be content), so both policy passes escape identically.\n if (inString) {\n const code = ch.charCodeAt(0);\n if (code < 0x20) {\n out += controlCharEscape(code);\n i++;\n continue;\n }\n }\n if (ch === '\"') {\n // Peek-ahead: skip whitespace, then look at the next non-whitespace char.\n let j = i + 1;\n while (j < text.length && (text[j] === ' ' || text[j] === '\\t' || text[j] === '\\n' || text[j] === '\\r')) {\n j++;\n }\n const next = j < text.length ? text[j] : '';\n\n if (!inString) {\n // A `\"` sitting at structural level right before a container close\n // is stray punctuation from a mis-tracked string boundary — emitting\n // it would open an unterminated string and guarantee JSON.parse\n // rejects the candidate. Skip the quote itself, preserve any\n // whitespace the peek-ahead skipped, emit the close, and pop.\n if (next === '}' || next === ']') {\n if (j > i + 1) out += text.slice(i + 1, j);\n out += next;\n i = j + 1;\n stack.pop();\n if (stack.length === 0) {\n if (tryEmitCandidate(out)) return { success: bestSuccess, failed: bestFailed, escapes, ambiguous };\n if (attempts >= MAX_REPAIR_CANDIDATES) break;\n out = '';\n }\n continue;\n }\n // Structural opening quote — always treated as opening (no escape).\n // Determine the string's role from the top frame: object + expectKey\n // → key, otherwise value. Arrays always treat strings as values.\n const top = stack[stack.length - 1];\n stringRole = top?.container === 'object' && top.expectKey ? 'key' : 'value';\n out += ch;\n inString = true;\n i++;\n continue;\n }\n\n // We're inside a string. Closing if next is one of , } ] : or another \" followed by :\n // Suppress the comma-only close when we have an open bare quote —\n // a `,` peek-ahead after an odd number of bare quotes means the\n // comma is body content, not a structural separator.\n //\n // Role-aware: `next === ':'` and `next === '\"' && text[j+1] === ':'`\n // are KEY-close signals (the `: ` is the JSON \"this string was a key\"\n // separator) and only fire for `stringRole === 'key'`. For value\n // strings, a `:` after the closing quote is body content (e.g.\n // `{\"body\":\"foo: \"bar\": baz\"}`) — closing prematurely there corrupts\n // the value. The `,` `}` `]` cases are value-close signals and always\n // apply.\n const commaOnly = next === ',';\n const isKeyClose = stringRole === 'key' && (\n next === ':' ||\n (next === '\"' && j + 1 < text.length && text[j + 1] === ':')\n );\n const isValueClose = !commaOnly && (\n next === ',' ||\n next === '}' ||\n next === ']'\n );\n // Comma-ambiguity: when the peek-ahead is `,` after at least one\n // bare-quote content escape, neither interpretation is structurally\n // implied — the comma is either a value separator OR content body.\n // The two passes diverge ONLY here (see the parameter docs on\n // `containerAwareRepair`): the `closeOnEvenParity=true` pass closes\n // on an even count (the legacy heuristic), the false pass on an odd\n // count. When `bareQuoteCount === 0` no ambiguity exists — the comma\n // must close — so both passes close and the caller can skip the\n // second pass entirely (see RepairResult.ambiguous).\n if (commaOnly && bareQuoteCount > 0) ambiguous = true;\n const shouldCommaClose =\n commaOnly && (\n bareQuoteCount === 0 ||\n (closeOnEvenParity\n ? bareQuoteCount % 2 === 0\n : bareQuoteCount % 2 === 1)\n );\n const isClosing =\n isKeyClose ||\n isValueClose ||\n shouldCommaClose;\n\n if (isClosing) {\n out += ch;\n inString = false;\n // Update the top frame's expectKey state. After closing a key, the\n // next string token is a value (separator is `:`) — expectKey=false.\n // After closing a value in an object, the next string token is a key\n // (separator is `,` or end-of-object) — expectKey=true. Array frames\n // ignore this flag (every string in an array is a value).\n const topFrame = stack[stack.length - 1];\n if (topFrame && topFrame.container === 'object') {\n topFrame.expectKey = stringRole === 'value';\n }\n stringRole = null;\n bareQuoteCount = 0;\n i++;\n continue;\n }\n\n // Content quote — escape it.\n out += '\\\\' + ch;\n bareQuoteCount++;\n escapes++;\n i++;\n continue;\n }\n if (!inString && (ch === '{' || ch === '[')) {\n // Push a new frame. Objects start expecting a key; arrays ignore the\n // flag (every string token is a value).\n stack.push({ container: ch === '{' ? 'object' : 'array', expectKey: true });\n out += ch;\n i++;\n continue;\n }\n if (!inString && ch === ',') {\n // A `,` in an object leaves us expecting a key. The string-close handler\n // already sets `expectKey=true` after a value close, so the only case\n // we need to handle here is the unit-structural case where the prior\n // element was a primitive (number, null, true, false, etc.) — its\n // position in the OUT stream is identical to a value close for the\n // purposes of the next string token.\n const topFrame = stack[stack.length - 1];\n if (topFrame && topFrame.container === 'object') {\n topFrame.expectKey = true;\n }\n out += ch;\n i++;\n continue;\n }\n if (!inString && (ch === '}' || ch === ']')) {\n out += ch;\n stack.pop();\n if (stack.length === 0) {\n // Balanced close at this position — try the candidate. The largest\n // outer span is the first one tried, so this short-circuits on the\n // success path. On a rejection, reset `out` so any trailing sibling\n // span is emitted standalone rather than concatenated onto the\n // already-rejected prefix.\n if (tryEmitCandidate(out)) return { success: bestSuccess, failed: bestFailed, escapes, ambiguous };\n if (attempts >= MAX_REPAIR_CANDIDATES) break;\n out = '';\n }\n i++;\n continue;\n }\n\n out += ch;\n i++;\n }\n\n return { success: null, failed: bestFailed, escapes, ambiguous };\n}\n\n/**\n * Maps a C0 control character's code point to its JSON string escape.\n * Uses the short forms JSON shares with JS (\\n, \\t, \\r, \\b, \\f) and\n * \\u00XX for everything else, exactly as JSON.stringify would.\n */\nfunction controlCharEscape(code: number): string {\n switch (code) {\n case 0x0A: return '\\\\n';\n case 0x09: return '\\\\t';\n case 0x0D: return '\\\\r';\n case 0x08: return '\\\\b';\n case 0x0C: return '\\\\f';\n default: return '\\\\u' + code.toString(16).padStart(4, '0');\n }\n}\n\n/**\n * Pulls the position offset out of a V8 `SyntaxError` message when present.\n * The V8 message format is `\"Unexpected token X in JSON at position N\"` (or\n * `\"Unexpected end of JSON input\"` with no position). We return `null` when\n * no position can be parsed — `WikiParseError.position` is `number | null`.\n *\n * Delegates the unknown→string coercion to `safeErrorToString` so a hostile\n * value (throwing toString, Proxy rejecting property access) can never throw\n * out of this helper and unwind the walker. JSON.parse always throws a\n * `SyntaxError`, so the defensive branch is rarely exercised in practice,\n * but the fallback is here to keep the walker non-throwing by construction.\n */\nfunction extractParsePosition(err: unknown): number | null {\n const match = /position\\s+(\\d+)/.exec(safeErrorToString(err));\n return match ? Number(match[1]) : null;\n}\n\n/**\n * Non-throwing coercion of an arbitrary JavaScript value to a string for\n * error-message reporting. JavaScript's `String(e)` returns `e.toString()`\n * for objects, which can throw if `toString` itself throws (e.g. an object\n * with a misbehaving prototype). Without this guard, a single provider-side\n * rejection can escape an `ingestDocument` per-chunk `catch` and tear down\n * `withConcurrency`, discarding every sibling chunk's results — the exact\n * silent-forever failure mode the partial-commit work exists to prevent.\n *\n * Falls back through:\n * - `Error.message` for `Error` instances (always available).\n * - `String(e)`, wrapped in try/catch.\n * - `Object.prototype.toString.call(e)` if `String(e)` threw (also wrapped).\n * - A static `[unstringifiable error]` marker as a final guarantee.\n */\nexport function safeErrorToString(e: unknown): string {\n // `e instanceof Error` invokes the `getPrototypeOf` trap on `e`. A Proxy\n // whose trap rejects turns the type-check itself into a throw point,\n // escaping every catch around this function body. Treat the trap throw\n // as \"not an Error\" and fall through to the String() / Object.prototype\n // paths, which themselves catch their own throws.\n let isErrorLike = false;\n try {\n isErrorLike = e instanceof Error;\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects — fall through\n }\n if (isErrorLike) {\n // Defensive: a hostile `Error` subclass or a tampered native Error could\n // set `message` to a non-string (e.g. `err.message = 42`) or make it a\n // throwing getter. `e.name` is similarly attacker-controllable. Coerce\n // both without unwinding so this helper is truly non-throwing.\n const msg = readErrorField(e, 'message');\n if (typeof msg === 'string' && msg.length > 0) return msg;\n const name = readErrorField(e, 'name');\n if (typeof name === 'string' && name.length > 0) return name;\n return '[Error]';\n }\n try {\n return String(e);\n } catch {\n try {\n return Object.prototype.toString.call(e);\n } catch {\n return '[unstringifiable error]';\n }\n }\n}\n\n/**\n * Read a fixed string-typed field off an `Error` instance without ever\n * throwing, even if a subclass installs a hostile getter. Internal helper\n * for `safeErrorToString`.\n */\nfunction readErrorField(e: unknown, key: 'message' | 'name'): unknown {\n try {\n return (e as Record<string, unknown>)[key];\n } catch {\n return undefined;\n }\n}\n\nexport function sanitizeRankerError(err: unknown, sanitizeRankerErrors: boolean | undefined): Error {\n // `err instanceof Error` invokes the `getPrototypeOf` trap on `err`. A\n // hostile Proxy (e.g. an injected VectorRanker returning one) whose trap\n // rejects would otherwise escape this \"sanitize\" function. Compute the\n // guard once — the property accesses below share the same hostile-input\n // surface and need their own guards.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n /* hostile Proxy — treat as non-Error */\n }\n if (sanitizeRankerErrors === false) {\n // `String(err)` invokes the `toString` / `Symbol.toPrimitive` trap on\n // `err`; a hostile Proxy whose trap rejects would throw out of this\n // function, defeating the non-throwing contract. Delegate to the\n // hardened `safeErrorToString` helper which converges all coercion\n // paths onto the static `[unstringifiable error]` marker on throw.\n return isErrorLike ? (err as Error) : new Error(safeErrorToString(err));\n }\n // `errLike.constructor?.name` and `.cause` access can also throw on a\n // hostile Error subclass with throwing getters (optional chaining `?.`\n // only short-circuits null/undefined, not trap throws). Wrap each access\n // so the function's documented non-throwing contract holds for all\n // attacker-controlled inputs.\n let errLike: Error | null = null;\n if (isErrorLike) errLike = err as Error;\n let typeName: string;\n try {\n if (errLike) {\n const rawName: unknown = errLike.constructor?.name;\n typeName = typeof rawName === 'string' ? rawName : 'Error';\n } else {\n typeName = typeof err;\n }\n } catch {\n typeName = isErrorLike ? 'Error' : typeof err;\n }\n let innerCause: Error | undefined;\n if (errLike) {\n let cause: unknown;\n try { cause = errLike.cause; } catch { cause = undefined; }\n if (cause !== undefined) {\n let causeName: string;\n try {\n const rawCauseName: unknown = (cause as Error)?.constructor?.name;\n causeName = typeof rawCauseName === 'string' ? rawCauseName : typeof cause;\n } catch {\n causeName = typeof cause;\n }\n innerCause = new Error(`Caused by: ${causeName}`);\n }\n }\n const sanitized = new Error(\n `VectorRanker ${typeName} (message scrubbed for security)`,\n innerCause ? { cause: innerCause } : undefined,\n );\n try { sanitized.name = typeName; } catch { /* hostile name setter — leave default */ }\n return sanitized;\n}\n\n/**\n * Slices a string like `String.prototype.slice`, but clamps out-of-range\n * indices instead of relying on JS's implicit clamping, normalizes a\n * start-after-end range by swapping the two bounds, and nudges either bound\n * off a UTF-16 surrogate pair boundary so slicing never splits one code\n * point in half.\n *\n * @param value - The source string to slice.\n * @param start - Start index; negative counts from the end, out-of-range\n * values are clamped to `[0, value.length]`.\n * @param end - End index (exclusive); defaults to `value.length` when\n * omitted. Same clamping/negative-index rules as `start`.\n * @returns The sliced substring, never splitting a surrogate pair.\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\n/**\n * Splits `input` into chunks of at most `maxChunkLength` characters,\n * preferring to split on a paragraph break, then a sentence terminator,\n * then whitespace, falling back to a hard cut only when none of those are\n * found within the window. Consecutive chunks overlap by up to `overlap`\n * characters so context isn't lost at a chunk boundary. This is the exact\n * chunking algorithm `IngestionService.ingestDocument` uses before\n * embedding, so callers can reproduce ingest-time chunk boundaries exactly\n * given the same `maxChunkLength`/`overlap` (see `DEFAULT_MAX_CHUNK_LENGTH`\n * and `DEFAULT_CHUNK_OVERLAP` for the defaults ingest uses).\n *\n * @param input - The text to chunk; leading/trailing whitespace is trimmed\n * before chunking. Empty/whitespace-only input returns the empty result\n * below without validating `maxChunkLength`/`overlap`.\n * @param maxChunkLength - For non-empty input, maximum characters per chunk;\n * must be an integer >= 2.\n * @param overlap - For non-empty input, maximum number of characters each\n * chunk repeats from the end of the previous chunk; must be a\n * non-negative integer less than `maxChunkLength`. A chunk repeats fewer\n * characters when the previous chunk was shorter than `overlap`.\n * @returns `chunks` — the resulting chunk strings (empty array for\n * empty/whitespace-only input); `truncated` — `true` if any split had to\n * fall back to a hard cut (no paragraph/sentence/whitespace boundary\n * found in the window).\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\n/** Hard ceiling on evidence quotes per fact (spec §6.2). More than this makes the fact ungrounded. */\nexport const MAX_EVIDENCE_QUOTES = 10;\n\n/**\n * Normalize a fact's raw `evidence`: an array of strings, each trimmed, with\n * non-strings and empty entries ignored. Collection stops one entry past the\n * ceiling, which is enough to decide `too_many_quotes` without trimming an\n * unbounded array. Returns undefined when `raw` is not an array.\n */\nexport function normalizeEvidence(raw: unknown): string[] | undefined {\n if (!Array.isArray(raw)) return undefined;\n const out: string[] = [];\n for (const entry of raw) {\n if (typeof entry !== 'string') continue;\n const trimmed = entry.trim();\n if (!trimmed) continue;\n out.push(trimmed);\n if (out.length > MAX_EVIDENCE_QUOTES) break;\n }\n return out;\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 const valid: ExtractedFact = {\n ...fact,\n title,\n body,\n confidence,\n tags: validateTags(fact.tags)\n };\n const evidence = normalizeEvidence(fact.evidence);\n if (evidence) valid.evidence = evidence;\n else delete valid.evidence;\n return valid;\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\n/** Why `validateFact` rejected `raw`. Only meaningful when `validateFact(raw)` returned null. */\nexport function factRejectionReason(raw: unknown): 'invalid_shape' | 'missing_title' | 'missing_body' {\n const fact = raw as { title?: unknown; body?: unknown } | null | undefined;\n if (typeof fact?.title !== 'string' || typeof fact?.body !== 'string') return 'invalid_shape';\n if (!clip(fact.title, 80)) return 'missing_title';\n return 'missing_body';\n}\n\n/** Why `validateTask` rejected `raw`. Only meaningful when `validateTask(raw)` returned null. */\nexport function taskRejectionReason(raw: unknown): 'invalid_shape' | 'missing_description' {\n const task = raw as { description?: unknown } | null | undefined;\n if (typeof task?.description !== 'string') return 'invalid_shape';\n return 'missing_description';\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 { OkfVerifiedEntry } from '@equationalapplications/core-okf';\nimport type { GroundingConfig } from '../types';\nimport { MAX_EVIDENCE_QUOTES, safeSlice } from './pure';\n\nexport type GroundingWriter = 'ingest' | 'librarian' | 'heal';\n\nexport interface ResolvedGrounding {\n writers: ReadonlySet<GroundingWriter>;\n minEvidenceChars: number;\n maxEvidence: number;\n maxEvidenceChars: number;\n}\n\n/** Actor recorded in `okf_verified` for a fact that passed the check. `process:` keeps the trust tier at machine-confirmed. */\nexport const GROUNDING_VERIFIER = 'process:grounding-check';\n\nconst WRITERS: readonly GroundingWriter[] = ['ingest', 'librarian', 'heal'];\n\nfunction positiveInt(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;\n}\n\n/** `null` means grounding is off: no prompt change, no checks, no status or trust writes (spec §6.5). */\nexport function resolveGrounding(config: GroundingConfig | undefined): ResolvedGrounding | null {\n if (!config || config.mode !== 'draft') return null;\n const writers: GroundingWriter[] = Array.isArray(config.writers)\n ? config.writers.filter((w): w is GroundingWriter => WRITERS.includes(w as GroundingWriter))\n : ['ingest'];\n return {\n writers: new Set(writers),\n minEvidenceChars: positiveInt(config.minEvidenceChars, 20),\n // Never ask for more quotes than checkGrounding accepts (MAX_EVIDENCE_QUOTES).\n maxEvidence: Math.min(MAX_EVIDENCE_QUOTES, positiveInt(config.maxEvidence, 3)),\n maxEvidenceChars: positiveInt(config.maxEvidenceChars, 300),\n };\n}\n\n/** Spec §6.4 step 1: NFKC, collapse every whitespace run to one space, trim. Case is preserved. */\nexport function normalizeForGrounding(text: string): string {\n return text.normalize('NFKC').replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Build the normalized corpus from the raw in-memory values the model was\n * shown (spec §6.3), one normalized string per part. Never pass serialized\n * prompt text: JSON escapes would cause false `quote_not_found`. Non-string\n * parts are ignored. Parts stay separate so a quote can only ground inside\n * a single source — joining them would let a quote stitched across the\n * boundary of two sources pass.\n */\nexport function buildGroundingCorpus(parts: readonly unknown[]): string[] {\n return parts.filter((p): p is string => typeof p === 'string').map(normalizeForGrounding);\n}\n\nexport type GroundingReason = 'no_evidence' | 'evidence_too_short' | 'quote_not_found' | 'too_many_quotes';\n\nexport type GroundingVerdict =\n | { status: 'grounded'; retained: string[] }\n | { status: 'missing'; reason: 'no_evidence' | 'evidence_too_short' }\n | { status: 'failed'; reason: 'quote_not_found' | 'too_many_quotes' };\n\n/**\n * Deterministic check (spec §6.2, §6.4). `evidence` is `validateFact`'s\n * normalized list; `normalizedCorpus` comes from {@link buildGroundingCorpus}.\n * A quote passes only inside a single corpus part; it cannot span two\n * sources. Every quote is checked before any retention cap applies.\n */\nexport function checkGrounding(\n evidence: readonly string[] | undefined,\n normalizedCorpus: readonly string[],\n cfg: ResolvedGrounding,\n): GroundingVerdict {\n const quotes = evidence ?? [];\n if (quotes.length > MAX_EVIDENCE_QUOTES) return { status: 'failed', reason: 'too_many_quotes' };\n if (quotes.length === 0) return { status: 'missing', reason: 'no_evidence' };\n const qualifying = quotes.map(normalizeForGrounding).filter((q) => q.length >= cfg.minEvidenceChars);\n if (qualifying.length === 0) return { status: 'missing', reason: 'evidence_too_short' };\n if (qualifying.some((q) => !normalizedCorpus.some((part) => part.includes(q)))) {\n return { status: 'failed', reason: 'quote_not_found' };\n }\n return {\n status: 'grounded',\n retained: qualifying.slice(0, cfg.maxEvidence).map((q) => safeSlice(q, 0, cfg.maxEvidenceChars)),\n };\n}\n\n/** Insert-time trust fields. Spread onto a new `WikiFact`; `EntryRepository.upsert` writes them on INSERT only. */\nexport interface GroundingTrust {\n lifecycle_status: 'stable' | 'draft';\n okf_verified?: OkfVerifiedEntry[];\n last_verified_at?: number;\n last_verified_by?: string;\n}\n\nexport interface GroundingOutcome {\n trust: GroundingTrust;\n /** Present exactly when the fact lands as a draft. */\n diagnostic?: { code: 'grounding_missing' | 'grounding_failed'; reason: GroundingReason };\n}\n\n/** Spec §6.5. */\nexport function groundingOutcome(verdict: GroundingVerdict, now: number): GroundingOutcome {\n if (verdict.status === 'grounded') {\n return {\n trust: {\n lifecycle_status: 'stable',\n okf_verified: [{ by: GROUNDING_VERIFIER, at: new Date(now).toISOString() }],\n last_verified_at: now,\n last_verified_by: GROUNDING_VERIFIER,\n },\n };\n }\n return {\n trust: { lifecycle_status: 'draft' },\n diagnostic: { code: verdict.status === 'missing' ? 'grounding_missing' : 'grounding_failed', reason: verdict.reason },\n };\n}\n","import type {\n WikiDiagnostic,\n WikiDiagnosticCode,\n WikiDiagnosticDetail,\n WikiDiagnosticOperation,\n WikiDiagnosticSeverity,\n WikiDiagnosticTrigger,\n WikiOptions,\n} from '../types';\nimport type { EdgeDrop } from './ontology';\n\n/** What a call site supplies; severity, message and timestamp are derived from `code`. */\nexport type WikiDiagnosticInput = Omit<WikiDiagnostic, 'severity' | 'message' | 'at'>;\n\ntype DiagnosticTarget = Pick<WikiOptions, 'onDiagnostic'>;\n\nconst SEVERITY: Record<WikiDiagnosticCode, WikiDiagnosticSeverity> = {\n ingest_chunk_failed: 'warn',\n fact_rejected: 'warn',\n task_rejected: 'warn',\n fact_deduplicated: 'info',\n edge_dropped: 'warn',\n embedding_failed: 'warn',\n hook_failed: 'warn',\n background_job_failed: 'error',\n heal_skipped: 'warn',\n grounding_missing: 'warn',\n grounding_failed: 'warn',\n classification_low_confidence: 'info',\n classification_invalid: 'warn',\n};\n\n// Fixed templates (REQ-DIAG-03): never interpolate content into these.\nconst MESSAGE: Record<WikiDiagnosticCode, string> = {\n ingest_chunk_failed: 'One or more document chunks failed to parse or generate.',\n fact_rejected: 'An extracted fact failed validation and was not written.',\n task_rejected: 'An extracted task failed validation and was not written.',\n fact_deduplicated: 'An extracted fact duplicated an existing fact and was not written.',\n edge_dropped: 'An extracted edge could not be resolved against the ontology and was not written.',\n embedding_failed: 'A fact could not be embedded.',\n hook_failed: 'A host hook threw or rejected.',\n background_job_failed: 'A background maintenance job failed.',\n heal_skipped: 'Heal skipped a candidate fact.',\n grounding_missing: 'A fact carried no qualifying evidence and was stored as a draft.',\n grounding_failed: 'A fact carried evidence not found in its source and was stored as a draft.',\n classification_low_confidence: 'A classifier answer was below the confidence threshold and was not applied.',\n classification_invalid: 'A classifier answer was invalid and was not applied.',\n};\n\nconst warnedNonFunction = new WeakSet<object>();\n\nfunction copyDetail(detail: WikiDiagnosticDetail): WikiDiagnosticDetail {\n const copy: WikiDiagnosticDetail = { ...detail };\n if (detail.chunkIndexes) copy.chunkIndexes = detail.chunkIndexes.slice();\n return copy;\n}\n\n/**\n * Deliver one diagnostic to the host hook. Never throws, never awaits, and\n * never writes to the console unless the hook itself misbehaves (REQ-DIAG-02).\n */\nexport function emitDiagnostic(options: DiagnosticTarget, input: WikiDiagnosticInput): void {\n const hook: unknown = options.onDiagnostic;\n if (hook === undefined || hook === null) return;\n if (typeof hook !== 'function') {\n if (!warnedNonFunction.has(options)) {\n warnedNonFunction.add(options);\n console.warn('[WikiMemory] onDiagnostic is not a function; diagnostics are disabled.');\n }\n return;\n }\n const diagnostic: WikiDiagnostic = {\n code: input.code,\n severity: SEVERITY[input.code],\n operation: input.operation,\n trigger: input.trigger,\n entityId: input.entityId,\n at: Date.now(),\n message: MESSAGE[input.code],\n ...(input.detail ? { detail: copyDetail(input.detail) } : {}),\n };\n try {\n const returned: unknown = (hook as (d: WikiDiagnostic) => unknown)(diagnostic);\n if (returned !== undefined) {\n // Promise.resolve never throws synchronously; a hostile thenable rejects instead.\n Promise.resolve(returned).catch((err: unknown) => {\n console.warn('[WikiMemory] onDiagnostic hook rejected:', err);\n });\n }\n } catch (err) {\n console.warn('[WikiMemory] onDiagnostic hook threw:', err);\n }\n}\n\n/**\n * Operation-scoped buffer (spec §4.2.4): push while the operation's\n * transaction is open, `flush` after it commits, `discard` (or simply drop the\n * buffer) when the operation throws.\n */\nexport class DiagnosticBuffer {\n private items: WikiDiagnosticInput[] = [];\n\n push(input: WikiDiagnosticInput): void {\n this.items.push(input);\n }\n\n get size(): number {\n return this.items.length;\n }\n\n flush(options: DiagnosticTarget): void {\n const pending = this.items;\n this.items = [];\n for (const input of pending) emitDiagnostic(options, input);\n }\n\n discard(): void {\n this.items = [];\n }\n}\n\n/** Map an `EdgeDrop` to an `edge_dropped` diagnostic input. Omits unknown locators instead of sending nulls. */\nexport function edgeDropDiagnostic(\n drop: EdgeDrop,\n ctx: {\n entityId: string;\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n sourceRef?: string;\n factId?: string;\n },\n): WikiDiagnosticInput {\n const detail: WikiDiagnosticDetail = { reason: drop.reason };\n const factId = ctx.factId ?? drop.sourceId;\n if (factId) detail.factId = factId;\n if (drop.edgeType) detail.edgeType = drop.edgeType;\n if (drop.sourceNodeType) detail.sourceNodeType = drop.sourceNodeType;\n if (drop.targetNodeType) detail.targetNodeType = drop.targetNodeType;\n if (ctx.sourceRef) detail.sourceRef = ctx.sourceRef;\n return { code: 'edge_dropped', operation: ctx.operation, trigger: ctx.trigger, entityId: ctx.entityId, detail };\n}\n","import type { GroundingWriter, ResolvedGrounding } from './utils/grounding';\n\nexport 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. JSON escaping rules: every literal \" character in the source must be escaped as \\\\\" inside any JSON string body, and every literal newline as \\\\n. Source prose containing quotes (e.g. a worked example with \"...\") must still be reproduced exactly — re-escape, do not omit. 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.\nWhen echoing an existing fact's title verbatim into \"target_title\", preserve every JSON escape sequence (\\\\\", \\\\n, \\\\\\\\, \\\\/) exactly as it appeared in the input body — do not strip backslashes, do not add unescaped quotes. Do not return markdown, just raw JSON.`;\n\nconst GROUNDING_SOURCE: Record<GroundingWriter, { key: string; source: string }> = {\n ingest: { key: 'facts', source: 'the document chunk' },\n librarian: { key: 'facts', source: 'the \"summary\" text of the events' },\n heal: { key: 'newFacts', source: 'the \"summary\" text of the recent events or the \"body\" text of the document anchors' },\n};\n\n/** Evidence instruction appended to an in-scope writer's system prompt (spec §6.2). */\nexport function groundingEvidenceBlock(writer: GroundingWriter, cfg: ResolvedGrounding): string {\n const { key, source } = GROUNDING_SOURCE[writer];\n return `EVIDENCE REQUIREMENT: every object in \"${key}\" must also carry an \"evidence\" array of 1 to ${cfg.maxEvidence} quotes. Each quote must be an exact substring copied character-for-character from ${source} (the SOURCE section), at least ${cfg.minEvidenceChars} characters long. Do not paraphrase. Do not quote these instructions, the ontology manifest, or any existing fact. A fact whose quotes cannot be found in the SOURCE section is stored as an unreviewed draft.\n\"evidence\": [\"exact substring copied from the SOURCE section\"]`;\n}\n","/**\n * Shared constants for the heal pipeline.\n *\n * Both `PromptService.buildHealPrompt` (which applies the L0 anchor cap and\n * the L3 body truncation default) and `MaintenanceService.doRunHeal` (which\n * fetches tasks at the cap and looks up anchors with the overfetch sized off\n * it) read from this module. The spec (\"heal output-bounded convergence\n * ladder\") explicitly requires the values to match across the two callers —\n * if they drift, the L0 anchor slice and `_selectHealAnchors`'s overfetch\n * silently disagree with no test catching the gap.\n *\n * Lives in `utils/` rather than alongside `MaintenanceService` because\n * `PromptService` is constructed before `MaintenanceService` exists, and\n * importing from `MaintenanceService` would create a cycle at construction\n * time. A leaf constants module has no such risk.\n *\n * Heal-specific batch sizing, recheck cadence, and prompt char limits\n * (`HEAL_BATCH_SIZE`, `HEAL_RECHECK_MS`, `HEAL_MAX_PROMPT_CHARS`,\n * `HEAL_ANCHOR_SEARCH_OVERFETCH`) are not duplicated across files and stay\n * in `MaintenanceService.ts` — moving them here would expand this module's\n * surface without buying anything.\n */\n\n/** Cap on document anchors surfaced to the model at L0. */\nexport const HEAL_MAX_ANCHORS = 50;\n\n/** Per-candidate anchor ratio used at L0: `min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE)`. */\nexport const HEAL_ANCHORS_PER_CANDIDATE = 4;\n\n/**\n * Default body truncation cap applied at L3 only. A fact whose body is at or\n * below this cap passes through unchanged; a fact above it is sliced to this\n * length with a `...[truncated at N chars, original was M]` marker.\n */\nexport const HEAL_MAX_FACT_BODY_CHARS_L3 = 4_000;\n\n/**\n * Hard ceiling on the `allTasks` slice fed to the heal prompt at L0. Tasks\n * are entity-global (not batch-local), so this is a constant rather than a\n * function of batch length.\n */\nexport const HEAL_MAX_TASKS = 50;\n\n/**\n * Clip for a document anchor's body in the heal prompt. Bodies are shown only\n * when heal is a grounding writer (spec §6.2, rev 7). Host `upsertGraph` nodes\n * are anchors too and have no body limit, so the clip bounds the prompt.\n */\nexport const HEAL_ANCHOR_BODY_CHARS = 800;","import {\n INGEST_SYSTEM_PROMPT,\n LIBRARIAN_SYSTEM_PROMPT,\n HEAL_SYSTEM_PROMPT,\n ONTOLOGY_BACKFILL_SYSTEM_PROMPT,\n groundingEvidenceBlock,\n} from '../prompts';\nimport type { DegradedRecord, PromptOverrides, OntologyPromptContext } from '../types';\nimport {\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_ANCHOR_BODY_CHARS,\n HEAL_MAX_ANCHORS,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n} from '../utils/healConstants';\nimport { safeSlice } from '../utils/pure';\nimport {\n buildGroundingCorpus,\n type GroundingWriter,\n type ResolvedGrounding,\n} from '../utils/grounding';\n\nexport class PromptService {\n constructor(\n private globalOverrides?: PromptOverrides,\n private grounding: ResolvedGrounding | null = null,\n ) {}\n\n /** The resolved grounding config when `writer` is in `grounding.writers`; otherwise null (spec §6.2). */\n groundingFor(writer: GroundingWriter): ResolvedGrounding | null {\n return this.grounding?.writers.has(writer) ? this.grounding : null;\n }\n\n /** Appended after any override and after ontology context, so it is always last. */\n private appendGrounding(systemPrompt: string, writer: GroundingWriter): string {\n const cfg = this.groundingFor(writer);\n return cfg ? `${systemPrompt}\\n\\n${groundingEvidenceBlock(writer, cfg)}` : systemPrompt;\n }\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.appendGrounding(this.buildSystemPrompt(template, { documentChunk }, ontologyContext), 'ingest'),\n userPrompt: hasDocumentChunk ? 'Please extract the facts.' : `Document Chunk:\\n${documentChunk}`,\n };\n }\n return {\n systemPrompt: this.appendGrounding(this.appendOntology(template, ontologyContext), 'ingest'),\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; groundingCorpus?: 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 // grounding: spec §6.3, event summaries only — the \"Current Facts\" shown\n // beside them are excluded so a new inference cannot be grounded by an\n // earlier one. A template that places {{currentFacts}} without {{events}}\n // never shows the events, so they are not in the corpus either.\n const eventsShown = hasEvents || !hasCurrentFacts;\n const corpusField = this.groundingFor('librarian')\n ? { groundingCorpus: buildGroundingCorpus(eventsShown ? events.map(summaryOf) : []) }\n : {};\n if (hasEvents || hasCurrentFacts || this.hasOntologyPlaceholders(template)) {\n return {\n systemPrompt: this.appendGrounding(this.buildSystemPrompt(template, { events, currentFacts }, ontologyContext), 'librarian'),\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 ...corpusField,\n };\n }\n return {\n systemPrompt: this.appendGrounding(this.appendOntology(template, ontologyContext), 'librarian'),\n userPrompt: `Events:\\n${JSON.stringify(events, null, 2)}\\n\\nCurrent Facts:\\n${JSON.stringify(currentFacts, null, 2)}`,\n ...corpusField,\n };\n }\n\n /**\n * Heal-prompt level interpretation for the `attemptLevel` ladder.\n *\n * Caller contract: `documentAnchors` may be a slice sized for `batch.length`\n * or a larger set (e.g. a cache hit from `_selectHealAnchors`). This function\n * applies the prompt-side anchor cap `min(HEAL_MAX_ANCHORS=50, batch.length\n * * HEAL_ANCHORS_PER_CANDIDATE=4)` so the rendered prompt is bounded\n * regardless of caller input. `HEAL_MAX_ANCHORS` and\n * `HEAL_ANCHORS_PER_CANDIDATE` live here too — keeping the formula\n * co-located with its application avoids a \"MaintenanceService policy\"\n * import cycle (`PromptService` is constructed before `MaintenanceService`\n * exists) and makes the cap testable without a `MaintenanceService`\n * instance. Task 3 exports the same two constants from `MaintenanceService`\n * for caller-side overfetch sizing; the values must match.\n *\n * Level semantics:\n * - L0: allTasks + recentEvents + full candidate bodies; anchors re-capped\n * - L1: drop allTasks; recentEvents present; candidate bodies full\n * - L2: drop allTasks and recentEvents; candidate bodies full\n * - L3: drop allTasks and recentEvents; truncate each candidate body to\n * `bodyTruncationChars` and emit a `degraded` record per truncated fact\n */\n buildHealPrompt(\n healCandidates: unknown[],\n documentAnchors: unknown[],\n allTasks: unknown[],\n recentEvents: unknown[],\n runtimeOverride: string | undefined,\n attemptLevel: 0 | 1 | 2 | 3,\n bodyTruncationChars: number = HEAL_MAX_FACT_BODY_CHARS_L3,\n ): { prompts: { systemPrompt: string; userPrompt: string }; degraded: DegradedRecord[]; groundingCorpus?: string[] } {\n // L0: all context. L1: drop allTasks. L2: also drop recentEvents.\n const effectiveTasks = attemptLevel >= 1 ? [] : allTasks;\n const effectiveEvents = attemptLevel >= 2 ? [] : recentEvents;\n\n // L0 anchor cap: min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE).\n // The caller is responsible for sizing the documentAnchors slice; we re-cap\n // here in case the caller passed a superset (e.g. from _selectHealAnchors\n // cache). Constants live in utils/healConstants so PromptService and\n // MaintenanceService cannot drift apart (spec: \"values must match\").\n const maxAnchors = Math.max(1, Math.min(HEAL_MAX_ANCHORS, healCandidates.length * HEAL_ANCHORS_PER_CANDIDATE));\n const effectiveAnchors = documentAnchors.slice(0, maxAnchors);\n\n const template = runtimeOverride ?? this.globalOverrides?.healSystemPrompt ?? HEAL_SYSTEM_PROMPT;\n const hasRecentEvents = /\\{\\{\\s*recentEvents\\s*\\}\\}/.test(template);\n const hasDocumentAnchors = /\\{\\{\\s*documentAnchors\\s*\\}\\}/.test(template);\n const usesPlaceholders =\n /\\{\\{\\s*healCandidates\\s*\\}\\}/.test(template) ||\n hasDocumentAnchors ||\n /\\{\\{\\s*allTasks\\s*\\}\\}/.test(template) ||\n hasRecentEvents;\n\n // grounding: only when heal is a grounding writer do anchors show a\n // clipped body, and the corpus is built from exactly what this prompt\n // shows (spec §6.3, rev 7). A placeholder template shows a source only\n // when it places that source's placeholder. lifecycle_status decides\n // corpus membership but is never shown to the model.\n const healGrounding = this.groundingFor('heal');\n const promptAnchors = healGrounding ? effectiveAnchors.map(toGroundingAnchor) : effectiveAnchors;\n const eventsShown = !usesPlaceholders || hasRecentEvents;\n const anchorsShown = !usesPlaceholders || hasDocumentAnchors;\n const groundingCorpus = healGrounding\n ? buildGroundingCorpus([\n ...(eventsShown ? effectiveEvents.map(summaryOf) : []),\n ...(anchorsShown\n ? effectiveAnchors\n .map((a, i) => ({ status: (a as { lifecycle_status?: unknown } | null)?.lifecycle_status, shown: promptAnchors[i] }))\n .filter((x) => x.status !== 'draft')\n .map((x) => (x.shown as { body?: unknown } | null)?.body)\n : []),\n ])\n : null;\n\n // L3: truncate each candidate's body independently. A fact whose body\n // is already <= bodyTruncationChars passes through unchanged; the\n // caller sees that fact is absent from `degraded` and can treat the\n // result as if no truncation had occurred.\n const { shapedCandidates, degraded } = applyBodyTruncation(\n healCandidates,\n attemptLevel,\n bodyTruncationChars,\n );\n const corpusField = groundingCorpus !== null ? { groundingCorpus } : {}; // grounding\n\n if (usesPlaceholders) {\n return {\n prompts: {\n systemPrompt: this.appendGrounding(this.hydrate(template, {\n healCandidates: shapedCandidates,\n documentAnchors: promptAnchors,\n allTasks: effectiveTasks,\n recentEvents: effectiveEvents,\n }), 'heal'),\n userPrompt: 'Please heal the memory graph.',\n },\n degraded,\n ...corpusField,\n };\n }\n return {\n prompts: {\n systemPrompt: this.appendGrounding(template, 'heal'),\n userPrompt: `Heal Candidates:\\n${JSON.stringify(shapedCandidates, null, 2)}\\nDocument Anchors (DO NOT MODIFY OR DELETE):\\n${JSON.stringify(promptAnchors, null, 2)}\\nAll Tasks:\\n${JSON.stringify(effectiveTasks, null, 2)}\\nRecent Events:\\n${JSON.stringify(effectiveEvents, null, 2)}\\nThe following document anchors are provided for contradiction detection only. Do not include them in \\`downgraded\\`, \\`deleted\\`, or \\`newFacts\\`.`,\n },\n degraded,\n ...corpusField,\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\n/**\n * Truncate candidate bodies at L3 only. Each fact is sliced independently;\n * a fact whose body is at or below the cap passes through unchanged. The\n * trailing marker is what the post-reconcile log line references — an\n * operator scanning the log sees the truncation magnitude without\n * re-querying the fact.\n *\n * A candidate that needs truncation but lacks a string id passes through\n * untruncated: the upstream contract (`WikiFact.id` is a `TEXT PRIMARY KEY`)\n * guarantees string ids in practice, and truncating without an id would\n * emit a body the model can verdict under but with no DegradedRecord for\n * `MaintenanceService.doRunHeal` to reconcile — violating the\n * degraded ⊥ skipped invariant on id.\n */\nfunction applyBodyTruncation(\n candidates: unknown[],\n attemptLevel: 0 | 1 | 2 | 3,\n bodyTruncationChars: number,\n): { shapedCandidates: unknown[]; degraded: DegradedRecord[] } {\n if (attemptLevel < 3) {\n return { shapedCandidates: candidates, degraded: [] };\n }\n const shapedCandidates: unknown[] = [];\n const degraded: DegradedRecord[] = [];\n for (const c of candidates) {\n if (typeof c !== 'object' || c === null) {\n shapedCandidates.push(c);\n continue;\n }\n const fact = c as { id?: unknown; body?: unknown };\n const body = typeof fact.body === 'string' ? fact.body : '';\n if (body.length <= bodyTruncationChars) {\n shapedCandidates.push(c);\n continue;\n }\n // A candidate that needs L3 truncation must carry a string id so\n // doRunHeal can reconcile the truncation back to the source row\n // (`HealResult.degraded` is keyed by id, and degraded ⊥ skipped on id).\n // Without one the candidate passes through untruncated — the invariant\n // \"every truncated candidate has a DegradedRecord\" holds, and the\n // upstream contract (WikiFact.id is a TEXT PRIMARY KEY) means this\n // branch is defensive against future schema drift, not a happy path.\n if (typeof fact.id !== 'string') {\n shapedCandidates.push(c);\n continue;\n }\n const originalBodyChars = body.length;\n // `safeSlice` (utils/pure) keeps the boundary inside a UTF-16 surrogate\n // pair intact — a bare `String.prototype.slice` can land mid-codepoint and\n // emit a lone high surrogate that JSON.stringify turns into U+FFFD. The\n // same hazard is handled for `formatSkipError` log lines in\n // MaintenanceService. Bodies can be emoji-heavy. The returned prefix may\n // be one or two chars shorter than `bodyTruncationChars` when the cut\n // backs off the surrogate boundary, so `truncatedBodyChars` reads from\n // `prefix.length` rather than the requested limit.\n const prefix = safeSlice(body, 0, bodyTruncationChars);\n const truncatedBodyChars = prefix.length;\n const truncated = `${prefix}…[truncated at ${truncatedBodyChars} chars, original was ${originalBodyChars}]`;\n shapedCandidates.push({ ...fact, body: truncated });\n degraded.push({ id: fact.id, originalBodyChars, truncatedBodyChars });\n }\n return { shapedCandidates, degraded };\n}\n\n/** An event's `summary` — the only event field that enters a grounding corpus (spec §6.3). */\nfunction summaryOf(event: unknown): unknown {\n return (event as { summary?: unknown } | null)?.summary;\n}\n\n/** Prompt shape of a heal anchor when heal is a grounding writer: body clipped, lifecycle_status hidden. */\nfunction toGroundingAnchor(anchor: unknown): unknown {\n if (typeof anchor !== 'object' || anchor === null) return anchor;\n const a = anchor as { id?: unknown; title?: unknown; source_ref?: unknown; body?: unknown };\n return {\n id: a.id,\n title: a.title,\n source_ref: a.source_ref,\n body: typeof a.body === 'string' ? safeSlice(a.body, 0, HEAL_ANCHOR_BODY_CHARS) : '',\n };\n}\n","/**\n * Default maximum characters per chunk that `ingestDocument` uses when a\n * caller doesn't override `maxChunkLength` (directly or via\n * `WikiOptions.config.maxChunkLength`).\n */\nexport const DEFAULT_MAX_CHUNK_LENGTH = 12000;\n\n/**\n * Default/fallback character overlap between consecutive chunks.\n * `ingestDocument` uses this when a caller doesn't override `chunkOverlap`\n * (directly or via `WikiOptions.config.chunkOverlap`), and clamps the\n * effective overlap (including this default) to `maxChunkLength - 1` when\n * needed. The clamp is a no-op for the shipped defaults; it can also apply\n * when a custom `maxChunkLength` makes the resolved overlap too large.\n */\nexport const DEFAULT_CHUNK_OVERLAP = 400;\n","import { chunkText, withConcurrency, validateFact, factRejectionReason, parseJsonResponse, normalizeSourceRef, normalizeSourceHash, safeErrorToString } from '../utils/pure';\nimport { normalizeTitleKey, typeSatisfies } from '../utils/ontology';\nimport { DiagnosticBuffer, emitDiagnostic, edgeDropDiagnostic } from '../utils/diagnostics';\nimport type { EdgeDrop } from '../utils/ontology';\nimport { generateId } from '../utils/ids';\nimport { WikiParseError, WikiIngestEmptyError, WikiDuplicateHashError, WikiTransactionError, WikiStrictOntologyViolation, WikiGraphNodeOwnershipConflict } from '../types';\nimport type { ChunkFailure, WikiOptions, ExtractedFact, ExtractedFactEdge, ExtractedFactWithOntology, WikiFact, OntologyUpdates, WikiEdge, IngestDocumentResult } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport { extractSqliteCode } from '../db/sqliteCodes';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SourceRefIndexRepository } from '../repositories/SourceRefIndexRepository';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\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';\nimport { DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_CHUNK_OVERLAP } from '../utils/chunkingDefaults';\nimport { resolveGrounding, buildGroundingCorpus, checkGrounding, groundingOutcome } from '../utils/grounding';\nimport type { GroundingTrust, GroundingVerdict } from '../utils/grounding';\n\ntype ChunkResult =\n | { status: 'ok'; facts: ExtractedFact[]; itemIndexes: number[]; rejected: Array<{ itemIndex: number; reason: ReturnType<typeof factRejectionReason> }>; verdicts: GroundingVerdict[]; ontology_updates?: OntologyUpdates }\n | { status: 'failed'; error: ChunkFailure };\n\n/** Shape returned by {@link IngestionService.ingestDocument} when no chunks\n * ran — used for both the `chunks.length === 0` early-return and the\n * `onDuplicateHash: 'skip'` early-return. `duplicateOf` is present as an own\n * key ONLY when the skip is owed to a duplicate-hash collision — hosts using\n * `'duplicateOf' in result` to detect that case must not see the key on the\n * empty-document path (matching the pre-widening contract). */\nfunction zeroChunkResult(duplicateOf?: string): IngestDocumentResult {\n const result: IngestDocumentResult = {\n truncated: false,\n chunks: 0,\n ingestedChunks: 0,\n failedChunks: 0,\n };\n if (duplicateOf !== undefined) result.duplicateOf = duplicateOf;\n return result;\n}\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 sourceRefIndexRepo: SourceRefIndexRepository,\n private metadataRepo: MetadataRepository,\n private edgeRepo: EdgeRepository,\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, resolveGrounding(this.options.config?.grounding));\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 opts?: { onDuplicateHash?: 'ingest' | 'skip' | 'throw' },\n ): Promise<IngestDocumentResult> {\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 ?? DEFAULT_MAX_CHUNK_LENGTH;\n const rawOverlap = params.chunkOverlap ?? this.options.config?.chunkOverlap ?? DEFAULT_CHUNK_OVERLAP;\n const chunkOverlap = Math.min(\n Number.isFinite(rawOverlap) && rawOverlap >= 0 ? Math.floor(rawOverlap) : DEFAULT_CHUNK_OVERLAP,\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 // Acquire the hash + sourceRef ingest locks BEFORE the duplicate pre-check\n // so concurrent same-hash callers serialize here. Two callers that both\n // observe no duplicate at the pre-check can otherwise both reach the\n // INSERT and trip the v9 UNIQUE constraint — see\n // docs/superpowers/specs/2026-08-07-dependabot-concurrency-release-hygiene-design.md §B.\n const releaseIngestLocks = await this.jobManager.acquireIngestLocks(entityId, sourceRef, sourceHash);\n\n try {\n // Duplicate-hash guard: runs AFTER acquireIngestLocks but BEFORE chunking\n // and any LLM call. With the per-hash lock held by the previous holder,\n // we are guaranteed to observe any committed write they made before\n // releasing. Early duplicate returns go through the `finally` block\n // below so both locks are released cleanly.\n const onDuplicateHash = opts?.onDuplicateHash ?? 'ingest';\n if (onDuplicateHash !== 'ingest') {\n // Source_ref_index is the source of truth for \"who currently holds\n // this hash\"; the pre-check queries it directly. At most one sourceRef\n // can hold a given hash, so the result is either null (no live ref)\n // or a single sourceRef (which cannot echo the incoming ref because\n // the source_ref_index row is the OTHER writer's).\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n if (canonical !== null && canonical !== sourceRef) {\n if (onDuplicateHash === 'throw') {\n throw new WikiDuplicateHashError({ canonical, sourceHash, entityId });\n }\n // 'skip'\n return zeroChunkResult(canonical);\n }\n }\n\n const { chunks, truncated } = chunkText(params.documentChunk, maxChunkLength, chunkOverlap);\n if (chunks.length === 0) return zeroChunkResult();\n\n // Hoist the ontology prompt context out of the per-chunk closure:\n // `buildPromptContext(entityId)` depends only on entityId and reads\n // the manifest ONCE; running it per chunk is N-1 wasted DB reads.\n // Hoisting also makes its DB-systemic nature structural — a fault\n // surfaces before any LLM tokens are spent, not buried under\n // `WikiIngestEmptyError` after the first LLM call. See spec §3.\n const ontologyContext = await this.ontologyService?.buildPromptContext(entityId) ?? null;\n const ingestGrounding = this.promptService.groundingFor('ingest');\n\n const chunkResults = await withConcurrency(\n chunks.map((chunk, chunkIndex) => async () => {\n // Prompt building is INTENTIONALLY outside the try — it's a\n // template-driven step whose failures (malformatted\n // `promptOverride`, configured-template regression) are systemic\n // and identical for every chunk. Surfacing as a raw throw means\n // the host sees the real cause on the first chunk instead of\n // after `chunks.length` LLM calls under a `WikiIngestEmptyError`.\n // See spec §3.\n const { systemPrompt, userPrompt } = this.promptService.buildIngestPrompt(\n chunk,\n params.promptOverride,\n ontologyContext,\n );\n try {\n const responseText = await this.options.llmProvider.generateText({ systemPrompt, userPrompt });\n const result = parseJsonResponse<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>(responseText);\n const rawFacts: unknown[] = Array.isArray(result.facts) ? result.facts : [];\n const facts: ExtractedFact[] = [];\n const itemIndexes: number[] = [];\n const rejected: Array<{ itemIndex: number; reason: ReturnType<typeof factRejectionReason> }> = [];\n rawFacts.forEach((raw, itemIndex) => {\n const valid = validateFact(raw);\n if (valid) {\n facts.push(valid);\n itemIndexes.push(itemIndex);\n } else {\n rejected.push({ itemIndex, reason: factRejectionReason(raw) });\n }\n });\n // Spec §6.3: the ingest corpus is exactly the chunk the model was shown.\n const verdicts: GroundingVerdict[] = ingestGrounding\n ? (() => {\n const corpus = buildGroundingCorpus([chunk]);\n return facts.map((f) => checkGrounding(f.evidence, corpus, ingestGrounding));\n })()\n : [];\n\n return {\n status: 'ok' as const,\n facts,\n itemIndexes,\n rejected,\n verdicts,\n ontology_updates: result.ontology_updates,\n };\n } catch (e) {\n const failure: ChunkFailure = e instanceof WikiParseError\n ? {\n chunkIndex,\n sourceRef,\n source: 'parse',\n tier: e.tier,\n position: e.position,\n message: e.message,\n }\n : {\n chunkIndex,\n sourceRef,\n source: 'llm',\n // `safeErrorToString` is a non-throwing coercion: an LLM\n // provider may reject with a non-Error value, and even\n // `String(e)` itself can throw when `e.toString()` throws.\n // Letting such an exception escape this catch would cause\n // `withConcurrency` to reject, discarding every sibling\n // chunk's results — the exact failure mode this per-chunk\n // try/catch exists to prevent. Keeping the value in the\n // `ChunkFailure` preserves the typed diagnostic for\n // callers (see parseFailures) without unwinding the loop.\n position: null,\n message: safeErrorToString(e),\n };\n // Spec §2: log once per failure, NEVER include the raw response.\n // We deliberately omit `failure.message` here:\n // - For `source: 'parse'` the message is the parser's diagnostic\n // (safe) but in the interest of a single, narrow warn format we\n // surface only the tier (and position when known) on the log.\n // - For `source: 'llm'` the message is provider-controlled: an\n // LLM SDK commonly surfaces the raw response body, document\n // content, or a multi-megabyte HTTP error in `Error.message`.\n // Even a parser-diagnostic message that happens to share bytes\n // with a never-logged raw response would leak if we printed\n // it verbatim. The full message stays in `parseFailures` for\n // callers that want it; the warn line is intentionally narrow.\n const total = chunks.length;\n const tags: string[] = [];\n if (failure.tier) tags.push(`tier=${failure.tier}`);\n if (failure.position !== null) tags.push(`position=${failure.position}`);\n const tagsSuffix = tags.length > 0 ? `; ${tags.join(' ')}` : '';\n console.warn(\n `[WikiMemory] ingest chunk ${chunkIndex + 1}/${total} ${failure.source} failed (sourceRef=${sourceRef}${tagsSuffix})`,\n );\n return { status: 'failed' as const, error: failure };\n }\n }),\n chunkConcurrency\n );\n\n // Single pass: collect failures, dedup ok facts against the cross-chunk\n // `seen` set, and count `ingestedChunks` / `failedChunks` together.\n let ingestedChunks = 0;\n let failedChunks = 0;\n const failures: ChunkFailure[] = [];\n const seen = new Set<string>();\n const orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }> = [];\n // Keyed by fact object identity: the same objects flow through dedupe,\n // the full path and the partial path. Empty when grounding is off.\n const groundingLedger = new Map<ExtractedFact, { verdict: GroundingVerdict; chunkIndex: number; itemIndex: number }>();\n const diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'ingest' as const, trigger: 'call' as const };\n for (const [chunkIndex, slot] of chunkResults.entries()) {\n if (slot.status === 'failed') {\n failedChunks++;\n failures.push(slot.error);\n continue;\n }\n ingestedChunks++;\n for (const r of slot.rejected) {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { sourceRef, chunkIndex, itemIndex: r.itemIndex, reason: r.reason } });\n }\n const dedupedFacts: ExtractedFact[] = [];\n slot.facts.forEach((fact, k) => {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (!seen.has(normalizedTitle)) {\n seen.add(normalizedTitle);\n dedupedFacts.push(fact);\n if (ingestGrounding) groundingLedger.set(fact, { verdict: slot.verdicts[k], chunkIndex, itemIndex: slot.itemIndexes[k] });\n } else {\n diagBuffer.push({\n ...diagBase, code: 'fact_deduplicated',\n detail: { sourceRef, chunkIndex, itemIndex: slot.itemIndexes[k], reason: 'exact_title' },\n });\n }\n });\n orderedChunkFacts.push({ facts: dedupedFacts, ontology_updates: slot.ontology_updates });\n }\n\n for (const reason of ['parse', 'llm'] as const) {\n const ofReason = failures.filter((f) => f.source === reason);\n if (ofReason.length === 0) continue;\n diagBuffer.push({\n ...diagBase, code: 'ingest_chunk_failed',\n detail: {\n sourceRef, reason, count: ofReason.length,\n chunkIndexes: ofReason.map((f) => f.chunkIndex).sort((a, b) => a - b).slice(0, 20),\n },\n });\n }\n\n // Total failure: throw WikiIngestEmptyError before any persistence runs.\n // A silent zero-fact ingest is a worse regression than a typed throw.\n if (failedChunks === chunks.length) {\n throw new WikiIngestEmptyError({\n parseFailures: failures,\n sourceRef,\n chunks: chunks.length,\n });\n }\n\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const deletedSourceFactIds: string[] = [];\n\n try {\n if (failedChunks === 0) {\n // Happy path — full upsertGraphCore supersession + ownership.\n const fullResult = await this.db.withTransactionAsync(async (tx) => {\n return await this.runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer, groundingLedger);\n });\n deletedSourceFactIds.push(...fullResult.deletedSourceFactIds);\n insertedFacts.push(...fullResult.insertedFacts);\n } else {\n // Partial path — append dedup-only, NO supersession, NO ownership update.\n // See spec §4.2. `insertedFacts` carries the per-fact descriptors\n // the post-commit hook loop needs to fire `embedFact` after the\n // partial transaction commits — without this, partial-row facts\n // would never reach the embedding service and the vector ranker\n // would never be notified for them (despite them being live in\n // the entries table). See the copilot review note on\n // `embeddingService.embedFact` vs. the partial-path gate.\n const partialResult = await this.db.withTransactionAsync(async (tx) => {\n const flat: ExtractedFact[] = [];\n for (const slot of orderedChunkFacts) flat.push(...slot.facts);\n return await this.appendPartialFacts(entityId, sourceRef, flat, tx, diagBuffer, groundingLedger);\n });\n insertedFacts.push(...partialResult.insertedDescriptors);\n }\n } catch (err) {\n // A concurrent ingest for a DIFFERENT sourceRef beat us to the same\n // sourceHash between the pre-check above and this write — the\n // source_ref_index partial UNIQUE index (entity_id, source_hash)\n // rejected the upsert. Translate into the same duplicate-hash\n // outcome the pre-check would have produced, by mode. Any other\n // error re-throws unmodified. With the entries-level UNIQUE gone,\n // every UNIQUE violation inside this transaction originates from\n // source_ref_index, so the single check is sufficient.\n const sqliteCode = err instanceof WikiTransactionError\n ? err.sqliteErrorCode\n : extractSqliteCode(err);\n if (sqliteCode !== 'SQLITE_CONSTRAINT_UNIQUE') throw err;\n\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n // No other live ref holds this hash (e.g. a different constraint\n // fired, or the racing writer's row was itself rolled back) — the\n // UNIQUE violation isn't explained by a duplicate-hash race; surface\n // the original error rather than a misleading result.\n if (canonical === null) throw err;\n\n if (onDuplicateHash === 'throw' || onDuplicateHash === 'ingest') {\n throw new WikiDuplicateHashError({ canonical, sourceHash, entityId });\n }\n // 'skip'\n return zeroChunkResult(canonical);\n }\n\n // Post-commit (spec §4.2.4). The duplicate-hash `return zeroChunkResult(...)`\n // paths in the catch above leave without flushing: nothing was committed.\n diagBuffer.flush(this.options);\n\n await this.searchService.sync(entityId);\n\n // Post-commit hook loop. `notifyEmbeddingPersisted(entityId, factId, null)`\n // is the embedding-lifecycle retirement signal — only relevant on the\n // full path, which is the only path that calls `softDeleteBySource`.\n // `embedFact` runs for every newly-inserted fact on EITHER path: the\n // partial path appends live rows, and those rows must participate in\n // semantic retrieval just like full-path facts — otherwise a 6-of-7\n // partial commit would leave the embedded fields null until a later\n // full retry, and a vector ranker wouldn't be notified for them.\n // (The earlier gate `if (failedChunks === 0)` blocked both halves of\n // this block on the partial path and was the bug copilot flagged.)\n if (failedChunks === 0) {\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 emitDiagnostic(this.options, {\n entityId, operation: 'ingest', trigger: 'call', code: 'hook_failed',\n detail: { factId, reason: 'on_embedding_persisted' },\n });\n }\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'ingest', trigger: 'call' });\n }\n\n this.searchService.evictCache(entityId);\n\n const result: IngestDocumentResult = {\n truncated,\n chunks: chunks.length,\n ingestedChunks,\n failedChunks,\n };\n if (failedChunks > 0) result.parseFailures = failures;\n return result;\n\n } finally {\n releaseIngestLocks();\n }\n }\n\n /**\n * Reject the whole write when any incoming node ID is already owned by a\n * different entity. Runs entirely inside the supplied `tx`, through the\n * repository abstraction, and — being the first thing `upsertGraphCore`\n * does — before ontology resolution, which can itself persist a configured\n * seed manifest.\n *\n * The lookup has no deleted-row filter, so a soft-deleted foreign row keeps\n * its ID reserved. Only the lookup IDs are deduplicated; `params.nodes` and\n * the later write loops keep their ordering and counts.\n *\n * The error is deliberately contextless — see WikiGraphNodeOwnershipConflict.\n *\n * @param entityId - the entity the caller is writing on behalf of. Foreign\n * rows under a different entity trigger the rejection.\n * @param nodes - incoming node set; only the IDs are inspected, so callers\n * may pass the public `params.nodes` shape directly without slicing.\n * @param tx - the open transaction. Reuses the same handle every later\n * statement in `upsertGraphCore` runs against, so atomicity is enforced\n * by the host transaction's commit/rollback, not by this method.\n */\n private async assertGraphNodeOwnership(\n entityId: string,\n nodes: readonly { id: string }[],\n tx: SQLiteAdapter,\n ): Promise<void> {\n const ids = [...new Set(nodes.map(node => node.id))];\n const existing = await this.entryRepo.findExistingMetadataByIds(ids, tx);\n for (const row of existing) {\n if (row.entity_id !== entityId) {\n throw new WikiGraphNodeOwnershipConflict();\n }\n }\n }\n\n /**\n * Implements spec §2 data flow steps a–j with the host-facing\n * `{sourceRef, sourceHash, nodes, edges}` parameter shape. Shared between\n * `ingestDocument` (with `{ strict: false }` to preserve current behavior)\n * and `WikiMemory.upsertGraph` (which lets the persisted ontology mode\n * decide strictness).\n *\n * Runs ENTIRELY inside the supplied `tx`. Does not acquire locks, does not\n * open a nested transaction, does not perform post-commit work (search\n * sync, embedding, cache eviction). Those concerns remain in `ingestDocument`.\n *\n * The pre-flight validation (steps a–c) lives INSIDE this method per the\n * spec, so the public `WikiMemory.upsertGraph` can be a thin wrapper that\n * performs only the C2 probe before delegating.\n *\n * @returns Counts: nodesWritten (validated nodes persisted), edgesWritten\n * (manifest-valid edges persisted), superseded (prior facts soft-deleted\n * plus prior source-ref edges hard-deleted).\n *\n * Node-ownership pre-flight (spec §3, REQ-GRAPH-01): the first statement\n * is `assertGraphNodeOwnership(entityId, params.nodes, tx)`, which runs\n * before ontology resolution, seed-manifest persistence, and every other\n * write. A foreign-owned ID throws `WikiGraphNodeOwnershipConflict` with\n * no disclosed owner, node ID, or content; the caller's transaction\n * remains open and must be rolled back by the host. Soft-deleted foreign\n * rows keep their IDs reserved. Duplicate incoming IDs are deduplicated\n * only for the lookup; `params.nodes` and the write loops keep their\n * ordering and counts so success counts match the pre-change contract.\n */\n async upsertGraphCore(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n nodes: readonly { id: string; type: string; title: string; body?: string; tags?: readonly string[]; confidence?: 'certain' | 'inferred' | 'tentative' }[];\n edges: readonly { type: string; sourceId: string; targetId: string; id?: string }[];\n },\n tx: SQLiteAdapter,\n opts?: {\n strict?: boolean;\n diag?: { buffer: DiagnosticBuffer; operation: 'ingest' | 'upsertGraph' };\n /** Insert-time trust by node id. Ingest-only (spec §6.5); the public upsertGraph never passes it, so host nodes are never grounded. */\n nodeTrust?: ReadonlyMap<string, GroundingTrust>;\n },\n ): Promise<{ nodesWritten: number; edgesWritten: number; superseded: number }> {\n // Node-ownership pre-flight FIRST — before ontology resolution and every\n // persistent mutation, so a rejected write leaves no seeded manifest\n // behind. Shared with ingestDocument's full path via runFullUpsertGraph;\n // that is intended. No bypass flag exists by design.\n await this.assertGraphNodeOwnership(entityId, params.nodes, tx);\n\n const now = Date.now();\n\n // (a) Resolve the effective ontology state through OntologyService rather\n // than reading metadataRepo.getManifest directly. OntologyService handles\n // the seedManifests contract (types.ts:65-66 — seeds are persisted on\n // first access when a tx is supplied, and cached otherwise) and the\n // ontologyConfig.mode fallback. Reading the repo directly here would\n // return null for an entity that has only a seedManifests entry, leaving\n // the strict mode silently unwritten and letting out-of-manifest data\n // through even when the host configured strict via the seed.\n const ontologyState = await this.ontologyService?.getEffectiveState(entityId, tx)\n ?? { mode: 'off' as const, manifest: { node_types: [], edge_types: [] } };\n let { mode, manifest } = ontologyState;\n // `opts.strict === false` overrides the persisted mode (used by\n // ingestDocument to preserve its pre-strict-mode silent-drop behavior).\n // `opts.strict === true` forces strict. `opts.strict === undefined`\n // follows the persisted mode.\n const strictEffective = opts?.strict === false\n ? false\n : opts?.strict === true || mode === 'strict';\n\n // (b) Pre-flight node validation — all-or-nothing under strict mode.\n // Build WikiFacts ready for upsert, with canonical okf_type.\n const wikiFacts: WikiFact[] = [];\n for (const node of params.nodes) {\n const factLike = { okf_type: node.type, edges: [] } as unknown as ExtractedFactWithOntology;\n const normalized = this.ontologyService?.validateAndNormalizeFact(factLike, manifest, {\n strict: strictEffective,\n entityId,\n }) ?? { okf_type: null, edges: [] };\n const wikiFact: WikiFact = {\n id: node.id,\n entity_id: entityId,\n title: node.title,\n body: node.body ?? '',\n // Public upsertGraph callers don't supply tags/confidence, so they\n // default to [] / 'certain' for deterministic AST-grade facts.\n // ingestDocument routes through this method for the LLM path and\n // forwards the LLM-supplied tags + confidence, preserving the prior\n // behavior (search filterability, heal-candidate selection, runReembed\n // embedding-text signal).\n tags: node.tags ? Array.from(node.tags) : [],\n confidence: node.confidence ?? 'certain',\n source_type: 'immutable_document',\n source_hash: params.sourceHash,\n source_ref: params.sourceRef,\n created_at: now,\n updated_at: now,\n last_accessed_at: null,\n access_count: 0,\n deleted_at: null,\n okf_type: normalized.okf_type,\n ...opts?.nodeTrust?.get(node.id),\n };\n wikiFacts.push(wikiFact);\n }\n\n // (c) Pre-flight edge validation, grouped by sourceId.\n // C3: dangling targetIds are stored verbatim. We only validate against\n // the manifest's (source_type, edge_type) lookup.\n const sourceIdToType = new Map<string, string | null>();\n for (const fact of wikiFacts) sourceIdToType.set(fact.id, fact.okf_type ?? null);\n\n // When the manifest is empty (no node_types AND no edge_types), the user\n // has expressed no constraints; edges pass through verbatim. This is\n // the documented \"no validation\" semantics — the host gets exactly the\n // edges it supplied, including dangling targetIds (C3).\n const hasConstraints = (manifest.node_types?.length ?? 0) > 0 || (manifest.edge_types?.length ?? 0) > 0;\n\n const validEdges: WikiEdge[] = [];\n for (const edge of params.edges) {\n if (!hasConstraints) {\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: edge.type,\n created_at: now,\n });\n continue;\n }\n // Per spec step (c): \"for each source node `n` in `params.nodes`, validate\n // that node's outgoing edges\". Edges whose sourceId references a node\n // OUTSIDE this call's nodes (a prior sourceRef's node) cannot have their\n // source type resolved without a DB lookup, so they pass through verbatim\n // — same lenient treatment C3 gives dangling targetIds.\n if (!sourceIdToType.has(edge.sourceId)) {\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: edge.type,\n created_at: now,\n });\n continue;\n }\n const sourceType = sourceIdToType.get(edge.sourceId);\n const candidates = (manifest.edge_types ?? []).filter(d =>\n d.type.toLowerCase() === edge.type.toLowerCase()\n && typeSatisfies(d.source_type, sourceType ?? '', manifest),\n );\n const match = candidates[0];\n if (!match) {\n if (strictEffective) throw new WikiStrictOntologyViolation(entityId, 'edge', edge.type);\n opts?.diag?.buffer.push({\n entityId, operation: opts.diag.operation, trigger: 'call', code: 'edge_dropped',\n detail: {\n reason: 'manifest_violation', factId: edge.sourceId, edgeType: edge.type,\n ...(sourceType ? { sourceNodeType: sourceType } : {}), sourceRef: params.sourceRef,\n },\n });\n continue;\n }\n validEdges.push({\n id: edge.id ?? generateId(),\n entity_id: entityId,\n source_id: edge.sourceId,\n target_id: edge.targetId,\n edge_type: match.type,\n created_at: now,\n });\n }\n\n // (d) Supersede prior facts for sourceRef.\n const deletedFactIds = await this.entryRepo.findIdsBySource(entityId, params.sourceRef, null, tx, false);\n await this.entryRepo.softDeleteBySource(entityId, tx, params.sourceRef, null);\n\n // (e) Supersede prior edges whose source is in deletedFactIds.\n const deletedEdgeCount = await this.edgeRepo.softDeleteBySourceFactIds(entityId, deletedFactIds, tx);\n\n // (f) Clear prior source_ref_index row for (entity, sourceRef).\n await this.sourceRefIndexRepo.softDeleteByEntityAndSourceRef(entityId, params.sourceRef, tx);\n\n // (g) Take ownership of (entity, hash).\n await this.sourceRefIndexRepo.upsert(entityId, params.sourceHash, params.sourceRef, tx);\n\n // (h) Write nodes (per-row outbox INSERT via entryRepo.upsert).\n for (const wikiFact of wikiFacts) {\n await this.entryRepo.upsert(wikiFact, tx);\n }\n\n // (i) Write edges (C3: dangling targets stored verbatim, no FK, no title-index resolution).\n // Count actual inserts via addIgnoreDuplicate; an edge whose id already\n // exists with the same (entity_id, source_id, target_id, edge_type) tuple\n // — e.g. a deterministic edge id reused across two distinct sourceRefs —\n // is silently skipped (returns false) and must NOT be counted as written.\n // Counting `validEdges.length` over-reports when caller-supplied edge ids\n // collide across sourceRefs, breaking the spec's C3 invariant that the\n // caller can rely on `edgesWritten` to assert \"did you drop anything?\".\n let edgesInsertedCount = 0;\n for (const edge of validEdges) {\n const inserted = await this.edgeRepo.addIgnoreDuplicate(edge, tx);\n if (inserted) edgesInsertedCount++;\n }\n\n // (j) Return counts.\n return {\n nodesWritten: wikiFacts.length,\n edgesWritten: edgesInsertedCount,\n superseded: deletedFactIds.length + deletedEdgeCount,\n };\n }\n\n /**\n * Full supersession + ownership path: identical to the pre-issue-#92 behavior\n * for the happy path. Called from the `failedChunks === 0` branch of\n * `ingestDocument`. Runs INSIDE the caller's tx.\n *\n * Returns `{ deletedSourceFactIds, insertedFacts }` so the caller can fire\n * post-commit hooks (embedding lifecycle) AFTER the transaction commits.\n * On the partial path the caller never invokes this method; the empty\n * arrays stay empty.\n */\n private async runFullUpsertGraph(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n orderedChunkFacts: Array<{ facts: ExtractedFact[]; ontology_updates?: OntologyUpdates }>,\n tx: SQLiteAdapter,\n diagBuffer: DiagnosticBuffer,\n groundingLedger: ReadonlyMap<ExtractedFact, { verdict: GroundingVerdict; chunkIndex: number; itemIndex: number }> = new Map(),\n ): Promise<{ deletedSourceFactIds: string[]; insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> }> {\n const deletedSourceFactIds: string[] = [];\n const insertedFacts: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n const nodeTrust = new Map<string, GroundingTrust>();\n\n // Capture the IDs of facts about to be soft-deleted so we can fire\n // onEmbeddingPersisted hooks AFTER the transaction commits. The\n // capture happens BEFORE the softDelete, so even though\n // upsertGraphCore performs its own findIdsBySource for edge\n // supersession, the IDs here are the canonical \"what we retired\"\n // set for the embedding lifecycle.\n deletedSourceFactIds.push(...(await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false)));\n\n // Build title index from PRIOR facts EXCLUDING the current sourceRef.\n // Facts from this sourceRef are about to be superseded by\n // upsertGraphCore step (d); seeding them here would let resolveEdges\n // target a soon-to-be-retired fact and leave the new edge pointing\n // at a soft-deleted record (the new edge's source is fresh, so step\n // (e) only retires edges whose SOURCE is in the deleted-fact set).\n // The sourceRef exclusion is applied in SQL (via\n // findRecentByEntityId's excludeSourceRef param) so the 500-row\n // LIMIT applies to usable rows only — a re-ingest where the current\n // sourceRef owns most recent facts otherwise leaves the index empty\n // after the post-query filter, silently losing cross-sourceRef edges\n // that a first ingest would have resolved.\n const titleIndex = new Map<string, TitleIndexEntry>();\n const existingFacts = await this.entryRepo.findRecentByEntityId(entityId, 500, tx, sourceRef);\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 // Two-pass conversion of LLM extraction into host-facing shape.\n // Pass 1 (below) populates hostNodes and stages raw edge requests\n // for every replacement fact — facts from this ingest enter the\n // titleIndex as they're added, so forward references resolve in\n // pass 2 against the FINALIZED index. Pass 2 then resolves each\n // staged request into concrete hostEdges. upsertGraphCore owns the\n // persistence step.\n const hostNodes: { id: string; type: string; title: string; body: string; tags?: readonly string[]; confidence?: 'certain' | 'inferred' | 'tentative' }[] = [];\n const rawEdgeRequests: { sourceId: string; sourceType: string | null; edges: ExtractedFactEdge[] }[] = [];\n const now = Date.now();\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 id = generateId('fact_');\n const validationDrops: EdgeDrop[] = [];\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest, { strict: false, drops: validationDrops })\n ?? { okf_type: null, edges: [] };\n for (const drop of validationDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { entityId, operation: 'ingest', trigger: 'call', sourceRef, factId: id }));\n }\n\n hostNodes.push({\n id,\n type: ontologyFact.okf_type ?? '',\n title: fact.title,\n body: fact.body,\n // Forward the LLM-extracted tags/confidence through the\n // extracted-shape upsertGraphCore path so the entries row\n // stores them (search filterability, heal-candidate\n // selection, runReembed embedding-text signal). The public\n // WikiMemory.upsertGraph API doesn't accept tags/confidence\n // — host-supplied deterministic nodes default to [] and\n // 'certain' as documented.\n tags: fact.tags,\n confidence: fact.confidence,\n });\n const grounding = groundingLedger.get(fact);\n if (grounding) {\n const outcome = groundingOutcome(grounding.verdict, now);\n nodeTrust.set(id, outcome.trust);\n if (outcome.diagnostic) {\n diagBuffer.push({\n entityId, operation: 'ingest', trigger: 'call', code: outcome.diagnostic.code,\n detail: { factId: id, sourceRef, chunkIndex: grounding.chunkIndex, itemIndex: grounding.itemIndex, reason: outcome.diagnostic.reason },\n });\n }\n }\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 rawEdgeRequests.push({ sourceId: id, sourceType: normalized.okf_type, edges: normalized.edges });\n }\n }\n }\n\n // Pass 2: resolve every staged edge against the finalized title\n // index. By this point the index contains both surviving prior\n // facts (excluding this sourceRef) AND every replacement fact from\n // this ingest, so forward references resolve correctly and no\n // resolved edge points at a fact that's about to be soft-deleted.\n const hostEdges: { type: string; sourceId: string; targetId: string }[] = [];\n for (const req of rawEdgeRequests) {\n const resolveDrops: EdgeDrop[] = [];\n const resolved = this.ontologyService?.resolveEdges(\n entityId, req.sourceId, req.sourceType, req.edges, manifest, titleIndex, now, resolveDrops,\n ) ?? [];\n for (const drop of resolveDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { entityId, operation: 'ingest', trigger: 'call', sourceRef }));\n }\n for (const e of resolved) {\n hostEdges.push({ type: e.edge_type, sourceId: e.source_id, targetId: e.target_id });\n }\n }\n\n await this.upsertGraphCore(\n entityId,\n { sourceRef, sourceHash, nodes: hostNodes, edges: hostEdges },\n tx,\n { strict: false, diag: { buffer: diagBuffer, operation: 'ingest' }, ...(nodeTrust.size > 0 ? { nodeTrust } : {}) },\n );\n\n return { deletedSourceFactIds, insertedFacts };\n }\n\n /**\n * Partial-commit path for `ingestDocument`. Inserts ONLY facts whose\n * normalized title is not already in the live set for this (entityId,\n * sourceRef). Does NOT call `entryRepo.softDeleteBySource` (no\n * supersession) and does NOT call `sourceRefIndexRepo.upsert` (no\n * ownership). Edges are NOT resolved on this path (no ontology-context\n * build, no `resolveEdges`, no `mergeEmergentUpdates`). Stale edges from\n * prior attempts are recovered on the next full run's supersession.\n *\n * Source-hash is stored as NULL on partial rows. `findLatestSourceHash`\n * reads from the most recently updated live row for the sourceRef, so\n * storing the incoming hash here would cause `hasChanged` to return\n * `false` on a same-hash retry — the failed chunks would never get a\n * second chance. With NULL, a retry sees `storedHash === null`, `hasChanged`\n * returns `true`, and the partial commit's sibling rows remain live\n * (deduped, not superseded) for the next attempt to extend.\n *\n * Runs INSIDE the caller's `tx`. Does not open a nested transaction.\n * Returns `{ inserted, skippedDuplicate }` for observability.\n */\n private async appendPartialFacts(\n entityId: string,\n sourceRef: string,\n dedupedFacts: ExtractedFact[],\n tx: SQLiteAdapter,\n diagBuffer: DiagnosticBuffer,\n groundingLedger: ReadonlyMap<ExtractedFact, { verdict: GroundingVerdict; chunkIndex: number; itemIndex: number }> = new Map(),\n ): Promise<{\n inserted: number;\n skippedDuplicate: number;\n /** Descriptors for the rows this call actually inserted, in the same\n * shape `runFullUpsertGraph` returns — the post-commit hook loop\n * passes these to `embedFact`. Without them, partial-path inserts\n * would skip the embedding service entirely. */\n insertedDescriptors: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }>;\n }> {\n // Partial rows are intentionally stored with `source_hash: null` so\n // `hasChanged` keeps returning true on every retry of the same hash —\n // the failed chunks get a second chance. The full path stamps the actual\n // hash via `runFullUpsertGraph`; this helper deliberately does not.\n // Load the live (sourceRef, *) rows so we can dedup by title against prior\n // partial attempts AND prior full attempts. includeDeleted=false matches\n // the pre-supersession dedup semantics of the full path. Per spec §4.2:\n // `findIdsBySource` returns the ids (already scoped to `entityId` and\n // excluding deleted rows); `findByIds` resolves titles — no entity filter\n // needed because the ids carry that scope already.\n const liveIds = await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false);\n const liveFacts = liveIds.length === 0\n ? []\n : await this.entryRepo.findByIds(liveIds, undefined, tx);\n const liveTitles = new Set(liveFacts.map((f) => normalizeTitleKey(f.title)));\n\n let inserted = 0;\n let skippedDuplicate = 0;\n const now = Date.now();\n const insertedDescriptors: Array<{ id: string; entity_id: string; title: string; body: string; tags: string }> = [];\n for (const fact of dedupedFacts) {\n const normalizedTitle = normalizeTitleKey(fact.title);\n if (liveTitles.has(normalizedTitle)) {\n diagBuffer.push({\n entityId, operation: 'ingest', trigger: 'call', code: 'fact_deduplicated',\n detail: { sourceRef, reason: 'exact_title' },\n });\n skippedDuplicate++;\n continue;\n }\n liveTitles.add(normalizedTitle);\n\n const id = generateId('fact_');\n const grounding = groundingLedger.get(fact);\n const outcome = grounding ? groundingOutcome(grounding.verdict, now) : null;\n if (grounding && outcome?.diagnostic) {\n diagBuffer.push({\n entityId, operation: 'ingest', trigger: 'call', code: outcome.diagnostic.code,\n detail: { factId: id, sourceRef, chunkIndex: grounding.chunkIndex, itemIndex: grounding.itemIndex, reason: outcome.diagnostic.reason },\n });\n }\n const wikiFact: WikiFact = {\n id,\n entity_id: entityId,\n title: fact.title,\n body: fact.body,\n tags: fact.tags,\n confidence: fact.confidence,\n source_type: 'immutable_document',\n // source_hash: null on partial rows — see method docstring. The\n // full path stamps the actual hash; partial rows stay hash-less so\n // `hasChanged` keeps returning true for retries.\n source_hash: null,\n source_ref: sourceRef,\n created_at: now,\n updated_at: now,\n last_accessed_at: null,\n access_count: 0,\n deleted_at: null,\n okf_type: null,\n ...outcome?.trust,\n };\n await this.entryRepo.upsert(wikiFact, tx);\n // Mirror the shape `runFullUpsertGraph` returns so the caller's\n // post-commit `embedFact` loop is path-agnostic.\n insertedDescriptors.push({\n id,\n entity_id: entityId,\n title: fact.title,\n body: fact.body,\n tags: JSON.stringify(fact.tags),\n });\n inserted++;\n }\n return { inserted, skippedDuplicate, insertedDescriptors };\n }\n}\n","import type { ClassifierAnswer, ClassifierQuestion } from '../types';\n\nexport type ClassifierRejection =\n | 'malformed'\n | 'missing_answer'\n | 'kind_mismatch'\n | 'choice_not_offered'\n | 'score_out_of_range'\n | 'invalid_probability';\n\ntype Checked = { ok: true; answer: ClassifierAnswer } | { ok: false; reason: ClassifierRejection };\n\nconst isUnit = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0 && v <= 1;\n\n/**\n * Validate one answer from an untrusted classifier response (spec REQ-CLASS-02).\n * Never throws: hostile objects (throwing getters, Proxies) yield `malformed`.\n * Returns a fresh plain object, never the provider's own reference.\n */\nexport function validateClassifierAnswer(response: unknown, key: string, question: ClassifierQuestion): Checked {\n try {\n if (response === null || typeof response !== 'object') return { ok: false, reason: 'malformed' };\n const answers = (response as { answers?: unknown }).answers;\n if (answers === null || typeof answers !== 'object') return { ok: false, reason: 'missing_answer' };\n if (!Object.prototype.hasOwnProperty.call(answers, key)) return { ok: false, reason: 'missing_answer' };\n const raw = (answers as Record<string, unknown>)[key];\n if (raw === null || typeof raw !== 'object') return { ok: false, reason: 'missing_answer' };\n const a = raw as Record<string, unknown>;\n if (a.kind !== question.kind) return { ok: false, reason: 'kind_mismatch' };\n\n if (question.kind === 'choice') {\n if (typeof a.choice !== 'string' || !question.options.includes(a.choice)) return { ok: false, reason: 'choice_not_offered' };\n if (!isUnit(a.confidence)) return { ok: false, reason: 'invalid_probability' };\n const probs = a.probabilities;\n if (probs === null || typeof probs !== 'object' || Array.isArray(probs)) return { ok: false, reason: 'invalid_probability' };\n const probabilities: Record<string, number> = {};\n for (const [k, v] of Object.entries(probs as Record<string, unknown>)) {\n if (!isUnit(v)) return { ok: false, reason: 'invalid_probability' };\n probabilities[k] = v;\n }\n return { ok: true, answer: { kind: 'choice', choice: a.choice, confidence: a.confidence, probabilities } };\n }\n\n if (question.kind === 'binary') {\n if (!isUnit(a.probability)) return { ok: false, reason: 'invalid_probability' };\n return { ok: true, answer: { kind: 'binary', probability: a.probability } };\n }\n\n const maxScore = question.levels.length - 1;\n if (typeof a.score !== 'number' || !Number.isFinite(a.score) || a.score < 0 || a.score > maxScore) {\n return { ok: false, reason: 'score_out_of_range' };\n }\n if (!isUnit(a.confidence)) return { ok: false, reason: 'invalid_probability' };\n if (!Array.isArray(a.probabilities) || !a.probabilities.every(isUnit)) return { ok: false, reason: 'invalid_probability' };\n return { ok: true, answer: { kind: 'score', score: a.score, confidence: a.confidence, probabilities: a.probabilities.slice() } };\n } catch {\n return { ok: false, reason: 'malformed' };\n }\n}\n\n/** The classifier `state` for a fact: title, body, and tags when present. */\nexport function classifierStateForFact(fact: { title: string; body: string; tags: string[] }): string {\n const parts = [fact.title, fact.body];\n if (Array.isArray(fact.tags) && fact.tags.length > 0) parts.push(`Tags: ${fact.tags.join(', ')}`);\n return parts.join('\\n\\n');\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 *\n * The contract is explicit: this function must never throw. The\n * `err instanceof Error` check below invokes the `getPrototypeOf` trap on\n * `err`. A hostile Proxy whose trap rejects would otherwise throw out of\n * `runBatched` — and any throw inside `runBatched` is the silent-batch-\n * failure mode this whole helper exists to prevent. On a hostile trap, we\n * fall back to `false` (treat as not a truncation error): the consequence\n * is at most one wasted batch split, which is the correct trade-off.\n */\nfunction getErrorMessage(err: unknown): string | undefined {\n try {\n return err instanceof Error ? err.message : String(err ?? '');\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects\n return undefined;\n }\n}\n\nexport function isTruncationError(err: unknown): boolean {\n const message = getErrorMessage(err);\n if (message === undefined) return false;\n if (EXCEEDS_LIMIT_PATTERN.test(message)) return false;\n return TRUNCATION_PATTERNS.some((pattern) => pattern.test(message));\n}\n\n/**\n * Whether a thrown error looks like a model-config error — the caller\n * requested more output than the model allows, and re-running it in the\n * next pass produces the same failure. Distinguished from transient\n * provider failures (`ECONNRESET`, auth blip, 5xx) so the cooldown-stamp\n * filter in `doRunHeal` / `doRunOntologyBackfill` does not exclude these\n * facts from eligibility: a model-config bug is the host's problem to\n * fix, and a fact that errored this way can recover only when the host\n * does, so the cooldown stamp is the right behavior.\n *\n * Same Proxy-safety contract as `isTruncationError`: hostile\n * `getPrototypeOf` trap must not propagate out of this function.\n */\nexport function isConfigError(err: unknown): boolean {\n const message = getErrorMessage(err);\n if (message === undefined) return false;\n return EXCEEDS_LIMIT_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 /**\n * May be async: heal selects anchors per batch via a search + repository read.\n *\n * `attemptLevel` is the escalation level at which this build is being asked\n * to produce a prompt. trim()'s speculatives always pass `0` (they only\n * measure length). Real attempts pass the current escalation level: `0`\n * (normal), `1` (less shared context), `2` (less again), or `3` (last\n * resort — caller is expected to shrink or truncate the prompt itself).\n * Defaults to `0` so callers that don't care about the level are unchanged.\n */\n buildPrompt: (\n batch: TItem[],\n attemptLevel?: 0 | 1 | 2 | 3,\n ) => 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, and the\n * exact prompt object that was sent (heal keys its grounding corpus to it).\n * Throwing is the signal that the response was unusable. */\n parse: (responseText: string, batch: TItem[], prompts: BuiltPrompt) => 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 /**\n * Items that could not converge after the helper's full escalation path.\n * The discriminator separates genuine non-convergence (`'non_convergent'`\n * — terminal give-up at L3, parse error, or a model-config error) from\n * transient provider failures (`'call_error'` — non-truncation error\n * originating in `call()` at `batch.length === 1`). Callers that stamp a\n * cooldown on skipped facts (e.g. `doRunHeal`) must filter out the\n * `'call_error'` ids so a momentary 5xx doesn't lock the fact out for a\n * week.\n */\n skipped: Array<{ item: TItem; reason: 'non_convergent' | 'call_error' }>;\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: Array<{ item: TItem; reason: 'non_convergent' | 'call_error' }> = [];\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 (\n batch: TItem[],\n err: unknown,\n attemptLevel: 0 | 1 | 2 | 3,\n fromCall: boolean,\n ): Promise<void> => {\n if (batch.length === 1) {\n // Gate: escalation only on a truncation-shaped error at the lowest batch\n // size, and only while the ladder has levels left. Anything else at this\n // point — parse error, exceeds-limit config error, or a non-truncation\n // call error — is a terminal give-up. A parse error is not retryable by\n // context-shedding (the JSON desync shape is the same at L1, L2, and L3);\n // escalating would burn three calls before reaching skip. The gate\n // prevents that.\n if (fromCall && isTruncationError(err) && attemptLevel < 3) {\n // Bypass trim: its prebuilt prompt is the L0 form, invalid at the new\n // level. attempt() will call buildPrompt(batch, attemptLevel + 1) to\n // produce the level-appropriate prompt.\n await attempt(batch, undefined, (attemptLevel + 1) as 0 | 1 | 2 | 3);\n } else {\n // Subreason: a non-truncation error originating in `call()` is a\n // transient provider failure (5xx, network reset, auth blip), not a\n // model capability failure or a model-config bug. Distinguishing it\n // lets orchestration callers (doRunHeal, doRunOntologyBackfill)\n // refuse to apply a recheck cooldown stamp to facts whose skip is\n // operationally reversible. EXCEEDS_LIMIT-shaped errors are\n // model-config bugs that retry identically every pass, so they stay\n // `'non_convergent'` and receive the cooldown stamp. See\n // docs/superpowers/specs/2026-08-17-...-design.md §\"Revision 1 —\n // call_error subreason\".\n const reason: 'non_convergent' | 'call_error' =\n fromCall && !isTruncationError(err) && !isConfigError(err) ? 'call_error' : 'non_convergent';\n skipped.push({ item: batch[0], reason });\n onSkip?.(batch[0], err);\n }\n return;\n }\n // Non-truncation call errors at batch.length > 1 are real errors (network,\n // auth) and must propagate rather than silently split/skip the corpus.\n // Parse errors always split — the JSON may parse after shedding context.\n if (fromCall && !isTruncationError(err)) throw err;\n // batch.length > 1: split path, unchanged. Sticky-down batchSize\n // adaptation and the inner trim/attempt loop at level 0 are preserved.\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 (\n batch: TItem[],\n prebuilt?: BuiltPrompt,\n attemptLevel: 0 | 1 | 2 | 3 = 0,\n ): Promise<void> => {\n if (batch.length === 0) return;\n // prebuilt is the L0 form from trim(); only valid at attemptLevel === 0.\n // The level-advance path in onFailure passes `undefined` to force a rebuild.\n const prompts =\n prebuilt && attemptLevel === 0\n ? prebuilt\n : (await buildPrompt(batch, attemptLevel));\n\n batches++;\n let responseText: string;\n try {\n responseText = await call(prompts);\n } catch (err) {\n // Non-truncation call errors: hand to onFailure (skips at batch.length===1,\n // throws at batch.length>1). Truncation errors also go to onFailure for\n // potential ladder escalation.\n await onFailure(batch, err, attemptLevel, true);\n return;\n }\n\n let result: TResult;\n try {\n result = parse(responseText, batch, prompts);\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 // Parse errors always split, never throw — the JSON may parse after\n // shedding context. The gate inside onFailure handles ladder escalation.\n await onFailure(batch, err, attemptLevel, false);\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, 0);\n }\n\n return { results, skipped, batches };\n}\n","import { parseJsonResponse, validateFact, validateTask, titleTokens, jaccardScore, normalizeSourceRef, normalizeSourceHash, sanitizeRankerError, safeErrorToString, safeSlice, withConcurrency, factRejectionReason, taskRejectionReason } from '../utils/pure';\nimport { resolveGrounding, checkGrounding, groundingOutcome } from '../utils/grounding';\nimport { normalizeTitleKey } from '../utils/ontology';\nimport { validateClassifierAnswer, classifierStateForFact, type ClassifierRejection } from '../utils/classifier';\nimport { DiagnosticBuffer, emitDiagnostic, edgeDropDiagnostic } from '../utils/diagnostics';\nimport type { EdgeDrop } 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, HealResult, DegradedRecord, ReembedResult, ClassifierQuestion, OntologyManifest, WikiDiagnosticTrigger } from '../types';\nimport type { SQLiteAdapter } from '../types';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { SourceRefIndexRepository } from '../repositories/SourceRefIndexRepository';\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';\nimport type { BuiltPrompt } from './BoundedLlmCall';\nimport {\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_MAX_ANCHORS,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n HEAL_MAX_TASKS,\n} from '../utils/healConstants';\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// Heal constants live in `utils/healConstants` so PromptService and\n// MaintenanceService cannot drift apart on the anchor cap formula\n// (spec: \"values must match\"). Re-exported here to preserve the existing\n// `MaintenanceService.HEAL_*` public surface that index.ts and other\n// downstream consumers already import.\nexport { HEAL_MAX_ANCHORS, HEAL_ANCHORS_PER_CANDIDATE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS } from '../utils/healConstants';\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/**\n * Heal candidates fetched per pass. Bounds the pool runBatched draws from, not\n * the size of an individual LLM call — runBatched still packs ~10 candidates per\n * request and splits further on failure. At this default one pass costs roughly\n * 2-3 provider calls instead of an unbounded count (#67).\n */\nexport const HEAL_BATCH_SIZE = 25;\n\n/** Cooldown before an already-healed fact is offered again. Matches ontology backfill. */\nexport const HEAL_RECHECK_MS = 7 * 24 * 60 * 60 * 1000;\n\n/** Attempts after which a fact is considered permanently un-embeddable. */\nexport const MAX_EMBED_ATTEMPTS = 5;\n/** First retry delay after a recoverable embedding failure. */\nexport const EMBED_RETRY_BASE_MS = 60_000;\n/** Upper bound on the exponential retry delay. */\nexport const EMBED_RETRY_CAP_MS = 24 * 60 * 60 * 1000;\n\n/** Exponential backoff: base * 2^(attempts-1), capped. */\nexport function embedRetryDelayMs(attempts: number): number {\n const n = Math.max(1, Math.trunc(attempts || 0));\n const delay = EMBED_RETRY_BASE_MS * Math.pow(2, n - 1);\n return Math.min(delay, EMBED_RETRY_CAP_MS);\n}\n\nexport type ReembedDisposition = 'attempt' | 'defer' | 'permanent';\n\n/**\n * Decide what to do with one candidate row. Pure: no DB, no clock.\n *\n * `float32_overflow` is terminal because it is deterministic arithmetic on the\n * same vector — retrying can only produce the same overflow.\n */\nexport function classifyReembedRow(\n row: {\n embedding_failed_at?: number | null;\n embedding_failure_kind?: string | null;\n embedding_attempts?: number | null;\n },\n now: number,\n force: boolean,\n): ReembedDisposition {\n if (force) return 'attempt';\n\n const failedAt = row.embedding_failed_at;\n if (failedAt === null || failedAt === undefined) return 'attempt';\n\n if (row.embedding_failure_kind === 'float32_overflow') return 'permanent';\n\n const attempts = row.embedding_attempts ?? 0;\n if (attempts >= MAX_EMBED_ATTEMPTS) return 'permanent';\n\n return now - failedAt >= embedRetryDelayMs(attempts) ? 'attempt' : 'defer';\n}\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; body?: string; lifecycle_status?: string };\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 /** Corpus of the prompt that produced this response; null when heal is not a grounding writer. */\n corpus: string[] | null;\n}\n\n/**\n * Hard cap on skipped-item error text in the log. A provider response or\n * prompt artifact can carry a multi-MB message; one unbounded failure must\n * not flood stderr (or any downstream log-shipping pipeline) by being logged\n * once per skipped item.\n */\nconst SKIP_ERROR_LOG_CHARS = 4096;\n\n/**\n * Stringify an unknown error from `RunBatchedArgs.onSkip` for the log.\n * Exported for unit testing only — callers must always treat the return\n * value as a bounded, log-safe string. Internal callers feed this through\n * `console.warn` from heal/ontology-backfill `onSkip` paths.\n *\n * The callback receives `unknown`, so the value is not guaranteed to be a\n * `WikiParseError` with a small `.message`; a raw provider stack, an HTTP\n * error object, or a `string` is all possible. `String(err)` on a plain object\n * uses `Object.prototype.toString` and stays small, but `JSON.stringify` is\n * needed to surface anything structured, and the output is bounded either\n * way so a degenerate payload cannot slip through.\n *\n * Implementation note: every coercion path delegates to `safeErrorToString`,\n * which guarantees a non-throwing string return via a static\n * `[unstringifiable error]` marker. The previous hand-rolled chain had a\n * hole — `JSON.stringify` throws and the `catch` then ran\n * `Object.prototype.toString.call(err)`, which itself can throw (a Proxy\n * whose `get` trap rejects every property access — including\n * `Symbol.toStringTag`). That throw escaped the function and rejected the\n * surrounding `runBatched` operation wholesale. `safeErrorToString` was\n * hardened against this exact path; reuse it.\n */\nexport const formatSkipError = (err: unknown): string => {\n // Two goals:\n // 1. Surface structured provider errors as JSON when present\n // (e.g. `{code: 500, msg: 'oops'}` -> `\"{\"code\":500,\"msg\":\"oops\"}\"`).\n // 2. Never throw, regardless of what hostile value reaches us via\n // `onSkip` (Symbol, function, throwing toString, Proxy rejecting\n // property access, Error with bad message, etc).\n //\n // `safeErrorToString` is the hardened non-throwing helper; every path\n // either uses it directly or falls back to it. JSON.stringify failure\n // paths (throwing toJSON, circular structure, Proxy) all converge on\n // `safeErrorToString`, which itself wraps String() and\n // Object.prototype.toString.call() in nested try/catch.\n let base: string;\n // `err instanceof Error` invokes the `getPrototypeOf` trap on `err`. A\n // hostile Proxy (e.g. one passed through `onSkip` from a misbehaving\n // provider plugin) whose trap rejects would throw out of this function —\n // defeating the documented \"never throw\" contract. Treat the trap throw\n // as \"not an Error\" and fall through to the JSON.stringify / safeErrorToString\n // branch below.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n // hostile Proxy whose getPrototypeOf trap rejects — fall through\n }\n if (isErrorLike || (typeof err !== 'object' && typeof err !== 'function')) {\n // Errors -> safeErrorToString (returns err.message verbatim, or .name,\n // or '[Error]' for hostile Error subclasses)\n // Primitives (string, number, boolean, bigint, undefined, symbol) ->\n // safeErrorToString (String() handles them all)\n base = safeErrorToString(err);\n } else {\n // null + plain objects + arrays -> try JSON.stringify to surface\n // structure. `null` JSON-stringifies to 'null', `typeof null ===\n // 'object'` so it lands here safely.\n try {\n const json = JSON.stringify(err);\n base = typeof json === 'string' ? json : safeErrorToString(err);\n } catch {\n base = safeErrorToString(err);\n }\n }\n if (base.length > SKIP_ERROR_LOG_CHARS) {\n // safeSlice (from utils/pure) never splits a UTF-16 surrogate pair at the\n // cut boundary — a bare String.slice can, leaving a lone high surrogate\n // that renders as U+FFFD in the log line.\n const truncated = safeSlice(base, 0, SKIP_ERROR_LOG_CHARS);\n return `${truncated}…[+${base.length - SKIP_ERROR_LOG_CHARS} chars truncated]`;\n }\n return base;\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 sourceRefIndexRepo: SourceRefIndexRepository,\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, resolveGrounding(this.options.config?.grounding));\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(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number; bodyTruncationChars?: number },\n ): Promise<HealResult> {\n this.jobManager.acquireLock('heal', entityId);\n try {\n return await this.doRunHeal(entityId, options);\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n\n async runOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number; classifier?: 'auto' | 'llm' },\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 /**\n * Re-embed facts, honouring per-row failure markers and exponential backoff.\n *\n * Marker lifecycle (spec §2): markers are cleared by a successful embed, by\n * an upsert carrying a valid blob, and by an embedding-dimension promotion.\n * A promotion revives rows for the NEXT sweep, not this one — reconciliation\n * runs after candidates were already classified.\n *\n * Residual, by design: swapping to a provider with the SAME dimension never\n * sets embedding_dimension_mismatch, so promotion never fires and markers\n * survive the swap. Use `runReembed({ force: true })` to clear that state —\n * `force` bypasses classification entirely and retries every row.\n *\n * Lock scope (spec 2026-09-05 §2): a marker mutation is legal while a sweep\n * is in flight if and only if it cannot resurrect a row the sweep has\n * classified. Mutations scoped to entities not under an active sweep key are\n * legal — the entity-scoped ingest/import lock checks enforce that. The one\n * mutation that spans every entity, `reconcileEmbeddingDimension`'s marker\n * clear, is made legal by DEFERRING (importDump gates on\n * `JobManager.isAnyReembedActive()`), never by widening a lock. Auto-heal is\n * excluded from sweeps for the same reason.\n */\n async runReembed(\n entityId?: string,\n opts?: { force?: boolean; skipExisting?: boolean },\n ): Promise<ReembedResult> {\n const embedFn = this.options.llmProvider.embed;\n // Same callability guard as EmbeddingService.tryEmbedFact (spec §2.4): a\n // misconfigured provider short-circuits the sweep instead of iterating and\n // marking every row.\n if (typeof embedFn !== 'function') {\n return { embedded: 0, skipped: 0, failed: 0, deferred: 0, permanentlyFailed: 0 };\n }\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 let deferred = 0;\n let permanentlyFailed = 0;\n const force = opts?.force ?? false;\n // One clock snapshot for the whole sweep: backoff eligibility is decided\n // against sweep-start time, so rows whose window elapses mid-sweep stay\n // deferred until the next sweep. Keeps classifyReembedRow pure and the\n // sweep's deferral decisions deterministic for a single invocation.\n const now = Date.now();\n\n try {\n for (const row of rows) {\n const existingBlob = row.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 disposition = classifyReembedRow(row, now, force);\n if (disposition === 'defer') { deferred++; continue; }\n if (disposition === 'permanent') { permanentlyFailed++; continue; }\n\n const result = await this.embeddingService.tryEmbedFact(row, { operation: 'reembed', trigger: 'call' });\n if (result.ok) 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, deferred, permanentlyFailed };\n } finally {\n this.jobManager.releaseLock(op, entityId ?? '*');\n }\n }\n\n async forget(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n opts?: { dryRun?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\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 // Dry-run: read-only, no lock, no outbox events, no embedding hooks.\n if (opts?.dryRun === true) {\n return this.forgetDryRun(entityId, params);\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 // Mirror the clearAll to source_ref_index so the post-clearAll state\n // has no live index rows for the entity. Hard-delete via the soft-delete\n // path keeps the CDC contract identical to entries (outbox events are\n // not fired for source_ref_index, so this is purely an internal\n // invariant cleanup).\n // TODO: add a bulk source_ref_index soft-delete once the v9 backfill\n // gap is closed; for now, leaving the rows in place is safe because\n // the partial UNIQUE index excludes deleted_at != NULL rows from\n // re-ingest — a re-ingest would correctly take ownership.\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 // Soft-delete the source_ref_index row so a re-ingest of this\n // sourceRef+hash can take ownership. The pre-check at the start of\n // ingestDocument will now see no live ref and proceed. No-op when\n // the row is already soft-deleted or never existed.\n const sourceRefIndexPromise = sourceRef\n ? this.sourceRefIndexRepo.softDeleteByEntityAndSourceRef(entityId, sourceRef, tx).then(() => undefined)\n : 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 sourceRefIndexPromise ?? Promise.resolve(undefined),\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 params.clearAll\n ? { deleted: { entries: deletedEntries, tasks: deletedTasks }, metadataReset: true }\n : { deleted: { entries: deletedEntries, tasks: deletedTasks } };\n } finally {\n this.jobManager.releaseLock('forget', entityId);\n }\n }\n\n /**\n * Read-only dry-run preview of {@link forget}. Returns the same shape as a\n * real call would, without acquiring the lock, opening a transaction, staging\n * outbox events, or firing embedding hooks. Counts may be off-by-N during a\n * concurrent real forget — this is accepted, not considered a bug.\n *\n * `metadataReset` mirrors the real call: only `clearAll: true` returns true,\n * because only `clearAll` actually resets the metadata checkpoint.\n * `standard` (sourceRef/sourceHash) returns no metadataReset field, just like\n * the real call. `entryId`/`taskId` selectors are rejected with a clear error\n * (the spec keeps dry-run narrow).\n */\n private async forgetDryRun(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\n // Note: the clearAll mutual-exclusion check is performed by the public\n // forget() before dispatching here. forgetDryRun is private and unreachable\n // for callers that violate that contract, so it does not re-validate.\n\n if (params.entryId !== undefined || params.taskId !== undefined) {\n throw new Error('forget({ dryRun: true }) does not support entryId/taskId selectors; use sourceRef/sourceHash or clearAll');\n }\n\n if (params.clearAll) {\n const entries = await this.entryRepo.countLiveByEntityId(entityId);\n const tasks = await this.taskRepo.countLiveByEntityId(entityId);\n return { deleted: { entries, tasks }, metadataReset: true };\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 // No source selectors supplied: the real call is a no-op (softDeleteBySource\n // is gated on `if (sourceRef || sourceHash)`). Mirror that — do NOT count all\n // live entries, which would silently mask a caller bug as a large blast radius.\n if (sourceRef === null && sourceHash === null) {\n return { deleted: { entries: 0, tasks: 0 } };\n }\n\n const entries = await this.entryRepo.countLiveBySource(entityId, sourceRef, sourceHash);\n return { deleted: { entries, tasks: 0 } };\n }\n\n /** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */\n async doRunLibrarian(entityId: string, promptOverride?: string, trigger: WikiDiagnosticTrigger = 'call'): 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 promptEvents = events.reverse();\n const librarianGrounding = this.promptService.groundingFor('librarian');\n\n // groundingCorpus (spec §6.3) is built with the prompt, from the event\n // summaries that prompt actually shows.\n const { systemPrompt, userPrompt, groundingCorpus: librarianCorpus = [] } = this.promptService.buildLibrarianPrompt(\n promptEvents,\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 diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'librarian' as const, trigger };\n const validFacts: ExtractedFact[] = [];\n const validFactItemIndexes: number[] = [];\n facts.forEach((raw, itemIndex) => {\n const valid = validateFact(raw);\n if (valid) {\n validFacts.push(valid);\n validFactItemIndexes.push(itemIndex);\n } else {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { itemIndex, reason: factRejectionReason(raw) } });\n }\n });\n const validTasks: ExtractedTask[] = [];\n tasks.forEach((raw, itemIndex) => {\n const valid = validateTask(raw);\n if (valid) validTasks.push(valid);\n else diagBuffer.push({ ...diagBase, code: 'task_rejected', detail: { itemIndex, reason: taskRejectionReason(raw) } });\n });\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 [k, fact] of validFacts.entries()) {\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) {\n diagBuffer.push({ ...diagBase, code: 'fact_deduplicated', detail: { itemIndex: validFactItemIndexes[k], reason: 'fuzzy_title' } });\n continue;\n }\n\n const ontologyFact = fact as ExtractedFactWithOntology;\n const id = generateId('fact_');\n const validationDrops: EdgeDrop[] = [];\n const normalized = this.ontologyService?.validateAndNormalizeFact(ontologyFact, manifest, { strict: false, drops: validationDrops })\n ?? { okf_type: null, edges: [] };\n for (const drop of validationDrops) diagBuffer.push(edgeDropDiagnostic(drop, { ...diagBase, factId: id }));\n\n const grounding = librarianGrounding\n ? groundingOutcome(checkGrounding(fact.evidence, librarianCorpus, librarianGrounding), now)\n : null;\n if (grounding?.diagnostic) {\n diagBuffer.push({ ...diagBase, code: grounding.diagnostic.code, detail: { factId: id, itemIndex: validFactItemIndexes[k], reason: grounding.diagnostic.reason } });\n }\n\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 ...grounding?.trust,\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 const resolveDrops: EdgeDrop[] = [];\n await this.ontologyService?.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges ?? [], manifest, titleIndex, tx, now, resolveDrops,\n );\n for (const drop of resolveDrops) diagBuffer.push(edgeDropDiagnostic(drop, diagBase));\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 diagBuffer.flush(this.options);\n\n await this.searchService.sync(entityId);\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'librarian', trigger });\n }\n\n this.searchService.evictCache(entityId);\n }\n\n /**\n * Core heal pass (locks handled by {@link runHeal}). Package-internal orchestration hook.\n *\n * Bounded: at most `batchSize` candidates per pass (#67). Loop on\n * `result.remaining > 0` for convergence — see {@link HealResult.remaining}\n * for what convergence means here.\n */\n async doRunHeal(\n entityId: string,\n options?: {\n promptOverride?: string;\n batchSize?: number;\n bodyTruncationChars?: number;\n trigger?: WikiDiagnosticTrigger;\n },\n ): Promise<HealResult> {\n const promptOverride = options?.promptOverride;\n const batchSize = options?.batchSize ?? HEAL_BATCH_SIZE;\n const trigger: WikiDiagnosticTrigger = options?.trigger ?? 'call';\n const diagBase = { entityId, operation: 'heal' as const, trigger };\n if (!Number.isInteger(batchSize) || batchSize < 1) {\n throw new Error('Invalid batchSize: must be an integer >= 1');\n }\n\n const bodyTruncationChars = options?.bodyTruncationChars ?? HEAL_MAX_FACT_BODY_CHARS_L3;\n if (!Number.isInteger(bodyTruncationChars) || bodyTruncationChars < 1) {\n throw new Error('Invalid bodyTruncationChars: must be an integer >= 1');\n }\n\n const now = Date.now();\n const recheckCutoff = now - HEAL_RECHECK_MS;\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 // The SQL passes below mutate rows before candidates are even selected, so\n // their ids are folded into the HealResult counters — otherwise a pass that\n // soft-deletes 50 orphans but offers no candidates reports `deleted: 0`.\n const staleDowngradedIds: 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 staleDowngradedIds.push(...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 emitDiagnostic(this.options, { ...diagBase, code: 'hook_failed', detail: { factId, reason: 'on_embedding_persisted' } });\n }\n }\n\n const healCandidates = await this.entryRepo.findHealCandidatesByEntityId(entityId, batchSize, recheckCutoff);\n if (healCandidates.length === 0) {\n // The orphan/stale SQL passes above may still have mutated rows, so the\n // search index sync must happen before returning — it did today, after\n // runBatched no-oped on an empty candidate list.\n await this.searchService.sync(entityId);\n this.searchService.evictCache(entityId);\n const counts = await this.entryRepo.countHealCandidatesByEntityId(entityId, recheckCutoff);\n return {\n scanned: 0,\n downgraded: staleDowngradedIds.length,\n deleted: orphanedIds.length,\n newFactsCreated: 0,\n skipped: [], degraded: [], remaining: counts.eligible, deferred: counts.deferred,\n };\n }\n // Cap applied once at fetch time. The bound is the one remaining\n // unbounded input to the heal prompt (#101's L0 fix). AllTasks is\n // entity-global; we don't re-fetch per level. L1+ levels omit the\n // array via buildHealPrompt's level logic.\n const allTasks = await this.taskRepo.findAllPending([entityId], HEAL_MAX_TASKS);\n const recentEvents = await this.eventRepo.getRecent(entityId, 20);\n\n const healGrounding = this.promptService.groundingFor('heal');\n\n const toPromptShape = (f: WikiFact) => {\n const { embedding: _embedding, embedding_blob: _blob, ...rest } = f as WikiFact & { embedding?: unknown; embedding_blob?: unknown };\n // grounding: spec §6.2 hides trust fields from a grounding writer only;\n // with heal outside grounding.writers the candidate shape is unchanged.\n const shown = healGrounding\n ? (({ lifecycle_status: _l, okf_verified: _v, last_verified_at: _a, last_verified_by: _b, ...r }) => r)(rest)\n : rest;\n return { ...shown, tags: typeof shown.tags === 'string' ? JSON.parse(shown.tags) : shown.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 // runBatched rebuilds prompts while trimming, splitting and escalating, so\n // the corpus is keyed to the exact prompt object each response came from.\n const corpusByPrompt = new WeakMap<BuiltPrompt, string[]>();\n\n // Captured in the doRunHeal scope so the buildPrompt lambda can push\n // L3 truncation records into it. Reconcile after runBatched returns:\n // any record whose id also ended up in outcome.skipped is a\n // contradiction (degraded = healed, skipped = dropped) and is dropped.\n // The post-reconcile log line fires for the survivors only.\n const degraded: DegradedRecord[] = [];\n\n const outcome = await runBatched<WikiFact, HealBatch>({\n items: healCandidates,\n buildPrompt: async (batch, attemptLevel = 0) => {\n const documentAnchors = await this._selectHealAnchors(\n entityId,\n batch,\n // Per-batch anchor cap: `batch.length * HEAL_ANCHORS_PER_CANDIDATE` (capped at\n // HEAL_MAX_ANCHORS) right-sizes the anchor lookup so a 1-fact batch does\n // not overfetch the same 200 keyword hits a 25-fact batch once did.\n // buildHealPrompt applies the matching cap on its side — values must match.\n Math.min(HEAL_MAX_ANCHORS, batch.length * HEAL_ANCHORS_PER_CANDIDATE),\n anchorCache,\n healGrounding !== null,\n );\n const { prompts, degraded: batchDegraded, groundingCorpus } = await this.promptService.buildHealPrompt(\n batch.map(toPromptShape),\n documentAnchors,\n allTasks,\n recentEvents,\n promptOverride,\n attemptLevel,\n bodyTruncationChars,\n );\n // L0 calls (including trim's speculatives) return degraded: [].\n // Only L3 real attempts can push here.\n degraded.push(...batchDegraded);\n if (groundingCorpus !== undefined) corpusByPrompt.set(prompts, groundingCorpus);\n return prompts;\n },\n call: (prompts) => this.options.llmProvider.generateText(prompts),\n parse: (responseText, batch, prompts) => {\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 corpus: corpusByPrompt.get(prompts) ?? null,\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: ${formatSkipError(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 // Position within the producing batch's response, not the merged list, so\n // a diagnostic's itemIndex points into an array the model actually returned.\n const newFactItemIndexes: number[] = [];\n const newFactCorpora: Array<string[] | null> = [];\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 batchResult.newFacts.forEach((raw, itemIndex) => {\n newFacts.push(raw);\n newFactItemIndexes.push(itemIndex);\n newFactCorpora.push(batchResult.corpus);\n });\n }\n\n const safeDowngraded = Array.from(safeDowngradedSet);\n const safeDeleted = Array.from(safeDeletedSet);\n const diagBuffer = new DiagnosticBuffer();\n const validNewFacts: ExtractedFact[] = [];\n const validNewFactItemIndexes: number[] = [];\n const validNewFactCorpora: Array<string[] | null> = [];\n newFacts.forEach((raw, k) => {\n const itemIndex = newFactItemIndexes[k];\n const valid = validateFact(raw);\n if (valid) {\n validNewFacts.push(valid);\n validNewFactItemIndexes.push(itemIndex);\n validNewFactCorpora.push(newFactCorpora[k]);\n } else {\n diagBuffer.push({ ...diagBase, code: 'fact_rejected', detail: { itemIndex, reason: factRejectionReason(raw) } });\n }\n });\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 // Full-breadth, independent of batchSize. Seeding from healCandidates would\n // shrink dedupe to a batchSize window, letting a synthesized fact that\n // duplicates a librarian_inferred fact outside the window pass the Jaccard\n // check — and a convergence loop would then multiply those duplicates.\n //\n // Read inside the transaction, after softDeleteByIds. The query filters\n // deleted_at IS NULL, so rows this pass retires leave the corpus naturally\n // — no explicit safeDeletedSet filter needed. Ordering is load-bearing:\n // the read must follow softDeleteByIds, or a delete-plus-restate (heal's\n // normal output shape) would match the replacement against the row it\n // replaces, drop the replacement, and leave the fact gone entirely (#68).\n // Reading inside the transaction also closes the race with concurrent\n // librarian passes (#69): withSerializedTransactions ensures a librarian\n // transaction either commits entirely before this transaction begins or\n // entirely after it ends, so there is no interleaving point at which a\n // librarian insert could land unseen.\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 const healFactsForDedupe: Array<{ id: string; title: string }> =\n await this.entryRepo.findInferredTitlesByEntityId(entityId, tx);\n\n for (const [k, fact] of validNewFacts.entries()) {\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 // The query already restricts to librarian_inferred, so the\n // projected { id, title } rows carry everything the check needs.\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) {\n diagBuffer.push({ ...diagBase, code: 'fact_deduplicated', detail: { itemIndex: validNewFactItemIndexes[k], reason: 'fuzzy_title' } });\n continue;\n }\n\n const id = generateId('fact_');\n // A missing corpus is treated as empty, so every quote fails: fail closed.\n const grounding = healGrounding\n ? groundingOutcome(checkGrounding(fact.evidence, validNewFactCorpora[k] ?? [], healGrounding), now)\n : null;\n if (grounding?.diagnostic) {\n diagBuffer.push({ ...diagBase, code: grounding.diagnostic.code, detail: { factId: id, itemIndex: validNewFactItemIndexes[k], reason: grounding.diagnostic.reason } });\n }\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 ...grounding?.trust,\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({ id, title: fact.title });\n }\n\n // Every candidate offered this pass is stamped, whether it landed in a\n // successful batch or in outcome.skipped: otherwise skipped facts stay at\n // the head of the updated_at ASC queue and starve everything behind them.\n // Facts heal just created are stamped too — without this each synthesized\n // fact is immediately an eligible candidate again and a host\n // `while (remaining > 0)` loop feeds on heal's own output.\n //\n // Transient-error ids (`reason: 'call_error'` from the runBatched helper,\n // added in Revision 1 of the ladder spec) are excluded from the stamp:\n // a momentary provider hiccup would otherwise lock a fact out of heals\n // for the full HEAL_RECHECK_MS window. The fact is reattempted as soon\n // as the host's scheduler runs heal again — `markHealChecked` skips\n // soft-deleted rows above, which is also correct (a deleted row is not\n // a candidate under any future pass).\n const callErrorIds = new Set(\n outcome.skipped.filter((s) => s.reason === 'call_error').map((s) => s.item.id),\n );\n await this.entryRepo.markHealChecked(\n [\n ...healCandidates.map((f) => f.id).filter((id) => !callErrorIds.has(id)),\n ...insertedFacts.map((f) => f.id),\n ],\n entityId,\n now,\n tx,\n );\n });\n\n for (const { item, reason } of outcome.skipped) {\n diagBuffer.push({ ...diagBase, code: 'heal_skipped', detail: { factId: item.id, reason } });\n }\n diagBuffer.flush(this.options);\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 emitDiagnostic(this.options, { ...diagBase, code: 'hook_failed', detail: { factId, reason: 'on_embedding_persisted' } });\n }\n }\n\n for (const fact of insertedFacts) {\n await this.embeddingService.embedFact(fact, { operation: 'heal', trigger });\n }\n\n this.searchService.evictCache(entityId);\n\n // Reconcile: a degraded record for an id in outcome.skipped is a\n // contradiction (degraded = healed, skipped = dropped). Drop the\n // contradiction. The reconciliation makes the two arrays mutually\n // exclusive on id, which is the contract HealResult promises.\n const skippedIds = new Set(outcome.skipped.map(({ item }) => item.id));\n const healedDegraded = degraded.filter((d) => !skippedIds.has(d.id));\n\n // Post-reconcile log. A naive implementation that logs inside the\n // buildPrompt lambda would emit this warning for facts whose L3\n // attempt still failed; that warning is a property of the log\n // stream, not just the data shape, and the test suite locks it.\n for (const d of healedDegraded) {\n console.warn(\n `[WikiMemory] heal healed under degraded context ${entityId}/${d.id}: ` +\n `body truncated from ${d.originalBodyChars} to ${d.truncatedBodyChars} chars`,\n );\n }\n\n // Skipped candidates were sent to the provider too — they just came back\n // unusable, possibly after being split down to a batch of one. Counting\n // only successful batches would under-report provider exposure, which is\n // the number this field exists to report.\n let scanned = outcome.skipped.length;\n for (const batchResult of outcome.results) scanned += batchResult.batch.length;\n\n // Union rather than sum: the orphan pass runs before candidate selection so\n // its ids cannot also be model-deleted, but a fact the stale pass downgraded\n // can be downgraded again by the model in the same pass.\n const allDowngraded = new Set([...staleDowngradedIds, ...safeDowngraded]);\n const allDeleted = new Set([...orphanedIds, ...uniqueDeletedFactIds]);\n\n const counts = await this.entryRepo.countHealCandidatesByEntityId(entityId, recheckCutoff);\n return {\n scanned,\n downgraded: allDowngraded.size,\n deleted: allDeleted.size,\n newFactsCreated: insertedFacts.length,\n skipped: outcome.skipped.map(({ item, reason }) => ({ id: item.id, reason })),\n degraded: healedDegraded,\n remaining: counts.eligible,\n deferred: counts.deferred,\n };\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; classifier?: 'auto' | 'llm' },\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, manifest: effectiveManifest } = 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 // Spec §7.3 / REQ-COMPAT-01.5: capability alone never switches paths.\n const classifierMode = options?.classifier ?? this.options.config?.ontology?.backfillClassifier ?? 'llm';\n const classify = this.options.llmProvider.classify;\n if (classifierMode === 'auto' && typeof classify === 'function') {\n const slugs = effectiveManifest.node_types.map((n) => n.type);\n if (slugs.length > 0 && slugs.length <= 255) {\n return this._runClassifierBackfill(entityId, candidates, effectiveManifest, now, recheckCutoff);\n }\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: ${formatSkipError(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 — except\n // transient-error ids (`reason: 'call_error'` from the runBatched helper,\n // added in Revision 1 of the ladder spec), which are excluded so a\n // momentary provider hiccup doesn't lock them out of backfill for a full\n // ONTOLOGY_BACKFILL_RECHECK_MS window. Without the stamp on the non-\n // transient cases, those would stay at the head of the updated_at ASC\n // queue and every later pass would re-attempt them first, starving\n // everything behind them.\n if (outcome.skipped.length > 0) {\n const callErrorIds = new Set(\n outcome.skipped.filter((s) => s.reason === 'call_error').map((s) => s.item.id),\n );\n await this.entryRepo.markOntologyChecked(\n outcome.skipped\n .filter(({ item }) => !callErrorIds.has(item.id))\n .map(({ item }) => item.id),\n entityId,\n now,\n this.db,\n );\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 * Classifier-mode backfill (spec §7.3): one `choice` question per untyped\n * fact over the effective manifest's node-type slugs. Accepted answers go\n * through `_applyOntologyBackfillBatch` exactly like LLM classifications.\n * No edges are proposed.\n */\n private async _runClassifierBackfill(\n entityId: string,\n candidates: WikiFact[],\n manifest: OntologyManifest,\n now: number,\n recheckCutoff: number,\n ): Promise<OntologyBackfillResult> {\n // Call through the provider so a class-based provider keeps its `this`.\n const provider = this.options.llmProvider;\n const rawMin = this.options.config?.ontology?.classifyMinConfidence;\n const minConfidence = typeof rawMin === 'number' && Number.isFinite(rawMin) && rawMin >= 0 && rawMin <= 1 ? rawMin : 0.5;\n const rawConcurrency = this.options.config?.chunkConcurrency ?? 1;\n const concurrency = Number.isFinite(rawConcurrency) && rawConcurrency >= 1 ? Math.floor(rawConcurrency) : 1;\n\n // Manifest descriptions are host-authored ontology vocabulary, not fact content.\n const question: ClassifierQuestion = {\n kind: 'choice',\n options: manifest.node_types.map((n) => n.type),\n instructions:\n 'Choose the ontology node type that best describes this fact.\\n' +\n manifest.node_types.map((n) => `- ${n.type}: ${n.description}`).join('\\n'),\n };\n\n type Outcome =\n | { fact: WikiFact; kind: 'accepted'; okfType: string }\n | { fact: WikiFact; kind: 'low_confidence' }\n | { fact: WikiFact; kind: 'invalid'; reason: ClassifierRejection }\n | { fact: WikiFact; kind: 'threw' };\n\n const outcomes = await withConcurrency<Outcome>(\n candidates.map((fact) => async (): Promise<Outcome> => {\n let response: unknown;\n try {\n response = await provider.classify!({ state: classifierStateForFact(fact), questions: { okf_type: question } });\n } catch {\n return { fact, kind: 'threw' };\n }\n const checked = validateClassifierAnswer(response, 'okf_type', question);\n if (!checked.ok) return { fact, kind: 'invalid', reason: checked.reason };\n if (checked.answer.kind !== 'choice') return { fact, kind: 'invalid', reason: 'kind_mismatch' };\n if (checked.answer.confidence < minConfidence) return { fact, kind: 'low_confidence' };\n return { fact, kind: 'accepted', okfType: checked.answer.choice };\n }),\n concurrency,\n );\n\n // Thrown calls are transient (like `call_error`): no cooldown stamp.\n const attempted = outcomes.filter((o) => o.kind !== 'threw').map((o) => o.fact);\n const skipped = outcomes.length - attempted.length;\n const classifications = outcomes\n .filter((o): o is Extract<Outcome, { kind: 'accepted' }> => o.kind === 'accepted')\n .map((o) => ({ id: o.fact.id, okf_type: o.okfType }));\n const invalidCount = outcomes.filter((o) => o.kind === 'invalid').length;\n\n let typed = 0;\n let failedValidation = 0;\n let edgesAdded = 0;\n let aborted = false;\n if (attempted.length > 0) {\n const applied = await this._applyOntologyBackfillBatch(\n entityId,\n { batch: attempted, classifications, ontologyUpdates: undefined },\n now,\n );\n aborted = applied.abortedOntologyOff;\n if (!aborted) {\n typed = applied.typed;\n failedValidation = invalidCount + applied.failedValidation;\n edgesAdded = applied.edgesAdded;\n }\n }\n\n const diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'ontologyBackfill' as const, trigger: 'call' as const };\n for (const o of outcomes) {\n if (o.kind === 'low_confidence') {\n diagBuffer.push({ ...diagBase, code: 'classification_low_confidence', detail: { factId: o.fact.id, reason: 'below_threshold' } });\n } else if (o.kind === 'invalid') {\n diagBuffer.push({ ...diagBase, code: 'classification_invalid', detail: { factId: o.fact.id, reason: o.reason } });\n } else if (o.kind === 'threw') {\n diagBuffer.push({ ...diagBase, code: 'classification_invalid', detail: { factId: o.fact.id, reason: 'classify_threw' } });\n }\n }\n // After the apply transaction committed (spec §4.2.4). Classifier answers\n // are reported even on an ontology-off abort: they describe the provider,\n // not a write.\n diagBuffer.flush(this.options);\n\n const counts = await this.entryRepo.countUntypedByEntityId(entityId, recheckCutoff);\n if (aborted) {\n // Mirrors the LLM path: nothing from the aborted batch was written; the host loop terminates.\n return { scanned: 0, typed: 0, failedValidation: 0, edgesAdded: 0, skipped, remaining: 0, deferred: counts.deferred };\n }\n this.searchService.evictCache(entityId);\n return {\n scanned: candidates.length,\n typed,\n failedValidation,\n edgesAdded,\n skipped,\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 const diagBuffer = new DiagnosticBuffer();\n const diagBase = { entityId, operation: 'ontologyBackfill' as const, trigger: 'call' as const };\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 validationDrops: EdgeDrop[] = [];\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 { strict: false, drops: validationDrops },\n );\n for (const drop of validationDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, { ...diagBase, factId: fact.id }));\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 const resolveDrops: EdgeDrop[] = [];\n const added = await ontologyService.resolveAndPersistEdges(\n entityId, item.sourceId, item.sourceType, item.edges, manifest, titleIndex, tx, now, resolveDrops,\n );\n edgesAdded += added;\n for (const drop of resolveDrops) {\n diagBuffer.push(edgeDropDiagnostic(drop, diagBase));\n }\n }\n\n await this.entryRepo.markOntologyChecked(batch.map(f => f.id), entityId, now, tx);\n });\n\n diagBuffer.flush(this.options);\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 cap: number = HEAL_MAX_ANCHORS,\n cache?: Map<string, HealAnchor[]>,\n withBodies: boolean = false,\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 // Overfetch is sized off the cap we were given, not the global max —\n // a single-candidate query asks for fewer search hits.\n const hits = this.searchService.searchKeyword(\n query,\n [entityId],\n cap * 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 = withBodies\n ? await this.entryRepo.findAnchorRowsByIds(entityId, hitIds, undefined, { withBody: true })\n : 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 >= cap) 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","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, normalizeSourceRef } from '../utils/pure';\nimport { latestVerified } from '@equationalapplications/core-okf';\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 // Normalize source_ref using the same rules as ingestDocument and the\n // startup migration. Persisting the raw value would let a later re-ingest\n // collide on shape mismatch (raw DB ref vs. normalized incoming ref) and\n // would skip soft-deletion on the default-path overwrite.\n // A non-null source_ref that normalizes to null (e.g. all-special-chars\n // or whitespace-only) is rejected to mirror ingestDocument — silently\n // coercing it to NULL would create a legacy row that many APIs\n // intentionally exclude.\n let normalizedSourceRef: string | null = null;\n if (fact.source_ref !== null && fact.source_ref !== undefined) {\n normalizedSourceRef = normalizeSourceRef(fact.source_ref);\n if (normalizedSourceRef === null) {\n throw new Error(\n `importDump: invalid source_ref ${JSON.stringify(fact.source_ref)} ` +\n `for entity \"${entityId}\" fact \"${fact.id}\" ` +\n `(must normalize to a non-empty string; see ingestDocument's sourceRef validation)`,\n );\n }\n }\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: normalizedSourceRef,\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 // OKF v0.2 — forwarded as-is; parseOkfBundle / the caller is responsible for\n // populating these per spec, importDump does not derive or validate them.\n lifecycle_status: fact.lifecycle_status ?? 'stable',\n stale_after: fact.stale_after ?? null,\n generated_by: fact.generated_by ?? null,\n okf_sources: fact.okf_sources ?? [],\n okf_verified: fact.okf_verified ?? [],\n okf_usage_window: fact.okf_usage_window ?? null,\n // last_verified_at/_by are DERIVED mirrors of `okf_verified` per spec\n // §5.3. Recomputing here (instead of trusting the payload field) closes\n // the invariant that a raw importDump cannot carry a\n // last_verified_by that contradicts its own okf_verified list.\n ...(() => {\n const latest = latestVerified(fact.okf_verified ?? [], Date.now());\n return { last_verified_at: latest?.at ?? null, last_verified_by: latest?.by ?? null };\n })(),\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 // OKF v0.2\n lifecycle_status: task.lifecycle_status ?? 'stable',\n stale_after: task.stale_after ?? null,\n generated_by: task.generated_by ?? null,\n okf_sources: task.okf_sources ?? [],\n okf_verified: task.okf_verified ?? [],\n okf_usage_window: task.okf_usage_window ?? null,\n // Derived mirrors — see fact branch above; same invariant.\n ...(() => {\n const latest = latestVerified(task.okf_verified ?? [], Date.now());\n return { last_verified_at: latest?.at ?? null, last_verified_by: latest?.by ?? null };\n })(),\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 }, { operation: 'importDump', trigger: 'call' });\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 this.embeddingService.reportHookFailed(\n { operation: 'importDump', trigger: 'call' },\n entityId,\n fact.id,\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 this.embeddingService.reportHookFailed(\n { operation: 'importDump', trigger: 'call' },\n entityId,\n factId,\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 // Dimension promotion clears embedding failure markers for EVERY\n // entity, but this import holds only entity-scoped locks — so it can\n // erase classifications a concurrent runReembed(otherEntity) just\n // made. Defer instead of widening the lock: the mismatch key is\n // sticky, so a later import or a productive sweep tail (one that\n // embeds > 0 rows — MaintenanceService runs the tail reconciliation\n // only `if (embedded > 0)`) completes the promotion.\n // Spec 2026-09-05-reembed-lock-scope-design.md §3.2.\n if (this.jobManager.isAnyReembedActive()) {\n console.info(\n '[WikiMemory] importDump: embedding-dimension promotion deferred; a reembed sweep is in flight',\n );\n } else {\n await this.embeddingService.reconcileEmbeddingDimension();\n }\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","/**\n * Default clamp on embed input length, in characters (~1,500 tokens).\n * Chosen to fit common embedding windows including nomic-embed-text's 2,048 tokens.\n */\nexport const DEFAULT_MAX_EMBED_CHARS = 6_000;\n\n/**\n * Hard upper bound on embed input length, in characters.\n * An unbounded-input guard from `5e04bad fix(core): security hardening phase 2`.\n * Configuration may lower the effective limit but must never raise it past this.\n */\nexport const EMBED_CHARS_CEILING = 16_000;\n","import type { SQLiteAdapter, WikiOptions, EmbeddingMarkerKind, WikiDiagnosticOperation, WikiDiagnosticTrigger } 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';\nimport { DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING } from '../utils/embedDefaults';\nimport { emitDiagnostic } from '../utils/diagnostics';\n\nexport type { EmbeddingMarkerKind };\n\nexport type EmbedFailureKind =\n | EmbeddingMarkerKind\n | 'no_provider'\n | 'storage_error';\n\nexport type EmbedFactResult =\n | { ok: true; dimension: number }\n | { ok: false; kind: EmbedFailureKind };\n\nexport interface EmbedDiagnosticContext {\n operation: WikiDiagnosticOperation;\n trigger: WikiDiagnosticTrigger;\n}\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 /**\n * Promotes embedding_dimension_mismatch to canonical embedding_dimension when\n * safe, and clears embedding failure markers as part of the same event.\n *\n * Marker reset (spec §2.3): a promoted dimension means a different model is\n * producing the vectors, so prior failures no longer predict future ones.\n * `float32_overflow` is cleared too — it is terminal only because retrying is\n * the same arithmetic on the same vector, and after a model change it is not.\n *\n * All three writes commit atomically; see the transaction note inline.\n *\n * Revived rows are NOT embedded here. They become eligible and are picked up\n * by the NEXT sweep, because runReembed calls this after its candidates were\n * already classified; same-sweep revival would be re-entrant.\n *\n * Caller contract (spec 2026-09-05 §3.2): callers must not invoke this while\n * a reembed sweep is in flight unless they hold that sweep's lock, because\n * the marker clear spans every entity. `runReembed`'s tail call is exempt —\n * by the tail, the sweep's classification phase is complete, so the clear\n * cannot resurrect a row THIS sweep classified; any overlap with a\n * concurrent import's entity-scoped, blob-guarded writes (an importDump of a\n * different entity can run during a per-entity sweep) is bounded redundant\n * work. External callers\n * gate on `JobManager.isAnyReembedActive()` and defer. This service\n * deliberately holds no `JobManager` reference: gating here instead of at\n * the call site would make `runReembed`'s own tail call see its own lock and\n * defer forever.\n */\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 // One transaction for the whole promotion (spec §2.3): the three writes\n // are a single logical event. Committed separately, a failure after\n // clearDimensionMismatch would leave markers set with no mismatch key\n // left to re-trigger promotion, stranding those rows until `force: true`.\n // Safe to open here — both callers (runReembed, importDump's dimension\n // reconciliation) invoke this outside their own transactions, and the\n // adapter does not support nesting.\n await this.db.withTransactionAsync(async (tx) => {\n await this.metadataRepo.setMeta('embedding_dimension', mismatchValue, tx);\n await this.metadataRepo.clearDimensionMismatch(tx);\n await this.entryRepo.clearEmbeddingFailureMarkers(tx);\n });\n }\n }\n\n async tryEmbedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }, ctx?: EmbedDiagnosticContext): Promise<EmbedFactResult> {\n // Callability, not truthiness: a truthy non-function would pass a `!embedFn`\n // guard, throw TypeError at the call, and be marked `provider_error` —\n // burning an attempt per sweep until a host config error permanently\n // excluded the fact. `no_provider` never marks. (spec §2.4)\n if (typeof this.options.llmProvider.embed !== 'function') return { ok: false, kind: 'no_provider' };\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 configuredMaxEmbedChars = this.options.config?.maxEmbedChars;\n const maxEmbedChars = Number.isFinite(configuredMaxEmbedChars)\n ? Math.min(Math.max(0, Math.trunc(configuredMaxEmbedChars as number)), EMBED_CHARS_CEILING)\n : DEFAULT_MAX_EMBED_CHARS;\n const text = clip(`${fact.title} ${fact.body} ${tagsStr}`.trim(), maxEmbedChars);\n let float32Vector: Float32Array;\n try {\n const vector = await this.options.llmProvider.embed(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 this.reportEmbed(ctx, fact, 'embedding_failed', 'invalid_vector');\n await this.markFailure(fact.id, 'invalid_vector');\n return { ok: false, kind: 'invalid_vector' };\n }\n 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 this.reportEmbed(ctx, fact, 'embedding_failed', 'float32_overflow');\n await this.markFailure(fact.id, 'float32_overflow');\n return { ok: false, kind: 'float32_overflow' };\n }\n } catch (err) {\n console.warn(`[WikiMemory] embedFact failed for ${fact.id}:`, err);\n this.reportEmbed(ctx, fact, 'embedding_failed', 'embed_threw');\n await this.markFailure(fact.id, 'provider_error');\n return { ok: false, kind: 'provider_error' };\n }\n\n // Storage is a separate failure domain: a DB error here is NOT an\n // embedding failure and must not be marked as one (spec §3.2, D3).\n try {\n await this.storeEmbeddingDimension(float32Vector.length);\n const blob = new Uint8Array(float32Vector.buffer);\n await this.entryRepo.updateEmbeddingBlob(fact.id, blob);\n } catch (err) {\n console.warn(`[WikiMemory] embedFact: persisting embedding failed for ${fact.id}:`, err);\n this.reportEmbed(ctx, fact, 'embedding_failed', 'persist_failed');\n return { ok: false, kind: 'storage_error' };\n }\n\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 this.reportEmbed(ctx, fact, 'hook_failed', 'on_embedding_persisted');\n }\n return { ok: true, dimension: float32Vector.length };\n }\n\n private reportEmbed(\n ctx: EmbedDiagnosticContext | undefined,\n fact: { id: string; entity_id: string },\n code: 'embedding_failed' | 'hook_failed',\n reason: 'invalid_vector' | 'float32_overflow' | 'embed_threw' | 'persist_failed' | 'on_embedding_persisted',\n ): void {\n if (!ctx) return;\n emitDiagnostic(this.options, {\n code, operation: ctx.operation, trigger: ctx.trigger, entityId: fact.entity_id,\n detail: { factId: fact.id, reason },\n });\n }\n\n /** For callers that invoke `notifyEmbeddingPersisted` directly and catch its failure. */\n reportHookFailed(ctx: EmbedDiagnosticContext, entityId: string, factId: string): void {\n this.reportEmbed(ctx, { id: factId, entity_id: entityId }, 'hook_failed', 'on_embedding_persisted');\n }\n\n /** Marker writes must never fail the caller. Only marker-eligible kinds reach here. */\n private async markFailure(id: string, kind: EmbeddingMarkerKind): Promise<void> {\n try {\n await this.entryRepo.markEmbeddingFailure(id, kind, Date.now());\n } catch (err) {\n console.warn(`[WikiMemory] failed to record embedding failure for ${id}:`, err);\n }\n }\n\n /**\n * Back-compatible boolean form. Kept because callers such as\n * ImportExportService branch on `if (!embedded)`; a discriminated result\n * object is always truthy and would silently disable that branch.\n */\n async embedFact(fact: {\n id: string;\n entity_id: string;\n title: string;\n body: string;\n tags: string | string[];\n }, ctx?: EmbedDiagnosticContext): Promise<boolean> {\n const result = await this.tryEmbedFact(fact, ctx);\n return result.ok;\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 { WikiInvalidReadOptions } from './types';\n\nexport 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\n/**\n * Validates and sanitizes `ReadOptions.tierFloors`.\n *\n * Throws `WikiInvalidReadOptions` for contradictions detectable without touching\n * data. Sanitizes value-shape noise. Never throws for data-dependent shortfalls —\n * an entity with fewer facts than its floor simply contributes what it has.\n */\nexport function validateTierFloors(\n entityIds: readonly string[],\n tierFloors: Record<string, number> | undefined,\n sanitizedTierWeights: Record<string, number> | undefined,\n includeZeroWeightEntities: boolean | undefined,\n maxResults: number,\n): Record<string, number> | undefined {\n if (tierFloors === undefined) return undefined;\n\n const known = new Set(entityIds);\n for (const key of Object.keys(tierFloors)) {\n // Per §4.2: non-finite values are sanitized away as absent. Filtering them\n // before key validation matches the documented rule and lets a typo like\n // { typo: NaN } fall through cleanly instead of tripping the \"key is not\n // one of the entity IDs\" check on a value the caller did not actually set.\n const raw = tierFloors[key];\n if (raw === undefined || !Number.isFinite(raw)) continue;\n if (!known.has(key)) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `\"${key}\" is not one of the entity IDs passed to read(); ` +\n `a floor on an unrequested entity can never be satisfied`,\n );\n }\n }\n\n const sanitized = Object.create(null) as Record<string, number>;\n let total = 0;\n for (const entityId of entityIds) {\n const raw = tierFloors[entityId];\n if (raw === undefined || !Number.isFinite(raw)) continue;\n const floor = Math.max(0, Math.trunc(raw));\n\n if (floor > 0 && includeZeroWeightEntities !== true && sanitizedTierWeights?.[entityId] === 0) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `\"${entityId}\" has tierWeight 0 and includeZeroWeightEntities is not set, ` +\n `so it is excluded from retrieval and its floor of ${floor} can never be met`,\n );\n }\n\n sanitized[entityId] = floor;\n total += floor;\n }\n\n if (total > maxResults) {\n throw new WikiInvalidReadOptions(\n 'tierFloors',\n `floors sum to ${total}, which exceeds maxResults (${maxResults})`,\n );\n }\n\n return sanitized;\n}\n\n/**\n * Selects up to `maxResults` rows, reserving each entity's top-N first.\n *\n * PRECONDITION: `sortedRows` must already be in final rank order (the caller's\n * tie-break sort). Selection order is restored from each row's position in the\n * input, so unsorted input yields silently wrong output rather than an error.\n *\n * Floors change which rows are selected, never the order they are returned in.\n */\nexport function selectWithFloors<T extends { id: string; entity_id: string }>(\n sortedRows: readonly T[],\n floors: Record<string, number> | undefined,\n maxResults: number,\n): T[] {\n if (maxResults <= 0) return [];\n if (floors === undefined || Object.keys(floors).length === 0) {\n return sortedRows.slice(0, maxResults);\n }\n\n const selected = new Set<number>();\n const taken = Object.create(null) as Record<string, number>;\n\n // Pass 1 — reserve each entity's top-N. Bounded by sum(floors) <= maxResults,\n // which validateTierFloors guarantees, so this cannot overflow the window.\n for (let i = 0; i < sortedRows.length; i++) {\n const entityId = sortedRows[i].entity_id;\n const floor = floors[entityId] ?? 0;\n if (floor <= 0) continue;\n const count = taken[entityId] ?? 0;\n if (count >= floor) continue;\n taken[entityId] = count + 1;\n selected.add(i);\n }\n\n // Pass 2 — fill the remaining slots in rank order.\n for (let i = 0; i < sortedRows.length && selected.size < maxResults; i++) {\n if (!selected.has(i)) selected.add(i);\n }\n\n // Restore global rank order: input was sorted, so index order is rank order.\n return Array.from(selected)\n .sort((a, b) => a - b)\n .map(i => sortedRows[i]);\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, selectWithFloors, shouldExposeReadMetadata, validateTierFloors } from '../readOptions';\nimport { sanitizeRankerError, safeErrorToString } from '../utils/pure';\n\ntype ReadCandidateRowMetadata = EntryRowMetadata;\ntype ReadCandidateRowWithEmbeddings = EntryRowWithEmbeddings;\n\nconst EMPTY_ID_SET: ReadonlySet<string> = new Set<string>();\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 excludeDrafts = (options?.excludeDrafts ?? config?.excludeDrafts ?? false) === true;\n const trimmedQuery = query.trim();\n // §3.3 — tierFloors is ignored on the empty-query recency path. Skipping\n // validation here keeps the public contract honest: an empty-query call\n // with floors that would otherwise be invalid must not throw, since the\n // floors are dropped before the cut anyway.\n const sanitizedTierFloors = trimmedQuery && exposeMetadata\n ? validateTierFloors(\n entityIds,\n options?.tierFloors,\n sanitizedTierWeights,\n options?.includeZeroWeightEntities,\n maxResults,\n )\n : undefined;\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\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 // Spec §5.1: one SQLite read per call; status is never taken from an index.\n const draftIds: ReadonlySet<string> = excludeDrafts && scoredEntityIds.length > 0\n ? await this.entryRepo.findDraftIdsByEntityIds(scoredEntityIds)\n : EMPTY_ID_SET;\n const draftPad = draftIds.size;\n const padLimit = (n: number): number => (n >= Number.MAX_SAFE_INTEGER ? n : n + draftPad);\n\n // Fast-path: all entities zero-weight — skip embed(), 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 && typeof this.options.llmProvider.embed === 'function') {\n let rankerShouldRethrow = false;\n let pendingRankerFallbackError: Error | undefined;\n try {\n const queryVec = await this.options.llmProvider.embed(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\n .searchKeyword(trimmedQuery, scoredEntityIds, Number.MAX_SAFE_INTEGER)\n .filter((r) => !draftIds.has(r.id));\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 = this._withoutDrafts(await this.entryRepo.findMetadataByEntityIds(scoredEntityIds), draftIds);\n } else {\n candidateRows = this._withoutDrafts(await this.entryRepo.findWithEmbeddingsByEntityIds(scoredEntityIds), draftIds);\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: padLimit(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 // Reserve per-entity floor shortfalls from omitted rows BEFORE\n // the global backfill pass. Without this reservation, the global\n // backfill budget caps at `maxResults - scored.length` (pure\n // semantic) or `maxResults` selected by kwScore (hybrid), and\n // either cap can silently drop every row from a floored entity\n // when the ranker returned no scores for it. selectWithFloors\n // cannot reserve a starved entity's floor from a `scored`\n // array that does not contain enough of its rows.\n type CandidateRow = typeof candidateRows[number];\n const floorShortfallByEntity: Record<string, number> = Object.create(null);\n let totalFloorShortfall = 0;\n if (sanitizedTierFloors) {\n const scoredCounts = new Map<string, number>();\n for (const s of scored) {\n scoredCounts.set(s.entity_id, (scoredCounts.get(s.entity_id) ?? 0) + 1);\n }\n for (const [entityId, floor] of Object.entries(sanitizedTierFloors)) {\n if (floor <= 0) continue;\n const currentCount = scoredCounts.get(entityId) ?? 0;\n const shortfall = Math.max(0, floor - currentCount);\n if (shortfall > 0) {\n floorShortfallByEntity[entityId] = shortfall;\n totalFloorShortfall += shortfall;\n }\n }\n }\n\n const reservedIds = new Set<string>();\n const reserved: Array<{ row: CandidateRow; kwScore: number }> = [];\n if (totalFloorShortfall > 0) {\n for (const [entityId, shortfall] of Object.entries(floorShortfallByEntity)) {\n const entityOmitted: Array<{ row: CandidateRow; kwScore: number }> = [];\n for (const row of candidateRows) {\n if (scoredIds.has(row.id) || reservedIds.has(row.id)) continue;\n if (row.entity_id !== entityId) continue;\n const kwScore = miniSearchScores?.get(row.id) ?? 0;\n entityOmitted.push({ row, kwScore });\n }\n // Sort within the floored entity by kwScore desc with the\n // shared tie-break. Within a single entity the kwScore\n // pool is small, so a full sort is fine here.\n entityOmitted.sort((a, b) => this._compareScoredRows(\n { id: a.row.id, score: a.kwScore, updated_at: a.row.updated_at, access_count: a.row.access_count },\n { id: b.row.id, score: b.kwScore, updated_at: b.row.updated_at, access_count: b.row.access_count },\n ));\n for (let i = 0; i < Math.min(shortfall, entityOmitted.length); i++) {\n reserved.push(entityOmitted[i]);\n reservedIds.add(entityOmitted[i].row.id);\n }\n }\n }\n\n const isHybrid = weight !== undefined && weight < 1;\n\n if (reserved.length > 0) {\n if (isHybrid) {\n for (const { row, kwScore } of reserved) {\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 for (const { row } of reserved) {\n scored.push({\n id: row.id,\n entity_id: row.entity_id,\n score: -2,\n updated_at: row.updated_at,\n access_count: row.access_count,\n });\n }\n }\n }\n\n // Compute the backfill budget AFTER the reserved rows have been\n // pushed into `scored`, so pure semantic fills only the slots the\n // reservation left over rather than over-materializing by\n // `reserved.length`. Hybrid keeps a global top-K of `maxResults`\n // selected by keyword score, unchanged.\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 const topK: Array<{ row: CandidateRow; kwScore: number }> = [];\n\n for (const row of candidateRows) {\n if (scoredIds.has(row.id) || reservedIds.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) || reservedIds.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 // `rankerErr instanceof Error` invokes the getPrototypeOf\n // trap on rankerErr. A hostile VectorRanker plugin could\n // return one whose trap rejects — treat as non-Error and\n // wrap in a synthetic Error so the fallback callback still\n // receives an Error instance.\n let isErrorLike = false;\n try {\n isErrorLike = rankerErr instanceof Error;\n } catch {\n // hostile Proxy — fall through\n }\n // `String(rankerErr)` invokes the `toString` /\n // `Symbol.toPrimitive` trap on rankerErr — a hostile Proxy\n // whose trap rejects would throw out of this catch and tear\n // down the retrieval. Delegate to the hardened\n // `safeErrorToString` helper (converges on the static\n // `[unstringifiable error]` marker on throw) to honor the\n // non-throwing contract this guard exists to provide.\n const rankerError = isErrorLike ? (rankerErr as Error) : new Error(safeErrorToString(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. When\n // preFilterLimit was active, candidateRows was already\n // narrowed to the pre-filtered IDs (§3.5); restrict this\n // keyword call to that same set so a floor cannot resurrect\n // a fact excluded by preFilterLimit.\n //\n // Active floors force full materialization here too, mirroring\n // the JS-cosine path's `jsCosineNeedsTierSort` widening and\n // the ordinary keyword fallback's `hasActiveFloors` widening:\n // selectWithFloors can only reserve a starved entity's rows\n // if they survive this keyword call's oversampling limit, and\n // a pre-truncated top-K is exactly the starved window the\n // floor exists to correct.\n const hasActiveFloorsKeywordFallback = sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0);\n const keywordOversampledLimit = hasActiveFloorsKeywordFallback\n ? Number.MAX_SAFE_INTEGER\n : padLimit(Math.max(maxResults * 2, maxResults + 50));\n const preFilteredIds = effectivePreFilterLimit !== undefined\n ? new Set((candidateRows as ReadCandidateRowMetadata[]).map(r => r.id))\n : undefined;\n const keywordResults = this.searchService.searchKeyword(trimmedQuery, scoredEntityIds, keywordOversampledLimit);\n const topResults = preFilteredIds === undefined\n ? keywordResults\n : keywordResults.filter(r => preFilteredIds.has(r.id));\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 // Active floors force materialization too: selectWithFloors can only reserve a\n // starved entity's rows if they survive the ranker's own limit, and a pre-truncated\n // top-K is exactly the starved window the floor exists to correct.\n const jsCosineNeedsTierSort = (sanitizedTierWeights !== undefined &&\n Object.values(sanitizedTierWeights).some(w => w !== 1)) ||\n (sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0));\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 (draftPad > 0) scored = scored.filter((s) => !draftIds.has(s.id));\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 = selectWithFloors(scored, sanitizedTierFloors, 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 // `err instanceof Error` invokes the getPrototypeOf trap on err.\n // A hostile Proxy (e.g. from a VectorRanker plugin or a wrapped\n // inner-call result) whose trap rejects must not throw out of\n // this catch — it would tear down the entire retrieval operation.\n let isErrorLike = false;\n try {\n isErrorLike = err instanceof Error;\n } catch {\n // hostile Proxy — fall through\n }\n // Narrowed view: only valid when `isErrorLike` is true (guaranteed\n // by the try/catch above). Cast captures that runtime invariant\n // for the typechecker; the runtime is already proven correct.\n // `String(err)` invokes the `toString` / `Symbol.toPrimitive` trap\n // on err — delegate to the hardened `safeErrorToString` helper\n // so a hostile Proxy whose trap rejects cannot escape this catch.\n const error = isErrorLike ? (err as Error) : new Error(safeErrorToString(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 try {\n (error as any).cause = pendingRankerFallbackError;\n } catch {\n // Hostile or frozen error object — the assignment threw, so the\n // ranker diagnostic would otherwise be silently dropped. Surface\n // it as its own fallback notification instead of losing it.\n this.options.onRetrievalFallback?.(pendingRankerFallbackError);\n }\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 // Active floors force full materialization: selectWithFloors can only\n // reserve a starved entity's rows if they survive the keyword\n // oversampling limit, and a pre-truncated top-K is exactly the starved\n // window the floor exists to correct. Mirrors the JS-cosine path's\n // `jsCosineNeedsTierSort` widening.\n const hasActiveFloors = sanitizedTierFloors !== undefined &&\n Object.values(sanitizedTierFloors).some(f => f > 0);\n const fallbackOversampledLimit = hasActiveFloors\n ? Number.MAX_SAFE_INTEGER\n : padLimit(Math.max(maxResults * 2, maxResults + 50));\n const results = this.searchService\n .searchKeyword(trimmedQuery, scoredEntityIds, fallbackOversampledLimit)\n .filter((r) => !draftIds.has(r.id as string));\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 = selectWithFloors(candidates, sanitizedTierFloors, 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 // Pass `excludeDrafts` opts only when true; the default path keeps its\n // 2-arg call signature for callers that prefer the strict form.\n facts = excludeDrafts\n ? await this.entryRepo.findRecentByEntityIds(entityIds, maxResults, undefined, { excludeDrafts: true })\n : 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 (sanitizedTierFloors && Object.keys(sanitizedTierFloors).length > 0) bundle.metadata.tierFloors = sanitizedTierFloors;\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 private _withoutDrafts<T extends { id: string }>(rows: T[], draftIds: ReadonlySet<string>): T[] {\n return draftIds.size === 0 ? rows : rows.filter((row) => !draftIds.has(row.id));\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","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';\nimport { emitDiagnostic } from '../utils/diagnostics';\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 let eventCount = 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 eventCount = count;\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 const stage: { job: 'librarian' | 'heal' } = { job: 'librarian' };\n this.runLibrarianThenMaybeHeal(entityId, librarianCount, prevMemoryCheckpoint, stage)\n .catch((err: unknown) => {\n console.error(err);\n this.reportBackgroundFailure(entityId, stage.job);\n })\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 } else if (!this.jobManager.isBlocked('librarian', entityId)) {\n // Auto-heal is evaluated on every write, not only on writes that also\n // trigger a librarian pass. doRunHeal is bounded to HEAL_BATCH_SIZE\n // candidates (#67) and a non-converged pass deliberately holds its\n // checkpoint back, so the gap stays above autoHealThreshold; gating the\n // retry on a librarian pass would stall a partial sweep until the next\n // librarian threshold crossing (another autoLibrarianThreshold events),\n // or forever if no further librarian pass runs.\n //\n // heal and librarian can overlap (deliberate mutex split in\n // JobManager.acquireLock). This check only reduces redundant passes — a\n // librarian pass already calls maybeRunHeal when it finishes, so losing\n // the race costs a duplicate pass, not correctness. Correctness rests on\n // heal's dedupe read being inside its transaction (#69).\n // tryAcquireAutoHealLock inside maybeRunHeal prevents a burst of writes\n // from stacking passes.\n this.maybeRunHeal(entityId, eventCount).catch((err: unknown) => {\n console.error(err);\n this.reportBackgroundFailure(entityId, 'heal');\n });\n }\n }\n\n private async runLibrarianThenMaybeHeal(entityId: string, currentEventCount: number, prevCheckpoint: number, stage: { job: 'librarian' | 'heal' }): Promise<void> {\n try {\n await this.maintenanceService.doRunLibrarian(entityId, undefined, 'auto');\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 stage.job = 'heal';\n await this.maybeRunHeal(entityId, currentEventCount);\n }\n\n /**\n * Run one bounded auto-heal pass if the heal checkpoint has fallen\n * `autoHealThreshold` events behind. Called after every write (see\n * {@link write}) so a partial pass retries on the next write.\n */\n private async maybeRunHeal(entityId: string, currentEventCount: number): Promise<void> {\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 const result = await this.maintenanceService.doRunHeal(entityId, { trigger: 'auto' });\n // Advance only when the pass converged. doRunHeal is bounded to\n // HEAL_BATCH_SIZE candidates (#67); advancing unconditionally would cap\n // auto-heal at one batch per autoHealThreshold events and leave most of\n // a large corpus never auto-healed. Held back, the checkpoint gap stays\n // above the threshold, so the next write runs another bounded pass —\n // cost per write stays bounded while the corpus still converges.\n //\n // Sits inside the try, after the call: on a throw the checkpoint is not\n // advanced, exactly as before this change.\n if (result.remaining === 0) {\n await this.metadataRepo.updateCheckpoint(entityId, { heal: currentEventCount }, this.db);\n }\n } finally {\n this.jobManager.releaseLock('heal', entityId);\n }\n }\n }\n\n private reportBackgroundFailure(entityId: string, job: 'librarian' | 'heal'): void {\n emitDiagnostic(this.options, {\n code: 'background_job_failed', operation: job, trigger: 'auto', entityId,\n detail: { reason: 'unhandled_rejection' },\n });\n }\n}\n","import type { OntologyMode } from '../types';\n\nconst FACT_ONTOLOGY_FIELDS = `\nEach fact may optionally include:\n- \"okf_type\": string — must be one of the node_types in the manifest\n- \"edges\": [{ \"edge_type\": string, \"target_title\": string }] — target_title must match another fact's title in this response or existing memory\n- An edge_type may appear in the manifest multiple times with different source_type/target_type; use the row whose types match your fact and target.`;\n\nconst EMERGENT_EXTRA = `\nYou may also return \"ontology_updates\" to propose new types:\n\"ontology_updates\": {\n \"node_types\": [{ \"type\": \"slug\", \"description\": \"...\", \"parent_type\": \"optional existing slug\" }],\n \"edge_types\": [{ \"type\": \"slug\", \"source_type\": \"...\", \"target_type\": \"...\", \"description\": \"...\" }]\n}\nOnly propose types not already in the manifest. Do not redefine existing types.`;\n\nexport function buildOntologyPromptAppendix(\n mode: OntologyMode,\n manifestJson: string,\n): { ontologyManifest: string; ontologyModeInstructions: string } {\n const strictRules = mode === 'strict'\n ? 'STRICT MODE: Use ONLY types defined in the manifest. If a fact does not fit any node_type, omit okf_type and edges entirely.'\n : 'EMERGENT MODE: Prefer manifest types. You may propose new types via ontology_updates when necessary.';\n\n const fallback = 'If okf_type or an edge is invalid, omit them rather than inventing unlisted types.';\n\n const ontologyModeInstructions = [\n '## Ontology constraints',\n strictRules,\n fallback,\n FACT_ONTOLOGY_FIELDS,\n mode === 'emergent' ? EMERGENT_EXTRA : '',\n 'Manifest:',\n manifestJson,\n ].filter(Boolean).join('\\n');\n\n return { ontologyManifest: manifestJson, ontologyModeInstructions };\n}\n","import type {\n OntologyConfig,\n OntologyManifest,\n OntologyMode,\n OntologyPromptContext,\n OntologyUpdates,\n ExtractedFactWithOntology,\n ExtractedFactEdge,\n SQLiteAdapter,\n WikiEdge,\n} from '../types';\nimport { WikiStrictOntologyViolation } from '../types';\nimport type { MetadataRepository } from '../repositories/MetadataRepository';\nimport type { EdgeRepository } from '../repositories/EdgeRepository';\nimport { buildOntologyPromptAppendix } from '../prompts/ontology';\nimport {\n emptyManifest,\n normalizeTitleKey,\n resolveNodeType,\n resolveEdgeDefinitions,\n typeSatisfies,\n validateInlineEdges,\n validateManifest,\n type EdgeDrop,\n} from '../utils/ontology';\nimport { generateId } from '../utils/ids';\n\nexport type TitleIndexEntry = { id: string; okf_type: string | null };\n\n/**\n * Coordinates ontology mode resolution, manifest caching, LLM output validation, and edge persistence.\n * Cache is per WikiMemory instance (single-process); not shared across instances.\n */\nexport class OntologyService {\n private cache = new Map<string, { mode: OntologyMode; manifest: OntologyManifest }>();\n\n constructor(\n private metadataRepo: MetadataRepository,\n private edgeRepo: EdgeRepository,\n private ontologyConfig?: OntologyConfig,\n ) {}\n\n resolveMode(storedMode?: OntologyMode): OntologyMode {\n return storedMode ?? this.ontologyConfig?.mode ?? 'off';\n }\n\n invalidateCache(entityId: string): void {\n this.cache.delete(entityId);\n }\n\n async getEffectiveState(entityId: string, tx?: SQLiteAdapter): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n }> {\n if (!tx) {\n const cached = this.cache.get(entityId);\n if (cached) return cached;\n }\n\n const row = await this.metadataRepo.getManifest(entityId, tx);\n if (row) {\n const state = { mode: this.resolveMode(row.mode), manifest: row.manifest };\n if (!tx) this.cache.set(entityId, state);\n return state;\n }\n\n const seed = this.ontologyConfig?.seedManifests?.[entityId];\n if (seed) {\n // D11: the tx branch validates via setManifest; the cache branch did not.\n validateManifest(seed.manifest);\n const state = {\n mode: this.resolveMode(seed.mode),\n manifest: seed.manifest,\n };\n if (tx) {\n await this.metadataRepo.setManifest(entityId, state, tx);\n } else {\n this.cache.set(entityId, state);\n }\n return state;\n }\n\n return { mode: 'off', manifest: emptyManifest() };\n }\n\n async buildPromptContext(entityId: string): Promise<OntologyPromptContext | null> {\n const { mode, manifest } = await this.getEffectiveState(entityId);\n if (mode === 'off') return null;\n const manifestJson = JSON.stringify(manifest, null, 2);\n return buildOntologyPromptAppendix(mode, manifestJson);\n }\n\n async mergeEmergentUpdates(\n entityId: string,\n updates: OntologyUpdates,\n tx: SQLiteAdapter,\n ): Promise<OntologyManifest> {\n const merged = await this.metadataRepo.mergeManifestUpdates(entityId, updates, tx);\n this.invalidateCache(entityId);\n return merged;\n }\n\n validateAndNormalizeFact(\n fact: ExtractedFactWithOntology,\n manifest: OntologyManifest,\n opts?: { strict?: boolean; entityId?: string; drops?: EdgeDrop[] },\n ): { okf_type: string | null; edges: ExtractedFactEdge[] } {\n const rawType = typeof fact.okf_type === 'string' ? fact.okf_type : '';\n const strict = opts?.strict === true;\n const canonical = resolveNodeType(rawType, manifest);\n if (!canonical) {\n if (strict) throw new WikiStrictOntologyViolation(opts?.entityId ?? '', 'node', rawType);\n if (opts?.drops && Array.isArray(fact.edges)) {\n for (const edge of fact.edges) {\n opts.drops.push({\n reason: 'no_source_type',\n sourceId: null,\n edgeType: typeof edge?.edge_type === 'string' ? edge.edge_type : null,\n sourceNodeType: null,\n targetNodeType: null,\n });\n }\n }\n return { okf_type: null, edges: [] };\n }\n const edges = validateInlineEdges(canonical, null, fact.edges ?? [], manifest, opts);\n return { okf_type: canonical, edges };\n }\n\n /**\n * Pure resolver: given a source type, LLM-supplied edges, the manifest,\n * and a title index, return a list of concrete `WikiEdge` objects ready\n * for persistence. Performs no DB writes. Used by callers that batch edge\n * writes inside their own transaction (e.g. `IngestionService.ingestDocument`\n * when delegating to `upsertGraphCore`).\n */\n resolveEdges(\n entityId: string,\n sourceId: string,\n sourceType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n titleIndex: Map<string, TitleIndexEntry>,\n now: number,\n drops?: EdgeDrop[],\n ): WikiEdge[] {\n if (edges.length === 0) return [];\n if (!sourceType) {\n for (const edge of edges) {\n drops?.push({ reason: 'no_source_type', sourceId, edgeType: edge.edge_type, sourceNodeType: null, targetNodeType: null });\n }\n return [];\n }\n const out: WikiEdge[] = [];\n for (const edge of edges) {\n const candidates = resolveEdgeDefinitions(edge.edge_type, manifest)\n .filter(d => typeSatisfies(d.source_type, sourceType, manifest));\n if (candidates.length === 0) {\n drops?.push({ reason: 'type_not_in_manifest', sourceId, edgeType: edge.edge_type, sourceNodeType: sourceType, targetNodeType: null });\n continue;\n }\n\n const targetKey = normalizeTitleKey(edge.target_title);\n const target = titleIndex.get(targetKey);\n if (!target) {\n drops?.push({ reason: 'target_not_found', sourceId, edgeType: edge.edge_type, sourceNodeType: sourceType, targetNodeType: null });\n continue;\n }\n\n const targetType = (target.okf_type ?? '').trim().toLowerCase();\n const def = candidates.find(d => d.target_type.trim().toLowerCase() === targetType)\n ?? candidates.find(d => typeSatisfies(d.target_type, targetType, manifest));\n if (!def) {\n drops?.push({\n reason: 'target_type_mismatch', sourceId, edgeType: edge.edge_type,\n sourceNodeType: sourceType, targetNodeType: target.okf_type ?? null,\n });\n continue;\n }\n\n out.push({\n id: generateId(),\n entity_id: entityId,\n source_id: sourceId,\n target_id: target.id,\n edge_type: def.type,\n created_at: now,\n });\n }\n return out;\n }\n\n /**\n * Backwards-compatible wrapper: resolves edges via {@link resolveEdges},\n * then persists each via `edgeRepo.addIgnoreDuplicate` in the supplied\n * transaction. Returns the number of edges persisted. Used by paths that\n * want self-contained edge persistence (e.g. MaintenanceService heal /\n * backfill callers that do not have a separate edge-write step).\n */\n async resolveAndPersistEdges(\n entityId: string,\n sourceId: string,\n sourceType: string | null,\n edges: ExtractedFactEdge[],\n manifest: OntologyManifest,\n titleIndex: Map<string, TitleIndexEntry>,\n tx: SQLiteAdapter,\n now: number,\n drops?: EdgeDrop[],\n ): Promise<number> {\n const resolved = this.resolveEdges(entityId, sourceId, sourceType, edges, manifest, titleIndex, now, drops);\n let persisted = 0;\n for (const edge of resolved) {\n const inserted = await this.edgeRepo.addIgnoreDuplicate(edge, tx);\n if (inserted) persisted++;\n }\n return persisted;\n }\n}\n","import type { EdgeRepository, NeighborhoodQueryOptions } from '../repositories/EdgeRepository';\nimport type { EntryRepository } from '../repositories/EntryRepository';\nimport type { GraphTraversalOptions, GraphNeighborhood, WikiConfig } from '../types';\n\n/**\n * Pure orchestrator — no SQL. Merges WikiConfig defaults with per-call options,\n * delegates the recursive walk to EdgeRepository, then hydrates node IDs into facts.\n */\nexport class GraphTraversalService {\n constructor(\n private edgeRepo: EdgeRepository,\n private entryRepo: EntryRepository,\n private config: WikiConfig,\n ) {}\n\n async traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood> {\n const fallbackMaxNodes = 20;\n const rawConfigDefault = this.config.maxTraversalNodes ?? fallbackMaxNodes;\n const defaultMaxNodes =\n Number.isFinite(rawConfigDefault) && rawConfigDefault >= 1\n ? Math.floor(rawConfigDefault)\n : fallbackMaxNodes;\n const rawMaxNodes = options.maxTraversalNodes ?? defaultMaxNodes;\n const maxNodes =\n Number.isFinite(rawMaxNodes) && rawMaxNodes >= 1 ? Math.floor(rawMaxNodes) : defaultMaxNodes;\n\n const opts: NeighborhoodQueryOptions = {\n maxDepth: Math.max(1, Math.min(options.maxDepth ?? 1, 3)),\n direction: options.direction ?? this.config.traversalDirection ?? 'both',\n edgeTypes: options.edgeTypes,\n minConfidence: options.minTraversalConfidence ?? this.config.minTraversalConfidence ?? 'tentative',\n excludeSourceTypes: options.excludeSourceTypes ?? this.config.excludeSourceTypes ?? [],\n excludeDrafts: options.excludeDrafts ?? this.config.excludeDrafts ?? false,\n maxNodes,\n };\n\n const { nodeIds, edges } = await this.edgeRepo.getNeighborhood(entityId, options.sourceId, opts);\n if (nodeIds.length === 0) return { nodes: [], edges: [] };\n\n // findByIds() returns facts in input-ID order (Map-based lookup,\n // see packages/core/src/repositories/EntryRepository.ts:104-108) — no re-sort needed.\n const nodes = await this.entryRepo.findByIds(nodeIds, [entityId]);\n const hydratedIds = new Set(nodes.map((node) => node.id));\n const filteredEdges = edges.filter(\n (edge) => hydratedIds.has(edge.source_id) && hydratedIds.has(edge.target_id),\n );\n return { nodes, edges: filteredEdges };\n }\n}\n","import type { SQLiteAdapter } from '../types';\nimport {\n formatSourcesJson,\n formatVerifiedJson,\n latestVerified,\n} from '@equationalapplications/core-okf';\n\nexport type OkfSource = {\n id?: string;\n resource: string;\n title?: string;\n author?: string;\n usage_count?: number;\n last_modified?: string;\n usage_window?: { from: string; to: string };\n};\nexport type OkfVerifiedEntry = { by: string; at: string };\n\n/**\n * DAO discipline (spec §8): only knowledge-content writes may bump `updated_at`.\n * Trust / provenance / lifecycle / freshness writes MUST NOT touch it. Every\n * `UPDATE` in this class is a non-content metadata write. Tests in\n * `__tests__/daoDiscipline.test.ts` and `__tests__/okfTrustWrites.test.ts`\n * snapshot the SQL via a logging adapter and assert the SET clause omits\n * `updated_at`.\n *\n * Deliberately does NOT push an outbox event, unlike `EntryRepository.upsert`\n * / `TaskRepository.upsert` (spec §8 \"Outbox/transaction scope\" note): outbox\n * delivery exists for *content* sync, and these writes are metadata, not\n * content, by the same reasoning that exempts them from `updated_at`. A\n * downstream sync consumer will not learn about a new verifier until the\n * next full re-export/re-import — accepted for v0.2.\n */\nexport class OkfTrustWritesRepository {\n constructor(private db: SQLiteAdapter, private prefix: string) {}\n\n private getExecutor(tx?: SQLiteAdapter): SQLiteAdapter {\n return tx ?? this.db;\n }\n\n /**\n * Append one or more verification events to a fact's `okf_verified` JSON\n * array, atomically, in a single SQL statement.\n *\n * The implementation uses json_each over the existing array UNION ALL'd\n * with json_each over the new events wrapped in json_group_array — a single\n * UPDATE expression. SQLite serializes this against concurrent writers on\n * the same row, so two callers appending simultaneously cannot lose each\n * other's events (the previous implementation serialized only the supplied\n * array and overwrote, dropping any pre-existing history).\n *\n * Sets the `last_verified_*` convenience columns from the latest event in\n * the union (computed in code; see {@link latestVerified}).\n */\n async writeOkfTrust(\n entryId: string,\n entityId: string,\n verified: OkfVerifiedEntry[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n if (verified.length === 0) return;\n const latest = latestVerified(verified, Date.now());\n const newEventsJson = JSON.stringify(verified);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET okf_verified = COALESCE(\n (SELECT json_group_array(json_object('by', s.by_val, 'at', s.at_val))\n FROM (\n SELECT json_extract(value, '$.by') AS by_val,\n json_extract(value, '$.at') AS at_val\n FROM json_each(okf_verified)\n UNION ALL\n SELECT json_extract(value, '$.by'),\n json_extract(value, '$.at')\n FROM json_each(?)\n ) AS s\n ORDER BY s.at_val),\n '[]'\n ),\n last_verified_by = ?,\n last_verified_at = ?\n WHERE id = ? AND entity_id = ?`,\n [newEventsJson, latest?.by ?? null, latest?.at ?? null, entryId, entityId],\n );\n }\n\n /** Replace the `sources` list (provenance). */\n async writeOkfSources(\n entryId: string,\n entityId: string,\n sources: OkfSource[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n const json = formatSourcesJson(sources);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET okf_sources = ?\n WHERE id = ? AND entity_id = ?`,\n [json, entryId, entityId],\n );\n }\n\n /** Set the OKF v0.2 lifecycle status. */\n async setLifecycleStatus(\n entryId: string,\n entityId: string,\n status: 'draft' | 'stable' | 'deprecated',\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET lifecycle_status = ?\n WHERE id = ? AND entity_id = ?`,\n [status, entryId, entityId],\n );\n }\n\n /** Set the absolute cutoff (epoch ms) for staleness, or NULL to clear. */\n async setStaleAfter(\n entryId: string,\n entityId: string,\n date: number | null,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET stale_after = ?\n WHERE id = ? AND entity_id = ?`,\n [date, entryId, entityId],\n );\n }\n\n /** Set the producer / verifier actor string. Rare. */\n async setGeneratedBy(\n entryId: string,\n entityId: string,\n actor: string,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}entries\n SET generated_by = ?\n WHERE id = ? AND entity_id = ?`,\n [actor, entryId, entityId],\n );\n }\n\n // The same five methods exist for tasks, with `tasks` instead of `entries`.\n // Tasks are symmetric per spec §2.5.\n\n /** Atomic append, task variant — mirrors {@link writeOkfTrust}. */\n async writeOkfTrustTask(\n taskId: string,\n entityId: string,\n verified: OkfVerifiedEntry[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n if (verified.length === 0) return;\n const latest = latestVerified(verified, Date.now());\n const newEventsJson = JSON.stringify(verified);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET okf_verified = COALESCE(\n (SELECT json_group_array(json_object('by', s.by_val, 'at', s.at_val))\n FROM (\n SELECT json_extract(value, '$.by') AS by_val,\n json_extract(value, '$.at') AS at_val\n FROM json_each(okf_verified)\n UNION ALL\n SELECT json_extract(value, '$.by'),\n json_extract(value, '$.at')\n FROM json_each(?)\n ) AS s\n ORDER BY s.at_val),\n '[]'\n ),\n last_verified_by = ?,\n last_verified_at = ?\n WHERE id = ? AND entity_id = ?`,\n [newEventsJson, latest?.by ?? null, latest?.at ?? null, taskId, entityId],\n );\n }\n\n async writeOkfSourcesTask(\n taskId: string,\n entityId: string,\n sources: OkfSource[],\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n const json = formatSourcesJson(sources);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET okf_sources = ?\n WHERE id = ? AND entity_id = ?`,\n [json, taskId, entityId],\n );\n }\n\n async setLifecycleStatusTask(\n taskId: string,\n entityId: string,\n status: 'draft' | 'stable' | 'deprecated',\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET lifecycle_status = ?\n WHERE id = ? AND entity_id = ?`,\n [status, taskId, entityId],\n );\n }\n\n async setStaleAfterTask(\n taskId: string,\n entityId: string,\n date: number | null,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET stale_after = ?\n WHERE id = ? AND entity_id = ?`,\n [date, taskId, entityId],\n );\n }\n\n async setGeneratedByTask(\n taskId: string,\n entityId: string,\n actor: string,\n tx?: SQLiteAdapter,\n ): Promise<void> {\n const executor = this.getExecutor(tx);\n await executor.runAsync(\n `UPDATE ${this.prefix}tasks\n SET generated_by = ?\n WHERE id = ? AND entity_id = ?`,\n [actor, taskId, entityId],\n );\n }\n}\n","import type { SQLiteAdapter } from './types';\nimport type { WikiOutboxEvent } from './outbox/types';\nimport { setupDatabase } from './db/schema';\nimport { withSerializedTransactions } from './db/serializedAdapter';\nimport { MIGRATIONS, CURRENT_SCHEMA_VERSION } from './db/migrations';\nimport {\n WikiOptions,\n MemoryBundle,\n MemoryDump,\n WikiEvent,\n EntityStatus,\n ReadOptions,\n WikiSourceRefHashCollision,\n WikiDraftNotFound,\n} from './types';\nimport type { DraftPage } from './types';\nimport { EntryRepository } from './repositories/EntryRepository';\nimport { OutboxRepository } from './repositories/OutboxRepository';\nimport { SourceRefIndexRepository } from './repositories/SourceRefIndexRepository';\nimport { TaskRepository } from './repositories/TaskRepository';\nimport { EventRepository } from './repositories/EventRepository';\nimport { EdgeRepository } from './repositories/EdgeRepository';\nimport { MetadataRepository, entitySummaryMetaKey } from './repositories/MetadataRepository';\nimport { SearchService } from './services/SearchService';\nimport { JobManager } from './services/JobManager';\nimport { normalizeSourceRef, normalizeSourceHash, validateFact, validateTask, clip, chunkText } from './utils/pure';\nimport { resolveGrounding } from './utils/grounding';\nimport { IngestionService } from './services/IngestionService';\nimport { MaintenanceService } from './services/MaintenanceService';\nimport { ImportExportService } from './services/ImportExportService';\nimport { EmbeddingService } from './services/EmbeddingService';\nimport { RetrievalService } from './services/RetrievalService';\nimport { WriteService } from './services/WriteService';\nimport { PromptService } from './services/PromptService';\nimport { OntologyService } from './services/OntologyService';\nimport { GraphTraversalService } from './services/GraphTraversalService';\nimport { OkfTrustWritesRepository } from './db/okf-trust-writes';\nimport { validateManifest } from './utils/ontology';\nimport { DiagnosticBuffer } from './utils/diagnostics';\nimport type { OntologyManifest, OntologyMode, GraphTraversalOptions, GraphNeighborhood, OntologyBackfillResult, HealResult, IngestDocumentResult, ReembedResult } from './types';\n\nexport { WikiBusyError, WikiTransactionError, PrunePartialFailureError, HOOK_TIMEOUT_MARKER, WikiStrictOntologyViolation, WikiSourceRefHashCollision, WikiParseError, WikiIngestEmptyError, WikiGraphNodeOwnershipConflict } from './types';\n\nconst TABLE_PREFIX_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,30}_$/;\n\n/** Typed escape hatch for tests — not part of the supported consumer API. */\nexport interface WikiMemoryTestAccess {\n embeddingService: EmbeddingService;\n importExportService: ImportExportService;\n ingestionService: IngestionService;\n maintenanceService: MaintenanceService;\n retrievalService: RetrievalService;\n searchService: SearchService;\n writeService: WriteService;\n promptService: PromptService;\n graphTraversalService: GraphTraversalService;\n entryRepo: EntryRepository;\n sourceRefIndexRepo: SourceRefIndexRepository;\n metadataRepo: MetadataRepository;\n jobManager: JobManager;\n}\n\n/** `listDrafts` cursors are `${created_at}:${id}`; opaque to callers. */\nfunction decodeDraftCursor(cursor: unknown): { createdAt: number; id: string } {\n const sep = typeof cursor === 'string' ? cursor.indexOf(':') : -1;\n const createdAt = sep > 0 ? Number((cursor as string).slice(0, sep)) : Number.NaN;\n const id = sep > 0 ? (cursor as string).slice(sep + 1) : '';\n if (!Number.isSafeInteger(createdAt) || id.length === 0) {\n throw new TypeError('Invalid listDrafts cursor.');\n }\n return { createdAt, id };\n}\n\nexport class WikiMemory {\n /** Emits `__testAccess` console warning at most once per instance when NODE_ENV ≠ \"test\". */\n #testAccessNonTestEnvWarned = false;\n\n private db: SQLiteAdapter;\n private prefix: string;\n private options: WikiOptions;\n private entryRepo: EntryRepository;\n private outboxRepo: OutboxRepository;\n private sourceRefIndexRepo: SourceRefIndexRepository;\n private taskRepo: TaskRepository;\n private eventRepo: EventRepository;\n private edgeRepo: EdgeRepository;\n private metadataRepo: MetadataRepository;\n private embeddingService: EmbeddingService;\n private searchService: SearchService;\n private jobManager: JobManager;\n private ingestionService: IngestionService;\n private maintenanceService: MaintenanceService;\n private importExportService: ImportExportService;\n private retrievalService: RetrievalService;\n private writeService: WriteService;\n private promptService: PromptService;\n private ontologyService: OntologyService;\n private graphTraversalService: GraphTraversalService;\n private readonly okfTrustWrites: OkfTrustWritesRepository;\n\n constructor(db: SQLiteAdapter, options: WikiOptions) {\n // Serialize transactions on the single shared connection before the adapter\n // reaches any repository or service. See docs/superpowers/specs/2026-07-09-transaction-serialization-spec.md.\n this.db = withSerializedTransactions(db);\n this.options = options;\n this.prefix = options.config?.tablePrefix ?? 'llm_wiki_';\n if (!TABLE_PREFIX_PATTERN.test(this.prefix)) {\n throw new Error(\n `Invalid tablePrefix: ${JSON.stringify(this.prefix)}. ` +\n `Must match ${TABLE_PREFIX_PATTERN} (letter, then alphanumeric/underscore, ending in \"_\", max 32 chars total).`,\n );\n }\n this.outboxRepo = new OutboxRepository(this.db, this.prefix, !!options.config?.enableOutbox);\n this.entryRepo = new EntryRepository(this.db, this.prefix, this.outboxRepo);\n this.sourceRefIndexRepo = new SourceRefIndexRepository(this.db, this.prefix);\n this.taskRepo = new TaskRepository(this.db, this.prefix, this.outboxRepo);\n this.eventRepo = new EventRepository(this.db, this.prefix);\n this.edgeRepo = new EdgeRepository(this.db, this.prefix);\n this.metadataRepo = new MetadataRepository(this.db, this.prefix);\n this.ontologyService = new OntologyService(\n this.metadataRepo,\n this.edgeRepo,\n options.config?.ontology,\n );\n this.embeddingService = new EmbeddingService(this.db, this.options, this.entryRepo, this.metadataRepo);\n this.searchService = new SearchService(this.entryRepo);\n this.jobManager = new JobManager(this.prefix);\n this.promptService = new PromptService(options.config?.prompts, resolveGrounding(options.config?.grounding));\n this.ingestionService = new IngestionService(\n this.db,\n this.prefix,\n this.options,\n this.entryRepo,\n this.sourceRefIndexRepo,\n this.metadataRepo,\n this.edgeRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n this.promptService,\n this.ontologyService,\n );\n this.maintenanceService = new MaintenanceService(\n this.db,\n this.prefix,\n this.options,\n this.entryRepo,\n this.sourceRefIndexRepo,\n this.taskRepo,\n this.eventRepo,\n this.metadataRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n this.promptService,\n this.ontologyService,\n );\n this.importExportService = new ImportExportService(\n this.db,\n this.entryRepo,\n this.taskRepo,\n this.eventRepo,\n this.edgeRepo,\n this.metadataRepo,\n this.searchService,\n this.jobManager,\n this.embeddingService,\n );\n this.retrievalService = new RetrievalService(\n this.options,\n this.entryRepo,\n this.taskRepo,\n this.eventRepo,\n this.metadataRepo,\n this.searchService,\n );\n this.writeService = new WriteService(\n this.db,\n this.options,\n this.entryRepo,\n this.eventRepo,\n this.metadataRepo,\n this.jobManager,\n this.maintenanceService,\n );\n this.graphTraversalService = new GraphTraversalService(\n this.edgeRepo,\n this.entryRepo,\n this.options.config ?? {},\n );\n this.okfTrustWrites = new OkfTrustWritesRepository(this.db, this.prefix);\n }\n\n /**\n * Explicit escape hatch for test suites: typed access to composed services for mocks/spies.\n * If `NODE_ENV` is not `\"test\"`, emits a single `console.warn` per instance (skipped when `process` is undefined).\n */\n get __testAccess(): WikiMemoryTestAccess {\n const processEnv = typeof globalThis !== 'undefined'\n ? (globalThis as any).process?.env\n : undefined;\n\n if (\n processEnv !== undefined &&\n processEnv.NODE_ENV !== 'test' &&\n !this.#testAccessNonTestEnvWarned\n ) {\n this.#testAccessNonTestEnvWarned = true;\n console.warn('Warning: WikiMemory.__testAccess is intended for tests (NODE_ENV !== \"test\").');\n }\n return {\n embeddingService: this.embeddingService,\n importExportService: this.importExportService,\n ingestionService: this.ingestionService,\n maintenanceService: this.maintenanceService,\n retrievalService: this.retrievalService,\n searchService: this.searchService,\n writeService: this.writeService,\n promptService: this.promptService,\n graphTraversalService: this.graphTraversalService,\n entryRepo: this.entryRepo,\n sourceRefIndexRepo: this.sourceRefIndexRepo,\n metadataRepo: this.metadataRepo,\n jobManager: this.jobManager,\n };\n }\n\n async setup() {\n const entriesExistedBeforeSetup = await this.metadataRepo.tableExists(`${this.prefix}entries`);\n\n await setupDatabase(this.db, this.prefix);\n\n let currentVersion: number;\n\n if (!entriesExistedBeforeSetup) {\n await this.metadataRepo.setMeta('schema_version', String(CURRENT_SCHEMA_VERSION), this.db);\n currentVersion = CURRENT_SCHEMA_VERSION;\n } else {\n const schemaVersionValue = await this.metadataRepo.getMeta('schema_version');\n\n if (schemaVersionValue) {\n currentVersion = parseInt(schemaVersionValue, 10);\n if (!Number.isFinite(currentVersion)) currentVersion = 0;\n } else {\n const ftsDdl = await this.metadataRepo.getTableDdl(`${this.prefix}entries_fts`);\n const hasPorter = /tokenize\\s*=\\s*['\"]porter\\s+unicode61['\"]/i.test(ftsDdl ?? '');\n currentVersion = hasPorter ? 1 : 0;\n }\n }\n\n for (const migration of MIGRATIONS) {\n if (migration.version > currentVersion) {\n await migration.run(this.db, this.prefix);\n await this.metadataRepo.setMeta('schema_version', String(migration.version), this.db);\n currentVersion = migration.version;\n }\n }\n\n if (entriesExistedBeforeSetup) {\n const schemaVersionCheck = await this.metadataRepo.getMeta('schema_version');\n if (!schemaVersionCheck) {\n await this.metadataRepo.setMeta('schema_version', String(currentVersion), this.db);\n }\n }\n\n if (entriesExistedBeforeSetup) {\n await this.importExportService.assertNoLegacySourceTypes();\n }\n\n const rows = await this.entryRepo.findRowsForSourceRefMigration();\n await this.db.withTransactionAsync(async (tx) => {\n for (const row of rows) {\n const normalized = normalizeSourceRef(row.source_ref);\n if (normalized !== row.source_ref) {\n await this.entryRepo.updateSourceRefByRowid(row.rowid, normalized, tx);\n }\n }\n });\n\n await this.searchService.sync();\n }\n\n async hasChanged(\n entityId: string,\n sourceRef: string,\n sourceHash: string,\n ): Promise<boolean>;\n /**\n * Batched overload.\n *\n * `duplicateOf`, when present, is the canonical stored DIFFERENT `source_ref`\n * holding the same hash — never the incoming ref itself (the incoming ref is\n * excluded from the canonical-sort set so a self-reference is impossible).\n * `duplicateOf` reflects the *DB-side* normalized spelling; `sourceRef` in\n * each result echoes the raw caller value. Hosts should not compare these\n * two fields directly to infer canonical status.\n */\n async hasChanged(\n entityId: string,\n entries: Array<{ sourceRef: string; sourceHash: string }>,\n ): Promise<Array<{ sourceRef: string; changed: boolean; duplicateOf?: string }>>;\n async hasChanged(\n entityId: string,\n sourceRefOrEntries: string | Array<{ sourceRef: string; sourceHash: string }>,\n sourceHashArg?: string,\n ): Promise<boolean | Array<{ sourceRef: string; changed: boolean; duplicateOf?: string }>> {\n // Single-doc path: delegate to existing semantics.\n if (typeof sourceRefOrEntries === 'string') {\n const sourceRef = normalizeSourceRef(sourceRefOrEntries);\n if (!sourceRef) {\n throw new Error(`Invalid sourceRef: ${JSON.stringify(sourceRefOrEntries)}`);\n }\n const sourceHash = normalizeSourceHash(sourceHashArg!);\n if (!sourceHash) {\n throw new Error('Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)');\n }\n const storedHash = await this.entryRepo.findLatestSourceHash(entityId, sourceRef);\n if (storedHash === null) return true;\n const normalizedStoredHash = normalizeSourceHash(storedHash);\n return normalizedStoredHash !== sourceHash;\n }\n\n // Batched path: empty input -> empty result, zero SQL calls.\n const entries = sourceRefOrEntries;\n if (entries.length === 0) return [];\n\n // Normalize all inputs (validation up front). Preserve the raw ref so the\n // result echoes the caller's spelling (DB refs are normalized on setup,\n // but the caller hasn't seen that normalization yet).\n const normalized = entries.map(e => {\n const r = normalizeSourceRef(e.sourceRef);\n if (!r) throw new Error(`Invalid sourceRef: ${JSON.stringify(e.sourceRef)}`);\n const h = normalizeSourceHash(e.sourceHash);\n if (!h) throw new Error('Invalid sourceHash: must be a 64-character hex string (normalized to lowercase)');\n return { rawSourceRef: e.sourceRef, sourceRef: r, sourceHash: h };\n });\n\n // 1 + H SQL queries: one batched latest-hash lookup, plus one source_ref_index\n // lookup per distinct input hash. Lookups are issued in parallel — the bound\n // is the SQL-query count, not the await count.\n const latestHashes = await this.entryRepo.findLatestSourceHashes(entityId, normalized.map(e => e.sourceRef));\n\n const distinctHashes = Array.from(new Set(normalized.map(e => e.sourceHash)));\n const dupRefs = await Promise.all(\n distinctHashes.map(h => this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, h)),\n );\n const dupMap = new Map<string, string | null>(); // hash -> canonical sourceRef (or null)\n for (let i = 0; i < distinctHashes.length; i++) {\n dupMap.set(distinctHashes[i], dupRefs[i]);\n }\n\n return normalized.map(e => {\n const stored = latestHashes.get(e.sourceRef);\n const changed = stored === undefined || stored === null || normalizeSourceHash(stored) !== e.sourceHash;\n const canonical = dupMap.get(e.sourceHash) ?? null;\n if (canonical === null || canonical === e.sourceRef) {\n return { sourceRef: e.rawSourceRef, changed };\n }\n // Canonical: the single sourceRef from source_ref_index that holds\n // this hash, if any. Because the partial UNIQUE index allows at most\n // one live row per (entity, hash), the canonical cannot be the\n // incoming ref (it would be the same sourceRef) — we filter that out\n // above. Non-ASCII sourceRefs are still compared by the DB's\n // source_ref index, so the canonical matches the DB ordering.\n return { sourceRef: e.rawSourceRef, changed, duplicateOf: canonical };\n });\n }\n\n /**\n * Returns the live source_refs for an entity, one row per ref, with the most\n * recently-updated live `source_hash` and a live fact count. Refs are sorted\n * `COLLATE BINARY` (no locale dependency). Used by hosts to reconcile stored\n * state against a live source, or audit duplicate-hash collisions via\n * `findSourceRefsByHash`.\n */\n async listSourceRefs(entityId: string): Promise<Array<{\n sourceRef: string;\n sourceHash: string | null;\n factCount: number;\n lastIngestedAt: number;\n }>> {\n return this.entryRepo.listSourceRefs(entityId);\n }\n\n /**\n * Returns the live source_refs for an entity that hold the given source_hash.\n * With v9, source_ref_index is the source of truth for the sourceRef-level\n * TOCTOU-race invariant: at most one sourceRef can hold a given\n * (entity_id, source_hash). The result is either a single-element array\n * (one canonical ref) or empty (no live ref holds the hash). Returned as\n * an array to preserve the existing public-API shape used by hosts\n * auditing duplicate-content collisions.\n */\n async findSourceRefsByHash(entityId: string, sourceHash: string): Promise<string[]> {\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);\n return canonical === null ? [] : [canonical];\n }\n\n /**\n * Returns the set of `entity_id` values with at least one row in this\n * database, INCLUDING entities whose only remaining rows are soft-deleted\n * — sorted ascending `entity_id COLLATE BINARY`. Empty array when the\n * database has no entities.\n *\n * The deliberate inclusion of soft-deleted-only entities closes the\n * decommissioned-scope leak: a scoped namespace whose documents have all\n * been forgotten or superseded must still appear so host maintenance\n * sweeps (`runLibrarian`, `runHeal`, `runOntologyBackfill`, `runPrune`)\n * can visit it and reap the soft-deleted rows.\n *\n * Read-only. Never acquires a lock. Never opens a transaction. Propagates\n * underlying read errors.\n *\n * @param options.prefix - Optional string filter applied as\n * `id.startsWith(prefix)`. O(n) over distinct ids because the\n * `(entity_id, source_ref)` index is not seekable on `entity_id`-only\n * prefix. Empty-string prefix matches every id.\n *\n * Note: this widens the coverage of `exportDump` (which delegates to\n * `MetadataRepository.getDistinctEntityIds`); exported dumps now include\n * orphaned entities. This is a deliberate widening for backup/migration\n * coverage, not a breaking change to `exportDump`'s return shape.\n */\n async listEntityIds(options?: { prefix?: string }): Promise<string[]> {\n const ids = await this.metadataRepo.getDistinctEntityIds();\n if (options?.prefix === undefined) return ids;\n return ids.filter(id => id.startsWith(options.prefix!));\n }\n\n async runPrune(\n entityId: string,\n options?: {\n retainSoftDeletedFor?: number | null;\n retainEventsFor?: number | null;\n vacuum?: boolean;\n },\n ): Promise<{ entries: number; tasks: number; events: number }> {\n return this.maintenanceService.runPrune(entityId, options);\n }\n\n async read(entityId: string | string[], query: string, options?: ReadOptions): Promise<MemoryBundle> {\n return this.retrievalService.read(entityId, query, options);\n }\n\n async traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood> {\n return this.graphTraversalService.traverseGraph(entityId, options);\n }\n\n async getMemoryBundle(entityId: string): Promise<MemoryBundle> {\n return this.importExportService.getFullBundle(entityId, { maxEvents: 10 });\n }\n\n async write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void> {\n return this.writeService.write(entityId, event);\n }\n\n /**\n * @param options.promptOverride - Applies only to this manual call. Does NOT affect\n * WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,\n * set `options.config.prompts.librarianSystemPrompt` at WikiMemory construction time.\n */\n async runLibrarian(entityId: string, options?: { promptOverride?: string }): Promise<void> {\n return this.maintenanceService.runLibrarian(entityId, options);\n }\n\n /**\n * Reviews stored facts with the LLM: removes orphans, downgrades stale\n * inferences, synthesizes corrections.\n *\n * Bounded per call: covers at most `batchSize` candidates (default 25), so\n * one call no longer sweeps the whole entity. Hosts own the cadence; loop\n * `while (result.remaining > 0)` for convergence.\n *\n * `remaining === 0` means \"every mutable fact is inside the 7-day recheck\n * cooldown\", not \"there is no more work\" — heal's candidate set is the live\n * mutable corpus, not a draining backlog, so it climbs back as the cooldown\n * lapses and as new facts are written. Do not write a loop expecting a drain.\n *\n * @param options.promptOverride - Applies only to this manual call. Does NOT affect\n * WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,\n * set `options.config.prompts.healSystemPrompt` at WikiMemory construction time.\n * @param options.batchSize - Candidates per run (default 25) for providers with\n * tighter context limits.\n */\n async runHeal(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number },\n ): Promise<HealResult> {\n return this.maintenanceService.runHeal(entityId, options);\n }\n\n /**\n * Types already-persisted untyped facts (okf_type IS NULL) in place via one\n * librarian-style LLM call. Strictly additive: never creates, deletes, or\n * rewrites facts; never overwrites an existing okf_type. Free when there is\n * nothing to do (ontology off, or zero eligible untyped facts).\n *\n * Hosts own the trigger cadence (e.g. after each sync); loop `while\n * result.remaining > 0` for convergence. Throws WikiBusyError when another\n * backfill (or conflicting maintenance op) is running for the entity.\n *\n * @param options.promptOverride - Applies only to this call. For persistent\n * customization set `options.config.prompts.ontologyBackfillSystemPrompt`.\n * @param options.batchSize - Facts per run (default 25) for providers with\n * tighter context limits.\n */\n async runOntologyBackfill(\n entityId: string,\n options?: { promptOverride?: string; batchSize?: number; classifier?: 'auto' | 'llm' },\n ): Promise<OntologyBackfillResult> {\n return this.maintenanceService.runOntologyBackfill(entityId, options);\n }\n\n async runReembed(\n entityId?: string,\n opts?: { force?: boolean; skipExisting?: boolean },\n ): Promise<ReembedResult> {\n return this.maintenanceService.runReembed(entityId, opts);\n }\n\n getEntityStatus(entityId: string): EntityStatus {\n return this.jobManager.getEntityStatus(entityId);\n }\n\n subscribeEntityStatus(\n entityId: string,\n callback: (status: EntityStatus) => void,\n ): () => void {\n return this.jobManager.subscribeEntityStatus(entityId, callback);\n }\n\n clearVectorCache(): void {\n this.searchService.evictCache();\n }\n\n async exportDump(entityIds?: string[]): Promise<MemoryDump> {\n return this.importExportService.exportDump(entityIds);\n }\n\n /** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */\n async getEntitySummary(entityId: string): Promise<string | null> {\n return this.metadataRepo.getMeta(entitySummaryMetaKey(entityId));\n }\n\n async importDump(dump: MemoryDump, opts?: { merge?: boolean }): Promise<void> {\n return this.importExportService.importDump(dump, opts);\n }\n\n async forget(\n entityId: string,\n params: { entryId?: string; taskId?: string; sourceRef?: string; sourceHash?: string; clearAll?: boolean },\n opts?: { dryRun?: boolean },\n ): Promise<{ deleted: { entries: number; tasks: number }; metadataReset?: boolean }> {\n return this.maintenanceService.forget(entityId, params, opts);\n }\n\n /**\n * Full and partial ingestion both reject foreign-owned generated fact IDs with\n * `WikiGraphNodeOwnershipConflict`. Such collisions are unexpected. Ingestion\n * may already have persisted ontology or other state before rejection; unlike\n * direct graph preflight, it relies on transaction rollback for atomicity.\n *\n * @param params.promptOverride - Overrides the system prompt for this ingest call only.\n * For persistent customization, set `options.config.prompts.ingestSystemPrompt` at\n * WikiMemory construction time.\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 opts?: { onDuplicateHash?: 'ingest' | 'skip' | 'throw' },\n ): Promise<IngestDocumentResult> {\n return this.ingestionService.ingestDocument(entityId, params, opts);\n }\n\n /**\n * Deterministic write path into the graph. Accepts caller-supplied\n * `(nodes, edges)` and writes them under `(sourceRef, sourceHash)`\n * semantics identical to `ingestDocument`, minus the LLM extraction step.\n *\n * MUST be called from inside an open `db.withTransactionAsync` callback —\n * the third argument is the caller's `tx`. The method does not open a\n * nested transaction, does not acquire any lock, and does not perform\n * post-commit work (search sync, embedding, cache eviction). Hosts that\n * want embeddings synced should drive the existing maintenance sweep\n * (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,\n * scoped via `listEntityIds`).\n *\n * Contract (full pre-flight validation lives inside\n * `IngestionService.upsertGraphCore`, which this method delegates to):\n * - C2: no-op when `(entityId, sourceHash)` is already mapped to\n * `params.sourceRef`; throws `WikiSourceRefHashCollision` if mapped to\n * a different `sourceRef`.\n * - C3: edges with dangling `targetId` are stored verbatim (no FK, no\n * resolution).\n * - C4: under persisted ontology mode `'strict'`, an out-of-manifest node\n * or edge `type` throws `WikiStrictOntologyViolation` (pre-flight,\n * all-or-nothing — NONE written on failure).\n *\n * Entry IDs share one database-wide namespace. Existing rows, including\n * soft-deleted rows, reserve their IDs for their entity; same-entity updates\n * and resurrection remain supported. Hosts authenticate callers and select\n * the authorized entity ID; entity-qualified IDs are optional, not required.\n * After the live-only C2 probe above, a foreign node ID throws the fixed,\n * privacy-preserving `WikiGraphNodeOwnershipConflict` before persistent writes\n * (including seed manifests). Deleted source mappings do not trigger C2.\n *\n * Propagate later failures to roll back the host transaction. In particular,\n * foreign edge-ID collisions remain late bare `Error`s: the foreign edge is\n * not overwritten, but catching and committing can retain earlier writes.\n * This method neither commits nor rolls back the caller's transaction.\n *\n * @returns Counts: nodesWritten (validated nodes persisted), edgesWritten\n * (manifest-valid edges persisted), superseded (prior facts soft-deleted\n * plus prior source-ref edges hard-deleted).\n */\n async upsertGraph(\n entityId: string,\n params: {\n sourceRef: string;\n sourceHash: string;\n nodes: readonly { id: string; type: string; title: string; body?: string }[];\n edges: readonly { type: string; sourceId: string; targetId: string; id?: string }[];\n },\n adapter: SQLiteAdapter,\n ): Promise<{ nodesWritten: number; edgesWritten: number; superseded: number }> {\n const sourceRef = normalizeSourceRef(params.sourceRef);\n if (!sourceRef) throw new Error('Invalid sourceRef');\n const sourceHash = normalizeSourceHash(params.sourceHash);\n if (!sourceHash) throw new Error('Invalid sourceHash (must be 64-char hex string)');\n\n // C2 probe — runs inside the caller's tx so it sees the in-flight state.\n const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash, adapter);\n if (canonical !== null && canonical === sourceRef) {\n return { nodesWritten: 0, edgesWritten: 0, superseded: 0 };\n }\n if (canonical !== null && canonical !== sourceRef) {\n throw new WikiSourceRefHashCollision({\n entityId,\n sourceHash,\n existingSourceRef: canonical,\n attemptedSourceRef: sourceRef,\n });\n }\n\n // Delegate to upsertGraphCore for steps a–j (manifest read, validation,\n // supersession, writes, returns counts). No opts.strict override — let\n // the persisted ontology mode drive strictness per the spec.\n // The host owns this transaction and core never sees its commit, so\n // diagnostics are delivered when upsertGraph resolves (spec §4.2.4).\n // Hosts that roll back should disregard them.\n const diagBuffer = new DiagnosticBuffer();\n const result = await this.ingestionService.upsertGraphCore(\n entityId,\n { sourceRef, sourceHash, nodes: params.nodes, edges: params.edges },\n adapter,\n { diag: { buffer: diagBuffer, operation: 'upsertGraph' } },\n );\n diagBuffer.flush(this.options);\n return result;\n }\n\n /**\n * Returns up to `limit` unprocessed outbox events, oldest first.\n * Works regardless of enableOutbox value — allows draining after disabling.\n */\n async getUnprocessedOutboxEvents(limit = 100): Promise<WikiOutboxEvent[]> {\n if (Number.isFinite(limit) && limit <= 0) return [];\n const safeLimit = Number.isFinite(limit) && limit >= 1 ? Math.trunc(limit) : 100;\n const rows = await this.outboxRepo.fetchPending(safeLimit);\n return rows.map(row => {\n let payload: unknown = null;\n try {\n payload = JSON.parse(row.payload);\n } catch {\n // corrupted row — surface null payload rather than poisoning the batch\n }\n return { ...row, payload } as WikiOutboxEvent;\n });\n }\n\n /**\n * Deletes the given event IDs from the outbox table.\n * Call after successfully committing events to the external system.\n */\n async markOutboxEventsProcessed(eventIds: string[]): Promise<void> {\n await this.outboxRepo.acknowledge(eventIds);\n }\n\n /**\n * Returns the effective ontology mode and manifest for an entity.\n * Resolution order: persisted DB row → `WikiConfig.ontology.seedManifests[entityId]` → `null`.\n */\n async getOntologyManifest(entityId: string): Promise<{\n mode: OntologyMode;\n manifest: OntologyManifest;\n } | null> {\n const row = await this.metadataRepo.getManifest(entityId);\n if (row) return { mode: this.ontologyService.resolveMode(row.mode), manifest: row.manifest };\n const seed = this.options.config?.ontology?.seedManifests?.[entityId];\n if (seed) {\n return {\n mode: this.ontologyService.resolveMode(seed.mode),\n manifest: seed.manifest,\n };\n }\n return null;\n }\n\n /**\n * Seeds or replaces an entity's ontology manifest and optional mode override.\n * Validates manifest invariants (unique type slugs, edge endpoints reference node types).\n * Invalidates the in-memory ontology cache for this entity.\n *\n * Delegates to `setOntologyManifests` so there is a single write path. The\n * observable contract is unchanged: same upsert semantics, same cache\n * invalidation, same `void` result.\n */\n async setOntologyManifest(\n entityId: string,\n manifest: OntologyManifest,\n options?: { mode?: OntologyMode },\n ): Promise<void> {\n await this.setOntologyManifests([{ entityId, manifest, mode: options?.mode }]);\n }\n\n /**\n * Write several entities' ontology manifests in a single transaction.\n *\n * All succeed or none do. The transaction is opened on this instance's\n * serialized adapter — callers pass data, never a transaction handle, because\n * a consumer holds the unwrapped adapter and a transaction opened on it would\n * bypass the serialization mutex applied in the constructor.\n *\n * Returns which entities were written. `skipped` is only ever non-empty under\n * `opts.ifAbsent`.\n *\n * Sharp edge: `ifAbsent` checks for a PERSISTED row, not for an effective\n * manifest. An entity whose manifest currently comes from\n * `WikiConfig.ontology.seedManifests` has no row until the seed is\n * materialized on first access that supplies a transaction (in practice, an\n * ingest). Until then `ifAbsent` treats the entity as absent, writes the new\n * manifest over the configured seed, and reports it in `written`; the same\n * call after the seed has been materialized reports it in `skipped`. See the\n * `ifAbsent` notes in the package README.\n */\n async setOntologyManifests(\n entries: Array<{\n entityId: string;\n manifest: OntologyManifest;\n mode?: OntologyMode;\n }>,\n opts?: { ifAbsent?: boolean },\n ): Promise<{ written: string[]; skipped: string[] }> {\n // Nothing to do — and deliberately no transaction, so an empty batch never\n // takes the serialization mutex.\n if (entries.length === 0) return { written: [], skipped: [] };\n\n // Two entries naming one entity express ambiguous intent. Applying the last\n // one silently would hide a caller bug whose symptom — a manifest that is\n // not the one the caller believed it wrote — surfaces far from its cause.\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.entityId)) {\n throw new Error(`Duplicate entityId in batch: ${entry.entityId}`);\n }\n seen.add(entry.entityId);\n }\n\n // Validate every manifest BEFORE opening the transaction, so a doomed batch\n // never reaches the database and never takes the mutex. `setManifest`\n // validates again inside the transaction; that is the invariant protecting\n // every other repository caller, and is not redundant with this gate.\n for (const entry of entries) {\n validateManifest(entry.manifest);\n }\n\n const written: string[] = [];\n const skipped: string[] = [];\n\n await this.db.withTransactionAsync(async (tx) => {\n for (const entry of entries) {\n const mode = entry.mode ?? this.ontologyService.resolveMode();\n const wrote = await this.metadataRepo.setManifest(\n entry.entityId,\n { mode, manifest: entry.manifest },\n tx,\n { ifAbsent: opts?.ifAbsent === true },\n );\n (wrote ? written : skipped).push(entry.entityId);\n }\n });\n\n // After a successful commit, and for EVERY entry rather than just the\n // written ones: under `ifAbsent` a skipped entry means another writer won\n // the race, so this instance's cached copy may be stale and dropping it is\n // more correct than keeping it. A failed transaction throws above and never\n // reaches this loop, which is fine — a rolled-back batch changed nothing,\n // so the cache is still consistent with the database. Invalidating is cheap\n // either way: it only drops a cached copy, and the next read reloads from\n // the database.\n for (const entry of entries) {\n this.ontologyService.invalidateCache(entry.entityId);\n }\n\n return { written, skipped };\n }\n\n /** Append a verification event to a fact. Does NOT touch `updated_at`. */\n async writeOkfTrust(entryId: string, entityId: string, verified: { by: string; at: string }[]): Promise<void> {\n return this.okfTrustWrites.writeOkfTrust(entryId, entityId, verified);\n }\n\n /** Replace a fact's source list. Does NOT touch `updated_at`. */\n async writeOkfSources(entryId: string, entityId: string, sources: Array<{ resource: string; [k: string]: unknown }>): Promise<void> {\n return this.okfTrustWrites.writeOkfSources(entryId, entityId, sources as any);\n }\n\n /** Set a fact's OKF v0.2 lifecycle status. Does NOT touch `updated_at`. */\n async setLifecycleStatus(entryId: string, entityId: string, status: 'draft' | 'stable' | 'deprecated'): Promise<void> {\n return this.okfTrustWrites.setLifecycleStatus(entryId, entityId, status);\n }\n\n /**\n * Live draft facts for one entity, newest first (spec §5.2). Default page\n * size 50, clamped to [1, 500]. Pass `nextCursor` back unchanged for the next page.\n */\n async listDrafts(entityId: string, options?: { limit?: number; cursor?: string }): Promise<DraftPage> {\n const rawLimit = options?.limit;\n const limit = typeof rawLimit === 'number' && Number.isFinite(rawLimit)\n ? Math.min(500, Math.max(1, Math.floor(rawLimit)))\n : 50;\n const after = options?.cursor === undefined ? null : decodeDraftCursor(options.cursor);\n const rows = await this.entryRepo.listDraftsByEntityId(entityId, limit + 1, after);\n const facts = rows.slice(0, limit);\n const last = facts[facts.length - 1];\n return {\n facts,\n nextCursor: rows.length > limit && last ? `${last.created_at}:${last.id}` : null,\n };\n }\n\n /**\n * Promote a draft to `stable` and record who reviewed it, atomically\n * (spec §5.2). Metadata writes only: `updated_at` is not bumped and no\n * outbox event is pushed. Pass `by: 'human:<id>'` so `trustTier` becomes\n * `'human-reviewed'`.\n *\n * @throws WikiDraftNotFound when no live draft with that id exists for the entity.\n */\n async promoteDraft(entryId: string, entityId: string, reviewer: { by: string }): Promise<void> {\n const by = reviewer?.by;\n if (typeof by !== 'string' || by.trim().length === 0) {\n throw new TypeError('promoteDraft requires reviewer.by to be a non-empty string.');\n }\n await this.db.withTransactionAsync(async (tx) => {\n if (!(await this.entryRepo.isLiveDraft(entryId, entityId, tx))) {\n throw new WikiDraftNotFound();\n }\n await this.okfTrustWrites.setLifecycleStatus(entryId, entityId, 'stable', tx);\n await this.okfTrustWrites.writeOkfTrust(entryId, entityId, [{ by, at: new Date().toISOString() }], tx);\n });\n }\n\n /** Set a fact's stale_after (epoch ms) or clear it. Does NOT touch `updated_at`. */\n async setStaleAfter(entryId: string, entityId: string, date: number | null): Promise<void> {\n return this.okfTrustWrites.setStaleAfter(entryId, entityId, date);\n }\n\n /** Set a fact's generated_by actor string. Does NOT touch `updated_at`. */\n async setGeneratedBy(entryId: string, entityId: string, actor: string): Promise<void> {\n return this.okfTrustWrites.setGeneratedBy(entryId, entityId, actor);\n }\n\n /** Task variants of the same five DAO methods. Symmetric per spec §2.5. */\n async writeOkfTrustTask(taskId: string, entityId: string, verified: { by: string; at: string }[]): Promise<void> {\n return this.okfTrustWrites.writeOkfTrustTask(taskId, entityId, verified);\n }\n async writeOkfSourcesTask(taskId: string, entityId: string, sources: Array<{ resource: string; [k: string]: unknown }>): Promise<void> {\n return this.okfTrustWrites.writeOkfSourcesTask(taskId, entityId, sources as any);\n }\n async setLifecycleStatusTask(taskId: string, entityId: string, status: 'draft' | 'stable' | 'deprecated'): Promise<void> {\n return this.okfTrustWrites.setLifecycleStatusTask(taskId, entityId, status);\n }\n async setStaleAfterTask(taskId: string, entityId: string, date: number | null): Promise<void> {\n return this.okfTrustWrites.setStaleAfterTask(taskId, entityId, date);\n }\n async setGeneratedByTask(taskId: string, entityId: string, actor: string): Promise<void> {\n return this.okfTrustWrites.setGeneratedByTask(taskId, entityId, actor);\n }\n}\n\nexport const __testables = { validateFact, validateTask, clip, chunkText };\n","import type { MemoryBundle, WikiFact, WikiTask, WikiEvent, FormatContextOptions } from '../types';\n\nfunction validateMaxOption(value: number, name: string): void {\n if (!isFinite(value) || value < 0) {\n throw new Error(`Invalid ${name}: must be a non-negative finite number`);\n }\n}\n\nconst CONFIDENCE_WEIGHT: Record<string, number> = {\n certain: 1.0,\n inferred: 0.6,\n tentative: 0.3,\n};\n\nfunction scoreFactFor(\n fact: WikiFact,\n weights: Required<NonNullable<FormatContextOptions['factWeights']>>,\n now: number\n): number {\n const confW = CONFIDENCE_WEIGHT[fact.confidence] ?? 0.3;\n const ageDays = (now - fact.updated_at) / 86400000;\n const recencyDecay = Math.exp(-ageDays / 30);\n return (\n confW * weights.confidence +\n Math.log(1 + fact.access_count) * weights.accessCount +\n recencyDecay * weights.recency\n );\n}\n\nfunction renderFactMarkdown(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `- **${fact.title}**${confPart}${tagPart}${sourcePart}${scorePart}\\n ${fact.body.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderFactPlain(\n fact: WikiFact,\n includeConfidence: boolean,\n includeTags: boolean,\n includeEntityIds: boolean,\n score: number | undefined,\n): string {\n const confPart = includeConfidence ? ` (${fact.confidence})` : '';\n const tagPart = includeTags && fact.tags.length > 0 ? ` [${fact.tags.join(', ')}]` : '';\n const sourcePart = includeEntityIds ? ` {entity_id=${fact.entity_id}}` : '';\n const scorePart = score !== undefined ? ` {score=${score.toFixed(4)}}` : '';\n return `${fact.title}${confPart}${tagPart}${sourcePart}${scorePart}: ${fact.body}`;\n}\n\nfunction renderTaskMarkdown(task: WikiTask): string {\n return `- [P${task.priority}] ${task.description.replace(/\\n/g, '\\n ')} (${task.status})`;\n}\n\nfunction renderTaskPlain(task: WikiTask): string {\n return `[P${task.priority}] ${task.description} (${task.status})`;\n}\n\nfunction renderEventMarkdown(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `- [${event.event_type} @ ${ts}] ${event.summary.replace(/\\n/g, '\\n ')}`;\n}\n\nfunction renderEventPlain(event: WikiEvent): string {\n const ts = new Date(event.created_at).toISOString();\n return `[${event.event_type} @ ${ts}] ${event.summary}`;\n}\n\nexport function formatContext(\n bundle: MemoryBundle,\n options?: FormatContextOptions\n): string {\n const opts: Required<FormatContextOptions> = {\n format: options?.format ?? 'markdown',\n maxFacts: options?.maxFacts ?? 10,\n maxTasks: options?.maxTasks ?? 10,\n maxEvents: options?.maxEvents ?? 10,\n includeConfidence: options?.includeConfidence ?? true,\n includeTags: options?.includeTags ?? true,\n includeEntityIds: options?.includeEntityIds ?? false,\n includeFactScores: options?.includeFactScores ?? false,\n factWeights: {\n confidence: options?.factWeights?.confidence ?? 1.0,\n accessCount: options?.factWeights?.accessCount ?? 0.3,\n recency: options?.factWeights?.recency ?? 0.5,\n },\n };\n\n validateMaxOption(opts.maxFacts, 'maxFacts');\n validateMaxOption(opts.maxTasks, 'maxTasks');\n validateMaxOption(opts.maxEvents, 'maxEvents');\n\n const weights = opts.factWeights as Required<NonNullable<FormatContextOptions['factWeights']>>;\n\n const now = Date.now();\n const sortedFacts = bundle.factScores\n ? [...bundle.facts].slice(0, opts.maxFacts)\n : [...bundle.facts]\n .sort((a, b) => scoreFactFor(b, weights, now) - scoreFactFor(a, weights, now))\n .slice(0, opts.maxFacts);\n\n const sortedTasks = [...bundle.tasks]\n .sort((a, b) => b.priority - a.priority || a.created_at - b.created_at)\n .slice(0, opts.maxTasks);\n\n const sortedEvents = [...bundle.events]\n .sort((a, b) => b.created_at - a.created_at)\n .slice(0, opts.maxEvents);\n\n if (sortedFacts.length === 0 && sortedTasks.length === 0 && sortedEvents.length === 0) {\n return '';\n }\n\n const isMarkdown = opts.format === 'markdown';\n const lines: string[] = [];\n\n if (isMarkdown) {\n lines.push('## Memory');\n\n if (sortedFacts.length > 0) {\n lines.push('');\n lines.push('### Known Facts');\n for (const fact of sortedFacts) {\n lines.push(renderFactMarkdown(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n\n if (sortedTasks.length > 0) {\n lines.push('');\n lines.push('### Open Tasks');\n for (const task of sortedTasks) {\n lines.push(renderTaskMarkdown(task));\n }\n }\n\n if (sortedEvents.length > 0) {\n lines.push('');\n lines.push('### Recent Events');\n for (const event of sortedEvents) {\n lines.push(renderEventMarkdown(event));\n }\n }\n } else {\n if (sortedFacts.length > 0) {\n lines.push('KNOWN FACTS:');\n for (const fact of sortedFacts) {\n lines.push(renderFactPlain(fact, opts.includeConfidence, opts.includeTags, opts.includeEntityIds, opts.includeFactScores ? bundle.factScores?.[fact.id] : undefined));\n }\n }\n if (sortedTasks.length > 0) {\n lines.push('OPEN TASKS:');\n for (const task of sortedTasks) {\n lines.push(renderTaskPlain(task));\n }\n }\n if (sortedEvents.length > 0) {\n lines.push('RECENT EVENTS:');\n for (const event of sortedEvents) {\n lines.push(renderEventPlain(event));\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import type { GraphNeighborhood, WikiEdge } from '../types';\n\n/**\n * Pure presenter — dense text serialization of a GraphNeighborhood for LLM prompt\n * injection. Deterministic: same input always produces byte-identical output\n * (matters for prompt caching).\n */\nexport function formatGraphContext(neighborhood: GraphNeighborhood): string {\n const { nodes, edges } = neighborhood;\n if (nodes.length === 0) return '';\n\n const nodeById = new Map(nodes.map((n) => [n.id, n]));\n const nodeIndex = new Map(nodes.map((n, i) => [n.id, i]));\n const lines: string[] = [];\n\n for (const node of nodes) {\n lines.push(`[${node.okf_type ?? 'fact'}] ${node.title} (ID: ${node.id})`);\n\n const outbound = edgesByDirection(edges, node.id, 'source_id', nodeById, nodeIndex);\n const inbound = edgesByDirection(edges, node.id, 'target_id', nodeById, nodeIndex);\n\n for (const { edge, other } of outbound) {\n lines.push(` -[${edge.edge_type}]-> [${other.okf_type ?? 'fact'}] ${other.title}`);\n }\n for (const { edge, other } of inbound) {\n lines.push(` <-[${edge.edge_type}]- [${other.okf_type ?? 'fact'}] ${other.title}`);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction edgesByDirection(\n edges: WikiEdge[],\n nodeId: string,\n endpoint: 'source_id' | 'target_id',\n nodeById: Map<string, GraphNeighborhood['nodes'][number]>,\n nodeIndex: Map<string, number>,\n) {\n const otherEndpoint = endpoint === 'source_id' ? 'target_id' : 'source_id';\n return edges\n .filter((e) => e[endpoint] === nodeId)\n .filter((e) => {\n const otherId = e[otherEndpoint];\n const selfIdx = nodeIndex.get(nodeId)!;\n const otherIdx = nodeIndex.get(otherId);\n return otherIdx !== undefined && selfIdx < otherIdx;\n })\n .map((edge) => ({ edge, other: nodeById.get(edge[otherEndpoint])! }))\n .sort(\n (a, b) =>\n a.edge.edge_type.localeCompare(b.edge.edge_type) ||\n a.other.title.localeCompare(b.other.title) ||\n a.other.id.localeCompare(b.other.id) ||\n a.edge.id.localeCompare(b.edge.id),\n );\n}\n","function shortHash(value: string): string {\n let h1 = 5381;\n let h2 = 52711;\n for (let i = 0; i < value.length; i += 1) {\n const c = value.charCodeAt(i);\n h1 = Math.imul(h1, 33) ^ c;\n h2 = Math.imul(h2, 31) ^ c;\n }\n return (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0');\n}\n\nconst OKF_RESERVED_CONCEPT_NAMES = new Set(['index', 'log']);\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n 'con',\n 'prn',\n 'aux',\n 'nul',\n 'com1',\n 'com2',\n 'com3',\n 'com4',\n 'com5',\n 'com6',\n 'com7',\n 'com8',\n 'com9',\n 'lpt1',\n 'lpt2',\n 'lpt3',\n 'lpt4',\n 'lpt5',\n 'lpt6',\n 'lpt7',\n 'lpt8',\n 'lpt9',\n]);\n\nfunction isWindowsReservedName(name: string): boolean {\n const base = name.split('.')[0];\n return WINDOWS_RESERVED_NAMES.has(base.toLowerCase());\n}\n\nexport function sanitizeForFilename(value: string): string {\n const normalized = value.normalize('NFKC');\n const sanitized = normalized\n .replace(/[^A-Za-z0-9._-]+/g, '_')\n .replace(/^\\.+/, '_')\n .replace(/_+/g, '_')\n .replace(/^[_-]+|[_-]+$/g, '');\n\n // Enforce a max base-name length so the final filename stays within typical\n // filesystem limits (~255 bytes). Reserve ~20 chars for `-<16hexchars>`.\n const MAX_BASE = 200;\n const trimmed = sanitized.length > MAX_BASE ? sanitized.slice(0, MAX_BASE) : sanitized;\n\n let baseName = trimmed && trimmed !== '.' && trimmed !== '..' ? trimmed : 'entity';\n\n // Windows disallows trailing dots and spaces in filenames.\n const withoutTrailingDotSpace = baseName.replace(/[. ]+$/, '');\n const hadTrailingDotSpace = withoutTrailingDotSpace !== baseName;\n if (hadTrailingDotSpace) {\n baseName = withoutTrailingDotSpace || 'entity';\n }\n\n const windowsReserved = isWindowsReservedName(baseName);\n const needsSuffix =\n baseName !== value || sanitized.length > MAX_BASE || hadTrailingDotSpace || windowsReserved;\n\n if (!needsSuffix) return baseName;\n\n const suffix = `-${shortHash(value)}`;\n return `${baseName}${suffix}`;\n}\n\n/** Sanitize a fact/task id for use as a concept filename (without .md). */\nexport function sanitizeConceptId(id: string): string {\n const sanitized = sanitizeForFilename(id);\n if (OKF_RESERVED_CONCEPT_NAMES.has(sanitized.toLowerCase())) {\n return `${sanitized}-${shortHash(id)}`;\n }\n return sanitized;\n}\n","import type { MemoryDump, FormattedMemoryDump, MemoryBundle, WikiFact, WikiTask, WikiEvent } from '../types';\nimport { sanitizeForFilename } from './sanitizeForFilename';\n\nfunction renderFact(f: WikiFact): string {\n const tags = (f.tags || []).join(', ');\n const source = f.source_ref ?? f.source_type;\n return `### ${f.title}\n**Tags:** ${tags}\n**Confidence:** ${f.confidence}\n**Source:** ${source}\n\n${f.body}\n\n---\n`;\n}\n\nfunction renderTask(t: WikiTask): string {\n const checked = t.status === 'done' ? 'x' : ' ';\n const note = t.status === 'done' ? ' (done)'\n : t.status === 'abandoned' ? ' (abandoned)'\n : t.status === 'in_progress' ? ' (in progress)'\n : '';\n return `- [${checked}] ${t.description}${note}\\n`;\n}\n\nfunction renderEvent(e: WikiEvent): string {\n const ts = new Date(e.created_at).toISOString();\n return `- [${ts}] (${e.event_type}) ${e.summary}\\n`;\n}\n\nfunction renderEntity(entityId: string, bundle: MemoryBundle, generatedAt: number): string {\n const lines: string[] = [];\n lines.push(`# Memory Dump: ${entityId}`);\n lines.push(`Generated: ${new Date(generatedAt).toISOString()}`);\n lines.push('');\n lines.push('## Facts');\n lines.push('');\n if (bundle.facts.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const f of bundle.facts) lines.push(renderFact(f));\n }\n lines.push('## Tasks');\n lines.push('');\n if (bundle.tasks.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const t of bundle.tasks) lines.push(renderTask(t));\n }\n lines.push('');\n lines.push('## Recent Events');\n lines.push('');\n if (bundle.events.length === 0) {\n lines.push('_(none)_\\n');\n } else {\n for (const e of bundle.events) lines.push(renderEvent(e));\n }\n return lines.join('\\n');\n}\n\nfunction formatEntityFileName(entityId: string): string {\n return `${sanitizeForFilename(entityId)}.md`;\n}\n\nexport function formatMemoryDump(dump: MemoryDump): FormattedMemoryDump {\n const files = Object.entries(dump.entities).map(([entityId, bundle]) => ({\n name: formatEntityFileName(entityId),\n content: renderEntity(entityId, bundle, dump.generatedAt),\n }));\n\n // Strip embedding_blob from each fact before JSON-serialising the manifest.\n // exportDump() now includes raw Uint8Array blobs for importDump() round-trips,\n // but those binaries serve no purpose in a human-readable manifest and can\n // massively inflate its size for non-trivial datasets.\n const manifestDump: MemoryDump = {\n generatedAt: dump.generatedAt,\n entities: Object.fromEntries(\n Object.entries(dump.entities).map(([entityId, bundle]) => [\n entityId,\n {\n ...bundle,\n facts: bundle.facts.map(f => {\n const { embedding_blob: _blob, ...rest } = f as WikiFact & { embedding_blob?: unknown };\n return rest as WikiFact;\n }),\n },\n ])\n ),\n };\n\n return {\n manifest: JSON.stringify(manifestDump, null, 2),\n files,\n };\n}\n","import type { MemoryDump, WikiEdge, WikiFact, WikiTask, WikiEvent } from '../types';\nimport {\n appendEventIdComment,\n appendRelatedSection,\n buildConceptDocument,\n buildEntityIndexMd,\n buildRootIndexMd,\n buildLogMd,\n serializeActorString,\n type OkfFile,\n type OkfFrontmatter,\n type OkfIndexEntry,\n type OkfIndexSection,\n type OkfLogEntry,\n} from '@equationalapplications/core-okf';\nimport { sanitizeConceptId, sanitizeForFilename } from './sanitizeForFilename';\n\nexport type OkfFormatProfile = 'llm-wiki/1' | 'llm-wiki/2';\n\nexport interface FormatOkfBundleOptions {\n /** Defaults to 'llm-wiki/2'. Pass 'llm-wiki/1' to force the v0.1 subset. */\n profile?: OkfFormatProfile;\n}\n\nconst DEFAULT_PROFILE: OkfFormatProfile = 'llm-wiki/2';\n\n/**\n * Format an epoch-ms timestamp as ISO 8601 with a double fallback:\n * 1. NaN / Infinity / non-finite -> epoch (0).\n * 2. Outside JS Date's representable range (e.g. 1e300) -> epoch.\n * `new Date(finite).toISOString()` throws RangeError only when the value is\n * outside the supported range; a finite but absurd number still throws. We\n * validate the constructed Date before calling toISOString so the helper\n * never aborts the bundle export.\n */\nfunction isoOrFallback(updatedAt: number): string {\n if (!Number.isFinite(updatedAt)) return new Date(0).toISOString();\n const d = new Date(updatedAt);\n if (!Number.isFinite(d.getTime())) return new Date(0).toISOString();\n return d.toISOString();\n}\n\nfunction isoDateOrOmit(ms: number | null | undefined): string | undefined {\n if (ms == null || !Number.isFinite(ms)) return undefined;\n const d = new Date(ms);\n if (!Number.isFinite(d.getTime())) return undefined;\n return d.toISOString().slice(0, 10);\n}\n\nfunction factFrontmatterV2(f: WikiFact): OkfFrontmatter {\n return {\n type: f.okf_type ?? 'fact',\n title: f.title,\n tags: f.tags,\n // `timestamp` rides along deliberately even on the v0.2 path — a naive\n // consumer that only understands the v0.1 key still gets a readable date\n // without needing flow-mapping support. `generated.at` is the canonical\n // v0.2 field and always wins on import when both are present (spec §2.4).\n timestamp: isoOrFallback(f.updated_at),\n resource: f.source_ref ?? undefined,\n id: f.id,\n entity_id: f.entity_id,\n confidence: f.confidence,\n source_type: f.source_type,\n source_hash: f.source_hash,\n created_at: f.created_at,\n access_count: f.access_count,\n last_accessed_at: f.last_accessed_at,\n deleted_at: f.deleted_at,\n // OKF v0.2\n status: f.lifecycle_status ?? 'stable',\n ...(isoDateOrOmit(f.stale_after) ? { stale_after: isoDateOrOmit(f.stale_after) } : {}),\n // Omit `generated` entirely when there's no actor on record — never\n // fabricate a `generated_by` (mirrors the import side's rule in §4.8:\n // it never invents one either, so export must not manufacture one that\n // would then round-trip back in as if it had always been asserted).\n ...(f.generated_by ? { generated: { by: f.generated_by, at: isoOrFallback(f.updated_at) } } : {}),\n // Omit `verified`/`sources` when empty — an emitted `[]` is not the same\n // shape as an absent key (spec §5.3 derives `unverified` from \"no\n // `verified` key\", not from \"empty `verified` list\").\n ...(f.okf_verified && f.okf_verified.length > 0 ? { verified: f.okf_verified } : {}),\n ...(f.okf_sources && f.okf_sources.length > 0 ? { sources: f.okf_sources } : {}),\n ...(f.okf_usage_window ? { usage_window: f.okf_usage_window } : {}),\n };\n}\n\nfunction taskFrontmatterV2(t: WikiTask): OkfFrontmatter {\n return {\n type: t.okf_type ?? 'task',\n title: t.description,\n timestamp: isoOrFallback(t.updated_at), // see factFrontmatterV2 comment — deliberate back-compat duplication\n id: t.id,\n entity_id: t.entity_id,\n status: t.lifecycle_status ?? 'stable', // OKF v0.2 lifecycle\n execution_status: t.status, // execution state under renamed key\n priority: t.priority,\n created_at: t.created_at,\n resolved_at: t.resolved_at,\n deleted_at: t.deleted_at,\n // OKF v0.2 — symmetric with facts (spec §2.5): stale_after applies to\n // tasks too (a hallucinated task needs a freshness signal as much as a\n // hallucinated fact does).\n ...(isoDateOrOmit(t.stale_after) ? { stale_after: isoDateOrOmit(t.stale_after) } : {}),\n ...(t.generated_by ? { generated: { by: t.generated_by, at: isoOrFallback(t.updated_at) } } : {}),\n ...(t.okf_verified && t.okf_verified.length > 0 ? { verified: t.okf_verified } : {}),\n ...(t.okf_sources && t.okf_sources.length > 0 ? { sources: t.okf_sources } : {}),\n ...(t.okf_usage_window ? { usage_window: t.okf_usage_window } : {}),\n };\n}\n\nfunction factFrontmatterV1(f: WikiFact): OkfFrontmatter {\n return {\n type: f.okf_type ?? 'fact',\n title: f.title,\n tags: f.tags,\n timestamp: isoOrFallback(f.updated_at),\n resource: f.source_ref ?? undefined,\n id: f.id,\n entity_id: f.entity_id,\n confidence: f.confidence,\n source_type: f.source_type,\n source_hash: f.source_hash,\n created_at: f.created_at,\n access_count: f.access_count,\n last_accessed_at: f.last_accessed_at,\n deleted_at: f.deleted_at,\n };\n}\n\nfunction taskFrontmatterV1(t: WikiTask): OkfFrontmatter {\n return {\n type: t.okf_type ?? 'task',\n title: t.description,\n timestamp: isoOrFallback(t.updated_at),\n id: t.id,\n entity_id: t.entity_id,\n status: t.status,\n priority: t.priority,\n created_at: t.created_at,\n resolved_at: t.resolved_at,\n deleted_at: t.deleted_at,\n };\n}\n\nfunction formatLogDate(timestampMs: number): string {\n return new Date(timestampMs).toISOString().slice(0, 10);\n}\n\nfunction conceptRelativePath(sourceFilePath: string, targetFilePath: string): string {\n const sourceDir = sourceFilePath.slice(0, sourceFilePath.lastIndexOf('/'));\n const targetDir = targetFilePath.slice(0, targetFilePath.lastIndexOf('/'));\n const targetName = targetFilePath.slice(targetFilePath.lastIndexOf('/') + 1);\n if (sourceDir === targetDir) return `./${targetName}`;\n if (sourceDir.endsWith('/facts') && targetDir.endsWith('/tasks')) return `../tasks/${targetName}`;\n if (sourceDir.endsWith('/tasks') && targetDir.endsWith('/facts')) return `../facts/${targetName}`;\n return targetFilePath.replace(/^entities\\/[^/]+\\//, '');\n}\n\nfunction buildEventLogEntries(\n events: WikiEvent[],\n factIdToFilename: Map<string, string>,\n): OkfLogEntry[] {\n return events.map(e => {\n const factFilename = e.related_entry_id ? factIdToFilename.get(e.related_entry_id) : undefined;\n const summary = e.summary\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\\r?\\n/g, ' ');\n\n const text = factFilename\n ? `(${e.event_type}) [${summary}](./facts/${factFilename}.md)`\n : `(${e.event_type}) ${summary}`;\n return { date: formatLogDate(e.created_at), text: appendEventIdComment(text, e.id) };\n });\n}\n\nexport function formatOkfBundle(\n dump: MemoryDump,\n options?: FormatOkfBundleOptions,\n): { files: OkfFile[] } {\n const profile: OkfFormatProfile = options?.profile ?? DEFAULT_PROFILE;\n const okfVersion = profile === 'llm-wiki/2' ? '0.2' : '0.1';\n const factFm = profile === 'llm-wiki/2' ? factFrontmatterV2 : factFrontmatterV1;\n const taskFm = profile === 'llm-wiki/2' ? taskFrontmatterV2 : taskFrontmatterV1;\n\n const files: OkfFile[] = [];\n const rootEntries: OkfIndexEntry[] = [];\n\n for (const [entityId, bundle] of Object.entries(dump.entities)) {\n const dir = sanitizeForFilename(entityId);\n const factIdToFilename = new Map(\n bundle.facts.map(f => [f.id, sanitizeConceptId(f.id)] as const),\n );\n\n const idToConceptPath = new Map<string, string>();\n for (const f of bundle.facts) {\n idToConceptPath.set(f.id, `entities/${dir}/facts/${factIdToFilename.get(f.id)!}.md`);\n }\n for (const t of bundle.tasks) {\n idToConceptPath.set(t.id, `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`);\n }\n\n const edgesBySource = new Map<string, WikiEdge[]>();\n for (const edge of bundle.edges ?? []) {\n const group = edgesBySource.get(edge.source_id) ?? [];\n group.push(edge);\n edgesBySource.set(edge.source_id, group);\n }\n\n function relatedLinksFor(sourcePath: string, sourceId: string) {\n return (edgesBySource.get(sourceId) ?? [])\n .map(edge => {\n const targetPath = idToConceptPath.get(edge.target_id);\n if (!targetPath) return null;\n return { edge_type: edge.edge_type, path: conceptRelativePath(sourcePath, targetPath) };\n })\n .filter((link): link is { edge_type: string; path: string } => link != null);\n }\n\n const factEntries: OkfIndexEntry[] = bundle.facts.map(f => ({\n path: `facts/${factIdToFilename.get(f.id)!}.md`,\n title: f.title,\n }));\n for (const f of bundle.facts) {\n const factPath = `entities/${dir}/facts/${factIdToFilename.get(f.id)!}.md`;\n const factBody = appendRelatedSection(f.body, relatedLinksFor(factPath, f.id));\n files.push({\n path: factPath,\n content: buildConceptDocument(factFm(f), factBody),\n });\n }\n\n const taskEntries: OkfIndexEntry[] = bundle.tasks.map(t => ({\n path: `tasks/${sanitizeConceptId(t.id)}.md`,\n title: t.description,\n }));\n for (const t of bundle.tasks) {\n const taskPath = `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`;\n const taskBody = appendRelatedSection('', relatedLinksFor(taskPath, t.id));\n files.push({\n path: taskPath,\n content: buildConceptDocument(taskFm(t), taskBody),\n });\n }\n\n files.push({\n path: `entities/${dir}/log.md`,\n content: buildLogMd(buildEventLogEntries(bundle.events, factIdToFilename)),\n });\n\n const entityIndexSections: OkfIndexSection[] = [\n { heading: 'Facts', entries: factEntries },\n { heading: 'Tasks', entries: taskEntries },\n ];\n files.push({\n path: `entities/${dir}/index.md`,\n content: buildEntityIndexMd({\n summary: bundle.summary,\n sections: entityIndexSections,\n }),\n });\n\n rootEntries.push({ path: `entities/${dir}/index.md`, title: entityId });\n }\n\n files.push({\n path: 'index.md',\n content: buildRootIndexMd(\n okfVersion,\n rootEntries.length > 0 ? [{ heading: 'Entities', entries: rootEntries }] : [],\n { profile },\n ),\n });\n\n return { files };\n}","import type { MemoryDump, WikiFact, WikiTask, WikiEvent, WikiEdge } from '../types';\nimport type { OkfFile, OkfFrontmatter, OkfFrontmatterValue } from '@equationalapplications/core-okf';\nimport {\n parseConcept,\n parseLogMd,\n parseRootIndexMd,\n parseEntityIndexMd,\n parseEventIdComment,\n splitRelatedSection,\n isAllowedOkfPath,\n extractMarkdownLinks,\n parseVerifiedFlexible,\n parseCitationsList,\n latestVerified,\n formatVerifiedJson,\n formatSourcesJson,\n type OkfSource,\n type OkfVerified,\n} from '@equationalapplications/core-okf';\nimport { generateId } from './ids';\n\nexport interface OkfImportOptions {\n typeMapping?: Record<string, 'fact' | 'task' | 'ignore'>;\n defaultSchema?: 'fact' | 'task' | 'ignore';\n}\n\ntype Route = 'fact' | 'task' | 'ignore';\n\nconst CONFIDENCE_VALUES = new Set(['certain', 'inferred', 'tentative']);\nconst SOURCE_TYPES = new Set([\n 'user_stated',\n 'librarian_inferred',\n 'user_confirmed',\n 'immutable_document',\n]);\nconst TASK_STATUSES = new Set(['pending', 'in_progress', 'done', 'abandoned']);\nconst EVENT_TYPES = new Set(['observation', 'decision', 'action', 'outcome']);\n\nfunction basenameMd(filePath: string): string {\n const name = filePath.slice(filePath.lastIndexOf('/') + 1);\n return name.endsWith('.md') ? name.slice(0, -3) : name;\n}\n\nfunction isConceptFile(filePath: string): boolean {\n if (!filePath.endsWith('.md')) return false;\n if (filePath.endsWith('/index.md') || filePath === 'index.md') return false;\n if (filePath.endsWith('/log.md') || filePath === 'log.md') return false;\n return true;\n}\n\nfunction isStructuralPath(filePath: string): boolean {\n return (\n filePath.endsWith('/index.md') ||\n filePath === 'index.md' ||\n filePath.endsWith('/log.md') ||\n filePath === 'log.md'\n );\n}\n\nfunction posixDirname(filePath: string): string {\n const idx = filePath.lastIndexOf('/');\n return idx === -1 ? '' : filePath.slice(0, idx);\n}\n\nfunction resolveRelativePath(fromFile: string, linkPath: string): string {\n const baseDir = posixDirname(fromFile);\n const segments = [...(baseDir ? baseDir.split('/') : []), ...linkPath.split('/')];\n const resolved: string[] = [];\n for (const seg of segments) {\n if (seg === '' || seg === '.') continue;\n if (seg === '..') {\n resolved.pop();\n continue;\n }\n resolved.push(seg);\n }\n return resolved.join('/');\n}\n\nfunction decodeLinkPath(path: string): string {\n if (!path.includes('%')) return path;\n try {\n return decodeURIComponent(path);\n } catch {\n return path;\n }\n}\n\nfunction addPathAliases(map: Map<string, string>, filePath: string, resolvedId: string): void {\n map.set(filePath, resolvedId);\n const withoutDot = filePath.replace(/^\\.\\//, '');\n if (withoutDot !== filePath) map.set(withoutDot, resolvedId);\n const entityRelative = filePath.replace(/^entities\\/[^/]+\\//, '');\n if (entityRelative !== filePath) {\n map.set(entityRelative, resolvedId);\n map.set(`./${entityRelative}`, resolvedId);\n }\n}\n\nfunction lookupResolvedId(map: Map<string, string>, path: string): string | undefined {\n const normalized = path.replace(/^\\.\\//, '');\n return map.get(path) ?? map.get(normalized) ?? map.get(`./${normalized}`);\n}\n\nfunction stripLinkSuffix(linkPath: string): string {\n const hashIdx = linkPath.indexOf('#');\n const queryIdx = linkPath.indexOf('?');\n if (hashIdx === -1 && queryIdx === -1) return linkPath;\n const cut =\n hashIdx === -1 ? queryIdx : queryIdx === -1 ? hashIdx : Math.min(hashIdx, queryIdx);\n return linkPath.slice(0, cut);\n}\n\nfunction resolveRoute(filePath: string, frontmatterType: string, options?: OkfImportOptions): Route {\n if (\n options?.typeMapping &&\n Object.prototype.hasOwnProperty.call(options.typeMapping, frontmatterType)\n ) {\n return options.typeMapping[frontmatterType]!;\n }\n if (filePath.includes('/facts/')) return 'fact';\n if (filePath.includes('/tasks/')) return 'task';\n return options?.defaultSchema ?? 'fact';\n}\n\nfunction parseFrontmatterTimestamp(value: OkfFrontmatterValue | undefined, fallback: number): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const parsed = Date.parse(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return fallback;\n}\n\n/**\n * Parse an OKF v0.2 `stale_after` YYYY-MM-DD wire string into an epoch ms\n * value. Returns null on non-string, regex mismatch, or a calendar-invalid\n * date — the previous inline regex accepted any three numeric components, so\n * `2026-13-45` would yield NaN and crash the SQLite bind downstream.\n */\nfunction parseStaleAfterRaw(raw: unknown): number | null {\n if (typeof raw !== 'string') return null;\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(raw);\n if (!m) return null;\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n const ms = Date.UTC(year, month - 1, day);\n if (!Number.isFinite(ms)) return null;\n // Reject calendar-invalid dates that Date.UTC silently normalizes (e.g.\n // 2025-02-29 → 2025-03-01). Compare the round-tripped components.\n const d = new Date(ms);\n if (\n d.getUTCFullYear() !== year ||\n d.getUTCMonth() + 1 !== month ||\n d.getUTCDate() !== day\n ) {\n return null;\n }\n return ms;\n}\n\nfunction unescapeLogSummary(summary: string): string {\n return summary.replace(/\\\\\\]/g, ']').replace(/\\\\\\[/g, '[').replace(/\\\\\\\\/g, '\\\\');\n}\n\nconst LOG_LINE_PATTERN = /^\\(([^)]+)\\)\\s*(?:\\[((?:\\\\.|[^\\]])*)\\]\\(([^)]+)\\)|(.+))$/;\n\nfunction parseLogEntryText(text: string): {\n event_type: WikiEvent['event_type'];\n summary: string;\n linkPath?: string;\n} | null {\n const match = LOG_LINE_PATTERN.exec(text.trim());\n if (!match) return null;\n const [, rawType, linkedSummary, linkPath, plainSummary] = match;\n const event_type = EVENT_TYPES.has(rawType) ? (rawType as WikiEvent['event_type']) : 'observation';\n if (linkPath) {\n return { event_type, summary: unescapeLogSummary(linkedSummary), linkPath };\n }\n return { event_type, summary: (plainSummary ?? '').trim() };\n}\n\nfunction frontmatterToFact(\n entityId: string,\n id: string,\n frontmatter: OkfFrontmatter,\n body: string,\n now: number,\n): WikiFact {\n const created_at = parseFrontmatterTimestamp(frontmatter.created_at, now);\n // Precedence (spec §2.4): v0.2 `generated.at` -> v0.1 `timestamp` -> legacy\n // `updated_at` -> `now`. The previous order swapped `updated_at` ahead of\n // the other two, so a present-but-finite `updated_at` clobbered\n // `generated.at`. We nest the fallbacks so the first finite wins.\n const updated_at = parseFrontmatterTimestamp(\n (frontmatter as any).generated?.at,\n parseFrontmatterTimestamp(\n frontmatter.timestamp,\n parseFrontmatterTimestamp(frontmatter.updated_at, now),\n ),\n );\n\n const verified: OkfVerified = parseVerifiedFlexible((frontmatter as any).verified);\n const rawSources = (frontmatter as any).sources;\n const hasSourcesKey = rawSources !== undefined;\n const sources: OkfSource[] = Array.isArray(rawSources) ? rawSources as OkfSource[] : [];\n const usageWindow = (frontmatter as any).usage_window && typeof (frontmatter as any).usage_window === 'object'\n ? (frontmatter as any).usage_window as { from: string; to: string }\n : null;\n const lastV = latestVerified(verified, now);\n const lifecycleRaw = (frontmatter as any).status;\n const lifecycle_status: 'draft' | 'stable' | 'deprecated' =\n lifecycleRaw === 'draft' || lifecycleRaw === 'stable' || lifecycleRaw === 'deprecated'\n ? lifecycleRaw : 'stable';\n const staleAfterRaw = (frontmatter as any).stale_after;\n const stale_after = parseStaleAfterRaw(staleAfterRaw);\n const generated_by = (frontmatter as any).generated?.by ?? null;\n\n // Spec §13.1 fallback (applies to v0.1, profile-0, AND v0.2 paths): body\n // `# Citations` -> synthetic sources, one entry per URL. The fallback only\n // fires when the `sources` key is ABSENT — a bundle that explicitly declares\n // `sources: []` (an author clearing provenance) MUST NOT have body citations\n // silently synthesized back into it. `hasSourcesKey` distinguishes absent\n // from explicitly-empty.\n if (!hasSourcesKey) {\n const urls = parseCitationsList(body);\n for (const url of urls) {\n sources.push({ resource: url });\n }\n }\n\n return {\n id,\n entity_id: entityId,\n title: typeof frontmatter.title === 'string' ? frontmatter.title : '',\n body,\n tags: Array.isArray(frontmatter.tags)\n ? frontmatter.tags.filter((t): t is string => typeof t === 'string')\n : [],\n confidence: CONFIDENCE_VALUES.has(String(frontmatter.confidence))\n ? (frontmatter.confidence as WikiFact['confidence'])\n : 'tentative',\n source_type: SOURCE_TYPES.has(String(frontmatter.source_type))\n ? (frontmatter.source_type as WikiFact['source_type'])\n : 'user_stated',\n source_hash: typeof frontmatter.source_hash === 'string' ? frontmatter.source_hash : null,\n source_ref: typeof frontmatter.resource === 'string' ? frontmatter.resource : null,\n created_at,\n updated_at,\n last_accessed_at:\n frontmatter.last_accessed_at != null\n ? parseFrontmatterTimestamp(frontmatter.last_accessed_at, now)\n : null,\n access_count: typeof frontmatter.access_count === 'number' ? frontmatter.access_count : 0,\n deleted_at:\n frontmatter.deleted_at != null ? parseFrontmatterTimestamp(frontmatter.deleted_at, 0) : null,\n okf_type: frontmatter.type,\n // OKF v0.2\n lifecycle_status,\n stale_after,\n generated_by,\n okf_sources: sources,\n okf_verified: verified,\n okf_usage_window: usageWindow,\n last_verified_at: lastV?.at ?? null,\n last_verified_by: lastV?.by ?? null,\n };\n}\n\nfunction frontmatterToTask(\n entityId: string,\n id: string,\n frontmatter: OkfFrontmatter,\n now: number,\n // Treat profile-1 explicit and version-only legacy the same: in both cases\n // `status` on the wire is the v0.1 execution state. Profile-2 (and unknown\n // profile with okf_version 0.2) uses the v0.2 rename rule.\n usesV1StatusRule: boolean,\n): WikiTask {\n const created_at = parseFrontmatterTimestamp(frontmatter.created_at, now);\n // Precedence (spec §2.4) — same nested-fallback chain as frontmatterToFact.\n const updated_at = parseFrontmatterTimestamp(\n (frontmatter as any).generated?.at,\n parseFrontmatterTimestamp(\n frontmatter.timestamp,\n parseFrontmatterTimestamp(frontmatter.updated_at, now),\n ),\n );\n\n const verified: OkfVerified = parseVerifiedFlexible((frontmatter as any).verified);\n const sources: OkfSource[] = Array.isArray((frontmatter as any).sources) ? (frontmatter as any).sources as OkfSource[] : [];\n const usageWindow = (frontmatter as any).usage_window && typeof (frontmatter as any).usage_window === 'object'\n ? (frontmatter as any).usage_window as { from: string; to: string }\n : null;\n const lastV = latestVerified(verified, now);\n const lifecycleRaw = (frontmatter as any).status;\n const lifecycle_status: 'draft' | 'stable' | 'deprecated' =\n lifecycleRaw === 'draft' || lifecycleRaw === 'stable' || lifecycleRaw === 'deprecated'\n ? lifecycleRaw : 'stable';\n // stale_after is symmetric with facts (spec §2.5) — parsed the same way,\n // not hardcoded to null.\n const staleAfterRaw = (frontmatter as any).stale_after;\n const stale_after = parseStaleAfterRaw(staleAfterRaw);\n\n // Status rename rule (spec §2.3):\n // - v0.2: wire `status` = lifecycle (already in lifecycle_status above);\n // wire `execution_status` = execution -> `task.status`.\n // - v0.1 / profile 0: wire `status` = execution -> `task.status`; lifecycle\n // is implicit 'stable'. Profile-1 bundles are explicit about being v0.1\n // (`profile: llm-wiki/1`); profile-0 (no profile key, `okf_version: 0.1`)\n // is the version-only fallback; both MUST use the v0.1 rule.\n const executionRaw = (frontmatter as any).execution_status;\n let executionState: WikiTask['status'];\n if (usesV1StatusRule) {\n executionState = TASK_STATUSES.has(String(frontmatter.status))\n ? (frontmatter.status as WikiTask['status']) : 'pending';\n } else {\n // v0.2 (or unknown profile — best-effort per spec §6 \"profile key unknown\").\n executionState = TASK_STATUSES.has(String(executionRaw))\n ? (executionRaw as WikiTask['status'])\n : TASK_STATUSES.has(String(frontmatter.status))\n ? (frontmatter.status as WikiTask['status'])\n : 'pending';\n }\n\n return {\n id,\n entity_id: entityId,\n description: typeof frontmatter.title === 'string' ? frontmatter.title : '',\n status: executionState,\n priority: typeof frontmatter.priority === 'number' ? frontmatter.priority : 0,\n created_at,\n updated_at,\n resolved_at:\n frontmatter.resolved_at != null\n ? parseFrontmatterTimestamp(frontmatter.resolved_at, now)\n : null,\n deleted_at:\n frontmatter.deleted_at != null ? parseFrontmatterTimestamp(frontmatter.deleted_at, 0) : null,\n okf_type: frontmatter.type,\n // OKF v0.2\n lifecycle_status,\n stale_after,\n generated_by: (frontmatter as any).generated?.by ?? null,\n okf_sources: sources,\n okf_verified: verified,\n okf_usage_window: usageWindow,\n last_verified_at: lastV?.at ?? null,\n last_verified_by: lastV?.by ?? null,\n };\n}\n\nfunction findLogMdPath(files: OkfFile[]): string | undefined {\n return files.find(f => f.path.endsWith('/log.md') || f.path === 'log.md')?.path;\n}\n\nfunction extractEdgesFromLinks(\n filePath: string,\n resolvedId: string,\n links: Array<{ text: string; path: string }>,\n pathToResolvedId: Map<string, string>,\n entityId: string,\n now: number,\n seenEdges: Set<string>,\n edges: WikiEdge[],\n): void {\n for (const link of links) {\n const strippedPath = stripLinkSuffix(decodeLinkPath(link.path));\n const directTargetId = lookupResolvedId(pathToResolvedId, strippedPath);\n const resolvedTargetPath = resolveRelativePath(filePath, strippedPath);\n if (isStructuralPath(strippedPath) || isStructuralPath(resolvedTargetPath)) continue;\n const targetId = directTargetId ?? lookupResolvedId(pathToResolvedId, resolvedTargetPath);\n if (!targetId) continue;\n const edgeKey = `${resolvedId}\\u0000${targetId}\\u0000${link.text}`;\n if (seenEdges.has(edgeKey)) continue;\n seenEdges.add(edgeKey);\n edges.push({\n id: generateId(),\n entity_id: entityId,\n source_id: resolvedId,\n target_id: targetId,\n edge_type: link.text,\n created_at: now,\n });\n }\n}\n\nexport function parseOkfBundle(\n entityId: string,\n files: OkfFile[],\n options?: OkfImportOptions,\n): MemoryDump {\n const now = Date.now();\n const normalizeOkfPath = (p: string) => p.replace(/^\\.\\//, '').replace(/\\\\/g, '/');\n\n const normalizedFiles = files.map(f => ({ ...f, path: normalizeOkfPath(f.path) }));\n\n const allowlistedFiles = normalizedFiles.filter(f => isAllowedOkfPath(f.path));\n\n const entityDirs = new Set(\n allowlistedFiles\n .map(f => /^entities\\/([^/]+)\\//.exec(f.path)?.[1])\n .filter((dir): dir is string => !!dir),\n );\n if (entityDirs.size > 1) {\n throw new Error(\n `parseOkfBundle: expected a single-entity bundle for \"${entityId}\", found entities: ${Array.from(entityDirs).join(', ')}`,\n );\n }\n const entityDir = entityDirs.values().next().value ?? entityId;\n const entityPrefix = `entities/${entityDir}/`;\n\n const allowedFiles = allowlistedFiles.filter(\n f => f.path === 'index.md' || f.path.startsWith(entityPrefix),\n );\n const rootIndex = allowedFiles.find(f => f.path === 'index.md');\n const profileMeta = rootIndex ? parseRootIndexMd(rootIndex.content) : {};\n const okfVersion = profileMeta.okf_version;\n const profile = profileMeta.profile;\n const isProfile1 = profile === 'llm-wiki/1';\n const isProfile2 = profile === 'llm-wiki/2';\n const isLegacyV1 = profile === undefined && okfVersion === '0.1';\n\n // Entity summary is a profile >= 1 feature (§4 of the profile doc). The\n // documented detection order (§4.8 detection plan) names four v0.1 and v0.2\n // entry points: explicit profile, version-only v0.1, version-only v0.2, and\n // unknown-profile v0.2 (best-effort). All four should pick up the summary.\n const isVersionOnlyV2 = profile === undefined && okfVersion === '0.2';\n const isUnknownProfileV2 = profile !== undefined && profile !== 'llm-wiki/1' && profile !== 'llm-wiki/2' && okfVersion === '0.2';\n const summaryEligible = isProfile1 || isProfile2 || isLegacyV1 || isVersionOnlyV2 || isUnknownProfileV2;\n let entitySummary: string | undefined;\n const entityIndex = allowedFiles.find(f => f.path === `${entityPrefix}index.md`);\n if (summaryEligible && entityIndex) {\n const summary = parseEntityIndexMd(entityIndex.content).summary;\n entitySummary = summary || undefined;\n }\n\n const pathToResolvedId = new Map<string, string>();\n\n for (const file of allowedFiles) {\n if (!isConceptFile(file.path)) continue;\n const { frontmatter } = parseConcept(file.content);\n const route = resolveRoute(file.path, frontmatter.type ?? '', options);\n if (route === 'ignore') continue;\n const resolvedId =\n typeof frontmatter.id === 'string' && frontmatter.id ? frontmatter.id : basenameMd(file.path);\n addPathAliases(pathToResolvedId, file.path, resolvedId);\n }\n\n const facts: WikiFact[] = [];\n const tasks: WikiTask[] = [];\n const edges: WikiEdge[] = [];\n let logContent: string | null = null;\n const logMdPath = findLogMdPath(allowedFiles);\n\n for (const file of allowedFiles) {\n if (file.path.endsWith('/log.md') || file.path === 'log.md') {\n logContent = file.content;\n continue;\n }\n if (!isConceptFile(file.path)) continue;\n\n const { frontmatter, body } = parseConcept(file.content);\n const route = resolveRoute(file.path, frontmatter.type ?? '', options);\n if (route === 'ignore') continue;\n\n const resolvedId =\n typeof frontmatter.id === 'string' && frontmatter.id ? frontmatter.id : basenameMd(file.path);\n\n const { body: storedBody, relatedLinks } = splitRelatedSection(body);\n const edgeLinks = (isProfile1 || isLegacyV1)\n ? relatedLinks\n : [...relatedLinks, ...extractMarkdownLinks(storedBody)];\n\n // Task status rename rule (spec §2.3) — v0.1 wire uses `status` as\n // execution state; v0.2 wire uses `status` as lifecycle and adds\n // `execution_status`. The flag we pass below is true when we are NOT\n // reading this task as a v0.2-style bundle.\n const usesV1StatusRule = isProfile1 || isLegacyV1 || (profile === undefined && okfVersion === undefined);\n\n if (route === 'fact') {\n facts.push(frontmatterToFact(entityId, resolvedId, frontmatter, storedBody, now));\n } else {\n tasks.push(frontmatterToTask(entityId, resolvedId, frontmatter, now, usesV1StatusRule));\n }\n\n const seenEdges = new Set<string>();\n extractEdgesFromLinks(\n file.path,\n resolvedId,\n edgeLinks,\n pathToResolvedId,\n entityId,\n now,\n seenEdges,\n edges,\n );\n }\n\n const events: WikiEvent[] = [];\n if (logContent != null) {\n const logPath = logMdPath ?? `entities/${entityId}/log.md`;\n for (const entry of parseLogMd(logContent)) {\n const { text, eventId } = parseEventIdComment(entry.text);\n const parsed = parseLogEntryText(text);\n if (!parsed) continue;\n let related_entry_id: string | null = null;\n if (parsed.linkPath) {\n const targetPath = resolveRelativePath(\n logPath,\n stripLinkSuffix(decodeLinkPath(parsed.linkPath)),\n );\n if (!isStructuralPath(targetPath) && targetPath.includes('/facts/')) {\n related_entry_id = lookupResolvedId(pathToResolvedId, targetPath) ?? null;\n }\n }\n const created_at = new Date(`${entry.date}T00:00:00.000Z`).getTime();\n if (!Number.isFinite(created_at)) continue;\n\n events.push({\n id: eventId ?? generateId('evt_'),\n entity_id: entityId,\n event_type: parsed.event_type,\n summary: parsed.summary,\n related_entry_id,\n created_at,\n });\n }\n }\n\n return {\n generatedAt: now,\n entities: {\n [entityId]: { facts, tasks, events, edges, summary: entitySummary },\n },\n };\n}\n","import type { ReadOptions } from './types';\n\nexport interface LibrarianOptions {\n /** If provided, replaces the default Librarian system instructions. */\n systemPrompt?: string;\n /** entity_id -> score multiplier, forwarded to WikiMemory.read() as tierWeights. */\n entityWeights?: Record<string, number>;\n /** Forwarded to WikiMemory.read() for zero-weight filler context. */\n includeZeroWeightEntities?: boolean;\n temperature?: number;\n}\n\nexport interface LibrarianPromptVariables {\n context: string;\n tasks: string;\n query: string;\n}\n\nexport const DEFAULT_LIBRARIAN_SYNTHESIS_PROMPT = `You are a careful memory synthesis assistant.\nUse only the retrieved context when answering the request.\nPreserve source provenance when facts come from different entity namespaces.\n\nRequest:\n{{query}}\n\nRetrieved context:\n{{context}}\n\nOpen tasks:\n{{tasks}}`;\n\nexport function hydrateLibrarianPrompt(\n template: string,\n variables: LibrarianPromptVariables,\n): string {\n return template.replace(/\\{\\{(context|tasks|query)\\}\\}/g, (_, key) => variables[key as keyof LibrarianPromptVariables]);\n}\n\nexport function validateLibrarianPromptTemplate(\n template: string,\n options: { custom: boolean; taskCount: number },\n): string[] {\n if (!options.custom) return [];\n\n const warnings: string[] = [];\n if (!template.includes('{{context}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{context}}; retrieved memory will not be injected.');\n }\n if (!template.includes('{{query}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{query}}; the original request will not be injected.');\n }\n if (options.taskCount > 0 && !template.includes('{{tasks}}')) {\n warnings.push('Custom Librarian systemPrompt omits {{tasks}} while retrieved tasks are available.');\n }\n return warnings;\n}\n\nexport function mapLibrarianOptionsToReadOptions(\n options: LibrarianOptions,\n): Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> {\n const readOptions: Pick<ReadOptions, 'tierWeights' | 'includeZeroWeightEntities'> = {};\n if (options.entityWeights !== undefined) readOptions.tierWeights = options.entityWeights;\n if (options.includeZeroWeightEntities !== undefined) {\n readOptions.includeZeroWeightEntities = options.includeZeroWeightEntities;\n }\n return readOptions;\n}\n","import { WikiMemory } from './WikiMemory';\nimport type { SQLiteAdapter, WikiOptions } from './types';\n\nexport * from './types';\nexport type { WikiOutboxEvent } from './outbox/types';\nexport { WikiMemory } from './WikiMemory';\nexport type { WikiMemoryTestAccess } from './WikiMemory';\nexport { formatContext } from './utils/formatContext';\nexport { formatGraphContext } from './utils/formatGraphContext';\nexport { formatMemoryDump } from './utils/formatMemoryDump';\nexport { formatOkfBundle, type FormatOkfBundleOptions, type OkfFormatProfile } from './utils/formatOkfBundle';\nexport { parseOkfBundle, type OkfImportOptions } from './utils/parseOkfBundle';\nexport { parseEmbedding } from './utils/embedding';\nexport { validateManifest } from './utils/ontology';\nexport { configureRandomSource } from './utils/ids';\nexport { chunkText, safeSlice } from './utils/pure';\nexport { DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_CHUNK_OVERLAP } from './utils/chunkingDefaults';\nexport { DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING } from './utils/embedDefaults';\nexport * from './librarianPrompt';\nexport { PromptService } from './services/PromptService';\nexport type { EmbedFactResult, EmbedFailureKind } from './services/EmbeddingService';\nexport {\n ONTOLOGY_BACKFILL_BATCH_SIZE,\n ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS,\n ONTOLOGY_BACKFILL_RECHECK_MS,\n HEAL_ANCHORS_PER_CANDIDATE,\n HEAL_BATCH_SIZE,\n HEAL_MAX_FACT_BODY_CHARS_L3,\n HEAL_MAX_TASKS,\n HEAL_RECHECK_MS,\n} from './services/MaintenanceService';\nexport { ONTOLOGY_BACKFILL_SYSTEM_PROMPT } from './prompts';\n\nexport function createWiki(db: SQLiteAdapter, options: WikiOptions): WikiMemory {\n return new WikiMemory(db, options);\n}\n"]}