@timmeck/brain-core 2.36.63 → 2.36.64

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.
@@ -637,6 +637,16 @@ export class ResearchOrchestrator {
637
637
  }
638
638
  ts?.emit('hypothesis', 'analyzing', 'Testing pending hypotheses...');
639
639
  const testResults = this.hypothesisEngine.testAll();
640
+ // Quality filter: auto-reject weak hypotheses (confidence < 0.3 after testing)
641
+ const weak = testResults.filter(r => r.newStatus === 'testing' && r.confidence < 0.3 && (r.evidenceFor + r.evidenceAgainst) >= 3);
642
+ for (const w of weak) {
643
+ try {
644
+ this.db.prepare("UPDATE hypotheses SET status = 'rejected' WHERE id = ?").run(w.hypothesisId);
645
+ }
646
+ catch { /* best effort */ }
647
+ }
648
+ if (weak.length > 0)
649
+ this.log.debug(`[orchestrator] Rejected ${weak.length} weak hypotheses (confidence < 0.3)`);
640
650
  const confirmed = testResults.filter(r => r.newStatus === 'confirmed');
641
651
  const rejected = testResults.filter(r => r.newStatus === 'rejected');
642
652
  if (confirmed.length > 0 || rejected.length > 0) {
@@ -821,6 +831,12 @@ export class ResearchOrchestrator {
821
831
  catch { /* goal recording non-critical */ }
822
832
  }
823
833
  }
834
+ // Diagnostics: log prediction stats for debugging stale accuracy
835
+ try {
836
+ const summary = this.predictionEngine.getSummary();
837
+ this.log.debug(`[orchestrator] Prediction stats: total=${summary.total_predictions}, resolved=${summary.resolved ?? 'N/A'}, pending=${summary.pending ?? 'N/A'}, accuracy=${(summary.accuracy_rate * 100).toFixed(1)}%`);
838
+ }
839
+ catch { /* non-critical */ }
824
840
  ts?.emit('prediction', 'predicting', 'Generating new predictions...');
825
841
  const newPredictions = this.predictionEngine.autoPredictAll();
826
842
  if (newPredictions.length > 0) {
@@ -1244,6 +1260,26 @@ export class ResearchOrchestrator {
1244
1260
  this.log.debug(`[orchestrator] Auto-mission check error: ${err.message}`);
1245
1261
  }
1246
1262
  }
1263
+ // 18c. Curiosity Auto-Answer: periodically answer unanswered questions via NarrativeEngine
1264
+ if (this.curiosityEngine && this.narrativeEngine && this.cycleCount % (this.reflectEvery * 5) === 0) {
1265
+ try {
1266
+ const questions = this.curiosityEngine.getQuestions(10);
1267
+ const unanswered = questions.filter(q => !q.answered).slice(0, 2);
1268
+ for (const q of unanswered) {
1269
+ const answer = this.narrativeEngine.ask(q.question);
1270
+ if (answer.sources.length > 0 && q.id) {
1271
+ this.curiosityEngine.answerQuestion(q.id, answer.answer);
1272
+ this.log.debug(`[orchestrator] Auto-answered curiosity question #${q.id}: "${q.question.substring(0, 60)}"`);
1273
+ }
1274
+ }
1275
+ if (unanswered.length > 0) {
1276
+ ts?.emit('curiosity', 'exploring', `Auto-answered ${unanswered.length} curiosity question(s)`, 'routine');
1277
+ }
1278
+ }
1279
+ catch (err) {
1280
+ this.log.debug(`[orchestrator] Curiosity auto-answer error: ${err.message}`);
1281
+ }
1282
+ }
1247
1283
  // 19. Emergence Tracking: detect emergent patterns + record complexity metrics
1248
1284
  if (this.emergenceEngine && this.cycleCount % this.reflectEvery === 0) {
1249
1285
  ts?.emit('emergence', 'exploring', 'Scanning for emergent behaviors...');
@@ -2442,8 +2478,8 @@ export class ResearchOrchestrator {
2442
2478
  this.log.warn(`[orchestrator] Step 57 (roadmap) error: ${err.message}`);
2443
2479
  }
2444
2480
  }
