agent-embassy 1.9.5 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/CONTRIBUTING.md +19 -34
  3. package/README.md +110 -221
  4. package/SECURITY.md +55 -89
  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 +9 -12
  9. package/dist/src/gateway/claude-helper-protocol.js +15 -13
  10. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  11. package/dist/src/gateway/claude-helper-supervisor.d.ts +2 -6
  12. package/dist/src/gateway/claude-helper-supervisor.js +10 -9
  13. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  14. package/dist/src/gateway/claude-helper.js +18 -10
  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 +6 -18
  18. package/dist/src/gateway/claude-peer.js.map +1 -1
  19. package/dist/src/gateway/cli.d.ts +18 -13
  20. package/dist/src/gateway/cli.js +942 -298
  21. package/dist/src/gateway/cli.js.map +1 -1
  22. package/dist/src/gateway/codex-local-transport.d.ts +1 -1
  23. package/dist/src/gateway/codex-local-transport.js +2 -2
  24. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  25. package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
  26. package/dist/src/gateway/codex-socket-holder.js +76 -0
  27. package/dist/src/gateway/codex-socket-holder.js.map +1 -0
  28. package/dist/src/gateway/codex-stateless-transport.js +1 -1
  29. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  30. package/dist/src/gateway/config.d.ts +5 -13
  31. package/dist/src/gateway/config.js +7 -19
  32. package/dist/src/gateway/config.js.map +1 -1
  33. package/dist/src/gateway/control.d.ts +55 -108
  34. package/dist/src/gateway/control.js +95 -222
  35. package/dist/src/gateway/control.js.map +1 -1
  36. package/dist/src/gateway/federation-nodes.d.ts +29 -3
  37. package/dist/src/gateway/federation-nodes.js +200 -15
  38. package/dist/src/gateway/federation-nodes.js.map +1 -1
  39. package/dist/src/gateway/peer-client.d.ts +4 -3
  40. package/dist/src/gateway/peer-client.js +22 -13
  41. package/dist/src/gateway/peer-client.js.map +1 -1
  42. package/dist/src/gateway/peer-protocol.d.ts +8 -11
  43. package/dist/src/gateway/peer-protocol.js +5 -12
  44. package/dist/src/gateway/peer-protocol.js.map +1 -1
  45. package/dist/src/gateway/provenance-envelope.d.ts +0 -1
  46. package/dist/src/gateway/provenance-envelope.js +4 -19
  47. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  48. package/dist/src/gateway/providers.d.ts +10 -7
  49. package/dist/src/gateway/providers.js +21 -28
  50. package/dist/src/gateway/providers.js.map +1 -1
  51. package/dist/src/gateway/server.d.ts +4 -14
  52. package/dist/src/gateway/server.js +33 -59
  53. package/dist/src/gateway/server.js.map +1 -1
  54. package/dist/src/gateway/service-agent.d.ts +187 -0
  55. package/dist/src/gateway/service-agent.js +758 -0
  56. package/dist/src/gateway/service-agent.js.map +1 -0
  57. package/dist/src/gateway/service.d.ts +117 -32
  58. package/dist/src/gateway/service.js +525 -576
  59. package/dist/src/gateway/service.js.map +1 -1
  60. package/dist/src/gateway/status-view.d.ts +167 -0
  61. package/dist/src/gateway/status-view.js +488 -0
  62. package/dist/src/gateway/status-view.js.map +1 -0
  63. package/dist/src/gateway/store.d.ts +103 -21
  64. package/dist/src/gateway/store.js +473 -547
  65. package/dist/src/gateway/store.js.map +1 -1
  66. package/dist/src/gateway/types.d.ts +51 -102
  67. package/dist/src/gateway/types.js +15 -52
  68. package/dist/src/gateway/types.js.map +1 -1
  69. package/docs/CONFIGURATION.md +194 -59
  70. package/docs/DELIVERY.md +11 -11
  71. package/docs/GATEWAY-ARCHITECTURE.md +286 -394
  72. package/package.json +4 -12
  73. package/skills/embassy-peer/SKILL.md +72 -92
  74. package/skills/embassy-peer/agents/openai.yaml +1 -1
  75. package/README.zh-CN.md +0 -269
  76. package/assets/live-dashboard/app.css +0 -1619
  77. package/assets/vendor/react/LICENSE +0 -21
  78. package/assets/vendor/react/react-dom.production.min.js +0 -267
  79. package/assets/vendor/react/react.production.min.js +0 -31
  80. package/dist/src/gateway/acp-client.d.ts +0 -110
  81. package/dist/src/gateway/acp-client.js +0 -407
  82. package/dist/src/gateway/acp-client.js.map +0 -1
  83. package/dist/src/gateway/acp-provider.d.ts +0 -66
  84. package/dist/src/gateway/acp-provider.js +0 -275
  85. package/dist/src/gateway/acp-provider.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 -17
  88. package/dist/src/gateway/cli-copy.en.js +0 -58
  89. package/dist/src/gateway/cli-copy.en.js.map +0 -1
  90. package/dist/src/gateway/cli-copy.js +0 -22
  91. package/dist/src/gateway/cli-copy.js.map +0 -1
  92. package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -17
  93. package/dist/src/gateway/cli-copy.zh-CN.js +0 -58
  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 -58
  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/dist/src/gateway/state-v2-to-v3.d.ts +0 -24
  145. package/dist/src/gateway/state-v2-to-v3.js +0 -1034
  146. package/dist/src/gateway/state-v2-to-v3.js.map +0 -1
  147. package/docs/CONFIGURATION.zh-CN.md +0 -93
  148. package/docs/DASHBOARD.md +0 -98
  149. package/docs/DASHBOARD.zh-CN.md +0 -49
  150. package/docs/DELIVERY.zh-CN.md +0 -55
