@holoscript/framework 6.0.3

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 (329) hide show
  1. package/ALL-test-results.json +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/ROADMAP.md +175 -0
  5. package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
  6. package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
  7. package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
  8. package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
  9. package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
  10. package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
  11. package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
  12. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
  13. package/dist/agents/index.cjs +4790 -0
  14. package/dist/agents/index.d.cts +1788 -0
  15. package/dist/agents/index.d.ts +1788 -0
  16. package/dist/agents/index.js +4695 -0
  17. package/dist/ai/index.cjs +5347 -0
  18. package/dist/ai/index.d.cts +1753 -0
  19. package/dist/ai/index.d.ts +1753 -0
  20. package/dist/ai/index.js +5244 -0
  21. package/dist/behavior.cjs +449 -0
  22. package/dist/behavior.d.cts +130 -0
  23. package/dist/behavior.d.ts +130 -0
  24. package/dist/behavior.js +407 -0
  25. package/dist/economy/index.cjs +3659 -0
  26. package/dist/economy/index.d.cts +747 -0
  27. package/dist/economy/index.d.ts +747 -0
  28. package/dist/economy/index.js +3617 -0
  29. package/dist/implementations-D9T3un9D.d.cts +236 -0
  30. package/dist/implementations-D9T3un9D.d.ts +236 -0
  31. package/dist/index.cjs +24550 -0
  32. package/dist/index.d.cts +1729 -0
  33. package/dist/index.d.ts +1729 -0
  34. package/dist/index.js +24277 -0
  35. package/dist/learning/index.cjs +219 -0
  36. package/dist/learning/index.d.cts +104 -0
  37. package/dist/learning/index.d.ts +104 -0
  38. package/dist/learning/index.js +189 -0
  39. package/dist/negotiation/index.cjs +970 -0
  40. package/dist/negotiation/index.d.cts +610 -0
  41. package/dist/negotiation/index.d.ts +610 -0
  42. package/dist/negotiation/index.js +931 -0
  43. package/dist/skills/index.cjs +1118 -0
  44. package/dist/skills/index.d.cts +289 -0
  45. package/dist/skills/index.d.ts +289 -0
  46. package/dist/skills/index.js +1079 -0
  47. package/dist/swarm/index.cjs +5268 -0
  48. package/dist/swarm/index.d.cts +2433 -0
  49. package/dist/swarm/index.d.ts +2433 -0
  50. package/dist/swarm/index.js +5221 -0
  51. package/dist/training/index.cjs +2745 -0
  52. package/dist/training/index.d.cts +1734 -0
  53. package/dist/training/index.d.ts +1734 -0
  54. package/dist/training/index.js +2687 -0
  55. package/extract-failures.js +10 -0
  56. package/package.json +82 -0
  57. package/src/__tests__/bounty-marketplace.test.ts +374 -0
  58. package/src/__tests__/delegation.test.ts +144 -0
  59. package/src/__tests__/distributed-claimer.test.ts +147 -0
  60. package/src/__tests__/done-log-audit.test.ts +342 -0
  61. package/src/__tests__/framework.test.ts +865 -0
  62. package/src/__tests__/goal-synthesizer.test.ts +236 -0
  63. package/src/__tests__/presence.test.ts +223 -0
  64. package/src/__tests__/protocol-agent.test.ts +254 -0
  65. package/src/__tests__/revenue-splitter.test.ts +114 -0
  66. package/src/__tests__/scenario-driven-todo.test.ts +197 -0
  67. package/src/__tests__/self-improve.test.ts +349 -0
  68. package/src/__tests__/service-lifecycle.test.ts +237 -0
  69. package/src/__tests__/skill-router.test.ts +121 -0
  70. package/src/agents/AgentManifest.ts +493 -0
  71. package/src/agents/AgentRegistry.ts +475 -0
  72. package/src/agents/AgentTypes.ts +585 -0
  73. package/src/agents/AgentWalletRegistry.ts +83 -0
  74. package/src/agents/AuthenticatedCRDT.ts +388 -0
  75. package/src/agents/CapabilityMatcher.ts +453 -0
  76. package/src/agents/CrossRealityHandoff.ts +305 -0
  77. package/src/agents/CulturalMemory.ts +454 -0
  78. package/src/agents/FederatedRegistryAdapter.ts +429 -0
  79. package/src/agents/NormEngine.ts +450 -0
  80. package/src/agents/OrchestratorAgent.ts +414 -0
  81. package/src/agents/SkillWorkflowEngine.ts +472 -0
  82. package/src/agents/TaskDelegationService.ts +551 -0
  83. package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
  84. package/src/agents/__tests__/AgentManifest.test.ts +182 -0
  85. package/src/agents/__tests__/AgentModule.test.ts +864 -0
  86. package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
  87. package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
  88. package/src/agents/__tests__/AgentTypes.test.ts +534 -0
  89. package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
  90. package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
  91. package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
  92. package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
  93. package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
  94. package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
  95. package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
  96. package/src/agents/__tests__/NormEngine.test.ts +276 -0
  97. package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
  98. package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
  99. package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
  100. package/src/agents/index.ts +107 -0
  101. package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
  102. package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
  103. package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
  104. package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
  105. package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
  106. package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
  107. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
  108. package/src/agents/spatial-comms/index.ts +66 -0
  109. package/src/ai/AIAdapter.ts +313 -0
  110. package/src/ai/AICopilot.ts +331 -0
  111. package/src/ai/AIOutputValidator.ts +203 -0
  112. package/src/ai/BTNodes.ts +239 -0
  113. package/src/ai/BehaviorSelector.ts +135 -0
  114. package/src/ai/BehaviorTree.ts +153 -0
  115. package/src/ai/Blackboard.ts +165 -0
  116. package/src/ai/GenerationAnalytics.ts +461 -0
  117. package/src/ai/GenerationCache.ts +265 -0
  118. package/src/ai/GoalPlanner.ts +165 -0
  119. package/src/ai/HoloScriptGenerator.ts +580 -0
  120. package/src/ai/InfluenceMap.ts +180 -0
  121. package/src/ai/NavMesh.ts +168 -0
  122. package/src/ai/PerceptionSystem.ts +178 -0
  123. package/src/ai/PromptTemplates.ts +453 -0
  124. package/src/ai/SemanticSearchService.ts +80 -0
  125. package/src/ai/StateMachine.ts +196 -0
  126. package/src/ai/SteeringBehavior.ts +150 -0
  127. package/src/ai/SteeringBehaviors.ts +244 -0
  128. package/src/ai/TrainingDataGenerator.ts +1082 -0
  129. package/src/ai/UtilityAI.ts +145 -0
  130. package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
  131. package/src/ai/__tests__/AIAdapter.test.ts +109 -0
  132. package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
  133. package/src/ai/__tests__/AICopilot.test.ts +178 -0
  134. package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
  135. package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
  136. package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
  137. package/src/ai/__tests__/BTNodes.test.ts +263 -0
  138. package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
  139. package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
  140. package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
  141. package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
  142. package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
  143. package/src/ai/__tests__/Blackboard.test.ts +183 -0
  144. package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
  145. package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
  146. package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
  147. package/src/ai/__tests__/GenerationCache.test.ts +171 -0
  148. package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
  149. package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
  150. package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
  151. package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
  152. package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
  153. package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
  154. package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
  155. package/src/ai/__tests__/NavMesh.test.ts +159 -0
  156. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
  157. package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
  158. package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
  159. package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
  160. package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
  161. package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
  162. package/src/ai/__tests__/StateMachine.test.ts +163 -0
  163. package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
  164. package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
  165. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
  166. package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
  167. package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
  168. package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
  169. package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
  170. package/src/ai/__tests__/UtilityAI.test.ts +155 -0
  171. package/src/ai/__tests__/adapters.prod.test.ts +263 -0
  172. package/src/ai/__tests__/adapters.test.ts +320 -0
  173. package/src/ai/adapters.ts +1585 -0
  174. package/src/ai/index.ts +130 -0
  175. package/src/behavior/BehaviorPresets.ts +140 -0
  176. package/src/behavior/BehaviorTree.ts +236 -0
  177. package/src/behavior/StateMachine.ts +176 -0
  178. package/src/behavior/StateTrait.ts +67 -0
  179. package/src/behavior/index.ts +8 -0
  180. package/src/behavior.ts +8 -0
  181. package/src/board/audit.ts +284 -0
  182. package/src/board/board-ops.ts +336 -0
  183. package/src/board/board-types.ts +302 -0
  184. package/src/board/index.ts +69 -0
  185. package/src/define-agent.ts +46 -0
  186. package/src/define-team.ts +33 -0
  187. package/src/delegation.ts +265 -0
  188. package/src/distributed-claimer.ts +228 -0
  189. package/src/economy/AgentBudgetEnforcer.ts +464 -0
  190. package/src/economy/BountyManager.ts +185 -0
  191. package/src/economy/CreatorRevenueAggregator.ts +460 -0
  192. package/src/economy/InvisibleWallet.ts +82 -0
  193. package/src/economy/KnowledgeMarketplace.ts +193 -0
  194. package/src/economy/PaymentWebhookService.ts +512 -0
  195. package/src/economy/RevenueSplitter.ts +156 -0
  196. package/src/economy/SubscriptionManager.ts +546 -0
  197. package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
  198. package/src/economy/UsageMeter.ts +440 -0
  199. package/src/economy/_core-stubs.ts +219 -0
  200. package/src/economy/index.ts +100 -0
  201. package/src/economy/x402-facilitator.ts +1978 -0
  202. package/src/index.ts +348 -0
  203. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
  204. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
  205. package/src/knowledge/brain.ts +167 -0
  206. package/src/knowledge/consolidation.ts +581 -0
  207. package/src/knowledge/knowledge-consolidator.ts +510 -0
  208. package/src/knowledge/knowledge-store.ts +616 -0
  209. package/src/learning/MemoryConsolidator.ts +102 -0
  210. package/src/learning/MemoryScorer.ts +69 -0
  211. package/src/learning/ProceduralCompiler.ts +45 -0
  212. package/src/learning/SemanticClusterer.ts +66 -0
  213. package/src/learning/index.ts +8 -0
  214. package/src/llm/llm-adapter.ts +159 -0
  215. package/src/mesh/index.ts +309 -0
  216. package/src/negotiation/NegotiationProtocol.ts +694 -0
  217. package/src/negotiation/NegotiationTypes.ts +473 -0
  218. package/src/negotiation/VotingMechanisms.ts +691 -0
  219. package/src/negotiation/index.ts +49 -0
  220. package/src/protocol/goal-synthesizer.ts +317 -0
  221. package/src/protocol/implementations.ts +474 -0
  222. package/src/protocol/micro-phase-decomposer.ts +299 -0
  223. package/src/protocol/micro-step-decomposer.test.ts +306 -0
  224. package/src/protocol-agent.test.ts +353 -0
  225. package/src/protocol-agent.ts +670 -0
  226. package/src/self-improve/absorb-scanner.ts +252 -0
  227. package/src/self-improve/evolution-engine.ts +149 -0
  228. package/src/self-improve/framework-absorber.ts +214 -0
  229. package/src/self-improve/index.ts +50 -0
  230. package/src/self-improve/prompt-optimizer.ts +212 -0
  231. package/src/self-improve/test-generator.ts +175 -0
  232. package/src/skill-router.ts +186 -0
  233. package/src/skills/index.ts +5 -0
  234. package/src/skills/skill-md-bridge.ts +1699 -0
  235. package/src/swarm/ACOEngine.ts +261 -0
  236. package/src/swarm/CollectiveIntelligence.ts +383 -0
  237. package/src/swarm/ContributionSynthesizer.ts +481 -0
  238. package/src/swarm/LeaderElection.ts +393 -0
  239. package/src/swarm/PSOEngine.ts +206 -0
  240. package/src/swarm/QuorumPolicy.ts +173 -0
  241. package/src/swarm/SwarmCoordinator.ts +335 -0
  242. package/src/swarm/SwarmManager.ts +442 -0
  243. package/src/swarm/SwarmMembership.ts +456 -0
  244. package/src/swarm/VotingRound.ts +255 -0
  245. package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
  246. package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
  247. package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
  248. package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
  249. package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
  250. package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
  251. package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
  252. package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
  253. package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
  254. package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
  255. package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
  256. package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
  257. package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
  258. package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
  259. package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
  260. package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
  261. package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
  262. package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
  263. package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
  264. package/src/swarm/__tests__/VotingRound.test.ts +174 -0
  265. package/src/swarm/analytics/SwarmInspector.ts +476 -0
  266. package/src/swarm/analytics/SwarmMetrics.ts +449 -0
  267. package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
  268. package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
  269. package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
  270. package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
  271. package/src/swarm/analytics/index.ts +7 -0
  272. package/src/swarm/index.ts +69 -0
  273. package/src/swarm/messaging/BroadcastChannel.ts +509 -0
  274. package/src/swarm/messaging/GossipProtocol.ts +565 -0
  275. package/src/swarm/messaging/SwarmEventBus.ts +443 -0
  276. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
  277. package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
  278. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
  279. package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
  280. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
  281. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
  282. package/src/swarm/messaging/index.ts +8 -0
  283. package/src/swarm/spatial/FlockingBehavior.ts +462 -0
  284. package/src/swarm/spatial/FormationController.ts +500 -0
  285. package/src/swarm/spatial/Vector3.ts +170 -0
  286. package/src/swarm/spatial/ZoneClaiming.ts +509 -0
  287. package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
  288. package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
  289. package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
  290. package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
  291. package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
  292. package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
  293. package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
  294. package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
  295. package/src/swarm/spatial/index.ts +28 -0
  296. package/src/team.ts +1245 -0
  297. package/src/training/LRScheduler.ts +377 -0
  298. package/src/training/QualityScoringPipeline.ts +139 -0
  299. package/src/training/SoftDedup.ts +461 -0
  300. package/src/training/SparsityMonitor.ts +685 -0
  301. package/src/training/SparsityMonitorTypes.ts +209 -0
  302. package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
  303. package/src/training/SpatialTrainingDataTypes.ts +216 -0
  304. package/src/training/TrainingPipelineConfig.ts +215 -0
  305. package/src/training/constants.ts +94 -0
  306. package/src/training/index.ts +138 -0
  307. package/src/training/schema.ts +147 -0
  308. package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  309. package/src/training/scripts/generate-spatial-dataset.ts +521 -0
  310. package/src/training/training/data/novel-use-cases.jsonl +153 -0
  311. package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
  312. package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  313. package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  314. package/src/training/trainingmonkey/index.ts +26 -0
  315. package/src/training/trait-mappings.ts +157 -0
  316. package/src/types/core-stubs.d.ts +113 -0
  317. package/src/types.ts +304 -0
  318. package/test-output.txt +0 -0
  319. package/test-result.json +1 -0
  320. package/tsc-errors.txt +4 -0
  321. package/tsc_output.txt +0 -0
  322. package/tsconfig.json +14 -0
  323. package/tsup-learning-esm.config.ts +12 -0
  324. package/tsup.config.ts +21 -0
  325. package/typescript-errors-2.txt +0 -0
  326. package/typescript-errors.txt +22 -0
  327. package/vitest-log-utf8.txt +268 -0
  328. package/vitest-log.txt +0 -0
  329. package/vitest.config.ts +8 -0
