> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** A cs-shipped `/merge` skill that closes out a feature branch or task worktree with the full gated ritual: gates, merge --no-ff, gates on the merged result, cleanup, offers. **Architecture:** One SKILL.md (the deliverable is instructions, not shell), registered in ...
Scanned 8/30/2026
Install to Claude Code
npx -y skills add hex/claude-sessions --skill plans --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Plans?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hex-plans)More formats (shields.io, HTML) on the badges page.
# /merge Skill Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** A cs-shipped `/merge` skill that closes out a feature branch or task worktree with the full gated ritual: gates, merge --no-ff, gates on the merged result, cleanup, offers.
**Architecture:** One SKILL.md (the deliverable is instructions, not shell), registered in both CS_SKILLS manifests and pinned by a new contract-test suite. Spec: `docs/superpowers/specs/2026-07-16-merge-skill-design.md`.
**Tech Stack:** Markdown skill, bash test suite, ./build.sh regeneration.
## Global Constraints
- `bin/cs` is GENERATED from `lib/` by `./build.sh` (the CS_SKILLS manifest lives in `lib/00-header.sh`): build BEFORE tests, commit the regenerated `bin/cs` in the SAME commit.
- Both CS_SKILLS manifests (`lib/00-header.sh` AND `install.sh`) gain `merge`; each block carries a KEEP-IN-SYNC comment — edit both.
- The SKILL.md text MUST contain these exact phrases (the contract tests pin them): `git merge --no-ff`, `Preflight gates`, `merged result`, `uncommitted`, `cs <base> --merge <task>`, `Never push`, `until the post-merge gates are green`.
- Safety rails stated in the skill, verbatim intent from the spec: never push; never merge over uncommitted changes; never delete a branch until the post-merge gates are green; never bypass a failing gate; deploy and checkpoint are OFFERS.
- Test discipline: every assert `|| return 1`; `report_results` last; the new suite is auto-discovered by `tests/run_all.sh`'s glob; make the file executable like its siblings.
- bash 3.2 + BSD floor for the test suite.
---
### Task 1: The skill, registration, and contract tests
**Files:**
- Create: `skills/merge/SKILL.md`
- Create: `tests/test_merge_skill.sh`
- Modify: `lib/00-header.sh` (CS_SKILLS block), `install.sh` (CS_SKILLS block)
- Modify: `bin/cs` (regenerated by `./build.sh` — never by hand)
**Interfaces:**
- Consumes: the existing CS_SKILLS blocks (`lib/00-header.sh` ~line 69, `install.sh` ~line 126, both listing `store-secret`, `prose-hygiene`, `rotate`); the test harness (`tests/test_lib.sh`).
- Produces: `skills/merge/SKILL.md` (deployed by install/update to `~/.claude/skills/merge/`); nothing Task 2 consumes programmatically.
- [ ] **Step 1: Write the failing tests**
Create `tests/test_merge_skill.sh` (then `chmod +x` it):
```bash
#!/usr/bin/env bash
# ABOUTME: Tests that the merge skill ships, is registered, and teaches the gated ritual
# ABOUTME: Contract pins for skills/merge/SKILL.md and the CS_SKILLS manifests
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/test_lib.sh"
SKILL="$SCRIPT_DIR/../skills/merge/SKILL.md"
test_merge_skill_exists_with_frontmatter() {
[ -f "$SKILL" ] || { echo " FAIL: skills/merge/SKILL.md missing"; return 1; }
assert_eq "---" "$(head -1 "$SKILL")" "SKILL.md opens with YAML frontmatter" || return 1
assert_file_contains "$SKILL" "name: merge" "frontmatter names the skill" || return 1
assert_file_contains "$SKILL" "description:" "frontmatter has a description" || return 1
}
test_merge_skill_registered_in_both_manifests() {
grep -A 6 '^CS_SKILLS=(' "$SCRIPT_DIR/../lib/00-header.sh" | grep -q 'merge' \
|| { echo " FAIL: merge missing from lib/00-header.sh CS_SKILLS"; return 1; }
grep -A 6 '^CS_SKILLS=(' "$SCRIPT_DIR/../install.sh" | grep -q 'merge' \
|| { echo " FAIL: merge missing from install.sh CS_SKILLS"; return 1; }
}
test_merge_skill_teaches_the_gated_ritual() {
assert_file_contains "$SKILL" "git merge --no-ff" "teaches --no-ff merges" || return 1
assert_file_contains "$SKILL" "Preflight gates" "gates run before the merge" || return 1
assert_file_contains "$SKILL" "merged result" "gates run again after the merge" || return 1
assert_file_contains "$SKILL" "uncommitted" "clean-tree guard stated" || return 1
assert_file_contains "$SKILL" "cs <base> --merge <task>" "wraps the worktree merge verb" || return 1
assert_file_contains "$SKILL" "Never push" "publishing rail stated" || return 1
assert_file_contains "$SKILL" "until the post-merge gates are green" "branch-deletion condition stated" || return 1
}
test_merge_skill_in_built_manifest() {
grep -A 6 '^CS_SKILLS=(' "$SCRIPT_DIR/../bin/cs" | grep -q 'merge' \
|| { echo " FAIL: built bin/cs CS_SKILLS lacks merge (run ./build.sh)"; return 1; }
}
run_test test_merge_skill_exists_with_frontmatter
run_test test_merge_skill_registered_in_both_manifests
run_test test_merge_skill_teaches_the_gated_ritual
run_test test_merge_skill_in_built_manifest
report_results
```
- [ ] **Step 2: Run the suite to verify it fails**
Run: `/bin/bash tests/test_merge_skill.sh`
Expected: all four tests FAIL (no skill file, no registrations).
- [ ] **Step 3: Write the skill and register it**
Create `skills/merge/SKILL.md` with EXACTLY this content:
```markdown
---
name: merge
description: Close out a feature branch or cs task worktree - run the repo's gates, merge --no-ff, re-run gates on the merged result, clean up. Invoke when the user asks to merge a branch or worktree, or to close out a finished feature.
---
Merging is a ritual, not a git command: gates before, merge, gates after,
cleanup only when everything is green. This skill closes out work that is
already reviewed to the user's standard — it is the mechanical closer, not
a quality gate or a review.
## Prerequisites
- A clean tree. If `git status --porcelain` shows uncommitted changes,
offer to commit them first; if the user declines, stop. Never merge
over an uncommitted tree.
- A context (below). If neither applies — already on the default branch
with nothing to merge — say so and stop.
## Detect the context
1. **cs task worktree**: the workspace is a cs session named
`<base>@<task>`, or `git rev-parse --git-dir` differs from
`git rev-parse --git-common-dir` inside a cs-managed worktree
session. The merge verb here is `cs <base> --merge <task>` — it
fuses the session records, merges the branch, and removes the
worktree. This skill wraps it with gates.
2. **Feature branch**: an ordinary checkout on a non-default branch.
The target is the branch it forked from — usually the repo's
default branch (`git merge-base` confirms ancestry); ask the user
when the target is ambiguous.
## Discover the gates
Project instructions govern absolutely. Read CLAUDE.md (and the rules
it imports) for build steps, test commands, generated artifacts, and
deploy steps — a repo that generates a file from source fragments needs
its build run BEFORE tests and the generated file committed with the
branch, exactly as its instructions say.
Without instructions, use the first conventional entry point that
exists: `tests/run_all.sh`, a `Makefile` test target, `package.json`
scripts.test, `cargo test`, `go test ./...`, `pytest`. If none exists,
ask the user once for the gate command and use it for the rest of the
conversation.
## The ritual
1. **Preflight gates** on the branch (worktree context: inside the
worktree): the build step first if the repo has one, then the full
test gate. Everything green before anything merges.
2. **Merge.**
- Feature branch: `git checkout <target>`, then
`git merge --no-ff <branch>` with a merge message summarizing the
feature.
- Task worktree: run `cs <base> --merge <task>` from outside the
worktree; it merges and cleans up the worktree itself.
3. **Gates again on the merged result** (worktree context: in the base
session checkout). A merge that was green on the branch can still
break the target.
4. **Cleanup**: delete the merged feature branch with `git branch -d` —
but not until the post-merge gates are green. The worktree verb
already cleaned up its own.
## When a gate fails
Diagnose it — that is why this is a skill and not a script. Find the
root cause per the project's debugging rules, fix forward on the
branch, and re-run the ritual from the top. A post-merge failure leaves
the merge commit in place: report it with the failing output and let
the user decide between fix-forward and revert. Never bypass, skip, or
weaken a gate to make a merge pass.
## After a green merge — offers, not actions
- If the project instructions document a deploy step, offer to run it
(one question). Never deploy unprompted.
- In a cs session, offer `/checkpoint <feature>-merged`.
## Never
- Never push, to any remote — publishing is the user's decision, made
separately.
- Never merge over uncommitted changes.
- Never delete a branch until the post-merge gates are green, and never
use `git branch -D` on unmerged work.
- Never bypass a failing gate or force a merge.
```
Then register it. In `lib/00-header.sh`, the block
```bash
CS_SKILLS=(
store-secret
prose-hygiene
rotate
)
```
becomes
```bash
CS_SKILLS=(
store-secret
prose-hygiene
rotate
merge
)
```
Make the IDENTICAL change to the `CS_SKILLS=(` block in `install.sh`.
- [ ] **Step 4: Build and run the suites**
Run: `./build.sh && git status --porcelain` — `bin/cs` modified, nothing unexpected.
Run: `/bin/bash tests/test_merge_skill.sh`
Expected: 4/4 PASS.
Run: `/bin/bash tests/test_rotation.sh`
Expected: PASS (its `grep -A 5` manifest checks must still find `rotate` after the block grew).
Run: `/bin/bash tests/run_all.sh`
Expected: all suites PASS — `tests/test_install.sh` directly guards `CS_SKILLS ⇄ skills/ ⇄ bin/cs` sync and must see the new entry everywhere.
- [ ] **Step 5: Commit**
```bash
git add skills/merge/SKILL.md lib/00-header.sh install.sh bin/cs tests/test_merge_skill.sh
git commit -m "feat: /merge skill - the gated merge ritual for branches and task worktrees"
```
---
### Task 2: README
**Files:**
- Modify: `README.md` (two edits)
**Interfaces:**
- Consumes: the skill shipped in Task 1.
- Produces: nothing downstream.
- [ ] **Step 1: Update the installed-skills line**
The line (~68)
```markdown
- Adds `/summary`, `/checkpoint`, `/sweep`, and `/wrap` commands, and the `store-secret` and `prose-hygiene` skills to `~/.claude/`
```
becomes
```markdown
- Adds `/summary`, `/checkpoint`, `/sweep`, and `/wrap` commands, and the `store-secret`, `prose-hygiene`, `rotate`, and `merge` skills to `~/.claude/`
```
(This also repairs the line's existing drift: `rotate` shipped earlier and was never added here.)
- [ ] **Step 2: Point the worktrees section at /merge**
Find the paragraph around line 214 that CONTAINS "`cs myproj --merge <task>` is the way back" (the paragraph itself begins "You don't have to remember the syntax") and append one sentence after its final line ("…won't merge the branch by hand."):
```markdown
The `merge` skill (`/merge` in a conversation) wraps this — and ordinary feature branches — in the full gated ritual: tests before, `--no-ff` merge, tests again on the merged result, cleanup only when green.
```
- [ ] **Step 3: Verify and commit**
Run: `/bin/bash tests/test_merge_skill.sh`
Expected: 4/4 PASS (docs only).
```bash
git add README.md
git commit -m "docs: /merge skill in the skills list and worktrees section"
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!