| name | commit |
| description | Split and organize AI code changes into well-structured commits following this project's conventions. Use this skill whenever committing changes โ whether one file or many. Trigger when the user asks to commit, save, submit, or stage changes, or when dirty files need committing after a task. Also use when multiple files were edited and need logical grouping into separate commits, or when the user asks about commit conventions for this project. |
One big commit is a black box โ you can't bisect, can't cherry-pick, and can't tell "which change broke what." Split commits give you:
git bisect works โ each commit is either good or bad, no mixed states
git revert is safe โ revert one logical change without pulling out others
- Reviewable history โ humans and AI can audit what happened, in order
- Rollback confidence โ if a refactor broke something, revert just the refactor
Design principles
-
Split granularity โ group by logical change unit
A logical change unit is a set of file edits that together accomplish one coherent purpose. We do this instead of per-file splitting because this project's files are tightly coupled (server โ web โ cli form one product). Per-file would create meaningless fragments; per-TDD-stage is overkill.
-
Who decides grouping โ AI drafts plan, human confirms
The AI inspects dirty state and proposes a commit plan, but the human has final say. This balances automation speed with human oversight over their own git history.
-
Commit message format โ Conventional Commits, match existing history
Our history already uses feat(server):, feat(web):, feat(cli):, fix(...), ci(...), chore:, docs:. Staying consistent makes git log readable and predictable.
-
Verification gate โ lint + test must pass before each commit
We have cargo fmt + cargo clippy + cargo test (server) and pnpm lint + pnpm test (web/cli) in CI. Running them before commit catches issues early and saves CI round-trips.
-
Push policy โ never auto-push
Pushing is an irreversible outward-facing action. The user always decides when to push.
Rules
1. Group by logical change, not by file
A "logical change unit" is a set of file edits that together accomplish one coherent purpose. Examples:
| Logical change | Files | Rationale |
|---|
| Add multi-select support | server/src/ + web/src/ + SKILL.md | Feature spans backend, frontend, and docs โ one commit |
| Fix a CSS padding bug | web/src/styles/ only | Isolated fix โ one commit |
| Update CI to add Node 22 | ci.yml only | CI change โ one commit |
| Bump version + update CHANGELOG | package.json + CHANGELOG.md | Release housekeeping โ always together |
2. Ordering: infrastructure โ feature โ fix โ docs โ chore
When multiple commits are needed, follow this order:
1. chore / ci โ build system, dependencies, tooling
2. feat โ new features
3. fix โ bug fixes
4. refactor โ code reorganization
5. docs โ README, CHANGELOG, comments
6. test โ test additions/changes
7. chore(release) โ version bump, changelog update (always last)
Rationale: infrastructure changes first (they're prerequisites), features and fixes in the middle (the actual work), docs and release housekeeping last (they describe what happened).
3. Commit message format
<type>(<scope>): <description>
Types: feat, fix, refactor, docs, test, chore, ci, perf
Scopes: server (Rust backend), web (React frontend), cli (Node.js CLI), github (CI/release), or omit scope for root-level changes.
Rules:
- Lowercase description, no trailing period
- Match the language of the change (Chinese files โ Chinese message, English โ English)
- Imperative mood: "add" not "added", "fix" not "fixed"
Examples from our history:
feat(web): add round indicator and auto-recommended select
fix(server): avoid session collisions across different instances
ci(github): add changelog check and set latest release flag
chore: release v0.2.0-rc.1
4. Verification gate โ lint & test before commit
Before every commit, run relevant checks:
cd server && cargo fmt --check && cargo clippy -- -D warnings && cargo test && cd ..
cd cli && pnpm install --frozen-lockfile && pnpm lint && pnpm test && cd ..
cd web && pnpm install --frozen-lockfile && pnpm lint && pnpm test && cd ..
If anything fails โ fix first, then commit. Never commit failing code.
5. The commit plan protocol
When multiple files are dirty, the AI must:
- Inspect dirty state:
git status --porcelain
- Learn existing style:
git log --oneline -5
- Classify files:
- AI-edited this session โ files the AI wrote/edited
- Unrecognized โ files the AI didn't touch (user edits, other tools)
- Draft a commit plan grouping AI-edited files into logical commits
- Present the plan once for human confirmation:
Proposed commits (in order):
1. feat(server): add multi-select question support
- server/src/handlers/rounds.rs
- server/src/models/mod.rs
2. feat(web): add multi-select UI control
- web/src/components/MultiControl.tsx
- web/src/pages/QuestionsPage.tsx
3. docs: update README with multi-select example
- README.md
- README_zh.md
Unrecognized dirty files (NOT in any commit):
- .gitignore
Reply 'ok' / '่ก' to execute. Reply with edits, or 'ๆ่ชๅทฑๆฅ' / 'manual' to abort.
- On confirmation: execute
git add + git commit for each batch in order. No --amend. No push.
- On rejection: stop. Do not propose a second plan. Let the user commit manually.
6. Special cases
| Case | Rule |
|---|
| Only one file changed | Skip the plan protocol โ commit directly with a descriptive message |
| Release commit | Version bump in package.json + CHANGELOG entry = always one commit, type chore: release vX.Y.Z |
| Generated/trivial changes (lint auto-fix, .gitignore) | Bundle with the commit that caused them, or a single chore commit if standalone |
| Mixed language edits (e.g., README.md + README_zh.md) | Keep in one commit if they describe the same change |
| Scope-only change (SKILL.md prompt wording) | One commit with scope server or cli |
7. What NOT to do
- โ One giant commit for everything โ defeats the purpose
- โ Per-file commits when files are logically coupled (server handler + web component = one feature)
- โ Commit with failing tests โ always verify first
- โ
git commit --amend โ never rewrite history
- โ
git push without explicit user request
- โ Include unrecognized dirty files silently โ always list them separately
- โ Placeholder commit messages like "wip" or "update files"
Quick reference
1. git status --porcelain โ what changed?
2. git log --oneline -5 โ what style?
3. Group by logical change โ plan commits
4. Present plan โ human confirms โ one shot
5. cargo/pnpm checks โ verify BEFORE each commit
6. git add + git commit โ execute in order
7. Never push, never amend