gitlink-cli/skills/gitlink-gatekeeper/examples/decision-request-changes.md

6.2 KiB
Raw Blame History

裁决记录 — REQUEST_CHANGES硬门禁失败 + 1 个 major

模拟 gitlink-gatekeeper 的完整执行记录:采集 → 逐维算分 → 硬门禁 → 裁决 → 渲染评分卡 → dry-run 回写命令。 策略:默认 gatekeeper.yaml(权重 40/20/15/15/10severity_penalty blocker=100/major=25/minor=5/nit=1thresholds pass=85 / request_changes=60max_changed_files=80。 命令均来自 REFERENCE.md 第 7 节 CLI 映射,已对照真实 shortcut 核验。

场景Gitlink/forgeplus 仓库 PR #305重构订单结算逻辑改动了 4 个源码文件但未附带任何测试其中一处折扣计算有边界缺陷major。CI 通过。


① 采集上下文

gitlink-cli pr +view  -i 305 --owner Gitlink --repo forgeplus --format json
gitlink-cli pr +files -i 305 --owner Gitlink --repo forgeplus --format json
gitlink-cli pr +diff  -i 305 --owner Gitlink --repo forgeplus --format json
gitlink-cli api GET /Gitlink/forgeplus/pulls/305/commits --format json
gitlink-cli ci +builds --owner Gitlink --repo forgeplus --format json

采集结果摘要

信号
标题 refactor(billing): rework settlement pipeline
描述 非空,长度 88 字符≥30 #<n> 关联
changed_files 4
changed_src 4settlement.go / discount.go / invoice.go / tax.go
changed_tests 0
commits 3 条,符合 Conventional Commits 的 2 条1 条为 wip: fix)→ conforming=2
CI passing
AI 审查发现 0 blocker / 1 major / 1 minor / 2 nit

② 逐维算分(公式代入,可复算)

review_findings权重 40 — §3.1

penalty = 25(major) + 1×5(minor) + 2×1(nit) = 32
score   = 40 × max(0, 1  32/40) = 40 × (1  0.8) = 40 × 0.2 = 8

test_coverage权重 20 — §3.2

changed_src=4 > 0, changed_tests=0
→ score = 0

pr_hygiene权重 15 — §3.3

描述≥30 ✓ (+1/3)
关联 Issue ✗ (0)
体量 changed_files=4 ≤ max_changed_files/2 = 40 ✓ (+1/3)
命中比例 = 2/3
score = round(15 × 2/3) = round(10.0) = 10

commit_quality权重 15 — §3.4

conforming/total = 2/3
score = round(15 × 2/3) = round(10.0) = 10

ci_status权重 10 — §3.5

CI passing → score = 10

总分

total = 8 + 0 + 10 + 10 + 10 = 38

③ 硬门禁判定§4

门禁 配置 命中?
forbid_blocker_findings true 0 blocker
require_ci_pass true passing
require_tests_for_src_changes true changed_src=4>0 且 changed_tests=0
require_linked_issue false —(未启用)
max_changed_files 80 4 ≤ 80

hard_gate_failed = true


④ 裁决§5

hard_gate_failed = true
→ verdict = REQUEST_CHANGES   (无视总分;本例 total=38 < request_changes(60) 也指向 REQUEST_CHANGES结论一致

⑤ 渲染的评分卡

## 🛡️ Gatekeeper Report — PR #305 refactor(billing): rework settlement pipeline

**Verdict: ❌ REQUEST_CHANGES**  ·  Score: 38/100  ·  policy: gatekeeper.yaml@v1

| Dimension | Weight | Score | Notes |
|-----------|:------:|:-----:|-------|
| Review findings | 40 | 8/40 | 0 blocker / 1 major / 1 minor / 2 nit |
| Test coverage   | 20 | 0/20 | 4 src / 0 test files |
| PR hygiene      | 15 | 10/15 | desc ✓ / linked issue ✗ / size ✓ |
| Commit quality  | 15 | 10/15 | 2/3 conventional |
| CI status       | 10 | 10/10 | passing |

### ⛔ Hard gate failures (1)
- `require_tests_for_src_changes`: 改动了 4 个源码文件,但本 PR 未包含任何测试文件

### 🔴 Must fix (1)
- [major] 折扣金额未做下限保护,满减叠加时可算出负数总价 — discount.go:72

### 🟡 Should fix (1)
- [minor] `settle()` 吞掉了 tax 计算的 error应向上传播 — settlement.go:118

### 🔵 Nits (2)
- [nit] commit `wip: fix` 不符合 Conventional Commits建议 rebase 整理 — (commit)
- [nit] 导出结构体 `Invoice` 字段缺少注释 — invoice.go:14

### ✅ Strengths
- 改动聚焦、体量适中4 文件CI 全绿

### Next steps
1. **补测试**(最高优先级):为 4 个改动源码文件补单元测试,解除 `require_tests_for_src_changes` 硬门禁
2. 修复折扣下限的 major 缺陷,建议补一条针对负数总价的回归测试
3. 整理 `wip: fix` commit、补充 error 传播后,重新触发 gatekeeper
---
*Generated by gitlink-gatekeeper · policy-as-code PR gate · re-run after changes*

⑥ 将执行的回写命令dry-run 展示)

默认 dry-run不传 --apply 时仅打印。REQUEST_CHANGES 永不涉及合并。

# [dry-run] 1) 评分卡作为评论回写(与 workflow 脚本一致,走 pr +comment
gitlink-cli pr +comment -i 305 -b "$(cat scorecard.md)" --owner Gitlink --repo forgeplus
#   裁决=REQUEST_CHANGES 不直接用平台的强语义 rejected留给人工裁决靠评分卡标题 + 标签表达

# [dry-run] 2) 打 needs-changes 标签labels.request_changes = "gatekeeper:needs-changes"
gitlink-cli label +create -n "gatekeeper:needs-changes" -c "#D1242F" \
  -d "Gatekeeper verdict: REQUEST_CHANGES" --owner Gitlink --repo forgeplus
#   标签挂到 PR 背后的 issue.id非 PR 号):
ISSUE_ID=$(gitlink-cli pr +view -i 305 --owner Gitlink --repo forgeplus --format json | jq -r '.data.issue.id')
gitlink-cli api POST /Gitlink/forgeplus/issues/$ISSUE_ID --body '{
  "issue_tag_ids": [<gatekeeper:needs-changes 的 tag_id>],
  "done_ratio": 0,
  "subject": "<PR 原标题>",
  "description": "<PR 原描述>"
}'

# [dry-run] 3)(子题三善后)创建 tracking issue 汇总必修项并关联 PR #305
#   注意:用 $'...' 让 \n 成为真实换行(双引号里的字面 \n 不会换行)
gitlink-cli issue +create --owner Gitlink --repo forgeplus \
  -t "[gatekeeper] PR #305 必修项跟踪" \
  -b $'由 gatekeeper 裁决 REQUEST_CHANGES 触发。\n硬门禁: require_tests_for_src_changes。\nMust fix: discount.go:72 折扣下限。\n关联 PR: #305'

实际写回需追加 --applyAgent 会先复述「将回写 1 条评论 + 打 gatekeeper:needs-changes 标签 + 建 1 条 tracking issue不合并」并等待确认。