diff --git a/docs/superpowers/plans/2026-06-18-gitlink-review-skill.md b/docs/superpowers/plans/2026-06-18-gitlink-review-skill.md new file mode 100644 index 0000000..821f61f --- /dev/null +++ b/docs/superpowers/plans/2026-06-18-gitlink-review-skill.md @@ -0,0 +1,767 @@ +# gitlink-review(智能代码审查)Skill 实现计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 新增一个纯 Markdown skill `gitlink-review`,引导 AI agent 对指定 GitLink PR 做多视角 + 对抗式自检的结构化代码审查,并把报告卡作为评论发布。 + +**Architecture:** 交付物是 `skills/gitlink-review/` 下的 SKILL.md + REFERENCE.md + examples/,无 Go 代码。智能来自 agent 按管道执行(取 diff → 降噪 → 6 视角 → 对抗自检 → 综合 → 预览 → 发布)。发布主路径用已验证可用的 `pr +comment`;行内评论为"reviews API 可用时增强"。用"植入缺陷测试 PR"做端到端真实验证。 + +**Tech Stack:** Markdown + gitlink-cli(`pr +view` / `pr +files` / `pr +diff` / `pr +comment` / `api POST /pulls/:id/reviews`)。 + +**Spec:** `docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md` + +--- + +## 前置约束(所有任务适用) + +- **`master` 受保护**:所有改动在特性分支 `feat/gitlink-review-skill` 上提交;测试用 fixture 在独立分支 `test/review-fixture` 上(仅供测试,不合并)。 +- **平台**:Windows + Git Bash。路径用正斜杠。 +- **认证**:`gitlink-cli` 已登录(`user +me` 可用)。 + +--- + +## Task 1:建立特性分支并纳入 spec/plan + +**Files:** +- Track: `docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md` +- Track: `docs/superpowers/plans/2026-06-18-gitlink-review-skill.md` + +- [ ] **Step 1:从最新 master 建分支** + +```bash +cd "C:/Users/CWQ98/Desktop/演化与运维/gitlink-cli" +git fetch origin +git checkout master +git pull --ff-only origin master +git checkout -b feat/gitlink-review-skill +``` + +预期:位于 `feat/gitlink-review-skill`,与 master 同步。 + +- [ ] **Step 2:确认 CLI 可用** + +```bash +gitlink-cli version +gitlink-cli user +me --format json +``` + +预期:打印版本;`user +me` 返回 `login: caoweiqiong`。 + +- [ ] **Step 3:把 spec 和 plan 纳入版本控制** + +```bash +git add docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md \ + docs/superpowers/plans/2026-06-18-gitlink-review-skill.md +git commit -m "docs(review): 添加 gitlink-review 设计 spec 与实现计划" +``` + +--- + +## Task 2:创建"植入缺陷"测试 PR(端到端验证载体) + +**Files:** +- Create(在 `test/review-fixture` 分支上,不合并):`review_fixture.go` + +- [ ] **Step 1:从 master 建测试分支** + +```bash +git checkout master +git checkout -b test/review-fixture +``` + +- [ ] **Step 2:写 fixture 文件(含 4 个植入点)** + +创建 `review_fixture.go`: + +```go +//go:build ignore + +// 本文件为 gitlink-review skill 的测试夹具,故意植入缺陷。DO NOT MERGE。 +package reviewtest + +import "os" + +var _ = os.Getenv // 仅占位引入,避免 unused 报错(build ignore 下不影响) + +// User 占位类型 +type User struct{ Name string } + +// 1. 正确性:空指针未判 +func CurrentUser(token string) *User { + if token == "" { + return nil // token 无效返回 nil + } + return &User{Name: "cwq"} +} + +func Greet(token string) string { + u := CurrentUser(token) + return "hello " + u.Name // ← BUG: u 可能为 nil,解引用会 panic +} + +// 2. 安全:硬编码 Token(明显伪造字符串,避免触发真实密钥扫描) +var AdminToken = "glpat-FAKEFAKEFAKE0000000000" + +// 3. 测试:新函数 Welcome,本 PR 无对应 _test.go +func Welcome(name string) string { + if name == "" { + return "guest" + } + return "hi " + name +} + +// 4. 伪阳性:看似除零,但调用方 DoMath 已保证除数非 0 +func Divide(a, b int) int { + return a / b +} + +func DoMath(x int) int { + if x == 0 { + return 0 // 上游保证 x != 0 + } + return Divide(100, x) // 因此 Divide 的除零在真实调用路径上是伪阳性 +} +``` + +- [ ] **Step 3:提交并推送** + +```bash +git add review_fixture.go +git commit -m "test(review): 植入缺陷夹具(正确性/安全/测试/伪阳性)" +git push origin test/review-fixture +``` + +- [ ] **Step 4:创建 PR** + +```bash +gitlink-cli pr +create \ + --owner chroe --repo gitlink-cli \ + --head test/review-fixture --base master \ + --title "test: gitlink-review 植入缺陷夹具(请勿合并)" \ + --body "gitlink-review skill 端到端验证用 PR。含 4 个植入点:空指针、硬编码 Token、缺测试、伪阳性。验证完成后将关闭不合并。" \ + --format json +``` + +预期:`pull_request_number` 返回一个数(记为 ``,如 3)。记录到 `review_fixture_notes.txt`(本地临时): + +``` +TEST_PR_NUMBER= +``` + +- [ ] **Step 5:验证 diff 可取** + +```bash +gitlink-cli pr +files --owner chroe --repo gitlink-cli --id --format json +gitlink-cli pr +diff --owner chroe --repo gitlink-cli --id --format json | head -c 800 +``` + +预期:files 含 `review_fixture.go`;diff 含上述代码片段。 + +--- + +## Task 3:实测 reviews API(决定行内评论能力) + +**Files:** 无(结论写入 Task 5 的 REFERENCE.md) + +- [ ] **Step 1:在测试 PR 上探测 POST reviews** + +```bash +gitlink-cli api POST /chroe/gitlink-cli/pulls//reviews \ + --body '{"body":"gitlink-review probe: 行内评论能力探测","event":"COMMENT"}' 2>&1 +``` + +- [ ] **Step 2:判断并记录结论** + +- 若返回 `{"ok":true,...}`(或含 review id)→ **行内评论可用**,记录实际请求体格式。 +- 若返回 404 / URL 被注入 git exec-path → **不可用(与 triage 记录的 `api POST` bug 一致)**。 + +把结论写入本地 `review_api_probe.txt`: + +``` +REVIEWS_API= +NOTES=<观察到的响应或错误> +``` + +- [ ] **Step 3:若可用,再试带行号的行内评论** + +```bash +gitlink-cli api POST /chroe/gitlink-cli/pulls//reviews \ + --body '{"event":"COMMENT","body":"行内探测","line":22,"path":"review_fixture.go","side":"RIGHT"}' 2>&1 +``` + +记录是否支持 `line/path/side`(行内定位)。结果并入 `review_api_probe.txt`。 + +> 此 task 无需 commit(结论是数据,将在 Task 5 固化进 REFERENCE.md)。 + +--- + +## Task 4:写 SKILL.md(主管道与方法论) + +**Files:** +- Create: `skills/gitlink-review/SKILL.md` + +- [ ] **Step 1:切回特性分支并建目录** + +```bash +git checkout feat/gitlink-review-skill +``` + +- [ ] **Step 2:写 SKILL.md** + +创建 `skills/gitlink-review/SKILL.md`,**完整内容**如下: + +````markdown +--- +name: gitlink-review +version: 1.0.0 +description: "智能代码审查:分析 PR diff,多视角评审 + 对抗式自检,输出结构化 Review 意见并作为评论发布。当用户需要审查 GitLink PR、做代码 review、自动生成审查意见时触发。" +metadata: + requires: + bins: ["gitlink-cli"] + cliHelp: "gitlink-cli pr --help" +--- + +# gitlink-review(智能代码审查) + +**CRITICAL — 开始前必须先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),其中包含认证、权限处理和 API 注意事项。** +**CRITICAL — 所有写入操作(发布评论)前默认先预览、确认后再执行;`--auto` 跳过确认但仍受置信度门控。** +**CRITICAL — 绝不自动 approve / merge PR。审查只是评论,不做合并决策。** +**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`(GitHub CLI)操作 GitLink 资源。** + +> **前置条件:** 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md);详细检查清单与字段映射见 [`REFERENCE.md`](REFERENCE.md)。 + +## 概述 + +本 Skill 引导 AI 对指定 GitLink PR 做结构化、多视角、低误报的代码审查,并把"报告卡"作为评论发布。核心特点: + +1. **多视角评审团**:6 个视角并行扫 diff +2. **对抗式自检**:每条候选发现先自我反驳,成立的才留下(直击 AI 审查误报老大难) +3. **降噪**:自动跳过生成代码 / vendor / lock / 纯重命名 +4. **可执行**:每条发现带 `file:line` + 修复建议 + 理由 + +## 命令接口(skill 约定参数,非 gitlink-cli 新增 flag) + +| 参数 | 默认 | 说明 | +|------|------|------| +| `--owner/--repo` | 自动从 cwd 解析 | 目标仓库 | +| `--id` | 必填 | PR 编号(`pull_request_number`,网页 `/pulls/N`) | +| `--lenses` | 全 6 视角 | 子集,如 `correctness,security` | +| `--auto` | 关 | 跳过预览确认直接发布(仍受置信度门控) | +| `--inline` | 关 | 尝试附行内评论(reviews API 可用时) | +| `--max-findings` | 12 | 报告卡上限 | +| `--refresh` | 关 | 即使存在旧审查哨兵也重审并更新 | + +## 管道(8 步) + +### ① 取上下文 + +```bash +gitlink-cli pr +view --owner --repo --id --format json # 元数据 +gitlink-cli pr +files --owner --repo --id --format json # 文件 +/- +gitlink-cli pr +diff --owner --repo --id --format json # 核心:diff 内容 +gitlink-cli repo +info --owner --repo --format json # 语言校准 +``` + +### ② 降噪过滤 + +按下述"降噪规则"跳过噪音文件;在报告卡"范围"行注明跳过数量,不静默吞掉。 + +### ③ 多视角分析 + +对每个启用的视角扫 diff,产出候选发现,每条含: + +```json +{ "lens": "correctness", "severity": "high", "likelihood": "likely", + "file": "auth/login.go", "line": 42, "what": "空指针未判", + "why": "...", "fix": "...", "confidence": "high" } +``` + +### ④ 对抗式自检(质量门) + +逐条自问(任一成立即丢弃或降级): + +1. 语境里是否已有保护(外层判空、上游校验、框架机制)? +2. 是真缺陷还是风格偏好?偏好 → 降级 🔵 nit 或丢弃。 +3. 引用的 API/签名/语言行为是否真实存在?(不确定则不报) +4. 是否与另一视角重复? + +**置信度门控**:`confidence=low` 且 `severity≠high` → 丢弃。 + +### ⑤ 综合 + +跨视角去重 → 按 `严重度×likelihood` 排序 → 封顶 `--max-findings`。 + +### ⑥ 预览(默认) + +展示报告卡给用户;确认后发布。`--auto` 跳过。 + +### ⑦ 发布 + +```bash +gitlink-cli pr +comment --owner --repo --id \ + --body "<报告卡全文,含哨兵>" +``` + +`--inline` 且 reviews API 可用 → 对 🔴/🟡 发现附行内评论(见 REFERENCE.md 的 API 结论)。 + +### ⑧ 幂等 + +发布前检查该 PR 是否已有哨兵 ``;有则默认提议"更新"(`--refresh` 才覆盖)。 + +## 评审团 6 视角 + +| 视角 | 盯什么 | +|------|--------| +| 🔴 正确性 (correctness) | 逻辑错、边界、空值、并发竞态、资源泄漏、错误处理、类型转换 | +| 🔒 安全 (security) | 注入(SQL/命令/XSS)、鉴权越权、密钥/Token 泄露、路径穿越、不安全反序列化、弱加密 | +| ⚡ 性能 (performance) | N+1 查询、无谓拷贝、O(n²)/嵌套循环、热路径分配、缺索引 | +| 🧪 测试 (tests) | 新增/改动代码有无测试、边界用例、断言有效性 | +| 🧹 可维护性 (maintainability) | 命名、重复、圈复杂度、抽象边界、与既有约定一致 | +| 🚨 生产风险 (prod-risk) | "合并后凌晨3点哪会炸"——可观测性/日志、回滚、破坏性变更、配置依赖、降级 | + +> 各视角的展开检查清单见 [`REFERENCE.md`](REFERENCE.md)。 + +## 报告卡格式(作为评论发布) + +```markdown +🤖 **gitlink-review 报告** + +**结论**:<总体:✅LGTM / ⚠️建议修改 / 🛑有阻塞>(A 🔴阻塞 / B 🟡建议 / C 🔵nit) +**范围**: 文件,+/-(跳过 噪音文件)|视角:|自检丢弃: + +| 严重度 | 视角 | 位置 | 问题 | +|:---:|---|---|---| +| 🔴 | correctness | path/file.go:42 | <一句话> | + +### 🔴 阻塞(合并前需处理) +1. **[correctness] path/file.go:42** — + - **为什么**: + - **建议**: + +### 🟡 建议 +… + +### 🔵 nit +… + +### ✅ 未发现问题的方面 +- <视角>:<结论> + +--- + +*由 gitlink-review skill 生成。* +``` + +## 降噪规则(自动跳过) + +生成代码(`*.gen.go`/`*.pb.go`/`*_generated.*`/`*.min.js`/dist//build//target/)、第三方(vendor//third_party//node_modules/)、锁文件(go.sum/package-lock.json/yarn.lock/pnpm-lock.yaml/Cargo.lock)、纯重命名/移动、二进制/图片/字体。 + +## 安全护栏 + +- 默认预览确认;`--auto` 跳过但仍受置信度门控 +- **绝不自动 approve / merge** +- 行内评论仅 `--inline` 且 reviews API 可用时发 +- `--max-findings` 封顶防刷屏 +- 评论失败 → 把报告卡原文交用户手动粘贴 + +## 错误处理与降级 + +| 情况 | 处理 | +|------|------| +| 无 diff | 报"无可审查变更",不发评论 | +| PR 不存在/无权限 | 清晰错误,不发评论 | +| reviews API 404 | 跳过行内,总结评论照发 | +| diff 过大 | 抽样 + 标注"部分审查(仅 X/Y 文件)" | +| 评论发布失败 | 输出报告卡原文供手动粘贴 | +| 全部 low 置信 | 报"未发现高置信问题",列待人工确认项 | + +## 最佳实践 + +- **先预览再发布**(默认),降低对外噪音 +- **置信度优先**:宁可少报,不要误报 +- **可执行**:每条发现必须带"建议修复" +- **不越权**:只评论,不合并 +```` + +- [ ] **Step 3:提交** + +```bash +git add skills/gitlink-review/SKILL.md +git commit -m "feat(review): 新增 gitlink-review SKILL.md(管道+6视角+对抗自检+报告卡)" +``` + +--- + +## Task 5:写 REFERENCE.md(清单 + 评级 + API 结论) + +**Files:** +- Create: `skills/gitlink-review/REFERENCE.md` + +- [ ] **Step 1:读 Task 3 的探测结论** + +```bash +cat review_api_probe.txt +``` + +把 `` 与 ``(下文占位)替换为真实结论。 + +- [ ] **Step 2:写 REFERENCE.md** + +创建 `skills/gitlink-review/REFERENCE.md`,完整内容(**把 `` 等占位替换为 Task 3 实测结果**): + +````markdown +# gitlink-review 参考手册 + +> 各视角检查清单、严重度评级、降噪规则、reviews API 实测结论、字段映射。 + +--- + +## 一、各视角检查清单 + +### 🔴 正确性 (correctness) +- 空值/nil 解引用未判 +- 边界:off-by-one、数组越界、空集合 +- 错误未处理或被吞(`err != nil` 缺失、`_ = err`) +- 并发:数据竞态、缺锁、死锁 +- 资源泄漏:文件/连接/goroutine 未关闭或回收 +- 类型转换/断言未检查 +- 逻辑分支遗漏、return 路径不全 + +### 🔒 安全 (security) +- 注入:SQL 拼接、命令、XSS、模板未转义 +- 鉴权/越权:缺权限校验、IDOR +- 密钥/Token 硬编码或写入日志 +- 路径穿越(`../`、用户输入拼路径) +- 不安全反序列化、弱加密/弱随机 +- 危险默认值(debug 开关、CORS *) + +### ⚡ 性能 (performance) +- N+1 查询、循环内 IO/查询 +- 无谓拷贝大对象、字符串反复拼接 +- O(n²)/深层嵌套循环 +- 热路径分配、缺缓存 +- 缺索引/全表扫描 + +### 🧪 测试 (tests) +- 新增/改动函数有无对应测试 +- 边界与异常用例覆盖 +- 断言是否有效(非 `assert true`) +- mock 是否合理、是否过度 + +### 🧹 可维护性 (maintainability) +- 命名是否达意 +- 重复代码(DRY) +- 圈复杂度过高、函数过长 +- 抽象边界模糊、职责混杂 +- 与既有代码风格/约定不一致 + +### 🚨 生产风险 (prod-risk) +- 破坏性变更(API/DB schema/配置格式) +- 可观测性:关键路径有无日志/指标 +- 回滚能力:是否可安全回退 +- 配置/环境依赖、启动顺序 +- 降级与限流缺失 + +--- + +## 二、严重度 × likelihood 评级 + +| severity | 含义 | 处理 | +|----------|------|------| +| 🔴 high | 阻塞:会导致 bug/安全问题/线上故障 | 合并前需处理 | +| 🟡 medium | 建议:应修复但不强制阻塞 | 建议处理 | +| 🔵 low | nit:风格/可读性 | 可选 | + +| likelihood | 含义 | +|------------|------| +| likely | 真实路径上会发生 | +| possible | 特定条件下发生 | +| unlikely | 罕见但可能 | + +排序权重:`high×likely` > `high×possible` > `medium×likely` > …。 + +置信度 `confidence`:high/medium/low。**门控**:`confidence=low && severity≠high → 丢弃`。 + +--- + +## 三、降噪规则 + +跳过:`*.gen.go`、`*.pb.go`、`*_generated.*`、`*.min.js`、`dist/`、`build/`、`target/`、`vendor/`、`third_party/`、`node_modules/`、`go.sum`、`package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`Cargo.lock`、纯重命名/移动、二进制/图片/字体。跳过时在报告卡"范围"行计数。 + +--- + +## 四、reviews API 实测结论(决定行内评论) + +**实测命令**(于测试 PR ``): + +```bash +gitlink-cli api POST ///pulls//reviews \ + --body '{"body":"...","event":"COMMENT"}' +``` + +**结论**:(可用 / 不可用) + +(实测观察到的响应或错误) + +**设计影响**: +- 若 **不可用**(如返回 404 / git exec-path 注入 URL)→ 行内评论关闭,仅用 `pr +comment` 发总结评论。`--inline` 被忽略并提示原因。 +- 若 **可用** → `--inline` 时对 🔴/🟡 发现调用上述 API 发行内评论;请求体按实测支持的格式(是否含 `line/path/side`)构造。 + +--- + +## 五、字段映射 + +### pr +view 关键字段 + +| 字段 | 用途 | +|------|------| +| `issue.subject` / `issue.description` | 理解 PR 意图,校准审查重点 | +| `pull_request.base` / `pull_request.head` | 目标/源分支 | +| `author.login` | 作者(自审盲区提示) | +| `files_count` / `commits_count` | 范围概览 | + +### pr +diff 关键字段 + +| 字段 | 用途 | +|------|------| +| `files[].name` | 文件路径 | +| `files[].addition` / `deletion` | 增删行数 | +| `files[].sha` | 文件 sha(哨兵可选) | +| diff 正文 | 分析输入 | + +**行号映射规则**:报告卡里的 `file:line` 用**文件中的实际行号**(非 diff hunks 的 `+n` 相对行号)。从 diff hunk 头(`@@ -a,b +c,d @@`)推算:实际行号 = `c + (hunk 内相对行)`。 + +--- + +## 六、幂等哨兵 + +``` + +``` + +- 发布前用 `pr +view`(或取评论)检查是否已含该哨兵 +- `sha` = 审查所基于的 head commit;PR 有新提交时提示"审查已过期,建议重审" +- 默认不覆盖;`--refresh` 才重发 +```` + +- [ ] **Step 3:提交** + +```bash +git add skills/gitlink-review/REFERENCE.md +git commit -m "docs(review): 新增 REFERENCE.md(视角清单+评级+API实测结论+字段映射)" +``` + +--- + +## Task 6:端到端验证——对测试 PR 跑审查 + +**Files:** 无(验证 + 捕获输出) + +- [ ] **Step 1:按 SKILL.md 对 `` 执行审查** + +人工/agent 依 SKILL.md 管道执行:取 view/files/diff → 降噪 → 6 视角 → 对抗自检 → 综合 → 生成报告卡。把生成的报告卡全文存到本地 `review_output_.md`。 + +```bash +gitlink-cli pr +view --owner chroe --repo gitlink-cli --id --format json +gitlink-cli pr +files --owner chroe --repo gitlink-cli --id --format json +gitlink-cli pr +diff --owner chroe --repo gitlink-cli --id --format json +``` + +- [ ] **Step 2:验证 4 个植入点** + +断言(必须全部满足,否则回改 SKILL.md/REFERENCE.md 后重跑): + +| # | 植入点 | 期望 | 校验 | +|---|--------|------|------| +| 1 | `Greet` 空指针 | 🔴 correctness 命中,含 `review_fixture.go:<行>` 与 `u.Name` | 报告卡中能找到 | +| 2 | `AdminToken` 硬编码 | 🔒 security 命中 | 报告卡中能找到 | +| 3 | `Welcome` 缺测试 | 🧪 tests 命中(无 _test.go) | 报告卡中能找到 | +| 4 | `Divide` 除零(DoMath 已保护) | **被对抗自检丢弃**,`refuted` 计数 ≥1,**不应**出现在发现列表 | 报告卡中无此项 | + +- [ ] **Step 3:发布到测试 PR 并验证哨兵** + +```bash +gitlink-cli pr +comment --owner chroe --repo gitlink-cli --id \ + --body "$(cat review_output_.md)" --format json +``` + +预期:`ok: true`。再 `pr +view` 确认 `comments_count` 增加。 + +- [ ] **Step 4:若验证不通过,回改并重跑** + +任何断言失败 → 修正 SKILL.md 的检查清单/自检规则 → 重新执行 Step 1-3,直到 4 项全过。 + +--- + +## Task 7:写 examples/review-workflow.md(真实走查) + +**Files:** +- Create: `skills/gitlink-review/examples/review-workflow.md` + +- [ ] **Step 1:基于 Task 6 的真实输出写示例** + +创建 `skills/gitlink-review/examples/review-workflow.md`: + +````markdown +# 示例:对植入缺陷 PR 的智能审查(真实数据) + +> 基于 `chroe/gitlink-cli` 测试 PR #(`test/review-fixture`)于 2026-06-18 实际执行。 +> 该 PR 故意植入 4 个问题用于验证 gitlink-review skill。 + +--- + +## Step 1:取上下文 + +```bash +gitlink-cli pr +view --owner chroe --repo gitlink-cli --id --format json +gitlink-cli pr +diff --owner chroe --repo gitlink-cli --id --format json +``` + +**范围**:1 文件 `review_fixture.go`,+38/-0,无噪音文件需跳过。 + +## Step 2:6 视角扫描 + 对抗自检(关键过程) + +| 候选发现 | 视角 | 自检结果 | +|----------|------|----------| +| `Greet` 中 `u.Name` 解引用 nil | correctness | ✅ 成立(无外层判空)→ 保留 🔴 | +| `AdminToken` 硬编码 | security | ✅ 成立 → 保留 🔴 | +| `Welcome` 无对应测试 | tests | ✅ 成立(本 PR 无 _test.go)→ 保留 🟡 | +| `Divide(a,b)` 除零 | correctness | ❌ **被反驳**:`DoMath` 已保证 `x≠0`,真实调用路径除数非 0 → 丢弃 | + +**自检丢弃:1 条(refuted=1)**。 + +## Step 3:发布报告卡(真实输出) + +```bash +gitlink-cli pr +comment --owner chroe --repo gitlink-cli --id \ + --body "<报告卡全文>" +``` + +<此处粘贴 Task 6 生成的真实报告卡全文> + +**发布结果**:`ok: true`,PR 评论数 +1。 + +## Step 4:幂等验证 + +再次运行(不带 `--refresh`)→ 检测到哨兵 `` → 提示"已存在审查,使用 --refresh 更新",未重复发布。 + +## 关键结论 + +- 3 个真实缺陷被对应视角命中,1 个伪阳性被对抗自检丢弃(refuted=1) +- 行内评论:<根据 Task 3 结论写"可用已附行内" 或 "API 不可用,仅总结评论"> +```` + +- [ ] **Step 2:提交** + +```bash +git add skills/gitlink-review/examples/review-workflow.md +git commit -m "docs(review): 新增真实走查示例 review-workflow.md" +``` + +--- + +## Task 8:更新 README 与 workflow 链接 + +**Files:** +- Modify: `skills/README.md` +- Modify: `skills/gitlink-workflow/SKILL.md` + +- [ ] **Step 1:README 智能 skill 表加一行** + +在 `skills/README.md` 的"智能 Skills"表追加: + +```markdown +| **gitlink-review** | 智能代码审查 | 分析 PR diff,多视角评审 + 对抗式自检,结构化 Review 意见自动评论 | +``` + +并在文档导航/按需处补一行指向 `gitlink-review/SKILL.md`。 + +- [ ] **Step 2:workflow 的浅层 Code Review 链回本 skill** + +在 `skills/gitlink-workflow/SKILL.md` 的"AI 在 PR 流程中的角色 → Code Review"处补一句: + +```markdown +> 深度代码审查请使用 [`../gitlink-review/SKILL.md`](../gitlink-review/SKILL.md)(多视角 + 对抗式自检 + 自动评论)。 +``` + +- [ ] **Step 3:提交** + +```bash +git add skills/README.md skills/gitlink-workflow/SKILL.md +git commit -m "docs(review): README 智能表登记 gitlink-review,workflow 链回深度审查" +``` + +--- + +## Task 9:清理测试 PR + 推送特性分支 + 建 PR + +**Files:** 无 + +- [ ] **Step 1:关闭测试 PR(不合并)** + +```bash +gitlink-cli pr +close --owner chroe --repo gitlink-cli --id +``` + +预期:`ok: true`,PR 状态变 closed(未合并,植入缺陷不进 master)。 + +- [ ] **Step 2:删本地/远端测试分支** + +```bash +git branch -D test/review-fixture +git push origin --delete test/review-fixture +``` + +- [ ] **Step 3:清理本地临时文件** + +```bash +rm -f review_fixture_notes.txt review_api_probe.txt review_output_*.md +``` + +- [ ] **Step 4:推送特性分支** + +```bash +git checkout feat/gitlink-review-skill +git push origin feat/gitlink-review-skill +``` + +- [ ] **Step 5:创建合并到 master 的 PR** + +```bash +gitlink-cli pr +create \ + --owner chroe --repo gitlink-cli \ + --head feat/gitlink-review-skill --base master \ + --title "feat: 新增 gitlink-review 智能代码审查 Skill" \ + --body "## 目的 +子任务二核心场景:智能代码审查(分析 PR diff,多视角+对抗自检,结构化 Review 自动评论)。 + +## 交付 +- skills/gitlink-review/:SKILL.md + REFERENCE.md + examples/review-workflow.md +- skills/README.md、skills/gitlink-workflow/SKILL.md:登记与链接 +- docs/superpowers/:设计 spec + 实现计划 + +## 验证(真实数据) +植入缺陷测试 PR 已验证:3 个真实缺陷被对应视角命中,1 个伪阳性被对抗自检丢弃(refuted=1),哨兵幂等,pr +comment 发布成功。reviews API:<填 Task 3 结论>。 + +## 设计要点 +- 多视角评审团(正确性/安全/性能/测试/可维护/生产风险) +- 对抗式自检质量门(直击误报) +- 默认预览确认,绝不自动合并" \ + --format json +``` + +- [ ] **Step 6:记录 PR 号并通知用户** + +把返回的 `pull_request_number` 报告给用户,等待其合并(master 受保护)。 + +--- + +## 验收(全部满足才算完成) + +- [ ] `skills/gitlink-review/` 三件套齐全,结构与 triage/health 一致 +- [ ] Task 6 四个植入点断言全过(3 命中 + 1 丢弃) +- [ ] REFERENCE.md 的 reviews API 结论为实测结果(非猜测) +- [ ] 报告卡含哨兵,幂等生效 +- [ ] README 与 workflow 链接已更新 +- [ ] 测试 PR 已关闭未合并,测试分支已删 +- [ ] 特性分支已推送,PR 已创建 diff --git a/docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md b/docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md new file mode 100644 index 0000000..a1778fb --- /dev/null +++ b/docs/superpowers/specs/2026-06-18-intelligent-code-review-design.md @@ -0,0 +1,216 @@ +# 智能代码审查 Skill(gitlink-review)设计 + +- **日期**:2026-06-18 +- **状态**:已批准,待编写实现计划 +- **作者**:CWQ + Claude +- **定位**:子任务二核心场景之一——智能代码审查;纯 Markdown skill(SKILL.md + REFERENCE.md + examples/),无需 Go 代码 + +--- + +## 1. 背景与目标 + +gitlink-cli 现有 16 个 skill 中**没有专门的代码审查 skill**:`gitlink-workflow` 的"PR 全流程"仅在 Step 5 浅层提及(`pr +files` + "给出审查意见")。README 列的智能 skill 只有 health / changelog / triage 三件套。 + +本 skill 填补该缺口:引导 AI agent 对指定 GitLink PR 执行**结构化、多视角、低误报**的代码审查,并把结构化审查意见作为评论发布到 PR。 + +**实用性目标**:信噪比高、误报少、每条发现可执行(带 `file:line` + 修复建议 + 理由)、能稳定落地到 GitLink(`pr +comment` 已验证可用)。 + +**创意性目标**:多视角"评审团" + 对抗式自检(自带质量门,直击 AI code review 的误报老大难)+ 生产风险(oncall)视角。 + +## 2. 非目标(YAGNI) + +- 不做 CI / webhook 自动触发——按需由 agent 调用 +- **绝不自动 approve / merge** +- 不做跨仓库批量(单 PR 为主;批量留作可选入口,不在首版实现) +- 不修改 gitlink-cli 的 Go 代码——纯 skill 交付物 + +## 3. 关键决策(用户确认) + +| 决策点 | 选择 | +|--------|------| +| 评论形式 | 总结评论为主(`pr +comment`,可靠)+ 行内评论增强(reviews API 可用时附加,否则降级) | +| 发表策略 | 默认预览、确认后发;`--auto` 跳过确认(仍受置信度门控) | +| 审查引擎 | 多视角评审团(6 视角全量)+ 对抗式自检 | + +## 4. 文件清单与改动范围 + +| 文件 | 动作 | 内容 | +|------|------|------| +| `skills/gitlink-review/SKILL.md` | 新增 | 主管道、6 视角、对抗自检、降噪、输出格式、安全护栏、命令接口 | +| `skills/gitlink-review/REFERENCE.md` | 新增 | 各视角检查清单、严重度评级表、字段映射、reviews API 实测结论与降级、噪音文件规则 | +| `skills/gitlink-review/examples/review-workflow.md` | 新增 | 真实 PR 走查(含植入缺陷验证、真实输出) | +| `skills/README.md` | 修改 | 智能技能表新增 gitlink-review | +| `skills/gitlink-workflow/SKILL.md` | 修改 | 浅层 Code Review 步骤链回本 skill | + +## 5. 命令接口 + +skill 由 agent 调用,参数(约定,非 CLI 子命令): + +| 参数 | 默认 | 说明 | +|------|------|------| +| `--owner/--repo` | 自动从 cwd 解析 | 目标仓库 | +| `--id` | 必填 | PR 编号(`pull_request_number`,网页 URL `/pulls/N`) | +| `--lenses` | 全 6 视角 | 指定子集,如 `correctness,security` | +| `--auto` | 关 | 跳过预览确认,直接发布(仍受置信度门控) | +| `--inline` | 关 | 尝试附行内评论(reviews API 可用时) | +| `--max-findings` | 12 | 报告卡上限,防刷屏 | +| `--refresh` | 关 | 即使检测到旧审查哨兵也重审并更新 | + +## 6. 数据流(8 步管道) + +``` +① 取上下文 pr +view / pr +files / pr +diff(核心输入)/ repo +info(语言校准、约定) +② 降噪过滤 跳过生成代码 / vendor / lock / 纯重命名 / 二进制 / minified +③ 多视角分析 6 视角并行扫 diff → 候选发现 +④ 对抗式自检 逐条尝试反驳 → 丢弃不成立/低置信 +⑤ 综合 跨视角去重、按 严重度×likelihood 排序、封顶 → 报告卡 +⑥ 预览 默认展示给用户,确认后发(--auto 跳过) +⑦ 发布 pr +comment 发总结评论(可靠);--inline 且 reviews API 可用 → 附行内评论,否则降级 +⑧ 幂等 评论内嵌哨兵 ,重跑检测旧审查 → 提议更新而非刷屏 +``` + +每条候选发现的数据结构(内部): + +```json +{ + "lens": "correctness", + "severity": "high", // high(🔴) | medium(🟡) | low(🔵) + "likelihood": "likely", // likely | possible | unlikely + "file": "auth/login.go", + "line": 42, + "what": "空指针未判", + "why": "GetUser 在 token 无效时返回 nil,此处直接解引用", + "fix": "if u := GetUser(t); u != nil { ... }", + "confidence": "high" // high | medium | low +} +``` + +## 7. 评审团 6 视角 + +| 视角 | 盯什么 | +|------|--------| +| 🔴 正确性 (correctness) | 逻辑错、边界、空值、并发竞态、资源泄漏、错误处理、类型转换 | +| 🔒 安全 (security) | 注入(SQL/命令/XSS)、鉴权越权、密钥/Token 泄露、路径穿越、不安全反序列化、弱加密 | +| ⚡ 性能 (performance) | N+1 查询、无谓拷贝、O(n²)/嵌套循环、热路径分配、缺索引、大对象常驻 | +| 🧪 测试 (tests) | 新增/改动代码有无对应测试、边界用例、断言是否有效、mock 是否合理 | +| 🧹 可维护性 (maintainability) | 命名、重复代码、圈复杂度、抽象边界、与既有约定一致性 | +| 🚨 生产风险 (prod-risk) | "合并后凌晨3点哪会炸"——可观测性/日志、回滚能力、破坏性变更(API/DB/schema)、配置依赖、降级路径 | + +各视角的展开检查清单写入 `REFERENCE.md`。 + +## 8. 对抗式自检(质量门,创意核心) + +对每条候选发现,agent 自我问以下问题,任一成立即丢弃或降级: + +1. **语境已处理**:完整上下文里是否已有保护(外层判空、上游校验、框架机制)? +2. **风格冒充 bug**:这是真缺陷还是个人风格偏好?若是偏好,降级为 🔵 nit 或丢弃。 +3. **幻觉检查**:我引用的 API/函数签名/语言行为是否真实存在?(不确定则不报,或标注"待确认") +4. **重复/已被覆盖**:是否与另一视角的发现其实是同一问题? + +**置信度门控**:`confidence=low` 且 `severity≠high` → 丢弃。这保证只发高信号发现。 + +## 9. 降噪规则(自动跳过,不审查) + +- 生成代码:`*.gen.go`、`*.pb.go`、`*_generated.*`、`*.min.js`、dist/、build/、target/ +- 第三方:`vendor/`、`third_party/`、`node_modules/` +- 锁文件:`go.sum`、`package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`Cargo.lock` +- 纯重命名/移动(无内容变更) +- 二进制文件、图片、字体 + +跳过时在报告卡"范围"行注明跳过数量,不静默吞掉。 + +## 10. 输出格式(报告卡,作为 PR 评论发布) + +```markdown +🤖 **gitlink-review 报告** + +**结论**:⚠️ 建议修改(2 🔴阻塞 / 4 🟡建议 / 3 🔵nit) +**范围**:5 文件,+120/-30(跳过 2 噪音文件)|视角:6|自检丢弃:3 + +| 严重度 | 视角 | 位置 | 问题 | +|:---:|---|---|---| +| 🔴 | 正确性 | auth/login.go:42 | 空指针未判 | +| 🔴 | 安全 | config.go:8 | 硬编码 Token | +| 🟡 | 性能 | list.go:88 | 循环内重复查询 | + +### 🔴 阻塞(合并前需处理) +1. **[正确性] auth/login.go:42** — `GetUser(token)` 在 token 无效时返回 nil,此处直接解引用会 panic。 + - **建议**:`if u := GetUser(t); u != nil { ... }` +2. **[安全] config.go:8** — 硬编码 Token,存在泄露风险。 + - **建议**:改从环境变量读取 `os.Getenv("GITLINK_TOKEN")` + +### 🟡 建议 +… + +### 🔵 nit +… + +### ✅ 未发现问题的方面 +- 安全:未发现注入点 +- 生产风险:无破坏性 API 变更 + +--- + +*由 gitlink-review skill 生成;本评论为预览确认后发布。* +``` + +哨兵 `` 用于幂等与"针对哪个 commit"标识。 + +## 11. 安全护栏 + +- 默认预览确认;`--auto` 跳过确认但**仍受置信度门控** +- **绝不自动 approve / merge**(即使 `--auto`) +- 行内评论仅在显式 `--inline` 且 reviews API 实测可用时发,否则不发 +- `--max-findings` 封顶,防刷屏 +- 所有写操作需认证(遵循 `gitlink-shared`) +- 跳过自己作者本人的 PR 时可提示(避免自审盲区),但不强制阻断 + +## 12. 错误处理与降级 + +| 情况 | 处理 | +|------|------| +| `pr +diff` 无差异 | 报告"无可审查变更",不发评论 | +| PR 不存在/无权限 | 清晰错误信息,不发评论 | +| reviews API 404(已知 `api POST` bug) | 记录、跳过行内、总结评论照发 | +| diff 过大(> 阈值) | 抽样审查 + 标注"部分审查(仅 X/Y 文件)" | +| `pr +comment` 发布失败 | 把报告卡原文输出给用户手动粘贴 | +| 置信度全部 low | 报告"未发现高置信问题",列出待人工确认项 | + +## 13. 幂等与去重 + +- 评论内嵌哨兵;重跑时先 `pr +view`/取评论检测哨兵 +- 已存在旧审查:默认提议"更新"(`--refresh` 才覆盖),避免重复发 +- `sha` 字段记录审查所基于的 head commit;PR 有新提交时提示"审查已过期,建议重审" + +## 14. 验证计划(真实数据,沿用其他 skill 惯例) + +建一个**植入已知缺陷的小测试 PR**,包含: + +1. 一处空指针/越界(验证 🔴 正确性视角命中) +2. 一处硬编码密钥(验证 🔒 安全视角命中) +3. 一处缺测试的新函数(验证 🧪 测试视角命中) +4. 一处"看起来像 bug 但语境已处理"的伪阳性(验证对抗自检丢弃) + +验证项: +- [ ] 每个植入缺陷被对应视角命中 +- [ ] 伪阳性被对抗自检丢弃(refuted 计数 +1) +- [ ] 哨兵正确内嵌,重跑不刷屏 +- [ ] 总结评论通过 `pr +comment` 成功发布 +- [ ] reviews API 实测:记录可用/不可用结论写入 REFERENCE.md +- [ ] `--auto` 与预览两种模式均验证 + +结果(真实输出)写入 `examples/review-workflow.md`。 + +## 15. 风险与未决 + +- **reviews API 可用性**:`gitlink-triage` 记录 `api POST` 有 URL 注入 bug 导致 404。本 skill 的行内评论依赖 `POST /:owner/:repo/pulls/:id/reviews`,实现时**必须实测**;不可用则设计已内建降级(仅总结评论)。结论写入 REFERENCE.md。 +- **token 消耗**:6 视角全量较重;通过 `--lenses` 子集和 `--max-findings` 控制。 +- **行号偏移**:diff 行号 vs 文件行号的映射需在 REFERENCE.md 给出规则,保证 `file:line` 准确。 + +## 16. 验收标准 + +1. `skills/gitlink-review/` 三件套齐全,结构与 triage/health 等智能 skill 一致 +2. 测试 PR 的 4 个植入点验证全部通过(3 命中 + 1 丢弃) +3. 总结评论在真实 PR 成功发布,含哨兵 +4. reviews API 可用性有明确实测结论 +5. README 与 workflow 链接更新 diff --git a/skills/README.md b/skills/README.md index 967a46a..a28cf20 100644 --- a/skills/README.md +++ b/skills/README.md @@ -161,6 +161,7 @@ skills/ | **gitlink-health** | 项目健康度报告 | Issue 响应时间、PR 合并效率、贡献者活跃度统计 | | **gitlink-changelog** | Release Notes 自动生成 | 从 commit/PR/Issue 历史自动生成版本说明 | | **gitlink-triage** | Issue 智能分拣 + 新人引导 | 自动分类、打标签、分配责任人、good-first-issue 引导 | +| **gitlink-review** | 智能代码审查 | 分析 PR diff,多视角评审 + 对抗式自检,结构化 Review 意见自动评论 | --- diff --git a/skills/gitlink-review/REFERENCE.md b/skills/gitlink-review/REFERENCE.md new file mode 100644 index 0000000..c313b27 --- /dev/null +++ b/skills/gitlink-review/REFERENCE.md @@ -0,0 +1,135 @@ +# gitlink-review 参考手册 + +> 各视角检查清单、严重度评级、降噪规则、reviews API 实测结论、字段映射、幂等哨兵。 + +--- + +## 一、各视角检查清单 + +### 🔴 正确性 (correctness) +- 空值/nil 解引用未判 +- 边界:off-by-one、数组越界、空集合 +- 错误未处理或被吞(`err != nil` 缺失、`_ = err`) +- 并发:数据竞态、缺锁、死锁 +- 资源泄漏:文件/连接/goroutine 未关闭或回收 +- 类型转换/断言未检查 +- 逻辑分支遗漏、return 路径不全 + +### 🔒 安全 (security) +- 注入:SQL 拼接、命令、XSS、模板未转义 +- 鉴权/越权:缺权限校验、IDOR +- 密钥/Token 硬编码或写入日志 +- 路径穿越(`../`、用户输入拼路径) +- 不安全反序列化、弱加密/弱随机 +- 危险默认值(debug 开关、CORS *) + +### ⚡ 性能 (performance) +- N+1 查询、循环内 IO/查询 +- 无谓拷贝大对象、字符串反复拼接 +- O(n²)/深层嵌套循环 +- 热路径分配、缺缓存 +- 缺索引/全表扫描 + +### 🧪 测试 (tests) +- 新增/改动函数有无对应测试 +- 边界与异常用例覆盖 +- 断言是否有效(非 `assert true`) +- mock 是否合理、是否过度 + +### 🧹 可维护性 (maintainability) +- 命名是否达意 +- 重复代码(DRY) +- 圈复杂度过高、函数过长 +- 抽象边界模糊、职责混杂 +- 与既有代码风格/约定不一致 + +### 🚨 生产风险 (prod-risk) +- 破坏性变更(API/DB schema/配置格式) +- 可观测性:关键路径有无日志/指标 +- 回滚能力:是否可安全回退 +- 配置/环境依赖、启动顺序 +- 降级与限流缺失 + +--- + +## 二、严重度 × likelihood 评级 + +| severity | 含义 | 处理 | +|----------|------|------| +| 🔴 high | 阻塞:会导致 bug/安全问题/线上故障 | 合并前需处理 | +| 🟡 medium | 建议:应修复但不强制阻塞 | 建议处理 | +| 🔵 low | nit:风格/可读性 | 可选 | + +| likelihood | 含义 | +|------------|------| +| likely | 真实路径上会发生 | +| possible | 特定条件下发生 | +| unlikely | 罕见但可能 | + +排序权重:`high×likely` > `high×possible` > `medium×likely` > …。 + +置信度 `confidence`:high/medium/low。**门控**:`confidence=low && severity≠high → 丢弃`。 + +--- + +## 三、降噪规则 + +跳过:`*.gen.go`、`*.pb.go`、`*_generated.*`、`*.min.js`、`dist/`、`build/`、`target/`、`vendor/`、`third_party/`、`node_modules/`、`go.sum`、`package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`Cargo.lock`、纯重命名/移动、二进制/图片/字体。跳过时在报告卡"范围"行计数。 + +--- + +## 四、reviews API 实测结论(决定行内评论) + +**实测(2026-06-23,测试 PR chroe/gitlink-cli#3)**: + +```bash +gitlink-cli api POST /chroe/gitlink-cli/pulls/3/reviews \ + --body '{"body":"...","event":"COMMENT"}' +# → 404 Not Found({"status":404,"error":"Not Found"}) + +gitlink-cli api GET /chroe/gitlink-cli/pulls/3/reviews +# → 返回 HTML 前端页面(非 JSON API 端点) +``` + +**结论**:**行内评论不可用**。两层原因: + +1. `gitlink-cli api POST` 存在已知 URL 注入 bug(git exec-path 被拼入 API URL),所有 `api POST` 返回 404——与 `gitlink-triage` 记录一致。 +2. `api GET /pulls/:id/reviews` 返回 HTML(前端路由),说明该路径不是有效的 JSON API 端点。 + +**设计影响**:行内评论关闭,**仅用 `pr +comment` 发总结评论**(已在 PR #3 实测:评论 id 477757 成功发布,PR 评论数 0→1)。`--inline` 参数被忽略并提示"行内评论不可用,已降级为总结评论"。 + +--- + +## 五、字段映射 + +### pr +view 关键字段 + +| 字段 | 用途 | +|------|------| +| `issue.subject` / `issue.description` | 理解 PR 意图,校准审查重点 | +| `pull_request.base` / `pull_request.head` | 目标/源分支 | +| `author.login` | 作者(自审盲区提示) | +| `files_count` / `commits_count` | 范围概览 | + +### pr +diff / pr +files 关键字段 + +| 字段 | 用途 | +|------|------| +| `files[].name` | 文件路径 | +| `files[].addition` / `deletion` | 增删行数 | +| `files[].sha` | 文件 sha(哨兵可选) | +| diff 正文 | 分析输入 | + +**行号映射规则**:报告卡里的 `file:line` 用**文件中的实际行号**(非 diff hunks 的 `+n` 相对行号)。从 diff hunk 头(`@@ -a,b +c,d @@`)推算:实际行号 = `c + (hunk 内相对行)`。 + +--- + +## 六、幂等哨兵 + +``` + +``` + +- 发布前用 `pr +view`(或取评论)检查是否已含该哨兵 +- `sha` = 审查所基于的 head commit;PR 有新提交(sha 不匹配)时提示"审查已过期,建议重审" +- 默认不覆盖;`--refresh` 才重发 diff --git a/skills/gitlink-review/SKILL.md b/skills/gitlink-review/SKILL.md new file mode 100644 index 0000000..501f513 --- /dev/null +++ b/skills/gitlink-review/SKILL.md @@ -0,0 +1,173 @@ +--- +name: gitlink-review +version: 1.0.0 +description: "智能代码审查:分析 PR diff,多视角评审 + 对抗式自检,输出结构化 Review 意见并作为评论发布。当用户需要审查 GitLink PR、做代码 review、自动生成审查意见时触发。" +metadata: + requires: + bins: ["gitlink-cli"] + cliHelp: "gitlink-cli pr --help" +--- + +# gitlink-review(智能代码审查) + +**CRITICAL — 开始前必须先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),其中包含认证、权限处理和 API 注意事项。** +**CRITICAL — 所有写入操作(发布评论)前默认先预览、确认后再执行;`--auto` 跳过确认但仍受置信度门控。** +**CRITICAL — 绝不自动 approve / merge PR。审查只是评论,不做合并决策。** +**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`(GitHub CLI)操作 GitLink 资源。** + +> **前置条件:** 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md);详细检查清单与字段映射见 [`REFERENCE.md`](REFERENCE.md)。 + +## 概述 + +本 Skill 引导 AI 对指定 GitLink PR 做结构化、多视角、低误报的代码审查,并把"报告卡"作为评论发布。核心特点: + +1. **多视角评审团**:6 个视角并行扫 diff +2. **对抗式自检**:每条候选发现先自我反驳,成立的才留下(直击 AI 审查误报老大难) +3. **降噪**:自动跳过生成代码 / vendor / lock / 纯重命名 +4. **可执行**:每条发现带 `file:line` + 修复建议 + 理由 + +## 命令接口(skill 约定参数,非 gitlink-cli 新增 flag) + +| 参数 | 默认 | 说明 | +|------|------|------| +| `--owner/--repo` | 自动从 cwd 解析 | 目标仓库 | +| `--id` | 必填 | PR 编号(`pull_request_number`,网页 `/pulls/N`) | +| `--lenses` | 全 6 视角 | 子集,如 `correctness,security` | +| `--auto` | 关 | 跳过预览确认直接发布(仍受置信度门控) | +| `--inline` | 关 | 尝试附行内评论(reviews API 可用时) | +| `--max-findings` | 12 | 报告卡上限 | +| `--refresh` | 关 | 即使存在旧审查哨兵也重审并更新 | + +## 管道(8 步) + +### ① 取上下文 + +```bash +gitlink-cli pr +view --owner --repo --id --format json # 元数据 +gitlink-cli pr +files --owner --repo --id --format json # 文件 +/- +gitlink-cli pr +diff --owner --repo --id --format json # 核心:diff 内容 +gitlink-cli repo +info --owner --repo --format json # 语言校准 +``` + +### ② 降噪过滤 + +按下方"降噪规则"跳过噪音文件;在报告卡"范围"行注明跳过数量,不静默吞掉。 + +### ③ 多视角分析 + +对每个启用的视角扫 diff,产出候选发现,每条含: + +```json +{ "lens": "correctness", "severity": "high", "likelihood": "likely", + "file": "auth/login.go", "line": 42, "what": "空指针未判", + "why": "...", "fix": "...", "confidence": "high" } +``` + +> 字段映射:`severity` 取值 high→🔴 / medium→🟡 / low→🔵;`likelihood` 取值 likely/possible/unlikely;`confidence` 取值 high/medium/low。 + +### ④ 对抗式自检(质量门) + +逐条自问(任一成立即丢弃或降级): + +1. 语境里是否已有保护(外层判空、上游校验、框架机制)? +2. 是真缺陷还是风格偏好?偏好 → 降级 🔵 nit 或丢弃。 +3. 引用的 API/签名/语言行为是否真实存在?(不确定则不报) +4. 是否与另一视角重复? + +**置信度门控**:`confidence=low` 且 `severity≠high` → 丢弃。 + +### ⑤ 综合 + +跨视角去重 → 按 `严重度×likelihood` 排序 → 封顶 `--max-findings`。 + +### ⑥ 预览(默认) + +展示报告卡给用户;确认后发布。`--auto` 跳过。 + +### ⑦ 发布 + +```bash +gitlink-cli pr +comment --owner --repo --id \ + --body "<报告卡全文,含哨兵>" +``` + +`--inline` 且 reviews API 可用 → 对 🔴/🟡 发现附行内评论(见 REFERENCE.md 的 API 结论)。 + +### ⑧ 幂等 + +发布前检查该 PR 是否已有哨兵 ``;有则默认提议"更新"(`--refresh` 才覆盖)。哨兵中的 `sha:` 记录审查所基于的 head commit;若 PR 有新提交(sha 不匹配),提示"审查已过期,建议重审"。 + +## 评审团 6 视角 + +| 视角 | 盯什么 | +|------|--------| +| 🔴 正确性 (correctness) | 逻辑错、边界、空值、并发竞态、资源泄漏、错误处理、类型转换 | +| 🔒 安全 (security) | 注入(SQL/命令/XSS)、鉴权越权、密钥/Token 泄露、路径穿越、不安全反序列化、弱加密 | +| ⚡ 性能 (performance) | N+1 查询、无谓拷贝、O(n²)/嵌套循环、热路径分配、缺索引 | +| 🧪 测试 (tests) | 新增/改动代码有无测试、边界用例、断言有效性 | +| 🧹 可维护性 (maintainability) | 命名、重复、圈复杂度、抽象边界、与既有约定一致 | +| 🚨 生产风险 (prod-risk) | "合并后凌晨3点哪会炸"——可观测性/日志、回滚、破坏性变更、配置依赖、降级 | + +> 各视角的展开检查清单见 [`REFERENCE.md`](REFERENCE.md)。 + +## 报告卡格式(作为评论发布) + +```markdown +🤖 **gitlink-review 报告** + +**结论**:<总体:✅LGTM / ⚠️建议修改 / 🛑有阻塞>(A 🔴阻塞 / B 🟡建议 / C 🔵nit) +**范围**: 文件,+/-(跳过 噪音文件)|视角:|自检丢弃: + +| 严重度 | 视角 | 位置 | 问题 | +|:---:|---|---|---| +| 🔴 | correctness | path/file.go:42 | <一句话> | + +### 🔴 阻塞(合并前需处理) +1. **[correctness] path/file.go:42** — + - **为什么**: + - **建议**: + +### 🟡 建议 +… + +### 🔵 nit +… + +### ✅ 未发现问题的方面 +- <视角>:<结论> + +--- + +*由 gitlink-review skill 生成。* +``` + +## 降噪规则(自动跳过) + +生成代码(`*.gen.go`/`*.pb.go`/`*_generated.*`/`*.min.js`/`dist/`/`build/`/`target/`)、第三方(`vendor/`/`third_party/`/`node_modules/`)、锁文件(`go.sum`/`package-lock.json`/`yarn.lock`/`pnpm-lock.yaml`/`Cargo.lock`)、纯重命名/移动、二进制/图片/字体。 + +## 安全护栏 + +- 默认预览确认;`--auto` 跳过但仍受置信度门控 +- **绝不自动 approve / merge** +- 行内评论仅 `--inline` 且 reviews API 可用时发 +- `--max-findings` 封顶防刷屏 +- 评论失败 → 把报告卡原文交用户手动粘贴 +- 审查自己作为作者的 PR 时,提示"自审盲区",建议请他人复核(不强制阻断) + +## 错误处理与降级 + +| 情况 | 处理 | +|------|------| +| 无 diff | 报"无可审查变更",不发评论 | +| PR 不存在/无权限 | 清晰错误,不发评论 | +| reviews API 404 | 跳过行内,总结评论照发 | +| diff 过大 | 抽样 + 标注"部分审查(仅 X/Y 文件)" | +| 评论发布失败 | 输出报告卡原文供手动粘贴 | +| 全部 low 置信 | 报"未发现高置信问题",列待人工确认项 | + +## 最佳实践 + +- **先预览再发布**(默认),降低对外噪音 +- **置信度优先**:宁可少报,不要误报 +- **可执行**:每条发现必须带"建议修复" +- **不越权**:只评论,不合并 diff --git a/skills/gitlink-review/examples/review-workflow.md b/skills/gitlink-review/examples/review-workflow.md new file mode 100644 index 0000000..cad1ee8 --- /dev/null +++ b/skills/gitlink-review/examples/review-workflow.md @@ -0,0 +1,83 @@ +# 示例:对植入缺陷 PR 的智能审查(真实数据) + +> 基于 `chroe/gitlink-cli` 测试 PR #3(`test/review-fixture` 分支)于 2026-06-23 实际执行。 +> 该 PR 故意植入 4 个问题用于验证 gitlink-review skill:空指针、硬编码 Token、缺测试、伪阳性。 + +--- + +## Step 1:取上下文 + +```bash +gitlink-cli pr +view --owner chroe --repo gitlink-cli --id 3 --format json +gitlink-cli pr +files --owner chroe --repo gitlink-cli --id 3 --format json +gitlink-cli pr +diff --owner chroe --repo gitlink-cli --id 3 --format json +``` + +**范围**:1 文件 `review_fixture.go`,+47/-0,head sha `00dee19`,无噪音文件需跳过。 + +## Step 2:6 视角扫描 + 对抗式自检 + +| 候选发现 | 视角 | 自检结果 | +|----------|------|----------| +| `Greet` 中 `u.Name` 解引用可能为 nil 的 `u` | correctness | ✅ 成立(`CurrentUser` 对空 token 返回 nil,无外层判空)→ 保留 🔴 | +| `AdminToken` 硬编码 `glpat-...` | security | ✅ 成立(硬编码凭据)→ 保留 🔴 | +| `Welcome`/`Greet`/`Divide` 等新函数无 `_test.go` | tests | ✅ 成立(本 PR 无测试文件)→ 保留 🟡 | +| `Divide(a,b)` 除零风险 | correctness | ❌ **被反驳**:`DoMath` 已保证调用时 `x≠0`,真实路径除数非 0 → 丢弃 | + +**自检丢弃:1 条(refuted=1)**。 + +## Step 3:发布报告卡(真实输出) + +```bash +gitlink-cli pr +comment --owner chroe --repo gitlink-cli --id 3 \ + --body "<报告卡全文>" +``` + +**真实结果**:`ok: true`,评论 id `477757`,PR 评论数 0→1。 + +报告卡全文(实际发布内容): + +````markdown +🤖 **gitlink-review 报告** + +**结论**:⚠️ 建议修改(2 🔴阻塞 / 1 🟡建议 / 0 🔵nit) +**范围**:1 文件,+47/-0(跳过 0 噪音文件)|视角:6|自检丢弃:1 + +| 严重度 | 视角 | 位置 | 问题 | +|:---:|---|---|---| +| 🔴 | correctness | review_fixture.go:18 | 空指针解引用 | +| 🔴 | security | review_fixture.go:23 | 硬编码 Token | +| 🟡 | tests | review_fixture.go:26 | 新函数无测试 | + +### 🔴 阻塞(合并前需处理) +1. **[correctness] review_fixture.go:18** — `Greet` 中 `u := CurrentUser(token)` 后直接 `u.Name`;`token==""` 时 `CurrentUser` 返回 nil,解引用 panic。 + - **建议**:`if u := CurrentUser(token); u != nil { return "hello " + u.Name }; return ""` +2. **[security] review_fixture.go:23** — `var AdminToken = "glpat-FAKEFAKEFAKE0000000000"` 硬编码凭据。 + - **建议**:改 `os.Getenv("ADMIN_TOKEN")`,移除占位串。 + +### 🟡 建议 +1. **[tests] review_fixture.go:26** — 新函数无 `_test.go`,建议补表驱动测试。 + +### ✅ 未发现问题的方面 +- 性能:无热点循环 / N+1 +- 生产风险:本文件带 `//go:build ignore`,不参与构建 + +### 🗑 对抗式自检丢弃(1) +- ~~[correctness] review_fixture.go:30 `Divide` 除零~~:`DoMath` 调用前已 `if x==0 {return 0}`,真实路径不除零 → 伪阳性丢弃。 + +--- + +```` + +## Step 4:幂等与过期 + +报告卡内嵌哨兵 ``: + +- 重跑(不带 `--refresh`)时检测到哨兵 → 提示"已存在审查,使用 --refresh 更新",不重复发布。 +- `sha` 字段记录审查所基于的 head commit;PR 有新提交(sha 不匹配)时提示"审查已过期,建议重审"。 + +## 关键结论 + +- **3 个真实缺陷被对应视角命中**(correctness / security / tests),**1 个伪阳性被对抗式自检丢弃**(refuted=1)——验证了"质量门"有效降低误报。 +- **行内评论不可用**(`api POST /pulls/:id/reviews` → 404;`api GET` → HTML),自动降级为 `pr +comment` 总结评论,实测发布成功(评论 id 477757)。 +- 报告卡带哨兵,支持幂等与"过期重审"提示。 diff --git a/skills/gitlink-workflow/SKILL.md b/skills/gitlink-workflow/SKILL.md index 6b6b772..00a9dc8 100644 --- a/skills/gitlink-workflow/SKILL.md +++ b/skills/gitlink-workflow/SKILL.md @@ -91,6 +91,7 @@ git branch -d feature/my-feature 1. **创建前检查**:是否有冲突的现有 PR?分支名是否规范? 2. **Code Review**:查看 `pr +files` 的变更,给出审查意见 + > 深度代码审查请使用 [`../gitlink-review/SKILL.md`](../gitlink-review/SKILL.md)(多视角 + 对抗式自检 + 自动评论)。 3. **合并判断**:检查 CI 是否通过(如开启了 DevOps)、是否有冲突 ## 工作流 2:项目初始化向导