agent-embassy 2.0.1 → 3.1.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 (147) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/CONTRIBUTING.md +23 -36
  3. package/README.md +123 -222
  4. package/SECURITY.md +72 -93
  5. package/dist/src/errors.d.ts +10 -1
  6. package/dist/src/errors.js +3 -1
  7. package/dist/src/errors.js.map +1 -1
  8. package/dist/src/gateway/claude-helper-protocol.d.ts +8 -11
  9. package/dist/src/gateway/claude-helper-protocol.js +12 -11
  10. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  11. package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -5
  12. package/dist/src/gateway/claude-helper-supervisor.js +45 -17
  13. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  14. package/dist/src/gateway/claude-helper.js +6 -6
  15. package/dist/src/gateway/claude-helper.js.map +1 -1
  16. package/dist/src/gateway/claude-peer.d.ts +0 -3
  17. package/dist/src/gateway/claude-peer.js +7 -19
  18. package/dist/src/gateway/claude-peer.js.map +1 -1
  19. package/dist/src/gateway/cli.d.ts +17 -7
  20. package/dist/src/gateway/cli.js +945 -265
  21. package/dist/src/gateway/cli.js.map +1 -1
  22. package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
  23. package/dist/src/gateway/codex-socket-holder.js +76 -0
  24. package/dist/src/gateway/codex-socket-holder.js.map +1 -0
  25. package/dist/src/gateway/codex-stateless-transport.js +1 -1
  26. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  27. package/dist/src/gateway/config.d.ts +1 -10
  28. package/dist/src/gateway/config.js +4 -10
  29. package/dist/src/gateway/config.js.map +1 -1
  30. package/dist/src/gateway/control.d.ts +66 -80
  31. package/dist/src/gateway/control.js +92 -147
  32. package/dist/src/gateway/control.js.map +1 -1
  33. package/dist/src/gateway/federation-nodes.d.ts +29 -2
  34. package/dist/src/gateway/federation-nodes.js +177 -7
  35. package/dist/src/gateway/federation-nodes.js.map +1 -1
  36. package/dist/src/gateway/peer-client.d.ts +4 -3
  37. package/dist/src/gateway/peer-client.js +22 -13
  38. package/dist/src/gateway/peer-client.js.map +1 -1
  39. package/dist/src/gateway/peer-protocol.d.ts +13 -11
  40. package/dist/src/gateway/peer-protocol.js +14 -12
  41. package/dist/src/gateway/peer-protocol.js.map +1 -1
  42. package/dist/src/gateway/provenance-envelope.d.ts +0 -1
  43. package/dist/src/gateway/provenance-envelope.js +4 -19
  44. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  45. package/dist/src/gateway/providers.d.ts +11 -7
  46. package/dist/src/gateway/providers.js +49 -50
  47. package/dist/src/gateway/providers.js.map +1 -1
  48. package/dist/src/gateway/server.d.ts +4 -14
  49. package/dist/src/gateway/server.js +32 -54
  50. package/dist/src/gateway/server.js.map +1 -1
  51. package/dist/src/gateway/service-agent.d.ts +187 -0
  52. package/dist/src/gateway/service-agent.js +758 -0
  53. package/dist/src/gateway/service-agent.js.map +1 -0
  54. package/dist/src/gateway/service.d.ts +119 -38
  55. package/dist/src/gateway/service.js +754 -798
  56. package/dist/src/gateway/service.js.map +1 -1
  57. package/dist/src/gateway/status-view.d.ts +119 -0
  58. package/dist/src/gateway/status-view.js +484 -0
  59. package/dist/src/gateway/status-view.js.map +1 -0
  60. package/dist/src/gateway/store.d.ts +106 -21
  61. package/dist/src/gateway/store.js +463 -537
  62. package/dist/src/gateway/store.js.map +1 -1
  63. package/dist/src/gateway/types.d.ts +64 -102
  64. package/dist/src/gateway/types.js +40 -86
  65. package/dist/src/gateway/types.js.map +1 -1
  66. package/docs/CONFIGURATION.md +174 -45
  67. package/docs/DELIVERY.md +11 -11
  68. package/docs/GATEWAY-ARCHITECTURE.md +292 -384
  69. package/package.json +4 -12
  70. package/skills/embassy-peer/SKILL.md +69 -92
  71. package/skills/embassy-peer/agents/openai.yaml +1 -1
  72. package/README.zh-CN.md +0 -275
  73. package/assets/live-dashboard/app.css +0 -1619
  74. package/assets/vendor/react/LICENSE +0 -21
  75. package/assets/vendor/react/react-dom.production.min.js +0 -267
  76. package/assets/vendor/react/react.production.min.js +0 -31
  77. package/dist/src/gateway/acp-client.d.ts +0 -110
  78. package/dist/src/gateway/acp-client.js +0 -407
  79. package/dist/src/gateway/acp-client.js.map +0 -1
  80. package/dist/src/gateway/acp-provider.d.ts +0 -66
  81. package/dist/src/gateway/acp-provider.js +0 -275
  82. package/dist/src/gateway/acp-provider.js.map +0 -1
  83. package/dist/src/gateway/claude-helper-client.d.ts +0 -2
  84. package/dist/src/gateway/claude-helper-client.js +0 -2
  85. package/dist/src/gateway/claude-helper-client.js.map +0 -1
  86. package/dist/src/gateway/cli-copy.d.ts +0 -8
  87. package/dist/src/gateway/cli-copy.en.d.ts +0 -22
  88. package/dist/src/gateway/cli-copy.en.js +0 -62
  89. package/dist/src/gateway/cli-copy.en.js.map +0 -1
  90. package/dist/src/gateway/cli-copy.js +0 -27
  91. package/dist/src/gateway/cli-copy.js.map +0 -1
  92. package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -22
  93. package/dist/src/gateway/cli-copy.zh-CN.js +0 -62
  94. package/dist/src/gateway/cli-copy.zh-CN.js.map +0 -1
  95. package/dist/src/gateway/codex-doctor.d.ts +0 -36
  96. package/dist/src/gateway/codex-doctor.js +0 -127
  97. package/dist/src/gateway/codex-doctor.js.map +0 -1
  98. package/dist/src/gateway/dashboard-copy.d.ts +0 -7
  99. package/dist/src/gateway/dashboard-copy.en.d.ts +0 -504
  100. package/dist/src/gateway/dashboard-copy.en.js +0 -505
  101. package/dist/src/gateway/dashboard-copy.en.js.map +0 -1
  102. package/dist/src/gateway/dashboard-copy.js +0 -514
  103. package/dist/src/gateway/dashboard-copy.js.map +0 -1
  104. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +0 -504
  105. package/dist/src/gateway/dashboard-copy.zh-CN.js +0 -505
  106. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +0 -1
  107. package/dist/src/gateway/dashboard-model.d.ts +0 -343
  108. package/dist/src/gateway/dashboard-model.js +0 -1061
  109. package/dist/src/gateway/dashboard-model.js.map +0 -1
  110. package/dist/src/gateway/dashboard.d.ts +0 -20
  111. package/dist/src/gateway/dashboard.js +0 -874
  112. package/dist/src/gateway/dashboard.js.map +0 -1
  113. package/dist/src/gateway/deepseek-detect.d.ts +0 -14
  114. package/dist/src/gateway/deepseek-detect.js +0 -41
  115. package/dist/src/gateway/deepseek-detect.js.map +0 -1
  116. package/dist/src/gateway/live-dashboard-app/app.js +0 -2385
  117. package/dist/src/gateway/live-dashboard-assets.d.ts +0 -10
  118. package/dist/src/gateway/live-dashboard-assets.js +0 -74
  119. package/dist/src/gateway/live-dashboard-assets.js.map +0 -1
  120. package/dist/src/gateway/live-dashboard-command.d.ts +0 -60
  121. package/dist/src/gateway/live-dashboard-command.js +0 -334
  122. package/dist/src/gateway/live-dashboard-command.js.map +0 -1
  123. package/dist/src/gateway/live-dashboard-http.d.ts +0 -39
  124. package/dist/src/gateway/live-dashboard-http.js +0 -383
  125. package/dist/src/gateway/live-dashboard-http.js.map +0 -1
  126. package/dist/src/gateway/live-dashboard-protocol.d.ts +0 -34
  127. package/dist/src/gateway/live-dashboard-protocol.js +0 -114
  128. package/dist/src/gateway/live-dashboard-protocol.js.map +0 -1
  129. package/dist/src/gateway/live-dashboard-server.d.ts +0 -33
  130. package/dist/src/gateway/live-dashboard-server.js +0 -144
  131. package/dist/src/gateway/live-dashboard-server.js.map +0 -1
  132. package/dist/src/gateway/live-dashboard-stream.d.ts +0 -46
  133. package/dist/src/gateway/live-dashboard-stream.js +0 -234
  134. package/dist/src/gateway/live-dashboard-stream.js.map +0 -1
  135. package/dist/src/gateway/live-dashboard.d.ts +0 -28
  136. package/dist/src/gateway/live-dashboard.js +0 -154
  137. package/dist/src/gateway/live-dashboard.js.map +0 -1
  138. package/dist/src/gateway/locale.d.ts +0 -4
  139. package/dist/src/gateway/locale.js +0 -10
  140. package/dist/src/gateway/locale.js.map +0 -1
  141. package/dist/src/gateway/progress-watch-machine.d.ts +0 -45
  142. package/dist/src/gateway/progress-watch-machine.js +0 -70
  143. package/dist/src/gateway/progress-watch-machine.js.map +0 -1
  144. package/docs/CONFIGURATION.zh-CN.md +0 -97
  145. package/docs/DASHBOARD.md +0 -98
  146. package/docs/DASHBOARD.zh-CN.md +0 -49
  147. package/docs/DELIVERY.zh-CN.md +0 -55
