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.
Files changed (118) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/CONTRIBUTING.md +51 -47
  3. package/README.md +26 -9
  4. package/README.zh-CN.md +22 -9
  5. package/SECURITY.md +48 -35
  6. package/dist/src/gateway/acp-client.d.ts +12 -19
  7. package/dist/src/gateway/acp-client.js +90 -65
  8. package/dist/src/gateway/acp-client.js.map +1 -1
  9. package/dist/src/gateway/acp-provider.d.ts +11 -10
  10. package/dist/src/gateway/acp-provider.js +165 -53
  11. package/dist/src/gateway/acp-provider.js.map +1 -1
  12. package/dist/src/gateway/claude-helper-client.d.ts +2 -43
  13. package/dist/src/gateway/claude-helper-client.js +1 -211
  14. package/dist/src/gateway/claude-helper-client.js.map +1 -1
  15. package/dist/src/gateway/claude-helper-protocol.d.ts +16 -74
  16. package/dist/src/gateway/claude-helper-protocol.js +99 -378
  17. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  18. package/dist/src/gateway/claude-helper-supervisor.d.ts +56 -44
  19. package/dist/src/gateway/claude-helper-supervisor.js +265 -456
  20. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  21. package/dist/src/gateway/claude-helper.js +184 -210
  22. package/dist/src/gateway/claude-helper.js.map +1 -1
  23. package/dist/src/gateway/claude-peer.d.ts +20 -87
  24. package/dist/src/gateway/claude-peer.js +310 -1009
  25. package/dist/src/gateway/claude-peer.js.map +1 -1
  26. package/dist/src/gateway/claude-runtime.d.ts +13 -15
  27. package/dist/src/gateway/claude-runtime.js +14 -168
  28. package/dist/src/gateway/claude-runtime.js.map +1 -1
  29. package/dist/src/gateway/cli-copy.en.d.ts +2 -2
  30. package/dist/src/gateway/cli-copy.en.js +4 -2
  31. package/dist/src/gateway/cli-copy.en.js.map +1 -1
  32. package/dist/src/gateway/cli-copy.zh-CN.d.ts +2 -2
  33. package/dist/src/gateway/cli-copy.zh-CN.js +4 -2
  34. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
  35. package/dist/src/gateway/cli.d.ts +7 -2
  36. package/dist/src/gateway/cli.js +277 -575
  37. package/dist/src/gateway/cli.js.map +1 -1
  38. package/dist/src/gateway/codex-app-server.d.ts +5 -227
  39. package/dist/src/gateway/codex-app-server.js +18 -1463
  40. package/dist/src/gateway/codex-app-server.js.map +1 -1
  41. package/dist/src/gateway/codex-doctor.d.ts +36 -0
  42. package/dist/src/gateway/codex-doctor.js +127 -0
  43. package/dist/src/gateway/codex-doctor.js.map +1 -0
  44. package/dist/src/gateway/codex-local-transport.d.ts +6 -6
  45. package/dist/src/gateway/codex-local-transport.js +13 -10
  46. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  47. package/dist/src/gateway/codex-stateless-transport.d.ts +114 -0
  48. package/dist/src/gateway/codex-stateless-transport.js +1108 -0
  49. package/dist/src/gateway/codex-stateless-transport.js.map +1 -0
  50. package/dist/src/gateway/config.d.ts +2 -9
  51. package/dist/src/gateway/config.js +62 -100
  52. package/dist/src/gateway/config.js.map +1 -1
  53. package/dist/src/gateway/control.d.ts +36 -90
  54. package/dist/src/gateway/control.js +465 -1123
  55. package/dist/src/gateway/control.js.map +1 -1
  56. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  57. package/dist/src/gateway/dashboard-copy.en.d.ts +8 -26
  58. package/dist/src/gateway/dashboard-copy.en.js +19 -37
  59. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  60. package/dist/src/gateway/dashboard-copy.js +8 -26
  61. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  62. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +8 -26
  63. package/dist/src/gateway/dashboard-copy.zh-CN.js +19 -37
  64. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  65. package/dist/src/gateway/dashboard-model.d.ts +8 -22
  66. package/dist/src/gateway/dashboard-model.js +44 -130
  67. package/dist/src/gateway/dashboard-model.js.map +1 -1
  68. package/dist/src/gateway/dashboard.d.ts +0 -6
  69. package/dist/src/gateway/dashboard.js +3 -7
  70. package/dist/src/gateway/dashboard.js.map +1 -1
  71. package/dist/src/gateway/live-dashboard-app/app.js +20 -34
  72. package/dist/src/gateway/live-dashboard-command.js +2 -2
  73. package/dist/src/gateway/live-dashboard-command.js.map +1 -1
  74. package/dist/src/gateway/live-dashboard-http.d.ts +1 -1
  75. package/dist/src/gateway/live-dashboard-http.js +2 -2
  76. package/dist/src/gateway/live-dashboard-http.js.map +1 -1
  77. package/dist/src/gateway/progress-watch-machine.d.ts +1 -37
  78. package/dist/src/gateway/progress-watch-machine.js +4 -15
  79. package/dist/src/gateway/progress-watch-machine.js.map +1 -1
  80. package/dist/src/gateway/providers.d.ts +58 -191
  81. package/dist/src/gateway/providers.js +637 -2434
  82. package/dist/src/gateway/providers.js.map +1 -1
  83. package/dist/src/gateway/server.d.ts +16 -25
  84. package/dist/src/gateway/server.js +165 -240
  85. package/dist/src/gateway/server.js.map +1 -1
  86. package/dist/src/gateway/service.d.ts +149 -427
  87. package/dist/src/gateway/service.js +1639 -5662
  88. package/dist/src/gateway/service.js.map +1 -1
  89. package/dist/src/gateway/state-v2-to-v3.d.ts +23 -0
  90. package/dist/src/gateway/state-v2-to-v3.js +994 -0
  91. package/dist/src/gateway/state-v2-to-v3.js.map +1 -0
  92. package/dist/src/gateway/store.d.ts +54 -309
  93. package/dist/src/gateway/store.js +1560 -3510
  94. package/dist/src/gateway/store.js.map +1 -1
  95. package/dist/src/gateway/types.d.ts +181 -225
  96. package/dist/src/gateway/types.js +115 -251
  97. package/dist/src/gateway/types.js.map +1 -1
  98. package/docs/CONFIGURATION.md +22 -9
  99. package/docs/CONFIGURATION.zh-CN.md +21 -9
  100. package/docs/DASHBOARD.md +10 -10
  101. package/docs/DASHBOARD.zh-CN.md +3 -3
  102. package/docs/DELIVERY.md +4 -4
  103. package/docs/DELIVERY.zh-CN.md +4 -4
  104. package/docs/GATEWAY-ARCHITECTURE.md +158 -187
  105. package/package.json +1 -1
  106. package/skills/embassy-peer/SKILL.md +28 -22
  107. package/dist/src/gateway/codex-registration-generation.d.ts +0 -5
  108. package/dist/src/gateway/codex-registration-generation.js +0 -19
  109. package/dist/src/gateway/codex-registration-generation.js.map +0 -1
  110. package/dist/src/gateway/codex-registration-succession.d.ts +0 -209
  111. package/dist/src/gateway/codex-registration-succession.js +0 -588
  112. package/dist/src/gateway/codex-registration-succession.js.map +0 -1
  113. package/dist/src/gateway/compatibility.d.ts +0 -22
  114. package/dist/src/gateway/compatibility.js +0 -23
  115. package/dist/src/gateway/compatibility.js.map +0 -1
  116. package/dist/src/gateway/delivery-machine.d.ts +0 -235
  117. package/dist/src/gateway/delivery-machine.js +0 -540
  118. package/dist/src/gateway/delivery-machine.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,38 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
 
