noormme 1.0.5 → 1.0.6

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.
@@ -21,10 +21,9 @@ export declare class GovernanceManager {
21
21
  issues: string[];
22
22
  }>;
23
23
  /**
24
- * Retrieves the ID of the currently active persona.
25
- * Assumes there's a 'personas' table with an 'is_active' flag.
24
+ * Retrieves the currently active persona.
26
25
  */
27
- private getActivePersonaId;
26
+ private getActivePersona;
28
27
  /**
29
28
  * Trigger autonomous remediation steps
30
29
  */
@@ -63,13 +63,15 @@ class GovernanceManager {
63
63
  }
64
64
  if (issues.length > 0) {
65
65
  console.warn(`[GovernanceManager] Audit failed: ${issues.join(', ')}`);
66
- // Critical Self-Healing: If success rate is catastrophically low, trigger strategic rollback
67
- if (success < 0.3) {
68
- const activePersonaId = await this.getActivePersonaId();
69
- if (activePersonaId) {
70
- console.error(`[GovernanceManager] Catastrophic failure detected. Triggering emergency rollback for persona ${activePersonaId}`);
71
- await this.cortex.strategy.rollbackPersona(activePersonaId);
72
- issues.push(`Self-Healed: Triggered emergency rollback for persona ${activePersonaId}`);
66
+ // Critical Self-Healing: If persona is in verification or success rate is catastrophically low
67
+ const activePersona = await this.getActivePersona();
68
+ if (activePersona) {
69
+ const isVerifying = activePersona.metadata?.evolution_status === 'verifying';
70
+ if (isVerifying || success < 0.3) {
71
+ const reason = isVerifying ? `Verification failed` : `Catastrophic failure`;
72
+ console.error(`[GovernanceManager] ${reason} detected. Triggering emergency rollback for persona ${activePersona.id}`);
73
+ await this.cortex.strategy.rollbackPersona(activePersona.id);
74
+ issues.push(`Self-Healed: Triggered emergency rollback for persona ${activePersona.id} (${reason})`);
73
75
  }
74
76
  }
75
77
  // Automatically record a "Panic" reflection
@@ -83,16 +85,20 @@ class GovernanceManager {
83
85
  };
84
86
  }
85
87
  /**
86
- * Retrieves the ID of the currently active persona.
87
- * Assumes there's a 'personas' table with an 'is_active' flag.
88
+ * Retrieves the currently active persona.
88
89
  */
89
- async getActivePersonaId() {
90
- const activePersona = await this.db
90
+ async getActivePersona() {
91
+ const active = await this.db
91
92
  .selectFrom(this.personasTable)
92
- .select('id')
93
- .where('is_active', '=', true)
93
+ .selectAll()
94
+ .where('name', '=', 'default') // Or however we track the "active" one
94
95
  .executeTakeFirst();
95
- return activePersona?.id || null;
96
+ if (!active)
97
+ return null;
98
+ return {
99
+ ...active,
100
+ metadata: typeof active.metadata === 'string' ? JSON.parse(active.metadata) : (active.metadata || {})
101
+ };
96
102
  }
97
103
  /**
98
104
  * Trigger autonomous remediation steps
@@ -55,16 +55,22 @@ export declare class StrategicPlanner {
55
55
  */
56
56
  mutateStrategy(): Promise<string[]>;
57
57
  /**
58
- * Initiate a mutation by creating a "Challenger" persona instead of overwriting the original.
58
+ * Directly mutate a persona and put it into 'verifying' status.
59
+ * Performs a pre-flight conflict check and injects distilled lessons.
59
60
  */
60
- private initiateAblationMutation;
61
+ private applyDirectMutation;
61
62
  /**
62
- * Evaluate a challenger. If it performs better than the champion, promote it.
63
+ * Check if a persona in verification should be stabilized or rolled back.
64
+ * Uses dynamic statistical variance and adaptive meta-tuning.
63
65
  */
64
- private evaluateChallenger;
65
- private promoteChallenger;
66
+ private verifyEvolution;
67
+ /**
68
+ * Analyze recent actions for specific failure patterns.
69
+ */
70
+ private analyzeFailurePatterns;
66
71
  /**
67
72
  * Generate a performance report for a specific persona.
73
+ * Uses dynamic satisfaction thresholds based on global population stats (Phase 6).
68
74
  */
69
75
  analyzePersona(id: string | number): Promise<PerformanceReport>;
70
76
  /**
@@ -27,22 +27,42 @@ class StrategicPlanner {
27
27
  */
28
28
  async mutateStrategy() {
29
29
  const mutations = [];
30
+ // 0. Pre-Flight System Health Check (Phase 4)
31
+ const tests = await this.cortex.tests.runAllProbes();
32
+ const failedTests = tests.filter(t => !t.success);
33
+ if (failedTests.length > 0) {
34
+ console.warn(`[StrategicPlanner] Mutation cycle aborted. System health probes failed: ${failedTests.map(t => t.name).join(', ')}`);
35
+ return [];
36
+ }
30
37
  const personas = await this.typedDb
31
38
  .selectFrom(this.personasTable)
32
39
  .selectAll()
33
40
  .execute();
34
41
  for (const p of personas) {
35
42
  const persona = this.parsePersona(p);
36
- // If it's a challenger, check if it's ready for promotion or disposal
37
- if (persona.metadata?.isChallenger) {
38
- const promotionResult = await this.evaluateChallenger(persona);
39
- if (promotionResult)
40
- mutations.push(promotionResult);
43
+ // 1. Verification Monitor
44
+ if (persona.metadata?.evolution_status === 'verifying') {
45
+ const result = await this.verifyEvolution(persona);
46
+ if (result)
47
+ mutations.push(result);
41
48
  continue;
42
49
  }
50
+ // 2. Failure Analysis (Intelligence Refinement)
51
+ const failures = await this.analyzeFailurePatterns(persona.id);
43
52
  const report = await this.analyzePersona(persona.id);
44
- if (report.recommendation !== 'maintain') {
45
- const result = await this.initiateAblationMutation(persona, report);
53
+ // 3. Blacklist Check (Local & Global Phase 5)
54
+ const lastMutation = persona.metadata?.last_failed_mutation;
55
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
56
+ const isGloballyBlacklisted = allPersonas.some(p => {
57
+ const mp = this.parsePersona(p);
58
+ return mp.metadata?.last_failed_mutation?.type === report.recommendation && (Date.now() - (mp.metadata?.last_failed_mutation?.timestamp || 0) < 3600000);
59
+ });
60
+ if (isGloballyBlacklisted || (lastMutation && report.recommendation === lastMutation.type && (Date.now() - lastMutation.timestamp < 86400000))) {
61
+ console.log(`[StrategicPlanner] Skipping blacklisted mutation ${report.recommendation} for persona ${persona.id} (Global=${isGloballyBlacklisted})`);
62
+ continue;
63
+ }
64
+ if (report.recommendation !== 'maintain' || failures.length > 0) {
65
+ const result = await this.applyDirectMutation(persona, report, failures);
46
66
  if (result) {
47
67
  mutations.push(result);
48
68
  }
@@ -51,110 +71,180 @@ class StrategicPlanner {
51
71
  return mutations;
52
72
  }
53
73
  /**
54
- * Initiate a mutation by creating a "Challenger" persona instead of overwriting the original.
74
+ * Directly mutate a persona and put it into 'verifying' status.
75
+ * Performs a pre-flight conflict check and injects distilled lessons.
55
76
  */
56
- async initiateAblationMutation(persona, report) {
77
+ async applyDirectMutation(persona, report, failures = []) {
57
78
  return await this.db.transaction().execute(async (trx) => {
58
- console.log(`[StrategicPlanner] Initiating A/B test for persona ${persona.id} (Recommendation: ${report.recommendation})`);
79
+ const reason = failures.length > 0 ? `Failure Patterns: ${failures.join(', ')}` : report.recommendation;
80
+ console.log(`[StrategicPlanner] Applying direct mutation to persona ${persona.id} (Reason: ${reason})`);
59
81
  let updates = {};
60
82
  let mutationType = 'role_update';
61
- switch (report.recommendation) {
62
- case 'optimize_accuracy':
63
- updates = { role: `${persona.role || ''} (Focus strictly on accuracy and step-by-step verification)`.trim() };
64
- break;
65
- case 'optimize_efficiency':
66
- updates = { policies: [...(persona.policies || []), 'timeout_reduction', 'concise_output'] };
67
- mutationType = 'policy_update';
68
- break;
69
- case 'critical_intervention':
70
- // Critical usually bypasses A/B and rolls back or forces change
71
- return await this.rollbackPersona(persona.id);
72
- default:
83
+ if (failures.length > 0) {
84
+ // Lesson-Driven Synthesis: Pull categories of lessons
85
+ const lessons = await this.cortex.reasoner.synthesizeLessons();
86
+ const relevantLessons = updates.role ? [] : (lessons['general'] || []).slice(0, 2);
87
+ updates = { role: `${persona.role || ''} (Optimized for: ${failures.join(', ')}. Patterns: ${relevantLessons.join('; ')})`.trim() };
88
+ }
89
+ else {
90
+ // Evolutionary Cross-Pollination (Phase 5)
91
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
92
+ const winningMutations = allPersonas
93
+ .map(p => this.parsePersona(p))
94
+ .filter(p => (p.metadata?.evolution_status === 'stable' || !p.metadata?.evolution_status) && p.metadata?.mutation_reason?.includes(report.recommendation));
95
+ if (winningMutations.length > 0 && Math.random() > 0.5) {
96
+ console.log(`[StrategicPlanner] Cross-Pollinating success from Persona ${winningMutations[0].id}`);
97
+ updates = { role: winningMutations[0].role || persona.role };
98
+ }
99
+ else {
100
+ switch (report.recommendation) {
101
+ case 'optimize_accuracy':
102
+ updates = { role: `${persona.role || ''} (Focus strictly on accuracy and detailed verification)`.trim() };
103
+ break;
104
+ case 'optimize_efficiency':
105
+ updates = { policies: [...(persona.policies || []), 'timeout_reduction', 'concise_output'] };
106
+ mutationType = 'policy_update';
107
+ break;
108
+ case 'critical_intervention':
109
+ return await this.rollbackPersona(persona.id);
110
+ default:
111
+ return null;
112
+ }
113
+ }
114
+ }
115
+ // 1. Predictive Conflict Detection (Pre-flight)
116
+ const proposedState = { ...persona, ...updates };
117
+ const contradictions = await this.cortex.reasoner.detectContradictions();
118
+ // If the new role contradicts existing goals, block mutation
119
+ for (const contradiction of contradictions) {
120
+ if (updates.role && contradiction.includes(updates.role.slice(0, 20))) {
121
+ console.warn(`[StrategicPlanner] Mutation blocked due to goal contradiction: ${contradiction}`);
73
122
  return null;
123
+ }
74
124
  }
75
- // Create Challenger Persona
76
- const challengerName = `${persona.name} (Challenger v${Date.now()})`;
77
- const challengerMetadata = {
78
- parentPersonaId: persona.id,
79
- isChallenger: true,
80
- challengerSince: Date.now(),
81
- mutationType
125
+ // Record mutation in history
126
+ const mutation = {
127
+ id: `mut_${Date.now()}`,
128
+ timestamp: Date.now(),
129
+ type: mutationType,
130
+ previousState: {
131
+ role: persona.role,
132
+ policies: persona.policies,
133
+ capabilities: persona.capabilities
134
+ },
135
+ newState: { ...updates },
136
+ reason: `Auto-mutation triggered by ${report.recommendation}`
137
+ };
138
+ const history = [...(persona.metadata?.mutationHistory || []), mutation];
139
+ if (history.length > 5)
140
+ history.shift();
141
+ const newMetadata = {
142
+ ...persona.metadata,
143
+ mutationHistory: history,
144
+ evolution_status: 'verifying',
145
+ mutation_reason: report.recommendation, // Hive Signal (Phase 5)
146
+ verification_started_at: Date.now(),
147
+ verification_baseline: {
148
+ successRate: report.successRate,
149
+ averageLatency: report.averageLatency
150
+ }
82
151
  };
83
152
  await trx
84
- .insertInto(this.personasTable)
85
- .values({
86
- name: challengerName,
153
+ .updateTable(this.personasTable)
154
+ .set({
87
155
  role: updates.role || persona.role,
88
- capabilities: JSON.stringify(updates.capabilities || persona.capabilities),
89
- policies: JSON.stringify(updates.policies || persona.policies),
90
- metadata: JSON.stringify(challengerMetadata),
91
- created_at: new Date(),
156
+ policies: updates.policies ? JSON.stringify(updates.policies) : undefined,
157
+ capabilities: updates.capabilities ? JSON.stringify(updates.capabilities) : undefined,
158
+ metadata: JSON.stringify(newMetadata),
92
159
  updated_at: new Date()
93
160
  })
161
+ .where('id', '=', persona.id)
94
162
  .execute();
95
- return `Created Challenger persona for ${persona.id} to test ${mutationType}`;
163
+ return `Persona ${persona.id} mutated and entering verification window for ${mutationType}.`;
96
164
  });
97
165
  }
98
166
  /**
99
- * Evaluate a challenger. If it performs better than the champion, promote it.
167
+ * Check if a persona in verification should be stabilized or rolled back.
168
+ * Uses dynamic statistical variance and adaptive meta-tuning.
100
169
  */
101
- async evaluateChallenger(challenger) {
102
- const parentId = challenger.metadata?.parentPersonaId;
103
- if (!parentId)
104
- return null;
105
- const challengerReport = await this.analyzePersona(challenger.id);
106
- const championReport = await this.analyzePersona(parentId);
107
- // Minimum sample size for promotion
108
- if (challengerReport.sampleSize < 10)
170
+ async verifyEvolution(persona) {
171
+ const report = await this.analyzePersona(persona.id);
172
+ // Adaptive Meta-Tuning: Increase window based on rollback history (Phase 4)
173
+ const rollbackHistory = persona.metadata?.rollbackHistory || [];
174
+ const recentRollbacks = rollbackHistory.filter(ts => (Date.now() - ts < 604800000)).length;
175
+ // Hive-Mind Verification Speedups (Phase 5)
176
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
177
+ const hiveTrusted = allPersonas.map(p => this.parsePersona(p)).filter(p => p.metadata?.evolution_status === 'stable' && p.metadata?.mutation_reason === (persona.metadata?.mutation_reason)).length;
178
+ let sampleSizeThreshold = 10 + (recentRollbacks * 10);
179
+ if (hiveTrusted >= 3) {
180
+ console.log(`[StrategicPlanner] Accelerating verification for Persona ${persona.id} (Hive-Mind Trusted)`);
181
+ sampleSizeThreshold = Math.max(5, Math.floor(sampleSizeThreshold / 2));
182
+ }
183
+ if (report.sampleSize < sampleSizeThreshold)
109
184
  return null;
110
- const daysActive = (Date.now() - (challenger.metadata?.challengerSince || 0)) / 86400000;
111
- if (challengerReport.successRate > championReport.successRate || (challengerReport.successRate >= championReport.successRate && challengerReport.averageLatency < championReport.averageLatency)) {
112
- // PROMOTION
113
- return await this.promoteChallenger(challenger, parentId);
185
+ const baseline = persona.metadata?.verification_baseline || { successRate: 0.8, averageLatency: 500 };
186
+ // Dynamic Variance Calculation (Intelligence Refinement)
187
+ const recentMetrics = await this.cortex.metrics.getRecentMetrics(100);
188
+ const values = recentMetrics
189
+ .filter(m => m.metricName === 'success_rate')
190
+ .map(m => Number(m.metricValue));
191
+ const mean = values.reduce((a, b) => a + b, 0) / (values.length || 1);
192
+ const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / (values.length || 1);
193
+ const stdDev = Math.sqrt(variance) || 0.1;
194
+ const zScore = (report.successRate - baseline.successRate) / (stdDev || 1);
195
+ console.log(`[StrategicPlanner] Verifying persona ${persona.id}: Success=${report.successRate.toFixed(2)} (Baseline=${baseline.successRate.toFixed(2)}, σ=${stdDev.toFixed(3)}, Z-Score=${zScore.toFixed(2)}, Threshold=${sampleSizeThreshold})`);
196
+ // 1. Early Rollback (Critical statistical drop)
197
+ if (zScore < -2.0) {
198
+ console.warn(`[StrategicPlanner] STATISTICAL DEGRADATION detected for persona ${persona.id} (Z-Score: ${zScore.toFixed(2)}). Rolling back early.`);
199
+ return await this.rollbackPersona(persona.id);
114
200
  }
115
- else if (daysActive > 7 || (challengerReport.sampleSize > 20 && challengerReport.successRate < 0.6)) {
116
- // DISPOSAL
117
- await this.db.deleteFrom(this.personasTable).where('id', '=', challenger.id).execute();
118
- return `Disposed failed challenger persona ${challenger.id}`;
201
+ // 2. Stabilization (Proven improvement or stability)
202
+ if (report.sampleSize >= (sampleSizeThreshold * 2) && zScore >= -0.5) {
203
+ console.log(`[StrategicPlanner] Evolution for persona ${persona.id} STABILIZED.`);
204
+ // Cognitive Rule Distillation (Phase 4)
205
+ if (persona.metadata?.mutation_reason?.includes('optimize_efficiency')) {
206
+ await this.cortex.rules.defineRule('all', 'all', 'audit', {
207
+ condition: 'latency > 500',
208
+ priority: 10,
209
+ metadata: { reason: `Distilled from successful persona ${persona.id} optimization` }
210
+ });
211
+ }
212
+ await this.db.updateTable(this.personasTable)
213
+ .set({ metadata: JSON.stringify({ ...persona.metadata, evolution_status: 'stable' }) })
214
+ .where('id', '=', persona.id)
215
+ .execute();
216
+ return `Evolution stabilized for persona ${persona.id}`;
217
+ }
218
+ // 3. Time-out or persistent mild degradation
219
+ const timeInVerification = (Date.now() - (persona.metadata?.verification_started_at || 0)) / 1000;
220
+ if (timeInVerification > 86400 * 3) {
221
+ console.warn(`[StrategicPlanner] Verification period timed out for ${persona.id}. Rolling back to safety.`);
222
+ return await this.rollbackPersona(persona.id);
119
223
  }
120
224
  return null;
121
225
  }
122
- async promoteChallenger(challenger, championId) {
123
- return await this.db.transaction().execute(async (trx) => {
124
- const champion = await trx
125
- .selectFrom(this.personasTable)
126
- .selectAll()
127
- .where('id', '=', championId)
128
- .executeTakeFirst();
129
- const parsedChampion = this.parsePersona(champion);
130
- // Record mutation in champion history
131
- const mutation = {
132
- id: `prom_${Date.now()}`,
133
- timestamp: Date.now(),
134
- type: challenger.metadata?.mutationType || 'role_update',
135
- previousState: { role: parsedChampion.role, policies: parsedChampion.policies },
136
- newState: { role: challenger.role, policies: challenger.policies },
137
- reason: 'Promoted from successful A/B test'
138
- };
139
- const history = [...(parsedChampion.metadata?.mutationHistory || []), mutation];
140
- if (history.length > 10)
141
- history.shift();
142
- await trx
143
- .updateTable(this.personasTable)
144
- .set({
145
- role: challenger.role,
146
- policies: JSON.stringify(challenger.policies),
147
- metadata: JSON.stringify({ ...parsedChampion.metadata, mutationHistory: history })
148
- })
149
- .where('id', '=', championId)
150
- .execute();
151
- // Delete challenger
152
- await trx.deleteFrom(this.personasTable).where('id', '=', challenger.id).execute();
153
- return `Champion ${championId} upgraded via Challenger ${challenger.id} promotion.`;
154
- });
226
+ /**
227
+ * Analyze recent actions for specific failure patterns.
228
+ */
229
+ async analyzeFailurePatterns(personaId) {
230
+ const patterns = [];
231
+ // Use ActionJournal if available to find failing tools
232
+ try {
233
+ const failureReport = await this.cortex.actions.getFailureReport();
234
+ // Only consider tools that failed more than once
235
+ const frequentFailures = failureReport.filter(f => f.failureCount > 1);
236
+ for (const fail of frequentFailures) {
237
+ patterns.push(`tool_failure_${fail.toolName}`);
238
+ }
239
+ }
240
+ catch (e) {
241
+ // Fallback to basic metrics if ActionJournal is not reachable
242
+ }
243
+ return patterns;
155
244
  }
156
245
  /**
157
246
  * Generate a performance report for a specific persona.
247
+ * Uses dynamic satisfaction thresholds based on global population stats (Phase 6).
158
248
  */
159
249
  async analyzePersona(id) {
160
250
  const recentMetrics = await this.typedDb
@@ -167,11 +257,23 @@ class StrategicPlanner {
167
257
  .orderBy('created_at', 'desc')
168
258
  .limit(50)
169
259
  .execute();
260
+ // 1. Fetch Global Baseline for Dynamic Thresholds
261
+ const globalMetrics = await this.cortex.metrics.getRecentMetrics(200);
262
+ const calcStats = (metricName) => {
263
+ const vals = globalMetrics.filter(m => m.metricName === metricName).map(m => Number(m.metricValue));
264
+ if (vals.length < 10)
265
+ return { mean: metricName === 'query_latency' ? 500 : 0.9, stdDev: 0.1 };
266
+ const mean = vals.reduce((a, b) => a + b, 0) / vals.length;
267
+ const variance = vals.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / vals.length;
268
+ return { mean, stdDev: Math.sqrt(variance) || 0.05 };
269
+ };
270
+ const successStats = calcStats('task_success_rate');
271
+ const latencyStats = calcStats('query_latency');
170
272
  if (recentMetrics.length === 0) {
171
273
  return {
172
274
  personaId: id,
173
- successRate: 1.0,
174
- averageLatency: 0,
275
+ successRate: successStats.mean,
276
+ averageLatency: latencyStats.mean,
175
277
  sampleSize: 0,
176
278
  recommendation: 'maintain'
177
279
  };
@@ -180,20 +282,28 @@ class StrategicPlanner {
180
282
  const latencyMetrics = recentMetrics.filter(m => m.metric_name === 'query_latency');
181
283
  const avgSuccess = successMetrics.length > 0
182
284
  ? successMetrics.reduce((sum, m) => sum + Number(m.metric_value), 0) / successMetrics.length
183
- : 1.0;
285
+ : successStats.mean;
184
286
  const avgLatency = latencyMetrics.length > 0
185
287
  ? latencyMetrics.reduce((sum, m) => sum + Number(m.metric_value), 0) / latencyMetrics.length
186
- : 0;
288
+ : latencyStats.mean;
187
289
  let recommendation = 'maintain';
188
- if (avgSuccess < 0.7) {
290
+ // 2. Map Dynamic Thresholds to Recommendations
291
+ // Critical: Worse than 2.5 standard deviations from mean
292
+ const criticalThreshold = successStats.mean - (2.5 * successStats.stdDev);
293
+ // Optimize: Worse than 1.0 standard deviations from mean
294
+ const accuracyThreshold = successStats.mean - (1.0 * successStats.stdDev);
295
+ // Efficiency: Latency > 2 standard deviations above mean
296
+ const efficiencyThreshold = latencyStats.mean + (2.0 * latencyStats.stdDev);
297
+ if (avgSuccess < criticalThreshold) {
189
298
  recommendation = 'critical_intervention';
190
299
  }
191
- else if (avgSuccess < 0.9) {
300
+ else if (avgSuccess < accuracyThreshold) {
192
301
  recommendation = 'optimize_accuracy';
193
302
  }
194
- else if (avgLatency > 1000) {
303
+ else if (avgLatency > efficiencyThreshold) {
195
304
  recommendation = 'optimize_efficiency';
196
305
  }
306
+ console.log(`[StrategicPlanner] Analysis for ${id}: Success=${avgSuccess.toFixed(3)} (Min=${accuracyThreshold.toFixed(3)}), Latency=${avgLatency.toFixed(0)} (Max=${efficiencyThreshold.toFixed(0)})`);
197
307
  return {
198
308
  personaId: id,
199
309
  successRate: avgSuccess,
@@ -206,7 +316,7 @@ class StrategicPlanner {
206
316
  * (Deprecated in favor of initiateAblationMutation) Evolve a persona directly.
207
317
  */
208
318
  async evolvePersona(persona, report) {
209
- return await this.initiateAblationMutation(persona, report);
319
+ return await this.applyDirectMutation(persona, report);
210
320
  }
211
321
  /**
212
322
  * Revert the last mutation for a persona.
@@ -227,9 +337,17 @@ class StrategicPlanner {
227
337
  return `No mutations to rollback for persona ${id}`;
228
338
  }
229
339
  const previous = lastMutation.previousState;
340
+ const rollbackHistory = persona.metadata?.rollbackHistory || [];
341
+ rollbackHistory.push(Date.now());
230
342
  const newMetadata = {
231
343
  ...persona.metadata,
232
344
  mutationHistory: history,
345
+ rollbackHistory: rollbackHistory,
346
+ last_failed_mutation: {
347
+ type: lastMutation.type,
348
+ timestamp: Date.now()
349
+ },
350
+ evolution_status: 'stable',
233
351
  lastRollback: Date.now()
234
352
  };
235
353
  await trx
File without changes
@@ -21,10 +21,9 @@ export declare class GovernanceManager {
21
21
  issues: string[];
22
22
  }>;
23
23
  /**
24
- * Retrieves the ID of the currently active persona.
25
- * Assumes there's a 'personas' table with an 'is_active' flag.
24
+ * Retrieves the currently active persona.
26
25
  */
27
- private getActivePersonaId;
26
+ private getActivePersona;
28
27
  /**
29
28
  * Trigger autonomous remediation steps
30
29
  */
@@ -61,13 +61,15 @@ export class GovernanceManager {
61
61
  }
62
62
  if (issues.length > 0) {
63
63
  console.warn(`[GovernanceManager] Audit failed: ${issues.join(', ')}`);
64
- // Critical Self-Healing: If success rate is catastrophically low, trigger strategic rollback
65
- if (success < 0.3) {
66
- const activePersonaId = await this.getActivePersonaId();
67
- if (activePersonaId) {
68
- console.error(`[GovernanceManager] Catastrophic failure detected. Triggering emergency rollback for persona ${activePersonaId}`);
69
- await this.cortex.strategy.rollbackPersona(activePersonaId);
70
- issues.push(`Self-Healed: Triggered emergency rollback for persona ${activePersonaId}`);
64
+ // Critical Self-Healing: If persona is in verification or success rate is catastrophically low
65
+ const activePersona = await this.getActivePersona();
66
+ if (activePersona) {
67
+ const isVerifying = activePersona.metadata?.evolution_status === 'verifying';
68
+ if (isVerifying || success < 0.3) {
69
+ const reason = isVerifying ? `Verification failed` : `Catastrophic failure`;
70
+ console.error(`[GovernanceManager] ${reason} detected. Triggering emergency rollback for persona ${activePersona.id}`);
71
+ await this.cortex.strategy.rollbackPersona(activePersona.id);
72
+ issues.push(`Self-Healed: Triggered emergency rollback for persona ${activePersona.id} (${reason})`);
71
73
  }
72
74
  }
73
75
  // Automatically record a "Panic" reflection
@@ -81,16 +83,20 @@ export class GovernanceManager {
81
83
  };
82
84
  }
83
85
  /**
84
- * Retrieves the ID of the currently active persona.
85
- * Assumes there's a 'personas' table with an 'is_active' flag.
86
+ * Retrieves the currently active persona.
86
87
  */
87
- async getActivePersonaId() {
88
- const activePersona = await this.db
88
+ async getActivePersona() {
89
+ const active = await this.db
89
90
  .selectFrom(this.personasTable)
90
- .select('id')
91
- .where('is_active', '=', true)
91
+ .selectAll()
92
+ .where('name', '=', 'default') // Or however we track the "active" one
92
93
  .executeTakeFirst();
93
- return activePersona?.id || null;
94
+ if (!active)
95
+ return null;
96
+ return {
97
+ ...active,
98
+ metadata: typeof active.metadata === 'string' ? JSON.parse(active.metadata) : (active.metadata || {})
99
+ };
94
100
  }
95
101
  /**
96
102
  * Trigger autonomous remediation steps
@@ -55,16 +55,22 @@ export declare class StrategicPlanner {
55
55
  */
56
56
  mutateStrategy(): Promise<string[]>;
57
57
  /**
58
- * Initiate a mutation by creating a "Challenger" persona instead of overwriting the original.
58
+ * Directly mutate a persona and put it into 'verifying' status.
59
+ * Performs a pre-flight conflict check and injects distilled lessons.
59
60
  */
60
- private initiateAblationMutation;
61
+ private applyDirectMutation;
61
62
  /**
62
- * Evaluate a challenger. If it performs better than the champion, promote it.
63
+ * Check if a persona in verification should be stabilized or rolled back.
64
+ * Uses dynamic statistical variance and adaptive meta-tuning.
63
65
  */
64
- private evaluateChallenger;
65
- private promoteChallenger;
66
+ private verifyEvolution;
67
+ /**
68
+ * Analyze recent actions for specific failure patterns.
69
+ */
70
+ private analyzeFailurePatterns;
66
71
  /**
67
72
  * Generate a performance report for a specific persona.
73
+ * Uses dynamic satisfaction thresholds based on global population stats (Phase 6).
68
74
  */
69
75
  analyzePersona(id: string | number): Promise<PerformanceReport>;
70
76
  /**
@@ -25,22 +25,42 @@ export class StrategicPlanner {
25
25
  */
26
26
  async mutateStrategy() {
27
27
  const mutations = [];
28
+ // 0. Pre-Flight System Health Check (Phase 4)
29
+ const tests = await this.cortex.tests.runAllProbes();
30
+ const failedTests = tests.filter(t => !t.success);
31
+ if (failedTests.length > 0) {
32
+ console.warn(`[StrategicPlanner] Mutation cycle aborted. System health probes failed: ${failedTests.map(t => t.name).join(', ')}`);
33
+ return [];
34
+ }
28
35
  const personas = await this.typedDb
29
36
  .selectFrom(this.personasTable)
30
37
  .selectAll()
31
38
  .execute();
32
39
  for (const p of personas) {
33
40
  const persona = this.parsePersona(p);
34
- // If it's a challenger, check if it's ready for promotion or disposal
35
- if (persona.metadata?.isChallenger) {
36
- const promotionResult = await this.evaluateChallenger(persona);
37
- if (promotionResult)
38
- mutations.push(promotionResult);
41
+ // 1. Verification Monitor
42
+ if (persona.metadata?.evolution_status === 'verifying') {
43
+ const result = await this.verifyEvolution(persona);
44
+ if (result)
45
+ mutations.push(result);
39
46
  continue;
40
47
  }
48
+ // 2. Failure Analysis (Intelligence Refinement)
49
+ const failures = await this.analyzeFailurePatterns(persona.id);
41
50
  const report = await this.analyzePersona(persona.id);
42
- if (report.recommendation !== 'maintain') {
43
- const result = await this.initiateAblationMutation(persona, report);
51
+ // 3. Blacklist Check (Local & Global Phase 5)
52
+ const lastMutation = persona.metadata?.last_failed_mutation;
53
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
54
+ const isGloballyBlacklisted = allPersonas.some(p => {
55
+ const mp = this.parsePersona(p);
56
+ return mp.metadata?.last_failed_mutation?.type === report.recommendation && (Date.now() - (mp.metadata?.last_failed_mutation?.timestamp || 0) < 3600000);
57
+ });
58
+ if (isGloballyBlacklisted || (lastMutation && report.recommendation === lastMutation.type && (Date.now() - lastMutation.timestamp < 86400000))) {
59
+ console.log(`[StrategicPlanner] Skipping blacklisted mutation ${report.recommendation} for persona ${persona.id} (Global=${isGloballyBlacklisted})`);
60
+ continue;
61
+ }
62
+ if (report.recommendation !== 'maintain' || failures.length > 0) {
63
+ const result = await this.applyDirectMutation(persona, report, failures);
44
64
  if (result) {
45
65
  mutations.push(result);
46
66
  }
@@ -49,110 +69,180 @@ export class StrategicPlanner {
49
69
  return mutations;
50
70
  }
51
71
  /**
52
- * Initiate a mutation by creating a "Challenger" persona instead of overwriting the original.
72
+ * Directly mutate a persona and put it into 'verifying' status.
73
+ * Performs a pre-flight conflict check and injects distilled lessons.
53
74
  */
54
- async initiateAblationMutation(persona, report) {
75
+ async applyDirectMutation(persona, report, failures = []) {
55
76
  return await this.db.transaction().execute(async (trx) => {
56
- console.log(`[StrategicPlanner] Initiating A/B test for persona ${persona.id} (Recommendation: ${report.recommendation})`);
77
+ const reason = failures.length > 0 ? `Failure Patterns: ${failures.join(', ')}` : report.recommendation;
78
+ console.log(`[StrategicPlanner] Applying direct mutation to persona ${persona.id} (Reason: ${reason})`);
57
79
  let updates = {};
58
80
  let mutationType = 'role_update';
59
- switch (report.recommendation) {
60
- case 'optimize_accuracy':
61
- updates = { role: `${persona.role || ''} (Focus strictly on accuracy and step-by-step verification)`.trim() };
62
- break;
63
- case 'optimize_efficiency':
64
- updates = { policies: [...(persona.policies || []), 'timeout_reduction', 'concise_output'] };
65
- mutationType = 'policy_update';
66
- break;
67
- case 'critical_intervention':
68
- // Critical usually bypasses A/B and rolls back or forces change
69
- return await this.rollbackPersona(persona.id);
70
- default:
81
+ if (failures.length > 0) {
82
+ // Lesson-Driven Synthesis: Pull categories of lessons
83
+ const lessons = await this.cortex.reasoner.synthesizeLessons();
84
+ const relevantLessons = updates.role ? [] : (lessons['general'] || []).slice(0, 2);
85
+ updates = { role: `${persona.role || ''} (Optimized for: ${failures.join(', ')}. Patterns: ${relevantLessons.join('; ')})`.trim() };
86
+ }
87
+ else {
88
+ // Evolutionary Cross-Pollination (Phase 5)
89
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
90
+ const winningMutations = allPersonas
91
+ .map(p => this.parsePersona(p))
92
+ .filter(p => (p.metadata?.evolution_status === 'stable' || !p.metadata?.evolution_status) && p.metadata?.mutation_reason?.includes(report.recommendation));
93
+ if (winningMutations.length > 0 && Math.random() > 0.5) {
94
+ console.log(`[StrategicPlanner] Cross-Pollinating success from Persona ${winningMutations[0].id}`);
95
+ updates = { role: winningMutations[0].role || persona.role };
96
+ }
97
+ else {
98
+ switch (report.recommendation) {
99
+ case 'optimize_accuracy':
100
+ updates = { role: `${persona.role || ''} (Focus strictly on accuracy and detailed verification)`.trim() };
101
+ break;
102
+ case 'optimize_efficiency':
103
+ updates = { policies: [...(persona.policies || []), 'timeout_reduction', 'concise_output'] };
104
+ mutationType = 'policy_update';
105
+ break;
106
+ case 'critical_intervention':
107
+ return await this.rollbackPersona(persona.id);
108
+ default:
109
+ return null;
110
+ }
111
+ }
112
+ }
113
+ // 1. Predictive Conflict Detection (Pre-flight)
114
+ const proposedState = { ...persona, ...updates };
115
+ const contradictions = await this.cortex.reasoner.detectContradictions();
116
+ // If the new role contradicts existing goals, block mutation
117
+ for (const contradiction of contradictions) {
118
+ if (updates.role && contradiction.includes(updates.role.slice(0, 20))) {
119
+ console.warn(`[StrategicPlanner] Mutation blocked due to goal contradiction: ${contradiction}`);
71
120
  return null;
121
+ }
72
122
  }
73
- // Create Challenger Persona
74
- const challengerName = `${persona.name} (Challenger v${Date.now()})`;
75
- const challengerMetadata = {
76
- parentPersonaId: persona.id,
77
- isChallenger: true,
78
- challengerSince: Date.now(),
79
- mutationType
123
+ // Record mutation in history
124
+ const mutation = {
125
+ id: `mut_${Date.now()}`,
126
+ timestamp: Date.now(),
127
+ type: mutationType,
128
+ previousState: {
129
+ role: persona.role,
130
+ policies: persona.policies,
131
+ capabilities: persona.capabilities
132
+ },
133
+ newState: { ...updates },
134
+ reason: `Auto-mutation triggered by ${report.recommendation}`
135
+ };
136
+ const history = [...(persona.metadata?.mutationHistory || []), mutation];
137
+ if (history.length > 5)
138
+ history.shift();
139
+ const newMetadata = {
140
+ ...persona.metadata,
141
+ mutationHistory: history,
142
+ evolution_status: 'verifying',
143
+ mutation_reason: report.recommendation, // Hive Signal (Phase 5)
144
+ verification_started_at: Date.now(),
145
+ verification_baseline: {
146
+ successRate: report.successRate,
147
+ averageLatency: report.averageLatency
148
+ }
80
149
  };
81
150
  await trx
82
- .insertInto(this.personasTable)
83
- .values({
84
- name: challengerName,
151
+ .updateTable(this.personasTable)
152
+ .set({
85
153
  role: updates.role || persona.role,
86
- capabilities: JSON.stringify(updates.capabilities || persona.capabilities),
87
- policies: JSON.stringify(updates.policies || persona.policies),
88
- metadata: JSON.stringify(challengerMetadata),
89
- created_at: new Date(),
154
+ policies: updates.policies ? JSON.stringify(updates.policies) : undefined,
155
+ capabilities: updates.capabilities ? JSON.stringify(updates.capabilities) : undefined,
156
+ metadata: JSON.stringify(newMetadata),
90
157
  updated_at: new Date()
91
158
  })
159
+ .where('id', '=', persona.id)
92
160
  .execute();
93
- return `Created Challenger persona for ${persona.id} to test ${mutationType}`;
161
+ return `Persona ${persona.id} mutated and entering verification window for ${mutationType}.`;
94
162
  });
95
163
  }
96
164
  /**
97
- * Evaluate a challenger. If it performs better than the champion, promote it.
165
+ * Check if a persona in verification should be stabilized or rolled back.
166
+ * Uses dynamic statistical variance and adaptive meta-tuning.
98
167
  */
99
- async evaluateChallenger(challenger) {
100
- const parentId = challenger.metadata?.parentPersonaId;
101
- if (!parentId)
102
- return null;
103
- const challengerReport = await this.analyzePersona(challenger.id);
104
- const championReport = await this.analyzePersona(parentId);
105
- // Minimum sample size for promotion
106
- if (challengerReport.sampleSize < 10)
168
+ async verifyEvolution(persona) {
169
+ const report = await this.analyzePersona(persona.id);
170
+ // Adaptive Meta-Tuning: Increase window based on rollback history (Phase 4)
171
+ const rollbackHistory = persona.metadata?.rollbackHistory || [];
172
+ const recentRollbacks = rollbackHistory.filter(ts => (Date.now() - ts < 604800000)).length;
173
+ // Hive-Mind Verification Speedups (Phase 5)
174
+ const allPersonas = await this.typedDb.selectFrom(this.personasTable).selectAll().execute();
175
+ const hiveTrusted = allPersonas.map(p => this.parsePersona(p)).filter(p => p.metadata?.evolution_status === 'stable' && p.metadata?.mutation_reason === (persona.metadata?.mutation_reason)).length;
176
+ let sampleSizeThreshold = 10 + (recentRollbacks * 10);
177
+ if (hiveTrusted >= 3) {
178
+ console.log(`[StrategicPlanner] Accelerating verification for Persona ${persona.id} (Hive-Mind Trusted)`);
179
+ sampleSizeThreshold = Math.max(5, Math.floor(sampleSizeThreshold / 2));
180
+ }
181
+ if (report.sampleSize < sampleSizeThreshold)
107
182
  return null;
108
- const daysActive = (Date.now() - (challenger.metadata?.challengerSince || 0)) / 86400000;
109
- if (challengerReport.successRate > championReport.successRate || (challengerReport.successRate >= championReport.successRate && challengerReport.averageLatency < championReport.averageLatency)) {
110
- // PROMOTION
111
- return await this.promoteChallenger(challenger, parentId);
183
+ const baseline = persona.metadata?.verification_baseline || { successRate: 0.8, averageLatency: 500 };
184
+ // Dynamic Variance Calculation (Intelligence Refinement)
185
+ const recentMetrics = await this.cortex.metrics.getRecentMetrics(100);
186
+ const values = recentMetrics
187
+ .filter(m => m.metricName === 'success_rate')
188
+ .map(m => Number(m.metricValue));
189
+ const mean = values.reduce((a, b) => a + b, 0) / (values.length || 1);
190
+ const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / (values.length || 1);
191
+ const stdDev = Math.sqrt(variance) || 0.1;
192
+ const zScore = (report.successRate - baseline.successRate) / (stdDev || 1);
193
+ console.log(`[StrategicPlanner] Verifying persona ${persona.id}: Success=${report.successRate.toFixed(2)} (Baseline=${baseline.successRate.toFixed(2)}, σ=${stdDev.toFixed(3)}, Z-Score=${zScore.toFixed(2)}, Threshold=${sampleSizeThreshold})`);
194
+ // 1. Early Rollback (Critical statistical drop)
195
+ if (zScore < -2.0) {
196
+ console.warn(`[StrategicPlanner] STATISTICAL DEGRADATION detected for persona ${persona.id} (Z-Score: ${zScore.toFixed(2)}). Rolling back early.`);
197
+ return await this.rollbackPersona(persona.id);
112
198
  }
113
- else if (daysActive > 7 || (challengerReport.sampleSize > 20 && challengerReport.successRate < 0.6)) {
114
- // DISPOSAL
115
- await this.db.deleteFrom(this.personasTable).where('id', '=', challenger.id).execute();
116
- return `Disposed failed challenger persona ${challenger.id}`;
199
+ // 2. Stabilization (Proven improvement or stability)
200
+ if (report.sampleSize >= (sampleSizeThreshold * 2) && zScore >= -0.5) {
201
+ console.log(`[StrategicPlanner] Evolution for persona ${persona.id} STABILIZED.`);
202
+ // Cognitive Rule Distillation (Phase 4)
203
+ if (persona.metadata?.mutation_reason?.includes('optimize_efficiency')) {
204
+ await this.cortex.rules.defineRule('all', 'all', 'audit', {
205
+ condition: 'latency > 500',
206
+ priority: 10,
207
+ metadata: { reason: `Distilled from successful persona ${persona.id} optimization` }
208
+ });
209
+ }
210
+ await this.db.updateTable(this.personasTable)
211
+ .set({ metadata: JSON.stringify({ ...persona.metadata, evolution_status: 'stable' }) })
212
+ .where('id', '=', persona.id)
213
+ .execute();
214
+ return `Evolution stabilized for persona ${persona.id}`;
215
+ }
216
+ // 3. Time-out or persistent mild degradation
217
+ const timeInVerification = (Date.now() - (persona.metadata?.verification_started_at || 0)) / 1000;
218
+ if (timeInVerification > 86400 * 3) {
219
+ console.warn(`[StrategicPlanner] Verification period timed out for ${persona.id}. Rolling back to safety.`);
220
+ return await this.rollbackPersona(persona.id);
117
221
  }
118
222
  return null;
119
223
  }
120
- async promoteChallenger(challenger, championId) {
121
- return await this.db.transaction().execute(async (trx) => {
122
- const champion = await trx
123
- .selectFrom(this.personasTable)
124
- .selectAll()
125
- .where('id', '=', championId)
126
- .executeTakeFirst();
127
- const parsedChampion = this.parsePersona(champion);
128
- // Record mutation in champion history
129
- const mutation = {
130
- id: `prom_${Date.now()}`,
131
- timestamp: Date.now(),
132
- type: challenger.metadata?.mutationType || 'role_update',
133
- previousState: { role: parsedChampion.role, policies: parsedChampion.policies },
134
- newState: { role: challenger.role, policies: challenger.policies },
135
- reason: 'Promoted from successful A/B test'
136
- };
137
- const history = [...(parsedChampion.metadata?.mutationHistory || []), mutation];
138
- if (history.length > 10)
139
- history.shift();
140
- await trx
141
- .updateTable(this.personasTable)
142
- .set({
143
- role: challenger.role,
144
- policies: JSON.stringify(challenger.policies),
145
- metadata: JSON.stringify({ ...parsedChampion.metadata, mutationHistory: history })
146
- })
147
- .where('id', '=', championId)
148
- .execute();
149
- // Delete challenger
150
- await trx.deleteFrom(this.personasTable).where('id', '=', challenger.id).execute();
151
- return `Champion ${championId} upgraded via Challenger ${challenger.id} promotion.`;
152
- });
224
+ /**
225
+ * Analyze recent actions for specific failure patterns.
226
+ */
227
+ async analyzeFailurePatterns(personaId) {
228
+ const patterns = [];
229
+ // Use ActionJournal if available to find failing tools
230
+ try {
231
+ const failureReport = await this.cortex.actions.getFailureReport();
232
+ // Only consider tools that failed more than once
233
+ const frequentFailures = failureReport.filter(f => f.failureCount > 1);
234
+ for (const fail of frequentFailures) {
235
+ patterns.push(`tool_failure_${fail.toolName}`);
236
+ }
237
+ }
238
+ catch (e) {
239
+ // Fallback to basic metrics if ActionJournal is not reachable
240
+ }
241
+ return patterns;
153
242
  }
154
243
  /**
155
244
  * Generate a performance report for a specific persona.
245
+ * Uses dynamic satisfaction thresholds based on global population stats (Phase 6).
156
246
  */
157
247
  async analyzePersona(id) {
158
248
  const recentMetrics = await this.typedDb
@@ -165,11 +255,23 @@ export class StrategicPlanner {
165
255
  .orderBy('created_at', 'desc')
166
256
  .limit(50)
167
257
  .execute();
258
+ // 1. Fetch Global Baseline for Dynamic Thresholds
259
+ const globalMetrics = await this.cortex.metrics.getRecentMetrics(200);
260
+ const calcStats = (metricName) => {
261
+ const vals = globalMetrics.filter(m => m.metricName === metricName).map(m => Number(m.metricValue));
262
+ if (vals.length < 10)
263
+ return { mean: metricName === 'query_latency' ? 500 : 0.9, stdDev: 0.1 };
264
+ const mean = vals.reduce((a, b) => a + b, 0) / vals.length;
265
+ const variance = vals.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / vals.length;
266
+ return { mean, stdDev: Math.sqrt(variance) || 0.05 };
267
+ };
268
+ const successStats = calcStats('task_success_rate');
269
+ const latencyStats = calcStats('query_latency');
168
270
  if (recentMetrics.length === 0) {
169
271
  return {
170
272
  personaId: id,
171
- successRate: 1.0,
172
- averageLatency: 0,
273
+ successRate: successStats.mean,
274
+ averageLatency: latencyStats.mean,
173
275
  sampleSize: 0,
174
276
  recommendation: 'maintain'
175
277
  };
@@ -178,20 +280,28 @@ export class StrategicPlanner {
178
280
  const latencyMetrics = recentMetrics.filter(m => m.metric_name === 'query_latency');
179
281
  const avgSuccess = successMetrics.length > 0
180
282
  ? successMetrics.reduce((sum, m) => sum + Number(m.metric_value), 0) / successMetrics.length
181
- : 1.0;
283
+ : successStats.mean;
182
284
  const avgLatency = latencyMetrics.length > 0
183
285
  ? latencyMetrics.reduce((sum, m) => sum + Number(m.metric_value), 0) / latencyMetrics.length
184
- : 0;
286
+ : latencyStats.mean;
185
287
  let recommendation = 'maintain';
186
- if (avgSuccess < 0.7) {
288
+ // 2. Map Dynamic Thresholds to Recommendations
289
+ // Critical: Worse than 2.5 standard deviations from mean
290
+ const criticalThreshold = successStats.mean - (2.5 * successStats.stdDev);
291
+ // Optimize: Worse than 1.0 standard deviations from mean
292
+ const accuracyThreshold = successStats.mean - (1.0 * successStats.stdDev);
293
+ // Efficiency: Latency > 2 standard deviations above mean
294
+ const efficiencyThreshold = latencyStats.mean + (2.0 * latencyStats.stdDev);
295
+ if (avgSuccess < criticalThreshold) {
187
296
  recommendation = 'critical_intervention';
188
297
  }
189
- else if (avgSuccess < 0.9) {
298
+ else if (avgSuccess < accuracyThreshold) {
190
299
  recommendation = 'optimize_accuracy';
191
300
  }
192
- else if (avgLatency > 1000) {
301
+ else if (avgLatency > efficiencyThreshold) {
193
302
  recommendation = 'optimize_efficiency';
194
303
  }
304
+ console.log(`[StrategicPlanner] Analysis for ${id}: Success=${avgSuccess.toFixed(3)} (Min=${accuracyThreshold.toFixed(3)}), Latency=${avgLatency.toFixed(0)} (Max=${efficiencyThreshold.toFixed(0)})`);
195
305
  return {
196
306
  personaId: id,
197
307
  successRate: avgSuccess,
@@ -204,7 +314,7 @@ export class StrategicPlanner {
204
314
  * (Deprecated in favor of initiateAblationMutation) Evolve a persona directly.
205
315
  */
206
316
  async evolvePersona(persona, report) {
207
- return await this.initiateAblationMutation(persona, report);
317
+ return await this.applyDirectMutation(persona, report);
208
318
  }
209
319
  /**
210
320
  * Revert the last mutation for a persona.
@@ -225,9 +335,17 @@ export class StrategicPlanner {
225
335
  return `No mutations to rollback for persona ${id}`;
226
336
  }
227
337
  const previous = lastMutation.previousState;
338
+ const rollbackHistory = persona.metadata?.rollbackHistory || [];
339
+ rollbackHistory.push(Date.now());
228
340
  const newMetadata = {
229
341
  ...persona.metadata,
230
342
  mutationHistory: history,
343
+ rollbackHistory: rollbackHistory,
344
+ last_failed_mutation: {
345
+ type: lastMutation.type,
346
+ timestamp: Date.now()
347
+ },
348
+ evolution_status: 'stable',
231
349
  lastRollback: Date.now()
232
350
  };
233
351
  await trx
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "noormme",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "NOORMME - The Agentic Data Engine. High-fidelity persistence and cognitive governance for Autonomous AI Agents.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git://github.com/cardsorting/noormme.git"
7
+ "url": "https://github.com/CardSorting/NOORMEAI.git"
8
8
  },
9
- "homepage": "https://github.com/cardsorting/noormme",
9
+ "homepage": "https://github.com/CardSorting/NOORMEAI",
10
10
  "keywords": [
11
11
  "agentic",
12
12
  "ai-agent",
@@ -60,6 +60,48 @@
60
60
  "default": "./dist/cjs/cli/index.js"
61
61
  }
62
62
  },
63
+ "scripts": {
64
+ "clean": "rm -rf dist & rm -rf test/node/dist & rm -rf test/browser/bundle.js & rm -rf helpers",
65
+ "bench:ts": "pnpm build && cd ./test/ts-benchmarks && node --experimental-strip-types ./index.ts",
66
+ "test": "jest",
67
+ "test:watch": "jest --watch",
68
+ "test:coverage": "jest --coverage",
69
+ "test:unit": "jest tests/unit",
70
+ "test:integration": "jest tests/integration",
71
+ "test:cli": "jest tests/cli",
72
+ "test:original": "pnpm build && pnpm test:node:build && pnpm test:node:run && pnpm test:typings && pnpm test:esmimports && pnpm test:exports",
73
+ "test:node:build": "tsc -p test/node",
74
+ "test:node": "pnpm build && pnpm test:node:build && pnpm test:node:run",
75
+ "test:node:run": "mocha --timeout 15000 test/node/dist/**/*.test.js",
76
+ "test:browser:build": "rm -rf test/browser/bundle.js && esbuild test/browser/main.ts --bundle --outfile=test/browser/bundle.js",
77
+ "test:browser": "pnpm build && pnpm test:browser:build && node test/browser/test.js",
78
+ "test:bun": "pnpm build && bun link && cd test/bun && bun install && bun run test",
79
+ "test:cloudflare-workers": "pnpm build && pnpm -r test --filter kysely-cloudflare-workers-test",
80
+ "test:deno": "deno run --allow-env --allow-read --allow-net --no-lock test/deno/local.test.ts && deno run --allow-env --allow-read --allow-net --no-lock test/deno/cdn.test.ts",
81
+ "test:typings": "tsd test/typings",
82
+ "test:esmimports": "node scripts/check-esm-imports.js",
83
+ "test:esbuild": "esbuild --bundle --platform=node --external:pg-native dist/esm/index.js --outfile=/dev/null",
84
+ "test:exports": "attw --pack . && node scripts/check-exports.js",
85
+ "test:jsdocs": "deno check --doc-only --no-lock --unstable-sloppy-imports --config=\"deno.check.json\" ./src",
86
+ "test:outdatedts": "pnpm build && cd test/outdated-ts && pnpm i && pnpm test",
87
+ "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
88
+ "build": "pnpm clean && (pnpm build:esm & pnpm build:cjs) && pnpm script:module-fixup && pnpm script:copy-interface-doc",
89
+ "build:esm": "tsc -p tsconfig.json && pnpm script:add-deno-type-references",
90
+ "build:cjs": "tsc -p tsconfig-cjs.json",
91
+ "script:module-fixup": "node scripts/module-fixup.js",
92
+ "script:copy-interface-doc": "node scripts/copy-interface-documentation.js",
93
+ "script:add-deno-type-references": "node scripts/add-deno-type-references.js",
94
+ "script:align-site-version": "node --experimental-strip-types scripts/align-site-version.mts",
95
+ "script:generate-site-examples": "node scripts/generate-site-examples.js",
96
+ "script:exclude-test-files-for-backwards-compat": "node --experimental-strip-types scripts/exclude-test-files-for-backwards-compat.mts",
97
+ "prepublishOnly": "pnpm build",
98
+ "version": "pnpm script:align-site-version && git add .",
99
+ "postversion": "pnpm publish --no-git-checks",
100
+ "prepack": "pnpm build",
101
+ "postpack": "echo 'Package ready for npm publish'",
102
+ "publish:dry-run": "pnpm build && npm pack --dry-run",
103
+ "publish:check": "pnpm build && npm publish --dry-run"
104
+ },
63
105
  "author": "NOORMME Team",
64
106
  "license": "MIT",
65
107
  "devDependencies": {
@@ -94,6 +136,7 @@
94
136
  "tsd": "^0.33.0",
95
137
  "typescript": "~5.9.2"
96
138
  },
139
+ "packageManager": "pnpm@10.16.1+sha512.0e155aa2629db8672b49e8475da6226aa4bdea85fdcdfdc15350874946d4f3c91faaf64cbdc4a5d1ab8002f473d5c3fcedcd197989cf0390f9badd3c04678706",
97
140
  "dependencies": {
98
141
  "better-sqlite3": "^12.4.1",
99
142
  "chalk": "^5.0.0",
@@ -106,44 +149,5 @@
106
149
  },
107
150
  "bin": {
108
151
  "noormme": "./dist/cjs/cli/index.js"
109
- },
110
- "scripts": {
111
- "clean": "rm -rf dist & rm -rf test/node/dist & rm -rf test/browser/bundle.js & rm -rf helpers",
112
- "bench:ts": "pnpm build && cd ./test/ts-benchmarks && node --experimental-strip-types ./index.ts",
113
- "test": "jest",
114
- "test:watch": "jest --watch",
115
- "test:coverage": "jest --coverage",
116
- "test:unit": "jest tests/unit",
117
- "test:integration": "jest tests/integration",
118
- "test:cli": "jest tests/cli",
119
- "test:original": "pnpm build && pnpm test:node:build && pnpm test:node:run && pnpm test:typings && pnpm test:esmimports && pnpm test:exports",
120
- "test:node:build": "tsc -p test/node",
121
- "test:node": "pnpm build && pnpm test:node:build && pnpm test:node:run",
122
- "test:node:run": "mocha --timeout 15000 test/node/dist/**/*.test.js",
123
- "test:browser:build": "rm -rf test/browser/bundle.js && esbuild test/browser/main.ts --bundle --outfile=test/browser/bundle.js",
124
- "test:browser": "pnpm build && pnpm test:browser:build && node test/browser/test.js",
125
- "test:bun": "pnpm build && bun link && cd test/bun && bun install && bun run test",
126
- "test:cloudflare-workers": "pnpm build && pnpm -r test --filter kysely-cloudflare-workers-test",
127
- "test:deno": "deno run --allow-env --allow-read --allow-net --no-lock test/deno/local.test.ts && deno run --allow-env --allow-read --allow-net --no-lock test/deno/cdn.test.ts",
128
- "test:typings": "tsd test/typings",
129
- "test:esmimports": "node scripts/check-esm-imports.js",
130
- "test:esbuild": "esbuild --bundle --platform=node --external:pg-native dist/esm/index.js --outfile=/dev/null",
131
- "test:exports": "attw --pack . && node scripts/check-exports.js",
132
- "test:jsdocs": "deno check --doc-only --no-lock --unstable-sloppy-imports --config=\"deno.check.json\" ./src",
133
- "test:outdatedts": "pnpm build && cd test/outdated-ts && pnpm i && pnpm test",
134
- "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
135
- "build": "pnpm clean && (pnpm build:esm & pnpm build:cjs) && pnpm script:module-fixup && pnpm script:copy-interface-doc",
136
- "build:esm": "tsc -p tsconfig.json && pnpm script:add-deno-type-references",
137
- "build:cjs": "tsc -p tsconfig-cjs.json",
138
- "script:module-fixup": "node scripts/module-fixup.js",
139
- "script:copy-interface-doc": "node scripts/copy-interface-documentation.js",
140
- "script:add-deno-type-references": "node scripts/add-deno-type-references.js",
141
- "script:align-site-version": "node --experimental-strip-types scripts/align-site-version.mts",
142
- "script:generate-site-examples": "node scripts/generate-site-examples.js",
143
- "script:exclude-test-files-for-backwards-compat": "node --experimental-strip-types scripts/exclude-test-files-for-backwards-compat.mts",
144
- "version": "pnpm script:align-site-version && git add .",
145
- "postversion": "pnpm publish --no-git-checks",
146
- "publish:dry-run": "pnpm build && npm pack --dry-run",
147
- "publish:check": "pnpm build && npm publish --dry-run"
148
152
  }
149
153
  }