# Cleanup

> Post-merge workflow resolution. Verifies PR merge status, backfills synthesis metadata, force-resolves review statuses, transitions to completed, and cleans up worktrees/branches. Use when the user says 'cleanup', 'resolve workflow', 'mark as done', or runs /cleanup. Do NOT use before PRs are merged.

- Skill: `lvlup-sw/cleanup` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add lvlup-sw/cleanup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lvlup-sw/cleanup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: lvlup-sw (https://skillmd.com/u/lvlup-sw)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lvlup-sw/cleanup

---


# Cleanup Skill

## VCS Provider

This skill uses VCS operations through Exarchos MCP actions (`list_prs`, `get_pr_comments`, etc.).
These actions automatically detect and route to the correct VCS provider (GitHub, GitLab, Azure DevOps).
No `gh`/`glab`/`az` commands needed — the MCP server handles provider dispatch.

## Overview

Resolve merged workflows to `completed` state in a single operation. Replaces the manual multi-step process of navigating HSM guards after PR stacks merge.

## Batch Pruning for Stale Workflows

For bulk cleanup of accumulated stale or abandoned workflows (as opposed to resolving a single merged workflow), use `@skills/prune/SKILL.md`. That skill invokes `exarchos_orchestrate prune_stale_workflows` in dry-run mode, displays candidates, and applies after user confirmation. Safeguards automatically skip workflows with open PRs or recent commits.

**Rule of thumb:** cleanup is per-workflow (one merged feature → `completed`); prune is bulk (N inactive workflows → `cancelled`). They are complementary, not alternatives.

## Triggers

Activate this skill when:
- User runs `cleanup` command
- User says "cleanup", "resolve workflow", "mark as done"
- PR stack has merged and workflow needs resolution
- User wants to close out a completed feature

## Prerequisites

- Active workflow in any non-terminal phase
- All PRs merged on GitHub

## Process

### 1. Identify Target Workflow

Read workflow state to get current phase and metadata:
```typescript
exarchos:exarchos_workflow({ action: "get", featureId: "<id>" })
```

If featureId not provided, use pipeline view to list active workflows:
```typescript
exarchos:exarchos_view({ action: "pipeline" })
```
The pipeline view is **repo-scoped by default** — only the caller's repo. A workflow started in another repo won't appear; when the response reports `unscopedTotal` greater than `page.total`, re-query with `scope: "all"` to reveal the hidden rows.

### 2. Verify Merge Status

For each PR associated with the workflow, verify it is merged.

**Primary method** — VCS MCP action:
```typescript
exarchos_orchestrate({ action: "list_prs", state: "merged" })
```

For individual PR details, use `exarchos_orchestrate({ action: "get_pr_comments", prId: "<number>" })` or the VCS provider's native API.

Collect from merged PRs:
- `prUrl`: The PR URL (or array of URLs for stacked PRs)
- `mergedBranches`: The head branch names that were merged

**Safety check:** If ANY PR is not merged, abort with clear error message.

For detailed verification guidance, see `references/merge-verification.md`.

### 2.5. Post-Merge Regression Check (Advisory)

After verifying merge status, run the post-merge regression check:

```typescript
exarchos_orchestrate({
  action: "check_post_merge",
  featureId: "<id>",
  prUrl: "<url>",
  mergeSha: "<sha>"
})
```

This check is **advisory** — findings are reported but do not block cleanup. If findings are detected, log them for the user's awareness before proceeding.

### 3. Invoke Cleanup Action

Call the MCP cleanup action with collected data:
```typescript
exarchos:exarchos_workflow({
  action: "cleanup",
  featureId: "<id>",
  mergeVerified: true,
  prUrl: "<url-or-array>",
  mergedBranches: ["branch1", "branch2"]
})
```

This single call:
- Backfills `synthesis.prUrl` and `synthesis.mergedBranches`
- Force-resolves all blocking review statuses to `approved`
- Transitions to `completed` via universal cleanup path
- Emits `workflow.cleanup` event to event store

### 4. Worktree Cleanup

Reclaim all worktrees associated with the workflow through the governed
garbage-collector `prune_worktrees` — **not** ad-hoc `git worktree remove`.

> **GC cadence — after synthesize (INV-12).** Governed worktrees become
> reclaimable once a workflow reaches synthesis; cleanup runs post-merge (after
> synthesize completes), so this is the natural point to apply the reclamation.
> The `next_actions` projection surfaces the same `prune_worktrees` dry-run
> affordance from synthesis onward.

`prune_worktrees` runs the fail-closed safety ladder (it refuses to destroy a
worktree with unsaved work) and auto-emits the `worktree.remove.requested` /
`worktree.remove.executed` pair per deleted worktree. Dry-run first (the default
— reports candidates + reclaimable bytes + grouped skip reasons, deletes
nothing), then apply:

```typescript
// Dry-run (default) — preview candidates, delete nothing
exarchos:exarchos_orchestrate({ action: "prune_worktrees", repoRoot: "<repo-root>" })

// Apply — reclaim the delete-eligible candidates
exarchos:exarchos_orchestrate({ action: "prune_worktrees", repoRoot: "<repo-root>", dryRun: false })
```

Handle gracefully if worktrees are already removed. If the GC skips a worktree
(e.g. uncommitted work), resolve the reported reason before re-applying — never
force-remove a dirty worktree by hand.

### 5. Branch Sync

Remove merged local branches:
```bash
git fetch --prune
git branch -d <merged-branch-1> <merged-branch-2> ...
```

### 6. Report Completion

Output summary:
```markdown
## Cleanup Complete

**Feature:** <featureId>
**Transition:** <previousPhase> → completed
**PRs merged:** <count>
**Worktrees removed:** <count>
**Branches synced:** ✓
```

## Dry Run

Use `dryRun: true` to preview what cleanup would do without modifying state:
```typescript
exarchos:exarchos_workflow({
  action: "cleanup",
  featureId: "<id>",
  mergeVerified: true,
  dryRun: true
})
```

## Error Handling

| Error | Cause | Resolution |
|-------|-------|------------|
| STATE_NOT_FOUND | Invalid featureId | Check pipeline view for active workflows (repo-scoped by default; add `scope: "all"` if the workflow may live in another repo) |
| ALREADY_COMPLETED | Workflow already done | No action needed |
| INVALID_TRANSITION | Workflow is cancelled | Cannot cleanup cancelled workflows |
| GUARD_FAILED | mergeVerified is false | Verify PRs are merged before cleanup |

## Anti-Patterns

| Don't | Do Instead |
|-------|------------|
| Use cleanup as escape hatch during implementation | Only use after PRs are merged |
| Skip merge verification | Always verify via GitHub API |
| Manually navigate HSM guards post-merge | Use cleanup |
| Leave worktrees after cleanup | Include worktree removal in process |

## Exarchos Integration

The cleanup action auto-emits events — do NOT manually emit:
- `workflow.cleanup` — emitted by the MCP cleanup action for the phase change to completed

