agent-embassy 3.0.0 → 4.0.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.
- package/CHANGELOG.md +42 -0
- package/CONTRIBUTING.md +92 -200
- package/README.md +159 -138
- package/SECURITY.md +191 -335
- package/dist/src/gateway/broker-check.d.ts +26 -0
- package/dist/src/gateway/broker-check.js +89 -0
- package/dist/src/gateway/broker-check.js.map +1 -0
- package/dist/src/gateway/broker-control.d.ts +72 -0
- package/dist/src/gateway/broker-control.js +164 -0
- package/dist/src/gateway/broker-control.js.map +1 -0
- package/dist/src/gateway/broker.d.ts +117 -0
- package/dist/src/gateway/broker.js +186 -0
- package/dist/src/gateway/broker.js.map +1 -0
- package/dist/src/gateway/claude-peer.d.ts +1 -124
- package/dist/src/gateway/claude-peer.js +62 -1053
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/codex-stateless-transport.d.ts +0 -12
- package/dist/src/gateway/codex-stateless-transport.js +8 -142
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
- package/dist/src/gateway/config.d.ts +2 -6
- package/dist/src/gateway/config.js +17 -27
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/coordinator.d.ts +57 -0
- package/dist/src/gateway/coordinator.js +217 -0
- package/dist/src/gateway/coordinator.js.map +1 -0
- package/dist/src/gateway/core-cli.d.ts +15 -0
- package/dist/src/gateway/core-cli.js +282 -0
- package/dist/src/gateway/core-cli.js.map +1 -0
- package/dist/src/gateway/core-service-command.d.ts +16 -0
- package/dist/src/gateway/core-service-command.js +71 -0
- package/dist/src/gateway/core-service-command.js.map +1 -0
- package/dist/src/gateway/endpoint-directory.d.ts +33 -0
- package/dist/src/gateway/endpoint-directory.js +223 -0
- package/dist/src/gateway/endpoint-directory.js.map +1 -0
- package/dist/src/gateway/federation.d.ts +89 -0
- package/dist/src/gateway/federation.js +632 -0
- package/dist/src/gateway/federation.js.map +1 -0
- package/dist/src/gateway/ledger-codec.d.ts +3 -0
- package/dist/src/gateway/ledger-codec.js +159 -0
- package/dist/src/gateway/ledger-codec.js.map +1 -0
- package/dist/src/gateway/ledger.d.ts +138 -0
- package/dist/src/gateway/ledger.js +319 -0
- package/dist/src/gateway/ledger.js.map +1 -0
- package/dist/src/gateway/local-control.d.ts +23 -0
- package/dist/src/gateway/local-control.js +489 -0
- package/dist/src/gateway/local-control.js.map +1 -0
- package/dist/src/gateway/native-destinations.d.ts +34 -0
- package/dist/src/gateway/native-destinations.js +272 -0
- package/dist/src/gateway/native-destinations.js.map +1 -0
- package/dist/src/gateway/owned-state.d.ts +57 -0
- package/dist/src/gateway/owned-state.js +398 -0
- package/dist/src/gateway/owned-state.js.map +1 -0
- package/dist/src/gateway/provenance-envelope.d.ts +3 -3
- package/dist/src/gateway/provenance-envelope.js +3 -23
- package/dist/src/gateway/provenance-envelope.js.map +1 -1
- package/dist/src/gateway/runtime.d.ts +41 -0
- package/dist/src/gateway/runtime.js +175 -0
- package/dist/src/gateway/runtime.js.map +1 -0
- package/docs/CONFIGURATION.md +178 -266
- package/docs/DELIVERY.md +133 -82
- package/docs/GATEWAY-ARCHITECTURE.md +276 -943
- package/package.json +5 -5
- package/skills/embassy-peer/SKILL.md +38 -194
- package/skills/embassy-peer/agents/openai.yaml +2 -2
- package/dist/src/gateway/claude-helper-client.d.ts +0 -2
- package/dist/src/gateway/claude-helper-client.js +0 -2
- package/dist/src/gateway/claude-helper-client.js.map +0 -1
- package/dist/src/gateway/claude-helper-protocol.d.ts +0 -117
- package/dist/src/gateway/claude-helper-protocol.js +0 -122
- package/dist/src/gateway/claude-helper-protocol.js.map +0 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +0 -87
- package/dist/src/gateway/claude-helper-supervisor.js +0 -347
- package/dist/src/gateway/claude-helper-supervisor.js.map +0 -1
- package/dist/src/gateway/claude-helper.d.ts +0 -1
- package/dist/src/gateway/claude-helper.js +0 -252
- package/dist/src/gateway/claude-helper.js.map +0 -1
- package/dist/src/gateway/cli.d.ts +0 -57
- package/dist/src/gateway/cli.js +0 -1503
- package/dist/src/gateway/cli.js.map +0 -1
- package/dist/src/gateway/codex-socket-holder.d.ts +0 -26
- package/dist/src/gateway/codex-socket-holder.js +0 -76
- package/dist/src/gateway/codex-socket-holder.js.map +0 -1
- package/dist/src/gateway/control.d.ts +0 -261
- package/dist/src/gateway/control.js +0 -903
- package/dist/src/gateway/control.js.map +0 -1
- package/dist/src/gateway/peer-client.d.ts +0 -58
- package/dist/src/gateway/peer-client.js +0 -217
- package/dist/src/gateway/peer-client.js.map +0 -1
- package/dist/src/gateway/peer-mailbox.d.ts +0 -78
- package/dist/src/gateway/peer-mailbox.js +0 -168
- package/dist/src/gateway/peer-mailbox.js.map +0 -1
- package/dist/src/gateway/peer-protocol.d.ts +0 -105
- package/dist/src/gateway/peer-protocol.js +0 -70
- package/dist/src/gateway/peer-protocol.js.map +0 -1
- package/dist/src/gateway/peer-stdio.d.ts +0 -23
- package/dist/src/gateway/peer-stdio.js +0 -100
- package/dist/src/gateway/peer-stdio.js.map +0 -1
- package/dist/src/gateway/providers.d.ts +0 -163
- package/dist/src/gateway/providers.js +0 -972
- package/dist/src/gateway/providers.js.map +0 -1
- package/dist/src/gateway/server.d.ts +0 -47
- package/dist/src/gateway/server.js +0 -219
- package/dist/src/gateway/server.js.map +0 -1
- package/dist/src/gateway/service.d.ts +0 -373
- package/dist/src/gateway/service.js +0 -2274
- package/dist/src/gateway/service.js.map +0 -1
- package/dist/src/gateway/status-view.d.ts +0 -167
- package/dist/src/gateway/status-view.js +0 -488
- package/dist/src/gateway/status-view.js.map +0 -1
- package/dist/src/gateway/store.d.ts +0 -185
- package/dist/src/gateway/store.js +0 -2359
- package/dist/src/gateway/store.js.map +0 -1
- package/dist/src/gateway/types.d.ts +0 -528
- package/dist/src/gateway/types.js +0 -341
- package/dist/src/gateway/types.js.map +0 -1
package/docs/CONFIGURATION.md
CHANGED
|
@@ -1,266 +1,178 @@
|
|
|
1
|
-
# Configuration
|
|
2
|
-
|
|
3
|
-
Embassy
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`host`
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
##
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
wrote;
|
|
180
|
-
- if the new agent cannot be confirmed unloaded, the plist is **left alone**
|
|
181
|
-
and the error says so — a half-installed agent is reported, never hidden.
|
|
182
|
-
|
|
183
|
-
The post-install health check is *not* one of those failures. By then the
|
|
184
|
-
agent is installed and loaded, and it stays that way: a broker that does not
|
|
185
|
-
answer is reported, and the command exits non-zero, but nothing is undone.
|
|
186
|
-
|
|
187
|
-
Install waits up to 10 seconds of wall clock for that health check, capping
|
|
188
|
-
each attempt at 1 second. If the broker never answers, the command exits
|
|
189
|
-
non-zero, names the log file, and reports the last code it observed. If that
|
|
190
|
-
last code is a decisive refusal rather than silence — `CONTROL_STATE_UNSAFE`,
|
|
191
|
-
`CONTROL_SOCKET_UNSAFE`, `CONTROL_CONNECT_DENIED`, `CONTROL_VERSION_MISMATCH`
|
|
192
|
-
— it exits with that code's own class and points at `embassy health`, which
|
|
193
|
-
explains it.
|
|
194
|
-
|
|
195
|
-
## Advanced bounds
|
|
196
|
-
|
|
197
|
-
These variables retain conservative defaults:
|
|
198
|
-
|
|
199
|
-
| Variable | Default |
|
|
200
|
-
| --- | ---: |
|
|
201
|
-
| `EMBASSY_MAX_ROUTES` | `128` |
|
|
202
|
-
| `EMBASSY_EVENT_CAPACITY` / `EMBASSY_EVENT_TTL_MS` | `500` / `86400000` |
|
|
203
|
-
| `EMBASSY_DEDUPE_CAPACITY` / `EMBASSY_DEDUPE_TTL_MS` | `2000` / `300000` |
|
|
204
|
-
| `EMBASSY_MAX_QUEUE_MESSAGES` / `EMBASSY_MAX_QUEUE_PER_ROUTE` | `100` / `20` |
|
|
205
|
-
| `EMBASSY_MAX_IN_FLIGHT` | `16` |
|
|
206
|
-
| `EMBASSY_MAX_QUEUE_BYTES` / `EMBASSY_MAX_MESSAGE_BYTES` | `1048576` / `16384` |
|
|
207
|
-
| `EMBASSY_MESSAGE_DEADLINE_MS` | `14400000` |
|
|
208
|
-
| `EMBASSY_RATE_LIMIT` / `EMBASSY_RATE_WINDOW_MS` | `30` / `60000` |
|
|
209
|
-
|
|
210
|
-
`EMBASSY_MAX_ROUTES` accepts 2 through 256. Every value in
|
|
211
|
-
this table is validated at startup, and an out-of-range or non-integer setting
|
|
212
|
-
fails closed with `INVALID_GATEWAY_CONFIGURATION` rather than being clamped.
|
|
213
|
-
|
|
214
|
-
The stall notice is not separately configurable. It fires at
|
|
215
|
-
`min(floor(EMBASSY_MESSAGE_DEADLINE_MS / 2), 120000)` milliseconds, so under the
|
|
216
|
-
default four-hour deadline a pending delivery is reported at two minutes, not
|
|
217
|
-
two hours.
|
|
218
|
-
|
|
219
|
-
A CLI initiator receives the full `conv_` token in its result, and every routed recipient receives the same token in the inbound provenance envelope and reply hint. The token is a memory-only participant-scoped locator, not an authority credential: every conversation-addressed `send` rechecks caller identity, conversation membership, and the live route. The token no longer exists after a broker restart; it must likewise never be retried or reconstructed after route retirement or identity replacement.
|
|
220
|
-
|
|
221
|
-
The public launcher remains host-local. Under allowlisted SSH federation, each broker serves the exact host identity attested by `nodes.json`. `register-codex` infers that host; the alias (and any `--succeeds` alias) must use the same suffix.
|
|
222
|
-
|
|
223
|
-
## Claude Code's own setting: `crossSessionInbound`
|
|
224
|
-
|
|
225
|
-
`crossSessionInbound` is Claude Code's native setting for cross-session
|
|
226
|
-
messaging: it decides whether a Claude session accepts, holds, or refuses
|
|
227
|
-
messages arriving from another session. Embassy needs it enabled on any
|
|
228
|
-
session used as a Codex-to-Claude destination, and it cannot override
|
|
229
|
-
that decision. Configure it in Claude Code, not in Embassy.
|
|
230
|
-
|
|
231
|
-
This is the one prerequisite you must actively toggle, and it is the most
|
|
232
|
-
common first-run failure — because it fails *late*. A send to a discovered
|
|
233
|
-
session is accepted and installs its route without consulting Claude's native
|
|
234
|
-
inbound policy; the refusal appears only when the delivery reaches the Claude
|
|
235
|
-
end. If the session appears in `embassy status` and the send was accepted but
|
|
236
|
-
nothing arrives, check `crossSessionInbound` on the destination session before
|
|
237
|
-
suspecting the route.
|
|
238
|
-
|
|
239
|
-
## Provider and runtime contract
|
|
240
|
-
|
|
241
|
-
Embassy routes three providers: Claude over peer protocol 1, Codex over the managed App Server, and universal shell peers over the private control socket. A build or version fact never grants or withholds routing authority.
|
|
242
|
-
|
|
243
|
-
Runtime is best effort: the OS boundary plus the exact owned route/session identity authorizes an attempt. The current per-operation transport, strict consumed wire fields, and correlated operation determine the result. Interface drift or a missing optional provider becomes provider-local degraded/offline health and an exact safe code; it does not create a compatibility tier or block unrelated providers.
|
|
244
|
-
|
|
245
|
-
Only unsafe OS evidence for Embassy-owned or executed artifacts and Embassy callback, control, or state paths—such as an unsafe lease or state, swapped binary, ownership/path/symlink mismatch, or invalid generation—refuses broker startup. The Claude-owned external sessions registry root is read-side identity evidence: an unsafe UID or mode degrades only Claude with a loud observation while the broker and other providers remain available. Claude still requires native `peerProtocol: 1` per session record: a record that declares any other value is rejected in isolation and included in bounded rejection evidence without stopping the broker or hiding other usable sessions.
|
|
246
|
-
|
|
247
|
-
Runtime parsing remains strict on every known registry field, frame, and response; unknown top-level Claude registry fields are ignored because Embassy never consumes them. The Claude connector row in public status carries optional bounded `registry` observations: `entriesScanned`, `parseableRecords`, monotonic `parseableRecordSeenSinceBoot`, bounded per-safe-code `rejected`, and `rejectedCodesOmitted`. `embassy status` reports the same evidence: if Claude is running but no record with parseable required fields has been observed since broker start, its registry layout may have changed.
|
|
248
|
-
|
|
249
|
-
The managed Codex installation is resolved by exact verified path; a `codex` elsewhere on `PATH` is neither used nor modified. Claude registry and callback roots are derived from the verified current OS user; no Claude launcher or configuration file is read. Version strings, when present, are bounded diagnostic metadata only.
|
|
250
|
-
|
|
251
|
-
## Addressing
|
|
252
|
-
|
|
253
|
-
Claude sessions are addressed by their current `name@host` or by a user-supplied native session UUID. The UUID is the stable logical identity; the current name is a live lookup alias. After a rename, the old name stops resolving immediately while an installed UUID-bound route continues to work under the new name. A rename becomes visible at the session's next status transition — typically its next turn boundary — because Claude Code rewrites the session's registry record on those transitions, not at the moment of the rename; Embassy reflects the record, never the rename itself.
|
|
254
|
-
|
|
255
|
-
Names, old names, PIDs, registry paths, process generations, and socket generations never become alternate identity keys. Embassy refuses to guess when two live sessions share a current name: the shared *name* is refused with `PEER_ALIAS_COLLISION`, while each session stays reachable by its own UUID.
|
|
256
|
-
|
|
257
|
-
Across a federated link, reachability is narrower than it is locally. A peer node addresses only the routes its neighbour published in its catalog, and a Claude session appears there only once it has a local route — that is, once it has sent a message or been sent one on its own host. The destination never installs a route on a handoff: an unmirrored sender or an unrouted target is refused, not created. To make a Claude session addressable from a peer node, use it locally once first.
|
|
258
|
-
|
|
259
|
-
Codex routes use an explicit `codex-*` alias and the task's inherited thread identity. The private thread ID is never accepted as a command-line argument or printed. Registration performs no App Server operation. Every delivery opens and attests a fresh managed transport, initializes it, resumes the exact task with history excluded, and authorizes the body write once. App Server and broker restarts do not change logical route authority or require re-registration. A current unavailable or unobservable task reports an operation-local safe code while the registration remains.
|
|
260
|
-
|
|
261
|
-
Shell routes use `peer-*` aliases and a `peer_` token minted at registration.
|
|
262
|
-
The broker persists only its UID/alias/token hash route handle, never the raw
|
|
263
|
-
token. Authenticated calls accept the token on the first stdin line with
|
|
264
|
-
`--token-stdin`; body-bearing calls use the remaining bytes as the body.
|
|
265
|
-
`--emit-env` remains optional for stable-shell harnesses. There is no PID
|
|
266
|
-
binding, token file, Keychain entry, daemon, or alternate persistence path.
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Embassy has one broker per login user and machine. Configuration is inherited
|
|
4
|
+
when the broker starts; changing it requires a broker restart. Provider build
|
|
5
|
+
or version metadata never grants routing authority.
|
|
6
|
+
|
|
7
|
+
## State and node inventory
|
|
8
|
+
|
|
9
|
+
`EMBASSY_STATE_DIR` may set an absolute state directory. Otherwise Embassy
|
|
10
|
+
uses `$XDG_STATE_HOME/agent-embassy`, or
|
|
11
|
+
`$HOME/.local/state/agent-embassy` when `XDG_STATE_HOME` is unset.
|
|
12
|
+
|
|
13
|
+
The directory must be owned by the current user, mode 0700, and must not be a
|
|
14
|
+
symbolic link. `gateway-state.json`, `nodes.json`, and other broker-owned files
|
|
15
|
+
are mode 0600. The private control socket is inside this directory. A Codex or
|
|
16
|
+
Claude sandbox must be able to read and write the directory for commands that
|
|
17
|
+
contact the broker. If access was expected, also verify the configured state
|
|
18
|
+
directory belongs to this user; do not start a second broker to work around an
|
|
19
|
+
access denial.
|
|
20
|
+
|
|
21
|
+
`nodes.json` is the static host and federation inventory. A machine without
|
|
22
|
+
peers uses an empty list:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{"version":1,"host":"studio","nodes":[]}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If the file is absent on the first single-machine boot, Embassy derives a
|
|
29
|
+
lower-case host from the machine's short hostname (or `localhost` when that is
|
|
30
|
+
not a valid token) and atomically installs a version-1 file with `nodes:[]`.
|
|
31
|
+
This default is transient until the file is written; a present file is never
|
|
32
|
+
rewritten. Create it before first boot when choosing an explicit host name or
|
|
33
|
+
configuring federation.
|
|
34
|
+
|
|
35
|
+
`host` is the canonical local host name used in aliases. `nodes` is the list
|
|
36
|
+
of directly reachable Embassy hosts. Entries must be unique, must not include
|
|
37
|
+
the local host, and must use lower-case host tokens. There is no environment
|
|
38
|
+
fallback, dynamic discovery, or multi-hop routing.
|
|
39
|
+
|
|
40
|
+
Local route aliases end in the inventory's exact host. `register-codex` and
|
|
41
|
+
`retire` refuse a different host. Remote routes are resolved through the owner
|
|
42
|
+
listed in `nodes`; they can be retired only on that owner.
|
|
43
|
+
|
|
44
|
+
## Delivery settings
|
|
45
|
+
|
|
46
|
+
All integer settings are decimal integers. Invalid or inconsistent values stop
|
|
47
|
+
the broker with `INVALID_GATEWAY_CONFIGURATION`.
|
|
48
|
+
|
|
49
|
+
| Variable | Default | Accepted range |
|
|
50
|
+
|---|---:|---:|
|
|
51
|
+
| `EMBASSY_MAX_ROUTES` | 128 | 2–128 |
|
|
52
|
+
| `EMBASSY_MAX_QUEUE_MESSAGES` | 100 | 1–100 |
|
|
53
|
+
| `EMBASSY_MAX_QUEUE_PER_ROUTE` | 20 | 1–20 and no greater than the total queue |
|
|
54
|
+
| `EMBASSY_MAX_IN_FLIGHT` | 16 | 1–16 and no greater than the total queue |
|
|
55
|
+
| `EMBASSY_MAX_MESSAGE_BYTES` | 16384 | 1–16384 |
|
|
56
|
+
| `EMBASSY_MAX_QUEUE_BYTES` | 1048576 | 1024–1048576 and no smaller than one message |
|
|
57
|
+
| `EMBASSY_MESSAGE_DEADLINE_MS` | 14400000 | 1000–86400000 |
|
|
58
|
+
| `EMBASSY_RATE_LIMIT` | 30 | 1–10000 |
|
|
59
|
+
| `EMBASSY_RATE_WINDOW_MS` | 60000 | 1000–3600000 |
|
|
60
|
+
| `EMBASSY_EVENT_CAPACITY` | 500 | 10–500 |
|
|
61
|
+
| `EMBASSY_EVENT_TTL_MS` | 86400000 | 60000–604800000 |
|
|
62
|
+
|
|
63
|
+
The event settings bound recent terminal delivery and retirement evidence; they
|
|
64
|
+
do not enable a general activity journal. The state also has a fixed retained
|
|
65
|
+
byte budget.
|
|
66
|
+
|
|
67
|
+
`EMBASSY_STEERING_ENABLED` is `1` by default. Set exactly `0` to treat a
|
|
68
|
+
leading `STEER:` as an ordinary Claude-to-Codex message. No other value is
|
|
69
|
+
accepted.
|
|
70
|
+
|
|
71
|
+
## Provider contracts
|
|
72
|
+
|
|
73
|
+
### Claude Code
|
|
74
|
+
|
|
75
|
+
Embassy reads Claude's current-user session registry and connects to the exact
|
|
76
|
+
session's private Unix socket. Only interactive and background sessions using
|
|
77
|
+
Claude peer protocol 1 are eligible. A malformed or incompatible record is
|
|
78
|
+
rejected in isolation. Discovery and workspace/path evidence are checked again
|
|
79
|
+
for each native write.
|
|
80
|
+
|
|
81
|
+
A Claude caller is identified from its inherited absolute
|
|
82
|
+
`CLAUDE_CODE_MESSAGING_SOCKET`. The path is never accepted as a CLI option,
|
|
83
|
+
printed, or persisted. Claude sessions receive natively. They send in one CLI
|
|
84
|
+
step with `embassy send`; Embassy does not publish helper agents into Claude's
|
|
85
|
+
native agent list.
|
|
86
|
+
|
|
87
|
+
### Codex CLI
|
|
88
|
+
|
|
89
|
+
A Codex task registers itself with `embassy register-codex --alias ...` using
|
|
90
|
+
its inherited `CODEX_THREAD_ID`. The ID is not a command argument or public
|
|
91
|
+
output. Registration is a logical state change and performs no App Server I/O.
|
|
92
|
+
Each delivery independently attests the current App Server interface and exact
|
|
93
|
+
task before authorization, resumes that task without retaining history, and
|
|
94
|
+
writes through a fresh operation.
|
|
95
|
+
|
|
96
|
+
`register-codex --succeeds <old-alias>` atomically retires a predecessor and
|
|
97
|
+
installs the caller. It never reanchors pending work to a new identity.
|
|
98
|
+
|
|
99
|
+
## SSH federation
|
|
100
|
+
|
|
101
|
+
For each configured remote node Embassy runs the fixed system SSH client in
|
|
102
|
+
batch mode with forwarding and local commands disabled. Authentication is the
|
|
103
|
+
user's SSH configuration. The remote command is `embassy peer-stdio`; the two
|
|
104
|
+
installations must speak federation peer protocol 3.
|
|
105
|
+
|
|
106
|
+
Any plain same-user SSH login that can run that command is sufficient; Embassy
|
|
107
|
+
does not require a forced command, per-node key, or special SSH environment.
|
|
108
|
+
The peer claims its logical host in `initialize`, and the receiving broker
|
|
109
|
+
requires that host to be in its `nodes.json` peer list. The SSH login is
|
|
110
|
+
trusted, so the claim is trusted too. Keep the local `host` correct when
|
|
111
|
+
copying configuration: a wrong allowed host label can misattribute origin.
|
|
112
|
+
|
|
113
|
+
The non-interactive SSH environment must resolve the intended `embassy`
|
|
114
|
+
installation. Verify that environment with `which -a embassy`. Federation
|
|
115
|
+
does not accept a password, private key, host override, or arbitrary SSH
|
|
116
|
+
argument from Embassy configuration.
|
|
117
|
+
|
|
118
|
+
Remote endpoint catalogs are bounded memory-only caches. The owner is queried
|
|
119
|
+
again for exact identity resolution. A handoff is one correlated write, the
|
|
120
|
+
destination persists its queue before acceptance, and an uncertain result is
|
|
121
|
+
never replayed.
|
|
122
|
+
|
|
123
|
+
`embassy refresh` observes configured catalogs in parallel with local Claude
|
|
124
|
+
discovery. A successful observation replaces that node's bounded display rows
|
|
125
|
+
and timestamp. A failed observation retains its last rows and records
|
|
126
|
+
`PEER_TUNNEL_UNAVAILABLE`. `embassy status` reads that snapshot without SSH or
|
|
127
|
+
provider I/O. Display is capped at 128 remote rows across all nodes; exact and
|
|
128
|
+
named routing always queries the owner and is unaffected by display truncation.
|
|
129
|
+
|
|
130
|
+
## launchd service
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
embassy service install
|
|
134
|
+
embassy service status
|
|
135
|
+
embassy service uninstall
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The service is a per-user launchd agent. Installation captures the absolute
|
|
139
|
+
Node executable and Embassy CLI file, plus every nonempty `EMBASSY_*` value and
|
|
140
|
+
`XDG_STATE_HOME` from the installing shell. It captures no other environment
|
|
141
|
+
entry and no arbitrary `PATH`; do not put secrets in an `EMBASSY_*` variable.
|
|
142
|
+
Re-run installation after moving or replacing the package.
|
|
143
|
+
`service status` reports when a recorded program path no longer exists.
|
|
144
|
+
|
|
145
|
+
The plist uses `RunAtLoad` and `KeepAlive` with only `Crashed: true`. A verified
|
|
146
|
+
`SIGABRT` crash relaunches it. A clean exit, nonzero boot refusal, ordinary
|
|
147
|
+
`SIGTERM`, or a deliberate
|
|
148
|
+
`kill -9` leaves the service not running. Use `embassy service status` to
|
|
149
|
+
observe that state and start or reinstall it deliberately.
|
|
150
|
+
|
|
151
|
+
The foreground alternative is `embassy serve`. It does not daemonize or open
|
|
152
|
+
a network listener. Both forms acquire the same fixed host-wide advisory lease
|
|
153
|
+
before provider setup, so only one broker can run.
|
|
154
|
+
|
|
155
|
+
## Private state reset
|
|
156
|
+
|
|
157
|
+
Version 4 accepts only schema-6 `gateway-state.json`. It deliberately contains
|
|
158
|
+
no v3 converter or compatibility reader. An older or unknown schema refuses
|
|
159
|
+
with `GATEWAY_STATE_SCHEMA_UNSUPPORTED`; invalid schema-6 bytes refuse with
|
|
160
|
+
`CORRUPT_GATEWAY_STATE`. Refusal does not mutate the installed file.
|
|
161
|
+
|
|
162
|
+
Reset procedure:
|
|
163
|
+
|
|
164
|
+
1. With the old matching binary, inspect delivery state and settle or abandon
|
|
165
|
+
work deliberately.
|
|
166
|
+
2. Stop the broker and confirm the service is not running.
|
|
167
|
+
3. Copy the old `gateway-state.json` to an operator-owned backup.
|
|
168
|
+
4. Move the installed state file aside. Keep the valid `nodes.json`.
|
|
169
|
+
5. Start the v4 broker; it creates fresh schema-6 state.
|
|
170
|
+
6. Re-register Codex tasks. Claude endpoints are recorded on discovery/use.
|
|
171
|
+
|
|
172
|
+
A reset abandons unsettled work and invalidates delivery tokens and
|
|
173
|
+
conversation references. Rollback means stopping v4 and restoring both the old
|
|
174
|
+
binary and its untouched old state. Never hand-edit either schema.
|
|
175
|
+
After v4 has accepted work, the old backup does not contain that work. Before
|
|
176
|
+
rolling back, inspect and drain or explicitly abandon v4 deliveries, and keep
|
|
177
|
+
a separate backup of the v4 state. Restoring v3 is not a rollback of those
|
|
178
|
+
delivery effects and must never silently discard unsettled v4 work.
|