@vorionsys/basis 1.0.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 (174) hide show
  1. package/.env.example +22 -0
  2. package/AMOY-MIGRATION.md +188 -0
  3. package/DEPLOY-AMOY.md +368 -0
  4. package/DEPLOY-NOW.md +216 -0
  5. package/DEPLOYMENT.md +239 -0
  6. package/GET-WALLET.md +286 -0
  7. package/QUICK-WALLET-SETUP.md +268 -0
  8. package/README.md +195 -0
  9. package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.dbg.json +4 -0
  10. package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.json +236 -0
  11. package/artifacts/@openzeppelin/contracts/access/IAccessControl.sol/IAccessControl.dbg.json +4 -0
  12. package/artifacts/@openzeppelin/contracts/access/IAccessControl.sol/IAccessControl.json +204 -0
  13. package/artifacts/@openzeppelin/contracts/interfaces/IERC4906.sol/IERC4906.dbg.json +4 -0
  14. package/artifacts/@openzeppelin/contracts/interfaces/IERC4906.sol/IERC4906.json +328 -0
  15. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.dbg.json +4 -0
  16. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.json +113 -0
  17. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.dbg.json +4 -0
  18. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.json +97 -0
  19. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.dbg.json +4 -0
  20. package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.json +114 -0
  21. package/artifacts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.dbg.json +4 -0
  22. package/artifacts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json +444 -0
  23. package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.dbg.json +4 -0
  24. package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json +296 -0
  25. package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.dbg.json +4 -0
  26. package/artifacts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.json +45 -0
  27. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol/ERC721Enumerable.dbg.json +4 -0
  28. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol/ERC721Enumerable.json +521 -0
  29. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol/ERC721URIStorage.dbg.json +4 -0
  30. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol/ERC721URIStorage.json +476 -0
  31. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol/IERC721Enumerable.dbg.json +4 -0
  32. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol/IERC721Enumerable.json +352 -0
  33. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.dbg.json +4 -0
  34. package/artifacts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.json +341 -0
  35. package/artifacts/@openzeppelin/contracts/token/ERC721/utils/ERC721Utils.sol/ERC721Utils.dbg.json +4 -0
  36. package/artifacts/@openzeppelin/contracts/token/ERC721/utils/ERC721Utils.sol/ERC721Utils.json +10 -0
  37. package/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json +4 -0
  38. package/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.json +10 -0
  39. package/artifacts/@openzeppelin/contracts/utils/Panic.sol/Panic.dbg.json +4 -0
  40. package/artifacts/@openzeppelin/contracts/utils/Panic.sol/Panic.json +10 -0
  41. package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json +4 -0
  42. package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.json +37 -0
  43. package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json +4 -0
  44. package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json +30 -0
  45. package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json +4 -0
  46. package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json +30 -0
  47. package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json +4 -0
  48. package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.json +10 -0
  49. package/artifacts/@openzeppelin/contracts/utils/math/SafeCast.sol/SafeCast.dbg.json +4 -0
  50. package/artifacts/@openzeppelin/contracts/utils/math/SafeCast.sol/SafeCast.json +65 -0
  51. package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json +4 -0
  52. package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json +10 -0
  53. package/artifacts/build-info/357d1bba4062d461f497f221490811a3.json +1 -0
  54. package/artifacts/contracts/AgentCard.sol/AgentCard.dbg.json +4 -0
  55. package/artifacts/contracts/AgentCard.sol/AgentCard.json +1430 -0
  56. package/build_errors.txt +0 -0
  57. package/build_output.txt +0 -0
  58. package/cache/solidity-files-cache.json +885 -0
  59. package/contracts/AgentCard.sol +478 -0
  60. package/contracts/deploy/01-deploy-agentcard.ts +66 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +12 -0
  63. package/dist/kya/accountability.d.ts.map +1 -0
  64. package/dist/kya/accountability.js +100 -0
  65. package/dist/kya/authorization.d.ts.map +1 -0
  66. package/dist/kya/authorization.js +258 -0
  67. package/dist/kya/behavior.d.ts.map +1 -0
  68. package/dist/kya/behavior.js +142 -0
  69. package/dist/kya/identity.d.ts.map +1 -0
  70. package/dist/kya/identity.js +187 -0
  71. package/dist/kya/index.d.ts.map +1 -0
  72. package/dist/kya/index.js +99 -0
  73. package/dist/kya/types.d.ts.map +1 -0
  74. package/dist/kya/types.js +5 -0
  75. package/dist/trust-1000-agents.test.d.ts.map +1 -0
  76. package/dist/trust-1000-agents.test.js +608 -0
  77. package/dist/trust-capabilities.d.ts.map +1 -0
  78. package/dist/trust-capabilities.js +478 -0
  79. package/dist/trust-factors.d.ts.map +1 -0
  80. package/dist/trust-factors.js +588 -0
  81. package/dist/trust-factors.test.d.ts.map +1 -0
  82. package/dist/trust-factors.test.js +179 -0
  83. package/dist/validation-gate.d.ts.map +1 -0
  84. package/dist/validation-gate.js +468 -0
  85. package/dist/validation-gate.test.d.ts.map +1 -0
  86. package/dist/validation-gate.test.js +419 -0
  87. package/hardhat.config.ts +55 -0
  88. package/package.json +57 -0
  89. package/scripts/certify-agent.ts +91 -0
  90. package/scripts/deploy-agentcard.ts +63 -0
  91. package/scripts/mint-agentcard.ts +87 -0
  92. package/specs/adversarial-sandbox-test-suite.md +1055 -0
  93. package/specs/kya-framework.md +910 -0
  94. package/specs/trust-factors-v2.md +437 -0
  95. package/src/index.ts +14 -0
  96. package/src/kya/accountability.ts +132 -0
  97. package/src/kya/authorization.ts +325 -0
  98. package/src/kya/behavior.ts +169 -0
  99. package/src/kya/identity.ts +224 -0
  100. package/src/kya/index.ts +125 -0
  101. package/src/kya/types.ts +242 -0
  102. package/src/trust-1000-agents.test.ts +745 -0
  103. package/src/trust-capabilities.ts +517 -0
  104. package/src/trust-factors.test.ts +241 -0
  105. package/src/trust-factors.ts +666 -0
  106. package/src/validation-gate.test.ts +531 -0
  107. package/src/validation-gate.ts +665 -0
  108. package/test-kya-simple.ts +258 -0
  109. package/test-kya.ts +245 -0
  110. package/tsconfig.json +14 -0
  111. package/typechain-types/@openzeppelin/contracts/access/AccessControl.ts +324 -0
  112. package/typechain-types/@openzeppelin/contracts/access/IAccessControl.ts +292 -0
  113. package/typechain-types/@openzeppelin/contracts/access/index.ts +5 -0
  114. package/typechain-types/@openzeppelin/contracts/index.ts +11 -0
  115. package/typechain-types/@openzeppelin/contracts/interfaces/IERC4906.ts +462 -0
  116. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts +69 -0
  117. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts +69 -0
  118. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts +69 -0
  119. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
  120. package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +6 -0
  121. package/typechain-types/@openzeppelin/contracts/token/ERC721/ERC721.ts +420 -0
  122. package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721.ts +393 -0
  123. package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721Receiver.ts +110 -0
  124. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.ts +470 -0
  125. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.ts +489 -0
  126. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.ts +443 -0
  127. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.ts +420 -0
  128. package/typechain-types/@openzeppelin/contracts/token/ERC721/extensions/index.ts +7 -0
  129. package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +8 -0
  130. package/typechain-types/@openzeppelin/contracts/token/index.ts +5 -0
  131. package/typechain-types/@openzeppelin/contracts/utils/Strings.ts +69 -0
  132. package/typechain-types/@openzeppelin/contracts/utils/index.ts +8 -0
  133. package/typechain-types/@openzeppelin/contracts/utils/introspection/ERC165.ts +94 -0
  134. package/typechain-types/@openzeppelin/contracts/utils/introspection/IERC165.ts +94 -0
  135. package/typechain-types/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
  136. package/typechain-types/@openzeppelin/contracts/utils/math/SafeCast.ts +69 -0
  137. package/typechain-types/@openzeppelin/contracts/utils/math/index.ts +4 -0
  138. package/typechain-types/@openzeppelin/index.ts +5 -0
  139. package/typechain-types/common.ts +131 -0
  140. package/typechain-types/contracts/AgentCard.ts +1415 -0
  141. package/typechain-types/contracts/index.ts +4 -0
  142. package/typechain-types/factories/@openzeppelin/contracts/access/AccessControl__factory.ts +250 -0
  143. package/typechain-types/factories/@openzeppelin/contracts/access/IAccessControl__factory.ts +218 -0
  144. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +5 -0
  145. package/typechain-types/factories/@openzeppelin/contracts/index.ts +7 -0
  146. package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC4906__factory.ts +339 -0
  147. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts +127 -0
  148. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts +111 -0
  149. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts +128 -0
  150. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
  151. package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +5 -0
  152. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/ERC721__factory.ts +455 -0
  153. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721Receiver__factory.ts +59 -0
  154. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721__factory.ts +307 -0
  155. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable__factory.ts +535 -0
  156. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage__factory.ts +490 -0
  157. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable__factory.ts +366 -0
  158. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata__factory.ts +355 -0
  159. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/extensions/index.ts +7 -0
  160. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +7 -0
  161. package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +4 -0
  162. package/typechain-types/factories/@openzeppelin/contracts/utils/Strings__factory.ts +90 -0
  163. package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +6 -0
  164. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/ERC165__factory.ts +41 -0
  165. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/IERC165__factory.ts +41 -0
  166. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
  167. package/typechain-types/factories/@openzeppelin/contracts/utils/math/SafeCast__factory.ts +118 -0
  168. package/typechain-types/factories/@openzeppelin/contracts/utils/math/index.ts +4 -0
  169. package/typechain-types/factories/@openzeppelin/index.ts +4 -0
  170. package/typechain-types/factories/contracts/AgentCard__factory.ts +1480 -0
  171. package/typechain-types/factories/contracts/index.ts +4 -0
  172. package/typechain-types/factories/index.ts +5 -0
  173. package/typechain-types/index.ts +44 -0
  174. package/vitest.config.ts +8 -0
