| name | commit |
| description | Stage and commit changes using Conventional Commits. Use when there are dirty/staged files to commit, the user says "commit", or before pushing a PR. |
Commit
Create a git commit following this project's Conventional Commits convention. These messages are used by git-cliff (cliff.toml) to auto-generate changelogs and release notes. PRs are squash-merged, so the PR title becomes the commit on main — CI validates it via pr-title.yml.
Available skills and subagents
verify subagent — Run fmt, typecheck, test, and lint. Delegate to this before committing to catch issues early.
Format
type: lowercase description
Allowed Types
| Type | Use for | In changelog? |
|---|
feat | New features | Yes (Features) |
fix | Bug fixes | Yes (Bug Fixes) |
perf | Performance improvements | Yes (Performance) |
refactor | Code refactoring | Yes (Refactoring) |
docs | Documentation changes | Yes (Documentation) |
chore | Maintenance, deps, configs | No |
ci | CI/CD changes | No |
test | Test-only changes | No |
Rules
- Subject must start with a lowercase letter
- Scope is optional:
feat(ui): add dialog is valid
- Include PR/issue number when relevant:
feat: add release notes (#295)
- Breaking changes: add
! after type: feat!: remove legacy API
- Keep the first line under 72 characters
- Body lines must be ≤100 characters (commitlint
body-max-line-length). Hard-wrap bullet points before committing; long URLs or prose lines that exceed 100 chars will fail the hook with body's lines must not be longer than 100 characters. If a HEREDOC body fails, re-wrap and create a new commit — do not amend.
Examples
feat: add release notes dialog
fix: flaky test in orchestrator (#292)
refactor: extract session handler into separate module
chore: update dependencies
ci: add PR title linting workflow
Steps
Create a task for each step below and mark them as completed as you go.
-
Understand changes: Run git status and git diff to understand all changes. Review recent commits with git log --oneline -10 to match project style.
-
Ensure pre-commit hooks are wired up. This must work in worktrees too, where .git/ is a file (not a directory) and the real hooks path is shared with the main repo via core.hooksPath. Use git rev-parse --git-path so the check resolves correctly regardless:
pre-commit --version >/dev/null 2>&1 && echo "INSTALLED" || echo "NOT_INSTALLED"
HOOK_PATH=$(git rev-parse --git-path hooks/pre-commit)
test -f "$HOOK_PATH" && grep -q "pre-commit" "$HOOK_PATH" && echo "ACTIVE" || echo "INACTIVE"
Why this matters: a missing hook lets lint regressions slip past local commits and only surface in CI (e.g. funlen / cognitive complexity on backend Go code). The hook catches them in <1s at commit time. See Makefile's doctor target for the idempotent install command.
-
Run verify (MANDATORY — do NOT skip): Run /verify to complete the full verification pipeline (rebase, format, typecheck, test, lint). Depending on runtime policy, /verify may delegate to the verify subagent or use its documented direct-command fallback. Wait for it to complete before proceeding. Do NOT proceed to step 4 until verify passes. If verify cannot fix the failures, stop and surface the errors to the user — do not commit. Do NOT substitute this with a partial check (e.g. running only the changed package's tests).
-
Stage files: Stage relevant files (prefer specific files over git add -A).
- Splitting commits with new files: When introducing a brand-new file alongside the file that uses it, stage them together. The Go lint pre-commit hook stashes unstaged changes before linting but keeps untracked files in the working tree — so a new helper committed alone, while its (still-unstaged) caller sits in the working tree, lints as
unused and rejects the commit.
-
Commit: Write a commit message following the format above. If changes span multiple concerns, consider separate commits.