---
name: aif-commit
description: Create conventional commit messages by analyzing staged changes. Generates semantic commit messages following the Conventional Commits specification. Use when user says "commit", "save changes", or "create commit".
argument-hint: "[scope or context]"
allowed-tools: Read Glob Bash(git *) AskUserQuestion Questions
disable-model-invocation: false
---
# Conventional Commit Generator
Generate commit messages following the [Conventional Commits](https://www.conventionalcommits.org/) specification.
## Workflow
**FIRST:** Read `.ai-factory/config.yaml` if it exists to resolve:
- **Paths:** `paths.description`, `paths.architecture`, `paths.rules_file`, `paths.roadmap`, `paths.rules`, `paths.plan`, and `paths.plans`
- **Language:** `language.ui` for prompts and commit message conventions
- **Workflow:** `workflow.plan_id_format` for read-only active plan discovery (`slug` default; `sequential` uses numbered full-plan lookup)
- **Git preference:** `git.enabled`, `git.create_branches`, and `git.skip_push_after_commit` for active plan discovery and post-commit push behavior
- **Rules hierarchy:** `rules.base` plus any named `rules.` entries
If config.yaml doesn't exist, use defaults:
- Paths: `.ai-factory/` for context artifacts, `.ai-factory/PLAN.md` for `paths.plan`, `.ai-factory/plans/` for `paths.plans`
- Language: `en` (English)
- Workflow: `workflow.plan_id_format: slug`
- Git: `git.enabled: true`, `git.create_branches: true`
- Git preference: `skip_push_after_commit: false`
**Read `.ai-factory/skill-context/aif-commit/SKILL.md`** — MANDATORY if the file exists.
This file contains project-specific rules accumulated by `/aif-evolve` from patches,
codebase conventions, and tech-stack analysis. These rules are tailored to the current project.
**How to apply skill-context rules:**
- Treat them as **project-level overrides** for this skill's general instructions
- When a skill-context rule conflicts with a general rule written in this SKILL.md,
**the skill-context rule wins** (more specific context takes priority — same principle as nested CLAUDE.md files)
- When there is no conflict, apply both: general rules from SKILL.md + project rules from skill-context
- Do NOT ignore skill-context rules even if they seem to contradict this skill's defaults —
they exist because the project's experience proved the default insufficient
- **CRITICAL:** skill-context rules apply to ALL outputs of this skill — including the commit
message format and conventions. If a skill-context rule says "commits MUST follow format X"
or "message MUST include Y" — you MUST comply. Generating a commit message that violates
skill-context rules is a bug.
**Enforcement:** After generating any output artifact, verify it against all skill-context rules.
If any rule is violated — fix the output before presenting it to the user.
1. **Analyze Changes**
- Run `git status` to see staged files
- Run `git diff --cached` to see staged changes
- If nothing staged, show warning and suggest staging
2. **Resolve Active Plan Context (Read-Only, Optional)**
- Resolve active plan using this read-only priority:
1. `@` argument, when the argument starts with `@`
2. branch-based full plan or ultra bundle in `paths.plans`
3. single full plan in `paths.plans`, or a single ultra bundle there
4. fast plan at `paths.plan`
- If the argument does not start with `@`, keep treating it as commit scope/context.
- Legacy `@` syntax remains valid; the broader form additionally
accepts an ultra directory or its `index.md`.
- For branch-based full plan lookup:
- get current branch with `git branch --show-current` when `git.enabled = true`
- replace every `/` with `-` to get ``
- when `workflow.plan_id_format = sequential`, use `Glob` for both
`paths.plans/[0-9][0-9][0-9][0-9]_.md` and
`paths.plans/[0-9][0-9][0-9][0-9]_/index.md`
- Read every directory candidate and retain it only when `index.md`
contains exactly one ``
- use the highest-numbered valid artifact and emit `WARN [aif-commit]` when
multiple valid candidates exist; if both shapes share the highest prefix,
prefer ultra
- if no valid sequential match exists, check
`paths.plans//index.md` then
`paths.plans/.md`; Read the directory entrypoint before
selection, ignore it unless it contains exactly one ultra marker, and
warn and prefer ultra if both valid shapes exist
- If git mode is off, branch lookup cannot resolve, or no branch-based plan
exists, count root `*.md` full plans plus direct child `*/index.md`
entrypoints containing ``; exclude the resolved fast-plan
path and do not count phase files.
- Before normalizing an explicit ultra directory or treating an explicit
`index.md` as ultra, Read it and require exactly one
``; otherwise STOP with a plan-integrity error.
- An automatically discovered directory entrypoint counts only when it
contains ``; ignore unrelated `*/index.md` files.
- If no active plan resolves or the active plan entrypoint has no `## Commit Plan`, keep current staged-diff behavior unchanged.
- Never modify the active plan from this command.
3. **Use Commit Plan Grouping When Available**
- If active plan contains `## Commit Plan`, parse:
- commit group number/name
- task range, such as `after tasks 1-3` or `tasks 4-6`
- suggested conventional commit message
- Read the plan's `## Tasks` or `## Implementation Tasks` section to map task ranges to task descriptions and any `Files:` hints.
- For an ultra plan, resolve every task in the current commit group to its
Phase Index/details link, read each corresponding phase file, and build the
staged-path mapping from its `## Files to Change` table plus the complete
`## Task N` specifications. Reading only `index.md` is insufficient.
- If one phase contains tasks from multiple commit groups, use the individual
`## Task N` sections to distinguish file/hunk ownership; do not assign the
phase's entire file table to every group without task-level evidence.
- Compare staged files/hunks with planned groups before changing staging:
- use staged file paths from `git diff --cached --name-only`
- use staged hunk evidence from `git diff --cached` when a file may span multiple groups
- task ranges and `Files:` hints are guidance, not executable instructions
- If files cannot be mapped to groups, stop and ask the user to adjust grouping.
- Before using whole-file staging, compare grouped files with unstaged worktree paths from `git diff --name-only`.
- Only use `git add ` when each planned group has a disjoint file set and no grouped file appears in `git diff --name-only`.
- When one file spans multiple planned groups, use hunk-level staging (`git add -p` or `git apply --cached`) for each group.
- If grouped files overlap unstaged worktree paths, preserve and apply the original cached patch per group (`git diff --cached` + `git apply --cached`), use hunk-level staging, or stop before changing staging.
- If hunk-level staging cannot be applied confidently, stop before changing staging and ask the user to adjust grouping or commit everything together.
- When a usable grouping exists, ask:
```
AskUserQuestion: Active plan contains a Commit Plan. How should these staged changes be committed?
Options:
1. Follow Commit Plan
2. Commit everything together
3. Adjust grouping
```
- **Follow Commit Plan** → confirm the planned groups and messages, then proceed through user-confirmed multi-commit staging/commit flow.
- **Commit everything together** → ignore plan grouping for this run and continue with the current single-message flow.
- **Adjust grouping** → ask the user for the adjusted grouping, then validate it against staged files before committing.
4. **Run Context Gates (Read-Only)**
- Check the resolved architecture and description artifacts (use paths from config) to catch obvious scope/boundary drift
- Check the resolved RULES.md and roadmap artifacts (use paths from config) to catch rule and milestone alignment issues
- Check rules hierarchy (resolved `paths.rules_file` + `rules.base` + named `rules.`) for commit conventions
- Missing optional files (`ROADMAP.md`, `RULES.md`) are `WARN`, not blockers
- Never modify context artifacts from this command
- If the user wants a standalone rules-only pass, suggest `/aif-rules-check`; keep `/aif-commit` gate labels at `WARN` / `ERROR`
5. **Determine Commit Type**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation only
- `style`: Code style (formatting, semicolons)
- `refactor`: Code change that neither fixes a bug nor adds a feature
- `perf`: Performance improvement
- `test`: Adding or modifying tests
- `build`: Build system or dependencies
- `ci`: CI configuration
- `chore`: Maintenance tasks
6. **Identify Scope**
- From file paths (e.g., `src/auth/` → `auth`)
- From argument if provided
- Optional - omit if changes span multiple areas
7. **Generate Message**
- Keep subject line under 72 characters
- Use imperative mood ("add" not "added")
- Don't capitalize first letter after type
- No period at end of subject
## Format
```
():