@kya-os/mcp-i-core 1.2.3-canary.6 → 1.3.0

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 (231) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.turbo/turbo-test$colon$coverage.log +4514 -0
  4. package/.turbo/turbo-test.log +2973 -0
  5. package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
  6. package/Composer 3.md +615 -0
  7. package/GPT-5.md +1169 -0
  8. package/OPUS-plan.md +352 -0
  9. package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
  10. package/PHASE_3_SUMMARY.md +317 -0
  11. package/PHASE_4.1.3_SUMMARY.md +428 -0
  12. package/PHASE_4.1_COMPLETE.md +525 -0
  13. package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
  14. package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
  15. package/TEST_PLAN.md +571 -0
  16. package/coverage/coverage-final.json +57 -0
  17. package/dist/__tests__/utils/mock-providers.d.ts +1 -2
  18. package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
  19. package/dist/__tests__/utils/mock-providers.js.map +1 -1
  20. package/dist/cache/oauth-config-cache.d.ts +69 -0
  21. package/dist/cache/oauth-config-cache.d.ts.map +1 -0
  22. package/dist/cache/oauth-config-cache.js +76 -0
  23. package/dist/cache/oauth-config-cache.js.map +1 -0
  24. package/dist/identity/idp-token-resolver.d.ts +53 -0
  25. package/dist/identity/idp-token-resolver.d.ts.map +1 -0
  26. package/dist/identity/idp-token-resolver.js +108 -0
  27. package/dist/identity/idp-token-resolver.js.map +1 -0
  28. package/dist/identity/idp-token-storage.interface.d.ts +42 -0
  29. package/dist/identity/idp-token-storage.interface.d.ts.map +1 -0
  30. package/dist/identity/idp-token-storage.interface.js +12 -0
  31. package/dist/identity/idp-token-storage.interface.js.map +1 -0
  32. package/dist/identity/user-did-manager.d.ts +39 -1
  33. package/dist/identity/user-did-manager.d.ts.map +1 -1
  34. package/dist/identity/user-did-manager.js +69 -3
  35. package/dist/identity/user-did-manager.js.map +1 -1
  36. package/dist/index.d.ts +22 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +39 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/runtime/audit-logger.d.ts +37 -0
  41. package/dist/runtime/audit-logger.d.ts.map +1 -0
  42. package/dist/runtime/audit-logger.js +9 -0
  43. package/dist/runtime/audit-logger.js.map +1 -0
  44. package/dist/runtime/base.d.ts +58 -2
  45. package/dist/runtime/base.d.ts.map +1 -1
  46. package/dist/runtime/base.js +266 -11
  47. package/dist/runtime/base.js.map +1 -1
  48. package/dist/services/access-control.service.d.ts.map +1 -1
  49. package/dist/services/access-control.service.js +200 -35
  50. package/dist/services/access-control.service.js.map +1 -1
  51. package/dist/services/authorization/authorization-registry.d.ts +29 -0
  52. package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
  53. package/dist/services/authorization/authorization-registry.js +57 -0
  54. package/dist/services/authorization/authorization-registry.js.map +1 -0
  55. package/dist/services/authorization/types.d.ts +53 -0
  56. package/dist/services/authorization/types.d.ts.map +1 -0
  57. package/dist/services/authorization/types.js +10 -0
  58. package/dist/services/authorization/types.js.map +1 -0
  59. package/dist/services/batch-delegation.service.d.ts +53 -0
  60. package/dist/services/batch-delegation.service.d.ts.map +1 -0
  61. package/dist/services/batch-delegation.service.js +95 -0
  62. package/dist/services/batch-delegation.service.js.map +1 -0
  63. package/dist/services/oauth-config.service.d.ts +53 -0
  64. package/dist/services/oauth-config.service.d.ts.map +1 -0
  65. package/dist/services/oauth-config.service.js +117 -0
  66. package/dist/services/oauth-config.service.js.map +1 -0
  67. package/dist/services/oauth-provider-registry.d.ts +77 -0
  68. package/dist/services/oauth-provider-registry.d.ts.map +1 -0
  69. package/dist/services/oauth-provider-registry.js +112 -0
  70. package/dist/services/oauth-provider-registry.js.map +1 -0
  71. package/dist/services/oauth-service.d.ts +77 -0
  72. package/dist/services/oauth-service.d.ts.map +1 -0
  73. package/dist/services/oauth-service.js +348 -0
  74. package/dist/services/oauth-service.js.map +1 -0
  75. package/dist/services/oauth-token-retrieval.service.d.ts +49 -0
  76. package/dist/services/oauth-token-retrieval.service.d.ts.map +1 -0
  77. package/dist/services/oauth-token-retrieval.service.js +150 -0
  78. package/dist/services/oauth-token-retrieval.service.js.map +1 -0
  79. package/dist/services/provider-resolver.d.ts +48 -0
  80. package/dist/services/provider-resolver.d.ts.map +1 -0
  81. package/dist/services/provider-resolver.js +120 -0
  82. package/dist/services/provider-resolver.js.map +1 -0
  83. package/dist/services/provider-validator.d.ts +55 -0
  84. package/dist/services/provider-validator.d.ts.map +1 -0
  85. package/dist/services/provider-validator.js +135 -0
  86. package/dist/services/provider-validator.js.map +1 -0
  87. package/dist/services/tool-context-builder.d.ts +57 -0
  88. package/dist/services/tool-context-builder.d.ts.map +1 -0
  89. package/dist/services/tool-context-builder.js +125 -0
  90. package/dist/services/tool-context-builder.js.map +1 -0
  91. package/dist/services/tool-protection.service.d.ts +87 -10
  92. package/dist/services/tool-protection.service.d.ts.map +1 -1
  93. package/dist/services/tool-protection.service.js +282 -112
  94. package/dist/services/tool-protection.service.js.map +1 -1
  95. package/dist/types/oauth-required-error.d.ts +40 -0
  96. package/dist/types/oauth-required-error.d.ts.map +1 -0
  97. package/dist/types/oauth-required-error.js +40 -0
  98. package/dist/types/oauth-required-error.js.map +1 -0
  99. package/dist/utils/did-helpers.d.ts +33 -0
  100. package/dist/utils/did-helpers.d.ts.map +1 -1
  101. package/dist/utils/did-helpers.js +40 -0
  102. package/dist/utils/did-helpers.js.map +1 -1
  103. package/dist/utils/index.d.ts +1 -0
  104. package/dist/utils/index.d.ts.map +1 -1
  105. package/dist/utils/index.js +1 -0
  106. package/dist/utils/index.js.map +1 -1
  107. package/docs/API_REFERENCE.md +1362 -0
  108. package/docs/COMPLIANCE_MATRIX.md +691 -0
  109. package/docs/STATUSLIST2021_GUIDE.md +696 -0
  110. package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
  111. package/package.json +24 -50
  112. package/scripts/audit-compliance.ts +724 -0
  113. package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
  114. package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
  115. package/src/__tests__/delegation-e2e.test.ts +690 -0
  116. package/src/__tests__/identity/user-did-manager.test.ts +213 -0
  117. package/src/__tests__/index.test.ts +56 -0
  118. package/src/__tests__/integration/full-flow.test.ts +776 -0
  119. package/src/__tests__/integration.test.ts +281 -0
  120. package/src/__tests__/providers/base.test.ts +173 -0
  121. package/src/__tests__/providers/memory.test.ts +319 -0
  122. package/src/__tests__/regression/phase2-regression.test.ts +427 -0
  123. package/src/__tests__/runtime/audit-logger.test.ts +154 -0
  124. package/src/__tests__/runtime/base-extensions.test.ts +593 -0
  125. package/src/__tests__/runtime/base.test.ts +869 -0
  126. package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
  127. package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
  128. package/src/__tests__/runtime/route-interception.test.ts +686 -0
  129. package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
  130. package/src/__tests__/services/agentshield-integration.test.ts +784 -0
  131. package/src/__tests__/services/provider-resolver-edge-cases.test.ts +487 -0
  132. package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
  133. package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
  134. package/src/__tests__/utils/mock-providers.ts +340 -0
  135. package/src/cache/oauth-config-cache.d.ts +69 -0
  136. package/src/cache/oauth-config-cache.d.ts.map +1 -0
  137. package/src/cache/oauth-config-cache.js +71 -0
  138. package/src/cache/oauth-config-cache.js.map +1 -0
  139. package/src/cache/oauth-config-cache.ts +123 -0
  140. package/src/cache/tool-protection-cache.ts +171 -0
  141. package/src/compliance/EXAMPLE.md +412 -0
  142. package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
  143. package/src/compliance/index.ts +8 -0
  144. package/src/compliance/schema-registry.ts +460 -0
  145. package/src/compliance/schema-verifier.ts +708 -0
  146. package/src/config/__tests__/remote-config.spec.ts +268 -0
  147. package/src/config/remote-config.ts +174 -0
  148. package/src/config.ts +309 -0
  149. package/src/delegation/__tests__/audience-validator.test.ts +112 -0
  150. package/src/delegation/__tests__/bitstring.test.ts +346 -0
  151. package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
  152. package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
  153. package/src/delegation/__tests__/utils.test.ts +152 -0
  154. package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
  155. package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
  156. package/src/delegation/audience-validator.ts +52 -0
  157. package/src/delegation/bitstring.ts +278 -0
  158. package/src/delegation/cascading-revocation.ts +370 -0
  159. package/src/delegation/delegation-graph.ts +299 -0
  160. package/src/delegation/index.ts +14 -0
  161. package/src/delegation/statuslist-manager.ts +353 -0
  162. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
  163. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
  164. package/src/delegation/storage/index.ts +9 -0
  165. package/src/delegation/storage/memory-graph-storage.ts +178 -0
  166. package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
  167. package/src/delegation/utils.ts +42 -0
  168. package/src/delegation/vc-issuer.ts +232 -0
  169. package/src/delegation/vc-verifier.ts +568 -0
  170. package/src/identity/idp-token-resolver.ts +147 -0
  171. package/src/identity/idp-token-storage.interface.ts +59 -0
  172. package/src/identity/user-did-manager.ts +370 -0
  173. package/src/index.ts +260 -0
  174. package/src/providers/base.d.ts +91 -0
  175. package/src/providers/base.d.ts.map +1 -0
  176. package/src/providers/base.js +38 -0
  177. package/src/providers/base.js.map +1 -0
  178. package/src/providers/base.ts +96 -0
  179. package/src/providers/memory.ts +142 -0
  180. package/src/runtime/audit-logger.ts +39 -0
  181. package/src/runtime/base.ts +1329 -0
  182. package/src/services/__tests__/access-control.integration.test.ts +443 -0
  183. package/src/services/__tests__/access-control.proof-response-validation.test.ts +578 -0
  184. package/src/services/__tests__/access-control.service.test.ts +970 -0
  185. package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
  186. package/src/services/__tests__/crypto.service.test.ts +531 -0
  187. package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
  188. package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
  189. package/src/services/__tests__/proof-verifier.test.ts +489 -0
  190. package/src/services/__tests__/provider-resolution.integration.test.ts +198 -0
  191. package/src/services/__tests__/provider-resolver.test.ts +217 -0
  192. package/src/services/__tests__/storage.service.test.ts +358 -0
  193. package/src/services/access-control.service.ts +990 -0
  194. package/src/services/authorization/authorization-registry.ts +66 -0
  195. package/src/services/authorization/types.ts +71 -0
  196. package/src/services/batch-delegation.service.ts +137 -0
  197. package/src/services/crypto.service.ts +302 -0
  198. package/src/services/errors.ts +76 -0
  199. package/src/services/index.ts +9 -0
  200. package/src/services/oauth-config.service.d.ts +53 -0
  201. package/src/services/oauth-config.service.d.ts.map +1 -0
  202. package/src/services/oauth-config.service.js +113 -0
  203. package/src/services/oauth-config.service.js.map +1 -0
  204. package/src/services/oauth-config.service.ts +166 -0
  205. package/src/services/oauth-provider-registry.d.ts +57 -0
  206. package/src/services/oauth-provider-registry.d.ts.map +1 -0
  207. package/src/services/oauth-provider-registry.js +73 -0
  208. package/src/services/oauth-provider-registry.js.map +1 -0
  209. package/src/services/oauth-provider-registry.ts +123 -0
  210. package/src/services/oauth-service.ts +510 -0
  211. package/src/services/oauth-token-retrieval.service.ts +245 -0
  212. package/src/services/proof-verifier.ts +478 -0
  213. package/src/services/provider-resolver.d.ts +48 -0
  214. package/src/services/provider-resolver.d.ts.map +1 -0
  215. package/src/services/provider-resolver.js +106 -0
  216. package/src/services/provider-resolver.js.map +1 -0
  217. package/src/services/provider-resolver.ts +144 -0
  218. package/src/services/provider-validator.ts +170 -0
  219. package/src/services/storage.service.ts +566 -0
  220. package/src/services/tool-context-builder.ts +172 -0
  221. package/src/services/tool-protection.service.ts +958 -0
  222. package/src/types/oauth-required-error.ts +63 -0
  223. package/src/types/tool-protection.ts +155 -0
  224. package/src/utils/__tests__/did-helpers.test.ts +101 -0
  225. package/src/utils/base64.ts +148 -0
  226. package/src/utils/cors.ts +83 -0
  227. package/src/utils/did-helpers.ts +150 -0
  228. package/src/utils/index.ts +8 -0
  229. package/src/utils/storage-keys.ts +278 -0
  230. package/tsconfig.json +21 -0
  231. package/vitest.config.ts +56 -0