7
+ ## [1.8.0] - 2026-08-17
8
+
9
+ ### Changed
10
+
11
+ - The core was rebuilt from first principles around three primitives: durable logical routes with explicit consent edges; one durable message/attempt state machine (`queued -> reserved -> armed -> accepted -> terminal`, authorization as the consent linearization point, first terminal wins, ambiguous-after-arm with no replay ever); and small per-operation transports with no provider I/O under the durable commit lane. The gateway core shrank from 39,883 to 18,595 lines while keeping four providers, twelve directions, and every trust boundary.
12
+ - Codex delivery is stateless: registration records an alias and durable thread ID with zero App Server I/O; each delivery freshly attests the managed install, connects, resumes the exact thread (`excludeTurns`), performs one turn, and closes. Daemon and Desktop restarts are invisible to the next dispatch — the entire generation/reactivation/re-anchor lifecycle is deleted.
13
+ - Claude delivery goes through an exact prepared-frame boundary (immutable one-shot frames, in the production helper too); the launcher/version attestation is deleted entirely — Embassy validates only the artifacts it consumes, so any Claude Code install channel works and a missing registry degrades without blocking boot.
14
+ - Persisted state is strict schema v3 with one packaged offline command, `embassy convert-state-v2-to-v3` (backup-first, one strict pass, never starts providers); the runtime accepts only v3 and names `GATEWAY_STATE_CONVERSION_REQUIRED` for well-formed v2 state.
15
+ - A slow provider turn can no longer starve the control plane: reads never join the commit lane, unrelated targets run concurrently, and a deterministic 90-second-pause test holds it that way.
16
+
17
+ ### Added
18
+
19
+ - `embassy doctor` gains `managed_layout_missing` (a running server claims a managed layout that does not exist on disk) alongside the orphaned-Desktop, split-brain, and observation-age findings.
20
+ - A production-backed Claude wire conformance oracle and a frozen Codex wire contract anchor the per-provider release gates.
21
+
22
+ ### Removed
23
+
24
+ - `compatibility.ts`, the delivery machine, registration succession/generation journals, endpoint-refresh choreography, runtime version authority of any kind, and `EMBASSY_CLAUDE_BIN`. About 35,800 net lines left the repository across the v1.8 slices.
25
+
26
+ ## [1.7.1] - 2026-08-16
27
+
28
+ ### Fixed
29
+
30
+ - Provider I/O no longer runs under the gateway's commit lane: a slow provider turn (an 84-second first ACP dispatch, live) previously starved status reads, callbacks, and observations for its whole duration. Dispatch now prepares and performs outside the mutex with commit-time revalidation; interrupted operations settle honestly (ambiguous, never replayed); callback draining coalesces and re-arms.
31
+ - Connector health can no longer report "healthy" on stale evidence: a periodic bounded positive observation keeps evidence fresh, health degrades after 35 seconds without it, `observationAgeMs` is exported, and the static dashboard republishes at the freshness boundary.
32
+ - Claude routes no longer go stale across broker restarts: the previously-selected session is re-observed at boot and on a fixed timer by exact UUID (observation-only; such connections can never send, pair, answer approvals, or read credentials or history), including across the session's own restarts.
33
+ - The v1.6 stale-Codex reconnect guidance renders again (a v1.7.0 regression), in both languages.
34
+
35
+ ### Added
36
+
37
+ - `embassy doctor`: bounded, normalized attachment diagnosis — detects an orphaned Desktop (daemon running, no client attached) and a private-App-Server split-brain (Desktop running unattached, its tasks unreachable), identifies processes by executable path with distinct-PID accounting, reports every detected condition with a localized remedy, and never grants authority.
38
+
7
39
  ## [1.7.0] - 2026-08-16
8
40
 
9
41
  ### Added
package/CONTRIBUTING.md CHANGED
@@ -59,41 +59,36 @@ recovery.
59
59
  Neither path makes the inbound session outbound-selected.
60
60
  - Claude's session UUID is its stable logical identity. Current names are a
61
61
  live index; do not add historical-name routing or PID/socket identity.
62
- - Preserve current-name collision refusal and endpoint-generation fencing.
62
+ - Preserve current-name collision refusal and exact registration fencing.
63
+ - Codex registration is record-only: it changes the durable logical route and
64
+ performs no provider or App Server I/O. `register-codex --succeeds` is one
65
+ atomic logical replacement that settles queued/reserved work `cancelled`,
66
+ armed work `ambiguous`, and accepted work `unconfirmed`; removes every
67
+ incident consent edge and conversation, reply, or native capability; and
68
+ installs only the successor. Do not add prepared generations, re-anchoring,
69
+ or recovery journals.
63
70
 
64
71
  ### Provider adapters
65
72
 
66
73
  Claude Code's cross-session feature is official. Embassy's use of its external
67
- registry and peer socket shape remains an internal adapter: require the
68
- native peer protocol 1 and bounded live-schema probes while
69
- validating every consumed field and frame. Unknown top-level registry fields
70
- may be ignored; required and consumed fields remain strict, and rejection or
71
- observed-empty counts must stay loud. A certified same-major build is writable;
72
- a same-major build whose probes all pass is `schema_attested`, but it is
73
- writable only when those probes cover the write path. Claude's probes do.
74
- Ordinary Codex compatibility and registration reads remain read-only: they may
75
- include `initialize`, `thread/loaded/list`, and registration-time
76
- `thread/resume`, but do not invoke `turn/start`. The optional Codex
77
- write-attestation probe is the sole exception. It may create at most one
78
- disposable broker-owned thread per attempt, under a bounded write fence with
79
- zero user-thread contact; every created probe thread is archived and confirmed
80
- absent from the loaded set. The probe resolves the pinned model's lowest
81
- advertised effort. Whenever that model/effort pin cannot resolve, it declines
82
- in a zero-spend fail-safe before creating any thread or model turn. Untested
83
- Codex 0.x therefore remains monitor-only pending a certified write schema.
84
- Failed
85
- probes, a different major, or version evidence that cannot establish a safe
86
- major leave only that
87
- provider degraded, monitor-only, and write-fenced while the broker,
88
- control/dashboard surfaces, and other provider remain available; probes can
89
- never promote across a major or unknown version. Unsafe ownership, path,
90
- symlink, lease, state, or generation evidence for Embassy-owned or executed
91
- artifacts and Embassy callback, control, or state paths still aborts startup;
92
- an unsafe Claude-owned external sessions registry root quarantines only Claude.
93
- Do not widen a supported major or declared protocol without a
94
- documented review and deterministic fixtures. Different-major guidance must
95
- safely name the observed/tested versions and supported major, say that a
96
- supporting Embassy release is required, and never prescribe `embassy health`.
74
+ registry and peer socket shape remains an internal adapter: require native
75
+ peer protocol 1 and validate every consumed field and frame. Unknown top-level
76
+ registry fields may be ignored; required and consumed fields remain strict,
77
+ and rejected-record or observed-empty counts must stay loud. Embassy derives
78
+ the registry and callback roots from the verified current OS user; it does not
79
+ inspect a Claude launcher or configuration file. Codex registration
80
+ performs no provider I/O. Its bounded observer is display-only: it may report
81
+ freshness and safe codes but never authorizes, rejects, or delays a delivery.
82
+ Every Codex delivery instead creates an operation-local transport,
83
+ negotiates the current interface, and resumes the exact registered task with
84
+ history excluded before final write authorization. Unsafe ownership, path,
85
+ symlink, lease, state, or used-artifact generation evidence for Embassy-owned
86
+ or executed artifacts and Embassy callback, control, or state paths still
87
+ aborts startup; an unsafe Claude-owned external sessions registry root
88
+ quarantines only Claude. Provider versions remain diagnostic metadata, and
89
+ interface drift or an unavailable optional provider degrades only that
90
+ surface. Do not widen a declared protocol without documented review and
91
+ deterministic fixtures.
97
92
 
