ECC 验证闭环实战指南:从构建到 PR 的六阶段质量门禁与 Agent 自动化
【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
本文围绕 ECC(Everything Claude Code)仓库中的
verification-loop技能展开,系统讲解如何用一套六阶段验证流程(构建、类型、Lint、测试、安全、Diff)为 Claude Code / Codex / Opencode 等 Agent 会话把关。读者将掌握:何时触发验证、六阶段各自的可执行命令与判定标准、标准化的验证报告格式、长会话下的连续验证模式,以及 verification-loop 技能与/verify命令、PostToolUse 质量门禁 hooks 之间的分工协作关系。
一、什么是 Verification Loop:Agent 会话的“完工质检”
verification-loop是 ECC 仓库内置的一门技能(Skill),定位为“Claude Code 会话的完整验证系统”(a comprehensive verification system for Claude Code sessions)。它的英文规范源文件位于 skills/verification-loop/SKILL.md,本仓库同时维护了西班牙语译本 docs/es/skills/verification-loop/SKILL.md 等多个语言版本,便于不同语言环境的 Agent 直接加载使用。
与常规“写完代码就交差”的工作方式不同,Verification Loop 强调在声明“任务完成”之前,先跑完一套可重复、有输出、有结论的质量验证流程。它不是让 Agent 凭感觉自查,而是用确定性命令(构建、类型检查、Lint、测试、安全扫描、Diff 审查)逐项给出 PASS/FAIL 结论,最终产出一份结构化的验证报告,作为“是否可以创建 PR”的决策依据。
在 ECC 的文档体系中,该技能与/verify命令、quality-gatehook 构成了三层递进的验证能力,后续章节会逐一展开。
二、何时触发验证:四个关键时机
技能文档明确给出了调用时机,Agent 应在以下节点主动触发验证:
- 完成一个功能或重大代码变更之后(After completing a feature or significant code change)
- 创建 PR 之前(Before creating a PR)
- 希望确保质量门禁(quality gates)全部通过时(When you want to ensure quality gates pass)
- 重构之后(After refactoring)
其中“创建 PR 之前”是最核心的场景——验证报告的最终输出就是判断“是否 READY for PR”。
在 ECC 的legacy-command-shims/commands/verify.md中也可以看到,/verify斜杠命令被定义为 verification-loop 技能的兼容性入口(legacy shim),文档明确写着“优先直接使用 skill,此文件仅作为兼容入口保留”,并委托该技能“按当前仓库情况以正确顺序运行构建、类型、Lint、测试、安全/日志检查与 Diff 审查”。
三、六阶段验证流程详解
验证按固定顺序执行六个阶段,任何一阶段失败都应当停下来修复,而不是带着已知问题继续往下跑。下面结合仓库实际给出每个阶段的命令、判定标准与注意事项。
阶段 1:构建验证(Build Verification)
构建是验证的起点,只有项目能成功编译,后续检查才有意义。技能文档给出的标准命令:
# 检查项目能否编译 npm run build 2>&1 | tail -20 # 或者使用 pnpm pnpm build 2>&1 | tail -20判定标准:构建失败,立即停止(STOP),修复后再继续。tail -20用于截取构建输出的末尾 20 行——错误堆栈通常在末尾,可以避免超长输出淹没关键信息。
补充说明:并非所有项目都有build脚本。本仓库package.json中定义的build:opencode(执行node scripts/build-opencode.js)和prepack即属于构建类命令,而仓库的常规校验更多依赖lint与test脚本。验证时应以当前项目的实际脚本为准,若package.json中没有build脚本,应如实报告“该项目无构建脚本”而不是虚构一次构建。
阶段 2:类型检查(Type Check)
set -o pipefail # TypeScript 项目 npx --no-install tsc --noEmit 2>&1 | head -30 # Python 项目 pyright . 2>&1 | head -30要点解读:
set -o pipefail确保管道中任一命令失败都会传递为非零退出码,避免head提前截断管道而掩盖tsc的真实失败;--no-install防止npx在缺少依赖时自动下载安装(保持环境确定性);--noEmit只做类型检查、不产出编译产物,是 CI 环境的推荐用法;head -30限制只查看前 30 行错误,防止错误刷屏。
判定标准:报告所有类型错误(含文件:行号),修复关键错误后再继续。本仓库自身即为 TypeScript/JavaScript + Python 混编项目(src/llm/下为 Python,脚本目录为 JS/TS),类型检查阶段可分别覆盖两种语言。
阶段 3:Lint 检查(Lint Check)
# JavaScript / TypeScript npm run lint 2>&1 | head -30 # Python ruff check . 2>&1 | head -30本仓库package.json中实际定义的 lint 脚本为:
"lint": "eslint . && markdownlint '**/*.md' --ignore node_modules"也就是说,ECC 自身同时用 ESLint 检查 JS/TS 代码、用 markdownlint 检查全部 Markdown 文档(排除 node_modules)。这也印证了技能文档中“验证命令要贴合当前仓库实际脚本”的原则——同样的npm run lint,在不同仓库里背后可能是完全不同的工具链。
阶段 4:测试套件(Test Suite)
# 带覆盖率运行测试 npm run test -- --coverage 2>&1 | tail -50 # 检查覆盖率阈值 # 目标:最低 80%必须报告四项指标:测试总数、通过数、失败数、覆盖率百分比。
技能文档把覆盖率目标定在80% 最低阈值。有趣的是,ECC 仓库自己在package.json的coverage脚本中就是按这一标准实践的:
"coverage": "c8 --all --include=\"scripts/**/*.js\" --include=\"scripts/**/*.mjs\" --check-coverage --lines 80 --functions 80 --branches 79 --statements 80 --reporter=text --reporter=lcov node tests/run-all.js"可以看到--lines 80 --functions 80 --statements 80(分支略低为 79)——80% 行/函数/语句覆盖率正是仓库自身的质量红线,与技能文档的目标完全一致。测试入口为tests/run-all.js,它聚合了tests/目录下全部 JS 测试(tests/ci/、tests/hooks/、tests/lib/、tests/scripts/等子目录),并串联了仓库自带的scripts/ci/校验脚本(validate-agents.js、validate-commands.js、validate-rules.js、validate-skills.js、validate-hooks.js、validate-install-manifests.js、validate-no-personal-paths.js等)以及catalog:check、command-registry:check。
阶段 5:安全扫描(Security Scan)
安全阶段关注两类问题:密钥泄露和调试残留日志。
# 检查密钥(secrets) grep -rn "sk-" --include="*.ts" --include="*.js" . 2>/dev/null | head -10 grep -rn "api_key" --include="*.ts" --include="*.js" . 2>/dev/null | head -10 # 检查 console.log 残留 grep -rn "console.log" --include="*.ts" --include="*.tsx" src/ 2>/dev/null | head -10技巧说明:
2>/dev/null屏蔽“目录不可读/文件不存在”等噪音报错,只保留真实匹配;head -10限制输出条数,防止大量误报淹没结论;- 正则模式
sk-(OpenAI 风格密钥前缀)与api_key覆盖了最常见的密钥形态,实际使用时可替换为AKIA(AWS)、ghp_(GitHub PAT)、-----BEGIN(私钥)等目标模式。
密钥模式出现在源码中应当立即修复并考虑轮换;console.log需要区分是业务日志还是调试残留——残留日志在提交前应删除或替换为项目统一的日志方案。
阶段 6:Diff 审查(Diff Review)
# 显示变更概况 git diff --stat # 显示自上次提交以来修改了哪些文件 git diff HEAD~1 --name-only审查每个变更文件时,技能文档要求重点检查三点:
- 非预期变更(Unintended changes)——例如无关文件的格式化改动、意外删除的配置、不该提交的生成物;
- 缺失的错误处理(Missing error handling)——新增代码路径是否处理了失败分支;
- 潜在边界情况(Potential edge cases)——空值、并发、超时、超大输入等场景。
Diff 审查是唯一无法用命令“自动化判定”的阶段,它依赖 Agent 对变更意图与代码语义的理解,因此被放在最后,作为所有机械检查通过后的“人工”把关层。
四、标准化输出:验证报告格式
技能文档要求,跑完六个阶段后必须产出一份固定结构的验证报告。这一格式是刻意设计的:固定字段 + 明确结论,方便人类开发者快速扫读,也方便上层 Agent 或自动化流程解析结论。
VERIFICATION REPORT ================== Build: [PASS/FAIL] Types: [PASS/FAIL] (X errors) Lint: [PASS/FAIL] (X warnings) Tests: [PASS/FAIL] (X/Y passed, Z% coverage) Security: [PASS/FAIL] (X issues) Diff: [X files changed] Overall: [READY/NOT READY] for PR Issues to Fix: 1. ... 2. ...在 ECC 的命令体系中,/verify命令(中文译本见 docs/zh-CN/commands/verify.md)使用几乎相同的报告骨架,只是字段名略有差异(如“密钥检查”“日志”),并额外要求“如果存在任何关键问题,列出它们并提供修复建议”。这份报告的价值在于:它把一次 Agent 会话的“完工质量”压缩成了可传递、可留档、可追踪的结构化证据。
五、连续验证模式:长会话的 Checkpoint 节奏
对于持续数小时甚至跨天的长会话,一次性验证不足以保证质量。技能文档提出Continuous Mode:每 15 分钟或每次重大变更后运行一次验证,并设置“心智检查点(mental checkpoint)”:
- 完成每个函数之后(After completing each function)
- 完成一个组件之后(After finishing a component)
- 进入下一个任务之前(Before moving to next task)
在每个检查点执行/verify(即触发 verification-loop 技能)。这样做的目的,是把“大爆炸式”的提交前验证拆解为小步快跑的增量验证——问题在产生它的上下文里就被发现和修复,而不是攒到最后统一面对一堆跨模块的失败。
这一思路与 ECC 的PreToolUse/PostToolUsehooks 体系是互补的:hooks 在每个工具调用发生前后立即拦截问题(即时反馈),而 verification-loop 提供的是阶段性的全面复查(系统性结论)。技能文档最后一节对此有专门说明,详见下文。
六、与 Hooks 的集成:即时拦截 vs 全面复查
技能文档明确给出了与 hooks 的分工:
该技能是对 PostToolUse hooks 的补充,提供更深入的验证。Hooks 在问题发生时立即捕获;本技能提供全面复查。
在 ECC 仓库中,hooks/hooks.json注册了完整的 Claude Code hooks 体系(PreToolUse / PostToolUse 等),其中包括:
pre:bash:dispatcher——Bash 命令执行前的统一预检分发器,涵盖 quality、tmux、push 与 GateGuard 检查;pre:config-protection——阻止修改 linter/formatter 配置文件,引导 Agent“修复代码而非放宽配置”,这正是验证闭环的重要制度保障;pre:write:doc-file-warning、pre:observe:continuous-learning等其他护栏。
与此配套的是commands/quality-gate.md描述的格式质量门禁:它通常作为post:quality-gatePostToolUse hook 运行(实现为scripts/hooks/quality-gate.js),按文件类型执行格式化校验——.ts/.tsx/.js/.jsx/.json/.md用 Biomecheck或 Prettier--check,.go用gofmt,.py用ruff format。该文档特别注明:
Lint 与类型检查不属于该门禁的范畴,应使用
verification-loop技能或各语言的验证技能来完成 lint/type/test 管线。
这段注释把职责边界划得很清楚:quality-gate hook 管“单文件格式”,verification-loop 管“全量 lint/type/test 管线”。两者可以这样组合使用:
# 1. 单文件格式门禁(hook 式手动触发) echo '{"tool_input":{"file_path":"src/example.ts"}}' \ | ECC_QUALITY_GATE_FIX=true node scripts/hooks/quality-gate.js # 2. 全量六阶段验证(verification-loop 技能 / /verify 命令)其中ECC_QUALITY_GATE_FIX=true表示“应用格式化修复而非仅检查”,ECC_QUALITY_GATE_STRICT=true表示“将格式化失败视为门禁失败”,需要严格模式时可组合使用。
七、验证深度选择:/verify的四种模式
/verify命令支持通过$ARGUMENTS控制验证深度(见 docs/zh-CN/commands/verify.md),这在时间敏感的场景下很有用:
| 模式 | 检查范围 | 适用场景 |
|---|---|---|
quick | 仅构建 + 类型检查 | 快速迭代、确认无编译错误 |
full | 所有检查(默认) | 常规完工验证 |
pre-commit | 与提交相关的检查 | 提交前把关 |
pre-pr | 完整检查 + 安全扫描 | PR 前的最终把关 |
值得注意的是,验证深度虽然可以按需裁剪,但顺序不可打乱:构建失败必须先修、类型错误必须先清,这是legacy-command-shims/commands/verify.md中“以正确顺序运行”这一要求背后的工程理性——错误的验证顺序(例如在构建失败后继续跑测试)只会产生大量无效噪音。
八、实战要点速查
- 命令贴合仓库:六阶段的命令是“模板”,落到具体仓库时以
package.json的 scripts、语言生态的工具链为准(如 ECC 自身的 lint 是 ESLint + markdownlint,覆盖率红线是行/函数/语句 80%)。 - 失败即停:构建失败不继续、类型错误不清不进入测试阶段,避免噪音累积。
- 报告必须完整:六个字段的 PASS/FAIL、测试统计、覆盖率、Diff 文件数、总体结论、待修复问题列表,缺一不可。
- 与 hooks 协同:PostToolUse/PreToolUse hooks 做即时拦截,verification-loop 做全面复查,
quality-gate管单文件格式、本技能管全量管线,各司其职。 - 长会话用 Continuous Mode:15 分钟或重大变更后触发一次
/verify,以函数/组件/任务切换为心智检查点。
相关资源
- 技能英文规范源:skills/verification-loop/SKILL.md
- 技能西班牙语译本(本文关联文档):docs/es/skills/verification-loop/SKILL.md
/verify命令说明:docs/zh-CN/commands/verify.md/verify兼容入口说明:legacy-command-shims/commands/verify.md- 格式质量门禁与 verification-loop 的分工:commands/quality-gate.md
- Hooks 注册与触发配置:hooks/hooks.json
- 仓库实际 lint / test / coverage 脚本定义:package.json
- 测试聚合入口:tests/run-all.js
【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考