- commit
- 69d2f20
- parent
- 3cf57d0
- author
- im_wower
- date
- 2026-03-22 20:42:07 +0800 CST
docs: retain codexd while removing worker surface
5 files changed,
+343,
-10
+35,
-5
1@@ -71,11 +71,11 @@
2 - 负责 heartbeat、租约续约、最小调度循环和 runtime 探针
3 - 是后续统一 discovery / control / task / run 接口的目标承载面
4
5-### `apps/control-api-worker`
6+### legacy `control-api` surface(已移出当前仓库)
7
8-- Cloudflare Worker 入口
9-- 当前仍负责一部分 legacy control-plane HTTP 能力
10-- 只作为 cutover 兼容层保留,完成迁移后进入删旧范围
11+- `control-api.makefile.so`、Cloudflare Worker、D1 仍可能在线上或旧文档中出现
12+- 但它们已经不再是当前仓库中的实现组件
13+- 当前只把它们当作删旧阶段需要盘点的历史兼容面
14
15 ### `apps/status-api`
16
17@@ -83,6 +83,34 @@
18 - 当前仍依赖 `BAA_CONTROL_API_BASE`
19 - 定位是迁移期本地只读观察服务,不是主控制面
20
21+### `codexd`(设计中,尚未实现)
22+
23+- `mini` 本地常驻的 Codex 代理/执行组件
24+- 不是 TUI,不要求人工盯界面
25+- 负责把 Codex 作为双工工作组件来使用:
26+ - 执行 worker step
27+ - 完成异步任务
28+ - 参与 AI 对话
29+ - 持续记录日志
30+- 公开接口结论已经明确:
31+ - 主接口:`codex app-server`
32+ - 辅助兜底:`codex exec`
33+ - 不驱动 TUI
34+- 负责 Codex 特有的会话、子进程、重试、超时和恢复语义
35+
36+和现有组件的边界:
37+
38+- `conductor-daemon`:系统真相源、编排器、HTTP/WS 主接口
39+- `worker-runner`:通用 step 执行与落盘框架
40+- `codexd`:Codex 专用执行代理,负责把 Codex 从“手工 TUI”变成“可被本地系统调用的长期能力”
41+
42+当前状态:
43+
44+- 仓库里已经有 `codex` step kind、planner 和 step template 抽象
45+- 但还没有真正的 `codexd` 进程、Codex 子进程管理或常驻代理实现
46+- 所以 `codexd` 现在仍是设计项,不是已落地组件
47+- 后续实现时,不再把 `exec` 当作主双工方案;`exec` 只用于简单调用、测试和兜底
48+
49 ### `apps/worker-runner`
50
51 - 本地 step 执行器
52@@ -173,12 +201,14 @@
53 - `conductor.makefile.so -> 100.71.210.78:4317` 可持续对外提供入口
54 - 浏览器插件和后续调用方默认走新的 canonical host
55 - legacy control plane 依赖被逐步盘点并删除
56+- 为后续 `codexd` 预留清晰边界:`conductor` 管真相,`codexd` 管 Codex 会话和执行
57
58 ## 11. 当前已知残留
59
60 - `status-api` 仍通过 `BAA_CONTROL_API_BASE` 读取 legacy truth source
61 - `conductor.makefile.so` 目前只回源 `conductor-daemon` 已有路由,尚未承接完整业务 API
62-- 仓库中仍保留 `apps/control-api-worker`、Cloudflare / D1 相关脚手架
63+- 线上和历史文档里仍可能残留 `control-api.makefile.so`、Cloudflare / D1 相关资产或表述
64+- `codexd` 尚未实现;当前仍没有“Codex 常驻代理 / Codex daemon”能力
65
66 ## 12. 历史回溯
67
+18,
-5
1@@ -21,6 +21,15 @@
2 6. [`docs/ops/README.md`](./docs/ops/README.md)
3 7. [`coordination/TASK_OVERVIEW.md`](./coordination/TASK_OVERVIEW.md)
4
5+如果你关心“Codex 不再手工开 TUI,而是作为本地常驻代理工作”,再读:
6+
7+- [`docs/runtime/codexd.md`](./docs/runtime/codexd.md)
8+
9+其中当前结论已经固定:
10+
11+- `codex app-server` 是未来 `codexd` 的主接口
12+- `codex exec` 只保留为简单调用、测试和兜底 worker
13+
14 ## 面向 AI 的推荐阅读顺序
15
16 如果是网页版 AI、CLI AI 或手机网页 AI,推荐按这个顺序:
17@@ -37,7 +46,6 @@
18
19 ```text
20 apps/
21- control-api-worker/
22 conductor-daemon/
23 status-api/
24 worker-runner/
25@@ -78,14 +86,15 @@ docs/
26 - 所有新接口设计默认先落 `mini` 本地 `4317`
27 - 所有新公网说明统一写 `conductor.makefile.so`
28 - `status-api` 只作为本地只读观察面,不再作为默认对外业务接口
29-- `apps/control-api-worker` 只承担迁移期兼容职责,不再扩成主路径
30 - 运行中的浏览器插件代码以 [`plugins/baa-firefox`](./plugins/baa-firefox) 为准
31+- `codexd` 目前只是设计项,还不是已实现组件
32+- `codexd` 后续默认以 `app-server` 为主,不以 TUI 或 `exec` 作为主双工接口
33
34 ## Canonical 入口
35
36 | 面 | 地址 | 定位 | 说明 |
37 | --- | --- | --- | --- |
38-| local API | `http://100.71.210.78:4317` | 唯一主接口、内网真相源 | 当前已承接 `/describe`、`/health`、`/version`、`/v1/capabilities`、`/v1/system/state`、`/v1/controllers`、`/v1/tasks`、`/v1/runs` 和 `pause/resume/drain` |
39+| local API | `http://100.71.210.78:4317` | 唯一主接口、内网真相源 | 当前已承接 `/describe`、`/health`、`/version`、`/v1/capabilities`、`/v1/system/state`、`/v1/controllers`、`/v1/tasks`、`/v1/runs`、`pause/resume/drain`、`/v1/exec`、`/v1/files/read` 和 `/v1/files/write` |
40 | public host | `https://conductor.makefile.so` | 唯一公网域名 | 由 VPS Nginx 回源到 `100.71.210.78:4317` |
41 | local status view | `http://100.71.210.78:4318` | 本地只读观察面 | 迁移期保留,不是主控制面 |
42
43@@ -93,7 +102,7 @@ legacy 兼容说明:
44
45 - `https://control-api.makefile.so` 只用于迁移期间兜底和识别残留依赖
46 - 业务查询和系统控制写入已经不再依赖 Cloudflare Worker / D1 真相源
47-- `apps/control-api-worker` 在 cutover 完成后进入删旧范围
48+- `apps/control-api-worker` 已从当前仓库移除;剩余 legacy 只保留在线上资产和历史文档背景里
49
50 ## 迁移顺序
51
52@@ -121,4 +130,8 @@ legacy 兼容说明:
53 - `files/read`
54 - `files/write`
55
56-这个包只负责本地 Node 能力、输入输出合同和结构化错误;当前还没有接到 `conductor-daemon` 或公开 HTTP 路由,后续 `/v1/exec`、`/v1/files/read`、`/v1/files/write` 会基于它继续接。
57+这个包负责本地 Node 能力、输入输出合同和结构化错误;当前已经通过 `conductor-daemon` 暴露到:
58+
59+- `/v1/exec`
60+- `/v1/files/read`
61+- `/v1/files/write`
+2,
-0
1@@ -90,6 +90,7 @@ updated_at: 2026-03-22
2 - `docs/runtime/environment.md`
3 - `docs/runtime/launchd.md`
4 - `docs/runtime/node-verification.md`
5+- `docs/runtime/codexd.md`
6
7 ## commands_run
8
9@@ -106,6 +107,7 @@ updated_at: 2026-03-22
10 - runtime 脚本默认把兼容变量 `BAA_CONTROL_API_BASE` 收口到 `https://conductor.makefile.so`
11 - `install-mini.sh` 默认改读 `runtime-secrets.env`,仅在需要时回退到 legacy `control-api-worker.secrets.env`
12 - Firefox 插件文案、运行文档和 API/运维文档已统一为“本地 WS + conductor.makefile.so”,并明确 `status-api` 只保留本地只读角色
13+- 保留并恢复了 `codexd` 设计文档与入口,不再把这次删旧任务扩散成对 `codexd` 规划的回退
14 - `pnpm -r build` 与 `git diff --check` 已通过
15
16 ## risks
+10,
-0
1@@ -8,6 +8,7 @@
2 - [`environment.md`](./environment.md): 必要环境变量
3 - [`launchd.md`](./launchd.md): `mini` 上的 launchd 安装
4 - [`node-verification.md`](./node-verification.md): `mini` 节点 on-node 检查
5+- [`codexd.md`](./codexd.md): Codex 常驻代理的预留设计
6
7 ## 当前约定
8
9@@ -26,6 +27,15 @@ Firefox WS 说明:
10 - 固定 upgrade path 是 `/ws/firefox`
11 - 只给本地 Firefox 插件双向通讯使用,不是公网通道
12
13+`codexd` 说明:
14+
15+- 当前还没有真正的 Codex 常驻代理实现
16+- [`codexd.md`](./codexd.md) 只记录后续设计边界
17+- 当前不要把系统理解成已经有 Codex daemon
18+- 文档结论已经明确:
19+ - `codex app-server` 是未来主会话/双工能力面
20+ - `codex exec` 只作为简单调用、测试和兜底路径
21+
22 ## 最短路径
23
24 1. `./scripts/runtime/install-mini.sh`
+278,
-0
1@@ -0,0 +1,278 @@
2+# codexd
3+
4+`codexd` 是 `baa-conductor` 下一阶段预留的本地常驻组件设计。
5+
6+它的目标不是替代 `conductor-daemon`,而是把 Codex 从“手工打开一个 TUI 窗口”提升为“可被本地系统长期调用的 Codex 代理能力”。
7+
8+当前状态:
9+
10+- 这是设计文档
11+- 仓库里还没有 `codexd` 的实际实现
12+
13+## 目标
14+
15+`codexd` 需要解决的不是“再开一个 UI”,而是这 4 件事:
16+
17+1. 让 Codex 作为 worker 执行 step
18+2. 让 Codex 能完成异步任务,而不是只跑一次同步 CLI
19+3. 让 Codex 能参与 AI 对话,而不是只能手动开 TUI
20+4. 让 Codex 全程记录日志、可恢复、可观察
21+
22+## 为什么需要它
23+
24+当前仓库已经有:
25+
26+- `conductor-daemon`
27+- `worker-runner`
28+- `planner`
29+- `task / run / step`
30+- `checkpoint / logging`
31+
32+但还没有:
33+
34+- Codex 常驻进程
35+- Codex 会话代理
36+- Codex 子进程管理
37+- Codex 对话与任务统一入口
38+
39+所以目前的“Codex”仍停留在抽象层:
40+
41+- planner 和 step template 里有 `codex` step kind
42+- 但系统没有一个真正的 `codexd`
43+
44+## 定位
45+
46+`codexd` 的定位应该是:
47+
48+- 本地常驻进程
49+- 只跑在 `mini`
50+- 由 `launchd` 托管
51+- 通过本地 IPC、HTTP 或 WS 与 `conductor-daemon` 协作
52+
53+它不是:
54+
55+- 新的真相源
56+- 新的主控制面
57+- 新的公网入口
58+- 手工操作的主界面
59+
60+## 组件边界
61+
62+### `conductor-daemon`
63+
64+负责:
65+
66+- 系统真相
67+- 任务编排
68+- HTTP / WS 主接口
69+- pause / resume / drain
70+- task / run / state / capability 读写
71+
72+### `worker-runner`
73+
74+负责:
75+
76+- 通用 step 执行模型
77+- 本地目录结构
78+- checkpoint 落盘
79+- 日志文件管理
80+
81+### `codexd`
82+
83+负责:
84+
85+- 启动和托管 Codex 子进程
86+- 管理 Codex 会话
87+- 处理 Codex 对话和 worker step 执行
88+- 记录 Codex stdout / stderr / 结构化事件
89+- 超时、重试、崩溃恢复
90+
91+一句话:
92+
93+- `conductor-daemon` 管系统
94+- `worker-runner` 管通用执行框架
95+- `codexd` 管 Codex 本身
96+
97+## 运行模型
98+
99+`codexd` 最合理的运行模型是:
100+
101+1. `conductor-daemon` 接到任务或对话请求
102+2. 需要 Codex 时,转给 `codexd`
103+3. `codexd` 负责:
104+ - 创建或复用 Codex session
105+ - 启动子进程
106+ - 采集增量输出
107+ - 记录日志
108+ - 返回 step 结果或对话结果
109+4. `conductor-daemon` 把结果写回本地真相源
110+
111+## 官方接口结论
112+
113+基于当前本机已验证的 Codex CLI 公开接口,`codexd` 的设计结论应明确为:
114+
115+- 主会话与双工能力:基于 `codex app-server`
116+- 简单调用、批处理、测试和兜底 worker:基于 `codex exec`
117+- 不驱动 TUI
118+- 不逆向私有协议
119+
120+原因:
121+
122+- `codex exec` 适合一次性非交互执行,能输出结构化结果,但天然不是多轮双工模型
123+- `codex app-server` 虽然仍标记为 experimental,但它已经公开了最完整的线程、turn、流式事件和恢复语义
124+- 已验证单个 `app-server` 进程可承载多个 `thread`,因此默认不需要“一对话一进程”
125+
126+当前推荐口径:
127+
128+- `codexd v1` 就应直接围绕 `app-server` 实现
129+- `exec` 仅保留为:
130+ - 最小 smoke 测试
131+ - 简单离线调用
132+ - app-server 不可用时的兜底 worker
133+
134+## 支持的两类工作
135+
136+### 1. worker 模式
137+
138+用于:
139+
140+- `codex` step
141+- 代码修改
142+- 审阅
143+- 任务执行
144+
145+特点:
146+
147+- 有 task / step / run 关联
148+- 受 timeout / retry / checkpoint 约束
149+- 由 `worker-runner` / `conductor-daemon` 编排
150+- 默认仍优先走 `app-server`
151+- 只有简单批处理或兜底路径才落到 `exec`
152+
153+### 2. duplex 对话模式
154+
155+用于:
156+
157+- 和 AI 的持续双向对话
158+- 支持 CLI / 网页版 AI 参与
159+- 长于一次性 `codex exec`
160+
161+特点:
162+
163+- 需要会话 ID
164+- 需要增量输出
165+- 需要日志和历史
166+- 可以和任务执行共用同一个 `codexd`,但不能混淆真相
167+- 这一层应直接建立在 `app-server` 的 `thread` / `turn` 模型上
168+
169+## 推荐能力面
170+
171+`codexd` 后续可以提供这些本地能力:
172+
173+### 会话类
174+
175+- 创建会话
176+- 列出会话
177+- 读取会话状态
178+- 关闭会话
179+
180+### 对话类
181+
182+- 向某个会话发送输入
183+- 读取流式输出
184+- 拉取最近日志
185+
186+### worker 类
187+
188+- 启动某个 `codex` step
189+- 查询 step 执行状态
190+- 取消 step
191+- 读取 step 日志和产物
192+
193+## 推荐实现顺序
194+
195+### v1
196+
197+- 启动单个常驻 `codex app-server`
198+- 由 `codexd` 维护:
199+ - server 生命周期
200+ - thread 映射
201+ - turn 启动 / 打断 / 继续
202+ - 增量事件日志
203+- 对 `conductor-daemon` 暴露稳定的本地适配层
204+
205+### v1 兜底能力
206+
207+- 保留一个 `exec` 适配器
208+- 只做:
209+ - 健康检查
210+ - 最小 smoke
211+ - 简单一次性 worker 调用
212+ - app-server 不可用时的降级路径
213+
214+### v2
215+
216+- 在 `app-server` 之上继续补:
217+ - 会话恢复
218+ - 多 thread 管理
219+ - 对话 steering / interrupt
220+ - worker 与对话统一日志索引
221+
222+## 日志与可恢复性
223+
224+`codexd` 不应该只把结果打印到终端。
225+
226+最少需要:
227+
228+- 会话级日志
229+- step 级日志
230+- 结构化事件日志
231+- 最近输出缓存
232+
233+推荐落点:
234+
235+- `logs/codexd/`
236+- `runs/<run-id>/`
237+- `state/codexd/`
238+
239+要支持:
240+
241+- 进程重启后恢复会话索引
242+- 任务执行失败后保留日志和上下文
243+- CLI / 网页 UI 可查询最近输出
244+
245+## 自启动
246+
247+如果后续实现 `codexd`,推荐:
248+
249+- 新增 `launchd` 服务
250+- 例如:`so.makefile.baa-codexd`
251+
252+默认行为:
253+
254+- `mini` 启动后自动拉起
255+- 不要求用户手工开 TUI
256+- TUI 只作为调试手段,而不是主运行方式
257+
258+## 当前建议
259+
260+在 `codexd` 真正实现前,继续遵守当前边界:
261+
262+- `conductor-daemon` 是主接口
263+- `worker-runner` 是通用执行框架
264+- `codex` 仍只是 step kind 和未来的 worker 类型
265+
266+如果开始实现 `codexd`,默认遵守这条约束:
267+
268+- `app-server` 是主能力面
269+- `exec` 不是主会话系统,只是简单调用和测试工具
270+
271+不要把当前系统误认为已经有:
272+
273+- Codex daemon
274+- Codex 会话代理
275+- Codex 双工对话桥
276+
277+## 一句话定义
278+
279+`codexd` = `mini` 上的 Codex 常驻代理,用来承接 Codex 的 worker 执行、对话、日志与恢复;它是 `baa-conductor` 的后续组件,不是当前已上线能力。