Files
ai-proj-helper/skills-req/req-test-gate-plugin/skills/SKILL.md
John Qiu da57cccf96 chore(marketplace): update req-retro karpathy-score dimension, req-test-gate gate-0b docs
- req-retro: 新增 karpathy_score × 0.20 维度,QS 公式扩展为 5 维
- req-test-gate: Gate 0B 新增 check-surgical.sh Ratchet 文档

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:55:13 +09:30

22 KiB
Raw Blame History

name, description, arguments
name description arguments
req-test-gate 测试与质量门禁制度。覆盖需求级测试(Gates 1-5)、部署级验证(Deploy Gates)、持续回归(Regression)、Harness Engineering 工程约束方法论Ratchet、约定建立、门禁层级。当用户提到质量门禁、架构约束、约定检查、ratchet、harness 相关任务时自动激活。 <subcommand> [args]

测试与质量门禁制度 (req-test-gate) v2.1

概述

三层质量门禁架构,确保从需求到上线每个阶段都有结构化验证。

三层架构

需求级 (Gates 1-5)     → /req test 触发,单需求维度
部署级 (Deploy Gates)   → /req deploy 触发,批量部署维度
持续维度 (Regression)    → 定时/部署后触发,系统级回归

需求级门禁 (Gates 1-5)

触发时机/req test 执行、/req next 从 testing 推进

Gate 0: Scope 分级(自动,决定后续 Gate 裁剪)
    ↓
Gate 1: 前置条件检查(自动)
    ↓
Gate 2: 测试执行验证2A→2B→2C→2D→2E→2F按 scope 裁剪)
    ↓
Gate 3: 测试质量验证(子代理,按 scope 决定是否触发)
    ↓
Gate 4: 文档持久化(自动,按 scope 选模板)
    ↓
Gate 5: 回归贡献检查(按 scope 区分贡献形式)
    ↓
通过 → 允许 /req next 推进到待部署池

Gate 0: Scope 分级 + 约定检查(自动)

两件事:① 从 git diff 推断变更范围;② 运行项目内所有约定检查脚本。

0A: Scope 分级

git diff main...HEAD --name-only | classify_scope
scope 判断依据 Gate 裁剪效果
backend .go 文件变更 2A(go) + 2B 必须2C/2F 跳过
frontend .tsx/.ts 变更(含业务逻辑) 2A(tsc/build) 必须2B 跳过
style-only .css/.less 或 shared/ 变更 2A(build) + 2F(视觉验证) 必须2B/2C 跳过
fullstack 前后端都有改动 2A + 2B + 2C 全部必须

frontend vs style-only 区分.tsx/.ts 文件中是否包含 API 调用(import.*apifetchrequest)。仅样式/布局改动归为 style-only。

scope 影响全部后续 Gate,在测试报告中必须标注。

0B: 约定检查Harness 自动执行)

自动发现并运行项目内所有 scripts/check-*.sh 脚本。

# 自动执行逻辑
for script in scripts/check-*.sh; do
  [ -x "$script" ] && bash "$script" --ci
done
结果 处理
全部 PASS Gate 0 通过,继续 Gate 1
有 FAIL 阻塞,按下方「失败处理」修复后重新 /req test
无 scripts/check-*.sh 跳过(项目未建立约定检查)

失败处理(区分脚本类型):

脚本类型 判断方法 修复方式
Hard wall纯检测 脚本无 baseline 文件 修改代码消除违规
Ratchet基线对比 脚本有 .*-baseline.json 修改代码降低违规数,确认是故意增加 → ./scripts/check-{name}.sh baseline 更新基线 + AskUserQuestion 确认

更新基线是有意识的决策(如重构导致临时增加),不能静默执行。

报告格式

### 约定检查 (Gate 0B)
| 脚本 | 类型 | 结果 | 详情 |
|------|------|------|------|
| check-architecture.sh | Ratchet | ✅ PASS | 5 rules, all within baseline |
| check-modal-safety.sh | Hard wall | ✅ PASS | 0 violations |
| check-surgical.sh | Ratchet | ✅ PASS | 0 format-only violations (baseline=0) |

本项目已建立的约定检查脚本

脚本 类型 检测内容 来源
check-architecture.sh Ratchet Handler 直接引用 database/ 层 分层架构规范
check-modal-safety.sh Hard wall Modal.success 后立即操作 UI REQ-20260416
check-surgical.sh Ratchet PR diff 中疑似仅注释/格式变更的文件 Karpathy SurgicalREQ-20260421-0003

