noormme 1.2.0 → 1.2.1

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.
Files changed (132) hide show
  1. package/README.md +60 -6
  2. package/dist/cjs/agentic/ActionJournal.d.ts +5 -2
  3. package/dist/cjs/agentic/ActionJournal.js +13 -5
  4. package/dist/cjs/agentic/CapabilityManager.d.ts +7 -0
  5. package/dist/cjs/agentic/CapabilityManager.js +84 -7
  6. package/dist/cjs/agentic/CognitiveRepository.js +3 -6
  7. package/dist/cjs/agentic/Cortex.d.ts +4 -0
  8. package/dist/cjs/agentic/Cortex.js +38 -17
  9. package/dist/cjs/agentic/EpisodicMemory.d.ts +5 -1
  10. package/dist/cjs/agentic/EpisodicMemory.js +11 -4
  11. package/dist/cjs/agentic/PersonaManager.js +37 -31
  12. package/dist/cjs/agentic/PolicyEnforcer.d.ts +6 -1
  13. package/dist/cjs/agentic/PolicyEnforcer.js +74 -17
  14. package/dist/cjs/agentic/ResourceMonitor.d.ts +9 -0
  15. package/dist/cjs/agentic/ResourceMonitor.js +36 -2
  16. package/dist/cjs/agentic/SessionManager.js +24 -17
  17. package/dist/cjs/agentic/VectorIndexer.d.ts +1 -0
  18. package/dist/cjs/agentic/VectorIndexer.js +26 -17
  19. package/dist/cjs/agentic/improvement/AblationEngine.d.ts +4 -6
  20. package/dist/cjs/agentic/improvement/AblationEngine.js +57 -37
  21. package/dist/cjs/agentic/improvement/ActionRefiner.js +30 -14
  22. package/dist/cjs/agentic/improvement/ConflictResolver.d.ts +3 -1
  23. package/dist/cjs/agentic/improvement/ConflictResolver.js +59 -47
  24. package/dist/cjs/agentic/improvement/CortexJanitor.js +11 -0
  25. package/dist/cjs/agentic/improvement/CuriosityEngine.d.ts +1 -1
  26. package/dist/cjs/agentic/improvement/CuriosityEngine.js +48 -21
  27. package/dist/cjs/agentic/improvement/EvolutionRitual.js +26 -14
  28. package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +16 -4
  29. package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +6 -2
  30. package/dist/cjs/agentic/improvement/GoalArchitect.js +72 -34
  31. package/dist/cjs/agentic/improvement/GovernanceManager.d.ts +9 -3
  32. package/dist/cjs/agentic/improvement/GovernanceManager.js +232 -92
  33. package/dist/cjs/agentic/improvement/HiveLink.d.ts +7 -3
  34. package/dist/cjs/agentic/improvement/HiveLink.js +135 -113
  35. package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +43 -35
  36. package/dist/cjs/agentic/improvement/QuotaManager.d.ts +41 -0
  37. package/dist/cjs/agentic/improvement/QuotaManager.js +185 -0
  38. package/dist/cjs/agentic/improvement/RecursiveReasoner.js +50 -25
  39. package/dist/cjs/agentic/improvement/ReflectionEngine.d.ts +4 -1
  40. package/dist/cjs/agentic/improvement/ReflectionEngine.js +3 -1
  41. package/dist/cjs/agentic/improvement/RitualOrchestrator.js +27 -16
  42. package/dist/cjs/agentic/improvement/RuleEngine.d.ts +1 -1
  43. package/dist/cjs/agentic/improvement/RuleEngine.js +10 -4
  44. package/dist/cjs/agentic/improvement/SelfEvolution.js +21 -17
  45. package/dist/cjs/agentic/improvement/SelfTestRegistry.d.ts +5 -0
  46. package/dist/cjs/agentic/improvement/SelfTestRegistry.js +129 -109
  47. package/dist/cjs/agentic/improvement/SkillSynthesizer.d.ts +1 -0
  48. package/dist/cjs/agentic/improvement/SkillSynthesizer.js +22 -13
  49. package/dist/cjs/agentic/improvement/StrategicPlanner.d.ts +1 -0
  50. package/dist/cjs/agentic/improvement/StrategicPlanner.js +26 -19
  51. package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.d.ts +5 -0
  52. package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +54 -12
  53. package/dist/cjs/agentic/telemetry/EventHarvester.d.ts +1 -1
  54. package/dist/cjs/agentic/telemetry/EventHarvester.js +10 -3
  55. package/dist/cjs/agentic/telemetry/ResearchAlchemist.d.ts +7 -2
  56. package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +49 -8
  57. package/dist/cjs/agentic/telemetry/TelemetryOrchestrator.d.ts +4 -1
  58. package/dist/cjs/agentic/telemetry/TelemetryOrchestrator.js +38 -11
  59. package/dist/cjs/cli/commands/inspect.js +40 -1
  60. package/dist/cjs/cli/commands/watch.js +31 -25
  61. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -5
  62. package/dist/cjs/helpers/agent-schema.js +1 -0
  63. package/dist/cjs/migration/data_migrator.js +4 -4
  64. package/dist/cjs/migration/schema_differ.js +37 -15
  65. package/dist/cjs/types/index.d.ts +12 -0
  66. package/dist/cjs/util/safe-sql-helpers.js +7 -10
  67. package/dist/esm/agentic/ActionJournal.d.ts +5 -2
  68. package/dist/esm/agentic/ActionJournal.js +13 -5
  69. package/dist/esm/agentic/CapabilityManager.d.ts +7 -0
  70. package/dist/esm/agentic/CapabilityManager.js +84 -7
  71. package/dist/esm/agentic/CognitiveRepository.js +3 -6
  72. package/dist/esm/agentic/Cortex.d.ts +4 -0
  73. package/dist/esm/agentic/Cortex.js +38 -17
  74. package/dist/esm/agentic/EpisodicMemory.d.ts +5 -1
  75. package/dist/esm/agentic/EpisodicMemory.js +11 -4
  76. package/dist/esm/agentic/PersonaManager.js +37 -31
  77. package/dist/esm/agentic/PolicyEnforcer.d.ts +6 -1
  78. package/dist/esm/agentic/PolicyEnforcer.js +74 -17
  79. package/dist/esm/agentic/ResourceMonitor.d.ts +9 -0
  80. package/dist/esm/agentic/ResourceMonitor.js +36 -2
  81. package/dist/esm/agentic/SessionManager.js +24 -17
  82. package/dist/esm/agentic/VectorIndexer.d.ts +1 -0
  83. package/dist/esm/agentic/VectorIndexer.js +26 -17
  84. package/dist/esm/agentic/improvement/AblationEngine.d.ts +4 -6
  85. package/dist/esm/agentic/improvement/AblationEngine.js +57 -37
  86. package/dist/esm/agentic/improvement/ActionRefiner.js +30 -14
  87. package/dist/esm/agentic/improvement/ConflictResolver.d.ts +3 -1
  88. package/dist/esm/agentic/improvement/ConflictResolver.js +59 -47
  89. package/dist/esm/agentic/improvement/CortexJanitor.js +11 -0
  90. package/dist/esm/agentic/improvement/CuriosityEngine.d.ts +1 -1
  91. package/dist/esm/agentic/improvement/CuriosityEngine.js +48 -21
  92. package/dist/esm/agentic/improvement/EvolutionRitual.js +26 -14
  93. package/dist/esm/agentic/improvement/EvolutionaryPilot.js +16 -4
  94. package/dist/esm/agentic/improvement/GoalArchitect.d.ts +6 -2
  95. package/dist/esm/agentic/improvement/GoalArchitect.js +72 -34
  96. package/dist/esm/agentic/improvement/GovernanceManager.d.ts +9 -3
  97. package/dist/esm/agentic/improvement/GovernanceManager.js +232 -92
  98. package/dist/esm/agentic/improvement/HiveLink.d.ts +7 -3
  99. package/dist/esm/agentic/improvement/HiveLink.js +135 -113
  100. package/dist/esm/agentic/improvement/KnowledgeDistiller.js +43 -35
  101. package/dist/esm/agentic/improvement/QuotaManager.d.ts +41 -0
  102. package/dist/esm/agentic/improvement/QuotaManager.js +182 -0
  103. package/dist/esm/agentic/improvement/RecursiveReasoner.js +50 -25
  104. package/dist/esm/agentic/improvement/ReflectionEngine.d.ts +4 -1
  105. package/dist/esm/agentic/improvement/ReflectionEngine.js +3 -1
  106. package/dist/esm/agentic/improvement/RitualOrchestrator.js +27 -16
  107. package/dist/esm/agentic/improvement/RuleEngine.d.ts +1 -1
  108. package/dist/esm/agentic/improvement/RuleEngine.js +10 -4
  109. package/dist/esm/agentic/improvement/SelfEvolution.js +21 -17
  110. package/dist/esm/agentic/improvement/SelfTestRegistry.d.ts +5 -0
  111. package/dist/esm/agentic/improvement/SelfTestRegistry.js +129 -109
  112. package/dist/esm/agentic/improvement/SkillSynthesizer.d.ts +1 -0
  113. package/dist/esm/agentic/improvement/SkillSynthesizer.js +22 -13
  114. package/dist/esm/agentic/improvement/StrategicPlanner.d.ts +1 -0
  115. package/dist/esm/agentic/improvement/StrategicPlanner.js +26 -19
  116. package/dist/esm/agentic/telemetry/CognitiveSynthesizer.d.ts +5 -0
  117. package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +54 -12
  118. package/dist/esm/agentic/telemetry/EventHarvester.d.ts +1 -1
  119. package/dist/esm/agentic/telemetry/EventHarvester.js +10 -3
  120. package/dist/esm/agentic/telemetry/ResearchAlchemist.d.ts +7 -2
  121. package/dist/esm/agentic/telemetry/ResearchAlchemist.js +49 -8
  122. package/dist/esm/agentic/telemetry/TelemetryOrchestrator.d.ts +4 -1
  123. package/dist/esm/agentic/telemetry/TelemetryOrchestrator.js +38 -11
  124. package/dist/esm/cli/commands/inspect.js +40 -1
  125. package/dist/esm/cli/commands/watch.js +31 -25
  126. package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -5
  127. package/dist/esm/helpers/agent-schema.js +1 -0
  128. package/dist/esm/migration/data_migrator.js +4 -4
  129. package/dist/esm/migration/schema_differ.js +37 -15
  130. package/dist/esm/types/index.d.ts +12 -0
  131. package/dist/esm/util/safe-sql-helpers.js +7 -10
  132. package/package.json +1 -1
