R-P2-9 治理无号提交(不追溯历史,只管新增): 1. 判据单一来源 scripts/check-commit-issue.sh: - --message-file(本地 hook)/ --range(CI)/ --head-only(CI 回退) - 放行:信息含 #数字、显式 [skip-issue]、merge 提交;违规逐条列出后退出 1。 - 临时 git 仓正/负/区间/空区间/skip/merge/--no-verify 全部实测。 2. scripts/install-commit-msg-hook.sh:安装 .git/hooks/commit-msg 调用判据脚本 (与 gitleaks pre-commit 独立;判据随仓库更新无需重装)。 3. .gitea/workflows/test.yml 新增 commit-message-lint 轻量 job(纯 git 不依赖 docker): push 用 before..after、PR 用 base..head;两端不可达/新分支/force-push 回退仅查 HEAD, 保证不误阻断主干。 4. docs/standards/issue-workflow.md §1.5 + README 补提交规范与钩子安装说明。 5. 台账新增 §十七,据 Gitea API + git log 考据补录 #191~#197: #192/#194/#195/#197 closed 且均有关闭凭证评论;#191/#193/#196 open(附 commit/文档依据)。 R-P2-9 回填已完成。
13 KiB
工单驱动工作流规范(Issue Workflow)
性质:元需求(META)—— 约束"所有任务怎么流转" 生效日期:2026-09-03 适用范围:所有任务(含需求、事故、治理、缺陷、运维动作),不论由人还是 AI 执行 关联文档:AGENTS.md(全局约束)、task-work-order.md(AI 派工单模板)、arch/README.md(架构锁定流程)、review-checklist.md(审查清单)
目的:把「任务」统一收敛到 Gitea issue 工单,作为唯一入口与闭环凭证,杜绝口头驱动、散文档驱动、无痕开发。 背景:2026-09-02
cs_records接待数据缺口事件暴露「有审计、有文档、但无工单跟踪」的断层——审计结论与设计建议没有进入可跟踪的工单,导致治理无法闭环。
一、铁律
- 所有任务必须先建工单,再动手。禁止无工单开发、无工单运维、无工单改数据。
- 工单是唯一入口与唯一闭环凭证。口头/聊天/文档只能作为补充说明,不能替代工单。
- 一单一目标。事故类必须拆成「止损工单」与「治理工单」两条,禁止混单。
- 工单必须写「关闭条件」。没有关闭条件的工单视为无效工单。
- 代码变更必须关联工单。提交信息、PR 描述须携带
#issue号,否则审查不通过。 本地commit-msg钩子与 CI(commit-message-lint)双重校验(#216):安装钩子执行bash scripts/install-commit-msg-hook.sh(与 gitleaks 的 pre-commit 相互独立); 判据脚本scripts/check-commit-issue.sh两处同源。merge 提交自动放行;确无工单的纯维护/ 版本号提交须在信息中显式写[skip-issue];紧急可用git commit --no-verify(会同时绕过 gitleaks,慎用)。CI 只校验本次新增提交,不追溯历史。 - 禁止无凭证关闭。关闭工单前必须先追加
## 关闭凭证核验评论,逐条对应关闭 条件并给出可复现的核验方式(测试名 / commit sha / 实测命令);批量关闭时每张 工单各写一条。详见 §四点一。
二、工单分类(Label)
| 分类 | Label | 语义 | 责任人 | 示例 |
|---|---|---|---|---|
| 事故处理 | incident |
已发生的线上故障,止损/补救/闭环 | 运维 / 业务 / 数据负责人 | 09-02 数据缺口补跑 |
| 治理改进 | governance |
系统性缺陷的长效修复,防复发 | 后端 / 采集 / 监控 | 重试、熔断、告警 |
| 功能需求 | feature |
新功能或增强 | 架构师 → 开发者 | 新增导出能力 |
| 缺陷修复 | bug |
明确代码缺陷 | 开发者 | LIMIT 排序方向错误 |
| 技术债 | tech-debt |
重构、清理、基建 | 开发者 | 依赖锁定 |
| 运维动作 | ops |
备份、迁移、凭证轮换等人工操作 | 运维 | JWT 密钥轮换 |
标签在 Gitea 中按 Label 名称创建;
incident与governance为强约束分类(见第三节)。
三、事故类工单的强制拆分
当一个事件既造成线上影响、又暴露系统设计缺陷时,必须拆成两条工单,禁止合并:
| 维度 | 事故工单(incident) | 治理工单(governance) |
|---|---|---|
| 关注点 | 已经发生了什么、怎么止损 | 为什么会发生、怎么修复系统 |
| 责任人 | 运维 / 业务 / 数据负责人 | 后端 / 采集 / 监控 |
| 产出 | 补跑/回填结果、事件闭环说明 | 设计评审、代码实现、告警上线 |
| 关闭条件 | 数据已补齐或确认不可补、业务确认 | 验收标准全部满足、灰度验证通过 |
反例(禁止):
09-02 缺口处理 + 重试熔断改造合成一单——会导致事故无法快速闭环、治理无法独立验收、责任人互相消耗。
四、工单必填字段
每条工单正文至少包含:
## 背景
<发生了什么 / 为什么需要做>
## 影响范围
<涉及对象 / 时间窗口 / 影响程度>
## 根因判断(incident/bug 必填,feature 可略)
<事实与证据,区分「上游故障」vs「本地代码」>
## 处理动作 / 设计要求
- [ ] <可勾选的执行项>
## 验收标准 / 关闭条件
<明确、可验证的完成判据>
## 关联
- 审计/设计文档路径
- 关联工单号
四点一、关闭凭证块(强制)
⚠️ 背景(2026-09-10 审计,见
docs/reports/20260910-工单关闭凭证质量-审计报告.md): 审计发现 39 张已关闭工单中,19 张验收条件零勾选、1 张零评论,且有 3 批 「同一秒关闭多张」的批量关闭未逐张回填凭证。追溯后确认功能均已实现(非强行 关闭),但关闭时无证据留痕 → 任何人都无法区分「论证过的关闭」与「强行关闭」, 审计成本极高。用户原话:「我不确定是论证了关闭还是强行关闭的」。本节即为此落地:关闭工单前,必须先追加一条关闭凭证评论。
4.1.1 标准形态
关闭前必须追加一条评论,标题固定为 ## 关闭凭证核验,逐条对应正文的
「验收标准 / 关闭条件」:
## 关闭凭证核验 (YYYY-MM-DD)
| 关闭条件 | 核验方式 | 结果 |
|---|---|---|
| <条件1 原文或摘要> | <测试用例名 / commit sha / 实测命令 / 截图说明> | ✅ |
| <条件2> | <...> | ✅ |
**提交**: <sha 或多个 sha>
**结论**: 关闭条件全部满足,关闭本单。
硬性要求:
- 逐条对应 —— 关闭条件有几条,表格就有几行,不允许合并省略。
- 核验方式必须可复现 —— 写「测试用例名」/「commit sha」/「实测命令」, 不写「已测试通过」这种不可验证的话。
- 不满足的必须写明 —— 若某条确认无法满足但业务上接受,写
结论: 以 <具体理由> 降级验收,禁止静默关闭。 - 批量关闭也要逐张写 —— 子工单同时完成时,每张工单各写一条自己的凭证评论, 不允许只在父工单写一条。
- 勾选框同步勾上 —— 写凭证的同时,把正文里对应的
- [ ]改为- [x]。
4.1.2 关闭前强制校验清单
关闭任何工单前,自查(人工或 AI 助手均适用):
- 正文有「验收标准 / 关闭条件」节(没有则视为无效工单,先补)
- 已追加
## 关闭凭证核验评论,且逐条对应关闭条件 - 每条凭证的核验方式可复现(测试名 / sha / 命令)
- 正文勾选框已同步勾上
- 审查报告(若适用)已回写工单,且无 CRITICAL
- 结论行明确写「全部满足」或「降级验收 + 理由」
4.1.3 历史工单例外
对已关闭但缺凭证的历史工单:
- 不重开(功能大概率已实现,重开会造成更大混乱)。
- 补一条
## 关闭凭证核验(补记 · YYYY-MM-DD)评论,显式标注为事后追溯, 并说明「关闭时未留痕、现追溯核实、不重开」。 - 若追溯后无法确认是否满足 → 标注
⚠️ 凭证缺失(历史存疑),不要假装已核实。
五、状态流转
Open(新建)
→ 认领(指派责任人 + 设 Label)
→ In Progress(执行中,附执行证据)
→ 待验收(提交可验证产出:测试结果/补跑对比/灰度数据)
→ Closed(满足关闭条件,记录关闭日期与结论)
(任意阶段可回退:验收不通过 → In Progress)
| 状态 | 进入条件 | 离开条件 |
|---|---|---|
| Open | 创建 | 指派责任人 |
| In Progress | 认领 | 产出可验证证据 |
| 待验收 | 证据齐全 | 人工/机器验收通过或驳回 |
| Closed | 满足关闭条件 + 已写关闭凭证评论(§四点一) | ——(归档,禁止无痕重开) |
六、工单 × 四阶段协同机制(需求 → 架构 → 编码 → 测试)
工单是四阶段的「载体」,四阶段是工单的「流转节奏」。每一阶段都有明确的工单状态、通过凭证(Gate)与门禁,缺一不可。缺少钩子 = 工单只是挂个号,不驱动流转。
6.1 阶段状态机
| 阶段 | 工单状态 | 通过凭证(Gate) | 产出 |
|---|---|---|---|
| ① 需求分析 | Open → 需求确认 | 需求派工单/用户确认;「关闭条件」已定义 | 工单正文完整(背景/影响范围/验收标准) |
| ② 架构设计 | 设计中 | 架构文档 LOCKED + git tag + 人工审核通过 | docs/arch/ 锁定文档;工单引用其路径 |
| ③ 编码实现 | In Progress → 待验收 | 提交/PR 关联 #issue号;CI 通过(ruff + pytest) |
代码 + 测试,符合派工单约束 |
| ④ 测试验证 | 待验收 → Closed | 审查报告无 CRITICAL + 人工终审通过;满足关闭条件 | 审查报告回写工单;工单关闭并记录日期与结论 |
6.2 阶段门禁规则
- 不可跳阶段:未完成需求确认不得进入架构设计;未锁定架构不得编码实现。
- 凭证可追溯:每个 Gate 的凭证(派工单、架构文档、PR/提交、测试输出、审查报告)都回写到工单,作为流转依据。
- 回退规则:任一门禁不通过,工单回退到上一阶段(如审查有 CRITICAL → 回 In Progress 修复)。
6.3 双向引用(工单 ↔ 其他资产)
| 资产 | 工单侧 | 资产侧 |
|---|---|---|
| 架构文档 | 工单正文标「架构文档路径」 | 架构文档头标「关联工单 #号」 |
| 提交/PR | 工单评论记录 PR 链接 | 提交信息与 PR 描述带 #issue号 |
| 审查报告 | 工单评论贴审查结论 | 报告注明对应工单号 |
| 审计/台账 | 工单正文引用审计报告 | 审计报告与行动项台账标注工单号 |
6.4 自动化钩子(待建设)
- 当前「CI 通过(ruff + pytest)」与「工单状态」之间靠人工回写;设计草案已入
docs/arch/_pending/A-20260903-001-issue-automation-gates.md(PENDING 待审核),落地后由 CI 自动执行。 - 在自动化钩子落地前,编码完成者必须手工把 CI 结果与测试结果贴到工单,否则视为未通过「③ 编码实现」门禁。
七、工单粒度治理(防碎片化 / 防巨石单)
两个极端都要避免:① 工单碎片化(大量空壳或几行改动就单独开单,无法管理);② 巨石单(一个工单塞进一堆需求,无法逐步实现、验证、测试)。粒度以「可独立验收」为唯一标尺。
7.1 合并判定(应合并,不单独开单)
满足全部条件时,应并入关联工单或批量工单,禁止单独开单:
- 工作量极小(< 半天),无独立上线/验收价值;
- 与已有工单同模块、同责任人、同时间窗;
- 纯机械性改动(改一个变量名、一行注释、加一个日志等)。
例:顺手修一处拼写 → 并入正在做的工单;一批同类小清理 → 合并成一个
tech-debt批量工单。
7.2 拆分判定(应拆分,禁止巨石单)
满足任一条件时,必须拆成多个工单:
- 无法在一次上线中独立验收;
- 涉及不同模块 / 不同风险面 / 不同责任人;
- 总工作量 > 1 天,或需要分阶段灰度;
- 需求本身「逐步实现、逐步验证、逐步测试」的(先地基后上层)。
拆分产物要么是「父工单 + 子工单」,要么是多个并列工单,但每个叶子工单都必须能独立关闭。
7.3 拆分与验证节奏
- 先拆出最小可交付切片(先跑通主链路 / 先止血),后续工单逐步增强;
- 每个工单 = 一段可独立测试、可独立上线的增量;
- 上一个工单关闭(含测试通过)后,再启动下一个;
- 拆分顺序在父工单里列出,标注依赖关系(A → B → C)。
7.4 想法 / 待办池(先不建工单)
未到执行时机的想法、低优先级建议,不进 issue,先进 backlog 清单(如 docs/审查行动项登记.md 台账),避免工单碎片化;排期确认后再转正式工单。
八、禁止事项
- 禁止无工单直接改生产代码 / 数据 / 表结构。
- 禁止把事故与治理混在同一工单。
- 禁止创建无「关闭条件」的工单。
- 禁止工单长期停留在 Open 且无责任人。
- 禁止用聊天记录替代工单作为变更依据。
- 禁止为「< 半天、无独立验收价值」的琐碎改动单独开单(应合并)。
- 禁止创建无法独立验收的巨石单(应拆分)。
九、落地示例(本次 09-02 事件)
- 事故工单
#1:09-02 cs_records 缺口事故处理与补救闭环(incident + ops) - 治理工单
#2:ai-acc 大范围导出失败的重试、熔断与缺口补全机制治理(governance + backend)- 注:
#2若后续细分,应拆为子工单(重试退避 / 熔断半开探测 / 缺口补队列 / 数据量骤降告警),每个可独立上线验收;未排期前先留 backlog 台账,不空开 issue。
- 注:
- 审计报告
docs/debug/debug-cs-record-gap-2026-09-02.md头部标注关联#1#2 - 行动项登记
docs/审查行动项登记.md每条备注标注对应工单号