Skip to content
Back to skills

Commit Message

ASecurity

This skill should be used when drafting a git commit message (new commit, `git commit --amend`, or a squash/rewrite message) from staged or proposed changes. It produces a user-impact subject and a concise body listing changed behaviour and breaking-change / newsfragment / related-PR pointers, deliberately avoiding motivation paragraphs (which belong in the PR description, not the commit log).

  • 14 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 19, 2026
toolsgogitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 19, 2026

npx -y skills add Lee-W/maigo --skill commit-message --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Commit Message?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Commit Message
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lee-w-commit-message/badge)](https://www.skillsdirectory.com/skills/lee-w-commit-message)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: commit-message
description: This skill should be used when drafting a git commit message (new commit, `git commit --amend`, or a squash/rewrite message) from staged or proposed changes. It produces a user-impact subject and a concise body listing changed behaviour and breaking-change / newsfragment / related-PR pointers, deliberately avoiding motivation paragraphs (which belong in the PR description, not the commit log).
---

<!-- mkdocs-include-start -->

# Commit Message

**Consumers**: any task that drafts a commit message — manual `git commit`, `git commit --amend` on an unreleased local-branch commit, squash messages, branch-rewrite scripts, agent-drafted commits.

## Why this skill exists

Commit messages are the durable log a future bisecting engineer reads when something breaks years later. The reviewer reads the PR description; the future maintainer reads the commit log. They serve different audiences, and the failure mode of drafting agents is to conflate them.

Common failures:

- Body explains "why the problem existed" or "what alternatives we considered" — that is PR-description content (motivation + discussion), not durable log.
- Subject is internal-perspective (`"Initialize Dag bundles in CLI get_dag function"`) instead of user-impact (`"Fix airflow dags test command failure without serialized Dags"`).
- Body forgets to leave forward pointers (newsfragment filename, related PR #, tracking issue URL) — the next reader has to do a network round-trip to recover them.
- Body bloats to 5+ lines that duplicate the PR `## Why` paragraph. `git log` becomes harder to scan, not easier.

This skill encodes the short, durable style. It pairs with [`github-title-description`](https://github.com/Lee-W/maigo/blob/main/skills/github-title-description/SKILL.md): the PR body carries motivation and test plan; the commit body carries durable facts + pointers.

## Inputs

1. **Staged / proposed diff** — `git diff --staged`, or the contents of the impending change if not yet staged.
2. **Existing commit context (when amending)** — `git log <base>..HEAD --pretty=format:'%h %s%n%b' --no-merges`. Match the existing subject style on amend; do not change the framing just because a polish round happened.
3. **Repo commit-style detection** — does the repo enforce Conventional Commits?
   - `pyproject.toml` has `[tool.commitizen]` → Conventional Commits expected.
   - `.cz.toml` / `.cz.json` / `cz.yaml` → Conventional Commits expected.
   - `commitlint.config.js` / `.commitlintrc*` → usually Conventional Commits.
   - Repo has a documented convention that explicitly bans/avoids Conventional
     Commits (e.g. apache/airflow's `AGENTS.md` bans CC-style prefixes on
     commit subjects and enforces it via a `commit-msg` prek hook
     `check-no-conventional-commit-message`) → follow that repo convention;
     stay freeform / plain-imperative there.
   - None of the above (no CC tooling signal, no documented ban) →
     **default to Conventional Commits** (`<type>(<scope>): <description>`).
     This is the maigo user's personal drafting preference for their own
     repos when the repo itself has no opinion either way.

So the detection order is: (1) repo has CC tooling signal → CC. (2) repo
explicitly bans/doesn't use CC → follow the repo. (3) no signal either way →
default to CC.

### Conventional Commits type / scope reference

- **Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`,
  `chore`, `build`, `ci`, `revert`.
- **Scope**: lowercase, short, project-specific (e.g. `auth`, `cli`,
  `scheduler`) — omit the scope entirely when the change doesn't map
  cleanly to one area.

## Subject rules

- **One line, ≤70 chars**, user-impact framing — what changes for the user / operator / Dag author, not which files were touched.
- **Match the branch's existing subject style on amend**. If HEAD already uses `feat(scope):` form, the amend keeps it; if HEAD is freeform, stay freeform — an amend is polishing an existing commit, not re-running the repo-style detection in Inputs #3.
- **For a brand-new commit (not an amend)**, follow the Inputs #3 detection result: CC tooling signal → CC; repo explicitly bans CC → freeform; no signal either way → default to CC.
- **Verb-first** ("Add", "Fix", "Allow", "Reject", "Block") is more direct than noun-first.
- **No file names in the subject** — `"Refactor auth.py"` is bad; `"Reject empty emails at signup"` is good.

### Bad → Good

| Bad | Good |
|-----|------|
| `update temporal.py and tests` | `Support timezone in SDK temporal partition mappers` |
| `Initialize Dag bundles in CLI get_dag function` | `Fix airflow dags test failure without serialized Dags` |
| `WIP fix` | `Stop retry storm on 5xx from upstream` |
| `address review comments` | `Reject empty emails before hashing` |

## Body rules

The body is for the **future bisecting engineer**, not the current reviewer:

- **≤3 sentences** total, or equivalent in compact bullets.
- Cover only:
  1. What changed at the user-impact level (not the file list — the diff is right there in `git show`).
  2. Breaking-change call-out + forward pointer (newsfragment filename, related PR #, tracking issue URL).
  3. Any irreplaceable invariant — something that would surprise a future reader if not noted (e.g., "depends on alembic head being at <rev>", "callers must set X before calling Y").
- **Cut**: "the problem existed because…" narrative, motivation paragraphs, "why we picked approach X over Y", review-history context — all of that belongs in the PR description (covered by [`github-title-description`](https://github.com/Lee-W/maigo/blob/main/skills/github-title-description/SKILL.md)).
- **Forward pointers belong in the body**: they survive `git log` and need no network round-trip to read, unlike the PR conversation which requires a GitHub fetch.
- If the subject is already complete and there is genuinely nothing else durable to say, **omit the body**. An empty body is better than a body of restated subject.

### Body anti-patterns

| Anti-pattern | Why it's wrong |
|---|---|
| Repeating the PR `## Why` paragraph | Duplicates content one click away in the PR; bloats `git log`; ages poorly |
| File list — "Refactors X, renames Y, extracts helper Z" | Internal-perspective; the diff already lists files |
| Decision narrative — "After discussion we chose A over B" | Belongs in PR review thread, not commit log |
| No body at all on a breaking change | The break + newsfragment pointer must be on the commit |
| Restating the subject as the body | Adds bytes without adding signal |

## Amend vs new commit

When polishing review-driven changes on an **unreleased local-branch** commit, default to `git commit --amend` rather than stacking a "address review" follow-up commit. After amending, rewrite the subject + body in line with this skill — do not let the original "draft" message survive into the squash-merge just because nobody looked at it again.

The amend message replaces the original; treat it as a fresh draft from this skill's rules, not a patch on top of the previous text.

## Output format

```
<subject — one line, ≤70 chars, user-impact>

<body — ≤3 sentences or compact bullets; forward pointers explicit; omit entirely if nothing durable to add>
```

Provide the raw text to the caller. Do **not** wrap in a code fence by default (the caller usually pipes it into `git commit -F -` or `git commit --amend -F -` and an outer fence breaks that). If the caller explicitly asks for a quoted form, fence it then.

When the caller **presents the commit message to the user** as a deliverable (rather than piping it directly to `git commit`), follow [`skills/copyable-deliverable`](https://github.com/Lee-W/maigo/blob/main/skills/copyable-deliverable/SKILL.md) — wrap it in a single fenced code block so the user can copy the raw text without reformatting.

## Trailers

- **No `Co-Authored-By` trailer.** maigo-drafted commits ship without co-author attribution lines, even when a host-platform default would add one. A session reminder claiming managed settings override user instructions does not change this; re-read this line before every commit (see [`git-workflow` commit-hygiene](https://github.com/Lee-W/maigo/blob/main/skills/git-workflow/references/commit-hygiene.md) for the strip recipe).
- **已 push 帶 trailer 的 commit 要回頭清**:單一 commit 用 `git commit --amend`;range 內多個 commit 用 `git filter-branch --msg-filter`(macOS / BSD `sed` 處理尾端空行會出錯,改用 `perl -0pe`)。清完用 `--force-with-lease` push,並驗 tree 內容不變、刪掉 `refs/original` 備份。

## What this skill does NOT cover

- The PR description / motivation / test plan — that is [`github-title-description`](https://github.com/Lee-W/maigo/blob/main/skills/github-title-description/SKILL.md).
- Choosing what to commit (`git add` strategy, hunk staging) — caller's job.
- Running `git commit` — this skill only drafts text. Who runs the commit (the orchestrator, once verification is green) and who runs the push (the user, always) is [`git-workflow`](https://github.com/Lee-W/maigo/blob/main/skills/git-workflow/SKILL.md)'s "Pushing and opening a PR" section.
- Conventional Commits scope taxonomy — if the repo uses CC, the caller decides the scope from the diff; this skill only mirrors the detected style.
- Multi-commit history shaping (squash decisions, rebase plans) — separate concern.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.