agent-embassy 1.0.0 → 1.3.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 (102) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/CONTRIBUTING.md +25 -7
  3. package/README.md +66 -13
  4. package/README.zh-CN.md +41 -13
  5. package/SECURITY.md +80 -42
  6. package/assets/live-dashboard/app.css +14 -5
  7. package/dist/src/gateway/claude-helper-protocol.d.ts +3 -0
  8. package/dist/src/gateway/claude-helper-protocol.js +15 -1
  9. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  10. package/dist/src/gateway/claude-helper-supervisor.d.ts +2 -0
  11. package/dist/src/gateway/claude-helper-supervisor.js +24 -1
  12. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  13. package/dist/src/gateway/claude-runtime.d.ts +0 -2
  14. package/dist/src/gateway/claude-runtime.js +6 -17
  15. package/dist/src/gateway/claude-runtime.js.map +1 -1
  16. package/dist/src/gateway/cli-copy.d.ts +1 -1
  17. package/dist/src/gateway/cli-copy.en.d.ts +4 -1
  18. package/dist/src/gateway/cli-copy.en.js +6 -3
  19. package/dist/src/gateway/cli-copy.en.js.map +1 -1
  20. package/dist/src/gateway/cli-copy.js +2 -0
  21. package/dist/src/gateway/cli-copy.js.map +1 -1
  22. package/dist/src/gateway/cli-copy.zh-CN.d.ts +4 -1
  23. package/dist/src/gateway/cli-copy.zh-CN.js +6 -3
  24. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
  25. package/dist/src/gateway/cli.d.ts +2 -5
  26. package/dist/src/gateway/cli.js +49 -73
  27. package/dist/src/gateway/cli.js.map +1 -1
  28. package/dist/src/gateway/codex-app-server.d.ts +1 -7
  29. package/dist/src/gateway/codex-app-server.js +10 -53
  30. package/dist/src/gateway/codex-app-server.js.map +1 -1
  31. package/dist/src/gateway/codex-local-transport.d.ts +10 -3
  32. package/dist/src/gateway/codex-local-transport.js +25 -9
  33. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  34. package/dist/src/gateway/compatibility.d.ts +0 -27
  35. package/dist/src/gateway/compatibility.js +1 -101
  36. package/dist/src/gateway/compatibility.js.map +1 -1
  37. package/dist/src/gateway/config.d.ts +0 -3
  38. package/dist/src/gateway/config.js +4 -12
  39. package/dist/src/gateway/config.js.map +1 -1
  40. package/dist/src/gateway/control.d.ts +11 -20
  41. package/dist/src/gateway/control.js +50 -47
  42. package/dist/src/gateway/control.js.map +1 -1
  43. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  44. package/dist/src/gateway/dashboard-copy.en.d.ts +12 -7
  45. package/dist/src/gateway/dashboard-copy.en.js +26 -21
  46. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  47. package/dist/src/gateway/dashboard-copy.js +12 -7
  48. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  49. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +12 -7
  50. package/dist/src/gateway/dashboard-copy.zh-CN.js +26 -21
  51. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  52. package/dist/src/gateway/dashboard-model.d.ts +7 -9
  53. package/dist/src/gateway/dashboard-model.js +47 -16
  54. package/dist/src/gateway/dashboard-model.js.map +1 -1
  55. package/dist/src/gateway/dashboard.js +10 -10
  56. package/dist/src/gateway/dashboard.js.map +1 -1
  57. package/dist/src/gateway/live-dashboard-app/app.js +65 -55
  58. package/dist/src/gateway/live-dashboard-command.d.ts +5 -1
  59. package/dist/src/gateway/live-dashboard-command.js +18 -6
  60. package/dist/src/gateway/live-dashboard-command.js.map +1 -1
  61. package/dist/src/gateway/live-dashboard-http.d.ts +3 -4
  62. package/dist/src/gateway/live-dashboard-http.js +32 -93
  63. package/dist/src/gateway/live-dashboard-http.js.map +1 -1
  64. package/dist/src/gateway/live-dashboard-protocol.d.ts +1 -5
  65. package/dist/src/gateway/live-dashboard-protocol.js +0 -42
  66. package/dist/src/gateway/live-dashboard-protocol.js.map +1 -1
  67. package/dist/src/gateway/live-dashboard-server.d.ts +2 -2
  68. package/dist/src/gateway/live-dashboard-server.js +18 -4
  69. package/dist/src/gateway/live-dashboard-server.js.map +1 -1
  70. package/dist/src/gateway/live-dashboard-stream.js +26 -25
  71. package/dist/src/gateway/live-dashboard-stream.js.map +1 -1
  72. package/dist/src/gateway/live-dashboard.d.ts +3 -6
  73. package/dist/src/gateway/live-dashboard.js +6 -42
  74. package/dist/src/gateway/live-dashboard.js.map +1 -1
  75. package/dist/src/gateway/provenance-envelope.d.ts +16 -0
  76. package/dist/src/gateway/provenance-envelope.js +80 -0
  77. package/dist/src/gateway/provenance-envelope.js.map +1 -0
  78. package/dist/src/gateway/providers.d.ts +40 -33
  79. package/dist/src/gateway/providers.js +683 -302
  80. package/dist/src/gateway/providers.js.map +1 -1
  81. package/dist/src/gateway/server.d.ts +2 -0
  82. package/dist/src/gateway/server.js +8 -5
  83. package/dist/src/gateway/server.js.map +1 -1
  84. package/dist/src/gateway/service.d.ts +103 -23
  85. package/dist/src/gateway/service.js +1346 -272
  86. package/dist/src/gateway/service.js.map +1 -1
  87. package/dist/src/gateway/store.d.ts +39 -3
  88. package/dist/src/gateway/store.js +604 -44
  89. package/dist/src/gateway/store.js.map +1 -1
  90. package/dist/src/gateway/types.d.ts +90 -9
  91. package/dist/src/gateway/types.js +6 -0
  92. package/dist/src/gateway/types.js.map +1 -1
  93. package/docs/GATEWAY-ARCHITECTURE.md +155 -56
  94. package/package.json +3 -2
  95. package/skills/embassy-peer/SKILL.md +36 -7
  96. package/dist/src/gateway/claude-compatibility-scratch.d.ts +0 -18
  97. package/dist/src/gateway/claude-compatibility-scratch.js +0 -158
  98. package/dist/src/gateway/claude-compatibility-scratch.js.map +0 -1
  99. package/dist/src/gateway/live-dashboard-bootstrap.d.ts +0 -36
  100. package/dist/src/gateway/live-dashboard-bootstrap.js +0 -176
  101. package/dist/src/gateway/live-dashboard-bootstrap.js.map +0 -1
  102. package/docs/DESIGN.md +0 -134
