feat: configurable merge gate (branch protection + directory isolation) and skill body/appendix checks

- cloud/merge_gate.py: pure gate; directory check reuses the v0.3
  git diff --name-only merge-base command; protection modes
  record (default, explicit confirm required when unprotected),
  enforce (always blocks when unprotected), off (explicit only).
  Confirm covers protection risk only, never directory violations.
  Protection status is caller/env-declared only; unknown is a
  recorded risk, not a claim of protection.
- server POST /tasks/{id}/merge: applies the gate only when gate
  evidence is supplied (or env declares protection); no-evidence
  calls behave as before plus a merge_gate field in the response.
  Blocked merges return 409 without changing status; confirmed
  unprotected merges write a merge_gate_risk audit entry.
- skill_seed.py: whole-directory seeding evaluated and rejected
  (cannot preserve tenant deletions; no benefit while the pack
  holds only SKILL.md); SKILL.md-only behaviour unchanged.
- software-engineering SKILL.md: gate paragraph added to the body
  and to the coordinator + client appendix sections (v0.2 text on
  this base; port to v0.3 text on rebase after #199 merges).
- tests: 16 new tests covering gate modes, directory reuse,
  body/appendix bidirectional assertions naming the missing side,
  SKILL.md-only seeding and tenant-edit preservation.
This commit is contained in:
host committed 2026-11-03 02:48:55 +00:00
1 parent 44616a03dc
commit d553f9549c
5 files changed
+565

No files matched your search

@@ -535,6 +535,18 @@ tests/ # QA 线程专属,含跨端一致性用例
要求 PR、要求 CI 通过、禁止直接推。目标仓库没开保护时,
协调员要在决策记录里写明风险并去开通,不能假装已保护,
不能靠“大家自觉”代替保护。
- 合并门禁(2026-10-30 补,代码在 cloud/merge_gate.py,服务端
POST /tasks/{id}/merge 已接线):保护状态只能由调用方或环境变量
CLOUD_BRANCH_PROTECTION 显式声明,代码不去 GitHub 核实、不声称
已保护;状态 unknown 时记风险、不阻断。模式由
CLOUD_MERGE_GATE_MODE 控制,默认 record:未保护时须显式确认
(merge_gate_confirm)才放行,无确认阻断;enforce 模式下未保护
一律阻断,确认也不放行——切 enforce 前必须先由用户决定并开通
保护(升级 Pro、公开仓库、或保持纪律 + 记风险,三者用户侧定,
代码不替选)。显式确认只覆盖保护风险,绝不覆盖目录隔离违规;
目录检查复用 v0.3 的 git diff --name-only 口径,越目录只能靠
契约变更批准文件放行。技能播种仍只复制 SKILL.md,不做整目录复制
(租户已改文件绝不被覆盖,见 cloud/skill_seed.py 的评估结论)。
### 合并方式与合并记录
@@ -821,6 +833,13 @@ G8 的交付物是 v1.1 交接清单终版与下一轮 G0-G6 输入冻结清单
不批准、不合并;无 PR 时它会 409,先补 PR。
- 主分支保护:要求 PR、要求 CI 通过、禁止直接推,这是 GitHub 仓库设置,
不是本平台代码能替你开的。没开保护时记为风险并去开通,不假装已保护。
- 合并门禁:同正文,代码在 cloud/merge_gate.py,模式由
CLOUD_MERGE_GATE_MODE 控制,默认 record:未保护时须显式确认
才放行,无确认阻断;enforce 模式下未保护一律阻断,切 enforce
前须由用户决定并开通保护(升级 Pro、公开仓库、或保持纪律 +
记风险,三者用户侧定)。显式确认只覆盖保护风险,绝不覆盖
目录隔离违规;目录检查复用 v0.3 的 git diff --name-only 口径;
技能播种仍只复制 SKILL.md,不做整目录复制。
- 合并记录:默认 merge commit;记录必须含 PR 号、合并提交 hash、
CI 运行链接、执行人(人或宿主操作,不是你自己合);
合并后删远程分支,删前确认合并提交已在主线。
@@ -1048,6 +1067,11 @@ TODO-UPDATE 要求,缺一项就不发任务)。派生提示词里的精简
契约版本、测试证据、已知问题、关联待办或 PRD 项。没有 PR 号不算完成。
- 合并门由协调员判定:Checks 全绿、目录归属通过、契约版本是冻结版、
评审通过且无未解决意见;你不自己合并、不绕过评审推主线。
- 合并门禁:同正文,模式由 CLOUD_MERGE_GATE_MODE 控制,默认
record:未保护时须显式确认才放行;显式确认只覆盖保护风险,
绝不覆盖目录隔离违规;目录检查复用 v0.3 的
git diff --name-only 口径;技能播种仍只复制 SKILL.md,
不做整目录复制。
- 安全:密钥、口令、token 绝不进代码、commit、命令行、PR 正文;
需要调用 GitHub 时 token 只进子进程环境,不写进示例命令。