---
name: verify
description: 改完代码要验证时用。先从 CI 配置和构建脚本摸清这个项目把什么当作「过了」，再按静态检查、测试、真跑一遍的顺序执行。别把「编译过了」当成「验证过了」。
---

# 验证一次改动

「编译过了」「测试绿了」「真的工作」是三件事。每层拦的问题不一样，
只做第一层等于没验证——值得担心的 bug 基本都是「编译通过、类型正确、
看起来合理」的那种。

## 0. 先摸清这个项目的防线是什么

不要凭直觉猜命令，按顺序找：

1. **CI 配置**（`.github/workflows/`、`.gitlab-ci.yml` 之类）——CI 跑
   什么，本地就跑什么。CI 是这个仓库对「验证过了」的正式定义，本地跑的
   和 CI 不一致，本地全绿也不算数。
2. **构建脚本**：`package.json` 的 scripts、`Makefile`、`justfile`、
   `Cargo.toml`、`pyproject.toml`。`[约束]` 优先用仓库自己包好的入口
   （`npm run test` 而不是自己拼测试框架的参数）——包装里经常藏着必要
   的环境变量和 flag，绕开它跑出来的结果不可比。
3. **AGENTS.md / CONTRIBUTING.md** 里写明的验证要求。

## 1. 静态检查（最快，先跑）

typecheck、lint、fmt --check。秒级出结果，排最前面是为了 fail fast——
类型都不对就不用花几分钟等测试了。

## 2. 测试

- 大仓库先跑**和改动相关的子集**（按文件或模块过滤），过了再考虑要不要
  全量。上来就全量，反馈周期动辄十几分钟。
- `[约束]` 测试红了先分清：是这次改动弄红的，还是本来就红？
  `git stash` 后重跑一次是最快的判法。本来就红的说出来就行，不要顺手
  修——那是另一件事，混进来 diff 就说不清了。
- 没有测试的项目：说明这个事实，然后把第 3 层做扎实。

## 3. 真跑一遍

测试全绿但功能不工作，真实存在——测试只测断言写到的地方。改了什么就
以什么方式碰一下：

- CLI：真执行一次改到的命令路径；
- 服务 / API：起 dev server，对改动的端点发一次真实请求；
- 页面 / UI：有浏览器工具就打开看一眼，截图确认；
- 库函数：写个几行的临时脚本调一下，用完删掉。

跑不了的（要生产凭证、要特定硬件）就说跑不了和为什么，不要含糊地说
「应该没问题」。

## 报告

- 跑了哪几层、每层的结果；跳过的层说明为什么跳；
- 失败先说**哪一层**报的——lint 报的是规范问题，测试报的是行为问题，
  修法完全不同；
- 不要把没跑过的说成过了。「没跑，因为 X」是合格的报告，
  「应该没问题」不是。