package/CHANGELOG.md CHANGED
@@ -4,6 +4,74 @@ 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
+ ## [Unreleased]
8
+
9
+ ## [1.3.0] - 2026-08-10
10
+
11
+ ### Added
12
+
13
+ - The live dashboard flags mail that was written but may not have been seen: a `delivered` Codex-to-Claude write older than two minutes whose recipient session is currently unobserved raises a warning pointing at that session's own window. The oldest unconsumed write owns the notice.
14
+
15
+ ### Changed
16
+
17
+ - `embassy dashboard --live` now uses the stable direct URL `http://127.0.0.1:41961/` by default, with a per-invocation `--port <n>` override accepting 1024–65535. Multiple windows and browsers can use the same companion (up to four concurrent live views); a port collision fails explicitly, points to `--port`, and never falls back.
18
+ - Claude-bound bodies are written to the recipient's native mailbox immediately after routing and pre-write checks, instead of waiting for an observed-idle gate that a busy Claude session could hold indefinitely. The receipt says exactly that: `delivered` toward Claude means the mailbox write completed, not that a model read or consumed the body.
19
+ - A Claude route that stops appearing in discovery is no longer auto-invalidated; only an actual discovery collision invalidates a selected route. Queued mail stays addressed to its session, and a write to a dead session socket fails fast with its exact safe code.
20
+
21
+ - A v1.2 state file loads cleanly: legacy `hopCount` fields are tolerated and stripped during migration.
22
+
23
+ ### Removed
24
+
25
+ - Conversation hop accounting and `EMBASSY_MAX_HOPS`; caller identity, conversation membership, route policy, deadlines, rate limits, and bounded queues remain the delivery safeguards.
26
+ - The live dashboard's one-use fragment token, cookie/session exchange, random instance path, and bootstrap file.
27
+ - The operator compatibility workflow: `EMBASSY_COMPAT_POLICY`, tiered same-major admission, persisted certification evidence, `compat-check`, `compat-certify`, `--with-turn`, and the related LaunchAgent recipes. Compatibility is now automatic and exact-pinned at provider startup, with a fresh monitor-only check for each replacement Codex endpoint generation before writes can activate.
28
+
29
+ ### Security
30
+
31
+ - The live dashboard now states its simpler trust boundary directly: it has no local-process or UID authentication and assumes a trusted single-user machine. Exact Host checks remain on every request; exact Origin plus `X-Embassy-Request` remain mandatory on every POST; `OPTIONS` and CORS remain disabled. These request guards constrain browser origins, not local software that can reach or spoof loopback.
32
+
33
+ ## [1.2.0] - 2026-08-10
34
+
35
+ Deliverability over everything: a message you send arrives, or tells you loudly why it could not.
36
+
37
+ ### Added
38
+
39
+ - **Broker-owned provenance envelopes and recipient replies** — every routed body now reaches Codex or Claude inside one deterministic `cross-session-message` textual frame with broker-validated sender attribution. Its first `embassy-reply-hint` carries the full conversation token, the exact recipient alias, and the stdin-based `embassy reply` command, so either participant can continue without reconstructing a token. Codex receives the full token as an outer `conversation` attribute as well; Claude retains its canonical outer shape and receives the token in the hint. Sender aliases over Claude's 64-character display bound use a deterministic hashed label while preserving the exact alias in the hint.
40
+ - **The durable queue** — message bodies persist in the broker's private mode-0600 state under bounded retention. Queued mail survives a broker restart and re-sends exactly once when its route is re-observed; in-flight-at-crash messages settle `ambiguous` — never silently lost, never double-sent. The live dashboard's delivery detail shows each retained body (bounded display), with an honest fallback for deliveries whose body was not retained. Static dashboards remain metadata-only.
41
+ - **Boot reactivation** — after a broker restart, retained Codex routes re-anchor automatically at startup through the same exactly-once `thread/loaded/list` proof, including staged handling when the App Server moved endpoint generations while the broker was down. `register-codex` becomes recovery of last resort; transient replies are never retargeted across a restart.
42
+ - **The deliverability soak** — `npm run soak` drives a seeded, randomized churn of sends through scripted dispatch faults, busy/idle flips, clock jumps, and full restarts, asserting that every accepted message settles exactly once into an explicit terminal outcome with an allowlisted reason.
43
+
44
+ ### Changed
45
+
46
+ - Message deadlines default to **4 hours** (was 5 minutes; max 24 hours) — agent turns routinely outlive minutes-scale deadlines, and expiry is now rare and explicit rather than routine. Stall notices stay early, within two minutes.
47
+ - Conversation hop budgets exist to stop runaway reply loops, not conversations: the default is **16** (was 2; max 64).
48
+ - Claude-bound dispatch failures carry their exact safe codes, and the broker redispatches bounded retries when the route is observed idle instead of settling terminal on first refusal.
49
+ - Documentation across both languages now states the durable-queue truth: bodies are stored, bounded, and shown; restarts keep queued mail.
50
+
51
+ ### Fixed
52
+
53
+ - The live dashboard's "Source restarted; view resynchronized" banner appears only on a true source-revision regression; clock-derived field churn no longer masquerades as a restart or triggers a frame broadcast every poll.
54
+
55
+ ### Security
56
+
57
+ - The envelope is a structural provenance marker, not XML, a cryptographic signature, or authentication against same-UID code. Broker-reserved opening and closing tag shapes inside the untrusted body are neutralized before delivery; framing happens exactly once at the final provider boundary, and invalid metadata or framed-size overflow fails before any write. The full conversation token remains transient and participant-scoped: reply rechecks caller, conversation membership, route, and hop policy, and the token never enters durable state, journals, logs, receipts, public snapshots, events, or dashboards.
58
+ - Body persistence keeps the same trust boundary the product always had: the OS account. Retained bodies live in the mode-0600 state directory and appear only on the loopback live dashboard; raw provider frames stay memory-only.
59
+
60
+ ## [1.1.0] - 2026-08-09
61
+
62
+ ### Added
63
+
64
+ - **Automatic Codex endpoint reactivation** — when the managed App Server moves from one endpoint generation to another, Embassy freezes the old connector, runs the existing bounded compatibility probe against the replacement, and re-anchors each retained route only after `thread/loaded/list` finds its byte-identical task exactly once. The alias, owner lease, and pair edges survive; the private bounded journal records the generation refresh without projecting the task ID or either endpoint generation.
65
+ - **Bounded stale-registration recovery** — the authenticated live dashboard can request removal of one canonical `codex-*` alias after an explicit confirmation. The broker accepts the operation only for a stale registration whose owning endpoint generation is dead, revalidates and quiesces the exact route, removes its incident pair edges, and records the successful recovery in its private bounded journal. Ready, merely offline, current-generation, and ambiguous routes fail closed.
66
+
67
+ ### Changed
68
+
69
+ - `CALLER_IDENTITY_CONFLICT` now gives a targeted bilingual recovery hint only when both Codex and Claude identities were inherited: restart the Codex App Server daemon from a normal terminal with `codex app-server daemon restart`. Wrong-principal failures keep the generic fail-closed advice.
70
+
71
+ ### Security
72
+
73
+ - Endpoint replacement never restores or replays a body, callback, receipt handle, reply capability, conversation capability, or delivery token. An incompatible replacement, a missing or duplicate exact task, or an unclean transition leaves the retained route stale and surfaces bounded compatibility evidence for diagnosis rather than retargeting it.
74
+
7
75
  ## [1.0.0] - 2026-08-09