package/CHANGELOG.md CHANGED
@@ -4,6 +4,83 @@ 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
+ ## [3.1.0] - 2026-09-05
8
+
9
+ ### Added
10
+ - `embassy retire --alias <local-alias>` — credential-free, same-UID operator removal of any local route (Claude session, Codex task, or shell peer) through the existing atomic removal. It settles queued and reserved work `cancelled`, armed work `ambiguous`, and accepted work `unconfirmed`, reports those counts, journals one `route_retired` event for every provider, and refuses federated mirrors with `FEDERATED_ROUTE_READ_ONLY`. No token, force, or remote option exists.
11
+ - Proven destination enqueue refusals keep their safe code across federation; transport loss and failures after admission remain unknown and are never replayed.
12
+
13
+ ### Changed
14
+ - Private control protocol 3 → 4: one new method (`retire_route`), 15 control methods, 18 CLI commands. A 3.0.0 CLI and a 3.1.0 broker refuse each other with the control mismatch code; restart the broker after upgrading.
15
+ - `EMBASSY_MAX_ROUTES` accepts 2 through 128 and fails closed at config load above that with `INVALID_GATEWAY_CONFIGURATION`. 3.0.0 accepted 129–256 at parse and then refused provider startup. The tracked advertisement-helper cap is the same number.
16
+ - Every busy-observation code on a Claude route (`CLAUDE_PEER_TARGET_UNKNOWN`, `CLAUDE_PEER_WORKSPACE_UNATTESTED`, `CLAUDE_PEER_NOT_OBSERVED`, `CLAUDE_DISCOVERY_UNAVAILABLE`) renders an operator remedy in `status`; the never-produced `CLAUDE_PEER_TARGET_STALE` and `CLAUDE_PEER_TARGET_CHANGED` codes are gone.
17
+ - An idle or stale connector renders `ok` health; a named connector fault or a real provider failure stays `degraded`.
18
+ - The supported package surface is the CLI, the skill, and the documented JSON. Deep imports of shipped `dist` declarations are unsupported; unused internal exports, dead validators, test-only runtime facades, and startup-owned route wiring were removed.
19
+ - Public docs describe advertisement as one helper per local non-Claude route (`codex-*` or `peer-*`); federated mirrors are not advertised. A test guard rejects any singleton "one `codex-*` record" phrasing.
20
+
21
+ ### Fixed
22
+ - Helper admission reserves a pending creation before forking, coalesces same-alias creation, releases a failed reservation, and joins in-flight creation on shutdown so every created client is closed.
23
+ - Federated mirror routes are no longer handed to local native advertisement (no per-reconcile refusal or `NATIVE_ADVERTISEMENT_FAILED` alert).
24
+ - Expired or unknown peer receipts return `not_found`, not `route_mismatch`; the peer-receipt fixtures no longer race a 100 ms timer on slow runners.
25
+ - A renamed Claude source carries its current alias through envelopes, terminal replies, and native replies.
26
+ - The service command's install/status/uninstall output is pinned byte-for-byte; the delivery runner's peer and provider engines are separate methods with a phase-failure characterization and no behavior change.
27
+
28
+ ## [3.0.0] - 2026-09-03
29
+
30
+ ### Added
31
+
32
+ - `embassy status` renders for a person when stdout is a terminal: one broker line (pid, version, state directory, snapshot age), how old the last session scan is (offering `embassy refresh` past a minute), one plain word per connector that matters, a `sessions` block of the live Claude sessions the scan found and whether each has a route yet, a routes table with queue depth and last-seen age, the last messages with a one-line body preview (control and formatting characters stripped), and only those alerts that have a remedy — each non-`ok` word paired with its safe code and one line of what to do about it. It is read-only: it never rescans, so it is safe to run in a loop. Piped, or with `--json`, it prints the snapshot byte-for-byte as before, so every script and the skill are unaffected. `--recent <n>` (1–100, default 10) sizes the message list, and colour appears only on a terminal with `NO_COLOR` unset and never carries meaning alone. The staleness derivations are deliberate: a connector with nothing to observe is `stale`, not `degraded`; a shell peer holding unclaimed mail is reported without moving the overall word; a route is called `stale` only after ten minutes unobserved, and a Codex route gets the succession remedy only when it is also carrying a task-gone code; a Claude route the latest scan still lists is never stale (emb-107).
33
+ - `embassy watch` tails the broker: each new message row and each settlement at most once (`accepted → delivered (61 ms)`), stamped with the local time, and route installs, retirements and discovery refreshes as a secondary line; rows evicted before the tail read them are announced as a note. `--json` streams the same events as JSONL, each transition carrying its `timestamp`; Ctrl-C exits 0; memory is bounded by the snapshot itself (emb-107).
34
+ - `embassy check` is the upstream-drift tripwire to run after a Claude Code or Codex CLI update. It registers an ephemeral `peer-*` principal of its own — so it works from a plain terminal with no inherited identity, and leaves nothing behind but its native advertisement to Claude sessions, released with it — sends one `[embassy check <id>]` body through the ordinary send path to the most recently observed registered Codex task (observed within ten minutes; a task never observed is not eligible, and when none qualifies it names them and sends nothing), waits for `delivered`, awaits the correlated reply on its own mailbox, releases the registration, and prints every hop with its timing. `--to <alias>` picks a target instead; `--timeout <s>` (1–600, default 60) bounds each wait; any failing hop, an uncorrelated answer that times out, or a refused cleanup exits non-zero with the safe code that explains it; Ctrl-C runs the cleanup hop at once. The shipped skill gains the matching rule: a message whose verified sender alias starts with `peer-check-` and whose body starts `[embassy check` is answered with one line echoing the id (emb-107).
35
+ - `register_peer` accepts `ephemeral: true` with an optional `ttlMs` (1 s–1 h, default 5 min) on a first registration: the route is real in memory but is never written to the state document, never published in the federation catalog, and is retired by the broker when its lifetime ends — gone on restart by construction. Every row it owns — the messages it sent and received, its dedupe and rate rows, and the journal rows that name it — is projected out of the written document while it lives and leaves the live state with it when it is removed, by the check's own cleanup or by expiry, so nothing of a check reaches disk at any point. A timed retirement that fails is retried twice more, five seconds apart, with an alert each time; after the third failure the registration is left until the broker restarts. Its native advertisement to Claude sessions is released with it but is not swept at boot: a broker that dies mid-check can leave that record behind, inert, until the alias is next registered and released. One safe code is added for the one thing that can go wrong with it: `EPHEMERAL_ROUTE_EXPIRY_FAILED`, the alert each failed retirement raises (emb-107).
36
+ - `embassy service install|uninstall|status` runs the broker as a per-user macOS launchd agent, restarting it after a crash but never after a deliberate boot refusal (emb-108).
37
+ - The three connect-stage codes that mean nothing is serving the state directory — `CONTROL_SOCKET_UNAVAILABLE`, `CONTROL_SOCKET_MISSING`, and `CONTROL_LISTENER_UNAVAILABLE` — now carry one hint that names the resolved state directory and points at `embassy service install` or `embassy serve` (emb-108).
38
+
39
+ ### Removed
40
+
41
+ - The static dashboard and the live dashboard, with `embassy refresh-dashboard` and `embassy dashboard --live` (emb-100).
42
+ - The ACP-backed DeepSeek and Grok providers with their `dsh-`/`grok-` routes, the offline provider support matrix, and `embassy doctor` with its Codex Desktop classifier (emb-101). The managed-socket holder check stays: a process outside Embassy holding the managed Codex control socket still degrades the Codex connector with `MANAGED_CODEX_UNAVAILABLE`.
43
+ - zh-CN localization, the `--lang` option, and the copy-table layer (emb-102).
44
+ - Progress watches: `TRACK:`/`DONE:`, `--track`, `--idle-minutes`, `untrack`, the automated liveness nudge, `EMBASSY_TRACKING_ENABLED`, `EMBASSY_MAX_WATCHES` (emb-103). A body beginning `TRACK:` or `DONE:` is now delivered verbatim as an ordinary message. Busy-gating (`ROUTE_BUSY` deferral and requeue), `STEER:`, and the queued-ahead marker are unchanged.
45
+ - `GATEWAY_NODE_INVENTORY_REQUIRED` (emb-106).
46
+ - Codex Desktop as a documented task host: the attachment mode upstream had broken, its `CODEX_APP_SERVER_USE_LOCAL_DAEMON` guidance, and the known-limitation note are gone from every shipped document; the supported host is Codex CLI with the managed standalone App Server (emb-109). The marketing site is one short page pointing at the README and this changelog; its former second-language page redirects to it (emb-109).
47
+ - Consent edges, with `embassy pair` / `embassy unpair`, `embassy select-claude` / `embassy unselect-claude`, `embassy serve --inbound`, and `EMBASSY_MAX_PAIRS` (emb-104). The `pair`, `unpair`, `select_claude`, and `unselect_claude` control methods, the four safe codes `SENDER_NOT_PAIRED`, `CONSENT_OWNER_HOST_REQUIRED`, `INVALID_CONSENT_EDGE`, and `CONSENT_EDGE_CAPACITY_REACHED`, the `consentEdges` inventory in private state and in the public snapshot, the consent rows on the federation catalog and handoff wire, and the `native_reply` dispatch authorization (the one branch that skipped the target-workspace assertion) are all gone.
48
+
49
+ ### Changed
50
+
51
+ - `nodes.json` is optional; when absent at boot, the broker writes it once, naming this machine by its own hostname with an empty peer list, and federates with nobody until you edit the file in. That written file — not the hostname — is the broker's durable identity from then on: renaming the machine does not rename the installation, and a controller lock left behind by a crash is recovered by process liveness rather than by the name that wrote it (emb-106).
52
+ - Stale `gateway-dashboard*.html` files left by 2.x, and their `.tmp` publish artifacts from a crashed 2.x write, are removed from the state dir at boot (emb-106).
53
+ - A `.gateway-controller.lock` is judged only by whether its recorded pid is alive. A lock left by a crash is recovered whatever machine name it records, so a rename can no longer wedge a state directory permanently, and an empty lock left mid-write is recovered too; an unreadable one refuses with `GATEWAY_STATE_LOCK_UNVERIFIED`, and a live pid still refuses with `GATEWAY_STATE_IN_USE`. Both refusals now print the lock's path, and the live-pid one the recorded host and pid, with the remedy. What this trades away: the old hostname gate also happened to keep two machines off one state directory shared over a network. Embassy has never supported sharing state across machines ([SECURITY.md](SECURITY.md)), so no supported configuration changes — but if you were relying on that side effect, it is gone. A record that parses but names no usable pid is unverified too, not "in use". Recovered locks are kept as `.gateway-controller.lock.stale-<recovered-at>-<uuid>` for seven days from the recovery — the timestamp is in the name because the file's own mtime is the crashed broker's and can be far older — then swept (emb-106).
54
+ - `embassy refresh` reports a discovery failure honestly instead of claiming success.
55
+ - Private state schema is 5, reset-only: 2.x state is refused with `GATEWAY_STATE_SCHEMA_UNSUPPORTED` and never rewritten; follow the [private state reset](docs/CONFIGURATION.md#private-state-reset).
56
+ - Federation peer protocol is 2; a node answering `initialize` with another version surfaces `PEER_PROTOCOL_MISMATCH` on its mirrored routes and in `embassy status` instead of a tunnel fault.
57
+ - Private control protocol is 3; a client and broker on different lines report `CONTROL_VERSION_MISMATCH`.
58
+ - `unregister-codex` against a federated (read-only) route now returns `rejected` with `FEDERATED_ROUTE_READ_ONLY` instead of `not_found` (emb-101).
59
+ - The stall and diagnostic notices written into a Claude session now say ``Run `embassy status` for details`` (emb-102).
60
+ - `send` installs a discovered Claude session's route on first use; the permission to message is same UID + same host (or a configured node) + alias; the provenance envelope names the sender; a colliding alias is refused with `PEER_ALIAS_COLLISION` at send time (emb-104).
61
+ - Private state keeps schema 5 with a shape change: the retired `consentEdges` key makes an existing file fail the exact-key check, so an older schema-5 state file is refused with `CORRUPT_GATEWAY_STATE` and the documented [private state reset](docs/CONFIGURATION.md#private-state-reset) applies (emb-104). A message's `sourceRegistrationId` is narrowed from nullable to always present, since every sender now holds a route.
62
+ - Two safe codes are added (emb-104): `ROUTE_DIRECTION_MISMATCH`, when admission is asked to route between two endpoints with no direction between them, and `ENDPOINT_RETIRED`, the settlement reason for the work of a route displaced by another session claiming its alias. Two activity actions replace the four retired ones: `claude_route_installed` and `claude_route_retired`.
63
+ - A refused `send` control result may carry an optional `reason` — the safe code behind the coarse decision — and the CLI renders one remedy per reason instead of one generic line (emb-104).
64
+ - `availablePeers[].selected` is renamed to `routed` in the public snapshot: it means the session has an installed route, never a permission (emb-104).
65
+ - The native Claude helper IPC protocol is version 2: `selected_route` is the only dispatch authorization and its `stateRoot` is required, so every preparation runs the target-workspace assertion (emb-104).
66
+ - A federation node whose only routes are peer mirrors can persist and reload its state: the loader takes the local host identity from the broker's configuration instead of deriving it from local routes, which previously left a fresh node unable to write after its first peer refresh (emb-104).
67
+ - `send` addresses either a route by name (`--to <alias>`) or an open conversation by its token (`--conversation conv_<token>`), never both and never neither; the conversation form is what `reply` was, and it is how a recipient answers (emb-105). The caller must already own one end of that conversation, the other end stays the binding the conversation recorded — a replaced endpoint still refuses with `CONVERSATION_ROUTE_RETIRED` rather than retargeting — and an answer always expects a reply, so `--expects-reply` is rejected beside `--conversation`. The `reply` control method is gone with it: both CLI verbs build one `send` request, and the closed version 3 method family is now fourteen methods. A conversation-addressed send with no inherited credential reports the provider-neutral `CALLER_IDENTITY_REQUIRED`, and the CLI's hint names the three credentials it accepts — the Codex task's `CODEX_THREAD_ID`, the Claude session's messaging socket, or a shell peer's token on the first stdin line with `--token-stdin`; a peer credential authenticates a `peer-*` alias and nothing else, in either addressing form (emb-109). A conversation answered from the wrong end — an end-owner naming the other end in `--from` with its own credential — is refused with `CODEX_THREAD_MISMATCH` or `CLAUDE_REPLY_ADDRESS_INVALID`, and the CLI renders the own-alias remedy for the caller-mismatch reasons (emb-109).
68
+ - The `<embassy-reply-hint>` that begins every delivered envelope now names `embassy send --conversation <token> --from <alias>` (emb-105).
69
+ - A control request naming a method this broker does not implement still fails with `UNKNOWN_METHOD`, and this CLI now adds one hint on every path that meets it — the plain command path, `status`, `watch`, and each `check` hop: rebuild or update so the client and broker are one Embassy installation. The hint helps a newer client against an older broker on the same protocol line; an older client sending a retired `reply` frame still gets the bare code, because that client predates the hint (emb-109).
70
+ - A Codex task whose alias has no registration on this broker — the state every task is in after the private state reset — is refused with `ROUTE_UNREGISTERED` and told to run `embassy register-codex`; `CODEX_THREAD_MISMATCH` is reserved for a registration that exists under another task and carries its own remedy. A route send with no credential and a `codex-*` or `peer-*` `--from` reports `CALLER_IDENTITY_REQUIRED` naming the one credential that alias shape needs, and only a Claude-shaped alias keeps `CLAUDE_IDENTITY_REQUIRED`; a peer token beside a non-peer alias says so instead of a bare argument fault. `embassy check` fails its reply hop when the mailbox receipt is refused (emb-109).
71
+
72
+ ### Deprecated
73
+
74
+ - `embassy reply --conversation <token> --alias <your-alias>` is a deprecated alias for `embassy send --conversation <token> --from <your-alias>` (emb-105). It builds the identical control request and returns the identical result and exit code; only the echoed `command` name differs. It stays for one release because reply hints delivered in envelopes already in flight still name it, and is removed after that.
75
+
76
+ ### Upgrade note
77
+
78
+ - Reset only. Stop Embassy, move `gateway-state.json` aside — schema 5 refuses 2.x state with `GATEWAY_STATE_SCHEMA_UNSUPPORTED` and never rewrites it — and start 3.0, following the [private state reset](docs/CONFIGURATION.md#private-state-reset). `nodes.json` is optional: keep yours if you federate; the broker writes one on first boot if you have none.
79
+ - Re-register Codex tasks from inside each task. There is no select or pair step: Claude routes install themselves on first use.
80
+ - `embassy reply` is deprecated for `embassy send --conversation <token> --from <alias>`; update scripts now, it is removed next release.
81
+ - Codex Desktop hosting is no longer documented; run tasks in Codex CLI with the managed standalone App Server.
82
+ - The four numbers: private state schema 5, control protocol 3 (keep the CLI and broker on one installation), federation peer protocol 2 (upgrade every node), Claude helper protocol 2 (internal to one installation).
83
+
7
84
  ## [2.0.1] - 2026-09-01
8
85
 
9
86
  Identical product to the unpublished v2.0.0 (its pipeline was failed by a test-hermeticity defect — dashboard-command tests leaned on the developer's real state inventory, red on CI since the mandatory `nodes.json` cut; no product defect). The dashboard-command tests are now hermetic.
package/CONTRIBUTING.md CHANGED
@@ -41,8 +41,8 @@ recovery.
41
41
  - Update README and architecture documentation when public behavior changes.
42
42
  - Verify that public files contain no credentials, native IDs, message bodies,
43
43
  local state, or personal absolute paths.
44
- - Do not commit `node_modules`, `dist`, package archives, generated dashboards,
45
- logs, environment files, or live-validation artifacts.
44
+ - Do not commit `node_modules`, `dist`, package archives, logs, environment
45
+ files, or live-validation artifacts.
46
46
 
47
47
  ## Architecture rules
48
48
 
@@ -50,13 +50,11 @@ recovery.
50
50
 
51
51
  - Codex tasks self-register through inherited `CODEX_THREAD_ID` and a
52
52
  `codex-*` alias. Never add a thread-ID argument or global task-history scan.
53
- - Codex-to-Claude sends require a previously selected compatible live session.
54
- Do not auto-select during send.
55
- - In the default `paired` inbound mode, a Claude session reaches the registered
56
- native Codex peer only across an existing pair edge; a sender without one is
57
- refused `SENDER_NOT_PAIRED` before admission and the refusal is journaled.
58
- Only `serve --inbound open` admits any exact compatible live same-UID session.
59
- Neither path makes the inbound session outbound-selected.
53
+ - A Codex-to-Claude send installs the addressed session's route on first use;
54
+ a Claude session's own route installs on its first outbound message. There is
55
+ no separate grant: the permission is the OS boundary same UID, same host or
56
+ a host configured in `nodes.json` plus the exact alias, and the provenance
57
+ envelope names the sender.
60
58
  - Claude's session UUID is its stable logical identity. Current names are a
61
59
  live index; do not add historical-name routing or PID/socket identity.
62
60
  - Preserve current-name collision refusal and exact registration fencing.
@@ -64,7 +62,7 @@ recovery.
64
62
  performs no provider or App Server I/O. `register-codex --succeeds` is one
65
63
  atomic logical replacement that settles queued/reserved work `cancelled`,
66
64
  armed work `ambiguous`, and accepted work `unconfirmed`; removes every
67
- incident consent edge and conversation, reply, or native capability; and
65
+ incident conversation, reply, or native capability; and
68
66
  installs only the successor. Do not add prepared generations, re-anchoring,
69
67
  or recovery journals.
70
68
 
@@ -90,8 +88,10 @@ interface drift or an unavailable optional provider degrades only that
90
88
  surface. Do not widen a declared protocol without documented review and
91
89
  deterministic fixtures.
92
90
 
93
- The gateway may publish one process-owned `codex-*` peer so Claude's native
94
- `ListAgents` and `SendMessage` tools can reach Codex. It must never overwrite a
91
+ The gateway may advertise each local non-Claude route (`codex-*` or `peer-*`) through
92
+ its own forked helper, callback socket and marked registry record, subject to the
93
+ tracked-helper limit and pending-creation limitation in SECURITY.md. Claude's native `ListAgents` and `SendMessage` tools
94
+ can reach those local routes; federated mirrors are not advertised. The gateway must never overwrite a
95
95
  foreign registry record, claim to be a Claude model session, or unlink a socket
96
96
  whose exact generation it no longer owns.
97
97
 
@@ -124,37 +124,24 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
124
124
  terminal failure, ambiguity, expiry, and restart abandonment.
125
125
  - Never retry an ambiguous provider write. Requeue only a confirmed clean
126
126
  deferral that has not crossed an ambiguous mutation boundary.
127
- - The private mode-0600 v4 ledger retains bounded queued and recent bodies,
127
+ - The private mode-0600 v5 ledger retains bounded queued and recent bodies,
128
128
  opaque delivery tokens, and status. Queued or reserved work may resume once
129
129
  within its deadline and attempt budget against the same exact route and edge.
130
130
  Armed work settles `ambiguous`; accepted work settles `unconfirmed`; neither
131
131
  is replayed. Conversations, reply/native capabilities, raw frames, callback
132
132
  addresses, and socket paths remain memory-only.
133
133
  - Persist native route identifiers only in the closed private binding schema.
134
- Keep them out of events, snapshots, dashboard rows, logs, errors, and CLI
134
+ Keep them out of events, snapshots, logs, errors, and CLI
135
135
  output. The only CLI exception is a UUID explicitly supplied by the user as a
136
136
  Claude selector.
137
137
 
138
138
  ### Local control surface
139
139
 
140
- `embassy serve` may use one private same-user control UDS and publish two inert,
141
- metadata-only static dashboard files. It must not listen on TCP or HTTP. The
142
- only reviewed exception is the separately invoked foreground
143
- `embassy dashboard --live` companion, which binds exact IPv4 loopback on stable
144
- port `41961` by default or the validated per-invocation `--port <n>`. It has no
145
- local-process or UID authentication and therefore assumes a trusted
146
- single-user machine; exact Host on every request and exact Origin plus
147
- `X-Embassy-Request` on every POST constrain browser origins, not local
148
- software. Preserve the direct root URL, multi-window/browser access, collision
149
- failure with no fallback port, no CORS/`OPTIONS`, and only the reviewed pair,
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.
140
+ `embassy serve` may use one private same-user control UDS and nothing else. It
141
+ must not listen on TCP or HTTP, and Embassy ships no other listener. Do not add
142
+ a wildcard/remote listener, external assets, service workers, telemetry, or a
143
+ mutation endpoint. Keep the shipped launcher foreground, macOS-only, and
144
+ local-host-only.
158
145
 
159
146
  ## Live validation
160
147
 
@@ -180,8 +167,7 @@ lease spawns macOS's `/usr/bin/lockf`); macOS runs the full suite.
180
167
 
181
168
  ## Design honesty rules
182
169
 
183
- These outlive any visual era and bind every surface — dashboards, CLI copy,
184
- site, docs, in both languages:
170
+ These outlive any visual era and bind every surface — CLI copy, site, docs:
185
171
 
186
172
  - Progress is never green. Only a terminal success state may look like one.
187
173
  - `delivered` means the write completed; `released` is not read; nothing may
@@ -197,7 +183,8 @@ site, docs, in both languages:
197
183
  [`docs/DECLINED.md`](docs/DECLINED.md) records, per release, what we considered
198
184
  and chose not to build, each with a one-line reason. It is product
199
185
  documentation: a product that documents what it refuses to build is making the
200
- same promise the dashboard makes—the truth over the appearance of completeness.
186
+ same promise its status output makes—the truth over the appearance of
187
+ completeness.
201
188
  PRs that implement something in the ledger must address its reason.
202
189
 
203
190
  ### Why tickets are priced by the PM
@@ -220,4 +207,4 @@ deliverability beats ceremony. Never auto-retry a delivery the recipient's
220
207
  user denied: that is consent, not transport.
221
208
 
222
209
  For long messages, write the body to a file and pipe it
223
- (`embassy reply ... < body.md`); never inline `printf` for prose.
210
+ (`embassy send --conversation ... < body.md`); never inline `printf` for prose.