/** * Extraction Gate — Verification layer before BRAIN memory storage. * * Wraps all memory writes with three ordered checks: * A. Content-hash deduplication (always runs — fast, no embedding needed) * B. Cosine similarity deduplication (runs when embedding is available; skipped for trusted sources) * C. Confidence threshold enforcement (always runs) * * Trusted sources (manual, owner) bypass Check B but still run A and C. * * Design goals: * - NEVER block the primary write path on error — all checks wrapped in try/catch * - Degrade gracefully to hash-only dedup when embedding is unavailable * - Contradiction detection uses a polarity-flip heuristic (no LLM required) * * @task T549 Wave 2-A * @epic T549 */ import type { BrainCognitiveType, BrainMemoryTier, BrainSourceConfidence } from '../store/schema/memory-schema.js'; /** * A candidate memory entry produced by the extraction engine or supplied * directly by a trusted agent/owner. */ export interface MemoryCandidate { /** The main text content to store. */ text: string; /** Human-readable label for the entry. Defaults to first 120 chars of text. */ title?: string; /** * Cognitive type — determines which BRAIN table receives this entry. * Uses BRAIN_COGNITIVE_TYPES vocabulary (semantic/episodic/procedural). */ memoryType: BrainCognitiveType; /** Storage tier — determines eviction policy. */ tier: BrainMemoryTier; /** * Confidence 0.0–1.0. * Below MINIMUM_CONFIDENCE (0.40) sends entry to pending queue. */ confidence: number; /** Source pipeline that produced this candidate. */ source: 'transcript' | 'task-completion' | 'diff' | 'manual' | 'debrief'; /** Session ID of the originating session (for graph linking). */ sourceSessionId?: string; /** * Source reliability level for the memory entry. * Manual/owner sources skip similarity check (trusted bypass). */ sourceConfidence?: BrainSourceConfidence; /** * When true, skip Checks A-B (similarity/contradiction) — only Check C applies. * Automatically set for 'manual' source and 'owner'/'task-outcome' sourceConfidence. */ trusted?: boolean; } /** Result of passing a candidate through the verification gate. */ export interface GateResult { /** What the gate decided. */ action: 'stored' | 'merged' | 'pending' | 'rejected'; /** * ID of the stored or merged entry. * Null when action is 'pending' or 'rejected'. */ id: string | null; /** Human-readable explanation of the decision. */ reason: string; /** Cosine distance to the nearest match (when similarity check ran). */ similarity?: number; } /** * Title prefixes that identify known-noise entries (task lifecycle chatter, * session scaffolding, evidence bookkeeping, etc.). * * Check A0 in verifyCandidate rejects any candidate whose title starts with * one of these prefixes before any expensive hash/similarity work runs. * * Ported from brain-purge.ts:207-248 janitor classifier so this becomes the * single source of truth. brain-purge.ts should import this const if it needs * the same list (follow-on cleanup tracked separately). * * @task T993 */ export declare const BRAIN_NOISE_PREFIXES: readonly string[]; /** * Tables that support SHA-256 content-hash deduplication (T726 T737). * * All four typed tables now have a `content_hash` column (added in migration * T726 Wave 1A). The table searched is selected by the caller based on the * memory type being stored. */ export type HashDedupTable = 'brain_observations' | 'brain_decisions' | 'brain_patterns' | 'brain_learnings'; /** * Public SHA-256 content-hash deduplication check. * * Exported for use by write paths (llm-extraction.ts, decisions.ts, patterns.ts) * that need to run hash dedup before an INSERT without going through the full * verifyCandidate gate (T736, T737). * * @param projectRoot - Project root for brain.db access * @param text - Candidate content text (hashed internally) * @param table - Which typed table to probe */ export declare function checkHashDedup(projectRoot: string, text: string, table: HashDedupTable): Promise<{ matched: true; id: string; } | { matched: false; }>; /** * Run a MemoryCandidate through the verification gate. * * Checks (in order): * A0. Title-prefix blocklist (T993) — rejects known-noise titles before any DB work * A. Content-hash deduplication (always; degrades to observations-only when DB unavailable) * B. Cosine similarity deduplication + contradiction detection (skipped for trusted sources) * C. Confidence threshold >= 0.40 (always) * * The gate NEVER stores the entry itself — it only decides whether the caller * should store, merge into an existing entry, queue as pending, or reject. * * To store after receiving action='stored', call the appropriate storage * function (observeBrain, storeLearning, storePattern, storeDecision). * * @param projectRoot - Project root for brain.db access * @param candidate - Candidate to verify * @returns GateResult describing what should happen */ export declare function verifyCandidate(projectRoot: string, candidate: MemoryCandidate): Promise; /** * Run a batch of candidates through the verification gate sequentially. * * Sequential (not parallel) so that a 'merged' action on an earlier candidate * is visible as an existing entry when later candidates run their similarity checks. * * @param projectRoot - Project root for brain.db access * @param candidates - Array of candidates to verify * @returns Array of GateResults in input order */ export declare function verifyBatch(projectRoot: string, candidates: MemoryCandidate[]): Promise; /** * Store a verified candidate in the appropriate BRAIN table based on memoryType. * * Routes: * semantic → brain_learnings (storeLearning) * episodic → brain_observations (observeBrain) * procedural → brain_patterns (storePattern) * * Called only after verifyCandidate returns action='stored'. * * @param projectRoot - Project root for brain.db access * @param candidate - Verified candidate to store * @returns ID of the newly created entry */ export declare function storeVerifiedCandidate(projectRoot: string, candidate: MemoryCandidate): Promise; /** * Full gate-and-store pipeline for a single candidate. * * Runs verifyCandidate then calls storeVerifiedCandidate when action='stored'. * For 'merged', increments the existing entry's citation_count (already done inside verifyCandidate). * For 'pending' and 'rejected', returns the GateResult with no storage. * * After storage, adds a supersedes edge when the gate returned a contradiction reason. * * @param projectRoot - Project root for brain.db access * @param candidate - Candidate to verify and store * @returns Final GateResult with the stored/merged entry ID populated */ export declare function verifyAndStore(projectRoot: string, candidate: MemoryCandidate): Promise; /** * Full gate-and-store pipeline for a batch of candidates. * * Sequential execution ensures that earlier stores are visible to later similarity checks. * * @param projectRoot - Project root for brain.db access * @param candidates - Array of candidates to verify and store * @returns Array of final GateResults in input order */ export declare function verifyAndStoreBatch(projectRoot: string, candidates: MemoryCandidate[]): Promise; //# sourceMappingURL=extraction-gate.d.ts.map