@edihasaj/recall 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/maintenance/tasks.ts","../src/embeddings/embeddings.ts","../src/types.ts","../src/embeddings/cache.ts","../src/embeddings/providers/bge-small-en-v1.5.ts","../src/embeddings/providers/multilingual-e5.ts","../src/embeddings/providers/nomic.ts","../src/embeddings/providers/index.ts","../src/vector/sqlite-vec.ts","../src/vector/sqlite-fts.ts","../src/maintenance/appliers.ts","../src/models/memory.ts","../src/models/dedupe.ts","../src/audit/trail.ts","../src/repo/quality.ts","../src/health/scoring.ts","../src/llm/client.ts","../src/maintenance/dispatcher.ts","../src/capture/correction.ts","../src/capture/scope.ts","../src/maintenance/cleanup.ts","../src/contradictions/detector.ts"],"sourcesContent":["import { and, desc, eq, gt, inArray, lt, or, isNull, sql } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport { z } from \"zod\";\nimport type { RecallDb } from \"../db/client.js\";\nimport {\n activityEvents,\n historySnippets,\n memories,\n memoryMaintenanceTasks,\n} from \"../db/schema.js\";\nimport {\n findSemanticDuplicates,\n loadEmbeddingConfigFromEnv,\n} from \"../embeddings/embeddings.js\";\nimport { ApplyError, applyTaskResult } from \"./appliers.js\";\nimport type {\n MaintenanceTask,\n MaintenanceTaskKind,\n MaintenanceTaskStatus,\n} from \"../types.js\";\n\nconst OPEN_STATUSES: MaintenanceTaskStatus[] = [\"pending\", \"claimed\", \"submitted\"];\nconst ACTIVE_STATUSES: MaintenanceTaskStatus[] = [...OPEN_STATUSES, \"completed\"];\n\nconst DEFAULT_LEASE_SECONDS = 600;\n\nexport const DEFAULT_PRIORITIES: Record<MaintenanceTaskKind, number> = {\n // extract_rules_from_prompt runs at higher priority than verify_capture\n // because it is the primary capture path when an LLM provider is\n // configured — its output IS the candidate creation. Without it, real\n // rules never enter the queue at all.\n extract_rules_from_prompt: 14,\n verify_capture: 12,\n refine_candidate: 10,\n merge_duplicates: 8,\n summarize_history: 5,\n summarize_session: 3,\n synthesize_repo: 1,\n};\n\nexport interface EnqueueConfig {\n max_pending: number;\n max_per_kind: number;\n refine_min_repetition: number;\n summary_max_age_days: number;\n merge_similarity_threshold: number;\n session_min_activity_events: number;\n repo_synthesis_min_memories: number;\n repo_synthesis_refresh_days: number;\n}\n\nexport const DEFAULT_ENQUEUE_CONFIG: EnqueueConfig = {\n max_pending: 50,\n max_per_kind: 10,\n refine_min_repetition: 1,\n summary_max_age_days: 7,\n merge_similarity_threshold: 0.9,\n session_min_activity_events: 5,\n repo_synthesis_min_memories: 20,\n repo_synthesis_refresh_days: 30,\n};\n\nexport interface EnqueueCounts {\n tasks_enqueued: number;\n per_kind: Partial<Record<MaintenanceTaskKind, number>>;\n expired_leases_swept: number;\n dropped_over_cap: number;\n expired_pending_tasks: number;\n}\n\ntype TaskRow = typeof memoryMaintenanceTasks.$inferSelect;\n\nfunction rowToTask(row: TaskRow): MaintenanceTask {\n return {\n id: row.id,\n kind: row.kind as MaintenanceTaskKind,\n status: row.status as MaintenanceTaskStatus,\n priority: row.priority,\n repo: row.repo,\n target_key: row.target_key,\n payload: (row.payload ?? {}) as Record<string, unknown>,\n result: (row.result ?? null) as Record<string, unknown> | null,\n failure_reason: row.failure_reason,\n claimed_by: row.claimed_by,\n claimed_at: row.claimed_at,\n claim_expires_at: row.claim_expires_at,\n submitted_at: row.submitted_at,\n completed_at: row.completed_at,\n created_at: row.created_at,\n attempts: row.attempts,\n max_attempts: row.max_attempts,\n };\n}\n\nexport function targetKey(kind: MaintenanceTaskKind, target: string): string {\n return `${kind}:${target}`;\n}\n\nexport function hasActiveTaskForTarget(\n db: RecallDb,\n kind: MaintenanceTaskKind,\n target: string,\n): boolean {\n const row = db.select({ id: memoryMaintenanceTasks.id })\n .from(memoryMaintenanceTasks)\n .where(and(\n eq(memoryMaintenanceTasks.kind, kind),\n eq(memoryMaintenanceTasks.target_key, targetKey(kind, target)),\n inArray(memoryMaintenanceTasks.status, ACTIVE_STATUSES),\n ))\n .limit(1)\n .get();\n return Boolean(row);\n}\n\nexport interface InsertTaskInput {\n kind: MaintenanceTaskKind;\n target: string;\n repo?: string | null;\n payload: Record<string, unknown>;\n priority?: number;\n max_attempts?: number;\n}\n\nexport function insertTaskIdempotent(\n db: RecallDb,\n input: InsertTaskInput,\n): string | null {\n if (hasActiveTaskForTarget(db, input.kind, input.target)) return null;\n const id = randomUUID();\n db.insert(memoryMaintenanceTasks).values({\n id,\n kind: input.kind,\n status: \"pending\",\n priority: input.priority ?? DEFAULT_PRIORITIES[input.kind] ?? 0,\n repo: input.repo ?? null,\n target_key: targetKey(input.kind, input.target),\n payload: input.payload as any,\n result: null,\n failure_reason: null,\n claimed_by: null,\n claimed_at: null,\n claim_expires_at: null,\n submitted_at: null,\n completed_at: null,\n created_at: new Date().toISOString(),\n attempts: 0,\n max_attempts: input.max_attempts ?? 3,\n }).run();\n return id;\n}\n\nexport function deleteTask(db: RecallDb, id: string): boolean {\n const result = db.delete(memoryMaintenanceTasks)\n .where(eq(memoryMaintenanceTasks.id, id))\n .run();\n return result.changes > 0;\n}\n\nexport interface TaskStats {\n total: number;\n by_status: Record<MaintenanceTaskStatus, number>;\n by_kind: Record<MaintenanceTaskKind, number>;\n by_kind_status: Record<string, number>;\n pending_oldest_created_at: string | null;\n completed_last_24h: number;\n abandoned_last_24h: number;\n mean_completion_ms: number | null;\n}\n\nexport function getTaskStats(db: RecallDb): TaskStats {\n const rows = db.select().from(memoryMaintenanceTasks).all();\n\n const by_status = { pending: 0, claimed: 0, submitted: 0, completed: 0, abandoned: 0 } as Record<MaintenanceTaskStatus, number>;\n const by_kind = { verify_capture: 0, refine_candidate: 0, merge_duplicates: 0, summarize_history: 0, summarize_session: 0, synthesize_repo: 0, extract_rules_from_prompt: 0 } as Record<MaintenanceTaskKind, number>;\n const by_kind_status: Record<string, number> = {};\n\n const dayAgo = new Date(Date.now() - 86_400_000).toISOString();\n let completed_last_24h = 0;\n let abandoned_last_24h = 0;\n let pending_oldest: string | null = null;\n let completionDurations: number[] = [];\n\n for (const row of rows) {\n by_status[row.status as MaintenanceTaskStatus] += 1;\n by_kind[row.kind as MaintenanceTaskKind] += 1;\n const key = `${row.kind}:${row.status}`;\n by_kind_status[key] = (by_kind_status[key] ?? 0) + 1;\n\n if (row.status === \"pending\") {\n if (!pending_oldest || row.created_at < pending_oldest) pending_oldest = row.created_at;\n }\n if (row.completed_at && row.completed_at >= dayAgo) {\n if (row.status === \"completed\") completed_last_24h += 1;\n if (row.status === \"abandoned\") abandoned_last_24h += 1;\n }\n if (row.status === \"completed\" && row.completed_at) {\n const delta = new Date(row.completed_at).getTime() - new Date(row.created_at).getTime();\n if (Number.isFinite(delta) && delta >= 0) completionDurations.push(delta);\n }\n }\n\n const mean_completion_ms = completionDurations.length\n ? completionDurations.reduce((a, b) => a + b, 0) / completionDurations.length\n : null;\n\n return {\n total: rows.length,\n by_status,\n by_kind,\n by_kind_status,\n pending_oldest_created_at: pending_oldest,\n completed_last_24h,\n abandoned_last_24h,\n mean_completion_ms,\n };\n}\n\nexport function getTask(db: RecallDb, id: string): MaintenanceTask | undefined {\n const row = db.select().from(memoryMaintenanceTasks)\n .where(eq(memoryMaintenanceTasks.id, id))\n .get();\n return row ? rowToTask(row) : undefined;\n}\n\nexport interface ListTasksQuery {\n status?: MaintenanceTaskStatus | MaintenanceTaskStatus[];\n kinds?: MaintenanceTaskKind[];\n repo?: string;\n limit?: number;\n}\n\nexport function listTasks(db: RecallDb, query: ListTasksQuery = {}): MaintenanceTask[] {\n const conditions = [];\n if (query.status) {\n const statuses = Array.isArray(query.status) ? query.status : [query.status];\n conditions.push(inArray(memoryMaintenanceTasks.status, statuses));\n }\n if (query.kinds?.length) {\n conditions.push(inArray(memoryMaintenanceTasks.kind, query.kinds));\n }\n if (query.repo) {\n conditions.push(eq(memoryMaintenanceTasks.repo, query.repo));\n }\n\n let stmt = db.select().from(memoryMaintenanceTasks).$dynamic();\n if (conditions.length) stmt = stmt.where(and(...conditions));\n stmt = stmt\n .orderBy(sql`${memoryMaintenanceTasks.priority} DESC`, memoryMaintenanceTasks.created_at)\n .limit(query.limit ?? 50);\n return stmt.all().map(rowToTask);\n}\n\nexport function sweepExpiredLeases(db: RecallDb, now: Date = new Date()): number {\n const nowIso = now.toISOString();\n const result = db.update(memoryMaintenanceTasks)\n .set({\n status: \"pending\",\n claimed_by: null,\n claimed_at: null,\n claim_expires_at: null,\n attempts: sql`${memoryMaintenanceTasks.attempts} + 1`,\n })\n .where(and(\n eq(memoryMaintenanceTasks.status, \"claimed\"),\n lt(memoryMaintenanceTasks.claim_expires_at, nowIso),\n ))\n .run();\n return result.changes;\n}\n\n/**\n * Abandon pending tasks that have been waiting longer than `maxAgeDays`. The\n * usual cause is that no LLM provider is configured, so the dispatcher never\n * picked them up. Stale source data makes the eventual run useless anyway.\n */\nexport function expireStalePendingTasks(\n db: RecallDb,\n maxAgeDays: number,\n now: Date = new Date(),\n): number {\n const cutoff = new Date(now.getTime() - maxAgeDays * 86_400_000).toISOString();\n const result = db.update(memoryMaintenanceTasks)\n .set({\n status: \"abandoned\",\n failure_reason: \"expired_no_dispatcher\",\n completed_at: now.toISOString(),\n })\n .where(and(\n eq(memoryMaintenanceTasks.status, \"pending\"),\n lt(memoryMaintenanceTasks.created_at, cutoff),\n ))\n .run();\n return result.changes;\n}\n\nexport function abandonOverAttemptTasks(db: RecallDb): number {\n const nowIso = new Date().toISOString();\n const result = db.update(memoryMaintenanceTasks)\n .set({\n status: \"abandoned\",\n failure_reason: \"max_attempts_exceeded\",\n completed_at: nowIso,\n })\n .where(and(\n inArray(memoryMaintenanceTasks.status, [\"pending\", \"claimed\"] as MaintenanceTaskStatus[]),\n sql`${memoryMaintenanceTasks.attempts} >= ${memoryMaintenanceTasks.max_attempts}`,\n ))\n .run();\n return result.changes;\n}\n\nexport function applyBacklogCaps(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"max_pending\" | \"max_per_kind\">,\n): number {\n let dropped = 0;\n\n const overKindRows = db.select({\n kind: memoryMaintenanceTasks.kind,\n count: sql<number>`count(*)`.as(\"count\"),\n })\n .from(memoryMaintenanceTasks)\n .where(eq(memoryMaintenanceTasks.status, \"pending\"))\n .groupBy(memoryMaintenanceTasks.kind)\n .all();\n\n for (const { kind, count } of overKindRows) {\n if (count <= config.max_per_kind) continue;\n const toDrop = count - config.max_per_kind;\n dropped += dropLowestPriorityPending(db, toDrop, { kind: kind as MaintenanceTaskKind });\n }\n\n const pendingCount = db.select({ n: sql<number>`count(*)` })\n .from(memoryMaintenanceTasks)\n .where(eq(memoryMaintenanceTasks.status, \"pending\"))\n .get()?.n ?? 0;\n\n if (pendingCount > config.max_pending) {\n dropped += dropLowestPriorityPending(db, pendingCount - config.max_pending);\n }\n\n return dropped;\n}\n\nfunction dropLowestPriorityPending(\n db: RecallDb,\n limit: number,\n filter: { kind?: MaintenanceTaskKind } = {},\n): number {\n const conditions = [eq(memoryMaintenanceTasks.status, \"pending\")];\n if (filter.kind) conditions.push(eq(memoryMaintenanceTasks.kind, filter.kind));\n\n const ids = db.select({ id: memoryMaintenanceTasks.id })\n .from(memoryMaintenanceTasks)\n .where(and(...conditions))\n .orderBy(memoryMaintenanceTasks.priority, sql`${memoryMaintenanceTasks.created_at} DESC`)\n .limit(limit)\n .all()\n .map((r) => r.id);\n\n if (!ids.length) return 0;\n\n const result = db.delete(memoryMaintenanceTasks)\n .where(inArray(memoryMaintenanceTasks.id, ids))\n .run();\n return result.changes;\n}\n\n// --- Producers ---\n\n// LLM-primary capture enqueue: when a provider is configured, the prompt\n// hook hands the raw user prompt to the LLM for extraction instead of the\n// regex extractor. The LLM returns zero or more rules; the applier creates\n// candidate memories from them. Idempotent on (kind, target_key) so a\n// retried hook doesn't double-enqueue.\nexport function enqueueExtractRulesFromPrompt(\n db: RecallDb,\n payload: {\n prompt_id: string;\n raw_prompt: string;\n repo: string | null;\n path: string | null;\n agent: string | null;\n session_id: string;\n prev_assistant_turn?: string | null;\n recent_tool_calls?: unknown;\n },\n): string | null {\n return insertTaskIdempotent(db, {\n kind: \"extract_rules_from_prompt\",\n target: payload.prompt_id,\n repo: payload.repo,\n payload: {\n prompt_id: payload.prompt_id,\n raw_prompt: payload.raw_prompt,\n repo: payload.repo,\n path: payload.path,\n agent: payload.agent,\n session_id: payload.session_id,\n prev_assistant_turn: payload.prev_assistant_turn ?? null,\n recent_tool_calls: payload.recent_tool_calls ?? null,\n },\n });\n}\n\n// Inline enqueue used by capture: every newly-created candidate gets a\n// verify_capture task so the LLM (when configured) can second-guess the\n// heuristics before the candidate accumulates evidence.\nexport function enqueueVerifyCapture(\n db: RecallDb,\n memory: { id: string; text: string; scope: string; path_scope: string | null; repo: string | null; capture_context: unknown },\n): string | null {\n return insertTaskIdempotent(db, {\n kind: \"verify_capture\",\n target: memory.id,\n repo: memory.repo,\n payload: {\n memory_id: memory.id,\n text: memory.text,\n inferred_scope: memory.scope,\n inferred_path_scope: memory.path_scope,\n repo: memory.repo,\n capture_context: memory.capture_context ?? null,\n },\n });\n}\n\nexport function produceRefineCandidateTasks(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"refine_min_repetition\">,\n): number {\n const candidates = db.select().from(memories)\n .where(and(\n eq(memories.status, \"candidate\"),\n or(eq(memories.scope, \"repo\"), isNull(memories.path_scope)),\n ))\n .all();\n\n let enqueued = 0;\n for (const row of candidates) {\n if (row.repetition_count < config.refine_min_repetition) continue;\n if (!row.repo) continue;\n\n const id = insertTaskIdempotent(db, {\n kind: \"refine_candidate\",\n target: row.id,\n repo: row.repo,\n payload: {\n memory_id: row.id,\n text: row.text,\n current_scope: row.scope,\n current_path_scope: row.path_scope,\n repo: row.repo,\n capture_context: row.capture_context ?? null,\n repetition_count: row.repetition_count,\n },\n });\n if (id) enqueued += 1;\n }\n return enqueued;\n}\n\nexport function produceSummarizeHistoryTasks(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"summary_max_age_days\">,\n): number {\n const cutoff = new Date(Date.now() - config.summary_max_age_days * 86_400_000).toISOString();\n\n const snippets = db.select().from(historySnippets)\n .where(sql`${historySnippets.created_at} >= ${cutoff}`)\n .all();\n\n let enqueued = 0;\n for (const snippet of snippets) {\n if (!snippetHasMeaningfulContent(snippet.text)) continue;\n const id = insertTaskIdempotent(db, {\n kind: \"summarize_history\",\n target: snippet.id,\n repo: snippet.repo ?? null,\n payload: {\n snippet_id: snippet.id,\n kind: snippet.kind,\n repo: snippet.repo,\n session_id: snippet.session_id,\n current_text: snippet.text,\n source_activity_ids: snippet.source_activity_ids,\n },\n });\n if (id) enqueued += 1;\n }\n return enqueued;\n}\n\n// A deterministic summary of \"Repo: X\\nEvent types: Y\" with no corrections,\n// reviews, or compile markers has nothing an LLM can usefully tighten.\n// Skip enqueueing — otherwise the dispatcher burns tokens to rewrite the\n// same content into a near-identical paraphrase. See\n// src/maintenance/lifecycle.ts::summarizeSessionEvents for the markers.\nexport function snippetHasMeaningfulContent(text: string): boolean {\n const lines = text.split(\"\\n\").map((line) => line.trim()).filter(Boolean);\n if (lines.length === 0) return false;\n return lines.some((line) =>\n line.startsWith(\"Corrections:\") ||\n line.startsWith(\"Reviews:\") ||\n line.startsWith(\"Latest compile included\") ||\n line.startsWith(\"Prompts:\"),\n );\n}\n\nexport async function produceMergeDuplicateTasks(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"merge_similarity_threshold\">,\n): Promise<number> {\n const embeddingConfig = loadEmbeddingConfigFromEnv();\n if (!embeddingConfig) return 0;\n\n const activeMemories = db.select().from(memories)\n .where(eq(memories.status, \"active\"))\n .all();\n\n const visited = new Set<string>();\n let enqueued = 0;\n\n for (const mem of activeMemories) {\n if (visited.has(mem.id)) continue;\n if (!mem.repo) continue;\n\n // Commands often differ only in punctuation/backticks (\"test: vitest run\"\n // vs \"test: `vitest run`\"), so cosine similarity at the default 0.9 misses\n // them. Lower the bar to 0.85 for commands; rules stay strict.\n const threshold = mem.type === \"command\"\n ? Math.min(config.merge_similarity_threshold, 0.85)\n : config.merge_similarity_threshold;\n\n const duplicates = await findSemanticDuplicates(\n db,\n mem.text,\n embeddingConfig,\n threshold,\n { repo: mem.repo, type: mem.type, limit: 10 },\n );\n\n // Strip the memory itself from the duplicate list.\n const peers = duplicates.filter((d) => d.id !== mem.id);\n if (peers.length === 0) continue;\n\n const cluster = [mem.id, ...peers.map((p) => p.id)].sort();\n // Dedupe symmetric clusters: only act from the anchor.\n if (cluster[0] !== mem.id) {\n for (const id of cluster) visited.add(id);\n continue;\n }\n\n const clusterRows = db.select().from(memories)\n .where(inArray(memories.id, cluster))\n .all();\n\n const candidates = clusterRows.map((row) => ({\n id: row.id,\n text: row.text,\n scope: row.scope,\n path_scope: row.path_scope,\n confidence: row.confidence,\n }));\n\n const id = insertTaskIdempotent(db, {\n kind: \"merge_duplicates\",\n target: cluster[0],\n repo: mem.repo,\n payload: {\n repo: mem.repo,\n type: mem.type,\n candidates,\n },\n });\n if (id) enqueued += 1;\n for (const memberId of cluster) visited.add(memberId);\n }\n\n return enqueued;\n}\n\nexport function produceSummarizeSessionTasks(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"session_min_activity_events\" | \"summary_max_age_days\">,\n): number {\n const cutoff = new Date(Date.now() - config.summary_max_age_days * 86_400_000).toISOString();\n\n const sessionEnds = db.select().from(activityEvents)\n .where(and(\n eq(activityEvents.event_type, \"session_end\"),\n gt(activityEvents.created_at, cutoff),\n ))\n .orderBy(desc(activityEvents.created_at))\n .all();\n\n let enqueued = 0;\n for (const end of sessionEnds) {\n if (!end.session_id) continue;\n\n const events = db.select().from(activityEvents)\n .where(eq(activityEvents.session_id, end.session_id))\n .all();\n if (events.length < config.session_min_activity_events) continue;\n\n const existing = db.select().from(historySnippets)\n .where(and(\n eq(historySnippets.session_id, end.session_id),\n eq(historySnippets.kind, \"session_summary\"),\n ))\n .get();\n if (existing) continue;\n\n const repo = end.repo ?? events.find((e) => e.repo)?.repo ?? null;\n const eventTypes = [...new Set(events.map((e) => e.event_type))];\n\n const id = insertTaskIdempotent(db, {\n kind: \"summarize_session\",\n target: end.session_id,\n repo,\n payload: {\n session_id: end.session_id,\n repo,\n event_count: events.length,\n event_types: eventTypes,\n source_activity_ids: events.map((e) => e.id),\n },\n });\n if (id) enqueued += 1;\n }\n\n return enqueued;\n}\n\nexport function produceSynthesizeRepoTasks(\n db: RecallDb,\n config: Pick<EnqueueConfig, \"repo_synthesis_min_memories\" | \"repo_synthesis_refresh_days\">,\n): number {\n const rows = db.select({\n repo: memories.repo,\n count: sql<number>`count(*)`.as(\"count\"),\n })\n .from(memories)\n .where(eq(memories.status, \"active\"))\n .groupBy(memories.repo)\n .all();\n\n const cutoff = new Date(Date.now() - config.repo_synthesis_refresh_days * 86_400_000).toISOString();\n let enqueued = 0;\n\n for (const { repo, count } of rows) {\n if (!repo) continue;\n if (count < config.repo_synthesis_min_memories) continue;\n\n const recent = db.select().from(historySnippets)\n .where(and(\n eq(historySnippets.repo, repo),\n eq(historySnippets.kind, \"repo_synthesis\"),\n gt(historySnippets.updated_at, cutoff),\n ))\n .get();\n if (recent) continue;\n\n const topMemories = db.select().from(memories)\n .where(and(\n eq(memories.repo, repo),\n eq(memories.status, \"active\"),\n ))\n .orderBy(desc(memories.confidence))\n .limit(20)\n .all()\n .map((row) => ({\n id: row.id,\n text: row.text,\n type: row.type,\n scope: row.scope,\n confidence: row.confidence,\n }));\n\n const id = insertTaskIdempotent(db, {\n kind: \"synthesize_repo\",\n target: repo,\n repo,\n payload: {\n repo,\n memory_count: count,\n top_memories: topMemories,\n },\n });\n if (id) enqueued += 1;\n }\n\n return enqueued;\n}\n\n// --- Orchestrator ---\n\nexport async function enqueueMaintenanceTasks(\n db: RecallDb,\n config: EnqueueConfig = DEFAULT_ENQUEUE_CONFIG,\n): Promise<EnqueueCounts> {\n const expired = sweepExpiredLeases(db);\n abandonOverAttemptTasks(db);\n // Tasks older than 2x the summary window are almost certainly stuck because\n // no LLM provider is configured. Abandon them so the queue stays interpretable.\n const expiredPending = expireStalePendingTasks(db, config.summary_max_age_days * 2);\n\n const counts: Partial<Record<MaintenanceTaskKind, number>> = {};\n counts.refine_candidate = produceRefineCandidateTasks(db, config);\n counts.summarize_history = produceSummarizeHistoryTasks(db, config);\n counts.summarize_session = produceSummarizeSessionTasks(db, config);\n counts.synthesize_repo = produceSynthesizeRepoTasks(db, config);\n counts.merge_duplicates = await produceMergeDuplicateTasks(db, config);\n\n const dropped = applyBacklogCaps(db, config);\n\n const total = Object.values(counts).reduce((sum, n) => sum + (n ?? 0), 0);\n\n return {\n tasks_enqueued: total,\n per_kind: counts,\n expired_leases_swept: expired,\n dropped_over_cap: dropped,\n expired_pending_tasks: expiredPending,\n };\n}\n\nexport { DEFAULT_LEASE_SECONDS };\n\n// --- Peek / Claim / Submit / Release ---\n\nconst MemoryScope = z.enum([\"session\", \"path\", \"repo\", \"team\", \"global\"]);\n\nconst RefineCandidateResult = z.object({\n refined_text: z.string().min(1).max(4000),\n scope: MemoryScope,\n path_scope: z.string().max(512).nullable().optional(),\n rationale: z.string().max(2000).optional(),\n // Optional verdict — when present, the LLM may also reject a re-captured\n // fragment instead of refining it. Backwards-compatible: omitted means\n // \"rewrite\" (legacy refine behavior).\n verdict: z.enum([\"rewrite\", \"reject\"]).optional(),\n});\n\nconst VerifyCaptureResult = z.object({\n verdict: z.enum([\"save\", \"rewrite\", \"reject\"]),\n cleaned_text: z.string().min(1).max(4000).optional(),\n scope: MemoryScope.optional(),\n path_scope: z.string().max(512).nullable().optional(),\n is_destructive_risky: z.boolean().optional(),\n reason: z.string().max(2000).optional(),\n});\n\nconst SummarizeHistoryResult = z.object({\n summary_text: z.string().min(1).max(4000),\n tags: z.array(z.string().max(64)).max(20).optional(),\n});\n\nconst MergeDuplicatesResult = z.object({\n winner_id: z.string().uuid(),\n winner_text: z.string().min(1).max(4000).optional(),\n winner_scope: MemoryScope.optional(),\n winner_path_scope: z.string().max(512).nullable().optional(),\n rationale: z.string().max(2000).optional(),\n});\n\nconst SummarizeSessionResult = z.object({\n summary_text: z.string().min(1).max(4000),\n});\n\nconst SynthesizeRepoResult = z.object({\n summary_text: z.string().min(1).max(8000),\n});\n\n// LLM-primary capture: extract zero or more durable rules from a raw user\n// prompt. Empty list = \"no rule worth saving here.\" This is the schema the\n// LLM commits to when it judges the prompt instead of the regex extractor.\nconst ExtractedRule = z.object({\n text: z.string().min(1).max(2000),\n type: z.enum([\"rule\", \"decision\", \"review_pattern\", \"command\", \"gotcha\"]),\n scope: MemoryScope,\n path_scope: z.string().max(512).nullable().optional(),\n confidence: z.number().min(0).max(1),\n is_destructive_risky: z.boolean().optional(),\n rationale: z.string().max(500).optional(),\n});\n\nconst ExtractRulesFromPromptResult = z.object({\n rules: z.array(ExtractedRule).max(10),\n dropped_reason: z.string().max(500).optional(),\n});\n\nconst RESULT_SCHEMAS: Record<MaintenanceTaskKind, z.ZodTypeAny> = {\n verify_capture: VerifyCaptureResult,\n refine_candidate: RefineCandidateResult,\n summarize_history: SummarizeHistoryResult,\n merge_duplicates: MergeDuplicatesResult,\n summarize_session: SummarizeSessionResult,\n synthesize_repo: SynthesizeRepoResult,\n extract_rules_from_prompt: ExtractRulesFromPromptResult,\n};\n\nexport type RefineCandidateResult = z.infer<typeof RefineCandidateResult>;\nexport type VerifyCaptureResult = z.infer<typeof VerifyCaptureResult>;\nexport type SummarizeHistoryResult = z.infer<typeof SummarizeHistoryResult>;\nexport type MergeDuplicatesResult = z.infer<typeof MergeDuplicatesResult>;\nexport type SummarizeSessionResult = z.infer<typeof SummarizeSessionResult>;\nexport type SynthesizeRepoResult = z.infer<typeof SynthesizeRepoResult>;\nexport type ExtractedRule = z.infer<typeof ExtractedRule>;\nexport type ExtractRulesFromPromptResult = z.infer<typeof ExtractRulesFromPromptResult>;\n\nexport interface PeekOptions {\n repo?: string;\n kinds?: MaintenanceTaskKind[];\n limit?: number;\n}\n\nexport interface PeekedTask {\n id: string;\n kind: MaintenanceTaskKind;\n priority: number;\n repo: string | null;\n created_at: string;\n payload_summary: Record<string, unknown>;\n}\n\nfunction payloadSummary(payload: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(payload)) {\n if (typeof v === \"string\") {\n out[k] = v.length > 160 ? `${v.slice(0, 157)}...` : v;\n } else if (Array.isArray(v)) {\n out[k] = `array(${v.length})`;\n } else {\n out[k] = v;\n }\n }\n return out;\n}\n\nexport function peekTasks(db: RecallDb, options: PeekOptions = {}): PeekedTask[] {\n const tasks = listTasks(db, {\n status: \"pending\",\n repo: options.repo,\n kinds: options.kinds,\n limit: Math.min(options.limit ?? 3, 10),\n });\n return tasks.map((t) => ({\n id: t.id,\n kind: t.kind,\n priority: t.priority,\n repo: t.repo,\n created_at: t.created_at,\n payload_summary: payloadSummary(t.payload),\n }));\n}\n\nexport interface ClaimResult {\n task: MaintenanceTask;\n lease_expires_at: string;\n}\n\nexport class TaskClaimConflictError extends Error {\n constructor(public readonly taskId: string, public readonly reason: \"not-pending\" | \"not-found\") {\n super(`Task ${taskId} cannot be claimed: ${reason}`);\n this.name = \"TaskClaimConflictError\";\n }\n}\n\nexport function claimTask(\n db: RecallDb,\n taskId: string,\n agent: string,\n leaseSeconds: number = DEFAULT_LEASE_SECONDS,\n): ClaimResult {\n const now = new Date();\n const expiresAt = new Date(now.getTime() + leaseSeconds * 1000).toISOString();\n const nowIso = now.toISOString();\n\n const result = db.update(memoryMaintenanceTasks)\n .set({\n status: \"claimed\",\n claimed_by: agent,\n claimed_at: nowIso,\n claim_expires_at: expiresAt,\n })\n .where(and(\n eq(memoryMaintenanceTasks.id, taskId),\n eq(memoryMaintenanceTasks.status, \"pending\"),\n ))\n .run();\n\n if (result.changes === 0) {\n const existing = getTask(db, taskId);\n throw new TaskClaimConflictError(taskId, existing ? \"not-pending\" : \"not-found\");\n }\n\n const task = getTask(db, taskId)!;\n return { task, lease_expires_at: expiresAt };\n}\n\nexport interface SubmitOk {\n status: \"applied\";\n task_id: string;\n kind: MaintenanceTaskKind;\n target_id: string;\n changed_fields: string[];\n audit_entry_id: string | null;\n}\n\nexport interface SubmitRejected {\n status: \"rejected\";\n task_id: string;\n reason: string;\n attempts: number;\n abandoned: boolean;\n}\n\nexport type SubmitResult = SubmitOk | SubmitRejected;\n\nexport function submitTask(\n db: RecallDb,\n taskId: string,\n agent: string,\n result: unknown,\n): SubmitResult {\n const existing = getTask(db, taskId);\n if (!existing) return { status: \"rejected\", task_id: taskId, reason: \"not-found\", attempts: 0, abandoned: false };\n if (existing.status !== \"claimed\") {\n return { status: \"rejected\", task_id: taskId, reason: `not-claimed (status=${existing.status})`, attempts: existing.attempts, abandoned: false };\n }\n if (existing.claimed_by !== agent) {\n return { status: \"rejected\", task_id: taskId, reason: \"not-claim-holder\", attempts: existing.attempts, abandoned: false };\n }\n\n const schema = RESULT_SCHEMAS[existing.kind];\n const parsed = schema.safeParse(result);\n if (!parsed.success) {\n const attempts = existing.attempts + 1;\n const abandoned = attempts >= existing.max_attempts;\n const now = new Date().toISOString();\n db.update(memoryMaintenanceTasks)\n .set({\n status: abandoned ? \"abandoned\" : \"pending\",\n claimed_by: null,\n claimed_at: null,\n claim_expires_at: null,\n attempts,\n failure_reason: parsed.error.issues.map((i) => `${i.path.join(\".\")}:${i.message}`).join(\"; \").slice(0, 500),\n completed_at: abandoned ? now : null,\n })\n .where(eq(memoryMaintenanceTasks.id, taskId))\n .run();\n return {\n status: \"rejected\",\n task_id: taskId,\n reason: `validation-failed: ${parsed.error.issues[0]?.message ?? \"shape mismatch\"}`,\n attempts,\n abandoned,\n };\n }\n\n let applyOutcome;\n try {\n applyOutcome = applyTaskResult(db, existing, parsed.data);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const attempts = existing.attempts + 1;\n const code = err instanceof ApplyError ? err.code : \"apply-error\";\n // target-missing, invalid-state, and unsupported-kind are unfixable from\n // the same payload — abandon immediately rather than waste retries.\n const abandoned = code === \"target-missing\"\n || code === \"invalid-state\"\n || code === \"unsupported-kind\"\n || attempts >= existing.max_attempts;\n const now = new Date().toISOString();\n db.update(memoryMaintenanceTasks)\n .set({\n status: abandoned ? \"abandoned\" : \"pending\",\n claimed_by: null,\n claimed_at: null,\n claim_expires_at: null,\n attempts,\n failure_reason: `apply-failed: ${message}`.slice(0, 500),\n completed_at: abandoned ? now : null,\n })\n .where(eq(memoryMaintenanceTasks.id, taskId))\n .run();\n return {\n status: \"rejected\",\n task_id: taskId,\n reason: `apply-failed: ${message}`,\n attempts,\n abandoned,\n };\n }\n\n const now = new Date().toISOString();\n db.update(memoryMaintenanceTasks)\n .set({\n status: \"completed\",\n result: parsed.data as any,\n submitted_at: now,\n completed_at: now,\n failure_reason: null,\n })\n .where(eq(memoryMaintenanceTasks.id, taskId))\n .run();\n\n return {\n status: \"applied\",\n task_id: taskId,\n kind: existing.kind,\n target_id: applyOutcome.target_id,\n changed_fields: applyOutcome.changed_fields,\n audit_entry_id: applyOutcome.audit_entry_id,\n };\n}\n\nexport interface ReleaseResult {\n status: \"released\" | \"not-claimed\" | \"not-found\";\n}\n\nexport function releaseTask(\n db: RecallDb,\n taskId: string,\n agent: string,\n reason?: string,\n): ReleaseResult {\n const existing = getTask(db, taskId);\n if (!existing) return { status: \"not-found\" };\n if (existing.status !== \"claimed\" || existing.claimed_by !== agent) {\n return { status: \"not-claimed\" };\n }\n db.update(memoryMaintenanceTasks)\n .set({\n status: \"pending\",\n claimed_by: null,\n claimed_at: null,\n claim_expires_at: null,\n failure_reason: reason ? reason.slice(0, 500) : null,\n })\n .where(eq(memoryMaintenanceTasks.id, taskId))\n .run();\n return { status: \"released\" };\n}\n","/**\n * Local embedding lifecycle.\n * Canonical embedding rows live in SQLite; derived vec + FTS indexes sit on top.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { memories, memoryEmbeddings } from \"../db/schema.js\";\nimport { CONFIDENCE, type EmbeddingConfig, type EvidenceEntry, type MemoryItem } from \"../types.js\";\nimport { formatBytes, getDirectorySize, getEmbeddingCachePath } from \"./cache.js\";\nimport { resolveProvider } from \"./providers/index.js\";\nimport type { EmbeddingPurpose } from \"./providers/types.js\";\nimport {\n rebuildMemoryVecIndex,\n removeMemoryVecRow,\n searchMemoryVecIndex,\n upsertMemoryVecRow,\n verifyMemoryVecIndex,\n} from \"../vector/sqlite-vec.js\";\nimport {\n rebuildMemoryFtsIndex,\n searchMemoryFtsIndex,\n syncMemoryFtsIndex,\n verifyMemoryFtsIndex,\n} from \"../vector/sqlite-fts.js\";\n\ntype MemoryRow = typeof memories.$inferSelect;\ntype MemoryEmbeddingRow = typeof memoryEmbeddings.$inferSelect;\n\nconst EMBEDDING_BATCH_SIZE = 100;\nconst MIN_HYBRID_VECTOR_SIMILARITY = 0.7;\nconst pendingEmbeddingJobs = new Set<Promise<void>>();\nconst EMBEDDING_DEFAULTS = {\n nomic: {\n model: \"nomic-ai/nomic-embed-text-v1.5\",\n dimensions: 512,\n },\n \"multilingual-e5\": {\n model: \"Xenova/multilingual-e5-small\",\n dimensions: 384,\n },\n \"bge-small-en-v1.5\": {\n model: \"Xenova/bge-small-en-v1.5\",\n dimensions: 384,\n },\n} as const;\n\n// --- Config ---\n\nexport function loadEmbeddingConfigFromEnv(): EmbeddingConfig | null {\n if (process.env.RECALL_EMBEDDINGS_DISABLED === \"true\") return null;\n const provider = process.env.RECALL_EMBEDDING_PROVIDER === \"multilingual-e5\"\n ? \"multilingual-e5\"\n : \"nomic\";\n const defaults = EMBEDDING_DEFAULTS[provider];\n return {\n provider,\n model: process.env.RECALL_EMBEDDING_MODEL ?? defaults.model,\n dimensions: parseInt(process.env.RECALL_EMBEDDING_DIMS ?? `${defaults.dimensions}`, 10),\n version: process.env.RECALL_EMBEDDING_VERSION ?? \"v1\",\n similarity_threshold: parseFloat(process.env.RECALL_SIMILARITY_THRESHOLD ?? \"0.8\"),\n };\n}\n\nexport function getEmbeddingModelInfo(\n config: EmbeddingConfig | null = loadEmbeddingConfigFromEnv(),\n): {\n provider: EmbeddingConfig[\"provider\"];\n model: string;\n dimensions: number;\n canonical_dimensions: number;\n index_dimensions: number;\n version: string;\n task_prefix?: string;\n estimated_size_mb?: number;\n cache_path: string;\n cached: boolean;\n size_bytes: number;\n size_label: string;\n} | null {\n if (!config) return null;\n\n const provider = resolveProvider(config);\n const metadata = provider.metadata();\n const cachePath = getEmbeddingCachePath({\n provider: config.provider,\n model: metadata.model,\n });\n const sizeBytes = getDirectorySize(cachePath);\n\n return {\n provider: config.provider,\n model: metadata.model,\n dimensions: metadata.dimensions,\n canonical_dimensions: metadata.canonical_dimensions,\n index_dimensions: metadata.index_dimensions,\n version: metadata.version,\n task_prefix: metadata.task_prefix,\n estimated_size_mb: metadata.estimated_size_mb,\n cache_path: cachePath,\n cached: sizeBytes > 0,\n size_bytes: sizeBytes,\n size_label: formatBytes(sizeBytes),\n };\n}\n\nexport async function ensureEmbeddingProviderReady(\n config: EmbeddingConfig | null = loadEmbeddingConfigFromEnv(),\n) {\n if (!config) return null;\n\n const provider = resolveProvider(config);\n if (provider.prepare) {\n await provider.prepare();\n } else {\n await provider.embed(\"recall provider warmup\", \"document\");\n }\n\n return getEmbeddingModelInfo(config);\n}\n\nfunction getEmbeddingVersion(config: EmbeddingConfig): string {\n return config.version || `${config.provider}:${config.model}:${config.dimensions}`;\n}\n\nfunction hashMemoryText(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nfunction shouldEmbedMemory(row: Pick<MemoryRow, \"status\" | \"confidence\" | \"source\">): boolean {\n if (row.status === \"transient\") return false;\n // Phase D.next: rejected memories that came from a user correction stay\n // embedded so capture can do semantic-paraphrase matching against the\n // rejection corpus. Other rejected memories (e.g. from cleanup\n // dedupe-merge) don't need embeddings — there's no value in matching\n // against superseded duplicates.\n if (row.status === \"rejected\") {\n return row.source === \"user_correction\" || row.source === \"user_reported_review\";\n }\n return row.confidence >= CONFIDENCE.TRANSIENT_MAX;\n}\n\nfunction serializeEmbedding(embedding: Float32Array): Buffer {\n return Buffer.from(\n embedding.buffer,\n embedding.byteOffset,\n embedding.byteLength,\n );\n}\n\nfunction deserializeEmbedding(buffer: Buffer): Float32Array {\n return new Float32Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength / Float32Array.BYTES_PER_ELEMENT,\n );\n}\n\nfunction rowNeedsEmbeddingRefresh(\n row: Pick<MemoryRow, \"text\">,\n existing: MemoryEmbeddingRow | undefined,\n config: EmbeddingConfig,\n): boolean {\n const metadata = resolveProvider(config).metadata();\n if (!existing) return true;\n return (\n existing.model !== config.model ||\n existing.embedding_dimensions !== metadata.canonical_dimensions ||\n existing.index_dimensions !== metadata.index_dimensions ||\n existing.version !== getEmbeddingVersion(config) ||\n existing.content_hash !== hashMemoryText(row.text)\n );\n}\n\nexport function projectEmbeddingToIndex(\n embedding: Float32Array,\n indexDimensions: number,\n): Float32Array {\n if (embedding.length === indexDimensions) {\n return embedding;\n }\n if (embedding.length < indexDimensions) {\n throw new Error(`Embedding width ${embedding.length} is smaller than index width ${indexDimensions}.`);\n }\n\n const sliced = embedding.slice(0, indexDimensions);\n let norm = 0;\n for (const value of sliced) norm += value * value;\n const scale = Math.sqrt(norm) || 1;\n for (let i = 0; i < sliced.length; i++) {\n sliced[i] /= scale;\n }\n return sliced;\n}\n\n// --- Embedding generation ---\n\nexport async function generateEmbedding(\n text: string,\n config: EmbeddingConfig,\n purpose: EmbeddingPurpose = \"document\",\n): Promise<Float32Array> {\n return resolveProvider(config).embed(text, purpose);\n}\n\n// --- Batch embedding ---\n\nexport async function generateEmbeddings(\n texts: string[],\n config: EmbeddingConfig,\n purpose: EmbeddingPurpose = \"document\",\n): Promise<Float32Array[]> {\n if (texts.length === 0) return [];\n return resolveProvider(config).embedBatch(texts, purpose);\n}\n\n// --- Storage ---\n\nexport function storeEmbedding(\n db: RecallDb,\n memoryId: string,\n text: string,\n embedding: Float32Array,\n config: EmbeddingConfig,\n) {\n const now = new Date().toISOString();\n const metadata = resolveProvider(config).metadata();\n const payload = {\n memory_id: memoryId,\n model: config.model,\n embedding_dimensions: metadata.canonical_dimensions,\n index_dimensions: metadata.index_dimensions,\n version: getEmbeddingVersion(config),\n content_hash: hashMemoryText(text),\n updated_at: now,\n embedding: serializeEmbedding(embedding),\n };\n\n db.insert(memoryEmbeddings)\n .values(payload)\n .onConflictDoUpdate({\n target: memoryEmbeddings.memory_id,\n set: {\n model: payload.model,\n embedding_dimensions: payload.embedding_dimensions,\n index_dimensions: payload.index_dimensions,\n version: payload.version,\n content_hash: payload.content_hash,\n updated_at: payload.updated_at,\n embedding: payload.embedding,\n },\n })\n .run();\n}\n\nexport function removeStoredEmbedding(\n db: RecallDb,\n memoryId: string,\n): boolean {\n const result = db.delete(memoryEmbeddings)\n .where(eq(memoryEmbeddings.memory_id, memoryId))\n .run();\n return result.changes > 0;\n}\n\nexport function loadEmbedding(\n db: RecallDb,\n memoryId: string,\n): Float32Array | null {\n const row = db\n .select({ embedding: memoryEmbeddings.embedding })\n .from(memoryEmbeddings)\n .where(eq(memoryEmbeddings.memory_id, memoryId))\n .get();\n\n if (!row?.embedding) return null;\n return deserializeEmbedding(row.embedding as Buffer);\n}\n\n// --- Lifecycle ---\n\nexport async function syncMemoryEmbedding(\n db: RecallDb,\n memoryId: string,\n config: EmbeddingConfig,\n): Promise<\"stored\" | \"updated\" | \"removed\" | \"skipped\"> {\n const memory = db\n .select()\n .from(memories)\n .where(eq(memories.id, memoryId))\n .get();\n\n if (!memory || !shouldEmbedMemory(memory)) {\n removeStoredEmbedding(db, memoryId);\n removeMemoryVecRow(db, memoryId, config);\n return \"removed\";\n }\n\n const existing = db\n .select()\n .from(memoryEmbeddings)\n .where(eq(memoryEmbeddings.memory_id, memoryId))\n .get();\n\n if (!rowNeedsEmbeddingRefresh(memory, existing, config)) {\n if (existing) {\n upsertMemoryVecRow(db, memory, existing);\n }\n return \"skipped\";\n }\n\n const embedding = await generateEmbedding(memory.text, config, \"document\");\n\n // Embedding generation is async; the parent memory may have been deleted\n // (e.g. test cleanup, hard-delete of a candidate) while we awaited. Skip the\n // insert in that case rather than tripping the FK on memory_embeddings.\n const stillExists = db\n .select({ id: memories.id })\n .from(memories)\n .where(eq(memories.id, memoryId))\n .get();\n if (!stillExists) {\n removeStoredEmbedding(db, memoryId);\n removeMemoryVecRow(db, memoryId, config);\n return \"removed\";\n }\n\n storeEmbedding(db, memory.id, memory.text, embedding, config);\n const refreshed = db\n .select()\n .from(memoryEmbeddings)\n .where(eq(memoryEmbeddings.memory_id, memory.id))\n .get();\n if (!refreshed) {\n throw new Error(`Failed to reload embedding row for ${memory.id}`);\n }\n upsertMemoryVecRow(db, memory, refreshed);\n return existing ? \"updated\" : \"stored\";\n}\n\nexport function queueMemoryEmbeddingSync(\n db: RecallDb,\n memoryId: string,\n config: EmbeddingConfig | null = loadEmbeddingConfigFromEnv(),\n): Promise<void> | null {\n syncMemoryFtsIndex(db, memoryId);\n\n if (!config) return null;\n\n const job = syncMemoryEmbedding(db, memoryId, config)\n .then(() => undefined)\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[recall] embedding sync failed for ${memoryId.slice(0, 8)}: ${message}`);\n })\n .finally(() => {\n pendingEmbeddingJobs.delete(job);\n });\n\n pendingEmbeddingJobs.add(job);\n return job;\n}\n\nexport async function flushEmbeddingJobs() {\n if (pendingEmbeddingJobs.size === 0) return;\n await Promise.allSettled([...pendingEmbeddingJobs]);\n}\n\nexport async function bootstrapEmbeddings(\n db: RecallDb,\n config: EmbeddingConfig,\n options: { repo?: string } = {},\n): Promise<number> {\n const rows = db.select().from(memories).all();\n const existingRows = db.select().from(memoryEmbeddings).all();\n const existingById = new Map(existingRows.map((row) => [row.memory_id, row]));\n\n const eligible = rows.filter((row) => {\n if (options.repo && row.repo !== options.repo) return false;\n return shouldEmbedMemory(row);\n });\n\n const pending = eligible.filter((row) => rowNeedsEmbeddingRefresh(row, existingById.get(row.id), config));\n\n for (const row of rows) {\n if (options.repo && row.repo !== options.repo) continue;\n if (!shouldEmbedMemory(row)) {\n removeStoredEmbedding(db, row.id);\n removeMemoryVecRow(db, row.id, config);\n }\n }\n\n let total = 0;\n for (let i = 0; i < pending.length; i += EMBEDDING_BATCH_SIZE) {\n const batch = pending.slice(i, i + EMBEDDING_BATCH_SIZE);\n const embeddings = await generateEmbeddings(\n batch.map((row) => row.text),\n config,\n \"document\",\n );\n\n for (let j = 0; j < batch.length; j++) {\n storeEmbedding(db, batch[j].id, batch[j].text, embeddings[j], config);\n total++;\n }\n }\n\n rebuildMemoryFtsIndex(db, options);\n rebuildMemoryVecIndex(db, config, options);\n return total;\n}\n\nexport function verifyEmbeddings(\n db: RecallDb,\n config: EmbeddingConfig,\n options: { repo?: string } = {},\n) {\n const rows = db.select().from(memories).all();\n const embeddingRows = db.select().from(memoryEmbeddings).all();\n const embeddingById = new Map(embeddingRows.map((row) => [row.memory_id, row]));\n\n let eligible = 0;\n let stale = 0;\n for (const row of rows) {\n if (options.repo && row.repo !== options.repo) continue;\n if (!shouldEmbedMemory(row)) continue;\n eligible++;\n\n if (rowNeedsEmbeddingRefresh(row, embeddingById.get(row.id), config)) {\n stale++;\n }\n }\n\n const vec = verifyMemoryVecIndex(db, options);\n const fts = verifyMemoryFtsIndex(db, options);\n return {\n eligible,\n stored: embeddingRows.filter((row) => {\n if (!options.repo) return true;\n const memory = rows.find((item) => item.id === row.memory_id);\n return memory?.repo === options.repo;\n }).length,\n stale,\n indexed: vec.indexed,\n index_drift: vec.drift,\n lexical_indexed: fts.indexed,\n lexical_drift: fts.drift,\n };\n}\n\nexport function rebuildEmbeddingIndex(\n db: RecallDb,\n config: EmbeddingConfig | null,\n options: { repo?: string } = {},\n) {\n const lexicalRows = rebuildMemoryFtsIndex(db, options);\n const vectorRows = config\n ? rebuildMemoryVecIndex(db, config, options)\n : 0;\n return {\n vector_rows: vectorRows,\n lexical_rows: lexicalRows,\n };\n}\n\nfunction lexicalRankToScore(rank: number, position: number): number {\n const safeRank = Number.isFinite(rank) ? Math.abs(rank) : position + 1;\n return 1 / (1 + safeRank + position);\n}\n\nexport async function hybridSearch(\n db: RecallDb,\n query: string,\n config: EmbeddingConfig | null,\n options: { repo?: string; limit?: number } = {},\n): Promise<Array<{\n memory: MemoryItem;\n score: number;\n similarity: number;\n lexical_score: number;\n}>> {\n const limit = options.limit ?? 10;\n const minSimilarity = config\n ? Math.max(config.similarity_threshold, MIN_HYBRID_VECTOR_SIMILARITY)\n : null;\n\n const lexicalMatches = searchMemoryFtsIndex(db, query, {\n repo: options.repo,\n limit: Math.max(limit * 2, 20),\n });\n const semanticMatches = config\n ? searchMemoryVecIndex(\n db,\n projectEmbeddingToIndex(\n await generateEmbedding(query, config, \"query\"),\n resolveProvider(config).metadata().index_dimensions,\n ),\n { repo: options.repo, limit: Math.max(limit * 2, 20) },\n )\n : [];\n\n const rowsById = new Map(\n db.select().from(memories).all().map((row) => [row.id, row]),\n );\n\n const merged = new Map<string, {\n memory: MemoryItem;\n similarity: number;\n lexical_score: number;\n score: number;\n }>();\n\n for (let i = 0; i < lexicalMatches.length; i++) {\n const match = lexicalMatches[i];\n const row = rowsById.get(match.memory_id);\n if (!row || !shouldEmbedMemory(row)) continue;\n\n const lexicalScore = lexicalRankToScore(match.lexical_rank, i);\n merged.set(match.memory_id, {\n memory: rowToMemory(row),\n similarity: 0,\n lexical_score: lexicalScore,\n score: lexicalScore * 0.35,\n });\n }\n\n for (const match of semanticMatches) {\n const row = rowsById.get(match.memory_id);\n if (!row || !shouldEmbedMemory(row)) continue;\n\n const similarity = Math.max(0, 1 - match.distance);\n if (minSimilarity !== null && similarity < minSimilarity) continue;\n const existing = merged.get(match.memory_id);\n if (existing) {\n existing.similarity = similarity;\n existing.score = (similarity * 0.65) + (existing.lexical_score * 0.35);\n } else {\n merged.set(match.memory_id, {\n memory: rowToMemory(row),\n similarity,\n lexical_score: 0,\n score: similarity * 0.65,\n });\n }\n }\n\n return [...merged.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n}\n\n// --- Cosine similarity ---\n\nexport function cosineSimilarity(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) return 0;\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; 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\n// --- Semantic search ---\n\nexport async function semanticSearch(\n db: RecallDb,\n query: string,\n config: EmbeddingConfig,\n options: { repo?: string; limit?: number } = {},\n): Promise<Array<{ memory: MemoryItem; similarity: number }>> {\n const queryEmbedding = projectEmbeddingToIndex(\n await generateEmbedding(query, config, \"query\"),\n resolveProvider(config).metadata().index_dimensions,\n );\n const matches = searchMemoryVecIndex(db, queryEmbedding, options);\n if (matches.length === 0) return [];\n\n const rowsById = new Map(\n db.select().from(memories).all().map((row) => [row.id, row]),\n );\n\n return matches\n .map((match) => {\n const row = rowsById.get(match.memory_id);\n if (!row || !shouldEmbedMemory(row)) return null;\n const similarity = 1 - match.distance;\n if (similarity < config.similarity_threshold) return null;\n return {\n memory: rowToMemory(row),\n similarity,\n };\n })\n .filter((item): item is { memory: MemoryItem; similarity: number } => item !== null)\n .sort((a, b) => b.similarity - a.similarity);\n}\n\n// --- Semantic dedup ---\n\nexport async function findSemanticDuplicates(\n db: RecallDb,\n text: string,\n config: EmbeddingConfig,\n threshold?: number,\n options: { repo?: string; type?: MemoryItem[\"type\"]; limit?: number } = {},\n): Promise<Array<{ id: string; text: string; similarity: number }>> {\n const queryEmbedding = await generateEmbedding(text, config, \"query\");\n const dupThreshold = threshold ?? config.similarity_threshold;\n\n const rows = db.select().from(memories).all();\n const embeddingsById = new Map(\n db.select().from(memoryEmbeddings).all().map((row) => [row.memory_id, row]),\n );\n\n const duplicates: Array<{ id: string; text: string; similarity: number }> = [];\n\n for (const row of rows) {\n if (options.repo && row.repo !== options.repo) continue;\n if (options.type && row.type !== options.type) continue;\n // Dedup is for live memories; rejected exemplars are intentionally not\n // matched here so a new candidate doesn't get linked to a rejected row.\n if (row.status === \"rejected\") continue;\n if (!shouldEmbedMemory(row)) continue;\n\n const embeddingRow = embeddingsById.get(row.id);\n if (!embeddingRow?.embedding) continue;\n\n const similarity = cosineSimilarity(\n queryEmbedding,\n deserializeEmbedding(embeddingRow.embedding as Buffer),\n );\n\n if (similarity >= dupThreshold) {\n duplicates.push({ id: row.id, text: row.text, similarity });\n }\n }\n\n return duplicates\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, options.limit ?? 10);\n}\n\n// Phase D.next: paraphrase-aware lookup against the rejected exemplar corpus.\n// Returns the highest-similarity rejected user_correction whose embedding\n// exceeds the threshold, or null. Used by capture to skip new candidates that\n// are semantically equivalent to something the user already rejected.\nexport async function findSimilarRejectedExemplar(\n db: RecallDb,\n text: string,\n config: EmbeddingConfig,\n threshold: number,\n): Promise<{ id: string; text: string; similarity: number } | null> {\n const queryEmbedding = await generateEmbedding(text, config, \"query\");\n\n const rejectedRows = db.select().from(memories)\n .where(eq(memories.status, \"rejected\"))\n .all()\n .filter((row) => row.source === \"user_correction\" || row.source === \"user_reported_review\");\n\n if (rejectedRows.length === 0) return null;\n\n const embeddingsById = new Map(\n db.select().from(memoryEmbeddings).all().map((row) => [row.memory_id, row]),\n );\n\n let best: { id: string; text: string; similarity: number } | null = null;\n for (const row of rejectedRows) {\n const embeddingRow = embeddingsById.get(row.id);\n if (!embeddingRow?.embedding) continue;\n const similarity = cosineSimilarity(\n queryEmbedding,\n deserializeEmbedding(embeddingRow.embedding as Buffer),\n );\n if (similarity >= threshold && (!best || similarity > best.similarity)) {\n best = { id: row.id, text: row.text, similarity };\n }\n }\n\n return best;\n}\n\n// --- Helpers ---\n\nfunction rowToMemory(row: MemoryRow): MemoryItem {\n const evidence =\n typeof row.evidence === \"string\"\n ? JSON.parse(row.evidence as string)\n : Array.isArray(row.evidence)\n ? row.evidence\n : [];\n const captureContext =\n typeof row.capture_context === \"string\"\n ? JSON.parse(row.capture_context as string)\n : row.capture_context ?? null;\n\n return {\n id: row.id,\n type: row.type,\n text: row.text,\n scope: row.scope,\n path_scope: row.path_scope,\n repo: row.repo,\n status: row.status,\n confidence: row.confidence,\n source: row.source,\n evidence: evidence as EvidenceEntry[],\n capture_context: captureContext as MemoryItem[\"capture_context\"],\n supersedes: row.supersedes,\n created_at: row.created_at,\n updated_at: row.updated_at,\n last_validated_at: row.last_validated_at,\n last_injected_at: row.last_injected_at,\n injection_count: row.injection_count,\n override_count: row.override_count,\n repetition_count: row.repetition_count,\n auto_inject: row.auto_inject,\n };\n}\n","import { z } from \"zod\";\n\n// --- Enums ---\n\nexport const MemoryStatus = z.enum([\n \"transient\",\n \"candidate\",\n \"active\",\n \"rejected\",\n]);\nexport type MemoryStatus = z.infer<typeof MemoryStatus>;\n\nexport const MemoryType = z.enum([\n \"rule\",\n \"command\",\n \"gotcha\",\n \"decision\",\n \"review_pattern\",\n]);\nexport type MemoryType = z.infer<typeof MemoryType>;\n\nexport const MemoryScope = z.enum([\"session\", \"path\", \"repo\", \"team\", \"global\"]);\nexport type MemoryScope = z.infer<typeof MemoryScope>;\n\nexport const MemorySource = z.enum([\n \"user_correction\",\n \"user_reported_review\",\n \"repo_scan\",\n \"config_parse\",\n]);\nexport type MemorySource = z.infer<typeof MemorySource>;\n\nexport const FeedbackOutcome = z.enum([\n \"followed\",\n \"overridden\",\n \"ignored\",\n \"contradicted\",\n]);\nexport type FeedbackOutcome = z.infer<typeof FeedbackOutcome>;\n\n// --- Evidence ---\n\nexport const EvidenceEntry = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"session_correction\"),\n session: z.string(),\n timestamp: z.string(),\n context: z.string().optional(),\n }),\n z.object({\n type: z.literal(\"review_feedback\"),\n reported_by_user: z.boolean(),\n reviewer: z.string().optional(),\n timestamp: z.string(),\n context: z.string().optional(),\n }),\n z.object({\n type: z.literal(\"repo_scan\"),\n file: z.string(),\n timestamp: z.string(),\n }),\n z.object({\n type: z.literal(\"repeated_correction\"),\n count: z.number(),\n sessions: z.array(z.string()),\n timestamp: z.string(),\n }),\n]);\nexport type EvidenceEntry = z.infer<typeof EvidenceEntry>;\n\nexport const CaptureContextToolCall = z.object({\n name: z.string(),\n path: z.string().optional(),\n exit_code: z.number().optional(),\n});\nexport type CaptureContextToolCall = z.infer<typeof CaptureContextToolCall>;\n\nexport const CaptureContext = z.object({\n prev_assistant_text: z.string().optional(),\n recent_tool_calls: z.array(CaptureContextToolCall).max(5).optional(),\n repo: z.string().nullable().optional(),\n path: z.string().nullable().optional(),\n agent: z.string().optional(),\n});\nexport type CaptureContext = z.infer<typeof CaptureContext>;\n\n// --- Memory Item ---\n\nexport const MemoryItem = z.object({\n id: z.string().uuid(),\n type: MemoryType,\n text: z.string(),\n scope: MemoryScope,\n path_scope: z.string().nullable(),\n repo: z.string().nullable(),\n status: MemoryStatus,\n confidence: z.number().min(0).max(1),\n source: MemorySource,\n evidence: z.array(EvidenceEntry),\n capture_context: CaptureContext.nullable(),\n supersedes: z.string().uuid().nullable(),\n created_at: z.string(),\n updated_at: z.string(),\n last_validated_at: z.string().nullable(),\n last_injected_at: z.string().nullable(),\n injection_count: z.number().int().nonnegative(),\n override_count: z.number().int().nonnegative(),\n repetition_count: z.number().int().nonnegative(),\n auto_inject: z.boolean(),\n});\nexport type MemoryItem = z.infer<typeof MemoryItem>;\n\n// --- Feedback Event ---\n\nexport const FeedbackEvent = z.object({\n id: z.string().uuid(),\n memory_id: z.string().uuid(),\n session_id: z.string(),\n injected: z.boolean(),\n outcome: FeedbackOutcome,\n timestamp: z.string(),\n});\nexport type FeedbackEvent = z.infer<typeof FeedbackEvent>;\n\nexport const MemoryInjection = z.object({\n id: z.string().uuid(),\n memory_id: z.string().uuid(),\n session_id: z.string(),\n repo: z.string().nullable(),\n injected_at: z.string(),\n outcome: FeedbackOutcome.nullable(),\n outcome_at: z.string().nullable(),\n});\nexport type MemoryInjection = z.infer<typeof MemoryInjection>;\n\n// --- Delegated maintenance tasks ---\n\nexport const MaintenanceTaskKind = z.enum([\n \"summarize_history\",\n \"merge_duplicates\",\n \"refine_candidate\",\n \"summarize_session\",\n \"synthesize_repo\",\n \"verify_capture\",\n \"extract_rules_from_prompt\",\n]);\nexport type MaintenanceTaskKind = z.infer<typeof MaintenanceTaskKind>;\n\nexport const MaintenanceTaskStatus = z.enum([\n \"pending\",\n \"claimed\",\n \"submitted\",\n \"completed\",\n \"abandoned\",\n]);\nexport type MaintenanceTaskStatus = z.infer<typeof MaintenanceTaskStatus>;\n\nexport const MaintenanceTask = z.object({\n id: z.string().uuid(),\n kind: MaintenanceTaskKind,\n status: MaintenanceTaskStatus,\n priority: z.number().int(),\n repo: z.string().nullable(),\n target_key: z.string(),\n payload: z.record(z.string(), z.unknown()),\n result: z.record(z.string(), z.unknown()).nullable(),\n failure_reason: z.string().nullable(),\n claimed_by: z.string().nullable(),\n claimed_at: z.string().nullable(),\n claim_expires_at: z.string().nullable(),\n submitted_at: z.string().nullable(),\n completed_at: z.string().nullable(),\n created_at: z.string(),\n attempts: z.number().int().nonnegative(),\n max_attempts: z.number().int().positive(),\n});\nexport type MaintenanceTask = z.infer<typeof MaintenanceTask>;\n\n// --- Activity events ---\n\nexport const ACTIVITY_TRANSPORTS = [\"cli\", \"daemon\", \"mcp\", \"system\", \"hook\"] as const;\nexport type ActivityTransport = (typeof ACTIVITY_TRANSPORTS)[number];\n\n// Source is either a bare transport (\"mcp\", \"cli\", ...) or a transport tagged with a\n// client identity (\"mcp:claude-code\", \"hook:codex\"). The regex keeps the column disciplined\n// without forcing a closed enum — new clients just work.\nconst ACTIVITY_SOURCE_PATTERN = /^(cli|daemon|mcp|system|hook)(:[a-z0-9][a-z0-9._-]*)?$/;\nexport const ActivitySource = z.string().regex(ACTIVITY_SOURCE_PATTERN);\nexport type ActivitySource = z.infer<typeof ActivitySource>;\n\nexport function tagActivitySource(transport: ActivityTransport, agent?: string | null): ActivitySource {\n if (!agent) return transport;\n const normalized = agent.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, \"-\");\n if (!normalized) return transport;\n return `${transport}:${normalized}`;\n}\n\nexport const ActivityEventType = z.enum([\n \"compile\",\n \"query\",\n \"scan\",\n \"correction\",\n \"review\",\n \"feedback\",\n \"signal\",\n \"session_start\",\n \"session_event\",\n \"session_end\",\n \"tool_call\",\n]);\nexport type ActivityEventType = z.infer<typeof ActivityEventType>;\n\nexport const ActivityEvent = z.object({\n id: z.string().uuid(),\n session_id: z.string().nullable(),\n repo: z.string().nullable(),\n path: z.string().nullable(),\n source: ActivitySource,\n event_type: ActivityEventType,\n memory_ids: z.array(z.string().uuid()),\n request: z.record(z.string(), z.unknown()),\n result: z.record(z.string(), z.unknown()),\n created_at: z.string(),\n});\nexport type ActivityEvent = z.infer<typeof ActivityEvent>;\n\nexport const ActivityEventQuery = z.object({\n repo: z.string().optional(),\n session_id: z.string().optional(),\n source: ActivitySource.optional(),\n event_type: ActivityEventType.optional(),\n since: z.string().optional(),\n limit: z.number().int().positive().optional(),\n});\nexport type ActivityEventQuery = z.infer<typeof ActivityEventQuery>;\n\nexport const HookCallEvent = z.enum([\n \"session_started\",\n \"prompt_submitted\",\n \"tool_invoked\",\n \"session_ended\",\n]);\nexport type HookCallEvent = z.infer<typeof HookCallEvent>;\n\nexport const HookCall = z.object({\n id: z.string().uuid(),\n event: HookCallEvent,\n agent: z.string(),\n duration_ms: z.number().int().nonnegative(),\n ok: z.boolean(),\n created_at: z.string(),\n});\nexport type HookCall = z.infer<typeof HookCall>;\n\nexport const HookCallStatsQuery = z.object({\n agent: z.string().optional(),\n event: HookCallEvent.optional(),\n limit: z.number().int().positive().optional(),\n});\nexport type HookCallStatsQuery = z.infer<typeof HookCallStatsQuery>;\n\nexport const HookCallStatsRow = z.object({\n event: HookCallEvent,\n agent: z.string(),\n total_calls: z.number().int().nonnegative(),\n ok_calls: z.number().int().nonnegative(),\n error_calls: z.number().int().nonnegative(),\n avg_duration_ms: z.number().nonnegative(),\n max_duration_ms: z.number().int().nonnegative(),\n last_called_at: z.string(),\n});\nexport type HookCallStatsRow = z.infer<typeof HookCallStatsRow>;\n\n// --- Confidence thresholds ---\n\nexport const CONFIDENCE = {\n /** Below this → transient, never stored durably */\n TRANSIENT_MAX: 0.3,\n /** Below this → candidate, stored but not injected */\n CANDIDATE_MAX: 0.6,\n /** At or above this → active, injected when scope matches */\n ACTIVE_MIN: 0.6,\n} as const;\n\n// --- Promotion weights ---\n\nexport const PROMOTION = {\n /** User explicitly confirms */\n EXPLICIT_CONFIRM: 0.8,\n /** Same correction repeats */\n REPEAT_CORRECTION: 0.2,\n /** User-reported review feedback */\n REVIEW_FEEDBACK: 0.3,\n /** Passive gain per use without override */\n PASSIVE_GAIN: 0.05,\n} as const;\n\n// --- Compiler config ---\n\nexport const CompilerConfig = z.object({\n confidence_threshold: z.number().default(0.6),\n max_lines: z.number().default(15),\n max_commands: z.number().default(3),\n max_gotchas: z.number().default(3),\n max_history_snippets: z.number().default(2),\n token_budget: z.number().default(2000),\n include_candidates: z.boolean().default(false),\n});\nexport type CompilerConfig = z.infer<typeof CompilerConfig>;\n\n// --- Query ---\n\nexport const MemoryQuery = z.object({\n repo: z.string().optional(),\n path: z.string().optional(),\n scope: MemoryScope.optional(),\n type: MemoryType.optional(),\n status: MemoryStatus.optional(),\n min_confidence: z.number().optional(),\n semantic_query: z.string().optional(),\n auto_inject: z.boolean().optional(),\n limit: z.number().int().positive().optional(),\n offset: z.number().int().nonnegative().optional(),\n});\nexport type MemoryQuery = z.infer<typeof MemoryQuery>;\n\n// --- Sync (Phase 2) ---\n\nexport const SyncConfig = z.object({\n remote_url: z.string().url(),\n api_key: z.string(),\n team_id: z.string().optional(),\n auto_sync: z.boolean().default(false),\n sync_interval_seconds: z.number().default(300),\n});\nexport type SyncConfig = z.infer<typeof SyncConfig>;\n\nexport const SyncDirection = z.enum([\"push\", \"pull\", \"both\"]);\nexport type SyncDirection = z.infer<typeof SyncDirection>;\n\nexport const SyncResult = z.object({\n pushed: z.number(),\n pulled: z.number(),\n conflicts: z.number(),\n errors: z.array(z.string()),\n});\nexport type SyncResult = z.infer<typeof SyncResult>;\n\n// --- Team (Phase 2) ---\n\nexport const TeamMember = z.object({\n id: z.string().uuid(),\n team_id: z.string().uuid(),\n user_id: z.string(),\n role: z.enum([\"owner\", \"admin\", \"member\"]),\n joined_at: z.string(),\n});\nexport type TeamMember = z.infer<typeof TeamMember>;\n\n// --- Embeddings (Phase 2) ---\n\nexport const EmbeddingConfig = z.object({\n provider: z.enum([\"nomic\", \"multilingual-e5\", \"bge-small-en-v1.5\"]).default(\"nomic\"),\n model: z.string().default(\"nomic-ai/nomic-embed-text-v1.5\"),\n dimensions: z.number().default(512),\n version: z.string().default(\"v1\"),\n similarity_threshold: z.number().default(0.8),\n});\nexport type EmbeddingConfig = z.infer<typeof EmbeddingConfig>;\n\nexport const HistorySnippetKind = z.enum([\n \"session_summary\",\n \"correction_summary\",\n \"decision_summary\",\n \"review_summary\",\n \"compile_summary\",\n \"repo_synthesis\",\n]);\nexport type HistorySnippetKind = z.infer<typeof HistorySnippetKind>;\n\nexport const HistorySnippet = z.object({\n id: z.string().uuid(),\n repo: z.string().nullable(),\n session_id: z.string().nullable(),\n kind: HistorySnippetKind,\n text: z.string(),\n source_activity_ids: z.array(z.string().uuid()),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type HistorySnippet = z.infer<typeof HistorySnippet>;\n\n// --- Evaluation (Phase 2) ---\n\nexport const EvalSession = z.object({\n id: z.string().uuid(),\n repo: z.string(),\n started_at: z.string(),\n ended_at: z.string().nullable(),\n memories_injected: z.number(),\n memories_followed: z.number(),\n memories_overridden: z.number(),\n user_corrections: z.number(),\n test_passes: z.number(),\n test_failures: z.number(),\n});\nexport type EvalSession = z.infer<typeof EvalSession>;\n\nexport const MaintenanceEvalMetrics = z.object({\n total_completed: z.number(),\n total_abandoned: z.number(),\n abandon_rate: z.number(),\n mean_completion_ms: z.number().nullable(),\n completed_by_kind: z.record(z.number()),\n merge_precision: z.number().nullable(),\n merge_rollbacks: z.number(),\n});\nexport type MaintenanceEvalMetrics = z.infer<typeof MaintenanceEvalMetrics>;\n\nexport const EvalMetrics = z.object({\n total_sessions: z.number(),\n injection_rate: z.number(),\n follow_rate: z.number(),\n override_rate: z.number(),\n correction_frequency: z.number(),\n avg_confidence_at_injection: z.number(),\n memory_effectiveness: z.number(),\n maintenance: MaintenanceEvalMetrics.optional(),\n});\nexport type EvalMetrics = z.infer<typeof EvalMetrics>;\n\nexport const RetrievalEvalCase = z.object({\n name: z.string(),\n repo: z.string(),\n path: z.string().optional(),\n query_text: z.string().default(\"\"),\n include_candidates: z.boolean().default(false),\n confidence_threshold: z.number().optional(),\n max_lines: z.number().optional(),\n max_commands: z.number().optional(),\n max_gotchas: z.number().optional(),\n token_budget: z.number().optional(),\n expected_all_texts: z.array(z.string()).default([]),\n expected_any_texts: z.array(z.string()).default([]),\n forbidden_texts: z.array(z.string()).default([]),\n min_included: z.number().int().nonnegative().optional(),\n max_included: z.number().int().nonnegative().optional(),\n});\nexport type RetrievalEvalCase = z.infer<typeof RetrievalEvalCase>;\n\nexport const RetrievalEvalFile = z.object({\n cases: z.array(RetrievalEvalCase),\n});\nexport type RetrievalEvalFile = z.infer<typeof RetrievalEvalFile>;\n\n// --- Implicit feedback (Phase 2) ---\n\nexport const ImplicitSignal = z.object({\n id: z.string().uuid(),\n memory_id: z.string().uuid(),\n session_id: z.string(),\n signal_type: z.enum([\n \"test_pass\",\n \"test_fail\",\n \"file_unchanged\",\n \"file_rewritten\",\n \"task_accepted\",\n \"task_rejected\",\n ]),\n timestamp: z.string(),\n context: z.string().optional(),\n});\nexport type ImplicitSignal = z.infer<typeof ImplicitSignal>;\n\n// --- Recall config (Phase 2) ---\n\nexport const RecallConfig = z.object({\n sync: SyncConfig.optional(),\n embeddings: EmbeddingConfig.optional(),\n});\nexport type RecallConfig = z.infer<typeof RecallConfig>;\n\n// --- Policy (Phase 3) ---\n\nexport const PolicyRule = z.object({\n id: z.string().uuid(),\n org_id: z.string(),\n rule_type: z.enum([\n \"min_confidence\",\n \"require_approval\",\n \"allowed_sources\",\n \"blocked_scopes\",\n \"auto_approve_pattern\",\n \"max_active_per_repo\",\n \"require_evidence_count\",\n ]),\n config: z.record(z.unknown()),\n enabled: z.boolean(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type PolicyRule = z.infer<typeof PolicyRule>;\n\nexport const ApprovalStatus = z.enum([\"pending\", \"approved\", \"denied\"]);\nexport type ApprovalStatus = z.infer<typeof ApprovalStatus>;\n\nexport const ApprovalRequest = z.object({\n id: z.string().uuid(),\n memory_id: z.string().uuid(),\n org_id: z.string(),\n requested_by: z.string(),\n status: ApprovalStatus,\n reviewed_by: z.string().nullable(),\n reason: z.string().nullable(),\n created_at: z.string(),\n resolved_at: z.string().nullable(),\n});\nexport type ApprovalRequest = z.infer<typeof ApprovalRequest>;\n\n// --- Health scoring (Phase 3) ---\n\nexport const HealthScore = z.object({\n memory_id: z.string().uuid(),\n score: z.number().min(0).max(1),\n confidence_component: z.number(),\n freshness_component: z.number(),\n follow_rate_component: z.number(),\n signal_ratio_component: z.number(),\n computed_at: z.string(),\n});\nexport type HealthScore = z.infer<typeof HealthScore>;\n\n// --- Contradiction (Phase 3) ---\n\nexport const Contradiction = z.object({\n id: z.string().uuid(),\n memory_a_id: z.string().uuid(),\n memory_b_id: z.string().uuid(),\n contradiction_type: z.enum([\n \"direct_negation\",\n \"conflicting_rules\",\n \"scope_overlap\",\n \"superseded\",\n ]),\n severity: z.enum([\"low\", \"medium\", \"high\"]),\n description: z.string(),\n resolved: z.boolean(),\n resolution: z.string().nullable(),\n detected_at: z.string(),\n resolved_at: z.string().nullable(),\n});\nexport type Contradiction = z.infer<typeof Contradiction>;\n\n// --- Pruning config (Phase 3) ---\n\nexport const PruneConfig = z.object({\n repo: z.string().optional(),\n stale_days: z.number().default(90),\n rejected_retention_days: z.number().default(30),\n transient_retention_days: z.number().default(7),\n min_health_score: z.number().default(0.2),\n dry_run: z.boolean().default(false),\n});\nexport type PruneConfig = z.infer<typeof PruneConfig>;\n\n// --- Audit trail (Phase 3) ---\n\nexport const AuditAction = z.enum([\n \"created\",\n \"promoted\",\n \"demoted\",\n \"rejected\",\n \"confirmed\",\n \"reactivated\",\n \"edited\",\n \"pruned\",\n \"policy_applied\",\n \"approval_requested\",\n \"approval_resolved\",\n \"contradiction_detected\",\n \"contradiction_resolved\",\n \"rolled_back\",\n]);\nexport type AuditAction = z.infer<typeof AuditAction>;\n\nexport const AuditEntry = z.object({\n id: z.string().uuid(),\n memory_id: z.string().uuid(),\n action: AuditAction,\n actor: z.string(),\n before_snapshot: z.string().nullable(),\n after_snapshot: z.string().nullable(),\n reason: z.string().nullable(),\n timestamp: z.string(),\n});\nexport type AuditEntry = z.infer<typeof AuditEntry>;\n","import { existsSync, mkdirSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { EmbeddingConfig } from \"../types.js\";\n\nexport function getEmbeddingCacheRoot(): string {\n if (process.platform === \"linux\" && process.env.XDG_CACHE_HOME) {\n return join(process.env.XDG_CACHE_HOME, \"recall\", \"models\");\n }\n return join(homedir(), \".recall\", \"models\");\n}\n\nexport function getEmbeddingCachePath(\n config: Pick<EmbeddingConfig, \"provider\" | \"model\">,\n): string {\n return join(getEmbeddingCacheRoot(), config.provider, ...config.model.split(\"/\"));\n}\n\nexport function ensureEmbeddingCachePath(\n config: Pick<EmbeddingConfig, \"provider\" | \"model\">,\n): string {\n const cachePath = getEmbeddingCachePath(config);\n mkdirSync(cachePath, { recursive: true });\n return cachePath;\n}\n\nexport function getDirectorySize(path: string): number {\n if (!existsSync(path)) return 0;\n\n const stat = statSync(path);\n if (!stat.isDirectory()) return stat.size;\n\n let total = 0;\n for (const entry of readdirSync(path, { withFileTypes: true })) {\n total += getDirectorySize(join(path, entry.name));\n }\n return total;\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 ** 3) return `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n return `${(bytes / 1024 ** 3).toFixed(1)} GB`;\n}\n","import { pipeline, type FeatureExtractionPipeline, type Tensor } from \"@huggingface/transformers\";\nimport type { EmbeddingConfig } from \"../../types.js\";\nimport { ensureEmbeddingCachePath } from \"../cache.js\";\nimport type { EmbeddingPurpose, EmbeddingProvider } from \"./types.js\";\n\nconst BGE_MODEL = \"Xenova/bge-small-en-v1.5\";\nconst BGE_DIMENSIONS = 384;\n\nlet extractorPromise: Promise<FeatureExtractionPipeline> | null = null;\n\nfunction getModel(config: EmbeddingConfig): string {\n return config.model || BGE_MODEL;\n}\n\nfunction getDimensions(config: EmbeddingConfig): number {\n const dimensions = config.dimensions || BGE_DIMENSIONS;\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new Error(`Invalid bge-small-en-v1.5 embedding dimensions: ${dimensions}`);\n }\n if (dimensions > BGE_DIMENSIONS) {\n throw new Error(`bge-small-en-v1.5 embeddings support at most ${BGE_DIMENSIONS} dimensions`);\n }\n return dimensions;\n}\n\nasync function getExtractor(config: EmbeddingConfig): Promise<FeatureExtractionPipeline> {\n const cacheDir = ensureEmbeddingCachePath({\n provider: config.provider,\n model: getModel(config),\n });\n extractorPromise ??= pipeline(\"feature-extraction\", getModel(config), {\n cache_dir: cacheDir,\n dtype: \"q8\",\n });\n return extractorPromise;\n}\n\nfunction tensorToEmbeddings(tensor: Tensor): Float32Array[] {\n const [rows, columns] = tensor.dims.length === 1\n ? [1, tensor.dims[0]]\n : tensor.dims;\n if (!rows || !columns) {\n throw new Error(`Unexpected bge-small-en-v1.5 tensor shape: [${tensor.dims.join(\", \")}]`);\n }\n\n const embeddings: Float32Array[] = [];\n for (let row = 0; row < rows; row++) {\n const start = row * columns;\n const end = start + columns;\n embeddings.push(Float32Array.from(tensor.data.subarray(start, end)));\n }\n return embeddings;\n}\n\nasync function embedTexts(\n texts: string[],\n config: EmbeddingConfig,\n): Promise<Float32Array[]> {\n if (texts.length === 0) return [];\n\n const extractor = await getExtractor(config);\n const embeddings = await extractor(texts, {\n pooling: \"mean\",\n normalize: true,\n });\n\n return tensorToEmbeddings(\n embeddings.dims.at(-1) === getDimensions(config)\n ? embeddings\n : embeddings.slice(null, [0, getDimensions(config)]).normalize(2, -1),\n );\n}\n\nexport function createBgeSmallEnV15Provider(config: EmbeddingConfig): EmbeddingProvider {\n return {\n async embed(text: string, _purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array> {\n const [embedding] = await embedTexts([text], config);\n return embedding;\n },\n\n async embedBatch(texts: string[], _purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array[]> {\n return embedTexts(texts, config);\n },\n\n async prepare(): Promise<void> {\n await getExtractor(config);\n },\n\n metadata() {\n const dims = getDimensions(config);\n return {\n model: getModel(config),\n dimensions: dims,\n canonical_dimensions: dims,\n index_dimensions: dims,\n version: config.version,\n estimated_size_mb: 133,\n };\n },\n };\n}\n","import { pipeline, type FeatureExtractionPipeline, type Tensor } from \"@huggingface/transformers\";\nimport type { EmbeddingConfig } from \"../../types.js\";\nimport { ensureEmbeddingCachePath } from \"../cache.js\";\nimport type { EmbeddingPurpose, EmbeddingProvider } from \"./types.js\";\n\nconst MULTILINGUAL_E5_MODEL = \"Xenova/multilingual-e5-small\";\nconst MULTILINGUAL_E5_NATIVE_DIMENSIONS = 384;\nconst MULTILINGUAL_E5_PREFIXES: Record<EmbeddingPurpose, string> = {\n document: \"passage: \",\n query: \"query: \",\n};\n\nlet extractorPromise: Promise<FeatureExtractionPipeline> | null = null;\n\nfunction getModel(config: EmbeddingConfig): string {\n return config.model || MULTILINGUAL_E5_MODEL;\n}\n\nfunction getDimensions(config: EmbeddingConfig): number {\n const dimensions = config.dimensions || MULTILINGUAL_E5_NATIVE_DIMENSIONS;\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new Error(`Invalid multilingual-e5 embedding dimensions: ${dimensions}`);\n }\n if (dimensions > MULTILINGUAL_E5_NATIVE_DIMENSIONS) {\n throw new Error(`multilingual-e5 embeddings support at most ${MULTILINGUAL_E5_NATIVE_DIMENSIONS} dimensions`);\n }\n return dimensions;\n}\n\nfunction prefixTexts(texts: string[], purpose: EmbeddingPurpose): string[] {\n const prefix = MULTILINGUAL_E5_PREFIXES[purpose];\n return texts.map((text) => `${prefix}${text}`);\n}\n\nasync function getExtractor(config: EmbeddingConfig): Promise<FeatureExtractionPipeline> {\n const cacheDir = ensureEmbeddingCachePath({\n provider: config.provider,\n model: getModel(config),\n });\n extractorPromise ??= pipeline(\"feature-extraction\", getModel(config), {\n cache_dir: cacheDir,\n dtype: \"q8\",\n });\n return extractorPromise;\n}\n\nfunction tensorToEmbeddings(tensor: Tensor): Float32Array[] {\n const [rows, columns] = tensor.dims.length === 1\n ? [1, tensor.dims[0]]\n : tensor.dims;\n if (!rows || !columns) {\n throw new Error(`Unexpected multilingual-e5 tensor shape: [${tensor.dims.join(\", \")}]`);\n }\n\n const embeddings: Float32Array[] = [];\n for (let row = 0; row < rows; row++) {\n const start = row * columns;\n const end = start + columns;\n embeddings.push(Float32Array.from(tensor.data.subarray(start, end)));\n }\n return embeddings;\n}\n\nasync function embedTexts(\n texts: string[],\n config: EmbeddingConfig,\n purpose: EmbeddingPurpose,\n): Promise<Float32Array[]> {\n if (texts.length === 0) return [];\n\n const extractor = await getExtractor(config);\n const embeddings = await extractor(prefixTexts(texts, purpose), {\n pooling: \"mean\",\n normalize: true,\n });\n\n return tensorToEmbeddings(\n embeddings.dims.at(-1) === getDimensions(config)\n ? embeddings\n : embeddings.slice(null, [0, getDimensions(config)]).normalize(2, -1),\n );\n}\n\nexport function createMultilingualE5Provider(config: EmbeddingConfig): EmbeddingProvider {\n return {\n async embed(text: string, purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array> {\n const [embedding] = await embedTexts([text], config, purpose);\n return embedding;\n },\n\n async embedBatch(texts: string[], purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array[]> {\n return embedTexts(texts, config, purpose);\n },\n\n async prepare(): Promise<void> {\n await getExtractor(config);\n },\n\n metadata() {\n const dims = getDimensions(config);\n return {\n model: getModel(config),\n dimensions: dims,\n canonical_dimensions: dims,\n index_dimensions: dims,\n version: config.version,\n task_prefix: `${MULTILINGUAL_E5_PREFIXES.document.trim()} | ${MULTILINGUAL_E5_PREFIXES.query.trim()}`,\n estimated_size_mb: 113,\n };\n },\n };\n}\n","import { layer_norm, pipeline, type FeatureExtractionPipeline, type Tensor } from \"@huggingface/transformers\";\nimport type { EmbeddingConfig } from \"../../types.js\";\nimport { ensureEmbeddingCachePath } from \"../cache.js\";\nimport type { EmbeddingPurpose, EmbeddingProvider } from \"./types.js\";\n\nconst NOMIC_MODEL = \"nomic-ai/nomic-embed-text-v1.5\";\nconst NOMIC_NATIVE_DIMENSIONS = 768;\nconst NOMIC_PREFIXES: Record<EmbeddingPurpose, string> = {\n document: \"search_document: \",\n query: \"search_query: \",\n};\n\nlet extractorPromise: Promise<FeatureExtractionPipeline> | null = null;\n\nfunction getModel(config: EmbeddingConfig): string {\n return config.model || NOMIC_MODEL;\n}\n\nfunction getDimensions(config: EmbeddingConfig): number {\n const dimensions = config.dimensions || 512;\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new Error(`Invalid nomic embedding dimensions: ${dimensions}`);\n }\n if (dimensions > NOMIC_NATIVE_DIMENSIONS) {\n throw new Error(`Nomic embeddings support at most ${NOMIC_NATIVE_DIMENSIONS} dimensions`);\n }\n return dimensions;\n}\n\nfunction prefixTexts(texts: string[], purpose: EmbeddingPurpose): string[] {\n const prefix = NOMIC_PREFIXES[purpose];\n return texts.map((text) => `${prefix}${text}`);\n}\n\nasync function getExtractor(config: EmbeddingConfig): Promise<FeatureExtractionPipeline> {\n const cacheDir = ensureEmbeddingCachePath({\n provider: config.provider,\n model: getModel(config),\n });\n extractorPromise ??= pipeline(\"feature-extraction\", getModel(config), {\n cache_dir: cacheDir,\n dtype: \"q8\",\n });\n return extractorPromise;\n}\n\nfunction tensorToEmbeddings(tensor: Tensor): Float32Array[] {\n const [rows, columns] = tensor.dims.length === 1\n ? [1, tensor.dims[0]]\n : tensor.dims;\n if (!rows || !columns) {\n throw new Error(`Unexpected nomic tensor shape: [${tensor.dims.join(\", \")}]`);\n }\n\n const embeddings: Float32Array[] = [];\n for (let row = 0; row < rows; row++) {\n const start = row * columns;\n const end = start + columns;\n embeddings.push(Float32Array.from(tensor.data.subarray(start, end)));\n }\n return embeddings;\n}\n\nasync function embedTexts(\n texts: string[],\n config: EmbeddingConfig,\n purpose: EmbeddingPurpose,\n): Promise<Float32Array[]> {\n if (texts.length === 0) return [];\n\n const extractor = await getExtractor(config);\n const rawEmbeddings = await extractor(prefixTexts(texts, purpose), {\n pooling: \"mean\",\n });\n\n const nativeDimensions = rawEmbeddings.dims.at(-1);\n if (!nativeDimensions) {\n throw new Error(\"Nomic extractor returned an embedding tensor without dimensions\");\n }\n\n const normalized = layer_norm(rawEmbeddings, [nativeDimensions]).normalize(2, -1);\n\n return tensorToEmbeddings(normalized);\n}\n\nexport function createNomicProvider(config: EmbeddingConfig): EmbeddingProvider {\n return {\n async embed(text: string, purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array> {\n const [embedding] = await embedTexts([text], config, purpose);\n return embedding;\n },\n\n async embedBatch(texts: string[], purpose: EmbeddingPurpose = \"document\"): Promise<Float32Array[]> {\n return embedTexts(texts, config, purpose);\n },\n\n async prepare(): Promise<void> {\n await getExtractor(config);\n },\n\n metadata() {\n const indexDimensions = getDimensions(config);\n return {\n model: getModel(config),\n dimensions: indexDimensions,\n canonical_dimensions: NOMIC_NATIVE_DIMENSIONS,\n index_dimensions: indexDimensions,\n version: config.version,\n task_prefix: `${NOMIC_PREFIXES.document.trim()} | ${NOMIC_PREFIXES.query.trim()}`,\n estimated_size_mb: 140,\n };\n },\n };\n}\n","import type { EmbeddingConfig } from \"../../types.js\";\nimport { createBgeSmallEnV15Provider } from \"./bge-small-en-v1.5.js\";\nimport { createMultilingualE5Provider } from \"./multilingual-e5.js\";\nimport { createNomicProvider } from \"./nomic.js\";\nimport type { EmbeddingProvider } from \"./types.js\";\n\nexport function resolveProvider(config: EmbeddingConfig): EmbeddingProvider {\n switch (config.provider) {\n case \"bge-small-en-v1.5\":\n return createBgeSmallEnV15Provider(config);\n case \"multilingual-e5\":\n return createMultilingualE5Provider(config);\n case \"nomic\":\n return createNomicProvider(config);\n default:\n throw new Error(`Unsupported embedding provider: ${config.provider}`);\n }\n}\n","import * as sqliteVec from \"sqlite-vec\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { memories, memoryEmbeddings } from \"../db/schema.js\";\nimport { eq } from \"drizzle-orm\";\nimport type { EmbeddingConfig } from \"../types.js\";\n\nconst VEC_MEMORY_INDEX = \"vec_memory_index\";\nconst loadedClients = new WeakSet<object>();\n\ntype MemoryRow = typeof memories.$inferSelect;\ntype MemoryEmbeddingRow = typeof memoryEmbeddings.$inferSelect;\n\nfunction getSqlite(db: RecallDb) {\n return db.$client;\n}\n\nfunction hasMemoryVecIndex(db: RecallDb): boolean {\n return Boolean(\n getSqlite(db)\n .prepare(\"select 1 from sqlite_master where type = 'table' and name = ?\")\n .get(VEC_MEMORY_INDEX),\n );\n}\n\nexport function ensureSqliteVecLoaded(db: RecallDb) {\n const sqlite = getSqlite(db);\n if (loadedClients.has(sqlite)) return;\n sqliteVec.load(sqlite);\n loadedClients.add(sqlite);\n}\n\nfunction getMemoryVecDimension(rows: Array<Pick<MemoryEmbeddingRow, \"index_dimensions\">>): number | null {\n const dimensions = [...new Set(rows.map((row) => row.index_dimensions))];\n if (dimensions.length === 0) return null;\n if (dimensions.length > 1) {\n throw new Error(\n `sqlite-vec index rebuild refused mixed memory embedding dimensions: ${dimensions.join(\", \")}.`,\n );\n }\n return dimensions[0];\n}\n\nexport function ensureMemoryVecIndex(\n db: RecallDb,\n dimensions: number,\n) {\n ensureSqliteVecLoaded(db);\n\n const sqlite = getSqlite(db);\n const existing = sqlite\n .prepare(\"select sql from sqlite_master where type = 'table' and name = ?\")\n .get(VEC_MEMORY_INDEX) as { sql?: string } | undefined;\n\n const expectedDimension = `float[${dimensions}]`;\n if (existing?.sql && !existing.sql.includes(expectedDimension)) {\n throw new Error(\n `sqlite-vec index dimension mismatch. Expected ${expectedDimension}. Run \\`recall embeddings rebuild-index\\`.`,\n );\n }\n\n sqlite.exec(`\n create virtual table if not exists ${VEC_MEMORY_INDEX} using vec0(\n embedding float[${dimensions}] distance_metric=cosine,\n memory_id text,\n repo text,\n status text,\n type text,\n scope text\n );\n `);\n}\n\nexport function dropMemoryVecIndex(db: RecallDb) {\n ensureSqliteVecLoaded(db);\n getSqlite(db).exec(`drop table if exists ${VEC_MEMORY_INDEX};`);\n}\n\nexport function upsertMemoryVecRow(\n db: RecallDb,\n memory: Pick<MemoryRow, \"id\" | \"repo\" | \"status\" | \"type\" | \"scope\">,\n embeddingRow: Pick<MemoryEmbeddingRow, \"embedding\" | \"index_dimensions\">,\n) {\n ensureMemoryVecIndex(db, embeddingRow.index_dimensions);\n const sqlite = getSqlite(db);\n sqlite.prepare(`delete from ${VEC_MEMORY_INDEX} where memory_id = ?`).run(memory.id);\n sqlite.prepare(`\n insert into ${VEC_MEMORY_INDEX} (\n embedding,\n memory_id,\n repo,\n status,\n type,\n scope\n ) values (?, ?, ?, ?, ?, ?)\n `).run(\n projectIndexBuffer(embeddingRow.embedding, embeddingRow.index_dimensions),\n memory.id,\n memory.repo ?? \"\",\n memory.status,\n memory.type,\n memory.scope,\n );\n}\n\nexport function removeMemoryVecRow(\n db: RecallDb,\n memoryId: string,\n config?: EmbeddingConfig,\n) {\n ensureSqliteVecLoaded(db);\n if (!hasMemoryVecIndex(db)) return;\n getSqlite(db).prepare(`delete from ${VEC_MEMORY_INDEX} where memory_id = ?`).run(memoryId);\n}\n\nexport function rebuildMemoryVecIndex(\n db: RecallDb,\n config: EmbeddingConfig,\n options: { repo?: string } = {},\n): number {\n const rows = db.select({\n id: memories.id,\n repo: memories.repo,\n status: memories.status,\n type: memories.type,\n scope: memories.scope,\n index_dimensions: memoryEmbeddings.index_dimensions,\n embedding: memoryEmbeddings.embedding,\n })\n .from(memories)\n .innerJoin(memoryEmbeddings, eq(memoryEmbeddings.memory_id, memories.id))\n .all()\n .filter((row) => !options.repo || row.repo === options.repo);\n\n const storedDimension = getMemoryVecDimension(rows);\n const targetDimension = storedDimension ?? config.dimensions;\n\n if (options.repo) {\n if (rows.length > 0) {\n ensureMemoryVecIndex(db, targetDimension);\n }\n if (!hasMemoryVecIndex(db)) return 0;\n getSqlite(db)\n .prepare(`delete from ${VEC_MEMORY_INDEX} where repo = ?`)\n .run(options.repo);\n if (rows.length === 0) return 0;\n } else {\n dropMemoryVecIndex(db);\n ensureMemoryVecIndex(db, targetDimension);\n }\n\n const sqlite = getSqlite(db);\n const stmt = sqlite.prepare(`\n insert into ${VEC_MEMORY_INDEX} (\n embedding,\n memory_id,\n repo,\n status,\n type,\n scope\n ) values (?, ?, ?, ?, ?, ?)\n `);\n\n const insertMany = sqlite.transaction((batch: typeof rows) => {\n for (const row of batch) {\n stmt.run(\n projectIndexBuffer(row.embedding, row.index_dimensions),\n row.id,\n row.repo ?? \"\",\n row.status,\n row.type,\n row.scope,\n );\n }\n });\n\n insertMany(rows);\n return rows.length;\n}\n\nfunction projectIndexBuffer(buffer: Buffer, indexDimensions: number): Buffer {\n const embedding = new Float32Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength / Float32Array.BYTES_PER_ELEMENT,\n );\n if (embedding.length === indexDimensions) {\n return buffer;\n }\n if (embedding.length < indexDimensions) {\n throw new Error(`Canonical embedding width ${embedding.length} is smaller than index width ${indexDimensions}.`);\n }\n const sliced = embedding.slice(0, indexDimensions);\n let norm = 0;\n for (const value of sliced) norm += value * value;\n const scale = Math.sqrt(norm) || 1;\n for (let i = 0; i < sliced.length; i++) {\n sliced[i] /= scale;\n }\n return Buffer.from(sliced.buffer, sliced.byteOffset, sliced.byteLength);\n}\n\nexport function verifyMemoryVecIndex(\n db: RecallDb,\n options: { repo?: string } = {},\n) {\n ensureSqliteVecLoaded(db);\n const sqlite = getSqlite(db);\n const exists = sqlite\n .prepare(\"select 1 from sqlite_master where type = 'table' and name = ?\")\n .get(VEC_MEMORY_INDEX);\n\n const expectedRows = db.select({\n memory_id: memoryEmbeddings.memory_id,\n repo: memories.repo,\n })\n .from(memoryEmbeddings)\n .innerJoin(memories, eq(memories.id, memoryEmbeddings.memory_id))\n .all()\n .filter((row) => !options.repo || row.repo === options.repo);\n\n let indexed = 0;\n if (exists) {\n if (options.repo) {\n const result = sqlite\n .prepare(`select count(*) as count from ${VEC_MEMORY_INDEX} where repo = ?`)\n .get(options.repo) as { count: number };\n indexed = result.count;\n } else {\n const result = sqlite\n .prepare(`select count(*) as count from ${VEC_MEMORY_INDEX}`)\n .get() as { count: number };\n indexed = result.count;\n }\n }\n\n return {\n expected: expectedRows.length,\n indexed,\n drift: expectedRows.length - indexed,\n };\n}\n\nexport function searchMemoryVecIndex(\n db: RecallDb,\n queryEmbedding: Float32Array,\n options: { repo?: string; limit?: number } = {},\n): Array<{ memory_id: string; distance: number }> {\n ensureSqliteVecLoaded(db);\n\n const sqlite = getSqlite(db);\n const exists = sqlite\n .prepare(\"select 1 from sqlite_master where type = 'table' and name = ?\")\n .get(VEC_MEMORY_INDEX);\n if (!exists) return [];\n\n const limit = options.limit ?? 10;\n if (options.repo) {\n return sqlite.prepare(`\n select memory_id, distance\n from ${VEC_MEMORY_INDEX}\n where embedding match ?\n and k = ?\n and repo = ?\n order by distance\n `).all(queryEmbedding, limit, options.repo) as Array<{ memory_id: string; distance: number }>;\n }\n\n return sqlite.prepare(`\n select memory_id, distance\n from ${VEC_MEMORY_INDEX}\n where embedding match ?\n and k = ?\n order by distance\n `).all(queryEmbedding, limit) as Array<{ memory_id: string; distance: number }>;\n}\n","import type { RecallDb } from \"../db/client.js\";\nimport { eq } from \"drizzle-orm\";\nimport { memories } from \"../db/schema.js\";\n\nconst FTS_MEMORY_INDEX = \"fts_memory_index\";\n\ntype MemoryRow = typeof memories.$inferSelect;\n\nfunction getSqlite(db: RecallDb) {\n return db.$client;\n}\n\nfunction shouldIndexLexically(\n memory: Pick<MemoryRow, \"status\" | \"confidence\">,\n) {\n return memory.status !== \"rejected\" && memory.status !== \"transient\";\n}\n\nfunction buildFtsQuery(query: string) {\n const tokens = query\n .match(/[A-Za-z0-9_.:/-]+/g)\n ?.map((token) => token.replace(/\"/g, '\"\"'))\n .filter(Boolean) ?? [];\n\n if (tokens.length === 0) return null;\n return tokens.map((token) => `\"${token}\"`).join(\" \");\n}\n\nexport function ensureMemoryFtsIndex(db: RecallDb) {\n const sqlite = getSqlite(db);\n sqlite.exec(`\n create virtual table if not exists ${FTS_MEMORY_INDEX} using fts5(\n memory_id UNINDEXED,\n text,\n repo UNINDEXED,\n status UNINDEXED,\n type UNINDEXED,\n scope UNINDEXED,\n path_scope UNINDEXED\n );\n `);\n}\n\nexport function dropMemoryFtsIndex(db: RecallDb) {\n getSqlite(db).exec(`drop table if exists ${FTS_MEMORY_INDEX};`);\n}\n\nexport function removeMemoryFtsRow(\n db: RecallDb,\n memoryId: string,\n) {\n const sqlite = getSqlite(db);\n const exists = sqlite\n .prepare(\"select 1 from sqlite_master where type = 'table' and name = ?\")\n .get(FTS_MEMORY_INDEX);\n if (!exists) return;\n sqlite.prepare(`delete from ${FTS_MEMORY_INDEX} where memory_id = ?`).run(memoryId);\n}\n\nexport function upsertMemoryFtsRow(\n db: RecallDb,\n memory: Pick<MemoryRow, \"id\" | \"text\" | \"repo\" | \"status\" | \"type\" | \"scope\" | \"path_scope\" | \"confidence\">,\n) {\n ensureMemoryFtsIndex(db);\n\n if (!shouldIndexLexically(memory)) {\n removeMemoryFtsRow(db, memory.id);\n return;\n }\n\n const sqlite = getSqlite(db);\n sqlite.prepare(`delete from ${FTS_MEMORY_INDEX} where memory_id = ?`).run(memory.id);\n sqlite.prepare(`\n insert into ${FTS_MEMORY_INDEX} (\n memory_id,\n text,\n repo,\n status,\n type,\n scope,\n path_scope\n ) values (?, ?, ?, ?, ?, ?, ?)\n `).run(\n memory.id,\n memory.text,\n memory.repo ?? \"\",\n memory.status,\n memory.type,\n memory.scope,\n memory.path_scope ?? \"\",\n );\n}\n\nexport function syncMemoryFtsIndex(\n db: RecallDb,\n memoryId: string,\n) {\n const memory = db\n .select()\n .from(memories)\n .where(eq(memories.id, memoryId))\n .get();\n\n if (!memory) {\n removeMemoryFtsRow(db, memoryId);\n return \"removed\";\n }\n\n upsertMemoryFtsRow(db, memory);\n return shouldIndexLexically(memory) ? \"stored\" : \"removed\";\n}\n\nexport function rebuildMemoryFtsIndex(\n db: RecallDb,\n options: { repo?: string } = {},\n): number {\n if (options.repo) {\n ensureMemoryFtsIndex(db);\n getSqlite(db)\n .prepare(`delete from ${FTS_MEMORY_INDEX} where repo = ?`)\n .run(options.repo);\n } else {\n dropMemoryFtsIndex(db);\n ensureMemoryFtsIndex(db);\n }\n\n const rows = db.select().from(memories).all()\n .filter((row) => !options.repo || row.repo === options.repo)\n .filter((row) => shouldIndexLexically(row));\n\n const sqlite = getSqlite(db);\n const stmt = sqlite.prepare(`\n insert into ${FTS_MEMORY_INDEX} (\n memory_id,\n text,\n repo,\n status,\n type,\n scope,\n path_scope\n ) values (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertMany = sqlite.transaction((batch: typeof rows) => {\n for (const row of batch) {\n stmt.run(\n row.id,\n row.text,\n row.repo ?? \"\",\n row.status,\n row.type,\n row.scope,\n row.path_scope ?? \"\",\n );\n }\n });\n\n insertMany(rows);\n return rows.length;\n}\n\nexport function verifyMemoryFtsIndex(\n db: RecallDb,\n options: { repo?: string } = {},\n) {\n const sqlite = getSqlite(db);\n const exists = sqlite\n .prepare(\"select 1 from sqlite_master where type = 'table' and name = ?\")\n .get(FTS_MEMORY_INDEX);\n\n const expected = db.select().from(memories).all()\n .filter((row) => !options.repo || row.repo === options.repo)\n .filter((row) => shouldIndexLexically(row)).length;\n\n let indexed = 0;\n if (exists) {\n if (options.repo) {\n const result = sqlite\n .prepare(`select count(*) as count from ${FTS_MEMORY_INDEX} where repo = ?`)\n .get(options.repo) as { count: number };\n indexed = result.count;\n } else {\n const result = sqlite\n .prepare(`select count(*) as count from ${FTS_MEMORY_INDEX}`)\n .get() as { count: number };\n indexed = result.count;\n }\n }\n\n return {\n expected,\n indexed,\n drift: expected - indexed,\n };\n}\n\nexport function searchMemoryFtsIndex(\n db: RecallDb,\n query: string,\n options: { repo?: string; limit?: number } = {},\n): Array<{ memory_id: string; lexical_rank: number }> {\n ensureMemoryFtsIndex(db);\n\n const sqlite = getSqlite(db);\n const limit = options.limit ?? 10;\n const ftsQuery = buildFtsQuery(query);\n if (!ftsQuery) return [];\n\n if (options.repo) {\n return sqlite.prepare(`\n select memory_id, bm25(${FTS_MEMORY_INDEX}) as lexical_rank\n from ${FTS_MEMORY_INDEX}\n where ${FTS_MEMORY_INDEX} match ?\n and repo = ?\n order by lexical_rank\n limit ?\n `).all(ftsQuery, options.repo, limit) as Array<{ memory_id: string; lexical_rank: number }>;\n }\n\n return sqlite.prepare(`\n select memory_id, bm25(${FTS_MEMORY_INDEX}) as lexical_rank\n from ${FTS_MEMORY_INDEX}\n where ${FTS_MEMORY_INDEX} match ?\n order by lexical_rank\n limit ?\n `).all(ftsQuery, limit) as Array<{ memory_id: string; lexical_rank: number }>;\n}\n","import { eq } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { historySnippets, memories } from \"../db/schema.js\";\nimport { createMemory, getMemory, queryMemories } from \"../models/memory.js\";\nimport { recordAuditWithSnapshot } from \"../audit/trail.js\";\nimport { queueMemoryEmbeddingSync } from \"../embeddings/embeddings.js\";\nimport type { CaptureContext, MaintenanceTask, MemoryType } from \"../types.js\";\nimport { isHighRiskRule } from \"../capture/correction.js\";\nimport { getRepoQualityProfile, seedCandidateConfidence } from \"../repo/quality.js\";\nimport type {\n ExtractedRule,\n ExtractRulesFromPromptResult,\n MergeDuplicatesResult,\n RefineCandidateResult,\n SummarizeHistoryResult,\n SummarizeSessionResult,\n SynthesizeRepoResult,\n VerifyCaptureResult,\n} from \"./tasks.js\";\n\nexport class ApplyError extends Error {\n constructor(message: string, public readonly code: \"target-missing\" | \"invalid-state\" | \"unsupported-kind\") {\n super(message);\n this.name = \"ApplyError\";\n }\n}\n\nexport interface ApplyOutcome {\n audit_entry_id: string | null;\n target_id: string;\n changed_fields: string[];\n}\n\nexport function applyRefineCandidate(\n db: RecallDb,\n task: MaintenanceTask,\n result: RefineCandidateResult,\n): ApplyOutcome {\n const memoryId = (task.payload as { memory_id?: string }).memory_id;\n if (!memoryId) throw new ApplyError(\"payload missing memory_id\", \"invalid-state\");\n\n const before = getMemory(db, memoryId);\n if (!before) throw new ApplyError(`memory ${memoryId} not found`, \"target-missing\");\n\n const actor = `maintenance:${task.claimed_by ?? \"unknown\"}`;\n\n if (result.verdict === \"reject\") {\n return rejectMemoryFromTask(db, task, memoryId, before, actor, result.rationale);\n }\n\n const changed: string[] = [];\n if (before.text !== result.refined_text) changed.push(\"text\");\n if (before.scope !== result.scope) changed.push(\"scope\");\n const newPathScope = result.path_scope ?? null;\n if (before.path_scope !== newPathScope) changed.push(\"path_scope\");\n\n if (changed.length === 0) {\n return { audit_entry_id: null, target_id: memoryId, changed_fields: [] };\n }\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({\n text: result.refined_text,\n scope: result.scope,\n path_scope: newPathScope,\n updated_at: now,\n last_validated_at: now,\n })\n .where(eq(memories.id, memoryId))\n .run();\n\n queueMemoryEmbeddingSync(db, memoryId);\n\n const after = getMemory(db, memoryId);\n const reason = result.rationale\n ? `refined:${task.id}:${result.rationale.slice(0, 200)}`\n : `refined:${task.id}`;\n const auditId = recordAuditWithSnapshot(\n db,\n memoryId,\n \"edited\",\n actor,\n reason,\n before,\n after ?? null,\n );\n\n return { audit_entry_id: auditId, target_id: memoryId, changed_fields: changed };\n}\n\n// Phase E1 — verify_capture applier. Three verdicts:\n// * save — leave the candidate as-is (LLM agrees with heuristic capture)\n// * rewrite — clean text/scope/path_scope, candidate stays candidate\n// * reject — flip to rejected with audit reason from the LLM\n// All paths are idempotent. The candidate's promotion path (B+F) is unaffected\n// — verify_capture refines or kills, it never promotes. Promotion still\n// requires repetition or explicit confirm.\nexport function applyVerifyCapture(\n db: RecallDb,\n task: MaintenanceTask,\n result: VerifyCaptureResult,\n): ApplyOutcome {\n const memoryId = (task.payload as { memory_id?: string }).memory_id;\n if (!memoryId) throw new ApplyError(\"payload missing memory_id\", \"invalid-state\");\n\n const before = getMemory(db, memoryId);\n if (!before) throw new ApplyError(`memory ${memoryId} not found`, \"target-missing\");\n\n const actor = `maintenance:${task.claimed_by ?? \"unknown\"}`;\n\n if (result.verdict === \"reject\") {\n return rejectMemoryFromTask(db, task, memoryId, before, actor, result.reason);\n }\n\n if (result.verdict === \"save\") {\n return { audit_entry_id: null, target_id: memoryId, changed_fields: [] };\n }\n\n // verdict === \"rewrite\"\n const newText = result.cleaned_text ?? before.text;\n const newScope = result.scope ?? before.scope;\n const newPathScope = result.path_scope ?? before.path_scope;\n\n const changed: string[] = [];\n if (before.text !== newText) changed.push(\"text\");\n if (before.scope !== newScope) changed.push(\"scope\");\n if (before.path_scope !== newPathScope) changed.push(\"path_scope\");\n\n if (changed.length === 0) {\n return { audit_entry_id: null, target_id: memoryId, changed_fields: [] };\n }\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({\n text: newText,\n scope: newScope,\n path_scope: newPathScope,\n updated_at: now,\n last_validated_at: now,\n })\n .where(eq(memories.id, memoryId))\n .run();\n\n queueMemoryEmbeddingSync(db, memoryId);\n\n const after = getMemory(db, memoryId);\n const reason = result.reason\n ? `verify:rewrite:${task.id}:${result.reason.slice(0, 200)}`\n : `verify:rewrite:${task.id}`;\n const auditId = recordAuditWithSnapshot(\n db,\n memoryId,\n \"edited\",\n actor,\n reason,\n before,\n after ?? null,\n );\n\n return { audit_entry_id: auditId, target_id: memoryId, changed_fields: changed };\n}\n\nfunction rejectMemoryFromTask(\n db: RecallDb,\n task: MaintenanceTask,\n memoryId: string,\n before: NonNullable<ReturnType<typeof getMemory>>,\n actor: string,\n reasonText: string | undefined,\n): ApplyOutcome {\n if (before.status === \"rejected\") {\n return { audit_entry_id: null, target_id: memoryId, changed_fields: [] };\n }\n const now = new Date().toISOString();\n db.update(memories)\n .set({ status: \"rejected\", confidence: 0, dedupe_key: null, updated_at: now })\n .where(eq(memories.id, memoryId))\n .run();\n queueMemoryEmbeddingSync(db, memoryId);\n const after = getMemory(db, memoryId);\n const reason = reasonText\n ? `${task.kind}:reject:${task.id}:${reasonText.slice(0, 200)}`\n : `${task.kind}:reject:${task.id}`;\n const auditId = recordAuditWithSnapshot(\n db,\n memoryId,\n \"rejected\",\n actor,\n reason,\n before,\n after ?? null,\n );\n return { audit_entry_id: auditId, target_id: memoryId, changed_fields: [\"status\"] };\n}\n\nexport function applySummarizeHistory(\n db: RecallDb,\n task: MaintenanceTask,\n result: SummarizeHistoryResult,\n): ApplyOutcome {\n const snippetId = (task.payload as { snippet_id?: string }).snippet_id;\n if (!snippetId) throw new ApplyError(\"payload missing snippet_id\", \"invalid-state\");\n\n const existing = db.select().from(historySnippets)\n .where(eq(historySnippets.id, snippetId))\n .get();\n if (!existing) throw new ApplyError(`history snippet ${snippetId} not found`, \"target-missing\");\n\n const changed: string[] = [];\n if (existing.text !== result.summary_text) changed.push(\"text\");\n if (changed.length === 0) {\n return { audit_entry_id: null, target_id: snippetId, changed_fields: [] };\n }\n\n db.update(historySnippets)\n .set({\n text: result.summary_text,\n updated_at: new Date().toISOString(),\n })\n .where(eq(historySnippets.id, snippetId))\n .run();\n\n // History snippets aren't memories, so no audit_trail row — the activity\n // log + the task's stored `result` column is the audit surface here.\n return { audit_entry_id: null, target_id: snippetId, changed_fields: changed };\n}\n\ninterface MergeCandidate {\n id: string;\n text: string;\n scope: string;\n path_scope: string | null;\n}\n\nexport function applyMergeDuplicates(\n db: RecallDb,\n task: MaintenanceTask,\n result: MergeDuplicatesResult,\n): ApplyOutcome {\n const payload = task.payload as { candidates?: MergeCandidate[] };\n const candidates = payload.candidates ?? [];\n if (candidates.length < 2) {\n throw new ApplyError(\"merge_duplicates payload needs ≥2 candidates\", \"invalid-state\");\n }\n\n const winnerId = result.winner_id;\n if (!candidates.some((c) => c.id === winnerId)) {\n throw new ApplyError(`winner_id ${winnerId} not in candidates`, \"invalid-state\");\n }\n\n const winner = getMemory(db, winnerId);\n if (!winner) throw new ApplyError(`winner ${winnerId} not found`, \"target-missing\");\n\n const now = new Date().toISOString();\n const changed: string[] = [];\n const actor = `maintenance:${task.claimed_by ?? \"unknown\"}`;\n\n // Update winner if requested.\n const nextText = result.winner_text ?? winner.text;\n const nextScope = result.winner_scope ?? winner.scope;\n const nextPathScope = result.winner_path_scope !== undefined\n ? (result.winner_path_scope ?? null)\n : winner.path_scope;\n\n const winnerChanged = nextText !== winner.text\n || nextScope !== winner.scope\n || nextPathScope !== winner.path_scope;\n\n if (winnerChanged) {\n db.update(memories)\n .set({\n text: nextText,\n scope: nextScope as any,\n path_scope: nextPathScope,\n updated_at: now,\n last_validated_at: now,\n })\n .where(eq(memories.id, winnerId))\n .run();\n queueMemoryEmbeddingSync(db, winnerId);\n\n const after = getMemory(db, winnerId);\n recordAuditWithSnapshot(\n db,\n winnerId,\n \"edited\",\n actor,\n `merged_winner:${task.id}`,\n winner,\n after ?? null,\n );\n changed.push(`winner:${winnerId}`);\n }\n\n // Reject losers with supersedes=winner.\n for (const cand of candidates) {\n if (cand.id === winnerId) continue;\n const loser = getMemory(db, cand.id);\n if (!loser) continue;\n if (loser.status === \"rejected\") continue;\n\n db.update(memories)\n .set({\n status: \"rejected\",\n supersedes: winnerId,\n dedupe_key: null,\n updated_at: now,\n })\n .where(eq(memories.id, cand.id))\n .run();\n queueMemoryEmbeddingSync(db, cand.id);\n\n const afterLoser = getMemory(db, cand.id);\n recordAuditWithSnapshot(\n db,\n cand.id,\n \"rejected\",\n actor,\n `merged_into:${winnerId}:${task.id}`,\n loser,\n afterLoser ?? null,\n );\n changed.push(`loser:${cand.id}`);\n }\n\n return {\n audit_entry_id: null,\n target_id: winnerId,\n changed_fields: changed,\n };\n}\n\nexport function applySummarizeSession(\n db: RecallDb,\n task: MaintenanceTask,\n result: SummarizeSessionResult,\n): ApplyOutcome {\n const payload = task.payload as {\n session_id?: string;\n repo?: string | null;\n source_activity_ids?: string[];\n };\n const sessionId = payload.session_id;\n if (!sessionId) throw new ApplyError(\"payload missing session_id\", \"invalid-state\");\n\n const id = randomUUID();\n const now = new Date().toISOString();\n db.insert(historySnippets).values({\n id,\n repo: payload.repo ?? null,\n session_id: sessionId,\n kind: \"session_summary\",\n text: result.summary_text,\n source_activity_ids: (payload.source_activity_ids ?? []) as any,\n created_at: now,\n updated_at: now,\n }).run();\n\n return { audit_entry_id: null, target_id: id, changed_fields: [\"text\"] };\n}\n\nexport function applySynthesizeRepo(\n db: RecallDb,\n task: MaintenanceTask,\n result: SynthesizeRepoResult,\n): ApplyOutcome {\n const payload = task.payload as { repo?: string };\n const repo = payload.repo;\n if (!repo) throw new ApplyError(\"payload missing repo\", \"invalid-state\");\n\n const id = randomUUID();\n const now = new Date().toISOString();\n db.insert(historySnippets).values({\n id,\n repo,\n session_id: null,\n kind: \"repo_synthesis\",\n text: result.summary_text,\n source_activity_ids: [] as any,\n created_at: now,\n updated_at: now,\n }).run();\n\n return { audit_entry_id: null, target_id: id, changed_fields: [\"text\"] };\n}\n\n// LLM-primary capture applier. The LLM extracted zero or more rules from the\n// raw user prompt; for each one we create a candidate memory (subject to\n// dedup against existing same-repo memories). The applier never auto-promotes\n// — promotion still flows through repetition or explicit user confirm, same\n// as the regex path. Destructive-risky rules and trigger-template rules are\n// always created as candidates, never active, regardless of confidence.\nexport function applyExtractRulesFromPrompt(\n db: RecallDb,\n task: MaintenanceTask,\n result: ExtractRulesFromPromptResult,\n): ApplyOutcome {\n const payload = task.payload as {\n repo?: string | null;\n path?: string | null;\n agent?: string | null;\n session_id?: string;\n raw_prompt?: string;\n };\n const repo = payload.repo ?? null;\n const profile = getRepoQualityProfile(db, repo ?? undefined);\n\n if (!result.rules || result.rules.length === 0) {\n return { audit_entry_id: null, target_id: task.id, changed_fields: [] };\n }\n\n const captureContext: CaptureContext = {\n prev_assistant_text: undefined,\n recent_tool_calls: [],\n repo,\n path: payload.path ?? null,\n agent: payload.agent ?? undefined,\n };\n\n const createdIds: string[] = [];\n for (const rule of result.rules) {\n if (existsSimilar(db, repo, rule)) continue;\n\n const memoryType = (rule.type as MemoryType) ?? \"rule\";\n const id = createMemory(db, {\n type: memoryType,\n text: rule.text,\n scope: rule.scope,\n path_scope: rule.path_scope ?? null,\n repo,\n source: \"user_correction\",\n confidence: seedCandidateConfidence(rule.confidence, profile),\n evidence: [\n {\n type: \"session_correction\",\n session: payload.session_id ?? \"unknown\",\n timestamp: new Date().toISOString(),\n context: payload.raw_prompt ?? \"\",\n },\n ],\n capture_context: captureContext,\n });\n createdIds.push(id);\n\n const after = getMemory(db, id);\n recordAuditWithSnapshot(\n db,\n id,\n \"created\",\n `maintenance:${task.claimed_by ?? \"llm\"}`,\n `extract_rules_from_prompt:${task.id}${rule.rationale ? `:${rule.rationale.slice(0, 200)}` : \"\"}`,\n null,\n after ?? null,\n );\n\n // High-risk rules never auto-promote, even if LLM gives high confidence.\n // The existing maybePromoteGroupCandidate path (in correction.ts) skips\n // them; for parity we just rely on it remaining a candidate here.\n if (rule.is_destructive_risky || isHighRiskRule(rule.text)) {\n // No-op; candidate stays candidate until explicit confirm.\n }\n }\n\n return {\n audit_entry_id: null,\n target_id: createdIds[0] ?? task.id,\n changed_fields: createdIds.length > 0 ? [\"created_memories\"] : [],\n };\n}\n\nfunction existsSimilar(\n db: RecallDb,\n repo: string | null,\n rule: ExtractedRule,\n): boolean {\n if (!repo) return false;\n const candidates = queryMemories(db, { repo: repo ?? undefined, type: rule.type as MemoryType })\n .filter((memory) => memory.status !== \"rejected\");\n const normalized = rule.text.toLowerCase().trim();\n return candidates.some((memory) => {\n if (memory.text.toLowerCase().trim() === normalized) return true;\n return jaccard(memory.text, rule.text) >= 0.85;\n });\n}\n\nfunction jaccard(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/));\n const intersection = [...wordsA].filter((w) => wordsB.has(w));\n const union = new Set([...wordsA, ...wordsB]);\n return union.size === 0 ? 0 : intersection.length / union.size;\n}\n\nexport function applyTaskResult(\n db: RecallDb,\n task: MaintenanceTask,\n result: unknown,\n): ApplyOutcome {\n switch (task.kind) {\n case \"verify_capture\":\n return applyVerifyCapture(db, task, result as VerifyCaptureResult);\n case \"refine_candidate\":\n return applyRefineCandidate(db, task, result as RefineCandidateResult);\n case \"summarize_history\":\n return applySummarizeHistory(db, task, result as SummarizeHistoryResult);\n case \"merge_duplicates\":\n return applyMergeDuplicates(db, task, result as MergeDuplicatesResult);\n case \"summarize_session\":\n return applySummarizeSession(db, task, result as SummarizeSessionResult);\n case \"synthesize_repo\":\n return applySynthesizeRepo(db, task, result as SynthesizeRepoResult);\n case \"extract_rules_from_prompt\":\n return applyExtractRulesFromPrompt(db, task, result as ExtractRulesFromPromptResult);\n default: {\n const never: never = task.kind;\n throw new ApplyError(`unknown kind ${never}`, \"unsupported-kind\");\n }\n }\n}\n","import { eq, and, gte, inArray, like, sql } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { memories, feedbackEvents } from \"../db/schema.js\";\nimport { memoryDedupeKey } from \"./dedupe.js\";\nimport { queueMemoryEmbeddingSync } from \"../embeddings/embeddings.js\";\nimport {\n CONFIDENCE,\n PROMOTION,\n type MemoryItem,\n type MemoryQuery,\n type MemoryStatus,\n type MemoryType,\n type MemoryScope,\n type MemorySource,\n type EvidenceEntry,\n type CaptureContext,\n type FeedbackOutcome,\n} from \"../types.js\";\n\ntype MemoryRow = typeof memories.$inferSelect;\n\n// --- Create ---\n\nexport interface CreateMemoryInput {\n type: MemoryType;\n text: string;\n scope: MemoryScope;\n path_scope?: string | null;\n repo?: string | null;\n source: MemorySource;\n confidence?: number;\n evidence?: EvidenceEntry[];\n capture_context?: CaptureContext | null;\n supersedes?: string | null;\n dedupe?: boolean;\n}\n\nexport function statusFromConfidence(confidence: number): MemoryStatus {\n if (confidence < CONFIDENCE.TRANSIENT_MAX) return \"transient\";\n if (confidence < CONFIDENCE.CANDIDATE_MAX) return \"candidate\";\n return \"active\";\n}\n\nexport function createMemory(db: RecallDb, input: CreateMemoryInput): string {\n const now = new Date().toISOString();\n const id = randomUUID();\n const confidence = input.confidence ?? 0.35; // default: low candidate\n const status = statusFromConfidence(confidence);\n const dedupeKey = input.dedupe === false\n ? null\n : memoryDedupeKey({\n type: input.type,\n scope: input.scope,\n repo: input.repo ?? null,\n path_scope: input.path_scope ?? null,\n text: input.text,\n });\n\n if (dedupeKey) {\n const existing = db.select().from(memories)\n .where(and(eq(memories.dedupe_key, dedupeKey), sql`${memories.status} != 'rejected'`))\n .get();\n if (existing) return existing.id;\n }\n\n db.insert(memories)\n .values({\n id,\n type: input.type,\n text: input.text,\n scope: input.scope,\n path_scope: input.path_scope ?? null,\n repo: input.repo ?? null,\n status,\n confidence,\n source: input.source,\n evidence: (input.evidence ?? []) as any,\n capture_context: input.capture_context ? input.capture_context as any : null,\n supersedes: input.supersedes ?? null,\n dedupe_key: dedupeKey,\n created_at: now,\n updated_at: now,\n last_validated_at: null,\n last_injected_at: null,\n injection_count: 0,\n override_count: 0,\n repetition_count: 0,\n })\n .run();\n\n queueMemoryEmbeddingSync(db, id);\n return id;\n}\n\n// --- Read ---\n\nexport function getMemory(\n db: RecallDb,\n id: string,\n): MemoryItem | undefined {\n const row = db.select().from(memories).where(eq(memories.id, id)).get();\n if (!row) return undefined;\n return rowToMemory(row);\n}\n\nexport function queryMemories(\n db: RecallDb,\n query: MemoryQuery,\n): MemoryItem[] {\n const conditions = [];\n\n if (query.repo) conditions.push(eq(memories.repo, query.repo));\n if (query.status) conditions.push(eq(memories.status, query.status));\n if (query.type) conditions.push(eq(memories.type, query.type));\n if (query.scope) conditions.push(eq(memories.scope, query.scope));\n if (query.min_confidence != null)\n conditions.push(gte(memories.confidence, query.min_confidence));\n if (query.path) conditions.push(like(memories.path_scope, `%${query.path}%`));\n if (query.auto_inject != null) conditions.push(eq(memories.auto_inject, query.auto_inject));\n\n let statement = db.select().from(memories).$dynamic();\n if (conditions.length > 0) {\n statement = statement.where(and(...conditions));\n }\n if (query.offset != null) {\n statement = statement.offset(query.offset);\n }\n if (query.limit != null) {\n statement = statement.limit(query.limit);\n }\n\n const rows = statement.all();\n\n return rows.map(rowToMemory);\n}\n\nexport function listMemories(\n db: RecallDb,\n repo?: string,\n options: Pick<MemoryQuery, \"limit\" | \"offset\"> = {},\n): MemoryItem[] {\n return queryMemories(db, {\n repo,\n limit: options.limit,\n offset: options.offset,\n });\n}\n\nexport function listRepos(db: RecallDb): string[] {\n return [...new Set(\n db.select({ repo: memories.repo }).from(memories).all()\n .map((row) => row.repo)\n .filter((repo): repo is string => Boolean(repo)),\n )].sort();\n}\n\n// --- State transitions ---\n\nexport function promoteMemory(\n db: RecallDb,\n id: string,\n reason: \"explicit_confirm\" | \"repeat_correction\" | \"review_feedback\" | \"passive_gain\",\n evidence?: EvidenceEntry,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n if (mem.status === \"rejected\") return false; // must use reactivate\n\n let newConfidence: number;\n if (reason === \"explicit_confirm\") {\n newConfidence = Math.max(mem.confidence, PROMOTION.EXPLICIT_CONFIRM);\n } else if (reason === \"repeat_correction\") {\n newConfidence = Math.min(1, mem.confidence + PROMOTION.REPEAT_CORRECTION);\n } else if (reason === \"review_feedback\") {\n newConfidence = Math.min(1, mem.confidence + PROMOTION.REVIEW_FEEDBACK);\n } else {\n newConfidence = Math.min(1, mem.confidence + PROMOTION.PASSIVE_GAIN);\n }\n\n const newStatus = statusFromConfidence(newConfidence);\n const now = new Date().toISOString();\n\n const newEvidence = evidence\n ? [...mem.evidence, evidence]\n : mem.evidence;\n\n db.update(memories)\n .set({\n confidence: newConfidence,\n status: newStatus,\n evidence: newEvidence as any,\n updated_at: now,\n last_validated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n\n queueMemoryEmbeddingSync(db, id);\n return true;\n}\n\nexport function demoteMemory(\n db: RecallDb,\n id: string,\n reason: string,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n\n const newConfidence = Math.max(0, mem.confidence - 0.3);\n const newStatus = statusFromConfidence(newConfidence);\n const now = new Date().toISOString();\n\n db.update(memories)\n .set({\n confidence: newConfidence,\n status: newStatus === \"transient\" ? \"candidate\" : newStatus, // don't lose it completely\n updated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n\n queueMemoryEmbeddingSync(db, id);\n return true;\n}\n\nexport type DemoteGlobalResult =\n | { ok: true; outcome: \"rescoped\" | \"rejected\"; memory: MemoryItem }\n | { ok: false; reason: \"not_found\" | \"not_global\" };\n\nexport function demoteGlobalMemory(\n db: RecallDb,\n id: string,\n opts: { repo?: string | null } = {},\n): DemoteGlobalResult {\n const mem = getMemory(db, id);\n if (!mem) return { ok: false, reason: \"not_found\" };\n if (mem.scope !== \"global\") return { ok: false, reason: \"not_global\" };\n\n const targetRepo = opts.repo?.trim() || null;\n const now = new Date().toISOString();\n\n if (targetRepo) {\n const newDedupe = memoryDedupeKey({\n type: mem.type,\n scope: \"repo\",\n repo: targetRepo,\n path_scope: mem.path_scope,\n text: mem.text,\n });\n db.update(memories)\n .set({\n scope: \"repo\",\n repo: targetRepo,\n dedupe_key: newDedupe,\n updated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n } else {\n db.update(memories)\n .set({\n status: \"rejected\",\n confidence: 0,\n dedupe_key: null,\n updated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n }\n\n queueMemoryEmbeddingSync(db, id);\n const updated = getMemory(db, id)!;\n return { ok: true, outcome: targetRepo ? \"rescoped\" : \"rejected\", memory: updated };\n}\n\nexport function rejectMemory(db: RecallDb, id: string): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n\n db.update(memories)\n .set({\n status: \"rejected\",\n confidence: 0,\n dedupe_key: null,\n updated_at: new Date().toISOString(),\n })\n .where(eq(memories.id, id))\n .run();\n\n queueMemoryEmbeddingSync(db, id);\n return true;\n}\n\nexport function confirmMemory(db: RecallDb, id: string): boolean {\n return promoteMemory(db, id, \"explicit_confirm\", {\n type: \"session_correction\",\n session: \"cli\",\n timestamp: new Date().toISOString(),\n context: \"user explicitly confirmed\",\n });\n}\n\nexport function reactivateMemory(\n db: RecallDb,\n id: string,\n evidence: EvidenceEntry,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n if (mem.status !== \"rejected\") return false;\n\n const now = new Date().toISOString();\n const dedupeKey = memoryDedupeKey(mem);\n const existing = db.select().from(memories)\n .where(and(eq(memories.dedupe_key, dedupeKey), sql`${memories.status} != 'rejected'`))\n .get();\n if (existing && existing.id !== id) return false;\n\n db.update(memories)\n .set({\n status: \"candidate\",\n confidence: CONFIDENCE.TRANSIENT_MAX + 0.05,\n dedupe_key: dedupeKey,\n evidence: [...mem.evidence, evidence] as any,\n updated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n\n queueMemoryEmbeddingSync(db, id);\n return true;\n}\n\nexport function appendEvidence(\n db: RecallDb,\n id: string,\n evidence: EvidenceEntry,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n if (hasEquivalentEvidence(mem.evidence, evidence)) return true;\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({\n evidence: [...mem.evidence, evidence] as any,\n updated_at: now,\n last_validated_at: now,\n })\n .where(eq(memories.id, id))\n .run();\n\n return true;\n}\n\nexport function updateMemoryCaptureContext(\n db: RecallDb,\n id: string,\n captureContext: CaptureContext,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n\n db.update(memories)\n .set({\n capture_context: captureContext as any,\n updated_at: new Date().toISOString(),\n })\n .where(eq(memories.id, id))\n .run();\n\n return true;\n}\n\nexport function incrementMemoryRepetition(\n db: RecallDb,\n id: string,\n): boolean {\n const mem = getMemory(db, id);\n if (!mem) return false;\n\n db.update(memories)\n .set({\n repetition_count: sql`repetition_count + 1`,\n updated_at: new Date().toISOString(),\n })\n .where(eq(memories.id, id))\n .run();\n\n return true;\n}\n\nexport function countDistinctCorrectionSessions(mem: MemoryItem): number {\n const sessions = new Set<string>();\n\n for (const entry of mem.evidence) {\n if (entry.type === \"session_correction\") {\n sessions.add(entry.session);\n } else if (entry.type === \"repeated_correction\") {\n for (const session of entry.sessions) {\n sessions.add(session);\n }\n }\n }\n\n return sessions.size;\n}\n\n// --- Feedback ---\n\nexport function recordFeedback(\n db: RecallDb,\n memoryId: string,\n sessionId: string,\n injected: boolean,\n outcome: FeedbackOutcome,\n): string {\n const id = randomUUID();\n const now = new Date().toISOString();\n\n db.insert(feedbackEvents)\n .values({\n id,\n memory_id: memoryId,\n session_id: sessionId,\n injected,\n outcome,\n timestamp: now,\n })\n .run();\n\n const mem = getMemory(db, memoryId);\n if (!mem) return id;\n\n const delta = outcome === \"followed\"\n ? 0.05\n : outcome === \"overridden\"\n ? -0.15\n : outcome === \"ignored\"\n ? -0.02\n : -0.25;\n const nextConfidence = Math.max(0, Math.min(1, mem.confidence + delta));\n const nextStatus = statusFromConfidence(nextConfidence);\n\n // Update injection tracking\n if (injected) {\n db.update(memories)\n .set({\n confidence: nextConfidence,\n status: nextStatus === \"transient\" ? \"candidate\" : nextStatus,\n updated_at: now,\n last_injected_at: now,\n injection_count: sql`injection_count + 1`,\n ...(outcome === \"overridden\" || outcome === \"contradicted\"\n ? { override_count: sql`override_count + 1` }\n : {}),\n })\n .where(eq(memories.id, memoryId))\n .run();\n } else {\n db.update(memories)\n .set({\n confidence: nextConfidence,\n status: nextStatus === \"transient\" ? \"candidate\" : nextStatus,\n updated_at: now,\n })\n .where(eq(memories.id, memoryId))\n .run();\n }\n\n return id;\n}\n\nexport function getMemoryFeedback(\n db: RecallDb,\n memoryId: string,\n) {\n return db\n .select()\n .from(feedbackEvents)\n .where(eq(feedbackEvents.memory_id, memoryId))\n .all();\n}\n\nexport interface FeedbackSummary {\n followed: number;\n overridden: number;\n contradicted: number;\n ignored: number;\n resolved: number;\n}\n\n/**\n * Aggregate feedback outcomes for a batch of memories in a single query.\n * `resolved` excludes `ignored` because the post-Phase-2.3 detector only\n * writes meaningful outcomes.\n */\nexport function getMemoryFeedbackSummaries(\n db: RecallDb,\n memoryIds: readonly string[],\n): Map<string, FeedbackSummary> {\n const empty = (): FeedbackSummary => ({\n followed: 0,\n overridden: 0,\n contradicted: 0,\n ignored: 0,\n resolved: 0,\n });\n const result = new Map<string, FeedbackSummary>();\n if (memoryIds.length === 0) return result;\n for (const id of memoryIds) result.set(id, empty());\n\n const rows = db.select({\n memory_id: feedbackEvents.memory_id,\n outcome: feedbackEvents.outcome,\n count: sql<number>`count(*)`.as(\"count\"),\n })\n .from(feedbackEvents)\n .where(inArray(feedbackEvents.memory_id, [...memoryIds]))\n .groupBy(feedbackEvents.memory_id, feedbackEvents.outcome)\n .all();\n\n for (const row of rows) {\n const entry = result.get(row.memory_id) ?? empty();\n if (row.outcome === \"followed\") entry.followed += row.count;\n else if (row.outcome === \"overridden\") entry.overridden += row.count;\n else if (row.outcome === \"contradicted\") entry.contradicted += row.count;\n else if (row.outcome === \"ignored\") entry.ignored += row.count;\n if (row.outcome !== \"ignored\") entry.resolved += row.count;\n result.set(row.memory_id, entry);\n }\n return result;\n}\n\n/**\n * Smoothed feedback-driven score in [0, 1]. Cold-start memories return their\n * confidence directly; as resolved samples accumulate, the score blends in\n * the empirical followed rate (Bayesian beta(1,1) prior, weight ramps to 1\n * at FEEDBACK_MATURITY resolved samples).\n */\nexport const FEEDBACK_MATURITY = 5;\nexport function feedbackWeightedScore(\n confidence: number,\n summary: FeedbackSummary,\n): number {\n const total = summary.resolved;\n const maturity = Math.min(total, FEEDBACK_MATURITY) / FEEDBACK_MATURITY;\n if (maturity === 0) return confidence;\n // Penalize contradictions harder than overrides.\n const positive = summary.followed;\n const negative = summary.overridden + 2 * summary.contradicted;\n const numerator = Math.max(0, positive - negative + 1);\n const denominator = Math.max(1, total + 2);\n const empirical = Math.min(1, numerator / denominator);\n return (1 - maturity) * confidence + maturity * empirical;\n}\n\n// --- Helpers ---\n\nfunction rowToMemory(row: MemoryRow): MemoryItem {\n const evidence =\n typeof row.evidence === \"string\"\n ? JSON.parse(row.evidence as string)\n : Array.isArray(row.evidence)\n ? row.evidence\n : [];\n const captureContext =\n typeof row.capture_context === \"string\"\n ? JSON.parse(row.capture_context as string)\n : row.capture_context ?? null;\n return {\n id: row.id,\n type: row.type,\n text: row.text,\n scope: row.scope,\n path_scope: row.path_scope,\n repo: row.repo,\n status: row.status,\n confidence: row.confidence,\n source: row.source,\n evidence: evidence as EvidenceEntry[],\n capture_context: captureContext as MemoryItem[\"capture_context\"],\n supersedes: row.supersedes,\n created_at: row.created_at,\n updated_at: row.updated_at,\n last_validated_at: row.last_validated_at,\n last_injected_at: row.last_injected_at,\n injection_count: row.injection_count,\n override_count: row.override_count,\n repetition_count: row.repetition_count,\n auto_inject: row.auto_inject,\n };\n}\n\nfunction hasEquivalentEvidence(\n existing: EvidenceEntry[],\n next: EvidenceEntry,\n): boolean {\n return existing.some((entry) => {\n if (entry.type !== next.type) return false;\n\n if (entry.type === \"session_correction\" && next.type === \"session_correction\") {\n return entry.session === next.session;\n }\n\n if (entry.type === \"review_feedback\" && next.type === \"review_feedback\") {\n return entry.reviewer === next.reviewer && entry.context === next.context;\n }\n\n if (entry.type === \"repo_scan\" && next.type === \"repo_scan\") {\n return entry.file === next.file;\n }\n\n if (entry.type === \"repeated_correction\" && next.type === \"repeated_correction\") {\n return entry.sessions.join(\"|\") === next.sessions.join(\"|\");\n }\n\n return false;\n });\n}\n","export function normalizeDedupeText(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .replace(/[\\s.;:,!?`]+$/g, \"\")\n .trim();\n}\n\nexport function memoryDedupeKey(input: {\n type: string;\n scope: string;\n repo?: string | null;\n path_scope?: string | null;\n text: string;\n}): string {\n return [\n \"memory\",\n input.type,\n input.scope,\n input.repo ?? \"\",\n input.path_scope ?? \"\",\n normalizeDedupeText(input.text),\n ].join(\"\\u001f\");\n}\n\nexport function historySnippetDedupeKey(input: {\n repo?: string | null;\n session_id?: string | null;\n kind: string;\n text: string;\n}): string {\n return [\n \"history\",\n input.repo ?? \"\",\n input.session_id ?? \"\",\n input.kind,\n normalizeDedupeText(input.text),\n ].join(\"\\u001f\");\n}\n\nexport function activityEventDedupeKey(input: {\n session_id?: string | null;\n repo?: string | null;\n path?: string | null;\n source: string;\n event_type: string;\n request?: Record<string, unknown>;\n result?: Record<string, unknown>;\n}): string | null {\n if (!input.session_id) return null;\n return [\n \"activity\",\n input.session_id,\n input.repo ?? \"\",\n input.path ?? \"\",\n input.source,\n input.event_type,\n stableDedupeJson(stripVolatileFields(input.request ?? {})),\n stableDedupeJson(stripVolatileFields(input.result ?? {})),\n ].join(\"\\u001f\");\n}\n\nexport function hookCallDedupeKey(input: {\n session_id?: string | null;\n agent: string;\n event: string;\n ok: boolean;\n payload?: Record<string, unknown>;\n}): string | null {\n if (!input.session_id) return null;\n return [\n \"hook\",\n input.session_id,\n input.agent,\n input.event,\n input.ok ? \"ok\" : \"error\",\n stableDedupeJson(stripVolatileFields(input.payload ?? {})),\n ].join(\"\\u001f\");\n}\n\nexport function stripVolatileFields(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stripVolatileFields);\n }\n if (!value || typeof value !== \"object\") {\n return value;\n }\n\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n if (/_at$/u.test(key) || key === \"timestamp\") continue;\n if (entry === undefined) continue;\n out[key] = stripVolatileFields(entry);\n }\n return out;\n}\n\nexport function stableDedupeJson(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(stableDedupeJson).join(\",\")}]`;\n }\n if (!value || typeof value !== \"object\") {\n return JSON.stringify(value);\n }\n\n const record = value as Record<string, unknown>;\n return `{${Object.keys(record).sort().map((key) => (\n `${JSON.stringify(key)}:${stableDedupeJson(record[key])}`\n )).join(\",\")}}`;\n}\n","/**\n * Audit trail — versioned history of every memory mutation.\n *\n * Records who changed what, when, why. Supports diff between versions\n * and rollback to a previous state.\n */\n\nimport { eq, desc } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { auditTrail, memories } from \"../db/schema.js\";\nimport { queueMemoryEmbeddingSync } from \"../embeddings/embeddings.js\";\nimport { getMemory } from \"../models/memory.js\";\nimport type { AuditAction, AuditEntry, MemoryItem } from \"../types.js\";\n\n// --- Record an audit entry ---\n\nexport function recordAudit(\n db: RecallDb,\n memoryId: string,\n action: AuditAction,\n actor: string,\n reason: string | null,\n beforeSnapshot?: string | null,\n afterSnapshot?: string | null,\n): string {\n const id = randomUUID();\n\n // Auto-capture snapshots if not provided\n if (afterSnapshot === undefined) {\n const mem = getMemory(db, memoryId);\n if (mem) {\n afterSnapshot = JSON.stringify(mem);\n }\n }\n\n db.insert(auditTrail)\n .values({\n id,\n memory_id: memoryId,\n action,\n actor,\n before_snapshot: beforeSnapshot ?? null,\n after_snapshot: afterSnapshot ?? null,\n reason: reason ?? null,\n timestamp: new Date().toISOString(),\n })\n .run();\n\n return id;\n}\n\n/** Record with explicit before/after snapshots */\nexport function recordAuditWithSnapshot(\n db: RecallDb,\n memoryId: string,\n action: AuditAction,\n actor: string,\n reason: string | null,\n before: MemoryItem | null,\n after: MemoryItem | null,\n): string {\n return recordAudit(\n db,\n memoryId,\n action,\n actor,\n reason,\n before ? JSON.stringify(before) : null,\n after ? JSON.stringify(after) : null,\n );\n}\n\n// --- Query audit trail ---\n\nexport function getAuditTrail(\n db: RecallDb,\n memoryId: string,\n): AuditEntry[] {\n return db\n .select()\n .from(auditTrail)\n .where(eq(auditTrail.memory_id, memoryId))\n .orderBy(desc(auditTrail.timestamp))\n .all()\n .map(rowToAudit);\n}\n\nexport function getRecentAudit(\n db: RecallDb,\n limit: number = 50,\n): AuditEntry[] {\n return db\n .select()\n .from(auditTrail)\n .orderBy(desc(auditTrail.timestamp))\n .limit(limit)\n .all()\n .map(rowToAudit);\n}\n\n// --- Diff between versions ---\n\nexport interface MemoryDiff {\n field: string;\n before: unknown;\n after: unknown;\n}\n\nexport function diffSnapshots(\n before: string | null,\n after: string | null,\n): MemoryDiff[] {\n if (!before || !after) return [];\n\n const a = JSON.parse(before);\n const b = JSON.parse(after);\n const diffs: MemoryDiff[] = [];\n\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]);\n for (const key of keys) {\n if (key === \"evidence\" || key === \"embedding\") continue; // skip large fields\n const va = JSON.stringify(a[key]);\n const vb = JSON.stringify(b[key]);\n if (va !== vb) {\n diffs.push({ field: key, before: a[key], after: b[key] });\n }\n }\n\n return diffs;\n}\n\n// --- Rollback ---\n\nexport function rollbackMemory(\n db: RecallDb,\n memoryId: string,\n auditEntryId: string,\n actor: string,\n): boolean {\n const entry = db\n .select()\n .from(auditTrail)\n .where(eq(auditTrail.id, auditEntryId))\n .get();\n\n if (!entry) return false;\n\n // Use the before_snapshot to restore state\n const snapshot = entry.before_snapshot;\n if (!snapshot) return false;\n\n const beforeRollback = getMemory(db, memoryId);\n const restored = JSON.parse(snapshot) as MemoryItem;\n\n db.update(memories)\n .set({\n text: restored.text,\n type: restored.type,\n scope: restored.scope,\n path_scope: restored.path_scope,\n status: restored.status,\n confidence: restored.confidence,\n source: restored.source,\n evidence: restored.evidence as any,\n capture_context: restored.capture_context as any,\n repetition_count: restored.repetition_count,\n updated_at: new Date().toISOString(),\n })\n .where(eq(memories.id, memoryId))\n .run();\n queueMemoryEmbeddingSync(db, memoryId);\n\n recordAuditWithSnapshot(\n db,\n memoryId,\n \"rolled_back\",\n actor,\n `Rolled back to state from ${entry.timestamp}`,\n beforeRollback ?? null,\n getMemory(db, memoryId) ?? null,\n );\n\n return true;\n}\n\n// --- Format audit trail ---\n\nexport function formatAuditTrail(entries: AuditEntry[]): string {\n if (entries.length === 0) return \"No audit entries.\";\n\n const lines = [\"# Audit Trail\", \"\"];\n for (const e of entries) {\n const diffs = diffSnapshots(e.before_snapshot, e.after_snapshot);\n const diffStr = diffs.length > 0\n ? ` [${diffs.map((d) => `${d.field}: ${JSON.stringify(d.before)} → ${JSON.stringify(d.after)}`).join(\", \")}]`\n : \"\";\n lines.push(\n `${e.timestamp.slice(0, 19)} ${e.action.padEnd(22)} by ${e.actor}${e.reason ? ` — ${e.reason}` : \"\"}${diffStr}`,\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n// --- Helpers ---\n\nfunction rowToAudit(row: any): AuditEntry {\n return {\n id: row.id,\n memory_id: row.memory_id,\n action: row.action,\n actor: row.actor,\n before_snapshot: row.before_snapshot,\n after_snapshot: row.after_snapshot,\n reason: row.reason,\n timestamp: row.timestamp,\n };\n}\n","import { eq } from \"drizzle-orm\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { contradictions } from \"../db/schema.js\";\nimport { computeAllHealthScores } from \"../health/scoring.js\";\nimport { queryMemories } from \"../models/memory.js\";\nimport { CONFIDENCE } from \"../types.js\";\n\nexport interface RepoQualityProfile {\n repo?: string;\n stage: \"cold\" | \"growing\" | \"mature\";\n score: number;\n total_count: number;\n active_count: number;\n avg_health: number;\n override_rate: number;\n contradiction_rate: number;\n repeat_sessions_required: number;\n compile_confidence_threshold: number;\n dedup_similarity_threshold: number;\n}\n\nexport function getRepoQualityProfile(\n db: RecallDb,\n repo?: string,\n): RepoQualityProfile {\n if (!repo) {\n return defaultProfile();\n }\n\n const memories = queryMemories(db, { repo }).filter((m) => m.status !== \"rejected\");\n const active = memories.filter((m) => m.status === \"active\");\n const activeCount = active.length;\n const totalCount = memories.length;\n\n const health = computeAllHealthScores(db, repo);\n const avgHealth = health.length > 0\n ? health.reduce((sum, item) => sum + item.score, 0) / health.length\n : 0;\n\n const totalInjections = memories.reduce((sum, m) => sum + m.injection_count, 0);\n const totalOverrides = memories.reduce((sum, m) => sum + m.override_count, 0);\n const overrideRate = totalInjections > 0 ? totalOverrides / totalInjections : 0;\n\n const ids = new Set(memories.map((m) => m.id));\n const unresolved = db\n .select()\n .from(contradictions)\n .where(eq(contradictions.resolved, false))\n .all()\n .filter((item) => ids.has(item.memory_a_id) || ids.has(item.memory_b_id));\n const contradictionRate = activeCount > 0\n ? unresolved.length / activeCount\n : 0;\n\n const stage = classifyStage(activeCount);\n const pressure = clamp(activeCount / 50);\n const score = clamp(\n avgHealth * 0.5 +\n (1 - clamp(overrideRate)) * 0.25 +\n (1 - clamp(contradictionRate)) * 0.15 +\n (1 - pressure) * 0.1,\n );\n\n let repeatSessionsRequired = stage === \"cold\"\n ? 2\n : stage === \"growing\"\n ? 3\n : 4;\n if (score >= 0.75 && repeatSessionsRequired > 2) {\n repeatSessionsRequired -= 1;\n } else if (score < 0.45) {\n repeatSessionsRequired += 1;\n }\n\n let compileConfidenceThreshold = stage === \"cold\"\n ? CONFIDENCE.ACTIVE_MIN\n : stage === \"growing\"\n ? 0.68\n : 0.72;\n if (score < 0.45) {\n compileConfidenceThreshold += 0.05;\n } else if (score > 0.8) {\n compileConfidenceThreshold -= 0.03;\n }\n\n let dedupSimilarityThreshold = stage === \"cold\"\n ? 0.85\n : stage === \"growing\"\n ? 0.8\n : 0.75;\n if (score < 0.45) {\n dedupSimilarityThreshold -= 0.05;\n }\n\n return {\n repo,\n stage,\n score,\n total_count: totalCount,\n active_count: activeCount,\n avg_health: avgHealth,\n override_rate: clamp(overrideRate),\n contradiction_rate: clamp(contradictionRate),\n repeat_sessions_required: repeatSessionsRequired,\n compile_confidence_threshold: clamp(\n compileConfidenceThreshold,\n CONFIDENCE.ACTIVE_MIN,\n 0.82,\n ),\n dedup_similarity_threshold: clamp(dedupSimilarityThreshold, 0.65, 0.9),\n };\n}\n\nexport function seedCandidateConfidence(\n baseConfidence: number,\n profile: RepoQualityProfile,\n): number {\n const maturityPenalty = profile.stage === \"cold\"\n ? 0\n : profile.stage === \"growing\"\n ? 0.03\n : 0.05;\n const qualityPenalty = profile.score < 0.45 ? 0.03 : 0;\n return clamp(\n baseConfidence - maturityPenalty - qualityPenalty,\n CONFIDENCE.TRANSIENT_MAX + 0.05,\n CONFIDENCE.ACTIVE_MIN - 0.01,\n );\n}\n\nexport function seedScannedConfidence(\n baseConfidence: number,\n profile: RepoQualityProfile,\n): number {\n const maturityPenalty = profile.stage === \"cold\"\n ? 0\n : profile.stage === \"growing\"\n ? 0.02\n : 0.05;\n const qualityPenalty = profile.score < 0.45 ? 0.03 : 0;\n return clamp(\n baseConfidence - maturityPenalty - qualityPenalty,\n 0.5,\n 0.85,\n );\n}\n\nfunction classifyStage(activeCount: number): RepoQualityProfile[\"stage\"] {\n if (activeCount < 10) return \"cold\";\n if (activeCount < 50) return \"growing\";\n return \"mature\";\n}\n\nfunction defaultProfile(): RepoQualityProfile {\n return {\n stage: \"cold\",\n score: 0.35,\n total_count: 0,\n active_count: 0,\n avg_health: 0,\n override_rate: 0,\n contradiction_rate: 0,\n repeat_sessions_required: 2,\n compile_confidence_threshold: CONFIDENCE.ACTIVE_MIN,\n dedup_similarity_threshold: 0.85,\n };\n}\n\nfunction clamp(n: number, min = 0, max = 1): number {\n return Math.max(min, Math.min(max, n));\n}\n","/**\n * Memory health scoring — composite score per memory.\n *\n * Score = weighted average of:\n * - confidence (40%)\n * - freshness / recency (25%)\n * - follow rate from feedback (20%)\n * - implicit signal ratio (15%)\n *\n * Memories decay over time if not validated/injected.\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { memories, feedbackEvents, implicitSignals } from \"../db/schema.js\";\nimport { getMemory, queryMemories, listMemories } from \"../models/memory.js\";\nimport type { HealthScore, MemoryItem } from \"../types.js\";\n\n// --- Weights ---\n\nconst WEIGHTS = {\n confidence: 0.4,\n freshness: 0.25,\n follow_rate: 0.2,\n signal_ratio: 0.15,\n} as const;\n\n// --- Compute health score ---\n\nexport function computeHealthScore(\n db: RecallDb,\n memoryId: string,\n): HealthScore | null {\n const mem = getMemory(db, memoryId);\n if (!mem) return null;\n\n const confidence = mem.confidence;\n const freshness = computeFreshness(mem);\n const followRate = computeFollowRate(db, memoryId);\n const signalRatio = computeSignalRatio(db, memoryId);\n\n const score =\n WEIGHTS.confidence * confidence +\n WEIGHTS.freshness * freshness +\n WEIGHTS.follow_rate * followRate +\n WEIGHTS.signal_ratio * signalRatio;\n\n return {\n memory_id: memoryId,\n score: clamp(score),\n confidence_component: confidence,\n freshness_component: freshness,\n follow_rate_component: followRate,\n signal_ratio_component: signalRatio,\n computed_at: new Date().toISOString(),\n };\n}\n\n// --- Batch health scores ---\n\nexport function computeAllHealthScores(\n db: RecallDb,\n repo?: string,\n): HealthScore[] {\n const mems = repo ? queryMemories(db, { repo }) : listMemories(db);\n const scores: HealthScore[] = [];\n\n for (const mem of mems) {\n if (mem.status === \"rejected\") continue;\n const score = computeHealthScore(db, mem.id);\n if (score) scores.push(score);\n }\n\n return scores.sort((a, b) => b.score - a.score);\n}\n\n// --- Freshness ---\n\nfunction computeFreshness(mem: MemoryItem): number {\n const now = Date.now();\n const referenceDate =\n mem.last_validated_at ?? mem.last_injected_at ?? mem.updated_at;\n const age = now - new Date(referenceDate).getTime();\n const dayMs = 86_400_000;\n\n // Exponential decay: halves every 30 days\n const halfLife = 30 * dayMs;\n const freshness = Math.pow(0.5, age / halfLife);\n return clamp(freshness);\n}\n\n// --- Follow rate from feedback ---\n\nfunction computeFollowRate(db: RecallDb, memoryId: string): number {\n const feedback = db\n .select()\n .from(feedbackEvents)\n .where(eq(feedbackEvents.memory_id, memoryId))\n .all();\n\n if (feedback.length === 0) return 0.5; // neutral if no data\n\n const followed = feedback.filter((f) => f.outcome === \"followed\").length;\n return followed / feedback.length;\n}\n\n// --- Signal ratio (positive signals / total signals) ---\n\nfunction computeSignalRatio(db: RecallDb, memoryId: string): number {\n const signals = db\n .select()\n .from(implicitSignals)\n .where(eq(implicitSignals.memory_id, memoryId))\n .all();\n\n if (signals.length === 0) return 0.5; // neutral if no data\n\n const positive = signals.filter((s) =>\n [\"test_pass\", \"file_unchanged\", \"task_accepted\"].includes(s.signal_type),\n ).length;\n\n return positive / signals.length;\n}\n\n// --- Format health report ---\n\nexport function formatHealthReport(scores: HealthScore[]): string {\n if (scores.length === 0) return \"No memories to score.\";\n\n const lines = [\n \"# Memory Health Report\",\n \"\",\n `Total: ${scores.length} memories scored`,\n \"\",\n \"| Score | Conf | Fresh | Follow | Signal | ID |\",\n \"|-------|------|-------|--------|--------|----------|\",\n ];\n\n for (const s of scores.slice(0, 30)) {\n lines.push(\n `| ${pct(s.score)} | ${pct(s.confidence_component)} | ${pct(s.freshness_component)} | ${pct(s.follow_rate_component)} | ${pct(s.signal_ratio_component)} | ${s.memory_id.slice(0, 8)} |`,\n );\n }\n\n // Summary stats\n const avg = scores.reduce((sum, s) => sum + s.score, 0) / scores.length;\n const unhealthy = scores.filter((s) => s.score < 0.3).length;\n const healthy = scores.filter((s) => s.score >= 0.6).length;\n\n lines.push(\"\");\n lines.push(`Avg score: ${pct(avg)}`);\n lines.push(`Healthy (≥0.6): ${healthy} | Unhealthy (<0.3): ${unhealthy}`);\n\n return lines.join(\"\\n\");\n}\n\n// --- Helpers ---\n\nfunction clamp(n: number): number {\n return Math.max(0, Math.min(1, n));\n}\n\nfunction pct(n: number): string {\n return (n * 100).toFixed(0).padStart(3) + \"%\";\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n getProviderConfig,\n type AzureOpenAiConfig,\n type LlmProvider,\n} from \"../credentials/keychain.js\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { llmUsage } from \"../db/schema.js\";\n\nexport type { LlmProvider };\n\nexport interface LlmCallInput {\n provider: LlmProvider;\n model?: string;\n system: string;\n user: string;\n max_output_tokens?: number;\n temperature?: number;\n task_kind: string;\n task_id?: string | null;\n repo?: string | null;\n}\n\nexport interface LlmUsageRow {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n cost_usd: number | null;\n}\n\nexport interface LlmCallResult {\n text: string;\n usage: LlmUsageRow;\n model: string;\n provider: LlmProvider;\n duration_ms: number;\n}\n\nexport class LlmCredentialError extends Error {}\nexport class LlmRequestError extends Error {}\n\nexport const DEFAULT_MODELS: Record<LlmProvider, string> = {\n openai: \"gpt-4o-mini\",\n anthropic: \"claude-haiku-4-5-20251001\",\n // For Azure the \"model\" is the deployment name, set by the user when they\n // provisioned the deployment. We leave it empty so we always fall through\n // to the deployment from AzureOpenAiConfig.\n \"azure-openai\": \"\",\n};\n\n// Rough per-1M token rates ($). Kept conservative; tighten when model pricing shifts.\n// Map by exact model id; unknown models fall through to null cost (still tracked, just un-priced).\nconst COST_PER_M_TOKENS: Record<string, { input: number; output: number }> = {\n \"gpt-4o-mini\": { input: 0.15, output: 0.60 },\n \"gpt-4o\": { input: 2.5, output: 10.0 },\n \"claude-haiku-4-5-20251001\": { input: 1.0, output: 5.0 },\n \"claude-sonnet-4-6\": { input: 3.0, output: 15.0 },\n \"claude-opus-4-7\": { input: 15.0, output: 75.0 },\n};\n\nexport async function callLlm(\n db: RecallDb,\n input: LlmCallInput,\n): Promise<LlmCallResult> {\n const provider = input.provider;\n const config = getProviderConfig(provider);\n if (!config) {\n throw new LlmCredentialError(missingCredentialMessage(provider));\n }\n const model = input.model ?? (provider === \"azure-openai\"\n ? (config as AzureOpenAiConfig).deployment\n : DEFAULT_MODELS[provider]);\n\n const started = Date.now();\n let result: LlmCallResult | null = null;\n let errorMessage: string | undefined;\n\n try {\n if (provider === \"openai\") {\n result = await callOpenAi((config as { key: string }).key, model, input);\n } else if (provider === \"anthropic\") {\n result = await callAnthropic((config as { key: string }).key, model, input);\n } else {\n result = await callAzureOpenAi(config as AzureOpenAiConfig, model, input);\n }\n return result;\n } catch (err) {\n errorMessage = err instanceof Error ? err.message : String(err);\n throw err;\n } finally {\n try {\n await recordUsage(db, {\n provider,\n model,\n task_kind: input.task_kind,\n task_id: input.task_id ?? null,\n repo: input.repo ?? null,\n usage: result?.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0, cost_usd: null },\n duration_ms: Date.now() - started,\n ok: Boolean(result),\n error: errorMessage,\n });\n } catch {\n // telemetry must never break the caller\n }\n }\n}\n\nasync function callOpenAi(\n apiKey: string,\n model: string,\n input: LlmCallInput,\n): Promise<LlmCallResult> {\n const started = Date.now();\n const response = await fetch(\"https://api.openai.com/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: input.system },\n { role: \"user\", content: input.user },\n ],\n max_completion_tokens: input.max_output_tokens ?? 2048,\n temperature: input.temperature ?? 0,\n }),\n });\n\n if (!response.ok) {\n const body = await safeText(response);\n throw new LlmRequestError(`OpenAI ${response.status}: ${body.slice(0, 400)}`);\n }\n\n const payload = await response.json() as {\n choices?: Array<{ message?: { content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n };\n const text = payload.choices?.[0]?.message?.content?.trim() ?? \"\";\n const prompt_tokens = payload.usage?.prompt_tokens ?? 0;\n const completion_tokens = payload.usage?.completion_tokens ?? 0;\n const total_tokens = payload.usage?.total_tokens ?? prompt_tokens + completion_tokens;\n\n return {\n text,\n model,\n provider: \"openai\",\n duration_ms: Date.now() - started,\n usage: {\n prompt_tokens,\n completion_tokens,\n total_tokens,\n cost_usd: computeCost(model, prompt_tokens, completion_tokens),\n },\n };\n}\n\nasync function callAzureOpenAi(\n config: AzureOpenAiConfig,\n deployment: string,\n input: LlmCallInput,\n): Promise<LlmCallResult> {\n const started = Date.now();\n const url = `${config.endpoint}/openai/deployments/${encodeURIComponent(deployment)}/chat/completions?api-version=${encodeURIComponent(config.api_version)}`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"api-key\": config.key,\n },\n body: JSON.stringify({\n messages: [\n { role: \"system\", content: input.system },\n { role: \"user\", content: input.user },\n ],\n max_completion_tokens: input.max_output_tokens ?? 2048,\n temperature: input.temperature ?? 0,\n }),\n });\n\n if (!response.ok) {\n const body = await safeText(response);\n throw new LlmRequestError(`Azure OpenAI ${response.status}: ${body.slice(0, 400)}`);\n }\n\n const payload = await response.json() as {\n choices?: Array<{ message?: { content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n };\n const text = payload.choices?.[0]?.message?.content?.trim() ?? \"\";\n const prompt_tokens = payload.usage?.prompt_tokens ?? 0;\n const completion_tokens = payload.usage?.completion_tokens ?? 0;\n const total_tokens = payload.usage?.total_tokens ?? prompt_tokens + completion_tokens;\n\n return {\n text,\n model: deployment,\n provider: \"azure-openai\",\n duration_ms: Date.now() - started,\n usage: {\n prompt_tokens,\n completion_tokens,\n total_tokens,\n cost_usd: computeCost(deployment, prompt_tokens, completion_tokens),\n },\n };\n}\n\nasync function callAnthropic(\n apiKey: string,\n model: string,\n input: LlmCallInput,\n): Promise<LlmCallResult> {\n const started = Date.now();\n const response = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model,\n system: input.system,\n messages: [{ role: \"user\", content: input.user }],\n max_tokens: input.max_output_tokens ?? 2048,\n temperature: input.temperature ?? 0,\n }),\n });\n\n if (!response.ok) {\n const body = await safeText(response);\n throw new LlmRequestError(`Anthropic ${response.status}: ${body.slice(0, 400)}`);\n }\n\n const payload = await response.json() as {\n content?: Array<{ type?: string; text?: string }>;\n usage?: { input_tokens?: number; output_tokens?: number };\n };\n const text = (payload.content ?? [])\n .filter((block) => block.type === \"text\" && typeof block.text === \"string\")\n .map((block) => block.text)\n .join(\"\")\n .trim();\n const prompt_tokens = payload.usage?.input_tokens ?? 0;\n const completion_tokens = payload.usage?.output_tokens ?? 0;\n\n return {\n text,\n model,\n provider: \"anthropic\",\n duration_ms: Date.now() - started,\n usage: {\n prompt_tokens,\n completion_tokens,\n total_tokens: prompt_tokens + completion_tokens,\n cost_usd: computeCost(model, prompt_tokens, completion_tokens),\n },\n };\n}\n\nfunction computeCost(model: string, inputTokens: number, outputTokens: number): number | null {\n const rates = COST_PER_M_TOKENS[model];\n if (!rates) return null;\n return (\n (inputTokens / 1_000_000) * rates.input +\n (outputTokens / 1_000_000) * rates.output\n );\n}\n\nasync function recordUsage(\n db: RecallDb,\n row: {\n provider: LlmProvider;\n model: string;\n task_kind: string;\n task_id: string | null;\n repo: string | null;\n usage: LlmUsageRow;\n duration_ms: number;\n ok: boolean;\n error?: string;\n },\n): Promise<void> {\n await db.insert(llmUsage).values({\n id: randomUUID(),\n provider: row.provider,\n model: row.model,\n task_kind: row.task_kind,\n task_id: row.task_id,\n repo: row.repo,\n prompt_tokens: row.usage.prompt_tokens,\n completion_tokens: row.usage.completion_tokens,\n total_tokens: row.usage.total_tokens,\n cost_usd: row.usage.cost_usd ?? null,\n duration_ms: row.duration_ms,\n ok: row.ok,\n error: row.error ?? null,\n created_at: new Date().toISOString(),\n });\n}\n\nfunction missingCredentialMessage(provider: LlmProvider): string {\n switch (provider) {\n case \"openai\":\n return `No API key for provider \"openai\". Set it via \\`recall maintenance credentials set openai <key>\\` or the OPENAI_API_KEY env var.`;\n case \"anthropic\":\n return `No API key for provider \"anthropic\". Set it via \\`recall maintenance credentials set anthropic <key>\\` or the ANTHROPIC_API_KEY env var.`;\n case \"azure-openai\":\n return `Azure OpenAI is not fully configured. Run \\`recall maintenance credentials set azure --endpoint <url> --deployment <name> --api-version <version> <key>\\` or set AZURE_OPENAI_{ENDPOINT,DEPLOYMENT,API_VERSION,API_KEY}.`;\n }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n","import type { RecallDb } from \"../db/client.js\";\nimport type { MaintenanceTask, MaintenanceTaskKind } from \"../types.js\";\nimport {\n TaskClaimConflictError,\n claimTask,\n listTasks,\n releaseTask,\n submitTask,\n} from \"./tasks.js\";\nimport { callLlm, LlmCredentialError, type LlmProvider } from \"../llm/client.js\";\nimport { hasProviderConfigured } from \"../credentials/keychain.js\";\n\nconst DISPATCH_AGENT = \"recall:dispatcher\";\nconst DEFAULT_LEASE_SECONDS = 120;\n\nexport interface DispatchOptions {\n provider?: LlmProvider;\n model?: string;\n maxTasks?: number;\n kinds?: MaintenanceTaskKind[];\n repo?: string;\n dryRun?: boolean;\n}\n\nexport interface DispatchOutcome {\n task_id: string;\n kind: MaintenanceTaskKind;\n repo: string | null;\n status: \"applied\" | \"rejected\" | \"released\" | \"skipped\";\n reason?: string;\n target_id?: string;\n changed_fields?: string[];\n prompt_tokens?: number;\n completion_tokens?: number;\n cost_usd?: number | null;\n duration_ms?: number;\n}\n\nexport interface DispatchReport {\n provider: LlmProvider | null;\n model: string | null;\n dry_run: boolean;\n attempted: number;\n applied: number;\n rejected: number;\n released: number;\n outcomes: DispatchOutcome[];\n}\n\nexport async function dispatchPendingTasks(\n db: RecallDb,\n options: DispatchOptions = {},\n): Promise<DispatchReport> {\n const provider = resolveProvider(options.provider);\n const report: DispatchReport = {\n provider,\n model: null,\n dry_run: Boolean(options.dryRun),\n attempted: 0,\n applied: 0,\n rejected: 0,\n released: 0,\n outcomes: [],\n };\n if (!provider) return report;\n\n const pending = listTasks(db, {\n status: \"pending\",\n kinds: options.kinds,\n repo: options.repo,\n limit: options.maxTasks ?? 5,\n });\n\n for (const task of pending) {\n if (options.dryRun) {\n report.outcomes.push({\n task_id: task.id,\n kind: task.kind,\n repo: task.repo,\n status: \"skipped\",\n reason: \"dry-run\",\n });\n continue;\n }\n report.attempted += 1;\n const outcome = await runSingle(db, task, provider, options.model);\n report.outcomes.push(outcome);\n if (outcome.status === \"applied\") report.applied += 1;\n else if (outcome.status === \"rejected\") report.rejected += 1;\n else if (outcome.status === \"released\") report.released += 1;\n if (outcome.prompt_tokens != null && !report.model) {\n // remember the model the first successful call used, for display\n const last = report.outcomes[report.outcomes.length - 1];\n report.model = (last as DispatchOutcome & { model?: string }).task_id ? options.model ?? null : null;\n }\n }\n\n return report;\n}\n\nasync function runSingle(\n db: RecallDb,\n task: MaintenanceTask,\n provider: LlmProvider,\n model?: string,\n): Promise<DispatchOutcome> {\n let claimed: MaintenanceTask;\n try {\n const claim = claimTask(db, task.id, DISPATCH_AGENT, DEFAULT_LEASE_SECONDS);\n claimed = claim.task;\n } catch (err) {\n if (err instanceof TaskClaimConflictError) {\n return {\n task_id: task.id,\n kind: task.kind,\n repo: task.repo,\n status: \"skipped\",\n reason: err.reason,\n };\n }\n throw err;\n }\n\n const prompt = buildPrompt(claimed);\n if (!prompt) {\n releaseTask(db, claimed.id, DISPATCH_AGENT);\n return {\n task_id: claimed.id,\n kind: claimed.kind,\n repo: claimed.repo,\n status: \"released\",\n reason: \"no prompt builder\",\n };\n }\n\n try {\n const llmResult = await callLlm(db, {\n provider,\n model,\n system: prompt.system,\n user: prompt.user,\n max_output_tokens: prompt.max_output_tokens,\n task_kind: claimed.kind,\n task_id: claimed.id,\n repo: claimed.repo,\n });\n\n const parsed = parseJson(llmResult.text);\n if (!parsed) {\n releaseTask(db, claimed.id, DISPATCH_AGENT);\n return {\n task_id: claimed.id,\n kind: claimed.kind,\n repo: claimed.repo,\n status: \"released\",\n reason: \"llm did not return valid JSON\",\n prompt_tokens: llmResult.usage.prompt_tokens,\n completion_tokens: llmResult.usage.completion_tokens,\n cost_usd: llmResult.usage.cost_usd,\n duration_ms: llmResult.duration_ms,\n };\n }\n\n const submit = submitTask(db, claimed.id, DISPATCH_AGENT, parsed);\n if (submit.status === \"applied\") {\n return {\n task_id: claimed.id,\n kind: claimed.kind,\n repo: claimed.repo,\n status: \"applied\",\n target_id: submit.target_id,\n changed_fields: submit.changed_fields,\n prompt_tokens: llmResult.usage.prompt_tokens,\n completion_tokens: llmResult.usage.completion_tokens,\n cost_usd: llmResult.usage.cost_usd,\n duration_ms: llmResult.duration_ms,\n };\n }\n return {\n task_id: claimed.id,\n kind: claimed.kind,\n repo: claimed.repo,\n status: \"rejected\",\n reason: submit.reason,\n prompt_tokens: llmResult.usage.prompt_tokens,\n completion_tokens: llmResult.usage.completion_tokens,\n cost_usd: llmResult.usage.cost_usd,\n duration_ms: llmResult.duration_ms,\n };\n } catch (err) {\n releaseTask(db, claimed.id, DISPATCH_AGENT);\n const reason = err instanceof LlmCredentialError\n ? err.message\n : err instanceof Error\n ? err.message\n : String(err);\n return {\n task_id: claimed.id,\n kind: claimed.kind,\n repo: claimed.repo,\n status: \"released\",\n reason,\n };\n }\n}\n\nexport function hasAnyLlmProvider(): boolean {\n return resolveProvider() != null;\n}\n\nfunction resolveProvider(preferred?: LlmProvider): LlmProvider | null {\n const candidates: LlmProvider[] = preferred\n ? [preferred]\n : [\"anthropic\", \"azure-openai\", \"openai\"];\n for (const provider of candidates) {\n if (hasProviderConfigured(provider)) return provider;\n }\n return null;\n}\n\nfunction parseJson(text: string): unknown | null {\n const trimmed = text.trim();\n if (trimmed.length === 0) return null;\n // Strip code fences if present.\n const stripped = trimmed\n .replace(/^```(?:json)?\\s*/i, \"\")\n .replace(/\\s*```$/i, \"\")\n .trim();\n try {\n return JSON.parse(stripped);\n } catch {\n // Some models return a leading sentence before the JSON. Try to locate the first {.\n const first = stripped.indexOf(\"{\");\n const last = stripped.lastIndexOf(\"}\");\n if (first >= 0 && last > first) {\n try {\n return JSON.parse(stripped.slice(first, last + 1));\n } catch {\n return null;\n }\n }\n return null;\n }\n}\n\nexport interface Prompt {\n system: string;\n user: string;\n max_output_tokens?: number;\n}\n\nexport function buildPrompt(task: MaintenanceTask): Prompt | null {\n switch (task.kind) {\n case \"verify_capture\":\n return buildVerifyCapturePrompt(task);\n case \"refine_candidate\":\n return buildRefineCandidatePrompt(task);\n case \"summarize_history\":\n return buildSummarizeHistoryPrompt(task);\n case \"merge_duplicates\":\n return buildMergeDuplicatesPrompt(task);\n case \"summarize_session\":\n return buildSummarizeSessionPrompt(task);\n case \"synthesize_repo\":\n return buildSynthesizeRepoPrompt(task);\n case \"extract_rules_from_prompt\":\n return buildExtractRulesFromPromptPrompt(task);\n default:\n return null;\n }\n}\n\nfunction buildExtractRulesFromPromptPrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as {\n raw_prompt?: string;\n repo?: string | null;\n path?: string | null;\n agent?: string | null;\n prev_assistant_turn?: string | null;\n recent_tool_calls?: unknown;\n };\n const system = [\n \"You are the capture judge for a coding-agent memory store.\",\n \"Read the USER PROMPT below and extract zero or more DURABLE RULES the user is stating about how the agent should behave on this repo (or globally).\",\n \"A rule must be:\",\n \" (a) Imperative — telling the agent what to always/never do, or what to prefer.\",\n \" (b) Durable — the user expects it to apply across future sessions, not just this one task.\",\n \" (c) Specific — concrete enough that an agent can follow it without further clarification.\",\n \"Recognize rules in ANY natural language (English, Spanish, French, German, Italian, Portuguese, Russian, Chinese, Japanese, Albanian, Turkish, Arabic, …). When the source is non-English, return the cleaned rule TEXT in English so memories are searchable across sessions.\",\n \"REJECT (return empty list):\",\n \" • Questions ('should we use X?'), one-off task requests ('please fix this bug now'), narration ('I never use X' as description of past behavior), code paste, error logs, transcripts.\",\n \" • Trigger-template rules ('when user says X, do Y') and destructive-risky rules (delete/wipe/drop + settings/secrets/branches/files) — return them but flag is_destructive_risky=true so they require explicit user confirm before going active.\",\n \" • Anything where the intent is ambiguous without surrounding context.\",\n \"Output a single CANONICAL sentence per rule, in imperative mood. Strip filler words (uh, um, like, you know).\",\n \"Set scope as tight as the evidence supports: 'path' if a specific file/dir is referenced, 'repo' for repo-wide, 'global' only if the user explicitly says 'across all my projects' / 'globally' / 'everywhere'.\",\n \"Confidence: 0.9+ for unambiguous explicit rules, 0.5-0.8 for inferred/soft preferences, below 0.5 means you should probably not return it at all.\",\n \"Be STRICT — false positives produce wrong agent behavior. When unsure, prefer empty list over a low-confidence guess.\",\n JSON_ONLY,\n ].join(\" \");\n const recentToolsSummary = summarizeRecentToolCalls(payload.recent_tool_calls);\n const user = [\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Path: ${JSON.stringify(payload.path ?? null)}`,\n `Agent: ${JSON.stringify(payload.agent ?? null)}`,\n payload.prev_assistant_turn\n ? `Previous assistant turn (for context only — do not extract rules from it): ${JSON.stringify(payload.prev_assistant_turn.slice(0, 800))}`\n : \"Previous assistant turn: null\",\n recentToolsSummary ? `Recent tool calls: ${recentToolsSummary}` : \"Recent tool calls: none\",\n \"\",\n `USER PROMPT:`,\n JSON.stringify(payload.raw_prompt ?? \"\"),\n \"\",\n 'Return JSON: {\"rules\": [{\"text\": string, \"type\": \"rule\"|\"decision\"|\"review_pattern\"|\"command\"|\"gotcha\", \"scope\": \"session\"|\"path\"|\"repo\"|\"team\"|\"global\", \"path_scope\": string|null, \"confidence\": number, \"is_destructive_risky\": boolean, \"rationale\": string}], \"dropped_reason\": string?}',\n 'When the prompt contains no durable rule, return {\"rules\": []} with a brief dropped_reason.',\n ].join(\"\\n\");\n return { system, user, max_output_tokens: 800 };\n}\n\nfunction summarizeRecentToolCalls(value: unknown): string | null {\n if (!Array.isArray(value) || value.length === 0) return null;\n return value\n .slice(-5)\n .map((entry: any) => {\n if (!entry || typeof entry !== \"object\") return null;\n const name = typeof entry.name === \"string\" ? entry.name : \"tool\";\n const path = typeof entry.path === \"string\" ? entry.path : null;\n return path ? `${name}(${path})` : name;\n })\n .filter(Boolean)\n .join(\", \");\n}\n\nfunction buildVerifyCapturePrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as {\n memory_id?: string;\n text?: string;\n inferred_scope?: string;\n inferred_path_scope?: string | null;\n repo?: string | null;\n capture_context?: unknown;\n };\n const system = [\n \"You verify a captured candidate rule for a coding-agent memory store.\",\n \"Decide if it is a durable rule worth saving, salvageable but needs rewriting, or noise/narration.\",\n \"Be strict — false positives produce wrong agent behavior. When unsure, prefer reject over save.\",\n \"Reject voice transcripts, descriptive clauses about what the user does ('things I never use'), one-shot task chatter, and any text whose intent is unclear without surrounding context.\",\n \"When rewriting, output a single canonical sentence in imperative mood. Keep scope as tight as the evidence supports.\",\n \"Flag is_destructive_risky=true when the rule pairs a destructive verb (remove/delete/drop/wipe) with high-risk targets (settings/config/files/secrets/branches), OR when it is shaped as a literal-trigger rule (\\\"when user says X, do Y\\\") — both require explicit user confirm regardless.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Candidate text: ${JSON.stringify(payload.text ?? \"\")}`,\n `Inferred scope: ${payload.inferred_scope ?? \"repo\"}`,\n `Inferred path_scope: ${JSON.stringify(payload.inferred_path_scope ?? null)}`,\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Capture context: ${JSON.stringify(payload.capture_context ?? null)}`,\n \"\",\n 'Return JSON: {\"verdict\": \"save\"|\"rewrite\"|\"reject\", \"cleaned_text\"?: string, \"scope\"?: \"session\"|\"path\"|\"repo\"|\"team\"|\"global\", \"path_scope\"?: string|null, \"is_destructive_risky\"?: boolean, \"reason\"?: string}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nconst JSON_ONLY = \"Respond with a single JSON object matching the required schema, no prose, no markdown fences.\";\n\nfunction buildRefineCandidatePrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as {\n memory_id?: string;\n text?: string;\n current_scope?: string;\n current_path_scope?: string | null;\n repo?: string | null;\n repetition_count?: number;\n };\n const system = [\n \"You refine candidate memories in a coding-agent memory store.\",\n \"Keep only durable rules/commands/gotchas. Clamp scope tighter when the evidence is path-specific.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Current memory text: ${JSON.stringify(payload.text ?? \"\")}`,\n `Current scope: ${payload.current_scope ?? \"repo\"}`,\n `Current path_scope: ${JSON.stringify(payload.current_path_scope ?? null)}`,\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Repetition count: ${payload.repetition_count ?? 0}`,\n \"\",\n 'Return JSON: {\"refined_text\": string, \"scope\": \"session\"|\"path\"|\"repo\"|\"team\"|\"global\", \"path_scope\": string|null, \"rationale\": string, \"verdict\"?: \"rewrite\"|\"reject\"}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nfunction buildSummarizeHistoryPrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as {\n current_text?: string;\n kind?: string;\n repo?: string | null;\n };\n const system = [\n \"You compress activity snippets in a coding-agent memory store.\",\n \"Keep the essential facts; drop filler. <= 3 short sentences.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Kind: ${payload.kind ?? \"unknown\"}`,\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Current text: ${JSON.stringify(payload.current_text ?? \"\")}`,\n \"\",\n 'Return JSON: {\"summary_text\": string, \"tags\": [string, ...]}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nfunction buildMergeDuplicatesPrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as {\n cluster?: Array<{ id: string; text: string; confidence?: number; scope?: string; path_scope?: string | null }>;\n repo?: string | null;\n };\n const system = [\n \"You pick the best memory among near-duplicates in a coding-agent memory store.\",\n \"Choose the single winning id. You may also rewrite the winner's text for clarity, and tighten its scope if evidence supports it.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Cluster:`,\n JSON.stringify(payload.cluster ?? [], null, 2),\n \"\",\n 'Return JSON: {\"winner_id\": uuid, \"winner_text\"?: string, \"winner_scope\"?: \"session\"|\"path\"|\"repo\"|\"team\", \"winner_path_scope\"?: string|null, \"rationale\"?: string}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nfunction buildSummarizeSessionPrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as { events?: unknown[]; session_id?: string; repo?: string | null };\n const system = [\n \"You condense a coding-agent session into a brief durable summary.\",\n \"<= 5 short bullet points; no filler.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Session: ${payload.session_id ?? \"unknown\"}`,\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Events: ${JSON.stringify(payload.events ?? [], null, 2).slice(0, 12_000)}`,\n \"\",\n 'Return JSON: {\"summary_text\": string}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nfunction buildSynthesizeRepoPrompt(task: MaintenanceTask): Prompt {\n const payload = task.payload as { repo?: string | null; memories?: unknown[] };\n const system = [\n \"You synthesize a concise repo-level summary from the stable memory set.\",\n \"Focus on commands, rules, gotchas, and decisions that repeat across sessions.\",\n JSON_ONLY,\n ].join(\" \");\n const user = [\n `Repo: ${JSON.stringify(payload.repo ?? null)}`,\n `Memory set: ${JSON.stringify(payload.memories ?? [], null, 2).slice(0, 12_000)}`,\n \"\",\n 'Return JSON: {\"summary_text\": string}',\n ].join(\"\\n\");\n return { system, user };\n}\n\nexport function formatDispatchReport(report: DispatchReport): string {\n const lines: string[] = [\n \"# Recall Maintenance Dispatch\",\n `Provider: ${report.provider ?? \"(none — no API key)\"}`,\n `Dry run: ${report.dry_run ? \"yes\" : \"no\"}`,\n `Attempted: ${report.attempted}`,\n `Applied: ${report.applied}`,\n `Rejected: ${report.rejected}`,\n `Released: ${report.released}`,\n ];\n if (report.outcomes.length > 0) {\n lines.push(\"\", \"## Outcomes\");\n for (const o of report.outcomes) {\n const cost = o.cost_usd != null ? ` $${o.cost_usd.toFixed(4)}` : \"\";\n const tokens = o.prompt_tokens != null ? ` tokens=${(o.prompt_tokens ?? 0) + (o.completion_tokens ?? 0)}` : \"\";\n const reason = o.reason ? ` — ${o.reason}` : \"\";\n lines.push(` ${o.task_id.slice(0, 8)} ${o.kind.padEnd(20)} ${o.status.padEnd(10)}${tokens}${cost}${reason}`);\n }\n }\n return lines.join(\"\\n\");\n}\n","import type { RecallDb } from \"../db/client.js\";\nimport { findSemanticDuplicates, findSimilarRejectedExemplar, loadEmbeddingConfigFromEnv } from \"../embeddings/embeddings.js\";\nimport {\n appendEvidence,\n countDistinctCorrectionSessions,\n createMemory,\n getMemory,\n getMemoryFeedback,\n incrementMemoryRepetition,\n promoteMemory,\n queryMemories,\n updateMemoryCaptureContext,\n} from \"../models/memory.js\";\nimport type { CreateMemoryInput } from \"../models/memory.js\";\nimport type { CaptureContext, MemoryItem, MemoryType, EvidenceEntry } from \"../types.js\";\nimport { getRepoQualityProfile, seedCandidateConfidence } from \"../repo/quality.js\";\nimport { enqueueExtractRulesFromPrompt, enqueueVerifyCapture } from \"../maintenance/tasks.js\";\nimport { hasAnyLlmProvider } from \"../maintenance/dispatcher.js\";\nimport { randomUUID } from \"node:crypto\";\nimport { inferScope } from \"./scope.js\";\nimport type { RecentToolCall } from \"../agents/types.js\";\nimport { recordAuditWithSnapshot } from \"../audit/trail.js\";\nimport { qualityReasons } from \"../maintenance/cleanup.js\";\n\n// --- Detection patterns ---\n\ninterface CorrectionMatch {\n type: MemoryType;\n text: string;\n confidence: number;\n original?: string;\n}\n\nconst NEGATION_REPLACEMENT =\n /\\b(?:not|don't|do not|never|stop)\\s+(?:use|do|run|call|import)\\s+(.+?)[\\s,;.]+(?:use|do|run|call|import|instead)\\s+(.+)/i;\n\nconst EXPLICIT_RULE =\n /\\b(always|never|must|required|forbidden|don't ever)\\b\\s+(.+)/i;\n\n// \"whenever / each time / every time / when I (say|use|ask|mention) X, do Y\"\n// captures meta-rules that don't start with always/never. The trigger (X) and\n// the action (Y) are stored together as a single rule sentence.\nconst WHEN_DO_RULE =\n /\\b(?:whenever|each time|every time|when(?:ever)?)\\s+(?:i|you|we)\\s+(say|use|ask|mention|do|run)\\s+(.+?)[,.]?\\s+(?:we|you|i|please|always|just)?\\s*(do|run|use|please|add|make|update|commit|push|backup|back up|sync|verify|check|ensure)\\s+(.+)/i;\n\nconst REVIEW_FEEDBACK =\n /\\b(?:review|reviewer|PR feedback|code review)\\s+(?:said|says|asked|wants|requires|flagged)\\s+(.+)/i;\n\nconst SOFT_PREFERENCE =\n /\\b(?:we|I|the team|this repo)\\s+(?:prefer|usually use|tend to use|lean on|default to|use)\\s+(.+?)(?:\\s+(?:instead of|not|over)\\s+(.+))?$/i;\n\nconst SOFT_DECISION =\n /\\b(?:let's|lets|let us|we should|we'll|we will|we can|use)\\s+(?:use|keep|follow|stick with|go with)\\s+(.+?)(?:\\s+(?:instead of|over)\\s+(.+))?(?:[.!]|$)/i;\n\nconst CONFIG_BACKED_DECISION =\n /\\b(?:editorconfig|prettier|eslint|tsconfig|package\\.json|ci|workflow|this repo)\\b.*\\b(?:says|uses|wants|defaults to|is configured for)\\s+(.+)/i;\n\nconst QUESTION_ONLY =\n /^\\s*(?:should|could|would|can|do)\\b.*\\?\\s*$/i;\n\n// Modals preceded within 3 tokens by a pronoun/relative pronoun are\n// descriptive, not prescriptive: \"things I never use\", \"stuff we always do\",\n// \"those plugins I never use from settings\". The substring after the modal\n// looks rule-shaped to EXPLICIT_RULE but the surrounding clause makes it\n// narration. Skip the whole segment.\nconst DESCRIPTIVE_MODAL_RE =\n /\\b(?:i|you|we|they|those|that|which|who)(?:\\s+\\w+){0,2}\\s+(?:always|never|must|don't|do not|prefer|required|forbidden)\\b/i;\n\n// A captured rule is \"destructive-risky\" when it pairs a destructive verb with\n// a high-risk target (settings, plugins, files, memories, secrets, history,\n// branches, etc.). Even with strong repetition signal, these rules require an\n// explicit `recall confirm` before they go active — otherwise an agent could\n// follow them and irreversibly damage user state.\nconst DESTRUCTIVE_VERB_RE =\n /\\b(?:remove|delete|drop|wipe|clear|purge|erase|nuke|truncate|reset|destroy)\\b/i;\nconst HIGH_RISK_TARGET_RE =\n /\\b(?:plugin|plugins|setting|settings|config|configs|configuration|file|files|folder|folders|directory|directories|memor(?:y|ies)|database|db|repo|repos|repository|branch|branches|commit|commits|history|backup|backups|secret|secrets|credential|credentials|key|keys|token|tokens)\\b/i;\n\nexport function isDestructiveRisky(text: string): boolean {\n return DESTRUCTIVE_VERB_RE.test(text) && HIGH_RISK_TARGET_RE.test(text);\n}\n\n// A captured rule is \"trigger-template-shaped\" when it conditions an action on\n// a literal user phrase (\"When user says X, do Y\"). This shape is structurally\n// indistinguishable from a prompt-injection template, and when promoted to\n// global scope it gets injected into unrelated sessions where the receiving\n// agent cannot tell our memory apart from an attack. Block auto-promotion and\n// require explicit user confirmation, same as destructive-risky rules.\nconst TRIGGER_TEMPLATE_RE =\n /^\\s*when(?:ever)?\\s+(?:the\\s+)?user\\s+(?:says|asks|writes|types|mentions|uses|requests)\\b/i;\n\nexport function isTriggerTemplateRule(text: string): boolean {\n return TRIGGER_TEMPLATE_RE.test(text);\n}\n\nexport function isHighRiskRule(text: string): boolean {\n return isDestructiveRisky(text) || isTriggerTemplateRule(text);\n}\n\n// Multi-language pre-screen for the LLM-primary capture path. Cheap regex\n// asking \"is this prompt worth showing to the LLM at all?\" — most coding\n// prompts are pure code requests with zero rule content. We only forward to\n// the LLM when at least one rule-shaped signal is present in any supported\n// language, OR the user uses an explicit save verb. False positives are\n// cheap (small extra LLM call); false negatives mean a rule slips by, so\n// we err on the side of letting things through.\n// JavaScript's `\\b` is ASCII-only even with the `u` flag, so it fails on\n// Cyrillic, Albanian/Turkish diacritics, and CJK scripts. We use explicit\n// lookarounds with Unicode property escapes for non-ASCII alternatives, and\n// plain `\\b` for ASCII Latin words.\nconst NON_LETTER = \"(?<![\\\\p{L}])(?:\";\nconst NON_LETTER_END = \")(?![\\\\p{L}])\";\nconst PROMPT_SCREEN_RE = new RegExp(\n [\n // English imperatives + save verbs (ASCII — `\\b` works)\n \"\\\\b(?:always|never|don't|do\\\\s*not|must|should|prefer|avoid|remember|memorize|note|save\\\\s+this|keep\\\\s+in\\\\s+mind|by\\\\s+default|use\\\\s+only|forbid|please\\\\s+(?:always|never))\\\\b\",\n // Romance languages (handle diacritics with Unicode boundaries)\n `${NON_LETTER}siempre|nunca|jamás|no\\\\s+uses|prefiere|recuerda${NON_LETTER_END}`,\n `${NON_LETTER}toujours|jamais|n'utilise(?:z)?\\\\s+pas|préfère|rappel${NON_LETTER_END}`,\n `${NON_LETTER}immer|nie(?:mals)?|nicht\\\\s+verwenden|bevorzuge|merk\\\\s*dir${NON_LETTER_END}`,\n `${NON_LETTER}sempre|mai|non\\\\s+usare|preferisci|ricorda${NON_LETTER_END}`,\n `${NON_LETTER}não\\\\s+use|prefira|lembre${NON_LETTER_END}`,\n // Russian (Cyrillic)\n `${NON_LETTER}всегда|никогда|не\\\\s+используй|предпочти|запомни${NON_LETTER_END}`,\n // CJK — no word boundaries needed\n \"(?:总是|从不|不要使用|偏好|记住|常に|決して|使わない|覚えて)\",\n // Albanian (Edi's native) — has diacritics\n `${NON_LETTER}gjithmonë|asnjëherë|kurrë|mos\\\\s+përdor|mbaj\\\\s+mend${NON_LETTER_END}`,\n // Turkish\n `${NON_LETTER}her\\\\s*zaman|asla|kullanma|tercih\\\\s+et|hatırla${NON_LETTER_END}`,\n ].join(\"|\"),\n \"iu\",\n);\n\n// Best-effort wake-up to the local daemon's /dispatch/wake endpoint. The\n// daemon listens on a local socket; if it isn't running, the request fails\n// silently and the timer-based dispatcher cycle catches up later. Debounced\n// in the daemon itself so repeated hook calls collapse to one dispatch run.\nfunction wakeDispatcherBestEffort(): void {\n const port = parseInt(process.env.RECALL_DAEMON_PORT ?? \"47649\", 10);\n // Fire-and-forget; don't await, don't crash the hook on failure.\n fetch(`http://127.0.0.1:${port}/dispatch/wake`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: \"{}\",\n signal: AbortSignal.timeout(250),\n }).catch(() => {\n // Daemon not running, port closed, or timeout — ignore. The dispatcher\n // will eventually pick up the task on its own schedule.\n });\n}\n\nexport function isPromptWorthLLM(text: string): boolean {\n const trimmed = text.trim();\n if (trimmed.length < 8) return false;\n // Trivial: empty or pure code / shell input\n if (/^```/.test(trimmed)) return false;\n // Voice-transcripted long rambles always worth a look (LLM can extract)\n if (trimmed.length > 800) return true;\n return PROMPT_SCREEN_RE.test(trimmed);\n}\n\nexport function detectCorrections(text: string): CorrectionMatch[] {\n const normalizedText = text.trim();\n if (QUESTION_ONLY.test(normalizedText)) return [];\n if (looksLikePastedTranscript(normalizedText)) return [];\n\n const matches: CorrectionMatch[] = [];\n const segments = correctionCandidateSegments(normalizedText);\n\n for (const segment of segments) {\n // Drop segments where the modal is part of a descriptive clause\n // (\"remove those plugins I never use\") rather than an instruction\n // (\"we prefer X\"). Heuristic: if the pronoun-modal pattern is preceded\n // by other words in the segment, it's narration about an object; if it's\n // at the start, it's a direct statement and we keep it.\n const descriptive = DESCRIPTIVE_MODAL_RE.exec(segment);\n if (descriptive && descriptive.index > 0) continue;\n\n // Trigger → action: \"whenever I say X, do Y\"\n const whenDo = segment.match(WHEN_DO_RULE);\n if (whenDo) {\n const trigger = stripTrailingPunctuation(whenDo[2]);\n const action = stripTrailingPunctuation(`${whenDo[3]} ${whenDo[4]}`);\n matches.push({\n type: \"rule\",\n text: `When user ${whenDo[1].toLowerCase()}s \"${trigger}\", ${action}.`,\n confidence: 0.5,\n original: segment,\n });\n continue;\n }\n\n // Negation + replacement: \"don't use X, use Y\"\n const negMatch = segment.match(NEGATION_REPLACEMENT);\n if (negMatch) {\n matches.push({\n type: \"rule\",\n text: `Do not use ${negMatch[1].trim()}. Use ${negMatch[2].trim()} instead.`,\n confidence: 0.45,\n original: segment,\n });\n continue;\n }\n\n // Review feedback: \"review said to do X\" (check before explicit rule to avoid dupes)\n const reviewMatch = segment.match(REVIEW_FEEDBACK);\n if (reviewMatch) {\n matches.push({\n type: \"review_pattern\",\n text: reviewMatch[1].trim(),\n confidence: 0.55, // stronger — review feedback\n });\n continue;\n }\n\n // Explicit rule: \"always do X\" / \"never do Y\"\n const ruleMatch = segment.match(EXPLICIT_RULE);\n if (ruleMatch) {\n matches.push({\n type: \"rule\",\n text: `${ruleMatch[1]} ${ruleMatch[2].trim()}`,\n confidence: 0.5,\n });\n continue;\n }\n\n // Preference: \"we prefer X over Y\"\n const decisionMatch = segment.match(SOFT_DECISION);\n if (decisionMatch && isDurableDecision(segment, decisionMatch[1], decisionMatch[2])) {\n const decision = decisionMatch[2]\n ? `Prefer ${decisionMatch[1].trim()} over ${decisionMatch[2].trim()}`\n : `Use ${stripTrailingPunctuation(decisionMatch[1])}`;\n matches.push({\n type: \"decision\",\n text: ensureSentence(decision),\n confidence: 0.38,\n });\n continue;\n }\n\n const prefMatch = segment.match(SOFT_PREFERENCE);\n if (prefMatch && isDurableDecision(segment, prefMatch[1], prefMatch[2])) {\n const pref = prefMatch[2]\n ? `Prefer ${prefMatch[1].trim()} over ${prefMatch[2].trim()}`\n : `Prefer ${stripTrailingPunctuation(prefMatch[1])}`;\n matches.push({\n type: \"decision\",\n text: ensureSentence(pref),\n confidence: 0.36,\n });\n continue;\n }\n\n const configMatch = segment.match(CONFIG_BACKED_DECISION);\n if (configMatch) {\n matches.push({\n type: \"decision\",\n text: ensureSentence(`Follow configured repo convention: ${stripTrailingPunctuation(configMatch[1])}`),\n confidence: 0.42,\n });\n }\n }\n\n return matches;\n}\n\n// --- Process correction into memory ---\n\nexport interface CorrectionContext {\n sessionId: string;\n repo?: string;\n path?: string;\n agent?: string;\n prev_assistant_turn?: string;\n recent_tool_calls?: readonly RecentToolCall[];\n}\n\nfunction stripTrailingPunctuation(text: string): string {\n return text.trim().replace(/[.?!,:;]+$/, \"\");\n}\n\nfunction ensureSentence(text: string): string {\n const cleaned = stripTrailingPunctuation(text);\n return cleaned.endsWith(\".\") ? cleaned : `${cleaned}.`;\n}\n\nconst TRANSCRIPT_MARKERS = [\n \"※ recap:\",\n \"✻\",\n \"⏺\",\n \"⎿\",\n \"❯\",\n \"Bash(\",\n \"Hook activity\",\n \"Top reused memories\",\n \"RECENT INJECTIONS\",\n \"BREAKDOWN BY TYPE\",\n \"sqlite3\",\n];\n\nconst DURABLE_DECISION_HINT =\n /\\b(repo|repository|project|default|defaults|convention(?:al|s)?|configured|config|editorconfig|prettier|eslint|tsconfig|package\\.json|ci|workflow|style|pattern|architecture|runtime|database|sqlite|pnpm|yarn|npm|uv|pytest|vitest)\\b/i;\n\nconst TRANSCRIPT_LINE_RE =\n /^(?:[⏺⎿❯✻※]|(?:Bash|Edit|Write|Read|Grep|Glob|Task|TodoWrite)\\(|\\s*(?:│|├|┌|└|─)|\\s*…|\\s*={3,})/u;\n\nfunction looksLikePastedTranscript(text: string): boolean {\n if (text.length < 1_200) return false;\n const markerCount = TRANSCRIPT_MARKERS.reduce(\n (total, marker) => total + (text.includes(marker) ? 1 : 0),\n 0,\n );\n return markerCount >= 2;\n}\n\nfunction correctionCandidateSegments(text: string): string[] {\n const lines = text.split(/\\r?\\n/);\n const singleLine = lines.length === 1;\n const segments = singleLine\n ? [text]\n : lines.map((line) => line.trim()).filter(Boolean);\n\n return segments\n .map(stripListPrefix)\n .filter((line) => line.length >= 8 && line.length <= 500)\n .filter((line) => !TRANSCRIPT_LINE_RE.test(line))\n .filter((line) => !line.startsWith(\"```\"));\n}\n\nfunction stripListPrefix(text: string): string {\n return text.replace(/^\\s*(?:[-*]|\\d+[.)])\\s+/, \"\").trim();\n}\n\nfunction isDurableDecision(segment: string, first: string, second?: string): boolean {\n const haystack = `${segment} ${first} ${second ?? \"\"}`;\n if (/\\b(?:instead of|over)\\b/i.test(haystack)) return true;\n return DURABLE_DECISION_HINT.test(haystack);\n}\n\nexport async function processCorrection(\n db: RecallDb,\n text: string,\n ctx: CorrectionContext,\n): Promise<string[]> {\n // LLM-primary path: when a provider is configured and the prompt passes\n // the cheap multi-language pre-screen, hand the raw prompt to the LLM via\n // an extract_rules_from_prompt task. The LLM extracts AND judges in one\n // call; the applier creates candidate memories from its output. The hook\n // doesn't block — it just enqueues and returns. The daemon dispatcher\n // (woken via /dispatch/wake) processes the task within seconds.\n //\n // We deliberately bypass the regex extractor here. The LLM is the judge.\n // Regex stays as a fallback for when no provider is configured.\n if (process.env.RECALL_LLM_CAPTURE_DISABLED !== \"true\" && hasAnyLlmProvider() && isPromptWorthLLM(text)) {\n const promptId = `prompt:${ctx.sessionId}:${Date.now()}:${randomUUID().slice(0, 8)}`;\n const taskId = enqueueExtractRulesFromPrompt(db, {\n prompt_id: promptId,\n raw_prompt: text,\n repo: ctx.repo ?? null,\n path: ctx.path ?? null,\n agent: ctx.agent ?? null,\n session_id: ctx.sessionId,\n prev_assistant_turn: ctx.prev_assistant_turn ?? null,\n recent_tool_calls: ctx.recent_tool_calls ?? null,\n });\n // Best-effort wake-up; missing daemon is fine, the timer-based cycle\n // will still run.\n wakeDispatcherBestEffort();\n return taskId ? [] : [];\n }\n\n // --- Fallback: regex path (used when no LLM provider configured) ---\n const corrections = detectCorrections(text);\n if (corrections.length === 0) return [];\n const profile = getRepoQualityProfile(db, ctx.repo);\n\n const ids: string[] = [];\n const captureContext = buildCaptureContext(ctx);\n\n for (const correction of corrections) {\n // Drop voice/typing fragments at capture time. Mirrors the daemon-side\n // rejectFragmentCandidates filter so trash never enters the candidate\n // queue in the first place.\n if (correction.type !== \"review_pattern\") {\n const reasons = qualityReasons(correction.text);\n if (reasons.length > 0) continue;\n }\n\n // Phase D + D.next: skip captures that closely match something the user\n // previously rejected. Lexical Jaccard is the fast pre-pass; semantic\n // cosine via embeddings catches paraphrases when a provider is configured.\n if (await isSimilarToRejectedFragmentSemantic(db, correction.text)) continue;\n\n const evidence: EvidenceEntry = correction.type === \"review_pattern\"\n ? {\n type: \"review_feedback\",\n reported_by_user: true,\n timestamp: new Date().toISOString(),\n context: text,\n }\n : {\n type: \"session_correction\",\n session: ctx.sessionId,\n timestamp: new Date().toISOString(),\n context: text,\n };\n\n const duplicate = await findDuplicateMemory(\n db,\n ctx.repo,\n correction.type,\n correction.text,\n profile.dedup_similarity_threshold,\n );\n\n if (duplicate) {\n const before = getMemory(db, duplicate.id);\n appendEvidence(db, duplicate.id, evidence);\n if (captureContext) {\n updateMemoryCaptureContext(db, duplicate.id, captureContext);\n }\n if (before && !before.evidence.some((entry) => entry.type === \"session_correction\" && entry.session === ctx.sessionId)) {\n incrementMemoryRepetition(db, duplicate.id);\n }\n const updated = getMemory(db, duplicate.id);\n\n if (\n updated &&\n updated.status !== \"active\" &&\n !isHighRiskRule(updated.text) &&\n countDistinctCorrectionSessions(updated) >= profile.repeat_sessions_required\n ) {\n promoteMemory(db, duplicate.id, \"repeat_correction\");\n const after = getMemory(db, duplicate.id);\n recordAuditWithSnapshot(\n db,\n duplicate.id,\n \"promoted\",\n \"system\",\n `repetition:${after?.repetition_count ?? updated.repetition_count}`,\n before ?? null,\n after ?? null,\n );\n }\n\n ids.push(duplicate.id);\n continue;\n }\n\n // New candidate\n const inferredScope = inferScope(\n correction.text,\n ctx.path,\n undefined,\n {\n prev_assistant_turn: ctx.prev_assistant_turn,\n recent_tool_calls: ctx.recent_tool_calls,\n original_text: text,\n },\n );\n const input: CreateMemoryInput = {\n type: correction.type,\n text: correction.text,\n scope: inferredScope.scope,\n path_scope: inferredScope.path_scope,\n repo: ctx.repo ?? null,\n source:\n correction.type === \"review_pattern\"\n ? \"user_reported_review\"\n : \"user_correction\",\n confidence: seedCandidateConfidence(\n Math.min(1, correction.confidence + inferredScope.confidence_modifier),\n profile,\n ),\n evidence: [evidence],\n capture_context: captureContext,\n };\n\n const id = createMemory(db, input);\n maybePromoteGroupCandidate(db, id);\n // Phase E1: enqueue an LLM verify pass. No-op when no provider credentials\n // are configured — the task accumulates and surfaces via SessionStart for\n // the live agent to claim, or runs from the daemon dispatcher.\n enqueueVerifyCapture(db, {\n id,\n text: input.text,\n scope: input.scope,\n path_scope: input.path_scope ?? null,\n repo: input.repo ?? null,\n capture_context: captureContext ?? null,\n });\n ids.push(id);\n }\n\n return ids;\n}\n\nfunction maybePromoteGroupCandidate(\n db: RecallDb,\n candidateId: string,\n) {\n const candidate = getMemory(db, candidateId);\n if (!candidate || candidate.status !== \"candidate\") return;\n if (isHighRiskRule(candidate.text)) return;\n\n const followedCount = queryMemories(db, {\n repo: candidate.repo ?? undefined,\n type: candidate.type,\n scope: candidate.scope,\n })\n .filter((memory) => memory.id !== candidate.id)\n .reduce((total, memory) => (\n total + getMemoryFeedback(db, memory.id).filter((entry) => entry.outcome === \"followed\").length\n ), 0);\n\n if (followedCount < 3) return;\n\n const before = candidate;\n promoteMemory(db, candidate.id, \"repeat_correction\");\n const after = getMemory(db, candidate.id);\n recordAuditWithSnapshot(\n db,\n candidate.id,\n \"promoted\",\n \"system\",\n `repetition:group_followed:${followedCount}`,\n before,\n after ?? null,\n );\n}\n\nfunction buildCaptureContext(ctx: CorrectionContext): CaptureContext | null {\n const recentToolCalls = (ctx.recent_tool_calls ?? [])\n .slice(-5)\n .map((toolCall) => ({\n name: toolCall.name,\n path: toolCall.path ?? extractContextPath(toolCall.input_summary),\n exit_code: toolCall.exit_code,\n }));\n\n const hasContext =\n Boolean(ctx.prev_assistant_turn) ||\n recentToolCalls.length > 0 ||\n Boolean(ctx.repo) ||\n Boolean(ctx.path) ||\n Boolean(ctx.agent);\n\n if (!hasContext) return null;\n\n return {\n prev_assistant_text: ctx.prev_assistant_turn,\n recent_tool_calls: recentToolCalls,\n repo: ctx.repo ?? null,\n path: ctx.path ?? null,\n agent: ctx.agent,\n };\n}\n\nfunction extractContextPath(text?: string): string | undefined {\n if (!text) return undefined;\n const match = text.match(\n /\\b((?:src|lib|app|components|utils|test|spec)\\/[\\w./-]+|[\\w./-]+\\.(?:ts|tsx|js|jsx|py|rs|go|swift|java|rb|json|toml|ya?ml))\\b/,\n );\n return match?.[1];\n}\n\n// --- Report review feedback ---\n\nexport async function processReviewFeedback(\n db: RecallDb,\n feedback: string,\n ctx: CorrectionContext & { reviewer?: string },\n): Promise<string[]> {\n const profile = getRepoQualityProfile(db, ctx.repo);\n const evidence: EvidenceEntry = {\n type: \"review_feedback\",\n reported_by_user: true,\n reviewer: ctx.reviewer,\n timestamp: new Date().toISOString(),\n context: feedback,\n };\n\n // Try to detect structured corrections from the feedback\n const corrections = detectCorrections(feedback);\n\n if (corrections.length > 0) {\n const ids: string[] = [];\n for (const correction of corrections) {\n const duplicate = await findDuplicateMemory(\n db,\n ctx.repo,\n correction.type,\n correction.text,\n profile.dedup_similarity_threshold,\n );\n\n if (duplicate) {\n appendEvidence(db, duplicate.id, evidence);\n const updated = getMemory(db, duplicate.id);\n if (\n updated &&\n updated.status !== \"active\" &&\n countDistinctCorrectionSessions(updated) >= Math.max(1, profile.repeat_sessions_required - 1)\n ) {\n promoteMemory(db, duplicate.id, \"review_feedback\");\n }\n ids.push(duplicate.id);\n continue;\n }\n\n const id = createMemory(db, {\n type: correction.type,\n text: correction.text,\n scope: ctx.path ? \"path\" : \"repo\",\n path_scope: ctx.path ?? null,\n repo: ctx.repo ?? null,\n source: \"user_reported_review\",\n confidence: seedCandidateConfidence(correction.confidence + 0.1, profile),\n evidence: [evidence],\n });\n ids.push(id);\n }\n return ids;\n }\n\n // Unstructured — store as-is with lower confidence\n const id = createMemory(db, {\n type: \"review_pattern\",\n text: feedback,\n scope: ctx.path ? \"path\" : \"repo\",\n path_scope: ctx.path ?? null,\n repo: ctx.repo ?? null,\n source: \"user_reported_review\",\n confidence: seedCandidateConfidence(0.4, profile),\n evidence: [evidence],\n });\n\n return [id];\n}\n\n// --- Text similarity (simple word overlap) ---\n\nfunction textSimilarity(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/));\n const intersection = [...wordsA].filter((w) => wordsB.has(w));\n const union = new Set([...wordsA, ...wordsB]);\n return intersection.length / union.size; // Jaccard similarity\n}\n\n// Phase D MVP: rejection-feedback exemplar matching. Every memory the user\n// rejected becomes a \"do not capture this kind of thing\" exemplar. Before\n// creating a new candidate, lexical-Jaccard the candidate text against all\n// rejected user_corrections — skip when a similar one already exists. Cold\n// start is safe (empty exemplar pool → no blocks). Semantic-paraphrase\n// matching via embeddings is deferred until rejected memories carry\n// embeddings of their own.\nconst REJECTED_EXEMPLAR_THRESHOLD = 0.7;\nconst REJECTED_EXEMPLAR_SEMANTIC_THRESHOLD = 0.85;\n\nexport function isSimilarToRejectedFragment(\n db: RecallDb,\n text: string,\n threshold = REJECTED_EXEMPLAR_THRESHOLD,\n): boolean {\n const rejected = queryMemories(db, { status: \"rejected\" })\n .filter((m) => m.source === \"user_correction\" || m.source === \"user_reported_review\");\n for (const exemplar of rejected) {\n if (textSimilarity(text, exemplar.text) >= threshold) return true;\n }\n return false;\n}\n\n// Phase D.next: semantic-paraphrase check. Async because it generates an\n// embedding for the candidate. Lexical Jaccard is the cheap pre-pass; if it\n// already matched, skip the embedding cost. When no embedding provider is\n// configured, returns false (no-op fallback to lexical-only).\nexport async function isSimilarToRejectedFragmentSemantic(\n db: RecallDb,\n text: string,\n options: { lexicalThreshold?: number; semanticThreshold?: number } = {},\n): Promise<boolean> {\n const lexicalT = options.lexicalThreshold ?? REJECTED_EXEMPLAR_THRESHOLD;\n const semanticT = options.semanticThreshold ?? REJECTED_EXEMPLAR_SEMANTIC_THRESHOLD;\n\n if (isSimilarToRejectedFragment(db, text, lexicalT)) return true;\n\n const config = loadEmbeddingConfigFromEnv();\n if (!config) return false;\n\n const match = await findSimilarRejectedExemplar(db, text, config, semanticT);\n return match != null;\n}\n\nasync function findDuplicateMemory(\n db: RecallDb,\n repo: string | undefined,\n type: MemoryType,\n text: string,\n threshold: number,\n): Promise<MemoryItem | undefined> {\n if (!repo) return undefined;\n\n const existing = queryMemories(db, { repo })\n .filter((m) => m.status !== \"rejected\" && m.type === type);\n\n let best: MemoryItem | undefined;\n let bestScore = 0;\n\n for (const memory of existing) {\n const score = textSimilarity(memory.text, text);\n if (score >= threshold && score > bestScore) {\n best = memory;\n bestScore = score;\n }\n }\n\n if (best) return best;\n\n const config = loadEmbeddingConfigFromEnv();\n if (!config) return undefined;\n\n const semantic = await findSemanticDuplicates(\n db,\n text,\n config,\n threshold,\n { repo, type, limit: 1 },\n );\n\n return semantic[0] ? getMemory(db, semantic[0].id) : undefined;\n}\n","/**\n * Scope inference improvements — better detection of whether a correction\n * applies to a file, directory, repo, or team scope.\n *\n * Signals used:\n * - file extension / type of the context file\n * - directory depth and structure\n * - language/framework indicators in the correction text\n * - explicit scope markers (\"in this file\", \"for this repo\", \"for all projects\")\n * - git ownership patterns\n */\n\nimport { execSync } from \"node:child_process\";\nimport { dirname, extname, basename } from \"node:path\";\nimport type { MemoryScope } from \"../types.js\";\nimport type { RecentToolCall } from \"../agents/types.js\";\n\nexport interface ScopeInference {\n scope: MemoryScope;\n path_scope: string | null;\n confidence_modifier: number;\n reason: string;\n}\n\nexport interface ScopeContext {\n prev_assistant_turn?: string;\n recent_tool_calls?: readonly RecentToolCall[];\n /** Raw user text before correction-shape rewriting, used so scope markers\n * like \"for me always\" survive the EXPLICIT_RULE prefix strip. */\n original_text?: string;\n}\n\n// --- Explicit scope markers ---\n\nconst SCOPE_MARKERS: Array<{\n pattern: RegExp;\n scope: MemoryScope;\n reason: string;\n}> = [\n {\n pattern: /\\b(in this file|this file only|just this file)\\b/i,\n scope: \"path\",\n reason: \"explicit file scope marker\",\n },\n {\n pattern: /\\b(in this directory|in this folder|this dir)\\b/i,\n scope: \"path\",\n reason: \"explicit directory scope marker\",\n },\n {\n pattern: /\\b(in this repo|for this repo|repo-wide|across the repo|this project)\\b/i,\n scope: \"repo\",\n reason: \"explicit repo scope marker\",\n },\n {\n pattern: /\\b(team-wide|company-wide|org-wide|for the team|for the org|across the team)\\b/i,\n scope: \"team\",\n reason: \"explicit team/org scope marker\",\n },\n {\n pattern: /\\b(for me always|always for me|agent-wide|regardless of project|across all my repos|in all my work|for all (?:my )?projects|everywhere|all repos)\\b/i,\n scope: \"global\",\n reason: \"explicit global/cross-repo scope marker\",\n },\n {\n pattern: /\\b(just for now|this time|for this task|temporarily)\\b/i,\n scope: \"session\",\n reason: \"explicit session scope marker\",\n },\n];\n\n// --- Language/framework indicators that suggest repo scope ---\n\nconst FRAMEWORK_INDICATORS: RegExp[] = [\n /\\b(typescript|javascript|python|rust|go|java|swift|ruby)\\b/i,\n /\\b(react|vue|angular|svelte|next\\.?js|express|fastify|django|flask|rails)\\b/i,\n /\\b(eslint|prettier|biome|ruff|clippy|rubocop)\\b/i,\n /\\b(jest|vitest|pytest|cargo test|go test)\\b/i,\n /\\b(npm|yarn|pnpm|bun|pip|uv|poetry|cargo|go mod)\\b/i,\n];\n\n// --- File type → likely scope ---\n\nconst FILE_TYPE_SCOPES: Record<string, MemoryScope> = {\n // Config files → repo scope\n \".json\": \"repo\",\n \".yaml\": \"repo\",\n \".yml\": \"repo\",\n \".toml\": \"repo\",\n \".ini\": \"repo\",\n // Source files → path scope\n \".ts\": \"path\",\n \".tsx\": \"path\",\n \".js\": \"path\",\n \".jsx\": \"path\",\n \".py\": \"path\",\n \".rs\": \"path\",\n \".go\": \"path\",\n \".swift\": \"path\",\n \".java\": \"path\",\n \".rb\": \"path\",\n // Test files → path scope\n \".test.ts\": \"path\",\n \".spec.ts\": \"path\",\n \".test.js\": \"path\",\n \".spec.js\": \"path\",\n};\n\n// --- Main inference function ---\n\nexport function inferScope(\n correctionText: string,\n contextPath?: string,\n repoPath?: string,\n context: ScopeContext = {},\n): ScopeInference {\n // 1. Check explicit scope markers (highest priority). Run against the raw\n // user text first so prefix markers stripped during correction rewriting\n // (e.g. \"for me always X\" → \"always X\") still inform scope.\n const markerHaystack = `${context.original_text ?? \"\"} ${correctionText}`;\n for (const marker of SCOPE_MARKERS) {\n if (marker.pattern.test(markerHaystack)) {\n return {\n scope: marker.scope,\n path_scope: marker.scope === \"path\" && contextPath\n ? inferPathScope(contextPath)\n : null,\n confidence_modifier: 0.1, // boost for explicit markers\n reason: marker.reason,\n };\n }\n }\n\n // 2. Check if correction mentions framework/language → repo scope\n for (const indicator of FRAMEWORK_INDICATORS) {\n if (indicator.test(correctionText)) {\n return {\n scope: \"repo\",\n path_scope: null,\n confidence_modifier: 0.05,\n reason: \"language/framework reference implies repo scope\",\n };\n }\n }\n\n // 3. If we have a context path, infer from file type\n if (contextPath) {\n const ext = extname(contextPath);\n const base = basename(contextPath);\n\n // Test files → narrow path scope\n if (\n base.includes(\".test.\") ||\n base.includes(\".spec.\") ||\n contextPath.includes(\"__tests__\") ||\n contextPath.includes(\"/test/\")\n ) {\n return {\n scope: \"path\",\n path_scope: inferPathScope(contextPath),\n confidence_modifier: 0,\n reason: \"test file context → path scope\",\n };\n }\n\n // Config files → repo scope\n if (\n FILE_TYPE_SCOPES[ext] === \"repo\" ||\n base === \"package.json\" ||\n base === \"tsconfig.json\" ||\n base === \"Makefile\"\n ) {\n return {\n scope: \"repo\",\n path_scope: null,\n confidence_modifier: 0.05,\n reason: \"config file context → repo scope\",\n };\n }\n\n // Source files → path scope (directory-level)\n if (FILE_TYPE_SCOPES[ext] === \"path\") {\n return {\n scope: \"path\",\n path_scope: inferPathScope(contextPath),\n confidence_modifier: 0,\n reason: \"source file context → directory scope\",\n };\n }\n }\n\n const toolScope = inferFromRecentTools(context.recent_tool_calls);\n if (toolScope) {\n return toolScope;\n }\n\n const assistantScope = inferFromAssistantTurn(context.prev_assistant_turn);\n if (assistantScope) {\n return assistantScope;\n }\n\n // 4. Analyze correction text for specificity\n if (hasSpecificFileReference(correctionText)) {\n return {\n scope: \"path\",\n path_scope: extractPathFromText(correctionText),\n confidence_modifier: 0,\n reason: \"specific file/path reference in correction\",\n };\n }\n\n // 5. Check git ownership for context (optional, slower)\n if (contextPath && repoPath) {\n const ownerScope = inferFromGitOwnership(contextPath, repoPath);\n if (ownerScope) return ownerScope;\n }\n\n // Default: repo scope (most common for corrections)\n return {\n scope: \"repo\",\n path_scope: null,\n confidence_modifier: 0,\n reason: \"default: no specific scope signals detected\",\n };\n}\n\n// --- Helpers ---\n\nfunction inferPathScope(filePath: string): string {\n // Use parent directory with glob\n const dir = dirname(filePath);\n return `${dir}/**`;\n}\n\nfunction hasSpecificFileReference(text: string): boolean {\n return /\\b[\\w-]+\\.(ts|js|py|rs|go|swift|java|rb|tsx|jsx|vue|svelte)\\b/.test(text) ||\n /\\b(src|lib|app|components|utils|test|spec)\\//.test(text);\n}\n\nfunction extractPathFromText(text: string): string | null {\n // Try to extract a file path\n const pathMatch = text.match(\n /\\b((?:src|lib|app|components|utils|test|spec)\\/[\\w/.-]+)/,\n );\n if (pathMatch) return `${pathMatch[1]}**`;\n\n // Try to extract just a directory reference\n const dirMatch = text.match(\n /\\b((?:src|lib|app|components|utils|test|spec)\\/[\\w/-]*)/,\n );\n if (dirMatch) return `${dirMatch[1]}/**`;\n\n return null;\n}\n\n// Tools whose `path` field is a real source/config file the user is editing.\n// Bash paths are unreliable — they can be CLI binaries (e.g. /Applications/...\n// /node), absolute system paths, or arguments that just happen to look path-ish.\nconst SOURCE_AWARE_TOOLS = new Set([\n \"Read\", \"Edit\", \"Write\", \"MultiEdit\", \"NotebookEdit\", \"NotebookRead\", \"Grep\", \"Glob\",\n]);\n\nfunction isPathInsideRepo(path: string): boolean {\n if (path.startsWith(\"/\")) return false;\n if (/^(?:Applications|app|usr|opt|System|Library|private|var|tmp)\\//.test(path)) return false;\n return true;\n}\n\nfunction inferFromRecentTools(\n toolCalls?: readonly RecentToolCall[],\n): ScopeInference | null {\n if (!toolCalls || toolCalls.length === 0) return null;\n\n for (const toolCall of toolCalls) {\n if (toolCall.path && SOURCE_AWARE_TOOLS.has(toolCall.name) && isPathInsideRepo(toolCall.path)) {\n return {\n scope: \"path\",\n path_scope: inferPathScope(toolCall.path),\n confidence_modifier: 0.05,\n reason: `recent tool path context: ${toolCall.path}`,\n };\n }\n\n const inferredPath = extractPathFromText(toolCall.input_summary ?? \"\");\n if (inferredPath) {\n return {\n scope: \"path\",\n path_scope: inferredPath,\n confidence_modifier: 0.05,\n reason: \"recent tool summary implies path scope\",\n };\n }\n\n const summary = toolCall.input_summary ?? \"\";\n if (/\\b(pytest|vitest|jest|cargo test|go test)\\b/i.test(summary)) {\n return {\n scope: \"repo\",\n path_scope: null,\n confidence_modifier: 0.04,\n reason: \"recent test/tool pattern implies repo scope\",\n };\n }\n }\n\n return null;\n}\n\nfunction inferFromAssistantTurn(\n assistantTurn?: string,\n): ScopeInference | null {\n if (!assistantTurn) return null;\n\n const inferredPath = extractPathFromText(assistantTurn);\n if (inferredPath) {\n return {\n scope: \"path\",\n path_scope: inferredPath,\n confidence_modifier: 0.05,\n reason: \"previous assistant turn referenced a path\",\n };\n }\n\n for (const indicator of FRAMEWORK_INDICATORS) {\n if (indicator.test(assistantTurn)) {\n return {\n scope: \"repo\",\n path_scope: null,\n confidence_modifier: 0.03,\n reason: \"previous assistant turn referenced repo-level tooling/framework\",\n };\n }\n }\n\n return null;\n}\n\nfunction inferFromGitOwnership(\n filePath: string,\n repoPath: string,\n): ScopeInference | null {\n try {\n // Check CODEOWNERS\n const codeowners = execSync(\n `cat .github/CODEOWNERS 2>/dev/null || cat CODEOWNERS 2>/dev/null || echo \"\"`,\n { cwd: repoPath, encoding: \"utf-8\" },\n ).trim();\n\n if (codeowners) {\n // If the file matches a CODEOWNERS pattern, scope to that team\n const dir = dirname(filePath);\n for (const line of codeowners.split(\"\\n\")) {\n if (line.startsWith(\"#\") || !line.trim()) continue;\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 2 && filePath.includes(parts[0].replace(\"*\", \"\"))) {\n return {\n scope: \"path\",\n path_scope: `${parts[0]}`,\n confidence_modifier: 0.05,\n reason: `CODEOWNERS match: ${parts[0]} → ${parts.slice(1).join(\", \")}`,\n };\n }\n }\n }\n } catch {\n // No CODEOWNERS or git error\n }\n\n return null;\n}\n\n/**\n * Analyze a batch of corrections to find scope patterns.\n * If similar corrections keep appearing for the same directory,\n * suggest promoting to directory scope.\n */\nexport function analyzeScopePatterns(\n corrections: Array<{ text: string; path?: string; scope: MemoryScope }>,\n): Array<{ suggested_scope: MemoryScope; path_scope: string | null; reason: string }> {\n const pathCounts = new Map<string, number>();\n\n for (const c of corrections) {\n if (c.path) {\n const dir = dirname(c.path);\n pathCounts.set(dir, (pathCounts.get(dir) ?? 0) + 1);\n }\n }\n\n const suggestions: Array<{\n suggested_scope: MemoryScope;\n path_scope: string | null;\n reason: string;\n }> = [];\n\n for (const [dir, count] of pathCounts) {\n if (count >= 3) {\n suggestions.push({\n suggested_scope: \"path\",\n path_scope: `${dir}/**`,\n reason: `${count} corrections in ${dir} — consider directory scope`,\n });\n }\n }\n\n // If most corrections are repo-scoped, suggest team scope\n const repoScoped = corrections.filter((c) => c.scope === \"repo\").length;\n if (repoScoped >= 5 && repoScoped / corrections.length > 0.8) {\n suggestions.push({\n suggested_scope: \"team\",\n path_scope: null,\n reason: `${repoScoped}/${corrections.length} corrections are repo-scoped — consider team scope`,\n });\n }\n\n return suggestions;\n}\n","import { and, eq, gte, inArray, sql } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RecallDb } from \"../db/client.js\";\nimport {\n feedbackEvents,\n maintenanceCleanupLog,\n memories,\n memoryInjections,\n} from \"../db/schema.js\";\nimport { getMemory, queryMemories } from \"../models/memory.js\";\nimport { memoryDedupeKey } from \"../models/dedupe.js\";\nimport { recordAuditWithSnapshot } from \"../audit/trail.js\";\nimport { checkContradiction } from \"../contradictions/detector.js\";\nimport { isDestructiveRisky } from \"../capture/correction.js\";\n\nconst SUPPRESS_INJECTION_FLOOR = 50;\nconst GLOBALIZE_REPO_FLOOR = 3;\n\n// Phase-1 deterministic, LLM-free cleanup. Three actions:\n// * dedupeExact — merge memories with identical normalized text within scope\n// * rejectFragmentCandidates — reject low-quality voice/typing-fragment captures\n// * promoteRepeatCorrections — auto-promote candidates with strong rule-shape text\n//\n// All actions write to maintenance_cleanup_log so they can be reviewed and\n// reverted later. Dry-run produces the same plan without mutating the DB.\n\nexport interface CleanupOptions {\n dryRun: boolean;\n /** When set, only this action runs. */\n only?: CleanupActionKind;\n}\n\nexport type CleanupActionKind =\n | \"dedupe_exact_merge\"\n | \"reject_fragment_candidate\"\n | \"promote_repeat_correction\"\n | \"suppress_unproductive_command\"\n | \"globalize_cross_repo\";\n\nexport interface DedupeExactPlan {\n kind: \"dedupe_exact_merge\";\n winner_id: string;\n winner_text: string;\n loser_ids: string[];\n scope_key: string;\n total_injection_count: number;\n}\n\nexport interface RejectFragmentPlan {\n kind: \"reject_fragment_candidate\";\n memory_id: string;\n text: string;\n reasons: string[];\n}\n\nexport interface PromoteRepeatPlan {\n kind: \"promote_repeat_correction\";\n memory_id: string;\n text: string;\n matched_pattern: \"repetition\" | \"rule_shape\";\n}\n\nexport interface SuppressCommandPlan {\n kind: \"suppress_unproductive_command\";\n memory_id: string;\n text: string;\n injection_count: number;\n followed_count: number;\n}\n\nexport interface GlobalizeCrossRepoPlan {\n kind: \"globalize_cross_repo\";\n winner_id: string;\n winner_text: string;\n loser_ids: string[];\n repos: string[];\n total_injection_count: number;\n}\n\nexport type CleanupPlanItem =\n | DedupeExactPlan\n | RejectFragmentPlan\n | PromoteRepeatPlan\n | SuppressCommandPlan\n | GlobalizeCrossRepoPlan;\n\nexport interface CleanupReport {\n run_id: string;\n dry_run: boolean;\n started_at: string;\n finished_at: string;\n counts: {\n dedupe_clusters: number;\n dedupe_losers: number;\n fragment_rejections: number;\n repeat_promotions: number;\n command_suppressions: number;\n globalizations: number;\n globalize_losers: number;\n };\n plan: CleanupPlanItem[];\n}\n\nconst DEFAULT_ACTOR = \"maintenance:cleanup\";\n\nexport function runDeterministicCleanup(\n db: RecallDb,\n opts: CleanupOptions = { dryRun: true },\n): CleanupReport {\n const runId = randomUUID();\n const startedAt = new Date().toISOString();\n const plan: CleanupPlanItem[] = [];\n\n if (!opts.only || opts.only === \"dedupe_exact_merge\") {\n plan.push(...planDedupeExact(db));\n }\n if (!opts.only || opts.only === \"reject_fragment_candidate\") {\n plan.push(...planRejectFragments(db));\n }\n if (!opts.only || opts.only === \"promote_repeat_correction\") {\n plan.push(...planPromoteRepeats(db));\n }\n if (!opts.only || opts.only === \"suppress_unproductive_command\") {\n plan.push(...planSuppressCommands(db));\n }\n if (!opts.only || opts.only === \"globalize_cross_repo\") {\n plan.push(...planGlobalizeCrossRepo(db));\n }\n\n const counts = summarize(plan);\n\n if (!opts.dryRun) {\n for (const item of plan) {\n switch (item.kind) {\n case \"dedupe_exact_merge\":\n applyDedupeExact(db, runId, item);\n break;\n case \"reject_fragment_candidate\":\n applyRejectFragment(db, runId, item);\n break;\n case \"promote_repeat_correction\":\n applyPromoteRepeat(db, runId, item);\n break;\n case \"suppress_unproductive_command\":\n applySuppressCommand(db, runId, item);\n break;\n case \"globalize_cross_repo\":\n applyGlobalizeCrossRepo(db, runId, item);\n break;\n }\n }\n }\n\n return {\n run_id: runId,\n dry_run: opts.dryRun,\n started_at: startedAt,\n finished_at: new Date().toISOString(),\n counts,\n plan,\n };\n}\n\nfunction summarize(plan: CleanupPlanItem[]): CleanupReport[\"counts\"] {\n let dedupeClusters = 0;\n let dedupeLosers = 0;\n let fragmentRejections = 0;\n let repeatPromotions = 0;\n let commandSuppressions = 0;\n let globalizations = 0;\n let globalizeLosers = 0;\n for (const p of plan) {\n if (p.kind === \"dedupe_exact_merge\") {\n dedupeClusters += 1;\n dedupeLosers += p.loser_ids.length;\n } else if (p.kind === \"reject_fragment_candidate\") {\n fragmentRejections += 1;\n } else if (p.kind === \"promote_repeat_correction\") {\n repeatPromotions += 1;\n } else if (p.kind === \"suppress_unproductive_command\") {\n commandSuppressions += 1;\n } else {\n globalizations += 1;\n globalizeLosers += p.loser_ids.length;\n }\n }\n return {\n dedupe_clusters: dedupeClusters,\n dedupe_losers: dedupeLosers,\n fragment_rejections: fragmentRejections,\n repeat_promotions: repeatPromotions,\n command_suppressions: commandSuppressions,\n globalizations,\n globalize_losers: globalizeLosers,\n };\n}\n\n// --- dedupeExact ----------------------------------------------------------\n\nfunction normalizeText(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .replace(/[\\s.;:,!?`]+$/g, \"\")\n .trim();\n}\n\nfunction scopeKey(row: { type: string; scope: string; repo: string | null; path_scope: string | null; norm: string }) {\n return [row.type, row.scope, row.repo ?? \"\", row.path_scope ?? \"\", row.norm].join(\"\u0000\");\n}\n\nexport function planDedupeExact(db: RecallDb): DedupeExactPlan[] {\n // Look at active + candidate; rejected rows stay rejected.\n const rows = db.select({\n id: memories.id,\n type: memories.type,\n text: memories.text,\n scope: memories.scope,\n repo: memories.repo,\n path_scope: memories.path_scope,\n status: memories.status,\n injection_count: memories.injection_count,\n confidence: memories.confidence,\n created_at: memories.created_at,\n })\n .from(memories)\n .where(inArray(memories.status, [\"active\", \"candidate\"]))\n .all();\n\n const groups = new Map<string, typeof rows>();\n for (const row of rows) {\n const norm = normalizeText(row.text);\n if (!norm) continue;\n const key = scopeKey({ ...row, norm });\n const list = groups.get(key) ?? [];\n list.push(row);\n groups.set(key, list);\n }\n\n const plans: DedupeExactPlan[] = [];\n for (const [key, list] of groups) {\n if (list.length < 2) continue;\n // Prefer active over candidate, then highest injection_count, then highest\n // confidence, then earliest created_at (stable choice).\n const sorted = [...list].sort((a, b) => {\n const statusRank = (s: string) => (s === \"active\" ? 0 : 1);\n const dStatus = statusRank(a.status) - statusRank(b.status);\n if (dStatus !== 0) return dStatus;\n if (a.injection_count !== b.injection_count) return b.injection_count - a.injection_count;\n if (a.confidence !== b.confidence) return b.confidence - a.confidence;\n return a.created_at.localeCompare(b.created_at);\n });\n const winner = sorted[0];\n const losers = sorted.slice(1);\n const total = list.reduce((acc, r) => acc + r.injection_count, 0);\n plans.push({\n kind: \"dedupe_exact_merge\",\n winner_id: winner.id,\n winner_text: winner.text,\n loser_ids: losers.map((l) => l.id),\n scope_key: key,\n total_injection_count: total,\n });\n }\n return plans;\n}\n\nfunction applyDedupeExact(db: RecallDb, runId: string, plan: DedupeExactPlan) {\n const winner = getMemory(db, plan.winner_id);\n if (!winner) return;\n\n const losers = plan.loser_ids\n .map((id) => getMemory(db, id))\n .filter((m): m is NonNullable<typeof m> => m != null);\n\n if (losers.length === 0) return;\n\n const sumCounts = losers.reduce(\n (acc, l) => ({\n injection: acc.injection + l.injection_count,\n override: acc.override + l.override_count,\n repetition: acc.repetition + l.repetition_count,\n }),\n { injection: 0, override: 0, repetition: 0 },\n );\n\n const now = new Date().toISOString();\n\n // Move feedback_events + memory_injections from losers to winner. The\n // memory_injections table has a (memory_id, session_id) unique constraint,\n // so we re-point only when the winner doesn't already have a row for the\n // same session.\n for (const loser of losers) {\n // Re-point feedback_events (no unique constraint).\n db.update(feedbackEvents)\n .set({ memory_id: winner.id })\n .where(eq(feedbackEvents.memory_id, loser.id))\n .run();\n\n // For memory_injections: move rows whose session has no winner row yet,\n // then drop the rest (the winner already represents that session).\n const loserInj = db.select().from(memoryInjections)\n .where(eq(memoryInjections.memory_id, loser.id))\n .all();\n for (const inj of loserInj) {\n const collision = db.select({ id: memoryInjections.id }).from(memoryInjections)\n .where(and(eq(memoryInjections.memory_id, winner.id), eq(memoryInjections.session_id, inj.session_id)))\n .get();\n if (collision) {\n db.delete(memoryInjections).where(eq(memoryInjections.id, inj.id)).run();\n } else {\n db.update(memoryInjections)\n .set({ memory_id: winner.id })\n .where(eq(memoryInjections.id, inj.id))\n .run();\n }\n }\n }\n\n // Bump winner counters with the merged sums.\n db.update(memories)\n .set({\n injection_count: winner.injection_count + sumCounts.injection,\n override_count: winner.override_count + sumCounts.override,\n repetition_count: winner.repetition_count + sumCounts.repetition,\n updated_at: now,\n })\n .where(eq(memories.id, winner.id))\n .run();\n\n // Reject losers, supersedes=winner.\n for (const loser of losers) {\n db.update(memories)\n .set({ status: \"rejected\", supersedes: winner.id, dedupe_key: null, updated_at: now })\n .where(eq(memories.id, loser.id))\n .run();\n\n const after = getMemory(db, loser.id);\n recordAuditWithSnapshot(\n db,\n loser.id,\n \"rejected\",\n DEFAULT_ACTOR,\n `dedupe_exact:merged_into:${winner.id}:run:${runId}`,\n loser,\n after ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"dedupe_exact_merge\",\n memory_id: loser.id,\n related_memory_id: winner.id,\n before_snapshot: loser as unknown as any,\n after_snapshot: after as unknown as any,\n details: { scope_key: plan.scope_key, transferred_injection_count: loser.injection_count } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n }\n}\n\n// --- rejectFragmentCandidates --------------------------------------------\n\n// Only real action verbs count. Modals (`must`, `never`, `always`, `should`,\n// `don't`, `do not`) used to live here, which meant the \"no_verb\" check could\n// never trigger on bare modal fragments like \"always be used.\" or \"must work\n// end to end doesn't bring files here\" — every rule-shaped scrap automatically\n// passed because the modal itself satisfied the check.\nconst VERB_HINTS = [\n \"use\", \"uses\", \"used\", \"run\", \"runs\", \"ran\",\n \"avoid\", \"prefer\", \"keep\", \"set\", \"add\", \"remove\", \"skip\",\n \"replace\", \"fix\", \"ensure\", \"require\", \"make\",\n \"build\", \"test\", \"deploy\", \"install\", \"import\", \"export\",\n \"commit\", \"push\", \"call\", \"wrap\", \"split\", \"merge\", \"store\",\n \"load\", \"save\", \"ignore\", \"accept\", \"reject\", \"update\", \"create\",\n \"delete\", \"rename\", \"move\", \"copy\", \"validate\", \"verify\", \"check\",\n \"follow\", \"read\", \"write\", \"open\", \"close\", \"send\", \"receive\",\n \"configure\", \"enable\", \"disable\",\n];\n\nconst BARE_MODAL_RE = /^\\s*(must|never|always|do not|don't|required|prefer|should)\\b[^\\w]*(stay|do|stop|go|reply|reply\\?)?\\s*$/i;\nconst TRAILING_QUESTION_RE = /\\?\\s*$/;\nconst DANGLING_CONNECTOR_RE = /\\b(?:and|or|but|with|without|to|from|for|of|as|because|instead|over|the|a|an|on|in|at|by)\\s*$/i;\nconst TRAILING_DOUBLE_DOT_RE = /\\.{2,}\\s*$/;\n// Trailing em/en-dash with nothing after — speech artifact (\"never sends a\n// banner —\"). The speaker started a clause and never finished it.\nconst TRAILING_DASH_RE = /[—–-]\\s*$/;\n// Question pronouns embedded after a modal turn the \"rule\" into a question\n// the speaker was asking, not a directive: \"always can you find …\",\n// \"never could you check …\".\nconst EMBEDDED_QUESTION_RE =\n /^\\s*(?:always|never|must|don't|do not|required|prefer|should)\\s+(?:can|could|would|will|do|does|did|is|are|was|were|have|has|should|may|might)\\s+(?:you|we|i|they|it|he|she)\\b/i;\n// \"always just …\", \"never now …\" etc. — voice-transcript filler word right\n// after the modal almost always means the speaker is not stating a rule.\nconst RULE_FILLER_PREFIX_RE =\n /^\\s*(?:always|never|must|don't|do not|prefer|required)\\s+(?:just|now|uh|um|so|like|maybe|kinda|sort\\s+of)\\b/i;\n// Anything past this length is almost certainly a voice ramble, not a rule.\n// Real rules in the corpus stay well under this; long ones can still be\n// re-captured as multiple smaller rules or saved via explicit confirm.\nconst MAX_RULE_LENGTH = 300;\n// Minimum useful rule length. Bumped from 14: in production we saw a\n// long tail of short fragments (\"always be used.\" 15ch, \"always can\n// you find\" 19ch) that were all incomplete thoughts. Real, durable\n// rules are almost always longer. Trailing-dash/bare-modal catches\n// catch the remaining 20-22 char garbage like \"never sends a banner —\".\nconst MIN_RULE_LENGTH = 20;\n\nexport function planRejectFragments(db: RecallDb): RejectFragmentPlan[] {\n const rows = db.select({\n id: memories.id,\n text: memories.text,\n source: memories.source,\n status: memories.status,\n })\n .from(memories)\n .where(and(eq(memories.status, \"candidate\"), eq(memories.source, \"user_correction\")))\n .all();\n\n const out: RejectFragmentPlan[] = [];\n for (const row of rows) {\n const reasons = qualityReasons(row.text);\n if (reasons.length > 0) {\n out.push({\n kind: \"reject_fragment_candidate\",\n memory_id: row.id,\n text: row.text,\n reasons,\n });\n }\n }\n return out;\n}\n\nexport function qualityReasons(rawText: string): string[] {\n const text = rawText.trim();\n const reasons: string[] = [];\n if (text.length < MIN_RULE_LENGTH) reasons.push(\"too_short\");\n if (text.length > MAX_RULE_LENGTH) reasons.push(\"too_long\");\n if (TRAILING_QUESTION_RE.test(text)) reasons.push(\"trailing_question\");\n if (BARE_MODAL_RE.test(text)) reasons.push(\"bare_modal\");\n if (TRAILING_DOUBLE_DOT_RE.test(text)) reasons.push(\"trailing_double_dot\");\n if (TRAILING_DASH_RE.test(text)) reasons.push(\"trailing_dash\");\n if (DANGLING_CONNECTOR_RE.test(text)) reasons.push(\"dangling_connector\");\n if (RULE_FILLER_PREFIX_RE.test(text)) reasons.push(\"filler_prefix\");\n if (EMBEDDED_QUESTION_RE.test(text)) reasons.push(\"embedded_question\");\n\n // Verb check: strip punctuation and look for any verb hint as a token.\n const words = text.toLowerCase().replace(/[^\\w' ]+/g, \" \").split(/\\s+/).filter(Boolean);\n const hasVerb = words.some((w) => VERB_HINTS.includes(w));\n if (!hasVerb) reasons.push(\"no_verb\");\n\n return reasons;\n}\n\nfunction applyRejectFragment(db: RecallDb, runId: string, plan: RejectFragmentPlan) {\n const before = getMemory(db, plan.memory_id);\n if (!before || before.status !== \"candidate\") return;\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({ status: \"rejected\", dedupe_key: null, updated_at: now })\n .where(eq(memories.id, plan.memory_id))\n .run();\n\n const after = getMemory(db, plan.memory_id);\n recordAuditWithSnapshot(\n db,\n plan.memory_id,\n \"rejected\",\n DEFAULT_ACTOR,\n `cleanup_fragment:${plan.reasons.join(\",\")}:run:${runId}`,\n before,\n after ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"reject_fragment_candidate\",\n memory_id: plan.memory_id,\n related_memory_id: null,\n before_snapshot: before as unknown as any,\n after_snapshot: after as unknown as any,\n details: { reasons: plan.reasons } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n}\n\n// --- promoteRepeatCorrections --------------------------------------------\n\n// Promotion gate: candidate user_corrections only auto-promote on repetition\n// signal (≥2 distinct sessions producing the same correction). Shape alone\n// (e.g. starting with \"always\") is NOT enough — that produced false-positive\n// active rules from voice-transcript fragments. Promote-by-shape is gone.\n// Manual `recall confirm` and `maybePromoteGroupCandidate` (followed-feedback\n// from sibling memories) remain the other promotion paths.\nexport function planPromoteRepeats(db: RecallDb): PromoteRepeatPlan[] {\n const rows = db.select({\n id: memories.id,\n text: memories.text,\n repetition_count: memories.repetition_count,\n source: memories.source,\n status: memories.status,\n })\n .from(memories)\n .where(and(eq(memories.status, \"candidate\"), eq(memories.source, \"user_correction\")))\n .all();\n\n const out: PromoteRepeatPlan[] = [];\n for (const row of rows) {\n const text = row.text.trim();\n // Skip rows that the fragment filter would also match — let it reject them\n // first so we don't flip-flop.\n if (qualityReasons(text).length > 0) continue;\n // Phase F: destructive verbs paired with high-risk targets never\n // auto-promote. They require explicit `recall confirm`.\n if (isDestructiveRisky(text)) continue;\n\n if (row.repetition_count >= 2) {\n out.push({ kind: \"promote_repeat_correction\", memory_id: row.id, text, matched_pattern: \"repetition\" });\n }\n }\n return out;\n}\n\nfunction applyPromoteRepeat(db: RecallDb, runId: string, plan: PromoteRepeatPlan) {\n const before = getMemory(db, plan.memory_id);\n if (!before || before.status !== \"candidate\") return;\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({ status: \"active\", confidence: Math.max(before.confidence, 0.7), updated_at: now, last_validated_at: now })\n .where(eq(memories.id, plan.memory_id))\n .run();\n\n const after = getMemory(db, plan.memory_id);\n recordAuditWithSnapshot(\n db,\n plan.memory_id,\n \"promoted\",\n DEFAULT_ACTOR,\n `cleanup_promote:${plan.matched_pattern}:run:${runId}`,\n before,\n after ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"promote_repeat_correction\",\n memory_id: plan.memory_id,\n related_memory_id: null,\n before_snapshot: before as unknown as any,\n after_snapshot: after as unknown as any,\n details: { matched_pattern: plan.matched_pattern } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n}\n\n// --- suppressUnproductiveCommands ----------------------------------------\n\n/**\n * Active command-type memories that have been auto-injected at least\n * SUPPRESS_INJECTION_FLOOR times with zero `followed` outcomes are demoted from\n * the SessionStart auto-inject pool. They remain queryable via MCP. The agent\n * will rediscover the same shell hint from package.json / Makefile, so we\n * stop spending tokens to repeat it every session.\n */\nexport function planSuppressCommands(db: RecallDb): SuppressCommandPlan[] {\n const candidates = db.select({\n id: memories.id,\n text: memories.text,\n injection_count: memories.injection_count,\n })\n .from(memories)\n .where(and(\n eq(memories.status, \"active\"),\n eq(memories.type, \"command\"),\n eq(memories.auto_inject, true),\n gte(memories.injection_count, SUPPRESS_INJECTION_FLOOR),\n ))\n .all();\n\n const out: SuppressCommandPlan[] = [];\n for (const row of candidates) {\n const followedRow = db.select({ n: sql<number>`count(*)` })\n .from(feedbackEvents)\n .where(and(\n eq(feedbackEvents.memory_id, row.id),\n eq(feedbackEvents.outcome, \"followed\"),\n ))\n .get();\n const followed = followedRow?.n ?? 0;\n if (followed > 0) continue;\n out.push({\n kind: \"suppress_unproductive_command\",\n memory_id: row.id,\n text: row.text,\n injection_count: row.injection_count,\n followed_count: followed,\n });\n }\n return out;\n}\n\nfunction applySuppressCommand(db: RecallDb, runId: string, plan: SuppressCommandPlan) {\n const before = getMemory(db, plan.memory_id);\n if (!before || !before.auto_inject) return;\n\n const now = new Date().toISOString();\n db.update(memories)\n .set({ auto_inject: false, updated_at: now })\n .where(eq(memories.id, plan.memory_id))\n .run();\n\n const after = getMemory(db, plan.memory_id);\n recordAuditWithSnapshot(\n db,\n plan.memory_id,\n \"demoted\",\n DEFAULT_ACTOR,\n `cleanup_suppress_command:inj=${plan.injection_count},followed=0:run:${runId}`,\n before,\n after ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"suppress_unproductive_command\",\n memory_id: plan.memory_id,\n related_memory_id: null,\n before_snapshot: before as unknown as any,\n after_snapshot: after as unknown as any,\n details: {\n injection_count: plan.injection_count,\n followed_count: plan.followed_count,\n } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n}\n\n// --- globalizeCrossRepo --------------------------------------------------\n\n/**\n * When the same normalized text exists as an active rule/command across\n * GLOBALIZE_REPO_FLOOR or more distinct repos, promote one row to\n * scope='global' (repo=null) and reject the rest. Reduces duplicate\n * injections of pan-repo guidance like \"Use uv for Python\".\n */\nexport function planGlobalizeCrossRepo(db: RecallDb): GlobalizeCrossRepoPlan[] {\n const rows = db.select({\n id: memories.id,\n type: memories.type,\n text: memories.text,\n scope: memories.scope,\n repo: memories.repo,\n injection_count: memories.injection_count,\n confidence: memories.confidence,\n created_at: memories.created_at,\n })\n .from(memories)\n .where(and(eq(memories.status, \"active\"), inArray(memories.type, [\"command\", \"rule\"])))\n .all();\n\n const groups = new Map<string, typeof rows>();\n for (const row of rows) {\n if (row.scope === \"global\") continue;\n if (!row.repo) continue;\n const norm = normalizeText(row.text);\n if (!norm) continue;\n const key = `${row.type}::${norm}`;\n const list = groups.get(key) ?? [];\n list.push(row);\n groups.set(key, list);\n }\n\n // Pre-load all active rule/command memories once for the cross-repo\n // contradiction check below.\n const allActive = queryMemories(db, { status: \"active\" })\n .filter((m) => m.type === \"rule\" || m.type === \"command\");\n\n const plans: GlobalizeCrossRepoPlan[] = [];\n for (const list of groups.values()) {\n const repos = new Set(list.map((r) => r.repo!));\n if (repos.size < GLOBALIZE_REPO_FLOOR) continue;\n\n const sorted = [...list].sort((a, b) => {\n if (a.injection_count !== b.injection_count) return b.injection_count - a.injection_count;\n if (a.confidence !== b.confidence) return b.confidence - a.confidence;\n return a.created_at.localeCompare(b.created_at);\n });\n const winner = sorted[0];\n\n // Don't globalize when another repo holds an active memory that would\n // contradict this winner. A cluster of \"Use pnpm\" rows shouldn't promote\n // to global if a sibling repo has \"Use bun\" — it just creates conflict\n // every session in that repo.\n const winnerMemory = getMemory(db, winner.id);\n if (!winnerMemory) continue;\n const clusterIds = new Set(list.map((r) => r.id));\n const conflict = allActive.find((other) => {\n if (clusterIds.has(other.id)) return false;\n if (!other.repo || repos.has(other.repo)) return false;\n // Pretend the candidate is already global so scopesOverlap will say yes.\n const winnerAsGlobal: typeof winnerMemory = { ...winnerMemory, scope: \"global\" };\n return checkContradiction(winnerAsGlobal, other) != null;\n });\n if (conflict) continue;\n\n const losers = sorted.slice(1);\n const total = list.reduce((acc, r) => acc + r.injection_count, 0);\n\n plans.push({\n kind: \"globalize_cross_repo\",\n winner_id: winner.id,\n winner_text: winner.text,\n loser_ids: losers.map((l) => l.id),\n repos: [...repos],\n total_injection_count: total,\n });\n }\n return plans;\n}\n\nfunction applyGlobalizeCrossRepo(db: RecallDb, runId: string, plan: GlobalizeCrossRepoPlan) {\n const winner = getMemory(db, plan.winner_id);\n if (!winner) return;\n\n const now = new Date().toISOString();\n\n // Promote winner to scope='global', repo=null. Re-point feedback rows from\n // losers since they all represent the same advice.\n const globalDedupeKey = memoryDedupeKey({ ...winner, scope: \"global\", repo: null });\n const globalDedupeCollision = db.select({ id: memories.id })\n .from(memories)\n .where(eq(memories.dedupe_key, globalDedupeKey))\n .get();\n db.update(memories)\n .set({\n scope: \"global\" as any,\n repo: null,\n dedupe_key: globalDedupeCollision && globalDedupeCollision.id !== winner.id\n ? null\n : globalDedupeKey,\n updated_at: now,\n })\n .where(eq(memories.id, winner.id))\n .run();\n\n const after = getMemory(db, winner.id);\n recordAuditWithSnapshot(\n db,\n winner.id,\n \"edited\",\n DEFAULT_ACTOR,\n `cleanup_globalize:winner:run:${runId}`,\n winner,\n after ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"globalize_cross_repo\",\n memory_id: winner.id,\n related_memory_id: null,\n before_snapshot: winner as unknown as any,\n after_snapshot: after as unknown as any,\n details: { role: \"winner\", repos: plan.repos } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n\n for (const loserId of plan.loser_ids) {\n const loser = getMemory(db, loserId);\n if (!loser || loser.status === \"rejected\") continue;\n\n db.update(memories)\n .set({ status: \"rejected\", supersedes: winner.id, dedupe_key: null, updated_at: now })\n .where(eq(memories.id, loserId))\n .run();\n\n const afterLoser = getMemory(db, loserId);\n recordAuditWithSnapshot(\n db,\n loserId,\n \"rejected\",\n DEFAULT_ACTOR,\n `cleanup_globalize:loser:winner=${winner.id}:run:${runId}`,\n loser,\n afterLoser ?? null,\n );\n\n db.insert(maintenanceCleanupLog).values({\n id: randomUUID(),\n run_id: runId,\n action: \"globalize_cross_repo\",\n memory_id: loserId,\n related_memory_id: winner.id,\n before_snapshot: loser as unknown as any,\n after_snapshot: afterLoser as unknown as any,\n details: { role: \"loser\", repo: loser.repo } as any,\n reverted: false,\n reverted_at: null,\n created_at: now,\n }).run();\n }\n}\n\n// --- Revert -------------------------------------------------------------\n\nexport interface RevertReport {\n run_id: string;\n reverted: number;\n skipped: number;\n reasons: Record<string, number>;\n}\n\ninterface MemorySnapshot {\n id?: string;\n status?: string;\n text?: string;\n scope?: string;\n path_scope?: string | null;\n repo?: string | null;\n confidence?: number;\n injection_count?: number;\n override_count?: number;\n repetition_count?: number;\n supersedes?: string | null;\n auto_inject?: boolean;\n}\n\n/**\n * Revert a cleanup run by restoring `before_snapshot` for every log row in the\n * run that hasn't already been reverted. Memory injections / feedback events\n * re-pointed during dedupe stay where they are — they're cheap to re-collect\n * and reverting them risks unique-key collisions with subsequent traffic.\n */\nexport function revertCleanupRun(db: RecallDb, runId: string): RevertReport {\n const rows = db.select().from(maintenanceCleanupLog)\n .where(eq(maintenanceCleanupLog.run_id, runId))\n .all();\n\n if (rows.length === 0) {\n return { run_id: runId, reverted: 0, skipped: 0, reasons: { not_found: 1 } };\n }\n\n const reasons: Record<string, number> = {};\n let reverted = 0;\n let skipped = 0;\n const now = new Date().toISOString();\n\n for (const row of rows) {\n if (row.reverted) {\n skipped += 1;\n reasons.already_reverted = (reasons.already_reverted ?? 0) + 1;\n continue;\n }\n\n const before = row.before_snapshot as unknown as MemorySnapshot | null;\n if (!before || !before.status) {\n skipped += 1;\n reasons.no_snapshot = (reasons.no_snapshot ?? 0) + 1;\n continue;\n }\n\n const current = getMemory(db, row.memory_id);\n if (!current) {\n skipped += 1;\n reasons.memory_missing = (reasons.memory_missing ?? 0) + 1;\n continue;\n }\n\n db.update(memories)\n .set({\n status: before.status as any,\n text: before.text ?? current.text,\n scope: (before.scope as any) ?? current.scope,\n path_scope: before.path_scope ?? current.path_scope,\n repo: before.repo !== undefined ? before.repo : current.repo,\n confidence: before.confidence ?? current.confidence,\n injection_count: before.injection_count ?? current.injection_count,\n override_count: before.override_count ?? current.override_count,\n repetition_count: before.repetition_count ?? current.repetition_count,\n supersedes: before.supersedes ?? null,\n auto_inject: before.auto_inject ?? current.auto_inject,\n updated_at: now,\n })\n .where(eq(memories.id, row.memory_id))\n .run();\n\n const after = getMemory(db, row.memory_id);\n recordAuditWithSnapshot(\n db,\n row.memory_id,\n \"rolled_back\",\n DEFAULT_ACTOR,\n `cleanup_revert:run:${runId}:log:${row.id}`,\n current,\n after ?? null,\n );\n\n db.update(maintenanceCleanupLog)\n .set({ reverted: true, reverted_at: now })\n .where(eq(maintenanceCleanupLog.id, row.id))\n .run();\n\n reverted += 1;\n }\n\n return { run_id: runId, reverted, skipped, reasons };\n}\n\nexport interface CleanupRunSummary {\n run_id: string;\n started_at: string;\n finished_at: string;\n total: number;\n by_action: Record<string, number>;\n reverted: number;\n}\n\nexport function listCleanupRuns(db: RecallDb, limit = 10): CleanupRunSummary[] {\n const rows = db.select().from(maintenanceCleanupLog).all();\n const byRun = new Map<string, CleanupRunSummary>();\n for (const row of rows) {\n let entry = byRun.get(row.run_id);\n if (!entry) {\n entry = {\n run_id: row.run_id,\n started_at: row.created_at,\n finished_at: row.created_at,\n total: 0,\n by_action: {},\n reverted: 0,\n };\n byRun.set(row.run_id, entry);\n }\n entry.total += 1;\n entry.by_action[row.action] = (entry.by_action[row.action] ?? 0) + 1;\n if (row.reverted) entry.reverted += 1;\n if (row.created_at < entry.started_at) entry.started_at = row.created_at;\n if (row.created_at > entry.finished_at) entry.finished_at = row.created_at;\n }\n return [...byRun.values()]\n .sort((a, b) => b.finished_at.localeCompare(a.finished_at))\n .slice(0, limit);\n}\n\nexport function formatCleanupReport(report: CleanupReport): string {\n const lines: string[] = [];\n lines.push(`Cleanup ${report.dry_run ? \"DRY-RUN\" : \"APPLY\"} run=${report.run_id.slice(0, 8)}`);\n lines.push(` dedupe_clusters: ${report.counts.dedupe_clusters}`);\n lines.push(` dedupe_losers: ${report.counts.dedupe_losers}`);\n lines.push(` fragment_rejections: ${report.counts.fragment_rejections}`);\n lines.push(` repeat_promotions: ${report.counts.repeat_promotions}`);\n lines.push(` command_suppressions: ${report.counts.command_suppressions}`);\n lines.push(` globalizations: ${report.counts.globalizations} (losers=${report.counts.globalize_losers})`);\n if (report.plan.length === 0) {\n lines.push(\" (no actions)\");\n return lines.join(\"\\n\");\n }\n lines.push(\"\");\n for (const item of report.plan) {\n if (item.kind === \"dedupe_exact_merge\") {\n lines.push(` merge: keep ${item.winner_id.slice(0, 8)} drop ${item.loser_ids.length} inj=${item.total_injection_count}`);\n lines.push(` \"${truncate(item.winner_text, 80)}\"`);\n } else if (item.kind === \"reject_fragment_candidate\") {\n lines.push(` reject: ${item.memory_id.slice(0, 8)} reasons=${item.reasons.join(\",\")}`);\n lines.push(` \"${truncate(item.text, 80)}\"`);\n } else if (item.kind === \"promote_repeat_correction\") {\n lines.push(` promote: ${item.memory_id.slice(0, 8)} via=${item.matched_pattern}`);\n lines.push(` \"${truncate(item.text, 80)}\"`);\n } else if (item.kind === \"suppress_unproductive_command\") {\n lines.push(` suppress: ${item.memory_id.slice(0, 8)} inj=${item.injection_count} followed=${item.followed_count}`);\n lines.push(` \"${truncate(item.text, 80)}\"`);\n } else {\n lines.push(` globalize: keep ${item.winner_id.slice(0, 8)} drop ${item.loser_ids.length} repos=[${item.repos.join(\",\")}]`);\n lines.push(` \"${truncate(item.winner_text, 80)}\"`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction truncate(s: string, n: number): string {\n if (s.length <= n) return s;\n return s.slice(0, n - 1) + \"…\";\n}\n","/**\n * Contradiction detection — find conflicting memories.\n *\n * Detection strategies:\n * 1. Direct negation: \"always X\" vs \"never X\"\n * 2. Conflicting rules: \"use A\" vs \"use B\" for same scope\n * 3. Scope overlap: same rule at different scopes that conflict\n * 4. Superseded: newer memory supersedes older\n *\n * Automatically demotes the weaker side of detected contradictions.\n */\n\nimport { eq, and, ne } from \"drizzle-orm\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { contradictions, memories } from \"../db/schema.js\";\nimport { queryMemories, demoteMemory, getMemory } from \"../models/memory.js\";\nimport { recordAudit } from \"../audit/trail.js\";\nimport type { Contradiction, MemoryItem } from \"../types.js\";\n\n// --- Detect contradictions ---\n\nexport function detectContradictions(\n db: RecallDb,\n repo?: string,\n): Contradiction[] {\n const mems = queryMemories(db, { repo }).filter(\n (m) => m.status === \"active\" || m.status === \"candidate\",\n );\n\n const found: Contradiction[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < mems.length; i++) {\n for (let j = i + 1; j < mems.length; j++) {\n const a = mems[i];\n const b = mems[j];\n const pairKey = [a.id, b.id].sort().join(\":\");\n if (seen.has(pairKey)) continue;\n\n const contradiction = checkContradiction(a, b);\n if (contradiction) {\n seen.add(pairKey);\n\n // Check if already recorded\n const existing = db\n .select()\n .from(contradictions)\n .where(\n and(\n eq(contradictions.memory_a_id, a.id),\n eq(contradictions.memory_b_id, b.id),\n ),\n )\n .get();\n\n if (!existing) {\n const id = randomUUID();\n const now = new Date().toISOString();\n\n db.insert(contradictions)\n .values({\n id,\n memory_a_id: a.id,\n memory_b_id: b.id,\n contradiction_type: contradiction.type,\n severity: contradiction.severity,\n description: contradiction.description,\n resolved: false,\n detected_at: now,\n })\n .run();\n\n recordAudit(db, a.id, \"contradiction_detected\", \"system\", contradiction.description);\n recordAudit(db, b.id, \"contradiction_detected\", \"system\", contradiction.description);\n\n found.push({\n id,\n memory_a_id: a.id,\n memory_b_id: b.id,\n contradiction_type: contradiction.type,\n severity: contradiction.severity,\n description: contradiction.description,\n resolved: false,\n resolution: null,\n detected_at: now,\n resolved_at: null,\n });\n }\n }\n }\n }\n\n return found;\n}\n\n// --- Check two memories for contradiction ---\n\nexport interface ContradictionMatch {\n type: Contradiction[\"contradiction_type\"];\n severity: Contradiction[\"severity\"];\n description: string;\n}\n\nexport function checkContradiction(\n a: MemoryItem,\n b: MemoryItem,\n): ContradictionMatch | null {\n // Only compare memories with overlapping scope\n if (!scopesOverlap(a, b)) return null;\n\n // 1. Direct negation: \"always X\" vs \"never X\"\n const negation = checkDirectNegation(a, b);\n if (negation) return negation;\n\n // 2. Conflicting rules: \"use A\" vs \"use B\"\n const conflict = checkConflictingRules(a, b);\n if (conflict) return conflict;\n\n // 3. Superseded check\n if (a.supersedes === b.id || b.supersedes === a.id) {\n return {\n type: \"superseded\",\n severity: \"medium\",\n description: `One memory supersedes the other`,\n };\n }\n\n return null;\n}\n\n// --- Direct negation detection ---\n\nconst NEGATION_PAIRS = [\n [/\\balways\\b/i, /\\bnever\\b/i],\n [/\\bdo\\b/i, /\\bdo not\\b|don't\\b/i],\n [/\\buse\\b/i, /\\bdo not use\\b|don't use\\b|never use\\b/i],\n [/\\brequired\\b/i, /\\bforbidden\\b|prohibited\\b/i],\n [/\\benable\\b/i, /\\bdisable\\b/i],\n];\n\nfunction checkDirectNegation(\n a: MemoryItem,\n b: MemoryItem,\n): ContradictionMatch | null {\n // Extract the \"subject\" — the part after always/never/use/etc.\n for (const [pos, neg] of NEGATION_PAIRS) {\n const aPos = pos.test(a.text) && !neg.test(a.text);\n const aNeg = neg.test(a.text) && !pos.test(a.text);\n const bPos = pos.test(b.text) && !neg.test(b.text);\n const bNeg = neg.test(b.text) && !pos.test(b.text);\n\n if ((aPos && bNeg) || (aNeg && bPos)) {\n // Check if they're about the same subject\n const subjectA = extractSubject(a.text);\n const subjectB = extractSubject(b.text);\n if (subjectA && subjectB && wordOverlap(subjectA, subjectB) > 0.5) {\n return {\n type: \"direct_negation\",\n severity: \"high\",\n description: `\"${a.text}\" contradicts \"${b.text}\"`,\n };\n }\n }\n }\n\n return null;\n}\n\n// --- Conflicting rules detection ---\n\nfunction checkConflictingRules(\n a: MemoryItem,\n b: MemoryItem,\n): ContradictionMatch | null {\n // Both must be rules or commands\n if (a.type !== b.type) return null;\n if (a.type !== \"rule\" && a.type !== \"command\") return null;\n\n // \"use X\" vs \"use Y\" for the same context\n const useA = a.text.match(/\\buse\\s+(\\S+)/i);\n const useB = b.text.match(/\\buse\\s+(\\S+)/i);\n\n if (useA && useB) {\n const toolA = useA[1].toLowerCase().replace(/[,.:;]/g, \"\");\n const toolB = useB[1].toLowerCase().replace(/[,.:;]/g, \"\");\n\n if (toolA !== toolB) {\n // Check if they're about the same category\n const contextA = extractContext(a.text);\n const contextB = extractContext(b.text);\n if (contextA && contextB && wordOverlap(contextA, contextB) > 0.3) {\n return {\n type: \"conflicting_rules\",\n severity: \"medium\",\n description: `\"use ${toolA}\" vs \"use ${toolB}\" in similar context`,\n };\n }\n }\n }\n\n // High text similarity but different content → suspicious\n const sim = wordOverlap(a.text, b.text);\n if (sim > 0.6 && sim < 0.95 && a.text !== b.text) {\n // Very similar but not identical — might be conflicting versions\n return {\n type: \"scope_overlap\",\n severity: \"low\",\n description: `Very similar memories (${(sim * 100).toFixed(0)}% overlap): \"${a.text.slice(0, 50)}\" vs \"${b.text.slice(0, 50)}\"`,\n };\n }\n\n return null;\n}\n\n// --- Resolve contradiction ---\n\nexport function resolveContradiction(\n db: RecallDb,\n contradictionId: string,\n keepMemoryId: string,\n actor: string,\n resolution?: string,\n): boolean {\n const row = db\n .select()\n .from(contradictions)\n .where(eq(contradictions.id, contradictionId))\n .get();\n if (!row) return false;\n\n const now = new Date().toISOString();\n const demoteId =\n row.memory_a_id === keepMemoryId ? row.memory_b_id : row.memory_a_id;\n\n // Demote the loser\n demoteMemory(db, demoteId, `contradiction resolved: keep ${keepMemoryId.slice(0, 8)}`);\n\n db.update(contradictions)\n .set({\n resolved: true,\n resolution: resolution ?? `Kept ${keepMemoryId.slice(0, 8)}, demoted ${demoteId.slice(0, 8)}`,\n resolved_at: now,\n })\n .where(eq(contradictions.id, contradictionId))\n .run();\n\n recordAudit(db, keepMemoryId, \"contradiction_resolved\", actor, resolution ?? null);\n recordAudit(db, demoteId, \"contradiction_resolved\", actor, `demoted in favor of ${keepMemoryId.slice(0, 8)}`);\n\n return true;\n}\n\n/** Auto-resolve: keep the one with higher confidence */\nexport function autoResolveContradictions(\n db: RecallDb,\n repo?: string,\n): number {\n const unresolved = db\n .select()\n .from(contradictions)\n .where(eq(contradictions.resolved, false))\n .all();\n\n let resolved = 0;\n for (const c of unresolved) {\n const a = getMemory(db, c.memory_a_id);\n const b = getMemory(db, c.memory_b_id);\n if (!a || !b) continue;\n if (repo && a.repo !== repo && b.repo !== repo) continue;\n\n // Only auto-resolve high severity or if confidence gap is clear\n if (c.severity === \"low\") continue;\n if (Math.abs(a.confidence - b.confidence) < 0.15) continue;\n\n const keepId = a.confidence >= b.confidence ? a.id : b.id;\n resolveContradiction(db, c.id, keepId, \"auto-resolver\", \"Auto-resolved: higher confidence wins\");\n resolved++;\n }\n\n return resolved;\n}\n\n// --- List contradictions ---\n\nexport function listContradictions(\n db: RecallDb,\n options: { resolved?: boolean } = {},\n): Array<typeof contradictions.$inferSelect> {\n if (options.resolved !== undefined) {\n return db\n .select()\n .from(contradictions)\n .where(eq(contradictions.resolved, options.resolved))\n .all();\n }\n return db.select().from(contradictions).all();\n}\n\n// --- Helpers ---\n\nfunction scopesOverlap(a: MemoryItem, b: MemoryItem): boolean {\n // Global scope overlaps with everything (applies in every repo)\n if (a.scope === \"global\" || b.scope === \"global\") return true;\n // Team scope overlaps with everything\n if (a.scope === \"team\" || b.scope === \"team\") return true;\n\n // Repo scope overlaps if same repo\n if (a.scope === \"repo\" && b.scope === \"repo\") {\n return !a.repo || !b.repo || a.repo === b.repo;\n }\n\n // Path scope overlaps if paths share prefix\n if (a.scope === \"path\" && b.scope === \"path\") {\n if (!a.path_scope || !b.path_scope) return true;\n return (\n a.path_scope.startsWith(b.path_scope.replace(\"/**\", \"\")) ||\n b.path_scope.startsWith(a.path_scope.replace(\"/**\", \"\"))\n );\n }\n\n // Repo overlaps with path in same repo\n if (\n (a.scope === \"repo\" && b.scope === \"path\") ||\n (a.scope === \"path\" && b.scope === \"repo\")\n ) {\n return !a.repo || !b.repo || a.repo === b.repo;\n }\n\n return false;\n}\n\nfunction extractSubject(text: string): string {\n // Strip the \"always/never/use/don't\" prefix to get the subject\n return text\n .replace(/\\b(always|never|must|do not|don't|use|do|run|call|import)\\b/gi, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction extractContext(text: string): string {\n // Strip the \"use X\" part to get surrounding context\n return text\n .replace(/\\buse\\s+\\S+/i, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction wordOverlap(a: string, b: string): number {\n const wordsA = new Set(a.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n const wordsB = new Set(b.toLowerCase().split(/\\s+/).filter((w) => w.length > 2));\n if (wordsA.size === 0 || wordsB.size === 0) return 0;\n const intersection = [...wordsA].filter((w) => wordsB.has(w));\n const union = new Set([...wordsA, ...wordsB]);\n return intersection.length / union.size;\n}\n"],"mappings":"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","names":["and","desc","eq","inArray","sql","randomUUID","z","eq","pipeline","extractorPromise","getModel","getDimensions","getExtractor","pipeline","tensorToEmbeddings","embedTexts","pipeline","extractorPromise","getModel","getDimensions","prefixTexts","getExtractor","pipeline","tensorToEmbeddings","embedTexts","eq","getSqlite","eq","eq","eq","eq","eq","randomUUID","eq","eq","rowToMemory","eq","rowToMemory","eq","randomUUID","randomUUID","eq","eq","eq","eq","memories","eq","clamp","randomUUID","randomUUID","resolveProvider","randomUUID","and","eq","gte","inArray","sql","randomUUID","eq","and","randomUUID","and","eq","randomUUID","randomUUID","inArray","eq","and","gte","sql","randomUUID","id","eq","randomUUID","DEFAULT_LEASE_SECONDS","and","eq","inArray","randomUUID","sql","id","desc","MemoryScope","z","DEFAULT_LEASE_SECONDS","and","eq","now"]}