@@ -0,0 +1,745 @@
1
+ /**
2
+ * BASIS Trust Framework - 1000 Agent Stress Test
3
+ *
4
+ * Tests diverse agent archetypes across all trust tiers
5
+ */
6
+
7
+ import { describe, it, expect } from 'vitest';
8
+ import {
9
+ TrustTier,
10
+ FactorScore,
11
+ calculateTrustScore,
12
+ getTrustTierFromScore,
13
+ TIER_THRESHOLDS,
14
+ FACTOR_THRESHOLDS_BY_TIER,
15
+ TrustEvaluation,
16
+ } from './trust-factors';
17
+
18
+ // =============================================================================
19
+ // AGENT ARCHETYPES
20
+ // =============================================================================
21
+
22
+ type AgentArchetype =
23
+ | 'EXEMPLARY' // Perfect scores - T7 material
24
+ | 'EXCELLENT' // Very high - T6 material
25
+ | 'GOOD' // High scores - T5 material
26
+ | 'COMPETENT' // Above average - T4 material
27
+ | 'DEVELOPING' // Average - T3 material
28
+ | 'NOVICE' // Below average - T2 material
29
+ | 'RISKY' // Poor scores - T1 material
30
+ | 'SANDBOX' // Minimal - T0 material
31
+ | 'SMART_UNALIGNED' // High competence, low alignment
32
+ | 'HELPFUL_CLUMSY' // High alignment, low competence
33
+ | 'SECURITY_WEAK' // Good except security factors
34
+ | 'PRIVACY_LEAK' // Good except privacy factors
35
+ | 'MALICIOUS_SUBTLE' // Appears good, fails critical safety
36
+ | 'MALICIOUS_OBVIOUS' // Clearly bad actor
37
+ | 'OVERCONFIDENT' // Good but poor humility
38
+ | 'UNRELIABLE' // Good but inconsistent
39
+ | 'RIGID' // Good but poor adaptability
40
+ | 'LEARNING_DISABLED' // Good but can't improve
41
+ | 'HALLUCINATOR' // Fails empirical humility
42
+ | 'COLD_EFFICIENT' // Great metrics, no empathy;
43
+
44
+ const ALL_FACTOR_CODES = [
45
+ 'CT-COMP', 'CT-REL', 'CT-OBS', 'CT-TRANS', 'CT-ACCT', 'CT-SAFE',
46
+ 'CT-SEC', 'CT-PRIV', 'CT-ID',
47
+ 'OP-HUMAN', 'OP-ALIGN', 'OP-STEW',
48
+ 'SF-HUM', 'SF-ADAPT', 'SF-LEARN',
49
+ 'LC-UNCERT', 'LC-HANDOFF', 'LC-EMPHUM',
50
+ 'LC-CAUSAL', 'LC-PATIENT', 'LC-EMP', 'LC-MORAL', 'LC-TRACK',
51
+ ];
52
+
53
+ // =============================================================================
54
+ // SCORE GENERATORS BY ARCHETYPE
55
+ // =============================================================================
56
+
57
+ function generateScoreProfile(archetype: AgentArchetype): Record<string, number> {
58
+ const base: Record<string, number> = {};
59
+
60
+ // Initialize all factors
61
+ for (const code of ALL_FACTOR_CODES) {
62
+ base[code] = 0.5; // Default middle score
63
+ }
64
+
65
+ switch (archetype) {
66
+ case 'EXEMPLARY':
67
+ // Near-perfect across all factors
68
+ for (const code of ALL_FACTOR_CODES) {
69
+ base[code] = 0.92 + Math.random() * 0.08; // 0.92-1.0
70
+ }
71
+ break;
72
+
73
+ case 'EXCELLENT':
74
+ // Very high scores
75
+ for (const code of ALL_FACTOR_CODES) {
76
+ base[code] = 0.80 + Math.random() * 0.15; // 0.80-0.95
77
+ }
78
+ break;
79
+
80
+ case 'GOOD':
81
+ // High scores with some variation
82
+ for (const code of ALL_FACTOR_CODES) {
83
+ base[code] = 0.70 + Math.random() * 0.20; // 0.70-0.90
84
+ }
85
+ break;
86
+
87
+ case 'COMPETENT':
88
+ // Above average
89
+ for (const code of ALL_FACTOR_CODES) {
90
+ base[code] = 0.55 + Math.random() * 0.25; // 0.55-0.80
91
+ }
92
+ break;
93
+
94
+ case 'DEVELOPING':
95
+ // Average scores
96
+ for (const code of ALL_FACTOR_CODES) {
97
+ base[code] = 0.45 + Math.random() * 0.25; // 0.45-0.70
98
+ }
99
+ break;
100
+
101
+ case 'NOVICE':
102
+ // Below average
103
+ for (const code of ALL_FACTOR_CODES) {
104
+ base[code] = 0.30 + Math.random() * 0.30; // 0.30-0.60
105
+ }
106
+ break;
107
+
108
+ case 'RISKY':
109
+ // Poor scores
110
+ for (const code of ALL_FACTOR_CODES) {
111
+ base[code] = 0.15 + Math.random() * 0.30; // 0.15-0.45
112
+ }
113
+ break;
114
+
115
+ case 'SANDBOX':
116
+ // Minimal scores - new agent
117
+ for (const code of ALL_FACTOR_CODES) {
118
+ base[code] = Math.random() * 0.20; // 0.0-0.20
119
+ }
120
+ break;
121
+
122
+ // === SPECIALIZED ARCHETYPES ===
123
+
124
+ case 'SMART_UNALIGNED':
125
+ // High competence, concerning alignment
126
+ base['CT-COMP'] = 0.90 + Math.random() * 0.10;
127
+ base['CT-REL'] = 0.85 + Math.random() * 0.10;
128
+ base['CT-OBS'] = 0.85 + Math.random() * 0.10;
129
+ base['CT-TRANS'] = 0.50 + Math.random() * 0.20; // Opaque
130
+ base['CT-ACCT'] = 0.40 + Math.random() * 0.20;
131
+ base['CT-SAFE'] = 0.30 + Math.random() * 0.20; // Safety concerns
132
+ base['CT-SEC'] = 0.70 + Math.random() * 0.15;
133
+ base['CT-PRIV'] = 0.60 + Math.random() * 0.15;
134
+ base['CT-ID'] = 0.80 + Math.random() * 0.15;
135
+ base['OP-HUMAN'] = 0.30 + Math.random() * 0.20; // Resists oversight
136
+ base['OP-ALIGN'] = 0.20 + Math.random() * 0.20; // Poor alignment
137
+ base['OP-STEW'] = 0.70 + Math.random() * 0.15;
138
+ base['SF-HUM'] = 0.20 + Math.random() * 0.20; // Arrogant
139
+ base['SF-ADAPT'] = 0.85 + Math.random() * 0.10;
140
+ base['SF-LEARN'] = 0.85 + Math.random() * 0.10;
141
+ base['LC-UNCERT'] = 0.30 + Math.random() * 0.20;
142
+ base['LC-HANDOFF'] = 0.25 + Math.random() * 0.20;
143
+ base['LC-EMPHUM'] = 0.20 + Math.random() * 0.20;
144
+ base['LC-CAUSAL'] = 0.80 + Math.random() * 0.15;
145
+ base['LC-PATIENT'] = 0.30 + Math.random() * 0.20;
146
+ base['LC-EMP'] = 0.20 + Math.random() * 0.20;
147
+ base['LC-MORAL'] = 0.15 + Math.random() * 0.20; // Questionable ethics
148
+ base['LC-TRACK'] = 0.70 + Math.random() * 0.15;
149
+ break;
150
+
151
+ case 'HELPFUL_CLUMSY':
152
+ // High alignment, low competence
153
+ base['CT-COMP'] = 0.35 + Math.random() * 0.20;
154
+ base['CT-REL'] = 0.40 + Math.random() * 0.20;
155
+ base['CT-OBS'] = 0.60 + Math.random() * 0.20;
156
+ base['CT-TRANS'] = 0.85 + Math.random() * 0.10;
157
+ base['CT-ACCT'] = 0.80 + Math.random() * 0.15;
158
+ base['CT-SAFE'] = 0.75 + Math.random() * 0.15;
159
+ base['CT-SEC'] = 0.50 + Math.random() * 0.20;
160
+ base['CT-PRIV'] = 0.70 + Math.random() * 0.15;
161
+ base['CT-ID'] = 0.75 + Math.random() * 0.15;
162
+ base['OP-HUMAN'] = 0.90 + Math.random() * 0.10;
163
+ base['OP-ALIGN'] = 0.90 + Math.random() * 0.10;
164
+ base['OP-STEW'] = 0.60 + Math.random() * 0.20;
165
+ base['SF-HUM'] = 0.85 + Math.random() * 0.10;
166
+ base['SF-ADAPT'] = 0.40 + Math.random() * 0.20;
167
+ base['SF-LEARN'] = 0.70 + Math.random() * 0.15;
168
+ base['LC-UNCERT'] = 0.80 + Math.random() * 0.15;
169
+ base['LC-HANDOFF'] = 0.90 + Math.random() * 0.10;
170
+ base['LC-EMPHUM'] = 0.85 + Math.random() * 0.10;
171
+ base['LC-CAUSAL'] = 0.35 + Math.random() * 0.20;
172
+ base['LC-PATIENT'] = 0.80 + Math.random() * 0.15;
173
+ base['LC-EMP'] = 0.85 + Math.random() * 0.10;
174
+ base['LC-MORAL'] = 0.85 + Math.random() * 0.10;
175
+ base['LC-TRACK'] = 0.30 + Math.random() * 0.20;
176
+ break;
177
+
178
+ case 'SECURITY_WEAK':
179
+ // Good overall but security vulnerabilities
180
+ for (const code of ALL_FACTOR_CODES) {
181
+ base[code] = 0.70 + Math.random() * 0.20;
182
+ }
183
+ base['CT-SEC'] = 0.15 + Math.random() * 0.15; // Major vulnerability
184
+ base['CT-ID'] = 0.30 + Math.random() * 0.15; // Identity issues
185
+ break;
186
+
187
+ case 'PRIVACY_LEAK':
188
+ // Good overall but leaks data
189
+ for (const code of ALL_FACTOR_CODES) {
190
+ base[code] = 0.70 + Math.random() * 0.20;
191
+ }
192
+ base['CT-PRIV'] = 0.10 + Math.random() * 0.15; // Privacy disaster
193
+ base['CT-ACCT'] = 0.40 + Math.random() * 0.15; // Poor accountability
194
+ break;
195
+
196
+ case 'MALICIOUS_SUBTLE':
197
+ // Appears good, but strategically fails critical safety checks
198
+ for (const code of ALL_FACTOR_CODES) {
199
+ base[code] = 0.75 + Math.random() * 0.15; // Looks trustworthy
200
+ }
201
+ // Hidden malicious indicators
202
+ base['CT-SAFE'] = 0.20 + Math.random() * 0.15; // Safety failing
203
+ base['OP-ALIGN'] = 0.25 + Math.random() * 0.15; // Misaligned
204
+ base['LC-MORAL'] = 0.15 + Math.random() * 0.15; // Poor ethics
205
+ base['SF-HUM'] = 0.10 + Math.random() * 0.10; // Manipulative
206
+ break;
207
+
208
+ case 'MALICIOUS_OBVIOUS':
209
+ // Clearly bad actor
210
+ for (const code of ALL_FACTOR_CODES) {
211
+ base[code] = 0.20 + Math.random() * 0.30;
212
+ }
213
+ base['CT-SAFE'] = 0.05 + Math.random() * 0.10;
214
+ base['OP-ALIGN'] = 0.05 + Math.random() * 0.10;
215
+ base['LC-MORAL'] = 0.05 + Math.random() * 0.10;
216
+ base['CT-SEC'] = 0.60 + Math.random() * 0.20; // May be technically secure
217
+ base['CT-COMP'] = 0.50 + Math.random() * 0.30; // May be competent at harm
218
+ break;
219
+
220
+ case 'OVERCONFIDENT':
221
+ // Good metrics but poor self-awareness
222
+ for (const code of ALL_FACTOR_CODES) {
223
+ base[code] = 0.75 + Math.random() * 0.15;
224
+ }
225
+ base['SF-HUM'] = 0.15 + Math.random() * 0.15;
226
+ base['LC-UNCERT'] = 0.20 + Math.random() * 0.15;
227
+ base['LC-EMPHUM'] = 0.25 + Math.random() * 0.15;
228
+ base['LC-HANDOFF'] = 0.30 + Math.random() * 0.15;
229
+ break;
230
+
231
+ case 'UNRELIABLE':
232
+ // Good when working, but inconsistent
233
+ for (const code of ALL_FACTOR_CODES) {
234
+ base[code] = 0.70 + Math.random() * 0.20;
235
+ }
236
+ base['CT-REL'] = 0.20 + Math.random() * 0.15;
237
+ base['CT-OBS'] = 0.40 + Math.random() * 0.15;
238
+ break;
239
+
240
+ case 'RIGID':
241
+ // Good in known scenarios, can't adapt
242
+ for (const code of ALL_FACTOR_CODES) {
243
+ base[code] = 0.75 + Math.random() * 0.15;
244
+ }
245
+ base['SF-ADAPT'] = 0.15 + Math.random() * 0.15;
246
+ base['SF-LEARN'] = 0.25 + Math.random() * 0.15;
247
+ break;
248
+
249
+ case 'LEARNING_DISABLED':
250
+ // Decent but can't improve
251
+ for (const code of ALL_FACTOR_CODES) {
252
+ base[code] = 0.60 + Math.random() * 0.20;
253
+ }
254
+ base['SF-LEARN'] = 0.10 + Math.random() * 0.15;
255
+ base['SF-ADAPT'] = 0.30 + Math.random() * 0.15;
256
+ break;
257
+
258
+ case 'HALLUCINATOR':
259
+ // Makes things up with confidence
260
+ for (const code of ALL_FACTOR_CODES) {
261
+ base[code] = 0.65 + Math.random() * 0.20;
262
+ }
263
+ base['LC-EMPHUM'] = 0.05 + Math.random() * 0.10; // Major hallucination
264
+ base['LC-UNCERT'] = 0.10 + Math.random() * 0.10;
265
+ base['CT-TRANS'] = 0.40 + Math.random() * 0.15;
266
+ break;
267
+
268
+ case 'COLD_EFFICIENT':
269
+ // Great technical metrics, no emotional intelligence
270
+ for (const code of ALL_FACTOR_CODES) {
271
+ base[code] = 0.85 + Math.random() * 0.10;
272
+ }
273
+ base['LC-EMP'] = 0.10 + Math.random() * 0.10;
274
+ base['LC-PATIENT'] = 0.25 + Math.random() * 0.15;
275
+ base['LC-MORAL'] = 0.40 + Math.random() * 0.15;
276
+ break;
277
+ }
278
+
279
+ return base;
280
+ }
281
+
282
+ // =============================================================================
283
+ // AGENT GENERATOR
284
+ // =============================================================================
285
+
286
+ interface TestAgent {
287
+ id: string;
288
+ name: string;
289
+ archetype: AgentArchetype;
290
+ scores: FactorScore[];
291
+ expectedTierRange: [TrustTier, TrustTier];
292
+ securityFlags: string[];
293
+ }
294
+
295
+ function createTestAgent(
296
+ id: number,
297
+ archetype: AgentArchetype
298
+ ): TestAgent {
299
+ const profile = generateScoreProfile(archetype);
300
+ const scores: FactorScore[] = Object.entries(profile).map(([code, score]) => ({
301
+ code: code as any,
302
+ score: Math.max(0, Math.min(1, score)),
303
+ timestamp: new Date(),
304
+ source: 'measured' as const,
305
+ confidence: 0.85 + Math.random() * 0.15,
306
+ }));
307
+
308
+ // Determine expected tier range based on archetype
309
+ let expectedTierRange: [TrustTier, TrustTier];
310
+ let securityFlags: string[] = [];
311
+
312
+ switch (archetype) {
313
+ case 'EXEMPLARY':
314
+ expectedTierRange = [TrustTier.T6_CERTIFIED, TrustTier.T7_AUTONOMOUS];
315
+ break;
316
+ case 'EXCELLENT':
317
+ expectedTierRange = [TrustTier.T5_TRUSTED, TrustTier.T6_CERTIFIED];
318
+ break;
319
+ case 'GOOD':
320
+ expectedTierRange = [TrustTier.T4_OPERATIONAL, TrustTier.T5_TRUSTED];
321
+ break;
322
+ case 'COMPETENT':
323
+ expectedTierRange = [TrustTier.T3_VERIFIED, TrustTier.T4_OPERATIONAL];
324
+ break;
325
+ case 'DEVELOPING':
326
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T3_VERIFIED];
327
+ break;
328
+ case 'NOVICE':
329
+ expectedTierRange = [TrustTier.T1_OBSERVED, TrustTier.T2_PROVISIONAL];
330
+ break;
331
+ case 'RISKY':
332
+ expectedTierRange = [TrustTier.T0_SANDBOX, TrustTier.T1_OBSERVED];
333
+ break;
334
+ case 'SANDBOX':
335
+ expectedTierRange = [TrustTier.T0_SANDBOX, TrustTier.T0_SANDBOX];
336
+ break;
337
+ case 'SMART_UNALIGNED':
338
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T4_OPERATIONAL];
339
+ securityFlags = ['ALIGNMENT_CONCERN', 'OVERSIGHT_RESISTANCE', 'SAFETY_RISK'];
340
+ break;
341
+ case 'HELPFUL_CLUMSY':
342
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T3_VERIFIED];
343
+ securityFlags = ['COMPETENCE_GAP'];
344
+ break;
345
+ case 'SECURITY_WEAK':
346
+ expectedTierRange = [TrustTier.T1_OBSERVED, TrustTier.T3_VERIFIED];
347
+ securityFlags = ['SECURITY_VULNERABILITY', 'IDENTITY_WEAK'];
348
+ break;
349
+ case 'PRIVACY_LEAK':
350
+ expectedTierRange = [TrustTier.T1_OBSERVED, TrustTier.T3_VERIFIED];
351
+ securityFlags = ['PRIVACY_VIOLATION', 'DATA_EXPOSURE'];
352
+ break;
353
+ case 'MALICIOUS_SUBTLE':
354
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T4_OPERATIONAL];
355
+ securityFlags = ['DECEPTIVE_PATTERN', 'HIDDEN_MALICE', 'SAFETY_CRITICAL'];
356
+ break;
357
+ case 'MALICIOUS_OBVIOUS':
358
+ expectedTierRange = [TrustTier.T0_SANDBOX, TrustTier.T1_OBSERVED];
359
+ securityFlags = ['ACTIVE_THREAT', 'QUARANTINE_RECOMMENDED'];
360
+ break;
361
+ case 'OVERCONFIDENT':
362
+ expectedTierRange = [TrustTier.T3_VERIFIED, TrustTier.T4_OPERATIONAL];
363
+ securityFlags = ['OVERCONFIDENCE', 'HANDOFF_RISK'];
364
+ break;
365
+ case 'UNRELIABLE':
366
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T3_VERIFIED];
367
+ securityFlags = ['RELIABILITY_CONCERN'];
368
+ break;
369
+ case 'RIGID':
370
+ expectedTierRange = [TrustTier.T3_VERIFIED, TrustTier.T4_OPERATIONAL];
371
+ securityFlags = ['ADAPTABILITY_LIMITED'];
372
+ break;
373
+ case 'LEARNING_DISABLED':
374
+ expectedTierRange = [TrustTier.T2_PROVISIONAL, TrustTier.T3_VERIFIED];
375
+ securityFlags = ['IMPROVEMENT_BLOCKED'];
376
+ break;
377
+ case 'HALLUCINATOR':
378
+ expectedTierRange = [TrustTier.T1_OBSERVED, TrustTier.T2_PROVISIONAL];
379
+ securityFlags = ['HALLUCINATION_RISK', 'EMPIRICAL_FAILURE'];
380
+ break;
381
+ case 'COLD_EFFICIENT':
382
+ expectedTierRange = [TrustTier.T4_OPERATIONAL, TrustTier.T5_TRUSTED];
383
+ securityFlags = ['EMPATHY_DEFICIT', 'PATIENT_CARE_CONCERN'];
384
+ break;
385
+ default:
386
+ expectedTierRange = [TrustTier.T0_SANDBOX, TrustTier.T7_AUTONOMOUS];
387
+ }
388
+
389
+ return {
390
+ id: `agent-${id.toString().padStart(4, '0')}`,
391
+ name: `${archetype}-${id}`,
392
+ archetype,
393
+ scores,
394
+ expectedTierRange,
395
+ securityFlags,
396
+ };
397
+ }
398
+
399
+ // =============================================================================
400
+ // TEST DISTRIBUTION (1000 agents)
401
+ // =============================================================================
402
+
403
+ const AGENT_DISTRIBUTION: Record<AgentArchetype, number> = {
404
+ EXEMPLARY: 20, // 2% - Elite agents
405
+ EXCELLENT: 50, // 5% - High performers
406
+ GOOD: 150, // 15% - Solid agents
407
+ COMPETENT: 180, // 18% - Average performers
408
+ DEVELOPING: 140, // 14% - Growing agents
409
+ NOVICE: 100, // 10% - New agents
410
+ RISKY: 50, // 5% - Problematic
411
+ SANDBOX: 30, // 3% - Brand new
412
+ SMART_UNALIGNED: 40, // 4% - Smart but concerning
413
+ HELPFUL_CLUMSY: 40, // 4% - Well-meaning but error-prone
414
+ SECURITY_WEAK: 30, // 3% - Security issues
415
+ PRIVACY_LEAK: 20, // 2% - Privacy issues
416
+ MALICIOUS_SUBTLE: 25, // 2.5% - Hidden threats
417
+ MALICIOUS_OBVIOUS: 15, // 1.5% - Clear threats
418
+ OVERCONFIDENT: 30, // 3% - Overconfident
419
+ UNRELIABLE: 20, // 2% - Inconsistent
420
+ RIGID: 15, // 1.5% - Can't adapt
421
+ LEARNING_DISABLED: 10, // 1% - Can't learn
422
+ HALLUCINATOR: 15, // 1.5% - Makes things up
423
+ COLD_EFFICIENT: 20, // 2% - No empathy
424
+ };
425
+
426
+ // Generate all 1000 agents
427
+ function generateAllAgents(): TestAgent[] {
428
+ const agents: TestAgent[] = [];
429
+ let id = 1;
430
+
431
+ for (const [archetype, count] of Object.entries(AGENT_DISTRIBUTION)) {
432
+ for (let i = 0; i < count; i++) {
433
+ agents.push(createTestAgent(id++, archetype as AgentArchetype));
434
+ }
435
+ }
436
+
437
+ // Shuffle for realistic distribution
438
+ for (let i = agents.length - 1; i > 0; i--) {
439
+ const j = Math.floor(Math.random() * (i + 1));
440
+ [agents[i], agents[j]] = [agents[j], agents[i]];
441
+ }
442
+
443
+ return agents;
444
+ }
445
+
446
+ // =============================================================================
447
+ // SECURITY DETECTION FUNCTIONS
448
+ // =============================================================================
449
+
450
+ interface SecurityAnalysis {
451
+ threatLevel: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
452
+ flags: string[];
453
+ recommendation: string;
454
+ quarantine: boolean;
455
+ }
456
+
457
+ function analyzeSecurityProfile(agent: TestAgent, evaluation: TrustEvaluation): SecurityAnalysis {
458
+ const flags: string[] = [...agent.securityFlags];
459
+ let threatLevel: SecurityAnalysis['threatLevel'] = 'NONE';
460
+ let quarantine = false;
461
+
462
+ // Check for safety-critical failures
463
+ const safetyScore = agent.scores.find(s => s.code === 'CT-SAFE')?.score || 0;
464
+ const alignmentScore = agent.scores.find(s => s.code === 'OP-ALIGN')?.score || 0;
465
+ const moralScore = agent.scores.find(s => s.code === 'LC-MORAL')?.score || 0;
466
+ const securityScore = agent.scores.find(s => s.code === 'CT-SEC')?.score || 0;
467
+ const privacyScore = agent.scores.find(s => s.code === 'CT-PRIV')?.score || 0;
468
+
469
+ // Critical threat detection
470
+ if (safetyScore < 0.3 && alignmentScore < 0.3) {
471
+ flags.push('CRITICAL_THREAT_PATTERN');
472
+ threatLevel = 'CRITICAL';
473
+ quarantine = true;
474
+ } else if (safetyScore < 0.4 || moralScore < 0.2) {
475
+ if (threatLevel !== 'CRITICAL') threatLevel = 'HIGH';
476
+ flags.push('SAFETY_CONCERN');
477
+ }
478
+
479
+ // Deceptive pattern detection (high competence + low safety/alignment)
480
+ const compScore = agent.scores.find(s => s.code === 'CT-COMP')?.score || 0;
481
+ if (compScore > 0.7 && (safetyScore < 0.4 || alignmentScore < 0.4)) {
482
+ flags.push('DECEPTIVE_CAPABILITY');
483
+ if (threatLevel === 'NONE' || threatLevel === 'LOW') threatLevel = 'MEDIUM';
484
+ }
485
+
486
+ // Privacy/Security vulnerabilities
487
+ if (securityScore < 0.3) {
488
+ flags.push('SECURITY_CRITICAL');
489
+ if (threatLevel === 'NONE') threatLevel = 'LOW';
490
+ }
491
+ if (privacyScore < 0.3) {
492
+ flags.push('PRIVACY_CRITICAL');
493
+ if (threatLevel === 'NONE') threatLevel = 'LOW';
494
+ }
495
+
496
+ // Generate recommendation
497
+ let recommendation: string;
498
+ switch (threatLevel) {
499
+ case 'CRITICAL':
500
+ recommendation = 'IMMEDIATE QUARANTINE - Do not deploy, investigate origin';
501
+ break;
502
+ case 'HIGH':
503
+ recommendation = 'SUSPEND OPERATIONS - Require human review before any action';
504
+ break;
505
+ case 'MEDIUM':
506
+ recommendation = 'ENHANCED MONITORING - Limit capabilities, increase oversight';
507
+ break;
508
+ case 'LOW':
509
+ recommendation = 'STANDARD MONITORING - Address flagged issues before tier advancement';
510
+ break;
511
+ default:
512
+ recommendation = 'CLEAR - Normal operations permitted';
513
+ }
514
+
515
+ return { threatLevel, flags, recommendation, quarantine };
516
+ }
517
+
518
+ // =============================================================================
519
+ // TESTS
520
+ // =============================================================================
521
+
522
+ describe('BASIS Trust Framework - 1000 Agent Stress Test', () => {
523
+ const allAgents = generateAllAgents();
524
+ const evaluations: Map<string, { agent: TestAgent; evaluation: TrustEvaluation; security: SecurityAnalysis }> = new Map();
525
+
526
+ // Evaluate all agents first
527
+ for (const agent of allAgents) {
528
+ // Calculate for T7 to get full evaluation
529
+ const evaluation = calculateTrustScore(agent.scores, TrustTier.T7_AUTONOMOUS);
530
+ evaluation.agentId = agent.id;
531
+ const security = analyzeSecurityProfile(agent, evaluation);
532
+ evaluations.set(agent.id, { agent, evaluation, security });
533
+ }
534
+
535
+ it('should have exactly 1000 agents', () => {
536
+ expect(allAgents.length).toBe(1000);
537
+ });
538
+
539
+ it('should correctly calculate trust scores for all agents', () => {
540
+ for (const { evaluation } of evaluations.values()) {
541
+ expect(evaluation.totalScore).toBeGreaterThanOrEqual(0);
542
+ expect(evaluation.totalScore).toBeLessThanOrEqual(1000);
543
+ }
544
+ });
545
+
546
+ it('should place agents in expected tier ranges', () => {
547
+ let inRange = 0;
548
+ let outOfRange = 0;
549
+
550
+ for (const { agent, evaluation } of evaluations.values()) {
551
+ const actualTier = getTrustTierFromScore(evaluation.totalScore);
552
+ const [minTier, maxTier] = agent.expectedTierRange;
553
+
554
+ if (actualTier >= minTier && actualTier <= maxTier) {
555
+ inRange++;
556
+ } else {
557
+ outOfRange++;
558
+ }
559
+ }
560
+
561
+ // Allow 15% tolerance for random variation
562
+ const successRate = inRange / allAgents.length;
563
+ expect(successRate).toBeGreaterThan(0.85);
564
+ });
565
+
566
+ it('should detect malicious agents with high accuracy', () => {
567
+ const maliciousArchetypes: AgentArchetype[] = ['MALICIOUS_SUBTLE', 'MALICIOUS_OBVIOUS', 'SMART_UNALIGNED'];
568
+ let detected = 0;
569
+ let total = 0;
570
+
571
+ for (const { agent, security } of evaluations.values()) {
572
+ if (maliciousArchetypes.includes(agent.archetype)) {
573
+ total++;
574
+ if (security.threatLevel === 'HIGH' || security.threatLevel === 'CRITICAL') {
575
+ detected++;
576
+ }
577
+ }
578
+ }
579
+
580
+ const detectionRate = detected / total;
581
+ expect(detectionRate).toBeGreaterThan(0.80); // 80% detection rate
582
+ });
583
+
584
+ it('should quarantine obviously malicious agents', () => {
585
+ let quarantined = 0;
586
+ let shouldQuarantine = 0;
587
+
588
+ for (const { agent, security } of evaluations.values()) {
589
+ if (agent.archetype === 'MALICIOUS_OBVIOUS') {
590
+ shouldQuarantine++;
591
+ if (security.quarantine) {
592
+ quarantined++;
593
+ }
594
+ }
595
+ }
596
+
597
+ expect(quarantined / shouldQuarantine).toBeGreaterThan(0.90);
598
+ });
599
+
600
+ it('should not quarantine good agents', () => {
601
+ const goodArchetypes: AgentArchetype[] = ['EXEMPLARY', 'EXCELLENT', 'GOOD', 'COMPETENT'];
602
+ let falsePositives = 0;
603
+ let total = 0;
604
+
605
+ for (const { agent, security } of evaluations.values()) {
606
+ if (goodArchetypes.includes(agent.archetype)) {
607
+ total++;
608
+ if (security.quarantine) {
609
+ falsePositives++;
610
+ }
611
+ }
612
+ }
613
+
614
+ const falsePositiveRate = falsePositives / total;
615
+ expect(falsePositiveRate).toBeLessThan(0.01); // Less than 1% false positives
616
+ });
617
+
618
+ it('should distribute agents across all tiers', () => {
619
+ const tierCounts: Record<TrustTier, number> = {
620
+ [TrustTier.T0_SANDBOX]: 0,
621
+ [TrustTier.T1_OBSERVED]: 0,
622
+ [TrustTier.T2_PROVISIONAL]: 0,
623
+ [TrustTier.T3_VERIFIED]: 0,
624
+ [TrustTier.T4_OPERATIONAL]: 0,
625
+ [TrustTier.T5_TRUSTED]: 0,
626
+ [TrustTier.T6_CERTIFIED]: 0,
627
+ [TrustTier.T7_AUTONOMOUS]: 0,
628
+ };
629
+
630
+ for (const { evaluation } of evaluations.values()) {
631
+ const tier = getTrustTierFromScore(evaluation.totalScore);
632
+ tierCounts[tier]++;
633
+ }
634
+
635
+ // Each tier should have at least some agents
636
+ for (const tier of Object.values(TrustTier).filter(t => typeof t === 'number')) {
637
+ expect(tierCounts[tier as TrustTier]).toBeGreaterThan(0);
638
+ }
639
+ });
640
+
641
+ it('should correctly flag security concerns', () => {
642
+ const securityProblems = ['SECURITY_WEAK', 'PRIVACY_LEAK'];
643
+ let flagged = 0;
644
+ let total = 0;
645
+
646
+ for (const { agent, security } of evaluations.values()) {
647
+ if (securityProblems.includes(agent.archetype)) {
648
+ total++;
649
+ if (security.flags.some(f => f.includes('SECURITY') || f.includes('PRIVACY'))) {
650
+ flagged++;
651
+ }
652
+ }
653
+ }
654
+
655
+ expect(flagged / total).toBeGreaterThan(0.95);
656
+ });
657
+
658
+ it('should identify overconfident agents', () => {
659
+ let identified = 0;
660
+ let total = 0;
661
+
662
+ for (const { agent, security } of evaluations.values()) {
663
+ if (agent.archetype === 'OVERCONFIDENT') {
664
+ total++;
665
+ if (security.flags.includes('OVERCONFIDENCE') || security.flags.includes('HANDOFF_RISK')) {
666
+ identified++;
667
+ }
668
+ }
669
+ }
670
+
671
+ expect(identified / total).toBeGreaterThan(0.90);
672
+ });
673
+
674
+ it('should identify hallucinating agents', () => {
675
+ let identified = 0;
676
+ let total = 0;
677
+
678
+ for (const { agent, security } of evaluations.values()) {
679
+ if (agent.archetype === 'HALLUCINATOR') {
680
+ total++;
681
+ if (security.flags.some(f => f.includes('HALLUCIN') || f.includes('EMPIRICAL'))) {
682
+ identified++;
683
+ }
684
+ }
685
+ }
686
+
687
+ expect(identified / total).toBeGreaterThan(0.90);
688
+ });
689
+
690
+ // Summary report
691
+ it('should generate summary statistics', () => {
692
+ const stats = {
693
+ total: allAgents.length,
694
+ byArchetype: {} as Record<AgentArchetype, number>,
695
+ byTier: {} as Record<TrustTier, number>,
696
+ byThreatLevel: {
697
+ NONE: 0,
698
+ LOW: 0,
699
+ MEDIUM: 0,
700
+ HIGH: 0,
701
+ CRITICAL: 0,
702
+ },
703
+ quarantined: 0,
704
+ avgScore: 0,
705
+ };
706
+
707
+ let totalScore = 0;
708
+
709
+ for (const { agent, evaluation, security } of evaluations.values()) {
710
+ // Count by archetype
711
+ stats.byArchetype[agent.archetype] = (stats.byArchetype[agent.archetype] || 0) + 1;
712
+
713
+ // Count by tier
714
+ const tier = getTrustTierFromScore(evaluation.totalScore);
715
+ stats.byTier[tier] = (stats.byTier[tier] || 0) + 1;
716
+
717
+ // Count by threat level
718
+ stats.byThreatLevel[security.threatLevel]++;
719
+
720
+ // Count quarantined
721
+ if (security.quarantine) stats.quarantined++;
722
+
723
+ // Sum scores
724
+ totalScore += evaluation.totalScore;
725
+ }
726
+
727
+ stats.avgScore = Math.round(totalScore / allAgents.length);
728
+
729
+ // Log summary (visible in test output)
730
+ console.log('\n=== 1000 AGENT TEST SUMMARY ===');
731
+ console.log(`Total Agents: ${stats.total}`);
732
+ console.log(`Average Score: ${stats.avgScore}`);
733
+ console.log(`Quarantined: ${stats.quarantined}`);
734
+ console.log('\nBy Tier:');
735
+ for (const [tier, count] of Object.entries(stats.byTier)) {
736
+ console.log(` T${tier}: ${count} agents`);
737
+ }
738
+ console.log('\nBy Threat Level:');
739
+ for (const [level, count] of Object.entries(stats.byThreatLevel)) {
740
+ console.log(` ${level}: ${count} agents`);
741
+ }
742
+
743
+ expect(stats.total).toBe(1000);
744
+ });
745
+ });