Commit Review
Review all changes, group them by intent, and produce Conventional Commit messages terse and exact enough for any company's git log. Why over what. No fluff.
The rule that overrides everything
Never commit without explicit user approval. Always present the report first and wait for a "go". No exceptions, no shortcuts, no "this one is obvious".
Step 0 — detect repo conventions
Before drafting anything, learn what this repo actually accepts:
- Read
scripts/hooks/commit-msg.sh, .husky/commit-msg, commitlint.config.*, or package.json commitlint block — note the regex and any non-conventional shapes (e.g. deploy triggers like (build): front).
git log --oneline -50 to detect: capitalization after the colon, scope style (feat(webapp) vs feat:), body habits, and whether the repo's local hooks inject trailers (Made-with: …, Generated-by: …) — those are repo policy, leave them alone.
- If the hook rejects the Conventional
! breaking-change marker (regex without an ! slot — common), use the BREAKING CHANGE: footer only. Never feat!: / feat(scope)!: until Step 0 confirms the regex accepts it.
- If the repo defines extra shapes (e.g.
^\(build\):.* deploy trigger), accept them as first-class. Don't force everything into Conventional.
Step 1 — context depth (tier the work)
Default is fast: current conversation + working-tree diff + AGENTS.md. Most commits don't need more.
Escalate to session archaeology (tier 2) when any of:
- This session has < 3 user messages but the diff is large
- Branch has been worked on > 48h (see anchor below)
- User explicitly asks for "full context" / "session-aware" review
- You're picking up a branch you weren't part of in this session
Tier 2 recipe — session archaeology
Anchor on git history, not file mtime. Pick anchor by scope — mtime is reset by git checkout, formatters, bun install, and pre-commit hooks; never use it.
Reviewing only uncommitted changes (the common case):
ANCHOR=$(git log -1 --format=%cI HEAD)
Reviewing the entire branch (less common — usually for PR-prep):
MERGE_BASE=$(git merge-base origin/HEAD HEAD)
ANCHOR=$(git log -1 --format=%cI "$MERGE_BASE")
Candidate sessions — transcript directories with folder mtime ≥ $ANCHOR:
find <transcripts-root> -maxdepth 1 -type d -newermt "$ANCHOR"
Index pass — don't read whole transcripts. Per candidate, one ripgrep pass each:
First user message — rg -m1 '<user_query>' <session>.jsonl (the brief)
Last user message — rg '<user_query>' <session>.jsonl | tail -1 (final state)
Edited file paths — rg -o '"path":"[^"]+"' <session>.jsonl | sort -u
Delegation paths — when a session is small (< 50 lines) but contains "name":"Task", the real work happened in an inaccessible subagent transcript. The parent has 0 "path" keys but the user's brief is still high-signal. Extract path-shape strings from the parent's Task prompt and Shell command bodies as a substitute for the edited-file list:
rg -o '(packages/[a-zA-Z0-9_/.+-]+|\.cursor/[a-zA-Z0-9_/.+-]+|src/[a-zA-Z0-9_/.+-]+)' <session>.jsonl | sort -u
Filter — by overlap strength, not single hits. Single-file overlap is noisy: a long-lived file like TipTap.tsx is touched by every editor feature for years. Score each session:
- Strong: edited-file set covers ≥ 30% of
git status filelist, or session is < 48h old AND covers ≥ 1 file
- Weak: 1 file overlap, session > 48h old → false-positive risk, drop
- Delegation-parent: brief mentions a feature folder present in the diff → keep, treat as low-confidence brief
If 0 sessions score Strong, escalate to fallback (below) immediately — don't waste tokens reading Weak ones.
Read survivors selectively — user-message slices and final tool-call summaries only. Skip the agent's exploratory monologue, abandoned approaches, and code-reading rabbit holes.
The "why" is the user's stated brief, not the agent's narrative. Reconcile brief vs diff: if they disagree (user said "refactor", diff adds new endpoints = feat), flag the mismatch in the report rather than parroting the user's framing.
Tier 2 fallback (used freely, not "only when archaeology fails")
These three sources together give a HoE-grade picture in seconds and are the correct answer when:
- All candidate sessions are delegation-parents (no local edits)
- Work is iterative across many sessions touching the same files
- Branch is older than ~5 days
- Archaeology returned only Weak-scored sessions
- Work was pulled from a teammate (no local sessions at all)
git log --oneline origin/HEAD..HEAD # the branch's prior commit messages tell the story arc
git status --porcelain # diff already groups itself by feature folder
cat AGENTS.md # workspace context for the why
Use this whenever it's sufficient. Tier 2 archaeology is for when conversation history actually carries unique signal that git + AGENTS.md don't.
Format
<type>(<scope>): <imperative summary>
<body — only if "why" isn't obvious from the subject>
<footer — breaking changes, issue refs>
Allowed types
| Type |
When to use |
feat |
New user-facing capability |
fix |
Bug or broken behavior corrected |
refactor |
Code restructured, no behavior change |
perf |
Performance improvement |
style |
Formatting, whitespace, naming only |
test |
Test additions or corrections |
build |
Build system or dependency changes |
ci |
CI/CD pipeline changes |
docs |
Documentation only |
chore |
Maintenance that doesn't fit above |
revert |
Reverts a previous commit |
Repo-specific shapes detected in Step 0 are also valid — e.g. (build): front, (build): back, (build): front back as deploy triggers (no scope, no body, exact phrasing).
Choosing a scope
Pick the most specific shared thing the change touches. The scope should help a future reader filter git log quickly.
- Single-app repo: feature or module name —
auth, parser, cli, editor
- Monorepo: derive from the path — files under
packages/foo/*, apps/foo/*, libs/foo/*, or services/foo/* → scope foo
- Cross-cutting: a domain noun —
deps, build, config, ci, docs
- No useful scope: omit it — write
feat: … rather than feat(misc): …
Subject line — quality bar
- Imperative mood:
add, fix, remove — never added, fixed, updated, adding
- ≤ 50 characters when possible, editorial cap 72 (hooks often allow up to 100 — go past 72 only when wrapping makes the subject worse)
- No trailing period
- Match the project's capitalization convention after the colon (from Step 0)
- Atomic — if the summary needs "and", it's two commits
- Don't restate the filename when the scope already says it
Body — only when needed
Skip the body entirely when the subject is self-explanatory. Padding noise into a body is worse than no body.
Add a body only for:
- Non-obvious why (the diff already shows what)
- Breaking changes and migration notes
- Security fixes
- Data migrations
- Reverts of prior commits
- Linked issues or trade-offs worth recording
Body rules:
- Wrap at 72 chars
- Bullets use
-, not *
- Issue refs at the end. Use
Closes #N only on the commit that actually fixes the issue (usually the last in the group); other commits in the same PR use Refs #N so GitHub doesn't close on the first-merged commit.
- Breaking changes:
BREAKING CHANGE: <description> footer. Use the ! subject marker only if Step 0 confirmed the hook accepts it.
Strictly forbidden
- Past tense (
added, fixed, updated) or gerunds (adding, fixing)
I, we, now, currently, This commit does X, As requested by …
- Tautology (
refactor: refactor code, fix(editor): fix issue)
- Filler:
just, simply, basically, actually
- Vague summaries:
update files, fix bug, misc, stuff, various changes
- Emoji, unless the project's existing
git log uses them
- Authoring tool-attribution trailers (
Made-with: …, Generated-by: …, Co-authored-by: AI) or mentioning AI / Cursor / Copilot / ChatGPT / Claude in the message. Repo-injected trailers added post-commit are not yours to police — leave them alone. Use Co-authored-by: only for real human collaborators.
- Reproducing agent monologue, exploration, or abandoned approaches in the body. The body summarizes the decision, not the journey.
- Combining unrelated changes in one commit
--no-verify to skip hooks; --no-gpg-sign to skip signing
Workflow
1. Gather
Run in parallel:
git status
git diff --stat # cost gate — paginate per-group if huge
git diff
git diff --cached
git diff --check # whitespace / unresolved conflict markers
git log --oneline -20
- Default scope follows the user's ask: "review my staged changes" → skip unstaged; "review changes" → both.
- If there's nothing to commit, stop and tell the user.
- If the diff includes anything that looks like a secret or machine-local file —
**/.env*, **/credentials*.json, **/service-account*.json, **/*.pem, **/*.key, **/id_rsa*, **/*.p12, **/*.pfx, **/*.kubeconfig, or paths normally listed in .gitignore that slipped in — exclude them from every group and flag them so the user can decide. Do not substring-match *token* / *secret* (false-positives on tokenizer.ts, secretRotation.test.ts).
2. Propose
Group by intent: one logical concern per group, regardless of file count. Each group must be revertable on its own without breaking unrelated work. Tests and supporting config belong with the change they support, not in a separate chore.
Both forms use the same fields — Files / Why / Message.
Single group? Compact form:
### <type>(<scope>): <summary>
Files:
- path/to/file
Why: <one sentence — or "obvious from subject">
Message:
<full commit message — body omitted when not needed>
Two or more groups? Full report:
## Commit Review Report
### Group 1: <type>(<scope>): <summary>
Files:
- path/to/file1
- path/to/file2
Why: <one sentence — or "obvious from subject">
Message:
<full commit message — body omitted when not needed>
---
### Group 2: …
---
Total: X commits across Y files
Excluded: N files (<reason>) ← only if anything was flagged
Then wait. Ask the user to:
- Approve all — proceed to commit
- Edit — adjust specific messages
- Regroup — merge or split groups
- Drop — skip specific groups
- Reject all — discard and start over
3. Execute (only after approval)
For each approved group, in order:
Stage exactly that group's files — git add <paths>. Never git add -A or git add . during sequential commits; that destroys the grouping.
Commit with a HEREDOC so multi-line bodies keep their newlines. For subject-only commits, a -m flag is fine:
git commit -m "$(cat <<'EOF'
feat(auth): add passkey enrollment
Replaces the optional SMS step, which had a 12% failure rate
on cold-launch screens.
Closes #128
EOF
)"
If a pre-commit hook auto-modifies files, run git diff --name-only to see what it touched, re-stage those files, then amend — but only when all of: (a) you created the commit in this session, (b) git status still shows "Your branch is ahead" (not pushed), (c) it's the most recent commit. Otherwise create a follow-up commit.
If a hook rejects the commit, fix the underlying issue and create a new commit — never amend, never --no-verify, never --no-gpg-sign.
4. Self-check before reporting "done"
For each created commit, verify:
- Subject ≤ 72 chars, imperative mood, no trailing period
- Scope present where the rest of the log uses scopes
- No tool / AI mention you authored (repo-injected trailers are fine)
- Atomic — every group reverts cleanly on its own
Then run git status and git log --oneline -<N> and report the result.
Examples
Subject-only is enough
fix(parser): handle empty input
docs(readme): correct install command
test(auth): cover expired-token branch
chore(deps): bump zod to 3.23.8
Body earns its keep
feat(editor): add inline code formatting toggle
Toolbar button and Cmd+E shortcut wrap the current selection.
Matches Notion/Slack muscle memory users were already trying.
fix(tab-bar): restore active tab highlight after navigation
The route-change handler was overwriting the active state
before the highlight effect read it.
Closes #412
perf(build): lazy-load extension bundles on first use
Cuts initial bundle by ~40% on cold load. Table and image
extensions now resolve only when their nodes appear.
Breaking change (footer-only — works on every hook)
feat(api): rename /v1/orders to /v1/checkout
BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout
before 2026-06-01. Old route returns 410 after that date.
Use the Conventional feat(api)!: form only if Step 0 confirmed the repo's commit-msg regex includes an ! slot.
Boundaries
This skill proposes and, after approval, executes commits. It does not push, force-push, rebase, amend prior commits, or run git commit --no-verify / --no-gpg-sign. If the user wants any of those, they ask explicitly.
Source: docs-plus/docs.plus — distributed by TomeVault.
1---2name: commit-review3description: Review staged/unstaged changes and generate grouped, production-grade commit messages following Conventional Commits. Use when the user asks to review changes, write commits, prepare commits, or says "commit", "review changes", or "what did I change". Use when this capability is needed.4---56# Commit Review78Review all changes, group them by intent, and produce Conventional Commit messages terse and exact enough for any company's `git log`. Why over what. No fluff.910## The rule that overrides everything1112**Never commit without explicit user approval.** Always present the report first and wait for a "go". No exceptions, no shortcuts, no "this one is obvious".1314## Step 0 — detect repo conventions1516Before drafting anything, learn what this repo actually accepts:1718- Read `scripts/hooks/commit-msg.sh`, `.husky/commit-msg`, `commitlint.config.*`, or `package.json` `commitlint` block — note the regex and any non-conventional shapes (e.g. deploy triggers like `(build): front`).19- `git log --oneline -50` to detect: capitalization after the colon, scope style (`feat(webapp)` vs `feat:`), body habits, and whether the repo's local hooks inject trailers (`Made-with: …`, `Generated-by: …`) — those are repo policy, leave them alone.20- If the hook rejects the Conventional `!` breaking-change marker (regex without an `!` slot — common), use the `BREAKING CHANGE:` footer only. Never `feat!:` / `feat(scope)!:` until Step 0 confirms the regex accepts it.21- If the repo defines extra shapes (e.g. `^\(build\):.*` deploy trigger), accept them as first-class. Don't force everything into Conventional.2223## Step 1 — context depth (tier the work)2425Default is fast: current conversation + working-tree diff + `AGENTS.md`. Most commits don't need more.2627**Escalate to session archaeology (tier 2) when any of:**2829- This session has < 3 user messages but the diff is large30- Branch has been worked on > 48h (see anchor below)31- User explicitly asks for "full context" / "session-aware" review32- You're picking up a branch you weren't part of in this session3334### Tier 2 recipe — session archaeology35361. **Anchor on git history, not file `mtime`.** Pick anchor by scope — `mtime` is reset by `git checkout`, formatters, `bun install`, and pre-commit hooks; never use it.37 - **Reviewing only uncommitted changes** (the common case):3839 ```bash40 ANCHOR=$(git log -1 --format=%cI HEAD)41 ```4243 - **Reviewing the entire branch** (less common — usually for PR-prep):4445 ```bash46 MERGE_BASE=$(git merge-base origin/HEAD HEAD)47 ANCHOR=$(git log -1 --format=%cI "$MERGE_BASE")48 ```49502. **Candidate sessions** — transcript directories with folder mtime ≥ `$ANCHOR`:5152 ```bash53 find <transcripts-root> -maxdepth 1 -type d -newermt "$ANCHOR"54 ```55563. **Index pass — don't read whole transcripts.** Per candidate, one ripgrep pass each:57 - First user message — `rg -m1 '<user_query>' <session>.jsonl` (the brief)58 - Last user message — `rg '<user_query>' <session>.jsonl | tail -1` (final state)59 - Edited file paths — `rg -o '"path":"[^"]+"' <session>.jsonl | sort -u`60 - **Delegation paths** — when a session is small (< 50 lines) but contains `"name":"Task"`, the real work happened in an inaccessible subagent transcript. The parent has 0 `"path"` keys but the user's brief is still high-signal. Extract path-shape strings from the parent's Task prompt and Shell command bodies as a substitute for the edited-file list:6162 ```bash63 rg -o '(packages/[a-zA-Z0-9_/.+-]+|\.cursor/[a-zA-Z0-9_/.+-]+|src/[a-zA-Z0-9_/.+-]+)' <session>.jsonl | sort -u64 ```65664. **Filter — by overlap strength, not single hits.** Single-file overlap is noisy: a long-lived file like `TipTap.tsx` is touched by every editor feature for years. Score each session:67 - **Strong**: edited-file set covers ≥ 30% of `git status` filelist, **or** session is < 48h old AND covers ≥ 1 file68 - **Weak**: 1 file overlap, session > 48h old → false-positive risk, drop69 - **Delegation-parent**: brief mentions a feature folder present in the diff → keep, treat as low-confidence brief7071 If 0 sessions score Strong, **escalate to fallback (below) immediately** — don't waste tokens reading Weak ones.72735. **Read survivors selectively** — user-message slices and final tool-call summaries only. Skip the agent's exploratory monologue, abandoned approaches, and code-reading rabbit holes.74756. **The "why" is the user's stated brief, not the agent's narrative.** Reconcile brief vs diff: if they disagree (user said "refactor", diff adds new endpoints = `feat`), flag the mismatch in the report rather than parroting the user's framing.7677### Tier 2 fallback (used freely, not "only when archaeology fails")7879These three sources together give a HoE-grade picture in seconds and are the _correct_ answer when:8081- All candidate sessions are delegation-parents (no local edits)82- Work is iterative across many sessions touching the same files83- Branch is older than ~5 days84- Archaeology returned only Weak-scored sessions85- Work was pulled from a teammate (no local sessions at all)8687```bash88git log --oneline origin/HEAD..HEAD # the branch's prior commit messages tell the story arc89git status --porcelain # diff already groups itself by feature folder90cat AGENTS.md # workspace context for the why91```9293Use this **whenever** it's sufficient. Tier 2 archaeology is for when conversation history actually carries unique signal that git + AGENTS.md don't.9495## Format9697```98<type>(<scope>): <imperative summary>99100<body — only if "why" isn't obvious from the subject>101102<footer — breaking changes, issue refs>103```104105### Allowed types106107| Type | When to use |108| ---------- | ------------------------------------- |109| `feat` | New user-facing capability |110| `fix` | Bug or broken behavior corrected |111| `refactor` | Code restructured, no behavior change |112| `perf` | Performance improvement |113| `style` | Formatting, whitespace, naming only |114| `test` | Test additions or corrections |115| `build` | Build system or dependency changes |116| `ci` | CI/CD pipeline changes |117| `docs` | Documentation only |118| `chore` | Maintenance that doesn't fit above |119| `revert` | Reverts a previous commit |120121Repo-specific shapes detected in Step 0 are also valid — e.g. `(build): front`, `(build): back`, `(build): front back` as deploy triggers (no scope, no body, exact phrasing).122123### Choosing a scope124125Pick the most specific shared thing the change touches. The scope should help a future reader filter `git log` quickly.126127- **Single-app repo**: feature or module name — `auth`, `parser`, `cli`, `editor`128- **Monorepo**: derive from the path — files under `packages/foo/*`, `apps/foo/*`, `libs/foo/*`, or `services/foo/*` → scope `foo`129- **Cross-cutting**: a domain noun — `deps`, `build`, `config`, `ci`, `docs`130- **No useful scope**: omit it — write `feat: …` rather than `feat(misc): …`131132### Subject line — quality bar133134- Imperative mood: `add`, `fix`, `remove` — never `added`, `fixed`, `updated`, `adding`135- ≤ 50 characters when possible, **editorial cap 72** (hooks often allow up to 100 — go past 72 only when wrapping makes the subject worse)136- No trailing period137- Match the project's capitalization convention after the colon (from Step 0)138- Atomic — if the summary needs "and", it's two commits139- Don't restate the filename when the scope already says it140141### Body — only when needed142143**Skip the body entirely** when the subject is self-explanatory. Padding noise into a body is worse than no body.144145**Add a body only for:**146147- Non-obvious _why_ (the diff already shows _what_)148- Breaking changes and migration notes149- Security fixes150- Data migrations151- Reverts of prior commits152- Linked issues or trade-offs worth recording153154**Body rules:**155156- Wrap at 72 chars157- Bullets use `-`, not `*`158- Issue refs at the end. Use `Closes #N` **only** on the commit that actually fixes the issue (usually the last in the group); other commits in the same PR use `Refs #N` so GitHub doesn't close on the first-merged commit.159- Breaking changes: `BREAKING CHANGE: <description>` footer. Use the `!` subject marker only if Step 0 confirmed the hook accepts it.160161### Strictly forbidden162163- Past tense (`added`, `fixed`, `updated`) or gerunds (`adding`, `fixing`)164- `I`, `we`, `now`, `currently`, `This commit does X`, `As requested by …`165- Tautology (`refactor: refactor code`, `fix(editor): fix issue`)166- Filler: `just`, `simply`, `basically`, `actually`167- Vague summaries: `update files`, `fix bug`, `misc`, `stuff`, `various changes`168- Emoji, unless the project's existing `git log` uses them169- Authoring tool-attribution trailers (`Made-with: …`, `Generated-by: …`, `Co-authored-by: AI`) or mentioning AI / Cursor / Copilot / ChatGPT / Claude in the message. **Repo-injected trailers added post-commit are not yours to police — leave them alone.** Use `Co-authored-by:` only for real human collaborators.170- Reproducing agent monologue, exploration, or abandoned approaches in the body. The body summarizes the **decision**, not the journey.171- Combining unrelated changes in one commit172- `--no-verify` to skip hooks; `--no-gpg-sign` to skip signing173174## Workflow175176### 1. Gather177178Run in parallel:179180```bash181git status182git diff --stat # cost gate — paginate per-group if huge183git diff184git diff --cached185git diff --check # whitespace / unresolved conflict markers186git log --oneline -20187```188189- Default scope follows the user's ask: "review my staged changes" → skip unstaged; "review changes" → both.190- If there's nothing to commit, stop and tell the user.191- If the diff includes anything that looks like a secret or machine-local file — `**/.env*`, `**/credentials*.json`, `**/service-account*.json`, `**/*.pem`, `**/*.key`, `**/id_rsa*`, `**/*.p12`, `**/*.pfx`, `**/*.kubeconfig`, or paths normally listed in `.gitignore` that slipped in — **exclude them from every group** and flag them so the user can decide. Do **not** substring-match `*token*` / `*secret*` (false-positives on `tokenizer.ts`, `secretRotation.test.ts`).192193### 2. Propose194195Group by intent: one logical concern per group, regardless of file count. Each group must be revertable on its own without breaking unrelated work. Tests and supporting config belong with the change they support, not in a separate `chore`.196197Both forms use the same fields — `Files / Why / Message`.198199**Single group?** Compact form:200201```202### <type>(<scope>): <summary>203Files:204- path/to/file205Why: <one sentence — or "obvious from subject">206207Message:208<full commit message — body omitted when not needed>209```210211**Two or more groups?** Full report:212213```214## Commit Review Report215216### Group 1: <type>(<scope>): <summary>217Files:218- path/to/file1219- path/to/file2220Why: <one sentence — or "obvious from subject">221222Message:223<full commit message — body omitted when not needed>224225---226227### Group 2: …228229---230231Total: X commits across Y files232Excluded: N files (<reason>) ← only if anything was flagged233```234235Then wait. Ask the user to:2362371. **Approve all** — proceed to commit2382. **Edit** — adjust specific messages2393. **Regroup** — merge or split groups2404. **Drop** — skip specific groups2415. **Reject all** — discard and start over242243### 3. Execute (only after approval)244245For each approved group, in order:2462471. **Stage exactly that group's files** — `git add <paths>`. Never `git add -A` or `git add .` during sequential commits; that destroys the grouping.2482. **Commit with a HEREDOC** so multi-line bodies keep their newlines. For subject-only commits, a `-m` flag is fine:249250 ```bash251 git commit -m "$(cat <<'EOF'252 feat(auth): add passkey enrollment253254 Replaces the optional SMS step, which had a 12% failure rate255 on cold-launch screens.256257 Closes #128258 EOF259 )"260 ```2612623. **If a pre-commit hook auto-modifies files**, run `git diff --name-only` to see what it touched, re-stage those files, then amend — but **only** when all of: (a) you created the commit in this session, (b) `git status` still shows "Your branch is ahead" (not pushed), (c) it's the most recent commit. Otherwise create a follow-up commit.2634. **If a hook rejects the commit**, fix the underlying issue and create a **new** commit — never amend, never `--no-verify`, never `--no-gpg-sign`.264265### 4. Self-check before reporting "done"266267For each created commit, verify:268269- Subject ≤ 72 chars, imperative mood, no trailing period270- Scope present where the rest of the log uses scopes271- No tool / AI mention you authored (repo-injected trailers are fine)272- Atomic — every group reverts cleanly on its own273274Then run `git status` and `git log --oneline -<N>` and report the result.275276## Examples277278### Subject-only is enough279280```281fix(parser): handle empty input282```283284```285docs(readme): correct install command286```287288```289test(auth): cover expired-token branch290```291292```293chore(deps): bump zod to 3.23.8294```295296### Body earns its keep297298```299feat(editor): add inline code formatting toggle300301Toolbar button and Cmd+E shortcut wrap the current selection.302Matches Notion/Slack muscle memory users were already trying.303```304305```306fix(tab-bar): restore active tab highlight after navigation307308The route-change handler was overwriting the active state309before the highlight effect read it.310311Closes #412312```313314```315perf(build): lazy-load extension bundles on first use316317Cuts initial bundle by ~40% on cold load. Table and image318extensions now resolve only when their nodes appear.319```320321### Breaking change (footer-only — works on every hook)322323```324feat(api): rename /v1/orders to /v1/checkout325326BREAKING CHANGE: clients on /v1/orders must migrate to /v1/checkout327before 2026-06-01. Old route returns 410 after that date.328```329330Use the Conventional `feat(api)!:` form **only** if Step 0 confirmed the repo's commit-msg regex includes an `!` slot.331332## Boundaries333334This skill **proposes** and, after approval, **executes** commits. It does not push, force-push, rebase, amend prior commits, or run `git commit --no-verify` / `--no-gpg-sign`. If the user wants any of those, they ask explicitly.335336---337> Source: [docs-plus/docs.plus](https://github.com/docs-plus/docs.plus) — distributed by [TomeVault](https://tomevault.io).338<!-- tomevault:4.0:skill_md:2026-06-20 -->