About verify-before-commit
verify-before-commit is an agent skill that gates commits after implementation by running checks and a smoke test. After a successful commit, it can promote a matching draft into the wiki and close the associated task lifecycle.
Key features
- 01Runs typecheck, lint, and tests
- 02Runs available regression and task gates
- 03Checks the application's golden path
- 04Commits with a rationale-focused message
- 05Promotes drafts and updates task state
Use cases
- 01Validating changes before a commit
- 02Preventing commits when required checks fail
- 03Recording completed work in the wiki
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ rheinmir/ setup --skill verify-before-commitAfter installing, type/verify-before-commitin Claude Code to confirm it loaded.
Details
From the project READMESkill: verify-before-commit
WHAT
Purpose và context
- Purpose: gate every commit — typecheck, lint, test, smoke trước commit; sau commit promote draft lên wiki và đóng vòng đời task.
- Trigger (when to use): After any impl task, before
git commit. - Non-goals: không viết tính năng mới, không bỏ qua bước nào vì "thay đổi nhỏ", không tự đổi state-machine task ngoài lệnh
code-logger.pyđã khai.
Mental model
diff → typecheck → lint → test → qc-regression → task_lifecycle gate → smoke → commit (why) → promote draft (+ ## Origin) → log + index → task state=done.
Input và output contract
| Field | Required? | Ý nghĩa | |
|---|---|---|---|
| In | thay đổi code đã impl | có | đối tượng gate |
| In | draft khớp feature trong llmwiki/wiki/sources/draft/ | không | không có (hotfix/refactor) → ghi "no draft — " vào log |
| In | task: T-… trong frontmatter draft | không | không có → skip step 8 (fail-open) |
| Out | commit | có | message nói why, không what |
| Out | trang wiki đã promote có ## Origin | khi có draft | concepts/ hoặc sources/ |
| Out | llmwiki/wiki/log.md + index.md | có | cập nhật |
Rules và capabilities
- RULE-01 (MUST): All steps mandatory. No exceptions.
- RULE-02 (MUST): Post-commit — mandatory, never skip.
- Capabilities: chạy typecheck/lint/test/smoke của repo (tự dò theo manifest); chạy validator harness nếu có; ghi git commit + wiki + log vòng đời task.
Failure boundaries
- Typecheck/lint/test đỏ → blocked: fix rồi chạy lại, không commit.
qc-regression.py --runđỏ → blocked (bug đã fix tái phát hoặc chưa fix); chưa có testqc-*→ fail-open, không chặn.task_lifecycle.pychặn (task-ID sai state-machine) → blocked; không có file (install cũ) → bỏ qua.- Không có draft → không promote, ghi lý do vào log (succeeded hẹp). Không có
task:id → skip step 8, không phải lỗi.
HOW
Main workflow
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W01 | deterministic | repo | Type-check (dò lệnh theo repo) | rc 0 | lỗi → fix, lặp |
| W02 | deterministic | repo | Lint | rc 0, ghi chú warning | lỗi → fix, lặp |
| W03 | deterministic | repo | Test + test tái hiện qc-code (3b, nếu có harness) | rc 0 | fail → fix, lặp |
| W04 | deterministic | draft/task | Trụ 3 gate task_lifecycle.py (nếu có harness) | rc 0 | chặn → blocked |
| W05 | judgment | app | Smoke check golden path end-to-end | golden path chạy | hỏng → fix |
| W06 | effect | diff | Commit, message why | commit hash | — |
| W07 | effect | draft | Promote draft + ## Origin + log + index | trang wiki | không draft → B01 |
| W08 | effect | task: id | Đóng vòng đời task qua code-logger.py (best-effort) | state=done | không id → B02 |
Chi tiết từng bước (nguồn chân lý cho W01–W08; W01–W03 = bước 1–3b, W04 = 4, W05 = 5, W06 = 6 pre-commit, W07 = 6–7 post-commit, W08 = 8):
Pre-commit:
RUN: <type-check-cmd>— detect from repo:npx tsc --noEmit(package.json) /go build ./...(go.mod). Fix all errors.RUN: <lint-cmd>— detect:npx eslint src//go vet ./.... Fix errors; note warnings.RUN: <test-cmd>— detect:npm test/go test ./.... Fix failures. 3b. Test tái hiện qc-code (nếu có harness):RUN: [ -f harness/scripts/qc-regression.py ] && python3 harness/scripts/qc-regression.py --run— chạy các testqc-*do/qc-codesinh (tái hiện bug đã tìm). ĐỎ = một bug đã fix nay tái phát, hoặc chưa fix. Tất định, 0-token, KHÔNG gọi LLM. Fail-open nếu chưa có testqc-*nào (dự án chưa dùng qc-code) — không chặn.- Trụ 3 gate (nếu có harness):
RUN: [ -f harness/validators/task_lifecycle.py ] && python3 harness/validators/task_lifecycle.py --root .— chặn cứng nếu task-ID đi sai state-machine (lùi/nhảy/né gate) hoặc draft trỏ task lạ. Không có file (install cũ) → bỏ qua. Đây là bản CỨNG của step 8 best-effort bên dưới. - Smoke check: verify golden path end-to-end.
- Commit with message: why, not what.
Post-commit — mandatory, never skip:
6. Find draft in llmwiki/wiki/sources/draft/ matching feature.
- Promote to
llmwiki/wiki/concepts/orllmwiki/wiki/sources/(permanent). - Add
## Originsection:Draft: <path>/Commit: <hash> — <msg>/Date: YYYY-MM-DD CHECK: grep -l "## Origin" <promoted-file>— must return file.
RUN: echo "promoted" >> llmwiki/wiki/log.md— then edit log properly; updatellmwiki/wiki/index.md.- Trụ 3 — đóng vòng đời (best-effort, fail-open): draft có frontmatter
task: T-…→python3 harness/scripts/code-logger.py --task set <T-id> state=done note="<commit-hash>". Lệnh fail-open (thiếu--task/id → bỏ qua, không chặn commit). Xác nhận:--task show <T-id>in lifecycle proposed→approved→dispatched→done;--auditxác minh các transition nằm trong chuỗi bất biến.
No draft (hotfix/refactor)? Note "no draft — " in log.md, skip step 6. No
task:id (install cũ / propose bỏ qua mint)? Skip step 8 — fail-open, không phải lỗi.
All steps mandatory. No exceptions.
Branches
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | conditional_required | không có draft (hotfix/refactor) | ghi "no draft — " vào log.md, skip step 6 post-commit | — | W08 |
| B02 | conditional_required | draft không có task: id (install cũ / propose bỏ qua mint) | skip step 8 — fail-open | — | kết thúc |
| B03 | capability_optional | có harness/ (qc-regression, task_lifecycle, code-logger) | chạy 3b, 4, 8 | thiếu file → bỏ qua, fail-open | bước kế |
Validation và stopping
Tất định: rc của typecheck/lint/test/qc-regression/task_lifecycle; CHECK: grep -l "## Origin" <promoted-file> phải trả file; --task show <T-id> + --audit xác nhận lifecycle. Cần review: smoke golden path. Dừng khi mọi bước pre + post xong; đỏ ở pre-commit thì không commit.
Examples
- Positive: repo có
package.json→npx tsc --noEmit,npx eslint src/,npm testxanh,qc-regression.py --runxanh → commit "why" → promote draftDDMMYY-login-otp.mdvàowiki/concepts/có## Origin→code-logger.py --task set T-12 state=done note="<hash>". - Boundary/failure:
go test ./...fail 1 test → dừng ở W03, fix rồi chạy lại, chưa commit. Hotfix không có draft → log "no draft — hotfix typo", skip promote.
Delivery — Output Report
After all main skill tasks complete, write a propose draft to the wiki.
Steps
1. Build the filename:
- Format:
DDMMYY-<ten>.md DDMMYY= today (e.g.,020626for 2 June 2026)<ten>= 2–4 kebab-case words summarising what was done (e.g.,landing-page-coteccons,brand-kit-fintech,ingest-auth-spec)
2. Write 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. Update wiki index & log:
llmwiki/wiki/index.md— append one row:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |llmwiki/wiki/log.md— append:## YYYY-MM-DD — <skill-name> — <ten>
Skip only when the skill produces zero artefacts and zero decisions (e.g., a pure display mode like
/caveman-stats).