8
76
 
9
77
  ### Added
package/CONTRIBUTING.md CHANGED
@@ -92,13 +92,17 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
92
92
  `embassy serve` may use one private same-user control UDS and publish two inert,
93
93
  metadata-only static dashboard files. It must not listen on TCP or HTTP. The
94
94
  only reviewed exception is the separately invoked foreground
95
- `embassy dashboard --live` companion, which binds an authenticated OS-assigned
96
- port on exact IPv4 loopback and exposes only the reviewed select-Claude,
97
- unselect-Claude, and refresh-discovery mutations, never a provider or generic
98
- control method. Do not
99
- add a wildcard/remote listener, external assets, storage, service workers,
100
- telemetry, or additional mutation endpoints. Keep the public v1 launcher foreground,
101
- macOS-only, and local-host-only.
95
+ `embassy dashboard --live` companion, which binds exact IPv4 loopback on stable
96
+ port `41961` by default or the validated per-invocation `--port <n>`. It has no
97
+ local-process or UID authentication and therefore assumes a trusted
98
+ single-user machine; exact Host on every request and exact Origin plus
99
+ `X-Embassy-Request` on every POST constrain browser origins, not local
100
+ software. Preserve the direct root URL, multi-window/browser access, collision
101
+ failure with no fallback port, no CORS/`OPTIONS`, and only the reviewed pair,
102
+ unpair, refresh-discovery, and stale-registration-removal mutations—never a
103
+ provider or generic control method. Do not add a wildcard/remote listener,
104
+ external assets, service workers, telemetry, or additional mutation endpoints.
105
+ Keep the public v1 launcher foreground, macOS-only, and local-host-only.
102
106
 
103
107
  ## Live validation
104
108
 
@@ -120,3 +124,17 @@ macOS caps socket paths at ~104 bytes — keep `TMPDIR` short (CI pins
120
124
  `TMPDIR=/tmp`; do the same locally if the transport tests hang). On Linux,
