Files
pikasTech-unidesk/docs/reference/host-codex-commander.md
T

151 lines
14 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,不接管人工指挥官。高风险 Code Queue recovery 的 ClaudeQQ 审批在本阶段只生成 200 字以内中文纯文本草案和 backend-core proxy 命令,不走本机 skill、powershell 或本地 ClaudeQQ server。
当前允许存在一个 operator-run 的高鲁棒 stdio 保活形态,用于在人工授权下让 host Codex 持续承担指挥官工作。该形态不是仓库内正式 daemon,也不替代 skeleton contract;它应被视为过渡运行方式,后续产品化仍必须回到本文件的 contract、state、approval 和安全边界。
## 边界
- `host-codex-commander` 是独立的本地 skeleton,不是运行中的 live daemon。
- 只允许本地文件状态、trace 摘要和审批草案预览;审批通知草案必须是 200 字以内中文纯文本,不使用 Markdown。
- 所有输出必须 redaction token/secret/URL credential。
- 不得重启或接管 Code Queue backend,不得 cancel/interrupt 运行任务,不得打印 token 明文。
- ClaudeQQ 正式发送未在 skeleton 中实现;如后续获得授权,唯一允许路径是 UniDesk backend-core microservice proxy`bun scripts/cli.ts microservice proxy claudeqq /api/push/text --method POST --body-json '<payload>' --raw`
- 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。
- `pikasTech/unidesk#20` 只作为 UniDesk commander / Code Queue / CLI / infra governance 入口;HWLAB 用户和产品 issue 必须路由到 `pikasTech/HWLAB`,不能作为 #20 看板行维护。
## 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]
bun scripts/cli.ts commander prompt-lint --kind gpt55-pr (--prompt-file <file>|--stdin)
```
`plan``smoke``approval request` 必须显式使用 `--dry-run`,缺失时返回 `error=dry-run-required`
`commander prompt-lint --kind gpt55-pr` 是指挥官派 GPT-5.5 PR/收口类任务前的本地辅助检查。它只读取 `--prompt-file``--stdin`,返回结构化 JSON 字段 `ok``missingClauses``riskLevel``suggestedPatchSnippet``promptShape.textEchoed=false``policy.advisoryOnly=true`;不会提交 Code Queue task、不会修改 scheduler、不会访问 live service,也不会回显完整 prompt。即使 lint 发现缺失条款,CLI envelope 仍保持成功退出,调用方应把 `data.ok=false` 当作派单前修补建议,而不是业务 PR 门禁或 `codex submit` admission 规则。
`gpt55-pr` 当前检查的硬边界包括:普通 PR 创建/更新、自合并/关闭、rebase/update/冲突处理授权;repo-owned CI/CD、build/publish artifact、DEV image/artifact tag/digest/report 授权;DEV deploy apply、rollout 和 live health verification 默认由 host commander 统一执行;未显式包含 `ROLLOUT_OK` 时 runner 不得竞争 DEV CD lock、deploy apply、rollout 或 live verification;禁止 PROD mutation、密钥读取/打印、数据库手工写入和破坏性回滚。缺失时 `suggestedPatchSnippet` 只给可追加的边界片段,不包含原 prompt。
## 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 和创建 PR;当 GPT-5.5 runner 的 prompt 明确包含普通 PR 收口授权,且 PR 不涉及 prod/runtime/release/security/database/破坏性回滚、无冲突并通过任务要求检查时,runner 可以自行用 repo-owned GitHub merge/close 路径完成收口并报告 SHA。高风险、边界不清或用户/指挥官保留 final action 的 PR 仍由 host commander 审查。
DEV 发布职责必须区分镜像构建/发布与滚动上线。runner 可以在任务内完成实现、验证、PR、自合并、镜像构建、artifact publish 和报告镜像 tag/digest;同一 DEV 环境的 rollout/apply/verify owner 默认是 host commander。host commander 应在已构建镜像和 artifact 证据就绪后,通过 repo-owned 的唯一 DEV CD 入口和发布锁执行滚动上线、等待 rollout、复核 live health,并更新对应 issue/看板。除非 prompt 明确授权,runner 不应自行竞争 DEV CD lock、重复执行 deploy apply 或发起互相覆盖的 rollout。
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``dryRunNoClaudeQqSend=true``notificationDraft.message` 为 200 字以内中文纯文本、`notificationPath.error=notification-path-unavailable`,并返回 backend-core `microservice proxy claudeqq /api/push/text` 命令;禁止 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`
`commander approval request --dry-run` 的 ClaudeQQ 字段必须包含:
- `notificationDraft.message`:给用户看的 200 字以内中文纯文本审批草案,一段话,不含 Markdown。
- `dryRunNoClaudeQqSend=true`:确认 dry-run 不发送。
- `notificationPath.error=notification-path-unavailable`:说明当前 skeleton 未开放真实发送。
- `notificationPath.backendCoreProxyCommand`:授权后才可执行的 repo-owned 发送命令,路径固定为 `bun scripts/cli.ts microservice proxy claudeqq /api/push/text --method POST --body-json '<payload>' --raw`
不得使用 `/root/.agents/skills/claudeqq``powershell.exe`、本地 skill server 或 9082 端口作为高风险审批通知路径。若 backend-core ClaudeQQ proxy 发送失败,失败必须结构化为 `notification-proxy-failed` / `microservice-proxy-failed`,不得打印 token,不回滚已经完成的 GitHub issue 更新;指挥官应把失败原因写入 #24 或对应 blocker issue。
## 进入真实运行态前
启用 daemon、PTY/stdio bridge、SSH bridge 或 ClaudeQQ 发送路径前,必须先获得人工授权。授权必须绑定一个精确 action 和目标 session/task/service,已有 smoke/skeleton contract 通过,风险审查确认不会打印 token、不会直接 patch 数据库、不会绕过 backend 确认策略,并且已有可审计的 approval id、回滚步骤和观测步骤。ClaudeQQ 发送只能通过 backend-core `/api/microservices/claudeqq/proxy`,并设置超时和结构化失败输出。