Commit

SkillFiles & storage

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.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Commit skill

What this skill tells your AI

The instructions your AI receives, as published by kdlbs/kandev in .agents/skills/commit/SKILL.md and read by ahel’s review.

Planner Entry

Stage and commit changes in the primary conversation after the task-defined implementation checks pass. Do not add broad post-commit /verify before push by default. Preserve the hook receipt as normal commit evidence.

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

  • /pr-fixup — Use after the PR opens only for CI or actionable reviewer findings.

Format

type: lowercase description

Allowed Types

TypeUse forIn changelog?
featNew featuresYes (Features)
fixBug fixesYes (Bug Fixes)
perfPerformance improvementsYes (Performance)
refactorCode refactoringYes (Refactoring)
docsDocumentation changesYes (Documentation)
choreMaintenance, deps, configsNo
ciCI/CD changesNo
testTest-only changesNo

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

Track these steps with an internal todo/checklist and mark them complete as you go. Do not create, update, or delete Kandev subtasks for this workflow unless the user explicitly requests task tracking.

  1. Understand changes: Run git status and git diff to understand all changes. Review recent commits with git log --oneline -10 to match project style.

  2. 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:

    # Is the framework on PATH?
    pre-commit --version >/dev/null 2>&1 && echo "INSTALLED" || echo "NOT_INSTALLED"
    
    # Is the hook actually wired into git's hook system?
    PRE_COMMIT_HOOK_PATH=$(git rev-parse --git-path hooks/pre-commit)
    COMMIT_MSG_HOOK_PATH=$(git rev-parse --git-path hooks/commit-msg)
    test -f "$PRE_COMMIT_HOOK_PATH" && grep -q "pre-commit" "$PRE_COMMIT_HOOK_PATH" \
      && test -f "$COMMIT_MSG_HOOK_PATH" && grep -q "pre-commit" "$COMMIT_MSG_HOOK_PATH" \
      && echo "ACTIVE" || echo "INACTIVE"
    
    • If NOT_INSTALLED, tell the user once: "⚠️ pre-commit is not on PATH. Install it with pip install pre-commit so format/lint runs on every commit." Then continue (don't block).

    • If installed but INACTIVE, install it yourself — the project ships .pre-commit-config.yaml and make doctor is a no-op-on-already-installed wrapper around the same command:

      pre-commit install -t pre-commit -t commit-msg --overwrite
      

      Mention that you wired it up. Subsequent commits will run hooks automatically.

    • If both checks pass, no output needed.

    • Before the first commit, ensure the worktree can run the commit-msg dependency. If apps/node_modules/.bin/commitlint is absent, install it from apps/ before committing:

      cd apps && pnpm install --frozen-lockfile
      

      Retry the normal commit after the install; never bypass the hook.

    • After merging or rebasing the base branch, if apps/package.json or apps/pnpm-lock.yaml changed and a hook reports ERR_MODULE_NOT_FOUND even though apps/node_modules/.bin/commitlint exists, refresh the workspace dependencies from apps/:

      cd apps && pnpm install --frozen-lockfile
      

      Retry the normal commit without bypassing hooks.

    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.

  3. Capture the parent SHA and preserve hook evidence:

    git rev-parse HEAD
    

    Never use --no-verify, SKIP, or another hook-bypass option or environment variable. A bypassed commit is allowed only when the user explicitly requests it, and its receipt must say bypass: true; it never qualifies as a successful hook receipt.

  4. 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.
  5. Commit: Write a commit message following the format above. If changes span multiple concerns, consider separate commits. When MERGE_HEAD exists or a merge commit is being completed, use git commit --no-edit so a non-interactive runner does not open an editor; normal hooks still run. Confirm the merge commit exists and MERGE_HEAD is gone before reporting success. If a formatter changes files and prevents the commit, review and re-stage those files, then create a new commit attempt; do not use --amend. When editing harness files such as AGENTS.md, CLAUDE.md, or skills, run the shared validation in .agents/skills/harness-improvement/references/validation.md before committing. If a JSX layout-only edit touches an element containing an existing hardcoded user-facing literal, i18n-new-code may classify that literal as changed copy and fail. Localize it and add matching en/pseudo catalog entries before retrying; verify with cd apps/web && pnpm run i18n:check and the normal hook receipt. Capture the normal hook stream in a temporary log while committing and use that log to record each hook ID and result. Do not infer hook results from a condensed launcher summary. For example:

    COMMIT_LOG="$(mktemp "${TMPDIR:-/tmp}/kandev-commit.XXXXXX.log")"
    set -o pipefail
    git commit -m "type(scope): description" 2>&1 | tee "$COMMIT_LOG" >/dev/null
    

    Read the log to extract the hook receipt, rather than printing the full stream again. Remove the exact temporary file after copying the receipt into the handoff:

    unlink "$COMMIT_LOG"
    

    If the commit exits nonzero, preserve and print the full or bounded log before cleanup so hook diagnostics are not lost. Remove the temporary log only after copying a successful hook receipt or recording the failed output.

    If a hook fails only because another worktree is already running golangci-lint (for example, parallel golangci-lint is running), wait for that run to finish and retry the same commit. Do not bypass hooks or change code for this transient lock; verify the retry has a normal hook receipt and a clean worktree.

    If a hook fails with ENOSPC, load /verify's Disk-constrained runners guidance: inspect df, preserve managed caches, relocate only the affected cache to an explicit persistent agent-owned path, and never bypass hooks or blindly delete shared caches.

  6. Return a hook receipt: After a successful commit, report:

    parent_sha: <pre-commit HEAD>
    commit_sha: <new HEAD>
    pre_commit_hook: active|inactive
    commit_msg_hook: active|inactive
    hook_results: <hook-id=passed|skipped, ...>
    bypass: false|true
    commit_result: pass
    worktree: clean|dirty
    

    verify may use the receipt only when both hooks are active, bypass is false, the commit succeeded, the current HEAD still equals commit_sha, and the worktree is clean. The commit worker does not run verification.

Signals

GitHub stars
771
Forks
114
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
commit-kdlbs
Source
github.com/kdlbs/kandev