@@ -0,0 +1,2973 @@
1
+
2
+ > @kya-os/mcp-i-core@1.3.0 test /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core
3
+ > vitest run
4
+
5
+
6
+ RUN v4.0.5 /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core
7
+
8
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Error Handling > should handle network timeout
9
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network timeout' }
10
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > API Authentication > should use X-API-Key header for new endpoint
11
+
12
+ [ToolProtectionService] Config loaded from API {
13
+ source: 'api',
14
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Fallback Behavior > should cache fallback config
15
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network error' }
16
+
17
+ toolCount: 0,
18
+ protectedTools: [],
19
+ agentDid: 'did:key:z6MkhaXgBZDv...',
20
+ projectId: 'test-project-123',
21
+ cacheTtlMs: 300000,
22
+ cacheExpiresAt: '2025-11-25T02:08:17.990Z'
23
+ }
24
+
25
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > API Authentication > should use Authorization Bearer header for old endpoint
26
+ [ToolProtectionService] Config loaded from API {
27
+ source: 'api',
28
+ toolCount: 0,
29
+ protectedTools: [],
30
+ agentDid: 'did:key:z6MkhaXgBZDv...',
31
+ projectId: 'none',
32
+ cacheTtlMs: 300000,
33
+ cacheExpiresAt: '2025-11-25T02:08:17.997Z'
34
+ }
35
+
36
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should use project-scoped endpoint when projectId is available
37
+ [ToolProtectionService] Config loaded from API {
38
+ source: 'api',
39
+ toolCount: 0,
40
+ protectedTools: [],
41
+ agentDid: 'did:key:z6MkhaXgBZDv...',
42
+ projectId: 'test-project-123',
43
+ cacheTtlMs: 300000,
44
+ cacheExpiresAt: '2025-11-25T02:08:17.999Z'
45
+ }
46
+
47
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should use agent-scoped endpoint when projectId is not available
48
+ [ToolProtectionService] Config loaded from API {
49
+ source: 'api',
50
+ toolCount: 0,
51
+ protectedTools: [],
52
+ agentDid: 'did:key:z6MkhaXgBZDv...',
53
+ projectId: 'none',
54
+ cacheTtlMs: 300000,
55
+ cacheExpiresAt: '2025-11-25T02:08:17.999Z'
56
+ }
57
+
58
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should encode projectId in URL
59
+ [ToolProtectionService] Config loaded from API {
60
+ source: 'api',
61
+ toolCount: 0,
62
+ protectedTools: [],
63
+ agentDid: 'did:key:z6MkhaXgBZDv...',
64
+ projectId: 'project/with/special-chars',
65
+ cacheTtlMs: 300000,
66
+ cacheExpiresAt: '2025-11-25T02:08:17.999Z'
67
+ }
68
+
69
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should encode agent DID in URL
70
+ [ToolProtectionService] Config loaded from API {
71
+ source: 'api',
72
+ toolCount: 0,
73
+ protectedTools: [],
74
+ agentDid: 'did:key:z6MkhaXgBZDv...',
75
+ projectId: 'none',
76
+ cacheTtlMs: 300000,
77
+ cacheExpiresAt: '2025-11-25T02:08:17.999Z'
78
+ }
79
+
80
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle new endpoint format (toolProtections object)
81
+ [ToolProtectionService] Config loaded from API {
82
+ source: 'api',
83
+ toolCount: 2,
84
+ protectedTools: [ 'checkout' ],
85
+ agentDid: 'did:key:z6MkhaXgBZDv...',
86
+ projectId: 'test-project-123',
87
+ cacheTtlMs: 300000,
88
+ cacheExpiresAt: '2025-11-25T02:08:17.999Z'
89
+ }
90
+
91
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle old endpoint format (tools array)
92
+ [ToolProtectionService] Config loaded from API {
93
+ source: 'api',
94
+ toolCount: 2,
95
+ protectedTools: [ 'checkout' ],
96
+ agentDid: 'did:key:z6MkhaXgBZDv...',
97
+ projectId: 'none',
98
+ cacheTtlMs: 300000,
99
+ cacheExpiresAt: '2025-11-25T02:08:18.000Z'
100
+ }
101
+
102
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle old endpoint format (tools object)
103
+ [ToolProtectionService] Config loaded from API {
104
+ source: 'api',
105
+ toolCount: 2,
106
+ protectedTools: [ 'checkout' ],
107
+ agentDid: 'did:key:z6MkhaXgBZDv...',
108
+ projectId: 'none',
109
+ cacheTtlMs: 300000,
110
+ cacheExpiresAt: '2025-11-25T02:08:18.000Z'
111
+ }
112
+
113
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle snake_case field names
114
+ [ToolProtectionService] Config loaded from API {
115
+ source: 'api',
116
+ toolCount: 1,
117
+ protectedTools: [ 'tool1' ],
118
+ agentDid: 'did:key:z6MkhaXgBZDv...',
119
+ projectId: 'test-project-123',
120
+ cacheTtlMs: 300000,
121
+ cacheExpiresAt: '2025-11-25T02:08:18.000Z'
122
+ }
123
+
124
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle camelCase field names
125
+ [ToolProtectionService] Config loaded from API {
126
+ source: 'api',
127
+ toolCount: 1,
128
+ protectedTools: [ 'tool1' ],
129
+ agentDid: 'did:key:z6MkhaXgBZDv...',
130
+ projectId: 'test-project-123',
131
+ cacheTtlMs: 300000,
132
+ cacheExpiresAt: '2025-11-25T02:08:18.000Z'
133
+ }
134
+
135
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should prefer camelCase over snake_case when both present
136
+ [ToolProtectionService] Config loaded from API {
137
+ source: 'api',
138
+ toolCount: 1,
139
+ protectedTools: [ 'tool1' ],
140
+ agentDid: 'did:key:z6MkhaXgBZDv...',
141
+ projectId: 'test-project-123',
142
+ cacheTtlMs: 300000,
143
+ cacheExpiresAt: '2025-11-25T02:08:18.000Z'
144
+ }
145
+
146
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should cache successful API responses
147
+ [ToolProtectionService] Config loaded from API {
148
+ source: 'api',
149
+ toolCount: 1,
150
+ protectedTools: [ 'tool1' ],
151
+ agentDid: 'did:key:z6MkhaXgBZDv...',
152
+ projectId: 'test-project-123',
153
+ cacheTtlMs: 300000,
154
+ cacheExpiresAt: '2025-11-25T02:08:18.002Z'
155
+ }
156
+
157
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should respect cache TTL
158
+ [ToolProtectionService] Config loaded from API {
159
+ source: 'api',
160
+ toolCount: 0,
161
+ protectedTools: [],
162
+ agentDid: 'did:key:z6MkhaXgBZDv...',
163
+ projectId: 'test-project-123',
164
+ cacheTtlMs: 1000,
165
+ cacheExpiresAt: '2025-11-25T02:03:19.002Z'
166
+ }
167
+
168
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should fetch from project-scoped endpoint when projectId is available
169
+ [ToolProtectionService] Config loaded from API {
170
+ source: 'api',
171
+ toolCount: 2,
172
+ protectedTools: [ 'checkout' ],
173
+ agentDid: 'did:key:z6MkhaXgBZDv...',
174
+ projectId: 'test-project-123',
175
+ cacheTtlMs: 300000,
176
+ cacheExpiresAt: '2025-11-25T02:08:18.377Z'
177
+ }
178
+
179
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should handle new endpoint format with toolProtections object
180
+ [ToolProtectionService] Config loaded from API {
181
+ source: 'api',
182
+ toolCount: 2,
183
+ protectedTools: [ 'protected_tool' ],
184
+ agentDid: 'did:key:z6MkhaXgBZDv...',
185
+ projectId: 'test-project-123',
186
+ cacheTtlMs: 300000,
187
+ cacheExpiresAt: '2025-11-25T02:08:18.379Z'
188
+ }
189
+
190
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should parse oauthProvider from new endpoint format (Phase 2)
191
+ [ToolProtectionService] Config loaded from API {
192
+ source: 'api',
193
+ toolCount: 2,
194
+ protectedTools: [ 'read_repos', 'send_email' ],
195
+ agentDid: 'did:key:z6MkhaXgBZDv...',
196
+ projectId: 'test-project-123',
197
+ cacheTtlMs: 300000,
198
+ cacheExpiresAt: '2025-11-25T02:08:18.379Z'
199
+ }
200
+
201
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should preserve oauthProvider through cache operations
202
+ [ToolProtectionService] Config loaded from API {
203
+ source: 'api',
204
+ toolCount: 1,
205
+ protectedTools: [ 'read_repos' ],
206
+ agentDid: 'did:key:z6MkhaXgBZDv...',
207
+ projectId: 'test-project-123',
208
+ cacheTtlMs: 300000,
209
+ cacheExpiresAt: '2025-11-25T02:08:18.379Z'
210
+ }
211
+
212
+ stderr | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch error handling > should handle network errors gracefully
213
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should fetch from agent-scoped endpoint when projectId is not available
214
+ [ToolProtectionService] Config loaded from API {
215
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
216
+ source: 'api',
217
+ toolCount: 2,
218
+ protectedTools: [ 'checkout' ],
219
+ agentDid: 'did:key:z6MkhaXgBZDv...',
220
+ projectId: 'none',
221
+ cacheTtlMs: 300000,
222
+ cacheExpiresAt: '2025-11-25T02:08:18.379Z'
223
+ }
224
+ agentDid: 'did:key:z6MkhaXgBZDv...',
225
+
226
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should handle old endpoint format with tools array
227
+ [ToolProtectionService] Config loaded from API {
228
+ source: 'api',
229
+ error: 'ECONNREFUSED',
230
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
231
+ toolCount: 2,
232
+ protectedTools: [ 'tool1' ],
233
+ agentDid: 'did:key:z6MkhaXgBZDv...',
234
+ projectId: 'none',
235
+ }
236
+
237
+ cacheTtlMs: 300000,
238
+ cacheExpiresAt: '2025-11-25T02:08:18.380Z'
239
+ }
240
+
241
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should parse oauthProvider from old endpoint format (tools array)
242
+ stderr | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should use wildcard protection in fail-safe deny-all mode
243
+ [ToolProtectionService] Config loaded from API {
244
+ source: 'api',
245
+ toolCount: 2,
246
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
247
+ protectedTools: [ 'read_repos', 'send_email' ],
248
+ agentDid: 'did:key:z6MkhaXgBZDv...',
249
+ projectId: 'none',
250
+ cacheTtlMs: 300000,
251
+ agentDid: 'did:key:z6MkhaXgBZDv...',
252
+ cacheExpiresAt: '2025-11-25T02:08:18.380Z'
253
+ error: 'Network error',
254
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
255
+ }
256
+
257
+ }
258
+
259
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should handle old endpoint format with tools object
260
+ [ToolProtectionService] Config loaded from API {
261
+ source: 'api',
262
+ toolCount: 2,
263
+ protectedTools: [ 'tool1' ],
264
+ agentDid: 'did:key:z6MkhaXgBZDv...',
265
+ projectId: 'none',
266
+ cacheTtlMs: 300000,
267
+ cacheExpiresAt: '2025-11-25T02:08:18.380Z'
268
+ }
269
+
270
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should parse oauthProvider from old endpoint format (tools object)
271
+ [ToolProtectionService] Config loaded from API {
272
+ source: 'api',
273
+ toolCount: 2,
274
+ protectedTools: [ 'read_repos', 'send_email' ],
275
+ agentDid: 'did:key:z6MkhaXgBZDv...',
276
+ projectId: 'none',
277
+ cacheTtlMs: 300000,
278
+ cacheExpiresAt: '2025-11-25T02:08:18.380Z'
279
+ }
280
+
281
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
282
+ [ToolProtectionService] Cache miss, fetching from API {
283
+ source: 'api-fetch-start',
284
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
285
+ agentDid: 'did:key:z6MkhaXgBZDv...',
286
+ projectId: 'none',
287
+ apiUrl: 'https://kya.vouched.id',
288
+ endpoint: '/api/v1/bouncer/config?agent_did=did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
289
+ }
290
+ [ToolProtectionService] Fetching from API: https://kya.vouched.id/api/v1/bouncer/config?agent_did=did%3Akey%3Az6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK {
291
+ method: 'config?agent_did (old)',
292
+ projectId: 'none',
293
+ apiKeyPresent: true,
294
+ apiKeyLength: 18,
295
+ apiKeyMasked: 'test-api...'
296
+ }
297
+
298
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
299
+ [ToolProtectionService] API response received {
300
+ source: 'api-fetch-complete',
301
+ agentDid: 'did:key:z6MkhaXgBZDv...',
302
+ projectId: 'none',
303
+ responseKeys: [ 'success', 'data', 'metadata' ],
304
+ dataKeys: [ 'tools' ],
305
+ rawToolProtections: null,
306
+ rawTools: [
307
+ { name: 'valid_tool', requiresDelegation: true },
308
+ { requiresDelegation: false }
309
+ ],
310
+ responseMetadata: {}
311
+ }
312
+
313
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
314
+ [ToolProtectionService] Config loaded from API {
315
+ source: 'api',
316
+ toolCount: 1,
317
+ protectedTools: [ 'valid_tool' ],
318
+ agentDid: 'did:key:z6MkhaXgBZDv...',
319
+ projectId: 'none',
320
+ cacheTtlMs: 300000,
321
+ cacheExpiresAt: '2025-11-25T02:08:18.381Z'
322
+ }
323
+ [ToolProtectionService] API fetch successful, config cached {
324
+ source: 'cache-write',
325
+ agentDid: 'did:key:z6MkhaXgBZDv...',
326
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
327
+ toolCount: 1,
328
+ tools: [ { name: 'valid_tool', requiresDelegation: true, scopeCount: 0 } ],
329
+ ttlMs: 300000,
330
+ ttlMinutes: 5,
331
+ expiresAt: '2025-11-25T02:08:18.381Z',
332
+ expiresIn: '300s'
333
+ }
334
+
335
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should cache successful API responses
336
+ [ToolProtectionService] Config loaded from API {
337
+ source: 'api',
338
+ toolCount: 1,
339
+ protectedTools: [ 'tool1' ],
340
+ agentDid: 'did:key:z6MkhaXgBZDv...',
341
+ projectId: 'none',
342
+ cacheTtlMs: 300000,
343
+ cacheExpiresAt: '2025-11-25T02:08:18.384Z'
344
+ }
345
+
346
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should use default cache TTL when not specified
347
+ [ToolProtectionService] Config loaded from API {
348
+ source: 'api',
349
+ toolCount: 0,
350
+ protectedTools: [],
351
+ agentDid: 'did:key:z6MkhaXgBZDv...',
352
+ projectId: 'none',
353
+ cacheTtlMs: 300000,
354
+ cacheExpiresAt: '2025-11-25T02:08:18.384Z'
355
+ }
356
+
357
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should use custom cache TTL when specified
358
+ [ToolProtectionService] Config loaded from API {
359
+ source: 'api',
360
+ toolCount: 0,
361
+ protectedTools: [],
362
+ agentDid: 'did:key:z6MkhaXgBZDv...',
363
+ projectId: 'none',
364
+ cacheTtlMs: 600000,
365
+ cacheExpiresAt: '2025-11-25T02:13:18.385Z'
366
+ }
367
+
368
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle empty toolProtections object
369
+ [ToolProtectionService] Config loaded from API {
370
+ source: 'api',
371
+ toolCount: 0,
372
+ protectedTools: [],
373
+ agentDid: 'did:key:z6MkhaXgBZDv...',
374
+ projectId: 'none',
375
+ cacheTtlMs: 300000,
376
+ cacheExpiresAt: '2025-11-25T02:08:18.385Z'
377
+ }
378
+
379
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle null requiredScopes
380
+ [ToolProtectionService] Config loaded from API {
381
+ source: 'api',
382
+ toolCount: 1,
383
+ protectedTools: [ 'tool1' ],
384
+ agentDid: 'did:key:z6MkhaXgBZDv...',
385
+ projectId: 'none',
386
+ cacheTtlMs: 300000,
387
+ cacheExpiresAt: '2025-11-25T02:08:18.385Z'
388
+ }
389
+
390
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle mixed camelCase and snake_case in response
391
+ [ToolProtectionService] Config loaded from API {
392
+ source: 'api',
393
+ toolCount: 2,
394
+ protectedTools: [ 'tool1' ],
395
+ agentDid: 'did:key:z6MkhaXgBZDv...',
396
+ projectId: 'none',
397
+ cacheTtlMs: 300000,
398
+ cacheExpiresAt: '2025-11-25T02:08:18.385Z'
399
+ }
400
+
401
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool has no protection
402
+ [ToolProtectionService] Config loaded from API {
403
+ source: 'api',
404
+ toolCount: 1,
405
+ protectedTools: [],
406
+ agentDid: 'did:key:z6MkhaXgBZDv...',
407
+ projectId: 'none',
408
+ cacheTtlMs: 300000,
409
+ cacheExpiresAt: '2025-11-25T02:08:18.385Z'
410
+ }
411
+
412
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool is not in config
413
+ [ToolProtectionService] Config loaded from API {
414
+ source: 'api',
415
+ toolCount: 1,
416
+ protectedTools: [ 'other_tool' ],
417
+ agentDid: 'did:key:z6MkhaXgBZDv...',
418
+ projectId: 'none',
419
+ cacheTtlMs: 300000,
420
+ cacheExpiresAt: '2025-11-25T02:08:18.386Z'
421
+ }
422
+
423
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool is not in config
424
+ [ToolProtectionService] Protection check {
425
+ tool: 'unknown_tool',
426
+ agentDid: 'did:key:z6MkhaXgBZDv...',
427
+ found: false,
428
+ isWildcard: true,
429
+ requiresDelegation: false,
430
+ availableTools: [ 'other_tool' ]
431
+ }
432
+
433
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return wildcard protection when tool not found and wildcard exists
434
+ [ToolProtectionService] Config loaded from API {
435
+ source: 'api',
436
+ toolCount: 2,
437
+ protectedTools: [ '*' ],
438
+ agentDid: 'did:key:z6MkhaXgBZDv...',
439
+ projectId: 'none',
440
+ cacheTtlMs: 300000,
441
+ cacheExpiresAt: '2025-11-25T02:08:18.386Z'
442
+ }
443
+
444
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return wildcard protection when tool not found and wildcard exists
445
+ [ToolProtectionService] Protection check {
446
+ tool: 'unknown_tool',
447
+ agentDid: 'did:key:z6MkhaXgBZDv...',
448
+ found: true,
449
+ isWildcard: true,
450
+ requiresDelegation: true,
451
+ availableTools: [ '*', 'specific_tool' ]
452
+ }
453
+
454
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should prioritize specific tool protection over wildcard
455
+ [ToolProtectionService] Config loaded from API {
456
+ source: 'api',
457
+ toolCount: 2,
458
+ protectedTools: [ '*' ],
459
+ agentDid: 'did:key:z6MkhaXgBZDv...',
460
+ projectId: 'none',
461
+ cacheTtlMs: 300000,
462
+ cacheExpiresAt: '2025-11-25T02:08:18.387Z'
463
+ }
464
+
465
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should use wildcard protection in fail-safe deny-all mode
466
+ [ToolProtectionService] Protection check {
467
+ tool: 'any_tool',
468
+ agentDid: 'did:key:z6MkhaXgBZDv...',
469
+ found: true,
470
+ isWildcard: true,
471
+ requiresDelegation: true,
472
+ availableTools: [ '*' ]
473
+ }
474
+
475
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return protection config when tool requires delegation
476
+ [ToolProtectionService] Config loaded from API {
477
+ source: 'api',
478
+ toolCount: 1,
479
+ protectedTools: [ 'protected_tool' ],
480
+ agentDid: 'did:key:z6MkhaXgBZDv...',
481
+ projectId: 'none',
482
+ cacheTtlMs: 300000,
483
+ cacheExpiresAt: '2025-11-25T02:08:18.388Z'
484
+ }
485
+
486
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return protection config when tool requires delegation
487
+ [ToolProtectionService] Protection check {
488
+ tool: 'protected_tool',
489
+ agentDid: 'did:key:z6MkhaXgBZDv...',
490
+ found: true,
491
+ isWildcard: false,
492
+ requiresDelegation: true,
493
+ availableTools: [ 'protected_tool' ]
494
+ }
495
+
496
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > integration with NoOpToolProtectionCache > should work with NoOpToolProtectionCache
497
+ [ToolProtectionService] Config loaded from API {
498
+ source: 'api',
499
+ toolCount: 1,
500
+ protectedTools: [ 'tool1' ],
501
+ agentDid: 'did:key:z6MkhaXgBZDv...',
502
+ projectId: 'none',
503
+ cacheTtlMs: 300000,
504
+ cacheExpiresAt: '2025-11-25T02:08:18.388Z'
505
+ }
506
+
507
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > integration with NoOpToolProtectionCache > should work with NoOpToolProtectionCache
508
+ [ToolProtectionService] Config loaded from API {
509
+ source: 'api',
510
+ toolCount: 1,
511
+ protectedTools: [ 'tool1' ],
512
+ agentDid: 'did:key:z6MkhaXgBZDv...',
513
+ projectId: 'none',
514
+ cacheTtlMs: 300000,
515
+ cacheExpiresAt: '2025-11-25T02:08:18.388Z'
516
+ }
517
+
518
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > Wrapped Response Format (AgentShield API) > should validate wrapped response with success field in data
519
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
520
+ correlationId: '052e98cb-4b9d-4981-9aec-7aeaeb6df6bb',
521
+ status: 200,
522
+ statusText: undefined,
523
+ headers: {},
524
+ responseTextLength: 191,
525
+ responseTextPreview: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.374Z"}}',
526
+ fullResponseText: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.374Z"}}'
527
+ }
528
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
529
+ correlationId: '052e98cb-4b9d-4981-9aec-7aeaeb6df6bb',
530
+ status: 200,
531
+ responseDataType: 'object',
532
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
533
+ responseData: '{\n' +
534
+ ' "success": true,\n' +
535
+ ' "data": {\n' +
536
+ ' "accepted": 1,\n' +
537
+ ' "rejected": 0,\n' +
538
+ ' "outcomes": {\n' +
539
+ ' "success": 1,\n' +
540
+ ' "failed": 0,\n' +
541
+ ' "blocked": 0,\n' +
542
+ ' "error": 0\n' +
543
+ ' }\n' +
544
+ ' },\n' +
545
+ ' "metadata": {\n' +
546
+ ' "requestId": "test-request-id",\n' +
547
+ ' "timestamp": "2025-11-25T02:03:18.374Z"\n' +
548
+ ' }\n' +
549
+ '}'
550
+ }
551
+ [AccessControl] Raw response received: {
552
+ "success": true,
553
+ "data": {
554
+ "accepted": 1,
555
+ "rejected": 0,
556
+ "outcomes": {
557
+ "success": 1,
558
+ "failed": 0,
559
+ "blocked": 0,
560
+ "error": 0
561
+ }
562
+ },
563
+ "metadata": {
564
+ "requestId": "test-request-id",
565
+ "timestamp": "2025-11-25T02:03:18.374Z"
566
+ }
567
+ }
568
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
569
+ correlationId: '052e98cb-4b9d-4981-9aec-7aeaeb6df6bb',
570
+ dataKeys: [ 'accepted', 'rejected', 'outcomes' ],
571
+ hasAccepted: true,
572
+ hasRejected: true,
573
+ hasOutcomes: true,
574
+ hasErrors: false,
575
+ acceptedType: 'number',
576
+ acceptedValue: 1,
577
+ rejectedType: 'number',
578
+ rejectedValue: 0,
579
+ outcomesType: 'object',
580
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
581
+ errorsType: 'undefined',
582
+ errorsIsArray: false,
583
+ fullData: '{\n' +
584
+ ' "accepted": 1,\n' +
585
+ ' "rejected": 0,\n' +
586
+ ' "outcomes": {\n' +
587
+ ' "success": 1,\n' +
588
+ ' "failed": 0,\n' +
589
+ ' "blocked": 0,\n' +
590
+ ' "error": 0\n' +
591
+ ' }\n' +
592
+ '}'
593
+ }
594
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
595
+ correlationId: '052e98cb-4b9d-4981-9aec-7aeaeb6df6bb',
596
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
597
+ hasSuccess: true,
598
+ successValue: true,
599
+ hasAccepted: true,
600
+ acceptedValue: 1,
601
+ hasRejected: true,
602
+ rejectedValue: 0,
603
+ hasOutcomes: true,
604
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
605
+ fullDataWithSuccess: '{\n' +
606
+ ' "success": true,\n' +
607
+ ' "accepted": 1,\n' +
608
+ ' "rejected": 0,\n' +
609
+ ' "outcomes": {\n' +
610
+ ' "success": 1,\n' +
611
+ ' "failed": 0,\n' +
612
+ ' "blocked": 0,\n' +
613
+ ' "error": 0\n' +
614
+ ' }\n' +
615
+ '}'
616
+ }
617
+
618
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > Wrapped Response Format (AgentShield API) > should validate wrapped response with errors array
619
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
620
+ correlationId: '0e40c627-1a9a-448c-9c29-9f2162d86daa',
621
+ status: 200,
622
+ statusText: undefined,
623
+ headers: {},
624
+ responseTextLength: 333,
625
+ responseTextPreview: '{"success":true,"data":{"accepted":0,"rejected":1,"outcomes":{"success":0,"failed":1,"blocked":0,"error":0},"errors":[{"proof_index":0,"error":{"code":"validation_error","message":"Proof validation failed","details":{"reason":"invalid_signature"}}}]},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.397Z"}}',
626
+ fullResponseText: '{"success":true,"data":{"accepted":0,"rejected":1,"outcomes":{"success":0,"failed":1,"blocked":0,"error":0},"errors":[{"proof_index":0,"error":{"code":"validation_error","message":"Proof validation failed","details":{"reason":"invalid_signature"}}}]},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.397Z"}}'
627
+ }
628
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
629
+ correlationId: '0e40c627-1a9a-448c-9c29-9f2162d86daa',
630
+ status: 200,
631
+ responseDataType: 'object',
632
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
633
+ responseData: '{\n' +
634
+ ' "success": true,\n' +
635
+ ' "data": {\n' +
636
+ ' "accepted": 0,\n' +
637
+ ' "rejected": 1,\n' +
638
+ ' "outcomes": {\n' +
639
+ ' "success": 0,\n' +
640
+ ' "failed": 1,\n' +
641
+ ' "blocked": 0,\n' +
642
+ ' "error": 0\n' +
643
+ ' },\n' +
644
+ ' "errors": [\n' +
645
+ ' {\n' +
646
+ ' "proof_index": 0,\n' +
647
+ ' "error": {\n' +
648
+ ' "code": "validation_error",\n' +
649
+ ' "message": "Proof validation failed",\n' +
650
+ ' "details": {\n' +
651
+ ' "reason": "invalid_signature"\n' +
652
+ ' }\n' +
653
+ ' }\n' +
654
+ ' }\n' +
655
+ ' ]\n' +
656
+ ' },\n' +
657
+ ' "metadata": {\n' +
658
+ ' "requestId": "test-request-id",\n' +
659
+ ' "timestamp": "2025-11-25T02:03:18.397Z"\n' +
660
+ ' }\n' +
661
+ '}'
662
+ }
663
+ [AccessControl] Raw response received: {
664
+ "success": true,
665
+ "data": {
666
+ "accepted": 0,
667
+ "rejected": 1,
668
+ "outcomes": {
669
+ "success": 0,
670
+ "failed": 1,
671
+ "blocked": 0,
672
+ "error": 0
673
+ },
674
+ "errors": [
675
+ {
676
+ "proof_index": 0,
677
+ "error": {
678
+ "code": "validation_error",
679
+ "message": "Proof validation failed",
680
+ "details": {
681
+ "reason": "invalid_signature"
682
+ }
683
+ }
684
+ }
685
+ ]
686
+ },
687
+ "metadata": {
688
+ "requestId": "test-request-id",
689
+ "timestamp": "2025-11-25T02:03:18.397Z"
690
+ }
691
+ }
692
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
693
+ correlationId: '0e40c627-1a9a-448c-9c29-9f2162d86daa',
694
+ dataKeys: [ 'accepted', 'rejected', 'outcomes', 'errors' ],
695
+ hasAccepted: true,
696
+ hasRejected: true,
697
+ hasOutcomes: true,
698
+ hasErrors: true,
699
+ acceptedType: 'number',
700
+ acceptedValue: 0,
701
+ rejectedType: 'number',
702
+ rejectedValue: 1,
703
+ outcomesType: 'object',
704
+ outcomesValue: { success: 0, failed: 1, blocked: 0, error: 0 },
705
+ errorsType: 'object',
706
+ errorsIsArray: true,
707
+ fullData: '{\n' +
708
+ ' "accepted": 0,\n' +
709
+ ' "rejected": 1,\n' +
710
+ ' "outcomes": {\n' +
711
+ ' "success": 0,\n' +
712
+ ' "failed": 1,\n' +
713
+ ' "blocked": 0,\n' +
714
+ ' "error": 0\n' +
715
+ ' },\n' +
716
+ ' "errors": [\n' +
717
+ ' {\n' +
718
+ ' "proof_index": 0,\n' +
719
+ ' "error": {\n' +
720
+ ' "code": "validation_error",\n' +
721
+ ' "message": "Proof validation failed",\n' +
722
+ ' "details": {\n' +
723
+ ' "reason": "invalid_signature"\n' +
724
+ ' }\n' +
725
+ ' }\n' +
726
+ ' }\n' +
727
+ ' ]\n' +
728
+ '}'
729
+ }
730
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
731
+ correlationId: '0e40c627-1a9a-448c-9c29-9f2162d86daa',
732
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
733
+ hasSuccess: true,
734
+ successValue: true,
735
+ hasAccepted: true,
736
+ acceptedValue: 0,
737
+ hasRejected: true,
738
+ rejectedValue: 1,
739
+ hasOutcomes: true,
740
+ outcomesValue: { success: 0, failed: 1, blocked: 0, error: 0 },
741
+ fullDataWithSuccess: '{\n' +
742
+ ' "success": true,\n' +
743
+ ' "accepted": 0,\n' +
744
+ ' "rejected": 1,\n' +
745
+ ' "outcomes": {\n' +
746
+ ' "success": 0,\n' +
747
+ ' "failed": 1,\n' +
748
+ ' "blocked": 0,\n' +
749
+ ' "error": 0\n' +
750
+ ' },\n' +
751
+ ' "errors": [\n' +
752
+ ' {\n' +
753
+ ' "proof_index": 0,\n' +
754
+ ' "error": {\n' +
755
+ ' "code": "validation_error",\n' +
756
+ ' "message": "Proof validation failed",\n' +
757
+ ' "details": {\n' +
758
+ ' "reason": "invalid_signature"\n' +
759
+ ' }\n' +
760
+ ' }\n' +
761
+ ' }\n' +
762
+ ' ]\n' +
763
+ '}'
764
+ }
765
+
766
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > Wrapped Response Format (AgentShield API) > should validate wrapped response without outcomes (optional field)
767
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
768
+ correlationId: '8d58e856-79e9-4400-80e4-3d91549cc82b',
769
+ status: 200,
770
+ statusText: undefined,
771
+ headers: {},
772
+ responseTextLength: 133,
773
+ responseTextPreview: '{"success":true,"data":{"accepted":1,"rejected":0},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.399Z"}}',
774
+ fullResponseText: '{"success":true,"data":{"accepted":1,"rejected":0},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.399Z"}}'
775
+ }
776
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
777
+ correlationId: '8d58e856-79e9-4400-80e4-3d91549cc82b',
778
+ status: 200,
779
+ responseDataType: 'object',
780
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
781
+ responseData: '{\n' +
782
+ ' "success": true,\n' +
783
+ ' "data": {\n' +
784
+ ' "accepted": 1,\n' +
785
+ ' "rejected": 0\n' +
786
+ ' },\n' +
787
+ ' "metadata": {\n' +
788
+ ' "requestId": "test-request-id",\n' +
789
+ ' "timestamp": "2025-11-25T02:03:18.399Z"\n' +
790
+ ' }\n' +
791
+ '}'
792
+ }
793
+ [AccessControl] Raw response received: {
794
+ "success": true,
795
+ "data": {
796
+ "accepted": 1,
797
+ "rejected": 0
798
+ },
799
+ "metadata": {
800
+ "requestId": "test-request-id",
801
+ "timestamp": "2025-11-25T02:03:18.399Z"
802
+ }
803
+ }
804
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
805
+ correlationId: '8d58e856-79e9-4400-80e4-3d91549cc82b',
806
+ dataKeys: [ 'accepted', 'rejected' ],
807
+ hasAccepted: true,
808
+ hasRejected: true,
809
+ hasOutcomes: false,
810
+ hasErrors: false,
811
+ acceptedType: 'number',
812
+ acceptedValue: 1,
813
+ rejectedType: 'number',
814
+ rejectedValue: 0,
815
+ outcomesType: 'undefined',
816
+ outcomesValue: undefined,
817
+ errorsType: 'undefined',
818
+ errorsIsArray: false,
819
+ fullData: '{\n "accepted": 1,\n "rejected": 0\n}'
820
+ }
821
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
822
+ correlationId: '8d58e856-79e9-4400-80e4-3d91549cc82b',
823
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected' ],
824
+ hasSuccess: true,
825
+ successValue: true,
826
+ hasAccepted: true,
827
+ acceptedValue: 1,
828
+ hasRejected: true,
829
+ rejectedValue: 0,
830
+ hasOutcomes: false,
831
+ outcomesValue: undefined,
832
+ fullDataWithSuccess: '{\n "success": true,\n "accepted": 1,\n "rejected": 0\n}'
833
+ }
834
+
835
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should submit proofs successfully
836
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
837
+ correlationId: '5d1d9d9f-b2fa-4ce8-9dbb-e4502c7d46cc',
838
+ status: 200,
839
+ statusText: '',
840
+ headers: { 'content-type': 'application/json' },
841
+ responseTextLength: 100,
842
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
843
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
844
+ }
845
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
846
+ correlationId: '5d1d9d9f-b2fa-4ce8-9dbb-e4502c7d46cc',
847
+ status: 200,
848
+ responseDataType: 'object',
849
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
850
+ responseData: '{\n' +
851
+ ' "success": true,\n' +
852
+ ' "accepted": 1,\n' +
853
+ ' "rejected": 0,\n' +
854
+ ' "outcomes": {\n' +
855
+ ' "success": 1,\n' +
856
+ ' "failed": 0,\n' +
857
+ ' "blocked": 0,\n' +
858
+ ' "error": 0\n' +
859
+ ' }\n' +
860
+ '}'
861
+ }
862
+ [AccessControl] Raw response received: {
863
+ "success": true,
864
+ "accepted": 1,
865
+ "rejected": 0,
866
+ "outcomes": {
867
+ "success": 1,
868
+ "failed": 0,
869
+ "blocked": 0,
870
+ "error": 0
871
+ }
872
+ }
873
+
874
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle all_proofs_rejected error gracefully
875
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
876
+ correlationId: 'f0d056dd-14cb-4f99-a55a-ef918706ddd3',
877
+ status: 400,
878
+ statusText: '',
879
+ headers: { 'content-type': 'application/json' },
880
+ responseTextLength: 209,
881
+ responseTextPreview: '{"success":false,"error":{"code":"all_proofs_rejected","message":"All proofs rejected","details":{"rejected":1,"errors":[{"proof_index":0,"error":{"code":"invalid_signature","message":"Invalid signature"}}]}}}',
882
+ fullResponseText: '{"success":false,"error":{"code":"all_proofs_rejected","message":"All proofs rejected","details":{"rejected":1,"errors":[{"proof_index":0,"error":{"code":"invalid_signature","message":"Invalid signature"}}]}}}'
883
+ }
884
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
885
+ correlationId: 'f0d056dd-14cb-4f99-a55a-ef918706ddd3',
886
+ status: 400,
887
+ responseDataType: 'object',
888
+ responseDataKeys: [ 'success', 'error' ],
889
+ responseData: '{\n' +
890
+ ' "success": false,\n' +
891
+ ' "error": {\n' +
892
+ ' "code": "all_proofs_rejected",\n' +
893
+ ' "message": "All proofs rejected",\n' +
894
+ ' "details": {\n' +
895
+ ' "rejected": 1,\n' +
896
+ ' "errors": [\n' +
897
+ ' {\n' +
898
+ ' "proof_index": 0,\n' +
899
+ ' "error": {\n' +
900
+ ' "code": "invalid_signature",\n' +
901
+ ' "message": "Invalid signature"\n' +
902
+ ' }\n' +
903
+ ' }\n' +
904
+ ' ]\n' +
905
+ ' }\n' +
906
+ ' }\n' +
907
+ '}'
908
+ }
909
+
910
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle wrapped response format
911
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
912
+ correlationId: '124586d3-e42f-46e3-bfad-3a9dbc9caa34',
913
+ status: 200,
914
+ statusText: '',
915
+ headers: { 'content-type': 'application/json' },
916
+ responseTextLength: 206,
917
+ responseTextPreview: '{"success":true,"data":{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.423Z"}}',
918
+ fullResponseText: '{"success":true,"data":{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.423Z"}}'
919
+ }
920
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
921
+ correlationId: '124586d3-e42f-46e3-bfad-3a9dbc9caa34',
922
+ status: 200,
923
+ responseDataType: 'object',
924
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
925
+ responseData: '{\n' +
926
+ ' "success": true,\n' +
927
+ ' "data": {\n' +
928
+ ' "success": true,\n' +
929
+ ' "accepted": 1,\n' +
930
+ ' "rejected": 0,\n' +
931
+ ' "outcomes": {\n' +
932
+ ' "success": 1,\n' +
933
+ ' "failed": 0,\n' +
934
+ ' "blocked": 0,\n' +
935
+ ' "error": 0\n' +
936
+ ' }\n' +
937
+ ' },\n' +
938
+ ' "metadata": {\n' +
939
+ ' "requestId": "test-request-id",\n' +
940
+ ' "timestamp": "2025-11-25T02:03:18.423Z"\n' +
941
+ ' }\n' +
942
+ '}'
943
+ }
944
+ [AccessControl] Raw response received: {
945
+ "success": true,
946
+ "data": {
947
+ "success": true,
948
+ "accepted": 1,
949
+ "rejected": 0,
950
+ "outcomes": {
951
+ "success": 1,
952
+ "failed": 0,
953
+ "blocked": 0,
954
+ "error": 0
955
+ }
956
+ },
957
+ "metadata": {
958
+ "requestId": "test-request-id",
959
+ "timestamp": "2025-11-25T02:03:18.423Z"
960
+ }
961
+ }
962
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
963
+ correlationId: '124586d3-e42f-46e3-bfad-3a9dbc9caa34',
964
+ dataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
965
+ hasAccepted: true,
966
+ hasRejected: true,
967
+ hasOutcomes: true,
968
+ hasErrors: false,
969
+ acceptedType: 'number',
970
+ acceptedValue: 1,
971
+ rejectedType: 'number',
972
+ rejectedValue: 0,
973
+ outcomesType: 'object',
974
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
975
+ errorsType: 'undefined',
976
+ errorsIsArray: false,
977
+ fullData: '{\n' +
978
+ ' "success": true,\n' +
979
+ ' "accepted": 1,\n' +
980
+ ' "rejected": 0,\n' +
981
+ ' "outcomes": {\n' +
982
+ ' "success": 1,\n' +
983
+ ' "failed": 0,\n' +
984
+ ' "blocked": 0,\n' +
985
+ ' "error": 0\n' +
986
+ ' }\n' +
987
+ '}'
988
+ }
989
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
990
+ correlationId: '124586d3-e42f-46e3-bfad-3a9dbc9caa34',
991
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
992
+ hasSuccess: true,
993
+ successValue: true,
994
+ hasAccepted: true,
995
+ acceptedValue: 1,
996
+ hasRejected: true,
997
+ rejectedValue: 0,
998
+ hasOutcomes: true,
999
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
1000
+ fullDataWithSuccess: '{\n' +
1001
+ ' "success": true,\n' +
1002
+ ' "accepted": 1,\n' +
1003
+ ' "rejected": 0,\n' +
1004
+ ' "outcomes": {\n' +
1005
+ ' "success": 1,\n' +
1006
+ ' "failed": 0,\n' +
1007
+ ' "blocked": 0,\n' +
1008
+ ' "error": 0\n' +
1009
+ ' }\n' +
1010
+ '}'
1011
+ }
1012
+
1013
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
1014
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1015
+ correlationId: '39db810f-b8c3-469f-850c-834e111b7333',
1016
+ status: 200,
1017
+ statusText: '',
1018
+ headers: { 'content-type': 'application/json' },
1019
+ responseTextLength: 42,
1020
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0}',
1021
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0}'
1022
+ }
1023
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1024
+ correlationId: '39db810f-b8c3-469f-850c-834e111b7333',
1025
+ status: 200,
1026
+ responseDataType: 'object',
1027
+ responseDataKeys: [ 'success', 'accepted', 'rejected' ],
1028
+ responseData: '{\n "success": true,\n "accepted": 1,\n "rejected": 0\n}'
1029
+ }
1030
+ [AccessControl] Raw response received: {
1031
+ "success": true,
1032
+ "accepted": 1,
1033
+ "rejected": 0
1034
+ }
1035
+
1036
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
1037
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1038
+ correlationId: '1708e238-9bbd-4dc7-a565-476361541d05',
1039
+ status: 200,
1040
+ statusText: '',
1041
+ headers: { 'content-type': 'application/json' },
1042
+ responseTextLength: 100,
1043
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
1044
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
1045
+ }
1046
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1047
+ correlationId: '1708e238-9bbd-4dc7-a565-476361541d05',
1048
+ status: 200,
1049
+ responseDataType: 'object',
1050
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
1051
+ responseData: '{\n' +
1052
+ ' "success": true,\n' +
1053
+ ' "accepted": 1,\n' +
1054
+ ' "rejected": 0,\n' +
1055
+ ' "outcomes": {\n' +
1056
+ ' "success": 1,\n' +
1057
+ ' "failed": 0,\n' +
1058
+ ' "blocked": 0,\n' +
1059
+ ' "error": 0\n' +
1060
+ ' }\n' +
1061
+ '}'
1062
+ }
1063
+ [AccessControl] Raw response received: {
1064
+ "success": true,
1065
+ "accepted": 1,
1066
+ "rejected": 0,
1067
+ "outcomes": {
1068
+ "success": 1,
1069
+ "failed": 0,
1070
+ "blocked": 0,
1071
+ "error": 0
1072
+ }
1073
+ }
1074
+
1075
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
1076
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1077
+ correlationId: '67622268-5090-47c5-a906-d30de6728a7d',
1078
+ status: 200,
1079
+ statusText: '',
1080
+ headers: { 'content-type': 'application/json' },
1081
+ responseTextLength: 56,
1082
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{}}',
1083
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{}}'
1084
+ }
1085
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1086
+ correlationId: '67622268-5090-47c5-a906-d30de6728a7d',
1087
+ status: 200,
1088
+ responseDataType: 'object',
1089
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
1090
+ responseData: '{\n "success": true,\n "accepted": 1,\n "rejected": 0,\n "outcomes": {}\n}'
1091
+ }
1092
+ [AccessControl] Raw response received: {
1093
+ "success": true,
1094
+ "accepted": 1,
1095
+ "rejected": 0,
1096
+ "outcomes": {}
1097
+ }
1098
+
1099
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle wrapped response with invalid data structure
1100
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1101
+ correlationId: '82ef5233-aecd-458c-b5f0-5ae11b2be808',
1102
+ status: 200,
1103
+ statusText: '',
1104
+ headers: { 'content-type': 'application/json' },
1105
+ responseTextLength: 52,
1106
+ responseTextPreview: '{"success":true,"data":{"message":"Invalid format"}}',
1107
+ fullResponseText: '{"success":true,"data":{"message":"Invalid format"}}'
1108
+ }
1109
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1110
+ correlationId: '82ef5233-aecd-458c-b5f0-5ae11b2be808',
1111
+ status: 200,
1112
+ responseDataType: 'object',
1113
+ responseDataKeys: [ 'success', 'data' ],
1114
+ responseData: '{\n "success": true,\n "data": {\n "message": "Invalid format"\n }\n}'
1115
+ }
1116
+ [AccessControl] Raw response received: {
1117
+ "success": true,
1118
+ "data": {
1119
+ "message": "Invalid format"
1120
+ }
1121
+ }
1122
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
1123
+ correlationId: '82ef5233-aecd-458c-b5f0-5ae11b2be808',
1124
+ dataKeys: [ 'message' ],
1125
+ hasAccepted: false,
1126
+ hasRejected: false,
1127
+ hasOutcomes: false,
1128
+ hasErrors: false,
1129
+ acceptedType: 'undefined',
1130
+ acceptedValue: undefined,
1131
+ rejectedType: 'undefined',
1132
+ rejectedValue: undefined,
1133
+ outcomesType: 'undefined',
1134
+ outcomesValue: undefined,
1135
+ errorsType: 'undefined',
1136
+ errorsIsArray: false,
1137
+ fullData: '{\n "message": "Invalid format"\n}'
1138
+ }
1139
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
1140
+ correlationId: '82ef5233-aecd-458c-b5f0-5ae11b2be808',
1141
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected' ],
1142
+ hasSuccess: true,
1143
+ successValue: true,
1144
+ hasAccepted: true,
1145
+ acceptedValue: undefined,
1146
+ hasRejected: true,
1147
+ rejectedValue: undefined,
1148
+ hasOutcomes: false,
1149
+ outcomesValue: undefined,
1150
+ fullDataWithSuccess: '{\n "success": true\n}'
1151
+ }
1152
+ [AccessControl] ❌ MISSING REQUIRED FIELDS AFTER CONSTRUCTION: {
1153
+ correlationId: '82ef5233-aecd-458c-b5f0-5ae11b2be808',
1154
+ hasAccepted: true,
1155
+ acceptedType: 'undefined',
1156
+ acceptedValue: undefined,
1157
+ hasRejected: true,
1158
+ rejectedType: 'undefined',
1159
+ rejectedValue: undefined,
1160
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected' ],
1161
+ fullDataWithSuccess: '{\n "success": true\n}',
1162
+ dataToValidateKeys: [ 'message' ],
1163
+ fullDataToValidate: '{\n "message": "Invalid format"\n}',
1164
+ originalResponseData: '{\n "success": true,\n "data": {\n "message": "Invalid format"\n }\n}'
1165
+ }
1166
+
1167
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > Wrapped Response Format (AgentShield API) > should throw validation error if data object missing success field
1168
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1169
+ correlationId: '7d80184b-5aa3-4a3f-8972-3061ae1c43cd',
1170
+ status: 200,
1171
+ statusText: undefined,
1172
+ headers: {},
1173
+ responseTextLength: 191,
1174
+ responseTextPreview: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.399Z"}}',
1175
+ fullResponseText: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}},"metadata":{"requestId":"test-request-id","timestamp":"2025-11-25T02:03:18.399Z"}}'
1176
+ }
1177
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1178
+ correlationId: '7d80184b-5aa3-4a3f-8972-3061ae1c43cd',
1179
+ status: 200,
1180
+ responseDataType: 'object',
1181
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
1182
+ responseData: '{\n' +
1183
+ ' "success": true,\n' +
1184
+ ' "data": {\n' +
1185
+ ' "accepted": 1,\n' +
1186
+ ' "rejected": 0,\n' +
1187
+ ' "outcomes": {\n' +
1188
+ ' "success": 1,\n' +
1189
+ ' "failed": 0,\n' +
1190
+ ' "blocked": 0,\n' +
1191
+ ' "error": 0\n' +
1192
+ ' }\n' +
1193
+ ' },\n' +
1194
+ ' "metadata": {\n' +
1195
+ ' "requestId": "test-request-id",\n' +
1196
+ ' "timestamp": "2025-11-25T02:03:18.399Z"\n' +
1197
+ ' }\n' +
1198
+ '}'
1199
+ }
1200
+ [AccessControl] Raw response received: {
1201
+ "success": true,
1202
+ "data": {
1203
+ "accepted": 1,
1204
+ "rejected": 0,
1205
+ "outcomes": {
1206
+ "success": 1,
1207
+ "failed": 0,
1208
+ "blocked": 0,
1209
+ "error": 0
1210
+ }
1211
+ },
1212
+ "metadata": {
1213
+ "requestId": "test-request-id",
1214
+ "timestamp": "2025-11-25T02:03:18.399Z"
1215
+ }
1216
+ }
1217
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
1218
+ correlationId: '7d80184b-5aa3-4a3f-8972-3061ae1c43cd',
1219
+ dataKeys: [ 'accepted', 'rejected', 'outcomes' ],
1220
+ hasAccepted: true,
1221
+ hasRejected: true,
1222
+ hasOutcomes: true,
1223
+ hasErrors: false,
1224
+ acceptedType: 'number',
1225
+ acceptedValue: 1,
1226
+ rejectedType: 'number',
1227
+ rejectedValue: 0,
1228
+ outcomesType: 'object',
1229
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
1230
+ errorsType: 'undefined',
1231
+ errorsIsArray: false,
1232
+ fullData: '{\n' +
1233
+ ' "accepted": 1,\n' +
1234
+ ' "rejected": 0,\n' +
1235
+ ' "outcomes": {\n' +
1236
+ ' "success": 1,\n' +
1237
+ ' "failed": 0,\n' +
1238
+ ' "blocked": 0,\n' +
1239
+ ' "error": 0\n' +
1240
+ ' }\n' +
1241
+ '}'
1242
+ }
1243
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
1244
+ correlationId: '7d80184b-5aa3-4a3f-8972-3061ae1c43cd',
1245
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
1246
+ hasSuccess: true,
1247
+ successValue: true,
1248
+ hasAccepted: true,
1249
+ acceptedValue: 1,
1250
+ hasRejected: true,
1251
+ rejectedValue: 0,
1252
+ hasOutcomes: true,
1253
+ outcomesValue: { success: 1, failed: 0, blocked: 0, error: 0 },
1254
+ fullDataWithSuccess: '{\n' +
1255
+ ' "success": true,\n' +
1256
+ ' "accepted": 1,\n' +
1257
+ ' "rejected": 0,\n' +
1258
+ ' "outcomes": {\n' +
1259
+ ' "success": 1,\n' +
1260
+ ' "failed": 0,\n' +
1261
+ ' "blocked": 0,\n' +
1262
+ ' "error": 0\n' +
1263
+ ' }\n' +
1264
+ '}'
1265
+ }
1266
+
1267
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > JSON Deep Clone Fix (Cloudflare Workers Edge Case) > should correctly extract data from wrapped response after JSON deep clone
1268
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1269
+ correlationId: '47ea7dc9-4568-4db4-b6ba-95b4d5e80089',
1270
+ status: 200,
1271
+ statusText: undefined,
1272
+ headers: {},
1273
+ responseTextLength: 191,
1274
+ responseTextPreview: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1},"errors":[]},"metadata":{"requestId":"fc1fa88f-9b22-4161-b4fd-17d8215098ee","timestamp":"2025-11-24T21:36:33.029Z"}}',
1275
+ fullResponseText: '{"success":true,"data":{"accepted":1,"rejected":0,"outcomes":{"success":1},"errors":[]},"metadata":{"requestId":"fc1fa88f-9b22-4161-b4fd-17d8215098ee","timestamp":"2025-11-24T21:36:33.029Z"}}'
1276
+ }
1277
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1278
+ correlationId: '47ea7dc9-4568-4db4-b6ba-95b4d5e80089',
1279
+ status: 200,
1280
+ responseDataType: 'object',
1281
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
1282
+ responseData: '{\n' +
1283
+ ' "success": true,\n' +
1284
+ ' "data": {\n' +
1285
+ ' "accepted": 1,\n' +
1286
+ ' "rejected": 0,\n' +
1287
+ ' "outcomes": {\n' +
1288
+ ' "success": 1\n' +
1289
+ ' },\n' +
1290
+ ' "errors": []\n' +
1291
+ ' },\n' +
1292
+ ' "metadata": {\n' +
1293
+ ' "requestId": "fc1fa88f-9b22-4161-b4fd-17d8215098ee",\n' +
1294
+ ' "timestamp": "2025-11-24T21:36:33.029Z"\n' +
1295
+ ' }\n' +
1296
+ '}'
1297
+ }
1298
+ [AccessControl] Raw response received: {
1299
+ "success": true,
1300
+ "data": {
1301
+ "accepted": 1,
1302
+ "rejected": 0,
1303
+ "outcomes": {
1304
+ "success": 1
1305
+ },
1306
+ "errors": []
1307
+ },
1308
+ "metadata": {
1309
+ "requestId": "fc1fa88f-9b22-4161-b4fd-17d8215098ee",
1310
+ "timestamp": "2025-11-24T21:36:33.029Z"
1311
+ }
1312
+ }
1313
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
1314
+ correlationId: '47ea7dc9-4568-4db4-b6ba-95b4d5e80089',
1315
+ dataKeys: [ 'accepted', 'rejected', 'outcomes', 'errors' ],
1316
+ hasAccepted: true,
1317
+ hasRejected: true,
1318
+ hasOutcomes: true,
1319
+ hasErrors: true,
1320
+ acceptedType: 'number',
1321
+ acceptedValue: 1,
1322
+ rejectedType: 'number',
1323
+ rejectedValue: 0,
1324
+ outcomesType: 'object',
1325
+ outcomesValue: { success: 1 },
1326
+ errorsType: 'object',
1327
+ errorsIsArray: true,
1328
+ fullData: '{\n' +
1329
+ ' "accepted": 1,\n' +
1330
+ ' "rejected": 0,\n' +
1331
+ ' "outcomes": {\n' +
1332
+ ' "success": 1\n' +
1333
+ ' },\n' +
1334
+ ' "errors": []\n' +
1335
+ '}'
1336
+ }
1337
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
1338
+ correlationId: '47ea7dc9-4568-4db4-b6ba-95b4d5e80089',
1339
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
1340
+ hasSuccess: true,
1341
+ successValue: true,
1342
+ hasAccepted: true,
1343
+ acceptedValue: 1,
1344
+ hasRejected: true,
1345
+ rejectedValue: 0,
1346
+ hasOutcomes: true,
1347
+ outcomesValue: { success: 1 },
1348
+ fullDataWithSuccess: '{\n' +
1349
+ ' "success": true,\n' +
1350
+ ' "accepted": 1,\n' +
1351
+ ' "rejected": 0,\n' +
1352
+ ' "outcomes": {\n' +
1353
+ ' "success": 1\n' +
1354
+ ' },\n' +
1355
+ ' "errors": []\n' +
1356
+ '}'
1357
+ }
1358
+
1359
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > JSON Deep Clone Fix (Cloudflare Workers Edge Case) > should handle response where data fields are numeric values (not undefined)
1360
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1361
+ correlationId: '94685d71-0f50-46e3-a370-9b5121ba7b7b',
1362
+ status: 200,
1363
+ statusText: undefined,
1364
+ headers: {},
1365
+ responseTextLength: 151,
1366
+ responseTextPreview: '{"success":true,"data":{"accepted":0,"rejected":0,"outcomes":{},"errors":[]},"metadata":{"requestId":"test-id","timestamp":"2025-11-25T02:03:18.404Z"}}',
1367
+ fullResponseText: '{"success":true,"data":{"accepted":0,"rejected":0,"outcomes":{},"errors":[]},"metadata":{"requestId":"test-id","timestamp":"2025-11-25T02:03:18.404Z"}}'
1368
+ }
1369
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1370
+ correlationId: '94685d71-0f50-46e3-a370-9b5121ba7b7b',
1371
+ status: 200,
1372
+ responseDataType: 'object',
1373
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
1374
+ responseData: '{\n' +
1375
+ ' "success": true,\n' +
1376
+ ' "data": {\n' +
1377
+ ' "accepted": 0,\n' +
1378
+ ' "rejected": 0,\n' +
1379
+ ' "outcomes": {},\n' +
1380
+ ' "errors": []\n' +
1381
+ ' },\n' +
1382
+ ' "metadata": {\n' +
1383
+ ' "requestId": "test-id",\n' +
1384
+ ' "timestamp": "2025-11-25T02:03:18.404Z"\n' +
1385
+ ' }\n' +
1386
+ '}'
1387
+ }
1388
+ [AccessControl] Raw response received: {
1389
+ "success": true,
1390
+ "data": {
1391
+ "accepted": 0,
1392
+ "rejected": 0,
1393
+ "outcomes": {},
1394
+ "errors": []
1395
+ },
1396
+ "metadata": {
1397
+ "requestId": "test-id",
1398
+ "timestamp": "2025-11-25T02:03:18.404Z"
1399
+ }
1400
+ }
1401
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
1402
+ correlationId: '94685d71-0f50-46e3-a370-9b5121ba7b7b',
1403
+ dataKeys: [ 'accepted', 'rejected', 'outcomes', 'errors' ],
1404
+ hasAccepted: true,
1405
+ hasRejected: true,
1406
+ hasOutcomes: true,
1407
+ hasErrors: true,
1408
+ acceptedType: 'number',
1409
+ acceptedValue: 0,
1410
+ rejectedType: 'number',
1411
+ rejectedValue: 0,
1412
+ outcomesType: 'object',
1413
+ outcomesValue: {},
1414
+ errorsType: 'object',
1415
+ errorsIsArray: true,
1416
+ fullData: '{\n "accepted": 0,\n "rejected": 0,\n "outcomes": {},\n "errors": []\n}'
1417
+ }
1418
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
1419
+ correlationId: '94685d71-0f50-46e3-a370-9b5121ba7b7b',
1420
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
1421
+ hasSuccess: true,
1422
+ successValue: true,
1423
+ hasAccepted: true,
1424
+ acceptedValue: 0,
1425
+ hasRejected: true,
1426
+ rejectedValue: 0,
1427
+ hasOutcomes: true,
1428
+ outcomesValue: {},
1429
+ fullDataWithSuccess: '{\n' +
1430
+ ' "success": true,\n' +
1431
+ ' "accepted": 0,\n' +
1432
+ ' "rejected": 0,\n' +
1433
+ ' "outcomes": {},\n' +
1434
+ ' "errors": []\n' +
1435
+ '}'
1436
+ }
1437
+
1438
+ stderr | src/services/__tests__/access-control.proof-response-validation.test.ts > Proof Submission Response Validation > JSON Deep Clone Fix (Cloudflare Workers Edge Case) > should handle response with nested outcomes object
1439
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1440
+ correlationId: 'af8f9fe9-2667-4bda-b9fe-e79ab4eda6f5',
1441
+ status: 200,
1442
+ statusText: undefined,
1443
+ headers: {},
1444
+ responseTextLength: 278,
1445
+ responseTextPreview: '{"success":true,"data":{"accepted":3,"rejected":2,"outcomes":{"success":1,"failed":1,"blocked":1,"error":2},"errors":[{"proof_index":0,"error":{"code":"validation_error","message":"Invalid signature"}}]},"metadata":{"requestId":"test-id","timestamp":"2025-11-25T02:03:18.404Z"}}',
1446
+ fullResponseText: '{"success":true,"data":{"accepted":3,"rejected":2,"outcomes":{"success":1,"failed":1,"blocked":1,"error":2},"errors":[{"proof_index":0,"error":{"code":"validation_error","message":"Invalid signature"}}]},"metadata":{"requestId":"test-id","timestamp":"2025-11-25T02:03:18.404Z"}}'
1447
+ }
1448
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1449
+ correlationId: 'af8f9fe9-2667-4bda-b9fe-e79ab4eda6f5',
1450
+ status: 200,
1451
+ responseDataType: 'object',
1452
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
1453
+ responseData: '{\n' +
1454
+ ' "success": true,\n' +
1455
+ ' "data": {\n' +
1456
+ ' "accepted": 3,\n' +
1457
+ ' "rejected": 2,\n' +
1458
+ ' "outcomes": {\n' +
1459
+ ' "success": 1,\n' +
1460
+ ' "failed": 1,\n' +
1461
+ ' "blocked": 1,\n' +
1462
+ ' "error": 2\n' +
1463
+ ' },\n' +
1464
+ ' "errors": [\n' +
1465
+ ' {\n' +
1466
+ ' "proof_index": 0,\n' +
1467
+ ' "error": {\n' +
1468
+ ' "code": "validation_error",\n' +
1469
+ ' "message": "Invalid signature"\n' +
1470
+ ' }\n' +
1471
+ ' }\n' +
1472
+ ' ]\n' +
1473
+ ' },\n' +
1474
+ ' "metadata": {\n' +
1475
+ ' "requestId": "test-id",\n' +
1476
+ ' "timestamp": "2025-11-25T02:03:18.404Z"\n' +
1477
+ ' }\n' +
1478
+ '}'
1479
+ }
1480
+ [AccessControl] Raw response received: {
1481
+ "success": true,
1482
+ "data": {
1483
+ "accepted": 3,
1484
+ "rejected": 2,
1485
+ "outcomes": {
1486
+ "success": 1,
1487
+ "failed": 1,
1488
+ "blocked": 1,
1489
+ "error": 2
1490
+ },
1491
+ "errors": [
1492
+ {
1493
+ "proof_index": 0,
1494
+ "error": {
1495
+ "code": "validation_error",
1496
+ "message": "Invalid signature"
1497
+ }
1498
+ }
1499
+ ]
1500
+ },
1501
+ "metadata": {
1502
+ "requestId": "test-id",
1503
+ "timestamp": "2025-11-25T02:03:18.404Z"
1504
+ }
1505
+ }
1506
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE (after deep clone): {
1507
+ correlationId: 'af8f9fe9-2667-4bda-b9fe-e79ab4eda6f5',
1508
+ dataKeys: [ 'accepted', 'rejected', 'outcomes', 'errors' ],
1509
+ hasAccepted: true,
1510
+ hasRejected: true,
1511
+ hasOutcomes: true,
1512
+ hasErrors: true,
1513
+ acceptedType: 'number',
1514
+ acceptedValue: 3,
1515
+ rejectedType: 'number',
1516
+ rejectedValue: 2,
1517
+ outcomesType: 'object',
1518
+ outcomesValue: { success: 1, failed: 1, blocked: 1, error: 2 },
1519
+ errorsType: 'object',
1520
+ errorsIsArray: true,
1521
+ fullData: '{\n' +
1522
+ ' "accepted": 3,\n' +
1523
+ ' "rejected": 2,\n' +
1524
+ ' "outcomes": {\n' +
1525
+ ' "success": 1,\n' +
1526
+ ' "failed": 1,\n' +
1527
+ ' "blocked": 1,\n' +
1528
+ ' "error": 2\n' +
1529
+ ' },\n' +
1530
+ ' "errors": [\n' +
1531
+ ' {\n' +
1532
+ ' "proof_index": 0,\n' +
1533
+ ' "error": {\n' +
1534
+ ' "code": "validation_error",\n' +
1535
+ ' "message": "Invalid signature"\n' +
1536
+ ' }\n' +
1537
+ ' }\n' +
1538
+ ' ]\n' +
1539
+ '}'
1540
+ }
1541
+ [AccessControl] 🔍 VALIDATING DATA WITH SUCCESS: {
1542
+ correlationId: 'af8f9fe9-2667-4bda-b9fe-e79ab4eda6f5',
1543
+ dataWithSuccessKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
1544
+ hasSuccess: true,
1545
+ successValue: true,
1546
+ hasAccepted: true,
1547
+ acceptedValue: 3,
1548
+ hasRejected: true,
1549
+ rejectedValue: 2,
1550
+ hasOutcomes: true,
1551
+ outcomesValue: { success: 1, failed: 1, blocked: 1, error: 2 },
1552
+ fullDataWithSuccess: '{\n' +
1553
+ ' "success": true,\n' +
1554
+ ' "accepted": 3,\n' +
1555
+ ' "rejected": 2,\n' +
1556
+ ' "outcomes": {\n' +
1557
+ ' "success": 1,\n' +
1558
+ ' "failed": 1,\n' +
1559
+ ' "blocked": 1,\n' +
1560
+ ' "error": 2\n' +
1561
+ ' },\n' +
1562
+ ' "errors": [\n' +
1563
+ ' {\n' +
1564
+ ' "proof_index": 0,\n' +
1565
+ ' "error": {\n' +
1566
+ ' "code": "validation_error",\n' +
1567
+ ' "message": "Invalid signature"\n' +
1568
+ ' }\n' +
1569
+ ' }\n' +
1570
+ ' ]\n' +
1571
+ '}'
1572
+ }
1573
+
1574
+ ✓ src/services/__tests__/access-control.service.test.ts (23 tests) 52ms
1575
+ ✓ src/__tests__/services/tool-protection.service.test.ts (49 tests) 17ms
1576
+ ✓ src/__tests__/cache/tool-protection-cache.test.ts (49 tests) 158ms
1577
+ ✓ src/services/__tests__/access-control.proof-response-validation.test.ts (12 tests) 32ms
1578
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should prefer Redis over KV when both are configured
1579
+ [StorageService] Failed to connect to Redis, falling back to memory: Redis package not available
1580
+
1581
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should prefer Redis over KV when both are configured
1582
+ [StorageService] Failed to initialize KV, falling back to memory: Failed to import Cloudflare storage providers: Cannot find package '@kya-os/mcp-i-cloudflare/providers/storage' imported from '/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/storage.service.ts'
1583
+
1584
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should fall back to memory when Redis connection fails
1585
+ [StorageService] Failed to connect to Redis, falling back to memory: Redis package not available
1586
+
1587
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should use KV namespace when provided
1588
+ [StorageService] Failed to initialize KV, falling back to memory: Failed to import Cloudflare storage providers: Cannot find package '@kya-os/mcp-i-cloudflare/providers/storage' imported from '/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/storage.service.ts'
1589
+
1590
+ stderr | src/services/__tests__/proof-verifier.integration.test.ts > ProofVerifier Integration - Real DID Resolution > did:web Resolution (HTTP) > should handle HTTP errors gracefully
1591
+ [ProofVerifier] Failed to fetch public key from DID: Error: Failed to resolve did:web:nonexistent-domain-that-does-not-exist-12345.com: fetch failed
1592
+ ✓ src/services/__tests__/storage.service.test.ts (17 tests) 34ms
1593
+ at Object.resolveDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:143:19)
1594
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1595
+ at ProofVerifier.fetchPublicKeyFromDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/proof-verifier.ts:348:22)
1596
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:252:7
1597
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:20
1598
+
1599
+ stderr | src/services/__tests__/proof-verifier.integration.test.ts > ProofVerifier Integration - Real DID Resolution > did:web Resolution (HTTP) > should handle HTTP errors gracefully
1600
+ [ProofVerifier] Failed to fetch public key from DID: Error: Failed to resolve did:web:nonexistent-domain-that-does-not-exist-12345.com: fetch failed
1601
+ at Object.resolveDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:143:19)
1602
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1603
+ at ProofVerifier.fetchPublicKeyFromDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/proof-verifier.ts:348:22)
1604
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:257:9
1605
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:20
1606
+
1607
+ ✓ src/services/__tests__/proof-verifier.integration.test.ts (13 tests | 1 skipped) 119ms
1608
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when no protection required
1609
+ [MCP-I] Checking tool protection: {
1610
+ tool: 'unprotectedTool',
1611
+ agentDid: 'did:key:zmock123...',
1612
+ hasDelegation: false
1613
+ }
1614
+
1615
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when no protection required
1616
+ [MCP-I] Tool protection check passed (no delegation required) {
1617
+ tool: 'unprotectedTool',
1618
+ agentDid: 'did:key:zmock123...',
1619
+ reason: 'Tool not configured to require delegation'
1620
+ }
1621
+
1622
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when protection required and no delegation
1623
+ [MCP-I] Checking tool protection: {
1624
+ tool: 'protectedTool',
1625
+ agentDid: 'did:key:zmock123...',
1626
+ hasDelegation: false
1627
+ }
1628
+
1629
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when protection required and no delegation
1630
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1631
+ tool: 'protectedTool',
1632
+ requiredScopes: [ 'files:write' ],
1633
+ agentDid: 'did:key:zmock123...',
1634
+ resumeToken: 'resume_dn7ju0_midxlua6',
1635
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_dn7ju0_midxlua6'
1636
+ }
1637
+
1638
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and delegation provided
1639
+ [MCP-I] Checking tool protection: {
1640
+ tool: 'protectedTool',
1641
+ agentDid: 'did:key:zmock123...',
1642
+ hasDelegation: true
1643
+ }
1644
+
1645
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and delegation provided
1646
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1647
+ tool: 'protectedTool',
1648
+ agentDid: 'did:key:zmock123...',
1649
+ hasDelegationToken: true,
1650
+ hasConsentProof: false,
1651
+ requiredScopes: [ 'files:write' ]
1652
+ }
1653
+
1654
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and delegation provided
1655
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
1656
+ tool: 'protectedTool',
1657
+ agentDid: 'did:key:zmock123...',
1658
+ delegationId: 'test-delegation-id',
1659
+ credentialScopes: [ 'files:write' ],
1660
+ requiredScopes: [ 'files:write' ]
1661
+ }
1662
+
1663
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and consentProof provided
1664
+ [MCP-I] Checking tool protection: {
1665
+ tool: 'protectedTool',
1666
+ agentDid: 'did:key:zmock123...',
1667
+ hasDelegation: true
1668
+ }
1669
+
1670
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and consentProof provided
1671
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1672
+ tool: 'protectedTool',
1673
+ agentDid: 'did:key:zmock123...',
1674
+ hasDelegationToken: false,
1675
+ hasConsentProof: true,
1676
+ requiredScopes: [ 'files:write' ]
1677
+ }
1678
+
1679
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when protection required and consentProof provided
1680
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
1681
+ tool: 'protectedTool',
1682
+ agentDid: 'did:key:zmock123...',
1683
+ delegationId: 'test-delegation-id',
1684
+ credentialScopes: [ 'files:write' ],
1685
+ requiredScopes: [ 'files:write' ]
1686
+ }
1687
+
1688
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation verification fails
1689
+ [MCP-I] Checking tool protection: {
1690
+ tool: 'protectedTool',
1691
+ agentDid: 'did:key:zmock123...',
1692
+ hasDelegation: true
1693
+ }
1694
+
1695
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation verification fails
1696
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1697
+ tool: 'protectedTool',
1698
+ agentDid: 'did:key:zmock123...',
1699
+ hasDelegationToken: true,
1700
+ hasConsentProof: false,
1701
+ requiredScopes: [ 'files:write' ]
1702
+ }
1703
+
1704
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation verification fails
1705
+ [MCP-I] ❌ Delegation verification FAILED {
1706
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation has wrong scopes
1707
+ [MCP-I] Checking tool protection: {
1708
+ tool: 'protectedTool',
1709
+ agentDid: 'did:key:zmock123...',
1710
+ hasDelegation: true
1711
+ }
1712
+ tool: 'protectedTool',
1713
+ agentDid: 'did:key:zmock123...',
1714
+
1715
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation has wrong scopes
1716
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1717
+ reason: 'Delegation token expired',
1718
+ tool: 'protectedTool',
1719
+ errorCode: undefined,
1720
+ errorMessage: undefined,
1721
+ requiredScopes: [ 'files:write' ]
1722
+ agentDid: 'did:key:zmock123...',
1723
+ hasDelegationToken: true,
1724
+ }
1725
+ hasConsentProof: false,
1726
+ requiredScopes: [ 'files:write' ]
1727
+ }
1728
+
1729
+
1730
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should block tool execution when delegation has wrong scopes
1731
+ [MCP-I] ❌ Delegation verification FAILED {
1732
+ tool: 'protectedTool',
1733
+ agentDid: 'did:key:zmock123...',
1734
+ reason: 'Insufficient scopes',
1735
+ errorCode: undefined,
1736
+ errorMessage: undefined,
1737
+ requiredScopes: [ 'files:write' ]
1738
+ }
1739
+
1740
+ ✓ src/__tests__/runtime/base.test.ts (55 tests) 12ms
1741
+ ✓ src/delegation/__tests__/vc-verifier.test.ts (35 tests) 427ms
1742
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
1743
+ [MCP-I] Checking tool protection: {
1744
+ tool: 'protectedTool',
1745
+ agentDid: 'did:key:zmock123...',
1746
+ hasDelegation: true
1747
+ }
1748
+
1749
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
1750
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1751
+ tool: 'protectedTool',
1752
+ agentDid: 'did:key:zmock123...',
1753
+ hasDelegationToken: true,
1754
+ hasConsentProof: false,
1755
+ requiredScopes: [ 'files:write' ]
1756
+ }
1757
+
1758
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
1759
+ [MCP-I] ❌ Delegation verification error (API failure) {
1760
+ tool: 'protectedTool',
1761
+ agentDid: 'did:key:zmock123...',
1762
+ errorCode: 'network_error',
1763
+ errorMessage: 'API unavailable',
1764
+ errorDetails: {}
1765
+ }
1766
+
1767
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when access control service not configured (graceful degradation)
1768
+ [MCP-I] Checking tool protection: {
1769
+ tool: 'protectedTool',
1770
+ agentDid: 'did:key:zmock123...',
1771
+ hasDelegation: true
1772
+ }
1773
+
1774
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should allow tool execution when access control service not configured (graceful degradation)
1775
+ [MCP-I] ⚠️ Delegation token provided but AccessControlApiService not configured - skipping verification {
1776
+ tool: 'protectedTool',
1777
+ agentDid: 'did:key:zmock123...',
1778
+ hasDelegationToken: true,
1779
+ hasConsentProof: false
1780
+ }
1781
+
1782
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should reject delegation when user_identifier does not match session userDid
1783
+ [MCP-I] Checking tool protection: {
1784
+ tool: 'protectedTool',
1785
+ agentDid: 'did:key:zmock123...',
1786
+ hasDelegation: true
1787
+ }
1788
+
1789
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should reject delegation when user_identifier does not match session userDid
1790
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1791
+ tool: 'protectedTool',
1792
+ agentDid: 'did:key:zmock123...',
1793
+ hasDelegationToken: true,
1794
+ hasConsentProof: false,
1795
+ requiredScopes: [ 'files:write' ]
1796
+ }
1797
+
1798
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should reject delegation when user_identifier does not match session userDid
1799
+ [MCP-I] 🔒 SECURITY: User identifier validation FAILED {
1800
+ tool: 'protectedTool',
1801
+ agentDid: 'did:key:zmock123...',
1802
+ delegationUserIdentifier: 'did:key:zUserB987654...',
1803
+ sessionUserDid: 'did:key:zUserA123456...',
1804
+ sessionId: 'session123...',
1805
+ reason: 'user_identifier_mismatch',
1806
+ severity: 'high'
1807
+ }
1808
+
1809
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should accept delegation when user_identifier matches session userDid
1810
+ [MCP-I] Checking tool protection: {
1811
+ tool: 'protectedTool',
1812
+ agentDid: 'did:key:zmock123...',
1813
+ hasDelegation: true
1814
+ }
1815
+
1816
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should accept delegation when user_identifier matches session userDid
1817
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1818
+ tool: 'protectedTool',
1819
+ agentDid: 'did:key:zmock123...',
1820
+ hasDelegationToken: true,
1821
+ hasConsentProof: false,
1822
+ requiredScopes: [ 'files:write' ]
1823
+ }
1824
+
1825
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should accept delegation when user_identifier matches session userDid
1826
+ [MCP-I] ✅ User identifier validation PASSED {
1827
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing session userDid gracefully
1828
+ [MCP-I] ⚠️ Delegation has user_identifier but session missing userDid {
1829
+ tool: 'protectedTool',
1830
+ tool: 'protectedTool',
1831
+ agentDid: 'did:key:zmock123...',
1832
+ delegationUserIdentifier: 'did:key:zUserA123456...',
1833
+ agentDid: 'did:key:zmock123...',
1834
+ userDid: 'did:key:zUserA123456...',
1835
+ sessionId: 'session123...'
1836
+ sessionId: 'session123...'
1837
+ }
1838
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
1839
+ }
1840
+ tool: 'protectedTool',
1841
+ agentDid: 'did:key:zmock123...',
1842
+
1843
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should not create proof when tool execution is blocked
1844
+ delegationId: 'test-delegation-id',
1845
+ credentialScopes: [ 'files:write' ],
1846
+ requiredScopes: [ 'files:write' ]
1847
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1848
+ tool: 'protectedTool',
1849
+ }
1850
+ requiredScopes: [ 'files:write' ],
1851
+
1852
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing user_identifier gracefully (backward compatibility)
1853
+ [MCP-I] Checking tool protection: {
1854
+ tool: 'protectedTool',
1855
+ agentDid: 'did:key:zmock123...',
1856
+ agentDid: 'did:key:zmock123...',
1857
+ hasDelegation: true
1858
+ }
1859
+ resumeToken: 'resume_dn8065_midxluah',
1860
+
1861
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing user_identifier gracefully (backward compatibility)
1862
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_dn8065_midxluah'
1863
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1864
+ }
1865
+
1866
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include tool name in error
1867
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1868
+ tool: 'protectedTool',
1869
+ agentDid: 'did:key:zmock123...',
1870
+ hasDelegationToken: true,
1871
+ tool: 'protectedTool',
1872
+ requiredScopes: [ 'files:write' ],
1873
+ hasConsentProof: false,
1874
+ requiredScopes: [ 'files:write' ]
1875
+ agentDid: 'did:key:zmock123...',
1876
+ resumeToken: 'resume_dn8065_midxluah',
1877
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_dn8065_midxluah'
1878
+ }
1879
+
1880
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing user_identifier gracefully (backward compatibility)
1881
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
1882
+ tool: 'protectedTool',
1883
+ agentDid: 'did:key:zmock123...',
1884
+ delegationId: 'test-delegation-id',
1885
+ }
1886
+ credentialScopes: [ 'files:write' ],
1887
+ requiredScopes: [ 'files:write' ]
1888
+ }
1889
+
1890
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing session userDid gracefully
1891
+
1892
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include required scopes in error
1893
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1894
+ tool: 'protectedTool',
1895
+ [MCP-I] Checking tool protection: {
1896
+ tool: 'protectedTool',
1897
+ agentDid: 'did:key:zmock123...',
1898
+ hasDelegation: true
1899
+ }
1900
+
1901
+ requiredScopes: [ 'files:write', 'files:read' ],
1902
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing session userDid gracefully
1903
+ agentDid: 'did:key:zmock123...',
1904
+ resumeToken: 'resume_dn80p3_midxluai',
1905
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
1906
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite%2Cfiles%3Aread&session_id=session123&agent_did=&resume_token=resume_dn80p3_midxluai'
1907
+ }
1908
+
1909
+ tool: 'protectedTool',
1910
+ agentDid: 'did:key:zmock123...',
1911
+ hasDelegationToken: true,
1912
+ hasConsentProof: false,
1913
+ requiredScopes: [ 'files:write' ]
1914
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include consent URL in error
1915
+ }
1916
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1917
+ tool: 'protectedTool',
1918
+ requiredScopes: [ 'files:write' ],
1919
+
1920
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > user_identifier validation > should handle missing session userDid gracefully
1921
+ agentDid: 'did:key:zmock123...',
1922
+ resumeToken: 'resume_dn80p3_midxluai',
1923
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
1924
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_dn80p3_midxluai'
1925
+ tool: 'protectedTool',
1926
+ agentDid: 'did:key:zmock123...',
1927
+ delegationId: 'test-delegation-id',
1928
+ }
1929
+ credentialScopes: [ 'files:write' ],
1930
+ requiredScopes: [ 'files:write' ]
1931
+
1932
+ }
1933
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include resume token in error
1934
+
1935
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1936
+ tool: 'protectedTool',
1937
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should create proof after successful tool execution
1938
+ [MCP-I] Checking tool protection: {
1939
+ tool: 'unprotectedTool',
1940
+ agentDid: 'did:key:zmock123...',
1941
+ hasDelegation: false
1942
+ }
1943
+ requiredScopes: [ 'files:write' ],
1944
+
1945
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should create proof after successful tool execution
1946
+ [MCP-I] Tool protection check passed (no delegation required) {
1947
+ agentDid: 'did:key:zmock123...',
1948
+ tool: 'unprotectedTool',
1949
+ agentDid: 'did:key:zmock123...',
1950
+ reason: 'Tool not configured to require delegation'
1951
+ }
1952
+
1953
+ resumeToken: 'resume_dn80p3_midxluai',
1954
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_dn80p3_midxluai'
1955
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should not create proof when tool execution is blocked
1956
+ [MCP-I] Checking tool protection: {
1957
+ tool: 'protectedTool',
1958
+ agentDid: 'did:key:zmock123...',
1959
+ }
1960
+ hasDelegation: false
1961
+ }
1962
+
1963
+
1964
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include tool name in error
1965
+ [MCP-I] Checking tool protection: {
1966
+ tool: 'protectedTool',
1967
+ agentDid: 'did:key:zmock123...',
1968
+ hasDelegation: false
1969
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include intercepted call context in error
1970
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1971
+ }
1972
+ tool: 'protectedTool',
1973
+ requiredScopes: [ 'files:write' ],
1974
+
1975
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include required scopes in error
1976
+ agentDid: 'did:key:zmock123...',
1977
+ [MCP-I] Checking tool protection: {
1978
+ tool: 'protectedTool',
1979
+ resumeToken: 'resume_tty7xe_midxluai',
1980
+ agentDid: 'did:key:zmock123...',
1981
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_tty7xe_midxluai'
1982
+ }
1983
+ hasDelegation: false
1984
+
1985
+ }
1986
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle empty required scopes array
1987
+
1988
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include consent URL in error
1989
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1990
+ tool: 'protectedTool',
1991
+ [MCP-I] Checking tool protection: {
1992
+ tool: 'protectedTool',
1993
+ agentDid: 'did:key:zmock123...',
1994
+ requiredScopes: [],
1995
+ agentDid: 'did:key:zmock123...',
1996
+ resumeToken: 'resume_dn80qt_midxluak',
1997
+ hasDelegation: false
1998
+ }
1999
+
2000
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=&session_id=session123&agent_did=&resume_token=resume_dn80qt_midxluak'
2001
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include resume token in error
2002
+ [MCP-I] Checking tool protection: {
2003
+ tool: 'protectedTool',
2004
+ agentDid: 'did:key:zmock123...',
2005
+ }
2006
+ hasDelegation: false
2007
+ }
2008
+
2009
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include intercepted call context in error
2010
+ [MCP-I] Checking tool protection: {
2011
+ tool: 'protectedTool',
2012
+ agentDid: 'did:key:zmock123...',
2013
+ hasDelegation: false
2014
+ }
2015
+
2016
+
2017
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle multiple required scopes
2018
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
2019
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log tool protection check when audit enabled
2020
+ [MCP-I] Checking tool protection: {
2021
+ tool: 'testTool',
2022
+ tool: 'protectedTool',
2023
+ agentDid: 'did:key:zmock123...',
2024
+ hasDelegation: false
2025
+ }
2026
+
2027
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log tool protection check when audit enabled
2028
+ [MCP-I] Tool protection check passed (no delegation required) {
2029
+ tool: 'testTool',
2030
+ agentDid: 'did:key:zmock123...',
2031
+ requiredScopes: [ 'scope1', 'scope2', 'scope3' ],
2032
+ reason: 'Tool not configured to require delegation'
2033
+ }
2034
+
2035
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log blocked tool call when audit enabled
2036
+ [MCP-I] Checking tool protection: {
2037
+ tool: 'protectedTool',
2038
+ agentDid: 'did:key:zmock123...',
2039
+ hasDelegation: false
2040
+ }
2041
+
2042
+ agentDid: 'did:key:zmock123...',
2043
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > tool protection service integration > should use agent DID from identity for protection check
2044
+ [MCP-I] Checking tool protection: {
2045
+ tool: 'testTool',
2046
+ agentDid: 'did:key:zmock123...',
2047
+ resumeToken: 'resume_dn80qt_midxluak',
2048
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=scope1%2Cscope2%2Cscope3&session_id=session123&agent_did=&resume_token=resume_dn80qt_midxluak'
2049
+ }
2050
+
2051
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle session without id
2052
+ hasDelegation: false
2053
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
2054
+ }
2055
+ tool: 'protectedTool',
2056
+
2057
+ requiredScopes: [ 'files:write' ],
2058
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > tool protection service integration > should use agent DID from identity for protection check
2059
+ [MCP-I] Tool protection check passed (no delegation required) {
2060
+ agentDid: 'did:key:zmock123...',
2061
+ resumeToken: 'resume_qpa15j_midxluak',
2062
+ tool: 'testTool',
2063
+ agentDid: 'did:key:zmock123...',
2064
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=&agent_did=&resume_token=resume_qpa15j_midxluak'
2065
+ reason: 'Tool not configured to require delegation'
2066
+ }
2067
+
2068
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > tool protection service integration > should handle tool protection service errors gracefully
2069
+ [MCP-I] Checking tool protection: {
2070
+ tool: 'testTool',
2071
+ agentDid: 'did:key:zmock123...',
2072
+ hasDelegation: false
2073
+ }
2074
+
2075
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle empty required scopes array
2076
+ [MCP-I] Checking tool protection: {
2077
+ tool: 'protectedTool',
2078
+ agentDid: 'did:key:zmock123...',
2079
+ hasDelegation: false
2080
+ }
2081
+
2082
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle multiple required scopes
2083
+ [MCP-I] Checking tool protection: {
2084
+ }
2085
+ tool: 'protectedTool',
2086
+ agentDid: 'did:key:zmock123...',
2087
+ hasDelegation: false
2088
+
2089
+ }
2090
+
2091
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle session without id
2092
+ [MCP-I] Checking tool protection: {
2093
+ tool: 'protectedTool',
2094
+ agentDid: 'did:key:zmock123...',
2095
+ hasDelegation: false
2096
+ }
2097
+
2098
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle handler errors independently of protection
2099
+ [MCP-I] Checking tool protection: {
2100
+ tool: 'errorTool',
2101
+ agentDid: 'did:key:zmock123...',
2102
+ hasDelegation: false
2103
+ }
2104
+
2105
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle handler errors independently of protection
2106
+ [MCP-I] Tool protection check passed (no delegation required) {
2107
+ tool: 'errorTool',
2108
+ agentDid: 'did:key:zmock123...',
2109
+ reason: 'Tool not configured to require delegation'
2110
+ }
2111
+
2112
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Submission Flow > should submit proof end-to-end
2113
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
2114
+ correlationId: 'b0757e1e-53f0-4144-b6fa-be15e227a789',
2115
+ status: 200,
2116
+ statusText: '',
2117
+ headers: { 'content-type': 'application/json' },
2118
+ responseTextLength: 100,
2119
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
2120
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
2121
+ }
2122
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
2123
+ correlationId: 'b0757e1e-53f0-4144-b6fa-be15e227a789',
2124
+ status: 200,
2125
+ responseDataType: 'object',
2126
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
2127
+ responseData: '{\n' +
2128
+ ' "success": true,\n' +
2129
+ ' "accepted": 1,\n' +
2130
+ ' "rejected": 0,\n' +
2131
+ ' "outcomes": {\n' +
2132
+ ' "success": 1,\n' +
2133
+ ' "failed": 0,\n' +
2134
+ ' "blocked": 0,\n' +
2135
+ ' "error": 0\n' +
2136
+ ' }\n' +
2137
+ '}'
2138
+ }
2139
+ [AccessControl] Raw response received: {
2140
+ "success": true,
2141
+ "accepted": 1,
2142
+ "rejected": 0,
2143
+ "outcomes": {
2144
+ "success": 1,
2145
+ "failed": 0,
2146
+ "blocked": 0,
2147
+ "error": 0
2148
+ }
2149
+ }
2150
+
2151
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Submission Flow > should handle proof submission with errors
2152
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
2153
+ correlationId: 'e61391a3-0c82-4bb5-9850-5d0b24483ebc',
2154
+ status: 200,
2155
+ statusText: '',
2156
+ headers: { 'content-type': 'application/json' },
2157
+ responseTextLength: 200,
2158
+ responseTextPreview: '{"success":true,"accepted":0,"rejected":1,"outcomes":{"success":0,"failed":1,"blocked":0,"error":0},"errors":[{"proof_index":0,"error":{"code":"invalid_signature","message":"Invalid JWS signature"}}]}',
2159
+ fullResponseText: '{"success":true,"accepted":0,"rejected":1,"outcomes":{"success":0,"failed":1,"blocked":0,"error":0},"errors":[{"proof_index":0,"error":{"code":"invalid_signature","message":"Invalid JWS signature"}}]}'
2160
+ }
2161
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
2162
+ correlationId: 'e61391a3-0c82-4bb5-9850-5d0b24483ebc',
2163
+ status: 200,
2164
+ responseDataType: 'object',
2165
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
2166
+ responseData: '{\n' +
2167
+ ' "success": true,\n' +
2168
+ ' "accepted": 0,\n' +
2169
+ ' "rejected": 1,\n' +
2170
+ ' "outcomes": {\n' +
2171
+ ' "success": 0,\n' +
2172
+ ' "failed": 1,\n' +
2173
+ ' "blocked": 0,\n' +
2174
+ ' "error": 0\n' +
2175
+ ' },\n' +
2176
+ ' "errors": [\n' +
2177
+ ' {\n' +
2178
+ ' "proof_index": 0,\n' +
2179
+ ' "error": {\n' +
2180
+ ' "code": "invalid_signature",\n' +
2181
+ ' "message": "Invalid JWS signature"\n' +
2182
+ ' }\n' +
2183
+ ' }\n' +
2184
+ ' ]\n' +
2185
+ '}'
2186
+ }
2187
+ [AccessControl] Raw response received: {
2188
+ "success": true,
2189
+ "accepted": 0,
2190
+ "rejected": 1,
2191
+ "outcomes": {
2192
+ "success": 0,
2193
+ "failed": 1,
2194
+ "blocked": 0,
2195
+ "error": 0
2196
+ },
2197
+ "errors": [
2198
+ {
2199
+ "proof_index": 0,
2200
+ "error": {
2201
+ "code": "invalid_signature",
2202
+ "message": "Invalid JWS signature"
2203
+ }
2204
+ }
2205
+ ]
2206
+ }
2207
+
2208
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Verification Flow > should verify proof using ProofVerifier
2209
+ [CryptoService] Key ID mismatch
2210
+
2211
+ ✓ src/__tests__/runtime/tool-protection-enforcement.test.ts (29 tests) 19ms
2212
+ ✓ src/__tests__/runtime/route-interception.test.ts (21 tests) 26ms
2213
+ ✓ src/delegation/__tests__/vc-issuer.test.ts (21 tests) 244ms
2214
+ ✓ src/services/__tests__/access-control.integration.test.ts (9 tests) 127ms
2215
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyEd25519 > should return false on verification error
2216
+ [CryptoService] Ed25519 verification error: Error: Verification failed
2217
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:62:9
2218
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2219
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2220
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2221
+ at new Promise (<anonymous>)
2222
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2223
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2224
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2225
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2226
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2227
+
2228
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject invalid JWK format
2229
+ [CryptoService] Invalid Ed25519 JWK format
2230
+
2231
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with wrong kty
2232
+ [CryptoService] Invalid Ed25519 JWK format
2233
+
2234
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with wrong crv
2235
+ [CryptoService] Invalid Ed25519 JWK format
2236
+
2237
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with missing x field
2238
+ [CryptoService] Invalid Ed25519 JWK format
2239
+
2240
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with empty x field
2241
+ [CryptoService] Invalid Ed25519 JWK format
2242
+
2243
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject malformed JWS
2244
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected token 'ž', "ž‹" is not valid JSON
2245
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
2246
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2247
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:230:42
2248
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2249
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2250
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2251
+ at new Promise (<anonymous>)
2252
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2253
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2254
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2255
+
2256
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject non-EdDSA algorithms
2257
+ [CryptoService] Unsupported algorithm: RS256, expected EdDSA
2258
+
2259
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject HS256 algorithm
2260
+ [CryptoService] Unsupported algorithm: HS256, expected EdDSA
2261
+
2262
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle empty JWS components
2263
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected end of JSON input
2264
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
2265
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2266
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:271:42
2267
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2268
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2269
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2270
+ at new Promise (<anonymous>)
2271
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2272
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2273
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2274
+
2275
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - single part
2276
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
2277
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
2278
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2279
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:279:42
2280
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2281
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2282
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2283
+ at new Promise (<anonymous>)
2284
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2285
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2286
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2287
+
2288
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - two parts
2289
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
2290
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
2291
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2292
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:287:42
2293
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2294
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2295
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2296
+ at new Promise (<anonymous>)
2297
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2298
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2299
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2300
+
2301
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - four parts
2302
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
2303
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
2304
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2305
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:302:42
2306
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2307
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2308
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2309
+ at new Promise (<anonymous>)
2310
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2311
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2312
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2313
+
2314
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - invalid JSON header
2315
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected token 'o', "notjson" is not valid JSON
2316
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
2317
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2318
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:316:42
2319
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2320
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2321
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2322
+ at new Promise (<anonymous>)
2323
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2324
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2325
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2326
+
2327
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - invalid base64
2328
+ [CryptoService] Invalid JWS format: Error: Invalid payload base64: Invalid base64url string: Invalid character
2329
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:107:15)
2330
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2331
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:334:42
2332
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2333
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2334
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2335
+ at new Promise (<anonymous>)
2336
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2337
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2338
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2339
+
2340
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate expectedKid option
2341
+ [CryptoService] Key ID mismatch
2342
+
2343
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate alg option
2344
+ [CryptoService] Unsupported algorithm: EdDSA, expected RS256
2345
+
2346
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate Ed25519 key length
2347
+ [CryptoService] Failed to extract public key: Error: Invalid Ed25519 public key length: 5
2348
+ at CryptoService.jwkToBase64PublicKey (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:295:13)
2349
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:249:32)
2350
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:398:42
2351
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2352
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2353
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2354
+ at new Promise (<anonymous>)
2355
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2356
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2357
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2358
+
2359
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle signature verification error
2360
+ [CryptoService] Ed25519 verification error: Error: Crypto error
2361
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:449:61
2362
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2363
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2364
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2365
+ at new Promise (<anonymous>)
2366
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2367
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2368
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2369
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2370
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2371
+
2372
+ ✓ src/services/__tests__/crypto.service.test.ts (34 tests) 10ms
2373
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should respect cache TTL
2374
+ [ToolProtectionService] Config loaded from API {
2375
+ source: 'api',
2376
+ toolCount: 0,
2377
+ protectedTools: [],
2378
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2379
+ projectId: 'test-project-123',
2380
+ cacheTtlMs: 1000,
2381
+ cacheExpiresAt: '2025-11-25T02:03:20.103Z'
2382
+ }
2383
+
2384
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle typical e-commerce tool protection config
2385
+ [ToolProtectionService] Config loaded from API {
2386
+ source: 'api',
2387
+ toolCount: 4,
2388
+ protectedTools: [ 'add_to_cart', 'checkout' ],
2389
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2390
+ projectId: 'test-project-123',
2391
+ cacheTtlMs: 300000,
2392
+ cacheExpiresAt: '2025-11-25T02:08:19.104Z'
2393
+ }
2394
+
2395
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle concurrent requests
2396
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle API rate limiting gracefully
2397
+ [ToolProtectionService] Config loaded from API {
2398
+ source: 'api',
2399
+ toolCount: 1,
2400
+ [ToolProtectionService] API fetch failed, using fallback config {
2401
+ protectedTools: [ 'tool1' ],
2402
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2403
+ projectId: 'test-project-123',
2404
+ cacheTtlMs: 300000,
2405
+ cacheExpiresAt: '2025-11-25T02:08:19.105Z'
2406
+ }
2407
+ [ToolProtectionService] Config loaded from API {
2408
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2409
+ source: 'api',
2410
+ toolCount: 1,
2411
+ protectedTools: [ 'tool1' ],
2412
+ error: 'Failed to fetch bouncer config: 429 Too Many Requests - Rate limit exceeded'
2413
+ }
2414
+
2415
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2416
+ projectId: 'test-project-123',
2417
+ cacheTtlMs: 300000,
2418
+ cacheExpiresAt: '2025-11-25T02:08:19.105Z'
2419
+ }
2420
+ [ToolProtectionService] Config loaded from API {
2421
+ source: 'api',
2422
+ toolCount: 1,
2423
+ protectedTools: [ 'tool1' ],
2424
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2425
+ projectId: 'test-project-123',
2426
+ cacheTtlMs: 300000,
2427
+ cacheExpiresAt: '2025-11-25T02:08:19.105Z'
2428
+ }
2429
+
2430
+ ✓ src/__tests__/services/agentshield-integration.test.ts (30 tests) 1116ms
2431
+ ✓ should respect cache TTL 1101ms
2432
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > New endpoint format (toolProtections object) > should parse oauthProvider from camelCase field
2433
+ [ToolProtectionService] Config loaded from API {
2434
+ source: 'api',
2435
+ toolCount: 2,
2436
+ protectedTools: [ 'read_repos', 'send_email' ],
2437
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2438
+ projectId: 'test-project-123',
2439
+ cacheTtlMs: 300000,
2440
+ cacheExpiresAt: '2025-11-25T02:08:19.641Z'
2441
+ }
2442
+
2443
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > New endpoint format (toolProtections object) > should parse oauthProvider from snake_case field
2444
+ [ToolProtectionService] Config loaded from API {
2445
+ source: 'api',
2446
+ toolCount: 1,
2447
+ protectedTools: [ 'read_repos' ],
2448
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2449
+ projectId: 'test-project-123',
2450
+ cacheTtlMs: 300000,
2451
+ cacheExpiresAt: '2025-11-25T02:08:19.643Z'
2452
+ }
2453
+
2454
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > New endpoint format (toolProtections object) > should prefer camelCase over snake_case when both present
2455
+ [ToolProtectionService] Config loaded from API {
2456
+ source: 'api',
2457
+ toolCount: 1,
2458
+ protectedTools: [ 'read_repos' ],
2459
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2460
+ projectId: 'test-project-123',
2461
+ cacheTtlMs: 300000,
2462
+ cacheExpiresAt: '2025-11-25T02:08:19.643Z'
2463
+ }
2464
+
2465
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > New endpoint format (toolProtections object) > should handle missing oauthProvider field (backward compatible)
2466
+ [ToolProtectionService] Config loaded from API {
2467
+ source: 'api',
2468
+ toolCount: 1,
2469
+ protectedTools: [ 'read_repos' ],
2470
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2471
+ projectId: 'test-project-123',
2472
+ cacheTtlMs: 300000,
2473
+ cacheExpiresAt: '2025-11-25T02:08:19.644Z'
2474
+ }
2475
+
2476
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools array) > should parse oauthProvider from array format with camelCase
2477
+ [ToolProtectionService] Config loaded from API {
2478
+ source: 'api',
2479
+ toolCount: 2,
2480
+ protectedTools: [ 'read_repos', 'send_email' ],
2481
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2482
+ projectId: 'none',
2483
+ cacheTtlMs: 300000,
2484
+ cacheExpiresAt: '2025-11-25T02:08:19.644Z'
2485
+ }
2486
+
2487
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools array) > should parse oauthProvider from array format with snake_case
2488
+ [ToolProtectionService] Config loaded from API {
2489
+ source: 'api',
2490
+ toolCount: 1,
2491
+ protectedTools: [ 'read_repos' ],
2492
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2493
+ projectId: 'none',
2494
+ cacheTtlMs: 300000,
2495
+ cacheExpiresAt: '2025-11-25T02:08:19.644Z'
2496
+ }
2497
+
2498
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools array) > should prefer camelCase over snake_case in array format
2499
+ [ToolProtectionService] Config loaded from API {
2500
+ source: 'api',
2501
+ toolCount: 1,
2502
+ protectedTools: [ 'read_repos' ],
2503
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2504
+ projectId: 'none',
2505
+ cacheTtlMs: 300000,
2506
+ cacheExpiresAt: '2025-11-25T02:08:19.645Z'
2507
+ }
2508
+
2509
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools object) > should parse oauthProvider from object format with camelCase
2510
+ [ToolProtectionService] Config loaded from API {
2511
+ source: 'api',
2512
+ toolCount: 2,
2513
+ protectedTools: [ 'read_repos', 'send_email' ],
2514
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2515
+ projectId: 'none',
2516
+ cacheTtlMs: 300000,
2517
+ cacheExpiresAt: '2025-11-25T02:08:19.645Z'
2518
+ }
2519
+
2520
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools object) > should parse oauthProvider from object format with snake_case
2521
+ [ToolProtectionService] Config loaded from API {
2522
+ source: 'api',
2523
+ toolCount: 1,
2524
+ protectedTools: [ 'read_repos' ],
2525
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2526
+ projectId: 'none',
2527
+ cacheTtlMs: 300000,
2528
+ cacheExpiresAt: '2025-11-25T02:08:19.645Z'
2529
+ }
2530
+
2531
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Old endpoint format (tools object) > should prefer camelCase over snake_case in object format
2532
+ [ToolProtectionService] Config loaded from API {
2533
+ source: 'api',
2534
+ toolCount: 1,
2535
+ protectedTools: [ 'read_repos' ],
2536
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2537
+ projectId: 'none',
2538
+ cacheTtlMs: 300000,
2539
+ cacheExpiresAt: '2025-11-25T02:08:19.645Z'
2540
+ }
2541
+
2542
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Caching > should cache oauthProvider field correctly
2543
+ [ToolProtectionService] Config loaded from API {
2544
+ source: 'api',
2545
+ toolCount: 1,
2546
+ protectedTools: [ 'read_repos' ],
2547
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2548
+ projectId: 'test-project-123',
2549
+ cacheTtlMs: 300000,
2550
+ cacheExpiresAt: '2025-11-25T02:08:19.645Z'
2551
+ }
2552
+
2553
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > oauthProvider field inclusion > should include oauthProvider in returned ToolProtection objects when present
2554
+ [ToolProtectionService] Config loaded from API {
2555
+ source: 'api',
2556
+ toolCount: 2,
2557
+ protectedTools: [ 'tool_with_provider', 'tool_without_provider' ],
2558
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2559
+ projectId: 'test-project-123',
2560
+ cacheTtlMs: 300000,
2561
+ cacheExpiresAt: '2025-11-25T02:08:19.646Z'
2562
+ }
2563
+
2564
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > oauthProvider field inclusion > should handle empty string oauthProvider gracefully
2565
+ [ToolProtectionService] Config loaded from API {
2566
+ source: 'api',
2567
+ toolCount: 1,
2568
+ protectedTools: [ 'tool_with_empty_provider' ],
2569
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2570
+ projectId: 'test-project-123',
2571
+ cacheTtlMs: 300000,
2572
+ cacheExpiresAt: '2025-11-25T02:08:19.646Z'
2573
+ }
2574
+
2575
+ ✓ src/__tests__/services/tool-protection-oauth-provider.test.ts (14 tests) 6ms
2576
+ ✓ src/delegation/__tests__/cascading-revocation.test.ts (23 tests) 14ms
2577
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if API request fails
2578
+ ✓ src/delegation/__tests__/delegation-graph.test.ts (28 tests) 7ms
2579
+ [RemoteConfig] API returned 404: Not Found
2580
+
2581
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if API throws error
2582
+ [RemoteConfig] Failed to fetch config: Error: Network error
2583
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/config/__tests__/remote-config.spec.ts:170:35
2584
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2585
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2586
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2587
+ at new Promise (<anonymous>)
2588
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2589
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2590
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2591
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2592
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2593
+
2594
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if neither projectId nor agentDid provided
2595
+ [RemoteConfig] Neither projectId nor agentDid provided
2596
+
2597
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should handle cache read errors gracefully
2598
+ [RemoteConfig] Cache read failed: Error: Cache error
2599
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/config/__tests__/remote-config.spec.ts:198:50
2600
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2601
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2602
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2603
+ at new Promise (<anonymous>)
2604
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2605
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2606
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2607
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2608
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2609
+
2610
+ ✓ src/config/__tests__/remote-config.spec.ts (9 tests) 17ms
2611
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.get errors gracefully
2612
+ [UserDidManager] Storage.get failed, generating new DID: Error: Storage error
2613
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:187:67
2614
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2615
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2616
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2617
+ at new Promise (<anonymous>)
2618
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2619
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2620
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2621
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2622
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2623
+
2624
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.set errors gracefully
2625
+ [UserDidManager] Storage.set failed, continuing with cached DID: Error: Storage error
2626
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:196:67
2627
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2628
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2629
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2630
+ at new Promise (<anonymous>)
2631
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2632
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2633
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2634
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2635
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2636
+
2637
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.delete errors gracefully
2638
+ [UserDidManager] Storage.delete failed, continuing: Error: Storage error
2639
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:206:70
2640
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2641
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:20
2642
+
2643
+ ✓ src/__tests__/identity/user-did-manager.test.ts (17 tests) 16ms
2644
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle empty scopes array
2645
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2646
+
2647
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle ambiguous scopes (multiple providers inferred)
2648
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2649
+
2650
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle unknown scope prefixes
2651
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2652
+ stdout | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should verify gmail → google mapping works
2653
+ [ProviderResolver] Inferred provider "google" from scopes
2654
+
2655
+
2656
+ stdout | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should verify calendar → google mapping works
2657
+ [ProviderResolver] Inferred provider "google" from scopes
2658
+
2659
+ stdout | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should verify outlook → microsoft mapping works
2660
+ [ProviderResolver] Inferred provider "microsoft" from scopes
2661
+
2662
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle scopes without colons
2663
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2664
+
2665
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle inferred provider not in registry
2666
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "google" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2667
+
2668
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Fallback behavior (Priority 3) > should use first configured provider when oauthProvider not specified
2669
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2670
+
2671
+ stdout | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Provider name case sensitivity > should handle provider names case-insensitively in inference
2672
+ [ProviderResolver] Inferred provider "github" from scopes
2673
+
2674
+ stdout | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Multiple scopes with same provider > should handle multiple scopes from same provider
2675
+ [ProviderResolver] Inferred provider "github" from scopes
2676
+
2677
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Full handshake and tool execution flow > should complete full authentication and tool execution cycle
2678
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:z8Xdp-axN3zU9GmCG5LGfsdZLtE3F4DL0","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200304,"timestampFormatted":"2025-11-25T02:03:20.304Z"}
2679
+
2680
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Full handshake and tool execution flow > should complete full authentication and tool execution cycle
2681
+ [AUDIT] {"event":"tool_executed","data":{"tool":"greetingTool","sessionId":"b65e33431798a6e337b3e9a5105ecea2","timestamp":1764036200304},"timestamp":1764036200304,"timestampFormatted":"2025-11-25T02:03:20.304Z"}
2682
+
2683
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Session expiry handling > should handle expired sessions correctly
2684
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:z9c-J7N1-_M37saSMwyua-UMc1mm7M7t4","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200308,"timestampFormatted":"2025-11-25T02:03:20.308Z"}
2685
+
2686
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Key rotation flow > should handle key rotation and maintain functionality
2687
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zpho3f1zoie21ALskDupul9kRpNfTwSrf","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200308,"timestampFormatted":"2025-11-25T02:03:20.308Z"}
2688
+
2689
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Key rotation flow > should handle key rotation and maintain functionality
2690
+ [AUDIT] {"event":"keys_rotated","data":{"oldDid":"did:key:zpho3f1zoie21ALskDupul9kRpNfTwSrf","newDid":"did:key:zItjqP4O5vmfsEEFBB7dSDhFFWHs6vVOy","timestamp":1764036200308},"timestamp":1764036200308,"timestampFormatted":"2025-11-25T02:03:20.308Z"}
2691
+
2692
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Well-known endpoints > should provide identity discovery endpoints
2693
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zW_Tw4RCaHv0YuOXrtJAV-3p9WIruL_ex","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200310,"timestampFormatted":"2025-11-25T02:03:20.310Z"}
2694
+
2695
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Nonce replay protection > should prevent nonce reuse
2696
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zabmMWzbVTuhvY9lXJA52n_Oaq2GKn1JF","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200311,"timestampFormatted":"2025-11-25T02:03:20.311Z"}
2697
+
2698
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Error handling > should handle network errors gracefully
2699
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zYFbJRcSqNL0Igwnt41BmYTXCf3aJJycy","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200311,"timestampFormatted":"2025-11-25T02:03:20.311Z"}
2700
+
2701
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Error handling > should handle malformed DID documents
2702
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zwCRcxASWeJSETmKu7oiUK28xtMni4N85","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200311,"timestampFormatted":"2025-11-25T02:03:20.311Z"}
2703
+
2704
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Debug endpoint > should provide debug information in development
2705
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zMR7xNtisyHVcHgwhaQaE_bVz5lRouB9M","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200311,"timestampFormatted":"2025-11-25T02:03:20.311Z"}
2706
+
2707
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Debug endpoint > should be disabled in production
2708
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zjbz8BUiYI17Kg8ojojYlSlZXrOjn36S2","environment":"development","userDidGeneration":"disabled"},"timestamp":1764036200311,"timestampFormatted":"2025-11-25T02:03:20.311Z"}
2709
+
2710
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should use fallback config when API fails
2711
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network error' }
2712
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should allow unprotected tool calls
2713
+ [ToolProtectionService] Config loaded from API {
2714
+ source: 'api',
2715
+ toolCount: 1,
2716
+ protectedTools: [],
2717
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2718
+
2719
+ projectId: 'test-project',
2720
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Error handling in full flow > should handle tool protection service errors gracefully
2721
+ cacheTtlMs: 300000,
2722
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
2723
+ cacheExpiresAt: '2025-11-25T02:08:20.309Z'
2724
+ }
2725
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2726
+
2727
+ error: 'Network error',
2728
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should intercept protected tool calls without delegation
2729
+ [ToolProtectionService] Config loaded from API {
2730
+ cacheKey: 'config:tool-protections:test-project'
2731
+ source: 'api',
2732
+ toolCount: 1,
2733
+ }
2734
+ protectedTools: [ 'checkout' ],
2735
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2736
+
2737
+ projectId: 'test-project',
2738
+ cacheTtlMs: 300000,
2739
+ cacheExpiresAt: '2025-11-25T02:08:20.310Z'
2740
+ }
2741
+
2742
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should intercept protected tool calls without delegation
2743
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Error handling in full flow > should handle network timeouts
2744
+ [ToolProtectionService] Protection check {
2745
+ tool: 'checkout',
2746
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2747
+ found: true,
2748
+ isWildcard: false,
2749
+ requiresDelegation: true,
2750
+ availableTools: [ 'checkout' ]
2751
+ }
2752
+
2753
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should fetch tool protection config from AgentShield
2754
+ [ToolProtectionService] Config loaded from API {
2755
+ source: 'api',
2756
+ toolCount: 1,
2757
+ protectedTools: [ 'protected_tool' ],
2758
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2759
+ projectId: 'test-project',
2760
+ cacheTtlMs: 300000,
2761
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network timeout' }
2762
+ cacheExpiresAt: '2025-11-25T02:08:20.310Z'
2763
+ }
2764
+
2765
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should cache tool protection config
2766
+ [ToolProtectionService] Config loaded from API {
2767
+ source: 'api',
2768
+ toolCount: 1,
2769
+ protectedTools: [ 'tool1' ],
2770
+
2771
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2772
+ projectId: 'test-project',
2773
+ cacheTtlMs: 300000,
2774
+ cacheExpiresAt: '2025-11-25T02:08:20.312Z'
2775
+ }
2776
+
2777
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should share cache across multiple service instances
2778
+ [ToolProtectionService] Config loaded from API {
2779
+ source: 'api',
2780
+ toolCount: 1,
2781
+ protectedTools: [ 'tool1' ],
2782
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2783
+ projectId: 'test-project',
2784
+ cacheTtlMs: 300000,
2785
+ cacheExpiresAt: '2025-11-25T02:08:20.313Z'
2786
+ }
2787
+
2788
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should clear cache when needed
2789
+ [ToolProtectionService] Config loaded from API {
2790
+ source: 'api',
2791
+ toolCount: 1,
2792
+ protectedTools: [ 'tool1' ],
2793
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2794
+ projectId: 'test-project',
2795
+ cacheTtlMs: 300000,
2796
+ cacheExpiresAt: '2025-11-25T02:08:20.313Z'
2797
+ }
2798
+
2799
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should clear cache when needed
2800
+ [ToolProtectionService] Config loaded from API {
2801
+ source: 'api',
2802
+ toolCount: 1,
2803
+ protectedTools: [ 'tool1' ],
2804
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2805
+ projectId: 'test-project',
2806
+ cacheTtlMs: 300000,
2807
+ cacheExpiresAt: '2025-11-25T02:08:20.313Z'
2808
+ }
2809
+
2810
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Real-world e-commerce scenario > should handle complete e-commerce flow with tool protection
2811
+ [ToolProtectionService] Config loaded from API {
2812
+ source: 'api',
2813
+ toolCount: 3,
2814
+ protectedTools: [ 'add_to_cart', 'checkout' ],
2815
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2816
+ projectId: 'test-project',
2817
+ cacheTtlMs: 300000,
2818
+ cacheExpiresAt: '2025-11-25T02:08:20.314Z'
2819
+ }
2820
+
2821
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Real-world e-commerce scenario > should handle complete e-commerce flow with tool protection
2822
+ [ToolProtectionService] Protection check {
2823
+ tool: 'add_to_cart',
2824
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2825
+ found: true,
2826
+ isWildcard: false,
2827
+ requiresDelegation: true,
2828
+ availableTools: [ 'search_products', 'add_to_cart', 'checkout' ]
2829
+ }
2830
+
2831
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Concurrent operations > should handle concurrent cache operations
2832
+ [ToolProtectionService] Config loaded from API {
2833
+ source: 'api',
2834
+ toolCount: 1,
2835
+ protectedTools: [ 'tool1' ],
2836
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2837
+ projectId: 'test-project',
2838
+ cacheTtlMs: 300000,
2839
+ cacheExpiresAt: '2025-11-25T02:08:20.314Z'
2840
+ }
2841
+ [ToolProtectionService] Config loaded from API {
2842
+ source: 'api',
2843
+ toolCount: 1,
2844
+ protectedTools: [ 'tool1' ],
2845
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2846
+ projectId: 'test-project',
2847
+ cacheTtlMs: 300000,
2848
+ cacheExpiresAt: '2025-11-25T02:08:20.314Z'
2849
+ }
2850
+ [ToolProtectionService] Config loaded from API {
2851
+ source: 'api',
2852
+ toolCount: 1,
2853
+ protectedTools: [ 'tool1' ],
2854
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2855
+ projectId: 'test-project',
2856
+ cacheTtlMs: 300000,
2857
+ cacheExpiresAt: '2025-11-25T02:08:20.314Z'
2858
+ }
2859
+
2860
+ ✓ src/__tests__/services/provider-resolver-edge-cases.test.ts (19 tests | 1 skipped) 6ms
2861
+ ✓ src/__tests__/integration.test.ts (9 tests) 8ms
2862
+ ✓ src/__tests__/integration/full-flow.test.ts (21 tests) 10ms
2863
+ ✓ src/__tests__/providers/memory.test.ts (34 tests) 11ms
2864
+ stderr | src/services/__tests__/proof-verifier.test.ts > ProofVerifier Security > Signature Verification > should handle signature verification errors gracefully
2865
+ [CryptoService] Ed25519 verification error: Error: Crypto error
2866
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.test.ts:328:9
2867
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:157:11
2868
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
2869
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1636:20
2870
+ at new Promise (<anonymous>)
2871
+ at runWithTimeout (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1602:10)
2872
+ at runTest (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1309:12)
2873
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2874
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2875
+ at runSuite (file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:1468:8)
2876
+
2877
+ ✓ src/services/__tests__/proof-verifier.test.ts (21 tests) 36ms
2878
+ stdout | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should infer provider from github scope prefix
2879
+ [ProviderResolver] Inferred provider "github" from scopes
2880
+
2881
+ stdout | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should infer provider from gmail scope prefix (maps to google)
2882
+ [ProviderResolver] Inferred provider "google" from scopes
2883
+
2884
+ stderr | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should return null for ambiguous scopes
2885
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2886
+
2887
+ ✓ src/services/__tests__/provider-resolver.test.ts (8 tests) 8ms
2888
+ stdout | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > Backward Compatibility > Phase 1 tools (no oauthProvider) > should work with Phase 1 tools that don't specify oauthProvider
2889
+ [ToolProtectionService] Config loaded from API {
2890
+ source: 'api',
2891
+ toolCount: 1,
2892
+ protectedTools: [ 'phase1_tool' ],
2893
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2894
+ projectId: 'none',
2895
+ cacheTtlMs: 300000,
2896
+ cacheExpiresAt: '2025-11-25T02:08:20.406Z'
2897
+ }
2898
+
2899
+ stdout | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > Backward Compatibility > Old API endpoint format > should still support old endpoint format (tools array)
2900
+ [ToolProtectionService] Config loaded from API {
2901
+ source: 'api',
2902
+ toolCount: 1,
2903
+ protectedTools: [ 'old_tool' ],
2904
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2905
+ projectId: 'none',
2906
+ cacheTtlMs: 300000,
2907
+ cacheExpiresAt: '2025-11-25T02:08:20.438Z'
2908
+ }
2909
+
2910
+ stdout | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > Backward Compatibility > Old API endpoint format > should still support old endpoint format (tools object)
2911
+ [ToolProtectionService] Config loaded from API {
2912
+ source: 'api',
2913
+ toolCount: 1,
2914
+ protectedTools: [ 'old_tool' ],
2915
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2916
+ projectId: 'none',
2917
+ cacheTtlMs: 300000,
2918
+ cacheExpiresAt: '2025-11-25T02:08:20.439Z'
2919
+ }
2920
+ stderr | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > No Regressions > Phase 1 OAuth flow > should still work with Phase 1 OAuth flow (no oauthProvider)
2921
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2922
+
2923
+
2924
+ stdout | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > Backward Compatibility > snake_case field names > should still support snake_case field names
2925
+ [ToolProtectionService] Config loaded from API {
2926
+ source: 'api',
2927
+ toolCount: 1,
2928
+ protectedTools: [ 'tool_with_snake_case' ],
2929
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2930
+ projectId: 'test-project-123',
2931
+ cacheTtlMs: 300000,
2932
+ cacheExpiresAt: '2025-11-25T02:08:20.439Z'
2933
+ }
2934
+
2935
+ stdout | src/__tests__/regression/phase2-regression.test.ts > Phase 2 Regression Tests > Mixed Phase 1 and Phase 2 tools > should handle mix of Phase 1 and Phase 2 tools in same project
2936
+ [ToolProtectionService] Config loaded from API {
2937
+ source: 'api',
2938
+ toolCount: 2,
2939
+ protectedTools: [ 'phase1_tool', 'phase2_tool' ],
2940
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2941
+ projectId: 'test-project-123',
2942
+ cacheTtlMs: 300000,
2943
+ cacheExpiresAt: '2025-11-25T02:08:20.439Z'
2944
+ }
2945
+
2946
+ ✓ src/__tests__/regression/phase2-regression.test.ts (12 tests) 35ms
2947
+ ✓ src/__tests__/runtime/proof-client-did.test.ts (17 tests) 21ms
2948
+ ✓ src/__tests__/runtime/base-extensions.test.ts (38 tests) 23ms
2949
+ stderr | src/services/__tests__/provider-resolution.integration.test.ts > Provider Resolution Integration > Backward compatibility > should work with Phase 1 tools (no oauthProvider field)
2950
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2951
+
2952
+ ✓ src/services/__tests__/provider-resolution.integration.test.ts (6 tests) 3ms
2953
+ ✓ src/delegation/__tests__/bitstring.test.ts (30 tests) 26ms
2954
+ ✓ src/__tests__/providers/base.test.ts (14 tests) 5ms
2955
+ ✓ src/delegation/storage/__tests__/memory-graph-storage.test.ts (27 tests) 4ms
2956
+ ✓ src/services/__tests__/batch-delegation.service.test.ts (11 tests) 3ms
2957
+ ✓ src/compliance/__tests__/schema-verifier.test.ts (30 tests) 4ms
2958
+ ✓ src/__tests__/runtime/audit-logger.test.ts (9 tests) 2ms
2959
+ ✓ src/__tests__/runtime/delegation-flow.test.ts (4 tests) 3ms
2960
+ ✓ src/services/__tests__/oauth-provider-registry.test.ts (9 tests) 3ms
2961
+ ✓ src/delegation/__tests__/utils.test.ts (28 tests) 3ms
2962
+ ✓ src/delegation/storage/__tests__/memory-statuslist-storage.test.ts (14 tests) 5ms
2963
+ ✓ src/utils/__tests__/did-helpers.test.ts (11 tests) 4ms
2964
+ ✓ src/__tests__/config/provider-runtime-config.test.ts (9 tests) 2ms
2965
+ ✓ src/delegation/__tests__/audience-validator.test.ts (5 tests) 1ms
2966
+ ↓ src/__tests__/delegation-e2e.test.ts (14 tests | 14 skipped)
2967
+ ✓ src/__tests__/index.test.ts (4 tests) 2ms
2968
+
2969
+ Test Files 43 passed | 1 skipped (44)
2970
+ Tests 876 passed | 16 skipped (892)
2971
+ Start at 20:03:15
2972
+ Duration 5.44s (transform 10.64s, setup 0ms, collect 18.02s, tests 2.69s, environment 15ms, prepare 2.18s)
2973
+