@kya-os/mcp-i-core 1.2.2-canary.25 → 1.2.2-canary.26

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 (147) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.turbo/turbo-test$colon$coverage.log +3756 -0
  4. package/.turbo/turbo-test.log +2398 -0
  5. package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
  6. package/Composer 3.md +615 -0
  7. package/GPT-5.md +1169 -0
  8. package/OPUS-plan.md +352 -0
  9. package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
  10. package/PHASE_3_SUMMARY.md +317 -0
  11. package/PHASE_4.1.3_SUMMARY.md +428 -0
  12. package/PHASE_4.1_COMPLETE.md +525 -0
  13. package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
  14. package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
  15. package/TEST_PLAN.md +571 -0
  16. package/dist/services/authorization/authorization-registry.d.ts +29 -0
  17. package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
  18. package/dist/services/authorization/authorization-registry.js +57 -0
  19. package/dist/services/authorization/authorization-registry.js.map +1 -0
  20. package/dist/services/authorization/types.d.ts +53 -0
  21. package/dist/services/authorization/types.d.ts.map +1 -0
  22. package/dist/services/authorization/types.js +10 -0
  23. package/dist/services/authorization/types.js.map +1 -0
  24. package/docs/API_REFERENCE.md +1362 -0
  25. package/docs/COMPLIANCE_MATRIX.md +691 -0
  26. package/docs/STATUSLIST2021_GUIDE.md +696 -0
  27. package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
  28. package/package.json +20 -64
  29. package/scripts/audit-compliance.ts +724 -0
  30. package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
  31. package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
  32. package/src/__tests__/delegation-e2e.test.ts +690 -0
  33. package/src/__tests__/identity/user-did-manager.test.ts +213 -0
  34. package/src/__tests__/index.test.ts +56 -0
  35. package/src/__tests__/integration/full-flow.test.ts +776 -0
  36. package/src/__tests__/integration.test.ts +281 -0
  37. package/src/__tests__/providers/base.test.ts +173 -0
  38. package/src/__tests__/providers/memory.test.ts +319 -0
  39. package/src/__tests__/regression/phase2-regression.test.ts +427 -0
  40. package/src/__tests__/runtime/audit-logger.test.ts +154 -0
  41. package/src/__tests__/runtime/base-extensions.test.ts +593 -0
  42. package/src/__tests__/runtime/base.test.ts +869 -0
  43. package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
  44. package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
  45. package/src/__tests__/runtime/route-interception.test.ts +686 -0
  46. package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
  47. package/src/__tests__/services/agentshield-integration.test.ts +784 -0
  48. package/src/__tests__/services/provider-resolver-edge-cases.test.ts +487 -0
  49. package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
  50. package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
  51. package/src/__tests__/utils/mock-providers.ts +340 -0
  52. package/src/cache/oauth-config-cache.d.ts +69 -0
  53. package/src/cache/oauth-config-cache.d.ts.map +1 -0
  54. package/src/cache/oauth-config-cache.js +71 -0
  55. package/src/cache/oauth-config-cache.js.map +1 -0
  56. package/src/cache/oauth-config-cache.ts +123 -0
  57. package/src/cache/tool-protection-cache.ts +171 -0
  58. package/src/compliance/EXAMPLE.md +412 -0
  59. package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
  60. package/src/compliance/index.ts +8 -0
  61. package/src/compliance/schema-registry.ts +460 -0
  62. package/src/compliance/schema-verifier.ts +708 -0
  63. package/src/config/__tests__/remote-config.spec.ts +268 -0
  64. package/src/config/remote-config.ts +174 -0
  65. package/src/config.ts +309 -0
  66. package/src/delegation/__tests__/audience-validator.test.ts +112 -0
  67. package/src/delegation/__tests__/bitstring.test.ts +346 -0
  68. package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
  69. package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
  70. package/src/delegation/__tests__/utils.test.ts +152 -0
  71. package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
  72. package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
  73. package/src/delegation/audience-validator.ts +52 -0
  74. package/src/delegation/bitstring.ts +278 -0
  75. package/src/delegation/cascading-revocation.ts +370 -0
  76. package/src/delegation/delegation-graph.ts +299 -0
  77. package/src/delegation/index.ts +14 -0
  78. package/src/delegation/statuslist-manager.ts +353 -0
  79. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
  80. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
  81. package/src/delegation/storage/index.ts +9 -0
  82. package/src/delegation/storage/memory-graph-storage.ts +178 -0
  83. package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
  84. package/src/delegation/utils.ts +42 -0
  85. package/src/delegation/vc-issuer.ts +232 -0
  86. package/src/delegation/vc-verifier.ts +568 -0
  87. package/src/identity/idp-token-resolver.ts +147 -0
  88. package/src/identity/idp-token-storage.interface.ts +59 -0
  89. package/src/identity/user-did-manager.ts +370 -0
  90. package/src/index.ts +260 -0
  91. package/src/providers/base.d.ts +91 -0
  92. package/src/providers/base.d.ts.map +1 -0
  93. package/src/providers/base.js +38 -0
  94. package/src/providers/base.js.map +1 -0
  95. package/src/providers/base.ts +96 -0
  96. package/src/providers/memory.ts +142 -0
  97. package/src/runtime/audit-logger.ts +39 -0
  98. package/src/runtime/base.ts +1329 -0
  99. package/src/services/__tests__/access-control.integration.test.ts +443 -0
  100. package/src/services/__tests__/access-control.service.test.ts +970 -0
  101. package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
  102. package/src/services/__tests__/crypto.service.test.ts +531 -0
  103. package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
  104. package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
  105. package/src/services/__tests__/proof-verifier.test.ts +489 -0
  106. package/src/services/__tests__/provider-resolution.integration.test.ts +198 -0
  107. package/src/services/__tests__/provider-resolver.test.ts +217 -0
  108. package/src/services/__tests__/storage.service.test.ts +358 -0
  109. package/src/services/access-control.service.ts +877 -0
  110. package/src/services/authorization/authorization-registry.ts +66 -0
  111. package/src/services/authorization/types.ts +71 -0
  112. package/src/services/batch-delegation.service.ts +137 -0
  113. package/src/services/crypto.service.ts +302 -0
  114. package/src/services/errors.ts +76 -0
  115. package/src/services/index.ts +9 -0
  116. package/src/services/oauth-config.service.d.ts +53 -0
  117. package/src/services/oauth-config.service.d.ts.map +1 -0
  118. package/src/services/oauth-config.service.js +113 -0
  119. package/src/services/oauth-config.service.js.map +1 -0
  120. package/src/services/oauth-config.service.ts +166 -0
  121. package/src/services/oauth-provider-registry.d.ts +57 -0
  122. package/src/services/oauth-provider-registry.d.ts.map +1 -0
  123. package/src/services/oauth-provider-registry.js +73 -0
  124. package/src/services/oauth-provider-registry.js.map +1 -0
  125. package/src/services/oauth-provider-registry.ts +123 -0
  126. package/src/services/oauth-service.ts +510 -0
  127. package/src/services/oauth-token-retrieval.service.ts +245 -0
  128. package/src/services/proof-verifier.ts +478 -0
  129. package/src/services/provider-resolver.d.ts +48 -0
  130. package/src/services/provider-resolver.d.ts.map +1 -0
  131. package/src/services/provider-resolver.js +106 -0
  132. package/src/services/provider-resolver.js.map +1 -0
  133. package/src/services/provider-resolver.ts +144 -0
  134. package/src/services/provider-validator.ts +170 -0
  135. package/src/services/storage.service.ts +566 -0
  136. package/src/services/tool-context-builder.ts +172 -0
  137. package/src/services/tool-protection.service.ts +798 -0
  138. package/src/types/oauth-required-error.ts +63 -0
  139. package/src/types/tool-protection.ts +155 -0
  140. package/src/utils/__tests__/did-helpers.test.ts +101 -0
  141. package/src/utils/base64.ts +148 -0
  142. package/src/utils/cors.ts +83 -0
  143. package/src/utils/did-helpers.ts +150 -0
  144. package/src/utils/index.ts +8 -0
  145. package/src/utils/storage-keys.ts +278 -0
  146. package/tsconfig.json +21 -0
  147. package/vitest.config.ts +56 -0
