From 034b562e706ecab639da88744f9e7415e598737d Mon Sep 17 00:00:00 2001 From: csh Date: Wed, 15 Jul 2026 16:13:23 +0800 Subject: [PATCH] :bug: fix(commit-message): resolve policy and staged boundaries --- skills/commit-message/SKILL.md | 110 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/skills/commit-message/SKILL.md b/skills/commit-message/SKILL.md index 75173fc2..1af891b5 100644 --- a/skills/commit-message/SKILL.md +++ b/skills/commit-message/SKILL.md @@ -7,92 +7,86 @@ description: "Use when the user asks for help writing a commit message, wants em ## Overview -Turn a staged diff into a commit recommendation that matches repository policy. -Core principle: understand staged intent and commit boundaries before drafting the -message. - -Authority source: - -- `docs/common/commit_message.md` -- `docs/standards/playbook/docs/common/commit_message.md` (vendored playbook) +Create a repository-compliant recommendation from the staged diff. Resolve its +boundary and enforced rules before drafting. ## When to Use -- The user asks to write or improve a commit message -- The user wants emoji/type(scope): subject formatting -- The user asks whether current staged changes should be split before commit -- The user asks to review staged changes before running `git commit` +Use for commit-message drafting, staged-boundary review, split decisions, or +emoji/type(scope): subject formatting. ## When Not to Use -- No staged changes exist and the user expects a final commit message based on the - actual staged diff -- The task is writing a PR title, release note, or changelog instead of a git - commit message -- The user already provided an exact commit message and only wants it executed +Do not use for PR titles, release notes, changelogs, or exact-message execution. ## Inputs -- Current staging state (`git status --short`, `git diff --cached`) -- Nearest applicable `commit_message.md` -- Whether the user wants suggestions only or a command-ready final message +Use staged/unstaged state and repository policy. ## Procedure -1. **Baseline the repo state** +1. **Baseline state** - - Inspect staged and unstaged state separately. - - If nothing is staged, stop. Explain that a staged-diff-based recommendation - is unavailable and ask whether files should be staged first. - - If only unstaged changes exist, stop before proposing a final message. Offer - a draft only if the user explicitly wants one. + - Inspect staged and unstaged changes separately. + - If nothing is staged, do not produce a final diff-based message. Offer an + unstaged draft only when explicitly requested. + - Record the staged file list and summary for the final consistency check. -2. **Load the authority spec** +2. **Resolve effective policy** - - Prefer the nearest `commit_message.md`. - - Reuse its type, emoji, scope, and body/footer conventions exactly. + - Read applicable repository instructions, mechanical enforcement + (`commitlint`, hooks, CI workflow/env, validation scripts), then the nearest + `commit_message.md`. + - Effective enforcement overrides optional prose defaults. Report conflicts + and use a form accepted by both whenever possible. + - With no repository policy, state and use this Conventional Commits fallback: + `type(scope): subject`; optional scope; type from `feat`, `fix`, `docs`, + `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, or `revert`; no + emoji; imperative lowercase subject, at most 72 characters, no final period. -3. **Summarize staged intent** +3. **Classify the boundary** - - Read the staged diff at the smallest useful granularity. - - Identify the main logical change, affected areas, and whether the staged set - mixes unrelated work. - - If staged changes combine unrelated goals, strongly recommend splitting the commit - before drafting a single message. In other words, strongly recommend splitting - the commit instead of hiding multiple intents behind one subject. + - Identify the dominant intent and required coupled changes. + - For unrelated intents, stop before drafting a combined message. Output + ordered groups with files, intent, and a provisional message for each. + - Continue with one combined message only after the user explicitly opts out + of the recommended split. -4. **Draft message options** +4. **Draft and validate** - - Produce one recommended option and up to two alternatives. - - Keep the subject concrete, specific, and under the repo limit. - - Use body/footer only when they add real context such as motivation, impact, - verification, issue links, or breaking-change notes. + - Produce one recommendation. Add alternatives only when materially distinct + valid type or scope interpretations remain. + - Add body/footer only for motivation, impact, verification, issue links, or + breaking changes. + - Use a repository validator when it accepts candidate input. Otherwise check + type, emoji, scope, length, subject, body, and footer manually. A HEAD-only + check does not validate a candidate. + - Rerun the staged summary before finalizing. If it changed, reread the diff + and restart classification. 5. **Finalize safely** - - Make it explicit whether the output is a suggestion or a final chosen message. - - Do not run `git commit` unless the user explicitly asks for execution after - reviewing the recommendation. + Label the result as a suggestion or final choice. Run `git commit` only after + explicit user authorization. ## Output Contract -- `Detected:` staged files summary, dominant intent, and split/no-split judgment -- `Spec:` which `commit_message.md` was used -- `Proposed:` Option A (recommended), Option B, Option C -- `Optional body/footer:` only when justified -- `Notes:` risks, ambiguity, or split advice +| State | Required output | +| --- | --- | +| Single intent | `Detected`, `Spec`, one `Proposed`, `Validation`, optional body/footer and materially distinct alternatives | +| Mixed intents | `Detected`, `Split` groups, and `Notes`; no combined `Proposed` until the user opts out of splitting | + +`Spec` names the source, enforcement, and conflicts. `Validation` names the +validator result or manual checks. ## Success Criteria -- The recommendation matches the staged diff rather than guessed intent -- The selected format complies with the nearest commit policy -- Split advice appears when staged changes are logically mixed -- No commit command is executed unless the user asked for it +- Output matches the current staged diff and effective policy +- Mixed work yields a split plan, not a disguised combined message +- Every candidate is validated; filler alternatives are omitted +- No commit runs without explicit authorization ## Failure Handling -- If no staged diff exists, stop and explain the limitation instead of inventing a - final message -- If the staged set is too broad or ambiguous, recommend splitting and explain why -- If no local policy file is found, state the fallback convention before drafting -- If repo state changes during review, rerun the staged summary before finalizing +No staged diff: explain and stop. No policy: state the fallback. Conflicts: +report them and use the stricter accepted form. Changed staging: restart.