Atomic commits
Atomic commits on a feature branch with conventional messages — Commit mode for checkpoints, Ship mode for PR. Use when committing, checkpointing, shipping, pushing, or creating a PR.From its SKILL.md
npx -y skills add arndvs/ctrlshft --skill atomic-commitsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.1 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
Atomic Commits
If running interactively (human present), output "Read Atomic Commits skill." to acknowledge. If running with --dangerously-skip-permissions (AFK/unattended), skip acknowledgement and proceed directly.
When to use
Use this skill whenever work has been completed and needs to be committed or shipped. Enforces atomic commits — one logical change per commit with a conventional commit message — on a feature branch, merged via PR. Two modes: Commit (branch + stage + commit) for checkpoints, Ship (+ rebase + push + PR) when ready for review. Trigger any time the user asks to 'commit', 'save progress', 'checkpoint my work', 'ship', 'push', 'create a PR', or has just finished implementing a feature, fix, or refactor.
Core Principles
- One logical change per commit — each commit does exactly one thing
- Self-contained — every commit leaves the codebase in a working state
- Independently revertable — any commit can be reverted without breaking other commits
- Descriptive — the commit message fully explains what changed and why
- Branch-isolated — work happens on an
ai/feature branch, merged via PR
Two Modes
This skill operates in two modes depending on the user's intent:
| Mode | When | Steps |
|---|---|---|
| Commit | Default. User says "commit", "save progress", "checkpoint my work" | 0 → 1 → 2 → 3 |
| Ship | User says "ship", "push", "PR", "create a pull request", "open a PR" | 0 → 1 → 2 → 3 → 4 → 5 → 6 |
During multi-slice work, use Commit mode at each slice. Use Ship mode only when all slices are done and the work is ready for review.
Workflow
0. Ensure a feature branch
Before any staging, make sure you're on a feature branch — never commit directly to dev, main, or master.
CURRENT_BRANCH="$(git branch --show-current)"
If already on an ai/* branch or any non-base branch (e.g. feature/foo, bugfix/bar): reuse it — add commits to the current branch.
If on a base branch (dev, main, or master): create a new feature branch:
BASE_BRANCH="$CURRENT_BRANCH"
# Branch name format: ai/<type>/<short-desc>
# <type> matches the primary conventional commit type (feat, fix, refactor, docs, chore)
# <short-desc> is 2-4 kebab-case words describing the work
git checkout -b "ai/<type>/<short-desc>"
Examples:
ai/feat/compaction-guard-hooksai/fix/pagination-off-by-oneai/docs/sync-readme-with-projectai/refactor/extract-date-helpers
1. Survey the diff
Start by reviewing everything that changed:
git diff # unstaged changes
git diff --staged # already staged changes
git status # full picture of modified/untracked files
Identify natural "seams" — boundaries between distinct logical changes. These become your commit boundaries.
2. Group into logical units
Decompose the diff into an ordered commit plan. Each unit should have a single clear purpose:
1. feat(auth): add JWT refresh token rotation
2. test(auth): cover token rotation edge cases
3. chore(config): add REFRESH_SECRET env variable
If a change touches unrelated concerns, split the file-level staging accordingly using git add -p for partial file staging.
3. Stage and commit each unit
Work through each logical unit one at a time:
git add <specific-files> # stage only what belongs to this commit
git add -p <file> # stage partial file changes if needed
git diff --staged # confirm exactly what's going in
git commit -m "<type>(<scope>): <summary>"
Never use git add . blindly — always confirm what's staged before committing.
4. Sync with base branch (Ship mode only)
After all commits are made, rebase onto the base branch to catch conflicts early:
# Detect the base branch — check which of dev/main/master exists on remote
for candidate in dev main master; do
if git rev-parse --verify "origin/$candidate" >/dev/null 2>&1; then
BASE_BRANCH="$candidate"
break
fi
done
BASE_BRANCH="${BASE_BRANCH:-main}"
git fetch origin "$BASE_BRANCH"
git rebase "origin/$BASE_BRANCH"
If conflicts arise:
- Resolve each conflict manually — never auto-accept theirs or ours blindly
git add <resolved-file>after each resolutiongit rebase --continue- If the conflict is too complex,
git rebase --abortand ask the user
5. Push and create PR (Ship mode only)
Pre-push gate — run before git push. Do not push while any gate is red.
- Branch safety — confirm you are NOT on a base branch (
dev,main,master). - Quality gates — run the repo's detected feedback loops (tests, lint, typecheck via
package.jsonscripts,Makefile, etc.). If none exist, say so explicitly rather than skipping silently. - Secret scan — scan the staged/recent diff for secret-like content and filenames (
*.pem,*.key,.env,ghp_/github_pat_/sk-/AKIA, private keys). Abort the push if anything matches.
Only after all three pass:
git push -u origin HEAD
Then create a pull request targeting the base branch. Requires gh CLI:
if ! command -v gh >/dev/null 2>&1; then
echo "gh CLI not found — push completed. Create the PR manually."
else
gh pr create \
--base "$BASE_BRANCH" \
--title "<type>(<scope>): <summary of all changes>" \
--body "## Changes
- <bullet summary of each commit>
## Verification
- [ ] Tests pass
- [ ] Types check
- [ ] Reviewed diff"
fi
The PR title should summarize the full feature branch, not individual commits. Use the conventional commit format.
After creating the PR: report the PR URL to the user. Do not merge — the PR exists for review.
6. Request Copilot review (Ship mode only)
After the PR is created (or already exists), request a Copilot review. Do not stop at "no MCP/tool available" — use the GitHub CLI as the reliable fallback path.
Preferred order:
- If a dedicated Copilot-review tool is available, use it.
- Otherwise, use
ghagainst the explicit repository and PR number:
gh pr edit <PR_NUMBER> -R <OWNER>/<REPO> --add-reviewer copilot-pull-request-reviewer
- Verify the request:
gh pr view <PR_NUMBER> -R <OWNER>/<REPO> --json reviewRequests,reviews
- If GitHub accepts the command but
reviewRequestsdoes not show a Copilot reviewer, verify through the REST pull request endpoint before retrying. Some GitHub CLI JSON views omit the Copilot reviewer even when the direct REST payload includes a bot login. GitHub may returnCopilotorcopilot-pull-request-reviewer[bot]inrequested_reviewers[].login, so use an anchored, case-insensitive match:
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER> --jq '[.requested_reviewers[]?.login] | map(select(. != null)) | any(test("^(Copilot|copilot-pull-request-reviewer)(\\[bot\\])?$"; "i"))'
In PowerShell, avoid gh api --jq quote escaping problems by parsing the REST JSON directly:
$pull = gh api "repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>" | ConvertFrom-Json
$logins = @($pull.requested_reviewers | ForEach-Object { $_.login })
[bool]($logins | Where-Object { $_ -match '^(Copilot|copilot-pull-request-reviewer)(\[bot\])?$' })
- If the REST payload also does not include a Copilot reviewer bot login, retry the reviewer request once with the explicit PR reviewer app login:
gh pr edit <PR_NUMBER> -R <OWNER>/<REPO> --add-reviewer copilot-pull-request-reviewer
- If no Copilot reviewer bot login is present in
requested_reviewersafter the retry, report a manual fallback with the exact non-secret error and the PR URL.
Never post @copilot review as a fallback. On GitHub.com that comment can start the Copilot SWE/cloud-agent task flow instead of the Copilot Pull Request Reviewer, which may fail independently and does not guarantee a PR code review.
This ensures every PR gets at least one Copilot review pass before human review.
Conventional Commit Message Format
<type>(<scope>): <short imperative summary>
[optional body: explain WHY, not what — the diff shows what]
[optional footer: breaking changes, issue refs]
Types
| Type | When to use |
|---|---|
feat | New feature or capability |
fix | Bug fix |
refactor | Code restructuring with no behavior change |
test | Adding or updating tests |
docs | Documentation only |
chore | Tooling, deps, config, build scripts |
style | Formatting, whitespace (no logic change) |
perf | Performance improvement |
revert | Reverting a prior commit |
Rules
- Summary line: 50 chars or fewer, imperative mood ("add", not "added" or "adds")
- No period at end of summary
- Body: wrap at 72 chars, explain motivation and context
- Reference issues in footer:
Closes #42,Fixes #17
Examples
feat(auth): add JWT refresh token rotation
Tokens now rotate on each use to limit exposure window.
Previous single-token approach left sessions vulnerable
to replay attacks if a token was intercepted.
Closes #88
fix(api): return 404 instead of 500 for missing user
refactor(utils): extract date formatting into shared helper
What Makes a Good Atomic Commit?
✅ Good — single, clear purpose:
fix: correct off-by-one in pagination offsetfeat(search): add debounce to search inputtest: cover edge cases for empty cart checkout
❌ Bad — too broad or mixed:
fix stuffWIPfeat: add search, fix bug, update styles, refactor utils
If your message needs "and" to describe what changed — split it into two commits.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.