@holoscript/framework 6.0.3 → 6.0.4

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 (160) hide show
  1. package/CHANGELOG.md +1 -2
  2. package/ROADMAP.md +68 -66
  3. package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
  4. package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
  5. package/dist/agents/index.cjs +11 -10
  6. package/dist/agents/index.d.cts +4 -16
  7. package/dist/ai/index.cjs +2 -2
  8. package/dist/behavior.cjs +10 -0
  9. package/dist/economy/index.cjs +4 -4
  10. package/dist/economy/index.d.cts +2 -2
  11. package/dist/index.cjs +33 -11
  12. package/dist/index.d.cts +3 -3
  13. package/dist/swarm/index.cjs +3 -0
  14. package/package.json +14 -9
  15. package/src/__tests__/bounty-marketplace.test.ts +53 -21
  16. package/src/__tests__/delegation.test.ts +1 -4
  17. package/src/__tests__/done-log-audit.test.ts +38 -46
  18. package/src/__tests__/framework.test.ts +172 -53
  19. package/src/__tests__/goal-synthesizer.test.ts +9 -6
  20. package/src/__tests__/presence.test.ts +1 -1
  21. package/src/__tests__/protocol-agent.test.ts +12 -11
  22. package/src/__tests__/revenue-splitter.test.ts +22 -15
  23. package/src/__tests__/scenario-driven-todo.test.ts +55 -35
  24. package/src/__tests__/self-improve.test.ts +28 -9
  25. package/src/__tests__/service-lifecycle.test.ts +9 -3
  26. package/src/__tests__/skill-router.test.ts +3 -3
  27. package/src/agents/CulturalMemory.ts +6 -6
  28. package/src/agents/DelegationTraceHooks.ts +560 -0
  29. package/src/agents/FederatedRegistryAdapter.ts +1 -1
  30. package/src/agents/NormEngine.ts +3 -8
  31. package/src/agents/OrchestratorAgent.ts +1 -1
  32. package/src/agents/TaskDelegationService.ts +5 -9
  33. package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
  34. package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
  35. package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
  36. package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
  37. package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
  38. package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
  39. package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
  40. package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
  41. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
  42. package/src/ai/HoloScriptGenerator.ts +2 -2
  43. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
  44. package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
  45. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
  46. package/src/ai/index.ts +5 -1
  47. package/src/board/audit.ts +17 -6
  48. package/src/board/board-ops.ts +45 -15
  49. package/src/board/board-types.ts +94 -20
  50. package/src/delegation.ts +5 -3
  51. package/src/distributed-claimer.ts +13 -2
  52. package/src/economy/BountyManager.ts +40 -18
  53. package/src/economy/KnowledgeMarketplace.ts +27 -8
  54. package/src/economy/PaymentWebhookService.ts +0 -1
  55. package/src/economy/RevenueSplitter.ts +2 -4
  56. package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
  57. package/src/economy/_core-stubs.ts +1 -1
  58. package/src/economy/x402-facilitator.ts +17 -8
  59. package/src/index.ts +16 -12
  60. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
  61. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
  62. package/src/knowledge/brain.ts +7 -7
  63. package/src/knowledge/consolidation.ts +16 -16
  64. package/src/knowledge/knowledge-consolidator.ts +60 -30
  65. package/src/knowledge/knowledge-store.ts +83 -45
  66. package/src/learning/ProceduralCompiler.ts +6 -1
  67. package/src/learning/learning/MemoryConsolidator.ts +102 -0
  68. package/src/learning/learning/MemoryScorer.ts +69 -0
  69. package/src/learning/learning/ProceduralCompiler.ts +45 -0
  70. package/src/learning/learning/SemanticClusterer.ts +66 -0
  71. package/src/llm/llm-adapter.ts +24 -10
  72. package/src/mesh/index.ts +37 -17
  73. package/src/protocol/goal-synthesizer.ts +24 -34
  74. package/src/protocol/implementations.ts +91 -22
  75. package/src/protocol/micro-phase-decomposer.ts +25 -17
  76. package/src/protocol/micro-step-decomposer.test.ts +104 -39
  77. package/src/protocol-agent.test.ts +17 -7
  78. package/src/protocol-agent.ts +45 -42
  79. package/src/self-improve/absorb-scanner.ts +9 -6
  80. package/src/self-improve/evolution-engine.ts +36 -18
  81. package/src/self-improve/framework-absorber.ts +21 -16
  82. package/src/self-improve/index.ts +2 -10
  83. package/src/self-improve/prompt-optimizer.ts +31 -19
  84. package/src/self-improve/test-generator.ts +16 -12
  85. package/src/skill-router.ts +7 -6
  86. package/src/swarm/messaging/GossipProtocol.ts +1 -1
  87. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
  88. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
  89. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
  90. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
  91. package/src/team.ts +277 -122
  92. package/src/training/scripts/generate-spatial-dataset.ts +1 -1
  93. package/src/training/training/LRScheduler.ts +377 -0
  94. package/src/training/training/QualityScoringPipeline.ts +139 -0
  95. package/src/training/training/SoftDedup.ts +461 -0
  96. package/src/training/training/SparsityMonitor.ts +685 -0
  97. package/src/training/training/SparsityMonitorTypes.ts +209 -0
  98. package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
  99. package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
  100. package/src/training/training/TrainingPipelineConfig.ts +215 -0
  101. package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
  102. package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
  103. package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
  104. package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
  105. package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
  106. package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
  107. package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
  108. package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
  109. package/src/training/training/__tests__/schema.test.ts +72 -0
  110. package/src/training/training/__tests__/training-constants.test.ts +106 -0
  111. package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
  112. package/src/training/training/constants.ts +94 -0
  113. package/src/training/training/index.ts +17 -0
  114. package/src/training/training/schema.ts +147 -0
  115. package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  116. package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
  117. package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  118. package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  119. package/src/training/training/trainingmonkey/index.ts +26 -0
  120. package/src/training/training/trait-mappings.ts +157 -0
  121. package/src/types.ts +2 -7
  122. package/ALL-test-results.json +0 -1
  123. package/LICENSE +0 -21
  124. package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
  125. package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
  126. package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
  127. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
  128. package/dist/agents/index.d.ts +0 -1788
  129. package/dist/agents/index.js +0 -4695
  130. package/dist/ai/index.d.ts +0 -1753
  131. package/dist/ai/index.js +0 -5244
  132. package/dist/behavior.d.ts +0 -130
  133. package/dist/behavior.js +0 -407
  134. package/dist/economy/index.d.ts +0 -747
  135. package/dist/economy/index.js +0 -3617
  136. package/dist/implementations-D9T3un9D.d.ts +0 -236
  137. package/dist/index.d.ts +0 -1729
  138. package/dist/index.js +0 -24277
  139. package/dist/learning/index.d.ts +0 -104
  140. package/dist/learning/index.js +0 -189
  141. package/dist/negotiation/index.d.ts +0 -610
  142. package/dist/negotiation/index.js +0 -931
  143. package/dist/skills/index.d.ts +0 -289
  144. package/dist/skills/index.js +0 -1079
  145. package/dist/swarm/index.d.ts +0 -2433
  146. package/dist/swarm/index.js +0 -5221
  147. package/dist/training/index.d.ts +0 -1734
  148. package/dist/training/index.js +0 -2687
  149. package/extract-failures.js +0 -10
  150. package/src/training/training/data/novel-use-cases.jsonl +0 -153
  151. package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
  152. package/src/types/core-stubs.d.ts +0 -113
  153. package/test-output.txt +0 -0
  154. package/test-result.json +0 -1
  155. package/tsc-errors.txt +0 -4
  156. package/tsc_output.txt +0 -0
  157. package/typescript-errors-2.txt +0 -0
  158. package/typescript-errors.txt +0 -22
  159. package/vitest-log-utf8.txt +0 -268
  160. package/vitest-log.txt +0 -0
