/** * BRAIN lifecycle operations — temporal decay, memory consolidation, and tier promotion. * * Reduces confidence of stale learnings based on age, following an * exponential decay model: new_confidence = confidence * (decayRate ^ daysSinceUpdate). * * Consolidation groups old observations by keyword overlap and merges * clusters into summary observations, archiving the originals. * * Wave 3 additions (T549): * - runTierPromotion — promotes entries through short→medium→long based on citation count, * age, and verification; soft-evicts stale short-term entries. * - runConsolidation — orchestrates all consolidation steps (dedup, quality recompute, * tier promotion, contradiction detection, soft eviction, graph strengthening, summaries). * * @task T5394 T5395 T549 * @epic T5149 */ /** Result from applying temporal decay. */ export interface DecayResult { updated: number; tablesProcessed: string[]; } /** * Apply temporal decay to brain_learnings confidence values. * * Entries older than `olderThanDays` have their confidence reduced * by an exponential decay factor based on the number of days since * their last update (or creation if never updated). * * Formula: new_confidence = confidence * (decayRate ^ daysSinceUpdate) * * @param projectRoot - Project root directory for brain.db resolution * @param options - Decay configuration * @returns Count of updated rows and tables processed */ export declare function applyTemporalDecay(projectRoot: string, options?: { decayRate?: number; olderThanDays?: number; }): Promise; /** Result from consolidating memories. */ export interface ConsolidationResult { grouped: number; merged: number; archived: number; } /** * Consolidate old observations by keyword similarity. * * Groups observations older than `olderThanDays` by FTS5 keyword overlap. * For groups with at least `minClusterSize` entries, creates one summary * observation and marks originals as archived (updated_at set, narrative * prefixed with [ARCHIVED]). * * @param projectRoot - Project root directory for brain.db resolution * @param options - Consolidation configuration * @returns Counts of grouped, merged, and archived observations */ export declare function consolidateMemories(projectRoot: string, options?: { olderThanDays?: number; minClusterSize?: number; }): Promise; /** A single promoted or evicted entry record. */ export interface PromotionRecord { id: string; table: string; fromTier: string; toTier: string; reason: string; } /** Eviction record for soft-evicted entries. */ export interface EvictionRecord { id: string; table: string; tier: string; reason: string; } /** Result from runTierPromotion. */ export interface PromotionResult { promoted: PromotionRecord[]; evicted: EvictionRecord[]; } /** * Run tier promotion for all memory tables. * * Promotion rules (per spec §1.1–§1.3, relaxed in T614): * - short → medium: * A. (citationCount >= 3 AND age > 24h) — citation-based track * B. (qualityScore >= 0.7 AND age > 24h) — quality fast-track * C. (verified = true AND age > 24h) — owner-verified track * Note: `verified` is no longer a hard gate for routes A and B. * Requiring verified=true on all paths caused all 235 short-tier observations * to be permanently stuck (T614 bug). * - medium → long: * (citationCount >= 5 AND age > 7 days) OR (verified = true AND age > 7 days) * Verified entries accelerate to long-tier without citation threshold. * * Eviction rules: * - short-term entries older than 7 days with no promotion eligibility are * soft-evicted (invalidAt = now). * - long-term entries are NEVER auto-evicted. * * @param projectRoot - Project root directory for brain.db resolution * @returns Lists of promoted and evicted entries */ export declare function runTierPromotion(projectRoot: string): Promise; /** One promoted observation record from promoteObservationsToTyped. */ export interface TypedPromotionRecord { /** brain_observations.id */ observationId: string; /** Observation type (e.g. 'discovery', 'decision', 'feature') */ observationType: string; /** Target typed table tier ('learning' | 'pattern') */ toTier: string; /** Composite score that crossed the threshold */ score: number; /** ID of the row written to brain_promotion_log */ logId: string; } /** Result from promoteObservationsToTyped. */ export interface TypedPromotionResult { /** Observations that crossed the threshold and were logged for promotion */ promoted: TypedPromotionRecord[]; /** Observations that were evaluated but did not cross the threshold */ skippedCount: number; /** Observations already logged in brain_promotion_log (skipped for idempotency) */ alreadyPromotedCount: number; } /** * Scan unpromoted brain_observations and promote eligible entries via composite scoring. * * Uses a 6-signal composite scorer (promotion-score.ts) instead of the legacy 3-rule * OR union. Entries that cross the threshold get an audit row in brain_promotion_log. * Re-running is idempotent — observations already in brain_promotion_log are skipped. * * Signal weights (see promotion-score.ts for exact values): * 1. citation_count — normalised retrieval frequency * 2. quality_score — content richness at insert time * 3. stability_score — biological-analog consolidation metric * 4. recency — inverse age decay * 5. user_verified — hard boost for owner-verified entries * 6. outcome_correlated — tied to a completed task outcome * * This function writes to brain_promotion_log only — it does NOT insert rows * into brain_learnings or brain_patterns. The actual typed-table insert is * the responsibility of a downstream step (e.g. a nightly consolidation pass * that reads brain_promotion_log rows with decided_by='composite-scorer'). * * @param projectRoot - Project root directory for brain.db resolution * @param limit - Maximum number of observations to scan per run (default 100) * @param threshold - Minimum composite score to trigger promotion (default 0.6) * @returns Summary of promoted, skipped, and already-promoted observations * * @task T1001 * @epic T1000 */ export declare function promoteObservationsToTyped(projectRoot: string, limit?: number, threshold?: number): Promise; /** * Metrics from the auto-extract promotion pipeline (T1903). * * Tracks how many brain_promotion_log entries were fulfilled (converted * to actual brain_learnings/brain_patterns rows) during a consolidation * cycle. Surfaced in `cleo doctor brain` for observability. */ export interface AutoExtractMetrics { /** Total promotion_log rows processed in this run. */ invocations: number; /** Rows that passed dedup and were eligible for storage. */ candidates: number; /** Rows successfully written to brain_learnings or brain_patterns. */ promoted: number; /** Per-reason rejection counts. */ rejected: { already_fulfilled: number; store_error: number; no_narrative: number; dedup_hash: number; other: number; }; } /** Extended result returned by runConsolidation. */ export interface RunConsolidationResult { /** Entries merged by dedup pass. */ deduplicated: number; /** Entries whose quality score was recomputed. */ qualityRecomputed: number; /** Tier promotions applied. */ tierPromotions: PromotionResult; /** Contradiction pairs found. */ contradictions: number; /** Entries soft-evicted (low quality medium-term). */ softEvicted: number; /** Graph edges strengthened (BRAIN brain_page_edges, Step 6). */ edgesStrengthened: number; /** NEXUS nexus_relations edges strengthened by co-access (Step 6b, T998). */ nexusEdgesStrengthened: number; /** NEXUS nexus_relations edges decayed by plasticity time-decay (Step 6c, T1072). */ nexusEdgesDecayed?: number; /** Summary nodes generated. */ summariesGenerated: number; /** Code↔memory graph links created. */ graphLinksCreated?: number; /** * Auto-extract promotion result from Step 3b (T1903). * Counts how many promotion_log entries were fulfilled (written to brain_learnings/brain_patterns). */ autoExtractPromotion?: AutoExtractMetrics; /** * Pattern dedup result from Step 4b (T1896). * Counts near-duplicate brain_patterns rows removed in this consolidation cycle. */ patternDeduped?: number; /** R-STDP reward backfill result from step 9a (T681). */ rewardBackfilled?: { rowsLabeled: number; rowsSkipped: number; }; /** STDP plasticity result from step 9b. */ stdpPlasticity?: { ltpEvents: number; ltdEvents: number; edgesCreated: number; pairsExamined: number; }; /** * Homeostatic decay result from step 9c (T690). * Counts edges that had their weight reduced (decayed) and edges deleted (pruned). */ homeostaticDecay?: { edgesDecayed: number; edgesPruned: number; }; /** * Retention prune result from step 9d (T10348). * Counts rows deleted from brain_plasticity_events and brain_weight_history. * Populated when retention pruning ran. `skipped:true` indicates the * operator-override env var (`CLEO_BRAIN_HISTORY_RETENTION_DAYS=0`) * disabled the step. */ historyRetention?: { plasticityEventsDeleted: number; weightHistoryDeleted: number; skipped: boolean; }; /** * Outcome correlation result from Step 9a.5 (T994). * Populated when correlateOutcomes ran during consolidation. */ outcomeCorrelation?: { boosted: number; penalized: number; flaggedForPruning: number; }; /** * LLM-driven sleep consolidation result from Step 10 (T734). * Populated when sleep consolidation ran. Absent when skipped (disabled or no LLM). */ sleepConsolidation?: { ran: boolean; merged: number; pruned: number; patternsGenerated: number; insightsStored: number; }; /** * Hard-sweeper result from Step 9f (T995). * Deletes confirmed noise: prune_candidate=1 AND quality<0.2 AND citations=0 AND age>30d. * Populated when the step ran (always in runConsolidation — best-effort). */ pruneSweep?: { deleted: number; wouldDelete: number; dryRun: boolean; }; /** * Tier-2 attention consolidation result from Step 9g (T11382 · Epic T11289). * * The dream-cycle's review of the `brain_attention` working-memory buffer: * salient entries promoted to durable memory via the sticky-convert conduit, * noise/expired entries discarded via the homeostatic sweep, mid-salience * entries kept open. Populated when the step ran (always in runConsolidation — * best-effort). See `attention-consolidate.ts`. */ attentionConsolidation?: { /** Live attention entries reviewed this cycle. */ reviewed: number; /** Entries promoted to durable memory via the conduit. */ promoted: number; /** Entries left `open` for the next cycle. */ kept: number; /** Entries swept to `discarded` (TTL/decay). */ discarded: number; }; } /** * Run the full sleep-time consolidation pipeline. * * This is the "Letta OS sleep-time compute" pattern — consolidation runs * during idle time (after session end), never during active work. * * Steps (in order): * 1. Deduplication — merge entries with >0.85 content similarity * 2. Quality recompute — recalculate scores with current age/citations * 3. Tier promotion — runTierPromotion() * 4. Contradiction detection — from brain-consolidator * 5. Soft eviction — invalidate low-quality medium-term entries * 6. Graph edge strengthening — increment weight on frequently-traversed edges * 7. Summary generation — existing consolidateMemories() for large clusters * 8. Code↔memory graph linking * 9a. R-STDP reward backfill — assign reward_signal from task outcomes (T681) * 9a.5. Outcome correlation — correlateOutcomes quality adjustments (T994) * 9b. STDP timing-dependent plasticity — apply Δw using reward_signal (T679) * 9c. Homeostatic decay — synaptic scaling + pruning (T690) * 9d. History retention — prune brain_plasticity_events + brain_weight_history (T10348) * 9e. Consolidation event log — INSERT into brain_consolidation_events (T694) * 9f. Hard-sweeper — DELETE prune_candidate=1 + quality<0.2 + citations=0 + age>30d (T995) * * All steps are BEST-EFFORT — any step failure is caught and logged to console.warn. * * @param projectRoot - Project root directory for brain.db resolution * @param sessionId - Active session ID, passed to backfillRewardSignals (Step 9a). * If null/undefined, Step 9a is a no-op (no task correlation available). * @param trigger - What triggered this consolidation run (for observability). * Defaults to 'session_end'. Written to brain_consolidation_events. * @returns Aggregated counts from each consolidation step */ export declare function runConsolidation(projectRoot: string, sessionId?: string | null, trigger?: 'session_end' | 'maintenance' | 'scheduled' | 'manual'): Promise; /** * Fulfill pending entries in brain_promotion_log by inserting them into * brain_learnings or brain_patterns. * * `promoteObservationsToTyped` (Step 3 of runConsolidation) only writes audit * rows to brain_promotion_log — it does NOT insert into the typed tables. * This step reads those pending log rows and performs the actual inserts. * * Idempotent: rows that have already been fulfilled (fulfilled_at IS NOT NULL) * are skipped. * * @param projectRoot - Project root for brain.db resolution * @returns AutoExtractMetrics describing what happened * * @task T1903 */ export declare function fulfillPromotionLog(projectRoot: string): Promise; declare function strengthenCoRetrievedEdges(projectRoot: string): Promise; /** * Test export of strengthenCoRetrievedEdges for vitest (T790). * @internal for testing only */ export declare const strengthenCoRetrievedEdgesForTest: typeof strengthenCoRetrievedEdges; export {}; //# sourceMappingURL=brain-lifecycle.d.ts.map