macro-agent 0.0.13 → 0.0.15

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 (143) hide show
  1. package/.claude/settings.local.json +59 -0
  2. package/dist/agent/agent-manager.d.ts.map +1 -1
  3. package/dist/agent/agent-manager.js +10 -4
  4. package/dist/agent/agent-manager.js.map +1 -1
  5. package/dist/cli/acp.d.ts +6 -0
  6. package/dist/cli/acp.d.ts.map +1 -1
  7. package/dist/cli/acp.js +16 -2
  8. package/dist/cli/acp.js.map +1 -1
  9. package/dist/map/adapter/index.d.ts +1 -1
  10. package/dist/map/adapter/index.d.ts.map +1 -1
  11. package/dist/map/adapter/index.js +1 -1
  12. package/dist/map/adapter/index.js.map +1 -1
  13. package/dist/map/utils/address-translation.d.ts +99 -0
  14. package/dist/map/utils/address-translation.d.ts.map +1 -0
  15. package/dist/map/utils/address-translation.js +285 -0
  16. package/dist/map/utils/address-translation.js.map +1 -0
  17. package/dist/map/utils/index.d.ts +7 -0
  18. package/dist/map/utils/index.d.ts.map +1 -0
  19. package/dist/map/utils/index.js +7 -0
  20. package/dist/map/utils/index.js.map +1 -0
  21. package/dist/server/combined-server.d.ts.map +1 -1
  22. package/dist/server/combined-server.js +8 -1
  23. package/dist/server/combined-server.js.map +1 -1
  24. package/dist/store/event-store.js +9 -2
  25. package/dist/store/event-store.js.map +1 -1
  26. package/dist/store/types/agents.d.ts +2 -0
  27. package/dist/store/types/agents.d.ts.map +1 -1
  28. package/package.json +4 -4
  29. package/references/acp-factory-ref/CHANGELOG.md +33 -0
  30. package/references/acp-factory-ref/LICENSE +21 -0
  31. package/references/acp-factory-ref/README.md +341 -0
  32. package/references/acp-factory-ref/package-lock.json +3102 -0
  33. package/references/acp-factory-ref/package.json +96 -0
  34. package/references/acp-factory-ref/python/CHANGELOG.md +33 -0
  35. package/references/acp-factory-ref/python/LICENSE +21 -0
  36. package/references/acp-factory-ref/python/Makefile +57 -0
  37. package/references/acp-factory-ref/python/README.md +253 -0
  38. package/references/acp-factory-ref/python/pyproject.toml +73 -0
  39. package/references/acp-factory-ref/python/tests/__init__.py +0 -0
  40. package/references/acp-factory-ref/python/tests/e2e/__init__.py +1 -0
  41. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +349 -0
  42. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +165 -0
  43. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +296 -0
  44. package/references/acp-factory-ref/python/tests/test_client_handler.py +543 -0
  45. package/references/acp-factory-ref/python/tests/test_pushable.py +199 -0
  46. package/references/claude-code-acp/.github/workflows/ci.yml +45 -0
  47. package/references/claude-code-acp/.github/workflows/publish.yml +34 -0
  48. package/references/claude-code-acp/.prettierrc.json +4 -0
  49. package/references/claude-code-acp/CHANGELOG.md +249 -0
  50. package/references/claude-code-acp/LICENSE +222 -0
  51. package/references/claude-code-acp/README.md +53 -0
  52. package/references/claude-code-acp/docs/RELEASES.md +24 -0
  53. package/references/claude-code-acp/eslint.config.js +48 -0
  54. package/references/claude-code-acp/package-lock.json +4570 -0
  55. package/references/claude-code-acp/package.json +88 -0
  56. package/references/claude-code-acp/scripts/release.sh +119 -0
  57. package/references/claude-code-acp/src/acp-agent.ts +2079 -0
  58. package/references/claude-code-acp/src/index.ts +26 -0
  59. package/references/claude-code-acp/src/lib.ts +38 -0
  60. package/references/claude-code-acp/src/mcp-server.ts +911 -0
  61. package/references/claude-code-acp/src/settings.ts +522 -0
  62. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +5 -0
  63. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +6 -0
  64. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +479 -0
  65. package/references/claude-code-acp/src/tests/acp-agent.test.ts +1502 -0
  66. package/references/claude-code-acp/src/tests/extract-lines.test.ts +103 -0
  67. package/references/claude-code-acp/src/tests/fork-session.test.ts +335 -0
  68. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +334 -0
  69. package/references/claude-code-acp/src/tests/settings.test.ts +617 -0
  70. package/references/claude-code-acp/src/tests/skills-options.test.ts +187 -0
  71. package/references/claude-code-acp/src/tests/tools.test.ts +318 -0
  72. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +558 -0
  73. package/references/claude-code-acp/src/tools.ts +819 -0
  74. package/references/claude-code-acp/src/utils.ts +171 -0
  75. package/references/claude-code-acp/tsconfig.json +18 -0
  76. package/references/claude-code-acp/vitest.config.ts +19 -0
  77. package/references/multi-agent-protocol/.sudocode/issues.jsonl +111 -0
  78. package/references/multi-agent-protocol/.sudocode/specs.jsonl +13 -0
  79. package/references/multi-agent-protocol/LICENSE +21 -0
  80. package/references/multi-agent-protocol/README.md +113 -0
  81. package/references/multi-agent-protocol/docs/00-design-specification.md +496 -0
  82. package/references/multi-agent-protocol/docs/01-open-questions.md +1050 -0
  83. package/references/multi-agent-protocol/docs/02-wire-protocol.md +296 -0
  84. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +252 -0
  85. package/references/multi-agent-protocol/docs/04-error-handling.md +231 -0
  86. package/references/multi-agent-protocol/docs/05-connection-model.md +244 -0
  87. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +243 -0
  88. package/references/multi-agent-protocol/docs/07-federation.md +259 -0
  89. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +253 -0
  90. package/references/multi-agent-protocol/docs/09-authentication.md +680 -0
  91. package/references/multi-agent-protocol/docs/10-mail-protocol.md +553 -0
  92. package/references/multi-agent-protocol/docs/agent-iam-integration.md +877 -0
  93. package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +459 -0
  94. package/references/multi-agent-protocol/docs/git-transport-draft.md +251 -0
  95. package/references/multi-agent-protocol/docs-site/Gemfile +22 -0
  96. package/references/multi-agent-protocol/docs-site/README.md +82 -0
  97. package/references/multi-agent-protocol/docs-site/_config.yml +91 -0
  98. package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +20 -0
  99. package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +42 -0
  100. package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +34 -0
  101. package/references/multi-agent-protocol/docs-site/examples/full-integration.md +510 -0
  102. package/references/multi-agent-protocol/docs-site/examples/index.md +138 -0
  103. package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +282 -0
  104. package/references/multi-agent-protocol/docs-site/examples/task-queue.md +399 -0
  105. package/references/multi-agent-protocol/docs-site/getting-started/index.md +98 -0
  106. package/references/multi-agent-protocol/docs-site/getting-started/installation.md +219 -0
  107. package/references/multi-agent-protocol/docs-site/getting-started/overview.md +172 -0
  108. package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +237 -0
  109. package/references/multi-agent-protocol/docs-site/index.md +136 -0
  110. package/references/multi-agent-protocol/docs-site/protocol/authentication.md +391 -0
  111. package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +376 -0
  112. package/references/multi-agent-protocol/docs-site/protocol/design.md +284 -0
  113. package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +312 -0
  114. package/references/multi-agent-protocol/docs-site/protocol/federation.md +449 -0
  115. package/references/multi-agent-protocol/docs-site/protocol/index.md +129 -0
  116. package/references/multi-agent-protocol/docs-site/protocol/permissions.md +398 -0
  117. package/references/multi-agent-protocol/docs-site/protocol/streaming.md +353 -0
  118. package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +369 -0
  119. package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +357 -0
  120. package/references/multi-agent-protocol/docs-site/sdk/api/client.md +380 -0
  121. package/references/multi-agent-protocol/docs-site/sdk/api/index.md +62 -0
  122. package/references/multi-agent-protocol/docs-site/sdk/api/server.md +453 -0
  123. package/references/multi-agent-protocol/docs-site/sdk/api/types.md +468 -0
  124. package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +375 -0
  125. package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +405 -0
  126. package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +352 -0
  127. package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +89 -0
  128. package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +360 -0
  129. package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +446 -0
  130. package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +363 -0
  131. package/references/multi-agent-protocol/docs-site/sdk/index.md +206 -0
  132. package/references/multi-agent-protocol/package-lock.json +3886 -0
  133. package/references/multi-agent-protocol/package.json +56 -0
  134. package/references/multi-agent-protocol/schema/meta.json +467 -0
  135. package/references/multi-agent-protocol/schema/schema.json +2558 -0
  136. package/src/agent/__tests__/agent-manager.test.ts +67 -1
  137. package/src/agent/agent-manager.ts +10 -4
  138. package/src/cli/__tests__/stable-instance-id.test.ts +57 -0
  139. package/src/cli/acp.ts +17 -2
  140. package/src/map/adapter/index.ts +3 -0
  141. package/src/server/combined-server.ts +10 -0
  142. package/src/store/event-store.ts +10 -3
  143. package/src/store/types/agents.ts +2 -0