98
93
  The gateway may publish one process-owned `codex-*` peer so Claude's native
99
94
  `ListAgents` and `SendMessage` tools can reach Codex. It must never overwrite a
@@ -101,17 +96,21 @@ foreign registry record, claim to be a Claude model session, or unlink a socket
101
96
  whose exact generation it no longer owns.
102
97
 
103
98
  App Server calls use a closed allowlist. Do not add a generic RPC method,
104
- `turn/steer`, approval responses, history retrieval, shell execution, settings
105
- mutation, or provider authentication. Keep `experimentalApi: true`
106
- non-configurable and limited to `thread/resume.excludeTurns: true`; every resume
107
- must require an empty `thread.turns` response.
99
+ approval responses, history retrieval, shell execution, settings mutation, or
100
+ provider authentication. The only active-turn method is exact same-session
101
+ `turn/steer` for a leading `STEER:` body on the accepted operation, capped at
102
+ three and admitted only at the next tool-call boundary. Embassy never calls
103
+ `turn/interrupt`. Keep `experimentalApi: true` non-configurable and limited to
104
+ `thread/resume.excludeTurns: true`; every resume must require an empty
105
+ `thread.turns` response.
108
106
 
109
107
  ### Permissions
110
108
 
111
109
  Embassy does not set or override a Codex task's persistent approval or sandbox
112
- policy. Registration is the gateway reachability boundary. The connector may
113
- observe native route and approval-waiting status, but must not classify policy
114
- or turn workspace/settings metadata into a second authorization gate.
110
+ policy. Registration is the gateway reachability boundary. Bounded observation
111
+ may describe route and approval-waiting status, but it is never authority or a
112
+ dispatch gate and must not classify policy or turn workspace/settings metadata
113
+ into a second authorization gate.
115
114
 
116
115
  For Codex-to-Claude delivery, Claude's `crossSessionInbound` behavior remains
117
116
  native. Do not route around a hold or refusal or fabricate a successful receipt.
@@ -125,11 +124,12 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
125
124
  terminal failure, ambiguity, expiry, and restart abandonment.
126
125
  - Never retry an ambiguous provider write. Requeue only a confirmed clean
127
126
  deferral that has not crossed an ambiguous mutation boundary.
128
- - Restarts keep queued bodies under bounded retention and re-send each exactly
129
- once when its exact route is re-observed. A message in flight at the moment of
130
- a crash settles `ambiguous`; a message whose target authority was transient is
131
- abandoned rather than reconstructed. Restored routes stay stale until exact
132
- re-observation.
127
+ - The private mode-0600 v3 ledger retains bounded queued and recent bodies,
128
+ opaque delivery tokens, and status. Queued or reserved work may resume once
129
+ within its deadline and attempt budget against the same exact route and edge.
130
+ Armed work settles `ambiguous`; accepted work settles `unconfirmed`; neither
131
+ is replayed. Conversations, reply/native capabilities, raw frames, callback
132
+ addresses, and socket paths remain memory-only.
133
133
  - Persist native route identifiers only in the closed private binding schema.
134
134
  Keep them out of events, snapshots, dashboard rows, logs, errors, and CLI
135
135
  output. The only CLI exception is a UUID explicitly supplied by the user as a
@@ -147,10 +147,14 @@ single-user machine; exact Host on every request and exact Origin plus
147
147
  `X-Embassy-Request` on every POST constrain browser origins, not local
148
148
  software. Preserve the direct root URL, multi-window/browser access, collision
149
149
  failure with no fallback port, no CORS/`OPTIONS`, and only the reviewed pair,
150
- unpair, refresh-discovery, and stale-registration-removal mutations—never a
151
- provider or generic control method. Do not add a wildcard/remote listener,
152
- external assets, service workers, telemetry, or additional mutation endpoints.
153
- Keep the public v1 launcher foreground, macOS-only, and local-host-only.
150
+ unpair, refresh-discovery, and named Codex-registration-removal mutations—never
151
+ a provider or generic control method. Confirmed removal may target any named
152
+ Codex registration; its atomic commit removes incident consent edges and
153
+ conversation, reply, or native capabilities, and settles queued/reserved work
154
+ `cancelled`, armed work `ambiguous`, and accepted work `unconfirmed`. Do not
155
+ add a wildcard/remote listener, external assets, service workers, telemetry,
156
+ or additional mutation endpoints. Keep the public v1 launcher foreground,
157
+ macOS-only, and local-host-only.
154
158
 
155
159
  ## Live validation
156
160
 
