Conventional Commit Workflow
When To Use
- Generating conventional commit messages from staged changes
When NOT To Use
- Full PR preparation: use sanctum:pr-prep
- Amending existing commits: use git directly
Steps
Gather context (run in parallel):
git status -sb
git diff --cached --stat
git diff --cached
git log --oneline -5
- When sem is available (see
leyline:sem-integration):
sem diff --staged --json for entity-level changes
If nothing is staged, tell the user and stop.
When sem output is available, use entity names
(function, class, method) in the commit subject and
body instead of parsing raw diff hunks. For example,
"add function validate_webhook_url" instead of
"add validation logic to notify.py".
Classify: Pick type (feat, fix, docs, refactor,
test, chore, style, perf, ci) and optional scope.
Draft the message:
- Subject:
<type>(<scope>): <imperative summary> (50 chars max)
- Body: What and why, wrapped at 72 chars
- Footer: BREAKING CHANGE, issue refs, and the
discussion trailer below
3a. Discussion trailer: when the change resolves a finding
from the Discussions board, add a trailer on its own line:
Addresses-Discussion: #654
Addresses-Discussion: #604, #610
This is the only signal scripts/reconcile_discussions.py
accepts as proof a finding is done. It posts the resolution
comment and closes the discussion, so the board stops
carrying work that is already finished.
Only add it when this commit resolves the finding. Prose
that merely names a discussion is read as a mention and is
never written back. That distinction is load-bearing:
6b28aa1a says "posted 13 insights to discussions
#424-#436", which is the commit that opened those
discussions. A trailer there would have announced
"Addressed" on findings nobody had looked at yet.
Cite a discussion in the body for context as often as it
helps. Reserve the trailer for resolution.
Slop check: reject these words and replace with plain
alternatives:
| Reject |
Use instead |
| leverage, utilize |
use |
| seamless |
smooth |
| comprehensive |
complete |
| robust |
solid |
| facilitate |
enable |
| streamline |
simplify |
| optimize |
improve |
| delve |
explore |
| multifaceted |
varied |
| pivotal |
key |
| intricate |
detailed |
Also reject: "it's worth noting", "at its core",
"in essence", "a testament to"
4a. Character-level slop check: load shared/output-hygiene.md
(Contract A) and strip these markers. Inline fallback if that
module is absent:
| Marker |
Replace with |
"+" as a prose conjunction |
and (keep + in versions/code) |
em-dash — |
colon, period, comma, or rewrite |
-- as prose punctuation |
colon or rewrite |
arrows -> / → as connectors |
to / into |
smart quotes “ ” ‘ ’ |
straight " and ' |
4b. Subject-matter check (Contract B): describe the change by its
reader-facing effect. Name neither the AI origin nor the specific
marker removed. Do NOT write remove AI slop, de-slop,
AI-generated content, AI phrasing, replace em-dashes, or
remove smart quotes. Test: if the subject only makes sense as "I
cleaned up AI output", rewrite it. For example docs: clarify the setup section, not style: replace em-dashes with colons.
- Write to
./commit_msg.txt and preview.
Rules
- NEVER use
git commit --no-verify or -n
- Write for humans, not to impress
- If pre-commit hooks fail, fix the issues
- This skill drafts a message, it does not commit. Whoever commits
confirms HEAD advanced (
git rev-parse HEAD before and after)
before reporting the commit as landed. An auto-fixing hook aborts
the commit while printing a tail that reads like success, so hook
output is not evidence. See discussion #614.
Exit Criteria
1---2name: commit-messages3description: Generates conventional commit messages from staged changes. Use when committing and needing a well-formatted message. Do not use for full PR prep; use pr-prep.4---56# Conventional Commit Workflow78## When To Use910- Generating conventional commit messages from staged changes1112## When NOT To Use1314- Full PR preparation: use sanctum:pr-prep15- Amending existing commits: use git directly1617## Steps18191. **Gather context** (run in parallel):20 - `git status -sb`21 - `git diff --cached --stat`22 - `git diff --cached`23 - `git log --oneline -5`24 - When sem is available (see `leyline:sem-integration`):25 `sem diff --staged --json` for entity-level changes2627 If nothing is staged, tell the user and stop.2829 When sem output is available, use entity names30 (function, class, method) in the commit subject and31 body instead of parsing raw diff hunks. For example,32 "add function validate_webhook_url" instead of33 "add validation logic to notify.py".34352. **Classify**: Pick type (`feat`, `fix`, `docs`, `refactor`,36 `test`, `chore`, `style`, `perf`, `ci`) and optional scope.37383. **Draft the message**:39 - **Subject**: `<type>(<scope>): <imperative summary>` (50 chars max)40 - **Body**: What and why, wrapped at 72 chars41 - **Footer**: BREAKING CHANGE, issue refs, and the42 discussion trailer below43443a. **Discussion trailer**: when the change resolves a finding45 from the Discussions board, add a trailer on its own line:4647 ```48 Addresses-Discussion: #65449 Addresses-Discussion: #604, #61050 ```5152 This is the only signal `scripts/reconcile_discussions.py`53 accepts as proof a finding is done. It posts the resolution54 comment and closes the discussion, so the board stops55 carrying work that is already finished.5657 **Only add it when this commit resolves the finding.** Prose58 that merely names a discussion is read as a mention and is59 never written back. That distinction is load-bearing:60 `6b28aa1a` says "posted 13 insights to discussions61 #424-#436", which is the commit that *opened* those62 discussions. A trailer there would have announced63 "Addressed" on findings nobody had looked at yet.6465 Cite a discussion in the body for context as often as it66 helps. Reserve the trailer for resolution.67684. **Slop check**: reject these words and replace with plain69 alternatives:7071 | Reject | Use instead |72 |--------|-------------|73 | leverage, utilize | use |74 | seamless | smooth |75 | comprehensive | complete |76 | robust | solid |77 | facilitate | enable |78 | streamline | simplify |79 | optimize | improve |80 | delve | explore |81 | multifaceted | varied |82 | pivotal | key |83 | intricate | detailed |8485 Also reject: "it's worth noting", "at its core",86 "in essence", "a testament to"87884a. **Character-level slop check**: load `shared/output-hygiene.md`89 (Contract A) and strip these markers. Inline fallback if that90 module is absent:9192 | Marker | Replace with |93 |--------|--------------|94 | `"+"` as a prose conjunction | `and` (keep `+` in versions/code) |95 | em-dash `—` | colon, period, comma, or rewrite |96 | `--` as prose punctuation | colon or rewrite |97 | arrows `->` / `→` as connectors | `to` / `into` |98 | smart quotes `“ ” ‘ ’` | straight `"` and `'` |991004b. **Subject-matter check** (Contract B): describe the change by its101 reader-facing effect. Name neither the AI origin nor the specific102 marker removed. Do NOT write `remove AI slop`, `de-slop`,103 `AI-generated content`, `AI phrasing`, `replace em-dashes`, or104 `remove smart quotes`. Test: if the subject only makes sense as "I105 cleaned up AI output", rewrite it. For example `docs: clarify the106 setup section`, not `style: replace em-dashes with colons`.1071085. **Write** to `./commit_msg.txt` and preview.109110## Rules111112- NEVER use `git commit --no-verify` or `-n`113- Write for humans, not to impress114- If pre-commit hooks fail, fix the issues115- This skill drafts a message, it does not commit. Whoever commits116 confirms HEAD advanced (`git rev-parse HEAD` before and after)117 before reporting the commit as landed. An auto-fixing hook aborts118 the commit while printing a tail that reads like success, so hook119 output is not evidence. See discussion #614.120121## Exit Criteria122123- [ ] `commit_msg.txt` written to the working directory containing124 the drafted conventional commit message125- [ ] Subject line follows `<type>(<scope>): <summary>` format and126 is at most 50 characters127- [ ] Slop word check passes: none of the banned words (leverage,128 utilize, seamless, comprehensive, robust, etc.) appear in the129 message130- [ ] Character-level check passes: no em-dashes, no `+` as prose131 conjunction, no smart quotes, no `->` as prose connector132- [ ] If nothing is staged, skill halts immediately and reports133 "nothing staged" without producing a commit message