Files
pikasTech-unidesk/docs/reference/host-codex-commander.md
T
2026-05-23 08:04:05 +00:00

133 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Host Codex Commander Skeleton
本文定义 host Codex 指挥官的本地 skeleton 阶段。仓库内正式 `commander` CLI 当前只提供 `/health``/api/commander/contract``.state/commander/` 状态读写、trace summary dry-run 聚合和 approval draft preview;不接 live bridge,不发送 ClaudeQQ,不接管人工指挥官。
当前允许存在一个 operator-run 的高鲁棒 stdio 保活形态,用于在人工授权下让 host Codex 持续承担指挥官工作。该形态不是仓库内正式 daemon,也不替代 skeleton contract;它应被视为过渡运行方式,后续产品化仍必须回到本文件的 contract、state、approval 和安全边界。
## 边界
- `host-codex-commander` 是独立的本地 skeleton,不是运行中的 live daemon。
- 只允许本地文件状态、trace 摘要和审批草案预览。
- 所有输出必须 redaction token/secret/URL credential。
- 不得重启或接管 Code Queue backend,不得 cancel/interrupt 运行任务,不得打印 token 明文。
- Host commander 观察到 `bun scripts/cli.ts codex pr-preflight --remote` 返回 `scheduler-runner-env` / `auth-missing` 时,只能把它解释为 scheduler runtime preflight surface 缺少 GitHub auth;不得据此判定当前 active runner 或 dev container 不能 push、创建 PR 或评论 PR。
## PR 能力判读
PR 能力判读以 `docs/reference/code-queue-supervision.md` 的 runner preflight 规则为 source of truth。`authScopeSummary``scopeBoundary``activeRunnerDevContainer``recommendedActions` 必须同时保留:scheduler auth 与当前 CLI/dev container auth 是两个 scopeactive runner 能力只能用当前 runner 内的 `bun scripts/cli.ts gh auth status --repo pikasTech/unidesk``gh pr create --dry-run``gh pr comment create --dry-run` 判定。
Host commander 可以把 scheduler-side `auth-missing` 记录为长期 auth-broker 或 runtime secret 缺口,但只有 active runner/dev-container 检查也失败时,才允许把本 turn 归类为无法创建 PR。所有诊断只报告 token 来源和存在性,不打印 token 值。
## CLI
```bash
bun scripts/cli.ts commander contract
bun scripts/cli.ts commander plan --dry-run [--session-id primary]
bun scripts/cli.ts commander smoke --dry-run [--session-id primary]
bun scripts/cli.ts commander approval request --action <action> --dry-run [--reason text] [--task-id id]
```
`plan``smoke``approval request` 必须显式使用 `--dry-run`,缺失时返回 `error=dry-run-required`
## Operator-Run Stdio Loop
当前高鲁棒指挥官循环脚本固定放在 `/root/.unidesk/commander_loop.py`,工作目录使用 `/root/unidesk/`。它通过 `codex app-server --listen stdio://` 直连 Codex app-server JSON-RPC,而不是反复启动普通交互式 CLI;外层必须有持续循环和异常保护,fatal error 后自动重启,避免单次 stdio、网络或 app-server 错误让指挥官长期停止。
指挥 prompt 固定放在 `/root/.unidesk/commander_prompt.md`。脚本启动时读取该文件;运行中检测到 prompt 文件变化时,优先通过 `turn/steer` 注入当前 active turn。如果 steer 失败,脚本应记录失败、interrupt 当前 turn 并回到外层循环重启;不能静默忽略 prompt 变更。默认可以尝试 resume 指定 commander threadresume 失败时必须降级为新 thread 继续运行。
前台输出应保持低噪声、单行化和可读:只显示时间、总运行时间、message、tool command start/completed/failed、stderr 和关键状态;完整 app-server JSON-RPC 事件不应直接刷屏。前台输出只是监督界面,分析和追责以 JSONL 文件日志为准。
完整日志必须写入 `/root/unidesk/logs/commander.log.<启动时间戳>.jsonl`,其中启动时间戳精确到秒,例如 `commander.log.YYYYMMDD_HHMMSS.jsonl`。后续分析时先用以下命令定位当前或最近一次运行日志:
```bash
ls -t /root/unidesk/logs/commander.log.*.jsonl | head -n 1
```
日志中应保留完整 JSON-RPC 事件和脚本派生事件,重点关注:
- `thread/resume/requested``thread/resumed``thread/start/requested`:确认是否复用了预期 thread。
- `turn/started`:确认当前 active turn。
- `prompt/loaded``prompt/changed``prompt/steered``prompt/steer_failed`:确认外部 prompt 是否真实注入。
- `item/completed` 中的 `agentMessage``commandExecution`:复盘 commander 说了什么、派了什么命令以及命令结果。
- `stderr`:定位 Codex core、stdio bridge 或工具路由错误。
该运行形态可以用于指挥 Code Queue、审阅任务、创建/更新 issue、PR 收口和必要的热修复例外,但不得被解释为普通 worker。涉及实现、测试和 PR 创建的常规工作仍应优先通过 Code Queue 派单;host commander 直接执行只适用于授权的 PR 收口、基础设施热修复或 runner 权限缺口,并且必须留下复盘和长期改进 issue。
## 指挥职责
host commander 的工作是调度、监督、steer、审阅和 PR 收口;它维护并发窗口、阻塞分类、issue/#20/#24 记录,并在 checks 和审阅通过后负责合并裁决或走已批准的合并路径。Code Queue runner 的工作是实现、验证、提交、push head branch 和创建 PRrunner 不合并自己的 PR。
HWLAB 业务目标、验收和优先级属于 `pikasTech/HWLAB#7`;UniDesk 指挥治理、队列监督、并发窗口和 runner/PR handoff 属于 `pikasTech/unidesk#20`#20 可以链接 HWLAB #7 的证据和状态,但不能替代 HWLAB 业务 issue,也不能把 HWLAB 代码实现决策写成 UniDesk 指挥规则。
host commander 路由 HWLAB 工作时必须遵循 `docs/reference/code-queue-supervision.md` 的 HWLAB / #20 监督口径:HWLAB 产品和用户交付进入 `pikasTech/HWLAB` issue/PR 与 #7 看板,UniDesk#20 只记录指挥控制、Code Queue、CLI、基础设施和治理态势。
host commander 不直接编辑 HWLAB 业务代码,不以本地热修绕过 HWLAB runner PR。只有用户明确授权的 PR 收口、基础设施热修或 runner 权限缺口可以例外;例外必须最小化变更,在相关 issue/PR 中留下命令、diff、验证证据和影响范围,并创建或更新 follow-up issue 消除该例外原因。
## Dev 验证计划
`commander smoke --dry-run` 是无 daemon smoke contract。它只输出验证计划,不启动 HTTP daemon、不打开 SSH/PTY/stdio bridge、不发送 ClaudeQQ、不重启服务、不 interrupt/cancel 任务、不部署、不跑全量 check/e2e。
指挥官派发或审阅任何 `DEV smoke` 时,必须沿用 `docs/reference/code-queue-supervision.md` 的 DEV 测试授权分级:未显式授权的 smoke 默认是 `read-only`;读取 live DEV 状态必须标成 `live-read`;触发 deploy、rollout、task、operation、audit、evidence 或硬件/虚拟硬件链路的 smoke 必须标成 `live-mutating`,并在 prompt 中逐项列出授权命令和 closeout 证据要求。
需要验证的 source/contract 面:
- health endpoint:用 `createCommanderRequestHandler` 和临时 `RuntimeConfig` 调用 `GET /health`,期望返回 `service=host-codex-commander``stateRoot` 和日志文件路径;禁止 `Bun.serve` 和端口监听。
- state file:只在临时目录写读 `sessions/<sessionId>.json``events/<sessionId>.jsonl``approvals/draft.json`,确认 session 状态和 redaction round-trip;禁止触碰真实 `.state/commander/`
- trace summary dry-run:只喂 mock JSONL 给 `summarizeCommanderTrace`,确认 `taskId``sessionId``lastSeq``status``redactionsApplied` 和有界摘要;禁止读取 live Code Queue trace、标记已读、interrupt 或 cancel。
- approval draft preview:只运行 `commander approval request --dry-run``buildCommanderApprovalDraft`,确认 `requiresExplicitUserApproval=true``claudeqq.mutation=false``sendImplemented=false` 和敏感信息脱敏;禁止 POST ClaudeQQ。
- SSH bridge boundary:只检查 `commander plan --dry-run``bridge.mutation=false``startPlan.enabled=false``safetyBoundary.phaseOneMutationAllowed=false`;禁止打开 SSH、PTY 或 stdio bridge。
轻量契约测试是:
```bash
bun scripts/host-codex-commander-no-daemon-smoke-contract-test.ts
```
该测试只执行 CLI dry-run 和短命 source-level handler/helper,不启动长期进程。
## HTTP
| Method | Path | 说明 |
| --- | --- | --- |
| GET | `/health` | 返回 service id、启动时间、state root 和日志文件 |
| GET | `/api/commander/contract` | 返回机器可读 contract |
| GET | `/api/commander/sessions` | 读取本地 session 摘要 |
| POST | `/api/commander/state` | 写入本地 session state |
| GET | `/api/commander/trace-summary` | 对 mock trace JSONL 做 dry-run 摘要 |
| POST | `/api/commander/trace-summary` | 读取 mock trace JSONL 并更新本地 session 状态 |
| POST | `/api/commander/approvals` | 生成 approval draft preview 并落盘 |
## State
状态根目录固定为 `.state/commander/`,至少包含:
- `sessions/<sessionId>.json`
- `events/<sessionId>.jsonl`
- `approvals/<approvalId>.json`
- `logs/commander.jsonl`
session 状态只保留 `unknown``discovered``planned``starting``running``attention_required``stopping``stopped``degraded`
## Trace summary
trace summary 输入 mock Code Queue trace JSONL 和可选 task summary,输出:
- `taskId`
- `sessionId`
- `lastSeq`
- `status`
- `keyEvents`
- `openQuestions`
- `recommendedNextActions`
- `redactionsApplied`
输出只做摘要,不返回 live transcript。
## Approval draft
高风险动作只生成 approval draft JSON / Markdown preview。preview 必须显示 redaction 结果,并明确 `sendImplemented=false`
## 进入真实运行态前
启用 daemon、PTY/stdio bridge、SSH bridge 或 ClaudeQQ 发送路径前,必须先获得人工授权。授权必须绑定一个精确 action 和目标 session/task/service,已有 smoke/skeleton contract 通过,风险审查确认不会打印 token、不会直接 patch 数据库、不会绕过 backend 确认策略,并且已有可审计的 approval id、回滚步骤和观测步骤。