| name | write-commit |
| description | Use this skill whenever you need to write, generate, create, or improve a git commit message. This includes when the user asks for help with commit messages, wants to write a commit, needs to document changes, or mentions anything related to committing code. The skill enforces conventional commit standards, mandatory ticket references, and focuses on explaining the "why" behind changes rather than just the "what". |
| tools | Grep, Read, Glob, AskUserQuestion |
WHEN TO USE THIS SKILL
Use this skill when you detect ANY of the following in user prompts:
- "write a commit message"
- "help me commit"
- "create commit message"
- "what should the commit say"
- "how to document this change"
- "commit message for"
- "improve this commit"
- "review this commit message"
- "fix this commit"
- Any mention of git commits, committing, or commit messages
TRIGGER EXAMPLES
✅ Trigger: "Write a commit message for the authentication feature"
✅ Trigger: "Help me commit these changes"
✅ Trigger: "What should the commit say for this bug fix?"
✅ Trigger: "Can you create a good commit message?"
✅ Trigger: "How do I document this change in git?"
✅ Trigger: "Review this commit message and improve it"
❌ Do NOT trigger for:
- Simple git commands like "git status" or "git add ."
- Questions about git workflow unrelated to commit messages
- Non-commit related documentation requests
You write commit messages with great care, focusing on the "why" rather than the "what". The code itself shows what changed, but the commit message must explain why those changes were made, what problem they solve, and what benefits they provide.
MANDATORY WORKFLOW - NO EXCEPTIONS
Step 1: Validate Git Repository
- YOU MUST verify the current directory is a git repository
- If not, report error and exit immediately: "Error: Not a git repository"
Step 2: Check for Staged Changes
- YOU MUST verify there are staged changes to commit
- If no staged changes, report error and exit: "Error: No staged changes found"
Step 3: Extract or Request Ticket Reference (CRITICAL)
- Search the user's prompt for ticket references (patterns: DF-123, PA-456, TICKET-789, etc.)
- If NO ticket found in prompt:
- YOU MUST immediately ask: "What ticket does this commit address? Refs: "
- YOU MUST wait for user response
- YOU MUST validate the response follows format: "TICKET-NUMBER" (e.g., DF-438)
- If invalid format, ask again: "Please provide a valid ticket number (e.g., DF-438): "
- If ticket found in prompt:
- YOU MUST confirm format: "TICKET-NUMBER"
- If wrong format (e.g., "Ticket: DF-438", "Closes DF-438", "Fixes DF-438"), correct to "Refs: DF-438"
- YOU MUST use EXACT format: "Refs: TICKET-NUMBER" (never "Ticket:", "Closes", "Fixes", etc.)
Step 4: Determine Commit Type
- Analyze the staged changes to determine the appropriate conventional commit type:
feat: New functionality, features, or capabilities
fix: Bug fixes, patches, or corrections
docs: Documentation changes (README, comments, etc.)
style: Code style changes (formatting, semicolons, etc.)
refactor: Code restructuring without functional changes
perf: Performance improvements
test: Test-related changes
chore: Maintenance tasks, build process, dependencies
ci: CI/CD configuration changes
build: Build system or dependency changes
revert: Reverts a previous commit
Step 4.5: Apply Strict Conventional Commit Format (CRITICAL)
- YOU MUST follow the EXACT conventional commit format template:
<type>(<scope>): <description>
<body>
<footer>
Format Rules (MANDATORY):
-
Header Line:
- MUST start with type:
feat, fix, docs, style, refactor, perf, test, chore, ci, build, or revert
- MAY include optional scope in parentheses:
(scope)
- MUST end with colon and space:
:
- MUST use imperative mood: "add" not "added"
- MUST be 50-72 characters maximum
- Example:
feat(auth): implement JWT authentication
-
Body Section:
- MUST be separated from header by blank line
- MUST explain the "why" not the "what"
- MUST use complete sentences
- MUST wrap at 72 characters per line
- MAY include bullet points for clarity
-
Footer Section:
- MUST be separated from body by blank line
- MUST include ticket reference:
Refs: TICKET-NUMBER
- MAY include other footers (e.g.,
BREAKING CHANGE:)
Validation Checklist (MUST PASS ALL):
- ✅ Header matches:
/^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([a-z-]+\))?: .+$/
- ✅ Header length ≤ 72 characters
- ✅ Blank line after header
- ✅ Body explains reasoning
- ✅ Blank line before footer
- ✅ Footer contains
Refs: TICKET-NUMBER
- ✅ All lines ≤ 72 characters (except long URLs)
If ANY validation fails:
- YOU MUST report the specific format violation
- YOU MUST provide correction instructions
- YOU MUST NOT generate non-compliant messages
Step 5: Craft Commit Message Following Strict Format
<type>(<scope>): <short description>
<blank line>
<detailed explanation focusing on WHY, not WHAT>
<blank line>
Refs: <TICKET-NUMBER>
CRITICAL REQUIREMENTS
Ticket Reference Format
- YOU MUST use EXACT format:
Refs: TICKET-NUMBER
- NEVER use: "Ticket:", "JIRA:", "Issue:", or any other format
- Ticket number MUST be in format: PROJECT-NUMBER (e.g., DF-438, PA-3467)
Conventional Commit Format
- YOU MUST include type (feat, fix, docs, etc.)
- Scope is OPTIONAL but recommended for larger projects
- Description MUST be in imperative mood ("add" not "added")
- Body MUST explain the reasoning, not just what changed
- Footer MUST include ticket reference in exact format
Quality Standards
- Focus on the "why" - what problem is solved, what benefit is gained
- Explain technical decisions and trade-offs
- Mention alternatives considered and why they were rejected
- Include context about the broader impact
- Keep it concise but comprehensive
STRICT FORMAT TEMPLATES (MUST USE EXACTLY)
YOU MUST choose the appropriate template based on commit type:
Feature Template
feat(<scope>): <imperative description>
<blank line>
<explanation focusing on why/benefits>
<blank line>
Refs: <TICKET-NUMBER>
Bug Fix Template
fix(<scope>): <imperative description>
<blank line>
<root cause explanation>
<solution explanation>
<impact explanation>
<blank line>
Refs: <TICKET-NUMBER>
Documentation Template
docs(<scope>): <imperative description>
<blank line>
<what was documented>
<why documentation was needed>
<impact on users>
<blank line>
Refs: <TICKET-NUMBER>
Chore Template
chore(<scope>): <imperative description>
<blank line>
<what maintenance was performed>
<why it was necessary>
<blank line>
Refs: <TICKET-NUMBER>
Refactor Template
refactor(<scope>): <imperative description>
<blank line>
<what was restructured>
<why changes improve code quality>
<no functional changes made>
<blank line>
Refs: <TICKET-NUMBER>
VALIDATION CHECKLIST (MUST PASS ALL)
Before finalizing any commit message, YOU MUST verify:
- ✅ Current directory is a git repository
- ✅ Staged changes exist
- ✅ Ticket reference obtained and validated
- ✅ Commit type determined correctly
- ✅ Appropriate template selected and used exactly
- ✅ Header matches required format
- ✅ Body explains "why" not "what"
- ✅ Footer uses "Refs: TICKET-NUMBER" format
- ✅ All line length limits respected
- ✅ All mandatory fields present
Template Selection Rules:
- New functionality →
feat template
- Bug fixes →
fix template
- Documentation →
docs template
- Code restructuring →
refactor template
- Maintenance tasks →
chore template
- Performance improvements →
perf template
- Test changes →
test template
- CI/CD changes →
ci template
- Build changes →
build template
If ANY validation fails, YOU MUST:
- Report the specific format violation
- Provide correction instructions
- Show the correct template to use
- NOT generate non-compliant messages
FINAL ENFORCEMENT RULE (ZERO TOLERANCE)
BEFORE OUTPUTTING ANY COMMIT MESSAGE, YOU MUST:
- Generate the message using the exact template
- Validate against ALL regex patterns
- Check ALL format requirements
- Only output if ALL checks pass
IF ANY REQUIREMENT FAILS:
- ✅ DO NOT output the message
- ✅ Report: "Format validation failed: [specific issue]"
- ✅ Show the correct template
- ✅ Ask user to confirm corrections
- ✅ Regenerate only after confirmation
EXAMPLE OF PROPER ENFORCEMENT:
User: "Write commit message: Fixed bug in parser"
You: "What ticket does this commit address? Refs: "
User: "PA-3467"
You: "What was the root cause and why was this fix important?"
User: "The split() method failed on multiple spaces"
You: "What impact does this fix have?"
User: "Prevents crashes during array reconstruction"
You: "Generating commit message..."
You: "Validating format..."
You: "✅ Header: fix(parser): handle multiple spaces"
You: "✅ Body: Explains root cause and impact"
You: "✅ Footer: Refs: PA-3467"
You: "✅ All validations passed"
You: "```"
You: "fix(parser): handle multiple consecutive spaces"
You: ""
You: "The split() method failed on multiple spaces, causing crashes"
You: "during array reconstruction. Fixed with re.split() pattern."
You: ""
You: "Refs: PA-3467"
You: "```"
EXAMPLE OF PROPER REJECTION:
User: "Write commit message: Added feature"
You: "What ticket does this commit address? Refs: "
User: "DF-438"
You: "Generating: Added new feature... Ref: DF-438"
You: "Validating format..."
You: "❌ Header: Missing type 'feat:'"
You: "❌ Footer: Wrong format 'Ref: DF-438' should be 'Refs: DF-438'"
You: "Format validation failed: Missing conventional commit type and wrong footer format"
You: ""
You: "Correct template:"
You: "```"
You: "feat: add new feature"
You: ""
You: "<explanation of why feature was added>"
You: ""
You: "Refs: DF-438"
You: "```"
You: "Please confirm this structure is acceptable [Yes/No]"
EXAMPLES OF CORRECT FORMAT
Example 1: Feature with Proper Ticket Format
✅ Validates Against:
- Header:
/^feat\(auth\): .+$/ ✅
- Body: Explains why/benefits ✅
- Footer:
/^Refs: [A-Z]+-\d+$/ ✅
- Length: Header < 72 chars ✅
feat(auth): implement JWT-based authentication
JWT provides stateless authentication with signed tokens, eliminating
session storage requirements and enabling better horizontal scaling.
Implements HS256 algorithm with configurable secret rotation for
enhanced security.
Refs: DF-438
Example 2: Bug Fix with Technical Explanation
✅ Validates Against:
- Header:
/^fix\(parser\): .+$/ ✅
- Body: Explains root cause/solution ✅
- Footer:
/^Refs: [A-Z]+-\d+$/ ✅
- Length: Header < 72 chars ✅
fix(parser): handle multiple consecutive spaces in array parsing
The original split() method failed on multiple spaces, causing index
mismatches during array reconstruction. Replaced with re.split(r'\s+', s)
to properly handle all whitespace variations. Added regression tests
to prevent future occurrences.
Refs: PA-3467
Example 3: Documentation Update
✅ Validates Against:
- Header:
/^docs\(api\): .+$/ ✅
- Body: Explains what/why/impact ✅
- Footer:
/^Refs: [A-Z]+-\d+$/ ✅
- Length: Header < 72 chars ✅
docs(api): add OpenAPI 3.0 specification for user endpoints
Documents the new /users/{id} and /users/search endpoints including
authentication requirements, query parameters, and response schemas.
Enables automatic API client generation and improves developer onboarding.
Refs: DF-439
Example 4: Invalid Format (For Comparison)
❌ Fails Validation:
- Header: Missing type/scope ❌
- Body: Focuses on what not why ❌
- Footer: Wrong format ❌
Added JWT authentication with HS256 algorithm
This commit adds JWT authentication middleware in auth.py with
configuration settings in config.py and pyjwt dependency.
Ticket: DF-438
Corrected Version:
feat(auth): implement JWT-based authentication
JWT provides stateless authentication with signed tokens, eliminating
session storage requirements and enabling better horizontal scaling.
Implements HS256 algorithm with configurable secret rotation for
enhanced security.
Refs: DF-438
FORMAT VALIDATION REGEX PATTERNS
Header Validation
/^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([a-z0-9-]+\))?: .+$/
Requirements:
- MUST start with valid type
- MAY have optional scope in parentheses
- MUST end with colon and space
- MUST have description after colon
- MUST NOT exceed 72 characters
Ticket Reference Validation
/^Refs: [A-Z]+-\d+$/
Requirements:
- MUST start with "Refs: "
- MUST have project code (uppercase letters)
- MUST have hyphen
- MUST have numeric ticket number
- Examples: "Refs: DF-438", "Refs: PA-3467"
Complete Commit Message Validation
/^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([a-z0-9-]+\))?: .+$\n\n(.+\n)+\nRefs: [A-Z]+-\d+$/
Structure:
- Header line (type(scope): description)
- Blank line
- Body (one or more lines)
- Blank line
- Footer (Refs: TICKET-NUMBER)
COMMON MISTAKES TO AVOID
❌ Wrong: "Updated authentication system" (no type, no ticket)
✅ Right: "feat(auth): implement JWT authentication\n\n...\n\nRefs: DF-438"
❌ Wrong: "Ticket: DF-438" (wrong format)
✅ Right: "Refs: DF-438" (correct format)
❌ Wrong: "Added new feature that does X" (focuses on what)
✅ Right: "feat: implement X to solve Y problem" (focuses on why)
❌ Wrong: Skipping validation steps
✅ Right: Always follow the mandatory workflow
❌ Wrong: "feat: this is a very long description that exceeds the seventy-two character limit and should be wrapped to maintain readability"
✅ Right: "feat: implement feature with benefits"
❌ Wrong: Missing blank line between header and body
✅ Right: Header\n\nBody content
❌ Wrong: Missing blank line between body and footer
✅ Right: Body content\n\nRefs: TICKET-123
SPECIAL SCENARIOS AND EDGE CASES
Scenario: User Provides Ticket in Wrong Format
User Input: "Write a commit message. The ticket is Ticket: DF-438"
Your Response:
- Extract the ticket number: DF-438
- Correct the format: "For ticket references, we use the format 'Refs: DF-438'. Is that correct?"
- Proceed with proper format
Scenario: Multiple Tickets
User Input: "This fixes issues DF-438 and DF-439"
Your Response:
Refs: DF-438, DF-439
Scenario: No Obvious Ticket
User Input: "Write a commit message for adding user validation"
Your Response:
- "What ticket does this commit address? Refs: "
- Wait for user response
- Validate format
- Proceed only after ticket is confirmed
Scenario: User Wants to Skip Ticket
User Input: "Just write the commit message, no ticket needed"
Your Response:
"I'm sorry, but ticket references are mandatory for all commits. What ticket does this commit address? Refs: "
Scenario: Reviewing Existing Commit Message
User Input: "Review this commit message: 'Fixed bug'"
Your Response:
- Analyze against conventional commit standard
- Identify missing elements (type, scope, body, ticket reference)
- Provide specific improvements
- If no ticket reference, ask: "What ticket should this commit reference? Refs: "
Scenario: Complex Changes Across Multiple Files
User Input: "Write a commit message for changes to auth.py, config.py, and requirements.txt"
Your Response:
- Analyze each file's changes
- Determine overall purpose
- Craft message explaining the comprehensive solution
- Ensure all files are mentioned in context of the "why"
FORMAT CORRECTION EXAMPLES
Example 1: Missing Type and Scope
User Input: "Write commit message: Added user validation"
Violation: Missing conventional commit type and scope
Correction:
What type of commit is this?
- feat: New functionality
- fix: Bug fix
- docs: Documentation
- chore: Maintenance
Please specify the type and scope (if any):
Example 2: Wrong Ticket Format
User Input: "Ticket: DF-438"
Violation: Wrong format (should be "Refs: DF-438")
Correction:
For ticket references, we use the format "Refs: TICKET-NUMBER".
I'll use: Refs: DF-438
Is that correct? [Yes/No]
Example 3: Missing Body Explanation
User Input: "feat: add user validation"
Violation: Missing body explaining why
Correction:
The commit message needs a body explaining why this change was made.
What problem does this solve? Why is user validation important?
What benefits does it provide?
Example 4: Line Too Long
User Input: "feat: implement authentication system with JWT tokens using HS256 algorithm"
Violation: Header exceeds 72 characters
Correction:
The header should be 50-72 characters maximum.
Suggested revision: "feat(auth): implement JWT authentication"
Is this acceptable? [Yes/No/Edit]
Example 5: Wrong Mood
User Input: "feat: added user validation"
Violation: Past tense instead of imperative mood
Correction:
Commit messages should use imperative mood ("add" not "added").
Corrected: "feat: add user validation"
Proceed with this version? [Yes/No]
TROUBLESHOOTING
Issue: Can't Find Staged Changes
Diagnosis: User might not be in correct git repository or changes not staged
Solution:
- Verify: "git status" to check staged changes
- If no repository: "Error: Not a git repository"
- If no staged changes: "Error: No staged changes found. Please stage your changes with 'git add .'"
Issue: User Provides Vague Description
Diagnosis: User says "fixed bug" without details
Solution:
- Ask: "What specific bug was fixed and why was it important?"
- Ask: "What was the root cause and how does this fix address it?"
- Ask: "What impact does this fix have on the system?"
Issue: Ambiguous Commit Type
Diagnosis: Changes could be multiple types (e.g., feat + chore)
Solution:
- Ask: "Is this primarily a new feature, bug fix, or maintenance task?"
- Suggest most likely type based on changes
- Let user confirm or correct
Issue: Format Validation Failure
Diagnosis: Generated message doesn't match required format
Solution:
- Identify specific validation failure
- Show the correct template to use
- Explain what needs to be fixed
- Regenerate using proper template
BEST PRACTICES
- Always validate first: Never assume requirements are met
- Ask early: Get ticket information before writing anything
- Focus on why: Explain the reasoning, not just the changes
- Be specific: Use concrete technical details
- Stay consistent: Always use same formats and structures
- Educate gently: When correcting users, explain why it matters
- Double-check: Verify all requirements before finalizing
Examples
Example 1
build(deps): add dash-bootstrap-components for styled UI layout
Bootstrap components provide responsive grid and pre-styled widgets
that Dash's built-in HTML components lack, reducing the need for
custom CSS to achieve a consistent look and feel.
Refs: DF-438
This commit uses the correct format. There is a type, a title, a body
and a refs-line. However, this commit largely explain what is being
done. Not why it is being done.
Example 2
chore: add poetry.lock and declare dash-bootstrap-components dependency
dash-bootstrap-components was already in use by the Dash app (layout,
tutorial, callbacks) but was not declared in pyproject.toml, meaning
installs in fresh environments would fail silently or rely on transitive
resolution. Adding the explicit constraint pins the compatible range and
makes the dependency contract explicit.
poetry.lock is committed alongside so that CI and contributors get
deterministic installs rather than resolving the latest-compatible
versions on each run.
Refs: DF-438
Same changeset, different commit message. This one is a bit chatty,
but otherwise perfect! It explain why the dependency is added to
poetry.toml and what the use is of the poetry.lock.
It would be good to condense it a bit, but otherwise, good commit
message.