关于 verify-before-commit
verify-before-commit 是一项 Agent 技能,在实现后通过检查和冒烟测试为提交设关。成功提交后,它可将匹配的草稿纳入 wiki,并关闭关联任务的生命周期。
主要功能
- 01运行类型检查、lint 和测试
- 02执行可用的回归与任务关卡
- 03检查应用的黄金路径
- 04提交信息说明更改原因
- 05归档草稿并更新任务状态
适用场景
- 01提交前验证代码更改
- 02在必需检查失败时阻止提交
- 03在 wiki 中记录已完成工作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rheinmir/ setup --skill verify-before-commit安装后在 Claude Code 中输入/verify-before-commit确认已加载。
详细介绍
技能:verify-before-commit
WHAT
目的和上下文
- 目的: 对每次提交进行门禁检查——提交前运行类型检查、lint、测试和 smoke;提交后将草稿提升到 wiki,并关闭任务生命周期。
- 触发条件(何时使用): 完成任何实现任务后、执行
git commit前。 - 非目标: 不编写新功能;不因“改动很小”而跳过任何步骤;除
code-logger.py已声明的命令外,不自行更改任务状态机。
心智模型
diff → typecheck → lint → test → qc-regression → task_lifecycle gate → smoke → commit (why) → promote draft (+ ## Origin) → log + index → task state=done。
输入和输出约定
| 字段 | 必填? | 含义 | |
|---|---|---|---|
| 输入 | 已实现的代码更改 | 是 | 门禁检查对象 |
| 输入 | llmwiki/wiki/sources/draft/ 中与功能匹配的草稿 | 否 | 若没有(hotfix/refactor),则在日志中记录 "no draft — " |
| 输入 | 草稿 frontmatter 中的 task: T-… | 否 | 若没有 → 跳过步骤 8(开放失败) |
| 输出 | 提交 | 是 | 提交信息说明 原因,而非 内容 |
| 输出 | 已提升且包含 ## Origin 的 wiki 页面 | 有草稿时必填 | concepts/ 或 sources/ |
| 输出 | llmwiki/wiki/log.md + index.md | 是 | 更新 |
规则和能力
- RULE-01(MUST):所有步骤均为必需。无例外。
- RULE-02(MUST):提交后步骤为必需,绝不跳过。
- 能力:运行仓库的 typecheck/lint/test/smoke(根据清单自动检测);如有 validator harness,则运行该 harness;记录 git commit、wiki 和任务生命周期日志。
失败边界
- Typecheck/lint/test 未通过 → 阻塞:修复后重新运行,不得提交。
qc-regression.py --run未通过 → 阻塞(已修复的 bug 再次出现或尚未修复);没有qc-*测试 → 开放失败,不阻塞。task_lifecycle.py阻止操作(task-ID 不符合状态机要求)→ 阻塞;文件不存在(旧版本安装)→ 跳过。- 没有草稿 → 不执行提升,在日志中记录原因(狭义成功)。没有
task:ID → 跳过步骤 8,不视为错误。
HOW
主工作流
| 步骤 | 类型 | 输入 | 操作 | 输出/退出 | 失败/后续 |
|---|---|---|---|---|---|
| W01 | 确定性 | repo | 类型检查(从 repo 检测命令) | rc 0 | 出错 → 修复,重复 |
| W02 | 确定性 | repo | Lint | rc 0,记录警告 | 出错 → 修复,重复 |
| W03 | 确定性 | repo | 测试 + qc-code 回归测试(3b,如果有测试框架) | rc 0 | 失败 → 修复,重复 |
| W04 | 确定性 | draft/task | Trụ 3 gate task_lifecycle.py(如果有测试框架) | rc 0 | 阻止 → blocked |
| W05 | 判断 | app | 端到端 Smoke check golden path | golden path 运行 | 出错 → 修复 |
| W06 | 效果 | diff | 提交,提交信息写明 why | commit hash | — |
| W07 | 效果 | draft | 提升 draft + ## Origin + 日志 + 索引 | wiki 页面 | 没有 draft → B01 |
| W08 | 效果 | task: id | 通过 code-logger.py 结束 task 生命周期(尽力而为) | state=done | 没有 id → B02 |
各步骤详情(W01–W08 的权威来源;W01–W03 = 步骤 1–3b,W04 = 4,W05 = 5,W06 = 6 提交前,W07 = 6–7 提交后,W08 = 8):
提交前:
RUN: <type-check-cmd>— 从 repo 检测:npx tsc --noEmit(package.json)/go build ./...(go.mod)。修复所有错误。RUN: <lint-cmd>— 检测:npx eslint src//go vet ./...。修复错误;记录警告。RUN: <test-cmd>— 检测:npm test/go test ./...。修复失败项。 3b. qc-code 回归测试(如果有测试框架):RUN: [ -f harness/scripts/qc-regression.py ] && python3 harness/scripts/qc-regression.py --run— 运行由/qc-code生成的qc-*测试(复现已发现的 bug)。红色 = 一个已修复的 bug 再次出现,或尚未修复。完全确定性,0-token,不调用 LLM。如果还没有任何qc-*测试(项目尚未使用 qc-code),则失败时放行 — 不阻止。- Trụ 3 gate(如果有测试框架):
RUN: [ -f harness/validators/task_lifecycle.py ] && python3 harness/validators/task_lifecycle.py --root .— 如果 task-ID 违反状态机(回退/跳跃/绕过 gate),或 draft 指向陌生 task,则硬性阻止。没有该文件(旧版安装)→ 跳过。这是下文第 8 步尽力而为机制的硬性版本。 - Smoke check:验证端到端 golden path。
- 提交,提交信息写明 why,而不是 what。
提交后 — 必须执行,绝不跳过:
6. 在 llmwiki/wiki/sources/draft/ 中查找与功能匹配的 draft。
- 提升到
llmwiki/wiki/concepts/或llmwiki/wiki/sources/(永久保存)。 - 添加
## Origin部分:Draft: <path>/Commit: <hash> — <msg>/Date: YYYY-MM-DD CHECK: grep -l "## Origin" <promoted-file>— 必须返回文件。
RUN: echo "promoted" >> llmwiki/wiki/log.md— 然后妥善编辑日志;更新llmwiki/wiki/index.md。- Trụ 3 — 结束生命周期(尽力而为,失败时放行): draft 的 frontmatter 中有
task: T-…→python3 harness/scripts/code-logger.py --task set <T-id> state=done note="<commit-hash>"。命令失败时放行(缺少--task/id → 跳过,不阻止提交)。确认:--task show <T-id>输出 lifecycle proposed→approved→dispatched→done;--audit验证各 transition 位于不可变链中。
没有 draft(hotfix/refactor)?在 log.md 中记录 "no draft — ",跳过步骤 6。 没有
task:id(旧版安装 / propose 跳过 mint)?跳过步骤 8 — 失败时放行,不算错误。
所有步骤均为必需。没有例外。
分支
| ID | 类型 | 守卫条件 | 行为 | 跳过/失败 | 重新汇合 |
|---|---|---|---|---|---|
| B01 | 条件必需 | 没有 draft(hotfix/refactor) | 在 log.md 中记录 "no draft — ",跳过提交后步骤 6 | — | W08 |
| B02 | 条件必需 | draft 没有 task: id(旧版安装 / propose 跳过 mint) | 跳过步骤 8 — 失败时放行 | — | 结束 |
| B03 | 能力可选 | 有 harness/(qc-regression、task_lifecycle、code-logger) | 运行 3b、4、8 | 缺少文件 → 跳过,失败时放行 | 下一步 |
验证与停止
完全确定性:typecheck/lint/test/qc-regression/task_lifecycle 的 rc;CHECK: grep -l "## Origin" <promoted-file> 必须返回文件;--task show <T-id> + --audit 确认 lifecycle。需要 review:Smoke golden path。所有提交前和提交后步骤完成后停止;提交前出现红色则不要提交。
示例
- **正向:**代码仓库有
package.json→npx tsc --noEmit、npx eslint src/、npm test均通过,qc-regression.py --run通过 → 提交“原因” → 将草稿DDMMYY-login-otp.md提升到wiki/concepts/,并添加## Origin→code-logger.py --task set T-12 state=done note="<hash>"。 - 边界/失败:
go test ./...有 1 个测试失败 → 在 W03 停止,修复后重新运行,暂不提交。热修复没有草稿 → 记录“无草稿 — 热修复拼写错误”,跳过提升。
交付 — 输出报告
完成所有主要技能任务后,向 wiki 写入一份提案草稿。
步骤
1. 构建文件名:
- 格式:
DDMMYY-<ten>.md DDMMYY= 今天的日期(例如,2026 年 6 月 2 日对应020626)<ten>= 用于概括已完成事项的 2–4 个 kebab-case 单词(例如,landing-page-coteccons、brand-kit-fintech、ingest-auth-spec)
2. 编写 llmwiki/wiki/sources/draft/DDMMYY-<ten>.md:
---
type: draft
title: "DDMMYY-<ten>"
status: proposed
tags: [<skill-name>, output-report]
timestamp: YYYY-MM-DD
---
# DDMMYY-<ten>
**Type:** draft
**Status:** proposed
**Tags:** <skill-name>, output-report
**Proposed:** YYYY-MM-DD
## What
<One sentence — what this skill invocation produced or decided>
## Output
<Key artefacts, files created/modified, or decisions made>
## Files
| File | Action |
|------|--------|
| `path/to/file` | created / modified |
## Notes
- Invoked via: `/<skill-name>` skill
## Origin
- **Draft:** `wiki/sources/draft/DDMMYY-<ten>.md`
- **Commit:** _(filled by verify-before-commit)_
- **Date promoted:** _(filled by verify-before-commit)_
3. 更新 wiki 索引和日志:
llmwiki/wiki/index.md— 追加一行:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |llmwiki/wiki/log.md— 追加:## YYYY-MM-DD — <skill-name> — <ten>
仅当该技能没有产出任何制品且没有做出任何决策时才跳过(例如,像
/caveman-stats这样的纯显示模式)。