@@ -10,7 +10,6 @@ function mockKnowledgeStore(entries: Partial<StoredEntry>[] = []): KnowledgeStor
10
10
  }
11
11
 
12
12
  describe('Scenario-Driven Todo Generation', () => {
13
-
14
13
  it('Scenario 1: High Network Latency/Timeout generates DevOps/Performance todos', async () => {
15
14
  // Injecting a gotcha about network lag into the knowledge store
16
15
  const store = mockKnowledgeStore([
@@ -37,30 +36,35 @@ describe('Scenario-Driven Todo Generation', () => {
37
36
  reuseCount: 0,
38
37
  createdAt: new Date().toISOString(),
39
38
  authorAgent: 'monitor-agent',
40
- }
39
+ },
41
40
  ]);
42
-
41
+
43
42
  const synthesizer = new GoalSynthesizer({ knowledge: store });
44
-
43
+
45
44
  const performanceTodos = await synthesizer.synthesizeMultiple({ domain: 'performance' }, 50);
46
45
  const devopsTodos = await synthesizer.synthesizeMultiple({ domain: 'devops' }, 50);
47
-
46
+
48
47
  // Performance agent should prioritize the dropping packets bug
49
- expect(performanceTodos.some(t => t.category === 'knowledge-gap')).toBe(true);
50
- expect(performanceTodos.some(t => t.description.includes('gossip sync consistently dropping'))).toBe(true);
48
+ expect(performanceTodos.some((t) => t.category === 'knowledge-gap')).toBe(true);
49
+ expect(
50
+ performanceTodos.some((t) => t.description.includes('gossip sync consistently dropping'))
51
+ ).toBe(true);
51
52
 
52
53
  // DevOps agent should look at telemetry reporting issues
53
- expect(devopsTodos.some(t => t.category === 'knowledge-gap')).toBe(true);
54
- expect(devopsTodos.some(t => t.description.includes('Unbounded memory growth'))).toBe(true);
54
+ expect(devopsTodos.some((t) => t.category === 'knowledge-gap')).toBe(true);
55
+ expect(devopsTodos.some((t) => t.description.includes('Unbounded memory growth'))).toBe(true);
55
56
  });
56
57
 
57
58
  it('Scenario 2: Team switches to "Testing" mode after major logic refactoring', async () => {
58
59
  const synthesizer = new GoalSynthesizer();
59
60
  // In "testing" mode with no specific recent knowledge, should yield pure heuristic testing goals
60
61
  const testingTodos = await synthesizer.synthesizeMultiple({ domain: 'testing' }, 4);
61
-
62
+
62
63
  expect(testingTodos.length).toBe(4);
63
- const allowed = new Set([...DOMAIN_GOALS['testing'], ...DOMAIN_GOALS['performance'], ...DOMAIN_GOALS['devops'],
64
+ const allowed = new Set([
65
+ ...DOMAIN_GOALS['testing'],
66
+ ...DOMAIN_GOALS['performance'],
67
+ ...DOMAIN_GOALS['devops'],
64
68
  'Analyze accumulated wisdom for contradictions',
65
69
  'Refactor internal pattern database for efficiency',
66
70
  'Explore adjacent domain knowledge',
@@ -70,22 +74,29 @@ describe('Scenario-Driven Todo Generation', () => {
70
74
  'Optimize internal decision weights',
71
75
  'Study historical logs for anomaly detection',
72
76
  ]);
73
- expect(testingTodos.every(t => allowed.has(t.description) || t.description.startsWith('Investigate and resolve:'))).toBe(true);
77
+ expect(
78
+ testingTodos.every(
79
+ (t) => allowed.has(t.description) || t.description.startsWith('Investigate and resolve:')
80
+ )
81
+ ).toBe(true);
74
82
  });
75
83
 
76
84
  it('Scenario 3: Architecture re-evaluates service bounds based off system-mandated source', async () => {
77
85
  const synthesizer = new GoalSynthesizer();
78
-
86
+
79
87
  // Simulate legacy synchronous call
80
88
  const architectGoal = synthesizer.synthesize('architecture', 'system-mandate');
81
-
89
+
82
90
  expect(architectGoal).toBeDefined();
83
91
  expect(architectGoal.source).toBe('system-mandate');
84
92
  expect(['knowledge-gap', 'self-improvement']).toContain(architectGoal.category);
85
-
93
+
86
94
  // The description should match an architecture domain or generic fallback
87
95
  const archDomains = DOMAIN_GOALS['architecture'];
88
- expect(archDomains.includes(architectGoal.description) || GENERIC_GOALS.includes(architectGoal.description)).toBeTruthy();
96
+ expect(
97
+ archDomains.includes(architectGoal.description) ||
98
+ GENERIC_GOALS.includes(architectGoal.description)
99
+ ).toBeTruthy();
89
100
  });
90
101
 
91
102
  it('Scenario 4: Security agent triages code injection vulnerability knowledge', async () => {
@@ -101,33 +112,37 @@ describe('Scenario-Driven Todo Generation', () => {
101
112
  reuseCount: 0,
102
113
  createdAt: new Date().toISOString(),
103
114
  authorAgent: 'security-scanner',
104
- }
115
+ },
105
116
  ]);
106
-
117
+
107
118
  const synthesizer = new GoalSynthesizer({ knowledge: store });
108
119
  const secTodos = await synthesizer.synthesizeMultiple({ domain: 'security' }, 50);
109
120
 
110
- expect(secTodos.some(t => t.description.includes('CRDT delta payloads bypassing type serialization'))).toBe(true);
121
+ expect(
122
+ secTodos.some((t) =>
123
+ t.description.includes('CRDT delta payloads bypassing type serialization')
124
+ )
125
+ ).toBe(true);
111
126
  // Security agent should rank the injection gotcha with high priority
112
- const injectionTodo = secTodos.find(t => t.description.includes('CRDT delta'));
127
+ const injectionTodo = secTodos.find((t) => t.description.includes('CRDT delta'));
113
128
  expect(injectionTodo?.category).toBe('knowledge-gap');
114
129
  });
115
130
 
116
131
  it('Scenario 5: Goal Synthesizer todos are successfully converted and pushed to the Team board', async () => {
117
132
  // We can isolate the goal-to-task pipeline
118
133
  const synthesizer = new GoalSynthesizer();
119
-
134
+
120
135
  // Synthesize some tasks for testing
121
136
  const newGoals = await synthesizer.synthesizeMultiple({ domain: 'performance' }, 3);
122
-
137
+
123
138
  // Convert to board tasks structure
124
- const tasksToSubmit = newGoals.map(goal => ({
139
+ const tasksToSubmit = newGoals.map((goal) => ({
125
140
  title: goal.description,
126
141
  description: `[Auto-Synthesized] Rationale: ${goal.rationale}\nRelevance: ${goal.relevanceScore}`,
127
142
  priority: goal.priority === 'high' ? 1 : goal.priority === 'medium' ? 2 : 3,
128
- source: `synthesizer:${goal.id}`
143
+ source: `synthesizer:${goal.id}`,
129
144
  }));
130
-
145
+
131
146
  // Verify valid schema
132
147
  expect(tasksToSubmit.length).toBe(3);
133
148
  expect(tasksToSubmit[0].title).toBeDefined();
@@ -142,21 +157,23 @@ describe('Scenario-Driven Todo Generation', () => {
142
157
  type: 'gotcha',
143
158
  content: 'Neural Streaming data formats changing rapidly without backward compatibility',
144
159
  domain: 'research',
145
- confidence: 0.90,
160
+ confidence: 0.9,
146
161
  source: 'external',
147
162
  queryCount: 0,
148
163
  reuseCount: 0,
149
164
  createdAt: new Date().toISOString(),
150
165
  authorAgent: 'researcher-agent',
151
- }
166
+ },
152
167
  ]);
153
-
168
+
154
169
  const synthesizer = new GoalSynthesizer({ knowledge: store });
155
170
  const researchTodos = await synthesizer.synthesizeMultiple({ domain: 'research' }, 50);
156
171
 
157
- expect(researchTodos.some(t => t.description.includes('Neural Streaming'))).toBe(true);
172
+ expect(researchTodos.some((t) => t.description.includes('Neural Streaming'))).toBe(true);
158
173
  // At least one task should fall back to general heuristic if we asked for higher count
159
- const hasHeuristic = researchTodos.some(t => DOMAIN_GOALS['research'].includes(t.description));
174
+ const hasHeuristic = researchTodos.some((t) =>
175
+ DOMAIN_GOALS['research'].includes(t.description)
176
+ );
160
177
  expect(hasHeuristic).toBe(true);
161
178
  });
162
179
 
@@ -173,23 +190,26 @@ describe('Scenario-Driven Todo Generation', () => {
173
190
  reuseCount: 1,
174
191
  createdAt: new Date().toISOString(),
175
192
  authorAgent: 'dev-agent',
176
- }
193
+ },
177
194
  ]);
178
-
195
+
179
196
  const synthesizer = new GoalSynthesizer({ knowledge: store });
180
197
  const codingTodos = await synthesizer.synthesizeMultiple({ domain: 'coding' }, 50);
181
198
 
182
199
  // Should prioritize the urgent deprecation / silent failure bug
183
- expect(codingTodos.some(t => t.description.includes('UnhandledPromiseRejection')) || codingTodos.some(t => t.description.includes('V1 Mesh APIs'))).toBe(true);
200
+ expect(
201
+ codingTodos.some((t) => t.description.includes('UnhandledPromiseRejection')) ||
202
+ codingTodos.some((t) => t.description.includes('V1 Mesh APIs'))
203
+ ).toBe(true);
184
204
  });
185
205
 
186
206
  it('Scenario 8: Reviewer agent generates task based on heuristic fallback', async () => {
187
207
  const synthesizer = new GoalSynthesizer();
188
208
  const reviewerTodos = await synthesizer.synthesizeMultiple({ domain: 'reviewer' }, 4);
189
-
209
+
190
210
  expect(reviewerTodos.length).toBe(4);
191
211
  const allExpectedDomains = DOMAIN_GOALS['reviewer'];
192
- const hasReviewerHeuristic = reviewerTodos.some(t =>
212
+ const hasReviewerHeuristic = reviewerTodos.some((t) =>
193
213
  allExpectedDomains.includes(t.description)
194
214
  );
195
215
  expect(hasReviewerHeuristic).toBe(true);
@@ -56,9 +56,7 @@ describe('FrameworkAbsorber', () => {
56
56
  mockFetch.mockResolvedValueOnce({
57
57
  ok: true,
58
58
  json: async () => ({
59
- results: [
60
- { type: 'gotcha', content: 'Test gotcha', metadata: { domain: 'framework' } },
61
- ],
59
+ results: [{ type: 'gotcha', content: 'Test gotcha', metadata: { domain: 'framework' } }],
62
60
  }),
63
61
  });
64
62
 
@@ -77,7 +75,16 @@ describe('FrameworkAbsorber', () => {
77
75
  ok: true,
78
76
  json: async () => ({
79
77
  result: {
80
- content: [{ type: 'text', text: JSON.stringify({ file_count: 42, edge_count: 100, modules: ['core', 'self-improve'] }) }],
78
+ content: [
79
+ {
80
+ type: 'text',
81
+ text: JSON.stringify({
82
+ file_count: 42,
83
+ edge_count: 100,
84
+ modules: ['core', 'self-improve'],
85
+ }),
86
+ },
87
+ ],
81
88
  },
82
89
  }),
83
90
  });
@@ -110,8 +117,16 @@ describe('FrameworkAbsorber', () => {
110
117
  ok: true,
111
118
  json: async () => ({
112
119
  results: [
113
- { type: 'gotcha', content: 'Missing test coverage for X', metadata: { domain: 'framework', confidence: 0.8 } },
114
- { type: 'pattern', content: 'Use dependency injection', metadata: { domain: 'architecture' } },
120
+ {
121
+ type: 'gotcha',
122
+ content: 'Missing test coverage for X',
123
+ metadata: { domain: 'framework', confidence: 0.8 },
124
+ },
125
+ {
126
+ type: 'pattern',
127
+ content: 'Use dependency injection',
128
+ metadata: { domain: 'architecture' },
129
+ },
115
130
  ],
116
131
  }),
117
132
  });
@@ -286,7 +301,11 @@ describe('PromptOptimizer', () => {
286
301
  it('handles judge failures gracefully (neutral score)', async () => {
287
302
  mockedCallLLM.mockImplementation(async (_config, messages) => {
288
303
  // Judge prompt contains "Score the following"
289
- const isJudge = messages.some(m => m.content.includes('Score the following') || m.content.includes('prompt quality evaluator'));
304
+ const isJudge = messages.some(
305
+ (m) =>
306
+ m.content.includes('Score the following') ||
307
+ m.content.includes('prompt quality evaluator')
308
+ );
290
309
  if (isJudge) {
291
310
  throw new Error('LLM quota exceeded');
292
311
  }
@@ -310,12 +329,12 @@ describe('PromptOptimizer', () => {
310
329
  it('reports correct variant scores', async () => {
311
330
  // Make variant A consistently better than variant B
312
331
  mockedCallLLM.mockImplementation(async (_config, messages) => {
313
- const systemMsg = messages.find(m => m.role === 'system');
332
+ const systemMsg = messages.find((m) => m.role === 'system');
314
333
  const isJudge = systemMsg?.content.includes('prompt quality evaluator');
315
334
 
316
335
  if (isJudge) {
317
336
  // Check if the response being judged is from variant A or B
318
- const userMsg = messages.find(m => m.role === 'user');
337
+ const userMsg = messages.find((m) => m.role === 'user');
319
338
  const isVariantA = userMsg?.content.includes('Great response from A');
320
339
  return {
321
340
  content: JSON.stringify({
@@ -148,7 +148,9 @@ describe('ServiceError', () => {
148
148
  });
149
149
 
150
150
  it('carries optional details', () => {
151
- const err = new ServiceError(ServiceErrorCode.VALIDATION_ERROR, 'bad input', 400, { field: 'name' });
151
+ const err = new ServiceError(ServiceErrorCode.VALIDATION_ERROR, 'bad input', 400, {
152
+ field: 'name',
153
+ });
152
154
  expect(err.details).toEqual({ field: 'name' });
153
155
  });
154
156
  });
@@ -164,8 +166,12 @@ describe('ServiceManager', () => {
164
166
  constructor(name: string) {
165
167
  super({ name, version: '1.0.0', description: name });
166
168
  }
167
- protected override async onInit() { order.push(`init:${this.getMetadata().name}`); }
168
- protected override async onStop() { order.push(`stop:${this.getMetadata().name}`); }
169
+ protected override async onInit() {
170
+ order.push(`init:${this.getMetadata().name}`);
171
+ }
172
+ protected override async onStop() {
173
+ order.push(`stop:${this.getMetadata().name}`);
174
+ }
169
175
  }
170
176
 
171
177
  const mgr = new ServiceManager();
@@ -67,7 +67,7 @@ describe('SkillRouter', () => {
67
67
  const task = makeTask({ priority: 7 });
68
68
  // Reviewer has maxPriority 5, so should be filtered out
69
69
  const result = router.route(task, agents);
70
- expect(result.candidates.find(c => c.agent.name === 'Reviewer')).toBeUndefined();
70
+ expect(result.candidates.find((c) => c.agent.name === 'Reviewer')).toBeUndefined();
71
71
  });
72
72
 
73
73
  it('scores role match bonus', () => {
@@ -76,7 +76,7 @@ describe('SkillRouter', () => {
76
76
  role: 'reviewer',
77
77
  });
78
78
  const result = router.route(task, agents);
79
- const reviewerCandidate = result.candidates.find(c => c.agent.name === 'Reviewer');
79
+ const reviewerCandidate = result.candidates.find((c) => c.agent.name === 'Reviewer');
80
80
  expect(reviewerCandidate?.roleMatch).toBe(true);
81
81
  });
82
82
 
@@ -114,7 +114,7 @@ describe('SkillRouter', () => {
114
114
  it('tracks matched capabilities in result', () => {
115
115
  const task = makeTask({ title: 'Fix the parser bug in typescript' });
116
116
  const result = router.route(task, agents);
117
- const coderCandidate = result.candidates.find(c => c.agent.name === 'Coder');
117
+ const coderCandidate = result.candidates.find((c) => c.agent.name === 'Coder');
118
118
  expect(coderCandidate?.matchedCapabilities).toContain('parser');
119
119
  expect(coderCandidate?.matchedCapabilities).toContain('typescript');
120
120
  });
@@ -50,7 +50,7 @@ export interface StigmergicTrace {
50
50
  /** Creator */
51
51
  creatorId: string;
52
52
  /** Spatial position */
53
- position: { x: number; y: number; z: number };
53
+ position: [number, number, number];
54
54
  /** Zone the trace belongs to */
55
55
  zoneId: string;
56
56
  /** Type of trace */
@@ -209,7 +209,7 @@ export class CulturalMemory {
209
209
  creatorId: string,
210
210
  zoneId: string,
211
211
  label: string,
212
- position: { x: number; y: number; z: number },
212
+ position: [number, number, number],
213
213
  opts: Partial<
214
214
  Omit<
215
215
  StigmergicTrace,
@@ -249,13 +249,13 @@ export class CulturalMemory {
249
249
  /**
250
250
  * Perceive nearby traces from a position.
251
251
  */
252
- perceiveTraces(zoneId: string, position: { x: number; y: number; z: number }): StigmergicTrace[] {
252
+ perceiveTraces(zoneId: string, position: [number, number, number]): StigmergicTrace[] {
253
253
  const traces = this.stigmergic.get(zoneId) || [];
254
254
  return traces
255
255
  .filter((t) => {
256
- const dx = t.position.x - position.x;
257
- const dy = t.position.y - position.y;
258
- const dz = t.position.z - position.z;
256
+ const dx = t.position[0] - position[0];
257
+ const dy = t.position[1] - position[1];
258
+ const dz = t.position[2] - position[2];
259
259
  const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
260
260
  return dist <= t.radius && t.intensity > 0.01;
261
261
  })