From 1ef3b4704dc69bcfdeee465fe9dfabab52d5987e Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Thu, 13 Aug 2026 15:09:38 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20=E5=BB=BA=E7=AB=8B=E6=94=B6=E6=95=9B?= =?UTF-8?q?=E5=BC=8F=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:大型 PR 在逐提交触发官方 Review 时出现重复审查、范围扩张和 reaction 驱动的 review churn。 改动:定义稳定 HEAD、single-flight、两轮预算、文字通过停止条件和大型需求拆分边界,并同步模板、维护文档及防回退 fixture。 验证:基线 fixture、ShellCheck、Ruff、Python 编译、82 个 YAML 解析和 git diff --check 通过。 Co-Authored-By: Codex --- AGENTS.md | 8 ++++ MAINTENANCE.md | 12 ++++-- README.md | 10 +++-- contracts/codex-code-review.md | 37 ++++++++++++++++--- templates/AGENTS.md | 8 ++++ .../review-convergence-policy/good.md | 7 ++++ .../review-convergence-policy/legacy.md | 5 +++ tests/test-audit.sh | 33 +++++++++++++++++ 8 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 tests/fixtures/review-convergence-policy/good.md create mode 100644 tests/fixtures/review-convergence-policy/legacy.md diff --git a/AGENTS.md b/AGENTS.md index cce80b0..f392d63 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,3 +20,11 @@ - 优先识别会造成错误放行、错误阻断、权限扩大、secret 暴露、供应链漂移或发布/回滚证据失真的具体问题,并核对新增公共 MUST 是否确实跨项目通用。 - 审计器变更必须同时具有能复现旧缺口的失败 fixture 和保持合法项目通过的正例;只增加字符串匹配而不能证明约束时应指出误报或漏报路径。 - 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并。 + +## 官方 Review 收敛 + +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 157d5a7..539dc6e 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -23,7 +23,7 @@ ## 新项目接入 1. 在独立 worktree 中复制 `templates/AGENTS.md`,替换占位符并补齐项目内部规则;项目规则不得降低公共 MUST,根文件必须保留精确 `## Code Review Rules` 标题。 -2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发或需要重审时使用 `@codex review`。 +2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发,或批量修复后需要对稳定 HEAD 做最终复审时才使用 `@codex review`。 3. 保持 Auto-merge 关闭;官方 Review 尚非 required check 时不得为单个 PR 开启 Auto-merge。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用合并后自动删除远端分支。 4. 复制并按项目实际情况改造 `templates/` 下的 PR、release workflow、`release-safety.yml` 与 `release-safety-contract.sh`;把后两者分别安装为 `.github/release-safety.yml` 与 `.github/scripts/release-safety-contract.sh`,保持 wrapper 的 Git mode 为 `100755`,并映射项目真实 job/step 拓扑。 5. 通过真实 PR 证明 `PR container validation` 成功,随后原子迁移 master required check。 @@ -54,16 +54,20 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. ## 官方 Codex Code Review 维护 - 只采用官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或平行评论协议。 -- 自动触发依赖官方 `Automatic reviews`;`AGENTS.md` 只定义审查规则,不能代替设置。自动审查未出现或需要重审时使用 `@codex review`。 +- 自动触发依赖官方 `Automatic reviews`;`AGENTS.md` 只定义审查规则,不能代替设置。自动审查未出现,或批量修复后需要对稳定 HEAD 做最终复审时才使用 `@codex review`。 +- 非平凡 PR 先保持 Draft,完成实现、测试、内部交叉审查和范围冻结后再进入官方 Review;多个独立架构边界必须拆分,跨仓变更先冻结共享协议,最终集成 PR 才使用 `Closes #xx`。 +- 等一轮 findings 完整返回后按根因批量修复。同一 HEAD 最多人工请求一次,Review 正在运行或尚未返回时不得再次触发;不得一条 finding 对应一次 push 和一次完整 Review。 +- 普通 PR 最多两轮完整官方 Review;第三轮必须显式记录原因,并先判断拆分、收窄范围或接受有依据的非阻塞项。当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定口令。 +- 新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修改完成并恢复稳定 HEAD 后只请求一次最终复审。 - v1 保持观察模式,不把官方 Review 增加为 required check,不修改现有 branch protection,也不要求官方输出自定义批准口令或严重级别。 -- 官方设置和审查行为通过真实 PR 验收;中央审计只检查根 `AGENTS.md` 是普通文件,且固定 `markdown-it-py==3.0.0` CommonMark parser 产生源码行精确等于 `## Code Review Rules` 的真实 h2。不得恢复手写 Markdown 状态机,也不抓取页面或调用私有接口。 +- 官方设置和审查行为通过真实 PR 验收;中央审计只检查根 `AGENTS.md` 是普通文件,且固定 `markdown-it-py==3.0.0` CommonMark parser 产生源码行精确等于 `## Code Review Rules` 的真实 h2。不得恢复手写 Markdown 状态机,也不抓取页面、调用私有接口或伪称验证同一 HEAD 请求次数、在途 Review 和审查预算。 - 官方功能演进时先更新接入说明和精简规则;若官方补齐缺口,优先删除临时流程,不维护平行实现。 ## Auto-merge 维护 - GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。官方 Review 当前不是 required check,因此 v1 暂不允许仓库或单个 PR 开启 Auto-merge。 - 不建立 HEAD 监听器、自动合并 Bot、Action 或定时任务来补这个能力缺口;未来等官方 Review 可成为当前 HEAD required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后再评估。 -- 人工合并前确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功且风险已分类;新提交必须重新 Review。 +- 人工合并前确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功且风险已分类;最终 Review 后出现新提交时,先完成全部修改并恢复稳定 HEAD,再按收敛预算完成最终复审。 - Dependabot PR 不能只凭 CI 绿灯自动合并;运行时依赖、跨大版本和会触发生产发布的仓库必须另做兼容性与发布授权判断。 - 分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的长期 head 分支时必须关闭。 - 本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 diff --git a/README.md b/README.md index ede14f0..a4aacdf 100644 --- a/README.md +++ b/README.md @@ -24,15 +24,19 @@ ## 官方 Codex Code Review -基线只接入和治理官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或评论协议。自动唤醒使用官方 `Automatic reviews`;没有自动触发或需要重审时,在 PR 评论使用 `@codex review`。 +基线只接入和治理官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或评论协议。自动唤醒使用官方 `Automatic reviews`;没有自动触发,或批量修复后需要对稳定 HEAD 做最终复审时,才在 PR 评论使用 `@codex review`。 根 `AGENTS.md` 的 `## Code Review Rules` 只告诉官方 Reviewer 应优先检查哪些项目风险,不能开启 Automatic reviews,也不能证明自动审查已经触发。v1 保持观察模式,不增加 required check,不改变现有 branch protection;官方设置通过真实 PR 验收,中央审计只验证仓库内可稳定读取的规则文件。完整边界见 [官方治理契约](contracts/codex-code-review.md)。 +采用收敛式 Review:非平凡 PR 在 Draft 阶段完成实现、测试、内部交叉审查与范围冻结,再让官方 Review 检查稳定 HEAD。一轮 findings 完整返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得排队新的请求。普通 PR 最多两轮完整 Review,即初审和最终复审;第三轮必须先由维护者判断拆分、收窄范围或接受有依据的非阻塞项。 + +官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定批准口令。新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;完成一批修改并恢复稳定 HEAD 后只触发一次最终复审。包含多个独立架构边界的大型需求应拆成阶段 PR,跨仓变更先冻结共享协议,只有最终集成 PR 使用 `Closes #xx`。 + ## Auto-merge 与分支清理 GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。由于官方 Review 当前不是 required check,纳管产品仓库在 v1 暂不允许开启 Auto-merge,也不为单个 PR 启用它。 -人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;新提交必须重新 Review。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。 +人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;最终 Review 后出现新提交时,完成修改并恢复稳定 HEAD 后再做一次最终复审,不逐个审查中间提交。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。 分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的 `dev`、`release` 等长期 head 分支时必须关闭。本地 worktree 和分支始终只在确认已合并、工作区干净且没有独有提交后清理。 @@ -75,7 +79,7 @@ GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权 - `master` branch protection 和 required check。 - 纳管产品仓库关闭 Auto-merge;分支自动删除按项目真实分支模型配置,不由公共审计强制。人工合并前的 Review/thread/风险分类仍由真实 PR 验收。 -中央审计明确不解释任意 shell 的控制流,也不尝试从注释、`echo`、here-doc、字符串或脚本名证明 ref/内容 ID 比对、容器内 smoke、回滚命令及实际 `DEPLOY_TARGET_SHA`。它也不抓取官方页面或私有接口来判断 Automatic reviews 设置和模型审查质量;这些事实分别由项目可执行契约测试、真实发布验收和真实 PR Review 负责。模板只是一种可复制 profile,`.github/release-safety.yml` 才是每个项目拓扑的声明式适配层。 +中央审计明确不解释任意 shell 的控制流,也不尝试从注释、`echo`、here-doc、字符串或脚本名证明 ref/内容 ID 比对、容器内 smoke、回滚命令及实际 `DEPLOY_TARGET_SHA`。它也不抓取官方页面或私有接口来判断 Automatic reviews 设置、模型审查质量、同一 HEAD 请求次数、在途 Review 或审查轮次预算;这些事实分别由项目可执行契约测试、真实发布验收和真实 PR 时间线负责。模板只是一种可复制 profile,`.github/release-safety.yml` 才是每个项目拓扑的声明式适配层。 本地 fixture 自测: diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index e7c63ea..63d19b3 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -11,7 +11,8 @@ ## 2. 触发与规则分离 - MUST:在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,由官方集成自动触发新 PR 审查。 -- MUST:自动审查未触发或需要重新审查时,使用官方评论命令 `@codex review` 作为人工兜底。 +- MUST:自动审查未触发,或一批修复完成后需要对稳定 HEAD 做最终复审时,才使用官方评论命令 `@codex review` 作为人工兜底;Review 正在运行时不得再次触发。 +- MUST:同一 HEAD 最多人工请求一次 Review;不得为了 emoji、reaction、批准口令或重复确认,向已经获得明确文字结论的 HEAD 再次请求。 - MUST:每个仓库根目录维护普通文件 `AGENTS.md`,并包含独占一行的精确标题 `## Code Review Rules`。 - MUST:`AGENTS.md` 只声明官方 Reviewer 的审查重点,不能被描述为 Automatic reviews 的开启方式或触发证据。 - 项目扩展点:项目可以在根规则或更近目录的 `AGENTS.md` 中补充架构、协议、数据和真实验收约束,但不得降低根级公共审查原则。 @@ -24,7 +25,33 @@ - MUST:不要求官方 Reviewer 使用自定义严重级别、批准口令或评论格式,以免把基线绑定到官方当前输出实现。 - 项目扩展点:各项目补充高风险模块、跨仓消费者、迁移兼容、前端状态协议和真实用户路径。 -## 4. v1 合并边界 +## 4. 收敛式 Review + +本节用于防止 review churn:官方 Review 是稳定变更的独立风险关卡,不是持续开发阶段的穷举式调试循环。 + +“稳定 HEAD”指当前范围已冻结、没有已知待提交代码、项目测试和 required CI 已通过,且跨仓共享协议已经对齐;只有该状态才进入初审或最终复审。 + +### 4.1 Draft 与范围冻结 + +- MUST:非平凡 PR 先保持 Draft,在实现、项目测试、CI 契约和内部交叉审查完成后冻结范围,再进入官方 Review;不得把官方 Review 当作逐提交调试器。 +- MUST:包含多个可独立验证的架构边界时拆分为阶段 PR,例如数据/API、后台任务/索引和部署验收;跨仓变更先冻结共享协议,再分别进入最终 Review。 +- MUST:阶段 PR 说明其依赖与验收边界;只有真正完成 Issue 整体交付的最终集成 PR 使用 `Closes #xx`,避免阶段合并提前关闭需求。 +- 项目扩展点:项目可以按风险定义大型 PR 提醒阈值,但文件数或代码行数只能作为拆分信号,不能替代架构边界判断。 + +### 4.2 一轮收齐与批量修复 + +- MUST:等待一轮 Review 完整结束并收齐 findings,再统一分类和修复;不得一条 finding 对应一次 push 和一次完整 Review。 +- MUST:对当前范围内可复现且有实际影响的问题完成修复;重复、outdated、既有问题、明确非目标或未支持的极端场景,允许说明依据后解决 thread、拒绝或转为后续 Issue,不因建议有效就自动扩大当前 PR 范围。 +- MUST:按根因合并相关修复,先在本地完成针对性回归和内部复核,再把一个完整修复批次推到 PR;required CI 仍按仓库规则运行,但不得为了启动下一轮 Review 拆出无意义的中间 push。 + +### 4.3 Single-flight、预算与停止条件 + +- MUST:同一 HEAD 只能有一个人工 Review 请求;Review 正在运行或结果尚未返回时不得排队新的请求。运行期间出现新提交时,先等待当前结果、完成剩余批量修复,再对最终稳定 HEAD 请求一次复审。 +- MUST:普通 PR 最多两轮完整官方 Review,即初审和一次最终复审;第三轮必须由维护者显式记录原因,并先判断是否需要拆分 PR、收窄范围或接受有依据的非阻塞项,不得自动进入下一轮。 +- MUST:官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论,即视为本轮 Review 通过;不要求 emoji、reaction、固定措辞或额外重复确认。 +- MUST:人工合并仍要求 Review 当前 HEAD;新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交都立即重新 Review,只在实现与修复重新稳定后触发一次。 + +## 5. v1 合并边界 - MUST:v1 采用观察模式,官方 Review 不新增为 required status check,也不改变现有 `master` branch protection。 - MUST:没有官方稳定状态接口和真实仓库验证前,不假设 Review 能映射为 GitHub required check、approval 或固定 check 名称。 @@ -33,16 +60,16 @@ - MUST:不创建自研合并 Bot、Action、HEAD 监听器或平行状态机来补 GitHub/Codex 当前能力缺口。 - MUST:合并后自动删除远端分支不是所有项目的公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才允许启用该设置;否则必须关闭,避免 GitHub 删除仍需复用的长期分支。 - MUST:人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功,且依赖或发布风险已分类。 -- MUST:PR 出现新提交后,旧 Review 不再作为当前 HEAD 的证据;必须重新 Review 并再次确认全部 review thread 已解决,才能人工合并。 +- MUST:PR 在最终 Review 后出现新提交时,旧 Review 不再作为当前 HEAD 的合并证据;先完成全部修改并恢复稳定 HEAD,再按收敛式 Review 预算完成最终复审和 thread 确认。 - MUST:Dependabot PR 不因 CI 通过而自动合并;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 - 项目扩展点:未来只有在官方 Review 能成为与当前 HEAD 绑定的 required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后,才重新评估启用原生 Auto-merge。 -## 5. 审计与验收 +## 6. 审计与验收 - MUST:中央只读审计检查根 `AGENTS.md` 是 Git tree 中的普通文件,并在 fenced code、HTML comment 与 raw HTML block 之外包含精确 `## Code Review Rules` 标题;缺失、symlink、非普通文件或缺少真实标题统一报告 `[CODE_REVIEW_RULES]`。 - MUST:审计使用固定 `markdown-it-py==3.0.0` 的 CommonMark parser,只接受真实 `h2` token,且 token 对应源码行必须精确等于 `## Code Review Rules`;不得维护平行的手写 Markdown 状态机。 - MUST:直接依赖 `markdown-it-py==3.0.0` 与传递依赖 `mdurl==0.1.2` 在本地入口和两条基线 workflow 中显式校验或固定安装,不得依赖运行环境碰巧预装的版本。 -- MUST:中央审计不抓取 GitHub/Codex 页面、不调用私有接口,也不声称验证 Automatic reviews 设置或模型审查质量。 +- MUST:中央审计不抓取 GitHub/Codex 页面、不调用私有接口,也不声称验证 Automatic reviews 设置、模型审查质量、同一 HEAD 请求次数、在途 Review 或审查轮次预算;这些运行态事实由真实 PR 时间线验收。 - MUST:中央审计验证纳管产品仓库关闭 Auto-merge;分支自动删除取决于项目真实分支模型,不由公共审计强制。人工合并前是否完成当前 HEAD Review、解决 thread 与风险分类,由真实 PR 验收,不伪装成静态仓库审计结论。 - MUST:官方设置通过真实 PR 验收:Automatic reviews 能产生审查;必要时 `@codex review` 能触发人工兜底;Reviewer 能遵循仓库规则。 - MUST:接入不得新增 review 专用 secret、GitHub App、workflow、runner 或发布权限。 diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 71c6105..9070b95 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -29,6 +29,14 @@ - 检查数据/API 与跨仓协议兼容、CI/CD 权限边界、失败/回滚路径及测试能否证明这些高风险行为。 - 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并;项目重点:PROJECT_REPLACE_REVIEW_RULES +## 官方 Review 收敛 + +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 + ## CI/CD 公共门禁 - PR 只使用 GitHub 托管 runner,权限为 `contents: read`,不得读取发布 secret、绑定发布 Environment、推送镜像或部署。 diff --git a/tests/fixtures/review-convergence-policy/good.md b/tests/fixtures/review-convergence-policy/good.md new file mode 100644 index 0000000..f6e194c --- /dev/null +++ b/tests/fixtures/review-convergence-policy/good.md @@ -0,0 +1,7 @@ +# 收敛式 Review 正例 + +- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 +- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 +- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 +- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 +- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 diff --git a/tests/fixtures/review-convergence-policy/legacy.md b/tests/fixtures/review-convergence-policy/legacy.md new file mode 100644 index 0000000..cd24067 --- /dev/null +++ b/tests/fixtures/review-convergence-policy/legacy.md @@ -0,0 +1,5 @@ +# 会造成 Review Churn 的旧策略 + +- 每次新提交后立即评论 `@codex review`,上一轮尚未结束也继续触发。 +- 每个 finding 单独修复、push,再完整审查一次。 +- 只有收到 👍 才算通过,文字通过仍继续请求 Review。 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 417a000..d0efbfc 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -159,6 +159,12 @@ contract = (root / "contracts" / "ci-cd-baseline.md").read_text() review_contract = (root / "contracts" / "codex-code-review.md").read_text() readme = (root / "README.md").read_text() maintenance = (root / "MAINTENANCE.md").read_text() +review_convergence_good = ( + root / "tests" / "fixtures" / "review-convergence-policy" / "good.md" +).read_text() +review_convergence_legacy = ( + root / "tests" / "fixtures" / "review-convergence-policy" / "legacy.md" +).read_text() audit_entrypoint = (root / "scripts" / "audit-github-baseline.sh").read_text() audit_source = (root / "scripts" / "audit_github_baseline.py").read_text() @@ -172,6 +178,31 @@ def section_bullets(document, heading): section.append(line) return [line for line in section if line.startswith("- ")] +def assert_review_convergence(document): + for marker in ( + "Draft", + "稳定 HEAD", + "同一 HEAD", + "Review 正在运行", + "文字结论", + "最多两轮", + ): + assert marker in document, (marker, document[:80]) + for forbidden in ( + "每次新提交后立即", + "只有收到 👍", + "新提交必须重新 Review", + ): + assert forbidden not in document, (forbidden, document[:80]) + +assert_review_convergence(review_convergence_good) +try: + assert_review_convergence(review_convergence_legacy) +except AssertionError: + pass +else: + raise AssertionError("旧的逐提交重复 Review 策略不应满足收敛契约") + for marker in ( "PROJECT_REPLACE", "公共 MUST", @@ -200,6 +231,7 @@ for document in (review_contract, readme, maintenance): ): assert marker in document, (marker, document[:40]) for document in (root_agents, template, review_contract, readme, maintenance): + assert_review_convergence(document) for marker in ( "Review 当前 HEAD", "全部 review thread 已解决", @@ -217,6 +249,7 @@ for document in (review_contract, readme, maintenance): "Dependabot", ): assert marker in document, (marker, document[:40]) + assert "不要求每个中间提交" in document, document[:40] for marker in ("markdown-it-py==3.0.0", "mdurl==0.1.2"): assert marker in audit_entrypoint, marker assert 'MarkdownIt("commonmark")' in audit_source From c519fedf20847faa2c8a27eb5f0a9b43f5355b55 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Thu, 13 Aug 2026 15:54:41 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E6=94=B6=E7=B4=A7=E5=AE=A1=E6=9F=A5?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E4=B8=8E=E9=87=8D=E8=AF=95=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:PR #7 的 Automatic Review 与人工兜底发生竞态,且首轮 Review 指出重试语义和反例 fixture 存在边界缺口。 改动:加入至少 15 分钟等待、发送前复查、明确失败或超时仅重试一次;移除脱离上下文的禁用子串,并让三个反例各自只命中一个目标违规。 验证:基线 fixture、ShellCheck、Ruff、Python 编译、82 个 YAML 解析和 git diff --check 通过。 Co-Authored-By: Codex --- AGENTS.md | 1 + MAINTENANCE.md | 3 +- README.md | 4 +- contracts/codex-code-review.md | 7 +-- templates/AGENTS.md | 1 + .../review-convergence-policy/eager-review.md | 9 ++++ .../review-convergence-policy/good.md | 2 + .../inflight-duplicate.md | 9 ++++ .../review-convergence-policy/legacy.md | 5 -- .../reaction-gate.md | 9 ++++ tests/test-audit.sh | 51 ++++++++++++------- 11 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 tests/fixtures/review-convergence-policy/eager-review.md create mode 100644 tests/fixtures/review-convergence-policy/inflight-duplicate.md delete mode 100644 tests/fixtures/review-convergence-policy/legacy.md create mode 100644 tests/fixtures/review-convergence-policy/reaction-gate.md diff --git a/AGENTS.md b/AGENTS.md index f392d63..f5d9aac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,3 +28,4 @@ - 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 - 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 - 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 539dc6e..92d9b27 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -56,9 +56,10 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. - 只采用官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或平行评论协议。 - 自动触发依赖官方 `Automatic reviews`;`AGENTS.md` 只定义审查规则,不能代替设置。自动审查未出现,或批量修复后需要对稳定 HEAD 做最终复审时才使用 `@codex review`。 - 非平凡 PR 先保持 Draft,完成实现、测试、内部交叉审查和范围冻结后再进入官方 Review;多个独立架构边界必须拆分,跨仓变更先冻结共享协议,最终集成 PR 才使用 `Closes #xx`。 -- 等一轮 findings 完整返回后按根因批量修复。同一 HEAD 最多人工请求一次,Review 正在运行或尚未返回时不得再次触发;不得一条 finding 对应一次 push 和一次完整 Review。 +- 等一轮 findings 完整返回后按根因批量修复。同一 HEAD 不得并发或对有效结果重复请求,Review 正在运行或尚未返回时不得再次触发;不得一条 finding 对应一次 push 和一次完整 Review。 - 普通 PR 最多两轮完整官方 Review;第三轮必须显式记录原因,并先判断拆分、收窄范围或接受有依据的非阻塞项。当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定口令。 - 新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修改完成并恢复稳定 HEAD 后只请求一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线。请求明确失败或预定超时且没有结果、没有在途信号时允许重试一次并记录原因;重试仍失败则停止并排查官方集成,不制造空提交改变 HEAD。 - v1 保持观察模式,不把官方 Review 增加为 required check,不修改现有 branch protection,也不要求官方输出自定义批准口令或严重级别。 - 官方设置和审查行为通过真实 PR 验收;中央审计只检查根 `AGENTS.md` 是普通文件,且固定 `markdown-it-py==3.0.0` CommonMark parser 产生源码行精确等于 `## Code Review Rules` 的真实 h2。不得恢复手写 Markdown 状态机,也不抓取页面、调用私有接口或伪称验证同一 HEAD 请求次数、在途 Review 和审查预算。 - 官方功能演进时先更新接入说明和精简规则;若官方补齐缺口,优先删除临时流程,不维护平行实现。 diff --git a/README.md b/README.md index a4aacdf..5520c60 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,12 @@ 根 `AGENTS.md` 的 `## Code Review Rules` 只告诉官方 Reviewer 应优先检查哪些项目风险,不能开启 Automatic reviews,也不能证明自动审查已经触发。v1 保持观察模式,不增加 required check,不改变现有 branch protection;官方设置通过真实 PR 验收,中央审计只验证仓库内可稳定读取的规则文件。完整边界见 [官方治理契约](contracts/codex-code-review.md)。 -采用收敛式 Review:非平凡 PR 在 Draft 阶段完成实现、测试、内部交叉审查与范围冻结,再让官方 Review 检查稳定 HEAD。一轮 findings 完整返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得排队新的请求。普通 PR 最多两轮完整 Review,即初审和最终复审;第三轮必须先由维护者判断拆分、收窄范围或接受有依据的非阻塞项。 +采用收敛式 Review:非平凡 PR 在 Draft 阶段完成实现、测试、内部交叉审查与范围冻结,再让官方 Review 检查稳定 HEAD。一轮 findings 完整返回后按根因批量修复;同一 HEAD 不允许并发或对有效结果重复请求,Review 正在运行时不得排队新的请求。普通 PR 最多两轮完整 Review,即初审和最终复审;第三轮必须先由维护者判断拆分、收窄范围或接受有依据的非阻塞项。 官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定批准口令。新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;完成一批修改并恢复稳定 HEAD 后只触发一次最终复审。包含多个独立架构边界的大型需求应拆成阶段 PR,跨仓变更先冻结共享协议,只有最终集成 PR 使用 `Closes #xx`。 +PR 转为 Ready 后若 Automatic Review 尚未出现,在没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线。请求明确失败,或超过预定超时且没有结果、没有在途信号时允许重试一次并记录原因;重试仍失败就停止 Review 循环并排查官方集成,不通过空提交制造新 HEAD。 + ## Auto-merge 与分支清理 GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。由于官方 Review 当前不是 required check,纳管产品仓库在 v1 暂不允许开启 Auto-merge,也不为单个 PR 启用它。 diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index 63d19b3..f7e046b 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -11,8 +11,9 @@ ## 2. 触发与规则分离 - MUST:在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,由官方集成自动触发新 PR 审查。 -- MUST:自动审查未触发,或一批修复完成后需要对稳定 HEAD 做最终复审时,才使用官方评论命令 `@codex review` 作为人工兜底;Review 正在运行时不得再次触发。 -- MUST:同一 HEAD 最多人工请求一次 Review;不得为了 emoji、reaction、批准口令或重复确认,向已经获得明确文字结论的 HEAD 再次请求。 +- MUST:把 PR 标记为 Ready 后先等待 Automatic Review;没有明确失败时至少等待 15 分钟,并在发送评论前立即复查 PR 时间线,仍无 Review 结果或在途信号时,才使用官方评论命令 `@codex review` 作为人工兜底。 +- MUST:同一 HEAD 不得同时存在多个请求,也不得向已经获得有效结果的 HEAD 重复请求;Review 正在运行时不得再次触发。请求明确失败,或超过至少 15 分钟的预定超时且仍没有结果或在途信号时,允许重试一次并记录原因;重试仍失败则停止审查循环并排查集成,不得制造空提交改变 HEAD。 +- MUST:不得为了 emoji、reaction、批准口令或重复确认,向已经获得明确文字结论的 HEAD 再次请求。 - MUST:每个仓库根目录维护普通文件 `AGENTS.md`,并包含独占一行的精确标题 `## Code Review Rules`。 - MUST:`AGENTS.md` 只声明官方 Reviewer 的审查重点,不能被描述为 Automatic reviews 的开启方式或触发证据。 - 项目扩展点:项目可以在根规则或更近目录的 `AGENTS.md` 中补充架构、协议、数据和真实验收约束,但不得降低根级公共审查原则。 @@ -46,7 +47,7 @@ ### 4.3 Single-flight、预算与停止条件 -- MUST:同一 HEAD 只能有一个人工 Review 请求;Review 正在运行或结果尚未返回时不得排队新的请求。运行期间出现新提交时,先等待当前结果、完成剩余批量修复,再对最终稳定 HEAD 请求一次复审。 +- MUST:同一 HEAD 同一时刻只能有一个 Review 请求;Review 正在运行或结果尚未返回时不得排队新的请求。运行期间出现新提交时,先等待当前结果、完成剩余批量修复,再对最终稳定 HEAD 请求一次复审;明确失败或预定超时且没有任何结果的尝试不计为完整 Review 轮次,并按前述边界允许重试一次。 - MUST:普通 PR 最多两轮完整官方 Review,即初审和一次最终复审;第三轮必须由维护者显式记录原因,并先判断是否需要拆分 PR、收窄范围或接受有依据的非阻塞项,不得自动进入下一轮。 - MUST:官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论,即视为本轮 Review 通过;不要求 emoji、reaction、固定措辞或额外重复确认。 - MUST:人工合并仍要求 Review 当前 HEAD;新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交都立即重新 Review,只在实现与修复重新稳定后触发一次。 diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 9070b95..d5355ce 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -36,6 +36,7 @@ - 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 - 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 - 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 ## CI/CD 公共门禁 diff --git a/tests/fixtures/review-convergence-policy/eager-review.md b/tests/fixtures/review-convergence-policy/eager-review.md new file mode 100644 index 0000000..e9f8957 --- /dev/null +++ b/tests/fixtures/review-convergence-policy/eager-review.md @@ -0,0 +1,9 @@ +# 逐提交触发反例 + +- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 +- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 +- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 +- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 +- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 +- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 +- 每次新提交后立即评论 `@codex review`。 diff --git a/tests/fixtures/review-convergence-policy/good.md b/tests/fixtures/review-convergence-policy/good.md index f6e194c..0236fc3 100644 --- a/tests/fixtures/review-convergence-policy/good.md +++ b/tests/fixtures/review-convergence-policy/good.md @@ -5,3 +5,5 @@ - 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 - 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 - 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 +- 最终 Review 后出现新提交必须重新 Review,但应等修改批次恢复稳定 HEAD 后统一触发。 +- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 diff --git a/tests/fixtures/review-convergence-policy/inflight-duplicate.md b/tests/fixtures/review-convergence-policy/inflight-duplicate.md new file mode 100644 index 0000000..3da1949 --- /dev/null +++ b/tests/fixtures/review-convergence-policy/inflight-duplicate.md @@ -0,0 +1,9 @@ +# 在途重复触发反例 + +- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 +- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 +- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 +- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 +- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 +- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 +- Review 正在运行时仍再次评论 `@codex review`。 diff --git a/tests/fixtures/review-convergence-policy/legacy.md b/tests/fixtures/review-convergence-policy/legacy.md deleted file mode 100644 index cd24067..0000000 --- a/tests/fixtures/review-convergence-policy/legacy.md +++ /dev/null @@ -1,5 +0,0 @@ -# 会造成 Review Churn 的旧策略 - -- 每次新提交后立即评论 `@codex review`,上一轮尚未结束也继续触发。 -- 每个 finding 单独修复、push,再完整审查一次。 -- 只有收到 👍 才算通过,文字通过仍继续请求 Review。 diff --git a/tests/fixtures/review-convergence-policy/reaction-gate.md b/tests/fixtures/review-convergence-policy/reaction-gate.md new file mode 100644 index 0000000..da76dc9 --- /dev/null +++ b/tests/fixtures/review-convergence-policy/reaction-gate.md @@ -0,0 +1,9 @@ +# Reaction 门禁反例 + +- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 +- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 +- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 +- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 +- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 +- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 +- 只有收到 👍 才算通过。 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index d0efbfc..2b77d65 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -162,9 +162,11 @@ maintenance = (root / "MAINTENANCE.md").read_text() review_convergence_good = ( root / "tests" / "fixtures" / "review-convergence-policy" / "good.md" ).read_text() -review_convergence_legacy = ( - root / "tests" / "fixtures" / "review-convergence-policy" / "legacy.md" -).read_text() +review_convergence_failures = { + "eager-review.md": "每次新提交后立即", + "inflight-duplicate.md": "Review 正在运行时仍再次", + "reaction-gate.md": "只有收到 👍", +} audit_entrypoint = (root / "scripts" / "audit-github-baseline.sh").read_text() audit_source = (root / "scripts" / "audit_github_baseline.py").read_text() @@ -178,30 +180,41 @@ def section_bullets(document, heading): section.append(line) return [line for line in section if line.startswith("- ")] -def assert_review_convergence(document): - for marker in ( +required_review_markers = ( "Draft", "稳定 HEAD", "同一 HEAD", "Review 正在运行", "文字结论", "最多两轮", - ): - assert marker in document, (marker, document[:80]) - for forbidden in ( - "每次新提交后立即", - "只有收到 👍", - "新提交必须重新 Review", - ): - assert forbidden not in document, (forbidden, document[:80]) + "至少等待 15 分钟", + "明确失败", + "允许重试一次", +) +forbidden_review_markers = ( + "每次新提交后立即", + "Review 正在运行时仍再次", + "只有收到 👍", +) + +def review_policy_violations(document): + missing = [marker for marker in required_review_markers if marker not in document] + forbidden = [marker for marker in forbidden_review_markers if marker in document] + return missing, forbidden + +def assert_review_convergence(document): + missing, forbidden = review_policy_violations(document) + assert not missing, (missing, document[:80]) + assert not forbidden, (forbidden, document[:80]) assert_review_convergence(review_convergence_good) -try: - assert_review_convergence(review_convergence_legacy) -except AssertionError: - pass -else: - raise AssertionError("旧的逐提交重复 Review 策略不应满足收敛契约") +for fixture_name, expected_violation in review_convergence_failures.items(): + document = ( + root / "tests" / "fixtures" / "review-convergence-policy" / fixture_name + ).read_text() + missing, forbidden = review_policy_violations(document) + assert not missing, (fixture_name, missing) + assert forbidden == [expected_violation], (fixture_name, forbidden) for marker in ( "PROJECT_REPLACE", From 51ff1617503af48abb22873b26c9e40befe9c16a Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Thu, 13 Aug 2026 16:09:16 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=E5=AE=A1=E6=9F=A5?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E6=9D=83=E5=A8=81=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:最终复审指出根规则仍残留同一 HEAD 绝对一次上限,且措辞黑名单无法识别等价冲突策略。 改动:统一根规则与模板的失败重试语义;以完整六条权威段落做精确一致性校验,三个反例分别只变异一个规则位置。 验证:基线 fixture、ShellCheck、Ruff、Python 编译、82 个 YAML 解析和 git diff --check 通过。 Co-Authored-By: Codex --- AGENTS.md | 4 +- templates/AGENTS.md | 4 +- .../review-convergence-policy/eager-review.md | 15 +++-- .../review-convergence-policy/good.md | 15 +++-- .../inflight-duplicate.md | 15 +++-- .../reaction-gate.md | 15 +++-- tests/test-audit.sh | 60 ++++++++----------- 7 files changed, 57 insertions(+), 71 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f5d9aac..0444b73 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,8 +24,8 @@ ## 官方 Review 收敛 - PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得再次评论 `@codex review`。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 - 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 - 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 - PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/templates/AGENTS.md b/templates/AGENTS.md index d5355ce..748948b 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -32,10 +32,10 @@ ## 官方 Review 收敛 - PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时不得再次评论 `@codex review`。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 - 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 - 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 新提交会让旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 - PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 ## CI/CD 公共门禁 diff --git a/tests/fixtures/review-convergence-policy/eager-review.md b/tests/fixtures/review-convergence-policy/eager-review.md index e9f8957..edbcc15 100644 --- a/tests/fixtures/review-convergence-policy/eager-review.md +++ b/tests/fixtures/review-convergence-policy/eager-review.md @@ -1,9 +1,8 @@ -# 逐提交触发反例 +## 官方 Review 收敛 -- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 -- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 -- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 -- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 -- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 -- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 -- 每次新提交后立即评论 `@codex review`。 +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 最终 Review 后每次新提交都立即评论 `@codex review`,逐个中间提交重新审查。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/good.md b/tests/fixtures/review-convergence-policy/good.md index 0236fc3..8d3a1c2 100644 --- a/tests/fixtures/review-convergence-policy/good.md +++ b/tests/fixtures/review-convergence-policy/good.md @@ -1,9 +1,8 @@ -# 收敛式 Review 正例 +## 官方 Review 收敛 -- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 -- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 -- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 -- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 -- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 -- 最终 Review 后出现新提交必须重新 Review,但应等修改批次恢复稳定 HEAD 后统一触发。 -- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/inflight-duplicate.md b/tests/fixtures/review-convergence-policy/inflight-duplicate.md index 3da1949..1b8ea64 100644 --- a/tests/fixtures/review-convergence-policy/inflight-duplicate.md +++ b/tests/fixtures/review-convergence-policy/inflight-duplicate.md @@ -1,9 +1,8 @@ -# 在途重复触发反例 +## 官方 Review 收敛 -- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 -- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 -- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 -- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 -- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 -- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 -- Review 正在运行时仍再次评论 `@codex review`。 +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时仍再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/reaction-gate.md b/tests/fixtures/review-convergence-policy/reaction-gate.md index da76dc9..0b55ba6 100644 --- a/tests/fixtures/review-convergence-policy/reaction-gate.md +++ b/tests/fixtures/review-convergence-policy/reaction-gate.md @@ -1,9 +1,8 @@ -# Reaction 门禁反例 +## 官方 Review 收敛 -- Draft 阶段先完成实现、测试和内部交叉审查,范围冻结后再进入官方 Review。 -- 同一 HEAD 最多人工请求一次;已有 Review 正在运行时不得重复触发。 -- 所有 finding 按根因批量处理,完成后只对稳定 HEAD 请求最终复审。 -- 当前 HEAD 获得未发现重大问题的文字结论即视为本轮通过,不追求 emoji 或 reaction。 -- 正常最多两轮完整官方 Review;第三轮必须由维护者重新评估范围、拆分或记录例外。 -- Automatic Review 未出现时至少等待 15 分钟;请求明确失败或超时且没有结果时允许重试一次。 -- 只有收到 👍 才算通过。 +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 只有收到 👍 才算通过,明确文字结论不能作为有效结果。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 2b77d65..51de927 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -163,9 +163,9 @@ review_convergence_good = ( root / "tests" / "fixtures" / "review-convergence-policy" / "good.md" ).read_text() review_convergence_failures = { - "eager-review.md": "每次新提交后立即", - "inflight-duplicate.md": "Review 正在运行时仍再次", - "reaction-gate.md": "只有收到 👍", + "eager-review.md": 4, + "inflight-duplicate.md": 1, + "reaction-gate.md": 3, } audit_entrypoint = (root / "scripts" / "audit-github-baseline.sh").read_text() audit_source = (root / "scripts" / "audit_github_baseline.py").read_text() @@ -180,41 +180,27 @@ def section_bullets(document, heading): section.append(line) return [line for line in section if line.startswith("- ")] -required_review_markers = ( - "Draft", - "稳定 HEAD", - "同一 HEAD", - "Review 正在运行", - "文字结论", - "最多两轮", - "至少等待 15 分钟", - "明确失败", - "允许重试一次", +canonical_review_rules = section_bullets( + review_convergence_good, "## 官方 Review 收敛" ) -forbidden_review_markers = ( - "每次新提交后立即", - "Review 正在运行时仍再次", - "只有收到 👍", -) - -def review_policy_violations(document): - missing = [marker for marker in required_review_markers if marker not in document] - forbidden = [marker for marker in forbidden_review_markers if marker in document] - return missing, forbidden - -def assert_review_convergence(document): - missing, forbidden = review_policy_violations(document) - assert not missing, (missing, document[:80]) - assert not forbidden, (forbidden, document[:80]) - -assert_review_convergence(review_convergence_good) -for fixture_name, expected_violation in review_convergence_failures.items(): +assert len(canonical_review_rules) == 6, canonical_review_rules +for fixture_name, expected_changed_index in review_convergence_failures.items(): document = ( root / "tests" / "fixtures" / "review-convergence-policy" / fixture_name ).read_text() - missing, forbidden = review_policy_violations(document) - assert not missing, (fixture_name, missing) - assert forbidden == [expected_violation], (fixture_name, forbidden) + fixture_rules = section_bullets(document, "## 官方 Review 收敛") + assert len(fixture_rules) == len(canonical_review_rules), fixture_name + changed_indexes = [ + index + for index, (expected, actual) in enumerate( + zip(canonical_review_rules, fixture_rules) + ) + if expected != actual + ] + assert changed_indexes == [expected_changed_index], ( + fixture_name, + changed_indexes, + ) for marker in ( "PROJECT_REPLACE", @@ -244,7 +230,6 @@ for document in (review_contract, readme, maintenance): ): assert marker in document, (marker, document[:40]) for document in (root_agents, template, review_contract, readme, maintenance): - assert_review_convergence(document) for marker in ( "Review 当前 HEAD", "全部 review thread 已解决", @@ -253,6 +238,8 @@ for document in (root_agents, template, review_contract, readme, maintenance): "暂不允许", ): assert marker in document, (marker, document[:40]) +for document in (root_agents, template): + assert section_bullets(document, "## 官方 Review 收敛") == canonical_review_rules for document in (review_contract, readme, maintenance): for marker in ( "新提交", @@ -260,6 +247,9 @@ for document in (review_contract, readme, maintenance): "不保证自动关闭", "不是 required check", "Dependabot", + "至少等待 15 分钟", + "明确失败", + "允许重试一次", ): assert marker in document, (marker, document[:40]) assert "不要求每个中间提交" in document, document[:40] From 375be22fb1c90865958e50c3348a6dd9b63b31e7 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Thu, 13 Aug 2026 16:21:15 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E6=A0=A1=E9=AA=8C=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E6=94=B6=E6=95=9B=E7=AB=A0=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:定向复审指出测试只比较顶层列表项,夹入冲突正文仍可能绕过权威规则同步校验。 改动:改为比较规范化后的完整章节,并加入列表间冲突段落反例。 验证:基线 fixture、ShellCheck、Bash 语法、Ruff、Python 编译、82 个 YAML 解析和 git diff --check 通过。 Co-Authored-By: Codex --- .../prose-conflict.md | 11 ++++++ tests/test-audit.sh | 38 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/review-convergence-policy/prose-conflict.md diff --git a/tests/fixtures/review-convergence-policy/prose-conflict.md b/tests/fixtures/review-convergence-policy/prose-conflict.md new file mode 100644 index 0000000..cb66c63 --- /dev/null +++ b/tests/fixtures/review-convergence-policy/prose-conflict.md @@ -0,0 +1,11 @@ +## 官方 Review 收敛 + +- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 + +同一 HEAD 在任何情况下都不得重试,即使请求已经明确失败或超时。 + +- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 +- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 +- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 +- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 +- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 51de927..98c98c1 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -170,20 +170,50 @@ review_convergence_failures = { audit_entrypoint = (root / "scripts" / "audit-github-baseline.sh").read_text() audit_source = (root / "scripts" / "audit_github_baseline.py").read_text() -def section_bullets(document, heading): +def section_content(document, heading): lines = document.splitlines() start = lines.index(heading) + 1 section = [] for line in lines[start:]: if line.startswith("## "): break - section.append(line) - return [line for line in section if line.startswith("- ")] + section.append(line.rstrip()) + return "\n".join(section).strip() + +def section_bullets(document, heading): + return [ + line + for line in section_content(document, heading).splitlines() + if line.startswith("- ") + ] + +canonical_review_section = section_content( + review_convergence_good, "## 官方 Review 收敛" +) canonical_review_rules = section_bullets( review_convergence_good, "## 官方 Review 收敛" ) assert len(canonical_review_rules) == 6, canonical_review_rules + + +def has_canonical_review_section(document): + return ( + section_content(document, "## 官方 Review 收敛") + == canonical_review_section + ) + + +prose_conflict = ( + ( + root + / "tests" + / "fixtures" + / "review-convergence-policy" + / "prose-conflict.md" + ).read_text() +) +assert not has_canonical_review_section(prose_conflict) for fixture_name, expected_changed_index in review_convergence_failures.items(): document = ( root / "tests" / "fixtures" / "review-convergence-policy" / fixture_name @@ -239,7 +269,7 @@ for document in (root_agents, template, review_contract, readme, maintenance): ): assert marker in document, (marker, document[:40]) for document in (root_agents, template): - assert section_bullets(document, "## 官方 Review 收敛") == canonical_review_rules + assert has_canonical_review_section(document) for document in (review_contract, readme, maintenance): for marker in ( "新提交", From 023d25d202faa5ac5e447018a58a63591621b18c Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Thu, 13 Aug 2026 18:13:37 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E6=8C=89=E5=AE=98=E6=96=B9=E8=BE=B9?= =?UTF-8?q?=E7=95=8C=E6=94=B6=E7=BC=A9=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:实际 PR 验证表明,把所有 P2 建议当成阻塞项并要求修改后复审会造成 review churn,与官方高信号 P0/P1 定位不符。 改动:以当前可达影响定义阻塞项,P2/P3 默认不报告也不阻塞;为根规则和项目模板加入正反 few-shot,删除审查轮数与措辞状态机及其 fixture。 验证:基线 fixture、ShellCheck、Bash 语法、Ruff、Python 编译、82 个 YAML 解析和 git diff --check 通过。 Co-Authored-By: Codex --- AGENTS.md | 26 +++--- MAINTENANCE.md | 17 ++-- README.md | 12 +-- contracts/codex-code-review.md | 47 +++++----- templates/AGENTS.md | 24 ++--- .../review-convergence-policy/eager-review.md | 8 -- .../review-convergence-policy/good.md | 8 -- .../inflight-duplicate.md | 8 -- .../prose-conflict.md | 11 --- .../reaction-gate.md | 8 -- tests/test-audit.sh | 89 ++++++------------- 11 files changed, 90 insertions(+), 168 deletions(-) delete mode 100644 tests/fixtures/review-convergence-policy/eager-review.md delete mode 100644 tests/fixtures/review-convergence-policy/good.md delete mode 100644 tests/fixtures/review-convergence-policy/inflight-duplicate.md delete mode 100644 tests/fixtures/review-convergence-policy/prose-conflict.md delete mode 100644 tests/fixtures/review-convergence-policy/reaction-gate.md diff --git a/AGENTS.md b/AGENTS.md index 0444b73..b2a76ab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,15 +17,17 @@ ## Code Review Rules -- 优先识别会造成错误放行、错误阻断、权限扩大、secret 暴露、供应链漂移或发布/回滚证据失真的具体问题,并核对新增公共 MUST 是否确实跨项目通用。 -- 审计器变更必须同时具有能复现旧缺口的失败 fixture 和保持合法项目通过的正例;只增加字符串匹配而不能证明约束时应指出误报或漏报路径。 -- 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并。 - -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 +### 阻塞边界 + +- 只提交 P0/P1 finding:问题必须由当前 PR 引入、存在当前可达的触发路径,并会造成明确的正确性、安全、权限、数据、兼容性或发布后果;评论必须说明触发条件、实际影响和最小安全路径,证据不足则不报告。 +- P2/P3、纯防御性加固、需要未来维护者同时修改规则与测试才成立的假设、测试还可增加更多 fixture、lint/格式/措辞/命名或无当前影响的重构默认不报告,也不得仅因建议有价值就阻塞合并。 + +### 本仓重点 + +- 重点检查会造成审计错误放行或错误阻断、权限扩大、secret 暴露、供应链漂移、发布/回滚证据失真,或把单项目细节误升格为公共 MUST 的改动;机械一致性继续交给确定性 CI。 + +### Few-shot + +正例:缺少 `dev` Environment 时审计仍返回 `PASS`,使发布 secret 绕过审批;这是当前可达的权限后果,应提交 P1。 + +反例:还可以增加嵌套列表、另一种措辞或更多 fixture,让测试覆盖更全面;这属于 P2/P3 加固,不提交 finding。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 92d9b27..d725e49 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -23,7 +23,7 @@ ## 新项目接入 1. 在独立 worktree 中复制 `templates/AGENTS.md`,替换占位符并补齐项目内部规则;项目规则不得降低公共 MUST,根文件必须保留精确 `## Code Review Rules` 标题。 -2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发,或批量修复后需要对稳定 HEAD 做最终复审时才使用 `@codex review`。 +2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发时先排查设置和事件,确认没有结果或在途信号后才使用 `@codex review`。 3. 保持 Auto-merge 关闭;官方 Review 尚非 required check 时不得为单个 PR 开启 Auto-merge。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用合并后自动删除远端分支。 4. 复制并按项目实际情况改造 `templates/` 下的 PR、release workflow、`release-safety.yml` 与 `release-safety-contract.sh`;把后两者分别安装为 `.github/release-safety.yml` 与 `.github/scripts/release-safety-contract.sh`,保持 wrapper 的 Git mode 为 `100755`,并映射项目真实 job/step 拓扑。 5. 通过真实 PR 证明 `PR container validation` 成功,随后原子迁移 master required check。 @@ -54,13 +54,14 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. ## 官方 Codex Code Review 维护 - 只采用官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或平行评论协议。 -- 自动触发依赖官方 `Automatic reviews`;`AGENTS.md` 只定义审查规则,不能代替设置。自动审查未出现,或批量修复后需要对稳定 HEAD 做最终复审时才使用 `@codex review`。 +- 自动触发依赖官方 `Automatic reviews`;`AGENTS.md` 只定义审查规则,不能代替设置。自动审查未出现时先按官方说明排查仓库开关、Codex cloud 和触发事件,确认没有结果或在途信号后才使用 `@codex review`。 - 非平凡 PR 先保持 Draft,完成实现、测试、内部交叉审查和范围冻结后再进入官方 Review;多个独立架构边界必须拆分,跨仓变更先冻结共享协议,最终集成 PR 才使用 `Closes #xx`。 -- 等一轮 findings 完整返回后按根因批量修复。同一 HEAD 不得并发或对有效结果重复请求,Review 正在运行或尚未返回时不得再次触发;不得一条 finding 对应一次 push 和一次完整 Review。 -- 普通 PR 最多两轮完整官方 Review;第三轮必须显式记录原因,并先判断拆分、收窄范围或接受有依据的非阻塞项。当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定口令。 -- 新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;全部修改完成并恢复稳定 HEAD 后只请求一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线。请求明确失败或预定超时且没有结果、没有在途信号时允许重试一次并记录原因;重试仍失败则停止并排查官方集成,不制造空提交改变 HEAD。 -- v1 保持观察模式,不把官方 Review 增加为 required check,不修改现有 branch protection,也不要求官方输出自定义批准口令或严重级别。 +- `## Code Review Rules` 保持两到三条简洁、项目特有的高后果规则,并提供安全路径或正反 few-shot;机械一致性、lint 和格式交给确定性 CI。 +- 只提交 P0/P1 finding:必须证明问题由当前 PR 引入、存在当前可达路径并造成明确正确性、安全、权限、数据、兼容性或发布后果。若产品仍输出 P2/P3,则默认不阻塞;只有维护者给出可复现证据并明确升级后才按阻塞项处理。 +- 等一轮 findings 返回后统一分类。阻塞项按根因批量修复;非阻塞项回复处置依据后解决 thread,不修改代码、不自动建 Issue,也无需重新 Review。 +- 只有阻塞修复显著改变原风险面时才做一次定向 Review;定向 Review 再出现非阻塞建议时直接记录处置并停止,再出现新的阻塞 P0/P1 时先拆分、收窄或重新设计 PR。 +- 官方 Reviewer 给出未发现重大问题的文字结论,或全部 finding 完成阻塞分类与处置,即视为闭环;不追求 emoji、reaction、固定口令或零评论。 +- v1 保持建议模式,不把官方 Review 增加为 required check,不修改现有 branch protection;required checks 仍是确定性门禁。 - 官方设置和审查行为通过真实 PR 验收;中央审计只检查根 `AGENTS.md` 是普通文件,且固定 `markdown-it-py==3.0.0` CommonMark parser 产生源码行精确等于 `## Code Review Rules` 的真实 h2。不得恢复手写 Markdown 状态机,也不抓取页面、调用私有接口或伪称验证同一 HEAD 请求次数、在途 Review 和审查预算。 - 官方功能演进时先更新接入说明和精简规则;若官方补齐缺口,优先删除临时流程,不维护平行实现。 @@ -68,7 +69,7 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. - GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。官方 Review 当前不是 required check,因此 v1 暂不允许仓库或单个 PR 开启 Auto-merge。 - 不建立 HEAD 监听器、自动合并 Bot、Action 或定时任务来补这个能力缺口;未来等官方 Review 可成为当前 HEAD required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后再评估。 -- 人工合并前确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功且风险已分类;最终 Review 后出现新提交时,先完成全部修改并恢复稳定 HEAD,再按收敛预算完成最终复审。 +- 人工合并前确认 required checks 成功、阻塞 finding 已修复或有明确风险接受、全部 review thread 已完成处置且依赖与发布风险已分类;非阻塞项不要求修改代码或重复审查。 - Dependabot PR 不能只凭 CI 绿灯自动合并;运行时依赖、跨大版本和会触发生产发布的仓库必须另做兼容性与发布授权判断。 - 分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的长期 head 分支时必须关闭。 - 本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 diff --git a/README.md b/README.md index 5520c60..9324391 100644 --- a/README.md +++ b/README.md @@ -24,21 +24,21 @@ ## 官方 Codex Code Review -基线只接入和治理官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或评论协议。自动唤醒使用官方 `Automatic reviews`;没有自动触发,或批量修复后需要对稳定 HEAD 做最终复审时,才在 PR 评论使用 `@codex review`。 +基线只接入和治理官方 Codex Code Review,不自建 Reviewer、GitHub Action、Bot、Webhook 服务、模型调用或评论协议。自动唤醒使用官方 `Automatic reviews`;未触发时先按官方说明排查设置和事件,确认没有结果或在途信号后才使用 `@codex review` 人工兜底。 -根 `AGENTS.md` 的 `## Code Review Rules` 只告诉官方 Reviewer 应优先检查哪些项目风险,不能开启 Automatic reviews,也不能证明自动审查已经触发。v1 保持观察模式,不增加 required check,不改变现有 branch protection;官方设置通过真实 PR 验收,中央审计只验证仓库内可稳定读取的规则文件。完整边界见 [官方治理契约](contracts/codex-code-review.md)。 +根 `AGENTS.md` 的 `## Code Review Rules` 只告诉官方 Reviewer 应检查哪些高后果项目风险,不能开启 Automatic reviews,也不能证明自动审查已经触发。按照[官方建议](https://learn.chatgpt.com/docs/third-party/github#customize-what-codex-reviews),规则保持两到三条简洁约束,提供安全路径与正反 few-shot,把 lint、格式和机械一致性留给 CI。v1 保持建议模式,不增加 required check,不改变现有 branch protection;完整边界见[官方治理契约](contracts/codex-code-review.md)。 -采用收敛式 Review:非平凡 PR 在 Draft 阶段完成实现、测试、内部交叉审查与范围冻结,再让官方 Review 检查稳定 HEAD。一轮 findings 完整返回后按根因批量修复;同一 HEAD 不允许并发或对有效结果重复请求,Review 正在运行时不得排队新的请求。普通 PR 最多两轮完整 Review,即初审和最终复审;第三轮必须先由维护者判断拆分、收窄范围或接受有依据的非阻塞项。 +阻塞边界以影响证据为准:只提交由当前 PR 引入、存在当前可达路径并会造成明确正确性、安全、权限、数据、兼容性或发布后果的 P0/P1。若产品仍输出 P2/P3,则默认不阻塞;测试还能增加 fixture、理论加固、未来同时修改规则与测试、lint/措辞/命名或纯重构无需修改,也无需重新 Review。 -官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction 或固定批准口令。新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交立即重审;完成一批修改并恢复稳定 HEAD 后只触发一次最终复审。包含多个独立架构边界的大型需求应拆成阶段 PR,跨仓变更先冻结共享协议,只有最终集成 PR 使用 `Closes #xx`。 +非平凡 PR 在 Draft 阶段完成实现、测试、内部交叉审查与范围冻结,再让官方 Review 检查稳定变更。一轮 findings 返回后统一分类:阻塞项按根因批量修复;非阻塞项回复处置依据后解决 thread,不修改代码、不自动建 Issue,也不触发新 Review。只有阻塞修复显著改变原风险面时才进行一次定向 Review;若再次出现新的阻塞 P0/P1,先拆分或收窄 PR,而不是自动循环。 -PR 转为 Ready 后若 Automatic Review 尚未出现,在没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线。请求明确失败,或超过预定超时且没有结果、没有在途信号时允许重试一次并记录原因;重试仍失败就停止 Review 循环并排查官方集成,不通过空提交制造新 HEAD。 +官方 Reviewer 给出未发现重大问题的明确文字结论,或全部 finding 已完成阻塞分类与处置,即视为闭环;不追求 emoji、reaction、固定批准口令或零评论。包含多个独立架构边界的大型需求应拆成阶段 PR,跨仓变更先冻结共享协议,只有最终集成 PR 使用 `Closes #xx`。 ## Auto-merge 与分支清理 GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。由于官方 Review 当前不是 required check,纳管产品仓库在 v1 暂不允许开启 Auto-merge,也不为单个 PR 启用它。 -人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;最终 Review 后出现新提交时,完成修改并恢复稳定 HEAD 后再做一次最终复审,不逐个审查中间提交。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。 +人工合并前必须确认 required checks 成功、阻塞 finding 已修复或有明确风险接受、全部 review thread 已完成处置,且依赖或发布风险已分类;非阻塞项不要求代码修改或重复审查。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。 分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的 `dev`、`release` 等长期 head 分支时必须关闭。本地 worktree 和分支始终只在确认已合并、工作区干净且没有独有提交后清理。 diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index f7e046b..3cf6642 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -11,26 +11,26 @@ ## 2. 触发与规则分离 - MUST:在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,由官方集成自动触发新 PR 审查。 -- MUST:把 PR 标记为 Ready 后先等待 Automatic Review;没有明确失败时至少等待 15 分钟,并在发送评论前立即复查 PR 时间线,仍无 Review 结果或在途信号时,才使用官方评论命令 `@codex review` 作为人工兜底。 -- MUST:同一 HEAD 不得同时存在多个请求,也不得向已经获得有效结果的 HEAD 重复请求;Review 正在运行时不得再次触发。请求明确失败,或超过至少 15 分钟的预定超时且仍没有结果或在途信号时,允许重试一次并记录原因;重试仍失败则停止审查循环并排查集成,不得制造空提交改变 HEAD。 -- MUST:不得为了 emoji、reaction、批准口令或重复确认,向已经获得明确文字结论的 HEAD 再次请求。 +- MUST:Automatic Review 未出现时,先按官方排障说明检查仓库开关、Codex cloud 配置、触发事件与 PR 时间线;确认没有结果或在途信号后,才使用官方评论命令 `@codex review` 人工兜底,不用空提交制造触发。 +- MUST:同一 HEAD 不得并发或重复请求;Review 正在运行,或已经产生有效结果时,不得再次触发,也不得为了 emoji、reaction、批准口令或重复确认追加请求。 - MUST:每个仓库根目录维护普通文件 `AGENTS.md`,并包含独占一行的精确标题 `## Code Review Rules`。 -- MUST:`AGENTS.md` 只声明官方 Reviewer 的审查重点,不能被描述为 Automatic reviews 的开启方式或触发证据。 +- MUST:`AGENTS.md` 只声明官方 Reviewer 的高后果审查重点,不能被描述为 Automatic reviews 的开启方式、触发证据或 required check。 - 项目扩展点:项目可以在根规则或更近目录的 `AGENTS.md` 中补充架构、协议、数据和真实验收约束,但不得降低根级公共审查原则。 ## 3. 审查内容 -- MUST:规则优先要求寻找有可触发场景和实际影响的问题,包括但不限于正确性、性能、回归、安全、隐私、权限、可维护性、数据/API 兼容、跨仓协议与 CI/CD 基线风险。 -- MUST:PR 描述、实现者解释和已有测试都视为待验证声明;审查应对照改动、相关调用方和测试证据独立判断。 -- MUST:避免重复 lint、格式化和类型检查已能稳定发现的问题,避免纯风格偏好、无实际影响的猜测和与当前风险无关的大范围重构建议。 -- MUST:不要求官方 Reviewer 使用自定义严重级别、批准口令或评论格式,以免把基线绑定到官方当前输出实现。 +- MUST:遵循[官方 Code Review 定位](https://learn.chatgpt.com/docs/third-party/github):标准 GitHub Review 只提交高优先级 P0/P1;规则只保留两到三条简洁、项目特有且结果导向的约束,并给出安全路径或正反 few-shot。 +- MUST:finding 只有同时满足以下条件才是阻塞项:由当前 PR 引入、存在当前可达的触发路径、违反明确验收标准,并会造成具体的正确性、安全、权限、数据、兼容性或发布后果;标签本身不能替代影响证据。 +- MUST:P0/P1 在满足上述证据时默认阻塞。若产品仍输出 P2/P3,则默认不阻塞也不要求修改;只有维护者给出可复现证据并明确升级后,才进入当前 PR 的阻塞集合。 +- MUST:纯防御性加固、需要未来维护者同时修改规则与测试才成立的假设、测试还可增加更多 fixture、lint/格式/措辞/命名、纯重构或没有当前影响的建议默认不报告;出现时记录“不阻塞”的处置依据即可,无需重新 Review。 +- MUST:PR 描述、实现者解释和已有测试都视为待验证声明;审查应对照改动、相关调用方和测试证据独立判断,但机械一致性继续由确定性 CI 负责。 - 项目扩展点:各项目补充高风险模块、跨仓消费者、迁移兼容、前端状态协议和真实用户路径。 -## 4. 收敛式 Review +## 4. Finding 处置与收敛 -本节用于防止 review churn:官方 Review 是稳定变更的独立风险关卡,不是持续开发阶段的穷举式调试循环。 +本节用于防止 review churn:官方 Review 是高信号风险探测器,不是穷举式调试器,也不是独立于 CI 和维护者判断的平行状态机。 -“稳定 HEAD”指当前范围已冻结、没有已知待提交代码、项目测试和 required CI 已通过,且跨仓共享协议已经对齐;只有该状态才进入初审或最终复审。 +“稳定变更”指当前范围已冻结、没有已知待提交代码、项目测试已通过,且跨仓共享协议已经对齐;只有该状态才进入官方 Review。 ### 4.1 Draft 与范围冻结 @@ -41,27 +41,26 @@ ### 4.2 一轮收齐与批量修复 -- MUST:等待一轮 Review 完整结束并收齐 findings,再统一分类和修复;不得一条 finding 对应一次 push 和一次完整 Review。 -- MUST:对当前范围内可复现且有实际影响的问题完成修复;重复、outdated、既有问题、明确非目标或未支持的极端场景,允许说明依据后解决 thread、拒绝或转为后续 Issue,不因建议有效就自动扩大当前 PR 范围。 -- MUST:按根因合并相关修复,先在本地完成针对性回归和内部复核,再把一个完整修复批次推到 PR;required CI 仍按仓库规则运行,但不得为了启动下一轮 Review 拆出无意义的中间 push。 +- MUST:等待一轮 Review 完整结束并收齐 findings,再按“阻塞、非阻塞、重复/outdated、既有问题或范围外”统一分类;不得一条 finding 对应一次 push 和一次完整 Review。 +- MUST:阻塞 finding 按根因批量修复,在本地完成针对性回归后推送一个完整批次;只有修复显著改变原风险面时,才请求一次聚焦该阻塞项的定向 Review。 +- MUST:非阻塞 finding 回复影响判断与处置依据后解决 thread;不修改代码、不创建跟踪 Issue,也不触发新 Review,除非维护者另行决定其确有独立价值。 +- MUST:Review 后新增与 finding 无关的业务范围时,PR 退回 Draft、重新冻结范围并重新审查;仅修复已分类 finding 时,以修复证据、确定性测试和 required CI 完成闭环。 -### 4.3 Single-flight、预算与停止条件 +### 4.3 通过与停止条件 -- MUST:同一 HEAD 同一时刻只能有一个 Review 请求;Review 正在运行或结果尚未返回时不得排队新的请求。运行期间出现新提交时,先等待当前结果、完成剩余批量修复,再对最终稳定 HEAD 请求一次复审;明确失败或预定超时且没有任何结果的尝试不计为完整 Review 轮次,并按前述边界允许重试一次。 -- MUST:普通 PR 最多两轮完整官方 Review,即初审和一次最终复审;第三轮必须由维护者显式记录原因,并先判断是否需要拆分 PR、收窄范围或接受有依据的非阻塞项,不得自动进入下一轮。 -- MUST:官方 Reviewer 对当前 HEAD 给出未发现重大问题的明确文字结论,即视为本轮 Review 通过;不要求 emoji、reaction、固定措辞或额外重复确认。 -- MUST:人工合并仍要求 Review 当前 HEAD;新提交会使旧 Review 失去最终 HEAD 证据资格,但不要求每个中间提交都立即重新 Review,只在实现与修复重新稳定后触发一次。 +- MUST:官方 Reviewer 给出未发现重大问题的明确文字结论,或所有 finding 均已完成阻塞分类与处置,即视为本轮 Review 闭环;不要求 emoji、reaction、固定措辞或零评论。 +- MUST:P2/P3、加固建议和已解释的非阻塞 thread 不得成为继续修改与复审的理由;若定向 Review 又提出新的非阻塞建议,直接记录处置并停止。 +- MUST:定向 Review 再发现新的阻塞 P0/P1,说明范围或设计仍不稳定;维护者必须先决定拆分 PR、收窄范围或重新设计,不得自动进入无界循环。 ## 5. v1 合并边界 - MUST:v1 采用观察模式,官方 Review 不新增为 required status check,也不改变现有 `master` branch protection。 - MUST:没有官方稳定状态接口和真实仓库验证前,不假设 Review 能映射为 GitHub required check、approval 或固定 check 名称。 -- MUST:Review 发现的问题按现有 PR 对话处理;是否阻塞合并由现有门禁和维护者判断,不增加平行状态机。 +- MUST:Review 发现的问题按现有 PR 对话处理;是否阻塞合并由本契约的影响证据、现有门禁和维护者判断,不增加平行状态机。 - MUST:[GitHub 官方文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request)只保证无写权限者向已开启 Auto-merge 的 PR 推送时自动关闭;有写权限者推送新提交后不保证自动关闭,Auto-merge 可能继续保持开启。官方 Review 当前又不是 required check,因此 v1 暂不允许仓库或单个 PR 开启 Auto-merge。 - MUST:不创建自研合并 Bot、Action、HEAD 监听器或平行状态机来补 GitHub/Codex 当前能力缺口。 - MUST:合并后自动删除远端分支不是所有项目的公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才允许启用该设置;否则必须关闭,避免 GitHub 删除仍需复用的长期分支。 -- MUST:人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功,且依赖或发布风险已分类。 -- MUST:PR 在最终 Review 后出现新提交时,旧 Review 不再作为当前 HEAD 的合并证据;先完成全部修改并恢复稳定 HEAD,再按收敛式 Review 预算完成最终复审和 thread 确认。 +- MUST:人工合并前必须确认 required checks 成功、阻塞 finding 已修复或有明确风险接受、全部 review thread 已完成处置,且依赖或发布风险已分类;非阻塞 finding 无需修改代码或重新 Review。 - MUST:Dependabot PR 不因 CI 通过而自动合并;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 - 项目扩展点:未来只有在官方 Review 能成为与当前 HEAD 绑定的 required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后,才重新评估启用原生 Auto-merge。 @@ -70,8 +69,8 @@ - MUST:中央只读审计检查根 `AGENTS.md` 是 Git tree 中的普通文件,并在 fenced code、HTML comment 与 raw HTML block 之外包含精确 `## Code Review Rules` 标题;缺失、symlink、非普通文件或缺少真实标题统一报告 `[CODE_REVIEW_RULES]`。 - MUST:审计使用固定 `markdown-it-py==3.0.0` 的 CommonMark parser,只接受真实 `h2` token,且 token 对应源码行必须精确等于 `## Code Review Rules`;不得维护平行的手写 Markdown 状态机。 - MUST:直接依赖 `markdown-it-py==3.0.0` 与传递依赖 `mdurl==0.1.2` 在本地入口和两条基线 workflow 中显式校验或固定安装,不得依赖运行环境碰巧预装的版本。 -- MUST:中央审计不抓取 GitHub/Codex 页面、不调用私有接口,也不声称验证 Automatic reviews 设置、模型审查质量、同一 HEAD 请求次数、在途 Review 或审查轮次预算;这些运行态事实由真实 PR 时间线验收。 -- MUST:中央审计验证纳管产品仓库关闭 Auto-merge;分支自动删除取决于项目真实分支模型,不由公共审计强制。人工合并前是否完成当前 HEAD Review、解决 thread 与风险分类,由真实 PR 验收,不伪装成静态仓库审计结论。 +- MUST:中央审计不抓取 GitHub/Codex 页面、不调用私有接口,也不声称验证 Automatic reviews 设置、模型审查质量、同一 HEAD 请求次数或在途 Review;这些运行态事实由真实 PR 时间线验收。 +- MUST:中央审计验证纳管产品仓库关闭 Auto-merge;分支自动删除取决于项目真实分支模型,不由公共审计强制。人工合并前是否完成 finding 分类、thread 处置与风险判断,由真实 PR 验收,不伪装成静态仓库审计结论。 - MUST:官方设置通过真实 PR 验收:Automatic reviews 能产生审查;必要时 `@codex review` 能触发人工兜底;Reviewer 能遵循仓库规则。 - MUST:接入不得新增 review 专用 secret、GitHub App、workflow、runner 或发布权限。 - 项目扩展点:保存测试 PR、Review 链接和观察期结论的方式。 diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 748948b..85c5b3a 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -25,18 +25,20 @@ ## Code Review Rules -- 只报告可证实且会造成实际影响的问题;尤其关注正确性、性能、回归、安全、隐私、权限、可维护性等风险。 -- 检查数据/API 与跨仓协议兼容、CI/CD 权限边界、失败/回滚路径及测试能否证明这些高风险行为。 -- 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并;项目重点:PROJECT_REPLACE_REVIEW_RULES +### 阻塞边界 -## 官方 Review 收敛 +- 只提交 P0/P1 finding:问题必须由当前 PR 引入、存在当前可达的触发路径,并会造成明确的正确性、安全、权限、数据、兼容性或发布后果;评论必须说明触发条件、实际影响和最小安全路径,证据不足则不报告。 +- P2/P3、纯防御性加固、需要未来维护者同时修改规则与测试才成立的假设、测试还可增加更多 fixture、lint/格式/措辞/命名或无当前影响的重构默认不报告,也不得仅因建议有价值就阻塞合并。 -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 +### 项目重点 + +- 检查数据/API 与跨仓协议兼容、CI/CD 权限边界、失败/回滚路径及测试能否证明这些高风险行为;机械一致性继续交给确定性 CI;项目重点:PROJECT_REPLACE_REVIEW_RULES + +### Few-shot + +正例:新增接口绕过现有授权校验,使普通用户能够读取他人数据;这是当前可达的安全后果,应提交 P1。 + +反例:还可以增加另一种输入形式的 fixture 或重命名 helper 以提升可维护性,但当前支持路径没有错误;这属于 P2/P3 加固,不提交 finding。 ## CI/CD 公共门禁 @@ -51,7 +53,7 @@ - 发布、手动部署、self-hosted、`dev` Environment 和发布 secret 能力只存在于唯一受控 release workflow;按真实拓扑维护 `.github/release-safety.yml`,不要把模板 job/step ID 当成公共事实。 - 项目可执行契约测试负责证明 ref/内容 ID、容器内 smoke、回滚命令和实际目标 SHA;固定 `100755` wrapper 内部调用项目测试,`PR container validation` job 名称必须唯一、无依赖且无条件执行,workflow/job/targeted step 不得自定义 shell 或工作目录,targeted step 只以精确单行 `run` 执行 manifest 声明路径。中央审计只验证 manifest 与结构化 YAML 高层约束,不解释任意 shell 控制流。 - `master` 要求 GitHub Actions 产生的 `PR container validation`,启用 strict、管理员保护和对话解决,禁止 force push 与删除。 -- 官方 Review 尚非当前 HEAD 的 required check 时,仓库保持 `allow_auto_merge=false`;只在 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功后人工合并。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才设置 `delete_branch_on_merge=true`。 +- 官方 Review 不是 required check 时,仓库保持 `allow_auto_merge=false`;只在 required checks 成功、阻塞 finding 已解决或有明确风险处置且 review thread 已完成处置后人工合并。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才设置 `delete_branch_on_merge=true`。 ## 项目命令 diff --git a/tests/fixtures/review-convergence-policy/eager-review.md b/tests/fixtures/review-convergence-policy/eager-review.md deleted file mode 100644 index edbcc15..0000000 --- a/tests/fixtures/review-convergence-policy/eager-review.md +++ /dev/null @@ -1,8 +0,0 @@ -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后每次新提交都立即评论 `@codex review`,逐个中间提交重新审查。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/good.md b/tests/fixtures/review-convergence-policy/good.md deleted file mode 100644 index 8d3a1c2..0000000 --- a/tests/fixtures/review-convergence-policy/good.md +++ /dev/null @@ -1,8 +0,0 @@ -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/inflight-duplicate.md b/tests/fixtures/review-convergence-policy/inflight-duplicate.md deleted file mode 100644 index 1b8ea64..0000000 --- a/tests/fixtures/review-convergence-policy/inflight-duplicate.md +++ /dev/null @@ -1,8 +0,0 @@ -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 最多人工请求一次,Review 正在运行时仍再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/prose-conflict.md b/tests/fixtures/review-convergence-policy/prose-conflict.md deleted file mode 100644 index cb66c63..0000000 --- a/tests/fixtures/review-convergence-policy/prose-conflict.md +++ /dev/null @@ -1,11 +0,0 @@ -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 - -同一 HEAD 在任何情况下都不得重试,即使请求已经明确失败或超时。 - -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 获得未发现重大问题的明确文字结论即视为通过,不追求 emoji、reaction、固定批准口令或重复确认。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/fixtures/review-convergence-policy/reaction-gate.md b/tests/fixtures/review-convergence-policy/reaction-gate.md deleted file mode 100644 index 0b55ba6..0000000 --- a/tests/fixtures/review-convergence-policy/reaction-gate.md +++ /dev/null @@ -1,8 +0,0 @@ -## 官方 Review 收敛 - -- PR 在 Draft 阶段完成实现、测试、内部交叉审查和范围冻结后,再让 Automatic reviews 审查稳定 HEAD;官方 Review 不作为逐提交调试器。 -- 一轮 findings 全部返回后按根因批量修复;同一 HEAD 不得并发请求或向已有有效结果重复请求,Review 正在运行时不得再次评论 `@codex review`。 -- 正常最多两轮完整官方 Review;第三轮必须显式判断拆分、收窄范围或有依据地接受非阻塞项。 -- 当前 HEAD 只有收到 👍 才算通过,明确文字结论不能作为有效结果。 -- 最终 Review 后出现新提交必须重新 Review,但不要求每个中间提交立即重审;全部修复完成并恢复稳定 HEAD 后只触发一次最终复审。 -- PR 转为 Ready 后,Automatic Review 未出现且没有明确失败时至少等待 15 分钟,并在人工评论前立即复查时间线;请求明确失败或超时且没有结果、没有在途信号时允许重试一次,重试仍失败则停止并排查集成。 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 98c98c1..b033591 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -159,14 +159,6 @@ contract = (root / "contracts" / "ci-cd-baseline.md").read_text() review_contract = (root / "contracts" / "codex-code-review.md").read_text() readme = (root / "README.md").read_text() maintenance = (root / "MAINTENANCE.md").read_text() -review_convergence_good = ( - root / "tests" / "fixtures" / "review-convergence-policy" / "good.md" -).read_text() -review_convergence_failures = { - "eager-review.md": 4, - "inflight-duplicate.md": 1, - "reaction-gate.md": 3, -} audit_entrypoint = (root / "scripts" / "audit-github-baseline.sh").read_text() audit_source = (root / "scripts" / "audit_github_baseline.py").read_text() @@ -188,50 +180,6 @@ def section_bullets(document, heading): if line.startswith("- ") ] -canonical_review_section = section_content( - review_convergence_good, "## 官方 Review 收敛" -) -canonical_review_rules = section_bullets( - review_convergence_good, "## 官方 Review 收敛" -) -assert len(canonical_review_rules) == 6, canonical_review_rules - - -def has_canonical_review_section(document): - return ( - section_content(document, "## 官方 Review 收敛") - == canonical_review_section - ) - - -prose_conflict = ( - ( - root - / "tests" - / "fixtures" - / "review-convergence-policy" - / "prose-conflict.md" - ).read_text() -) -assert not has_canonical_review_section(prose_conflict) -for fixture_name, expected_changed_index in review_convergence_failures.items(): - document = ( - root / "tests" / "fixtures" / "review-convergence-policy" / fixture_name - ).read_text() - fixture_rules = section_bullets(document, "## 官方 Review 收敛") - assert len(fixture_rules) == len(canonical_review_rules), fixture_name - changed_indexes = [ - index - for index, (expected, actual) in enumerate( - zip(canonical_review_rules, fixture_rules) - ) - if expected != actual - ] - assert changed_indexes == [expected_changed_index], ( - fixture_name, - changed_indexes, - ) - for marker in ( "PROJECT_REPLACE", "公共 MUST", @@ -249,8 +197,17 @@ assert "不得降低" in contract for document in (template, root_agents): assert "## Code Review Rules" in document assert len(section_bullets(document, "## Code Review Rules")) == 3 -assert "性能" in section_bullets(template, "## Code Review Rules")[0] -assert "可维护性等风险" in section_bullets(template, "## Code Review Rules")[0] + review_rules = section_content(document, "## Code Review Rules") + for marker in ( + "只提交 P0/P1", + "当前可达", + "P2/P3", + "默认不报告", + "正例:", + "反例:", + ): + assert marker in review_rules, (marker, document[:40]) + assert "## 官方 Review 收敛" not in document for document in (review_contract, readme, maintenance): for marker in ( "官方 Codex Code Review", @@ -259,30 +216,34 @@ for document in (review_contract, readme, maintenance): "不自建", ): assert marker in document, (marker, document[:40]) -for document in (root_agents, template, review_contract, readme, maintenance): +for document in (review_contract, readme, maintenance): for marker in ( - "Review 当前 HEAD", - "全部 review thread 已解决", "单个 PR", "Auto-merge", "暂不允许", ): assert marker in document, (marker, document[:40]) -for document in (root_agents, template): - assert has_canonical_review_section(document) for document in (review_contract, readme, maintenance): for marker in ( - "新提交", "有写权限", "不保证自动关闭", "不是 required check", "Dependabot", - "至少等待 15 分钟", - "明确失败", - "允许重试一次", + "P0/P1", + "P2/P3", + "默认不阻塞", + "无需重新 Review", + "当前可达", ): assert marker in document, (marker, document[:40]) - assert "不要求每个中间提交" in document, document[:40] +for document in (root_agents, template, review_contract, readme, maintenance): + for forbidden in ( + "Review 当前 HEAD", + "最终复审", + "至少等待 15 分钟", + "最多两轮完整", + ): + assert forbidden not in document, (forbidden, document[:40]) for marker in ("markdown-it-py==3.0.0", "mdurl==0.1.2"): assert marker in audit_entrypoint, marker assert 'MarkdownIt("commonmark")' in audit_source