brainstorming
The Socratic spec-refinement front of /feature, and the planning front of /sprint. Routed to BEFORE any code — it takes a one-line idea and drives it to an…
Finish an already-merged branch. Proves the branch is contained in the fetched default, classifies leftover artifacts as unique / redundant / superseded, returns to a clean --ff-only default checkout, and deletes the merged local branch — every discard confirmed per item. Routed
$ npx -y skills add arbiterForge/codeArbiter --skill post-merge-cleanup --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/post-merge-cleanupContext preview
The summary Claude sees to decide when to auto-load this skill.
Finish an already-merged branch. Proves the branch is contained in the fetched default, classifies leftover artifacts as unique / redundant / superseded, returns to a clean --ff-only default checkout, and deletes the merged local branch — every discard confirmed per item. Routed
name: post-merge-cleanup
description: Finish an already-merged branch. Proves the branch is contained in the fetched default, classifies leftover artifacts as unique / redundant / superseded, returns to a clean --ff-only default checkout, and deletes the merged local branch — every discard confirmed per item. Routed to by {{CMD:cleanup}}.The walk back from a merged PR. Routed to by `{{CMD:cleanup}}`.
The work has landed on the default branch. What is left is local: the branch you are standing on, and whatever the run left in the tree. This skill returns you to a clean, fast-forwarded default checkout without losing anything you have not explicitly agreed to lose.
**It is ordinary lifecycle work and never needs `{{CMD:override}}`.** When it cannot proceed, it names the gate that stopped it. Issue #308 recorded the alternative: with no owner for this transition, the routing loop reached for `{{CMD:chore}}`, then for `{{CMD:override}}` — a bypass manufactured to cover a coverage hole.
Read this, or STOP and surface the gap — never guess the default-branch name:
If HEAD is already the default branch, there is no transition to make. Report the dirty state read-only and exit; branch pruning across *other* branches belongs to `{{CMD:standup}}`.
A branch that looks merged is not merged. Establish it against the network, not against a stale local ref. This repo squash-merges by default, so SHA-ancestry alone is the wrong instrument for most landings: it holds for a fast-forward or a merge-commit landing, but a squash merge writes a new commit with no SHA lineage back to the branch, and `--is-ancestor` will report non-zero for a branch that landed cleanly. The gate is **content-containment**, proven by whichever instrument fits the landing, always reported as a fact:
1. `git fetch` the remote holding the default branch. A fetch that fails STOPs — an unfetched comparison proves nothing. 2. Prove containment with two primary instruments plus a fallback, tried in order: 1. **Ancestry** — `git merge-base --is-ancestor HEAD origin/<default>`. Holds for a fast-forward or merge-commit landing. If it holds, that is the proof: report it and move on. 2. **Squash-merge proof via the PR record** — if ancestry fails, run `gh pr list --head "$(git branch --show-current)" --state merged --json number,state,headRefOid,mergeCommit`. A `MERGED` PR whose `headRefOid` equals local `git rev-parse HEAD` proves every commit on this branch rode that PR's squash into the default branch. Report the PR number, that `headRefOid == HEAD`, the merge commit (`mergeCommit.oid` in that JSON), **and** the ancestry check's negative result — all as facts, not as a failure. Corroborate with `git diff --quiet origin/<default> HEAD` when it happens to hold; a **non-empty** diff alongside a valid PR proof is normal (the default branch advanced since the merge landed) and is reported as a fact, never treated as a failure. The PR-record identity — `MERGED` plus `headRefOid == HEAD` — is the load-bearing proof; the diff is corroboration only when it happens to be fresh, never a requirement. 3. **Fallback when `gh` is unavailable or no PR record exists** — `git diff --quiet origin/<default> HEAD` (the tree is byte-identical to the fetched default) is an acceptable fallback proof. Report it as such. 3. Report whichever instrument held as a fact — the default branch, the fetched SHA, and which of the three proofs established containment.
If none of the three hold, STOP exactly as today. Name the un-landed commits and route to `{{CMD:pr}}`; nothing is deleted here.
> Deliberate deviation from issue #586's suggested contract: that suggestion > required the squash-merge proof's diff to be empty. That requirement > re-breaks this gate the moment any later PR merges to the default branch — > the common state, not an edge case. The PR-record identity is what proves > containment; the diff is corroboration, demoted from requirement to fact.
Gate: the remote is fetched and HEAD is proven contained in the fetched default branch — by ancestry, by the PR-record squash proof, or by the byte-identical fallback — or the skill has stopped.
List every dirty tracked change, every untracked file, and every stash reachable from this branch. Classify each into exactly one of three, and say *why* for each:
regenerated build artifact whose generator is committed and rerunnable. Safe to remove because removing it loses no information.
better shape. Name what supersedes it.
proven redundant or superseded IS unique. Uncertainty classifies as unique, not as redundant.
Present the classification before touching anything. A file whose class you cannot establish is reported as unique with the reason you could not classify it.
Gate: every dirty, untracked, and stashed artifact carries a class and a stated reason, with unclassifiable items counted as unique.
Per item, in the order Phase 2 listed them. Never batch:
transition, move it aside, or leave it in place and stop the cleanup. It is discarded only if the user explicitly confirms *that item by name*, with the Phase 2 reasoning in view.
it is and why it is safe. Declining leaves it exactly where it is.
A stash is never dropped
When you can't trust yourself with your code base, trust Arbiter.
Repo: arbiterForge/codeArbiter
The Socratic spec-refinement front of /feature, and the planning front of /sprint. Routed to BEFORE any code — it takes a one-line idea and drives it to an…
The only path to a commit. Routed to when the user invokes /commit or otherwise instructs codeArbiter to persist staged changes. Nine gated phases —…
Optional manual drift audit — report stale provenance-tracked docs (via _provenancelib drift detection across .codearbiter/.provenance/), then per stale doc…
The brownfield back-fill. Routed to by /create-context, and by startup when .codearbiter/CONTEXT.md lacks the <!--INITIALIZED--> body marker but source code…
The banned-primitive gate. Routed to when changed code hashes, signs, encrypts, derives keys, generates security-relevant randomness, configures TLS, or…
Investigate-then-decide root-cause analysis for a defect whose cause is unknown (distinct from /fix, which assumes a known bug). Five gated phases: capture,…