@@ -0,0 +1,276 @@
1
+ /**
2
+ * @fileoverview Tests for NormEngine — CRSEC Lifecycle
3
+ */
4
+
5
+ import { describe, it, expect } from 'vitest';
6
+ import { NormEngine, BUILTIN_NORMS, criticalMassForChange } from '../NormEngine';
7
+ import type { CulturalNorm } from '@holoscript/core';
8
+
9
+ describe('NormEngine', () => {
10
+ // ── Norm Registration ────────────────────────────────────────────────────
11
+
12
+ describe('Norm Registration', () => {
13
+ it('starts with built-in norms', () => {
14
+ const engine = new NormEngine();
15
+ expect(engine.listNorms().length).toBeGreaterThanOrEqual(BUILTIN_NORMS.length);
16
+ });
17
+
18
+ it('registers custom norms', () => {
19
+ const engine = new NormEngine();
20
+ const custom: CulturalNorm = {
21
+ id: 'custom_1',
22
+ name: 'Custom Norm',
23
+ category: 'cooperation',
24
+ description: 'Test norm',
25
+ enforcement: 'soft',
26
+ scope: 'zone',
27
+ activationThreshold: 0.5,
28
+ strength: 'moderate',
29
+ };
30
+ engine.registerNorm(custom);
31
+ expect(engine.getNorm('custom_1')).toBeDefined();
32
+ });
33
+ });
34
+
35
+ // ── Agent Adoption ───────────────────────────────────────────────────────
36
+
37
+ describe('Adoption', () => {
38
+ it('agents adopt norms', () => {
39
+ const engine = new NormEngine();
40
+ engine.registerAgent('agent1', ['no_griefing']);
41
+ expect(engine.adoptionRate('no_griefing')).toBe(1);
42
+ });
43
+
44
+ it('tracks adoption rate across population', () => {
45
+ const engine = new NormEngine();
46
+ engine.registerAgent('a1', ['no_griefing']);
47
+ engine.registerAgent('a2', ['no_griefing']);
48
+ engine.registerAgent('a3');
49
+ expect(engine.adoptionRate('no_griefing')).toBeCloseTo(2 / 3, 2);
50
+ });
51
+
52
+ it('agents abandon norms', () => {
53
+ const engine = new NormEngine();
54
+ engine.registerAgent('a1', ['no_griefing']);
55
+ engine.abandon('a1', 'no_griefing');
56
+ expect(engine.adoptionRate('no_griefing')).toBe(0);
57
+ });
58
+
59
+ it('norm becomes active when adoption exceeds threshold', () => {
60
+ const engine = new NormEngine({ activationThreshold: 0.5 });
61
+ engine.registerAgent('a1', ['resource_sharing']);
62
+ engine.registerAgent('a2');
63
+ // 50% adoption = threshold → active
64
+ expect(engine.isActive('resource_sharing')).toBe(true);
65
+ });
66
+ });
67
+
68
+ // ── Norm Evaluation ──────────────────────────────────────────────────────
69
+
70
+ describe('Evaluation', () => {
71
+ it('detects violation of no_griefing', () => {
72
+ const engine = new NormEngine();
73
+ // Make no_griefing active by having all agents adopt it
74
+ engine.registerAgent('a1', ['no_griefing']);
75
+ const violations = engine.evaluate('a1', ['agent:kill'], 'zone_a');
76
+ expect(violations.length).toBeGreaterThan(0);
77
+ expect(violations[0].normId).toBe('no_griefing');
78
+ });
79
+
80
+ it('no violation for allowed effects', () => {
81
+ const engine = new NormEngine();
82
+ engine.registerAgent('a1', ['no_griefing']);
83
+ const violations = engine.evaluate('a1', ['render:spawn', 'audio:play'], 'zone_a');
84
+ expect(violations).toHaveLength(0);
85
+ });
86
+
87
+ it('inactive norms do not trigger violations', () => {
88
+ const engine = new NormEngine({ activationThreshold: 0.8 });
89
+ engine.registerAgent('a1'); // Does not adopt resource_sharing
90
+ engine.registerAgent('a2');
91
+ // resource_sharing has activationThreshold of 0.5 in built-in, but nobody adopted it
92
+ const violations = engine.evaluate('a1', ['inventory:give'], 'zone_a');
93
+ // No violations because norm is not active
94
+ expect(violations.filter((v) => v.normId === 'resource_sharing')).toHaveLength(0);
95
+ });
96
+ });
97
+
98
+ // ── Compliance ───────────────────────────────────────────────────────────
99
+
100
+ describe('Compliance', () => {
101
+ it('rewards compliance', () => {
102
+ const engine = new NormEngine({ complianceReward: 0.1, violationPenalty: 0.3 });
103
+ engine.registerAgent('a1', ['no_griefing']);
104
+ // Lower compliance first via a violation
105
+ engine.recordViolation({
106
+ normId: 'no_griefing',
107
+ agentId: 'a1',
108
+ effect: 'agent:kill',
109
+ timestamp: 0,
110
+ severity: 'hard',
111
+ witnessed: [],
112
+ });
113
+ const before = engine.getCompliance('a1', 'no_griefing');
114
+ expect(before).toBeLessThan(1);
115
+ engine.recordCompliance('a1', 'no_griefing');
116
+ const after = engine.getCompliance('a1', 'no_griefing');
117
+ expect(after).toBeGreaterThan(before);
118
+ });
119
+
120
+ it('penalizes violations', () => {
121
+ const engine = new NormEngine({ violationPenalty: 0.2 });
122
+ engine.registerAgent('a1', ['no_griefing']);
123
+ const before = engine.getCompliance('a1', 'no_griefing');
124
+ engine.recordViolation({
125
+ normId: 'no_griefing',
126
+ agentId: 'a1',
127
+ effect: 'agent:kill',
128
+ timestamp: 0,
129
+ severity: 'hard',
130
+ witnessed: [],
131
+ });
132
+ const after = engine.getCompliance('a1', 'no_griefing');
133
+ expect(after).toBeLessThan(before);
134
+ });
135
+ });
136
+
137
+ // ── Proposals ────────────────────────────────────────────────────────────
138
+
139
+ describe('Proposals', () => {
140
+ it('agents propose new norms', () => {
141
+ const engine = new NormEngine();
142
+ engine.registerAgent('a1');
143
+ engine.registerAgent('a2');
144
+ const proposal = engine.proposeNorm('a1', {
145
+ id: 'quiet_zone',
146
+ name: 'Quiet Zone',
147
+ category: 'safety',
148
+ description: 'No audio in library zones',
149
+ enforcement: 'soft',
150
+ scope: 'zone',
151
+ activationThreshold: 0.3,
152
+ strength: 'moderate',
153
+ forbiddenEffects: ['audio:play', 'audio:global'],
154
+ });
155
+ expect(proposal.status).toBe('pending');
156
+ });
157
+
158
+ it('proposals are adopted when vote threshold met', () => {
159
+ const engine = new NormEngine({ proposalThreshold: 0.5 });
160
+ engine.registerAgent('a1');
161
+ engine.registerAgent('a2');
162
+ const proposal = engine.proposeNorm('a1', {
163
+ id: 'new_norm',
164
+ name: 'New',
165
+ category: 'cooperation',
166
+ description: 'Test',
167
+ enforcement: 'soft',
168
+ scope: 'zone',
169
+ activationThreshold: 0.3,
170
+ strength: 'moderate',
171
+ });
172
+ engine.vote(proposal.id, 'a1', true);
173
+ engine.vote(proposal.id, 'a2', true);
174
+ expect(proposal.status).toBe('adopted');
175
+ expect(engine.getNorm('new_norm')).toBeDefined();
176
+ });
177
+
178
+ it('proposals are rejected when votes fail', () => {
179
+ const engine = new NormEngine({ proposalThreshold: 0.8 });
180
+ engine.registerAgent('a1');
181
+ engine.registerAgent('a2');
182
+ const proposal = engine.proposeNorm('a1', {
183
+ id: 'bad_norm',
184
+ name: 'Bad',
185
+ category: 'authority',
186
+ description: 'Test',
187
+ enforcement: 'hard',
188
+ scope: 'world',
189
+ activationThreshold: 0,
190
+ strength: 'strong',
191
+ });
192
+ engine.vote(proposal.id, 'a1', true);
193
+ engine.vote(proposal.id, 'a2', false); // 50% < 80% threshold
194
+ expect(proposal.status).toBe('rejected');
195
+ });
196
+ });
197
+
198
+ // ── Cultural Health ──────────────────────────────────────────────────────
199
+
200
+ describe('Cultural Health', () => {
201
+ it('healthy population has high score', () => {
202
+ const engine = new NormEngine();
203
+ engine.registerAgent('a1', ['no_griefing', 'fair_trade']);
204
+ engine.registerAgent('a2', ['no_griefing', 'fair_trade']);
205
+ expect(engine.culturalHealth()).toBe(1); // All compliant
206
+ });
207
+
208
+ it('violations decrease health', () => {
209
+ const engine = new NormEngine({ violationPenalty: 0.5 });
210
+ engine.registerAgent('a1', ['no_griefing']);
211
+ engine.recordViolation({
212
+ normId: 'no_griefing',
213
+ agentId: 'a1',
214
+ effect: 'agent:kill',
215
+ timestamp: 0,
216
+ severity: 'hard',
217
+ witnessed: [],
218
+ });
219
+ expect(engine.culturalHealth()).toBeLessThan(1);
220
+ });
221
+
222
+ it('empty population has perfect health', () => {
223
+ const engine = new NormEngine();
224
+ expect(engine.culturalHealth()).toBe(1);
225
+ });
226
+ });
227
+
228
+ // ── Adoption Curves ──────────────────────────────────────────────────────
229
+
230
+ describe('Adoption Curves', () => {
231
+ it('tracks adoption over ticks', () => {
232
+ const engine = new NormEngine();
233
+ engine.registerAgent('a1');
234
+ engine.tick();
235
+ engine.adopt('a1', 'no_griefing');
236
+ engine.tick();
237
+ const curve = engine.adoptionCurve('no_griefing');
238
+ expect(curve).toHaveLength(2);
239
+ expect(curve[0].rate).toBe(0);
240
+ expect(curve[1].rate).toBe(1);
241
+ });
242
+ });
243
+
244
+ // ── Stats ────────────────────────────────────────────────────────────────
245
+
246
+ describe('Stats', () => {
247
+ it('reports correct stats', () => {
248
+ const engine = new NormEngine();
249
+ engine.registerAgent('a1', ['no_griefing']);
250
+ engine.registerAgent('a2');
251
+ const s = engine.stats();
252
+ expect(s.agents).toBe(2);
253
+ expect(s.norms).toBeGreaterThanOrEqual(BUILTIN_NORMS.length);
254
+ expect(s.activeNorms).toBeGreaterThan(0);
255
+ });
256
+ });
257
+
258
+ // ── Critical Mass ────────────────────────────────────────────────────────
259
+
260
+ describe('Critical Mass', () => {
261
+ it('weak norms require 2% for change', () => {
262
+ const weakNorm = BUILTIN_NORMS.find((n) => n.strength === 'weak')!;
263
+ expect(criticalMassForChange(weakNorm, 100)).toBe(2);
264
+ });
265
+
266
+ it('strong norms require 50% for change', () => {
267
+ const strongNorm = BUILTIN_NORMS.find((n) => n.strength === 'strong')!;
268
+ expect(criticalMassForChange(strongNorm, 100)).toBe(50);
269
+ });
270
+
271
+ it('moderate norms require 25% for change', () => {
272
+ const modNorm = BUILTIN_NORMS.find((n) => n.strength === 'moderate')!;
273
+ expect(criticalMassForChange(modNorm, 100)).toBe(25);
274
+ });
275
+ });
276
+ });
@@ -0,0 +1,182 @@
1
+ /**
2
+ * OrchestratorAgent Tests
3
+ *
4
+ * Tests the first concrete BaseAgent implementation with 7-phase protocol.
5
+ * Part of HoloScript v5.5 "Agents as Universal Orchestrators".
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
+ import { OrchestratorAgent, type OrchestratorConfig } from '../OrchestratorAgent';
10
+ import { resetDefaultRegistry, getDefaultRegistry } from '../AgentRegistry';
11
+
12
+ // =============================================================================
13
+ // FIXTURES
14
+ // =============================================================================
15
+
16
+ function makeConfig(overrides: Partial<OrchestratorConfig> = {}): OrchestratorConfig {
17
+ return {
18
+ name: 'Test Orchestrator',
19
+ domain: 'spatial',
20
+ autoDiscovery: false,
21
+ localExecutor: async (skillId, args) => ({
22
+ executed: true,
23
+ skillId,
24
+ args,
25
+ }),
26
+ ...overrides,
27
+ };
28
+ }
29
+
30
+ // =============================================================================
31
+ // TESTS
32
+ // =============================================================================
33
+
34
+ describe('OrchestratorAgent', () => {
35
+ beforeEach(() => {
36
+ resetDefaultRegistry();
37
+ });
38
+
39
+ afterEach(() => {
40
+ resetDefaultRegistry();
41
+ });
42
+
43
+ describe('identity', () => {
44
+ it('has correct identity fields', () => {
45
+ const agent = new OrchestratorAgent(makeConfig());
46
+
47
+ expect(agent.identity.id).toBe('orchestrator-test-orchestrator');
48
+ expect(agent.identity.name).toBe('Test Orchestrator');
49
+ expect(agent.identity.domain).toBe('spatial');
50
+ expect(agent.identity.version).toBe('1.0.0');
51
+ expect(agent.identity.capabilities).toContain('orchestrate');
52
+ expect(agent.identity.capabilities).toContain('delegate');
53
+ });
54
+ });
55
+
56
+ describe('runCycle', () => {
57
+ it('executes a complete 7-phase cycle', async () => {
58
+ const agent = new OrchestratorAgent(makeConfig());
59
+
60
+ const result = await agent.runCycle('test-task', { type: 'analyze' });
61
+
62
+ expect(result.status).toBe('complete');
63
+ expect(result.phases).toHaveLength(7);
64
+ expect(result.domain).toBe('spatial');
65
+ expect(result.task).toBe('test-task');
66
+ expect(result.totalDurationMs).toBeGreaterThanOrEqual(0);
67
+
68
+ // Verify phase order
69
+ const phaseNames = result.phases.map((p) => p.phase);
70
+ expect(phaseNames).toEqual([0, 1, 2, 3, 4, 5, 6]);
71
+ });
72
+
73
+ it('all phases succeed with no agents registered', async () => {
74
+ const agent = new OrchestratorAgent(makeConfig());
75
+
76
+ const result = await agent.runCycle('discover');
77
+
78
+ // Even with no agents to delegate to, the cycle completes
79
+ for (const phase of result.phases) {
80
+ expect(phase.status).toBe('success');
81
+ }
82
+ });
83
+
84
+ it('INTAKE phase discovers registered agents', async () => {
85
+ const registry = getDefaultRegistry();
86
+ await registry.register({
87
+ id: 'helper-agent',
88
+ name: 'Helper',
89
+ version: '1.0.0',
90
+ capabilities: [{ type: 'analyze', domain: 'spatial' }],
91
+ endpoints: [{ protocol: 'local', address: 'local://helper' }],
92
+ trustLevel: 'local',
93
+ status: 'online',
94
+ });
95
+
96
+ const agent = new OrchestratorAgent(makeConfig());
97
+ const result = await agent.runCycle('test');
98
+
99
+ const intakeData = result.phases[0].data as Record<string, unknown>;
100
+ expect(intakeData.totalAgents).toBe(1);
101
+ expect(intakeData.onlineAgents).toBe(1);
102
+ });
103
+ });
104
+
105
+ describe('delegateTask', () => {
106
+ it('delegates to a registered agent', async () => {
107
+ const registry = getDefaultRegistry();
108
+ await registry.register({
109
+ id: 'worker-agent',
110
+ name: 'Worker',
111
+ version: '1.0.0',
112
+ capabilities: [{ type: 'transform', domain: 'spatial' }],
113
+ endpoints: [{ protocol: 'local', address: 'local://worker', primary: true }],
114
+ trustLevel: 'local',
115
+ status: 'online',
116
+ });
117
+
118
+ const agent = new OrchestratorAgent(makeConfig());
119
+ const result = await agent.delegateTask('transform_data', { input: 'test' });
120
+
121
+ // Should be rejected because autoDelegate with empty query won't match
122
+ // (no type/domain specified in the query)
123
+ expect(result.taskId).toBeDefined();
124
+ });
125
+
126
+ it('returns rejected when no agents available', async () => {
127
+ const agent = new OrchestratorAgent(makeConfig());
128
+ const result = await agent.delegateTask('test_skill', {});
129
+
130
+ expect(result.status).toBe('rejected');
131
+ });
132
+ });
133
+
134
+ describe('runWorkflow', () => {
135
+ it('runs a workflow using localExecutor', async () => {
136
+ const agent = new OrchestratorAgent(makeConfig());
137
+
138
+ const result = await agent.runWorkflow({
139
+ id: 'test-wf',
140
+ name: 'Test Workflow',
141
+ steps: [
142
+ {
143
+ id: 'step1',
144
+ skillId: 'parse',
145
+ inputs: { code: { type: 'literal', value: 'test' } },
146
+ },
147
+ ],
148
+ });
149
+
150
+ expect(result.status).toBe('completed');
151
+ expect(result.stepResults).toHaveLength(1);
152
+ expect(result.stepResults[0].status).toBe('completed');
153
+ });
154
+ });
155
+
156
+ describe('getDiscoveredAgents', () => {
157
+ it('returns all agents from registry', async () => {
158
+ const registry = getDefaultRegistry();
159
+ await registry.register({
160
+ id: 'agent-a',
161
+ name: 'A',
162
+ version: '1.0.0',
163
+ capabilities: [{ type: 'analyze', domain: 'general' }],
164
+ endpoints: [{ protocol: 'local', address: 'local://a' }],
165
+ trustLevel: 'local',
166
+ });
167
+
168
+ const agent = new OrchestratorAgent(makeConfig());
169
+ const agents = agent.getDiscoveredAgents();
170
+
171
+ expect(agents).toHaveLength(1);
172
+ expect(agents[0].id).toBe('agent-a');
173
+ });
174
+ });
175
+
176
+ describe('shutdown', () => {
177
+ it('stops polling without error', () => {
178
+ const agent = new OrchestratorAgent(makeConfig());
179
+ expect(() => agent.shutdown()).not.toThrow();
180
+ });
181
+ });
182
+ });