/** * Graph Memory Bridge — connects brain.db memory nodes to nexus.db code nodes. * * Scans brain observations, decisions, patterns, and learnings for entity * references (file paths, function names, symbol names) and matches them * against nexus_nodes in the global nexus.db. Matching pairs are linked via * `code_reference` edges written to brain_page_edges in brain.db. * * Design constraints: * - brain.db is read-write (edges written here). * - nexus.db is READ-ONLY from this module — never mutated. * - All operations are BEST-EFFORT; failures never surface to callers. * - Cross-DB join is handled in-process: read nexus nodes, then write brain edges. * - Entity matching: exact match on filePath or symbol name; fuzzy match on * symbol name (case-insensitive substring, minimum 4 chars). * * @task graph-memory-bridge * @epic T523 */ import { getNexusNativeDb } from '../store/nexus-sqlite.js'; /** A single code-reference link created or found by the bridge. */ export interface CodeReferenceLink { /** Brain memory node ID (format: ':'). */ brainNodeId: string; /** Nexus node ID (format: '::' or ''). */ nexusNodeId: string; /** Human-readable nexus node label. */ nexusLabel: string; /** Match strategy used: 'exact-file', 'exact-symbol', or 'fuzzy-symbol'. */ matchStrategy: 'exact-file' | 'exact-symbol' | 'fuzzy-symbol'; /** Edge weight (exact matches = 1.0, fuzzy = 0.6). */ weight: number; } /** Summary result from autoLinkMemories. */ export interface AutoLinkResult { /** Total brain entries scanned for entity references. */ scanned: number; /** Number of new code_reference edges created. */ linked: number; /** Number of links that already existed (skipped). */ alreadyLinked: number; /** Individual links created in this run. */ links: CodeReferenceLink[]; } /** Result from queryMemoriesForCode. */ export interface MemoriesForCodeResult { /** The nexus node ID that was queried. */ nexusNodeId: string; /** Brain memory nodes reachable from this code node. */ memories: Array<{ nodeId: string; nodeType: string; label: string; qualityScore: number; edgeWeight: number; matchStrategy: string; }>; } /** Result from queryCodeForMemory. */ export interface CodeForMemoryResult { /** The brain memory node ID that was queried. */ brainNodeId: string; /** Nexus code nodes reachable from this memory node. */ codeNodes: Array<{ nexusNodeId: string; label: string; filePath: string | null; kind: string; edgeWeight: number; matchStrategy: string; }>; } /** * Create a `code_reference` edge from a brain memory node to a nexus code node. * * Writes to brain_page_edges (brain.db). The nexus node must already exist in * nexus.db but is never mutated. The brain node is upserted as a stub if it * does not yet exist in brain_page_nodes. * * This function is idempotent — calling it multiple times with the same * (memoryId, codeSymbol) pair is safe (the composite PK prevents duplicates). * * @param projectRoot - Absolute path to project root (locates brain.db) * @param memoryId - Brain memory node ID (format: ':') * @param codeSymbol - Nexus node ID (format: '::' or '') * @returns True if the edge was created or already existed; false on error */ export declare function linkMemoryToCode(projectRoot: string, memoryId: string, codeSymbol: string): Promise; /** * Write `modified_by` edges from file nodes to observation nodes. * * For each file path in the observation's files_modified_json, finds the * corresponding file node in nexus_nodes and writes a `modified_by` edge. * * This function is idempotent — calling it multiple times is safe. * * @param obsId - Brain observation node ID (format: 'observation:') * @param filesModifiedJson - JSON array of file paths (may be null) * @param projectRoot - Absolute path to project root * @param nexusNative - Optional pre-loaded nexus database handle * @returns Count of edges written */ export declare function linkObservationToModifiedFiles(obsId: string, filesModifiedJson: string | null, projectRoot: string, nexusNative?: ReturnType): Promise; /** * Write `mentions` edges from observation nodes to symbol nodes found in text. * * Scans the observation text for symbol names present in nexus_nodes using * case-sensitive word-boundary matching. Caps results at 20 matches per * observation to prevent runaway on large-text observations. * * This function is idempotent — calling it multiple times is safe. * * @param obsId - Brain observation node ID * @param text - Text content to scan for symbol names * @param projectRoot - Absolute path to project root * @param nexusNative - Optional pre-loaded nexus database handle * @returns Count of edges written */ export declare function linkObservationToMentionedSymbols(obsId: string, text: string, projectRoot: string, nexusNative?: ReturnType): Promise; /** * Write `documents` edges from decision nodes to symbol nodes found in context. * * Scans the decision's context text for symbol names present in nexus_nodes. * Same NER pattern as linkObservationToMentionedSymbols but for decisions. * Caps results at 20 matches per decision to prevent runaway. * * This function is idempotent — calling it multiple times is safe. * * @param decisionId - Brain decision node ID (format: 'decision:D-') * @param contextText - Context/rationale text to scan for symbol names * @param projectRoot - Absolute path to project root * @param nexusNative - Optional pre-loaded nexus database handle * @returns Count of edges written */ export declare function linkDecisionToSymbols(decisionId: string, contextText: string, projectRoot: string, nexusNative?: ReturnType): Promise; /** * Scan brain memory nodes for entity references and match them against nexus. * * For each brain node, extracts: * - File path references → matched against nexus_nodes.file_path (exact) * - Symbol name references → matched against nexus_nodes.name (exact, then fuzzy) * - Files modified (observations) → writes modified_by edges via linkObservationToModifiedFiles * - Symbol mentions (observations/decisions) → writes mentions/documents edges via symbol NER * * Matching edges are written to brain_page_edges with edge types: code_reference, modified_by, * mentions, documents. This function is idempotent — existing edges are skipped. * * Should be called from runConsolidation() as a best-effort step. All errors * are caught and logged; never throws. * * @param projectRoot - Absolute path to project root (locates brain.db) * @returns Summary of scanned entries and created links */ export declare function autoLinkMemories(projectRoot: string): Promise; /** * Given a code symbol (nexus node ID), find related brain memory nodes. * * Traverses `code_reference` edges in brain_page_edges where the target is * the given nexus node ID. Returns the brain memory nodes with edge metadata. * * @param projectRoot - Absolute path to project root (locates brain.db) * @param symbol - Nexus node ID (format: '::' or '') * @returns Memory nodes that reference the given code symbol */ export declare function queryMemoriesForCode(projectRoot: string, symbol: string): Promise; /** * Given a brain memory node ID, find related nexus code nodes. * * Traverses `code_reference` edges in brain_page_edges from the given memory * node ID, then fetches the corresponding nexus node metadata. * * @param projectRoot - Absolute path to project root (locates brain.db) * @param memoryId - Brain memory node ID (format: ':') * @returns Nexus code nodes referenced by the given memory entry */ export declare function queryCodeForMemory(projectRoot: string, memoryId: string): Promise; /** A single code-memory link for display. */ export interface CodeLinkEntry { /** Brain memory node ID. */ brainNodeId: string; /** Brain node type. */ brainNodeType: string; /** Brain node label. */ brainNodeLabel: string; /** Nexus code node ID. */ nexusNodeId: string; /** Nexus node label. */ nexusNodeLabel: string; /** File path in the nexus node (relative to project root). */ filePath: string | null; /** Code kind (function, class, file, etc.). */ kind: string; /** Edge weight. */ weight: number; /** When the edge was created. */ createdAt: string; } /** * Return all `code_reference` edges from brain.db enriched with nexus metadata. * * Used by `cleo memory code-links` CLI command. * * @param projectRoot - Absolute path to project root (locates brain.db) * @param limit - Maximum number of entries to return (default 100) * @returns Array of code link entries sorted by weight descending */ export declare function listCodeLinks(projectRoot: string, limit?: number): Promise; /** * Parameters for {@link queryMemoriesForContext}. */ export interface MemoriesForContextParams { /** * Peer ID filter for CANT agent memory isolation (T1085). * * When provided, only memory nodes belonging to this peer OR to the global * pool (`peer_id = 'global'`) are returned (controlled by `includeGlobal`). * * When omitted, all memory nodes are returned (backward-compatible). */ peerId?: string; /** * When true (default), include global-pool entries (`peer_id = 'global'`) * alongside peer-specific entries. Set false for strict per-peer isolation. */ includeGlobal?: boolean; /** Maximum number of results. Defaults to 50. */ limit?: number; } /** * A single memory node hit from {@link queryMemoriesForContext}. */ export interface MemoryContextHit { /** Brain page node ID (`:`). */ nodeId: string; /** Node type classification (e.g. `observation`, `decision`, `pattern`). */ nodeType: string; /** Human-readable label. */ label: string; /** Quality score [0..1]. */ qualityScore: number; /** * Peer ID that produced this entry. * `"global"` = shared pool; a specific string = peer-owned. */ peerId: string; } /** * Retrieve brain memory nodes filtered by peer identity. * * This is the primary Wave 2 retrieval hook: it queries `brain_page_nodes` * joining back to the underlying typed tables (brain_observations, * brain_decisions, brain_patterns, brain_learnings) to apply the peer_id * filter, then projects to {@link MemoryContextHit}. * * SQL pattern (per PLAN.md §5.2 T1085): * `WHERE peer_id = :peerId OR peer_id = 'global'` * * When `peerId` is omitted the peer filter is not applied (backward compat). * * @param projectRoot - Absolute path to project root (locates brain.db) * @param params - Peer-scoping and limit parameters * @returns Array of memory node hits, ordered by quality score descending * * @task T1085 * @epic T1081 */ export declare function queryMemoriesForContext(projectRoot: string, params?: MemoriesForContextParams): Promise; /** * Result from linkConduitMessagesToSymbols. */ export interface ConduitSymbolLinkResult { /** Number of new `conduit_mentions_symbol` edges created. */ linked: number; /** Total messages scanned. */ scanned: number; } /** * Scan conduit.messages for symbol name mentions and link them to nexus_nodes. * * Scope per HITL-4: * - Query messages where `attachments != '[]'` OR `content` FTS5-matches symbol names * - Build symbolNames FTS query from top 200 nexus nodes (most plastically weighted) * - For each matched message, write `conduit_mentions_symbol` edges to brain_page_edges * - Idempotent via UNIQUE (source, target, type) constraint * * Gracefully no-ops if: * - conduit.db file does not exist (not initialized) * - nexus.db is unavailable * * All errors are caught and logged; never throws. * * @param projectRoot - Absolute path to project root (locates conduit.db) * @returns Summary of scanned messages and created edges * @task T1071 * @epic T1042 */ export declare function linkConduitMessagesToSymbols(projectRoot: string): Promise; //# sourceMappingURL=graph-memory-bridge.d.ts.map