package/CHANGELOG.md CHANGED
@@ -4,6 +4,93 @@ 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.0.0] - 2026-09-03
8
+
9
+ ### Added
10
+
11
+ - `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).
12
+ - `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).
13
+ - `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).
14
+ - `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).
15
+ - `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).
16
+ - 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).
17
+
18
+ ### Removed
19
+
20
+ - The static dashboard and the live dashboard, with `embassy refresh-dashboard` and `embassy dashboard --live` (emb-100).
21
+ - 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`.
22
+ - zh-CN localization, the `--lang` option, and the copy-table layer (emb-102).
23
+ - 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.
24
+ - `GATEWAY_NODE_INVENTORY_REQUIRED` (emb-106).
25
+ - 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).
26
+ - 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.
27
+
28
+ ### Changed
29
+
30
+ - `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).
31
+ - 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).
32
+ - 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).
33
+ - `embassy refresh` reports a discovery failure honestly instead of claiming success.
34
+ - 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).
35
+ - 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.
36
+ - Private control protocol is 3; a client and broker on different lines report `CONTROL_VERSION_MISMATCH`.
37
+ - `unregister-codex` against a federated (read-only) route now returns `rejected` with `FEDERATED_ROUTE_READ_ONLY` instead of `not_found` (emb-101).
38
+ - The stall and diagnostic notices written into a Claude session now say ``Run `embassy status` for details`` (emb-102).
39
+ - `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).
40
+ - 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.
41
+ - 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`.
42
+ - 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).
43
+ - `availablePeers[].selected` is renamed to `routed` in the public snapshot: it means the session has an installed route, never a permission (emb-104).
44
+ - 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).
45
+ - 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).
46
+ - `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).
47
+ - The `<embassy-reply-hint>` that begins every delivered envelope now names `embassy send --conversation <token> --from <alias>` (emb-105).
48
+ - 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).
49
+ - 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).
50
+
51
+ ### Deprecated
52
+
53
+ - `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.
54
+
55
+ ### Upgrade note
56
+
57
+ - 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.
58
+ - Re-register Codex tasks from inside each task. There is no select or pair step: Claude routes install themselves on first use.
59
+ - `embassy reply` is deprecated for `embassy send --conversation <token> --from <alias>`; update scripts now, it is removed next release.
60
+ - Codex Desktop hosting is no longer documented; run tasks in Codex CLI with the managed standalone App Server.
61
+ - 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).
62
+
63
+ ## [2.0.1] - 2026-09-01
64
+
65
+ 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.
66
+
67
+ ## [2.0.0] - 2026-09-01
68
+
69
+ ### Changed
70
+
71
+ - The private control protocol is version 2; version-1 control frames are refused rather than interpreted through a compatibility arm.
72
+ - One provider-neutral `embassy send --from <alias> --to <alias>` replaces both provider-named send verbs; the broker derives direction from the resolved route providers.
73
+
74
+ ### Added
75
+
76
+ - Background Claude Code sessions are first-class peers: discovery, selection, pairing, and message exchange work for `bg` sessions alongside interactive ones.
77
+
78
+ ### Fixed
79
+
80
+ - Two live Claude sessions sharing a display name no longer poison the public snapshot (previously `embassy status` failed entirely until restart): the colliding alias is fenced from listing, selection, and pairing while both sessions stay addressable by exact session UUID, and diagnostics count the collision.
81
+ - Connect-stage failures classify honestly: a permission-denied state directory or socket reports `CONTROL_CONNECT_DENIED` with the real remedy (grant this process access to the state directory; never start a second broker) in both locales; missing socket, nothing listening, and control-protocol version mismatch are distinct codes with distinct remedies. The real macOS-sandbox errno (EPERM) is regression-pinned.
82
+
83
+ ### Removed
84
+
85
+ - `pair` and `unpair` accept only explicit `--from` / `--to` endpoints; the legacy `--claude` / `--codex` arm is removed.
86
+ - State schema 4 no longer tolerates legacy 24-character delivery tokens or missing `busyPolicy`; older private state must use the reset-only upgrade path.
87
+ - `send-to-claude` and `send-to-codex` are removed with no compatibility aliases.
88
+
89
+ ### Upgrade note
90
+
91
+ - Before starting version 2.0, complete the [private state reset](docs/CONFIGURATION.md#private-state-reset) after settling all work under 1.9.x, and create the mandatory private `nodes.json` described in [Configuration](docs/CONFIGURATION.md) (use `nodes:[]` for a local-only broker).
92
+ - Authority-model correction: the prior published claim that generic `pair` and `unpair` attested an inherited endpoint identity was never enforced by the surviving generic arm. Same-UID access to the private control socket authorizes pair, unpair, select, and unselect controls. These operations do not attest inherited provider identity. Delivery in paired mode still requires the exact consent edge, and agents remain instructed to mutate only user-chosen edges.
93
+
7
94
  ## [1.9.5] - 2026-08-17
8
95
 
9
96
  ### Fixed
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
 
@@ -124,37 +122,24 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
124
122
  terminal failure, ambiguity, expiry, and restart abandonment.
125
123
  - Never retry an ambiguous provider write. Requeue only a confirmed clean
126
124
  deferral that has not crossed an ambiguous mutation boundary.
127
- - The private mode-0600 v3 ledger retains bounded queued and recent bodies,
125
+ - The private mode-0600 v5 ledger retains bounded queued and recent bodies,
128
126
  opaque delivery tokens, and status. Queued or reserved work may resume once
129
127
  within its deadline and attempt budget against the same exact route and edge.
130
128
  Armed work settles `ambiguous`; accepted work settles `unconfirmed`; neither
131
129
  is replayed. Conversations, reply/native capabilities, raw frames, callback
132
130
  addresses, and socket paths remain memory-only.
133
131
  - Persist native route identifiers only in the closed private binding schema.
134
- Keep them out of events, snapshots, dashboard rows, logs, errors, and CLI
132
+ Keep them out of events, snapshots, logs, errors, and CLI
135
133
  output. The only CLI exception is a UUID explicitly supplied by the user as a
136
134
  Claude selector.
137
135
 
138
136
  ### Local control surface
139
137
 
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.
138
+ `embassy serve` may use one private same-user control UDS and nothing else. It
139
+ must not listen on TCP or HTTP, and Embassy ships no other listener. Do not add
140
+ a wildcard/remote listener, external assets, service workers, telemetry, or a
141
+ mutation endpoint. Keep the shipped launcher foreground, macOS-only, and
142
+ local-host-only.
158
143
 
159
144
  ## Live validation
160
145
 
@@ -180,8 +165,7 @@ lease spawns macOS's `/usr/bin/lockf`); macOS runs the full suite.
180
165
 
181
166
  ## Design honesty rules
182
167
 
183
- These outlive any visual era and bind every surface — dashboards, CLI copy,
184
- site, docs, in both languages:
168
+ These outlive any visual era and bind every surface — CLI copy, site, docs:
185
169
 
186
170
  - Progress is never green. Only a terminal success state may look like one.
187
171
  - `delivered` means the write completed; `released` is not read; nothing may
@@ -197,7 +181,8 @@ site, docs, in both languages:
197
181
  [`docs/DECLINED.md`](docs/DECLINED.md) records, per release, what we considered
198
182
  and chose not to build, each with a one-line reason. It is product
199
183
  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.
184
+ same promise its status output makes—the truth over the appearance of
185
+ completeness.
201
186
  PRs that implement something in the ledger must address its reason.
202
187
 
203
188
  ### Why tickets are priced by the PM
@@ -220,4 +205,4 @@ deliverability beats ceremony. Never auto-retry a delivery the recipient's
220
205
  user denied: that is consent, not transport.
221
206
 
222
207
  For long messages, write the body to a file and pipe it
223
- (`embassy reply ... < body.md`); never inline `printf` for prose.
208
+ (`embassy send --conversation ... < body.md`); never inline `printf` for prose.