From 0e6e4366ea3f04794488cd359bf799238c97f2d7 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Sun, 9 Aug 2026 23:49:26 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E5=BB=BA=E7=AB=8B=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=88=E5=B9=B6=E6=B2=BB=E7=90=86=E5=9F=BA=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 明确仅在官方 Codex Review 覆盖当前 HEAD、全部 review thread 已解决且风险已分类后,才允许为单个 PR 开启 GitHub 原生 Auto-merge。 中央审计新增仓库级 Auto-merge 与合并后远端分支自动删除检查,并以失败 fixture 锁定两项设置;同步更新契约、模板、README 与维护手册。 验证:bash tests/test-audit.sh;ruff check/format;ShellCheck;bash -n;py_compile;git diff --check。 Co-Authored-By: Codex --- AGENTS.md | 2 +- MAINTENANCE.md | 23 +++++++++++++------ README.md | 7 ++++++ contracts/ci-cd-baseline.md | 1 + contracts/codex-code-review.md | 5 ++++ scripts/audit_github_baseline.py | 8 +++++++ templates/AGENTS.md | 2 +- tests/fixtures/good/repo.json | 2 +- .../repository-auto-merge-disabled/repo.json | 1 + .../repo.json | 1 + tests/test-audit.sh | 18 +++++++++++++++ 11 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 tests/fixtures/repository-auto-merge-disabled/repo.json create mode 100644 tests/fixtures/repository-branch-auto-delete-disabled/repo.json diff --git a/AGENTS.md b/AGENTS.md index 32f45a8..fbe09d8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,4 +19,4 @@ - 优先识别会造成错误放行、错误阻断、权限扩大、secret 暴露、供应链漂移或发布/回滚证据失真的具体问题,并核对新增公共 MUST 是否确实跨项目通用。 - 审计器变更必须同时具有能复现旧缺口的失败 fixture 和保持合法项目通过的正例;只增加字符串匹配而不能证明约束时应指出误报或漏报路径。 -- 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。 +- 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。只有官方 Review 当前 HEAD、全部 review thread 已解决后,才允许对单个 PR 开启 Auto-merge。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index c08b3bf..27b6db3 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -24,13 +24,14 @@ 1. 在独立 worktree 中复制 `templates/AGENTS.md`,替换占位符并补齐项目内部规则;项目规则不得降低公共 MUST,根文件必须保留精确 `## Code Review Rules` 标题。 2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发或需要重审时使用 `@codex review`。 -3. 复制并按项目实际情况改造 `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 拓扑。 -4. 通过真实 PR 证明 `PR container validation` 成功,随后原子迁移 master required check。 -5. 通过一次 master 发布证明 Environment-only secret、旧运行态捕获、候选镜像身份、容器内 smoke、成功后清理和 `DEPLOY_TARGET_SHA` 发布证据。 -6. 将 `owner/repo` 追加到 `repositories.txt`。 -7. 将仓库名追加到中央 `.github/workflows/baseline-drift-audit.yml` 的 `repositories` 显式列表;测试会要求该列表与清单顺序一致。 -8. 把只读 GitHub App `Engineering Baseline Auditor` 的安装范围扩展到新仓库;纳管项目不得保存 App 私钥或个人访问令牌。 -9. 运行 fixture 测试,并在基线仓库人工触发中央 live 审计;两者都成功后才算纳入基线。 +3. 启用 GitHub 原生 Auto-merge 与合并后自动删除远端功能分支;这两个仓库设置不会自动开启任何单个 PR。 +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。 +6. 通过一次 master 发布证明 Environment-only secret、旧运行态捕获、候选镜像身份、容器内 smoke、成功后清理和 `DEPLOY_TARGET_SHA` 发布证据。 +7. 将 `owner/repo` 追加到 `repositories.txt`。 +8. 将仓库名追加到中央 `.github/workflows/baseline-drift-audit.yml` 的 `repositories` 显式列表;测试会要求该列表与清单顺序一致。 +9. 把只读 GitHub App `Engineering Baseline Auditor` 的安装范围扩展到新仓库;纳管项目不得保存 App 私钥或个人访问令牌。 +10. 运行 fixture 测试,并在基线仓库人工触发中央 live 审计;两者都成功后才算纳入基线。 固定 wrapper 内部可以复用既有语言或容器测试;`PR container validation` job 名称必须全局唯一、无 `if`、无 `needs`、无有效 `continue-on-error`,workflow/job 不得覆盖默认 `shell` 或 `working-directory`。manifest 映射的主 PR targeted step 必须以单行 `run` 精确等于 wrapper 路径,不能附加参数、前后命令、`;`、管道或 `||`,也不能声明 `if`、`continue-on-error`、`shell`、`working-directory`,或把 ID 挂到 checkout、`echo`、`test -f` 与不相关的完整构建步骤。 @@ -58,6 +59,14 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. - 官方设置和审查行为通过真实 PR 验收;中央审计只检查根 `AGENTS.md` 是普通文件,且固定 `markdown-it-py==3.0.0` CommonMark parser 产生源码行精确等于 `## Code Review Rules` 的真实 h2。不得恢复手写 Markdown 状态机,也不抓取页面或调用私有接口。 - 官方功能演进时先更新接入说明和精简规则;若官方补齐缺口,优先删除临时流程,不维护平行实现。 +## Auto-merge 维护 + +- 仓库级只启用 GitHub 原生能力,不建立自动开启 PR 的 Bot、Action 或定时任务;启用能力不会自动开启任何单个 PR。 +- 仅在官方 Review 当前 HEAD、全部 review thread 已解决、变更风险已完成分类后,对单个 PR 开启 Auto-merge;required checks 继续由 GitHub 原生门禁执行。 +- 新提交会使旧 HEAD 的审查证据失效,必须重新 Review、重新核对 thread,再重新开启 Auto-merge。 +- Dependabot PR 不能只凭 CI 绿灯自动合并;运行时依赖、跨大版本和会触发生产发布的仓库必须另做兼容性与发布授权判断。 +- 合并后远端功能分支由 GitHub 自动删除。本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 + ## Action 升级 - 只接受上游官方 release 对应的完整 40 位 commit SHA。 diff --git a/README.md b/README.md index ede84d8..cd1acfa 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,12 @@ 根 `AGENTS.md` 的 `## Code Review Rules` 只告诉官方 Reviewer 应优先检查哪些项目风险,不能开启 Automatic reviews,也不能证明自动审查已经触发。v1 保持观察模式,不增加 required check,不改变现有 branch protection;官方设置通过真实 PR 验收,中央审计只验证仓库内可稳定读取的规则文件。完整边界见 [官方治理契约](contracts/codex-code-review.md)。 +## Auto-merge 与分支清理 + +五仓只使用 GitHub 原生 Auto-merge:仓库允许该能力并不代表任何 PR 会自动开启。只有官方 Review 当前 HEAD、全部 review thread 已解决、依赖与发布风险已分类后,才对单个 PR 开启 Auto-merge;required checks 和 `master` 分支保护继续决定最终何时合并。 + +PR 出现新提交后必须重新 Review,不能沿用旧 HEAD 的审查证据。Dependabot PR 不会自动开启 Auto-merge;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。合并完成后由 GitHub 自动删除远端功能分支;本地 worktree 和分支只在确认已合并、工作区干净且没有独有提交后清理。 + ## 只读审计 前置条件:已安装并登录 `gh`,安装 `Python 3`、`PyYAML>=6`、`markdown-it-py==3.0.0` 与 `mdurl==0.1.2`,当前身份对目标仓库至少具有读取 Actions、Environment、branch protection 和 secret 名称元数据的权限。 @@ -64,6 +70,7 @@ - publish/deploy/finalize 的 master 边界、normal/rollback 分支、migration 跳过回滚和 rollback 允许式不能只靠 manifest 自我声明,中央会独立验证公共语义; - release 内未声明的特权 job、job 级写权限、动态分域 concurrency 和未锁定 digest 的 `docker://` Action; - `master` branch protection 和 required check。 +- 仓库允许原生 Auto-merge,且合并后自动删除远端功能分支;单个 PR 的 Review/thread/开启顺序仍由真实 PR 验收。 中央审计明确不解释任意 shell 的控制流,也不尝试从注释、`echo`、here-doc、字符串或脚本名证明 ref/内容 ID 比对、容器内 smoke、回滚命令及实际 `DEPLOY_TARGET_SHA`。它也不抓取官方页面或私有接口来判断 Automatic reviews 设置和模型审查质量;这些事实分别由项目可执行契约测试、真实发布验收和真实 PR Review 负责。模板只是一种可复制 profile,`.github/release-safety.yml` 才是每个项目拓扑的声明式适配层。 diff --git a/contracts/ci-cd-baseline.md b/contracts/ci-cd-baseline.md index 606870f..4933654 100644 --- a/contracts/ci-cd-baseline.md +++ b/contracts/ci-cd-baseline.md @@ -60,6 +60,7 @@ - MUST:required status checks 启用 strict,并要求 GitHub Actions app 产生的 `PR container validation`。 - MUST:要求通过 Pull Request、对管理员执行保护、要求解决对话、禁止 force push、禁止删除 `master`。 - MUST:迁移检查名时先让新检查在真实 PR 成功,再原子替换旧 required check。 +- MUST:仓库允许 GitHub 原生 Auto-merge,并在合并后自动删除远端功能分支;是否对单个 PR 开启 Auto-merge 由官方 Review 治理契约决定,不能仅凭 CI 通过自动开启。 - 项目扩展点:额外 required checks,例如 CodeQL、语言专项检查或合规扫描。 ## 7. Environment 与 secret 边界 diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index f7e07b2..a3635a6 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -29,6 +29,10 @@ - MUST:v1 采用观察模式,官方 Review 不新增为 required status check,也不改变现有 `master` branch protection。 - MUST:没有官方稳定状态接口和真实仓库验证前,不假设 Review 能映射为 GitHub required check、approval 或固定 check 名称。 - MUST:Review 发现的问题按现有 PR 对话处理;是否阻塞合并由现有门禁和维护者判断,不增加平行状态机。 +- MUST:仓库启用 GitHub 原生 Auto-merge 和合并后自动删除远端功能分支;仓库设置只提供能力,不会自动开启任何 PR,也不得创建自研合并 Bot、Action 或平行状态机。 +- MUST:只有官方 Review 当前 HEAD、全部 review thread 已解决、依赖或发布风险已人工分类后,才允许对单个 PR 开启 Auto-merge;required checks 与 branch protection 仍由 GitHub 原生门禁执行。 +- MUST:PR 出现新提交后,旧 Review 不再作为当前 HEAD 的证据;必须重新 Review 并再次确认全部 review thread 已解决,才能重新开启该单个 PR 的 Auto-merge。 +- MUST:Dependabot PR 不因 CI 通过而自动获得 Auto-merge;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 ## 5. 审计与验收 @@ -36,6 +40,7 @@ - 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:中央审计只验证仓库允许 Auto-merge 且合并后自动删除远端功能分支;单个 PR 是否按顺序完成 Review、解决 thread、重新 Review 和开启 Auto-merge,由真实 PR 验收,不伪装成静态仓库审计结论。 - MUST:官方设置通过真实 PR 验收:Automatic reviews 能产生审查;必要时 `@codex review` 能触发人工兜底;Reviewer 能遵循仓库规则。 - MUST:接入不得新增 review 专用 secret、GitHub App、workflow、runner 或发布权限。 - 项目扩展点:保存测试 PR、Review 链接和观察期结论的方式。 diff --git a/scripts/audit_github_baseline.py b/scripts/audit_github_baseline.py index 4d2d2eb..b20a7b9 100755 --- a/scripts/audit_github_baseline.py +++ b/scripts/audit_github_baseline.py @@ -531,6 +531,14 @@ def build_source(repo: str) -> RepositorySource: source = RepositorySource(repo=repo, workflows={}, tree={}) if metadata.get("default_branch") != "master": source.errors.append("[DEFAULT_BRANCH] 仓库 default_branch 必须是 master") + if metadata.get("allow_auto_merge") is not True: + source.errors.append( + "[REPOSITORY_MERGE_POLICY] 仓库必须允许对单个 PR 使用 Auto-merge" + ) + if metadata.get("delete_branch_on_merge") is not True: + source.errors.append( + "[REPOSITORY_MERGE_POLICY] 仓库必须在合并后自动删除远端功能分支" + ) workflows = gh_api_paginated(repo, "actions/workflows", "workflows") for workflow in workflows: diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 4a612a8..b8c0b2a 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -27,7 +27,7 @@ - 只报告可证实且会造成实际影响的问题;尤其关注正确性、性能、回归、安全、隐私、权限、可维护性等风险。 - 检查数据/API 与跨仓协议兼容、CI/CD 权限边界、失败/回滚路径及测试能否证明这些高风险行为。 -- 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;项目重点:PROJECT_REPLACE_REVIEW_RULES +- 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;只有官方 Review 当前 HEAD、全部 review thread 已解决后,才允许对单个 PR 开启 Auto-merge;项目重点:PROJECT_REPLACE_REVIEW_RULES ## CI/CD 公共门禁 diff --git a/tests/fixtures/good/repo.json b/tests/fixtures/good/repo.json index b30edcb..c960a1d 100644 --- a/tests/fixtures/good/repo.json +++ b/tests/fixtures/good/repo.json @@ -1 +1 @@ -{"full_name": "example/project", "default_branch": "master"} +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": true, "delete_branch_on_merge": true} diff --git a/tests/fixtures/repository-auto-merge-disabled/repo.json b/tests/fixtures/repository-auto-merge-disabled/repo.json new file mode 100644 index 0000000..4b4e854 --- /dev/null +++ b/tests/fixtures/repository-auto-merge-disabled/repo.json @@ -0,0 +1 @@ +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": false, "delete_branch_on_merge": true} diff --git a/tests/fixtures/repository-branch-auto-delete-disabled/repo.json b/tests/fixtures/repository-branch-auto-delete-disabled/repo.json new file mode 100644 index 0000000..dabe466 --- /dev/null +++ b/tests/fixtures/repository-branch-auto-delete-disabled/repo.json @@ -0,0 +1 @@ +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": true, "delete_branch_on_merge": false} diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 40c4341..4db2aa7 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -196,6 +196,22 @@ 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 marker in ( + "Review 当前 HEAD", + "全部 review thread 已解决", + "单个 PR", + "Auto-merge", + ): + assert marker in document, (marker, document[:40]) +for document in (review_contract, readme, maintenance): + for marker in ( + "新提交", + "重新 Review", + "不会自动开启", + "Dependabot", + ): + assert marker in document, (marker, 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 @@ -489,6 +505,8 @@ PY } run_expect_success good +run_expect_failure repository-auto-merge-disabled "[REPOSITORY_MERGE_POLICY]" +run_expect_failure repository-branch-auto-delete-disabled "[REPOSITORY_MERGE_POLICY]" run_expect_failure code-review-rules-missing "[CODE_REVIEW_RULES]" run_expect_failure code-review-rules-symlink "[CODE_REVIEW_RULES]" run_expect_failure code-review-rules-heading-missing "[CODE_REVIEW_RULES]" From 3e326b4414a16e7868a4dea6f4b634cceeb35181 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Mon, 10 Aug 2026 00:00:21 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E6=94=B6=E7=B4=A7=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=AE=89=E5=85=A8=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根据官方 Codex Review 与 GitHub 官方文档,维护者推送新提交后 Auto-merge 不保证自动关闭,而官方 Review 当前又不是 required check。 因此 v1 改为强制关闭 Auto-merge、保留合并后远端分支自动删除,并把当前 HEAD Review、thread 解决和风险分类作为人工合并前置;同步补齐新项目接入步骤与审计范围说明。 验证:bash tests/test-audit.sh;ruff check/format;ShellCheck;bash -n;py_compile;82 个 YAML 解析;git diff --check。 Co-Authored-By: Codex --- AGENTS.md | 2 +- MAINTENANCE.md | 8 +++---- README.md | 21 ++++++++++--------- contracts/ci-cd-baseline.md | 2 +- contracts/codex-code-review.md | 12 ++++++----- scripts/audit_github_baseline.py | 4 ++-- templates/AGENTS.md | 2 +- tests/fixtures/good/repo.json | 2 +- .../repo.json | 2 +- tests/test-audit.sh | 8 ++++--- 10 files changed, 34 insertions(+), 29 deletions(-) rename tests/fixtures/{repository-auto-merge-disabled => repository-auto-merge-enabled}/repo.json (53%) diff --git a/AGENTS.md b/AGENTS.md index fbe09d8..cce80b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,4 +19,4 @@ - 优先识别会造成错误放行、错误阻断、权限扩大、secret 暴露、供应链漂移或发布/回滚证据失真的具体问题,并核对新增公共 MUST 是否确实跨项目通用。 - 审计器变更必须同时具有能复现旧缺口的失败 fixture 和保持合法项目通过的正例;只增加字符串匹配而不能证明约束时应指出误报或漏报路径。 -- 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。只有官方 Review 当前 HEAD、全部 review thread 已解决后,才允许对单个 PR 开启 Auto-merge。 +- 修改 Action 或公共规则时,核对模板、审计器已知映射、契约和 fixture 是否同步;不重复报告 lint、格式化或纯风格问题,不要求与当前风险无关的重构。官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并。 diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 27b6db3..60a54b8 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -24,7 +24,7 @@ 1. 在独立 worktree 中复制 `templates/AGENTS.md`,替换占位符并补齐项目内部规则;项目规则不得降低公共 MUST,根文件必须保留精确 `## Code Review Rules` 标题。 2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发或需要重审时使用 `@codex review`。 -3. 启用 GitHub 原生 Auto-merge 与合并后自动删除远端功能分支;这两个仓库设置不会自动开启任何单个 PR。 +3. 保持 Auto-merge 关闭,并启用合并后自动删除远端功能分支;官方 Review 尚非 required check 时不得为单个 PR 开启 Auto-merge。 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。 6. 通过一次 master 发布证明 Environment-only secret、旧运行态捕获、候选镜像身份、容器内 smoke、成功后清理和 `DEPLOY_TARGET_SHA` 发布证据。 @@ -61,9 +61,9 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. ## Auto-merge 维护 -- 仓库级只启用 GitHub 原生能力,不建立自动开启 PR 的 Bot、Action 或定时任务;启用能力不会自动开启任何单个 PR。 -- 仅在官方 Review 当前 HEAD、全部 review thread 已解决、变更风险已完成分类后,对单个 PR 开启 Auto-merge;required checks 继续由 GitHub 原生门禁执行。 -- 新提交会使旧 HEAD 的审查证据失效,必须重新 Review、重新核对 thread,再重新开启 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。 - Dependabot PR 不能只凭 CI 绿灯自动合并;运行时依赖、跨大版本和会触发生产发布的仓库必须另做兼容性与发布授权判断。 - 合并后远端功能分支由 GitHub 自动删除。本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 diff --git a/README.md b/README.md index cd1acfa..fc408fc 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,14 @@ 1. 从独立 Git worktree 创建变更分支,避免污染长期开发目录。 2. 复制 `templates/AGENTS.md` 到项目根目录,替换全部 `PROJECT_REPLACE` 项并补齐项目内部规则,保留精确标题 `## Code Review Rules`。 3. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`;规则只决定审查重点,不负责触发,人工兜底使用 `@codex review`。 -4. 复制 `templates/pr-ci.yml`、`templates/release.yml`、`templates/release-safety.yml` 和 `templates/release-safety-contract.sh`;将后两份分别安装为 `.github/release-safety.yml` 与 `.github/scripts/release-safety-contract.sh`,保持 wrapper 为 `100755`,再替换所有 `PROJECT_REPLACE` 项。 -5. 在仓库内实现项目自己的 PR 验证、镜像发布、向前迁移、部署、自动恢复、容器内 smoke、成功后镜像清理和发布收尾脚本;由固定 wrapper 调用项目语言或容器内的可执行契约测试,并让 manifest 声明 wrapper 与 PR 稳定步骤 ID。 -6. 创建 `dev` Environment,把发布所需 secret 移入该 Environment;确认发布成功后清理 repository-scope secrets。 -7. 为 `master` 启用保护规则,要求 GitHub Actions 产生的 `PR container validation`,并保持 strict。 -8. 在真实 PR 上先让新检查通过,再原子替换旧 required check;不要先删除旧门禁。 -9. 合并后核对运行容器的 image ref、内容 ID 与 `DEPLOY_TARGET_SHA`,并执行容器内部 smoke。 -10. 使用只读审计检查规则漂移。 +4. 保持仓库 Auto-merge 关闭,并启用合并后自动删除远端功能分支;官方 Review 尚非 required check 时不得对单个 PR 开启 Auto-merge。 +5. 复制 `templates/pr-ci.yml`、`templates/release.yml`、`templates/release-safety.yml` 和 `templates/release-safety-contract.sh`;将后两份分别安装为 `.github/release-safety.yml` 与 `.github/scripts/release-safety-contract.sh`,保持 wrapper 为 `100755`,再替换所有 `PROJECT_REPLACE` 项。 +6. 在仓库内实现项目自己的 PR 验证、镜像发布、向前迁移、部署、自动恢复、容器内 smoke、成功后镜像清理和发布收尾脚本;由固定 wrapper 调用项目语言或容器内的可执行契约测试,并让 manifest 声明 wrapper 与 PR 稳定步骤 ID。 +7. 创建 `dev` Environment,把发布所需 secret 移入该 Environment;确认发布成功后清理 repository-scope secrets。 +8. 为 `master` 启用保护规则,要求 GitHub Actions 产生的 `PR container validation`,并保持 strict。 +9. 在真实 PR 上先让新检查通过,再原子替换旧 required check;不要先删除旧门禁。 +10. 合并后核对运行容器的 image ref、内容 ID 与 `DEPLOY_TARGET_SHA`,并执行容器内部 smoke。 +11. 使用只读审计检查规则漂移。 完整 MUST 和项目扩展点见 [CI/CD 公共契约](contracts/ci-cd-baseline.md) 与 [官方 Codex Code Review 治理契约](contracts/codex-code-review.md)。 @@ -29,9 +30,9 @@ ## Auto-merge 与分支清理 -五仓只使用 GitHub 原生 Auto-merge:仓库允许该能力并不代表任何 PR 会自动开启。只有官方 Review 当前 HEAD、全部 review thread 已解决、依赖与发布风险已分类后,才对单个 PR 开启 Auto-merge;required checks 和 `master` 分支保护继续决定最终何时合并。 +GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。由于官方 Review 当前不是 required check,纳管产品仓库在 v1 暂不允许开启 Auto-merge,也不为单个 PR 启用它。 -PR 出现新提交后必须重新 Review,不能沿用旧 HEAD 的审查证据。Dependabot PR 不会自动开启 Auto-merge;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。合并完成后由 GitHub 自动删除远端功能分支;本地 worktree 和分支只在确认已合并、工作区干净且没有独有提交后清理。 +人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;新提交必须重新 Review。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。合并完成后由 GitHub 自动删除远端功能分支;本地 worktree 和分支只在确认已合并、工作区干净且没有独有提交后清理。 ## 只读审计 @@ -70,7 +71,7 @@ PR 出现新提交后必须重新 Review,不能沿用旧 HEAD 的审查证据 - publish/deploy/finalize 的 master 边界、normal/rollback 分支、migration 跳过回滚和 rollback 允许式不能只靠 manifest 自我声明,中央会独立验证公共语义; - release 内未声明的特权 job、job 级写权限、动态分域 concurrency 和未锁定 digest 的 `docker://` Action; - `master` branch protection 和 required check。 -- 仓库允许原生 Auto-merge,且合并后自动删除远端功能分支;单个 PR 的 Review/thread/开启顺序仍由真实 PR 验收。 +- 纳管产品仓库关闭 Auto-merge,且合并后自动删除远端功能分支;人工合并前的 Review/thread/风险分类仍由真实 PR 验收。 中央审计明确不解释任意 shell 的控制流,也不尝试从注释、`echo`、here-doc、字符串或脚本名证明 ref/内容 ID 比对、容器内 smoke、回滚命令及实际 `DEPLOY_TARGET_SHA`。它也不抓取官方页面或私有接口来判断 Automatic reviews 设置和模型审查质量;这些事实分别由项目可执行契约测试、真实发布验收和真实 PR Review 负责。模板只是一种可复制 profile,`.github/release-safety.yml` 才是每个项目拓扑的声明式适配层。 diff --git a/contracts/ci-cd-baseline.md b/contracts/ci-cd-baseline.md index 4933654..6ddabea 100644 --- a/contracts/ci-cd-baseline.md +++ b/contracts/ci-cd-baseline.md @@ -60,7 +60,7 @@ - MUST:required status checks 启用 strict,并要求 GitHub Actions app 产生的 `PR container validation`。 - MUST:要求通过 Pull Request、对管理员执行保护、要求解决对话、禁止 force push、禁止删除 `master`。 - MUST:迁移检查名时先让新检查在真实 PR 成功,再原子替换旧 required check。 -- MUST:仓库允许 GitHub 原生 Auto-merge,并在合并后自动删除远端功能分支;是否对单个 PR 开启 Auto-merge 由官方 Review 治理契约决定,不能仅凭 CI 通过自动开启。 +- MUST:官方 Review 尚不能作为当前 HEAD 的 required check 时,仓库关闭 Auto-merge;合并后自动删除远端功能分支。人工合并边界由官方 Review 治理契约决定,不能仅凭 CI 通过合并。 - 项目扩展点:额外 required checks,例如 CodeQL、语言专项检查或合规扫描。 ## 7. Environment 与 secret 边界 diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index a3635a6..78b7f98 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -29,10 +29,12 @@ - MUST:v1 采用观察模式,官方 Review 不新增为 required status check,也不改变现有 `master` branch protection。 - MUST:没有官方稳定状态接口和真实仓库验证前,不假设 Review 能映射为 GitHub required check、approval 或固定 check 名称。 - MUST:Review 发现的问题按现有 PR 对话处理;是否阻塞合并由现有门禁和维护者判断,不增加平行状态机。 -- MUST:仓库启用 GitHub 原生 Auto-merge 和合并后自动删除远端功能分支;仓库设置只提供能力,不会自动开启任何 PR,也不得创建自研合并 Bot、Action 或平行状态机。 -- MUST:只有官方 Review 当前 HEAD、全部 review thread 已解决、依赖或发布风险已人工分类后,才允许对单个 PR 开启 Auto-merge;required checks 与 branch protection 仍由 GitHub 原生门禁执行。 -- MUST:PR 出现新提交后,旧 Review 不再作为当前 HEAD 的证据;必须重新 Review 并再次确认全部 review thread 已解决,才能重新开启该单个 PR 的 Auto-merge。 -- MUST:Dependabot PR 不因 CI 通过而自动获得 Auto-merge;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 +- 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:v1 只启用合并后自动删除远端功能分支;不创建自研合并 Bot、Action、HEAD 监听器或平行状态机来补 GitHub/Codex 当前能力缺口。 +- MUST:人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功,且依赖或发布风险已分类。 +- MUST:PR 出现新提交后,旧 Review 不再作为当前 HEAD 的证据;必须重新 Review 并再次确认全部 review thread 已解决,才能人工合并。 +- MUST:Dependabot PR 不因 CI 通过而自动合并;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 +- 项目扩展点:未来只有在官方 Review 能成为与当前 HEAD 绑定的 required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后,才重新评估启用原生 Auto-merge。 ## 5. 审计与验收 @@ -40,7 +42,7 @@ - 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:中央审计只验证仓库允许 Auto-merge 且合并后自动删除远端功能分支;单个 PR 是否按顺序完成 Review、解决 thread、重新 Review 和开启 Auto-merge,由真实 PR 验收,不伪装成静态仓库审计结论。 +- MUST:中央审计验证纳管产品仓库关闭 Auto-merge 且合并后自动删除远端功能分支;人工合并前是否完成当前 HEAD Review、解决 thread 与风险分类,由真实 PR 验收,不伪装成静态仓库审计结论。 - MUST:官方设置通过真实 PR 验收:Automatic reviews 能产生审查;必要时 `@codex review` 能触发人工兜底;Reviewer 能遵循仓库规则。 - MUST:接入不得新增 review 专用 secret、GitHub App、workflow、runner 或发布权限。 - 项目扩展点:保存测试 PR、Review 链接和观察期结论的方式。 diff --git a/scripts/audit_github_baseline.py b/scripts/audit_github_baseline.py index b20a7b9..7bd9113 100755 --- a/scripts/audit_github_baseline.py +++ b/scripts/audit_github_baseline.py @@ -531,9 +531,9 @@ def build_source(repo: str) -> RepositorySource: source = RepositorySource(repo=repo, workflows={}, tree={}) if metadata.get("default_branch") != "master": source.errors.append("[DEFAULT_BRANCH] 仓库 default_branch 必须是 master") - if metadata.get("allow_auto_merge") is not True: + if metadata.get("allow_auto_merge") is not False: source.errors.append( - "[REPOSITORY_MERGE_POLICY] 仓库必须允许对单个 PR 使用 Auto-merge" + "[REPOSITORY_MERGE_POLICY] 官方 Review 尚非 required check,仓库必须关闭 Auto-merge" ) if metadata.get("delete_branch_on_merge") is not True: source.errors.append( diff --git a/templates/AGENTS.md b/templates/AGENTS.md index b8c0b2a..b0a671f 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -27,7 +27,7 @@ - 只报告可证实且会造成实际影响的问题;尤其关注正确性、性能、回归、安全、隐私、权限、可维护性等风险。 - 检查数据/API 与跨仓协议兼容、CI/CD 权限边界、失败/回滚路径及测试能否证明这些高风险行为。 -- 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;只有官方 Review 当前 HEAD、全部 review thread 已解决后,才允许对单个 PR 开启 Auto-merge;项目重点:PROJECT_REPLACE_REVIEW_RULES +- 把 PR 说明和已有测试视为待验证声明,不重复 lint、格式化或纯风格意见,不要求与当前风险无关的工作;官方 Review 当前不是 required check,且 GitHub 对有写权限者推送新提交不保证自动关闭 Auto-merge;v1 暂不允许对单个 PR 开启 Auto-merge,只在 Review 当前 HEAD、全部 review thread 已解决后人工合并;项目重点:PROJECT_REPLACE_REVIEW_RULES ## CI/CD 公共门禁 diff --git a/tests/fixtures/good/repo.json b/tests/fixtures/good/repo.json index c960a1d..4b4e854 100644 --- a/tests/fixtures/good/repo.json +++ b/tests/fixtures/good/repo.json @@ -1 +1 @@ -{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": true, "delete_branch_on_merge": true} +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": false, "delete_branch_on_merge": true} diff --git a/tests/fixtures/repository-auto-merge-disabled/repo.json b/tests/fixtures/repository-auto-merge-enabled/repo.json similarity index 53% rename from tests/fixtures/repository-auto-merge-disabled/repo.json rename to tests/fixtures/repository-auto-merge-enabled/repo.json index 4b4e854..c960a1d 100644 --- a/tests/fixtures/repository-auto-merge-disabled/repo.json +++ b/tests/fixtures/repository-auto-merge-enabled/repo.json @@ -1 +1 @@ -{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": false, "delete_branch_on_merge": true} +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": true, "delete_branch_on_merge": true} diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 4db2aa7..bd4945a 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -202,13 +202,15 @@ for document in (root_agents, template, review_contract, readme, maintenance): "全部 review thread 已解决", "单个 PR", "Auto-merge", + "暂不允许", ): assert marker in document, (marker, document[:40]) for document in (review_contract, readme, maintenance): for marker in ( "新提交", - "重新 Review", - "不会自动开启", + "有写权限", + "不保证自动关闭", + "不是 required check", "Dependabot", ): assert marker in document, (marker, document[:40]) @@ -505,7 +507,7 @@ PY } run_expect_success good -run_expect_failure repository-auto-merge-disabled "[REPOSITORY_MERGE_POLICY]" +run_expect_failure repository-auto-merge-enabled "[REPOSITORY_MERGE_POLICY]" run_expect_failure repository-branch-auto-delete-disabled "[REPOSITORY_MERGE_POLICY]" run_expect_failure code-review-rules-missing "[CODE_REVIEW_RULES]" run_expect_failure code-review-rules-symlink "[CODE_REVIEW_RULES]" From edf423ca25b91e2c477e8226a36e4ad1635ac821 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Mon, 10 Aug 2026 00:06:25 +0800 Subject: [PATCH 3/5] =?UTF-8?q?test:=20=E9=9A=94=E7=A6=BB=E8=BF=9C?= =?UTF-8?q?=E7=AB=AF=E5=88=86=E6=94=AF=E6=B8=85=E7=90=86=E7=BA=A6=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 让关闭远端分支自动删除的失败 fixture 保持 Auto-merge 为合法关闭状态,确保测试只由目标约束触发。 mutation 验证:临时移除 delete_branch_on_merge 审计后,该 fixture 错误 PASS;恢复实现后 fixture 稳定失败,全量 tests/test-audit.sh 通过。 Co-Authored-By: Codex --- tests/fixtures/repository-branch-auto-delete-disabled/repo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/repository-branch-auto-delete-disabled/repo.json b/tests/fixtures/repository-branch-auto-delete-disabled/repo.json index dabe466..692f588 100644 --- a/tests/fixtures/repository-branch-auto-delete-disabled/repo.json +++ b/tests/fixtures/repository-branch-auto-delete-disabled/repo.json @@ -1 +1 @@ -{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": true, "delete_branch_on_merge": false} +{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": false, "delete_branch_on_merge": false} From a91a9d93178eb9a76cea13071d0f57623113b622 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Mon, 10 Aug 2026 00:13:39 +0800 Subject: [PATCH 4/5] =?UTF-8?q?docs:=20=E8=A1=A5=E9=BD=90=E6=96=B0?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=90=88=E5=B9=B6=E8=AE=BE=E7=BD=AE=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在项目 AGENTS 模板的 CI/CD 公共门禁中明确 allow_auto_merge=false 与 delete_branch_on_merge=true,并增加模板断言防止后续遗漏。 验证:新增断言先因模板缺失取得 RED,补齐模板后 tests/test-audit.sh 全量通过。 Co-Authored-By: Codex --- templates/AGENTS.md | 1 + tests/test-audit.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/templates/AGENTS.md b/templates/AGENTS.md index b0a671f..854737e 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -42,6 +42,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`、`delete_branch_on_merge=true`;只在 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功后人工合并。 ## 项目命令 diff --git a/tests/test-audit.sh b/tests/test-audit.sh index bd4945a..7b9cd5b 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -178,6 +178,8 @@ for marker in ( "子目录 `AGENTS.md`", "独立 Git worktree", "Co-Authored-By: Codex ", + "allow_auto_merge=false", + "delete_branch_on_merge=true", ): assert marker in template, marker From a349517e34920c314993368f13d57e9305ac3405 Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Mon, 10 Aug 2026 00:23:14 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E6=8C=89=E5=88=86=E6=94=AF=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=90=AF=E7=94=A8=E8=87=AA=E5=8A=A8=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Codex --- MAINTENANCE.md | 5 +++-- README.md | 8 +++++--- contracts/ci-cd-baseline.md | 2 +- contracts/codex-code-review.md | 5 +++-- scripts/audit_github_baseline.py | 4 ---- templates/AGENTS.md | 2 +- .../repository-branch-auto-delete-disabled/repo.json | 1 - tests/test-audit.sh | 8 ++++++-- 8 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 tests/fixtures/repository-branch-auto-delete-disabled/repo.json diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 60a54b8..157d5a7 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -24,7 +24,7 @@ 1. 在独立 worktree 中复制 `templates/AGENTS.md`,替换占位符并补齐项目内部规则;项目规则不得降低公共 MUST,根文件必须保留精确 `## Code Review Rules` 标题。 2. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`,并用真实 PR 验证自动审查;未触发或需要重审时使用 `@codex review`。 -3. 保持 Auto-merge 关闭,并启用合并后自动删除远端功能分支;官方 Review 尚非 required check 时不得为单个 PR 开启 Auto-merge。 +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。 6. 通过一次 master 发布证明 Environment-only secret、旧运行态捕获、候选镜像身份、容器内 smoke、成功后清理和 `DEPLOY_TARGET_SHA` 发布证据。 @@ -65,7 +65,8 @@ prepare 存在时,publish、migration 与 deploy 必须使用 `needs. - 不建立 HEAD 监听器、自动合并 Bot、Action 或定时任务来补这个能力缺口;未来等官方 Review 可成为当前 HEAD required gate,或 GitHub 保证任意新提交都会撤销 Auto-merge 后再评估。 - 人工合并前确认官方 Review 当前 HEAD、全部 review thread 已解决、required checks 成功且风险已分类;新提交必须重新 Review。 - Dependabot PR 不能只凭 CI 绿灯自动合并;运行时依赖、跨大版本和会触发生产发布的仓库必须另做兼容性与发布授权判断。 -- 合并后远端功能分支由 GitHub 自动删除。本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 +- 分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的长期 head 分支时必须关闭。 +- 本地 worktree/分支只在已合并、干净、没有独有提交且相关发布验收完成后删除。 ## Action 升级 diff --git a/README.md b/README.md index fc408fc..ede14f0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ 1. 从独立 Git worktree 创建变更分支,避免污染长期开发目录。 2. 复制 `templates/AGENTS.md` 到项目根目录,替换全部 `PROJECT_REPLACE` 项并补齐项目内部规则,保留精确标题 `## Code Review Rules`。 3. 在官方 GitHub/Codex 设置中启用 Code Review 与 `Automatic reviews`;规则只决定审查重点,不负责触发,人工兜底使用 `@codex review`。 -4. 保持仓库 Auto-merge 关闭,并启用合并后自动删除远端功能分支;官方 Review 尚非 required check 时不得对单个 PR 开启 Auto-merge。 +4. 保持仓库 Auto-merge 关闭;官方 Review 尚非 required check 时不得对单个 PR 开启 Auto-merge。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用合并后自动删除远端分支。 5. 复制 `templates/pr-ci.yml`、`templates/release.yml`、`templates/release-safety.yml` 和 `templates/release-safety-contract.sh`;将后两份分别安装为 `.github/release-safety.yml` 与 `.github/scripts/release-safety-contract.sh`,保持 wrapper 为 `100755`,再替换所有 `PROJECT_REPLACE` 项。 6. 在仓库内实现项目自己的 PR 验证、镜像发布、向前迁移、部署、自动恢复、容器内 smoke、成功后镜像清理和发布收尾脚本;由固定 wrapper 调用项目语言或容器内的可执行契约测试,并让 manifest 声明 wrapper 与 PR 稳定步骤 ID。 7. 创建 `dev` Environment,把发布所需 secret 移入该 Environment;确认发布成功后清理 repository-scope secrets。 @@ -32,7 +32,9 @@ GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权限者推送后不保证自动关闭。由于官方 Review 当前不是 required check,纳管产品仓库在 v1 暂不允许开启 Auto-merge,也不为单个 PR 启用它。 -人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;新提交必须重新 Review。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。合并完成后由 GitHub 自动删除远端功能分支;本地 worktree 和分支只在确认已合并、工作区干净且没有独有提交后清理。 +人工合并前必须确认官方 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功;新提交必须重新 Review。Dependabot PR 不会自动合并;尤其是运行时依赖、跨大版本升级、构建行为变化,以及合并即触发生产发布的仓库,仍需兼容性判断和明确发布授权。 + +分支自动删除不是公共强制项。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才启用 GitHub 的合并后自动删除;存在未保护且需要复用的 `dev`、`release` 等长期 head 分支时必须关闭。本地 worktree 和分支始终只在确认已合并、工作区干净且没有独有提交后清理。 ## 只读审计 @@ -71,7 +73,7 @@ GitHub 只保证无写权限者推送新提交时关闭 Auto-merge;有写权 - publish/deploy/finalize 的 master 边界、normal/rollback 分支、migration 跳过回滚和 rollback 允许式不能只靠 manifest 自我声明,中央会独立验证公共语义; - release 内未声明的特权 job、job 级写权限、动态分域 concurrency 和未锁定 digest 的 `docker://` Action; - `master` branch protection 和 required check。 -- 纳管产品仓库关闭 Auto-merge,且合并后自动删除远端功能分支;人工合并前的 Review/thread/风险分类仍由真实 PR 验收。 +- 纳管产品仓库关闭 Auto-merge;分支自动删除按项目真实分支模型配置,不由公共审计强制。人工合并前的 Review/thread/风险分类仍由真实 PR 验收。 中央审计明确不解释任意 shell 的控制流,也不尝试从注释、`echo`、here-doc、字符串或脚本名证明 ref/内容 ID 比对、容器内 smoke、回滚命令及实际 `DEPLOY_TARGET_SHA`。它也不抓取官方页面或私有接口来判断 Automatic reviews 设置和模型审查质量;这些事实分别由项目可执行契约测试、真实发布验收和真实 PR Review 负责。模板只是一种可复制 profile,`.github/release-safety.yml` 才是每个项目拓扑的声明式适配层。 diff --git a/contracts/ci-cd-baseline.md b/contracts/ci-cd-baseline.md index 6ddabea..f5c6c32 100644 --- a/contracts/ci-cd-baseline.md +++ b/contracts/ci-cd-baseline.md @@ -60,7 +60,7 @@ - MUST:required status checks 启用 strict,并要求 GitHub Actions app 产生的 `PR container validation`。 - MUST:要求通过 Pull Request、对管理员执行保护、要求解决对话、禁止 force push、禁止删除 `master`。 - MUST:迁移检查名时先让新检查在真实 PR 成功,再原子替换旧 required check。 -- MUST:官方 Review 尚不能作为当前 HEAD 的 required check 时,仓库关闭 Auto-merge;合并后自动删除远端功能分支。人工合并边界由官方 Review 治理契约决定,不能仅凭 CI 通过合并。 +- MUST:官方 Review 尚不能作为当前 HEAD 的 required check 时,仓库关闭 Auto-merge。人工合并边界由官方 Review 治理契约决定,不能仅凭 CI 通过合并;分支自动删除按项目分支模型配置,不作为 CI/CD 公共门禁。 - 项目扩展点:额外 required checks,例如 CodeQL、语言专项检查或合规扫描。 ## 7. Environment 与 secret 边界 diff --git a/contracts/codex-code-review.md b/contracts/codex-code-review.md index 78b7f98..e7c63ea 100644 --- a/contracts/codex-code-review.md +++ b/contracts/codex-code-review.md @@ -30,7 +30,8 @@ - MUST:没有官方稳定状态接口和真实仓库验证前,不假设 Review 能映射为 GitHub required check、approval 或固定 check 名称。 - 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:v1 只启用合并后自动删除远端功能分支;不创建自研合并 Bot、Action、HEAD 监听器或平行状态机来补 GitHub/Codex 当前能力缺口。 +- 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:Dependabot PR 不因 CI 通过而自动合并;运行时依赖、跨大版本升级、构建工具行为变化及会随合并触发生产发布的仓库,都必须先完成兼容性与发布授权判断。 @@ -42,7 +43,7 @@ - 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:中央审计验证纳管产品仓库关闭 Auto-merge 且合并后自动删除远端功能分支;人工合并前是否完成当前 HEAD Review、解决 thread 与风险分类,由真实 PR 验收,不伪装成静态仓库审计结论。 +- MUST:中央审计验证纳管产品仓库关闭 Auto-merge;分支自动删除取决于项目真实分支模型,不由公共审计强制。人工合并前是否完成当前 HEAD Review、解决 thread 与风险分类,由真实 PR 验收,不伪装成静态仓库审计结论。 - MUST:官方设置通过真实 PR 验收:Automatic reviews 能产生审查;必要时 `@codex review` 能触发人工兜底;Reviewer 能遵循仓库规则。 - MUST:接入不得新增 review 专用 secret、GitHub App、workflow、runner 或发布权限。 - 项目扩展点:保存测试 PR、Review 链接和观察期结论的方式。 diff --git a/scripts/audit_github_baseline.py b/scripts/audit_github_baseline.py index 7bd9113..922c48f 100755 --- a/scripts/audit_github_baseline.py +++ b/scripts/audit_github_baseline.py @@ -535,10 +535,6 @@ def build_source(repo: str) -> RepositorySource: source.errors.append( "[REPOSITORY_MERGE_POLICY] 官方 Review 尚非 required check,仓库必须关闭 Auto-merge" ) - if metadata.get("delete_branch_on_merge") is not True: - source.errors.append( - "[REPOSITORY_MERGE_POLICY] 仓库必须在合并后自动删除远端功能分支" - ) workflows = gh_api_paginated(repo, "actions/workflows", "workflows") for workflow in workflows: diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 854737e..71c6105 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -42,7 +42,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`、`delete_branch_on_merge=true`;只在 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功后人工合并。 +- 官方 Review 尚非当前 HEAD 的 required check 时,仓库保持 `allow_auto_merge=false`;只在 Review 当前 HEAD、全部 review thread 已解决且 required checks 成功后人工合并。只有仓库仅使用临时 PR head 分支,或所有长期 head 分支受保护时,才设置 `delete_branch_on_merge=true`。 ## 项目命令 diff --git a/tests/fixtures/repository-branch-auto-delete-disabled/repo.json b/tests/fixtures/repository-branch-auto-delete-disabled/repo.json deleted file mode 100644 index 692f588..0000000 --- a/tests/fixtures/repository-branch-auto-delete-disabled/repo.json +++ /dev/null @@ -1 +0,0 @@ -{"full_name": "example/project", "default_branch": "master", "allow_auto_merge": false, "delete_branch_on_merge": false} diff --git a/tests/test-audit.sh b/tests/test-audit.sh index 7b9cd5b..417a000 100755 --- a/tests/test-audit.sh +++ b/tests/test-audit.sh @@ -179,7 +179,8 @@ for marker in ( "独立 Git worktree", "Co-Authored-By: Codex ", "allow_auto_merge=false", - "delete_branch_on_merge=true", + "临时 PR head 分支", + "长期 head 分支受保护", ): assert marker in template, marker @@ -221,6 +222,10 @@ for marker in ("markdown-it-py==3.0.0", "mdurl==0.1.2"): assert 'MarkdownIt("commonmark")' in audit_source for forbidden in ("markdown_fence", "raw_html_block_start"): assert forbidden not in audit_source, forbidden +for document in (template, review_contract, readme, maintenance): + assert "临时 PR head 分支" in document + assert "长期 head 分支受保护" in document +assert "delete_branch_on_merge" not in audit_source print("AGENTS 模板、根规则与官方 Code Review 治理契约通过") PY then @@ -510,7 +515,6 @@ PY run_expect_success good run_expect_failure repository-auto-merge-enabled "[REPOSITORY_MERGE_POLICY]" -run_expect_failure repository-branch-auto-delete-disabled "[REPOSITORY_MERGE_POLICY]" run_expect_failure code-review-rules-missing "[CODE_REVIEW_RULES]" run_expect_failure code-review-rules-symlink "[CODE_REVIEW_RULES]" run_expect_failure code-review-rules-heading-missing "[CODE_REVIEW_RULES]"