baa-conductor


baa-conductor / docs / runtime
im_wower  ·  2026-03-25

codexd.md

  1# codexd
  2
  3`codexd` 现在是 `mini` 上的正式 Codex 运行时服务。
  4
  5它是由 `launchd` 托管的独立常驻进程,用来承接 Codex child、会话、日志、恢复和本地服务面。
  6
  7## 当前正式运行面
  8
  9- launchd label: `so.makefile.baa-codexd`
 10- 本地监听地址:`http://127.0.0.1:4319`
 11- 本地事件流:`ws://127.0.0.1:4319/v1/codexd/events`
 12- 会话链路:`app-server`
 13- child 策略:`spawn`
 14- child 命令:`codex app-server`
 15- 日志目录:`logs/codexd/`
 16- 状态目录:`state/codexd/`
 17
 18正式 launchd 运行面固定写入:
 19
 20```text
 21BAA_CODEXD_MODE=app-server
 22BAA_CODEXD_LOCAL_API_BASE=http://127.0.0.1:4319
 23BAA_CODEXD_EVENT_STREAM_PATH=/v1/codexd/events
 24BAA_CODEXD_SERVER_STRATEGY=spawn
 25BAA_CODEXD_SERVER_COMMAND=codex
 26BAA_CODEXD_SERVER_ARGS=app-server
 27BAA_CODEXD_SERVER_CWD=/Users/george/code/baa-conductor
 28BAA_CODEXD_SERVER_ENDPOINT=stdio://codex-app-server
 29BAA_CODEXD_LOGS_DIR=/Users/george/code/baa-conductor/logs/codexd
 30BAA_CODEXD_STATE_DIR=/Users/george/code/baa-conductor/state/codexd
 31```
 32
 33`conductor` 代理 `/v1/codex*` 时也依赖同一个地址:
 34
 35```text
 36BAA_CODEXD_LOCAL_API_BASE=http://127.0.0.1:4319
 37```
 38
 39如果 `conductor` 的 launchd 安装副本缺这个变量,live `/v1/codex` 会直接返回 `503 codexd_not_configured`,即使 `codexd` 自己的 `4319` 服务已经正常。
 40
 41## 组件边界
 42
 43### `conductor-daemon`
 44
 45负责:
 46
 47- 系统真相
 48- 任务编排
 49- 对外主 HTTP / WS 接口
 50- 健康感知、重连和降级
 51
 52### `codexd`
 53
 54负责:
 55
 56- 启动和托管 Codex child
 57- 管理本地 Codex session / turn / recent events 运行态
 58- 维护 `logs/codexd/**``state/codexd/**`
 59- 提供本地 HTTP / WS 服务面
 60- 处理 child 崩溃后的重建
 61
 62一句话:
 63
 64- `conductor-daemon` 管系统
 65- `codexd` 管 Codex 本身
 66
 67## 当前本地服务面
 68
 69`apps/codexd` 当前已经有本地 HTTP / WS 入口,正式运行时由 `launchd` 长期托管:
 70
 71- `GET /healthz`
 72- `GET /describe`
 73- `GET /v1/codexd/status`
 74- `GET /v1/codexd/sessions`
 75- `GET /v1/codexd/sessions/:session_id`
 76- `POST /v1/codexd/sessions`
 77- `POST /v1/codexd/turn`
 78- `WS /v1/codexd/events`
 79
 80推荐 AI 或自动化客户端直接先读:
 81
 82- `GET /describe`
 83
 84`/describe` 当前返回:
 85
 86- `ok`
 87- `name`
 88- `surface`
 89- `description`
 90- `mode`
 91- `base_url`
 92- `event_stream`
 93- `routes`
 94- `capabilities`
 95- `notes`
 96
 97正式口径只保留 `describe / status / sessions / turn / events` 98
 99`/describe` 只列正式能力,不包含批处理一次性调用路线。
100
101当前骨架已经会维护:
102
103- daemon identity
104- child state
105- session registry
106- recent event cache
107- 结构化事件日志
108
109`codexd` 对 app-server turn 的状态口径也要区分中间态和终态:
110
111- `error``willRetry=true` 只记入 `recentEvents`,session 仍保持当前 turn 进行中
112- 只有终态失败才把 session 的 `lastTurnStatus` 写成 `failed`
113- stdio transport 在 child `stdout` 结束或进程退出前,会先冲刷最后一个未换行的 JSON-RPC 消息,再关闭连接;`turn/completed` 不会再因为尾包没有换行而丢失
114- 顺序创建多个 session / thread 时,即使后一个 turn 先收到 `willRetry=true` 的错误,再在流尾收到最终完成事件,session 的 `lastTurnStatus` 也应收口到 `completed`
115- 如果 stdio transport 提前关闭,recent events 会先记录 `app-server.transport.closed`
116- 如果关闭时某个 session 仍有 `currentTurnId`,codexd 会把该 turn 收口为 `failed`,并追加 `app-server.turn.completed.missing`
117- 这类事件会带 `detail.failureClass = "transport_closed_before_turn_completed"`,用来明确区分“合法 completed 缺失”与“completed 已发出但尾包无换行”的旧问题
118
119## Reopen 规则
120
121下面这些仍属于已修复的旧尾包问题范围:
122
123- recent events 能看到目标 turn 的 `app-server.turn.completed`
124- session 最终收口到 `lastTurnStatus: completed`
125- transport close 前冲刷了无换行尾包,completed 成功入库
126
127下面这些应按新的 child / transport 故障 reopen:
128
129- recent events 出现 `app-server.transport.closed`
130- 同一 turn 没有任何合法 `app-server.turn.completed`
131- codexd 额外记录 `app-server.turn.completed.missing`
132- 事件 detail 标明 `failureClass = "transport_closed_before_turn_completed"`
133
134## 运行职责边界
135
136- `launchd` 负责开机自启动和硬重启
137- `conductor-daemon` 负责发现 `codexd` 不可用并重连
138- `codexd` 负责发现 Codex child 不可用并重建子进程
139- 不做 `conductor-daemon` 直接 spawn `codexd`
140- 不做 `codexd` 直接 spawn `conductor-daemon`
141
142## 正式口径明确排除的内容
143
144下面这些不属于正式 launchd 运行面:
145
146- `status / sessions / turn / events` 之外的额外运行面
147- TUI 常驻模式
148- 两个进程互相直接拉起
149-`codexd` 描述成“可选以后再说”的附属能力
150
151## 当前验收链路
152
153这条运行面当前至少要通过下面这组 smoke:
154
155- `codexd status`
156- `GET /v1/codex`
157- session create/read
158- turn create,然后通过 session read 回读 `lastTurn*``recentEvents`
159- `logs/codexd/**``state/codexd/**` 正常落盘
160
161仓库内对应命令:
162
163```bash
164./scripts/runtime/codexd-e2e-smoke.sh
165```
166
167mini 上重装 launchd 后,也应至少手工确认:
168
169```bash
170curl -fsSL http://127.0.0.1:4319/v1/codexd/status
171curl -fsSL http://100.71.210.78:4317/v1/codex
172```