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.
- package/dist/cjs/agentic/improvement/GovernanceManager.d.ts +2 -3
- package/dist/cjs/agentic/improvement/GovernanceManager.js +20 -14
- package/dist/cjs/agentic/improvement/StrategicPlanner.d.ts +11 -5
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +213 -95
- package/dist/cjs/cli/index.js +0 -0
- package/dist/esm/agentic/improvement/GovernanceManager.d.ts +2 -3
- package/dist/esm/agentic/improvement/GovernanceManager.js +20 -14
- package/dist/esm/agentic/improvement/StrategicPlanner.d.ts +11 -5
- package/dist/esm/agentic/improvement/StrategicPlanner.js +213 -95
- package/package.json +46 -42
|
@@ -21,10 +21,9 @@ export declare class GovernanceManager {
|
|
|
21
21
|
issues: string[];
|
|
22
22
|
}>;
|
|
23
23
|
/**
|
|
24
|
-
* Retrieves the
|
|
25
|
-
* Assumes there's a 'personas' table with an 'is_active' flag.
|
|
24
|
+
* Retrieves the currently active persona.
|
|
26
25
|
*/
|
|
27
|
-
private
|
|
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
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
87
|
-
* Assumes there's a 'personas' table with an 'is_active' flag.
|
|
88
|
+
* Retrieves the currently active persona.
|
|
88
89
|
*/
|
|
89
|
-
async
|
|
90
|
-
const
|
|
90
|
+
async getActivePersona() {
|
|
91
|
+
const active = await this.db
|
|
91
92
|
.selectFrom(this.personasTable)
|
|
92
|
-
.
|
|
93
|
-
.where('
|
|
93
|
+
.selectAll()
|
|
94
|
+
.where('name', '=', 'default') // Or however we track the "active" one
|
|
94
95
|
.executeTakeFirst();
|
|
95
|
-
|
|
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
|
-
*
|
|
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
|
|
61
|
+
private applyDirectMutation;
|
|
61
62
|
/**
|
|
62
|
-
*
|
|
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
|
|
65
|
-
|
|
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
|
-
//
|
|
37
|
-
if (persona.metadata?.
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
mutations.push(
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
*
|
|
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
|
|
77
|
+
async applyDirectMutation(persona, report, failures = []) {
|
|
57
78
|
return await this.db.transaction().execute(async (trx) => {
|
|
58
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
//
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
.
|
|
85
|
-
.
|
|
86
|
-
name: challengerName,
|
|
153
|
+
.updateTable(this.personasTable)
|
|
154
|
+
.set({
|
|
87
155
|
role: updates.role || persona.role,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
metadata: JSON.stringify(
|
|
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 `
|
|
163
|
+
return `Persona ${persona.id} mutated and entering verification window for ${mutationType}.`;
|
|
96
164
|
});
|
|
97
165
|
}
|
|
98
166
|
/**
|
|
99
|
-
*
|
|
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
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
//
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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:
|
|
174
|
-
averageLatency:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
288
|
+
: latencyStats.mean;
|
|
187
289
|
let recommendation = 'maintain';
|
|
188
|
-
|
|
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 <
|
|
300
|
+
else if (avgSuccess < accuracyThreshold) {
|
|
192
301
|
recommendation = 'optimize_accuracy';
|
|
193
302
|
}
|
|
194
|
-
else if (avgLatency >
|
|
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.
|
|
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
|
package/dist/cjs/cli/index.js
CHANGED
|
File without changes
|
|
@@ -21,10 +21,9 @@ export declare class GovernanceManager {
|
|
|
21
21
|
issues: string[];
|
|
22
22
|
}>;
|
|
23
23
|
/**
|
|
24
|
-
* Retrieves the
|
|
25
|
-
* Assumes there's a 'personas' table with an 'is_active' flag.
|
|
24
|
+
* Retrieves the currently active persona.
|
|
26
25
|
*/
|
|
27
|
-
private
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
85
|
-
* Assumes there's a 'personas' table with an 'is_active' flag.
|
|
86
|
+
* Retrieves the currently active persona.
|
|
86
87
|
*/
|
|
87
|
-
async
|
|
88
|
-
const
|
|
88
|
+
async getActivePersona() {
|
|
89
|
+
const active = await this.db
|
|
89
90
|
.selectFrom(this.personasTable)
|
|
90
|
-
.
|
|
91
|
-
.where('
|
|
91
|
+
.selectAll()
|
|
92
|
+
.where('name', '=', 'default') // Or however we track the "active" one
|
|
92
93
|
.executeTakeFirst();
|
|
93
|
-
|
|
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
|
-
*
|
|
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
|
|
61
|
+
private applyDirectMutation;
|
|
61
62
|
/**
|
|
62
|
-
*
|
|
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
|
|
65
|
-
|
|
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
|
-
//
|
|
35
|
-
if (persona.metadata?.
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
mutations.push(
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
*
|
|
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
|
|
75
|
+
async applyDirectMutation(persona, report, failures = []) {
|
|
55
76
|
return await this.db.transaction().execute(async (trx) => {
|
|
56
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
//
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
.
|
|
83
|
-
.
|
|
84
|
-
name: challengerName,
|
|
151
|
+
.updateTable(this.personasTable)
|
|
152
|
+
.set({
|
|
85
153
|
role: updates.role || persona.role,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
metadata: JSON.stringify(
|
|
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 `
|
|
161
|
+
return `Persona ${persona.id} mutated and entering verification window for ${mutationType}.`;
|
|
94
162
|
});
|
|
95
163
|
}
|
|
96
164
|
/**
|
|
97
|
-
*
|
|
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
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
//
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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:
|
|
172
|
-
averageLatency:
|
|
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
|
-
:
|
|
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
|
-
:
|
|
286
|
+
: latencyStats.mean;
|
|
185
287
|
let recommendation = 'maintain';
|
|
186
|
-
|
|
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 <
|
|
298
|
+
else if (avgSuccess < accuracyThreshold) {
|
|
190
299
|
recommendation = 'optimize_accuracy';
|
|
191
300
|
}
|
|
192
|
-
else if (avgLatency >
|
|
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.
|
|
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.
|
|
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": "
|
|
7
|
+
"url": "https://github.com/CardSorting/NOORMEAI.git"
|
|
8
8
|
},
|
|
9
|
-
"homepage": "https://github.com/
|
|
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
|
}
|