2445
- // Step 58: CreativeEngine — cross-pollination (every 20 cycles)
2446
- if (this.creativeEngine && this.cycleCount % 20 === 0) {
2481
+ // Step 58: CreativeEngine — cross-pollination (every reflectEvery cycles)
2482
+ if (this.creativeEngine && this.cycleCount % this.reflectEvery === 0) {
2447
2483
  try {
2448
2484
  const debugInfo = this.creativeEngine.getDebugInfo();
2449
2485
  this.log.debug(`[orchestrator] Step 58: ${debugInfo.principlesCount} principles, domains: ${JSON.stringify(debugInfo.domains)}`);
@@ -2463,8 +2499,12 @@ export class ResearchOrchestrator {
2463
2499
  });
2464
2500
  }
2465
2501
  else {
2466
- ts?.emit('creative', 'reflecting', `Step 58: 0 insights (${debugInfo.principlesCount} principles, ${Object.keys(debugInfo.domains).length} domains)`, 'notable');
2502
+ const domainCount = Object.keys(debugInfo.domains).length;
2503
+ this.log.debug(`[orchestrator] Step 58: 0 insights — ${domainCount} domain(s) (need 2+), ${debugInfo.principlesCount} principles`);
2504
+ ts?.emit('creative', 'reflecting', `Step 58: 0 insights (${debugInfo.principlesCount} principles, ${domainCount} domains)`, 'notable');
2467
2505
  }
2506
+ if (this.metaCognitionLayer)
2507
+ this.metaCognitionLayer.recordStep('creative_engine', this.cycleCount, { insights: insights.length });
2468
2508
  }
2469
2509
  catch (err) {
2470
2510
  this.log.warn(`[orchestrator] Step 58 (creative) error: ${err.message}`);
@@ -3548,6 +3588,7 @@ export class ResearchOrchestrator {
3548
3588
  if (this.featureRecommender) {
3549
3589
  try {
3550
3590
  const wishes = this.featureRecommender.getWishlist('matched');
3591
+ this.log.debug(`[selfmod] Source A: ${wishes.length} matched wishes`);
3551
3592
  const actionable = wishes.find(w => w.priority >= 0.5 && w.matchScore >= 0.3);
3552
3593
  if (actionable) {
3553
3594
  // Try to get reference code from matched feature
@@ -3569,6 +3610,9 @@ export class ResearchOrchestrator {
3569
3610
  }
3570
3611
  catch { /* featureRecommender not ready */ }
3571
3612
  }
3613
+ else {
3614
+ this.log.debug('[selfmod] Source A skipped: no featureRecommender');
3615
+ }
3572
3616
  // ── Source B: CodeHealth issues → SelfMod suggestions ──
3573
3617
  if (this.codeHealthMonitor) {
3574
3618
  try {
@@ -3593,12 +3637,19 @@ export class ResearchOrchestrator {
3593
3637
  }
3594
3638
  catch { /* code health not ready */ }
3595
3639
  }
3640
+ else {
3641
+ this.log.debug('[selfmod] Source B skipped: no codeHealthMonitor');
3642
+ }
3596
3643
  // ── Source C: Existing suggestions (filtered — skip AutoResponder noise) ──
3597
- if (!this.selfScanner)
3644
+ if (!this.selfScanner) {
3645
+ this.log.debug('[selfmod] Source C skipped: no selfScanner');
3598
3646
  return null;
3647
+ }
3599
3648
  const suggestions = this.generateSelfImprovementSuggestions();
3600
- if (suggestions.length === 0)
3649
+ if (suggestions.length === 0) {
3650
+ this.log.debug('[selfmod] Source C: 0 suggestions from generateSelfImprovementSuggestions()');
3601
3651
  return null;
3652
+ }
3602
3653
  // Engine name → module file mapping heuristics
3603
3654
  const engineMap = {
3604
3655
  SelfObserver: ['research/self-observer'],