如果 GitHub issue 是 AI 可执行合同,那么 label、branch 和 comment 就是这个合同的运行时状态。
很多 AI coding workflow 的问题,不是 agent 不会改代码,而是状态不清楚:这个 issue 是否已经被 claim?当前是在 triage、implement、PR review,还是 release verification?失败是测试失败、需求不清,还是已经有人接手?
这些状态如果只存在聊天里,很快就会丢。
一个实用的做法,是把 GitHub 本身当成轻量状态机。
Label 负责可见状态
Label 的优点是可见、可筛选、适合 human 和 automation 共用。
一组最小 label 可以是:
ai:needs-triage
ai:triaged
ai:analysis-only
ai:ready-for-worker
ai:claimed
ai:working
ai:evidence-ready
ai:pr-opened
ai:needs-human
ai:blocked
ai:done
这里最重要的不是 label 名字,而是互斥语义。
一个 issue 不应该同时处于 ready-for-worker 和 working。也不应该一边是 needs-human,一边又被 worker 继续实现。
如果 label 只是随手贴的标签,它们没有状态机价值。只有当 label 表示明确生命周期阶段时,它们才真正有用。
Branch 负责 claim lock
Label 不适合做锁。
两个 worker 可能几乎同时看到同一个 issue 都是 ready-for-worker,然后都开始工作。哪怕其中一个随后把 label 改成 working,另一个也可能已经启动。
所以需要 branch claim。
例如:
ai/issue-123-refresh-status-badge
这个 branch 的意义不是代码分支本身,而是“这个 issue 已经有一个 worker 拿到了执行权”。
推荐规则很简单:
- 一个 issue 只能有一个 active claim branch;
- worker 改代码前必须检查 branch 是否已存在;
- branch 已存在时,新的 worker 应停下来或只做 analysis;
- claim branch 的名字应该能反查 issue。
Label 告诉人“状态是什么”。Branch 告诉系统“谁已经拿到执行权”。
Comment 负责审计轨迹
Label 太短,branch 太隐式。状态变化背后的理由,需要 comment。
每次 worker pass 结束,都应该留下短评论:
Worker state: evidence-ready
Branch: ai/issue-123-refresh-status-badge
Summary: updated dashboard refresh handling
Evidence: npm test -- dashboard-refresh.test.ts
Risk: UI-only; no API contract change
Next: human PR review
这个 comment 有三个作用。
第一,它让 human reviewer 不需要翻聊天记录。
第二,它让下一个 worker 可以恢复上下文。
第三,它让状态机可以对账:label 说 evidence-ready,comment 也说明 evidence 在哪里,PR body 也能引用同一份证据。
三者不要互相替代
一个常见错误,是只用 label。
只用 label,状态可见,但缺少锁和原因。
另一个错误,是只用 branch。
只用 branch,可以避免并发冲突,但 human 很难从 issue 列表判断进度。
还有一个错误,是只用 comment。
只用 comment,审计信息完整,但 automation 很难高效筛选状态。
更稳定的组合是:
- label 表示当前阶段;
- branch 表示 claim lock;
- comment 表示状态变化原因和下一步。
这三者加起来,才是一个轻量但可用的 AI 工程状态机。
不要追求过度精细
状态机不应该一开始就设计成几十个状态。
过度精细会让 human 不愿意维护,也会让 automation 频繁出错。第一版只需要覆盖几个核心问题:
- 这个 issue 是否允许 AI 处理?
- 是否已经 triage?
- 是否已经被 claim?
- worker 是在分析、实现,还是等待 human?
- 是否已有 evidence?
- PR 是否已经打开?
- 发布或生产验证是否还没完成?
只要这些问题能被 GitHub 状态回答,你就已经从“聊天驱动 AI”前进到了“状态机驱动 AI”。