@@ -16,41 +16,50 @@ export class ConflictResolver {
16
16
  /**
17
17
  * Audit rules for direct conflicts and semantic overlaps.
18
18
  */
19
- async auditRuleConflicts() {
20
- console.log('[ConflictResolver] Auditing cognitive rules for conflicts and overlaps...');
21
- const rules = (await this.db
22
- .selectFrom(this.rulesTable)
23
- .selectAll()
24
- .where('is_enabled', '=', true)
25
- .execute());
19
+ async auditRuleConflicts(options = {}) {
20
+ const batchSize = options.batchSize ?? 500;
26
21
  const conflicts = [];
27
- // 1. Direct Conflicts: Same Table + Same Operation
28
- const seen = new Map();
29
- for (const rule of rules) {
30
- const key = `${rule.tableName}:${rule.operation}`;
31
- if (seen.has(key)) {
32
- const existing = seen.get(key);
33
- // If they have different actions but same triggers, it's a conflict
34
- if (existing.action !== rule.action) {
35
- conflicts.push(`Direct Conflict: Multiple actions for '${key}' ('${existing.action}' vs '${rule.action}')`);
22
+ let offset = 0;
23
+ console.log(`[ConflictResolver] Auditing cognitive rules (batchSize=${batchSize})...`);
24
+ const seenDirect = new Map();
25
+ const tableRules = new Map();
26
+ while (true) {
27
+ const rules = (await this.db
28
+ .selectFrom(this.rulesTable)
29
+ .selectAll()
30
+ .where('is_enabled', '=', true)
31
+ .limit(batchSize)
32
+ .offset(offset)
33
+ .execute());
34
+ if (rules.length === 0)
35
+ break;
36
+ for (const rule of rules) {
37
+ // 1. Direct Conflicts: Same Table + Same Operation
38
+ const directKey = `${rule.tableName}:${rule.operation}`;
39
+ if (seenDirect.has(directKey)) {
40
+ const existing = seenDirect.get(directKey);
41
+ if (existing.action !== rule.action) {
42
+ conflicts.push(`Direct Conflict: Multiple actions for '${directKey}' ('${existing.action}' vs '${rule.action}')`);
43
+ }
44
+ else if (existing.condition === rule.condition) {
45
+ conflicts.push(`Redundant Rules: Duplicate rule detected for '${directKey}' with same condition.`);
46
+ }
36
47
  }
37
- else if (existing.condition === rule.condition) {
38
- conflicts.push(`Redundant Rules: Duplicate rule detected for '${key}' with same condition.`);
48
+ seenDirect.set(directKey, rule);
49
+ // Group for semantic check
50
+ const list = tableRules.get(rule.tableName) || [];
51
+ if (list.length < 100) { // Audit Phase 16: Quadratic Guard per table
52
+ list.push(rule);
53
+ tableRules.set(rule.tableName, list);
39
54
  }
40
55
  }
41
- seen.set(key, rule);
42
- }
43
- // 2. Semantic Overlaps: Multiple rules targeting same table with potentially overlapping conditions
44
- // This is a rudimentary check for similar keywords in conditions
45
- const tableRules = new Map();
46
- for (const rule of rules) {
47
- const list = tableRules.get(rule.tableName) || [];
48
- list.push(rule);
49
- tableRules.set(rule.tableName, list);
56
+ if (rules.length < batchSize)
57
+ break;
58
+ offset += batchSize;
50
59
  }
60
+ // 2. Semantic Overlaps: Quadratic check with hard limits
51
61
  for (const [table, list] of tableRules.entries()) {
52
62
  if (list.length > 1) {
53
- // Check for overlapping conditions (e.g., both check 'status' or both check 'priority')
54
63
  for (let i = 0; i < list.length; i++) {
55
64
  for (let j = i + 1; j < list.length; j++) {
56
65
  const r1 = list[i];
@@ -58,7 +67,7 @@ export class ConflictResolver {
58
67
  if (r1.condition && r2.condition) {
59
68
  const similarity = calculateSimilarity(r1.condition, r2.condition);
60
69
  if (similarity > 0.6) {
61
- conflicts.push(`Potential Semantic Overlap on '${table}': Rules ${r1.id} and ${r2.id} have high condition similarity (${(similarity * 100).toFixed(1)}%)`);
70
+ conflicts.push(`Potential Semantic Overlap on '${table}': Rules ${r1.id} and ${r2.id} have high similarity (${(similarity * 100).toFixed(1)}%)`);
62
71
  }
63
72
  }
64
73
  }
@@ -73,23 +82,26 @@ export class ConflictResolver {
73
82
  */
74
83
  async resolveConflict(tableName, operation) {
75
84
  console.log(`[ConflictResolver] Resolving conflict for ${tableName}:${operation}`);
76
- const rules = (await this.db
77
- .selectFrom(this.rulesTable)
78
- .selectAll()
79
- .where('table_name', '=', tableName)
80
- .where('operation', '=', operation)
81
- .where('is_enabled', '=', true)
82
- .orderBy('created_at', 'desc')
83
- .execute());
84
- if (rules.length <= 1)
85
- return;
86
- // Keep the first (newest) one, disable the rest
87
- const toDisable = rules.slice(1).map((r) => r.id);
88
- await this.db
89
- .updateTable(this.rulesTable)
90
- .set({ is_enabled: false })
91
- .where('id', 'in', toDisable)
92
- .execute();
93
- console.log(`[ConflictResolver] Disabled ${toDisable.length} redundant rules for ${tableName}:${operation}`);
85
+ return await this.db.transaction().execute(async (trx) => {
86
+ const rules = (await trx
87
+ .selectFrom(this.rulesTable)
88
+ .selectAll()
89
+ .where('table_name', '=', tableName)
90
+ .where('operation', '=', operation)
91
+ .where('is_enabled', '=', true)
92
+ .orderBy('created_at', 'desc')
93
+ .forUpdate() // Audit Phase 10: Atomic resolution lock
94
+ .execute());
95
+ if (rules.length <= 1)
96
+ return;
97
+ // Keep the first (newest) one, disable the rest
98
+ const toDisable = rules.slice(1).map((r) => r.id);
99
+ await trx
100
+ .updateTable(this.rulesTable)
101
+ .set({ is_enabled: false })
102
+ .where('id', 'in', toDisable)
103
+ .execute();
104
+ console.log(`[ConflictResolver] Disabled ${toDisable.length} redundant rules for ${tableName}:${operation}`);
105
+ });
94
106
  }
95
107
  }
@@ -172,6 +172,17 @@ export class CortexJanitor {
172
172
  }
173
173
  async logRitual(type, status, metadata) {
174
174
  try {
175
+ // Audit Phase 18: Prevent log-spam in concurrent swarms
176
+ const windowStart = new Date(Date.now() - 10 * 60 * 1000); // 10 min window
177
+ const existing = await this.db
178
+ .selectFrom(this.ritualsTable)
179
+ .select('id')
180
+ .where('name', '=', `Automated ${type}`)
181
+ .where('type', '=', type)
182
+ .where('last_run', '>', windowStart)
183
+ .executeTakeFirst();
184
+ if (existing)
185
+ return;
175
186
  await this.db
176
187
  .insertInto(this.ritualsTable)
177
188
  .values({
@@ -36,7 +36,7 @@ export declare class CuriosityEngine {
36
36
  suggestQuestions(entity: string): Promise<string[]>;
37
37
  /**
38
38
  * Generate "Relationship Hypotheses" between high-confidence entities.
39
- * Suggests that entities with multi-tag overlaps might be related.
39
+ * Refactored Phase 11: Linear O(N) relationship discovery via tag-to-entity mapping.
40
40
  */
41
41
  generateHypotheses(): Promise<string[]>;
42
42
  /**
@@ -53,11 +53,13 @@ export class CuriosityEngine {
53
53
  .having((eb) => eb.fn.count('id'), '>', 1)
54
54
  .execute();
55
55
  for (const row of entities) {
56
+ // Audit Phase 11: Paginated fact retrieval to prevent OOM on dense entities
56
57
  const items = (await this.typedDb
57
58
  .selectFrom(this.knowledgeTable)
58
59
  .selectAll()
59
60
  .where('entity', '=', row.entity)
60
61
  .where('confidence', '>', 0.5)
62
+ .limit(200) // Prevent OOM on massive entity fact lists
61
63
  .execute());
62
64
  if (items.length > 1) {
63
65
  for (let i = 0; i < items.length; i++) {
@@ -167,44 +169,69 @@ export class CuriosityEngine {
167
169
  }
168
170
  /**
169
171
  * Generate "Relationship Hypotheses" between high-confidence entities.
170
- * Suggests that entities with multi-tag overlaps might be related.
172
+ * Refactored Phase 11: Linear O(N) relationship discovery via tag-to-entity mapping.
171
173
  */
172
174
  async generateHypotheses() {
173
175
  console.log('[CuriosityEngine] Generating relationship hypotheses...');
174
- // 1. Get high-confidence entities
176
+ // 1. Get high-confidence entities (Paginated to handle scale)
175
177
  const entities = (await this.typedDb
176
178
  .selectFrom(this.knowledgeTable)
177
179
  .select(['entity', 'tags'])
178
180
  .where('confidence', '>', 0.7)
179
181
  .where('tags', 'is not', null)
182
+ .limit(2000)
180
183
  .execute());
181
184
  const hypotheses = [];
182
- const entityTagsMap = new Map();
185
+ const tagToEntities = new Map();
186
+ // Audit Phase 11: Build inverted index O(N)
183
187
  for (const row of entities) {
184
188
  const tags = typeof row.tags === 'string' ? JSON.parse(row.tags) : row.tags || [];
185
- if (tags.length > 0) {
186
- entityTagsMap.set(row.entity, new Set(tags));
189
+ for (const tag of tags) {
190
+ const list = tagToEntities.get(tag) || [];
191
+ list.push(row.entity);
192
+ tagToEntities.set(tag, list);
187
193
  }
188
194
  }
189
- const entityNames = Array.from(entityTagsMap.keys());
190
- // 2. Identify entities sharing multiple matching tags (Density check)
191
- for (let i = 0; i < entityNames.length; i++) {
192
- for (let j = i + 1; j < entityNames.length; j++) {
193
- const tagsI = entityTagsMap.get(entityNames[i]);
194
- const tagsJ = entityTagsMap.get(entityNames[j]);
195
- // intersection
196
- const commonTags = [...tagsI].filter((t) => tagsJ.has(t));
197
- if (commonTags.length >= 2) {
198
- hypotheses.push(`[HYPOTHESIS] "${entityNames[i]}" and "${entityNames[j]}" share a dense tag set (${commonTags.join(', ')}). Is there a structural coupling?`);
199
- }
200
- else if (commonTags.length === 1 &&
201
- (tagsI.size === 1 || tagsJ.size === 1)) {
202
- // Specific probe for shared lone-tags
203
- hypotheses.push(`[HYPOTHESIS] Both "${entityNames[i]}" and "${entityNames[j]}" are uniquely identified by "${commonTags[0]}". Might be aliases or sub-components.`);
195
+ // 2. Identify dense tag overlaps via index lookup
196
+ const pairCouplings = new Map(); // Key: "entity1|entity2", Value: [commonTags]
197
+ let totalPairs = 0;
198
+ const MAX_PAIRS = 5000; // Audit Phase 15: Runaway coupling guard
199
+ for (const [tag, entityList] of tagToEntities.entries()) {
200
+ if (entityList.length < 2)
201
+ continue;
202
+ if (totalPairs >= MAX_PAIRS)
203
+ break;
204
+ // Limit inner pairing to prevent explosion on ubiquitous tags
205
+ const limitedList = entityList.slice(0, 50);
206
+ for (let i = 0; i < limitedList.length; i++) {
207
+ if (totalPairs >= MAX_PAIRS)
208
+ break;
209
+ for (let j = i + 1; j < limitedList.length; j++) {
210
+ const pairKey = [limitedList[i], limitedList[j]].sort().join('|');
211
+ const common = pairCouplings.get(pairKey) || [];
212
+ if (common.length === 0)
213
+ totalPairs++;
214
+ common.push(tag);
215
+ pairCouplings.set(pairKey, common);
216
+ if (totalPairs >= MAX_PAIRS)
217
+ break;
204
218
  }
205
219
  }
206
220
  }
207
- return hypotheses.slice(0, 10); // Limit to top 10
221
+ // 3. Synthesize hypotheses from dense coupling
222
+ for (const [pair, common] of pairCouplings.entries()) {
223
+ const [e1, e2] = pair.split('|');
224
+ if (common.length >= 2) {
225
+ hypotheses.push(`[HYPOTHESIS] "${e1}" and "${e2}" share a dense tag set (${common.join(', ')}). Is there a structural coupling?`);
226
+ }
227
+ else if (common.length === 1) {
228
+ // Only flag shared lone tags if they were rare or specific
229
+ hypotheses.push(`[HYPOTHESIS] Both "${e1}" and "${e2}" are identified by "${common[0]}". Might be aliases or sub-components.`);
230
+ }
231
+ if (hypotheses.length >= 20)
232
+ break;
233
+ }
234
+ return hypotheses.slice(0, 10);
208
235
  }
209
236
  /**
210
237
  * Propose a research ritual based on identified gaps, hotspots, and hypotheses.
@@ -60,22 +60,34 @@ export class EvolutionRitual {
60
60
  async identifyActiveDomains() {
61
61
  // Production Hardening: Entropy-Based Discovery
62
62
  // Find domains that are currently "hot" (high density of recent knowledge)
63
- // This represents areas where the agent is learning fast and needs stabilization.
64
- const result = await this.db
65
- .selectFrom(this.config.knowledgeTable || 'agent_knowledge_base')
66
- .select(['tags', 'confidence'])
67
- .where('updated_at', '>', new Date(Date.now() - 24 * 60 * 60 * 1000)) // Last 24h
68
- .execute();
63
+ // Refactored Phase 13: Paginated scanning to handle large knowledge bursts
69
64
  const domainScores = new Map();
70
- for (const row of result) {
71
- const tags = typeof row.tags === 'string' ? JSON.parse(row.tags) : row.tags || [];
72
- for (const t of tags) {
73
- if (t === 'hive_mind')
74
- continue;
75
- // Score based on confidence density: a mix of volume and high-quality signals
76
- const current = domainScores.get(t) || 0;
77
- domainScores.set(t, current + (row.confidence || 0));
65
+ const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
66
+ let offset = 0;
67
+ const limit = 1000;
68
+ while (true) {
69
+ const result = await this.db
70
+ .selectFrom(this.config.knowledgeTable || 'agent_knowledge_base')
71
+ .select(['tags', 'confidence'])
72
+ .where('updated_at', '>', cutoff)
73
+ .orderBy('updated_at', 'asc')
74
+ .limit(limit)
75
+ .offset(offset)
76
+ .execute();
77
+ if (result.length === 0)
78
+ break;
79
+ for (const row of result) {
80
+ const tags = typeof row.tags === 'string' ? JSON.parse(row.tags) : row.tags || [];
81
+ for (const t of tags) {
82
+ if (t === 'hive_mind')
83
+ continue;
84
+ const current = domainScores.get(t) || 0;
85
+ domainScores.set(t, current + (row.confidence || 0));
86
+ }
78
87
  }
88
+ if (result.length < limit)
89
+ break;
90
+ offset += limit;
79
91
  }
80
92
  // Sort by total confidence density (Entropy/Activity proxy)
81
93
  // Production Hardening: Only boost domains with significant activity (Threshold: 1.0)
@@ -27,32 +27,44 @@ export class EvolutionaryPilot {
27
27
  'total_cost',
28
28
  'trust_signal',
29
29
  ];
30
- const recentMetrics = await this.cortex.metrics.getRecentMetrics(100);
30
+ const samplingCount = this.config.evolution?.samplingCount || 100;
31
+ const recentMetrics = await this.cortex.metrics.getRecentMetrics(samplingCount);
31
32
  for (const metricName of metrics) {
33
+ // Audit Phase 17: Bounded metric slice for scale-safe baselining
32
34
  const values = recentMetrics
33
35
  .filter((m) => m.metricName === metricName)
36
+ .slice(0, 500) // Hard boundary for statistical window
34
37
  .map((m) => Number(m.metricValue));
35
38
  if (values.length < 5)
36
39
  continue;
37
40
  const stats = this.calculateZScore(values);
41
+ const minSamples = this.config.evolution?.minSamples || 5;
42
+ if (values.length < minSamples)
43
+ continue;
44
+ const policies = await this.cortex.policies.getActivePolicies();
45
+ const latencyZ = policies.find(p => p.name === 'latency_drift_z')?.definition?.threshold || 2.0;
46
+ const latencyMean = policies.find(p => p.name === 'latency_mean_ceiling')?.definition?.threshold || 1000;
38
47
  console.log(`[EvolutionaryPilot] Baselining ${metricName}: Mean=${stats.mean.toFixed(2)}, StdDev=${stats.stdDev.toFixed(2)}, Current=${stats.current.toFixed(2)}, Z-Score=${stats.zScore.toFixed(2)}`);
39
48
  // 2. Trigger Evolution based on metric-specific thresholds
40
49
  if (metricName === 'query_latency' &&
41
- (stats.zScore > 2.0 || stats.mean > 1000)) {
50
+ (stats.zScore > latencyZ || stats.mean > latencyMean)) {
42
51
  const result = await this.optimizeLatency();
43
52
  if (result) {
44
53
  changes.push(...result);
45
54
  evolved = true;
46
55
  }
47
56
  }
57
+ const successZ = policies.find(p => p.name === 'success_rate_z')?.definition?.threshold || -1.5;
58
+ const successMean = policies.find(p => p.name === 'min_success_rate')?.definition?.threshold || 0.7;
48
59
  if (metricName === 'success_rate' &&
49
- (stats.zScore < -1.5 || stats.mean < 0.7)) {
60
+ (stats.zScore < successZ || stats.mean < successMean)) {
50
61
  console.warn(`[EvolutionaryPilot] Success rate collapse detected (${stats.mean.toFixed(2)}). Triggering strategic mutation.`);
51
62
  const strategies = await this.cortex.strategy.mutateStrategy();
52
63
  changes.push(...strategies);
53
64
  evolved = true;
54
65
  }
55
- if (metricName === 'total_cost' && stats.zScore > 2.5) {
66
+ const costZThreshold = policies.find(p => p.name === 'cost_spike_z')?.definition?.threshold || 2.5;
67
+ if (metricName === 'total_cost' && stats.zScore > costZThreshold) {
56
68
  console.warn(`[EvolutionaryPilot] Cost spike detected. Triggering emergency compression.`);
57
69
  await this.cortex.rituals.scheduleRitual('Emergency Compression', 'compression', 'hourly', 'High cost spike detected via Z-score analysis.');
58
70
  changes.push('Scheduled emergency compression due to cost spike');
@@ -26,11 +26,16 @@ export declare class GoalArchitect {
26
26
  private get typedDb();
27
27
  /**
28
28
  * Deconstruct a goal into multiple sub-goals transactionally.
29
+ * Includes circular dependency and terminal duplicate protection.
29
30
  */
30
31
  deconstructGoal(goalId: string | number, subGoals: string[]): Promise<AgentGoal[]>;
32
+ /**
33
+ * Recursive check for circular dependencies in the goal tree.
34
+ * Prevents infinite loops caused by autonomous decomposition.
35
+ */
36
+ private detectCircularDependency;
31
37
  /**
32
38
  * Reorder goals by updating their priorities in batch.
33
- * Lower number = higher priority.
34
39
  */
35
40
  reorderGoals(goalIds: (string | number)[]): Promise<void>;
36
41
  /**
@@ -39,7 +44,6 @@ export declare class GoalArchitect {
39
44
  markGoalAs(goalId: string | number, status: AgentGoal['status'], outcome?: string): Promise<AgentGoal>;
40
45
  /**
41
46
  * Check if a goal is blocked by uncompleted sub-goals.
42
- * Returns true if all sub-goals are completed, false otherwise.
43
47
  */
44
48
  checkGoalDependencies(goalId: string | number): Promise<{
45
49
  canComplete: boolean;
@@ -1,4 +1,5 @@
1
1
  /// <reference types="./GoalArchitect.d.ts" />
2
+ import { calculateSimilarity } from '../../util/similarity.js';
2
3
  /**
3
4
  * GoalArchitect enables agents to autonomously deconstruct complex
4
5
  * objectives into manageable sub-goals.
@@ -17,22 +18,35 @@ export class GoalArchitect {
17
18
  }
18
19
  /**
19
20
  * Deconstruct a goal into multiple sub-goals transactionally.
21
+ * Includes circular dependency and terminal duplicate protection.
20
22
  */
21
23
  async deconstructGoal(goalId, subGoals) {
22
24
  return await this.db.transaction().execute(async (trx) => {
25
+ // 1. Audit Phase 9: Circular Dependency Protection inside transaction
26
+ await this.detectCircularDependency(goalId, new Set(), trx);
23
27
  const goal = (await trx
24
28
  .selectFrom(this.goalsTable)
25
29
  .selectAll()
26
30
  .where('id', '=', goalId)
31
+ .forUpdate() // Audit Phase 9: Atomic acquisition
27
32
  .executeTakeFirst());
28
33
  if (!goal)
29
34
  throw new Error(`Goal ${goalId} not found`);
30
- console.log(`[GoalArchitect] Deconstructing goal ${goalId}: "${goal.description}" into ${subGoals.length} steps.`);
35
+ // 2. Production Hardening: Semantic Duplicate Detection
36
+ const existingSubGoals = await trx
37
+ .selectFrom(this.goalsTable)
38
+ .select('description')
39
+ .where('parent_id', '=', goalId)
40
+ .execute();
31
41
  const created = [];
32
- // Calculate base priority for sub-goals (higher than parent)
33
42
  const basePriority = (goal.priority || 0) + 1;
34
43
  for (let i = 0; i < subGoals.length; i++) {
35
44
  const desc = subGoals[i];
45
+ const isDuplicate = existingSubGoals.some(ex => calculateSimilarity(ex.description, desc) > 0.9);
46
+ if (isDuplicate) {
47
+ console.log(`[GoalArchitect] Skipping duplicate sub-goal: "${desc}"`);
48
+ continue;
49
+ }
36
50
  const subGoal = (await trx
37
51
  .insertInto(this.goalsTable)
38
52
  .values({
@@ -40,7 +54,7 @@ export class GoalArchitect {
40
54
  parent_id: goalId,
41
55
  description: desc,
42
56
  status: 'pending',
43
- priority: basePriority + i, // Sequential priority
57
+ priority: basePriority + i,
44
58
  created_at: new Date(),
45
59
  updated_at: new Date(),
46
60
  })
@@ -48,7 +62,6 @@ export class GoalArchitect {
48
62
  .executeTakeFirstOrThrow());
49
63
  created.push(this.parseGoal(subGoal));
50
64
  }
51
- // Update parent status to in_progress if it was pending
52
65
  if (goal.status === 'pending') {
53
66
  await trx
54
67
  .updateTable(this.goalsTable)
@@ -59,12 +72,39 @@ export class GoalArchitect {
59
72
  return created;
60
73
  });
61
74
  }
75
+ /**
76
+ * Recursive check for circular dependencies in the goal tree.
77
+ * Prevents infinite loops caused by autonomous decomposition.
78
+ */
79
+ async detectCircularDependency(startId, visited = new Set(), trx) {
80
+ if (visited.has(startId)) {
81
+ throw new Error(`Circular dependency detected in goal hierarchy at ID: ${startId}`);
82
+ }
83
+ visited.add(startId);
84
+ const db = trx || this.db;
85
+ const goal = await db
86
+ .selectFrom(this.goalsTable)
87
+ .select('parent_id')
88
+ .where('id', '=', startId)
89
+ .executeTakeFirst();
90
+ if (goal?.parent_id) {
91
+ await this.detectCircularDependency(goal.parent_id, visited, trx);
92
+ }
93
+ }
62
94
  /**
63
95
  * Reorder goals by updating their priorities in batch.
64
- * Lower number = higher priority.
65
96
  */
66
97
  async reorderGoals(goalIds) {
98
+ // Audit Phase 9: Sort IDs to prevent deadlocks during batch acquisition
99
+ const sortedIds = [...goalIds].sort((a, b) => String(a).localeCompare(String(b)));
67
100
  await this.db.transaction().execute(async (trx) => {
101
+ // Pre-lock all rows in deterministic order
102
+ await trx
103
+ .selectFrom(this.goalsTable)
104
+ .select('id')
105
+ .where('id', 'in', sortedIds)
106
+ .forUpdate()
107
+ .execute();
68
108
  for (let i = 0; i < goalIds.length; i++) {
69
109
  await trx
70
110
  .updateTable(this.goalsTable)
@@ -78,34 +118,36 @@ export class GoalArchitect {
78
118
  * Update a goal's status and optionally log outcome/reason in metadata.
79
119
  */
80
120
  async markGoalAs(goalId, status, outcome) {
81
- const goal = await this.typedDb
82
- .selectFrom(this.goalsTable)
83
- .selectAll()
84
- .where('id', '=', goalId)
85
- .executeTakeFirst();
86
- if (!goal)
87
- throw new Error(`Goal ${goalId} not found`);
88
- const currentMeta = goal.metadata ? JSON.parse(goal.metadata) : {};
89
- const newMeta = {
90
- ...currentMeta,
91
- lastStatusChange: Date.now(),
92
- outcome: outcome || currentMeta.outcome,
93
- };
94
- const updated = (await this.db
95
- .updateTable(this.goalsTable)
96
- .set({
97
- status,
98
- metadata: JSON.stringify(newMeta),
99
- updated_at: new Date(),
100
- })
101
- .where('id', '=', goalId)
102
- .returningAll()
103
- .executeTakeFirstOrThrow());
104
- return this.parseGoal(updated);
121
+ return await this.db.transaction().execute(async (trx) => {
122
+ const goal = (await trx
123
+ .selectFrom(this.goalsTable)
124
+ .selectAll()
125
+ .where('id', '=', goalId)
126
+ .forUpdate() // Audit Phase 9: Atomic status/meta update
127
+ .executeTakeFirst());
128
+ if (!goal)
129
+ throw new Error(`Goal ${goalId} not found`);
130
+ const currentMeta = goal.metadata ? JSON.parse(goal.metadata) : {};
131
+ const newMeta = {
132
+ ...currentMeta,
133
+ lastStatusChange: Date.now(),
134
+ outcome: outcome || currentMeta.outcome,
135
+ };
136
+ const updated = (await trx
137
+ .updateTable(this.goalsTable)
138
+ .set({
139
+ status,
140
+ metadata: JSON.stringify(newMeta),
141
+ updated_at: new Date(),
142
+ })
143
+ .where('id', '=', goalId)
144
+ .returningAll()
145
+ .executeTakeFirstOrThrow());
146
+ return this.parseGoal(updated);
147
+ });
105
148
  }
106
149
  /**
107
150
  * Check if a goal is blocked by uncompleted sub-goals.
108
- * Returns true if all sub-goals are completed, false otherwise.
109
151
  */
110
152
  async checkGoalDependencies(goalId) {
111
153
  const subGoals = await this.typedDb
@@ -126,7 +168,6 @@ export class GoalArchitect {
126
168
  * Identify goals that have "stalled" (no status changes in > 7 days)
127
169
  */
128
170
  async trackStalledGoals(daysThreshold = 7) {
129
- console.log('[GoalArchitect] Identifying stalled objectives...');
130
171
  const thresholdDate = new Date(Date.now() - daysThreshold * 24 * 3600000);
131
172
  const stalled = (await this.typedDb
132
173
  .selectFrom(this.goalsTable)
@@ -134,9 +175,6 @@ export class GoalArchitect {
134
175
  .where('status', 'in', ['pending', 'in_progress'])
135
176
  .where('updated_at', '<', thresholdDate)
136
177
  .execute());
137
- if (stalled.length > 0) {
138
- console.log(`[GoalArchitect] Identified ${stalled.length} stalled goals.`);
139
- }
140
178
  return stalled.map((g) => this.parseGoal(g));
141
179
  }
142
180
  parseGoal(g) {
@@ -20,13 +20,19 @@ export declare class GovernanceManager {
20
20
  healthy: boolean;
21
21
  issues: string[];
22
22
  }>;
23
+ private getActivePersona;
23
24
  /**
24
- * Retrieves the currently active persona.
25
+ * Quarantine a persona that is behaving outside safety parameters.
25
26
  */
26
- private getActivePersona;
27
+ quarantinePersona(id: string | number, reason: string): Promise<void>;
28
+ /**
29
+ * Blacklist a skill that is causing systemic issues.
30
+ */
31
+ quarantineSkill(name: string, reason: string): Promise<void>;
27
32
  /**
28
- * Trigger autonomous remediation steps based on specific failure modes
33
+ * Monitor cross-node behaviors and flag sudden spikes or malicious patterns.
29
34
  */
35
+ validateEmergentBehavior(trx?: any): Promise<string[]>;
30
36
  private triggerRemediation;
31
37
  /**
32
38
  * Suggest architectural repairs if performance is degrading