check-surgical.sh 使用 Ratchet 模式:.surgical-baseline.json 记录基线,违规数只能降不能升。 首次无基线时仅告警,不阻塞。运行 ./scripts/check-surgical.sh baseline 建立基线。

这样 Harness 建立的约定脚本会在每次 /req test 时自动运行,无需手动执行 /harness report


Gate 1: 前置条件检查

自动检查,不可跳过。

检查项 检查方式 阻塞级别
CR 已通过 delivery_stage >= review 或有 completed 的 code_review 任务 阻塞
开发任务全部完成 所有 linkRole=implementation 的任务状态为 completed 阻塞
CR 文档存在code 类型) has_task_document 对 code_review 任务 警告

未通过处理

  • 阻塞项 → 直接拒绝,提示「请先完成 {缺失项}」
  • 警告项 → AskUserQuestion 确认是否继续

Gate 2: 测试执行验证

按需求类型执行分层测试,从静态到动态逐步验证。

类型推断

get_requirement_tasks 的 linkRole 集合推断:

  • code: 有 implementation 任务 → 代码需求
  • skill: 无 implementation,有 prd/test → Skill/文档需求
  • ops: 仅 deploy 任务 → 运维需求

code 类型:五阶段验证

2A: 静态验证(编译+类型检查)

按 scope 裁剪执行项:

序号 测试项 命令 scope 触发条件 通过条件
T1 后端编译 go build ./... backend / fullstack exit 0
T2 后端单元测试 go test ./... backend / fullstack 全部 PASS
T4 前端类型检查 tsc --noEmit frontend / fullstack exit 0
T4b 前端构建 vite build 所有前端 scope 构建成功
T5 前端测试 npm test 相关组件 frontend / fullstack PASS
T7 iOS 编译 xcodebuild build 有 iOS 改动时 exit 0

style-only scope:仅执行 T4b构建验证跳过 T1/T2/T4/T5。

2B: API 端点验证(后端独立)

序号 测试项 命令 必须 通过条件
T3 API 端点验证 curl localhost:8080 调用新/改 API 必须 预期状态码和数据
T3.1 DB 约束验证 curl 测试 FK/唯一约束 推荐 错误码正确400/404
T3.2 错误处理验证 无效输入/缺失参数 推荐 错误响应格式正确
T3.3 并发/原子性 2 个并发请求竞争边界量(如库存恰好=N发 2 个各 N 件的请求) 涉及库存/积分/财务时必须 恰好 1 个成功,另一个返回"不足"DB 无超卖
T3.4 租户隔离 用 tenant B token 操作 tenant A 的资源 ID 多租户系统必须 返回 403/无权DB 未被篡改
T3.5 状态流转完整性 触发所有 change_type/状态流转后查流水表 有状态机实体时必须 所有预期流水类型都出现过

触发判断(以下任一为真则 T3.3T3.5 必须执行):

  • 需求涉及库存/积分/余额/限购
  • 需求有多租户资源隔离要求
  • 需求引入了新的状态机status 枚举 ≥ 3 个)

2C: 前后端联调(开发环境)

触发条件scope 为 fullstack,或前端 .tsx/.ts 文件包含 API 调用(import.*apifetchrequest 不触发scope 为 backendstyle-only,或前端改动不涉及 API 调用

环境要求:本地开发环境,前端 :3000 + 后端 :8080 同时运行

无后端替代方案IT6 页面可访问性验证可用 Playwright API Mock 模式(page.route())替代真实后端。详见 dev-test 技能的 e2e-testing.md §API Mock 冒烟测试。

前置步骤

  1. 确认本地数据库已执行相关 migration菜单、表结构等
  2. 启动后端 cd backend && go run main.go
  3. 启动前端 cd frontend && npm start
  4. 获取 JWT TokenPOST /api/v1/auth/login
序号 测试项 方法 必须 通过条件
IT1 前端代理连通 curl localhost:3000/api/v1/health 必须 200前端代理到后端成功
IT2 菜单可见性 curl localhost:3000/api/v1/menus/user-menus 必须 新菜单出现在响应中
IT3 API 代理验证 curl localhost:3000/api/v1/<新端点> 必须 通过前端代理调用后端 API 返回预期数据
IT4 路由配置 检查 App.tsx 有 <Route path="..." /> 必须 路由存在且 lazy import 正确
IT5 图标映射 检查 Layout.tsx iconMap 有对应图标 条件 有新菜单图标时必须验证
IT6 页面可访问 浏览器访问 localhost:3000/<新路径> 推荐 页面加载无白屏、无 console 报错

无前端改动时:标记 ⏭️ 跳过: 无前端改动

常见联调问题及排查

问题 根因 解决方案
菜单不显示 本地 DB 未执行 menu migration 执行 migration SQL + 修复 sequence
API 返回 404 前端代理路径不匹配 检查 setupProxy.jspackage.json proxy 配置
页面白屏 React 组件 import 错误或 TS 类型不匹配 检查 console 错误,修复 import 路径
登录失败 本地用户密码不匹配 重新生成 bcrypt cost 12 哈希并更新本地 DB
Redis 缓存脏数据 菜单/权限缓存未清理 redis-cli KEYS "menu:user:*" 后逐个 DEL

2D: 冒烟测试Staging 环境)

