/**
 * SemanticMemory — Entity-relationship knowledge store with FTS5 + vector hybrid search.
 *
 * A typed, confidence-tracked knowledge graph stored in SQLite. Entities
 * represent knowledge (facts, people, projects, tools, patterns, decisions,
 * lessons) and edges represent relationships between them.
 *
 * Key features:
 *   - FTS5 full-text search with multi-signal ranking
 *   - Optional vector similarity search via sqlite-vec (Phase 5)
 *   - Hybrid scoring: FTS5 keyword + vector cosine similarity
 *   - Exponential confidence decay (lessons decay slower than facts)
 *   - BFS graph traversal with cycle detection
 *   - Export/import for portability
 *   - Formatted context generation for session injection
 *   - Graceful degradation: works FTS5-only when vectors unavailable
 *
 * Uses the same better-sqlite3 pattern as MemoryIndex and TopicMemory.
 */
import type { MemoryEntity, MemoryEdge, ScoredEntity, ConnectedEntity, DecayReport, ImportReport, SemanticMemoryStats, SemanticMemoryConfig, SemanticSearchOptions, ExploreOptions, EntityType, RelationType, MemoryEvidence, MemoryEvidenceKind, EvidenceProducerId } from '../core/types.js';
import type { PrivacyScopeType } from '../core/types.js';
import type { EmbeddingProvider } from './EmbeddingProvider.js';
/**
 * Structural shape of the RemediationContext that W-4's `invokeFromRemediator`
 * accepts. Mirrored here (rather than imported from `src/remediation/`) to keep
 * `src/memory/*` independent of the remediation tree — installs with a partial
 * CLI surface that omit the remediation module continue to work, and the
 * existing in-line corruption-recovery path inside `open()` stays intact.
 *
 * SELF-HEALING-REMEDIATOR-V2-SPEC §A3 (capability token), §A4 (abort signal),
 * §A57 (Tier-2 W-4 wrapper).
 */
export interface SemanticMemoryRemediatorContext {
    attemptId: string;
    runbookId: string;
    auditToken: Buffer;
    abortSignal: AbortSignal;
    expiresAt: number;
    monotonicDeadline: bigint;
    hmac?: Buffer;
    lockHandle: unknown;
}
/**
 * Result returned by `SemanticMemory.invokeFromRemediator` — mirrors
 * `RemediatorExecutionResult` in the remediation tree without importing it.
 */
export interface SemanticMemoryRemediatorResult {
    outcome: 'success' | 'failure';
    details: Record<string, unknown>;
}
/**
 * Optional capability-leaf vault for §A3 HMAC verification. Same structural
 * shape as `CapabilityLeafKeyVault` in `src/remediation/RemediationContext.ts`.
 */
