/** * NEXUS plasticity — Hebbian co-access strengthening for nexus_relations edges. * * Implements "fire together, wire together": each time two nodes are * co-accessed during BRAIN retrieval, the directed edge(s) between them in * nexus_relations gain plasticity weight. Weight is capped at 1.0 to prevent * runaway strengthening. * * T11545 (ADR-090 §5.3) partitioned the plasticity columns (`weight`, * `last_accessed_at`, `co_accessed_count`) out of `nexus_relations` into the * sibling 1:1 `nexus_relation_weights` table (keyed by `relation_id`). Writes * here UPSERT that sibling table; rows are created lazily on first strengthen. * * Designed as Step 6b in runConsolidation (brain-lifecycle.ts) so every * nexus-backed read passively strengthens the code-graph edges that * participated in that retrieval. * * @task T998 * @task T11545 * @epic T991 */ /** A directed edge pair to strengthen. */ export interface NexusEdgePair { /** Source node ID as stored in nexus_relations.source_id. */ sourceId: string; /** Target node ID as stored in nexus_relations.target_id. */ targetId: string; } /** Result from a strengthenNexusCoAccess call. */ export interface StrengthNexusResult { /** Number of rows updated (edges that existed and were strengthened). */ strengthened: number; /** Number of pairs that had no matching row in nexus_relations (skipped). */ skipped: number; } /** Result from applying plasticity decay. */ export interface PlasticityDecayResult { /** Number of rows updated in nexus_relations. */ updated: number; /** Half-life used for decay calculation (days). */ halfLifeDays: number; /** Decay factor applied per day (0–1). */ decayPerDay: number; } /** * Strengthen nexus_relations edges for co-accessed node pairs. * * For each `{sourceId, targetId}` pair, UPSERTs into the partitioned * `nexus_relation_weights` table (T11545 · ADR-090 §5.3) for every matching * `nexus_relations.id`: * ```sql * INSERT INTO nexus_relation_weights (relation_id, weight, last_accessed_at, co_accessed_count) * SELECT id, MIN(1.0, 0.05), datetime('now'), 1 * FROM nexus_relations * WHERE source_id = ? AND target_id = ? * ON CONFLICT(relation_id) DO UPDATE SET * weight = MIN(1.0, weight + 0.05), * co_accessed_count = co_accessed_count + 1, * last_accessed_at = excluded.last_accessed_at * ``` * * A weights row is created lazily on first strengthen and never for a pair that * has no matching code-graph edge — when the SELECT is empty, zero rows change * and the pair is silently skipped (recorded in `result.skipped`). This keeps * the plasticity pass additive and non-destructive. * * This function is safe to call from any consolidation context. It * gracefully no-ops when nexus.db has not been initialised (returns zeros). * * @param pairs - Array of source/target ID pairs to strengthen. * @returns Counts of strengthened and skipped pairs. * * @example * ```typescript * const result = await strengthenNexusCoAccess([ * { sourceId: 'src/foo.ts::bar', targetId: 'src/baz.ts::qux' }, * ]); * // result.strengthened → 1 (if edge existed) * // result.skipped → 0 * ``` */ export declare function strengthenNexusCoAccess(pairs: NexusEdgePair[]): Promise; /** * Apply temporal decay to nexus_relations plasticity weights. * * Weights decay exponentially based on days since last access using a * configurable half-life. Formula: * ``` * new_weight = weight * (0.5 ^ (daysSinceLastAccess / halfLifeDays)) * ``` * * The half-life can be configured via the `CLEO_PLASTICITY_HALFLIFE_DAYS` * environment variable (default 14 days). This matches the development * cadence of typical projects: edges unused for 14 days halve their weight, * unused for 28 days drop to 0.25, and so on. * * Only updates rows where `last_accessed_at` is not NULL — new edges * with no access record are left unchanged. * * Operates on the GLOBAL nexus.db (resolved via `getCleoHome()` through the * singleton `getNexusNativeDb()`), not a per-project database. The function * takes no arguments intentionally — nexus.db spans all projects in a * CLEO installation and decay is applied globally. * * @returns Decay result including row count and parameters used * * @example * ```typescript * const result = await applyPlasticityDecay(); * console.log(`Decayed ${result.updated} edges with ${result.halfLifeDays}-day half-life`); * ``` */ export declare function applyPlasticityDecay(): Promise; /** * Extract nexus node ID pairs from the brain_retrieval_log that were * co-retrieved in the same search session. * * Used by Step 6b in runConsolidation to derive which nexus edges to * strengthen from recent BRAIN retrieval activity. * * The entry_ids column stores a JSON array of brain entry IDs (e.g., * `["D-abc", "L-def", "O-ghi"]`). These are mapped to nexus node IDs * via the brain-nexus bridge (brain_page_edges of type `documents` / * `applies_to`). When no bridge data is available, the raw brain IDs * are returned as-is — callers should filter non-node-format IDs before * passing to nexus_relations. * * BUG-1 fix: The lookback window is separate from insertion timestamp. * Consolidation scans retrieval events within `lookbackDays` of now. * * @param projectRoot - Project root for brain.db resolution. * @param lookbackDays - How far back in time to scan retrieval events (default 30 days). * @returns Deduplicated source/target pairs ready for strengthenNexusCoAccess. */ export declare function extractNexusPairsFromRetrievalLog(projectRoot: string, lookbackDays?: number): Promise; //# sourceMappingURL=nexus-plasticity.d.ts.map