agent-embassy 1.7.0 → 1.8.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 +32 -0
- package/CONTRIBUTING.md +51 -47
- package/README.md +26 -9
- package/README.zh-CN.md +22 -9
- package/SECURITY.md +48 -35
- package/dist/src/gateway/acp-client.d.ts +12 -19
- package/dist/src/gateway/acp-client.js +90 -65
- package/dist/src/gateway/acp-client.js.map +1 -1
- package/dist/src/gateway/acp-provider.d.ts +11 -10
- package/dist/src/gateway/acp-provider.js +165 -53
- package/dist/src/gateway/acp-provider.js.map +1 -1
- package/dist/src/gateway/claude-helper-client.d.ts +2 -43
- package/dist/src/gateway/claude-helper-client.js +1 -211
- package/dist/src/gateway/claude-helper-client.js.map +1 -1
- package/dist/src/gateway/claude-helper-protocol.d.ts +16 -74
- package/dist/src/gateway/claude-helper-protocol.js +99 -378
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +56 -44
- package/dist/src/gateway/claude-helper-supervisor.js +265 -456
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-helper.js +184 -210
- package/dist/src/gateway/claude-helper.js.map +1 -1
- package/dist/src/gateway/claude-peer.d.ts +20 -87
- package/dist/src/gateway/claude-peer.js +310 -1009
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/claude-runtime.d.ts +13 -15
- package/dist/src/gateway/claude-runtime.js +14 -168
- package/dist/src/gateway/claude-runtime.js.map +1 -1
- package/dist/src/gateway/cli-copy.en.d.ts +2 -2
- package/dist/src/gateway/cli-copy.en.js +4 -2
- package/dist/src/gateway/cli-copy.en.js.map +1 -1
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +2 -2
- package/dist/src/gateway/cli-copy.zh-CN.js +4 -2
- package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/cli.d.ts +7 -2
- package/dist/src/gateway/cli.js +277 -575
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-app-server.d.ts +5 -227
- package/dist/src/gateway/codex-app-server.js +18 -1463
- package/dist/src/gateway/codex-app-server.js.map +1 -1
- package/dist/src/gateway/codex-doctor.d.ts +36 -0
- package/dist/src/gateway/codex-doctor.js +127 -0
- package/dist/src/gateway/codex-doctor.js.map +1 -0
- package/dist/src/gateway/codex-local-transport.d.ts +6 -6
- package/dist/src/gateway/codex-local-transport.js +13 -10
- package/dist/src/gateway/codex-local-transport.js.map +1 -1
- package/dist/src/gateway/codex-stateless-transport.d.ts +114 -0
- package/dist/src/gateway/codex-stateless-transport.js +1108 -0
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -0
- package/dist/src/gateway/config.d.ts +2 -9
- package/dist/src/gateway/config.js +62 -100
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +36 -90
- package/dist/src/gateway/control.js +465 -1123
- package/dist/src/gateway/control.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.d.ts +1 -1
- package/dist/src/gateway/dashboard-copy.en.d.ts +8 -26
- package/dist/src/gateway/dashboard-copy.en.js +19 -37
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.js +8 -26
- package/dist/src/gateway/dashboard-copy.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +8 -26
- package/dist/src/gateway/dashboard-copy.zh-CN.js +19 -37
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/dashboard-model.d.ts +8 -22
- package/dist/src/gateway/dashboard-model.js +44 -130
- package/dist/src/gateway/dashboard-model.js.map +1 -1
- package/dist/src/gateway/dashboard.d.ts +0 -6
- package/dist/src/gateway/dashboard.js +3 -7
- package/dist/src/gateway/dashboard.js.map +1 -1
- package/dist/src/gateway/live-dashboard-app/app.js +20 -34
- package/dist/src/gateway/live-dashboard-command.js +2 -2
- package/dist/src/gateway/live-dashboard-command.js.map +1 -1
- package/dist/src/gateway/live-dashboard-http.d.ts +1 -1
- package/dist/src/gateway/live-dashboard-http.js +2 -2
- package/dist/src/gateway/live-dashboard-http.js.map +1 -1
- package/dist/src/gateway/progress-watch-machine.d.ts +1 -37
- package/dist/src/gateway/progress-watch-machine.js +4 -15
- package/dist/src/gateway/progress-watch-machine.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +58 -191
- package/dist/src/gateway/providers.js +637 -2434
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.d.ts +16 -25
- package/dist/src/gateway/server.js +165 -240
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service.d.ts +149 -427
- package/dist/src/gateway/service.js +1639 -5662
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/state-v2-to-v3.d.ts +23 -0
- package/dist/src/gateway/state-v2-to-v3.js +994 -0
- package/dist/src/gateway/state-v2-to-v3.js.map +1 -0
- package/dist/src/gateway/store.d.ts +54 -309
- package/dist/src/gateway/store.js +1560 -3510
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +181 -225
- package/dist/src/gateway/types.js +115 -251
- package/dist/src/gateway/types.js.map +1 -1
- package/docs/CONFIGURATION.md +22 -9
- package/docs/CONFIGURATION.zh-CN.md +21 -9
- package/docs/DASHBOARD.md +10 -10
- package/docs/DASHBOARD.zh-CN.md +3 -3
- package/docs/DELIVERY.md +4 -4
- package/docs/DELIVERY.zh-CN.md +4 -4
- package/docs/GATEWAY-ARCHITECTURE.md +158 -187
- package/package.json +1 -1
- package/skills/embassy-peer/SKILL.md +28 -22
- package/dist/src/gateway/codex-registration-generation.d.ts +0 -5
- package/dist/src/gateway/codex-registration-generation.js +0 -19
- package/dist/src/gateway/codex-registration-generation.js.map +0 -1
- package/dist/src/gateway/codex-registration-succession.d.ts +0 -209
- package/dist/src/gateway/codex-registration-succession.js +0 -588
- package/dist/src/gateway/codex-registration-succession.js.map +0 -1
- package/dist/src/gateway/compatibility.d.ts +0 -22
- package/dist/src/gateway/compatibility.js +0 -23
- package/dist/src/gateway/compatibility.js.map +0 -1
- package/dist/src/gateway/delivery-machine.d.ts +0 -235
- package/dist/src/gateway/delivery-machine.js +0 -540
- package/dist/src/gateway/delivery-machine.js.map +0 -1
|
@@ -31,8 +31,8 @@ either agent runtime.
|
|
|
31
31
|
|
|
32
32
|
Provider versions are best-effort diagnostic metadata, never routing authority.
|
|
33
33
|
An explicit pair plus the exact owned route and session identity authorizes an
|
|
34
|
-
attempt; current
|
|
35
|
-
operation facts decide its result. The release-owned offline support matrix is
|
|
34
|
+
attempt; the current per-operation transport, strict wire, capability, and
|
|
35
|
+
correlated operation facts decide its result. The release-owned offline support matrix is
|
|
36
36
|
the tested-artifact record and is never imported by runtime. Unsafe OS evidence
|
|
37
37
|
for Embassy-owned or executed artifacts and Embassy callback, control, or state
|
|
38
38
|
paths refuses broker startup; unsafe UID or mode evidence on Claude's external
|
|
@@ -66,7 +66,7 @@ Claude–Codex address book the user wants.
|
|
|
66
66
|
|
|
67
67
|
The repo-shipped skill is the lightweight user/agent interface. A persistent
|
|
68
68
|
local broker is still required to own the private control socket, retain
|
|
69
|
-
transient reply correlation,
|
|
69
|
+
transient reply correlation, publish native advertisements, queue while a Codex
|
|
70
70
|
task is busy, and regenerate the dashboard between agent turns. The skill does
|
|
71
71
|
not wrap, replace, or recreate either provider.
|
|
72
72
|
|
|
@@ -169,17 +169,17 @@ The status below is intentionally narrower than the target architecture.
|
|
|
169
169
|
|
|
170
170
|
| Component | Current evidence |
|
|
171
171
|
| --- | --- |
|
|
172
|
-
| Neutral gateway types, metadata store,
|
|
172
|
+
| Neutral gateway types, native-v3 metadata store, bounded attempt state machine, queues, dedupe, rate limits, and public projection | **Implemented**, deterministic tests; message bodies persist under bounded retention |
|
|
173
173
|
| Private JSONL control protocol over a controller-owned UDS | **Implemented**, deterministic synthetic tests; no provider connection required |
|
|
174
174
|
| Static metadata-only dashboard renderer and atomic publisher | **Implemented**, deterministic security tests; the static renderer requires no browser or HTTP server |
|
|
175
175
|
| Opt-in live dashboard companion (`embassy dashboard --live`) | **Implemented**, deterministic tests over the stable loopback listener, direct multi-browser access, projection, request guards, and four bounded route actions; it is a separate foreground process, never part of `embassy serve` |
|
|
176
176
|
| Claude registry/peer adapter with strict peer protocol 1 and per-operation validation | **Implemented** and live-tested through Claude Code 2.1.227, including discovery, native status frames, cancellation, and accessible-workspace validation |
|
|
177
|
-
| Claude
|
|
178
|
-
|
|
|
177
|
+
| Claude current-user runtime roots | **Implemented**; derives the registry and callback roots from the verified OS user without inspecting a launcher or configuration file |
|
|
178
|
+
| Stateless allowlisted Codex App Server transport with bounded busy behavior | **Implemented**; every operation opens and attests its own transport, and the conformance suite covers idle gating, exact `STEER:` behavior, clean retry, and ambiguous no-replay settlement |
|
|
179
179
|
| Attach-only local Codex proxy transport and exact-owned cleanup | **Implemented**, five deterministic tests; no live App Server connection in routine tests |
|
|
180
180
|
| Local provider adapters | **Implemented**, focused synthetic tests cover Claude discovery, exact Codex ownership, and lazy ACP-backed DeepSeek and Grok routes with provider-local degradation and cleanup; remote adapters remain disabled |
|
|
181
|
-
| Gateway service composition | **Implemented**, including private control-server startup,
|
|
182
|
-
| Delivery receipt/status lifecycle | **Implemented**, deterministic synthetic tests cover stable-UUID native receipt re-resolution, the merged/verbose/quiet Claude notice policy, one bounded stall notice with pending age where enabled, opaque
|
|
181
|
+
| Gateway service composition | **Implemented**, including private control-server startup, synthetic cross-provider selection/dispatch/reply correlation, metadata-only publication, and restart attempt-phase tests |
|
|
182
|
+
| Delivery receipt/status lifecycle | **Implemented**, deterministic synthetic tests cover stable-UUID native receipt re-resolution, the merged/verbose/quiet Claude notice policy, one bounded stall notice with pending age where enabled, opaque private-v3 correlation handles, restart continuity, the closed status/terminal schema, and one-shot/bounded-wait CLI behavior |
|
|
183
183
|
| Broker-owned cross-provider provenance framing | **Implemented**, deterministic tests cover exact Codex and Claude wire shapes, bounded long-alias attribution, recipient reply hints, reserved-tag neutralization, single wrapping across clean retries, and pre-write failure |
|
|
184
184
|
| Operator/agent client CLI and package binary | **Implemented**, deterministic private-UDS tests cover the closed command family, inherited provider identity, bounded stdin-only bodies, normalized output, and ambiguous no-retry behavior |
|
|
185
185
|
| Repo-shipped cross-provider skill | **Implemented** as a repo-scoped workflow over the client CLI; it is not installed into either provider's global configuration |
|
|
@@ -213,41 +213,27 @@ are replaceable delivery coordinates, not identity, and are refreshed from the
|
|
|
213
213
|
live registry before a write. The gateway rejects duplicate current names and
|
|
214
214
|
duplicate live UUIDs rather than choosing between them.
|
|
215
215
|
|
|
216
|
-
The controller binds a Codex route to an exact host,
|
|
217
|
-
|
|
216
|
+
The controller binds a Codex route to an exact host, thread ID, and owner
|
|
217
|
+
lease. Other provider-native IDs, PIDs,
|
|
218
218
|
working directories, endpoint paths, and socket paths are never public
|
|
219
219
|
selectors or output fields. A Claude UUID may be supplied explicitly as a
|
|
220
220
|
destination, but the gateway never prints or invents one for the caller.
|
|
221
221
|
|
|
222
222
|
Codex registration is explicit. A task registers its own alias and
|
|
223
223
|
authoritative `CODEX_THREAD_ID`; the gateway does not enumerate global Codex
|
|
224
|
-
history to invent routes.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
activity, diagnostics, logs, or CLI output. An incompatible endpoint, a
|
|
238
|
-
missing or duplicate exact task, or an unclean transition leaves the route
|
|
239
|
-
stale and write-disabled. No body, callback, receipt handle, reply capability,
|
|
240
|
-
conversation capability, delivery token, or ambiguous write crosses this
|
|
241
|
-
boundary by replay.
|
|
242
|
-
|
|
243
|
-
The live dashboard exposes one bounded recovery operation for an orphaned
|
|
244
|
-
Codex registration. It carries only the public canonical `codex-*` alias and
|
|
245
|
-
requires explicit operator confirmation. The broker revalidates that the
|
|
246
|
-
route is stale and its owning endpoint generation is dead, then quiesces that
|
|
247
|
-
exact route before removing it and its incident pair edges and appending the
|
|
248
|
-
private recovery journal. Ready, merely offline, current-generation, and
|
|
249
|
-
ambiguous cases fail closed; the browser cannot name a thread ID or endpoint
|
|
250
|
-
generation.
|
|
224
|
+
history to invent routes. Registration performs no provider I/O. Each delivery
|
|
225
|
+
opens a fresh attested App Server transport, initializes it, resumes the exact
|
|
226
|
+
private task with history excluded, and authorizes one body write. Endpoint or
|
|
227
|
+
Desktop restart is therefore a transport fact, not a logical route transition;
|
|
228
|
+
an unavailable or duplicate exact task fails that operation with a safe code
|
|
229
|
+
without retargeting the alias or replaying an ambiguous write.
|
|
230
|
+
|
|
231
|
+
The live dashboard exposes the bounded `remove_codex_registration` operation.
|
|
232
|
+
It carries only one public canonical `codex-*` alias and requires explicit
|
|
233
|
+
operator confirmation of the consequences. In one fencing commit the broker
|
|
234
|
+
cancels queued or reserved work, settles armed work ambiguous and accepted work
|
|
235
|
+
unconfirmed, removes that registration and its incident consent edges, and
|
|
236
|
+
never replays uncertain work. The browser cannot name a thread ID.
|
|
251
237
|
|
|
252
238
|
Claude discovery is passive and limited to currently advertised genuine
|
|
253
239
|
Claude session records. Only a validated native record bearing the supported
|
|
@@ -275,26 +261,17 @@ invented additional owner or mode rule. A current name resolves to a UUID but
|
|
|
275
261
|
never substitutes for it.
|
|
276
262
|
|
|
277
263
|
A selected Claude UUID remains the durable route identity until explicit
|
|
278
|
-
unselection.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
authority. A later, separately authorized discovery operation may reactivate
|
|
286
|
-
the selection only when the full bounded scan contains exactly one compatible
|
|
287
|
-
interactive peer with the byte-identical UUID on the same provider, host, and
|
|
288
|
-
ownership lease. The adapter revalidates the current workspace and provider
|
|
289
|
-
selection before the store atomically adopts the current endpoint generation
|
|
290
|
-
and latest name. An incomplete scan, duplicate name or UUID, changed UUID,
|
|
291
|
-
workspace failure, or store collision leaves the route stale and releases any
|
|
292
|
-
provider selection acquired by the failed attempt. A name alone never restores
|
|
293
|
-
or retargets a durable selection.
|
|
264
|
+
unselection. Discovery publishes only bounded sanitized candidates and current
|
|
265
|
+
lookup aliases; it never changes the selected UUID. Immediately before a
|
|
266
|
+
Claude-bound write, Embassy performs a fresh bounded registry scan, resolves
|
|
267
|
+
that byte-identical UUID exactly once, and revalidates its current workspace,
|
|
268
|
+
process, socket, and used-artifact generation. An incomplete scan, duplicate
|
|
269
|
+
name or UUID, changed UUID, or unsafe current coordinate fails that operation
|
|
270
|
+
closed. A name alone never restores or retargets a durable selection.
|
|
294
271
|
|
|
295
272
|
The dashboard is the single pane for the human. It shows both sanitized
|
|
296
273
|
available/selected Claude aliases and explicitly registered Codex aliases,
|
|
297
|
-
including their host,
|
|
274
|
+
including their host, current state, last-seen age, and queue depth.
|
|
298
275
|
The thin skill/CLI exposes the same safe alias list to either provider.
|
|
299
276
|
|
|
300
277
|
## Message flows
|
|
@@ -340,9 +317,9 @@ Claude's native `SendMessage`, starts an App Server turn, and returns the
|
|
|
340
317
|
final reply.
|
|
341
318
|
|
|
342
319
|
1. The gateway advertises one process-owned `codex-*` record per registered
|
|
343
|
-
task in Claude's native registry.
|
|
344
|
-
|
|
345
|
-
|
|
320
|
+
task in Claude's native registry. The broker owns the advertisement,
|
|
321
|
+
callback socket, state, queue, and dispatch; provider process lifecycle is
|
|
322
|
+
not persisted as route authority.
|
|
346
323
|
2. A real Claude session uses native `ListAgents` and `SendMessage`; the
|
|
347
324
|
gateway validates that exact live registry/socket generation and treats the
|
|
348
325
|
text as untrusted user-role input. This inbound observation grants only a
|
|
@@ -364,13 +341,13 @@ final reply.
|
|
|
364
341
|
4. The gateway resolves the Codex alias to its private exact-thread binding.
|
|
365
342
|
5. The resumed task retains its existing native permissions. The gateway does
|
|
366
343
|
not supply policy overrides.
|
|
367
|
-
6.
|
|
368
|
-
peer record to `idle`, `busy`, or `waiting`.
|
|
369
|
-
7. Immediately before `turn/start` or `turn/steer`, the owning connector wraps
|
|
344
|
+
6. Immediately before `turn/start` or `turn/steer`, the delivery attempt wraps
|
|
370
345
|
the raw body once in Embassy's authoritative Codex-bound
|
|
371
|
-
`cross-session-message` frame.
|
|
372
|
-
|
|
373
|
-
|
|
346
|
+
`cross-session-message` frame. It opens and attests a fresh App Server
|
|
347
|
+
transport, resumes the exact task with history excluded, and starts one
|
|
348
|
+
dedicated turn only if the task is idle. Ordinary messages received while
|
|
349
|
+
it is active or awaiting approval remain queued. An exact leading `STEER:`
|
|
350
|
+
body in this direction is marked as a
|
|
374
351
|
steering message. If the connector has a positively observed active turn
|
|
375
352
|
and no RPC already in flight, it sends the closed `turn/steer` request with
|
|
376
353
|
that exact ID as `expectedTurnId`; App Server admits the input at the next
|
|
@@ -379,7 +356,7 @@ final reply.
|
|
|
379
356
|
boundary silently returns the same body to the normal queue. It does not
|
|
380
357
|
emit Claude's approval-specific native `held` control frame for ordinary
|
|
381
358
|
queueing.
|
|
382
|
-
|
|
359
|
+
7. In `merged` and `verbose` notice modes, if the delivery remains pending for
|
|
383
360
|
exactly `min(floor(messageDeadlineMs / 2), 120_000)` milliseconds, the
|
|
384
361
|
gateway may send the originating Claude session at most one nonterminal
|
|
385
362
|
`<gateway-delivery-stall>` user frame for that receipt. It contains only an
|
|
@@ -389,13 +366,13 @@ final reply.
|
|
|
389
366
|
default four-hour deadline the notice fires at two minutes, not two hours.
|
|
390
367
|
`quiet` suppresses this gateway-authored frame without changing native status
|
|
391
368
|
or dashboard state.
|
|
392
|
-
|
|
393
|
-
|
|
369
|
+
8. A later bounded attempt opens a new transport and starts the held message
|
|
370
|
+
after it observes the exact task idle. A route retains at most three queued steering
|
|
394
371
|
messages; accepting a fourth atomically cancels the oldest with safe code
|
|
395
372
|
`STEER_QUEUE_SUPERSEDED`, a normal terminal receipt, and a `STEER`-marked
|
|
396
373
|
journal event. Explicit registration is sufficient authorization; Embassy
|
|
397
374
|
does not run an additional workspace or policy classifier.
|
|
398
|
-
|
|
375
|
+
9. Successful App Server acceptance returns Claude's native `delivered`
|
|
399
376
|
receipt. A route or delivery error returns native `expired` with one safe
|
|
400
377
|
error code retained in its `reason` field. The default `merged` mode omits
|
|
401
378
|
the duplicate terminal user frame; `verbose` additionally sends a static
|
|
@@ -406,7 +383,7 @@ final reply.
|
|
|
406
383
|
reserved for an actual user or policy refusal.
|
|
407
384
|
A transient clean pre-dispatch failure returns the same message to the queue
|
|
408
385
|
instead of terminally failing it.
|
|
409
|
-
|
|
386
|
+
10. Completion is summarized into bounded normalized state and the correlated
|
|
410
387
|
reply is returned only to the same originating Claude session UUID after
|
|
411
388
|
its current coordinates are uniquely re-resolved and revalidated.
|
|
412
389
|
|
|
@@ -415,7 +392,7 @@ its mutable name, PID, registry record, or socket. Before every stall or
|
|
|
415
392
|
terminal receipt write, the adapter performs bounded discovery and revalidates
|
|
416
393
|
the UUID's current exact coordinates. This permits a receipt to follow ordinary
|
|
417
394
|
process/socket rotation without writing to a stale generation. If the UUID is
|
|
418
|
-
not uniquely
|
|
395
|
+
not uniquely re-observed with peer protocol 1, the write fails closed. A terminal
|
|
419
396
|
write whose outcome is ambiguous is never replayed; only a proven pre-write
|
|
420
397
|
failure may be retried while the bounded in-memory receipt remains live. The
|
|
421
398
|
receipt correlation does not add the UUID or receipt handle to public output
|
|
@@ -448,8 +425,8 @@ limits, deduplicates, and queues before presentation framing.
|
|
|
448
425
|
The store therefore retains only the raw unframed body, never the composed
|
|
449
426
|
envelope. A pure composer runs at the final semantic provider-write boundary so
|
|
450
427
|
a clean retry produces the same bytes with exactly one authoritative outer
|
|
451
|
-
wrapper.
|
|
452
|
-
|
|
428
|
+
wrapper. Provider connection setup and per-operation artifact validation,
|
|
429
|
+
receipt frames, and diagnostics do
|
|
453
430
|
not use this path.
|
|
454
431
|
|
|
455
432
|
Both provider directions use Claude-compatible textual framing with a
|
|
@@ -500,19 +477,20 @@ on by default and exact `0` disables classification. The tested 0.147.0 schema
|
|
|
500
477
|
requires `expectedTurnId`, rejects a nonmatching active turn, reports a clean
|
|
501
478
|
`activeTurnNotSteerable` condition, and returns the accepted turn ID. Embassy
|
|
502
479
|
validates all of those temporal correlations before settlement. `turn/interrupt`
|
|
503
|
-
is
|
|
504
|
-
|
|
505
|
-
escape hatch.
|
|
480
|
+
is never called or exposed, and there is no generic App Server RPC escape
|
|
481
|
+
hatch.
|
|
506
482
|
|
|
507
483
|
### Delivery status and bounded waits
|
|
508
484
|
|
|
509
485
|
Every accepted control-plane `send_to_claude`, `send_to_codex`, or `reply`
|
|
510
|
-
result contains both its conversation ID and a fresh opaque
|
|
511
|
-
|
|
486
|
+
result contains both its conversation ID and a fresh opaque delivery
|
|
487
|
+
correlation handle called a delivery token.
|
|
512
488
|
The token has the closed form `dlv_` followed by exactly 24 base64url
|
|
513
489
|
characters (`A-Z`, `a-z`, `0-9`, `_`, or `-`). It addresses one bounded
|
|
514
|
-
|
|
515
|
-
native identifier.
|
|
490
|
+
private-v3 message/status row and is not a provider receipt handle or a
|
|
491
|
+
provider native identifier. It is stored only in the mode-0600 broker state
|
|
492
|
+
and never appears in a public snapshot, normal log, provider receipt, or
|
|
493
|
+
dashboard.
|
|
516
494
|
|
|
517
495
|
The read-only `delivery_status` method accepts only that token and returns one
|
|
518
496
|
of these closed results:
|
|
@@ -557,21 +535,20 @@ never displaced to admit a new send. A pressure-evicted handle returns
|
|
|
557
535
|
### Replies and process restarts
|
|
558
536
|
|
|
559
537
|
Conversation IDs correlate replies, and callback addresses exist only in
|
|
560
|
-
memory, but
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
`
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
first.
|
|
538
|
+
memory, but message bodies and their bounded attempt phase are durable. After a
|
|
539
|
+
gateway restart, queued or reserved work may resume once against the same
|
|
540
|
+
logical route and consent edge. Work that crossed the armed boundary settles
|
|
541
|
+
`ambiguous`; provider-accepted work without terminal evidence settles
|
|
542
|
+
`unconfirmed`. Neither is replayed. Work already past its deadline settles
|
|
543
|
+
`expired`.
|
|
544
|
+
|
|
545
|
+
The delivery token and status of each retained message survive the restart: a
|
|
546
|
+
queued or reserved attempt remains inspectable while it resumes, and armed or
|
|
547
|
+
accepted work remains inspectable after it settles ambiguous or unconfirmed.
|
|
548
|
+
Pending replies, callbacks, native receipt handles, and conversation
|
|
549
|
+
capabilities do not survive. Logical registrations, Claude selections, and
|
|
550
|
+
consent edges remain, while each subsequent provider operation must attest its
|
|
551
|
+
own current transport facts.
|
|
575
552
|
|
|
576
553
|
## Gateway control plane
|
|
577
554
|
|
|
@@ -584,37 +561,49 @@ The closed version 1 method family is exactly these sixteen methods:
|
|
|
584
561
|
|
|
585
562
|
- `health` and `list_snapshot`, a safe public snapshot;
|
|
586
563
|
- `observe_snapshot`, a read-only projection that may settle already-due
|
|
587
|
-
|
|
564
|
+
delivery deadlines before projecting;
|
|
588
565
|
- `register_codex`, `unregister_codex`, and
|
|
589
|
-
`
|
|
590
|
-
|
|
591
|
-
owning endpoint generation is dead;
|
|
566
|
+
`remove_codex_registration` — explicit Codex registration and atomic
|
|
567
|
+
`--succeeds` replacement, owner unregister, and confirmed operator removal;
|
|
592
568
|
- `select_claude` and `unselect_claude`, from the current sanitized
|
|
593
569
|
available-peer inventory;
|
|
594
570
|
- `pair` and `unpair`, the two-endpoint permission edge;
|
|
595
|
-
- `delivery_status`, a lookup by opaque
|
|
571
|
+
- `delivery_status`, a lookup by an opaque correlation handle retained only in
|
|
572
|
+
bounded private v3 state;
|
|
596
573
|
- `untrack`, which closes one active progress watch by conversation token;
|
|
597
574
|
- `send_to_claude` and `send_to_codex`, the provider-specific sends;
|
|
598
575
|
- `reply`, the correlated reply operation; and
|
|
599
|
-
- `refresh_dashboard`, which refreshes
|
|
576
|
+
- `refresh_dashboard`, which refreshes provider discovery and republishes.
|
|
600
577
|
|
|
601
578
|
The live dashboard companion calls `observe_snapshot` for every read; its
|
|
602
579
|
mutation route additionally calls `pair`, `unpair`,
|
|
603
|
-
`
|
|
580
|
+
`remove_codex_registration`, and `refresh_dashboard`, and nothing else.
|
|
604
581
|
|
|
605
582
|
The installed binary is `embassy`, and it is the only installed binary. Its
|
|
606
|
-
|
|
583
|
+
eighteen implemented commands are
|
|
607
584
|
`serve`, `health`, `status`, `delivery-status`, `wait-delivery`, `untrack`,
|
|
608
585
|
`refresh-dashboard`, `dashboard`, `register-codex`, `unregister-codex`,
|
|
609
586
|
`select-claude`, `unselect-claude`, `pair`, `unpair`, `send-to-claude`,
|
|
610
|
-
`send-to-codex`, and `
|
|
587
|
+
`send-to-codex`, `reply`, and `convert-state-v2-to-v3`. `dashboard` requires `--live` and accepts an
|
|
611
588
|
optional `--lang en|zh-CN` and `--port <n>`; it starts the companion process
|
|
612
589
|
rather than issuing a single control request. Message bodies are non-empty
|
|
613
590
|
UTF-8 from standard input only, with a 16 KiB ceiling; they are never accepted
|
|
614
591
|
in an argument or file. The client emits one bounded normalized JSON line and
|
|
615
592
|
never returns a thread ID, provider-native ID, path, address, or message body.
|
|
616
593
|
These commands require the foreground broker, except that `serve` starts it in
|
|
617
|
-
the current terminal
|
|
594
|
+
the current terminal and `convert-state-v2-to-v3` is an offline one-shot
|
|
595
|
+
upgrade. The converter uses only the normally resolved state directory,
|
|
596
|
+
requires the controller lock, installs strict native schema 3 through an
|
|
597
|
+
fsynced atomic replacement, and reports only success plus the verified v2
|
|
598
|
+
backup basename. It starts no provider, helper, listener, discovery, or control
|
|
599
|
+
socket. The launcher never daemonizes itself.
|
|
600
|
+
|
|
601
|
+
`register-codex --alias <new> --succeeds <current>` is one atomic logical-route
|
|
602
|
+
transaction. It verifies the inherited identity of the replacement task,
|
|
603
|
+
settles the outgoing route's work according to recorded write phase, removes
|
|
604
|
+
its incident consent edges and transient capabilities, and publishes only the
|
|
605
|
+
new registration. There is no prepared, activated, endpoint-generation, or
|
|
606
|
+
manual-recovery state.
|
|
618
607
|
|
|
619
608
|
`select-claude --alias <current-name@host>` and
|
|
620
609
|
`select-claude --session <uuid>` select the same logical session.
|
|
@@ -733,35 +722,31 @@ any NVM-managed `codex` on the user's `PATH` (for example
|
|
|
733
722
|
it, and does not edit a shell profile. The two installations therefore do not
|
|
734
723
|
conflict.
|
|
735
724
|
|
|
736
|
-
The
|
|
737
|
-
may initialize,
|
|
738
|
-
|
|
725
|
+
The stateless transport has a fixed App Server method allowlist. One attempt
|
|
726
|
+
may initialize, resume the exact registered task, start a dedicated turn, or
|
|
727
|
+
steer the exact positively observed active turn. Loaded-task enumeration,
|
|
728
|
+
unsubscribe, interrupt, archive,
|
|
739
729
|
delete, history, shell, configuration, authentication, plugin,
|
|
740
730
|
approval-response, and generic RPC methods remain excluded everywhere.
|
|
741
731
|
|
|
742
732
|
The App Server capability first tested with 0.147.0 gates the privacy-preserving
|
|
743
733
|
`thread/resume.excludeTurns` field behind initialization capability
|
|
744
|
-
`experimentalApi: true`. The
|
|
745
|
-
non-configurable capability solely to suppress history retrieval.
|
|
746
|
-
resume
|
|
747
|
-
|
|
734
|
+
`experimentalApi: true`. The transport therefore hard-codes that one
|
|
735
|
+
non-configurable capability solely to suppress history retrieval. The attempt's
|
|
736
|
+
resume sends exactly `threadId` plus `excludeTurns: true`, then requires an
|
|
737
|
+
exact empty `thread.turns` array.
|
|
748
738
|
Missing, malformed, or nonempty turns fail closed and are never emitted or
|
|
749
739
|
persisted. The capability does not add an experimental client method or change
|
|
750
740
|
the closed RPC allowlist.
|
|
751
741
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
not read or retain reported working-directory or policy fields. Before
|
|
761
|
-
`turn/start`, including a queued drain, the connector refreshes that exact task
|
|
762
|
-
on the same live connection, requires it to be idle, and starts the turn with
|
|
763
|
-
no policy overrides. Settings notifications cannot make an explicitly
|
|
764
|
-
registered live route unreachable or discard its accepted queue.
|
|
742
|
+
Registration records the exact inherited task identity and establishes logical
|
|
743
|
+
reachability without provider I/O. For each `turn/start`, including a queued
|
|
744
|
+
drain, Embassy opens and attests a fresh transport, initializes the closed
|
|
745
|
+
interface, resumes that exact task with history excluded, requires it to be
|
|
746
|
+
idle, and authorizes one body write with no policy overrides. Version metadata
|
|
747
|
+
does not participate. Embassy does not read or retain reported
|
|
748
|
+
working-directory or policy fields, and a transport failure cannot discard the
|
|
749
|
+
registration or its accepted queue.
|
|
765
750
|
|
|
766
751
|
Version 1 never changes or independently classifies a Codex task's approval or
|
|
767
752
|
sandbox policy. Offline `TurnStartParams` schema evidence from tested App
|
|
@@ -770,7 +755,7 @@ policy overrides persist for the current and subsequent turns, so using them
|
|
|
770
755
|
as per-message restrictions would silently mutate the native task. Embassy
|
|
771
756
|
therefore starts the turn without overrides and leaves approval, sandbox, and
|
|
772
757
|
tool enforcement to the registered task's native Codex configuration. Explicit
|
|
773
|
-
`codex-*` registration plus exact
|
|
758
|
+
`codex-*` registration plus exact per-operation task and transport validation is the
|
|
774
759
|
gateway reachability boundary; native task policy remains Codex's concern.
|
|
775
760
|
|
|
776
761
|
A remote connector never starts, stops, replaces, signals, or unlinks a
|
|
@@ -860,7 +845,7 @@ Each page assembles seven sections:
|
|
|
860
845
|
|
|
861
846
|
- **Exchange** — aggregate gateway health plus every explicit cross-provider
|
|
862
847
|
pair and its per-edge counters.
|
|
863
|
-
- **Attention** — allowlisted alerts such as
|
|
848
|
+
- **Attention** — allowlisted alerts such as an unavailable route, protocol mismatch,
|
|
864
849
|
queue full, or ambiguous delivery.
|
|
865
850
|
- **Transit** — queued-message depth and bytes in flight.
|
|
866
851
|
- **Progress supervision** — active progress watches and their state.
|
|
@@ -910,15 +895,16 @@ gateway as unavailable when nothing is serving.
|
|
|
910
895
|
and cross-origin reads are unavailable.
|
|
911
896
|
- **Projection and actions.** The companion observes through
|
|
912
897
|
`observe_snapshot`. Its only mutations are exact two-endpoint `pair`,
|
|
913
|
-
`unpair`, `refresh_dashboard`, and `
|
|
914
|
-
control calls behind one closed `/action` route. The
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
898
|
+
`unpair`, `refresh_dashboard`, and `remove_codex_registration`
|
|
899
|
+
control calls behind one closed `/action` route. The removal action carries
|
|
900
|
+
only a canonical public `codex-*` alias; native task IDs never enter the
|
|
901
|
+
browser contract. In one fencing commit it cancels queued or reserved work,
|
|
902
|
+
settles armed work ambiguous and accepted work unconfirmed, removes the
|
|
903
|
+
route's consent edges, and never replays uncertain work. The browser shows
|
|
904
|
+
the consequence and requires
|
|
919
905
|
explicit confirmation; the server rejects bodies over 1 KiB and limits the
|
|
920
906
|
companion to six actions per minute. It cannot create a registration,
|
|
921
|
-
|
|
907
|
+
succeed,
|
|
922
908
|
send, reply, approve, interrupt, change settings, or invoke a generic/provider
|
|
923
909
|
method. Each mutation touches only the edge it names: adding an edge never
|
|
924
910
|
retires another, and removing one settles its accepted work before the
|
|
@@ -939,11 +925,13 @@ the static pair, which is always written in both languages.
|
|
|
939
925
|
|
|
940
926
|
The private store may retain:
|
|
941
927
|
|
|
942
|
-
-
|
|
943
|
-
handles inside the closed
|
|
944
|
-
-
|
|
945
|
-
|
|
946
|
-
|
|
928
|
+
- schema-3 logical registrations with aliases, registration IDs, and exact
|
|
929
|
+
provider-native route handles inside the closed private binding schema;
|
|
930
|
+
- consent edges tied to exact registration IDs, so alias reuse cannot inherit
|
|
931
|
+
permission;
|
|
932
|
+
- bounded messages with explicit `queued`, `reserved`, `armed`, `accepted`, or
|
|
933
|
+
`terminal` attempt phase and normalized activity used for accounting and
|
|
934
|
+
dashboard projection;
|
|
947
935
|
- timestamps, counters, dedupe/rate-limit records, and safe error codes.
|
|
948
936
|
|
|
949
937
|
It also retains message bodies under bounded caps — the queued body of every
|
|
@@ -952,23 +940,22 @@ oldest-first against a 1 MiB budget by default. It must never retain provider
|
|
|
952
940
|
output, tool input/output, raw App Server or Claude frames, stderr, histories,
|
|
953
941
|
credentials, Claude registry payloads, or callback/socket paths. The public
|
|
954
942
|
snapshot is a
|
|
955
|
-
strict projection that
|
|
956
|
-
|
|
943
|
+
strict projection that removes private route handles, registration IDs, and
|
|
944
|
+
operation-local endpoint evidence. The state directory is mode 0700 and state is mode 0600;
|
|
957
945
|
provider-native identifiers never enter normalized events, public snapshots,
|
|
958
946
|
the dashboard, CLI arguments/output, aliases, logs, or error text. On restart,
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
and
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
re-observed route; it is never replayed into a reconstructed capability.
|
|
947
|
+
logical routes and consent edges remain unchanged. Queued and reserved bodies
|
|
948
|
+
may resume once only after their exact registration and consent authority is
|
|
949
|
+
rechecked; armed and accepted work settles without replay. Callback, native
|
|
950
|
+
receipt, conversation, and reply capabilities are not reconstructed.
|
|
951
|
+
|
|
952
|
+
Private schema 3 is the binary's only native store format; the bounded public
|
|
953
|
+
snapshot deliberately remains schema version 2. Upgrading an existing schema-2
|
|
954
|
+
state requires the offline `embassy convert-state-v2-to-v3` command before
|
|
955
|
+
starting the broker. It verifies and retains a byte-identical v2 backup, then
|
|
956
|
+
atomically installs and reads back strict v3 state. The runtime performs no
|
|
957
|
+
in-binary migration or best-effort rewrite; any non-v3 state produces the
|
|
958
|
+
ordinary strict corrupt-state error.
|
|
972
959
|
|
|
973
960
|
## Minimum filesystem and process access
|
|
974
961
|
|
|
@@ -1001,8 +988,7 @@ paths, peers, and transports:
|
|
|
1001
988
|
|
|
1002
989
|
| Path/capability | Minimum purpose |
|
|
1003
990
|
| --- | --- |
|
|
1004
|
-
| `~/.
|
|
1005
|
-
| `~/.claude/sessions` | Read/enumerate only live registry JSON during the separately authorized passive-discovery gate |
|
|
991
|
+
| `~/.claude/sessions` | Derive from the verified current OS user's normalized home; read/enumerate only live registry JSON during the separately authorized passive-discovery gate, and validate exact records, PIDs, workspaces, and peer sockets used by the current operation. An absent or unsafe root degrades only Claude |
|
|
1006
992
|
| `/tmp/cc-socks` | At foreground startup, validate the private directory and create/remove only `/tmp/cc-socks/<gateway-pid>.sock` after inode/generation checks; search/stat genuine peers at passive discovery and connect one validated target only at the separately authorized send gate |
|
|
1007
993
|
| `~/.local/state/agent-embassy/.agent-embassy-state` | Validate or establish the exact ownership marker before creating the fixed host lease; an existing non-empty unmarked root is rejected without mutation |
|
|
1008
994
|
| `/usr/bin/lockf` and `/bin/cat` | Hold one fixed, non-waiting macOS advisory lease for the foreground controller; the helper receives no shell text, provider data, or model-supplied argument |
|
|
@@ -1033,48 +1019,33 @@ the preferred least-context setup, but it is not mandatory.
|
|
|
1033
1019
|
Embassy-owned or executed artifacts and Embassy callback, control, or state
|
|
1034
1020
|
paths refuses broker startup. Unsafe UID or mode evidence on Claude's
|
|
1035
1021
|
external sessions registry root quarantines only Claude. A malformed message version, required App Server response
|
|
1036
|
-
shape, or
|
|
1022
|
+
shape, or used-artifact generation fails closed on its current operation.
|
|
1037
1023
|
- Alias collisions, stale ownership leases, PID/socket races, unsafe
|
|
1038
1024
|
gateway-owned state, unexpected paths, queue overflow, deadline expiry, and ambiguous writes are
|
|
1039
1025
|
normalized failures, never raw diagnostics.
|
|
1040
|
-
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
writes are not retried.
|
|
1026
|
+
- A provider disconnect fails or defers only the current operation. The next
|
|
1027
|
+
eligible attempt opens and attests a new transport; logical registration and
|
|
1028
|
+
consent do not depend on a connector lifecycle.
|
|
1044
1029
|
- The first successful Codex registration locks its exact alias, task, and host
|
|
1045
|
-
until that registration is explicitly
|
|
1046
|
-
|
|
1047
|
-
by itself release the identity.
|
|
1030
|
+
until that registration is explicitly replaced or unregistered. Exact
|
|
1031
|
+
re-registration remains idempotent.
|
|
1048
1032
|
- `register-codex --alias <new> --succeeds <current>`, issued from inside the
|
|
1049
1033
|
successor task on the same host with its own inherited `CODEX_THREAD_ID`, is
|
|
1050
|
-
the one
|
|
1051
|
-
|
|
1052
|
-
different alias and
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
and delivery tokens belong to the retired identity and are purged rather than
|
|
1058
|
-
inherited, and the successor is published on a fresh listener generation.
|
|
1059
|
-
Publication arming is the irreversible boundary — before it, a failure rolls
|
|
1060
|
-
back to the old registration; at or after an armed, published, or unknown
|
|
1061
|
-
observation, the old registration is never restored, and an incomplete
|
|
1062
|
-
succession leaves registration offline and pinned until manual recovery
|
|
1063
|
-
rather than leaving two live registrations.
|
|
1064
|
-
- A failed reactivation of a retained route, or any fresh-registration rollback
|
|
1065
|
-
whose cleanup cannot be fully confirmed, pins that exact identity
|
|
1066
|
-
fail-closed. Only exact retry is permitted until the old route is confirmed
|
|
1067
|
-
unregistered and the controller is restarted.
|
|
1034
|
+
the one atomic transaction that changes the registered Codex identity. A
|
|
1035
|
+
replacement must name the exact current registration on the same host, with
|
|
1036
|
+
a different alias and thread. Embassy settles the outgoing registration's
|
|
1037
|
+
work from its durable attempt phase, removes its consent edges and transient
|
|
1038
|
+
capabilities, and publishes only the replacement. No conversation, reply
|
|
1039
|
+
capability, queued body, or permission transfers to the new identity, and no
|
|
1040
|
+
intermediate generation or manual-recovery state exists.
|
|
1068
1041
|
- No ambiguous mutation is retried automatically.
|
|
1069
|
-
- A queued body survives process loss under bounded retention and
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
message whose target authority was transient, or whose target route no longer
|
|
1073
|
-
exists, settles `abandoned` with the same code.
|
|
1042
|
+
- A queued or reserved body survives process loss under bounded retention and
|
|
1043
|
+
may resume once after exact logical authority is rechecked. Armed or accepted
|
|
1044
|
+
work settles `ambiguous` or `unconfirmed` and is never replayed.
|
|
1074
1045
|
- A provider or Desktop update that changes an internal interface degrades its
|
|
1075
1046
|
responsible route while the broker and other providers remain available. A
|
|
1076
|
-
Claude record outside peer protocol 1 is rejected per record, and
|
|
1077
|
-
|
|
1047
|
+
Claude record outside peer protocol 1 is rejected per record, and every
|
|
1048
|
+
current provider artifact used for an operation is re-attested before effect.
|
|
1078
1049
|
|
|
1079
1050
|
## Validation boundary
|
|
1080
1051
|
|