agent-embassy 1.9.4 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +28 -21
- package/README.zh-CN.md +26 -20
- package/dist/src/gateway/claude-helper-protocol.d.ts +1 -1
- package/dist/src/gateway/claude-helper-protocol.js +3 -2
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -1
- package/dist/src/gateway/claude-helper-supervisor.js +1 -1
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-helper.js +12 -4
- package/dist/src/gateway/claude-helper.js.map +1 -1
- package/dist/src/gateway/cli-copy.d.ts +1 -1
- package/dist/src/gateway/cli-copy.en.d.ts +9 -4
- package/dist/src/gateway/cli-copy.en.js +10 -6
- package/dist/src/gateway/cli-copy.en.js.map +1 -1
- package/dist/src/gateway/cli-copy.js +5 -0
- package/dist/src/gateway/cli-copy.js.map +1 -1
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +9 -4
- package/dist/src/gateway/cli-copy.zh-CN.js +10 -6
- package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/cli.d.ts +3 -9
- package/dist/src/gateway/cli.js +56 -63
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-local-transport.d.ts +1 -1
- package/dist/src/gateway/codex-local-transport.js +2 -2
- package/dist/src/gateway/codex-local-transport.js.map +1 -1
- package/dist/src/gateway/config.d.ts +4 -3
- package/dist/src/gateway/config.js +5 -11
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +20 -41
- package/dist/src/gateway/control.js +54 -96
- package/dist/src/gateway/control.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.en.js +2 -2
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.js +2 -2
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/federation-nodes.d.ts +1 -2
- package/dist/src/gateway/federation-nodes.js +29 -14
- package/dist/src/gateway/federation-nodes.js.map +1 -1
- package/dist/src/gateway/live-dashboard-app/app.js +2 -2
- package/dist/src/gateway/live-dashboard-command.d.ts +3 -1
- package/dist/src/gateway/live-dashboard-command.js +1 -1
- package/dist/src/gateway/live-dashboard-command.js.map +1 -1
- package/dist/src/gateway/peer-protocol.d.ts +1 -0
- package/dist/src/gateway/peer-protocol.js +5 -0
- package/dist/src/gateway/peer-protocol.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +3 -3
- package/dist/src/gateway/providers.js +7 -10
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.d.ts +1 -2
- package/dist/src/gateway/server.js +6 -13
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -1
- package/dist/src/gateway/service.js +93 -39
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/store.d.ts +1 -1
- package/dist/src/gateway/store.js +30 -29
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +4 -4
- package/docs/CONFIGURATION.md +27 -21
- package/docs/CONFIGURATION.zh-CN.md +19 -15
- package/docs/DASHBOARD.md +1 -1
- package/docs/DASHBOARD.zh-CN.md +1 -1
- package/docs/DELIVERY.md +2 -2
- package/docs/DELIVERY.zh-CN.md +2 -2
- package/docs/GATEWAY-ARCHITECTURE.md +48 -58
- package/package.json +1 -1
- package/skills/embassy-peer/SKILL.md +20 -15
- package/dist/src/gateway/state-v2-to-v3.d.ts +0 -24
- package/dist/src/gateway/state-v2-to-v3.js +0 -1034
- package/dist/src/gateway/state-v2-to-v3.js.map +0 -1
package/docs/CONFIGURATION.md
CHANGED
|
@@ -18,31 +18,37 @@ below.
|
|
|
18
18
|
| `EMBASSY_DELIVERY_NOTICES` | `merged` | Claude sender notice policy: `merged` keeps stalls and folds terminal diagnostics into native status; `verbose` emits both; `quiet` emits no gateway user-frame notices |
|
|
19
19
|
| `EMBASSY_TRACKING_ENABLED` | `1` | Global progress-watch kill switch; set exactly `0` to reject `--track`, `--idle-minutes`, and `TRACK:` open attempts. Active watches are memory-only and end with the broker process; they are never restored after restart. With no active watch, `DONE:` is inert and `untrack` is not specially rejected—it returns `NOT_FOUND`. Any value other than `1` or `0` is a configuration error |
|
|
20
20
|
| `EMBASSY_LOCALE` | `en` | CLI output language, exactly `en` or `zh-CN`. The `--lang` flag overrides it for the invocation that carries it; an unset or empty value means `en`, and any other value is an argument error |
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
Before any Embassy client call that talks to the broker, the CLI reads the state
|
|
23
|
+
directory and `nodes.json`, then connects to the control socket; grant a sandboxed
|
|
24
|
+
Codex task that directory as a writable root, or approve equivalent local access,
|
|
25
|
+
and do not relocate state or start a second broker to work around a denial.
|
|
22
26
|
|
|
23
27
|
Federation authority comes only from `nodes.json` in `EMBASSY_STATE_DIR`. It
|
|
24
28
|
must be a current-user-owned mode-0600 regular file whose exact object shape is
|
|
25
29
|
`{"version":1,"host":"<lowercase-host>","nodes":["<lowercase-ssh-alias>",...]}`.
|
|
26
|
-
`host` names this broker; `nodes` contains
|
|
30
|
+
`host` names this broker; `nodes` contains 0 through 31 unique OpenSSH aliases,
|
|
27
31
|
omits `host`, and keeps the federation at 32 total hosts or fewer. Each listed
|
|
28
|
-
node is the fixed SSH destination for `embassy peer-stdio`.
|
|
29
|
-
the
|
|
32
|
+
node is the fixed SSH destination for `embassy peer-stdio`. The file is mandatory;
|
|
33
|
+
when it is absent, Embassy prints the exact `nodes:[]` local-only fix and refuses startup.
|
|
34
|
+
Removing a peer does not remove its durable mirrors; reset private state before restarting with that peer absent.
|
|
30
35
|
|
|
31
|
-
###
|
|
36
|
+
### Private state reset
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
Version 2.0 accepts only fresh schema-4 private state; it does not convert or
|
|
39
|
+
rewrite older state. Before the reset, use the old running broker's `status`
|
|
40
|
+
and delivery lookups to verify that no queued, armed, or accepted work remains
|
|
41
|
+
and every delivery has settled. Then:
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
1. Stop the broker.
|
|
44
|
+
2. Move `gateway-state.json` aside so the old ledger remains recoverable.
|
|
45
|
+
3. Keep `nodes.json` in place.
|
|
46
|
+
4. Start the version-2 broker to create fresh state.
|
|
47
|
+
5. Re-register routes, select the Claude route, and pair the intended edges.
|
|
39
48
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
atomically installing and reading back v3 state. Normal output contains only
|
|
44
|
-
success and the backup basename. If conversion fails, use the exact normalized
|
|
45
|
-
safe code; do not retry a commit-unknown result or hand-edit the state file.
|
|
49
|
+
An old or unknown schema refuses with `GATEWAY_STATE_SCHEMA_UNSUPPORTED` and
|
|
50
|
+
does not mutate the state file. There is no conversion command or automatic
|
|
51
|
+
recovery path.
|
|
46
52
|
|
|
47
53
|
The live dashboard is available directly at `http://127.0.0.1:41961/` while
|
|
48
54
|
its foreground companion runs. Its port is a per-invocation CLI choice, not an
|
|
@@ -84,7 +90,7 @@ two hours.
|
|
|
84
90
|
|
|
85
91
|
A CLI initiator receives the full `conv_` token in its result, and every routed recipient receives the same token in the inbound provenance envelope and reply hint. The token is a memory-only participant-scoped locator, not an authority credential: every `reply` rechecks caller identity, conversation membership, and the live route. The token no longer exists after a broker restart; it must likewise never be retried or reconstructed after route retirement or identity replacement.
|
|
86
92
|
|
|
87
|
-
The public launcher remains host-local. Under
|
|
93
|
+
The public launcher remains host-local. Under allowlisted SSH federation, each broker serves the exact host identity attested by `nodes.json`. `register-codex` infers that host; the alias (and any `--succeeds` alias) must use the same suffix.
|
|
88
94
|
|
|
89
95
|
## Claude Code's own setting: `crossSessionInbound`
|
|
90
96
|
|
|
@@ -97,10 +103,10 @@ that decision. Configure it in Claude Code, not in Embassy.
|
|
|
97
103
|
This is the one prerequisite you must actively toggle, and it is the most
|
|
98
104
|
common first-run failure — because it fails *late*. Quickstart step 3
|
|
99
105
|
(`select-claude`) prints `"accepted":true` whether or not the setting is
|
|
100
|
-
enabled: selection
|
|
101
|
-
|
|
102
|
-
the send reaches the Claude end. If registration and
|
|
103
|
-
but your first `send
|
|
106
|
+
enabled: selection creates no permission edge and never consults Claude's
|
|
107
|
+
native inbound policy. Create an explicit edge with `pair`; the refusal appears
|
|
108
|
+
when the send reaches the Claude end. If registration, selection, and pairing succeeded
|
|
109
|
+
but your first `send` does not arrive, check `crossSessionInbound` on
|
|
104
110
|
the destination session before suspecting the route.
|
|
105
111
|
|
|
106
112
|
## Provider and runtime contract
|
|
@@ -14,24 +14,28 @@ Embassy 主要通过各命令启动时读取的环境变量进行配置。本文
|
|
|
14
14
|
| `EMBASSY_DELIVERY_NOTICES` | `merged` | Claude 发送方通知策略:`merged` 保留停滞通知并把终局诊断合并到原生状态;`verbose` 同时发送两者;`quiet` 不发送任何网关用户帧通知 |
|
|
15
15
|
| `EMBASSY_TRACKING_ENABLED` | `1` | 全局进度监视停用开关;精确设为 `0` 后,`--track`、`--idle-minutes` 与 `TRACK:` 开启请求会被拒绝。活跃监视只存在于内存中,并随代理进程结束;重启后绝不恢复。没有活跃监视时,`DONE:` 不产生作用;`untrack` 不会因开关而被特别拒绝,而是返回 `NOT_FOUND`。取值只能是 `1` 或 `0`,其他值均为配置错误 |
|
|
16
16
|
| `EMBASSY_LOCALE` | `en` | CLI 输出语言,精确取值 `en` 或 `zh-CN`。`--lang` 标志会覆盖当次调用;未设置或为空表示 `en`,其他任何取值都是参数错误 |
|
|
17
|
-
| `EMBASSY_HOSTS` | `this-mac` | 保留的旧版主机列表解析器:取值仍必须是 1 到 32 个唯一小写别名,但不构成联合权限。没有 `nodes.json` 时,无论此值为何,`serve` 都保持仅本地的 `this-mac`。已配置 `nodes.json` 时,显式设置此变量会以 `INVALID_GATEWAY_CONFIGURATION` 关闭失败 |
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
任何与网关通信的 Embassy 客户端调用,都会先读取状态目录和 `nodes.json`,
|
|
19
|
+
再连接控制套接字;请将该目录授予沙箱化 Codex 任务作为可写根目录,或批准
|
|
20
|
+
等效的本地访问,并且不要为了绕过拒绝而迁移状态或启动第二个网关进程。
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
联合权限仅来自 `EMBASSY_STATE_DIR` 中的 `nodes.json`。它必须是当前用户所有的 mode-0600 普通文件,且对象形状必须精确为 `{"version":1,"host":"<lowercase-host>","nodes":["<lowercase-ssh-alias>",...]}`。`host` 指定当前代理;`nodes` 包含 0 到 31 个唯一的 OpenSSH 别名,不得包含 `host`,使联合总主机数不超过 32。该文件是必需的;缺失时 Embassy 会打印精确的 `nodes:[]` 仅本地修复方法并拒绝启动。
|
|
23
|
+
移除节点不会删除其持久镜像;在缺少该节点的配置下重启前,请重置私有状态。
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
请先停止代理并运行:
|
|
25
|
+
### 私有状态重置
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
版本 2.0 只接受全新的架构-4 私有状态;它不会转换或重写旧状态。重置前,
|
|
28
|
+
请使用仍在运行的旧代理的 `status` 与投递查询,确认没有排队、已授权或已
|
|
29
|
+
接受的工作,并且每条投递都已结算。然后:
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
1. 停止代理。
|
|
32
|
+
2. 将 `gateway-state.json` 移到一旁,使旧账本仍可恢复。
|
|
33
|
+
3. 原样保留 `nodes.json`。
|
|
34
|
+
4. 启动版本-2 代理以创建全新状态。
|
|
35
|
+
5. 重新注册路由、选择 Claude 路由,并配对所需边。
|
|
36
|
+
|
|
37
|
+
旧版或未知架构会以 `GATEWAY_STATE_SCHEMA_UNSUPPORTED` 拒绝,且不会修改
|
|
38
|
+
状态文件。不存在转换命令或自动恢复路径。
|
|
35
39
|
|
|
36
40
|
当前台实时仪表盘组件运行时,可直接通过 `http://127.0.0.1:41961/` 访问。端口是单次命令的 CLI 选择,而不是环境设置;如需另一个稳定端口,请向 `embassy dashboard --live` 传入 `--port <n>`,其中整数范围为 1024 到 65535。当前台进程运行时,该 URL 最多支持四个并发实时视图(可分布在窗口、标签页或浏览器中);在其中一个关闭前,第五条流会被拒绝。端口冲突会以 `LIVE_DASHBOARD_PORT_IN_USE` 失败并提示使用 `--port`;Embassy 绝不会回退到临时或其他端口。
|
|
37
41
|
|
|
@@ -58,13 +62,13 @@ embassy convert-state-v2-to-v3
|
|
|
58
62
|
|
|
59
63
|
初始发送方从 CLI 结果获得完整 `conv_` 令牌,接收方则从入站消息的来源封装和回复提示中获得同一个令牌。令牌是内存中的参与方范围定位符,不是权限凭据:每次 `reply` 都会重新检查调用方身份、参与关系和实时路由。代理重启后令牌不再存在;路由失效或身份替换后,也不得重试或重构旧令牌。
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
公开发布的启动器仍绑定本地主机。在 SSH 许可清单联合模式下,每个代理服务 `nodes.json` 已验证的精确主机身份。`register-codex` 会推断该主机;别名及任何 `--succeeds` 别名都必须使用相同后缀。
|
|
62
66
|
|
|
63
67
|
## Claude Code 自身的设置:`crossSessionInbound`
|
|
64
68
|
|
|
65
69
|
`crossSessionInbound` 是 Claude Code 的原生跨会话消息设置:它决定一个 Claude 会话接受、挂起还是拒绝来自其他会话的消息。Embassy 需要在你选择作为 Codex→Claude 目的地的会话上启用此设置,且无法覆盖该决定。请在 Claude Code 中配置它,而不是在 Embassy 中。
|
|
66
70
|
|
|
67
|
-
这是你唯一必须主动开启的前置条件,也是最常见的首次运行故障——因为它**失败得很晚**。快速开始的第 3 步(`select-claude`)无论该设置是否启用都会打印 `"accepted":true
|
|
71
|
+
这是你唯一必须主动开启的前置条件,也是最常见的首次运行故障——因为它**失败得很晚**。快速开始的第 3 步(`select-claude`)无论该设置是否启用都会打印 `"accepted":true`:选择不会创建权限边,也不查询 Claude 的原生入站策略。请使用 `pair` 显式创建权限边;拒绝要到消息抵达 Claude 端时才出现。如果注册、选择与配对都成功,但第一条 `send` 没有送达,请先检查目的地会话上的 `crossSessionInbound`,再去怀疑路由。
|
|
68
72
|
|
|
69
73
|
## 提供方与运行时契约
|
|
70
74
|
|
package/docs/DASHBOARD.md
CHANGED
|
@@ -81,7 +81,7 @@ snapshot via same-origin `fetch`; after each bounded action it reads
|
|
|
81
81
|
a fresh snapshot. A snapshot observation may settle already-due delivery
|
|
82
82
|
deadlines before projecting state.
|
|
83
83
|
|
|
84
|
-
App Server generations, re-anchors, and refreshes do not appear in Activity or grant route authority. The dashboard reports only best-effort runtime facts from the bounded public snapshot. That public snapshot remains schema version 2 even though the private native store is schema
|
|
84
|
+
App Server generations, re-anchors, and refreshes do not appear in Activity or grant route authority. The dashboard reports only best-effort runtime facts from the bounded public snapshot. That public snapshot remains schema version 2 even though the private native store is schema 4. Overview and Routes dynamically enumerate Claude, Codex, DeepSeek, Grok Build, and shell peer even when a route or connector is absent; Deliveries filters by all five source and target providers; Diagnostics shows observed protocol/version metadata, current connector health, and the last safe code. Raw peer tokens and private mailbox receipts never enter the public model. Version metadata never changes route authority.
|
|
85
85
|
|
|
86
86
|
The Diagnostics registry block mirrors optional bounded `registry` observations on the Claude connector row: `entriesScanned`, `parseableRecords`, monotonic `parseableRecordSeenSinceBoot`, bounded per-safe-code `rejected`, and `rejectedCodesOmitted`. It derives “Parseable required fields observed”, “Empty since broker start”, or “No parseable record since broker start”. The last warning says that no Claude registry record with parseable required fields has been observed since broker start and that, if Claude is running, its registry layout may have changed; that possible layout change therefore cannot look like a healthy empty peer list. The dashboard never exposes retained native IDs, operation-local endpoint evidence, raw registry records, or the release-owned offline support matrix, and a later attempt never replays an uncertain message body.
|
|
87
87
|
|
package/docs/DASHBOARD.zh-CN.md
CHANGED
|
@@ -38,7 +38,7 @@ embassy dashboard --live --port 41962
|
|
|
38
38
|
|
|
39
39
|
每个请求都会检查精确的 Host 头。导航 GET 可以缺少 Origin,但每个 POST 都要求精确的 Origin 与 `X-Embassy-Request: 1`。服务器不接受 `OPTIONS`,也不发送 CORS 头。这些检查约束浏览器的跨来源请求,但不认证本地软件。没有通用控制或提供方路由、遥测或外部资源。唯一的变更路由只接受配对、取消配对、刷新发现结果和移除具名 Codex 注册四种精确操作;每次都要求页内明确说明后果并确认,正文上限为 1 KiB,并限制为每分钟六次。移除操作只携带公开的 `codex-*` 别名;代理会删除该注册的同意边,并按其持久化写入阶段结算活动工作。任务 ID 不会进入浏览器契约。浏览器客户端仅在 `localStorage` 中保存一个显示偏好键(当前选项卡与语言)。浏览器不能创建任务、发送、回复、审批、中断、更改设置,也不能调用任意代理或提供方方法。它通过同源 `fetch` 接收快照,并在每次有限操作后重新读取最新快照。一次快照观测可能会在投射状态之前结算已到期的投递截止时间。
|
|
40
40
|
|
|
41
|
-
App Server 代际、重新锚定与刷新不会出现在“活动”中,也不会授予路由权限。仪表盘只报告有界公开快照中的尽力而为运行时事实。即使私有原生存储使用架构
|
|
41
|
+
App Server 代际、重新锚定与刷新不会出现在“活动”中,也不会授予路由权限。仪表盘只报告有界公开快照中的尽力而为运行时事实。即使私有原生存储使用架构 4,公开快照仍保持架构版本 2。“总览”与“路由”会动态枚举 Claude、Codex、DeepSeek、Grok Build 与 Shell 对等方,即使路由或连接器缺失也会显示;“投递”可按五种发送方与接收方提供方筛选;“诊断”显示已观察协议/版本元数据、当前连接器健康度与最近安全代码。原始 peer 令牌与私有邮箱回执绝不会进入公开模型。版本元数据绝不改变路由权限。
|
|
42
42
|
|
|
43
43
|
“诊断”中的注册表区块会镜像 Claude 连接器行上可选的有界 `registry` 观测:`entriesScanned`、`parseableRecords`、单调的 `parseableRecordSeenSinceBoot`、按安全代码分组且有界的 `rejected`,以及 `rejectedCodesOmitted`。它会派生“已观察到可解析必需字段”、“自代理启动以来为空”或“自代理启动以来没有可解析记录”。最后一种警告会说明:自代理启动以来从未观察到带可解析必需字段的 Claude 注册表记录;如果 Claude 正在运行,它的注册表布局可能已更改。因此,这种变化不会伪装成健康的空对等列表。仪表盘绝不暴露保留的原生 ID、逐操作端点证据、原始注册表记录或发布版自有的离线支持矩阵;之后的尝试也绝不重放结果不确定的消息正文。
|
|
44
44
|
|
package/docs/DELIVERY.md
CHANGED
|
@@ -28,7 +28,7 @@ Embassy.
|
|
|
28
28
|
|
|
29
29
|
- **Progress watches are independent evidence.** An opt-in watch may outlive an opener that expired before delivery, so a worker can remain unaware of the original assignment even while thread activity keeps the watch healthy. Owners should check the opener's `delivery-status` separately before assuming the assignment text arrived.
|
|
30
30
|
|
|
31
|
-
- **Restarts keep clean work only.** Queued and reserved bodies persist under bounded retention and may resume once against the same logical route and consent edge. Armed or accepted work at crash settles ambiguous or unconfirmed and is never replayed. Each retained message keeps its opaque delivery token and status in the private
|
|
31
|
+
- **Restarts keep clean work only.** Queued and reserved bodies persist under bounded retention and may resume once against the same logical route and consent edge. Armed or accepted work at crash settles ambiguous or unconfirmed and is never replayed. Each retained message keeps its opaque delivery token and status in the private v4 state, so the sender can continue checking that exact attempt after restart. No pending waiter, shell receipt, reply, or conversation capability survives.
|
|
32
32
|
|
|
33
33
|
Accepted messages are tracked toward terminal delivery while the broker and provider connections remain healthy. The dashboard distinguishes acceptance, progress, delivery, expiry, failure, ambiguity, and abandonment.
|
|
34
34
|
|
|
@@ -76,7 +76,7 @@ classified as an ambiguous write or replayed.
|
|
|
76
76
|
|
|
77
77
|
## Delivery tokens
|
|
78
78
|
|
|
79
|
-
Every accepted `send
|
|
79
|
+
Every accepted `send` and `reply` returns a delivery token: `dlv_` followed by exactly 24 base64url characters. It addresses one bounded private v4 message/status row and is not a provider receipt handle. The token is persisted only in the mode-0600 broker state; it never enters a public snapshot, normal log, provider receipt, or dashboard.
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
82
|
embassy delivery-status --token dlv_<token>
|
package/docs/DELIVERY.zh-CN.md
CHANGED
|
@@ -23,7 +23,7 @@ Embassy 跟踪每条被接受的消息,从 CLI 接受到终态结算的全过
|
|
|
23
23
|
|
|
24
24
|
- **进度监视是独立证据。** 选择启用的监视可能比一条在投递前已过期的开启消息存续更久,因此即使线程活动让监视保持健康,工作方仍可能从未看到原始任务。所有者在假定任务文本已到达之前,应单独检查开启消息的 `delivery-status`。
|
|
25
25
|
|
|
26
|
-
- **重启仅保留干净工作。** 排队或已保留的消息体按有界策略持久化,并可在同一逻辑路由和同意边上恢复一次。崩溃时已授权或已接受的工作结算为 ambiguous 或 unconfirmed,绝不重放。每条仍保留的消息会在私有
|
|
26
|
+
- **重启仅保留干净工作。** 排队或已保留的消息体按有界策略持久化,并可在同一逻辑路由和同意边上恢复一次。崩溃时已授权或已接受的工作结算为 ambiguous 或 unconfirmed,绝不重放。每条仍保留的消息会在私有 v4 状态中保存其不透明投递令牌和状态,因此发送方可在重启后继续检查这一次精确尝试。待处理的等待者、shell 回执、回复或对话能力均不保留。
|
|
27
27
|
|
|
28
28
|
已接受的消息在代理和提供方连接保持健康的情况下被跟踪至终态投递。仪表盘区分接受、进行中、已投递、过期、失败、不明确和废弃等状态。
|
|
29
29
|
|
|
@@ -45,7 +45,7 @@ Embassy 的存储、队列、`STEER:` 分类、去重、速率限制和 16 KiB
|
|
|
45
45
|
|
|
46
46
|
## 投递令牌
|
|
47
47
|
|
|
48
|
-
每次被接受的 `send
|
|
48
|
+
每次被接受的 `send` 和 `reply` 都会返回一个投递令牌:`dlv_` 后跟恰好 24 个 base64url 字符。它指向私有 v4 状态中一条有界的消息/状态记录,不是提供方回执句柄。令牌只持久化在 mode-0600 的代理状态中,绝不会进入公开快照、普通日志、提供方回执或任何仪表盘。
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
embassy delivery-status --token dlv_<token>
|
|
@@ -26,7 +26,7 @@ from a session that already holds a pair edge to the addressed Codex task;
|
|
|
26
26
|
`embassy serve --inbound open` is the explicit opt-out that restores any exact
|
|
27
27
|
compatible live same-UID session as an inbound sender without making it
|
|
28
28
|
outbound-selected. Outbound Codex-to-Claude sends likewise require the pair
|
|
29
|
-
edge
|
|
29
|
+
edge created by explicit `pair`; Claude selection alone creates no edge. It provides
|
|
30
30
|
a single private operational view across the two products without rebuilding
|
|
31
31
|
either agent runtime.
|
|
32
32
|
|
|
@@ -170,7 +170,7 @@ The status below is intentionally narrower than the target architecture.
|
|
|
170
170
|
|
|
171
171
|
| Component | Current evidence |
|
|
172
172
|
| --- | --- |
|
|
173
|
-
| Neutral gateway types,
|
|
173
|
+
| Neutral gateway types, private-v4 metadata store, bounded attempt state machine, queues, dedupe, rate limits, and public projection | **Implemented**, deterministic tests; message bodies persist under bounded retention |
|
|
174
174
|
| Private JSONL control protocol over a controller-owned UDS | **Implemented**, deterministic synthetic tests; no provider connection required |
|
|
175
175
|
| Static metadata-only dashboard renderer and atomic publisher | **Implemented**, deterministic security tests; the static renderer requires no browser or HTTP server |
|
|
176
176
|
| Opt-in live dashboard companion (`embassy dashboard --live`) | **Implemented**, deterministic tests over the stable loopback listener, direct multi-browser access, projection, request guards, and four bounded route actions; it is a separate foreground process, never part of `embassy serve` |
|
|
@@ -181,7 +181,7 @@ The status below is intentionally narrower than the target architecture.
|
|
|
181
181
|
| Local provider adapters and Embassy-node federation | **Implemented**, focused synthetic tests cover Claude discovery, exact Codex ownership, lazy ACP-backed DeepSeek and Grok routes with provider-local degradation and cleanup, plus bounded catalog reconciliation and destination-owned handoff over the fixed attach-only SSH transport |
|
|
182
182
|
| Universal shell peer mailbox | **Implemented**, alias-plus-token same-UID attribution, hash-only durable ownership, bounded long polling, stdout-flush receipts, and restart uncertainty tests; no PID binding, token file, Keychain entry, or daemon |
|
|
183
183
|
| Gateway service composition | **Implemented**, including private control-server startup, synthetic cross-provider selection/dispatch/reply correlation, metadata-only publication, and restart attempt-phase tests |
|
|
184
|
-
| Delivery receipt/status lifecycle | **Implemented**, deterministic synthetic tests cover stable-UUID native receipt re-resolution, the merged/verbose/quiet Claude notice policy, one bounded stall notice with pending age where enabled, opaque private-
|
|
184
|
+
| Delivery receipt/status lifecycle | **Implemented**, deterministic synthetic tests cover stable-UUID native receipt re-resolution, the merged/verbose/quiet Claude notice policy, one bounded stall notice with pending age where enabled, opaque private-v4 correlation handles, restart continuity, the closed status/terminal schema, and one-shot/bounded-wait CLI behavior |
|
|
185
185
|
| Broker-owned cross-provider provenance framing | **Implemented**, deterministic tests cover exact Codex and Claude wire shapes, bounded long-alias attribution, recipient reply hints, reserved-tag neutralization, single wrapping across clean retries, and pre-write failure |
|
|
186
186
|
| Operator/agent client CLI and package binary | **Implemented**, deterministic private-UDS tests cover the closed command family, inherited provider identity, bounded stdin-only bodies, normalized output, and ambiguous no-retry behavior |
|
|
187
187
|
| Repo-shipped cross-provider skill | **Implemented** as a repo-scoped workflow over the client CLI; it is not installed into either provider's global configuration |
|
|
@@ -268,8 +268,11 @@ lookup aliases; it never changes the selected UUID. Immediately before a
|
|
|
268
268
|
Claude-bound write, Embassy performs a fresh bounded registry scan, resolves
|
|
269
269
|
that byte-identical UUID exactly once, and revalidates its current workspace,
|
|
270
270
|
process, socket, and used-artifact generation. An incomplete scan, duplicate
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
UUID, changed UUID, or unsafe current coordinate fails that operation closed.
|
|
272
|
+
A duplicate display name is fenced from listing, selection, and pair creation;
|
|
273
|
+
a pre-bound route retains its identity-pinned binding, and an operator-supplied
|
|
274
|
+
UUID remains the recovery selector. A name alone never restores or retargets a
|
|
275
|
+
durable selection.
|
|
273
276
|
|
|
274
277
|
The dashboard is the single pane for the human. It shows both sanitized
|
|
275
278
|
available/selected Claude aliases and explicitly registered Codex aliases,
|
|
@@ -484,12 +487,12 @@ hatch.
|
|
|
484
487
|
|
|
485
488
|
### Delivery status and bounded waits
|
|
486
489
|
|
|
487
|
-
Every accepted control-plane `
|
|
490
|
+
Every accepted control-plane `send` or `reply`
|
|
488
491
|
result contains both its conversation ID and a fresh opaque delivery
|
|
489
492
|
correlation handle called a delivery token.
|
|
490
493
|
The token has the closed form `dlv_` followed by exactly 24 base64url
|
|
491
494
|
characters (`A-Z`, `a-z`, `0-9`, `_`, or `-`). It addresses one bounded
|
|
492
|
-
private-
|
|
495
|
+
private-v4 message/status row and is not a provider receipt handle or a
|
|
493
496
|
provider native identifier. It is stored only in the mode-0600 broker state
|
|
494
497
|
and never appears in a public snapshot, normal log, provider receipt, or
|
|
495
498
|
dashboard.
|
|
@@ -559,7 +562,7 @@ controller-owned mode-0700 state directory. The socket and state files are
|
|
|
559
562
|
mode 0600. Frames are size-bounded and closed against unknown keys, methods,
|
|
560
563
|
versions, and enum values.
|
|
561
564
|
|
|
562
|
-
The closed version
|
|
565
|
+
The closed version 2 method family is exactly these twenty-one methods:
|
|
563
566
|
|
|
564
567
|
- `health` and `list_snapshot`, a safe public snapshot;
|
|
565
568
|
- `observe_snapshot`, a read-only projection that may settle already-due
|
|
@@ -571,34 +574,34 @@ The closed version 1 method family is exactly these sixteen methods:
|
|
|
571
574
|
available-peer inventory;
|
|
572
575
|
- `pair` and `unpair`, the two-endpoint permission edge;
|
|
573
576
|
- `delivery_status`, a lookup by an opaque correlation handle retained only in
|
|
574
|
-
bounded private
|
|
577
|
+
bounded private v4 state;
|
|
575
578
|
- `untrack`, which closes one active progress watch by conversation token;
|
|
576
|
-
- `
|
|
577
|
-
- `reply`, the correlated reply operation;
|
|
578
|
-
- `refresh_dashboard`, which refreshes provider discovery and republishes
|
|
579
|
+
- `send`, whose direction is derived from the resolved endpoint providers;
|
|
580
|
+
- `reply`, the correlated reply operation;
|
|
581
|
+
- `refresh_dashboard`, which refreshes provider discovery and republishes;
|
|
582
|
+
- `peer_catalog` and `peer_handoff`, the private federation catalog and
|
|
583
|
+
destination-owned handoff operations; and
|
|
584
|
+
- `register_peer`, `unregister_peer`, `await_peer`, and `peer_receipt`, the
|
|
585
|
+
shell-peer registration, mailbox, and flush-before-receipt operations.
|
|
579
586
|
|
|
580
587
|
The live dashboard companion calls `observe_snapshot` for every read; its
|
|
581
588
|
mutation route additionally calls `pair`, `unpair`,
|
|
582
589
|
`remove_codex_registration`, and `refresh_dashboard`, and nothing else.
|
|
583
590
|
|
|
584
591
|
The installed binary is `embassy`, and it is the only installed binary. Its
|
|
585
|
-
|
|
586
|
-
`serve`, `health`, `status`, `delivery-status`, `wait-delivery`, `untrack`,
|
|
592
|
+
twenty-one implemented commands are
|
|
593
|
+
`serve`, `health`, `status`, `doctor`, `delivery-status`, `wait-delivery`, `untrack`,
|
|
587
594
|
`refresh-dashboard`, `dashboard`, `register-codex`, `unregister-codex`,
|
|
588
|
-
`select-claude`, `unselect-claude`, `pair`, `unpair`, `send
|
|
589
|
-
`
|
|
595
|
+
`select-claude`, `unselect-claude`, `pair`, `unpair`, `send`,
|
|
596
|
+
`reply`, `register-peer`, `unregister-peer`, `await`, and
|
|
597
|
+
`peer-stdio`. `dashboard` requires `--live` and accepts an
|
|
590
598
|
optional `--lang en|zh-CN` and `--port <n>`; it starts the companion process
|
|
591
599
|
rather than issuing a single control request. Message bodies are non-empty
|
|
592
600
|
UTF-8 from standard input only, with a 16 KiB ceiling; they are never accepted
|
|
593
601
|
in an argument or file. The client emits one bounded normalized JSON line and
|
|
594
602
|
never returns a thread ID, provider-native ID, path, address, or message body.
|
|
595
603
|
These commands require the foreground broker, except that `serve` starts it in
|
|
596
|
-
the current terminal
|
|
597
|
-
upgrade. The converter uses only the normally resolved state directory,
|
|
598
|
-
requires the controller lock, installs strict native schema 3 through an
|
|
599
|
-
fsynced atomic replacement, and reports only success plus the verified v2
|
|
600
|
-
backup basename. It starts no provider, helper, listener, discovery, or control
|
|
601
|
-
socket. The launcher never daemonizes itself.
|
|
604
|
+
the current terminal. The launcher never daemonizes itself.
|
|
602
605
|
|
|
603
606
|
`register-codex --alias <new> --succeeds <current>` is one atomic logical-route
|
|
604
607
|
transaction. It verifies the inherited identity of the replacement task,
|
|
@@ -609,28 +612,26 @@ manual-recovery state.
|
|
|
609
612
|
|
|
610
613
|
`select-claude --alias <current-name@host>` and
|
|
611
614
|
`select-claude --session <uuid>` select the same logical session.
|
|
612
|
-
`send
|
|
615
|
+
`send --to` accepts either form only after explicit selection. UUID
|
|
613
616
|
input is normalized to lowercase. No command returns the
|
|
614
617
|
UUID, and no historical name remains routable after a rename.
|
|
615
618
|
|
|
616
|
-
Provider-authorized
|
|
619
|
+
Provider-authorized registration, send, and reply operations require one exclusive inherited principal.
|
|
617
620
|
Codex registration, unregister, and Codex-to-Claude send require only a valid
|
|
618
621
|
`CODEX_THREAD_ID`; they fail if a non-empty Claude messaging socket is also
|
|
619
622
|
inherited. Claude-to-Codex send requires only the raw inherited Claude socket
|
|
620
623
|
path and fails if a non-empty Codex thread ID is also present. `reply` likewise
|
|
621
|
-
fails with both identities or neither.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
dashboard refresh, live dashboard, untrack, and serve commands are the ones
|
|
633
|
-
that genuinely ignore provider identities.
|
|
624
|
+
fails with both identities or neither.
|
|
625
|
+
|
|
626
|
+
`pair`, `unpair`, `select-claude`, and `unselect-claude` are control-plane
|
|
627
|
+
operations authorized by access to the same-UID private socket; they do not
|
|
628
|
+
attest inherited provider identity. Pair and unpair mutate only the exact two
|
|
629
|
+
named endpoints, while selection installs or removes one Claude route and
|
|
630
|
+
creates no consent edge. Paired mode still rechecks exact edge membership at
|
|
631
|
+
delivery. Removing the selected route also removes its incident consent edges
|
|
632
|
+
and settles their in-flight work from the durable attempt phase. Agents are
|
|
633
|
+
instructed to create or remove only user-chosen edges; that is an operating
|
|
634
|
+
norm, not an additional gateway identity check.
|
|
634
635
|
|
|
635
636
|
The foreground command is:
|
|
636
637
|
|
|
@@ -668,7 +669,7 @@ does not publish candidates, select or connect to a peer, write a provider
|
|
|
668
669
|
socket, request provider history, start a model turn, or contact a remote host.
|
|
669
670
|
Validated target bindings may retain private native and socket-derived evidence
|
|
670
671
|
memory-only until rescan or close, but none enters public state or persistence.
|
|
671
|
-
Its ready result reports local host `
|
|
672
|
+
Its ready result reports the exact local host from `nodes.json`, dashboard filename
|
|
672
673
|
`gateway-dashboard.html`, and `codexMode: "native_messaging"` without exposing
|
|
673
674
|
paths.
|
|
674
675
|
|
|
@@ -682,7 +683,7 @@ thread/session generation, source alias, bounds, and conversation state.
|
|
|
682
683
|
|
|
683
684
|
### Progress watches
|
|
684
685
|
|
|
685
|
-
`send
|
|
686
|
+
`send` and `reply` each accept an opt-in `--track`
|
|
686
687
|
flag that opens one progress watch over the resulting conversation, plus an
|
|
687
688
|
optional `--idle-minutes <n>` that sets how long the watched thread may sit idle
|
|
688
689
|
before each bounded liveness nudge. If the watch ultimately times out, Embassy
|
|
@@ -705,17 +706,7 @@ may outlive an opener whose own delivery expired, so check the opener's
|
|
|
705
706
|
|
|
706
707
|
## Codex connectors and remote hosts
|
|
707
708
|
|
|
708
|
-
|
|
709
|
-
connector because each host has its own App Server and native state:
|
|
710
|
-
|
|
711
|
-
- `this-mac`: the managed local App Server shared with Desktop;
|
|
712
|
-
- `build-mac`: a host-local remote App Server reached through an attach-only SSH
|
|
713
|
-
proxy; and
|
|
714
|
-
- `lab-mac.example`: the same design, still unprobed and disabled by default.
|
|
715
|
-
|
|
716
|
-
The shipped foreground launcher accepts only `this-mac`; it rejects any remote
|
|
717
|
-
host configuration. The two SSH connectors above remain planned rather than
|
|
718
|
-
runnable v1 routes.
|
|
709
|
+
Each broker's mandatory `nodes.json` gives its local connector an explicit host identity; `this-mac` has no reserved meaning. Configured peers exchange only body-free local catalogs and destination-owned handoffs over fixed SSH.
|
|
719
710
|
|
|
720
711
|
The local connector resolves the managed standalone Codex release by exact
|
|
721
712
|
owned path; it does not use `PATH`. That installation is separate from
|
|
@@ -927,7 +918,7 @@ the static pair, which is always written in both languages.
|
|
|
927
918
|
|
|
928
919
|
The private store may retain:
|
|
929
920
|
|
|
930
|
-
- schema-
|
|
921
|
+
- schema-4 logical registrations with aliases, registration IDs, and exact
|
|
931
922
|
provider-native route handles inside the closed private binding schema;
|
|
932
923
|
- consent edges tied to exact registration IDs, so alias reuse cannot inherit
|
|
933
924
|
permission;
|
|
@@ -951,13 +942,12 @@ may resume once only after their exact registration and consent authority is
|
|
|
951
942
|
rechecked; armed and accepted work settles without replay. Callback, native
|
|
952
943
|
receipt, conversation, and reply capabilities are not reconstructed.
|
|
953
944
|
|
|
954
|
-
Private schema
|
|
955
|
-
snapshot deliberately remains schema version 2.
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
ordinary strict corrupt-state error.
|
|
945
|
+
Private schema 4 is the binary's only native store format; the bounded public
|
|
946
|
+
snapshot deliberately remains schema version 2. The runtime performs no
|
|
947
|
+
migration or best-effort rewrite. An old or unknown private schema refuses with
|
|
948
|
+
`GATEWAY_STATE_SCHEMA_UNSUPPORTED` without mutating the state file; the operator
|
|
949
|
+
must follow the reset-only runbook in `docs/CONFIGURATION.md`. A malformed
|
|
950
|
+
schema-4 document produces the ordinary strict corrupt-state error.
|
|
961
951
|
|
|
962
952
|
## Minimum filesystem and process access
|
|
963
953
|
|
package/package.json
CHANGED
|
@@ -1,35 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: embassy-peer
|
|
3
|
-
description: Operate Embassy through current name@host or Claude session-UUID selectors and universal peer-* shell routes. Use when an agent needs to register for inbound messaging, await shell-peer mail, list available peers, refresh the operator's static dashboard, manage a
|
|
3
|
+
description: Operate Embassy through current name@host or Claude session-UUID selectors and universal peer-* shell routes. Use when an agent needs to register for inbound messaging, await shell-peer mail, list available peers, refresh the operator's static dashboard, manage a user-chosen pair, send or reply under its own principal, or unregister without exposing provider credentials, socket paths, or message bodies.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Embassy Peer Gateway
|
|
7
7
|
|
|
8
8
|
Use only the installed `embassy` CLI. Treat it as the sole facade over the private, local Embassy control socket. Keep this skill repo-scoped; do not install, copy, or modify provider configuration.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Registration, send, reply, await, receipt, and unregister operations require the exact principal accepted by that command: inherited Codex identity, inherited Claude identity, or a shell-peer alias plus token. Stop on a missing or conflicting required principal; never choose one on the caller's behalf. `pair`, `unpair`, `select-claude`, and `unselect-claude` are same-UID control-plane operations authorized by the private control socket, not by inherited provider identity. Agents remain norm-bound to create or remove only the exact edges the user chose; paired-mode membership is rechecked at delivery.
|
|
11
11
|
|
|
12
|
-
If `CALLER_IDENTITY_CONFLICT` reports
|
|
12
|
+
If `CALLER_IDENTITY_CONFLICT` reports both inherited identities, strip only the unwanted identity at the call site: use `env -u CLAUDE_CODE_MESSAGING_SOCKET embassy …` for a Codex-side call, or `env -u CODEX_THREAD_ID embassy …` for a Claude-side call. Never inspect, print, clear, or copy either inherited value. Without the dual-identity hint, report only the generic fail-closed result; the caller may simply be the wrong principal.
|
|
13
13
|
|
|
14
14
|
## Select a peer
|
|
15
15
|
|
|
16
|
-
Address a Claude session by its latest `name@host` or by a user-supplied native session UUID. The UUID is the stable identity; the name is only the current live index. The gateway stores no historical names, so an old name stops resolving immediately after a rename.
|
|
16
|
+
Address a Claude session by its latest `name@host` or by a user-supplied native session UUID. The UUID is the stable identity; the name is only the current live index. The gateway stores no historical names, so an old name stops resolving immediately after a rename. The mandatory private `nodes.json` names the local host; configured allowlisted Embassy nodes exchange bounded public route catalogs and destination-owned handoffs over fixed attach-only SSH. Ask the user to choose a selector when it is ambiguous.
|
|
17
17
|
|
|
18
18
|
Run `embassy status` to read the current snapshot. Run `embassy refresh-dashboard` when passive live discovery is authorized. Claude Code's native `ListAgents` includes genuine Claude sessions plus each explicitly advertised `codex-*` Embassy peer.
|
|
19
19
|
|
|
20
|
-
Read the status snapshot's `availablePeers` as sanitized current-name candidates. Native records carrying Embassy's supported explicit versioned advertisement marker are excluded because they are not Claude destinations; a genuine unmarked Claude session remains visible even when its name starts with `codex-*`. A send never pairs with a Claude session automatically.
|
|
20
|
+
Read the status snapshot's `availablePeers` as sanitized current-name candidates. Native records carrying Embassy's supported explicit versioned advertisement marker are excluded because they are not Claude destinations; a genuine unmarked Claude session remains visible even when its name starts with `codex-*`. A send never pairs with a Claude session automatically. Select the Claude route, then create the exact user-chosen edge with `pair` before sending; an unpaired destination is not routable.
|
|
21
21
|
|
|
22
22
|
Accept a Claude session UUID only when the user supplies it or it is already part of the current task context. Never discover one by scanning history or configuration, and never infer a peer from a thread ID, process ID, working directory, socket path, or title.
|
|
23
23
|
|
|
24
24
|
## Check the gateway
|
|
25
25
|
|
|
26
|
+
Before any Embassy client call that talks to the broker, the CLI reads the state
|
|
27
|
+
directory and `nodes.json`, then connects to the private control socket. Grant a
|
|
28
|
+
sandboxed Codex task that directory as a writable root, or approve equivalent
|
|
29
|
+
local access. Do not relocate state or start a second broker to work around a denial.
|
|
30
|
+
|
|
26
31
|
Run this before a state-changing operation:
|
|
27
32
|
|
|
28
33
|
```sh
|
|
29
34
|
embassy health
|
|
30
35
|
```
|
|
31
36
|
|
|
32
|
-
If Embassy is unavailable, stop and report that it must be started in a trusted local terminal with `embassy serve`. `GATEWAY_INSTANCE_IN_USE` means an Embassy or recognized legacy lock already owns this login account; stop that foreground process rather than changing `EMBASSY_STATE_DIR`. If no legacy process remains, the operator may remove only the exact stale legacy controller lock and retry. Do not launch a background copy, retry in a loop, discover sockets, or fall back to a provider CLI.
|
|
37
|
+
If Embassy is unavailable, follow any accompanying denied-access or unsafe-path guidance first. Only when no access or unsafe-path condition is reported, stop and report that it must be started in a trusted local terminal with `embassy serve`. `GATEWAY_INSTANCE_IN_USE` means an Embassy or recognized legacy lock already owns this login account; stop that foreground process rather than changing `EMBASSY_STATE_DIR`. If no legacy process remains, the operator may remove only the exact stale legacy controller lock and retry. Do not launch a background copy, retry in a loop, discover sockets, or fall back to a provider CLI.
|
|
33
38
|
|
|
34
39
|
Embassy presents Claude, Codex, DeepSeek, Grok, and shell peers as first-class providers. Runtime status is best-effort: use observation freshness, connector health, observed metadata, and the last safe code to explain what is available now. Provider versions are diagnostic metadata, not routing authority; the release-owned offline support matrix is the record of tested artifacts, capabilities, limitations, and test dates. There is no agent or operator compatibility action. Report a degraded surface and stop rather than sending a test message or trying to override a failed operation.
|
|
35
40
|
|
|
@@ -83,13 +88,13 @@ Create one explicit cross-provider edge by naming both ends. Each endpoint must
|
|
|
83
88
|
embassy pair --from codex-reviewer@this-mac --to advisor@this-mac
|
|
84
89
|
```
|
|
85
90
|
|
|
86
|
-
Pairs are additive and bounded; many edges may coexist, and `pair` never retires another edge.
|
|
91
|
+
Pairs are additive and bounded; many edges may coexist, and `pair` never retires another edge. The same-UID private control socket authorizes this control-plane mutation; Embassy does not attest an inherited provider identity for pair or unpair. Create or remove only the exact user-chosen edge. Remove it by naming both endpoints:
|
|
87
92
|
|
|
88
93
|
```sh
|
|
89
94
|
embassy unpair --from codex-reviewer@this-mac --to advisor@this-mac
|
|
90
95
|
```
|
|
91
96
|
|
|
92
|
-
|
|
97
|
+
Claude selection is a separate operator control and creates no permission edge:
|
|
93
98
|
|
|
94
99
|
```sh
|
|
95
100
|
embassy select-claude --alias advisor@this-mac
|
|
@@ -101,17 +106,17 @@ Or address the same logical session directly by UUID:
|
|
|
101
106
|
embassy select-claude --session 123e4567-e89b-42d3-a456-426614174000
|
|
102
107
|
```
|
|
103
108
|
|
|
104
|
-
Remove the
|
|
109
|
+
Remove the selected Claude route by naming that endpoint:
|
|
105
110
|
|
|
106
111
|
```sh
|
|
107
112
|
embassy unselect-claude --alias advisor@this-mac
|
|
108
113
|
```
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
After selection, use explicit `pair --from <alias> --to <alias>` before sending; never infer or guess an edge on the user's behalf.
|
|
111
116
|
|
|
112
117
|
Let the gateway resolve either selector against the current genuine Claude discovery snapshot. It refreshes process and socket coordinates by UUID; those transport details are never caller inputs. If discovery is ambiguous, incompatible, or unavailable, stop on the result.
|
|
113
118
|
|
|
114
|
-
If the
|
|
119
|
+
If the selected session is offline or was renamed while Embassy was stopped, the user may recover selection by supplying its UUID with `select-claude --session`. UUID recovery applies only to selection; `pair` still requires two aliases. `unselect-claude` removes the selected route, removes its incident consent edges, and settles their in-flight work from the durable attempt phase. These controls do not start, interrupt, configure, or terminate Claude Code.
|
|
115
120
|
|
|
116
121
|
## Register a Codex task
|
|
117
122
|
|
|
@@ -160,7 +165,7 @@ Pass a non-empty UTF-8 body through standard input. Never place message text in
|
|
|
160
165
|
From a registered Codex task to a paired Claude session:
|
|
161
166
|
|
|
162
167
|
```sh
|
|
163
|
-
embassy send
|
|
168
|
+
embassy send \
|
|
164
169
|
--from codex-reviewer@this-mac \
|
|
165
170
|
--to advisor@this-mac <<'GATEWAY_MESSAGE'
|
|
166
171
|
Please review the current approach and note the main risk in your own session.
|
|
@@ -176,7 +181,7 @@ The foreground launcher supports native bidirectional messaging for each explici
|
|
|
176
181
|
|
|
177
182
|
Direction determines timing. Once routing and pre-write checks pass, every Claude-bound send or correlated reply writes immediately to Claude's native mailbox regardless of its observed busy or idle state. Do not wait for Claude to become idle or report its busy state as a queue reason. `transport_written` is the terminal `delivered` boundary for that direction and means mailbox write, not read or consumption. Codex-bound ordinary work remains idle/turn-boundary gated; only the exact `STEER:` behavior below may target the active turn's next tool-call boundary.
|
|
178
183
|
|
|
179
|
-
An accepted send returns a public conversation token and a fresh delivery token. The conversation token and reply capability are memory-only. The delivery token is an opaque correlation handle, exactly `dlv_` plus 24 base64url characters, retained only with its bounded private
|
|
184
|
+
An accepted send returns a public conversation token and a fresh delivery token. The conversation token and reply capability are memory-only. The delivery token is an opaque correlation handle, exactly `dlv_` plus 24 base64url characters, retained only with its bounded private v4 message row. Use the exact returned values only for their intended CLI calls; do not construct, shorten, log, persist yourself, or place either token in an agent-created file.
|
|
180
185
|
|
|
181
186
|
Use exactly one send for one user-authorized message. A send never selects a Claude session automatically. Do not automatically retry, fan out, hand-roll a poll loop, or fall back to Claude Code's native `SendMessage`.
|
|
182
187
|
|
|
@@ -222,7 +227,7 @@ embassy wait-delivery --token dlv_0123456789abcdefghijklmn
|
|
|
222
227
|
|
|
223
228
|
It checks every 250 ms and emits only a terminal result. It stops at the delivery deadline plus 3 seconds; an unknown token fails immediately. Exit `0` means `delivered`; every other terminal state (`unconfirmed`, `expired`, `failed`, `ambiguous`, or `cancelled`) preserves its exact JSON result and uses the shared delivery-failure exit `6`. An unknown token exits `3`. A local waiter timeout exits `4`, is not a terminal result, and is not permission to resend. A terminal result closes only that delivery attempt: `delivered` does not promise a reply, and `unconfirmed` or `ambiguous` must never be retried automatically.
|
|
224
229
|
|
|
225
|
-
The private
|
|
230
|
+
The private v4 message ledger is bounded. Under pressure, its oldest terminal row may be evicted while active `queued` or `stalled` rows are retained. A token absent from bounded retention returns `{"found":false}`.
|
|
226
231
|
|
|
227
232
|
## Interpret queue state
|
|
228
233
|
|
|
@@ -230,7 +235,7 @@ Treat `accepted` as gateway ownership, not proof that the peer read or answered
|
|
|
230
235
|
|
|
231
236
|
For native Claude-to-Codex ingress, Embassy first attempts immediate dispatch. A terminal result observed before the one-second prompt boundary produces only its terminal acknowledgement; native `held` is sent only when the body truly remains queued or dispatch is still nonterminal at that boundary, followed later by the terminal acknowledgement. Claude's rendered “approved and released” notice means only that the paired-consent gateway accepted and released the body to the recipient queue — released is not read, and no human approval is implied. The default `merged` notice policy separately sends at most one nonterminal stall user frame exactly at `floor(messageDeadlineMs / 2)`, containing only a bounded pending age and allowlisted reason. The operator may choose `verbose` to retain the additional terminal diagnostic user frame or `quiet` to suppress gateway-authored user-frame notices; native status and dashboard truth do not change. Codex-bound ordinary work queues while the Codex task is active or temporarily unavailable. Only when the user explicitly asks to steer the active Codex turn may a Claude sender put the exact prefix `STEER:` at the beginning of the body. Embassy uses the exact accepted operation's same-session capability at the next tool-call boundary, never mid-generation or by interruption. Clean boundary refusal returns it to the normal queue; the cap is three steers per exact active operation. Embassy never calls `turn/interrupt` and never retries an ambiguous write.
|
|
232
237
|
|
|
233
|
-
Do not synthesize `STEER:`, use it from Codex to Claude, approve permissions, widen tools, alter inbound-message policy, or interrupt a turn to force delivery. Report `held`, refused, incompatible, full, expired, unavailable, or `STEER_QUEUE_SUPERSEDED` outcomes or safe error codes without treating them as additional `delivery-status` states and without retrying. Native receipt settlement follows the originating Claude session's stable UUID and revalidates its current endpoint before every stall or terminal write; names, PIDs, and sockets are not receipt identity. Ordinary process/socket rotation for the same Claude UUID is refreshed for that write. After a gateway restart, queued or reserved messages and their delivery tokens/status remain inspectable in the bounded private
|
|
238
|
+
Do not synthesize `STEER:`, use it from Codex to Claude, approve permissions, widen tools, alter inbound-message policy, or interrupt a turn to force delivery. Report `held`, refused, incompatible, full, expired, unavailable, or `STEER_QUEUE_SUPERSEDED` outcomes or safe error codes without treating them as additional `delivery-status` states and without retrying. Native receipt settlement follows the originating Claude session's stable UUID and revalidates its current endpoint before every stall or terminal write; names, PIDs, and sockets are not receipt identity. Ordinary process/socket rotation for the same Claude UUID is refreshed for that write. After a gateway restart, queued or reserved messages and their delivery tokens/status remain inspectable in the bounded private v4 ledger and may resume once within their deadline and attempt budget against the same exact route and consent edge. Armed work settles `ambiguous`; accepted work settles `unconfirmed`; neither is replayed. Conversations, reply/native capabilities, raw provider frames, callbacks, pending replies, and socket paths remain memory-only. Best-effort observation may refresh what status displays, but it never authorizes or gates delivery.
|
|
234
239
|
|
|
235
240
|
## Preserve the boundary
|
|
236
241
|
|