触发条件:已部署到 staging

序号 测试项 命令 必须 通过条件
SM1 API 健康检查 curl staging/api/v1/health 必须 200
SM2 核心流程验证 curl 新功能关键 API 必须 预期响应
SM3 数据一致性 创建→读取→验证 推荐 数据完整返回

未部署到 staging 时:标记 ⏭️ 跳过: 未部署到 staging

2E: 原型符合性测试

触发条件:有关联原型 HTMLprototype-*.html

序号 测试项 方法 必须 通过条件
PC1 结构完整性 对比原型 Section 数 vs 实现区块 必须 所有 Section 有对应实现
PC2 数据模型对齐 对比原型字段 vs API 返回字段 必须 字段名/类型匹配
PC3 交互流程覆盖 对比原型操作 vs 实现事件绑定 推荐 所有交互有绑定
PC4 状态覆盖 对比原型状态标签 vs 实现枚举 推荐 状态集一致

无原型时:标记 ⏭️ 跳过: 无关联原型

原型冻结规则:原型在评审通过后冻结,设计变更需创建新需求。

2F: 视觉/响应式验证v2.1 新增)

触发条件scope 为 style-onlyfrontend(有 CSS/LESS 变更时) 不触发scope 为 backend

序号 测试项 方法 必须 通过条件
VR1 断点一致性 grep -rn "max-width|min-width" --include="*.css" --include="*.less" 对比 breakpoints 定义 必须 所有新增 media query 使用标准断点值
VR2 构建无警告 vite build 输出检查 必须 无 CSS 相关 warning
VR3 !important 审计 grep -c "!important" 统计新增数量 推荐 新增 !important ≤ 3 个,或有合理理由
VR4 文件完整性 新增组件/样式文件全部存在 必须 所有 import 的文件可解析
VR5 移动端适配 检查关键页面在 ≤768px 下的 CSS 规则覆盖 推荐 有对应的移动端样式

无 CSS 变更时:标记 ⏭️ 跳过: 无样式改动

skill 类型 Checklist

序号 测试项 方法 必须
S1 关键词一致性 grep 核心概念跨文件对齐 必须
S2 规则无歧义 审查每条规则触发条件和动作 必须
S3 边界情况 至少 1 个边界场景验证 必须
S4 交叉引用 文件间引用指向正确 推荐
S5 Token 大小 wc -w < 7500 词 推荐

ops 类型 Checklist

序号 测试项 方法 必须
O1 命令可执行 dry-run 或 staging 执行 必须
O2 健康检查 curl 健康端点 必须
O3 回滚方案 文档审查 推荐

UAT 场景设计(复杂业务需求适用)

当需求涉及以下任一情况时,在 2B 之后额外执行 UAT 场景矩阵:

  • 完整业务流程(下单→支付→发货→退款)
  • 并发控制(乐观锁/悲观锁/原子 SQL
  • 多角色协作(消费者 + 管理员 + 供应商)

执行方式:参照 uat-patterns.md 的 5 类场景框架逐一设计用例,用 ai-proj 创建 stage="testing" 的子任务跟踪进度。

执行记录格式

| T1 | 后端编译 | `go build ./...` | ✅ PASS | exit 0, 0 errors |
| IT1 | 前端代理连通 | `curl localhost:3000/api/v1/health` | ✅ PASS | 200 |
| IT2 | 菜单可见性 | user-menus API | ✅ PASS | 持续管理+2子菜单 |
| SM1 | 健康检查 | `curl staging/health` | ✅ PASS | 200 |
| PC1 | 结构完整性 | 原型 11 sections vs 实现 | ⏭️ 跳过 | 无关联原型 |

Gate 3: 测试质量验证(子代理)

派遣 test-validator 子代理审查。模板: ~/.claude/skills/req-test-gate/test-validator.md

触发规则(按 scope 裁剪)

  • code + backend / fullstack总是触发
  • code + frontend(含业务逻辑):触发
  • code + style-only不触发CR 已覆盖样式审查)
  • skill 类型:≥5 测试项时触发
  • ops 类型:不触发