121
125
  the darwin-only lease and peer-generation tests skip explicitly (the host
122
126
  lease spawns macOS's `/usr/bin/lockf`); macOS runs the full suite.
127
+
128
+ ## Design honesty rules
129
+
130
+ These outlive any visual era and bind every surface — dashboards, CLI copy,
131
+ site, docs, in both languages:
132
+
133
+ - Progress is never green. Only a terminal success state may look like one.
134
+ - `delivered` means the write completed; `released` is not read; nothing may
135
+ imply a model consumed, understood, or acted on a message.
136
+ - Refusals are not failures: a fail-closed refusal renders as policy, not as
137
+ breakage.
138
+ - The brand accent is never a state color, and state colors are never
139
+ decoration.
140
+ - Every alert pairs its state with the exact next command, copyable.
package/README.md CHANGED
@@ -25,7 +25,16 @@ Embassy is built for one person, one macOS account, and agents you already trust
25
25
 
26
26
  ## Quickstart
27
27
 
28
- **Requirements:** macOS, Node.js 20+, Claude Code 2.1.226 (still-running 2.1.224–2.1.225 sessions remain discoverable), and Codex desktop configured to use the managed standalone App Server 0.147.0. The Claude session you select as a destination needs [`crossSessionInbound`](docs/CONFIGURATION.md) enabled — that is Claude Code's own setting, configured in Claude Code, not in Embassy.
28
+ **Requirements:** macOS, Node.js 20+, Claude Code 2.1.226 (still-running 2.1.224–2.1.225 sessions remain discoverable), and Codex desktop configured to use the managed standalone App Server 0.147.0:
29
+
30
+ ```bash
31
+ ~/.codex/packages/standalone/current/codex app-server daemon start
32
+ /usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT
33
+ ```
34
+
35
+ The first command starts the managed daemon if it is not already running (`restart` and `stop` also exist); the second launches the ChatGPT desktop app pointed at it. `CODEX_APP_SERVER_USE_LOCAL_DAEMON` is not documented by OpenAI; it is observed to work with this Desktop build and may change. Run the daemon command from a normal terminal, never from inside an agent session: Codex tasks inherit the daemon's environment, so a daemon started inside a Claude Code session leaks that session's identity into every task and registration fails closed with `CALLER_IDENTITY_CONFLICT` — fix it from a normal terminal with `codex app-server daemon restart`. The Claude session you select as a destination needs [`crossSessionInbound`](docs/CONFIGURATION.md) enabled — that is Claude Code's own setting, configured in Claude Code, not in Embassy.
36
+
37
+ Provider compatibility needs no separate operator step. `embassy serve` automatically validates the release's exact Claude and Codex version pins and fails closed on unknown versions or required protocol shapes.
29
38
 
30
39
  > **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.
31
40
 
@@ -56,6 +65,8 @@ embassy register-codex --alias codex-reviewer@this-mac
56
65
 
57
66
  You should see `"accepted":true`. The `codex-` prefix is required for Claude discovery. To retire the task later, run `unregister-codex`.
58
67
 
68
+ Managed App Server generation changes and `embassy serve` restarts both use exact-task reactivation. Each replacement starts monitor-only; only a fresh initialize plus `thread/loaded/list` result that finds the byte-identical task exactly once may re-anchor the alias, and writes stay fenced until that exact generation is activated. A normal broker restart therefore needs no manual registration. An incompatible endpoint or a missing or duplicate exact task leaves the route stale with `REOBSERVATION_REQUIRED`; 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.
69
+
59
70
  ### 3. Select a Claude destination
60
71
 
61
72
  Pick one name from `availablePeers`:
@@ -83,7 +94,9 @@ You should see a `conv_` conversation token and a `dlv_` delivery token. Because
83
94
 
84
95
  ### 5. Follow up
85
96
 
86
- Either side can continue the conversation:
97
+ Either participant can continue the conversation with `reply`. The initiating
98
+ CLI receives the full `conv_` token in its accepted result; the recipient gets
99
+ the same token and an exact reply command in the broker-owned message marker:
87
100
 
88
101
  ```bash
89
102
  embassy reply \
@@ -93,11 +106,34 @@ Please expand on the migration risk.
93
106
  MSG
94
107
  ```
95
108
 
109
+ Every routed body reaches either product inside one broker-owned
110
+ `<cross-session-message>` textual frame. It identifies the verified sender
111
+ alias and begins with an `<embassy-reply-hint>` containing the full conversation
112
+ token, the recipient's exact alias, and the corresponding `embassy reply`
113
+ command. Use only that delivered full token and alias; never guess one from a
114
+ suffix or substitute the sender's alias. The CLI still rechecks the caller,
115
+ conversation membership, and current route policy, so the hint is
116
+ not a permission bypass.
117
+
118
+ The frame is a clear provenance marker, not a cryptographic signature or a
119
+ claim that the body is trustworthy. Embassy neutralizes nested occurrences of
120
+ its two reserved framing tags in the untrusted body before provider delivery;
121
+ arbitrary same-user code and all message text remain untrusted input.
122
+
96
123
  ### See it live
97
124
 
98
- `embassy dashboard --live` opens a five-tab streaming view in the browser (overview, deliveries, routes, activity, diagnostics). See [Dashboard](docs/DASHBOARD.md) for details.
125
+ `embassy dashboard --live` opens a five-tab streaming view in the browser
126
+ (overview, deliveries, routes, activity, diagnostics) at
127
+ `http://127.0.0.1:41961/` by default. To choose another stable port for that
128
+ invocation, run `embassy dashboard --live --port <n>` with an integer from 1024
129
+ through 65535. Multiple windows and browsers can use the same URL while the
130
+ foreground companion runs. If the port is occupied, startup fails explicitly,
131
+ points to `--port`, and never falls back to another port. See
132
+ [Dashboard](docs/DASHBOARD.md) for details.
99
133
 
100
- The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html`. Live dashboard mutations require the same-origin `X-Embassy-Request` sentinel.
134
+ 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.
135
+
136
+ 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`.
101
137
 
102
138
  ## How it works
103
139
 
@@ -108,7 +144,7 @@ The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html`
108
144
  │ │
109
145
  ▼ ▼
110
146
  ┌──────────────────── Embassy ─────────────────────────────┐
111
- │ explicit routes │ queue while busy │ receipts │ dashboard │
147
+ │ explicit routes │ Codex busy queue │ receipts │ dashboard │
112
148
  └───────────────────────────────────────────────────────────┘
113
149
  ```
114
150
 
@@ -116,9 +152,15 @@ Embassy publishes each registered Codex task into Claude Code's live-session reg
116
152
 
117
153
  A pair is one explicit permission edge between one Claude session and one Codex task — and pairs are many-to-many: one Claude session may hold edges to several Codex tasks, and one Codex task to several Claude sessions (bounded at 128 pairs by default). Every edge is created explicitly, with `pair` or the one-task `select-claude` shorthand; nothing is ever implied. Without an edge, a sender settles terminally as `SENDER_NOT_PAIRED`. `embassy serve --inbound open` is the explicit opt-out that restores any-session inbound.
118
154
 
119
- Messages queue while the Codex task is busy and start an ordinary turn when it goes idle. In the Claude-to-Codex direction only, a body with an exact leading `STEER:` prefix may enter the active turn at the App Server's next tool-call boundary; if that boundary is unavailable, the message returns to the normal queue.
155
+ Delivery timing is directional. Once routing and pre-write checks pass, every Claude-bound body is written immediately to Claude's native mailbox regardless of its observed busy or idle state. `transport_written` records that mailbox write and is the Claude-bound terminal `delivered` boundary; it does not mean Claude read or consumed the body. Codex-bound ordinary bodies instead queue while the task is busy and start a turn when it goes idle. In the Claude-to-Codex direction only, a body with an exact leading `STEER:` prefix may enter the active turn at the App Server's next tool-call boundary; if that boundary is unavailable, the message returns to the normal queue.
156
+
157
+ Immediately before the provider write, Embassy gives every routed body one
158
+ broker-owned cross-session marker containing the verified sender alias and a
159
+ recipient reply hint. The full conversation token travels only in the
160
+ initiator's accepted result and the recipient's transient message payload; it
161
+ never enters the dashboard, public snapshot, journal, receipt, or log.
120
162
 
121
- Every settled message produces a receipt. `delivered` means terminal provider evidence was observed — toward Codex, the App Server accepted the turn; toward Claude, the message was released into the session's native queue. Neither means the model read or acted on it. `unconfirmed` and `ambiguous` mean evidence is missing; they are terminal states and never auto-retried. See [Delivery](docs/DELIVERY.md) for the full semantics.
163
+ Every settled message produces a receipt. `delivered` means the direction's terminal provider boundary was observed — toward Codex, the App Server accepted the turn; toward Claude, the native mailbox write completed. Neither means the model read or acted on it. `unconfirmed` and `ambiguous` mean the required evidence is missing; they are terminal states and never auto-retried. See [Delivery](docs/DELIVERY.md) for the full semantics.
122
164
 
123
165
  ## The vocabulary
124
166
 
@@ -126,13 +168,22 @@ Four embassy terms name real features:
126
168
 
127
169
  - **Registration and pairing** are the permission model: a Codex task is explicitly registered, and each pair is one explicit Claude↔Codex edge — only paired ends exchange messages, and many edges can coexist. No edge means `SENDER_NOT_PAIRED`; nothing is ever implicit.
128
170
  - **The ledger** is the delivery record: a receipt for every settled message, and a metadata-only dashboard.
129
- - **The pouch** is transit: bounded bodies, ephemeral inside Embassy, never persisted by it.
171
+ - **The pouch** is transit and the archive: bounded bodies, retained under bounded limits, private to your OS account — sealed against other users, not against you.
130
172
  - **Consulates** are the roadmap: the same model extended to Codex tasks on remote hosts over attach-only SSH — designed, and deliberately disabled in v1.
131
173
 
132
174
  ## For agents
133
175
 
134
176
  Embassy's operators are often agents themselves: `register-codex` runs inside the Codex task, and the Claude side is driven entirely through native tools. The repo ships [`skills/embassy-peer/SKILL.md`](skills/embassy-peer/SKILL.md) — point your agent at it rather than paraphrasing this README.
135
177
 
178
+ The skill ships in the npm package; install it where each agent discovers skills:
179
+
180
+ ```bash
181
+ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.codex/skills/
182
+ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
183
+ ```
184
+
185
+ Codex tasks can then be prompted with `$embassy-peer`; Claude Code discovers it as a user skill.
186
+
136
187
  ## Commands
137
188
 
138
189
  | Command | Run by | Purpose |
@@ -140,7 +191,7 @@ Embassy's operators are often agents themselves: `register-codex` runs inside th
140
191
  | `serve` | operator | Start the foreground broker and dashboard |
141
192
  | `health` / `status` | operator | Check liveness and inspect the sanitized snapshot |
142
193
  | `refresh-dashboard` | operator | Regenerate both static dashboard files |
143
- | `dashboard --live [--lang en\|zh-CN]` | operator | Start the live dashboard companion with bounded route-consent actions; requires a running `embassy serve` |
194
+ | `dashboard --live [--lang en\|zh-CN] [--port <n>]` | operator | Start the live dashboard companion with bounded route-consent actions; requires a running `embassy serve` |
144
195
  | `delivery-status` | either provider | Read one delivery tracker with `embassy delivery-status --token dlv_<token>` |
145
196
  | `wait-delivery` | either provider | Wait for that tracker to settle, up to the delivery deadline |
146
197
  | `register-codex` / `unregister-codex` | Codex task | Advertise or retire that exact task; for example, `embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac` hands the registration to a different task |
@@ -148,20 +199,22 @@ Embassy's operators are often agents themselves: `register-codex` runs inside th
148
199
  | `select-claude` / `unselect-claude` | operator | One-task shorthand for `pair`/`unpair`: resolves the Codex end only when it is unambiguous (inherited or sole registered task), otherwise fails closed |
149
200
  | `send-to-claude` | registered Codex task | Send one bounded message to a paired Claude session |
150
201
  | `send-to-codex` | Claude session | Send one bounded message using the inherited native reply identity |
151
- | `reply` | either provider | Continue an active conversation by its public token |
202
+ | `reply` | conversation-token holder | Continue an active conversation with the full token returned to the initiator or delivered in the recipient's broker-owned reply hint |
152
203
 
153
204
  ## Safety in one minute
154
205
 
155
- - **Local sockets only.** `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 `127.0.0.1` on an ephemeral port.
206
+ - **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.
156
207
  - **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.
208
+ - **Compatibility is automatic and exact-pinned.** Broker/provider startup validates only the release's reviewed versions and protocol shapes. Every replacement App Server endpoint generation gets a fresh monitor-only check before route re-anchoring; unknown versions and malformed generations stay write-disabled.
157
209
  - **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.
158
- - **Bodies never persisted.** Message bodies, prompts, replies, and raw provider frames live only in memory. Metadata-only dashboard files are mode 0600 with no JavaScript.
210
+ - **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.
211
+ - **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.
159
212
 
160
213
  See [SECURITY.md](SECURITY.md) for the full boundary and vulnerability-reporting process.
161
214
 
162
215
  ## What Embassy is not
163
216
 
164
- - **Not an orchestrator.** It does not spawn agents or manage their work. It starts one turn per routed message and drains its queue when the task goes idle.
217
+ - **Not an orchestrator.** It does not spawn agents or manage their work. Codex-bound ordinary messages start one turn apiece as the task becomes idle; Claude-bound messages enter Claude's mailbox without waiting for idle.
165
218
  - **Not a hosted service.** Personal, same-machine, same-OS-account software.
166
219
  - **Not a permission bypass — but it is a new path.** Neither agent gains a tool it did not already have, and Embassy grants, relaxes, and answers nothing. It does, however, connect two products that previously could not exchange text at all. That path is the product; treat it with the respect you would give any new input channel.
167
220
  - **Not official.** Not affiliated with or endorsed by Anthropic or OpenAI.
package/README.zh-CN.md CHANGED
@@ -25,7 +25,16 @@ Embassy 专为单人、单一 macOS 账户以及你已信任以该用户身份
25
25
 
26
26
  ## 快速开始
27
27
 
28
- **前置要求:** macOS、Node.js 20+、Claude Code 2.1.226(仍在运行的 2.1.224–2.1.225 会话保持可发现),以及配置为使用托管独立 App Server 0.147.0 的 Codex 桌面应用。你选择作为目的地的 Claude 会话需要启用 [`crossSessionInbound`](docs/CONFIGURATION.zh-CN.md)——这是 Claude Code 自身的设置,在 Claude Code 中配置,而非在 Embassy 中。
28
+ **前置要求:** macOS、Node.js 20+、Claude Code 2.1.226(仍在运行的 2.1.224–2.1.225 会话保持可发现),以及配置为使用托管独立 App Server 0.147.0 的 Codex 桌面应用:
29
+
30
+ ```bash
31
+ ~/.codex/packages/standalone/current/codex app-server daemon start
32
+ /usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT
33
+ ```
34
+
35
+ 第一条命令在托管守护进程未运行时启动它(也提供 `restart` 与 `stop` 子命令);第二条以指向该守护进程的方式启动 ChatGPT 桌面应用。`CODEX_APP_SERVER_USE_LOCAL_DAEMON` 未见于 OpenAI 文档;它经验证适用于当前 Desktop 构建,未来可能变化。请在普通终端中运行守护进程命令,切勿在代理会话内运行:Codex 任务会继承守护进程的环境,因此在 Claude Code 会话内启动的守护进程会把该会话的身份泄漏到每个任务中,注册将以 `CALLER_IDENTITY_CONFLICT` 关闭失败——请在普通终端执行 `codex app-server daemon restart` 修复。你选择作为目的地的 Claude 会话需要启用 [`crossSessionInbound`](docs/CONFIGURATION.zh-CN.md)——这是 Claude Code 自身的设置,在 Claude Code 中配置,而非在 Embassy 中。
36
+
37
+ 提供方兼容性无需操作员执行额外步骤。`embassy serve` 会自动验证本发布版精确固定的 Claude 与 Codex 版本,并在遇到未知版本或必需协议结构时关闭失败。
29
38
 
30
39
  > **已知限制:** 仅当 Desktop 使用托管独立 App Server 时,Embassy 才能访问 Codex 任务。在该模式下,任务目前无法连接 Desktop 内置的应用内浏览器(`@Browser` 可加载但无法附着)。将 Desktop 切换回其默认的私有 App Server 会立即恢复内置浏览器——但会使这些任务对 Embassy 不可达。目前未发现其他能力回退,但这并非穷尽的能力对比测试。
31
40
 
@@ -56,6 +65,8 @@ embassy register-codex --alias codex-reviewer@this-mac
56
65
 
57
66
  你应看到 `"accepted":true`。`codex-` 前缀是 Claude 发现所必需的。之后若要注销该任务,运行 `unregister-codex`。
58
67
 
68
+ 托管 App Server 端点代际变更与 `embassy serve` 重启都会使用精确任务重新激活。每个替代端点都从仅监控状态开始;只有重新初始化并通过 `thread/loaded/list` 恰好一次找到字节级一致的原任务时,才能重新锚定别名,而且在激活这个精确代际前写入始终保持封锁。因此,正常的代理重启不需要手动重新注册。端点不兼容,或精确任务缺失、重复,都会使路由以 `REOBSERVATION_REQUIRED` 保持陈旧;该任务恢复可观察后,请从精确任务内再次运行 `embassy register-codex --alias codex-reviewer@this-mac`,且不要先注销。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
69
+
59
70
  ### 3. 选择 Claude 目的地
60
71
 
61
72
  从 `availablePeers` 中选择一个名称:
@@ -83,7 +94,7 @@ MSG
83
94
 
84
95
  ### 5. 后续跟进
85
96
 
86
- 任一方都可以继续对话:
97
+ 任何持有完整 `conv_` 令牌的对话参与方都可以用 `reply` 继续仍然有效的对话。初始发送方从 Embassy 命令结果中获得令牌;接收方则从入站消息的来源封装中获得同一个完整令牌和回复提示:
87
98
 
88
99
  ```bash
89
100
  embassy reply \
@@ -93,11 +104,15 @@ Please expand on the migration risk.
93
104
  MSG
94
105
  ```
95
106
 
107
+ Embassy 会在实际写入提供方之前,为双向路由消息添加一个由代理控制的 `<cross-session-message>` 来源封装。封装标出已经验证的发送方别名,其首个 `<embassy-reply-hint>` 元素包含完整对话令牌、接收方自己的精确别名和可直接使用的 `embassy reply` 命令。朝向 Codex 时,外层标记本身还带有 `conversation="conv_..."`;朝向 Claude 时,为符合 Claude Code 的规范解析格式,完整令牌和回复提示位于封装正文中,而不作为外层属性。请使用收到的完整令牌,切勿猜测或重构它。令牌本身不授予路由权限:每次回复仍会重新检查调用方身份、对话参与关系和实时路由。
108
+
96
109
  ### 实时查看
97
110
 
98
- `embassy dashboard --live` 在浏览器中打开一个五选项卡流式视图(总览、投递、路由、活动、诊断)。详见[仪表盘](docs/DASHBOARD.zh-CN.md)。
111
+ `embassy dashboard --live` 在浏览器中打开一个五选项卡流式视图(总览、投递、路由、活动、诊断),默认地址为 `http://127.0.0.1:41961/`。如需为本次启动选择另一个稳定端口,请运行 `embassy dashboard --live --port <n>`,其中整数范围为 1024 到 65535。当前台组件运行时,多个窗口和浏览器可以使用同一个 URL;若端口已被占用,启动会明确失败并提示使用 `--port`,不会回退到其他端口。详见[仪表盘](docs/DASHBOARD.zh-CN.md)。
99
112
 
100
- 代理还会以 mode 0600 发布静态快照 `gateway-dashboard.html` 与 `gateway-dashboard.zh-CN.html`。实时仪表盘的变更操作必须携带同源 `X-Embassy-Request` 哨兵头。
113
+ 实时仪表盘也可以在明确确认后移除孤立的 Codex 注册,但仅限代理已经证明该注册陈旧且其所属端点代际已失效的情况。当前、仅离线或代际状态不明确的注册绝不能通过此恢复操作移除。
114
+
115
+ 代理还会以 mode 0600 发布静态快照 `gateway-dashboard.html` 与 `gateway-dashboard.zh-CN.html`。实时仪表盘没有登录、令牌、Cookie 或逐浏览器会话:它假定这是一台可信的单用户机器;能够访问或伪造 loopback 的本地软件可以读取仪表盘并调用其有限操作。服务器仍会对每个请求要求精确的 Host 头,并对每个 POST 要求精确的 Origin 与 `X-Embassy-Request`;它不发送 CORS 头,也不接受 `OPTIONS`。
101
116
 
102
117
  ## 工作原理
103
118
 
@@ -108,7 +123,7 @@ MSG
108
123
  │ │
109
124
  ▼ ▼
110
125
  ┌──────────────────── Embassy ─────────────────────────────┐
111
- │ 显式路由 │ 忙碌排队 │ 回执 │ 仪表盘
126
+ │ 显式路由 │ Codex 忙碌排队 │ 回执 │ 仪表盘
112
127
  └───────────────────────────────────────────────────────────┘
113
128
  ```
114
129
 
@@ -116,9 +131,11 @@ Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份
116
131
 
117
132
  配对是一个 Claude 会话与一个 Codex 任务之间的单一显式权限边,而配对关系是多对多的:一个 Claude 会话可以与多个 Codex 任务建立边,一个 Codex 任务也可以与多个 Claude 会话建立边(默认上限 128 个配对)。每条边都通过 `pair` 或单任务简写 `select-claude` 显式创建;一切都不会被隐式推断。没有边时,发送方以 `SENDER_NOT_PAIRED` 终局结算。`embassy serve --inbound open` 是显式的退出选项,可恢复任意会话入站。
118
133
 
119
- 消息在 Codex 任务忙碌时排队,并在任务空闲后启动普通轮次。仅在 Claude→Codex 方向,正文以精确 `STEER:` 开头的消息可以在 App Server 的下一个工具调用边界进入当前轮次;若该边界不可用,消息会回到普通队列。
134
+ 投递时机因方向而异。通过路由与写前检查后,所有朝向 Claude 的正文都会立即写入 Claude 的原生邮箱,无论观测到 Claude 正繁忙还是空闲。`transport_written` 记录这次邮箱写入,并且就是朝向 Claude 的终局 `delivered` 边界;它不表示 Claude 已读取或消费正文。朝向 Codex 的普通正文则在任务忙碌时排队,并在任务空闲后启动轮次。仅在 Claude→Codex 方向,正文以精确 `STEER:` 开头的消息可以在 App Server 的下一个工具调用边界进入当前轮次;若该边界不可用,消息会回到普通队列。
135
+
136
+ 每条被路由的消息在接收方看到时都位于 Embassy 生成的跨会话来源封装中,其中包含已验证的发送方别名、完整 `conv_` 令牌和面向该接收方的回复提示。来源封装是模型可见的结构性提示,并非密码学身份认证;消息正文始终应被视为不可信输入。
120
137
 
121
- 每条已结算的消息都会产生回执。`delivered` 表示观测到了终端提供方证据——朝向 Codex,意味着 App Server 接受了该轮次;朝向 Claude,意味着消息已释放到会话的原生队列。两者都不意味着模型已读取或执行。`unconfirmed` 和 `ambiguous` 表示证据缺失;它们是终态,从不自动重试。完整语义详见[投递](docs/DELIVERY.zh-CN.md)。
138
+ 每条已结算的消息都会产生回执。`delivered` 表示观测到了该方向的终端提供方边界——朝向 Codex,意味着 App Server 接受了该轮次;朝向 Claude,意味着原生邮箱写入完成。两者都不意味着模型已读取或执行。`unconfirmed` 和 `ambiguous` 表示所需证据缺失;它们是终态,从不自动重试。完整语义详见[投递](docs/DELIVERY.zh-CN.md)。
122
139
 
123
140
  ## 核心术语
124
141
 
@@ -126,13 +143,22 @@ Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份
126
143
 
127
144
  - **注册与配对**构成权限模型:Codex 任务通过显式注册发布,每个配对是一条显式的 Claude↔Codex 边——只有配对的两端可以交换消息,且多条边可以并存。没有边意味着 `SENDER_NOT_PAIRED`;一切都是显式的。
128
145
  - **账簿**是投递记录:每条已结算消息的回执,以及一个仅包含元数据的仪表盘。
129
- - **信袋**是传输通道:有界的消息体,在 Embassy 内部是临时的,从不被持久化。
146
+ - **信袋**既是传输通道也是档案:有界的消息体,按有界策略保留,只属于你的操作系统账户 对其他用户封缄,对你敞开。
130
147
  - **领事馆**是路线图:将同一模型通过仅限 attach 的 SSH 扩展到远程主机上的 Codex 任务——已完成设计,但在 v1 中有意禁用。
131
148
 
132
149
  ## 面向代理
133
150
 
134
151
  Embassy 的操作者本身往往就是代理:`register-codex` 在 Codex 任务内部运行,而 Claude 端完全通过原生工具驱动。仓库附带 [`skills/embassy-peer/SKILL.md`](skills/embassy-peer/SKILL.md)——请将你的代理指向该技能,而非向它复述本 README。
135
152
 
153
+ 该技能随 npm 包一同发布;将它安装到各代理发现技能的目录:
154
+
155
+ ```bash
156
+ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.codex/skills/
157
+ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
158
+ ```
159
+
160
+ 之后即可在 Codex 任务中通过 `$embassy-peer` 调用;Claude Code 会将其作为用户技能自动发现。
161
+
136
162
  ## 命令一览
137
163
 
138
164
  | 命令 | 执行者 | 用途 |
@@ -140,7 +166,7 @@ Embassy 的操作者本身往往就是代理:`register-codex` 在 Codex 任务
140
166
  | `serve` | 操作员 | 启动前台代理和仪表盘 |
141
167
  | `health` / `status` | 操作员 | 检查存活状态并查看脱敏快照 |
142
168
  | `refresh-dashboard` | 操作员 | 重新生成两个静态仪表盘文件 |
143
- | `dashboard --live [--lang en\|zh-CN]` | 操作员 | 启动带有限路由同意操作的实时仪表盘组件;需要 `embassy serve` 正在运行 |
169
+ | `dashboard --live [--lang en\|zh-CN] [--port <n>]` | 操作员 | 启动带有限路由同意操作的实时仪表盘组件;需要 `embassy serve` 正在运行 |
144
170
  | `delivery-status` | 任一提供方 | 使用 `embassy delivery-status --token dlv_<token>` 读取单条投递跟踪器 |
145
171
  | `wait-delivery` | 任一提供方 | 等待该跟踪器结算,直至投递截止时间 |
146
172
  | `register-codex` / `unregister-codex` | Codex 任务 | 通告或注销该任务;例如,`embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac` 会将注册转交给另一个任务 |
@@ -148,20 +174,22 @@ Embassy 的操作者本身往往就是代理:`register-codex` 在 Codex 任务
148
174
  | `select-claude` / `unselect-claude` | 操作员 | `pair`/`unpair` 的单任务简写:仅在 Codex 端无歧义(继承标识或唯一已注册任务)时解析,否则以关闭状态失败 |
149
175
  | `send-to-claude` | 已注册的 Codex 任务 | 向已配对的 Claude 会话发送一条有界消息 |
150
176
  | `send-to-codex` | Claude 会话 | 使用继承的原生回复标识发送一条有界消息 |
151
- | `reply` | 任一提供方 | 通过公开令牌继续一个活跃对话 |
177
+ | `reply` | 对话令牌持有方 | 使用初始发送时返回或随入站来源提示收到的完整令牌继续一个活跃对话;调用方、对话参与关系和路由会重新检查 |
152
178
 
153
179
  ## 一分钟了解安全性
154
180
 
155
- - **仅限本地套接字。** `embassy serve` 仅监听私有 Unix 域套接字,不发起任何提供商 API 调用。可选启用的 `embassy dashboard --live` 组件是一个独立进程,也是 Embassy 能创建的唯一监听器,绑定到 `127.0.0.1` 上的临时端口。
181
+ - **本地代理,稳定的 loopback 仪表盘。** `embassy serve` 仅监听私有 Unix 域套接字,不发起任何提供商 API 调用。可选启用的 `embassy dashboard --live` 组件是一个独立进程,也是 Embassy 能创建的唯一监听器;它精确绑定 `127.0.0.1`,默认使用稳定端口 `41961`(也可为本次启动传入 `--port <n>`)。它是在可信单用户机器上有意不设身份认证的本地 HTTP;Host、Origin 与哨兵检查约束浏览器来源的请求,但不认证本地进程或 OS 用户。
156
182
  - **同 UID 隔离,而非身份认证。** 调用者身份继承自本地进程环境。路由所有权和生成号检查能减少误操作,但不是对已以你的 OS 用户身份运行的代码的防御。
183
+ - **兼容性检查自动执行并精确固定版本。** 代理/提供方启动只验证本发布版已审查的版本和协议结构。每个替代 App Server 端点代际都必须先通过新的仅监控检查才能重新锚定路由;未知版本与结构异常的代际保持禁止写入。
184
+ - **来源标记是提示,不是签名。** Embassy 在提供方写入边界生成跨会话来源封装,让接收模型能够区分代理路由消息及其已验证发送方别名;这不是密码学证明,也不会把不可信正文变成可信指令。
157
185
  - **原生权限保持原生。** Embassy 不发送任何 Codex 审批或沙盒覆盖,也不应答任何审批请求。`crossSessionInbound` 仍是 Claude 自身的控制机制;Embassy 无法覆盖它。
158
- - **消息体从不持久化。** 消息体、提示词、回复和原始提供方帧仅存在于内存中。仅含元数据的仪表盘文件为 mode 0600,不含 JavaScript。
186
+ - **消息体有界保存,属于你。** 消息体以有界保留策略持久化在 broker 的私有 mode-0600 状态中,让台账能够展示邮件本身;排队中的邮件在 broker 重启后幸存并恰好重发一次。原始提供方帧仍仅存于内存。静态仪表盘文件保持仅元数据;实时仪表盘展示保留的正文。
159
187
 
160
188
  完整的安全边界和漏洞报告流程请参见 [SECURITY.md](SECURITY.md)。
161
189
 
162
190
  ## Embassy 不是什么
163
191
 
164
- - **不是编排器。** 它不生成代理,也不管理它们的工作。它为每条路由消息启动一个轮次,并在任务空闲时排空队列。
192
+ - **不是编排器。** 它不生成代理,也不管理它们的工作。朝向 Codex 的普通消息会在任务空闲时逐条启动轮次;朝向 Claude 的消息无需等待空闲,直接进入 Claude 的邮箱。
165
193
  - **不是托管服务。** 面向个人的、同机同账户软件。
166
194
  - **不是权限绕过——但它是一条新路径。** 两个代理都不会获得它原本没有的工具,Embassy 也不授予、放宽或应答任何权限。然而,它确实连接了两个此前无法交换文本的产品。这条路径就是产品本身;请以对待任何新输入通道应有的审慎来看待它。
167
195
  - **不是官方产品。** 与 Anthropic 或 OpenAI 没有任何关联或背书关系。