Files
pikasTech-unidesk/docs/reference/code-queue-supervision.md
T
2026-05-20 17:34:33 +00:00

271 lines
32 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.
# Code Queue 指挥监督策略
本文定义在人工或 lead-agent 指挥官监督下,把 Code Queue 作为并行交付基础设施使用的长期运行模型。本文是协同策略,不替代 `docs/reference/microservices.md``docs/reference/observability.md``docs/reference/user-service-delivery.md` 或 Code Queue runtime 合同。
## 范围
当一个交付目标过大,无法由单个 Code Queue 任务完成,并且必须拆分到多个队列、服务或基础设施 lane 时,使用本策略。
本策略适用于:
- 用户服务 CI/CD 推广;
- 需要多个隔离 worktree 的跨服务修复;
- 用户服务开发过程中暴露出来的基础设施缺陷;
- 后续验证、retry、验收和任务接力协调;
- 指挥官为了保持 Code Queue 任务推进而做的手动监督工作,但不接管 worker 的具体实现。
本文不授权绕过正常部署、Git 或生产安全规则。
## 运行原则
指挥官对最终结果负责,Code Queue task 对边界明确的执行负责。
指挥官应维护交付目标、活跃队列、阻塞点、证据缺口和下一步恢复动作的实时地图。Code Queue worker 应收到自包含 prompt,prompt 中必须有足够上下文,不能依赖 GitHub issue 可见性或聊天历史。
集中指挥的目标是提升交付吞吐和可用性,而不是把每个缺陷都变成一次性的人工修补。
指挥官的最终目标是推动整体开发波次持续前进:跟踪队列进展、及时纠偏、审查完成质量,并安排下一轮任务,让交付计划持续复利式推进,而不是一批任务结束后停滞。
## 任务设计
每个 Code Queue task 都必须有清晰且狭窄的 ownership 边界。
- 尽量每个任务只负责一个服务、模块或基础设施缺陷。
- 每个任务使用共享 workspace 下自己的 detached worktree。
- 在 prompt 中直接写明写入范围、验证范围、提交/推送要求和禁止动作。
- 相关背景必须写进 prompt;issue 链接只能作为辅助引用,不能作为必要上下文。
- 优先复用已有队列;只有现有 lane 无法表达 ownership 边界时,才创建新队列。
- 队列并发必须受真实执行能力约束。通常目标是约 5 条并发 lane;当活跃任务写入范围彼此独立、heartbeat/trace 证据健康、成功率可接受时,指挥官可以把并发提高到约 10。若完成质量下降,应先降并发再继续扩张。
靠近生产的任务 prompt 必须明确禁止在 master server 上跑已知可能 OOM 的重型本地检查,并说明哪些验证应在 D601 CI、dev env 或目标服务容器中执行。
当一个指挥机需要突发创建大量 Code Queue 任务时,submit 默认应串行或接近串行。为了避免控制面在确认任务前被打爆,可以使用短本地锁或短延迟,尤其是在低内存主机上。目标是保持任务创建可观测且稳定,而不是最大化瞬时入队吞吐。
## 模型和成本路由
MiniMax/OpenCode runner 的可用性是 Code Queue 的主要能力方向之一。它不是可选实验项,而是控制 GPT-5.5 成本、扩大并发吞吐、让简单任务不占用高成本模型的基础设施能力。
指挥官派单时应按任务难度、风险和验收成本选择模型:
- 低风险、边界清晰、可用文件/命令/commit 直接验收的任务,优先分配给 MiniMax/OpenCode,例如只读调查、文档初稿、表格整理、轻量 CLI contract、局部测试补齐和小范围样板代码。
- 中等复杂度、需要跨文件判断但不触碰生产运行态的任务,可以在 MiniMax 可用且已有成功样本后尝试分担;prompt 必须更窄,验收证据必须更具体。
- 高风险任务继续优先使用 GPT-5.5,例如生产部署、凭证和网络变更、Code Queue/backend-core 运行态修复、跨模块架构调整、复杂回滚、以及最终质量裁决。
- MiniMax 任务不得降低验收标准。指挥官必须核验它声称读取的文件、执行的命令、远端 commit、测试输出和 live 证据;对推测、遗漏、伪造或把失败写成成功的情况,应拆小重派或改用 GPT-5.5。
MiniMax 路由策略的前置条件是 runner live smoke 稳定通过,并且失败能被结构化归类。若 MiniMax/OpenCode 本身不可用,相关修复归入 Code Queue 运行态维护线;在修通前,不应用 MiniMax 承担会阻塞主交付链路的任务。
## GitHub Issue 和 PR 使用
GitHub issue 是长期需求、缺陷、阻塞和决策的 source of record。聊天上下文、Code Queue final response 和指挥简报可以帮助恢复现场,但不能替代 issue 中的可检索记录。指挥简报自身也按 issue 主体维护,当前入口是 GitHub issue #24;后续只更新 #24 正文,不在评论区追加,且所有时间统一使用北京时间。
指挥官应在以下情况创建或更新 GitHub issue
- 新需求需要跨多个 Code Queue task、跨服务或跨部署阶段推进;
- 运行中发现可复用的基础设施缺陷,例如 CLI 能力缺口、凭证注入缺口、runner 局部观测误导、部署路径不可达;
- 任务完成但缺少远端 commit、live verification、dev/prod 部署证据等验收闭环;
- 某个手动临时绕行暴露出长期产品化需求;
- 战略、流程、发布线或 CI/CD 规则发生需要后续任务遵循的决策。
issue 内容必须自包含,至少写清楚背景、外部收益、当前观察、需求范围、非目标、验收标准和关联任务。不要只贴聊天摘要或只写“见某任务”;Code Queue worker 可能看不到 issue,也可能无法访问完整历史,因此 issue 是人类和指挥官恢复全局态势的记录,不是 worker prompt 的替代品。
如果某个 worker 任务需要依赖 GitHub issue 内容,但 runner 的 issue 可达性尚未被单独验证,指挥官不能默认 worker 已能读取该 issue。此时 worker prompt 必须直接内嵌完整需求、约束和验收点,issue URL 只能作为辅助引用。若要把 issue 作为任务输入源,先单独做可达性探测,再决定是否把 issue 作为常规前置条件。
GitHub issue/PR 操作应优先使用 UniDesk CLI 的安全入口:`bun scripts/cli.ts gh auth status``gh issue list/view/create/update/comment create/comment delete/close/reopen/scan-escape/cleanup-plan``gh pr list/view/create/update/comment create/comment delete/close/reopen`。该入口默认 repo 是 `pikasTech/unidesk`,支持 `--repo owner/name`,输出稳定 JSON,并把 `missing-binary``missing-token``auth-failed``network-proxy-failed``permission-denied``repo-not-found``repo-forbidden``issue-not-found``pr-not-found``scope-insufficient``validation-failed``invalid-response``unsupported-command` 等失败原因结构化。失败对象必须包含 `runnerDisposition=infra-blocked|business-failed`,runner 应用它区分基础设施阻塞和业务/参数失败。`gh issue list --state open --limit N --json number,title,state,url` 是有界 issue 发现入口,`--state` 只接受 `open|closed|all`list 字段白名单是 `number,title,state,url,updatedAt,createdAt,author,labels`;未知 state 或未知字段必须失败,不能静默返回空数组。`gh issue view <number> --json body` 是兼容入口,正文仍应从 `.data.issue.body` 读取;未知 `--json` 字段必须失败,不得让调用方把空正文误判为读取成功。`gh issue scan-escape --limit N [--dry-run]``gh issue cleanup-plan` 只读扫描 issue body/comments 的字面量 `\n`、shell escape、短 body、blank/null body,输出 `classification=suspected-pollution|explanatory-mention|risk`、body/comment id、预览和清理建议;说明性提到 `\n` 不应被当成污染,cleanup-plan 永远不真实清理历史评论。`gh pr list|view --json ...` 支持 `body,title,state,number,url,author,head,base,draft,createdAt,updatedAt` 字段白名单。issue/PR 创建、更新、评论、评论删除、关闭和重开使用 GitHub REST API;只要有 `GH_TOKEN``GITHUB_TOKEN`,就不依赖系统 `gh` binary。`gh` binary 只作为状态探测和 `gh auth token` fallback,不是写操作的主路径。GitHub 不支持 issue/PR 硬删除,`gh issue delete``gh pr delete` 必须结构化返回 `unsupported-command`;生命周期删除语义使用 `close``gh pr merge` 仍然不开放。
CLI 是短 shout 的需求原语,不是长驻服务器进程。CLI 功能不好用、兼容性不足、安全 guard 不够或输出不利于 runner/指挥官使用时,应默认创建 GitHub issue 并用 Code Queue 推进;这类 CLI 问题走 `master`、remote commit、轻量 contract test 和文档更新,不套用 backend-core、Code Queue runtime 这类运行态服务的重部署门禁。若 CLI 缺陷已经阻塞当前指挥,可以先做最小安全绕行,同时把长期修复写入 issue 并派单。
所有 GitHub Markdown 正文写入必须来自 `--body-file <file>`。不要使用 `gh issue comment --body``gh api -f body=...` 或把多行正文直接拼进 shell 参数;这些路径容易把真实换行、反引号和 Markdown 表格污染成字面量 `\n` 或 shell escape。从 shell 生成正文文件时使用 quoted heredoc,例如 `cat <<'EOF' > /tmp/body.md`,保证反引号和反斜杠不被展开;JSON 请求体场景优先使用对应 CLI 的 `--body-file``--body-stdin`,不要把长 JSON 塞进命令行参数。`gh issue` 写命令不接受 stdin 正文;需要更新 #20 总看板或创建新 issue/comment 时,先把正文写入 Markdown 文件,再运行 `bun scripts/cli.ts gh issue update|comment create|create ... --body-file <file>``gh issue update --mode replace|append --body-file` 是主更新入口,`edit` 只是兼容别名;`append` 会先读取当前正文再追加文件字节,保留真实换行、反引号和 Markdown 表格,不走 shell 拼接。`gh issue update --body-file` 默认拒绝 `null`、空白和过短正文;#20 自动要求 `## 看板(OPEN`#24 自动要求 `## 常驻观察与长期建议`。更新 body-only issue 前优先跑 `--dry-run`,查看旧/新正文长度、body SHA、关键标题、字面量 `\n` 和 shell 污染信号;正式写入长期正文时优先带上 `--expect-updated-at``--expect-body-sha`,避免旧缓存覆盖新正文。#24 指挥简报是长期记录入口,更新正文时默认只写 GitHub issue,不自动向 ClaudeQQ 推送;如确需提醒用户,按本文的 ClaudeQQ 通知门槛单独发送。提交前或巡检时可用 `gh issue scan-escape --limit N --dry-run``gh issue cleanup-plan --limit N` 只读扫描污染并生成建议,不自动修复。
PR 是审查型交付入口,不是所有 Code Queue 任务的默认出口。默认 master-only 交付仍按项目 Git 规则执行;当变更风险高、跨模块、需要人工审查、或任务目标明确要求 PR 交付时,worker 可以创建 PR。PR 型任务必须报告源分支、目标分支、PR URL、关联 issue、测试证据和未完成风险。禁止把 PR 当成隐藏分支仓库;PR 分支必须来自最新目标线,保持小而可审查,并在合并后确认目标分支远端 commit 可 fetch。
PR 支持本身是 Code Queue 能力的一部分。当前 UniDesk CLI 支持 `gh pr list|view|create|update|comment create|comment delete|close|reopen`,其中 create 需要显式 `--title``--base``--head` 和正文来源,update 需要显式 PR number、正文来源和 `--mode replace|append`comment create 需要显式 PR number 和正文来源,且推荐使用 `--body-file``pr create --dry-run``pr update --dry-run``pr comment create --dry-run` 只返回 planned operation,不创建 PR、不更新正文、不写评论;非 dry-run 创建前会校验 repo、base、head 和 compare ahead 状态,append 更新会先读取当前 PR body。`gh pr delete``gh pr merge` 仍是后续范围,本阶段没有 `--confirm` 可以启用真实 merge,也不能伪造硬删除;需要移除活跃 PR 时使用 `gh pr close`。普通 worker 不应隐式依赖未实现的 PR 合并能力;需要 PR 交付时,prompt 必须明确允许的人工或后续工具路径,并报告未覆盖范围。
### PR 驱动派单模板
PR 驱动是 Code Queue 协作的未来默认方向:worker 在独立 head branch 上提交,创建面向目标分支的 PR,指挥官审查后再合并并更新 issue/#20/#24。当前仍处于 runner GitHub 可达性补齐阶段;在 #19 的 runner GitHub 可达性未验收前,派单 prompt 必须自包含完整需求、约束、写入范围和验收标准,不能只贴 GitHub issue 链接。issue URL 只能作为辅助引用。
PR 型派单 prompt 至少包含以下字段:
- `目标 issue`:写明 issue 编号、URL 和本次任务要关闭或推进的验收点;不要假设 runner 能读取 issue。
- `目标分支`:明确 `master` 或经批准的维护分支;普通开发集成使用 `master`
- `head branch`:使用可追踪命名,例如 `code-queue/issue-35-pr-dry-run-probe``code-queue/issue-<number>-<short-topic>` 或包含 task id 的等价短名;head branch 必须从最新 `origin/<目标分支>` 创建。
- `禁止动作`:禁止直接 push 目标分支,禁止 merge PR,禁止改 release/v1 运行态服务,禁止输出 token,禁止跑本任务未要求的重型 check/e2e/Playwright。
- `必须动作`:提交前运行轻量自测;push head branch;创建面向目标分支的 PRPR body 写清关联 issue、修改文件、验证命令和风险;若创建 PR 前需要探测,先运行只读或 dry-run preflight。
- `final response 字段`:实际分支、目标分支、head branch、PR URL、远端 head commit、是否已创建 PR、是否未 merge、修改文件、验证命令和结果、遗留风险;如果 PR 未能创建,报告结构化原因和 runnerDisposition。
PR 型 prompt 可直接嵌入以下 Git 指令约束:
```text
Git/PR 交付要求:
- 目标分支:master。
- 从最新 origin/master 创建 head branchcode-queue/issue-<number>-<short-topic>。
- 不得直接 push master 或 release/v1。
- 必须 push head branch 并创建 PR 到 master;不得 merge PR。
- 创建 PR 前先运行只读/dry-run preflight,确认 GH_TOKEN/GITHUB_TOKEN、GitHub egress 和 repo 可见性,不得打印 token。
- final response 必须报告 head branch、PR URL、远端 head commit、修改文件、验证命令、是否未 merge。
```
Runner preflight 示例:
```bash
bun scripts/code-queue-pr-preflight-example.ts --repo pikasTech/unidesk --base master --head code-queue/issue-35-pr-dry-run-probe --comment-pr 1
```
该脚本只读调用 `gh auth status`,并执行 `gh pr create --dry-run``gh pr comment --dry-run`。它检查 `GH_TOKEN/GITHUB_TOKEN` 是否存在、GitHub REST egress 是否可达、repo 是否可见,并且只输出 token 来源和存在性,不输出 token 值。`--comment-pr` 只是 dry-run 计划中的 PR number,不会写评论。
指挥官审查 checklist
- PR base 是声明的目标分支,head branch 命名可追踪,远端 head commit 可 fetch。
- diff 只覆盖派单 ownership,未混入 release/v1 运行态服务或无关 dirty worktree。
- PR body 和 final response 都包含关联 issue、修改文件、验证证据、未完成风险和未 merge 状态。
- contract/dry-run 证据覆盖本次 PR 能力:`pr create --dry-run``pr list/view``pr comment --dry-run`,并确认 `gh pr merge` 返回结构化 unsupported。
- 没有 token、凭证、临时日志或构建产物进入 commit、PR body 或评论。
- 合并前由指挥官审查并决定是否 merge;合并后再验证目标分支远端 commit 可见,并按态势更新 issue/#20/#24
## 监控
指挥官必须用 task 级和 queue 级证据监控 Code Queue,不能只看单一状态字段。
常用入口:
- `bun scripts/cli.ts codex tasks --view supervisor --limit N`:查看默认有界监督视图,包括 running、完成未读、最近完成、queued/runnable、execution diagnostics 和下一步 drill-down 命令。
- `bun scripts/cli.ts codex queues`:查看低噪声队列计数、active task id、完成未读队列、runnable 队列和控制面诊断;只有需要完整队列行时才加 `--full`
- `bun scripts/cli.ts codex tasks --unread --limit N`:查看完成未读审阅积压;`--unread``--unread-only` 等价,不能被静默忽略。
- `bun scripts/cli.ts codex tasks --status succeeded --unread --limit N`:按具体终态过滤监督结果;不支持的 status filter 必须显式失败,不能扩大为未过滤结果。
- `bun scripts/cli.ts codex task <taskId>`:默认只查看原始 prompt、最终 response、最后错误和 drill-down 命令,这是完成未读任务审阅的第一步。
- 当默认审阅摘要不足时,再逐级使用 `bun scripts/cli.ts codex task <taskId> --detail``bun scripts/cli.ts codex task <taskId> --trace --limit N``codex output`
- 当 master 控制面状态和 D601 scheduler 状态看起来分裂时,使用 `docs/reference/observability.md` 中的活性规则判断。
默认 supervisor 视图必须保持低噪声。每个任务应带 `commands.show``commands.trace``commands.output``commands.full``commands.read`,让下一步渐进披露动作明确;默认不得嵌入完整 queue 列表、完整 final response、raw output 页或完整 trace 行。`commands.read` 只是在人工审阅后的建议命令,listing 命令绝不能自动执行。
完成未读任务的审阅也必须遵循渐进披露。指挥官默认只拉取原始 prompt 和最终 response,用它判断任务是否声称完成、是否有明显越界、是否缺少验收证据;不要默认拉完整 trace、全量 tool summary 或 raw output。只有当 final response 与目标不一致、证据不足、远端 commit 无法验证、任务疑似造假、或需要追溯失败原因时,才继续展开 `--detail`、分页 `--trace`、或按 seq 读取 `codex output`。这条规则的目标是降低上下文压力,同时保留通过多步查询拿到完整证据的能力。
队列诊断中的 `split-brain` 表示控制面/执行面观测分裂,不自动证明任务已经死亡。只要任务 heartbeat 还在刷新、trace 仍在推进,就不能把它判成服务中断或要求立刻 stop;应把它视为 `splitBrainLive=true` 的 live 任务,继续监督并推进 #20 里的已排任务,而不是 interrupt、替换或把 backend 当成已经挂掉。队列摘要应显示 `effectiveLiveness=live``splitBrainLive=true``recommendedAction=continue-supervision`;只有 heartbeat expired/missing 或满足 stale-recovery 条件时,才应显示 `effectiveLiveness=at-risk` 并进入恢复判断。
单次 `provider is not online`、SSH 超时、proxy 超时或 registry 请求失败只能证明“当前观察路径失败”,不能单独升级为 D601 全局离线、CI/CD 全局阻塞或业务任务不可推进。指挥官和 runner 必须用多信号裁决运行面状态,至少区分以下观察面:
- backend-core 节点视图和 provider heartbeat,例如 `debug health` 中的 D601 `status``lastHeartbeat` 和 gateway 版本;
- Host SSH / WSL SSH 维护桥,例如 `ssh D601 hostname` 或短 argv 命令;
- D601 artifact registry health、k3sctl-adapter health、目标 microservice health
- Code Queue scheduler heartbeat、任务 heartbeat、trace/output 是否持续入库;
- 当前 runner 容器内 CLI/proxy 路径是否只是局部不可达。
只有多个独立观察面同时失败,或同一关键路径在明确时间窗口内持续失败,才能把问题判为全局阻塞。否则应记录为 transient 或 runner-local observation gap,优先重试、steer 任务纠偏或拆出基础设施 follow-up;不得让业务 worker 把单次局部失败作为最终 blocker。CLI 和 runtime 后续应把错误输出结构化为 `scope=runner-local|provider-gateway|ssh|registry|k3s|scheduler|service-proxy``observedAt``retryable` 和建议的交叉验证命令。
ClaudeQQ 是面向用户的主动提醒通道,不是 #24 简报更新的自动转发器。指挥官只应在三类情况下自主发送 ClaudeQQ 消息:核心服务或关键执行面宕机且需要用户知情,高风险决策需要用户请示,或出现里程碑式进展值得同步。消息必须简明扼要,一次不超过 200 个中文字符,写成一段话,不使用 Markdown 语法。普通轮询、普通 issue 更新、普通 #24 简报追加、外部 token provider 正常限流、以及无用户动作要求的中间状态,不发送 ClaudeQQ。发送失败只记录到 #24 或对应 blocker issue,不回滚已经完成的 GitHub issue 更新。
重启 Code Queue backend、重建 Code Queue backend 容器、重启 Code Queue 执行面,或对运行中 Code Queue 任务执行 interrupt/cancel 这类会改变执行状态的操作,都属于高风险干预。即使看起来是最小恢复动作,指挥官也必须先通过 ClaudeQQ 向用户上报原因、影响范围和拟执行动作,并等待用户明确同意;未获得同意前只能做只读诊断、记录 issue、更新看板和准备恢复方案。
当多信号裁决显示 provider 服务器、D601 执行面或关键维护桥疑似需要人工检查时,指挥官可以在更新 #24/#40 等记录之外,通过 ClaudeQQ 额外提醒用户检查 provider 服务器状态。提醒只在首次确认、状态恶化、恢复或需要用户介入时发送,不能在每轮轮询中重复轰炸。ClaudeQQ 提醒是 best-effort:若 ClaudeQQ 本身依赖同一条故障 provider/k3sctl 链路而不可达,指挥官应把通知失败的原因写入 #24 或对应 blocker issue,并继续按轮询和恢复规则推进。
在 UniDesk CLI 中,`bun scripts/cli.ts provider triage <providerId>` 是只读多信号裁决入口,适合作为 worker 和指挥官的统一健康判断前置。它必须至少保留这些合同:`provider is not online` 这类单路径失败只应落到 `runner-local-observation-gap`,不得直接输出 `global-blocker`;只有 provider-gateway/SSH/k3s/scheduler 等多个独立关键路径同时失败,才允许输出 `global-blocker`registry 或单个 service proxy 失败但 heartbeat、SSH 或节点视图仍健康时,应输出 `service-degraded``provider-degraded``recommendedCrossChecks` 必须包含 `debug health``debug dispatch <providerId> host.ssh --wait-ms 15000``ssh <providerId> argv true``artifact-registry health --provider-id <providerId>``microservice health k3sctl-adapter``microservice health code-queue``codex tasks --view supervisor --limit 20`
对于 trace 或 heartbeat 新鲜的长任务,通常应保持运行。每几分钟轮询一次优于反复 interrupt/retry。
外部 token provider、模型 API 或上游服务的限流和短时不可用是正常预期,不应自动升级为 Code Queue 基础设施缺陷。典型表现包括 `429 Too Many Requests`、provider transient error、上游 timeout 或模型服务短时失败。只要 Code Queue 的状态机仍在自动指数退避,task heartbeat 或 scheduler heartbeat 新鲜,且任务仍能从 `retry_wait` 回到 `running`,指挥官应等待外部 provider 自行恢复,不创建额外修复 issue、不重派重复任务、不把该现象写成 blocker。只有当退避机制失效、任务丢失、heartbeat 过期、状态机卡死,或重试耗尽进入不可恢复终态时,才按 Code Queue 基础设施问题介入。
对于大规模 CI/CD 迁移波次,除非发生事故,否则使用稳定但可自适应的监督节奏。指挥官可以根据任务活跃度、完成未读积压、heartbeat 风险和外部等待性质自行决定 sleep 时长,但单次 sleep 不能低于 5 分钟、不能高于 30 分钟。活跃排障、刚派出新任务、存在完成未读或 heartbeat 风险时使用接近 5 分钟的短轮询;长时间等待外部 CI、模型 provider 退避或镜像构建且 heartbeat 新鲜时,可以拉长到 10 到 30 分钟。每轮醒来后读取 `codex queues`,读取 terminal 或可疑任务摘要,然后决定接受、retry、拆分 blocker,或让健康任务继续运行。循环期间指挥官可以做不重叠的有用工作,例如文档或 issue 梳理,但这些辅助工作不能接管 worker 已分配的实现。
当任务离开 `running``judging` 后,其结果仍然是未读工作。指挥官必须检查 final response 和 judge 记录,然后再决定是否补充并发窗口。
禁止在检查前用批量 read 动作清空完成未读任务。每个完成任务必须先单独审阅,再用 `bun scripts/cli.ts codex read <taskId>` 单独标记已读,使未读状态继续代表“仍需审阅”。
每次新增 Code Queue 任务、补发 follow-up task,或处理一批完成未读任务后,都必须同步更新 GitHub 总看板 issue `#20` 的正文主表;如果发生实质态势变化,还要同步更新指挥简报 issue `#24` 的正文。看板更新应反映当前任务分布、关键 blocker 和粗略进度,不要只改聊天上下文或只改单个 issue,而让总态势图落后于实际调度状态。
## 指挥工作流
对每个活跃任务,按顺序评估四件事:
1. 完成质量:是否真的满足任务验收边界;
2. 完成状态:是否已经终态、可 retry,或仍在推进;
3. 自阻塞风险:任务是否卡在它自己无法解决的问题上;
4. 下一步动作:接受、继续、替换为更窄任务,或上报基础设施问题。
如果 blocker 是可复用的基础设施问题,不要盲目反复重跑业务任务。应先把基础设施缺陷记录到 issue,再在 Code Queue 无法越过时手动修复基础设施,然后恢复交付波次。
指挥官应优先做只读分析和派发新的窄范围任务,而不是本地接管实现。手动工作只保留给基础设施 blocker、live recovery,以及队列无法安全自解的问题。
## 干预规则
只有存在明确理由时才干预。
- 如果任务还在运行且 trace 或 scheduler heartbeat 新鲜,应引导而不是 interrupt。
- 对运行中任务的引导应优先使用正式 CLI:`bun scripts/cli.ts codex steer <taskId> --prompt-file <path>`。该命令和 `codex task/tasks/read` 复用同一个 backend-core stable proxy helper`--dry-run` 会显示 `method/path/stableProxyPath`、prompt 摘要和 raw proxy 等价命令但不发送。非 dry-run 失败时先看 `.data.diagnostics.reason``backend-core-unreachable` 属于本机到 core 的观察路径,`code-queue-microservice-unregistered`/`proxy-unauthorized`/`proxy-404` 属于 stable proxy 配置或权限,`steer-endpoint-404`/`upstream-runtime-rejected` 属于 D601 runtime 或任务状态,`stable-proxy-failed` 多为 provider/k3s/tunnel 链路问题。若正式 CLI 自身不可用,临时通过受控 microservice proxy 调用只能作为现场恢复手段;这类绕行必须记录到指挥简报 issue #24 主体的常驻观察,并创建正式 issue 补齐 CLI 能力,避免长期依赖隐式 API。
- 如果任务进入终态但缺少必要验收证据,应使用聚焦 continuation prompt retry 同一任务。
- 如果任务被可复用基础设施缺陷阻塞,应把该缺陷分配给合适的空闲或低风险队列,让原业务任务等待,或在修复后 retry。
- 如果基础设施缺陷影响 Code Queue 控制面可用性,指挥官可以执行恢复队列所需的最小受控部署,然后验证原任务能继续。
- 如果 retry、cancel、move 或 scheduler 行为错误,不要把手动 patch PostgreSQL 当作最终修复。应修复代码路径,必要时部署,然后通过正常 API 恢复受影响任务。
上一条中的“最小受控部署”不包括未经用户同意的 Code Queue backend 重启、容器重建或运行中任务 interrupt/cancel。凡是会改变 Code Queue backend 或执行中任务状态的恢复动作,必须先走 ClaudeQQ 请示;没有用户明确同意时,指挥官只能继续只读观察、拆出基础设施 issue、准备恢复命令和等待授权。
手动干预应尽可能保留原任务身份,以保持上下文连续。创建重复替代任务是 fallback,不是默认动作。
## 完成标准
Code Queue task 不是只要 push 代码就算完成。
对于 CI/CD 交付任务,验收必须包含目标交付策略要求的证据。对用户服务 artifact 交付,这意味着:
- CI artifact producer 从已推送 commit 运行;
- artifact ref 和 digest 已记录;
- dev 环境消费同一个 artifact
- production CD 消费 artifact,且没有源代码 rebuild
- live health、live commit 或 image label 证据与请求 commit 匹配。
对于基础设施任务,验收必须证明原本被阻塞的 workflow 可以继续,或明确说明 live 系统消费该修复还缺哪个部署步骤。
完成未读任务仍然是指挥官工作。它们必须被阅读、分类,并被接受、retry,或转成新的窄范围 follow-up task。
## 基础设施缺陷处理
交付计划中发现的基础设施缺陷,只要拆分后能提高吞吐或减少混乱,就应从用户服务工作中拆出来。
基础设施缺陷示例:
- retry API 遗留 stale cancellation state
- healthcheck 不再匹配 runtime image
- CLI 可观测性无法快速看到 running、最近完成或完成未读任务;
- WebUI 和 CLI 的 proxy 路径不一致;
- deploy job 报失败但服务 API 实际健康;
- 指挥侧突发 submit 打满 Code Queue manager 或低内存主机,导致队列还没确认任务就被压垮;
- Code Queue 容器缺少监督所需的基础工具或凭证路径,例如 `gh``hub` 或 GitHub token 注入路径。
- D601、provider-gateway、registry、k3sctl-adapter 或 service proxy 的单路径瞬时失败被 worker 放大为全局阻塞,而缺少多信号健康裁决和可重试错误分类。
这些缺陷应分配给基础设施队列,prompt 中要包含具体观测失败、期望长期合同,以及原交付任务继续所需的恢复动作。
如果缺陷只存在于 Code Queue 执行环境,且服务可以在 dev 中安全热修而不触碰 prod,应先做最小临时 live remedy。然后把修复持久化到相关 Dockerfile、容器镜像或凭证传播路径,并在 dev 验证持久化修复后再关闭问题。
如果业务任务发现缺少工具或凭证路径,指挥官应把它拆成独立 infra task,而不是埋在业务任务 prompt 中。业务任务在 bridge 存在时应继续推进。
## 指挥边界
指挥官可以:
- 读取 task、queue、health、job 和 service 状态;
- 通过正常 Code Queue 和 microservice proxy API submit、retry、interrupt 或 cancel
- 创建自包含 follow-up task
- 在用户允许生产修复且部署路径已验证时,为基础设施恢复执行受控生产部署;
- 当 main worktree 有无关并行变更时,为文档或受控部署动作使用干净 detached worktree。
指挥官自己的 UniDesk 指挥仓库必须保持在单一根 worktree 的最新 `master` checkout 上。不要为指挥、队列判断或日常监督创建额外 worktree,这样指挥官始终看到当前仓库头和生产协调依赖的同一份实时状态。如果 worker 或受控一次性操作需要隔离 worktree,该 worktree 属于 worker 或具体操作,不属于指挥官的常驻环境。
每个由指挥官派发的 worker prompt,都必须在 Git 指令前明确写明目标线。`master` 用于主动开发和集成工作;`release/v1` 只用于明确批准的稳定维护修复。worker 的 final response 必须报告实际推送分支、远端 commit hash,以及该 commit 是否可从 `origin/<target-branch>` 获取。如果 final response 引用的 commit 不能被指挥官从声明的目标分支 fetch 到,该任务不得验收为完成。
指挥官不得:
- 本地重做 worker 已分配的实现,除非用户明确要求手动接管;
- 在 master server 上跑已知可能 OOM 的 full check、full e2e 或 Playwright
- 回滚无关 dirty worktree 变更;
- 在 Git 远端是 source of truth 时,把本地部署状态当作 source of truth
- 在缺少验收证据时宣布交付完成。
## 文档反馈回路
每个重复出现或阻塞交付的问题,都应反馈到以下至少一个位置:
- 修复该缺陷的 Code Queue task
- 记录阻塞条件和恢复依赖的 GitHub issue 或 issue comment
- 当经验具有长期复用价值时,写入长期参考文档。
长期参考文档应记录可复用规则,而不是完整事故流水账。过程知识应降低未来监督成本,而不是变成又一个一次性日志。