Task({
  subagent_type: "superpowers:code-reviewer",
  prompt: `使用 test-validator 模板审查测试质量。
    模板路径: ~/.claude/skills/req-test-gate/test-validator.md
    填充参数:
    - REQUIREMENT_TITLE: "{需求标题}"
    - REQUIREMENT_TYPE: "{code|skill|ops}"
    - TEST_RESULTS: "{Gate 2 的执行记录表格}"
    - CODE_CHANGES_SUMMARY: "{改动文件列表和摘要}"
    - CHECKLIST_USED: "{使用的 checklist 类型}"
  `
})
评估结果 处理
"测试充分" Gate 3 通过
"需补充测试"(Important) AskUserQuestion 确认
"测试不足"(Critical) 阻塞,必须补充后重新验证

Gate 4: 文档持久化

不可跳过。 create-and-attach 写入测试任务文档。按 scope 选择模板。

轻量模板scope = style-only / frontend 无 API

## 测试报告 - {需求标题}

| 字段 | 值 |
|------|-----|
| 需求 | REQ-XXXX |
| scope | {style-only/frontend} |
| 门禁版本 | test-gate v2.1 |

### 构建验证
| 项目 | 命令 | 结果 |
|------|------|------|
| TypeScript | tsc --noEmit | ✅/❌/⏭️ |
| Vite Build | vite build | ✅/❌ |

### 视觉验证 (2F)
| 序号 | 测试项 | 结果 | 备注 |
|------|--------|------|------|
| VR1 | 断点一致性 | ✅/❌ | ... |
| VR2 | 构建无警告 | ✅/❌ | ... |
| VR4 | 文件完整性 | ✅/❌ | ... |

### 总结
通过: {N}/{M} | 结论: ✅ 通过 / ❌ 未通过

完整模板scope = backend / fullstack

## 测试报告 - {需求标题}

| 字段 | 值 |
|------|-----|
| 需求 | REQ-XXXX |
| 类型 | {code/skill/ops} |
| 时间 | {YYYY-MM-DD HH:MM} |
| 门禁版本 | test-gate v2 |

### 前置条件 (Gate 1)
- CR 状态: ✅ 已通过
- 开发任务: ✅ 全部完成 ({N}/{N})

### 测试执行 (Gate 2)
| 序号 | 阶段 | 测试项 | 命令/方法 | 结果 | 备注 |
|------|------|--------|----------|------|------|
| T1 | 2A | 后端编译 | ... | ✅/❌/⏭️ | ... |
| IT1 | 2C | 前端代理连通 | ... | ✅/❌/⏭️ | ... |
| SM1 | 2D | 健康检查 | ... | ✅/❌/⏭️ | ... |
| PC1 | 2E | 结构完整性 | ... | ✅/❌/⏭️ | ... |

### 跳过的测试
⏭️ {测试项}: {原因}
(无则写「无」)

### 质量验证 (Gate 3)
{子代理结果摘要或「未触发ops 类型)」}

### 回归贡献 (Gate 5)
{贡献的回归用例数,或「无需贡献」或「⏭️ 跳过: 过渡期」}

### 总结
通过: {N}/{M} | 跳过: {K} | 结论: ✅ 通过 / ❌ 未通过