@@ -0,0 +1,2398 @@
1
+
2
+ > @kya-os/mcp-i-core@1.2.2-canary.24 test /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core
3
+ > vitest run
4
+
5
+ ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
6
+
7
+ package.json:32:6:
8
+ 32 │ "types": "./dist/utils/did-helpers.d.ts"
9
+ ╵ ~~~~~~~
10
+
11
+ The "import" condition comes earlier and will be used for all "import" statements:
12
+
13
+ package.json:31:6:
14
+ 31 │ "import": "./dist/utils/did-helpers.js",
15
+ ╵ ~~~~~~~~
16
+
17
+ The "require" condition comes earlier and will be used for all "require" calls:
18
+
19
+ package.json:30:6:
20
+ 30 │ "require": "./dist/utils/did-helpers.js",
21
+ ╵ ~~~~~~~~~
22
+
23
+
24
+ RUN v4.0.5 /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core
25
+
26
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > API Authentication > should use X-API-Key header for new endpoint
27
+ [ToolProtectionService] Config loaded from API {
28
+ source: 'api',
29
+ toolCount: 0,
30
+ protectedTools: [],
31
+ agentDid: 'did:key:z6MkhaXgBZDv...',
32
+ projectId: 'test-project-123',
33
+ cacheTtlMs: 300000,
34
+ cacheExpiresAt: '2025-11-22T07:00:54.411Z'
35
+ }
36
+
37
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > API Authentication > should use Authorization Bearer header for old endpoint
38
+ [ToolProtectionService] Config loaded from API {
39
+ source: 'api',
40
+ toolCount: 0,
41
+ protectedTools: [],
42
+ agentDid: 'did:key:z6MkhaXgBZDv...',
43
+ projectId: 'none',
44
+ cacheTtlMs: 300000,
45
+ cacheExpiresAt: '2025-11-22T07:00:54.414Z'
46
+ }
47
+
48
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should use project-scoped endpoint when projectId is available
49
+ [ToolProtectionService] Config loaded from API {
50
+ source: 'api',
51
+ toolCount: 0,
52
+ protectedTools: [],
53
+ agentDid: 'did:key:z6MkhaXgBZDv...',
54
+ projectId: 'test-project-123',
55
+ cacheTtlMs: 300000,
56
+ cacheExpiresAt: '2025-11-22T07:00:54.415Z'
57
+ }
58
+
59
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should use agent-scoped endpoint when projectId is not available
60
+ [ToolProtectionService] Config loaded from API {
61
+ source: 'api',
62
+ toolCount: 0,
63
+ protectedTools: [],
64
+ agentDid: 'did:key:z6MkhaXgBZDv...',
65
+ projectId: 'none',
66
+ cacheTtlMs: 300000,
67
+ cacheExpiresAt: '2025-11-22T07:00:54.415Z'
68
+ }
69
+
70
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should encode projectId in URL
71
+ [ToolProtectionService] Config loaded from API {
72
+ source: 'api',
73
+ toolCount: 0,
74
+ protectedTools: [],
75
+ agentDid: 'did:key:z6MkhaXgBZDv...',
76
+ projectId: 'project/with/special-chars',
77
+ cacheTtlMs: 300000,
78
+ cacheExpiresAt: '2025-11-22T07:00:54.416Z'
79
+ }
80
+
81
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Endpoint Selection > should encode agent DID in URL
82
+ [ToolProtectionService] Config loaded from API {
83
+ source: 'api',
84
+ toolCount: 0,
85
+ protectedTools: [],
86
+ agentDid: 'did:key:z6MkhaXgBZDv...',
87
+ projectId: 'none',
88
+ cacheTtlMs: 300000,
89
+ cacheExpiresAt: '2025-11-22T07:00:54.416Z'
90
+ }
91
+
92
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Error Handling > should handle network timeout
93
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network timeout' }
94
+
95
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle new endpoint format (toolProtections object)
96
+ [ToolProtectionService] Config loaded from API {
97
+ source: 'api',
98
+ toolCount: 2,
99
+ protectedTools: [ 'checkout' ],
100
+ agentDid: 'did:key:z6MkhaXgBZDv...',
101
+ projectId: 'test-project-123',
102
+ cacheTtlMs: 300000,
103
+ cacheExpiresAt: '2025-11-22T07:00:54.416Z'
104
+ }
105
+
106
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle old endpoint format (tools array)
107
+ [ToolProtectionService] Config loaded from API {
108
+ source: 'api',
109
+ toolCount: 2,
110
+ protectedTools: [ 'checkout' ],
111
+ agentDid: 'did:key:z6MkhaXgBZDv...',
112
+ projectId: 'none',
113
+ cacheTtlMs: 300000,
114
+ cacheExpiresAt: '2025-11-22T07:00:54.416Z'
115
+ }
116
+
117
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle old endpoint format (tools object)
118
+ [ToolProtectionService] Config loaded from API {
119
+ source: 'api',
120
+ toolCount: 2,
121
+ protectedTools: [ 'checkout' ],
122
+ agentDid: 'did:key:z6MkhaXgBZDv...',
123
+ projectId: 'none',
124
+ cacheTtlMs: 300000,
125
+ cacheExpiresAt: '2025-11-22T07:00:54.416Z'
126
+ }
127
+
128
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle snake_case field names
129
+ [ToolProtectionService] Config loaded from API {
130
+ source: 'api',
131
+ toolCount: 1,
132
+ protectedTools: [ 'tool1' ],
133
+ agentDid: 'did:key:z6MkhaXgBZDv...',
134
+ projectId: 'test-project-123',
135
+ cacheTtlMs: 300000,
136
+ cacheExpiresAt: '2025-11-22T07:00:54.417Z'
137
+ }
138
+
139
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should handle camelCase field names
140
+ [ToolProtectionService] Config loaded from API {
141
+ source: 'api',
142
+ toolCount: 1,
143
+ protectedTools: [ 'tool1' ],
144
+ agentDid: 'did:key:z6MkhaXgBZDv...',
145
+ projectId: 'test-project-123',
146
+ cacheTtlMs: 300000,
147
+ cacheExpiresAt: '2025-11-22T07:00:54.417Z'
148
+ }
149
+
150
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Response Format Compatibility > should prefer camelCase over snake_case when both present
151
+ [ToolProtectionService] Config loaded from API {
152
+ source: 'api',
153
+ toolCount: 1,
154
+ protectedTools: [ 'tool1' ],
155
+ agentDid: 'did:key:z6MkhaXgBZDv...',
156
+ projectId: 'test-project-123',
157
+ cacheTtlMs: 300000,
158
+ cacheExpiresAt: '2025-11-22T07:00:54.417Z'
159
+ }
160
+
161
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should cache successful API responses
162
+ [ToolProtectionService] Config loaded from API {
163
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Fallback Behavior > should cache fallback config
164
+ source: 'api',
165
+ toolCount: 1,
166
+ protectedTools: [ 'tool1' ],
167
+ agentDid: 'did:key:z6MkhaXgBZDv...',
168
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network error' }
169
+
170
+ projectId: 'test-project-123',
171
+ cacheTtlMs: 300000,
172
+ cacheExpiresAt: '2025-11-22T07:00:54.419Z'
173
+ }
174
+
175
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should respect cache TTL
176
+ [ToolProtectionService] Config loaded from API {
177
+ source: 'api',
178
+ toolCount: 0,
179
+ protectedTools: [],
180
+ agentDid: 'did:key:z6MkhaXgBZDv...',
181
+ projectId: 'test-project-123',
182
+ cacheTtlMs: 1000,
183
+ cacheExpiresAt: '2025-11-22T06:55:55.419Z'
184
+ }
185
+
186
+ 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
187
+ [ToolProtectionService] Config loaded from API {
188
+ source: 'api',
189
+ toolCount: 1,
190
+ protectedTools: [ 'phase1_tool' ],
191
+ agentDid: 'did:key:z6MkhaXgBZDv...',
192
+ projectId: 'none',
193
+ cacheTtlMs: 300000,
194
+ cacheExpiresAt: '2025-11-22T07:00:54.420Z'
195
+ }
196
+
197
+ 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)
198
+ [ToolProtectionService] Config loaded from API {
199
+ source: 'api',
200
+ toolCount: 1,
201
+ protectedTools: [ 'old_tool' ],
202
+ agentDid: 'did:key:z6MkhaXgBZDv...',
203
+ projectId: 'none',
204
+ cacheTtlMs: 300000,
205
+ cacheExpiresAt: '2025-11-22T07:00:54.425Z'
206
+ }
207
+
208
+ 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)
209
+ [ToolProtectionService] Config loaded from API {
210
+ source: 'api',
211
+ toolCount: 1,
212
+ protectedTools: [ 'old_tool' ],
213
+ agentDid: 'did:key:z6MkhaXgBZDv...',
214
+ projectId: 'none',
215
+ cacheTtlMs: 300000,
216
+ cacheExpiresAt: '2025-11-22T07:00:54.425Z'
217
+ }
218
+
219
+ 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)
220
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
221
+ 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
222
+ [ToolProtectionService] Config loaded from API {
223
+
224
+ source: 'api',
225
+ toolCount: 1,
226
+ protectedTools: [ 'tool_with_snake_case' ],
227
+ agentDid: 'did:key:z6MkhaXgBZDv...',
228
+ projectId: 'test-project-123',
229
+ cacheTtlMs: 300000,
230
+ cacheExpiresAt: '2025-11-22T07:00:54.425Z'
231
+ }
232
+
233
+ 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
234
+ [ToolProtectionService] Config loaded from API {
235
+ source: 'api',
236
+ toolCount: 2,
237
+ protectedTools: [ 'phase1_tool', 'phase2_tool' ],
238
+ agentDid: 'did:key:z6MkhaXgBZDv...',
239
+ projectId: 'test-project-123',
240
+ cacheTtlMs: 300000,
241
+ cacheExpiresAt: '2025-11-22T07:00:54.426Z'
242
+ }
243
+
244
+ ✓ src/__tests__/regression/phase2-regression.test.ts (12 tests) 8ms
245
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should prefer Redis over KV when both are configured
246
+ [StorageService] Failed to connect to Redis, falling back to memory: Redis package not available
247
+
248
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should prefer Redis over KV when both are configured
249
+ [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'
250
+
251
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should fall back to memory when Redis connection fails
252
+ [StorageService] Failed to connect to Redis, falling back to memory: Redis package not available
253
+
254
+ stderr | src/services/__tests__/storage.service.test.ts > StorageService > createStorageProviders > should use KV namespace when provided
255
+ [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'
256
+
257
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should submit proofs successfully
258
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
259
+ correlationId: 'c15ae448-52f1-4753-93d6-1f0d60c8fa0b',
260
+ status: 200,
261
+ statusText: '',
262
+ headers: { 'content-type': 'application/json' },
263
+ responseTextLength: 100,
264
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
265
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
266
+ }
267
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
268
+ correlationId: 'c15ae448-52f1-4753-93d6-1f0d60c8fa0b',
269
+ status: 200,
270
+ responseDataType: 'object',
271
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
272
+ responseData: '{\n' +
273
+ ' "success": true,\n' +
274
+ ' "accepted": 1,\n' +
275
+ ' "rejected": 0,\n' +
276
+ ' "outcomes": {\n' +
277
+ ' "success": 1,\n' +
278
+ ' "failed": 0,\n' +
279
+ ' "blocked": 0,\n' +
280
+ ' "error": 0\n' +
281
+ ' }\n' +
282
+ '}'
283
+ }
284
+ [AccessControl] Raw response received: {
285
+ "success": true,
286
+ "accepted": 1,
287
+ "rejected": 0,
288
+ "outcomes": {
289
+ "success": 1,
290
+ "failed": 0,
291
+ "blocked": 0,
292
+ "error": 0
293
+ }
294
+ }
295
+
296
+ ✓ src/services/__tests__/storage.service.test.ts (17 tests) 16ms
297
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle all_proofs_rejected error gracefully
298
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
299
+ correlationId: '3e395c63-242a-4f2a-abf1-9986bab09084',
300
+ status: 400,
301
+ statusText: '',
302
+ headers: { 'content-type': 'application/json' },
303
+ responseTextLength: 209,
304
+ 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"}}]}}}',
305
+ 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"}}]}}}'
306
+ }
307
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
308
+ correlationId: '3e395c63-242a-4f2a-abf1-9986bab09084',
309
+ status: 400,
310
+ responseDataType: 'object',
311
+ responseDataKeys: [ 'success', 'error' ],
312
+ responseData: '{\n' +
313
+ ' "success": false,\n' +
314
+ ' "error": {\n' +
315
+ ' "code": "all_proofs_rejected",\n' +
316
+ ' "message": "All proofs rejected",\n' +
317
+ ' "details": {\n' +
318
+ ' "rejected": 1,\n' +
319
+ ' "errors": [\n' +
320
+ ' {\n' +
321
+ ' "proof_index": 0,\n' +
322
+ ' "error": {\n' +
323
+ ' "code": "invalid_signature",\n' +
324
+ ' "message": "Invalid signature"\n' +
325
+ ' }\n' +
326
+ ' }\n' +
327
+ ' ]\n' +
328
+ ' }\n' +
329
+ ' }\n' +
330
+ '}'
331
+ }
332
+
333
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle wrapped response format
334
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
335
+ correlationId: '763cbfba-61ff-4bad-8d57-93789f897191',
336
+ status: 200,
337
+ statusText: '',
338
+ headers: { 'content-type': 'application/json' },
339
+ responseTextLength: 206,
340
+ 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-22T06:55:54.452Z"}}',
341
+ 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-22T06:55:54.452Z"}}'
342
+ }
343
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
344
+ correlationId: '763cbfba-61ff-4bad-8d57-93789f897191',
345
+ status: 200,
346
+ responseDataType: 'object',
347
+ responseDataKeys: [ 'success', 'data', 'metadata' ],
348
+ responseData: '{\n' +
349
+ ' "success": true,\n' +
350
+ ' "data": {\n' +
351
+ ' "success": true,\n' +
352
+ ' "accepted": 1,\n' +
353
+ ' "rejected": 0,\n' +
354
+ ' "outcomes": {\n' +
355
+ ' "success": 1,\n' +
356
+ ' "failed": 0,\n' +
357
+ ' "blocked": 0,\n' +
358
+ ' "error": 0\n' +
359
+ ' }\n' +
360
+ ' },\n' +
361
+ ' "metadata": {\n' +
362
+ ' "requestId": "test-request-id",\n' +
363
+ ' "timestamp": "2025-11-22T06:55:54.452Z"\n' +
364
+ ' }\n' +
365
+ '}'
366
+ }
367
+ [AccessControl] Raw response received: {
368
+ "success": true,
369
+ "data": {
370
+ "success": true,
371
+ "accepted": 1,
372
+ "rejected": 0,
373
+ "outcomes": {
374
+ "success": 1,
375
+ "failed": 0,
376
+ "blocked": 0,
377
+ "error": 0
378
+ }
379
+ },
380
+ "metadata": {
381
+ "requestId": "test-request-id",
382
+ "timestamp": "2025-11-22T06:55:54.452Z"
383
+ }
384
+ }
385
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE: {
386
+ correlationId: '763cbfba-61ff-4bad-8d57-93789f897191',
387
+ dataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
388
+ hasAccepted: true,
389
+ hasRejected: true,
390
+ hasOutcomes: true,
391
+ hasErrors: false,
392
+ acceptedType: 'number',
393
+ rejectedType: 'number',
394
+ outcomesType: 'object',
395
+ errorsType: 'undefined',
396
+ errorsIsArray: false,
397
+ fullData: '{\n' +
398
+ ' "success": true,\n' +
399
+ ' "accepted": 1,\n' +
400
+ ' "rejected": 0,\n' +
401
+ ' "outcomes": {\n' +
402
+ ' "success": 1,\n' +
403
+ ' "failed": 0,\n' +
404
+ ' "blocked": 0,\n' +
405
+ ' "error": 0\n' +
406
+ ' }\n' +
407
+ '}'
408
+ }
409
+
410
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
411
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
412
+ correlationId: '83067c19-4a75-4487-8c41-84154a231b4a',
413
+ status: 200,
414
+ statusText: '',
415
+ headers: { 'content-type': 'application/json' },
416
+ responseTextLength: 42,
417
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0}',
418
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0}'
419
+ }
420
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
421
+ correlationId: '83067c19-4a75-4487-8c41-84154a231b4a',
422
+ status: 200,
423
+ responseDataType: 'object',
424
+ responseDataKeys: [ 'success', 'accepted', 'rejected' ],
425
+ responseData: '{\n "success": true,\n "accepted": 1,\n "rejected": 0\n}'
426
+ }
427
+ [AccessControl] Raw response received: {
428
+ "success": true,
429
+ "accepted": 1,
430
+ "rejected": 0
431
+ }
432
+
433
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
434
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
435
+ correlationId: '04630779-2ff2-4a2d-956c-324823bc9fbc',
436
+ status: 200,
437
+ statusText: '',
438
+ headers: { 'content-type': 'application/json' },
439
+ responseTextLength: 100,
440
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
441
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
442
+ }
443
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
444
+ correlationId: '04630779-2ff2-4a2d-956c-324823bc9fbc',
445
+ status: 200,
446
+ responseDataType: 'object',
447
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
448
+ responseData: '{\n' +
449
+ ' "success": true,\n' +
450
+ ' "accepted": 1,\n' +
451
+ ' "rejected": 0,\n' +
452
+ ' "outcomes": {\n' +
453
+ ' "success": 1,\n' +
454
+ ' "failed": 0,\n' +
455
+ ' "blocked": 0,\n' +
456
+ ' "error": 0\n' +
457
+ ' }\n' +
458
+ '}'
459
+ }
460
+ [AccessControl] Raw response received: {
461
+ "success": true,
462
+ "accepted": 1,
463
+ "rejected": 0,
464
+ "outcomes": {
465
+ "success": 1,
466
+ "failed": 0,
467
+ "blocked": 0,
468
+ "error": 0
469
+ }
470
+ }
471
+
472
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle response with missing outcomes field (outcomes is optional)
473
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
474
+ correlationId: '3dc1bfbc-39a0-41f7-82d3-c87e0093ab55',
475
+ status: 200,
476
+ statusText: '',
477
+ headers: { 'content-type': 'application/json' },
478
+ responseTextLength: 56,
479
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{}}',
480
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{}}'
481
+ }
482
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
483
+ correlationId: '3dc1bfbc-39a0-41f7-82d3-c87e0093ab55',
484
+ status: 200,
485
+ responseDataType: 'object',
486
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
487
+ responseData: '{\n "success": true,\n "accepted": 1,\n "rejected": 0,\n "outcomes": {}\n}'
488
+ }
489
+ [AccessControl] Raw response received: {
490
+ "success": true,
491
+ "accepted": 1,
492
+ "rejected": 0,
493
+ "outcomes": {}
494
+ }
495
+
496
+ stderr | src/services/__tests__/access-control.service.test.ts > AccessControlApiService > submitProofs > should handle wrapped response with invalid data structure
497
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
498
+ correlationId: 'c8ced6df-58ca-44ec-b9db-c3973e9d7505',
499
+ status: 200,
500
+ statusText: '',
501
+ headers: { 'content-type': 'application/json' },
502
+ responseTextLength: 52,
503
+ responseTextPreview: '{"success":true,"data":{"message":"Invalid format"}}',
504
+ fullResponseText: '{"success":true,"data":{"message":"Invalid format"}}'
505
+ }
506
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
507
+ correlationId: 'c8ced6df-58ca-44ec-b9db-c3973e9d7505',
508
+ status: 200,
509
+ responseDataType: 'object',
510
+ responseDataKeys: [ 'success', 'data' ],
511
+ responseData: '{\n "success": true,\n "data": {\n "message": "Invalid format"\n }\n}'
512
+ }
513
+ [AccessControl] Raw response received: {
514
+ "success": true,
515
+ "data": {
516
+ "message": "Invalid format"
517
+ }
518
+ }
519
+ [AccessControl] 🔍 DATA OBJECT STRUCTURE: {
520
+ correlationId: 'c8ced6df-58ca-44ec-b9db-c3973e9d7505',
521
+ dataKeys: [ 'message' ],
522
+ hasAccepted: false,
523
+ hasRejected: false,
524
+ hasOutcomes: false,
525
+ hasErrors: false,
526
+ acceptedType: 'undefined',
527
+ rejectedType: 'undefined',
528
+ outcomesType: 'undefined',
529
+ errorsType: 'undefined',
530
+ errorsIsArray: false,
531
+ fullData: '{\n "message": "Invalid format"\n}'
532
+ }
533
+ [AccessControl] Wrapped response validation failed {
534
+ correlationId: 'c8ced6df-58ca-44ec-b9db-c3973e9d7505',
535
+ zodErrors: [
536
+ {
537
+ code: 'invalid_type',
538
+ expected: 'number',
539
+ received: 'undefined',
540
+ path: [Array],
541
+ message: 'Required'
542
+ },
543
+ {
544
+ code: 'invalid_type',
545
+ expected: 'number',
546
+ received: 'undefined',
547
+ path: [Array],
548
+ message: 'Required'
549
+ }
550
+ ],
551
+ zodErrorDetails: '[\n' +
552
+ ' {\n' +
553
+ ' "code": "invalid_type",\n' +
554
+ ' "expected": "number",\n' +
555
+ ' "received": "undefined",\n' +
556
+ ' "path": [\n' +
557
+ ' "accepted"\n' +
558
+ ' ],\n' +
559
+ ' "message": "Required"\n' +
560
+ ' },\n' +
561
+ ' {\n' +
562
+ ' "code": "invalid_type",\n' +
563
+ ' "expected": "number",\n' +
564
+ ' "received": "undefined",\n' +
565
+ ' "path": [\n' +
566
+ ' "rejected"\n' +
567
+ ' ],\n' +
568
+ ' "message": "Required"\n' +
569
+ ' }\n' +
570
+ ']',
571
+ dataToValidate: '{\n "message": "Invalid format"\n}',
572
+ dataWithSuccess: '{\n "message": "Invalid format",\n "success": true\n}',
573
+ dataKeys: [ 'message' ],
574
+ originalResponse: '{\n "success": true,\n "data": {\n "message": "Invalid format"\n }\n}'
575
+ }
576
+ [AccessControl] Original wrapped response: {
577
+ "success": true,
578
+ "data": {
579
+ "message": "Invalid format"
580
+ }
581
+ }
582
+ [AccessControl] ❌ ZOD VALIDATION FAILED - 2 error(s):
583
+ [AccessControl] Error 1: {
584
+ path: 'accepted',
585
+ message: 'Required',
586
+ code: 'invalid_type',
587
+ received: 'undefined',
588
+ expected: 'number'
589
+ }
590
+ [AccessControl] Error 2: {
591
+ path: 'rejected',
592
+ message: 'Required',
593
+ code: 'invalid_type',
594
+ received: 'undefined',
595
+ expected: 'number'
596
+ }
597
+ [AccessControl] ❌ Full ZOD errors JSON: [
598
+ {
599
+ "code": "invalid_type",
600
+ "expected": "number",
601
+ "received": "undefined",
602
+ "path": [
603
+ "accepted"
604
+ ],
605
+ "message": "Required"
606
+ },
607
+ {
608
+ "code": "invalid_type",
609
+ "expected": "number",
610
+ "received": "undefined",
611
+ "path": [
612
+ "rejected"
613
+ ],
614
+ "message": "Required"
615
+ }
616
+ ]
617
+ [AccessControl] Response validation failed {
618
+ zodErrors: [
619
+ {
620
+ code: 'invalid_type',
621
+ expected: 'number',
622
+ received: 'undefined',
623
+ path: [Array],
624
+ message: 'Required'
625
+ },
626
+ {
627
+ code: 'invalid_type',
628
+ expected: 'number',
629
+ received: 'undefined',
630
+ path: [Array],
631
+ message: 'Required'
632
+ }
633
+ ],
634
+ responseData: { success: true, data: { message: 'Invalid format' } }
635
+ }
636
+ [AccessControl] Response validation failed {
637
+ correlationId: 'c8ced6df-58ca-44ec-b9db-c3973e9d7505',
638
+ zodErrors: [
639
+ {
640
+ code: 'invalid_type',
641
+ expected: 'number',
642
+ received: 'undefined',
643
+ path: [Array],
644
+ message: 'Required'
645
+ },
646
+ {
647
+ code: 'invalid_type',
648
+ expected: 'number',
649
+ received: 'undefined',
650
+ path: [Array],
651
+ message: 'Required'
652
+ }
653
+ ],
654
+ zodErrorDetails: '[\n' +
655
+ ' {\n' +
656
+ ' "code": "invalid_type",\n' +
657
+ ' "expected": "number",\n' +
658
+ ' "received": "undefined",\n' +
659
+ ' "path": [\n' +
660
+ ' "accepted"\n' +
661
+ ' ],\n' +
662
+ ' "message": "Required"\n' +
663
+ ' },\n' +
664
+ ' {\n' +
665
+ ' "code": "invalid_type",\n' +
666
+ ' "expected": "number",\n' +
667
+ ' "received": "undefined",\n' +
668
+ ' "path": [\n' +
669
+ ' "rejected"\n' +
670
+ ' ],\n' +
671
+ ' "message": "Required"\n' +
672
+ ' }\n' +
673
+ ']',
674
+ responseData: '{\n "success": true,\n "data": {\n "message": "Invalid format"\n }\n}',
675
+ responseDataType: 'object',
676
+ responseKeys: [ 'success', 'data' ],
677
+ httpStatus: 200,
678
+ httpStatusText: ''
679
+ }
680
+ [AccessControl] ❌ ZOD VALIDATION FAILED (direct) - 2 error(s):
681
+ [AccessControl] Error 1: {
682
+ path: 'accepted',
683
+ message: 'Required',
684
+ code: 'invalid_type',
685
+ received: 'undefined',
686
+ expected: 'number'
687
+ }
688
+ [AccessControl] Error 2: {
689
+ path: 'rejected',
690
+ message: 'Required',
691
+ code: 'invalid_type',
692
+ received: 'undefined',
693
+ expected: 'number'
694
+ }
695
+ [AccessControl] ❌ Full ZOD errors JSON: [
696
+ {
697
+ "code": "invalid_type",
698
+ "expected": "number",
699
+ "received": "undefined",
700
+ "path": [
701
+ "accepted"
702
+ ],
703
+ "message": "Required"
704
+ },
705
+ {
706
+ "code": "invalid_type",
707
+ "expected": "number",
708
+ "received": "undefined",
709
+ "path": [
710
+ "rejected"
711
+ ],
712
+ "message": "Required"
713
+ }
714
+ ]
715
+ [AccessControl] ❌ ACTUAL RESPONSE DATA: {
716
+ "success": true,
717
+ "data": {
718
+ "message": "Invalid format"
719
+ }
720
+ }
721
+
722
+ ✓ src/delegation/__tests__/vc-verifier.test.ts (35 tests) 40ms
723
+ ✓ src/services/__tests__/access-control.service.test.ts (23 tests) 29ms
724
+ 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
725
+ [MCP-I] Checking tool protection: {
726
+ tool: 'unprotectedTool',
727
+ agentDid: 'did:key:zmock123...',
728
+ hasDelegation: false
729
+ }
730
+
731
+ 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
732
+ [MCP-I] Tool protection check passed (no delegation required) {
733
+ tool: 'unprotectedTool',
734
+ agentDid: 'did:key:zmock123...',
735
+ reason: 'Tool not configured to require delegation'
736
+ }
737
+
738
+ 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
739
+ [MCP-I] Checking tool protection: {
740
+ tool: 'protectedTool',
741
+ agentDid: 'did:key:zmock123...',
742
+ hasDelegation: false
743
+ }
744
+
745
+ 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
746
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
747
+ tool: 'protectedTool',
748
+ requiredScopes: [ 'files:write' ],
749
+ agentDid: 'did:key:zmock123...',
750
+ resumeToken: 'resume_hkgrpp_mi9xqkbt',
751
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_hkgrpp_mi9xqkbt'
752
+ }
753
+
754
+ 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
755
+ [MCP-I] Checking tool protection: {
756
+ tool: 'protectedTool',
757
+ agentDid: 'did:key:zmock123...',
758
+ hasDelegation: true
759
+ }
760
+
761
+ 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
762
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
763
+ tool: 'protectedTool',
764
+ agentDid: 'did:key:zmock123...',
765
+ hasDelegationToken: true,
766
+ hasConsentProof: false,
767
+ requiredScopes: [ 'files:write' ]
768
+ }
769
+
770
+ 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
771
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
772
+ tool: 'protectedTool',
773
+ agentDid: 'did:key:zmock123...',
774
+ delegationId: 'test-delegation-id',
775
+ credentialScopes: [ 'files:write' ],
776
+ requiredScopes: [ 'files:write' ]
777
+ }
778
+
779
+ 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
780
+ [MCP-I] Checking tool protection: {
781
+ tool: 'protectedTool',
782
+ agentDid: 'did:key:zmock123...',
783
+ hasDelegation: true
784
+ }
785
+
786
+ 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
787
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
788
+ tool: 'protectedTool',
789
+ agentDid: 'did:key:zmock123...',
790
+ hasDelegationToken: false,
791
+ hasConsentProof: true,
792
+ requiredScopes: [ 'files:write' ]
793
+ }
794
+
795
+ 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
796
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
797
+ tool: 'protectedTool',
798
+ agentDid: 'did:key:zmock123...',
799
+ delegationId: 'test-delegation-id',
800
+ credentialScopes: [ 'files:write' ],
801
+ requiredScopes: [ 'files:write' ]
802
+ }
803
+
804
+ 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
805
+ [MCP-I] Checking tool protection: {
806
+ tool: 'protectedTool',
807
+ agentDid: 'did:key:zmock123...',
808
+ hasDelegation: true
809
+ }
810
+
811
+ 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
812
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
813
+ tool: 'protectedTool',
814
+ agentDid: 'did:key:zmock123...',
815
+ hasDelegationToken: true,
816
+ hasConsentProof: false,
817
+ requiredScopes: [ 'files:write' ]
818
+ }
819
+
820
+ 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
821
+ [MCP-I] ❌ Delegation verification FAILED {
822
+ tool: 'protectedTool',
823
+ agentDid: 'did:key:zmock123...',
824
+ reason: 'Delegation token expired',
825
+ errorCode: undefined,
826
+ errorMessage: undefined,
827
+ requiredScopes: [ 'files:write' ]
828
+ }
829
+
830
+ 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
831
+ [MCP-I] Checking tool protection: {
832
+ tool: 'protectedTool',
833
+ agentDid: 'did:key:zmock123...',
834
+ hasDelegation: true
835
+ }
836
+
837
+ 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
838
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
839
+ tool: 'protectedTool',
840
+ agentDid: 'did:key:zmock123...',
841
+ hasDelegationToken: true,
842
+ hasConsentProof: false,
843
+ requiredScopes: [ 'files:write' ]
844
+ }
845
+
846
+ 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
847
+ [MCP-I] ❌ Delegation verification FAILED {
848
+ tool: 'protectedTool',
849
+ agentDid: 'did:key:zmock123...',
850
+ reason: 'Insufficient scopes',
851
+ errorCode: undefined,
852
+ errorMessage: undefined,
853
+ requiredScopes: [ 'files:write' ]
854
+ }
855
+
856
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
857
+ [MCP-I] Checking tool protection: {
858
+ tool: 'protectedTool',
859
+ agentDid: 'did:key:zmock123...',
860
+ hasDelegation: true
861
+ }
862
+
863
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
864
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
865
+ tool: 'protectedTool',
866
+ agentDid: 'did:key:zmock123...',
867
+ hasDelegationToken: true,
868
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should handle API errors during verification gracefully
869
+ [MCP-I] ❌ Delegation verification error (API failure) {
870
+ tool: 'protectedTool',
871
+ hasConsentProof: false,
872
+ requiredScopes: [ 'files:write' ]
873
+ agentDid: 'did:key:zmock123...',
874
+ }
875
+
876
+ 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)
877
+ [MCP-I] Checking tool protection: {
878
+ errorCode: 'network_error',
879
+ tool: 'protectedTool',
880
+ errorMessage: 'API unavailable',
881
+ agentDid: 'did:key:zmock123...',
882
+ errorDetails: {}
883
+ hasDelegation: true
884
+ }
885
+
886
+ }
887
+ 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)
888
+
889
+ 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
890
+ [MCP-I] ⚠️ Delegation token provided but AccessControlApiService not configured - skipping verification {
891
+ [MCP-I] Checking tool protection: {
892
+ tool: 'protectedTool',
893
+ agentDid: 'did:key:zmock123...',
894
+ tool: 'protectedTool',
895
+ hasDelegation: true
896
+ }
897
+ agentDid: 'did:key:zmock123...',
898
+
899
+ hasDelegationToken: true,
900
+ hasConsentProof: false
901
+ 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
902
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
903
+ tool: 'protectedTool',
904
+ agentDid: 'did:key:zmock123...',
905
+ }
906
+ hasDelegationToken: true,
907
+ hasConsentProof: false,
908
+
909
+ requiredScopes: [ 'files:write' ]
910
+ 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
911
+ }
912
+
913
+ 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
914
+ [MCP-I] Checking tool protection: {
915
+ [MCP-I] 🔒 SECURITY: User identifier validation FAILED {
916
+ tool: 'protectedTool',
917
+ agentDid: 'did:key:zmock123...',
918
+ tool: 'protectedTool',
919
+ hasDelegation: true
920
+ }
921
+
922
+ 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
923
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
924
+ agentDid: 'did:key:zmock123...',
925
+ delegationUserIdentifier: 'did:key:zUserB987654...',
926
+ tool: 'protectedTool',
927
+ agentDid: 'did:key:zmock123...',
928
+ sessionUserDid: 'did:key:zUserA123456...',
929
+ hasDelegationToken: true,
930
+ hasConsentProof: false,
931
+ requiredScopes: [ 'files:write' ]
932
+ }
933
+ sessionId: 'session123...',
934
+
935
+ 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
936
+ [MCP-I] ✅ User identifier validation PASSED {
937
+ tool: 'protectedTool',
938
+ reason: 'user_identifier_mismatch',
939
+ agentDid: 'did:key:zmock123...',
940
+ severity: 'high'
941
+ }
942
+
943
+ userDid: 'did:key:zUserA123456...',
944
+ sessionId: 'session123...'
945
+ }
946
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
947
+ tool: 'protectedTool',
948
+ agentDid: 'did:key:zmock123...',
949
+ delegationId: 'test-delegation-id',
950
+ credentialScopes: [ 'files:write' ],
951
+ requiredScopes: [ 'files:write' ]
952
+ }
953
+
954
+ 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)
955
+ [MCP-I] Checking tool protection: {
956
+ tool: 'protectedTool',
957
+ agentDid: 'did:key:zmock123...',
958
+ hasDelegation: true
959
+ }
960
+
961
+ 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)
962
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
963
+ tool: 'protectedTool',
964
+ agentDid: 'did:key:zmock123...',
965
+ hasDelegationToken: true,
966
+ hasConsentProof: false,
967
+ requiredScopes: [ 'files:write' ]
968
+ }
969
+
970
+ 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)
971
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
972
+ tool: 'protectedTool',
973
+ agentDid: 'did:key:zmock123...',
974
+ delegationId: 'test-delegation-id',
975
+ credentialScopes: [ 'files:write' ],
976
+ requiredScopes: [ 'files:write' ]
977
+ }
978
+
979
+ 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
980
+ [MCP-I] Checking tool protection: {
981
+ tool: 'protectedTool',
982
+ agentDid: 'did:key:zmock123...',
983
+ hasDelegation: true
984
+ }
985
+
986
+ 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
987
+ [MCP-I] 🔐 Verifying delegation token with AccessControlApiService {
988
+ tool: 'protectedTool',
989
+ agentDid: 'did:key:zmock123...',
990
+ hasDelegationToken: true,
991
+ hasConsentProof: false,
992
+ requiredScopes: [ 'files:write' ]
993
+ }
994
+
995
+ 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
996
+ [MCP-I] ✅ Delegation verification SUCCEEDED {
997
+ tool: 'protectedTool',
998
+ agentDid: 'did:key:zmock123...',
999
+ delegationId: 'test-delegation-id',
1000
+ credentialScopes: [ 'files:write' ],
1001
+ requiredScopes: [ 'files:write' ]
1002
+ }
1003
+
1004
+ 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
1005
+ [MCP-I] ⚠️ Delegation has user_identifier but session missing userDid {
1006
+ tool: 'protectedTool',
1007
+ agentDid: 'did:key:zmock123...',
1008
+ delegationUserIdentifier: 'did:key:zUserA123456...',
1009
+ sessionId: 'session123...'
1010
+ }
1011
+
1012
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should create proof after successful tool execution
1013
+ [MCP-I] Checking tool protection: {
1014
+ tool: 'unprotectedTool',
1015
+ agentDid: 'did:key:zmock123...',
1016
+ hasDelegation: false
1017
+ }
1018
+
1019
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > processToolCall with tool protection > should create proof after successful tool execution
1020
+ [MCP-I] Tool protection check passed (no delegation required) {
1021
+ tool: 'unprotectedTool',
1022
+ agentDid: 'did:key:zmock123...',
1023
+ reason: 'Tool not configured to require delegation'
1024
+ }
1025
+
1026
+ 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
1027
+ [MCP-I] Checking tool protection: {
1028
+ tool: 'protectedTool',
1029
+ agentDid: 'did:key:zmock123...',
1030
+ hasDelegation: false
1031
+ }
1032
+
1033
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Submission Flow > should submit proof end-to-end
1034
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1035
+ correlationId: '310c7df3-f656-4845-9d96-a3d1dde07c85',
1036
+ status: 200,
1037
+ statusText: '',
1038
+ headers: { 'content-type': 'application/json' },
1039
+ responseTextLength: 100,
1040
+ responseTextPreview: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}',
1041
+ fullResponseText: '{"success":true,"accepted":1,"rejected":0,"outcomes":{"success":1,"failed":0,"blocked":0,"error":0}}'
1042
+ }
1043
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1044
+ correlationId: '310c7df3-f656-4845-9d96-a3d1dde07c85',
1045
+ status: 200,
1046
+ responseDataType: 'object',
1047
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes' ],
1048
+ responseData: '{\n' +
1049
+ ' "success": true,\n' +
1050
+ ' "accepted": 1,\n' +
1051
+ ' "rejected": 0,\n' +
1052
+ ' "outcomes": {\n' +
1053
+ ' "success": 1,\n' +
1054
+ ' "failed": 0,\n' +
1055
+ ' "blocked": 0,\n' +
1056
+ ' "error": 0\n' +
1057
+ ' }\n' +
1058
+ '}'
1059
+ }
1060
+ [AccessControl] Raw response received: {
1061
+ "success": true,
1062
+ "accepted": 1,
1063
+ "rejected": 0,
1064
+ "outcomes": {
1065
+ "success": 1,
1066
+ "failed": 0,
1067
+ "blocked": 0,
1068
+ "error": 0
1069
+ }
1070
+ }
1071
+
1072
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Submission Flow > should handle proof submission with errors
1073
+ [AccessControl] 🔍 RAW API RESPONSE (before parsing): {
1074
+ correlationId: '320c0345-efcf-4339-832f-41a67055e5e2',
1075
+ status: 200,
1076
+ statusText: '',
1077
+ headers: { 'content-type': 'application/json' },
1078
+ responseTextLength: 200,
1079
+ 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"}}]}',
1080
+ 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"}}]}'
1081
+ }
1082
+ [AccessControl] 🔍 PARSED RESPONSE DATA: {
1083
+ correlationId: '320c0345-efcf-4339-832f-41a67055e5e2',
1084
+ status: 200,
1085
+ responseDataType: 'object',
1086
+ responseDataKeys: [ 'success', 'accepted', 'rejected', 'outcomes', 'errors' ],
1087
+ responseData: '{\n' +
1088
+ ' "success": true,\n' +
1089
+ ' "accepted": 0,\n' +
1090
+ ' "rejected": 1,\n' +
1091
+ ' "outcomes": {\n' +
1092
+ ' "success": 0,\n' +
1093
+ ' "failed": 1,\n' +
1094
+ ' "blocked": 0,\n' +
1095
+ ' "error": 0\n' +
1096
+ ' },\n' +
1097
+ ' "errors": [\n' +
1098
+ ' {\n' +
1099
+ ' "proof_index": 0,\n' +
1100
+ ' "error": {\n' +
1101
+ ' "code": "invalid_signature",\n' +
1102
+ ' "message": "Invalid JWS signature"\n' +
1103
+ ' }\n' +
1104
+ ' }\n' +
1105
+ ' ]\n' +
1106
+ '}'
1107
+ }
1108
+ [AccessControl] Raw response received: {
1109
+ "success": true,
1110
+ "accepted": 0,
1111
+ "rejected": 1,
1112
+ "outcomes": {
1113
+ "success": 0,
1114
+ "failed": 1,
1115
+ "blocked": 0,
1116
+ "error": 0
1117
+ },
1118
+ "errors": [
1119
+ {
1120
+ "proof_index": 0,
1121
+ "error": {
1122
+ "code": "invalid_signature",
1123
+ "message": "Invalid JWS signature"
1124
+ }
1125
+ }
1126
+ ]
1127
+ }
1128
+
1129
+ stderr | src/services/__tests__/access-control.integration.test.ts > AccessControlApiService Integration > Proof Verification Flow > should verify proof using ProofVerifier
1130
+ [CryptoService] Key ID mismatch
1131
+
1132
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should allow unprotected tool calls
1133
+ [ToolProtectionService] Config loaded from API {
1134
+ 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
1135
+ source: 'api',
1136
+ toolCount: 1,
1137
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1138
+ protectedTools: [],
1139
+ tool: 'protectedTool',
1140
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1141
+ requiredScopes: [ 'files:write' ],
1142
+ agentDid: 'did:key:zmock123...',
1143
+ projectId: 'test-project',
1144
+ cacheTtlMs: 300000,
1145
+ cacheExpiresAt: '2025-11-22T07:00:54.479Z'
1146
+ resumeToken: 'resume_hkgr0q_mi9xqkc0',
1147
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_hkgr0q_mi9xqkc0'
1148
+ }
1149
+
1150
+ }
1151
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should intercept protected tool calls without delegation
1152
+ [ToolProtectionService] Config loaded from API {
1153
+ source: 'api',
1154
+ toolCount: 1,
1155
+ protectedTools: [ 'checkout' ],
1156
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1157
+ projectId: 'test-project',
1158
+ cacheTtlMs: 300000,
1159
+
1160
+ cacheExpiresAt: '2025-11-22T07:00:54.480Z'
1161
+ }
1162
+
1163
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Tool protection enforcement flow > should intercept protected tool calls without delegation
1164
+ [ToolProtectionService] Protection check {
1165
+ tool: 'checkout',
1166
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1167
+ found: true,
1168
+ isWildcard: false,
1169
+ requiresDelegation: true,
1170
+ availableTools: [ 'checkout' ]
1171
+ }
1172
+
1173
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should fetch tool protection config from AgentShield
1174
+ [ToolProtectionService] Config loaded from API {
1175
+ source: 'api',
1176
+ toolCount: 1,
1177
+ protectedTools: [ 'protected_tool' ],
1178
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1179
+ projectId: 'test-project',
1180
+ cacheTtlMs: 300000,
1181
+ cacheExpiresAt: '2025-11-22T07:00:54.480Z'
1182
+ }
1183
+
1184
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should cache tool protection config
1185
+ [ToolProtectionService] Config loaded from API {
1186
+ source: 'api',
1187
+ toolCount: 1,
1188
+ protectedTools: [ 'tool1' ],
1189
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1190
+ projectId: 'test-project',
1191
+ cacheTtlMs: 300000,
1192
+ cacheExpiresAt: '2025-11-22T07:00:54.482Z'
1193
+ }
1194
+
1195
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include tool name in error
1196
+ [MCP-I] Checking tool protection: {
1197
+ tool: 'protectedTool',
1198
+ agentDid: 'did:key:zmock123...',
1199
+ hasDelegation: false
1200
+ }
1201
+
1202
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include tool name in error
1203
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1204
+ tool: 'protectedTool',
1205
+ requiredScopes: [ 'files:write' ],
1206
+ agentDid: 'did:key:zmock123...',
1207
+ resumeToken: 'resume_hkgqz0_mi9xqkc2',
1208
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_hkgqz0_mi9xqkc2'
1209
+ }
1210
+
1211
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include required scopes in error
1212
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include required scopes in error
1213
+ [MCP-I] Checking tool protection: {
1214
+ tool: 'protectedTool',
1215
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1216
+ tool: 'protectedTool',
1217
+ requiredScopes: [ 'files:write', 'files:read' ],
1218
+ agentDid: 'did:key:zmock123...',
1219
+ agentDid: 'did:key:zmock123...',
1220
+ hasDelegation: false
1221
+ }
1222
+ resumeToken: 'resume_hkgqz0_mi9xqkc2',
1223
+
1224
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite%2Cfiles%3Aread&session_id=session123&agent_did=&resume_token=resume_hkgqz0_mi9xqkc2'
1225
+ }
1226
+
1227
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > AgentShield integration flow > should use fallback config when API fails
1228
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network error' }
1229
+
1230
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include consent URL in error
1231
+ [MCP-I] Checking tool protection: {
1232
+ tool: 'protectedTool',
1233
+ agentDid: 'did:key:zmock123...',
1234
+ hasDelegation: false
1235
+ }
1236
+
1237
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include consent URL in error
1238
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1239
+ tool: 'protectedTool',
1240
+ requiredScopes: [ 'files:write' ],
1241
+ agentDid: 'did:key:zmock123...',
1242
+ resumeToken: 'resume_hkgqy5_mi9xqkc3',
1243
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_hkgqy5_mi9xqkc3'
1244
+ }
1245
+
1246
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Error handling in full flow > should handle tool protection service errors gracefully
1247
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
1248
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1249
+ error: 'Network error',
1250
+ cacheKey: 'config:tool-protections:test-project'
1251
+ }
1252
+
1253
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include resume token in error
1254
+ [MCP-I] Checking tool protection: {
1255
+ tool: 'protectedTool',
1256
+ agentDid: 'did:key:zmock123...',
1257
+ hasDelegation: false
1258
+ }
1259
+
1260
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include resume token in error
1261
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include intercepted call context in error
1262
+ [MCP-I] Checking tool protection: {
1263
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1264
+ tool: 'protectedTool',
1265
+ tool: 'protectedTool',
1266
+ agentDid: 'did:key:zmock123...',
1267
+ hasDelegation: false
1268
+ requiredScopes: [ 'files:write' ],
1269
+ }
1270
+
1271
+ agentDid: 'did:key:zmock123...',
1272
+ resumeToken: 'resume_hkgqy5_mi9xqkc3',
1273
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_hkgqy5_mi9xqkc3'
1274
+ }
1275
+
1276
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log tool protection check when audit enabled
1277
+ [MCP-I] Checking tool protection: {
1278
+ tool: 'testTool',
1279
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > DelegationRequiredError details > should include intercepted call context in error
1280
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1281
+ agentDid: 'did:key:zmock123...',
1282
+ hasDelegation: false
1283
+ }
1284
+
1285
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log tool protection check when audit enabled
1286
+ [MCP-I] Tool protection check passed (no delegation required) {
1287
+ tool: 'protectedTool',
1288
+ tool: 'testTool',
1289
+ agentDid: 'did:key:zmock123...',
1290
+ requiredScopes: [ 'files:write' ],
1291
+ reason: 'Tool not configured to require delegation'
1292
+ }
1293
+ agentDid: 'did:key:zmock123...',
1294
+ resumeToken: 'resume_1dqjpu_mi9xqkc3',
1295
+
1296
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=session123&agent_did=&resume_token=resume_1dqjpu_mi9xqkc3'
1297
+ }
1298
+
1299
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > audit logging > should log blocked tool call when audit enabled
1300
+ [MCP-I] Checking tool protection: {
1301
+ tool: 'protectedTool',
1302
+ agentDid: 'did:key:zmock123...',
1303
+ hasDelegation: false
1304
+ }
1305
+
1306
+ stderr | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Error handling in full flow > should handle network timeouts
1307
+ [ToolProtectionService] API fetch failed, using fallback config { agentDid: 'did:key:z6MkhaXgBZDv...', error: 'Network timeout' }
1308
+
1309
+ ✓ src/__tests__/runtime/base-extensions.test.ts (38 tests) 15ms
1310
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should share cache across multiple service instances
1311
+ [ToolProtectionService] Config loaded from API {
1312
+ source: 'api',
1313
+ toolCount: 1,
1314
+ protectedTools: [ 'tool1' ],
1315
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1316
+ projectId: 'test-project',
1317
+ cacheTtlMs: 300000,
1318
+ cacheExpiresAt: '2025-11-22T07:00:54.484Z'
1319
+ }
1320
+
1321
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should clear cache when needed
1322
+ [ToolProtectionService] Config loaded from API {
1323
+ source: 'api',
1324
+ toolCount: 1,
1325
+ protectedTools: [ 'tool1' ],
1326
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1327
+ projectId: 'test-project',
1328
+ cacheTtlMs: 300000,
1329
+ cacheExpiresAt: '2025-11-22T07:00:54.484Z'
1330
+ }
1331
+
1332
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Cache integration in full flow > should clear cache when needed
1333
+ [ToolProtectionService] Config loaded from API {
1334
+ source: 'api',
1335
+ toolCount: 1,
1336
+ protectedTools: [ 'tool1' ],
1337
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1338
+ projectId: 'test-project',
1339
+ cacheTtlMs: 300000,
1340
+ cacheExpiresAt: '2025-11-22T07:00:54.484Z'
1341
+ }
1342
+
1343
+ 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
1344
+ [ToolProtectionService] Config loaded from API {
1345
+ source: 'api',
1346
+ toolCount: 3,
1347
+ protectedTools: [ 'add_to_cart', 'checkout' ],
1348
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1349
+ projectId: 'test-project',
1350
+ cacheTtlMs: 300000,
1351
+ cacheExpiresAt: '2025-11-22T07:00:54.485Z'
1352
+ }
1353
+
1354
+ 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
1355
+ [ToolProtectionService] Protection check {
1356
+ tool: 'add_to_cart',
1357
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1358
+ found: true,
1359
+ isWildcard: false,
1360
+ requiresDelegation: true,
1361
+ availableTools: [ 'search_products', 'add_to_cart', 'checkout' ]
1362
+ }
1363
+
1364
+ 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
1365
+ [MCP-I] Checking tool protection: {
1366
+ tool: 'testTool',
1367
+ agentDid: 'did:key:zmock123...',
1368
+ hasDelegation: false
1369
+ }
1370
+
1371
+ 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
1372
+ [MCP-I] Tool protection check passed (no delegation required) {
1373
+ tool: 'testTool',
1374
+ agentDid: 'did:key:zmock123...',
1375
+ reason: 'Tool not configured to require delegation'
1376
+ }
1377
+
1378
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > tool protection service integration > should handle tool protection service errors gracefully
1379
+ [MCP-I] Checking tool protection: {
1380
+ tool: 'testTool',
1381
+ agentDid: 'did:key:zmock123...',
1382
+ hasDelegation: false
1383
+ }
1384
+
1385
+ stdout | src/__tests__/integration/full-flow.test.ts > Full Flow Integration > Concurrent operations > should handle concurrent cache operations
1386
+ [ToolProtectionService] Config loaded from API {
1387
+ source: 'api',
1388
+ toolCount: 1,
1389
+ protectedTools: [ 'tool1' ],
1390
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1391
+ projectId: 'test-project',
1392
+ cacheTtlMs: 300000,
1393
+ cacheExpiresAt: '2025-11-22T07:00:54.485Z'
1394
+ }
1395
+ [ToolProtectionService] Config loaded from API {
1396
+ source: 'api',
1397
+ toolCount: 1,
1398
+ protectedTools: [ 'tool1' ],
1399
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1400
+ projectId: 'test-project',
1401
+ cacheTtlMs: 300000,
1402
+ cacheExpiresAt: '2025-11-22T07:00:54.485Z'
1403
+ }
1404
+ [ToolProtectionService] Config loaded from API {
1405
+ source: 'api',
1406
+ toolCount: 1,
1407
+ protectedTools: [ 'tool1' ],
1408
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1409
+ projectId: 'test-project',
1410
+ cacheTtlMs: 300000,
1411
+ cacheExpiresAt: '2025-11-22T07:00:54.485Z'
1412
+ }
1413
+
1414
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle empty required scopes array
1415
+ [MCP-I] Checking tool protection: {
1416
+ tool: 'protectedTool',
1417
+ agentDid: 'did:key:zmock123...',
1418
+ hasDelegation: false
1419
+ }
1420
+
1421
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle empty required scopes array
1422
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1423
+ tool: 'protectedTool',
1424
+ requiredScopes: [],
1425
+ agentDid: 'did:key:zmock123...',
1426
+ resumeToken: 'resume_hkgqvk_mi9xqkc6',
1427
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=&session_id=session123&agent_did=&resume_token=resume_hkgqvk_mi9xqkc6'
1428
+ }
1429
+
1430
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle multiple required scopes
1431
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle multiple required scopes
1432
+ [MCP-I] Checking tool protection: {
1433
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1434
+ tool: 'protectedTool',
1435
+ agentDid: 'did:key:zmock123...',
1436
+ hasDelegation: false
1437
+ tool: 'protectedTool',
1438
+ requiredScopes: [ 'scope1', 'scope2', 'scope3' ],
1439
+ }
1440
+
1441
+ agentDid: 'did:key:zmock123...',
1442
+ resumeToken: 'resume_hkgqvk_mi9xqkc6',
1443
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=scope1%2Cscope2%2Cscope3&session_id=session123&agent_did=&resume_token=resume_hkgqvk_mi9xqkc6'
1444
+ }
1445
+
1446
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle session without id
1447
+ stderr | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle session without id
1448
+ [MCP-I] BLOCKED: Tool requires delegation but none provided {
1449
+ [MCP-I] Checking tool protection: {
1450
+ tool: 'protectedTool',
1451
+ tool: 'protectedTool',
1452
+ agentDid: 'did:key:zmock123...',
1453
+ requiredScopes: [ 'files:write' ],
1454
+ agentDid: 'did:key:zmock123...',
1455
+ resumeToken: 'resume_4ieqgu_mi9xqkc6',
1456
+ hasDelegation: false
1457
+ }
1458
+
1459
+ consentUrl: 'https://kya.vouched.id/bouncer/consent?tool=protectedTool&scopes=files%3Awrite&session_id=&agent_did=&resume_token=resume_4ieqgu_mi9xqkc6'
1460
+ }
1461
+
1462
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle handler errors independently of protection
1463
+ [MCP-I] Checking tool protection: {
1464
+ tool: 'errorTool',
1465
+ agentDid: 'did:key:zmock123...',
1466
+ hasDelegation: false
1467
+ }
1468
+
1469
+ stdout | src/__tests__/runtime/tool-protection-enforcement.test.ts > MCPIRuntimeBase - Tool Protection Enforcement > edge cases > should handle handler errors independently of protection
1470
+ [MCP-I] Tool protection check passed (no delegation required) {
1471
+ tool: 'errorTool',
1472
+ agentDid: 'did:key:zmock123...',
1473
+ reason: 'Tool not configured to require delegation'
1474
+ }
1475
+
1476
+ ✓ src/__tests__/integration/full-flow.test.ts (21 tests) 21ms
1477
+ ✓ src/__tests__/runtime/tool-protection-enforcement.test.ts (29 tests) 21ms
1478
+ ✓ src/delegation/__tests__/vc-issuer.test.ts (21 tests) 77ms
1479
+ ✓ src/__tests__/runtime/route-interception.test.ts (21 tests) 32ms
1480
+ stderr | src/services/__tests__/proof-verifier.integration.test.ts > ProofVerifier Integration - Real DID Resolution > did:web Resolution (HTTP) > should handle HTTP errors gracefully
1481
+ [ProofVerifier] Failed to fetch public key from DID: Error: Failed to resolve did:web:nonexistent-domain-that-does-not-exist-12345.com: fetch failed
1482
+ at Object.resolveDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:143:19)
1483
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1484
+ at ProofVerifier.fetchPublicKeyFromDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/proof-verifier.ts:348:22)
1485
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:252:7
1486
+ 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
1487
+
1488
+ stderr | src/services/__tests__/proof-verifier.integration.test.ts > ProofVerifier Integration - Real DID Resolution > did:web Resolution (HTTP) > should handle HTTP errors gracefully
1489
+ [ProofVerifier] Failed to fetch public key from DID: Error: Failed to resolve did:web:nonexistent-domain-that-does-not-exist-12345.com: fetch failed
1490
+ at Object.resolveDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:143:19)
1491
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1492
+ at ProofVerifier.fetchPublicKeyFromDID (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/proof-verifier.ts:348:22)
1493
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.integration.test.ts:257:9
1494
+ 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
1495
+
1496
+ ✓ src/services/__tests__/proof-verifier.integration.test.ts (13 tests | 1 skipped) 77ms
1497
+ ✓ src/__tests__/cache/tool-protection-cache.test.ts (49 tests) 161ms
1498
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.get errors gracefully
1499
+ [UserDidManager] Storage.get failed, generating new DID: Error: Storage error
1500
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:187:67
1501
+ 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
1502
+ 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
1503
+ 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
1504
+ at new Promise (<anonymous>)
1505
+ 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)
1506
+ 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)
1507
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1508
+ 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)
1509
+ 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)
1510
+
1511
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.set errors gracefully
1512
+ [UserDidManager] Storage.set failed, continuing with cached DID: Error: Storage error
1513
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:196:67
1514
+ 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
1515
+ 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
1516
+ 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
1517
+ at new Promise (<anonymous>)
1518
+ 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)
1519
+ 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)
1520
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1521
+ 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)
1522
+ 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)
1523
+
1524
+ stderr | src/__tests__/identity/user-did-manager.test.ts > UserDidManager > error handling > should handle storage.delete errors gracefully
1525
+ [UserDidManager] Storage.delete failed, continuing: Error: Storage error
1526
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/__tests__/identity/user-did-manager.test.ts:206:70
1527
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1528
+ 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
1529
+
1530
+ ✓ src/__tests__/identity/user-did-manager.test.ts (17 tests) 10ms
1531
+ ✓ src/services/__tests__/access-control.integration.test.ts (9 tests) 122ms
1532
+ 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
1533
+ [ToolProtectionService] Config loaded from API {
1534
+ source: 'api',
1535
+ toolCount: 2,
1536
+ protectedTools: [ 'checkout' ],
1537
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1538
+ projectId: 'test-project-123',
1539
+ cacheTtlMs: 300000,
1540
+ cacheExpiresAt: '2025-11-22T07:00:54.600Z'
1541
+ }
1542
+
1543
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should handle new endpoint format with toolProtections object
1544
+ [ToolProtectionService] Config loaded from API {
1545
+ source: 'api',
1546
+ toolCount: 2,
1547
+ protectedTools: [ 'protected_tool' ],
1548
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1549
+ projectId: 'test-project-123',
1550
+ cacheTtlMs: 300000,
1551
+ cacheExpiresAt: '2025-11-22T07:00:54.602Z'
1552
+ }
1553
+
1554
+ 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)
1555
+ [ToolProtectionService] Config loaded from API {
1556
+ source: 'api',
1557
+ toolCount: 2,
1558
+ protectedTools: [ 'read_repos', 'send_email' ],
1559
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1560
+ projectId: 'test-project-123',
1561
+ cacheTtlMs: 300000,
1562
+ cacheExpiresAt: '2025-11-22T07:00:54.602Z'
1563
+ }
1564
+
1565
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - new endpoint format > should preserve oauthProvider through cache operations
1566
+ [ToolProtectionService] Config loaded from API {
1567
+ source: 'api',
1568
+ toolCount: 1,
1569
+ protectedTools: [ 'read_repos' ],
1570
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1571
+ projectId: 'test-project-123',
1572
+ cacheTtlMs: 300000,
1573
+ cacheExpiresAt: '2025-11-22T07:00:54.602Z'
1574
+ }
1575
+
1576
+ 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
1577
+ [ToolProtectionService] Config loaded from API {
1578
+ source: 'api',
1579
+ toolCount: 2,
1580
+ protectedTools: [ 'checkout' ],
1581
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1582
+ projectId: 'none',
1583
+ cacheTtlMs: 300000,
1584
+ cacheExpiresAt: '2025-11-22T07:00:54.603Z'
1585
+ }
1586
+
1587
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should handle old endpoint format with tools array
1588
+ [ToolProtectionService] Config loaded from API {
1589
+ source: 'api',
1590
+ toolCount: 2,
1591
+ protectedTools: [ 'tool1' ],
1592
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1593
+ projectId: 'none',
1594
+ cacheTtlMs: 300000,
1595
+ cacheExpiresAt: '2025-11-22T07:00:54.603Z'
1596
+ }
1597
+
1598
+ 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)
1599
+ [ToolProtectionService] Config loaded from API {
1600
+ source: 'api',
1601
+ toolCount: 2,
1602
+ protectedTools: [ 'read_repos', 'send_email' ],
1603
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1604
+ projectId: 'none',
1605
+ cacheTtlMs: 300000,
1606
+ cacheExpiresAt: '2025-11-22T07:00:54.603Z'
1607
+ }
1608
+
1609
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should handle old endpoint format with tools object
1610
+ [ToolProtectionService] Config loaded from API {
1611
+ source: 'api',
1612
+ toolCount: 2,
1613
+ protectedTools: [ 'tool1' ],
1614
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1615
+ projectId: 'none',
1616
+ cacheTtlMs: 300000,
1617
+ cacheExpiresAt: '2025-11-22T07:00:54.603Z'
1618
+ }
1619
+
1620
+ 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)
1621
+ [ToolProtectionService] Config loaded from API {
1622
+ source: 'api',
1623
+ toolCount: 2,
1624
+ protectedTools: [ 'read_repos', 'send_email' ],
1625
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1626
+ projectId: 'none',
1627
+ cacheTtlMs: 300000,
1628
+ cacheExpiresAt: '2025-11-22T07:00:54.603Z'
1629
+ }
1630
+
1631
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
1632
+ [ToolProtectionService] Cache miss, fetching from API {
1633
+ source: 'api-fetch-start',
1634
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
1635
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1636
+ projectId: 'none',
1637
+ apiUrl: 'https://kya.vouched.id',
1638
+ endpoint: '/api/v1/bouncer/config?agent_did=did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
1639
+ }
1640
+ [ToolProtectionService] Fetching from API: https://kya.vouched.id/api/v1/bouncer/config?agent_did=did%3Akey%3Az6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK {
1641
+ method: 'config?agent_did (old)',
1642
+ projectId: 'none',
1643
+ apiKeyPresent: true,
1644
+ apiKeyLength: 18,
1645
+ apiKeyMasked: 'test-api...'
1646
+ }
1647
+
1648
+ ✓ src/__tests__/runtime/base.test.ts (55 tests) 14ms
1649
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
1650
+ [ToolProtectionService] API response received {
1651
+ source: 'api-fetch-complete',
1652
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1653
+ projectId: 'none',
1654
+ responseKeys: [ 'success', 'data', 'metadata' ],
1655
+ dataKeys: [ 'tools' ],
1656
+ rawToolProtections: null,
1657
+ rawTools: [
1658
+ { name: 'valid_tool', requiresDelegation: true },
1659
+ { requiresDelegation: false }
1660
+ ],
1661
+ responseMetadata: {}
1662
+ }
1663
+
1664
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch - old endpoint format > should skip tools without name in array format
1665
+ [ToolProtectionService] Config loaded from API {
1666
+ source: 'api',
1667
+ toolCount: 1,
1668
+ protectedTools: [ 'valid_tool' ],
1669
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1670
+ projectId: 'none',
1671
+ cacheTtlMs: 300000,
1672
+ cacheExpiresAt: '2025-11-22T07:00:54.604Z'
1673
+ }
1674
+ [ToolProtectionService] API fetch successful, config cached {
1675
+ source: 'cache-write',
1676
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1677
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
1678
+ toolCount: 1,
1679
+ tools: [ { name: 'valid_tool', requiresDelegation: true, scopeCount: 0 } ],
1680
+ ttlMs: 300000,
1681
+ ttlMinutes: 5,
1682
+ expiresAt: '2025-11-22T07:00:54.604Z',
1683
+ expiresIn: '300s'
1684
+ }
1685
+
1686
+ stderr | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > API fetch error handling > should handle network errors gracefully
1687
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
1688
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1689
+ error: 'ECONNREFUSED',
1690
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
1691
+ }
1692
+
1693
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should cache successful API responses
1694
+ [ToolProtectionService] Config loaded from API {
1695
+ source: 'api',
1696
+ toolCount: 1,
1697
+ protectedTools: [ 'tool1' ],
1698
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1699
+ projectId: 'none',
1700
+ cacheTtlMs: 300000,
1701
+ cacheExpiresAt: '2025-11-22T07:00:54.610Z'
1702
+ }
1703
+
1704
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should use default cache TTL when not specified
1705
+ [ToolProtectionService] Config loaded from API {
1706
+ source: 'api',
1707
+ toolCount: 0,
1708
+ protectedTools: [],
1709
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1710
+ projectId: 'none',
1711
+ cacheTtlMs: 300000,
1712
+ cacheExpiresAt: '2025-11-22T07:00:54.610Z'
1713
+ }
1714
+
1715
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > caching behavior > should use custom cache TTL when specified
1716
+ [ToolProtectionService] Config loaded from API {
1717
+ source: 'api',
1718
+ toolCount: 0,
1719
+ protectedTools: [],
1720
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1721
+ projectId: 'none',
1722
+ cacheTtlMs: 600000,
1723
+ cacheExpiresAt: '2025-11-22T07:05:54.611Z'
1724
+ }
1725
+
1726
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle empty toolProtections object
1727
+ [ToolProtectionService] Config loaded from API {
1728
+ source: 'api',
1729
+ toolCount: 0,
1730
+ protectedTools: [],
1731
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1732
+ projectId: 'none',
1733
+ cacheTtlMs: 300000,
1734
+ cacheExpiresAt: '2025-11-22T07:00:54.611Z'
1735
+ }
1736
+
1737
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle null requiredScopes
1738
+ [ToolProtectionService] Config loaded from API {
1739
+ source: 'api',
1740
+ toolCount: 1,
1741
+ protectedTools: [ 'tool1' ],
1742
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1743
+ projectId: 'none',
1744
+ cacheTtlMs: 300000,
1745
+ cacheExpiresAt: '2025-11-22T07:00:54.611Z'
1746
+ }
1747
+
1748
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > getToolProtectionConfig > edge cases > should handle mixed camelCase and snake_case in response
1749
+ [ToolProtectionService] Config loaded from API {
1750
+ source: 'api',
1751
+ toolCount: 2,
1752
+ protectedTools: [ 'tool1' ],
1753
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1754
+ projectId: 'none',
1755
+ cacheTtlMs: 300000,
1756
+ cacheExpiresAt: '2025-11-22T07:00:54.612Z'
1757
+ }
1758
+
1759
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool has no protection
1760
+ [ToolProtectionService] Config loaded from API {
1761
+ source: 'api',
1762
+ toolCount: 1,
1763
+ protectedTools: [],
1764
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1765
+ projectId: 'none',
1766
+ cacheTtlMs: 300000,
1767
+ cacheExpiresAt: '2025-11-22T07:00:54.613Z'
1768
+ }
1769
+
1770
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool is not in config
1771
+ [ToolProtectionService] Config loaded from API {
1772
+ source: 'api',
1773
+ toolCount: 1,
1774
+ protectedTools: [ 'other_tool' ],
1775
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1776
+ projectId: 'none',
1777
+ cacheTtlMs: 300000,
1778
+ cacheExpiresAt: '2025-11-22T07:00:54.613Z'
1779
+ }
1780
+
1781
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return null when tool is not in config
1782
+ [ToolProtectionService] Protection check {
1783
+ tool: 'unknown_tool',
1784
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1785
+ found: false,
1786
+ isWildcard: true,
1787
+ requiresDelegation: false,
1788
+ availableTools: [ 'other_tool' ]
1789
+ }
1790
+
1791
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return wildcard protection when tool not found and wildcard exists
1792
+ [ToolProtectionService] Config loaded from API {
1793
+ source: 'api',
1794
+ toolCount: 2,
1795
+ protectedTools: [ '*' ],
1796
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1797
+ projectId: 'none',
1798
+ cacheTtlMs: 300000,
1799
+ cacheExpiresAt: '2025-11-22T07:00:54.614Z'
1800
+ }
1801
+
1802
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return wildcard protection when tool not found and wildcard exists
1803
+ [ToolProtectionService] Protection check {
1804
+ tool: 'unknown_tool',
1805
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1806
+ found: true,
1807
+ isWildcard: true,
1808
+ requiresDelegation: true,
1809
+ availableTools: [ '*', 'specific_tool' ]
1810
+ }
1811
+
1812
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should prioritize specific tool protection over wildcard
1813
+ [ToolProtectionService] Config loaded from API {
1814
+ source: 'api',
1815
+ toolCount: 2,
1816
+ protectedTools: [ '*' ],
1817
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1818
+ projectId: 'none',
1819
+ cacheTtlMs: 300000,
1820
+ cacheExpiresAt: '2025-11-22T07:00:54.614Z'
1821
+ }
1822
+
1823
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should use wildcard protection in fail-safe deny-all mode
1824
+ [ToolProtectionService] Protection check {
1825
+ tool: 'any_tool',
1826
+ stderr | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should use wildcard protection in fail-safe deny-all mode
1827
+ [ToolProtectionService] API fetch failed, no fallback, failing closed (deny-all) {
1828
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1829
+ error: 'Network error',
1830
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1831
+ cacheKey: 'agent:did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'
1832
+ found: true,
1833
+ isWildcard: true,
1834
+ requiresDelegation: true,
1835
+ availableTools: [ '*' ]
1836
+ }
1837
+ }
1838
+
1839
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return protection config when tool requires delegation
1840
+ [ToolProtectionService] Config loaded from API {
1841
+ source: 'api',
1842
+
1843
+ toolCount: 1,
1844
+ protectedTools: [ 'protected_tool' ],
1845
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1846
+ projectId: 'none',
1847
+ cacheTtlMs: 300000,
1848
+ cacheExpiresAt: '2025-11-22T07:00:54.614Z'
1849
+ }
1850
+
1851
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > checkToolProtection > should return protection config when tool requires delegation
1852
+ [ToolProtectionService] Protection check {
1853
+ tool: 'protected_tool',
1854
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1855
+ found: true,
1856
+ isWildcard: false,
1857
+ requiresDelegation: true,
1858
+ availableTools: [ 'protected_tool' ]
1859
+ }
1860
+
1861
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > integration with NoOpToolProtectionCache > should work with NoOpToolProtectionCache
1862
+ [ToolProtectionService] Config loaded from API {
1863
+ source: 'api',
1864
+ toolCount: 1,
1865
+ protectedTools: [ 'tool1' ],
1866
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1867
+ projectId: 'none',
1868
+ cacheTtlMs: 300000,
1869
+ cacheExpiresAt: '2025-11-22T07:00:54.615Z'
1870
+ }
1871
+
1872
+ stdout | src/__tests__/services/tool-protection.service.test.ts > ToolProtectionService > integration with NoOpToolProtectionCache > should work with NoOpToolProtectionCache
1873
+ [ToolProtectionService] Config loaded from API {
1874
+ source: 'api',
1875
+ toolCount: 1,
1876
+ protectedTools: [ 'tool1' ],
1877
+ agentDid: 'did:key:z6MkhaXgBZDv...',
1878
+ projectId: 'none',
1879
+ cacheTtlMs: 300000,
1880
+ cacheExpiresAt: '2025-11-22T07:00:54.615Z'
1881
+ }
1882
+
1883
+ ✓ src/__tests__/services/tool-protection.service.test.ts (49 tests) 21ms
1884
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyEd25519 > should return false on verification error
1885
+ [CryptoService] Ed25519 verification error: Error: Verification failed
1886
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:62:9
1887
+ 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
1888
+ 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
1889
+ 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
1890
+ at new Promise (<anonymous>)
1891
+ 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)
1892
+ 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)
1893
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1894
+ 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)
1895
+ 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)
1896
+
1897
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject invalid JWK format
1898
+ [CryptoService] Invalid Ed25519 JWK format
1899
+
1900
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with wrong kty
1901
+ [CryptoService] Invalid Ed25519 JWK format
1902
+
1903
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with wrong crv
1904
+ [CryptoService] Invalid Ed25519 JWK format
1905
+
1906
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with missing x field
1907
+ [CryptoService] Invalid Ed25519 JWK format
1908
+
1909
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject JWK with empty x field
1910
+ [CryptoService] Invalid Ed25519 JWK format
1911
+
1912
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject malformed JWS
1913
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected token 'ž', "ž‹" is not valid JSON
1914
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
1915
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1916
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:230:42
1917
+ 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
1918
+ 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
1919
+ 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
1920
+ at new Promise (<anonymous>)
1921
+ 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)
1922
+ 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)
1923
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1924
+
1925
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject non-EdDSA algorithms
1926
+ [CryptoService] Unsupported algorithm: RS256, expected EdDSA
1927
+
1928
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should reject HS256 algorithm
1929
+ [CryptoService] Unsupported algorithm: HS256, expected EdDSA
1930
+
1931
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle empty JWS components
1932
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected end of JSON input
1933
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
1934
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1935
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:271:42
1936
+ 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
1937
+ 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
1938
+ 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
1939
+ at new Promise (<anonymous>)
1940
+ 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)
1941
+ 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)
1942
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1943
+
1944
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - single part
1945
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
1946
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
1947
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1948
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:279:42
1949
+ 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
1950
+ 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
1951
+ 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
1952
+ at new Promise (<anonymous>)
1953
+ 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)
1954
+ 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)
1955
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1956
+
1957
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - two parts
1958
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
1959
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
1960
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1961
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:287:42
1962
+ 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
1963
+ 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
1964
+ 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
1965
+ at new Promise (<anonymous>)
1966
+ 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)
1967
+ 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)
1968
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1969
+
1970
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - four parts
1971
+ [CryptoService] Invalid JWS format: Error: Invalid JWS format: expected header.payload.signature
1972
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:78:13)
1973
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1974
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:302:42
1975
+ 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
1976
+ 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
1977
+ 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
1978
+ at new Promise (<anonymous>)
1979
+ 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)
1980
+ 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)
1981
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1982
+
1983
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - invalid JSON header
1984
+ [CryptoService] Invalid JWS format: Error: Invalid header base64: Unexpected token 'o', "notjson" is not valid JSON
1985
+ ✓ src/delegation/__tests__/bitstring.test.ts (30 tests) 5ms
1986
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:91:13)
1987
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
1988
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:316:42
1989
+ 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
1990
+ 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
1991
+ 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
1992
+ at new Promise (<anonymous>)
1993
+ 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)
1994
+ 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)
1995
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
1996
+
1997
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle malformed JWS - invalid base64
1998
+ [CryptoService] Invalid JWS format: Error: Invalid payload base64: Invalid base64url string: Invalid character
1999
+ at CryptoService.parseJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:107:15)
2000
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:169:23)
2001
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:334:42
2002
+ 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
2003
+ 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
2004
+ 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
2005
+ at new Promise (<anonymous>)
2006
+ 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)
2007
+ 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)
2008
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2009
+
2010
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate expectedKid option
2011
+ [CryptoService] Key ID mismatch
2012
+
2013
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate alg option
2014
+ [CryptoService] Unsupported algorithm: EdDSA, expected RS256
2015
+
2016
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should validate Ed25519 key length
2017
+ [CryptoService] Failed to extract public key: Error: Invalid Ed25519 public key length: 5
2018
+ at CryptoService.jwkToBase64PublicKey (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:295:13)
2019
+ at CryptoService.verifyJWS (/Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/crypto.service.ts:249:32)
2020
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:398:42
2021
+ 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
2022
+ 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
2023
+ 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
2024
+ at new Promise (<anonymous>)
2025
+ 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)
2026
+ 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)
2027
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2028
+
2029
+ stderr | src/services/__tests__/crypto.service.test.ts > CryptoService > verifyJWS > should handle signature verification error
2030
+ [CryptoService] Ed25519 verification error: Error: Crypto error
2031
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/crypto.service.test.ts:449:61
2032
+ 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
2033
+ 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
2034
+ 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
2035
+ at new Promise (<anonymous>)
2036
+ 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)
2037
+ 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)
2038
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2039
+ 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)
2040
+ 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)
2041
+
2042
+ ✓ src/services/__tests__/crypto.service.test.ts (34 tests) 11ms
2043
+ stderr | src/services/__tests__/proof-verifier.test.ts > ProofVerifier Security > Signature Verification > should handle signature verification errors gracefully
2044
+ [CryptoService] Ed25519 verification error: Error: Crypto error
2045
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/services/__tests__/proof-verifier.test.ts:328:9
2046
+ 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
2047
+ 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
2048
+ 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
2049
+ at new Promise (<anonymous>)
2050
+ 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)
2051
+ 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)
2052
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2053
+ 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)
2054
+ 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)
2055
+
2056
+ ✓ src/services/__tests__/proof-verifier.test.ts (21 tests) 15ms
2057
+ ✓ src/__tests__/providers/memory.test.ts (34 tests) 13ms
2058
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > New endpoint format (toolProtections object) > should parse oauthProvider from camelCase field
2059
+ [ToolProtectionService] Config loaded from API {
2060
+ source: 'api',
2061
+ toolCount: 2,
2062
+ protectedTools: [ 'read_repos', 'send_email' ],
2063
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2064
+ projectId: 'test-project-123',
2065
+ cacheTtlMs: 300000,
2066
+ cacheExpiresAt: '2025-11-22T07:00:54.666Z'
2067
+ }
2068
+
2069
+ 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
2070
+ [ToolProtectionService] Config loaded from API {
2071
+ source: 'api',
2072
+ toolCount: 1,
2073
+ protectedTools: [ 'read_repos' ],
2074
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2075
+ projectId: 'test-project-123',
2076
+ cacheTtlMs: 300000,
2077
+ cacheExpiresAt: '2025-11-22T07:00:54.671Z'
2078
+ }
2079
+
2080
+ 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
2081
+ [ToolProtectionService] Config loaded from API {
2082
+ source: 'api',
2083
+ toolCount: 1,
2084
+ protectedTools: [ 'read_repos' ],
2085
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2086
+ projectId: 'test-project-123',
2087
+ cacheTtlMs: 300000,
2088
+ cacheExpiresAt: '2025-11-22T07:00:54.672Z'
2089
+ }
2090
+
2091
+ 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)
2092
+ [ToolProtectionService] Config loaded from API {
2093
+ source: 'api',
2094
+ toolCount: 1,
2095
+ protectedTools: [ 'read_repos' ],
2096
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2097
+ projectId: 'test-project-123',
2098
+ cacheTtlMs: 300000,
2099
+ cacheExpiresAt: '2025-11-22T07:00:54.672Z'
2100
+ }
2101
+
2102
+ 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
2103
+ [ToolProtectionService] Config loaded from API {
2104
+ source: 'api',
2105
+ toolCount: 2,
2106
+ protectedTools: [ 'read_repos', 'send_email' ],
2107
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2108
+ projectId: 'none',
2109
+ cacheTtlMs: 300000,
2110
+ cacheExpiresAt: '2025-11-22T07:00:54.672Z'
2111
+ }
2112
+
2113
+ 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
2114
+ [ToolProtectionService] Config loaded from API {
2115
+ source: 'api',
2116
+ toolCount: 1,
2117
+ protectedTools: [ 'read_repos' ],
2118
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2119
+ projectId: 'none',
2120
+ cacheTtlMs: 300000,
2121
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2122
+ }
2123
+
2124
+ 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
2125
+ [ToolProtectionService] Config loaded from API {
2126
+ source: 'api',
2127
+ toolCount: 1,
2128
+ protectedTools: [ 'read_repos' ],
2129
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2130
+ projectId: 'none',
2131
+ cacheTtlMs: 300000,
2132
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2133
+ }
2134
+
2135
+ 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
2136
+ [ToolProtectionService] Config loaded from API {
2137
+ source: 'api',
2138
+ toolCount: 2,
2139
+ protectedTools: [ 'read_repos', 'send_email' ],
2140
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2141
+ projectId: 'none',
2142
+ cacheTtlMs: 300000,
2143
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2144
+ }
2145
+
2146
+ 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
2147
+ [ToolProtectionService] Config loaded from API {
2148
+ source: 'api',
2149
+ toolCount: 1,
2150
+ protectedTools: [ 'read_repos' ],
2151
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2152
+ projectId: 'none',
2153
+ cacheTtlMs: 300000,
2154
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2155
+ }
2156
+
2157
+ 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
2158
+ [ToolProtectionService] Config loaded from API {
2159
+ source: 'api',
2160
+ toolCount: 1,
2161
+ protectedTools: [ 'read_repos' ],
2162
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2163
+ projectId: 'none',
2164
+ cacheTtlMs: 300000,
2165
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2166
+ }
2167
+
2168
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > Caching > should cache oauthProvider field correctly
2169
+ [ToolProtectionService] Config loaded from API {
2170
+ source: 'api',
2171
+ toolCount: 1,
2172
+ protectedTools: [ 'read_repos' ],
2173
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2174
+ projectId: 'test-project-123',
2175
+ cacheTtlMs: 300000,
2176
+ cacheExpiresAt: '2025-11-22T07:00:54.673Z'
2177
+ }
2178
+
2179
+ 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
2180
+ [ToolProtectionService] Config loaded from API {
2181
+ source: 'api',
2182
+ toolCount: 2,
2183
+ protectedTools: [ 'tool_with_provider', 'tool_without_provider' ],
2184
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2185
+ projectId: 'test-project-123',
2186
+ cacheTtlMs: 300000,
2187
+ cacheExpiresAt: '2025-11-22T07:00:54.674Z'
2188
+ }
2189
+
2190
+ stdout | src/__tests__/services/tool-protection-oauth-provider.test.ts > ToolProtectionService - oauthProvider Parsing > oauthProvider field inclusion > should handle empty string oauthProvider gracefully
2191
+ [ToolProtectionService] Config loaded from API {
2192
+ source: 'api',
2193
+ toolCount: 1,
2194
+ protectedTools: [ 'tool_with_empty_provider' ],
2195
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2196
+ projectId: 'test-project-123',
2197
+ cacheTtlMs: 300000,
2198
+ cacheExpiresAt: '2025-11-22T07:00:54.674Z'
2199
+ }
2200
+
2201
+ ✓ src/__tests__/services/tool-protection-oauth-provider.test.ts (14 tests) 9ms
2202
+ ✓ src/delegation/__tests__/delegation-graph.test.ts (28 tests) 9ms
2203
+ ✓ src/delegation/__tests__/cascading-revocation.test.ts (23 tests) 7ms
2204
+ ✓ src/delegation/storage/__tests__/memory-graph-storage.test.ts (27 tests) 4ms
2205
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Full handshake and tool execution flow > should complete full authentication and tool execution cycle
2206
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zeqxrq_Zh-Oegc6fQD_kt1M9ErLXRWDI6","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554785,"timestampFormatted":"2025-11-22T06:55:54.785Z"}
2207
+
2208
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Full handshake and tool execution flow > should complete full authentication and tool execution cycle
2209
+ [AUDIT] {"event":"tool_executed","data":{"tool":"greetingTool","sessionId":"c530c14265ef07e0c752bc47783137c9","timestamp":1763794554785},"timestamp":1763794554785,"timestampFormatted":"2025-11-22T06:55:54.785Z"}
2210
+
2211
+ ✓ src/__tests__/runtime/proof-client-did.test.ts (17 tests) 7ms
2212
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Session expiry handling > should handle expired sessions correctly
2213
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zxzn59vlikLFcjp4Ms1ky9NT58tfd_Nga","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554790,"timestampFormatted":"2025-11-22T06:55:54.790Z"}
2214
+
2215
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Key rotation flow > should handle key rotation and maintain functionality
2216
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zCwsCghSNSMbm1LFk7gdrOt_2A4wnZKDX","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554790,"timestampFormatted":"2025-11-22T06:55:54.790Z"}
2217
+
2218
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Key rotation flow > should handle key rotation and maintain functionality
2219
+ [AUDIT] {"event":"keys_rotated","data":{"oldDid":"did:key:zCwsCghSNSMbm1LFk7gdrOt_2A4wnZKDX","newDid":"did:key:za1bflbxqV3z4fePIgP0pDA9sPJwT-c-2","timestamp":1763794554790},"timestamp":1763794554790,"timestampFormatted":"2025-11-22T06:55:54.790Z"}
2220
+
2221
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Well-known endpoints > should provide identity discovery endpoints
2222
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zMX2zYkeub9P4A0KJFcf2Ub6CkG5Zm7Qx","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554790,"timestampFormatted":"2025-11-22T06:55:54.790Z"}
2223
+
2224
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Nonce replay protection > should prevent nonce reuse
2225
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zJVjnn3r9EqEgOzvAdoqVWPqXoWwW6fb1","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554791,"timestampFormatted":"2025-11-22T06:55:54.791Z"}
2226
+
2227
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Error handling > should handle network errors gracefully
2228
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:z8CR_h7UfAeM44qxgD7oaWnVXpThED5o2","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554791,"timestampFormatted":"2025-11-22T06:55:54.791Z"}
2229
+
2230
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Error handling > should handle malformed DID documents
2231
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zKEZjNv2uz55rsGbJ2-sGcSuqChtFX-tL","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554791,"timestampFormatted":"2025-11-22T06:55:54.791Z"}
2232
+
2233
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Debug endpoint > should provide debug information in development
2234
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:z833pBdL_6KZzuMEWAYx92Y1mpe9aQ7ef","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554791,"timestampFormatted":"2025-11-22T06:55:54.791Z"}
2235
+
2236
+ stdout | src/__tests__/integration.test.ts > Integration Tests > Debug endpoint > should be disabled in production
2237
+ [AUDIT] {"event":"runtime_initialized","data":{"did":"did:key:zJDzMR3c5sqTz2BmfkXQNIpD9RhDLr5td","environment":"development","userDidGeneration":"disabled"},"timestamp":1763794554792,"timestampFormatted":"2025-11-22T06:55:54.792Z"}
2238
+
2239
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if API request fails
2240
+ [RemoteConfig] API returned 404: Not Found
2241
+
2242
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle empty scopes array
2243
+ 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
2244
+ [ProviderResolver] Inferred provider "google" from scopes
2245
+
2246
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2247
+ 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
2248
+ [ProviderResolver] Inferred provider "google" from scopes
2249
+
2250
+
2251
+ 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)
2252
+ 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
2253
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2254
+ [ProviderResolver] Inferred provider "microsoft" from scopes
2255
+
2256
+ 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
2257
+ [ProviderResolver] Inferred provider "github" from scopes
2258
+
2259
+
2260
+ 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
2261
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle unknown scope prefixes
2262
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2263
+ [ProviderResolver] Inferred provider "github" from scopes
2264
+
2265
+
2266
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Scope inference edge cases (Priority 2) > should handle scopes without colons
2267
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2268
+
2269
+ 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
2270
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "google" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2271
+
2272
+ stderr | src/__tests__/services/provider-resolver-edge-cases.test.ts > ProviderResolver - Edge Cases > Fallback behavior (Priority 3) > should use first configured provider when oauthProvider not specified
2273
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2274
+
2275
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if API throws error
2276
+ ✓ src/__tests__/integration.test.ts (9 tests) 8ms
2277
+ [RemoteConfig] Failed to fetch config: Error: Network error
2278
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/config/__tests__/remote-config.spec.ts:170:35
2279
+ 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
2280
+ at file:///Users/dylanhobbs/Documents/@kya-os/xmcp-i/node_modules/.pnpm/@vitest+runner@4.0.5/node_modules/@vitest/runner/dist/index.js:753:26
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:1636:20
2282
+ at new Promise (<anonymous>)
2283
+ 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)
2284
+ 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)
2285
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2286
+ 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)
2287
+ 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)
2288
+
2289
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should return null if neither projectId nor agentDid provided
2290
+ [RemoteConfig] Neither projectId nor agentDid provided
2291
+
2292
+ stderr | src/config/__tests__/remote-config.spec.ts > fetchRemoteConfig > Error handling > should handle cache read errors gracefully
2293
+ [RemoteConfig] Cache read failed: Error: Cache error
2294
+ at /Users/dylanhobbs/Documents/@kya-os/xmcp-i/packages/mcp-i-core/src/config/__tests__/remote-config.spec.ts:198:50
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:157:11
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:753:26
2297
+ 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
2298
+ at new Promise (<anonymous>)
2299
+ 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)
2300
+ 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)
2301
+ at processTicksAndRejections (node:internal/process/task_queues:103:5)
2302
+ 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)
2303
+ 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)
2304
+
2305
+ ✓ src/__tests__/services/provider-resolver-edge-cases.test.ts (19 tests | 1 skipped) 6ms
2306
+ ✓ src/config/__tests__/remote-config.spec.ts (9 tests) 5ms
2307
+ ✓ src/__tests__/providers/base.test.ts (14 tests) 7ms
2308
+ ✓ src/services/__tests__/oauth-provider-registry.test.ts (9 tests) 3ms
2309
+ ✓ src/compliance/__tests__/schema-verifier.test.ts (30 tests) 4ms
2310
+ ✓ src/__tests__/runtime/delegation-flow.test.ts (4 tests) 8ms
2311
+ stdout | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should infer provider from github scope prefix
2312
+ [ProviderResolver] Inferred provider "github" from scopes
2313
+ stderr | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should return null for ambiguous scopes
2314
+
2315
+ stdout | src/services/__tests__/provider-resolver.test.ts > ProviderResolver > resolveProvider - Priority 2: Scope inference > should infer provider from gmail scope prefix (maps to google)
2316
+ [ProviderResolver] Inferred provider "google" from scopes
2317
+
2318
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2319
+
2320
+ ✓ src/services/__tests__/provider-resolver.test.ts (8 tests) 6ms
2321
+ stderr | src/services/__tests__/provider-resolution.integration.test.ts > Provider Resolution Integration > Backward compatibility > should work with Phase 1 tools (no oauthProvider field)
2322
+ [ProviderResolver] Tool does not specify oauthProvider. Using first configured provider "github" as fallback. This is deprecated - configure oauthProvider in AgentShield dashboard for Phase 2+.
2323
+
2324
+ ✓ src/services/__tests__/provider-resolution.integration.test.ts (6 tests) 5ms
2325
+ ✓ src/delegation/__tests__/utils.test.ts (28 tests) 3ms
2326
+ ✓ src/services/__tests__/batch-delegation.service.test.ts (11 tests) 5ms
2327
+ ✓ src/__tests__/runtime/audit-logger.test.ts (9 tests) 2ms
2328
+ ✓ src/utils/__tests__/did-helpers.test.ts (11 tests) 2ms
2329
+ ✓ src/__tests__/config/provider-runtime-config.test.ts (9 tests) 2ms
2330
+ ✓ src/delegation/storage/__tests__/memory-statuslist-storage.test.ts (14 tests) 3ms
2331
+ ✓ src/delegation/__tests__/audience-validator.test.ts (5 tests) 1ms
2332
+ ↓ src/__tests__/delegation-e2e.test.ts (14 tests | 14 skipped)
2333
+ ✓ src/__tests__/index.test.ts (4 tests) 2ms
2334
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Caching Integration > should respect cache TTL
2335
+ [ToolProtectionService] Config loaded from API {
2336
+ source: 'api',
2337
+ toolCount: 0,
2338
+ protectedTools: [],
2339
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2340
+ projectId: 'test-project-123',
2341
+ cacheTtlMs: 1000,
2342
+ cacheExpiresAt: '2025-11-22T06:55:56.520Z'
2343
+ }
2344
+
2345
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle typical e-commerce tool protection config
2346
+ [ToolProtectionService] Config loaded from API {
2347
+ source: 'api',
2348
+ toolCount: 4,
2349
+ protectedTools: [ 'add_to_cart', 'checkout' ],
2350
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2351
+ projectId: 'test-project-123',
2352
+ cacheTtlMs: 300000,
2353
+ cacheExpiresAt: '2025-11-22T07:00:55.520Z'
2354
+ }
2355
+
2356
+ stderr | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle API rate limiting gracefully
2357
+ [ToolProtectionService] API fetch failed, using fallback config {
2358
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2359
+ error: 'Failed to fetch bouncer config: 429 Too Many Requests - Rate limit exceeded'
2360
+ }
2361
+
2362
+ stdout | src/__tests__/services/agentshield-integration.test.ts > AgentShield Integration > Real-world Scenarios > should handle concurrent requests
2363
+ [ToolProtectionService] Config loaded from API {
2364
+ source: 'api',
2365
+ toolCount: 1,
2366
+ protectedTools: [ 'tool1' ],
2367
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2368
+ projectId: 'test-project-123',
2369
+ cacheTtlMs: 300000,
2370
+ cacheExpiresAt: '2025-11-22T07:00:55.521Z'
2371
+ }
2372
+ [ToolProtectionService] Config loaded from API {
2373
+ source: 'api',
2374
+ toolCount: 1,
2375
+ protectedTools: [ 'tool1' ],
2376
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2377
+ projectId: 'test-project-123',
2378
+ cacheTtlMs: 300000,
2379
+ cacheExpiresAt: '2025-11-22T07:00:55.521Z'
2380
+ }
2381
+ [ToolProtectionService] Config loaded from API {
2382
+ source: 'api',
2383
+ toolCount: 1,
2384
+ protectedTools: [ 'tool1' ],
2385
+ agentDid: 'did:key:z6MkhaXgBZDv...',
2386
+ projectId: 'test-project-123',
2387
+ cacheTtlMs: 300000,
2388
+ cacheExpiresAt: '2025-11-22T07:00:55.521Z'
2389
+ }
2390
+
2391
+ ✓ src/__tests__/services/agentshield-integration.test.ts (30 tests) 1112ms
2392
+ ✓ should respect cache TTL 1101ms
2393
+
2394
+ Test Files 42 passed | 1 skipped (43)
2395
+ Tests 864 passed | 16 skipped (880)
2396
+ Start at 00:55:54
2397
+ Duration 1.38s (transform 2.11s, setup 0ms, collect 3.19s, tests 1.92s, environment 3ms, prepare 321ms)
2398
+