export interface SemanticMemoryCapabilityLeafKeyVault {
    deriveLeafKey(context: 'capability', scopeId: string): Buffer;
}
export declare class SemanticMemory {
    /**
     * W-4 / §A57 — process-wide registry of active SemanticMemory instances.
     * The `db-corruption` runbook surfaceCallable resolves a target instance
     * by `dbPath` (preferred) or, failing that, by the registered "active"
     * instance set explicitly via `setActiveInstance()`. Construction does
     * NOT auto-register — callers (server bootstrap, CLI subcommands) opt in
     * explicitly so partial CLI surfaces aren't accidentally targeted by a
     * Remediator dispatch.
     */
    private static readonly _instancesByPath;
    private static _activeInstance;
    private static _remediatorKeyVault;
    /**
     * Register this instance as a candidate target for Remediator dispatch.
     * Keyed by config.dbPath. Multiple registrations of the same path replace
     * the prior entry — the most recent `open()` site owns the path.
     */
    static registerInstance(instance: SemanticMemory): void;
    /** Remove an instance from the registry (mirror of registerInstance). */
    static unregisterInstance(instance: SemanticMemory): void;
    /**
     * Mark an instance as the "active" target for Remediator dispatch when
     * the ctx does not specify a dbPath. Server bootstrap calls this with
     * the primary memory store.
     */
    static setActiveInstance(instance: SemanticMemory | null): void;
    /**
     * Optionally wire a capability-leaf key vault so `invokeFromRemediator`
     * can verify ctx HMAC per §A3. Test helpers and partial CLI surfaces
     * may leave this unset, in which case ctx HMAC is not verified (the
     * surface still acts on the call — matches W-1 behaviour where the
     * keyVault is also optional).
     */
    static setRemediatorKeyVault(keyVault: SemanticMemoryCapabilityLeafKeyVault | null): void;
    /** Reset all class-level state. Test-only. */
    static resetForTesting(): void;
    /**
     * Public read of the active Remediator-target instance. Used by the W-4
     * runbook's verify() to inspect db.mode + integrity post-recovery.
     */
    static getActiveInstanceForRemediator(): SemanticMemory | null;
    /**
     * §A3 — verify the HMAC on a Remediator-supplied ctx. Mirrors the
     * canonical body layout in `src/remediation/RemediationContext.ts`. We
     * inline rather than import to keep `src/memory/*` independent of the
     * remediation tree. Returns `true` only when the keyVault is wired AND
     * the HMAC verifies; an unwired keyVault returns `true` (call is
     * permitted) but the audit tail records `hmac-unverified` so it's clear
     * the call came in without §A3 enforcement.
     */
    private static verifyCtxHmac;
    /**
     * W-4 surface entry point — the Remediator-orchestrated parallel path
     * to the in-line corruption-recovery logic inside `open()`. The legacy
     * in-line entry point remains the canonical safety net for direct-
     * construction paths; this static method is what the `db-corruption`
     * runbook surfaceCallable invokes.
     *
     * SELF-HEALING-REMEDIATOR-V2-SPEC §A3 (HMAC), §A4 (abort), §A9
     * (durability assertion done by runbook.verify), §A34 (surface entry
     * point is real and live — this method wraps the actually-implemented
     * quarantine + JSONL-rebuild path on lines 178-243 of this file).
     */
    static invokeFromRemediator(ctx: SemanticMemoryRemediatorContext, overrides?: {
        instance?: SemanticMemory;
        keyVault?: SemanticMemoryCapabilityLeafKeyVault | null;
    }): Promise<SemanticMemoryRemediatorResult>;
    /**
     * Instance-scoped corruption-recovery driver. Closes the current handle
     * (if any), reopens via `open()` — which runs integrity_check, probe-
     * read, and auto-quarantine + JSONL rebuild on detection. Returns a
     * structured result the runbook surfaceCallable hands back.
     */
    private _invokeFromRemediatorInternal;
    /**
     * §A9 durability assertion helper. Returns the persistence mode of the
     * underlying db file. For better-sqlite3 instances opened against a real
     * filesystem path this is `'durable'`; opened against `:memory:` it is
     * `'in-memory'`. The `db-corruption` runbook's verify() asserts
     * `mode === 'durable'` per §A9 — falling back to in-memory is "live but
     * lossy" and triggers a `DURABILITY_DEGRADED` event.
     */
    getDurabilityMode(): 'durable' | 'in-memory' | 'closed';
    /** Internal — accessor for the configured dbPath. Used by the W-4 runbook. */
    getDbPath(): string;
    /**
     * §A9 durability assertion helper for the W-4 runbook's verify() step.
     * Returns the raw `integrity_check` string ('ok' on success). Throws if
     * the db is closed or pragma throws — the caller maps the throw to
     * `verify-inconclusive` per §A21.
     */
    runIntegrityCheckForRemediator(): string;
    private db;
    private readonly config;
    private embeddingProvider;
    private vectorSearch;
    private _vectorAvailable;
    private jsonlPath;
    /** Set after corruption auto-recovery — caller should reimport from JSONL */
    private _needsRebuild;
    /** §A57 W-4 — set true when the most recent `open()` ran the JSONL rebuild
     *  path (i.e., a corruption event was observed + recovered). The runbook's
     *  surfaceCallable reads this to record whether recovery actually fired. */
    private _lastRecoveryRebuilt;
    /** When true, `remember()` skips its own JSONL append (the wrapping
     *  `rememberWithEvidence` will emit a consolidated action instead). */
    private _suppressRememberJournal;
    /** Last full entity payload captured by `remember()` — read by
     *  `rememberWithEvidence` to build a full-fidelity JSONL action. */
    private _lastRememberedEntity;
    constructor(config: SemanticMemoryConfig);
    /**
     * Whether hybrid vector search is active (sqlite-vec loaded + embeddings table created).
     */
    get vectorSearchAvailable(): boolean;
    /**
     * Attach an EmbeddingProvider to enable hybrid search.
     * Must be called BEFORE open() for full effect, but can be called after
     * to enable vector search on an already-open database.
     */
    setEmbeddingProvider(provider: EmbeddingProvider): void;
    private initVectorSearch;
    /**
     * Async initialization for vector search.
     * Loads sqlite-vec module, then wires up the extension and creates tables.
     * Call this after open() and setEmbeddingProvider() for full hybrid search.
     */
    initializeVectorSearch(): Promise<boolean>;
    open(): Promise<void>;
    close(): void;
    /**
     * Checkpoint the WAL file. Call after sleep/wake to flush stale WAL locks.
     * Uses PASSIVE mode (non-blocking) — safe to call at any time.
     */
    checkpoint(): void;
    private ensureOpen;
    /**
     * Move a corrupt DB aside (rename, not delete) and drop a marker file so
     * operators can notice the auto-recovery. JSONL is source of truth, but
     * keeping the corrupt file enables forensic analysis (did WAL tear? disk full?).
     */
    private quarantineCorruptDb;
    private writeSkippedRebuildMarker;
    /**
     * Append a mutation record to the JSONL log.
     * This is the source of truth for disaster recovery — if semantic.db
     * is lost, the JSONL can reconstruct the full knowledge graph.
     *
     * Actions: remember, connect, forget, verify, supersede, update, import
     */
    private appendToJournal;
    private createSchema;
    /**
     * Migrate existing databases to add privacy columns.
     * Safe to call repeatedly — checks for column existence first.
     */
    private migrateIfNeeded;
    /**
     * Store a knowledge entity. Returns the generated UUID.
     */
    remember(input: {
        type: EntityType;
        name: string;
        content: string;
        confidence: number;
        lastVerified: string;
        source: string;
        sourceSession?: string;
        tags: string[];
        domain?: string;
        expiresAt?: string;
        ownerId?: string;
        privacyScope?: PrivacyScopeType;
    }): string;
    /**
     * Store a knowledge entity AND generate its embedding synchronously.
     * Use this when you need the embedding to be available immediately
     * (e.g., during migration or when testing search after insert).
     */
    rememberWithEmbedding(input: {
        type: EntityType;
        name: string;
        content: string;
        confidence: number;
        lastVerified: string;
        source: string;
        sourceSession?: string;
        tags: string[];
        domain?: string;
        expiresAt?: string;
        ownerId?: string;
        privacyScope?: PrivacyScopeType;
    }): Promise<string>;
    /**
     * Retrieve an entity by ID, including its connections.
     * Updates lastAccessed on read.
     */
    recall(id: string): {
        entity: MemoryEntity;
        connections: ConnectedEntity[];
    } | null;
    /**
     * Delete an entity and all its edges.
     */
    forget(id: string, _reason?: string): void;
    /**
     * Atomic create-with-evidence. Equivalent to `remember()` followed by
     * `addEvidence()`, but in one better-sqlite3 transaction so a producer
     * crash mid-call cannot leave an orphan entity.
     */
    rememberWithEvidence(input: Parameters<typeof this.remember>[0], evidence: MemoryEvidence[], producer: EvidenceProducerId): string;
    /**
     * Append one or more evidence entries to an existing entity. When called
     * with an array, all rows are inserted inside a single better-sqlite3
     * transaction so a partial-write crash cannot leave half the rows landed.
     */
    addEvidence(entityId: string, evidence: MemoryEvidence | MemoryEvidence[], producer: EvidenceProducerId): void;
    /**
     * Read evidence for an entity, filtered by viewer scope. Producers may
     * have written `privacyTier` more restrictive than the entity's own
     * `privacyScope`; we filter at read time so the renderer is the single
     * privacy-enforcement point.
     */
    getEvidence(entityId: string, viewerScope: PrivacyScopeType): MemoryEvidence[];
    /**
     * Inverse query: which entities cite this `(kind, sourceId)`? Filtered by
     * BOTH the entity's own privacyScope AND the citing evidence row's
     * privacyTier — per spec § Storage and Privacy line 316, no leak via
     * inverse query at any (viewerScope × evidence tier × entity scope)
     * combination.
     */
    findCitations(ref: {
        kind: MemoryEvidenceKind;
        sourceId: string;
    }, viewerScope: PrivacyScopeType): MemoryEntity[];
    /**
     * Eager variant of `recall()` (without `connections`). Returns the entity
     * with its evidence array attached, viewer-scope filtered.
     */
    getEntityWithEvidence(entityId: string, viewerScope: PrivacyScopeType): (MemoryEntity & {
        evidence: MemoryEvidence[];
    }) | null;
    private evidenceCapPerEntity;
    private assertProducerKindsAllowed;
    private insertEvidenceRows;
    private assertEvidenceShape;
    /**
     * Bounded defenses for `kind:'supersedes-evidence'`:
     * 1. The supersedes-evidence row's `sourceId` MUST NOT equal the entity's
     *    own id — that's a self-loop with no useful semantics.
     * 2. The total count of supersedes-evidence rows on this entity MUST stay
     *    under MAX_SUPERSEDES_DEPTH. This bounds chain length without
     *    requiring a parent-pointer column (the spec leaves the chain shape
     *    underspecified; bounding count is the conservative defense).
     */
    private assertSupersedesAcyclic;
    /**
     * Get all entities owned by a specific user.
     * Used for GDPR data export (/mydata).
     */
    getEntitiesByUser(userId: string): MemoryEntity[];
    /**
     * Delete all entities owned by a specific user and their associated edges.
     * Used for GDPR data erasure (/forget).
     * Returns the number of entities deleted.
     */
    deleteEntitiesByUser(userId: string): number;
    /**
     * Create a relationship between two entities.
     * Returns the edge ID. Silently returns existing edge ID if duplicate.
     */
    connect(fromId: string, toId: string, relation: RelationType, context?: string, weight?: number): string;
    /**
     * Find an entity by its exact source key.
     * Used for deduplication during migration.
     */
    findBySource(source: string): MemoryEntity | null;
    /**
     * Find an entity by case-insensitive name match, optionally scoped by type.
     *
     * Used by the activity-digest entity-extraction pipeline to dedupe across
     * digests — if "Tom Southam" was remembered in digest N, digest N+1's
     * mention of the same name resolves to the existing entity instead of
     * creating a duplicate. Type scoping prevents accidental cross-type
     * collisions (e.g., a `tool` named "React" must not collide with a
     * `pattern` of the same name).
     *
     * Returns the earliest match by created_at, or null. The current schema
     * doesn't have a soft-delete column; if soft-deletes land later this
     * method should add a deleted_at IS NULL filter.
     */
    findByName(name: string, type?: EntityType): MemoryEntity | null;
    /**
     * Full-text search with multi-signal ranking.
     *
     * Without vector search:
     *   Score = (fts5_rank * 0.5) + (confidence * 0.3) + (access * 0.1) + (recency * 0.1)
     *
     * With vector search (hybrid mode):
     *   Score = (fts5_rank * 0.4) + (confidence * 0.3) + (access * 0.1) + (vector_sim * 0.2)
     */
    search(query: string, options?: SemanticSearchOptions): ScoredEntity[];
    private _lastVectorScores;
    /**
     * Hybrid search — runs both FTS5 and vector KNN, then merges results.
     * This is the recommended search method when vector search is available.
     *
     * Falls back to FTS5-only search when vectors are not available.
     */
    searchHybrid(query: string, options?: SemanticSearchOptions): Promise<ScoredEntity[]>;
    /**
     * Batch-embed all entities that are missing embeddings.
     * Used for migration when enabling vector search on an existing database.
     *
     * @returns Number of entities embedded
     */
    embedAllEntities(onProgress?: (done: number, total: number) => void): Promise<number>;
    /**
     * Apply exponential confidence decay to all entities.
     * formula: new_confidence = confidence * exp(-0.693 * days_since_verified / half_life)
     */
    decayAll(): DecayReport;
    /**
     * Re-verify an entity, refreshing lastVerified and optionally updating confidence.
     */
    verify(id: string, newConfidence?: number): void;
    /**
     * Mark an entity as superseded by a newer one.
     * Creates a 'supersedes' edge and lowers the old entity's confidence.
     */
    supersede(oldId: string, newId: string, reason?: string): void;
    /**
     * BFS graph traversal from a starting entity.
     * Returns all reachable entities (excluding the start) up to maxDepth.
     */
    explore(startId: string, options?: ExploreOptions): MemoryEntity[];
    /**
     * Find entities that are stale (low confidence or old).
     */
    findStale(options?: {
        maxConfidence?: number;
        olderThan?: string;
        limit?: number;
    }): MemoryEntity[];
    /**
     * Export all entities and edges as a JSON-serializable structure.
     */
    export(): {
        entities: MemoryEntity[];
        edges: MemoryEdge[];
    };
    /**
     * Import entities and edges, skipping duplicates by ID.
     */
    import(data: {
        entities: MemoryEntity[];
        edges: MemoryEdge[];
    }): ImportReport;
    /**
     * Import entities and edges from the JSONL append log.
     * Replays all 'remember' and 'connect' actions, skipping duplicates.
     * Applies 'forget' actions to remove deleted entities.
     * Returns the number of entities and edges recovered.
     *
     * Follows TopicMemory's resilience pattern: JSONL is source of truth,
     * SQLite is derived query layer that can be rebuilt at any time.
     */
    importFromJsonl(jsonlPath?: string): {
        entities: number;
        edges: number;
        forgotten: number;
    };
    /**
     * Full rebuild — drop all entities and edges, rebuild from JSONL.
     * This is the nuclear option for disaster recovery.
     *
     * Preserves the JSONL log (source of truth) and rebuilds SQLite from it.
     */
    rebuild(jsonlPath?: string): {
        entities: number;
        edges: number;
        forgotten: number;
    };
    /**
     * Write a full JSON snapshot to disk for periodic backup.
     * This is a point-in-time export that complements the JSONL append log.
     */
    writeSnapshot(snapshotPath?: string): {
        path: string;
        entities: number;
        edges: number;
        sizeBytes: number;
    };
    /**
     * Get aggregate statistics about the memory store.
     */
    stats(): SemanticMemoryStats;
    /**
     * Generate formatted markdown context for a query, suitable for session injection.
     * Returns empty string if no relevant entities found.
     */
    getRelevantContext(query: string, options?: {
        maxTokens?: number;
        limit?: number;
        userId?: string;
    }): string;
    private getConnections;
}
export declare class EvidencePolicyError extends Error {
    constructor(message: string);
}
//# sourceMappingURL=SemanticMemory.d.ts.map