文档质量门禁(被 /req next 检查)

  • 含测试项表格(| 分隔符 ≥ 3 行)
  • 含通过/失败结论(✅ 通过❌ 未通过
  • 总字符数 ≥ 200
  • 门禁版本标记(test-gate v2test-gate v2.1

Gate 5: 回归贡献检查

确保 code 类型需求为回归池贡献测试用例。按 scope 区分贡献形式。

触发条件code 类型需求

检查项 说明 阻塞级别
有 regression linkRole 任务 get_requirement_tasks(linkRole=regression) 警告
任务有文档附件 has_task_document 警告
文档包含可执行用例 curl 命令或测试脚本 建议

过渡期规则v2.1警告但不阻塞AskUserQuestion 提醒补充。

Scope 贡献形式

scope 贡献形式 示例
backend curl 脚本API 回归) curl -X POST .../api → 201
frontend E2E 场景描述Playwright API Mock 页面加载 + 核心交互验证。编写模式见 dev-test 技能 e2e-testing.md
style-only 视觉回归 checklist 断点覆盖 + !important 审计
fullstack curl 脚本 + E2E 场景 两者都需要

回归用例模板backend / fullstack

## 回归用例 - REQ-XXXX {需求标题}

### 模块
{okr / task / auth / ...}

### 用例列表
| ID | 场景 | 命令 | 预期结果 | 优先级 |
|----|------|------|----------|--------|
| RC1 | ... | `curl ...` | 200 + ... | 高 |

回归用例模板frontend / style-only

## 回归用例 - REQ-XXXX {需求标题}

### 模块
{product / order / layout / ...}

### 视觉/交互用例
| ID | 场景 | 验证方法 | 预期结果 | 优先级 |
|----|------|---------|----------|--------|
| VRC1 | 移动端列表布局 | 浏览器 375px 宽度截图 | 卡片正常排列 | 高 |
| VRC2 | 响应式断点切换 | 768px→769px 切换 | 布局无跳变 | 中 |

详见 regression.md 了解完整回归系统设计。

部署级门禁 (Deploy Gates)

触发时机/req deploy 执行

详见 deploy-gates.md

概要流程:

DG1: 迁移检查(不可跳过) → 有未执行 migration?
DG2: Staging 部署 → 构建+部署到 singapore
DG3: 冒烟测试 → 核心 API 可用
DG4: 影响域回归 → module-deps 决定范围
DG5: 性能基线(推荐) → 关键 API 响应时间
DG6: 生产部署(不可跳过) → 健康检查+文档

回归测试模块

系统级持续活动,独立于单需求生命周期。

详见 regression.md

核心概念:

  • 回归池:所有需求贡献的测试用例汇集处
  • 回归判定:上次 PASS + 本次 FAIL = 回归(高优先级,自动创建 bug 需求)
  • 闭环:回归失败 → 创建 bug 需求 → 修复 → 回归池更新
  • 三种执行模式:影响域(部署触发)、关键路径(每日)、全量(每周)

Force 跳过规则

门禁 可否 Force 说明
Gate 1 前置条件 不可 必须满足
Gate 2 测试执行 单项可跳过 需记录原因
Gate 3 质量验证 Critical 不可Important 可 AskUserQuestion 后跳过
Gate 4 文档持久化 不可 必须生成文档
Gate 5 回归贡献 可(过渡期) 警告级别
Deploy Gates DG1/DG6 不可,其余可 迁移和健康检查不可跳过

与现有流程集成

/req test 增强

v1:   Gate 1 → Gate 2 → Gate 3 → Gate 4
v2:   Gate 1 → Gate 2(2A→2B→2C→2D→2E) → Gate 3 → Gate 4 → Gate 5
v2.1: Gate 0(scope) → Gate 1 → Gate 2(2A→2B→2C→2D→2E→2F) → Gate 3 → Gate 4 → Gate 5
v3:   Gate 0A(scope) + 0B(约定检查) → Gate 1 → Gate 2(按scope裁剪) → Gate 3 → Gate 4 → Gate 5

/req next testing→staging 门禁

验证测试文档Gate 1-5 全部通过的完整报告 + 门禁版本 test-gate v2

/req deploy 部署门禁

在 req-deploy 流程前增加 Deploy Gates (DG1-DG6) 检查。


Harness Engineering — 工程约束方法论

项目级基础设施的建立和维护方法论,与上述需求级门禁互补。

详见 harness-engineering.md 完整文档。

核心理念

建立自动化护栏防止新违规,同时允许渐进式清理遗留问题。

三大支柱:

  1. Ratchet — 遗留违规数只能减不能增 → ratchet-pattern.md
  2. 约定建立 — 每个 bug 修复后立即建立约定和检测 → convention-flow.md
  3. 门禁层级 — 按项目成熟度逐级引入 → project-bootstrap.md

/harness 命令集(手动可用 + 自动嵌入)

命令 手动 自动触发
/harness assess 随时 首次 /req dev
/harness init [level] 随时
/harness convention [name] 随时 /req cr + bug 类型需求
/harness report 随时 /req test Gate 0B

模板

templates/ 目录提供可复用的脚本模板:

与需求级门禁的关系

Harness项目级护栏             req-test-gate需求级门禁
├── .husky/ pre-commit           ├── Gate 0A: scope 分级
├── CI lint workflow             ├── Gate 0B: 运行 harness 的 check-*.sh ←─ 连接点
├── scripts/check-*.sh           ├── Gate 1: 前置条件
├── CLAUDE.md 约定               ├── Gate 2: 测试执行
│                                ├── Gate 3: 质量验证
│                                ├── Gate 4: 文档持久化
│                                └── Gate 5: 回归贡献

Harness 不使用 Gate 编号。它的产出物check-*.sh 脚本)通过 Gate 0B 接入 req-test-gate 流程。