multi-agent-protocol 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,641 @@
1
+ # Implementation Plan: ANP-Inspired MAP Improvements
2
+
3
+ ## Proposals Covered
4
+
5
+ | # | Proposal | Effort | Depends On | Status |
6
+ |---|----------|--------|------------|--------|
7
+ | **P6** | Single-Request Federation Auth | Low | — | ✅ Implemented |
8
+ | **P3** | Linked Capability Documents | Medium | — | ✅ Implemented |
9
+ | **P1** | `did:wba` Decentralized Identity | High | P6 | ✅ Implemented |
10
+
11
+ Implementation order: **P6 → P3 → P1** (P3 and P6 are independent; P1 builds on P6). All three phases are complete.
12
+
13
+ ### Backwards Compatibility
14
+
15
+ MAP is pre-release (v0.0.8). All changes are treated as non-breaking for semver purposes. However, for consumer awareness:
16
+
17
+ - **P6**: Fully additive — only optional fields added to existing interfaces.
18
+ - **P3**: Fully additive — only optional fields added to `Agent`, `AgentsListFilter`, register/spawn params.
19
+ - **P1**: Widens `FederationAuth.method` from `"bearer" | "api-key" | "mtls"` to `FederationAuthMethod` (includes `"did:wba"`, `"none"`, `"oauth2"`, `x-${string}`). Existing exhaustive switch statements on `method` will need a `default` case. Acceptable for pre-release.
20
+
21
+ ---
22
+
23
+ ## Phase 1: Single-Request Federation Auth (P6) ✅
24
+
25
+ ### Goal
26
+
27
+ When `auth` credentials are provided in the initial `map/federation/connect` request, the server authenticates immediately in the same round trip — reducing federation connection setup from 2 RTT to 1 RTT.
28
+
29
+ ### Step 1.1: Widen Federation Auth Types
30
+
31
+ **File**: `ts-sdk/src/types/index.ts`
32
+
33
+ **Change A** — Widen `FederationAuth` (~line 1193):
34
+
35
+ ```typescript
36
+ // BEFORE
37
+ export interface FederationAuth {
38
+ method: "bearer" | "api-key" | "mtls";
39
+ credentials?: string;
40
+ }
41
+
42
+ // AFTER
43
+ export type FederationAuthMethod = "bearer" | "api-key" | "mtls" | "none" | "oauth2" | `x-${string}`;
44
+
45
+ export interface FederationAuth {
46
+ method: FederationAuthMethod;
47
+ credentials?: string;
48
+ /** Method-specific additional data */
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ ```
52
+
53
+ **Change B** — Extend `FederationConnectRequestParams` (~line 2152):
54
+
55
+ Add:
56
+ ```typescript
57
+ /** Pre-fetched server auth context (e.g., from .well-known discovery) */
58
+ authContext?: {
59
+ source: "well-known" | "cached" | "configured";
60
+ challenge?: string;
61
+ };
62
+ /** System info about the connecting peer */
63
+ systemInfo?: { name: string; version: string; endpoint: string };
64
+ /** MAP protocol version */
65
+ protocolVersion?: string;
66
+ /** What this peer exposes to the other side */
67
+ exposure?: Record<string, unknown>;
68
+ ```
69
+
70
+ **Change C** — Extend `FederationConnectResponseResult` (~line 2164):
71
+
72
+ Add:
73
+ ```typescript
74
+ /** Federation session ID */
75
+ sessionId?: string;
76
+ /** Authenticated principal (when single-request auth succeeds) */
77
+ principal?: { id: string; issuer?: string; claims?: Record<string, unknown> };
78
+ /** Auth negotiation fallback (when auth not provided or failed recoverably) */
79
+ authRequired?: {
80
+ methods: string[];
81
+ challenge?: string;
82
+ required: boolean;
83
+ };
84
+ ```
85
+
86
+ ### Step 1.2: Update JSON Schema
87
+
88
+ **File**: `schema/schema.json`
89
+
90
+ - Extend `FederationConnectRequest` params (~line 1824) with `authContext`, `systemInfo`, `protocolVersion`, `exposure`
91
+ - Extend `FederationConnectResponse` result (~line 1859) with `sessionId`, `principal`, `authRequired`
92
+ - Widen `auth.method` enum to include `"none"`, `"oauth2"`, and `x-` pattern
93
+
94
+ ### Step 1.3: Extend Server Peer Connection Type
95
+
96
+ **File**: `ts-sdk/src/server/types.ts`
97
+
98
+ Extend `PeerConnection` (~line 1076) with:
99
+ ```typescript
100
+ principal?: { id: string; issuer?: string; claims?: Record<string, unknown> };
101
+ sessionId?: string;
102
+ ```
103
+
104
+ ### Step 1.4: Implement Single-Request Auth in Federation Handler
105
+
106
+ **File**: `ts-sdk/src/server/federation/handlers.ts`
107
+
108
+ Modify the `"map/federation/connect"` handler (~line 74):
109
+
110
+ 1. Accept optional `authManager` in `FederationHandlerOptions`:
111
+ ```typescript
112
+ export interface FederationHandlerOptions {
113
+ gateway: FederationGateway;
114
+ authManager?: AuthManager;
115
+ }
116
+ ```
117
+
118
+ 2. In the handler body:
119
+ - If `params.auth` provided AND `authManager` exists → attempt immediate auth via `authManager.authenticate()`
120
+ - On success → return `{ connected: true, sessionId, principal, systemInfo }`
121
+ - On recoverable failure → return `{ connected: false, authRequired: { methods, challenge } }`
122
+ - If no auth provided AND `authManager.config.required` → return `authRequired`
123
+ - If no auth required → proceed with existing behavior (backwards-compatible)
124
+
125
+ ### Step 1.5: Update Gateway Client Connection
126
+
127
+ **File**: `ts-sdk/src/connection/gateway.ts`
128
+
129
+ Modify `connectToSystem` (~line 257):
130
+ - Accept `authContext` in options
131
+ - Pass `authContext` through in request params
132
+ - Handle `authRequired` response variant (don't add to `#connectedSystems` if not connected)
133
+ - Widen `#lastConnectOptions.auth` type to `FederationAuth`
134
+
135
+ ### Step 1.6: Add Challenge Nonce Utility
136
+
137
+ **New file**: `ts-sdk/src/federation/challenge.ts`
138
+
139
+ ```typescript
140
+ export function generateFederationChallenge(): string;
141
+ export function validateChallengeAge(challenge: string, maxAgeMs: number): boolean;
142
+ ```
143
+
144
+ Simple utility — generates cryptographically random nonce with embedded timestamp for age validation.
145
+
146
+ ### Step 1.7: Tests
147
+
148
+ **New file**: `ts-sdk/src/__tests__/federation-single-request-auth.test.ts`
149
+
150
+ | Test Case | What It Verifies |
151
+ |-----------|-----------------|
152
+ | Auth provided in connect → immediate success | Single-RTT happy path |
153
+ | Auth required but not provided → authRequired response | Negotiation fallback |
154
+ | Auth provided but fails → authRequired with challenge | Recoverable failure |
155
+ | Auth provided, hard failure → error thrown | Non-recoverable failure |
156
+ | No auth required, no auth provided → connects | Backwards compatibility |
157
+
158
+ ### Step 1.8: Documentation
159
+
160
+ - `docs/07-federation.md`: Add "Single-Request Authentication" section after "Connection Establishment"
161
+ - `docs/09-authentication.md`: Add "Federation Authentication Optimization" section
162
+ - `schema/meta.json`: Update `map/federation/connect` description
163
+
164
+ ---
165
+
166
+ ## Phase 2: Linked Capability Documents (P3) ✅
167
+
168
+ ### Goal
169
+
170
+ Add an optional `MAPAgentCapabilityDescriptor` that agents publish at registration time, and extend `map/agents/list` to filter by capability ID, tags, and content type.
171
+
172
+ ### Step 2.1: Define Capability Descriptor Types
173
+
174
+ **File**: `ts-sdk/src/types/index.ts`
175
+
176
+ Add after `AgentEnvironment` (~line 131):
177
+
178
+ ```typescript
179
+ export interface MAPAgentCapabilityDescriptor {
180
+ version: 1;
181
+ description: string;
182
+ capabilities: MAPCapabilityDeclaration[];
183
+ accepts?: MAPInterfaceSpec[];
184
+ produces?: MAPInterfaceSpec[];
185
+ documentationUrl?: string;
186
+ tags?: string[];
187
+ }
188
+
189
+ export interface MAPCapabilityDeclaration {
190
+ id: string; // e.g., "doc:summarize"
191
+ name: string; // e.g., "Document Summarization"
192
+ description: string;
193
+ interfaceRef?: string; // URL to detailed spec
194
+ interface?: MAPInterfaceSpec; // Inline spec
195
+ }
196
+
197
+ export interface MAPInterfaceSpec {
198
+ contentType: string; // e.g., "application/json"
199
+ schema?: Record<string, unknown>; // JSON Schema
200
+ schemaRef?: string; // URL to external schema
201
+ example?: unknown;
202
+ }
203
+ ```
204
+
205
+ ### Step 2.2: Extend Agent Model
206
+
207
+ **File**: `ts-sdk/src/types/index.ts`
208
+
209
+ Add to `Agent` interface (~line 352, after `environment`):
210
+ ```typescript
211
+ capabilityDescriptor?: MAPAgentCapabilityDescriptor;
212
+ ```
213
+
214
+ Add to `AgentsRegisterRequestParams` (~line 1391):
215
+ ```typescript
216
+ capabilityDescriptor?: MAPAgentCapabilityDescriptor;
217
+ ```
218
+
219
+ Add to `AgentsSpawnRequestParams` (~line 1458):
220
+ ```typescript
221
+ capabilityDescriptor?: MAPAgentCapabilityDescriptor;
222
+ ```
223
+
224
+ ### Step 2.3: Extend List Filters
225
+
226
+ **File**: `ts-sdk/src/types/index.ts`
227
+
228
+ Add to `AgentsListFilter` (~line 1333):
229
+ ```typescript
230
+ capabilityId?: string; // Filter by capability declaration ID
231
+ tags?: string[]; // Filter by semantic tags
232
+ accepts?: string; // Filter by accepted content type
233
+ ```
234
+
235
+ ### Step 2.4: Extend Server Types
236
+
237
+ **File**: `ts-sdk/src/server/types.ts`
238
+
239
+ Add to `RegisteredAgent` (~line 142):
240
+ ```typescript
241
+ capabilityDescriptor?: import('../types').MAPAgentCapabilityDescriptor;
242
+ ```
243
+
244
+ Add to `AgentFilter` (~line 170):
245
+ ```typescript
246
+ capabilityId?: string;
247
+ tag?: string;
248
+ accepts?: string;
249
+ ```
250
+
251
+ Extend `AgentRegistry.register()` signature (~line 211) to accept `capabilityDescriptor`.
252
+
253
+ ### Step 2.5: Implement Storage Filtering
254
+
255
+ **File**: `ts-sdk/src/server/agents/stores/in-memory.ts`
256
+
257
+ Extend `list()` method (~line 36) with three new filter branches:
258
+
259
+ ```typescript
260
+ // After existing role/state/scope filters:
261
+
262
+ if (filter?.capabilityId) {
263
+ const match = agent.capabilityDescriptor?.capabilities?.some(
264
+ (cap) => cap.id === filter.capabilityId
265
+ );
266
+ if (!match) continue;
267
+ }
268
+
269
+ if (filter?.tag) {
270
+ if (!agent.capabilityDescriptor?.tags?.includes(filter.tag)) continue;
271
+ }
272
+
273
+ if (filter?.accepts) {
274
+ const match = agent.capabilityDescriptor?.accepts?.some(
275
+ (spec) => spec.contentType === filter.accepts
276
+ );
277
+ if (!match) continue;
278
+ }
279
+ ```
280
+
281
+ ### Step 2.6: Implement Handler Changes
282
+
283
+ **File**: `ts-sdk/src/server/agents/handlers.ts`
284
+
285
+ **A.** Extend `RegisterParams` (~line 45) with `capabilityDescriptor`
286
+
287
+ **B.** Modify `"map/agents/register"` handler (~line 139):
288
+ - Pass `capabilityDescriptor` to `agents.register()`
289
+ - Include `capabilityDescriptor` in response
290
+
291
+ **C.** Extend `ListParams` (~line 70) with `capabilityId`, `tags`, `accepts`
292
+
293
+ **D.** Modify `"map/agents/list"` handler (~line 194):
294
+ - Map new filter params to `AgentFilter`
295
+ - Include `capabilityDescriptor` in response objects
296
+
297
+ **E.** Modify `"map/agents/get"` handler (~line 212):
298
+ - Include `capabilityDescriptor` in response
299
+
300
+ ### Step 2.7: Update Agent Registry
301
+
302
+ **File**: `ts-sdk/src/server/agents/registry.ts`
303
+
304
+ Modify `register()` (~line 215):
305
+ - Accept `capabilityDescriptor` in params
306
+ - Store it on the `RegisteredAgent` object
307
+
308
+ ### Step 2.8: Update Federation Agent Decorator
309
+
310
+ **File**: `ts-sdk/src/server/federation/decorators/agents.ts`
311
+
312
+ - Update `register()` (~line 75) to accept and pass through `capabilityDescriptor`
313
+ - Update `broadcastAgentEvent()` (~line 228) to include `capabilityDescriptor` in broadcast payload
314
+
315
+ ### Step 2.9: Update JSON Schema
316
+
317
+ **File**: `schema/schema.json`
318
+
319
+ **A.** Add to `$defs`:
320
+ - `MAPAgentCapabilityDescriptor` (required: `version`, `description`, `capabilities`)
321
+ - `MAPCapabilityDeclaration` (required: `id`, `name`, `description`)
322
+ - `MAPInterfaceSpec` (required: `contentType`)
323
+
324
+ **B.** Add `capabilityDescriptor` property to:
325
+ - `Agent` definition (~line 408)
326
+ - `AgentsRegisterRequest` params (~line 1252)
327
+ - `AgentsSpawnRequest` params (~line 1292)
328
+
329
+ **C.** Add filter properties to `AgentsListRequest` params (~line 1040):
330
+ - `capabilityId`: string
331
+ - `tags`: array of strings
332
+ - `accepts`: string
333
+
334
+ ### Step 2.10: Tests
335
+
336
+ **New file**: `ts-sdk/src/__tests__/capability-descriptor.test.ts`
337
+
338
+ | Test Case | What It Verifies |
339
+ |-----------|-----------------|
340
+ | Register agent with capabilityDescriptor | Stored and returned correctly |
341
+ | Get agent includes capabilityDescriptor | Field appears in get response |
342
+ | List filter by capabilityId | Only matching agents returned |
343
+ | List filter by tag | Only matching agents returned |
344
+ | List filter by accepts content type | Only matching agents returned |
345
+ | Combined filters (capabilityId + role) | Intersection semantics |
346
+ | Agent without capabilityDescriptor | Still registers and lists normally |
347
+ | Spawn with capabilityDescriptor | Descriptor propagated to spawned agent |
348
+
349
+ **Modify**: `ts-sdk/src/__tests__/server-agents.test.ts` — add cases for new filter fields in `InMemoryAgentStore.list()`
350
+
351
+ ### Step 2.11: Documentation
352
+
353
+ - `docs/00-design-specification.md`: Add capability descriptor to Agent model section, show example registration
354
+ - Reference the design spec (`docs/11-anp-inspired-improvements.md`) for the full rationale
355
+
356
+ ---
357
+
358
+ ## Phase 3: `did:wba` Decentralized Identity (P1) ✅
359
+
360
+ ### Goal
361
+
362
+ Add `did:wba` as a federation authentication method. DID resolution via HTTPS provides domain-verified identity without pre-shared secrets.
363
+
364
+ ### Step 3.1: Add `did:wba` to Auth Types
365
+
366
+ **File**: `ts-sdk/src/types/index.ts`
367
+
368
+ **A.** Extend `StandardAuthMethod` (~line 1108):
369
+ ```typescript
370
+ export type StandardAuthMethod = "bearer" | "api-key" | "mtls" | "none" | "did:wba";
371
+ ```
372
+
373
+ **B.** Add after `FederationAuth` (~line 1196):
374
+ ```typescript
375
+ export interface DIDWBACredentials {
376
+ method: "did:wba";
377
+ did: string;
378
+ proof: DIDWBAProof;
379
+ }
380
+
381
+ export interface DIDWBAProof {
382
+ type: string; // e.g., "JsonWebSignature2020"
383
+ created: string; // ISO 8601
384
+ challenge: string; // Server-provided nonce
385
+ jws: string; // Signature over (challenge + did + created)
386
+ }
387
+
388
+ export interface DIDDocument {
389
+ "@context": string[];
390
+ id: string;
391
+ verificationMethod?: DIDVerificationMethod[];
392
+ authentication?: string[];
393
+ service?: DIDService[];
394
+ }
395
+
396
+ export interface DIDVerificationMethod {
397
+ id: string;
398
+ type: string;
399
+ controller: string;
400
+ publicKeyJwk?: Record<string, unknown>;
401
+ }
402
+
403
+ export interface DIDService {
404
+ id: string;
405
+ type: string;
406
+ serviceEndpoint: string;
407
+ mapProtocolVersion?: number;
408
+ mapCapabilities?: Record<string, boolean>;
409
+ }
410
+ ```
411
+
412
+ **C.** Create union type:
413
+ ```typescript
414
+ export type MAPFederationAuth = FederationAuth | DIDWBACredentials;
415
+ ```
416
+
417
+ Update `FederationConnectRequestParams.auth` type from `FederationAuth` to `MAPFederationAuth`.
418
+
419
+ **D.** Add error codes to `FEDERATION_ERROR_CODES` (~line 3093):
420
+ ```typescript
421
+ FEDERATION_DID_RESOLUTION_FAILED: 5004,
422
+ FEDERATION_DID_PROOF_INVALID: 5005,
423
+ ```
424
+
425
+ ### Step 3.2: Create DID Resolver Module
426
+
427
+ **New file**: `ts-sdk/src/federation/did-wba/resolver.ts`
428
+
429
+ ```
430
+ Class: DIDWBAResolver
431
+ - constructor(options?: { cacheTtlMs?, timeoutMs?, fetch? })
432
+ - resolve(did: string): Promise<DIDDocument>
433
+ - extractMAPEndpoint(doc: DIDDocument): string | undefined
434
+ - extractVerificationKeys(doc: DIDDocument): DIDVerificationMethod[]
435
+ - clearCache(): void
436
+
437
+ Functions:
438
+ - parseDIDWBA(did) → { domain, path }
439
+ - didToUrl(did) → HTTPS URL for DID document
440
+ ```
441
+
442
+ Resolution logic:
443
+ ```
444
+ did:wba:agents.example.com:worker-alpha
445
+ → parse → domain: "agents.example.com", path: "worker-alpha"
446
+ → construct → https://agents.example.com/worker-alpha/did.json
447
+ → fetch → DIDDocument
448
+ → cache with TTL
449
+ ```
450
+
451
+ ### Step 3.3: Create Proof Generation/Verification Module
452
+
453
+ **New file**: `ts-sdk/src/federation/did-wba/proof.ts`
454
+
455
+ ```
456
+ Functions:
457
+ - generateDIDWBAProof({ did, challenge, privateKey, proofType? }) → DIDWBAProof
458
+ - verifyDIDWBAProof({ did, proof, publicKey, maxAgeMs? }) → Promise<boolean>
459
+ ```
460
+
461
+ Proof generation:
462
+ 1. Construct payload: `JSON.stringify({ did, challenge, created })`
463
+ 2. Sign with private key (JWS compact serialization)
464
+ 3. Return `{ type, created, challenge, jws }`
465
+
466
+ Proof verification:
467
+ 1. Check proof age (`created` within `maxAgeMs`)
468
+ 2. Reconstruct payload from proof fields
469
+ 3. Verify JWS against public key
470
+ 4. Return boolean
471
+
472
+ ### Step 3.4: Create Module Index
473
+
474
+ **New file**: `ts-sdk/src/federation/did-wba/index.ts`
475
+
476
+ Re-exports `DIDWBAResolver`, `parseDIDWBA`, `didToUrl`, `generateDIDWBAProof`, `verifyDIDWBAProof`.
477
+
478
+ ### Step 3.5: Create Server-Side Authenticator
479
+
480
+ **New file**: `ts-sdk/src/server/auth/did-wba-authenticator.ts`
481
+
482
+ ```
483
+ Class: DIDWBAAuthenticator implements Authenticator
484
+ - methods: ['did:wba']
485
+ - constructor(options?: { resolver?, trustedDomains?, challengeTtlMs? })
486
+ - authenticate(credentials, context): Promise<AuthResult>
487
+ - generateChallenge(): string
488
+ - isTrustedDomain(did): boolean
489
+ ```
490
+
491
+ Authentication flow:
492
+ 1. Parse DID from credentials
493
+ 2. Validate DID matches trusted domain patterns (if configured)
494
+ 3. Resolve DID document via `DIDWBAResolver`
495
+ 4. Extract verification key matching `authentication` relationship
496
+ 5. Verify proof via `verifyDIDWBAProof()`
497
+ 6. Return `AuthResult` with principal `{ id: did, issuer: domain }`
498
+
499
+ ### Step 3.6: Wire Up Exports
500
+
501
+ **File**: `ts-sdk/src/server/auth/index.ts`
502
+ - Export `DIDWBAAuthenticator` and `DIDWBAAuthenticatorOptions`
503
+
504
+ **File**: `ts-sdk/src/federation/index.ts`
505
+ - Export `DIDWBAResolver`, `parseDIDWBA`, `didToUrl`, `generateDIDWBAProof`, `verifyDIDWBAProof`
506
+
507
+ ### Step 3.7: Extend Auth Context
508
+
509
+ **File**: `ts-sdk/src/server/auth/types.ts`
510
+
511
+ Add to `AuthContext` (~line 20):
512
+ ```typescript
513
+ didInfo?: { did: string; domain: string };
514
+ ```
515
+
516
+ ### Step 3.8: Update JSON Schema
517
+
518
+ **File**: `schema/schema.json`
519
+
520
+ **A.** Add `DIDWBACredentials` definition:
521
+ ```json
522
+ {
523
+ "type": "object",
524
+ "properties": {
525
+ "method": { "const": "did:wba" },
526
+ "did": { "type": "string", "pattern": "^did:wba:" },
527
+ "proof": {
528
+ "type": "object",
529
+ "properties": {
530
+ "type": { "type": "string" },
531
+ "created": { "type": "string", "format": "date-time" },
532
+ "challenge": { "type": "string" },
533
+ "jws": { "type": "string" }
534
+ },
535
+ "required": ["type", "created", "challenge", "jws"]
536
+ }
537
+ },
538
+ "required": ["method", "did", "proof"]
539
+ }
540
+ ```
541
+
542
+ **B.** Update `FederationConnectRequest.params.auth` to `oneOf` including existing auth + `DIDWBACredentials`
543
+
544
+ **C.** Add error codes 5004, 5005 to error definitions
545
+
546
+ **File**: `schema/meta.json`
547
+ - Add `DID_RESOLUTION_FAILED` (5004) and `DID_PROOF_INVALID` (5005) to federation errors
548
+
549
+ ### Step 3.9: Tests
550
+
551
+ **New file**: `ts-sdk/src/__tests__/did-wba-resolver.test.ts`
552
+
553
+ | Test Case | What It Verifies |
554
+ |-----------|-----------------|
555
+ | Parse valid `did:wba` string | Extracts domain + path correctly |
556
+ | Parse multi-segment path | `did:wba:example.com:agents:worker` works |
557
+ | Convert DID to URL | Correct HTTPS URL constructed |
558
+ | Resolve DID document (mocked fetch) | Document returned, cache populated |
559
+ | Cache hit on second resolve | No second fetch |
560
+ | Cache expiry | Fetches again after TTL |
561
+ | Invalid DID format → error | Throws on `did:key:...` |
562
+ | Network failure → error | Throws descriptive error |
563
+ | Extract MAP service endpoint | Finds `MAPFederationEndpoint` service |
564
+ | Extract verification keys | Returns keys from `authentication` relationship |
565
+
566
+ **New file**: `ts-sdk/src/__tests__/did-wba-proof.test.ts`
567
+
568
+ | Test Case | What It Verifies |
569
+ |-----------|-----------------|
570
+ | Generate proof with EC P-256 key | Valid JWS produced |
571
+ | Verify valid proof | Returns true |
572
+ | Reject expired proof (old `created`) | Returns false |
573
+ | Reject wrong challenge | Returns false |
574
+ | Reject wrong signing key | Returns false |
575
+ | Reject tampered payload | Returns false |
576
+
577
+ **New file**: `ts-sdk/src/__tests__/did-wba-authenticator.test.ts`
578
+
579
+ | Test Case | What It Verifies |
580
+ |-----------|-----------------|
581
+ | Full happy path (resolve → verify → principal) | End-to-end auth works |
582
+ | Trusted domain filtering | Rejects untrusted domains |
583
+ | Challenge nonce generation | Unique, time-embedded |
584
+ | Stale challenge rejection | Rejects old challenges |
585
+ | DID resolution failure → AuthResult.success=false | Graceful failure |
586
+ | Proof verification failure → AuthResult.success=false | Graceful failure |
587
+ | Integration with AuthManager | Works when registered as authenticator |
588
+
589
+ ### Step 3.10: Documentation
590
+
591
+ - `docs/09-authentication.md`:
592
+ - Add `did:wba` row to methods table
593
+ - Add "DID:WBA Authentication" section with resolution flow, proof format, trust model
594
+ - Add DID Document example with MAP service endpoint
595
+ - Add "Trust Model Comparison" table (mtls vs bearer vs api-key vs did:wba)
596
+
597
+ - `docs/07-federation.md`:
598
+ - Add `did:wba` to `MAPFederationAuth` type
599
+ - Add "DID-Based Federation Identity" section
600
+ - Add example federation connect with `did:wba` credentials
601
+
602
+ ---
603
+
604
+ ## File Change Summary
605
+
606
+ ### New Files (7)
607
+
608
+ | File | Phase | Purpose |
609
+ |------|-------|---------|
610
+ | `ts-sdk/src/federation/challenge.ts` | P6 | Challenge nonce utility |
611
+ | `ts-sdk/src/federation/did-wba/index.ts` | P1 | Module re-exports |
612
+ | `ts-sdk/src/federation/did-wba/resolver.ts` | P1 | DID document resolution + cache |
613
+ | `ts-sdk/src/federation/did-wba/proof.ts` | P1 | Proof generation + verification |
614
+ | `ts-sdk/src/server/auth/did-wba-authenticator.ts` | P1 | Server-side DID authenticator |
615
+ | `ts-sdk/src/__tests__/federation-single-request-auth.test.ts` | P6 | Single-request auth tests |
616
+ | `ts-sdk/src/__tests__/capability-descriptor.test.ts` | P3 | Capability descriptor tests |
617
+ | `ts-sdk/src/__tests__/did-wba-resolver.test.ts` | P1 | DID resolver tests |
618
+ | `ts-sdk/src/__tests__/did-wba-proof.test.ts` | P1 | Proof gen/verify tests |
619
+ | `ts-sdk/src/__tests__/did-wba-authenticator.test.ts` | P1 | Authenticator integration tests |
620
+
621
+ ### Modified Files (15)
622
+
623
+ | File | Phases | Changes |
624
+ |------|--------|---------|
625
+ | `ts-sdk/src/types/index.ts` | P6, P3, P1 | Widen `FederationAuth`, add capability descriptor types, add DID types, extend agent/filter/register interfaces |
626
+ | `ts-sdk/src/server/types.ts` | P6, P3 | Extend `PeerConnection`, `RegisteredAgent`, `AgentFilter`, `AgentRegistry` |
627
+ | `ts-sdk/src/server/federation/handlers.ts` | P6 | Add `authManager` option, single-request auth logic |
628
+ | `ts-sdk/src/server/federation/gateway.ts` | P6 | Store principal/session on peer connections |
629
+ | `ts-sdk/src/connection/gateway.ts` | P6 | Handle `authContext`, `authRequired` response |
630
+ | `ts-sdk/src/server/agents/registry.ts` | P3 | Accept/store `capabilityDescriptor` |
631
+ | `ts-sdk/src/server/agents/stores/in-memory.ts` | P3 | Filter by capabilityId, tag, accepts |
632
+ | `ts-sdk/src/server/agents/handlers.ts` | P3 | Pass through descriptor in register/list/get |
633
+ | `ts-sdk/src/server/federation/decorators/agents.ts` | P3 | Include descriptor in federation broadcasts |
634
+ | `ts-sdk/src/server/auth/index.ts` | P1 | Export `DIDWBAAuthenticator` |
635
+ | `ts-sdk/src/server/auth/types.ts` | P1 | Add `didInfo` to `AuthContext` |
636
+ | `ts-sdk/src/federation/index.ts` | P1 | Re-export DID utilities |
637
+ | `schema/schema.json` | P6, P3, P1 | Federation auth schemas, capability descriptor schemas, DID credential schema |
638
+ | `schema/meta.json` | P6, P1 | Update federation/connect description, add DID error codes |
639
+ | `docs/07-federation.md` | P6, P1 | Single-request auth section, DID federation section |
640
+ | `docs/09-authentication.md` | P6, P1 | Federation auth optimization, did:wba method |
641
+ | `docs/00-design-specification.md` | P3 | Capability descriptor in agent model |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multi-agent-protocol",
3
- "version": "0.0.4",
3
+ "version": "0.1.0",
4
4
  "description": "Multi-Agent Protocol (MAP) - A protocol for observing, coordinating, and routing messages within multi-agent AI systems",
5
5
  "type": "module",
6
6
  "main": "./schema/schema.json",