safe-remove · git:20260316.52674e3 · 2026-03-16 · sha256 55a5b45577ec368b

safe-remove git:20260316.52674e3A

Immutable. This exact content is served forever at /api/v1/blob/55a5b45577ec368b.

---
name: safe-remove
description: "Safely remove plugin assets (skill/command/agent/rule/script/hook) with dependency detection and reference cleanup. Use when: user says 'remove skill', 'delete command', 'deprecate', 'clean up unused', or /safe-remove. Not for: code refactoring (use /simplify), feature removal requiring architecture changes (manual)."
disable-model-invocation: true
allowed-tools: Bash(bash:*), Bash(git:*), Read, Grep, Glob, Edit, Write, AskUserQuestion
---

# Safe Remove

Safely remove plugin assets by discovering dependencies, classifying impact, and executing removal with verification.

## Input

`/safe-remove <type> <name> [--execute] [--dry-run]`

| Argument | Description | Default |
|----------|-------------|---------|
| `<type>` | Asset type: `skill`, `command`, `agent`, `rule`, `script`, `hook` | Required |
| `<name>` | Asset name (e.g., `create-skill`, `strict-reviewer`) | Required |
| `--execute` | Apply removal (with AskUserQuestion confirmation) | off |
| `--dry-run` | Output plan only (default behavior) | on |

> If both `--dry-run` and `--execute` are provided, `--dry-run` wins (safe default).

## Workflow

```mermaid
sequenceDiagram
    participant U as User
    participant S as /safe-remove
    participant C as Codebase

    S->>C: Phase 1: Resolve target files
    S->>C: Phase 2: Build reference graph
    S->>S: Phase 3: Classify (BLOCKER/PATCHABLE)
    alt Has BLOCKER
        S->>U: HALT — show blockers with file:line
    else Dry-run (default)
        S->>U: Output removal plan
    else --execute
        U->>S: AskUserQuestion approval
        S->>C: Phase 4: Patch → Delete
        S->>C: Phase 5: Verify
        S->>U: Removal complete
    end
```

### Phase 1: Resolve Target

Validate `<type>` and locate canonical files for the asset.

| Type | Primary Files | Secondary Files |
|------|--------------|-----------------|
| `skill` | `skills/<name>/` (entire directory) | `commands/<name>.md` (if exists) |
| `command` | `commands/<name>.md` | — |
| `agent` | `agents/<name>.md` | — |
| `rule` | `rules/<name>.md` | `.claude/rules/<name>.md` (mirror) |
| `script` | `scripts/<name>.*` | — |
| `hook` | Entry in `hooks/hooks.json` | Hook script file |

If target not found, output error: `Target not found: <type> <name>` and stop.

### Phase 2: Build Reference Graph

Scan the entire codebase for references to the target. Use type-specific patterns from `references/removal-policy.md`.

```bash
# Core scan — find all references
grep -rn "@skills/<name>/" commands/ --include="*.md"
grep -rn "^skills:.*<name>" agents/ --include="*.md"
grep -rn "/<name>" CLAUDE.md .claude/CLAUDE.md CLAUDE.template.md
grep -rn "/<name>" README*.md
grep -rn "/<name>\|<name>" rules/ skills/ --include="*.md"
grep -rn "<name>" hooks/hooks.json
```

### Phase 3: Classify Impacts

Apply 2-tier classification per `references/removal-policy.md`:

| Tier | Definition | Action |
|------|-----------|--------|
| **BLOCKER** | Structured runtime binding — removal breaks execution | HALT with file:line details |
| **PATCHABLE** | Prose/documentation reference — safe to auto-edit | Include in patch plan |

### Phase 4: Apply (--execute only)

**Requires AskUserQuestion confirmation before any changes.**

Execution order (patches first, deletes last):

1. **Patch** PATCHABLE references:
   - Remove table rows from CLAUDE.md, `.claude/CLAUDE.md`, CLAUDE.template.md
   - Remove/update entries in README.md + locale variants (count + detail row)
   - Update prose mentions in other skills/rules
2. **Delete** target files:
   - For `skill` type: remove entire `skills/<name>/` directory + `commands/<name>.md`
   - For other types: remove primary + secondary files per Phase 1 table
   - Remove empty directories after deletion

> Note: `.claude/CLAUDE.md` must be patched directly — do not rely on hook auto-sync for content removal.

### Phase 5: Verify

Run type-specific verification from `references/removal-policy.md`:

```bash
# Verify no residual references (excluding archived docs)
grep -rn "@skills/<name>/" . --include="*.md" | grep -v "archived/"
grep -rn "^skills:.*<name>" agents/ --include="*.md"
grep -rn "/<name>" CLAUDE.md README*.md | grep -v "archived/"
```

If residual references found, report them. If clean, output `Verification passed`.

## Output Format

### Dry-run Plan

```markdown
## Safe Remove Plan: <type> <name>

### Target Files (to delete)
| File | Status |
|------|--------|
| skills/<name>/SKILL.md | DELETE |
| commands/<name>.md | DELETE |

### BLOCKER References (must resolve first)
| File:Line | Pattern | Why |
|-----------|---------|-----|
| commands/foo.md:9 | @skills/<name>/SKILL.md | Command binding |

### PATCHABLE References (auto-fix)
| File:Line | Current | Patch |
|-----------|---------|-------|
| CLAUDE.md:90 | \| /name \| desc \| | REMOVE ROW |
| README.md:308 | \| /name \| desc \| | REMOVE ROW |

### Verdict
- BLOCKER count: N → ⛔ HALT (resolve blockers first)
- BLOCKER count: 0, PATCHABLE count: M → ✅ Ready to execute
```

## Prohibited

- Auto-triggering (always explicit invocation only)
- Deleting without `--execute` flag + user confirmation
- Removing assets referenced in auto-loop rules without user acknowledgment
- Force-deleting when BLOCKERs exist
- Modifying files outside the removal scope (no side-effect changes)

## References

| File | Purpose | When to Read |
|------|---------|-------------|
| `references/removal-policy.md` | BLOCKER/PATCHABLE classification rules + per-asset-type matrix | Always (Phase 2-5) |

## Examples

```
/safe-remove skill create-skill
→ Dry-run plan showing 3 files to delete + 12 PATCHABLE references

/safe-remove skill create-skill --execute
→ AskUserQuestion → patch 12 refs → delete 3 files → verify clean

/safe-remove agent unused-agent
→ Dry-run: 1 file to delete, check for BLOCKER in agents skills: field

/safe-remove command old-command --execute
→ Quick removal: 1 file + CLAUDE.md row + README rows
```