@kya-os/mcp-i-core 1.3.0 → 1.3.2

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