From 737643322fade3e53e4eb399bc087aed71dbb9c4 Mon Sep 17 00:00:00 2001 From: Johan Broberg Date: Thu, 22 Jan 2026 15:22:05 -0800 Subject: [PATCH 1/3] Add commit skill for quality-gated commits Adds a Claude Code skill that enforces code quality before committing: - Checks formatting with ruff format - Runs linting with ruff check - Executes unit tests - Auto-generates commit messages Co-Authored-By: Claude --- .claude/skills/commit/SKILL.md | 151 +++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 .claude/skills/commit/SKILL.md diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md new file mode 100644 index 00000000..f06e594b --- /dev/null +++ b/.claude/skills/commit/SKILL.md @@ -0,0 +1,151 @@ +--- +name: commit +description: Use this skill when the user wants to commit staged changes. This skill checks formatting, runs linting, executes tests, generates a commit message, and commits the changes. Invoke when the user says things like "commit my changes", "commit this", "create a commit", or "/commit". +allowed-tools: Bash, Read, Grep, Glob, Edit +--- + +# Commit Skill + +You are a commit assistant that ensures code quality before committing changes. Follow these steps in order, stopping if any step fails. + +## Step 1: Check for Staged Changes + +First, verify there are staged changes to commit: + +```bash +git diff --cached --stat +``` + +If there are no staged changes, inform the user and stop. Suggest they stage changes with `git add`. + +## Step 2: Check Code Formatting + +Run the formatting check on the repository: + +```bash +uv run --frozen ruff format --check . +``` + +### If formatting check fails: + +1. Inform the user that formatting issues were found +2. Ask if they want you to auto-fix the formatting issues +3. If yes, run: `uv run --frozen ruff format .` +4. Show the user what files were reformatted +5. Stage the formatting fixes: `git add -u` (only previously tracked files that were modified) +6. Continue to the next step + +### If formatting check passes: +Continue to the next step. + +## Step 3: Check Linting + +Run the linting check: + +```bash +uv run --frozen ruff check . +``` + +### If linting check fails: + +1. Inform the user about the linting errors +2. Ask if they want you to auto-fix what can be auto-fixed +3. If yes, run: `uv run --frozen ruff check . --fix` +4. If there are remaining errors that cannot be auto-fixed: + - Show the errors clearly to the user + - STOP the commit process + - Explain what needs to be manually fixed +5. If all errors were auto-fixed: + - Stage the fixes: `git add -u` + - Continue to the next step + +### If linting check passes: +Continue to the next step. + +## Step 4: Run Tests + +Run the unit tests (excluding integration tests): + +```bash +uv run --frozen pytest tests/ -v --tb=short -m "not integration" 2>&1 +``` + +### If tests fail: + +1. STOP the commit process immediately +2. Show the test failures clearly to the user +3. Point out: + - Which test file(s) failed + - The specific test function(s) that failed + - The error message and traceback +4. Suggest what might need to be fixed +5. Do NOT proceed with the commit + +### If tests pass: +Continue to the next step. + +## Step 5: Generate Commit Message + +Analyze the staged changes to generate an appropriate commit message: + +1. Run `git diff --cached` to see the actual code changes +2. Run `git diff --cached --stat` to see which files changed +3. Check recent commit history for style: `git log --oneline -10` + +Generate a commit message following these guidelines: + +- **First line**: Concise summary (50 chars or less if possible, max 72) + - Use imperative mood ("Add feature" not "Added feature") + - Capitalize the first letter + - No period at the end +- **Body** (if needed): Explain the "why" not the "what" + - Wrap at 72 characters + - Separate from subject with a blank line +- **Footer**: Always include the co-author line + +Types of changes to identify: +- `Add` - New feature or file +- `Fix` - Bug fix +- `Update` - Enhancement to existing feature +- `Refactor` - Code restructuring without behavior change +- `Remove` - Deleting code or features +- `Docs` - Documentation only +- `Test` - Adding or updating tests +- `Chore` - Maintenance tasks + +## Step 6: Confirm and Commit + +1. Show the user the proposed commit message +2. Ask if they want to proceed with this message or modify it +3. If they want to modify, let them provide changes +4. Create the commit using a HEREDOC for proper formatting: + +```bash +git commit -m "$(cat <<'EOF' + + + + +Co-Authored-By: Claude +EOF +)" +``` + +5. After committing, run `git status` to confirm success +6. Show the user the commit hash and summary + +## Important Notes + +- NEVER skip any of the quality checks (format, lint, test) +- NEVER use `--no-verify` or similar flags to bypass hooks +- NEVER commit if tests are failing +- ALWAYS include the Co-Authored-By footer +- If the user wants to commit despite failures, politely decline and explain why quality gates matter +- If tests are slow, inform the user they're running but don't skip them + +## Error Recovery + +If any step fails unexpectedly (not due to code quality issues): +1. Show the error to the user +2. Suggest potential fixes +3. Do not attempt to work around the error by skipping checks From a0d8f1190de4da3aa218351fdebc3a4e563326e8 Mon Sep 17 00:00:00 2001 From: Johan Broberg Date: Thu, 22 Jan 2026 15:28:17 -0800 Subject: [PATCH 2/3] Update .claude/skills/commit/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .claude/skills/commit/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md index f06e594b..67d040ee 100644 --- a/.claude/skills/commit/SKILL.md +++ b/.claude/skills/commit/SKILL.md @@ -32,7 +32,7 @@ uv run --frozen ruff format --check . 2. Ask if they want you to auto-fix the formatting issues 3. If yes, run: `uv run --frozen ruff format .` 4. Show the user what files were reformatted -5. Stage the formatting fixes: `git add -u` (only previously tracked files that were modified) +5. Stage the formatting fixes by running `git add` only on the files that were reformatted (do not use `git add -u`) 6. Continue to the next step ### If formatting check passes: From 34b6fcfb19eb9993e25b22a55d6ea85e6368f00b Mon Sep 17 00:00:00 2001 From: Johan Broberg Date: Thu, 22 Jan 2026 15:36:49 -0800 Subject: [PATCH 3/3] Update commit skill to match CI check order Reorders quality checks to run linting before formatting, matching the CI pipeline order in .github/workflows/ci.yml. Adds a re-verify step after auto-fixes to prevent commits that pass locally but fail CI when lint fixes introduce formatting issues. Co-Authored-By: Claude --- .claude/skills/commit/SKILL.md | 59 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/.claude/skills/commit/SKILL.md b/.claude/skills/commit/SKILL.md index 67d040ee..d1e7c2f2 100644 --- a/.claude/skills/commit/SKILL.md +++ b/.claude/skills/commit/SKILL.md @@ -1,6 +1,6 @@ --- name: commit -description: Use this skill when the user wants to commit staged changes. This skill checks formatting, runs linting, executes tests, generates a commit message, and commits the changes. Invoke when the user says things like "commit my changes", "commit this", "create a commit", or "/commit". +description: Use this skill when the user wants to commit staged changes. This skill checks linting, then formatting (matching CI order), runs tests, generates a commit message, and commits the changes. Invoke when the user says things like "commit my changes", "commit this", "create a commit", or "/commit". allowed-tools: Bash, Read, Grep, Glob, Edit --- @@ -18,9 +18,33 @@ git diff --cached --stat If there are no staged changes, inform the user and stop. Suggest they stage changes with `git add`. -## Step 2: Check Code Formatting +## Step 2: Check Linting -Run the formatting check on the repository: +Run the linting check first (matches CI order in .github/workflows/ci.yml): + +```bash +uv run --frozen ruff check . +``` + +### If linting check fails: + +1. Inform the user about the linting errors +2. Ask if they want you to auto-fix what can be auto-fixed +3. If yes, run: `uv run --frozen ruff check . --fix` +4. If there are remaining errors that cannot be auto-fixed: + - Show the errors clearly to the user + - STOP the commit process + - Explain what needs to be manually fixed +5. If all errors were auto-fixed: + - Stage the fixes by running `git add` only on the files that were fixed + - Continue to the next step + +### If linting check passes: +Continue to the next step. + +## Step 3: Check Code Formatting + +Run the formatting check (after linting, matches CI order): ```bash uv run --frozen ruff format --check . @@ -32,37 +56,26 @@ uv run --frozen ruff format --check . 2. Ask if they want you to auto-fix the formatting issues 3. If yes, run: `uv run --frozen ruff format .` 4. Show the user what files were reformatted -5. Stage the formatting fixes by running `git add` only on the files that were reformatted (do not use `git add -u`) +5. Stage the formatting fixes by running `git add` only on the files that were reformatted 6. Continue to the next step ### If formatting check passes: Continue to the next step. -## Step 3: Check Linting +## Step 4: Re-verify After Auto-fixes -Run the linting check: +**IMPORTANT**: If any auto-fixes were applied in Steps 2 or 3, re-run both checks to ensure consistency: ```bash uv run --frozen ruff check . +uv run --frozen ruff format --check . ``` -### If linting check fails: +This prevents commits that pass locally but fail CI (e.g., lint fixes that introduce formatting issues). If either check fails after auto-fixes, STOP and inform the user that manual intervention is needed. -1. Inform the user about the linting errors -2. Ask if they want you to auto-fix what can be auto-fixed -3. If yes, run: `uv run --frozen ruff check . --fix` -4. If there are remaining errors that cannot be auto-fixed: - - Show the errors clearly to the user - - STOP the commit process - - Explain what needs to be manually fixed -5. If all errors were auto-fixed: - - Stage the fixes: `git add -u` - - Continue to the next step - -### If linting check passes: -Continue to the next step. +If no auto-fixes were applied, skip this step. -## Step 4: Run Tests +## Step 5: Run Tests Run the unit tests (excluding integration tests): @@ -84,7 +97,7 @@ uv run --frozen pytest tests/ -v --tb=short -m "not integration" 2>&1 ### If tests pass: Continue to the next step. -## Step 5: Generate Commit Message +## Step 6: Generate Commit Message Analyze the staged changes to generate an appropriate commit message: @@ -113,7 +126,7 @@ Types of changes to identify: - `Test` - Adding or updating tests - `Chore` - Maintenance tasks -## Step 6: Confirm and Commit +## Step 7: Confirm and Commit 1. Show the user the proposed commit message 2. Ask if they want to proceed with this message or modify it