@kya-os/mcp-i-core 1.2.3-canary.7 → 1.3.0-canary.clientinfo.20251126003544

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