@timmeck/brain-core 2.36.51 → 2.36.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,6 +48,7 @@ export class ResearchOrchestrator {
48
48
  dataScout = null;
49
49
  simulationEngine = null;
50
50
  memoryPalace = null;
51
+ memoryPalaceRagRegistered = false;
51
52
  goalEngine = null;
52
53
  evolutionEngine = null;
53
54
  reasoningEngine = null;
@@ -76,6 +77,7 @@ export class ResearchOrchestrator {
76
77
  consensusEngine = null;
77
78
  traceCollector = null;
78
79
  lastAutoMissionTime = 0;
80
+ lastGoalMissionTime = 0;
79
81
  onSuggestionCallback = null;
80
82
  db;
81
83
  brainName;
@@ -763,6 +765,14 @@ export class ResearchOrchestrator {
763
765
  if (resolved > 0) {
764
766
  this.log.info(`[orchestrator] Predictions resolved: ${resolved}`);
765
767
  ts?.emit('prediction', 'predicting', `Resolved ${resolved} prediction${resolved > 1 ? 's' : ''}`);
768
+ // Cross-module: Prediction→Goal — feed accuracy into goal tracking
769
+ if (this.goalEngine) {
770
+ try {
771
+ const summary = this.predictionEngine.getSummary();
772
+ this.goalEngine.recordProgress(this.cycleCount, { predictionAccuracy: summary.accuracy_rate });
773
+ }
774
+ catch { /* goal recording non-critical */ }
775
+ }
766
776
  }
767
777
  ts?.emit('prediction', 'predicting', 'Generating new predictions...');
768
778
  const newPredictions = this.predictionEngine.autoPredictAll();
@@ -843,8 +853,8 @@ export class ResearchOrchestrator {
843
853
  }
844
854
  this.feedExperimentMeasurements(anomalies.length, insights.length);
845
855
  }
846
- // 13. Periodic Dream Consolidation: don't wait for idle, consolidate every 10 cycles
847
- if (this.dreamEngine && this.cycleCount % 10 === 0) {
856
+ // 13. Periodic Dream Consolidation: don't wait for idle, consolidate every 5 cycles
857
+ if (this.dreamEngine && this.cycleCount % 5 === 0) {
848
858
  ts?.emit('dream', 'dreaming', 'Feeding knowledge into memories for consolidation...');
849
859
  try {
850
860
  // Feed current knowledge into memories table so consolidation has material
@@ -963,6 +973,20 @@ export class ResearchOrchestrator {
963
973
  metadata: { type: c.type, statement_a: c.statement_a.substring(0, 100), statement_b: c.statement_b.substring(0, 100) },
964
974
  });
965
975
  }
976
+ // Cross-module: Narrative→Emotion — contradictions signal cognitive dissonance
977
+ if (this.emotionalModel && highSeverity.length > 0) {
978
+ try {
979
+ // Record contradiction observations so sense() picks up stress/frustration
980
+ this.hypothesisEngine.observe({
981
+ source: this.brainName,
982
+ type: 'high_severity_contradiction',
983
+ value: highSeverity.length,
984
+ timestamp: now,
985
+ metadata: { contradictionCount: contradictions.length, highSeverityCount: highSeverity.length },
986
+ });
987
+ }
988
+ catch { /* emotional signaling non-critical */ }
989
+ }
966
990
  // 17a. Actively resolve contradictions — lower confidence of weaker side
967
991
  let resolved = 0;
968
992
  for (const c of highSeverity.slice(0, 5)) {
@@ -1354,8 +1378,8 @@ export class ResearchOrchestrator {
1354
1378
  this.log.warn(`[orchestrator] Step 25 error: ${err.message}`);
1355
1379
  }
1356
1380
  }
1357
- // Step 26: Dream Retrospective — analyze pruning regret (every 10 cycles)
1358
- if (this.dreamEngine && this.cycleCount % 10 === 0) {
1381
+ // Step 26: Dream Retrospective — analyze pruning regret (every 5 cycles)
1382
+ if (this.dreamEngine && this.cycleCount % 5 === 0) {
1359
1383
  try {
1360
1384
  ts?.emit('orchestrator', 'reflecting', 'Step 26: Analyzing dream retrospective...', 'routine');
1361
1385
  const retrospectives = this.dreamEngine.analyzeRetrospective(5);
@@ -1465,8 +1489,8 @@ export class ResearchOrchestrator {
1465
1489
  this.log.warn(`[orchestrator] Step 30 error: ${err.message}`);
1466
1490
  }
1467
1491
  }
1468
- // Step 31: Meta-Trends — record system-wide trend data every cycle
1469
- if (this.metaCognitionLayer) {
1492
+ // Step 31: Meta-Trends — record system-wide trend data (every 5 cycles)
1493
+ if (this.metaCognitionLayer && this.cycleCount % 5 === 0) {
1470
1494
  try {
1471
1495
  const totalPrinciples = this.knowledgeDistiller.getPrinciples(undefined, 1000).length;
1472
1496
  const hypothesisSummary = this.hypothesisEngine.getSummary();
@@ -1508,6 +1532,15 @@ export class ResearchOrchestrator {
1508
1532
  significance: 'routine',
1509
1533
  data: { simulation: sim },
1510
1534
  });
1535
+ // Cross-module: Simulation→Prediction — feed predicted outcomes as synthetic metrics
1536
+ if (this.predictionEngine && sim.predictedOutcomes.length > 0) {
1537
+ try {
1538
+ for (const outcome of sim.predictedOutcomes) {
1539
+ this.predictionEngine.recordMetric(`sim_${outcome.metric}`, outcome.predicted * outcome.confidence, 'metric');
1540
+ }
1541
+ }
1542
+ catch { /* simulation metric recording non-critical */ }
1543
+ }
1511
1544
  if (this.metaCognitionLayer)
1512
1545
  this.metaCognitionLayer.recordStep('simulation', this.cycleCount, { predictions: sim.predictedOutcomes.length });
1513
1546
  }
@@ -1531,6 +1564,19 @@ export class ResearchOrchestrator {
1531
1564
  data: { memoryPalace: result },
1532
1565
  });
1533
1566
  }
1567
+ // Cross-module: MemoryPalace→RAG — index new connections for semantic search (once)
1568
+ if (result.newConnections > 0 && this.ragIndexer && !this.memoryPalaceRagRegistered) {
1569
+ try {
1570
+ this.ragIndexer.addSource({
1571
+ collection: 'memory_palace',
1572
+ query: `SELECT id, source_type || ':' || source_id || ' —[' || relation || ']→ ' || target_type || ':' || target_id as text FROM knowledge_connections ORDER BY strength DESC LIMIT 100`,
1573
+ textColumns: ['text'],
1574
+ idColumn: 'id',
1575
+ });
1576
+ this.memoryPalaceRagRegistered = true;
1577
+ }
1578
+ catch { /* source registration non-critical */ }
1579
+ }
1534
1580
  // Check for isolated knowledge
1535
1581
  const isolated = this.memoryPalace.getIsolatedNodes();
1536
1582
  if (isolated.length > 5) {
@@ -1559,6 +1605,22 @@ export class ResearchOrchestrator {
1559
1605
  if (this.goalEngine && this.cycleCount % this.reflectEvery === 0) {
1560
1606
  try {
1561
1607
  ts?.emit('orchestrator', 'reflecting', 'Step 35: Checking goals and suggesting new ones...', 'routine');
1608
+ // 35a — Bootstrap default goals on first reflect cycle
1609
+ if (this.cycleCount <= this.reflectEvery) {
1610
+ const bootstrapped = this.goalEngine.bootstrapDefaults(this.cycleCount);
1611
+ if (bootstrapped.length > 0) {
1612
+ this.journal.write({
1613
+ type: 'discovery',
1614
+ title: `Bootstrapped ${bootstrapped.length} default goals`,
1615
+ content: bootstrapped.map(g => `"${g.title}" (${g.metricName}→${g.targetValue})`).join(', '),
1616
+ tags: [this.brainName, 'goal', 'bootstrap'],
1617
+ references: [],
1618
+ significance: 'notable',
1619
+ data: { goals: bootstrapped },
1620
+ });
1621
+ }
1622
+ }
1623
+ // 35b — Check goals for achievement/failure
1562
1624
  const { achieved, failed } = this.goalEngine.checkGoals(this.cycleCount);
1563
1625
  for (const g of achieved) {
1564
1626
  this.journal.write({
@@ -1570,6 +1632,19 @@ export class ResearchOrchestrator {
1570
1632
  significance: 'notable',
1571
1633
  data: { goal: g },
1572
1634
  });
1635
+ // 35c — Ratchet: create harder successor goal
1636
+ const successor = this.goalEngine.ratchetGoal(g, this.cycleCount);
1637
+ if (successor) {
1638
+ this.journal.write({
1639
+ type: 'discovery',
1640
+ title: `Goal ratcheted: "${successor.title}"`,
1641
+ content: `New target: ${successor.metricName}=${successor.targetValue} (baseline=${successor.baselineValue})`,
1642
+ tags: [this.brainName, 'goal', 'ratchet'],
1643
+ references: [],
1644
+ significance: 'routine',
1645
+ data: { goal: successor },
1646
+ });
1647
+ }
1573
1648
  }
1574
1649
  for (const g of failed) {
1575
1650
  this.journal.write({
@@ -1582,6 +1657,22 @@ export class ResearchOrchestrator {
1582
1657
  data: { goal: g },
1583
1658
  });
1584
1659
  }
1660
+ // 35d — Goal-driven missions for struggling goals (2h cooldown)
1661
+ if (this.missionEngine && (Date.now() - this.lastGoalMissionTime) > 7_200_000) {
1662
+ const activeGoals = this.goalEngine.listGoals('active');
1663
+ for (const g of activeGoals) {
1664
+ const progress = this.goalEngine.getProgress(g.id);
1665
+ if (progress && progress.trend !== 'improving' && progress.dataPoints >= 5) {
1666
+ try {
1667
+ this.missionEngine.createMission(`Research: improve ${g.metricName} for goal "${g.title}" (current=${g.currentValue}, target=${g.targetValue})`);
1668
+ this.lastGoalMissionTime = Date.now();
1669
+ this.log.info(`[orchestrator] Goal-driven mission created for "${g.title}"`);
1670
+ }
1671
+ catch { /* mission engine full or error */ }
1672
+ break; // max 1 mission per check
1673
+ }
1674
+ }
1675
+ }
1585
1676
  // Suggest new goals
1586
1677
  const suggestions = this.goalEngine.suggestGoals(this.cycleCount);
1587
1678
  for (const s of suggestions.slice(0, 2)) {
@@ -1642,6 +1733,19 @@ export class ResearchOrchestrator {
1642
1733
  data: { chain },
1643
1734
  });
1644
1735
  insights++;
1736
+ // Cross-module: Reasoning→Hypothesis — high-confidence chains become testable hypotheses
1737
+ if (this.hypothesisEngine && chain.final_confidence > 0.5) {
1738
+ try {
1739
+ this.hypothesisEngine.propose({
1740
+ statement: chain.conclusion,
1741
+ type: 'correlation',
1742
+ source: 'reasoning_engine',
1743
+ variables: [q],
1744
+ condition: { type: 'correlation', params: { strategy: 'inference_chain', chain_id: chain.id, confidence: chain.final_confidence } },
1745
+ });
1746
+ }
1747
+ catch { /* dedup or other constraint — non-critical */ }
1748
+ }
1645
1749
  }
1646
1750
  // Abduce on surprising observations
1647
1751
  const explanations = this.reasoningEngine.abduce(q);
@@ -1675,6 +1779,19 @@ export class ResearchOrchestrator {
1675
1779
  for (const rec of recs) {
1676
1780
  ts?.emit('emotional', 'reflecting', `[${mood.mood}] ${rec}`, 'notable');
1677
1781
  }
1782
+ // Cross-module: Emotional→Attention — high arousal boosts attention on active topics
1783
+ if (mood.arousal > 0.7 && this.attentionEngine) {
1784
+ try {
1785
+ const topTopics = this.attentionEngine.getTopTopics?.(3) ?? [];
1786
+ for (const t of topTopics) {
1787
+ this.attentionEngine.setFocus(t.topic, mood.arousal * 2.0);
1788
+ }
1789
+ if (topTopics.length > 0) {
1790
+ this.log.info(`[orchestrator] High arousal (${mood.arousal.toFixed(2)}) → boosted attention on ${topTopics.length} topics`);
1791
+ }
1792
+ }
1793
+ catch { /* attention boost non-critical */ }
1794
+ }
1678
1795
  if (this.metaCognitionLayer)
1679
1796
  this.metaCognitionLayer.recordStep('emotional_model', this.cycleCount, { insights: 1 });
1680
1797
  }
@@ -1791,8 +1908,8 @@ export class ResearchOrchestrator {
1791
1908
  }
1792
1909
  }
1793
1910
  // ── Intelligence Upgrade Steps (Sessions 55-65) ─────────
1794
- // Step 42: FactExtractor — extract typed facts from recent insights (every 5 cycles)
1795
- if (this.factExtractor && this.knowledgeGraph && this.cycleCount % this.distillEvery === 0) {
1911
+ // Step 42: FactExtractor — extract typed facts from recent insights (every 3 cycles)
1912
+ if (this.factExtractor && this.knowledgeGraph && this.cycleCount % 3 === 0) {
1796
1913
  try {
1797
1914
  ts?.emit('fact_extractor', 'analyzing', 'Step 42: Extracting facts from insights...', 'routine');
1798
1915
  let factsAdded = 0;
@@ -1988,6 +2105,18 @@ export class ResearchOrchestrator {
1988
2105
  }
1989
2106
  if (taught > 0) {
1990
2107
  ts?.emit('teaching', 'discovering', `Taught ${taught} principle(s) to peer brain(s)`, 'routine');
2108
+ // Cross-module: Teaching→Consensus — propose teaching packages for multi-brain review
2109
+ if (this.consensusEngine && taught >= 2) {
2110
+ try {
2111
+ const topPrinciples = principles.filter(p => (p.confidence ?? 0) >= 0.7).slice(0, 3);
2112
+ this.consensusEngine.propose({
2113
+ type: 'teaching_review',
2114
+ description: `Review ${taught} principles for teaching: ${topPrinciples.map(p => p.statement.substring(0, 60)).join('; ')}`,
2115
+ options: ['adopt', 'reject', 'defer'],
2116
+ });
2117
+ }
2118
+ catch { /* consensus proposal non-critical */ }
2119
+ }
1991
2120
  }
1992
2121
  if (this.metaCognitionLayer)
1993
2122
  this.metaCognitionLayer.recordStep('teaching', this.cycleCount, { insights: taught });
@@ -2038,8 +2167,8 @@ export class ResearchOrchestrator {
2038
2167
  this.log.warn(`[orchestrator] Step 49 error: ${err.message}`);
2039
2168
  }
2040
2169
  }
2041
- // Step 50: FeatureRecommender — detect needs, match features, build connections (every 15 cycles)
2042
- if (this.featureRecommender && this.cycleCount % 15 === 0) {
2170
+ // Step 50: FeatureRecommender — detect needs, match features, build connections (every 20 cycles)
2171
+ if (this.featureRecommender && this.cycleCount % 20 === 0) {
2043
2172
  try {
2044
2173
  ts?.emit('feature_recommender', 'analyzing', 'Step 50: Scanning for feature needs & connections...', 'routine');
2045
2174
  const recResult = await this.featureRecommender.runCycle();
@@ -2973,7 +3102,31 @@ export class ResearchOrchestrator {
2973
3102
  }
2974
3103
  catch { /* featureRecommender not ready */ }
2975
3104
  }
2976
- // ── Source B: Existing suggestions (filtered skip AutoResponder noise) ──
3105
+ // ── Source B: CodeHealth issues SelfMod suggestions ──
3106
+ if (this.codeHealthMonitor) {
3107
+ try {
3108
+ const health = this.codeHealthMonitor.getStatus();
3109
+ if (health.lastScan && health.lastScan.techDebtScore > 60) {
3110
+ const scan = health.lastScan;
3111
+ const issues = [];
3112
+ if (scan.complexityScore > 70)
3113
+ issues.push(`high complexity (${scan.complexityScore.toFixed(0)})`);
3114
+ if (scan.duplicationScore > 30)
3115
+ issues.push(`code duplication (${scan.duplicationScore.toFixed(0)})`);
3116
+ if (scan.testRatio < 0.3)
3117
+ issues.push(`low test coverage (${(scan.testRatio * 100).toFixed(0)}%)`);
3118
+ if (issues.length > 0) {
3119
+ return {
3120
+ title: `Reduce tech debt (score: ${scan.techDebtScore.toFixed(0)})`,
3121
+ problem: `Code health scan detected: ${issues.join(', ')}. Tech debt score is ${scan.techDebtScore.toFixed(1)}/100.`,
3122
+ targetFiles: this.findTargetFilesForNeed('code quality'),
3123
+ };
3124
+ }
3125
+ }
3126
+ }
3127
+ catch { /* code health not ready */ }
3128
+ }
3129
+ // ── Source C: Existing suggestions (filtered — skip AutoResponder noise) ──
2977
3130
  if (!this.selfScanner)
2978
3131
  return null;
2979
3132
  const suggestions = this.generateSelfImprovementSuggestions();