kramme-cc-workflow/skills/kramme:git:recreate-commits/SKILL.md
Use when asked to recreate commits with narrative-quality history on the current branch. Not for merged branches or shared branches others have based work on — it rewrites history and uses --force-with-lease when remote synchronization is enabled.
npx skillsauth add abildtoft/kramme-cc-workflow kramme:git:recreate-commitsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reimplement the current branch with a clean, narrative-quality git commit history suitable for reviewer comprehension. By default, recreate commits on the current branch (not a new clean branch).
This rewrites history and requires a force-push to sync any existing remote history unless --no-push delegates that synchronization to a parent workflow. It is user-triggered only (it does not auto-invoke).
When not to use: Don't run this on a branch that is already merged, on a protected or shared base branch, or on a branch other contributors have based active work on without coordinating first — the recreation rewrites history and the remote can only be updated with a force-push.
Flags:
--auto — Skip the granularity question and automatically choose the best granularity based on diff size and complexity.--granular — Force atomic-level decomposition. Skips the granularity question. Use for very large PRs where 100+ commits are appropriate.--base <branch> — Use <branch> as the base instead of auto-detecting. Without this flag, the skill tries to detect the base from an existing GitHub pull request, then from origin/HEAD, then from origin/main or origin/master.--after <commit> — Only recreate commits after <commit>, keeping all earlier history intact. Accepts any valid git ref (SHA, short SHA, HEAD~3, etc.). The commit must exist and be an ancestor of HEAD. When set, the diff scope becomes <commit>..HEAD and the reset point becomes <commit> instead of the merge base.--force-backup — Allow the resolution script to replace an existing <branch>-recreate-backup branch after you have inspected that backup and confirmed it is safe to move. Without this flag, an existing backup makes the script stop so retries cannot destroy the original recovery point.--no-push — Rewrite and verify the local branch but do not mutate its remote. Report that synchronization is delegated to the caller. kramme:pr:create always uses this mode so description generation and confirmation finish before the only remote update.--authorize-history-rewrite — Explicit authorization for this invocation to skip the reset confirmation and, unless --no-push is also set, the lease-protected force-push confirmation. It never bypasses backup creation, branch validation, final-tree identity, or force-with-lease. --auto alone is not authorization.Validate and resolve the base — run the shared resolution script from the user's current repository. Do not cd into the plugin directory; the script intentionally inspects and mutates the current git repository in --backup mode. Pass through the skill's --base/--after/--force-backup values as BASE_FLAG/AFTER_ARG/FORCE_BACKUP. It determines the base ref, validates every precondition, fast-forwards a matching local base branch to its remote, and creates a recovery backup of the current tip before anything destructive happens:
ARGS=()
ARGS+=(--backup)
[ -n "${BASE_FLAG:-}" ] && ARGS+=(--base "$BASE_FLAG")
[ -n "${AFTER_ARG:-}" ] && ARGS+=(--after "$AFTER_ARG")
[ "${FORCE_BACKUP:-0}" = "1" ] && ARGS+=(--force-backup)
RESOLVED=$("${CLAUDE_PLUGIN_ROOT}/scripts/resolve-base.sh" "${ARGS[@]}") || {
echo "Base resolution failed; see the message above and stop." >&2
exit 1
}
eval "$RESOLVED"
On success the script prints shell-quoted assignments that eval loads into the environment: BASE_REF, BASE_BRANCH, MERGE_BASE, AFTER_COMMIT, RESET_POINT, ORIGINAL_TIP, and BACKUP_REF. On any failure it writes the reason to stderr and exits non-zero — stop and surface that message; do not continue.
The script enforces these preconditions, aborting on the first that fails: it is being run from the user's repository instead of the repository that contains the skill script, clean working tree, HEAD on a feature branch (not detached, not the base branch), BASE_REF resolves to a commit, a merge base exists with HEAD, --after (if given) resolves and is an ancestor of HEAD, a matching local base branch fast-forwards cleanly to its remote (it aborts rather than reconcile a diverged local base), and the recovery backup branch does not already exist unless --force-backup was explicitly passed.
It records two values you rely on later: ORIGINAL_TIP (the pre-reset HEAD, the byte-identical target end state) and BACKUP_REF (a branch pointing at ORIGINAL_TIP). Recover the original branch at any time with git reset --hard "$BACKUP_REF". If the backup already exists, inspect it before retrying; only pass --force-backup after confirming the previous recovery point can be replaced.
Analyze the diff
$RESET_POINT..HEAD (this is $AFTER_COMMIT..HEAD when --after was given, otherwise $MERGE_BASE..HEAD).Prepare the branch
{branch_name}-clean branch unless explicitly requested.{branch_name}-clean from $RESET_POINT.Plan the commit storyline
Assess diff size and determine granularity. After analyzing the diff, assess whether the PR is large (many files changed, significant lines added/removed, multiple distinct features or areas touched).
If --granular was passed, use Atomic granularity unconditionally — do not ask the user. If --auto was passed (without --granular), choose the most appropriate granularity yourself based on diff size and complexity — do not ask the user. Otherwise, if the diff is large, ask the user which granularity level they want before planning:
For normal-sized PRs (without --auto), skip this question and plan as usual.
Use recursive decomposition to plan commits:
Flatten the tree into a linear commit sequence that tells a coherent narrative — each step should reflect a logical stage of development, as if writing a tutorial.
Reimplement the work
--authorize-history-rewrite was passed, confirm with the user that you may rewrite the current branch's history before resetting. The original tip is preserved at BACKUP_REF, so this is recoverable, but the reset is destructive to the working tree. Explicit authorization skips only this prompt, not the backup or validation requirements.git reset --hard "$RESET_POINT". (RESET_POINT is AFTER_COMMIT when --after was given, otherwise the merge base.)$ORIGINAL_TIP rather than retyping it (retyping is how extra lines and drift creep in):
git checkout "$ORIGINAL_TIP" -- <paths>, then commit.git checkout -p "$ORIGINAL_TIP" -- <path> (or git restore -p --source "$ORIGINAL_TIP" <path>) and stage only the hunks that belong to this commit.Verify correctness
git diff "$ORIGINAL_TIP" HEAD must be empty. If it is non-empty, the recreation is wrong — fix it before continuing (recover with git reset --hard "$BACKUP_REF" if you need to start over).git commit --no-verify (skips commit-time hooks such as linters and formatters) is allowed only when necessary to get past a known-failing intermediate state. Individual commits need not pass tests, but this should be the exception, not the rule. Note this is distinct from git push --no-verify, which skips pre-push hooks (see the push step).It is essential that the end state of the branch be byte-identical to the original end state ($ORIGINAL_TIP); intermediate commits not building is tolerable, a wrong end state is not.
Sync the remote (only when enabled, with confirmation or explicit authorization)
--no-push was passed, do not run any push command. Report remote synchronization as delegated in POTENTIAL CONCERNS, then continue to the final summary.--authorize-history-rewrite was passed, confirm with the user, and warn explicitly if others may have based active work on this branch. Explicit authorization skips the prompt but not the warning or safety checks.git push --force-with-lease (never plain --force), so a concurrent remote update aborts the push instead of silently overwriting it.POTENTIAL CONCERNS.Emit end-of-run change summary
After the final commit lands and the branch matches the original end state, print a Change Summary block to the conversation (not to a commit). This is a required final emission — the skill is not done until it appears:
CHANGES MADE:
- <verb-led list of the new commit storyline, e.g. "split auth middleware into 4 steps">
THINGS I DIDN'T TOUCH:
- <anything noticed while rewriting that was deliberately left in its original shape; "None" if nothing>
POTENTIAL CONCERNS:
- <risk items for the user: force-push needed, --no-verify usage, commits that individually don't build; "None" if nothing>
Label casing must match exactly: CHANGES MADE, THINGS I DIDN'T TOUCH, POTENTIAL CONCERNS. All three blocks must be present even if one is "None".
BACKUP_REF so reviewers can compare.Never add AI attribution to any commit subject or body. Do not include generated-with banners (e.g. 🤖 Generated with ...) or Co-Authored-By: trailers that name an AI assistant.
Use these uppercase markers when reasoning about the recreation plan and reporting progress. One marker per line, no decoration:
STACK DETECTED: origin/main, diff scope HEAD~12..HEAD, medium granularity selected.git diff. UNVERIFIED: the test suite passes at each commit — only the final state was diffed.NOTICED BUT NOT TOUCHING: a stale comment in an untouched file — outside the recreation scope.CONFUSION: can't tell if the Phase 2 rename was intentional or accidental — folded into the rename commit.MISSING REQUIREMENT: granularity not specified and --auto not passed — asking the user before planning.PLAN: 12 commits across 3 groupings — auth middleware, user API, tests.Lies you'll tell yourself mid-recreation. Each has a correct response:
--no-verify through it." → Allowed as the exception, not the rule. Surface it in POTENTIAL CONCERNS or restructure so builds pass.Pause and reshape the storyline if any of these are true:
--force-with-lease, or without either explicit confirmation or --authorize-history-rewrite.Co-Authored-By: Claude.Before declaring the recreation done, self-check:
git diff "$ORIGINAL_TIP" HEAD is empty — end state matches exactly.--no-verify usage, if any, is called out in POTENTIAL CONCERNS.CHANGES MADE / THINGS I DIDN'T TOUCH / POTENTIAL CONCERNS block was emitted.tools
Requires Linear MCP. Implements one Linear issue end to end, selects applicable code-review, convention, and PR-refactor gates, runs them to bounded convergence, verifies, and optionally opens the PR and iterates on CI and review feedback until green. Use when the user wants a single Linear issue taken from implementation through a clean Pull Request. Not for implementation-only work, SIW-tracked issues, stacked PRs, existing PR updates, or post-merge rollout.
development
Reviews PR and local changes for convention drift and overcaution against documented rules and mined peer-file practice. Use for new patterns, dependencies, abstractions, or defensive complexity that departs from established practice; every finding cites evidence. Supports --inline. Not for general code quality (use kramme:pr:code-review) or spec review (use kramme:siw:spec-audit --team).
testing
Charts huge or foggy initiatives into a local `.context` decision map and resolves one typed frontier ticket per session until the work is ready for SIW or another execution workflow. Use when the route to a destination cannot fit in one agent session or parallel workspaces need coordinated planning state. Not for clear specs, ordinary issue decomposition, implementation, or Linear-native tracking.
development
Investigates a question against primary sources and saves one cited Markdown artifact. Use for reading legwork: official docs/API facts, source-code or spec checks, standards, and first-party service behavior before planning or implementation. Not for making product or architecture decisions, implementing code, broad web search, secondary blog summaries, or uncited answers.