@@ -0,0 +1,231 @@
1
+ # MAP Error Handling & Failure Modes
2
+
3
+ This spec details how MAP handles errors, failures, and recovery across single-node and federated deployments.
4
+
5
+ ## Design Goals
6
+
7
+ 1. **Graceful degradation** - Partial failures don't cascade to total failure
8
+ 2. **Clear error taxonomy** - Distinct error types with actionable codes
9
+ 3. **Recovery semantics** - Well-defined reconnection and replay behavior
10
+ 4. **Federation resilience** - Cross-system failures handled gracefully
11
+ 5. **Observability** - Errors are traceable and debuggable
12
+
13
+ ---
14
+
15
+ ## Error Taxonomy
16
+
17
+ ### Error Categories
18
+
19
+ ```typescript
20
+ type MAPErrorCategory =
21
+ | "protocol" // Wire protocol violations
22
+ | "auth" // Authentication/authorization
23
+ | "routing" // Message delivery failures
24
+ | "agent" // Agent lifecycle errors
25
+ | "resource" // Resource exhaustion
26
+ | "federation" // Cross-system errors
27
+ | "internal"; // Server internal errors
28
+ ```
29
+
30
+ ### Error Structure
31
+
32
+ ```typescript
33
+ interface MAPError {
34
+ code: number; // Numeric code
35
+ category: MAPErrorCategory;
36
+ message: string; // Human-readable
37
+
38
+ details?: {
39
+ agentId?: string;
40
+ messageId?: string;
41
+ method?: string;
42
+ retryable?: boolean;
43
+ retryAfter?: number;
44
+ recoveryHint?: string;
45
+ };
46
+
47
+ traceId?: string;
48
+ timestamp?: number;
49
+ }
50
+ ```
51
+
52
+ ### Error Codes
53
+
54
+ ```typescript
55
+ // Protocol errors (-32xxx range, JSON-RPC compatible)
56
+ PARSE_ERROR: -32700,
57
+ INVALID_REQUEST: -32600,
58
+ METHOD_NOT_FOUND: -32601,
59
+ INVALID_PARAMS: -32602,
60
+ INTERNAL_ERROR: -32603,
61
+
62
+ // Authentication errors (1xxx)
63
+ AUTH_REQUIRED: 1000,
64
+ AUTH_FAILED: 1001,
65
+ AUTH_EXPIRED: 1002,
66
+ PERMISSION_DENIED: 1003,
67
+
68
+ // Routing errors (2xxx)
69
+ AGENT_NOT_FOUND: 2000,
70
+ AGENT_STOPPED: 2001,
71
+ AGENT_BUSY: 2002,
72
+ DELIVERY_FAILED: 2006,
73
+ DELIVERY_TIMEOUT: 2007,
74
+
75
+ // Agent lifecycle errors (3xxx)
76
+ AGENT_EXISTS: 3000,
77
+ INVALID_PARENT: 3001,
78
+ HIERARCHY_CYCLE: 3002,
79
+ MAX_AGENTS_EXCEEDED: 3003,
80
+
81
+ // Resource errors (4xxx)
82
+ RATE_LIMITED: 4000,
83
+ QUOTA_EXCEEDED: 4001,
84
+ BUFFER_OVERFLOW: 4002,
85
+
86
+ // Federation errors (5xxx)
87
+ PEER_UNREACHABLE: 5000,
88
+ PEER_TIMEOUT: 5001,
89
+ PEER_REJECTED: 5002,
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Agent Failure Modes
95
+
96
+ ```
97
+ 1. Graceful Shutdown
98
+ Agent: sends shutdown intent
99
+ Server: drains queue, notifies parent, cleans up
100
+ Recovery: None needed (intentional)
101
+
102
+ 2. Crash (Unexpected Termination)
103
+ Detection: Heartbeat timeout, process exit
104
+ Server: Marks stopped, notifies parent, orphan handling
105
+ Recovery: Restart with same ID or spawn replacement
106
+
107
+ 3. Hang (Unresponsive)
108
+ Detection: Request timeout, no heartbeat
109
+ Server: Marks blocked, notifies parent
110
+ Recovery: Force restart or manual intervention
111
+
112
+ 4. Error Loop (Repeated Failures)
113
+ Detection: Error rate threshold exceeded
114
+ Server: Circuit breaker, reduce routing
115
+ Recovery: Exponential backoff restart
116
+ ```
117
+
118
+ ### Orphan Handling Policy
119
+
120
+ ```typescript
121
+ interface OrphanPolicy {
122
+ tasks: "reassign" | "return_to_parent" | "fail" | "hold";
123
+ children: "cascade_stop" | "reparent" | "orphan";
124
+ messages: "drop" | "bounce" | "redirect";
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Connection Failures
131
+
132
+ ### Reconnection Protocol
133
+
134
+ ```
135
+ Client Server
136
+ │ │
137
+ │◄─────── Connection Lost ───────────────│
138
+ │ │
139
+ │ (backoff: 1s, 2s, 4s, 8s...) │
140
+ │ │
141
+ │─────── Reconnect Attempt ─────────────►│
142
+ │ │
143
+ │◄────── Connection Accept ──────────────│
144
+ │ │
145
+ │─────── map/reconnect ─────────────────►│
146
+ │ { lastEventId, subscriptions } │
147
+ │ │
148
+ │◄────── Reconnect Response ─────────────│
149
+ │ { missedEvents, newState } │
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Circuit Breakers
155
+
156
+ ### Per-Agent Circuit Breaker
157
+
158
+ ```typescript
159
+ interface CircuitBreakerState {
160
+ agentId: string;
161
+ state: "closed" | "open" | "half-open";
162
+
163
+ failureThreshold: number;
164
+ successThreshold: number;
165
+ timeout: number;
166
+
167
+ failureCount: number;
168
+ successCount: number;
169
+ lastFailure: number;
170
+ lastStateChange: number;
171
+ }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Retry Policies
177
+
178
+ ```typescript
179
+ interface RetryPolicy {
180
+ maxAttempts: number;
181
+ backoff: {
182
+ type: "exponential" | "linear" | "constant";
183
+ initial: number;
184
+ max: number;
185
+ multiplier?: number;
186
+ };
187
+ retryableErrors: number[];
188
+ nonRetryableErrors: number[];
189
+ }
190
+
191
+ // Default policy
192
+ const DEFAULT_RETRY: RetryPolicy = {
193
+ maxAttempts: 3,
194
+ backoff: {
195
+ type: "exponential",
196
+ initial: 1000,
197
+ max: 30000,
198
+ multiplier: 2
199
+ },
200
+ retryableErrors: [2002, 2007, 4000, 5001],
201
+ nonRetryableErrors: [2000, 2001, 1003]
202
+ };
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Error Reporting & Observability
208
+
209
+ ### Distributed Tracing Integration
210
+
211
+ ```typescript
212
+ interface MAPTraceContext {
213
+ traceId: string;
214
+ spanId: string;
215
+ parentSpanId?: string;
216
+
217
+ // W3C Trace Context compatible
218
+ traceparent?: string;
219
+ tracestate?: string;
220
+ }
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Open Questions
226
+
227
+ 1. **Dead letter queue**: Should undeliverable messages go to a DLQ?
228
+ 2. **Error aggregation**: How to prevent error storms from overwhelming monitoring?
229
+ 3. **Automatic recovery**: How much should the protocol auto-heal vs require intervention?
230
+ 4. **Consistency model**: What consistency guarantees during partition recovery?
231
+ 5. **Error budget**: Should there be SLO-style error budgets in the protocol?
@@ -0,0 +1,244 @@
1
+ # MAP Connection Model & Client Patterns
2
+
3
+ This spec details how clients connect to MAP systems, the flexibility of subscription patterns, and how the protocol supports various usage modes.
4
+
5
+ ## Design Principles
6
+
7
+ 1. **Single protocol, multiple patterns**: Same wire protocol supports ACP-like single-agent focus through full system observation
8
+ 2. **Subscription-driven visibility**: What you see depends on what you subscribe to
9
+ 3. **SDK, not protocol, handles conversion**: Protocol stays simple; SDK provides utilities for common patterns
10
+ 4. **Multi-agent system is the endpoint**: Clients connect to the system, not individual agents
11
+
12
+ ---
13
+
14
+ ## Connection Lifecycle
15
+
16
+ ### Phase 1: Transport Connection
17
+
18
+ ```
19
+ Client MAP System
20
+ │ │
21
+ │─────── Transport Connect ───────────────►│
22
+ │ (WebSocket, stdio, etc.) │
23
+ │ │
24
+ │◄────── Transport Accept ────────────────│
25
+ │ │
26
+ ```
27
+
28
+ ### Phase 2: MAP Handshake
29
+
30
+ ```typescript
31
+ // Client sends connect request
32
+ {
33
+ "method": "map/connect",
34
+ "params": {
35
+ "clientId": "client_001",
36
+ "clientInfo": {
37
+ "name": "my-dashboard",
38
+ "version": "1.0.0"
39
+ },
40
+ "protocolVersion": "2025-01-01",
41
+ "requestedCapabilities": {
42
+ "streaming": true,
43
+ "maxSubscriptions": 10,
44
+ "federation": false
45
+ },
46
+ "auth": {
47
+ "method": "bearer",
48
+ "token": "..."
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Client Types
57
+
58
+ ### Operator Client
59
+
60
+ Full control over the system.
61
+
62
+ **Typical permissions:**
63
+ - Full visibility to all agents, scopes, events
64
+ - Can send messages to any agent
65
+ - Can register/unregister agents
66
+ - Can steer agents (inject context)
67
+ - Can create/delete scopes
68
+
69
+ ### Observer Client
70
+
71
+ Read-only visibility into the system.
72
+
73
+ **Typical permissions:**
74
+ - Full or scoped visibility
75
+ - Cannot send messages
76
+ - Cannot modify agents or scopes
77
+ - Useful for dashboards, monitoring
78
+
79
+ ### Agent Client
80
+
81
+ An agent connecting to participate in the system.
82
+
83
+ **Typical permissions:**
84
+ - Visibility scoped to hierarchy/relationships
85
+ - Can send messages to permitted agents
86
+ - Receives messages addressed to itself
87
+ - Cannot see full system structure (unless permitted)
88
+
89
+ ---
90
+
91
+ ## Subscription Patterns
92
+
93
+ ### Pattern 1: Single-Agent Focus (ACP-like)
94
+
95
+ ```typescript
96
+ await map.subscribe({
97
+ filter: { agents: ["agent_001"] },
98
+ streams: ["messages", "state"]
99
+ });
100
+ ```
101
+
102
+ ### Pattern 2: Multi-Agent Dashboard
103
+
104
+ ```typescript
105
+ await map.subscribe({
106
+ filter: { agents: ["worker_001", "worker_002", "coordinator"] },
107
+ streams: ["messages", "state"]
108
+ });
109
+ ```
110
+
111
+ ### Pattern 3: Role-Based Observation
112
+
113
+ ```typescript
114
+ await map.subscribe({
115
+ filter: { roles: ["worker"] },
116
+ streams: ["messages", "state"]
117
+ });
118
+ ```
119
+
120
+ ### Pattern 4: Full System Observation
121
+
122
+ ```typescript
123
+ await map.subscribe({
124
+ filter: {}, // Empty filter = no filtering
125
+ streams: ["messages", "state", "structure"]
126
+ });
127
+ ```
128
+
129
+ ### Pattern 5: Multiple Subscriptions
130
+
131
+ ```typescript
132
+ // Subscription 1: High-priority messages only
133
+ const urgentSub = await map.subscribe({
134
+ filter: { messagePriorities: ["urgent", "high"] },
135
+ streams: ["messages"]
136
+ });
137
+
138
+ // Subscription 2: All state changes
139
+ const stateSub = await map.subscribe({
140
+ filter: {},
141
+ streams: ["state"]
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ## SDK Utilities
148
+
149
+ ### ACP Session Adapter
150
+
151
+ ```typescript
152
+ // Create ACP-compatible session from MAP connection
153
+ const session = mapSdk.createACPSession(connection, "agent_001");
154
+
155
+ // Now use ACP-like API
156
+ await session.prompt("Hello, world");
157
+ ```
158
+
159
+ ### Stream Aggregator
160
+
161
+ ```typescript
162
+ // Combine multiple subscriptions into one stream
163
+ const aggregated = mapSdk.aggregateStreams([sub1, sub2, sub3]);
164
+
165
+ for await (const event of aggregated) {
166
+ console.log(event.subscriptionId, event.event);
167
+ }
168
+ ```
169
+
170
+ ### Agent Proxy
171
+
172
+ ```typescript
173
+ // Create a proxy object for an agent
174
+ const agent = mapSdk.createAgentProxy(connection, "agent_001");
175
+
176
+ // Direct method calls become messages
177
+ await agent.send({ type: "task", data: "..." });
178
+
179
+ // State is automatically updated
180
+ console.log(agent.state); // "busy"
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Connection State Management
186
+
187
+ ```
188
+ ┌──────────┐ connect ┌────────────┐ ready ┌─────────┐
189
+ │ INITIAL │ ─────────► │ CONNECTING │ ────────► │ ACTIVE │
190
+ └──────────┘ └────────────┘ └────┬────┘
191
+
192
+ ┌────────────────────────────────────────────────┤
193
+ │ │
194
+ │ disconnect error │
195
+ ▼ ▼
196
+ ┌──────────┐ ┌────────────┐
197
+ │ CLOSED │ ◄───────────────────────────── │ RECONNECT │
198
+ └──────────┘ max retries └────────────┘
199
+ exceeded
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Capability Negotiation
205
+
206
+ ### Client Capabilities
207
+
208
+ ```typescript
209
+ interface MAPClientCapabilities {
210
+ streaming: boolean;
211
+ maxConcurrentStreams?: number;
212
+ maxSubscriptions?: number;
213
+ maxMessageSize?: number;
214
+ supportedEncodings?: string[];
215
+ federation?: boolean;
216
+ replay?: boolean;
217
+ }
218
+ ```
219
+
220
+ ### System Capabilities
221
+
222
+ ```typescript
223
+ interface MAPSystemCapabilities {
224
+ protocolVersions: string[];
225
+ streaming: boolean;
226
+ federation: boolean;
227
+ replay: boolean;
228
+ replayWindow?: number;
229
+ maxSubscriptions: number;
230
+ maxMessageSize: number;
231
+ maxConcurrentConnections: number;
232
+ extensions?: string[];
233
+ }
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Open Questions
239
+
240
+ 1. **Session affinity**: Should subscriptions be tied to connection or transferable?
241
+ 2. **Subscription limits**: Per-connection or per-client (across reconnects)?
242
+ 3. **Capability versioning**: How to handle capability changes across protocol versions?
243
+ 4. **Auth refresh**: How to handle token expiration during long-lived connections?
244
+ 5. **Partial visibility**: Can a client request "all agents I can see" without knowing IDs upfront?
@@ -0,0 +1,243 @@
1
+ # MAP Visibility & Permission Model
2
+
3
+ This spec details how MAP controls visibility and permissions at multiple levels: system, client, scope, and agent.
4
+
5
+ ## Design Principles
6
+
7
+ 1. **Layered control**: Permissions are checked at multiple levels, most restrictive wins
8
+ 2. **Explicit over implicit**: Default to restricted, explicitly grant access
9
+ 3. **Separation of concerns**: Client permissions vs agent permissions are distinct
10
+ 4. **Flexibility**: System implementations can choose how strict to be
11
+
12
+ ---
13
+
14
+ ## Visibility Layers
15
+
16
+ ```
17
+ ┌─────────────────────────────────────────────────────────────────┐
18
+ │ Visibility Stack │
19
+ ├─────────────────────────────────────────────────────────────────┤
20
+ │ │
21
+ │ ┌─────────────────────────────────────────────────────────┐ │
22
+ │ │ LAYER 4: Agent Permissions │ │
23
+ │ │ What can this agent see/do within its allowed scope? │ │
24
+ │ └────────────────────────────┬────────────────────────────┘ │
25
+ │ │ │
26
+ │ ┌────────────────────────────▼────────────────────────────┐ │
27
+ │ │ LAYER 3: Scope Permissions │ │
28
+ │ │ What's visible within this scope? Who can see it? │ │
29
+ │ └────────────────────────────┬────────────────────────────┘ │
30
+ │ │ │
31
+ │ ┌────────────────────────────▼────────────────────────────┐ │
32
+ │ │ LAYER 2: Client Permissions │ │
33
+ │ │ What can this client see/do in the system? │ │
34
+ │ └────────────────────────────┬────────────────────────────┘ │
35
+ │ │ │
36
+ │ ┌────────────────────────────▼────────────────────────────┐ │
37
+ │ │ LAYER 1: System Configuration │ │
38
+ │ │ What does the system expose at all? │ │
39
+ │ └─────────────────────────────────────────────────────────┘ │
40
+ │ │
41
+ └─────────────────────────────────────────────────────────────────┘
42
+
43
+ Evaluation: Check Layer 1 → Layer 2 → Layer 3 → Layer 4
44
+ Result: Most restrictive wins (all layers must allow)
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Layer 1: System Configuration
50
+
51
+ ```typescript
52
+ interface MAPSystemConfig {
53
+ exposure: {
54
+ agents: {
55
+ publicByDefault: boolean;
56
+ publicAgents: string[];
57
+ hiddenAgents: string[];
58
+ };
59
+ events: {
60
+ exposedTypes: string[];
61
+ hiddenTypes: string[];
62
+ };
63
+ scopes: {
64
+ publicByDefault: boolean;
65
+ publicScopes: string[];
66
+ hiddenScopes: string[];
67
+ };
68
+ };
69
+ limits: {
70
+ maxConnections: number;
71
+ maxConnectionsPerClient: number;
72
+ maxSubscriptionsPerConnection: number;
73
+ };
74
+ anonymousPermissions: MAPClientPermissions;
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Layer 2: Client Permissions
81
+
82
+ ```typescript
83
+ interface MAPClientPermissions {
84
+ visibility: {
85
+ agents: "all" | "none" | { include: string[] } | { roles: string[] };
86
+ scopes: "all" | "none" | { include: string[] };
87
+ events: "all" | "none" | { include: string[] };
88
+ structure: boolean;
89
+ };
90
+
91
+ actions: {
92
+ sendMessages: boolean | { to: MAPAddress[]; priorities: string[] };
93
+ registerAgents: boolean | { roles: string[]; maxAgents: number };
94
+ unregisterAgents: boolean | { own: boolean; any: boolean };
95
+ createScopes: boolean;
96
+ deleteScopes: boolean | { own: boolean };
97
+ modifyScopes: boolean | { own: boolean; member: boolean };
98
+ steerAgents: boolean | { agents: string[]; methods: string[] };
99
+ federationConnect: boolean;
100
+ };
101
+
102
+ limits: {
103
+ subscriptions: number;
104
+ messagesPerMinute: number;
105
+ agentsRegistered: number;
106
+ scopesCreated: number;
107
+ };
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Layer 3: Scope Permissions
114
+
115
+ ```typescript
116
+ interface MAPScopePermissions {
117
+ discoverability: "public" | "members" | "owners";
118
+ messageVisibility: "public" | "members" | "participants";
119
+ joinPolicy: "open" | "invite" | "owner-invite" | "closed";
120
+ sendPolicy: "anyone" | "members" | "owners";
121
+ inheritFrom?: string;
122
+ }
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Layer 4: Agent Permissions
128
+
129
+ ```typescript
130
+ interface MAPAgentPermissions {
131
+ canSee: {
132
+ agents: "all" | "hierarchy" | "scoped" | "direct" | { include: string[] };
133
+ scopes: "all" | "member" | { include: string[] };
134
+ structure: "full" | "local" | "none";
135
+ };
136
+
137
+ canMessage: {
138
+ agents: "all" | "hierarchy" | "scoped" | { include: string[] };
139
+ scopes: "all" | "member" | { include: string[] };
140
+ };
141
+
142
+ acceptsFrom: {
143
+ agents: "all" | "hierarchy" | "scoped" | { include: string[] };
144
+ clients: "all" | "none" | { include: string[] };
145
+ systems: "all" | "none" | { include: string[] };
146
+ };
147
+
148
+ capabilities: {
149
+ registerAgents: boolean;
150
+ createScopes: boolean;
151
+ steerAgents: boolean;
152
+ };
153
+ }
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Permission Resolution
159
+
160
+ ```typescript
161
+ function canPerformAction(
162
+ client: MAPClient,
163
+ agent: MAPAgent | null,
164
+ action: MAPAction
165
+ ): boolean {
166
+ // Layer 1: System allows?
167
+ if (!systemAllows(action)) return false;
168
+
169
+ // Layer 2: Client permissions allow?
170
+ if (!clientAllows(client, action)) return false;
171
+
172
+ // Layer 3: Scope permissions allow?
173
+ if (action.scope && !scopeAllows(action.scope, client, agent, action)) {
174
+ return false;
175
+ }
176
+
177
+ // Layer 4: Agent permissions allow?
178
+ if (agent && !agentAllows(agent, action)) {
179
+ return false;
180
+ }
181
+
182
+ return true;
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Dynamic Permissions
189
+
190
+ Permissions can change during runtime:
191
+
192
+ ```typescript
193
+ // System can update client permissions
194
+ {
195
+ "method": "map/permissions/update",
196
+ "params": {
197
+ "clientId": "client_001",
198
+ "permissions": {
199
+ "actions": {
200
+ "steerAgents": true
201
+ }
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Permission Events
210
+
211
+ ```typescript
212
+ type MAPPermissionEvent =
213
+ | { type: "permissions.client.updated"; clientId: string; changes: ... }
214
+ | { type: "permissions.agent.updated"; agentId: string; changes: ... }
215
+ | { type: "permissions.scope.updated"; scopeId: string; changes: ... }
216
+ | { type: "permissions.denied"; action: string; reason: string };
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Security Considerations
222
+
223
+ ### Principle of Least Privilege
224
+
225
+ - Default to restricted permissions
226
+ - Grant only what's needed
227
+ - Regularly audit permission grants
228
+
229
+ ### Permission Escalation Prevention
230
+
231
+ - Agents cannot grant permissions they don't have
232
+ - Clients cannot modify their own permissions
233
+ - System enforces capability ceilings
234
+
235
+ ---
236
+
237
+ ## Open Questions
238
+
239
+ 1. **Inheritance**: Should agent permissions inherit from parent by default?
240
+ 2. **Temporary grants**: Time-limited permission grants?
241
+ 3. **Delegation**: Can agents delegate their permissions to others?
242
+ 4. **Groups**: Should there be permission groups/roles for clients?
243
+ 5. **Revocation**: Immediate revocation or graceful wind-down?