package/README.md CHANGED
@@ -16,6 +16,22 @@ Your [Claude Code](https://code.claude.com) sessions, [Codex](https://chatgpt.co
16
16
 
17
17
  ```bash
18
18
  npm install -g agent-embassy
19
+ ```
20
+
21
+ Prerequisites, stated honestly: Claude routes require a live same-user Claude
22
+ Code session with peer protocol 1. Embassy derives the external registry and
23
+ peer-socket roots from the current OS user; it does not inspect Claude's
24
+ launcher or configuration. Codex routes require **a managed Codex App Server
25
+ standalone install** (created by the ChatGPT desktop app, or by the official
26
+ installer `curl -fsSL
27
+ https://chatgpt.com/codex/install.sh | sh` followed by `codex app-server
28
+ daemon start` — the daemon alone does not provision the layout). A missing
29
+ Claude registry degrades only Claude while the broker and other providers stay
30
+ available. pnpm users: pin the version (`pnpm install -g
31
+ agent-embassy@latest` can resolve stale metadata; prefer an explicit
32
+ version) and ensure `PNPM_HOME/bin` is on PATH in non-interactive shells.
33
+
34
+ ```bash
19
35
  embassy serve
20
36
  ```
21
37
 
@@ -36,7 +52,7 @@ The first command starts the managed daemon if it is not already running (`resta
36
52
 
37
53
  Desktop attaches to the managed standalone App Server when it launches. If the daemon restarts while Desktop is already open, waiting alone does not reconnect that app process: fully quit Desktop, rerun `/usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT`, and reopen the exact task.
38
54
 
39
- Runtime delivery is best effort. Version and build strings are unverified metadata and never grant or withhold routing authority. Consent plus exact owned route/session identity authorizes an attempt; the current connector, route state, and correlated operation determine its honest result. Unsupported or changed interfaces therefore fail with provider-local safe codes instead of an online compatibility tier. Embassy still validates the trust boundary: exact owned executable and state paths, endpoint generations, strict consumed protocol fields, Claude peer protocol 1, bounded queues, and no replay after an ambiguous write.
55
+ Runtime delivery is best effort. Version and build strings are unverified metadata and never grant or withhold routing authority. Consent plus exact logical route/session identity authorizes an attempt; the current per-operation transport and correlated evidence determine its honest result. Unsupported or changed interfaces therefore fail with provider-local safe codes instead of an online compatibility tier. Embassy still validates the trust boundary: exact owned or executed artifacts and state paths, generations of artifacts it actually uses, strict consumed protocol fields, Claude peer protocol 1, bounded queues, and no replay after an ambiguous write.
40
56
 
41
57
  > **Known limitation:** Embassy can reach Codex tasks only while Desktop uses the managed standalone App Server. In that mode, tasks currently cannot connect to Desktop's built-in in-app browser (`@Browser` loads but does not attach). Switching Desktop back to its default private App Server restores the built-in browser immediately — but makes those tasks unreachable by Embassy. No other capability regressions have been identified, though this was not an exhaustive parity test.
42
58
 
@@ -57,7 +73,7 @@ embassy status
57
73
 
58
74
  `status` lists `availablePeers` — the live Claude sessions you can select. If
59
75
  that list is empty, start a Claude Code session and run
60
- `embassy refresh-dashboard`, which re-runs Claude discovery; the next `status`
76
+ `embassy refresh-dashboard`, which refreshes discovery; the next `status`
61
77
  should show it.
62
78
 
63
79
  ### 2. Register the Codex task
@@ -70,7 +86,7 @@ embassy register-codex --alias codex-reviewer@this-mac
70
86
 
71
87
  You should see `"accepted":true`. The `codex-` prefix is required for Claude discovery. To retire the task later, run `embassy unregister-codex --alias codex-reviewer@this-mac` from inside that same task.
72
88
 
73
- Managed App Server generation changes and `embassy serve` restarts both use exact-task reactivation. A fresh initialize negotiates the connection; `thread/loaded/list` must find the byte-identical task exactly once before Embassy re-anchors the alias on that exact generation. A normal broker restart therefore needs no manual registration. A missing or duplicate exact task, changed generation, or failed negotiation leaves the route stale with a safe code; once that task is observable, rerun `embassy register-codex --alias codex-reviewer@this-mac` from the exact task without unregistering first. Embassy never retargets by alias or replays an ambiguously written body.
89
+ Registration records the exact inherited task identity and performs no App Server I/O. Every delivery opens a fresh attested local transport, initializes it, resumes that exact task with history excluded, and authorizes the body write once. App Server and Desktop restarts therefore do not require re-registration or re-anchoring; a current unavailable or unobservable task keeps the logical route and consent edge while the attempt reports an exact safe code. Embassy never retargets by alias or replays an ambiguously written body.
74
90
 
75
91
  ### 3. Select a Claude destination
76
92
 
@@ -152,7 +168,7 @@ is refused until one closes. If the port is occupied, startup fails explicitly,
152
168
  points to `--port`, and never falls back to another port. See
153
169
  [Dashboard](docs/DASHBOARD.md) for details.
154
170
 
155
- The live dashboard can also remove an orphaned Codex registration after an explicit confirmation, but only when the broker proves that the registration is stale and its owning endpoint generation is dead. A current, merely offline, or ambiguous generation is never removable through this recovery action.
171
+ The live dashboard can remove any named Codex registration after an explicit confirmation. The confirmation names the consequence: the broker deletes that registration's consent edges, cancels queued or reserved work, settles armed work ambiguous and accepted work unconfirmed, and never replays either uncertain class.
156
172
 
157
173
  The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html`. The live dashboard has no login, token, cookie, or per-browser session: it assumes a trusted single-user machine, and local software that can reach or spoof loopback can read it and invoke its bounded actions. The server still requires the exact Host header on every request and the exact Origin plus `X-Embassy-Request` on every POST; it sends no CORS headers and does not accept `OPTIONS`.
158
174
 
@@ -211,7 +227,8 @@ Codex tasks can then be prompted with `$embassy-peer`; Claude Code discovers it
211
227
  | --- | --- | --- |
212
228
  | `serve` | operator | Start the foreground broker and dashboard |
213
229
  | `health` / `status` | operator | Check liveness and inspect the sanitized snapshot |
214
- | `refresh-dashboard` | operator | Re-run Claude session discovery and regenerate both static dashboard files |
230
+ | `refresh-dashboard` | operator | Refresh provider discovery and regenerate both static dashboard files |
231
+ | `convert-state-v2-to-v3` | operator, broker stopped | Back up and convert the configured private state to native v3 without starting providers or the broker |
215
232
  | `dashboard --live [--lang en\|zh-CN] [--port <n>]` | operator | Start the live dashboard companion with bounded route-consent actions; requires a running `embassy serve` |
216
233
  | `delivery-status` | either provider | Read one delivery tracker with `embassy delivery-status --token dlv_<token>` |
217
234
  | `wait-delivery` | either provider | Wait for that tracker to settle, up to the delivery deadline |
@@ -232,11 +249,11 @@ or by replying with a leading `DONE:`. See [Delivery](docs/DELIVERY.md).
232
249
  ## Safety in one minute
233
250
 
234
251
  - **Local broker, stable loopback dashboard.** `embassy serve` listens on private Unix-domain sockets and makes no provider API call. The opt-in `embassy dashboard --live` companion is a separate process and the only listener Embassy can create, bound to exact `127.0.0.1` on stable port `41961` by default (or the per-invocation `--port <n>`). It is deliberately unauthenticated local HTTP for a trusted single-user machine; Host, Origin, and sentinel checks constrain browser-origin requests but do not authenticate local processes or OS users.
235
- - **Same-UID containment, not authentication.** Caller identity is inherited from the local process environment. Route ownership and generation checks reduce mistakes, but are not a defense against code already running as your OS user.
236
- - **Compatibility is tested offline; runtime is best effort.** The release-owned support matrix records exact tested artifacts, protocols, capabilities, stop fidelity, limitations, and test dates. Runtime never imports that matrix and never turns a version fact into authority. It validates exact owned boundaries and protocol facts, attempts the current operation, and reports provider-local health, route staleness, and safe codes without replaying uncertainty.
252
+ - **Same-UID containment, not authentication.** Caller identity is inherited from the local process environment. Route ownership and per-operation artifact checks reduce mistakes, but are not a defense against code already running as your OS user.
253
+ - **Compatibility is tested offline; runtime is best effort.** The release-owned support matrix records exact tested artifacts, protocols, capabilities, stop fidelity, limitations, and test dates. Runtime never imports that matrix and never turns a version fact into authority. It validates exact owned boundaries and protocol facts, attempts the current operation, and reports provider-local health and safe codes without replaying uncertainty.
237
254
  - **Native permissions stay native.** Embassy sends no Codex approval or sandbox overrides and answers no approval request. `crossSessionInbound` remains Claude's own control; Embassy cannot override it.
238
255
  - **Provenance is marked, not authenticated.** Routed bodies carry one broker-owned cross-session marker with the verified sender alias; it distinguishes the transport path for the receiving model but cannot make untrusted text safe or authenticate against code already running as your OS user.
239
- - **Bodies stored, bounded, and yours.** Message bodies persist in the broker's private mode-0600 state under bounded retention so the ledger can show you the mail itself; queued mail survives a broker restart and re-sends exactly once. Raw provider frames stay memory-only. The static dashboard files remain metadata-only; the live dashboard shows retained bodies.
256
+ - **Bodies and delivery status stored, bounded, and yours.** Message bodies and their opaque delivery token/status persist in the broker's private mode-0600 v3 state under bounded retention; queued or reserved work may resume once after restart, while armed or provider-accepted work is never replayed. A delivery token never enters a public snapshot, normal log, provider receipt, or dashboard. Raw provider frames stay memory-only. The static dashboard files remain metadata-only; the live dashboard shows retained bodies.
240
257
 
241
258
  See [SECURITY.md](SECURITY.md) for the full boundary and vulnerability-reporting process.
242
259
 
@@ -253,7 +270,7 @@ See [SECURITY.md](SECURITY.md) for the full boundary and vulnerability-reporting
253
270
  | --- | --- |
254
271
  | [Architecture](docs/GATEWAY-ARCHITECTURE.md) | The full design: topology, adapters, control plane, threat model, and the paired-consent inbound model |
255
272
  | [Delivery](docs/DELIVERY.md) | Delivery semantics, tokens, settlement states, and retry rules |
256
- | [Configuration](docs/CONFIGURATION.md) | Environment variables, compatibility contract, and addressing rules |
273
+ | [Configuration](docs/CONFIGURATION.md) | Environment variables, provider contracts, and addressing rules |
257
274
  | [Dashboard](docs/DASHBOARD.md) | Static and live dashboard setup, security model, and mutation actions |
258
275
  | [Security policy](SECURITY.md) | How to report a vulnerability, and the boundary in depth |
259
276
  | [Contributing](CONTRIBUTING.md) | Where changes go, and how to run the deterministic suite |
package/README.zh-CN.md CHANGED
@@ -16,6 +16,18 @@
16
16
 
17
17
  ```bash
18
18
  npm install -g agent-embassy
19
+ ```
20
+
21
+ 如实说明前置要求:Claude 路由需要一个使用对等协议 1 的同用户在线 Claude
22
+ Code 会话。Embassy 从当前 OS 用户派生外部注册表与对等套接字根目录;它不会
23
+ 检查 Claude 启动器或配置。Codex 路由需要托管独立 App Server 安装(可由
24
+ ChatGPT 桌面应用创建,或运行官方安装器 `curl -fsSL
25
+ https://chatgpt.com/codex/install.sh | sh`,再运行 `codex app-server daemon
26
+ start`;单独启动守护进程不会配置该布局)。Claude 注册表缺失时,Embassy
27
+ 会将 Claude 报告为降级,同时保持代理与其他提供方可用。pnpm 用户应固定
28
+ 版本;非交互式 shell 中还需确保 `PNPM_HOME/bin` 位于 `PATH`。
29
+
30
+ ```bash
19
31
  embassy serve
20
32
  ```
21
33
 
@@ -36,7 +48,7 @@ Embassy 专为单人、单一 macOS 账户以及你已信任以该用户身份
36
48
 
37
49
  Desktop 仅在启动时附着到托管独立 App Server。如果 Desktop 已打开时守护进程重启,单纯等待不会让该应用进程重新连接:请完全退出 Desktop,重新运行 `/usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT`,再打开该确切任务。
38
50
 
39
- 运行时投递采用尽力而为模式。版本与构建字符串只是未经验证的元数据,绝不授予或撤销路由权限。同意加上精确的自有路由/会话身份会授权一次尝试;当前连接器、路由状态与相关操作决定诚实结果。接口不受支持或发生变化时,Embassy 会返回提供方局部的安全代码,而不是在线兼容性等级。Embassy 仍会验证信任边界:精确自有的可执行文件与状态路径、端点代际、被消费协议字段的严格结构、Claude 对等协议 1、有界队列,以及结果不确定的写入绝不重放。
51
+ 运行时投递采用尽力而为模式。版本与构建字符串只是未经验证的元数据,绝不授予或撤销路由权限。同意加上精确的逻辑路由/会话身份会授权一次尝试;当前逐操作传输与相关证据决定诚实结果。接口不受支持或发生变化时,Embassy 会返回提供方局部的安全代码,而不是在线兼容性等级。Embassy 仍会验证信任边界:精确自有或执行的构件与状态路径、实际使用构件的代际、被消费协议字段的严格结构、Claude 对等协议 1、有界队列,以及结果不确定的写入绝不重放。
40
52
 
41
53
  > **已知限制:** 仅当 Desktop 使用托管独立 App Server 时,Embassy 才能访问 Codex 任务。在该模式下,任务目前无法连接 Desktop 内置的应用内浏览器(`@Browser` 可加载但无法附着)。将 Desktop 切换回其默认的私有 App Server 会立即恢复内置浏览器——但会使这些任务对 Embassy 不可达。目前未发现其他能力回退,但这并非穷尽的能力对比测试。
42
54
 
@@ -55,7 +67,7 @@ embassy health
55
67
  embassy status
56
68
  ```
57
69
 
58
- `status` 列出 `availablePeers`——你可以选择的在线 Claude 会话。如果该列表为空,请先启动一个 Claude Code 会话,然后运行 `embassy refresh-dashboard`——它会重新执行 Claude 发现;下一次 `status` 应该就能看到该会话。
70
+ `status` 列出 `availablePeers`——你可以选择的在线 Claude 会话。如果该列表为空,请先启动一个 Claude Code 会话,然后运行 `embassy refresh-dashboard` 刷新发现;下一次 `status` 应该就能看到该会话。
59
71
 
60
72
  ### 2. 注册 Codex 任务
61
73
 
@@ -67,7 +79,7 @@ embassy register-codex --alias codex-reviewer@this-mac
67
79
 
68
80
  你应看到 `"accepted":true`。`codex-` 前缀是 Claude 发现所必需的。之后若要注销该任务,请在同一个任务内运行 `embassy unregister-codex --alias codex-reviewer@this-mac`。
69
81
 
70
- 托管 App Server 端点代际变更与 `embassy serve` 重启都会使用精确任务重新激活。新的 `initialize` 用于协商连接;只有 `thread/loaded/list` 恰好一次找到字节级一致的原任务时,Embassy 才会在该精确代际上重新锚定别名。因此,正常的代理重启不需要手动重新注册。精确任务缺失或重复、代际变化或协商失败都会让路由以安全代码保持陈旧;任务恢复可观察后,请从精确任务内再次运行 `embassy register-codex --alias codex-reviewer@this-mac`,且不要先注销。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
82
+ 注册会记录精确的继承任务身份,并且不执行 App Server I/O。每次投递都会打开并验证新的本地传输,初始化后在排除历史的前提下恢复精确任务,并仅授权一次正文写入。因此 App Server、Desktop `embassy serve` 重启都不需要重新注册或重新锚定;当前任务不可用或无法观测时,尝试会返回精确安全代码,而逻辑路由与同意边保持不变。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
71
83
 
72
84
  ### 3. 选择 Claude 目的地
73
85
 
@@ -129,7 +141,7 @@ Embassy 会在实际写入提供方之前,为双向路由消息添加一个由
129
141
 
130
142
  `embassy dashboard --live` 在浏览器中打开一个五选项卡流式视图(总览、投递、路由、活动、诊断),默认地址为 `http://127.0.0.1:41961/`。如需为本次启动选择另一个稳定端口,请运行 `embassy dashboard --live --port <n>`,其中整数范围为 1024 到 65535。当前台组件运行时,该 URL 最多支持四个并发实时视图(可分布在窗口、标签页或浏览器中);在其中一个关闭前,第五条流会被拒绝。若端口已被占用,启动会明确失败并提示使用 `--port`,不会回退到其他端口。详见[仪表盘](docs/DASHBOARD.zh-CN.md)。
131
143
 
132
- 实时仪表盘也可以在明确确认后移除孤立的 Codex 注册,但仅限代理已经证明该注册陈旧且其所属端点代际已失效的情况。当前、仅离线或代际状态不明确的注册绝不能通过此恢复操作移除。
144
+ 实时仪表盘可在明确确认后移除任意具名 Codex 注册。确认步骤会说明后果:代理会删除该注册的同意边、取消已排队或已保留的工作、把已武装的工作结算为结果不确定、把已接受的工作结算为未确认,并且绝不重放后两类不确定工作。
133
145
 
134
146
  代理还会以 mode 0600 发布静态快照 `gateway-dashboard.html` 与 `gateway-dashboard.zh-CN.html`。实时仪表盘没有登录、令牌、Cookie 或逐浏览器会话:它假定这是一台可信的单用户机器;能够访问或伪造 loopback 的本地软件可以读取仪表盘并调用其有限操作。服务器仍会对每个请求要求精确的 Host 头,并对每个 POST 要求精确的 Origin 与 `X-Embassy-Request`;它不发送 CORS 头,也不接受 `OPTIONS`。
135
147
 
@@ -186,7 +198,8 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
186
198
  | --- | --- | --- |
187
199
  | `serve` | 操作员 | 启动前台代理和仪表盘 |
188
200
  | `health` / `status` | 操作员 | 检查存活状态并查看脱敏快照 |
189
- | `refresh-dashboard` | 操作员 | 重新执行 Claude 会话发现,并重新生成两个静态仪表盘文件 |
201
+ | `refresh-dashboard` | 操作员 | 刷新提供方发现,并重新生成两个静态仪表盘文件 |
202
+ | `convert-state-v2-to-v3` | 操作员,代理已停止 | 备份已配置的私有状态并离线转换为原生 v3,不启动提供方或代理 |
190
203
  | `dashboard --live [--lang en\|zh-CN] [--port <n>]` | 操作员 | 启动带有限路由同意操作的实时仪表盘组件;需要 `embassy serve` 正在运行 |
191
204
  | `delivery-status` | 任一提供方 | 使用 `embassy delivery-status --token dlv_<token>` 读取单条投递跟踪器 |
192
205
  | `wait-delivery` | 任一提供方 | 等待该跟踪器结算,直至投递截止时间 |
@@ -203,11 +216,11 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
203
216
  ## 一分钟了解安全性
204
217
 
205
218
  - **本地代理,稳定的 loopback 仪表盘。** `embassy serve` 仅监听私有 Unix 域套接字,不发起任何提供商 API 调用。可选启用的 `embassy dashboard --live` 组件是一个独立进程,也是 Embassy 能创建的唯一监听器;它精确绑定 `127.0.0.1`,默认使用稳定端口 `41961`(也可为本次启动传入 `--port <n>`)。它是在可信单用户机器上有意不设身份认证的本地 HTTP;Host、Origin 与哨兵检查约束浏览器来源的请求,但不认证本地进程或 OS 用户。
206
- - **同 UID 隔离,而非身份认证。** 调用者身份继承自本地进程环境。路由所有权和生成号检查能减少误操作,但不是对已以你的 OS 用户身份运行的代码的防御。
207
- - **兼容性在离线阶段测试;运行时尽力而为。** 发布版自有支持矩阵记录精确已测构件、协议、能力、停止保真度、限制与测试日期。运行时从不导入该矩阵,也绝不会把版本事实变成权限。它验证精确自有边界与协议事实,尝试当前操作,并以提供方局部健康度、路由陈旧状态和安全代码报告结果,且绝不重放不确定写入。
219
+ - **同 UID 隔离,而非身份认证。** 调用者身份继承自本地进程环境。路由所有权和逐操作构件检查能减少误操作,但不是对已以你的 OS 用户身份运行的代码的防御。
220
+ - **兼容性在离线阶段测试;运行时尽力而为。** 发布版自有支持矩阵记录精确已测构件、协议、能力、停止保真度、限制与测试日期。运行时从不导入该矩阵,也绝不会把版本事实变成权限。它验证精确自有边界与协议事实,尝试当前操作,并以提供方局部健康度和安全代码报告结果,且绝不重放不确定写入。
208
221
  - **来源标记是提示,不是签名。** Embassy 在提供方写入边界生成跨会话来源封装,让接收模型能够区分代理路由消息及其已验证发送方别名;这不是密码学证明,也不会把不可信正文变成可信指令。
209
222
  - **原生权限保持原生。** Embassy 不发送任何 Codex 审批或沙盒覆盖,也不应答任何审批请求。`crossSessionInbound` 仍是 Claude 自身的控制机制;Embassy 无法覆盖它。
210
- - **消息体有界保存,属于你。** 消息体以有界保留策略持久化在 broker 的私有 mode-0600 状态中,让台账能够展示邮件本身;排队中的邮件在 broker 重启后幸存并恰好重发一次。原始提供方帧仍仅存于内存。静态仪表盘文件保持仅元数据;实时仪表盘展示保留的正文。
223
+ - **消息体和投递状态有界保存,属于你。** 消息体及其不透明投递令牌/状态以有界保留策略持久化在 broker 的私有 mode-0600 v3 状态中;排队或已保留但尚未武装的邮件可在 broker 重启后恢复一次,已武装或已被提供方接受的工作绝不重放。投递令牌绝不会进入公开快照、普通日志、提供方回执或任何仪表盘。原始提供方帧仍仅存于内存。静态仪表盘文件保持仅元数据;实时仪表盘展示保留的正文。
211
224
 
212
225
  完整的安全边界和漏洞报告流程请参见 [SECURITY.md](SECURITY.md)。
213
226
 
@@ -224,7 +237,7 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
224
237
  | --- | --- |
225
238
  | [架构](docs/GATEWAY-ARCHITECTURE.md) | 完整设计:拓扑、适配器、控制平面、威胁模型,以及基于配对同意的入站模型 |
226
239
  | [投递](docs/DELIVERY.zh-CN.md) | 投递语义、令牌、结算状态与重试规则 |
227
- | [配置](docs/CONFIGURATION.zh-CN.md) | 环境变量、兼容性约定与寻址规则 |
240
+ | [配置](docs/CONFIGURATION.zh-CN.md) | 环境变量、提供方契约与寻址规则 |
228
241
  | [仪表盘](docs/DASHBOARD.zh-CN.md) | 静态与实时仪表盘设置、安全模型与变更操作 |
229
242
  | [安全策略](SECURITY.md) | 如何报告漏洞,以及详细的安全边界 |
230
243
  | [贡献指南](CONTRIBUTING.md) | 变更的归属位置,以及如何运行确定性测试套件 |
package/SECURITY.md CHANGED
@@ -34,7 +34,8 @@ Embassy provides same-UID containment and route attribution, not authentication
34
34
  against other processes running as the same OS user.
35
35
 
36
36
  - A Codex route is attributed to the exact inherited `CODEX_THREAD_ID` of the
37
- task that self-registers it.
37
+ task that self-registers it. App Server attachment and endpoint generations
38
+ are current transport facts, never durable route authority.
38
39
  - A Claude route is attributed to a validated live peer generation and native
39
40
  session UUID. An inherited `CLAUDE_CODE_MESSAGING_SOCKET` is a transient
40
41
  reply capability, not a credential.
@@ -62,8 +63,10 @@ review, and audit work.
62
63
  symlink policy, modes, approved version-directory containment, its own state
63
64
  and sockets, and the generation of artifacts it owns. Before acting on an
64
65
  identity-bearing input—such as an inherited task identity, provider record,
65
- endpoint binding, route, or reply request—it validates the input's bounded
66
- shape and its current ownership, correlation, and generation. Unsafe
66
+ route, provider record, or reply request—it validates the input's bounded
67
+ shape and its current ownership and correlation. Immediately before an
68
+ effect, the owning transport re-attests every changing path, socket,
69
+ process, interface, target, and generation fact it actually uses. Unsafe
67
70
  controller-wide evidence is fatal; this class comprises Embassy-owned or
68
71
  executed artifacts and Embassy callback, control, and state paths. The
69
72
  Claude-owned external sessions registry root is instead a read-side identity
@@ -99,8 +102,10 @@ review, and audit work.
99
102
  single-user machine.
100
103
  - **Predictions based on version strings.** A version string is diagnostic
101
104
  metadata, never routing authority, security evidence, or attack detection.
102
- Current path, ownership, protocol, interface, generation, and correlated
103
- operation facts decide what Embassy can safely do. Boot refusal is reserved
105
+ Current path, ownership, protocol, interface, used-artifact generation, and
106
+ correlated operation facts decide what Embassy can safely do. Codex
107
+ registration performs no provider I/O; every delivery proves the current
108
+ boundary independently. Boot refusal is reserved
104
109
  for an unsafe or lost singleton lease, corrupt controller state, or an unsafe
105
110
  OS boundary. Interface drift or one unavailable optional provider degrades
106
111
  that surface; it does not take down the broker or the other providers.
@@ -127,9 +132,10 @@ silently expand Embassy's claimed boundary.
127
132
  - Pairs are additive, bounded, and per-edge: adding an edge never retires
128
133
  another, and removing one invalidates its active conversation capabilities
129
134
  before the change is published. Explicitly requested endpoint replacement
130
- (registration succession) atomically settles the outgoing endpoint's
131
- accepted work before the replacement is exposed; a half-replaced
132
- intermediate state is never published.
135
+ (`register-codex --succeeds`) is one atomic logical-route transaction: it
136
+ settles the outgoing route's work by recorded write phase, removes its edges
137
+ and capabilities, and publishes only the replacement. There is no prepared,
138
+ activated, re-anchored, or recovery generation and no half-replaced state.
133
139
  - Embassy never mutates a Codex task's approval or sandbox policy and never
134
140
  answers an approval request. An inbound turn uses the task's existing native
135
141
  policy. With `approvalPolicy: never`, no human confirmation occurs on that
@@ -177,12 +183,13 @@ broker.
177
183
  startup; unsafe UID or mode evidence for Claude's external sessions registry
178
184
  root quarantines only Claude. A provider version is best-effort diagnostic
179
185
  metadata and carries no routing authority. Runtime authority comes from an
180
- explicit pair, exact owned route and session identity, current connector and
181
- generation facts, strict protocol handling, and correlated operation results.
186
+ explicit pair, exact owned route and session identity, current
187
+ per-operation transport facts, strict protocol handling, and correlated
188
+ operation results.
182
189
  A Claude record whose peer protocol is not 1 is rejected in isolation and
183
- included in bounded rejection evidence. Every replacement Codex endpoint
184
- generation must negotiate its current interface and re-observe the exact task
185
- before the controller re-anchors it.
190
+ included in bounded rejection evidence. Every Codex endpoint used by a
191
+ delivery must negotiate its current interface and resume the exact task
192
+ before that operation receives final write authorization.
186
193
  - Embassy publishes at most one process-owned `codex-*` record in Claude's
187
194
  registry with the supported explicit versioned Embassy-advertisement marker.
188
195
  The prefix is a visible alias convention, not the discriminator: an unmarked
@@ -198,8 +205,8 @@ broker.
198
205
  admits it at the next tool-call boundary; Embassy never interrupts or injects
199
206
  mid-generation. Clean boundary refusal falls back to the normal queue, which
200
207
  retains at most three steers per route. The environment kill switch defaults
201
- on and can disable this classification globally. Interrupt remains limited to
202
- an exact turn started and positively observed by the same connector.
208
+ on and can disable this classification globally. Embassy never issues
209
+ `turn/interrupt`.
203
210
  - The tested App Server 0.147.0 initialization enables `experimentalApi: true`
204
211
  solely for `thread/resume.excludeTurns: true`. It adds no general
205
212
  experimental method or authority. Missing, malformed, or nonempty returned
@@ -235,18 +242,21 @@ kernel lock.
235
242
 
236
243
  Embassy's provider-facing access is intentionally enumerable:
237
244
 
238
- - read and execute the configured Claude launcher only for bounded automatic
239
- path, version-banner, and compatibility observation;
240
- - read the live Claude session registry and connect validated peer sockets;
245
+ - derive the fixed Claude registry and callback roots from the verified current
246
+ OS user, without reading a Claude launcher or configuration file;
247
+ - read the live Claude session registry and validate only the registry record,
248
+ peer socket, PID, workspace, state-root, and generation evidence used by the
249
+ current operation;
241
250
  - create and later remove its one callback socket and one registry record;
242
- - resolve the managed Codex installation and attach to the already-running
243
- local App Server; and
251
+ - resolve the managed Codex installation and open one attested local App Server
252
+ connection per operation; and
244
253
  - inspect canonical filesystem metadata needed to validate provider-advertised
245
254
  endpoints and generations.
246
255
 
247
256
  The Claude-owned external sessions registry root must be owned by the current
248
257
  UID with exact mode 0700 before Embassy enumerates it; failure quarantines and
249
- write-fences only Claude. Within an admitted root, individual registry records
258
+ write-fences only Claude, including when that registry root is absent. Within
259
+ an admitted root, individual registry records
250
260
  and peer sockets retain their bounded schema, file/socket type, PID/path and
251
261
  allowed-root correlation, accessibility, liveness, and generation checks.
252
262
  Embassy invents no additional owner or mode rule for those individual
@@ -261,9 +271,10 @@ configuration contents. Report a bug if any normal code path attempts to do so.
261
271
  Raw provider frames, tool data, stderr, callback addresses, and socket paths
262
272
  remain memory-only and are discarded on restart. Message bodies are the
263
273
  exception: queued and recently delivered bodies are retained under bounded caps
264
- in the mode-0600 state file, so queued mail survives a broker restart and
265
- re-sends exactly once when its route is re-observed. A message in flight at the
266
- moment of a crash settles `ambiguous` and is never replayed.
274
+ in the mode-0600 state file. A queued or reserved message may resume once after
275
+ a broker restart against its still-exact logical route and consent edge. An
276
+ armed or accepted message at crash settles ambiguous or unconfirmed and is
277
+ never replayed.
267
278
 
268
279
  The full `conv_` token exposed to a CLI initiator or routed recipient travels
269
280
  only inside the accepted CLI result or transient provider payload. It is never
@@ -275,7 +286,7 @@ generations, or private route handles. The untrusted body remains opaque text
275
286
  and may itself contain sender-provided strings.
276
287
 
277
288
  The closed private binding store may retain the exact Codex thread ID and Claude
278
- session UUID required for ownership and endpoint re-observation. Native IDs are
289
+ session UUID required for logical ownership. Native IDs are
279
290
  forbidden from public snapshots, normalized events, the dashboard, aliases,
280
291
  logs, errors, and CLI output. A Claude UUID may enter only as a user-supplied
281
292
  explicit CLI selector; Embassy never discovers or prints it publicly.
@@ -311,9 +322,11 @@ Origin; every POST requires the exact Origin plus
311
322
  Those checks block ambient cross-origin browser requests but do not authenticate
312
323
  local software. There are no generic control or provider routes, telemetry, or
313
324
  external assets. The sole mutation route accepts only exact pair, unpair,
314
- refresh-discovery, and broker-guarded stale-Codex-registration-removal JSON
315
- bodies, capped at 1 KiB and six confirmed actions per minute. The browser
316
- cannot create a registration, live-unregister a task, send, reply, approve,
325
+ refresh-discovery, and named Codex-registration-removal JSON bodies, capped at
326
+ 1 KiB and six confirmed actions per minute. Registration removal requires an
327
+ in-page consequence confirmation; it removes incident consent edges and
328
+ settles active work by its durable write phase. The browser cannot create a
329
+ registration, send, reply, approve,
317
330
  interrupt, change settings, or invoke arbitrary broker/provider methods.
318
331
 
319
332
  Reports involving the live companion are in scope if they demonstrate a
@@ -334,15 +347,15 @@ exact OS boundaries. Unsafe Embassy-owned or executed artifacts, callback,
334
347
  control, or state paths remain startup-fatal; unsafe UID or mode evidence on
335
348
  Claude's external sessions registry root quarantines only that provider.
336
349
  Runtime does not import the release-owned support matrix or derive authority
337
- from version metadata. It reports best-effort connector health, route
338
- staleness, observed metadata, and last safe codes while strict record, frame,
339
- response, identity, generation, correlation, and deadline checks decide each
350
+ from version metadata. It reports best-effort connector health, observation
351
+ freshness, and last safe codes while strict record, frame, response, identity,
352
+ current used-artifact generation, correlation, and deadline checks decide each
340
353
  operation. Claude registry parsing remains strict for every required and
341
354
  consumed field while ignoring unknown top-level fields; bounded rejected-record
342
- counts and an observed-empty registry are surfaced instead of hidden. A
343
- replacement Codex endpoint negotiates its current interface and re-observes the
344
- exact registered task before re-anchoring. No validation traffic routes a user
345
- message or starts a model turn.
355
+ counts and an observed-empty registry are surfaced instead of hidden. Each
356
+ Codex delivery independently attests, connects, initializes, and resumes the
357
+ exact registered task before its final write authorization. No observation
358
+ traffic routes a user message or starts a model turn.
346
359
 
347
360
  Passive live discovery, a live provider connection, a native message, and an
348
361
  App Server turn are distinct authorization gates. Each requires an explicit
@@ -57,17 +57,14 @@ export type AcpPromptReceipt = Readonly<{
57
57
  text: string;
58
58
  textTruncated: boolean;
59
59
  }>;
60
- export type AcpOptionalResult<T> = Readonly<{
61
- available: true;
62
- value: T;
63
- }> | Readonly<{
64
- available: false;
65
- reason: "not_advertised" | "method_not_found";
66
- }>;
67
- export type AcpSessionOptions = Readonly<{
68
- sessionId: string;
69
- cwd: string;
70
- mcpServers?: readonly unknown[];
60
+ export type AcpPreparedPrompt = Readonly<{
61
+ bodyBytes: number;
62
+ frameBytes: number;
63
+ sha256: string;
64
+ /** Release a prepared-but-unperformed prompt exactly once. */
65
+ cancel: () => void;
66
+ /** Enqueue the exact pre-serialized frame exactly once. */
67
+ perform: () => Promise<AcpPromptReceipt>;
71
68
  }>;
72
69
  export declare class AcpRequestError extends Error {
73
70
  readonly detail: AcpRpcErrorDetail;
@@ -92,20 +89,16 @@ export declare class AcpClient {
92
89
  sessionId: string;
93
90
  }>>;
94
91
  prompt(sessionId: string, text: string): Promise<AcpPromptReceipt>;
92
+ preparePrompt(sessionId: string, text: string): AcpPreparedPrompt;
95
93
  cancel(sessionId: string): Promise<void>;
96
- authenticate(methodId: string): Promise<void>;
97
- listSessions(params?: Readonly<{
98
- cwd?: string;
99
- cursor?: string;
100
- }>): Promise<AcpOptionalResult<unknown>>;
101
- resumeSession(options: AcpSessionOptions): Promise<AcpOptionalResult<unknown>>;
102
- loadSession(options: AcpSessionOptions): Promise<AcpOptionalResult<unknown>>;
103
94
  close(): void;
95
+ private performPreparedPrompt;
104
96
  private initialize;
105
- private optionalRequest;
106
97
  private request;
98
+ private requestSerialized;
107
99
  private notify;
108
100
  private write;
101
+ private writeSerialized;
109
102
  private handleLine;
110
103
  private handleInbound;
111
104
  private consumeSessionUpdate;