本方案交付目标
从对话发起、查询、续聊、取消任务
任务落到明确指定的 Linux 与工作区;同一条 Codex 会话可继续;断线不会静默重跑。
先划清产品边界
原生 Computers 接入仍待单独确认
公开资料和现有验证不足以证明任意 Linux 守护进程都能注册为 dot 的原生电脑。这里不依赖这个前提。
点击知识块看内容,点击连线看依据。没有关系的块也保留。
本方案交付目标
任务落到明确指定的 Linux 与工作区;同一条 Codex 会话可继续;断线不会静默重跑。
先划清产品边界
公开资料和现有验证不足以证明任意 Linux 守护进程都能注册为 dot 的原生电脑。这里不依赖这个前提。
**有一条基于公开接口的可行工程路线,仍需在真实 dot 上完成接入验证。**让 dot 使用一个经用户授权的私有插件工具,再由工具服务转交给 Linux 上的 Codex。实际可用性还取决于账号的插件能力、工作区政策、OAuth 连接和所选 Codex 版本。
01 / 原生能力
产品原生连接、任务与浏览器能力各有环境和权限边界。不要把“可运行 Linux 云任务”推成“任意 Linux 可自行注册”。
02 / 本方案
通过公开插件接入面提供五个有限任务工具。电脑不会因此自动出现在原生 Computers 列表中。
03 / 待验收
只有 dot 看到工具、完成授权、任务确实在指定 Linux 执行、结果关联返回,才能宣布这条桥接成功。
本文没有安装 daemon、创建机器凭据、修改 Fleet / Cloudflare 配置或开通长期访问。文中的域名、ID、路径、工具契约均为示例或拟定设计;不是现成可调用的服务,也不是一个已实现的 A2A 标准接口。
外部只需要一个公开可达、受鉴权保护的 HTTPS 网关。Linux 在 NAT 后面也可以主动连出;网关在这条已建立的双向连接内下发任务。
CONTROL PLANE箭头表示连接发起方向
OPENAI HOSTdot / 插件服务
用户授权
调用 MCP 工具
查询任务结果
→HTTPS
OAuth
PUBLIC GATEWAY私有任务网关
/mcp/codex
/agent/codex
鉴权 · 路由 · 状态
←出站 WSS
机器认证
YOUR LINUXCodex Agent
任务台账与工作区
本地 stdio 进程
Codex app-server
执行方向
dot → 网关 → 既有 WSS → Linux → 本地 Codex
结果方向
Codex → Linux → 网关 → 工具查询 / 授权事件
身份以 OAuth 和机器凭据校验。网关地址稳定即可;不要把来源 IP 当作用户身份或唯一安全边界。
本方案不向公网暴露 app-server,也不要求公网 SSH。Codex 的模型推理另有独立的认证出站连接。
dot 调用 start_codex_job
网关由 OAuth 主体确定 owner,校验 machine_id、workspace_id 与授权范围,保存幂等记录并立即返回 job_id。
网关持久化后发出调度消息
消息带 job_id、dispatch_id、请求摘要与控制版本;机器离线时先保留 queued,不伪造正在运行。
Linux 先记账,再启动 Codex
本地 SQLite 持久化接收记录,校验工作区映射与权限,确认同一 dispatch 没有启动过,再创建或恢复会话。
事件与日志按序回传
每条记录携带 job_id、attempt、event_seq;网关先落盘再 ACK。重发可去重,断线后从最后确认位置补传。
dot 取得最终结果
MVP 使用 get_codex_job 与分页日志。任务结束后返回摘要、明确终态、Codex thread / turn 关联及允许访问的产物信息。
示例地址:https://codex-gateway.example.com/mcp/codex 与 wss://codex-gateway.example.com/agent/codex。它们只说明路由设计。
| 组件 | 负责什么 | 关键边界 |
|---|---|---|
| Worker:OAuth + MCP | 协议握手、工具 schema、身份校验、输入限制、授权错误、速率限制 | 不能相信调用方提交的 owner;从已验证的 token 派生 |
| Durable Object:每 owner / machine | 当前 WSS、机器租约、任务状态、控制命令排序、ACK 与待发消息 | 不能仅靠内存;连接重建必须从持久化记录恢复 |
| Linux daemon | 工作区白名单、本地任务台账、子进程管理、协议适配、日志脱敏 | 普通专用用户运行;不提供任意 shell、路径或环境变量工具 |
| 存储:DO SQLite + 可选 R2 | 任务、事件、审计、幂等键;大产物按 owner / job 隔离存放 | 首版可不接 R2,先返回有上限的文本;产物不能默认公开 |
机器注册与 owner 索引可单独使用一个持久化目录服务;规模增长后再考虑 D1 索引。**DO 是协调点,本地台账是执行事实来源。**两边都保留关键信息,才能在网络故障后对账。
Cloudflare Durable Objects 的 WebSocket API 可用于维持入站连接;选择 hibernation 方案时,要把恢复所需信息放进持久化存储或连接附件,不能依赖实例内存。具体兼容性与配额按最终部署环境验证。Cloudflare WebSocket 文档
如果已有 Fleet 或 Cloudflare 基础设施,可作为隔离模块的候选宿主。复用前先审查权限、路由与数据边界;这里没有读取或改动任何真实机群配置。
以下五个名字、字段和返回值是本方案拟定的应用层契约,不是官方既有 Codex API。示例用 tool + arguments 表达调用意图;实际 MCP 外层封装由兼容所选协议版本的 SDK 实现。
所有工具都要求 OAuth。查询也必须校验 job 所属 owner。首版不允许工具传入任意路径、shell 命令、环境变量或原始 app-server RPC。
WRITEstart_codex_job发起任务
创建任务并快速返回 job_id。幂等键作用域为 owner + 工具 + client_request_id;同键同摘要返回已有任务,同键不同摘要返回冲突。instruction 设长度与速率上限。
拟定调用参数
{
"tool": "start_codex_job",
"arguments": {
"machine_id": "linux-dev-01",
"workspace_id": "demo-repo",
"instruction": "只读检查当前工作区的项目结构,给出摘要,不修改文件。",
"client_request_id": "request-example-001"
}
}拟定返回值
{
"job_id": "job_example_01",
"state": "queued",
"revision": 1,
"machine_id": "linux-dev-01",
"workspace_id": "demo-repo",
"deduplicated": false,
"poll_after_ms": 3000
}READget_codex_job读取状态
只读取已持久化状态,不触发重跑。包含 blocked_reason、终态错误与最新 revision。响应中的 poll_after_ms(非终态时)建议下次检查时间,不保证 dot 自动持续轮询。
拟定调用参数
{
"tool": "get_codex_job",
"arguments": {
"job_id": "job_example_01"
}
}拟定返回值
{
"job_id": "job_example_01",
"state": "succeeded",
"revision": 5,
"latest_event_seq": 28,
"result": {
"summary": "已完成工作区只读检查。",
"artifacts": []
},
"codex": {
"thread_id": "thr_example_01",
"turn_id": "turn_example_01"
},
"error": null,
"blocked_reason": null
}READget_codex_logs分页读取日志
limit 建议范围 1–200;cursor 必须是不透明、与 owner / job 绑定的分页位置。输出长度有限,脱敏并标记截断;禁止把完整环境或凭据转入日志。
拟定调用参数
{
"tool": "get_codex_logs",
"arguments": {
"job_id": "job_example_01",
"cursor": null,
"limit": 100
}
}拟定返回值
{
"job_id": "job_example_01",
"entries": [
{
"event_seq": 28,
"kind": "completion",
"text": "只读检查完成",
"redacted": true
}
],
"next_cursor": null,
"has_more": false,
"truncated": false
}WRITEcontinue_codex_job继续同一会话
仅允许已完成且可继续的 job。使用最新 expected_revision 做并发比较;持久化新的 continuation,恢复原 thread 后创建新 turn。运行中或 unknown 返回冲突,不隐式开第二个并行 turn。续聊不等于批准挂起的权限请求。
拟定调用参数
{
"tool": "continue_codex_job",
"arguments": {
"job_id": "job_example_01",
"instruction": "沿用这次会话,解释测试入口;仍然只读。",
"client_request_id": "request-example-002",
"expected_revision": 5
}
}拟定返回值
{
"job_id": "job_example_01",
"state": "queued",
"revision": 6,
"continuation_index": 1,
"codex_thread_id": "thr_example_01",
"deduplicated": false
}WRITEcancel_codex_job请求停止
queued 可在未派发时确认取消;运行中只先返回 cancel_requested。收到对应 turn 的中断终态后才标 cancelled;若任务已先完成,返回真实完成状态。停止不自动回滚已写文件。
拟定调用参数
{
"tool": "cancel_codex_job",
"arguments": {
"job_id": "job_example_01",
"client_request_id": "request-example-003"
}
}拟定返回值
{
"job_id": "job_example_01",
"state": "cancel_requested",
"revision": 8,
"confirmed_stopped": false
}统一错误建议:UNAUTHENTICATED、FORBIDDEN、INVALID_WORKSPACE、IDEMPOTENCY_CONFLICT、REVISION_CONFLICT、JOB_BUSY、RATE_LIMITED、RECONCILIATION_REQUIRED。错误码是应用约定,映射到 MCP 错误时不要冒充标准协议代码。
为覆盖流式进度、审批、会话续聊与取消,详细适配可使用 app-server;如果只做短批处理或 CI,应先评估更简单的 Codex SDK。app-server 与相关传输仍有实验性质:固定版本、生成对应 schema 并做兼容测试后再上线。App Server 文档 · Codex SDK 文档
daemon 通过子进程的 stdin / stdout 通信。本地线协议是逐行 JSON;app-server 的 JSON-RPC 消息省略 jsonrpc 字段。下面只是初始化与生命周期骨架;权限设置必须由已审查的本地配置和沙箱强制执行。
本地进程启动示例 · 不是安装命令
codex app-server --listen stdio://协议顺序示例 · 每个请求先等响应,再发送依赖消息
{"id":1,"method":"initialize","params":{"clientInfo":{"name":"linux_codex_bridge","version":"0.1.0"}}}
{"method":"initialized","params":{}}
{"id":2,"method":"thread/start","params":{"cwd":"/srv/codex-workspaces/demo"}}
// 从 id=2 的 result.thread.id 取真实 ID,再发送:
{"id":3,"method":"turn/start","params":{"threadId":"thr_example_01","input":[{"type":"text","text":"只读总结当前项目"}]}}
// 已有会话恢复后,再调用 turn/start:
{"id":4,"method":"thread/resume","params":{"threadId":"thr_example_01"}}
// 取消必须同时关联真实 thread 和正在运行的 turn:
{"id":5,"method":"turn/interrupt","params":{"threadId":"thr_example_01","turnId":"turn_example_01"}}代码中的注释用于阅读,不能写入 JSONL 管道。真实 thread_id / turn_id 必须从响应读取并先持久化;示例 ID 不能直接执行。
持续读取增量与生命周期消息,以对应 turn/completed 的最终状态映射成功、失败或中断。单次工具响应成功、stdout 暂时安静,都不等于任务完成。
捕获服务端审批请求,记录 blocked 与必要上下文,等待受控审批路径。没有审批实现时保持阻塞或安全拒绝,不能自动回答同意。
“只读”提示词不是安全沙箱。只读阶段必须使用经该版本验证的权限配置,加上容器 / OS 文件系统与网络隔离;写入阶段才显式开放指定工作区。禁止 full-access、自动批准或 root 运行。
queued_→dispatching→running→_succeededfailed
| 状态 | 含义 | 允许的下一步 |
|---|---|---|
| queued | 网关已持久化,尚未确认机器接收 | 等在线调度;未派发可取消;到期按策略失败 |
| dispatching | 已发送,执行端确认可能尚未到达 | 查询 dispatch 台账;不能创建替代任务 |
| running | 明确关联到已开始的 Codex turn | 读状态、日志,或请求取消 |
| blocked | 等待人工审批、认证恢复或必要输入 | 展示原因;经独立授权流程处理;不自动升级权限 |
| cancel_requested | 取消意图已保存,停止尚未确认 | 发送 / 重发同一控制意图,等待最终事实 |
| cancelled | 确认未启动,或对应 turn 已中断 | 返回已发生的副作用;不能宣称自动回滚 |
| succeeded / failed | 对应运行得到明确终态 | 返回结果;允许的会话可继续新 turn |
| unknown | 现有证据不足以判定是否执行或完成 | 冻结自动重派发,对账后更新真实状态 |
| 实体 | 最小字段 / 约束 |
|---|---|
| Owner / Machine | owner_id、machine_id、credential_version、revoked_at、agent_version、connection_epoch、last_seen;owner + machine 唯一 |
| Workspace | owner_id、machine_id、workspace_id、canonical_root、permission_profile、enabled;路径只在机器端解析 |
| Job / Continuation | job_id、owner_id、machine_id、workspace_id、state、revision、continuation_index、deadline、result / error、Codex thread_id / turn_id |
| Idempotency / Dispatch | owner + tool + client_request_id 唯一;request_digest、job_id、dispatch_id、attempt、local_receipt、spawn_intent、execution_identity |
| Event / Outbox / Audit | job + attempt + event_seq 唯一;payload_digest、ACK cursor、outbox 状态、脱敏内容、操作者与控制动作时间 |
网络通信无法凭空保证“严格只执行一次”。这里的目标是:重复请求不生成重复任务,重复投递不直接重跑;遇到执行事实不明时明确暂停并恢复证据。
同一工作区首版只允许一个写任务;revision 用于控制并发,event_seq 用于日志排序,两者不能混用。日志丢页要报告 gap,不把不完整输出包装成完整结果。
A / 用户授权
用户通过 OAuth 同意插件访问。拟定 scope 区分 jobs:read 与 jobs:run;服务端逐次验证 issuer、audience、有效期、scope 和 owner。
B / 机器注册
独立机器身份绑定 owner 与 machine。注册、生成或安装持久凭据需要用户明确批准,凭据可单机撤销与轮换。
C / 本地 Codex
使用该 Linux 上单独配置的合法登录 / 认证。MCP token 不能代替 Codex 登录,也不能转交给推理服务。
OAuth 发现、PKCE、resource / audience 与重连行为按官方插件认证规范实现;回调 URI 从实际插件管理界面复制,不猜固定地址。官方插件认证要求
拟定机器端工作区映射 · 示例路径,不含凭据
{
"machine_id": "linux-dev-01",
"gateway_url": "wss://codex-gateway.example.com/agent/codex",
"credential_source": "os-protected-store:machine-identity",
"workspaces": {
"demo-repo": {
"root": "/srv/codex-workspaces/demo",
"permission_profile": "reviewed-readonly",
"max_concurrent_jobs": 1
}
},
"ledger_path": "/var/lib/codex-bridge/ledger.sqlite",
"logs": {"redact": true, "max_event_bytes": 16384}
}安装常驻服务、创建长期凭据、扩展工作区权限、调整系统 / 网络安全设置,都应拆成明确授权步骤。页面中的配置和 service 模板仅用于评审,不能视为已批准执行。
拟定目录 · 网关与机器端共享契约
codex-bridge/
packages/contracts/ # 工具 schema、状态、错误与消息版本
services/gateway/
src/auth/ # OAuth 验证、owner 与 scope
src/mcp/ # 五个工具与输入校验
src/machine-object/ # WSS、租约、持久化、outbox
src/events/ # 第二阶段订阅与 webhook
services/linux-agent/
src/transport/ # WSS 重连、ACK、心跳
src/ledger/ # SQLite 调度与执行台账
src/workspaces/ # 白名单与权限校验
src/codex/ # stdio RPC、会话、审批适配
src/supervisor/ # 子进程、停止与恢复
tests/ # 契约、故障注入、安全与端到端
deploy/ # 经审查的配置与 service 模板
docs/ # 运维、撤销、升级与回滚手册冻结契约与测试夹具
定义五个工具、状态、身份边界、幂等规则。用假 Agent 跑通提交 → 结果,并覆盖重复调用。
实现网关与机器通道
分开验证 OAuth 用户身份和机器身份;先做持久化、ACK、重连与 owner 隔离,再接真实执行器。
实现本地 Codex 适配
逐请求关联响应,持续消费事件,处理审批和进程退出。用固定版本回归 initialization / resume / interrupt。
接入真实私有插件
使用当前平台支持的插件构建与测试流程配置 HTTPS MCP endpoint,完成用户连接后,检查五个工具是否出现在真实 dot 可用工具中。
故障注入后再加事件
断网、杀 daemon、重启网关、撤销凭据、并发续聊、乱序日志与重复 dispatch 全部有确定行为后,再实现主动完成通知。
codex-bridge-agent 是拟定的待实现程序名;下面没有对应已安装二进制。systemd 加固项须在目标系统逐项测试,不能替代 Codex 沙箱。
建议 systemd 模板 · 不包含 enable / start 安装步骤
[Unit]
Description=Private Codex Bridge Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=codexbridge
Group=codexbridge
ExecStart=/opt/codex-bridge/bin/codex-bridge-agent --config /etc/codex-bridge/config.json
Restart=on-failure
RestartSec=5
UMask=0077
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
StateDirectory=codex-bridge
ReadWritePaths=/var/lib/codex-bridge
ReadOnlyPaths=/srv/codex-workspaces/demo
[Install]
WantedBy=multi-user.target模板对应只读 MVP。Codex 状态目录、凭据读取与进程的 HOME 需按目标主机的受保护路径单独适配;确认无密钥被发送到 MCP。需要写工作区时,只在获准后替换相应只读挂载与写路径,并重复越界测试。
分开核算 Codex 使用额度 / 推理费用、Linux 主机、Worker 请求与 CPU、DO 请求 / 时长 / 存储、R2 容量与请求、日志保留、域名与身份服务。本文不估造价格;按最终地区、套餐和实际流量测量。先限制并发、单任务时长、日志大小、产物大小与排队期限。
**MVP 先查询,第二阶段再加 MCP Events。**不要把一次 MCP 工具调用挂起几十分钟。start 立即返回 job_id;get_job 查询进度。后台跑完后主动唤醒,需要平台支持且用户明确订阅事件。
官方文档已说明 MCP Events 可用于 dots,采用 MCP 2.0 协议版本 2026-07-28,由平台在订阅时提供回调地址与签名 secret。工作区政策仍然适用。MCP Events 官方文档
events/list、events/subscribe、events/unsubscribe。codex.job.completed 与 codex.job.blocked;按已认证 owner 与 job_id 限定订阅。这是基于公开机制提出的待实测集成,不是随意向 dot 发消息的通用 API。回调不能自造;先做 challenge 验证、签名、目的地址校验与防重放,并保护订阅 secret。
拟定事件业务数据 · 外层签名与投递遵循实际协议
{
"job_id": "job_example_01",
"state": "succeeded",
"revision": 5,
"event_seq": 28,
"summary": "指定工作区的只读检查已完成。"
}事件 payload 只含必要结果元数据,完整日志仍走带身份校验的 get_codex_logs。端到端验收要真实证明:订阅成功、完成事件到达对应对话、重复通知去重、取消订阅后不再触发。
M0
私有插件在真实 dot 中可见并完成 OAuth;模拟任务能返回稳定 job_id。若账号或管理策略不允许,停在这里,不先安装机器服务。
**产物:**工具目录、授权记录、模拟任务闭环。
M1
Linux 主动 WSS,Codex 只读执行,固定工作区。拒绝未授权 owner、机器和路径;日志可追溯。
**通过条件:**目标机文件断言与返回结果一致;重复提交只有一个任务。
M2
经批准开放测试工作区写权限;对比变更、限制并发,审批请求明确阻塞。无默认提交、推送、发布或自动提权。
**通过条件:**只改允许的文件,越界失败,变更可审阅与恢复。
M3
继续同一个 thread;取消得到真实终态;网关 / daemon 重启后台账可恢复,unknown 不会触发重复执行。
**通过条件:**故障注入、并发冲突、凭据撤销全部有审计证据。
M4
实现 MCP Events、订阅过期与取消,验证真实 dot 被正确唤醒。随后再考虑多机器与私有产物下载。
**通过条件:**事件送达可证实,取消订阅后无新通知。
浏览器控制是独立能力。安装 Codex CLI 不等于获得 Linux 桌面、浏览器会话或鼠标键盘权限;若后续需要,另设隔离浏览器、工具接口、登录与审批边界,再单独验收。
| 现象 | 先检查 | 不能做的“修复” |
|---|---|---|
| dot 看不到工具 | 插件是否安装 / 连接、工作区政策、工具发现与协议兼容 | 直接假定 Linux 出故障或绕过组织限制 |
| 持续 401 / 403 | issuer、resource / audience、scope、过期 / 撤销、owner 绑定 | 关掉鉴权、把 token 塞到查询参数 |
| 机器一直离线 | 出站 DNS / TLS / WSS、代理、机器凭据与网关日志 | 开放公网 app-server 或替换成 root 直连 |
| queued 不前进 | 机器在线、租约、工作区锁、outbox、ACK 与排队期限 | 反复创建新任务测试“是否好了” |
| Codex 不出结果 | 本地认证、协议版本、审批请求、进程状态与模型连接 | 把 stdout 静默当成功或自动批准 |
| 重连后 unknown | 本地 dispatch 台账、thread / turn 与已持久化事件 | 默认任务没运行,重新执行有副作用操作 |
| 取消后仍显示运行 | 正确 turn ID、控制消息 ACK、实际进程与最终事件 | 把 cancel_requested 展示为 cancelled |
| 完成却没有通知 | 订阅、challenge、签名、有效期、回调响应与投递 outbox | 为重发通知重跑 Codex 任务 |
先停止接收新任务并撤销受影响机器访问,记录在途任务事实;恢复到已测试的网关和 Agent 版本,保留兼容的台账与数据库备份。必须先确认本地进程状态,再决定是否重新执行。升级 Codex 时重跑协议与安全测试,不自动跟随 latest。
已有 Linux 云任务执行文件断言、继续同一任务的验证;也有已连接电脑的消息往返与原生浏览器验证。它们只说明那些已支持环境的能力。
任意自有 Linux 的原生 Computers 注册、本文新建 MCP 桥的真实端到端运行、机器凭据注册流程,以及本文事件到 dot 的唤醒闭环。
官方资料核对日期:2026 年 10 月 5 日。公开接口可能变化;上线时应再次核对并固定版本。以下来源支持接口能力;本文的网关拓扑、数据模型、工具名与可靠性策略属于设计建议。
[01]
传输、初始化、thread / turn 生命周期、审批与实验性边界。
[02]
批处理、脚本与自动化集成的替代入口。
[03]
通过插件向 OpenAI host 提供工具的公开接入面。
[04]
OAuth 发现、resource、scope、PKCE 与用户连接流程。
[05]
连接管理与 hibernation 的实现依据。
[06]
dots 支持范围、事件订阅、回调验证与签名投递。
**下一次实施的最小决策:**确认目标 Linux、唯一测试工作区、网关部署位置和只读范围;先完成 M0,再按步骤批准安装、凭据与常驻访问。