@kya-os/mcp-i-core 1.2.3-canary.7 → 1.3.1

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