| name | cleanup |
| description | 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. |
| metadata | {"author":"exarchos","version":"1.0.0","mcp-server":"exarchos","category":"workflow","phase-affinity":"completed"} |
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:
exarchos:exarchos_workflow({ action: "get", featureId: "<id>" })
If featureId not provided, use pipeline view to list active workflows:
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:
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:
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:
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:
exarchos:exarchos_orchestrate({ action: "prune_worktrees", repoRoot: "<repo-root>" })
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:
git fetch --prune
git branch -d <merged-branch-1> <merged-branch-2> ...
6. Report Completion
Output summary:
## 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:
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