@edihasaj/recall 0.5.8 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{chunk-K5FZ47NN.js → chunk-7XCLKPJ3.js} +6 -8
  2. package/dist/{chunk-K5FZ47NN.js.map → chunk-7XCLKPJ3.js.map} +1 -1
  3. package/dist/{chunk-A5UIRZU6.js → chunk-A6XEULA4.js} +3 -2
  4. package/dist/chunk-A6XEULA4.js.map +1 -0
  5. package/dist/{chunk-F56Y3SHS.js → chunk-E4HJDGCW.js} +7 -9
  6. package/dist/{chunk-F56Y3SHS.js.map → chunk-E4HJDGCW.js.map} +1 -1
  7. package/dist/{chunk-IILLSHLM.js → chunk-KAGIAOD7.js} +2583 -84
  8. package/dist/chunk-KAGIAOD7.js.map +1 -0
  9. package/dist/{chunk-FHKV6ELT.js → chunk-MJ4GGBTL.js} +11 -13
  10. package/dist/{chunk-FHKV6ELT.js.map → chunk-MJ4GGBTL.js.map} +1 -1
  11. package/dist/{chunk-LVQW6WHK.js → chunk-XUM7JEJU.js} +2 -2
  12. package/dist/{cleanup-TVOX2S2S.js → cleanup-MYSQ44EP.js} +4 -4
  13. package/dist/cli.js +206 -33
  14. package/dist/cli.js.map +1 -1
  15. package/dist/daemon.js +60 -49
  16. package/dist/daemon.js.map +1 -1
  17. package/dist/dispatcher-SUUX5AX6.js +16 -0
  18. package/dist/mcp.js +5 -5
  19. package/dist/{quality-Z7LPMMBC.js → quality-YTQKAEY6.js} +3 -3
  20. package/dist/{tasks-UOLSPXJQ.js → tasks-GSQUHD4F.js} +6 -3
  21. package/dist/{usage-CY3V72YN.js → usage-DU4TKVJH.js} +2 -2
  22. package/package.json +1 -1
  23. package/dist/chunk-A5UIRZU6.js.map +0 -1
  24. package/dist/chunk-GC5XMBG4.js +0 -551
  25. package/dist/chunk-GC5XMBG4.js.map +0 -1
  26. package/dist/chunk-IILLSHLM.js.map +0 -1
  27. package/dist/chunk-VEPXEHRZ.js +0 -1763
  28. package/dist/chunk-VEPXEHRZ.js.map +0 -1
  29. package/dist/dispatcher-UGMU6THT.js +0 -15
  30. /package/dist/{chunk-LVQW6WHK.js.map → chunk-XUM7JEJU.js.map} +0 -0
  31. /package/dist/{cleanup-TVOX2S2S.js.map → cleanup-MYSQ44EP.js.map} +0 -0
  32. /package/dist/{dispatcher-UGMU6THT.js.map → dispatcher-SUUX5AX6.js.map} +0 -0
  33. /package/dist/{quality-Z7LPMMBC.js.map → quality-YTQKAEY6.js.map} +0 -0
  34. /package/dist/{tasks-UOLSPXJQ.js.map → tasks-GSQUHD4F.js.map} +0 -0
  35. /package/dist/{usage-CY3V72YN.js.map → usage-DU4TKVJH.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/maintenance/cleanup.ts","../src/contradictions/detector.ts","../src/repo/quality.ts","../src/health/scoring.ts","../src/capture/scope.ts","../src/capture/correction.ts"],"sourcesContent":["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\nconst VERB_HINTS = [\n \"is\", \"are\", \"use\", \"uses\", \"used\", \"run\", \"runs\", \"ran\",\n \"must\", \"never\", \"always\", \"do\", \"don't\", \"do not\", \"should\",\n \"avoid\", \"prefer\", \"keep\", \"set\", \"add\", \"remove\", \"skip\",\n \"replace\", \"fix\", \"ensure\", \"require\", \"require \", \"make\",\n \"build\", \"test\", \"deploy\", \"install\", \"import\", \"export\",\n \"commit\", \"push\", \"call\", \"wrap\", \"split\", \"merge\", \"store\",\n \"load\", \"save\", \"ignore\", \"accept\", \"reject\",\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// \"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\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 < 14) 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 (DANGLING_CONNECTOR_RE.test(text)) reasons.push(\"dangling_connector\");\n if (RULE_FILLER_PREFIX_RE.test(text)) reasons.push(\"filler_prefix\");\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","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","/**\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 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 { enqueueVerifyCapture } from \"../maintenance/tasks.js\";\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\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 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"],"mappings":"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","names":["and","eq","randomUUID","eq","eq","eq","memories","eq","clamp","id","randomUUID","eq","and"]}
@@ -1,15 +0,0 @@
1
- import {
2
- buildPrompt,
3
- dispatchPendingTasks,
4
- formatDispatchReport
5
- } from "./chunk-GC5XMBG4.js";
6
- import "./chunk-IILLSHLM.js";
7
- import "./chunk-A5UIRZU6.js";
8
- import "./chunk-DNFKAHS6.js";
9
- import "./chunk-4CV4JOE5.js";
10
- export {
11
- buildPrompt,
12
- dispatchPendingTasks,
13
- formatDispatchReport
14
- };
15
- //# sourceMappingURL=dispatcher-UGMU6THT.js.map