From harmony-plugin
Use when the user wants to finish, complete, wrap up, land, or merge their current work. Triggers on phrases like "finish", "done", "wrap up", "land this", "merge", "ship it", or "we're done". This is the exit point for ALL development work in this project — it handles the full merge-and-cleanup sequence. In opinionated-mode projects it also drives the releasing + verifying activities; in manual-mode projects it behaves exactly as before.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harmony-plugin:finish-workThis skill is limited to the following tools:
These tools are removed from Claude's available pool while this skill is active:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Safely land completed work: verify readiness, rebase, squash merge, update main, and clean up the worktree and branch.
Safely land completed work: verify readiness, rebase, squash merge, update main, and clean up the worktree and branch.
Call mcp__harmony__get_project. If mode !== 'opinionated', follow Manual mode (the original
merge-and-cleanup flow below — unchanged). If mode === 'opinionated', follow Opinionated mode
(it wraps the same merge sequence with the release/verify gates).
The ticket should be at Built with awaiting_human_reason = 'release-decision-pending' (set by
/harmony-plugin:start-work). This path drives releasing (Built → Released) and verifying
(Released → Verified). It does NOT rewrite design knowledge (release role).
Check this BEFORE the release pre-flight. A decomposed parent (an "umbrella") has NO branch/PR of its
own — its real work shipped in its children's PRs. The DB trigger auto-advances such a parent
Decomposed → Released once all active children reach Verified, and surfaces verify by setting on
the parent row awaiting_human_input = true, awaiting_human_reason = 'verification-ack-pending',
awaiting_human_ref = {"kind":"umbrella-auto-verify"} — but it does NOT compose a brief (so
get_brief returns null for the umbrella until this skill composes one).
The umbrella's task_id is the ticket id passed to this skill — an umbrella has no worktree of its
own and therefore no .harmony-task.json; the cwd may even hold a different ticket's .harmony-task.json,
so do NOT read task_id from that file for an umbrella. Use the ticket id you were invoked with.
Detect an umbrella (the authoritative marker is the primary key):
mcp__harmony__get_task({ task_id }) and check
awaiting_human_ref.kind === 'umbrella-auto-verify'. The harmony-web Phase-1 trigger sets this on an
auto-advanced umbrella parent, alongside workflow_state = 'Released',
awaiting_human_input = true, and awaiting_human_reason = 'verification-ack-pending'. Equivalently:
workflow_state = 'Released' + awaiting_human_reason = 'verification-ack-pending' + it has children.
This awaiting_human_ref.kind marker is the authoritative, purpose-built signal — prefer it over any
proxy.mcp__harmony__list_subtasks({ task_id }) shows it
has children, and there is no open PR for its branch (.harmony-task.json has no branch, or
gh pr view fails). Treat these as confirmation, not as the primary signal: an umbrella has no
worktree of its own, so gh pr view runs against whatever arbitrary branch the cwd happens to be on and
is unreliable on its own.Such an umbrella is already at workflow_state Released (auto-advanced) with
awaiting_human_reason = 'verification-ack-pending' and awaiting_human_ref.kind = 'umbrella-auto-verify'.
If it is an umbrella → take the umbrella verify path and SKIP O1/O2 entirely (there is no code to merge — the children each shipped their own PR; do NOT run the release-decision gate or the merge/deploy sequence, and do NOT touch git):
Edge — still Decomposed (not all children Verified): if mcp__harmony__get_task shows the umbrella
is still at Decomposed (the trigger hasn't fired — and awaiting_human_ref.kind is therefore NOT
'umbrella-auto-verify'), it simply isn't ready: not all active children have reached Verified. Do
NOT verify. Tell the human it is not ready — its children are still in flight — and stop. Note that
list_subtasks selects each child's kanban status, not its workflow_state (where Verified
lives), so it cannot tell you which children are un-Verified. If you want to enumerate the un-Verified
children, mcp__harmony__get_task each child and read its workflow_state.
Compose the verify brief if missing: mcp__harmony__get_brief({ task_id }). If it is null (the
trigger set the flag but composed no brief), compose it:
mcp__harmony__compose_brief({
task_id, reason: "verification-ack-pending", pending_activity: "verifying",
doc: { decide: "Does the umbrella work end-to-end across its children?", items: [
{ kind: "decision", text: "Acknowledge the umbrella works end-to-end across its children", recommendation: "verify once confirmed" }
] }
})
Resolve on human ack: show the brief; on the human's accept →
mcp__harmony__resolve_brief({ task_id, command: "accept" }) advances Released → Verified
(terminal-positive). No git. Report completion and stop — do not fall through to O1/O2/O3.
(If awaiting_human_ref.kind is not 'umbrella-auto-verify' — e.g. the ticket has NO children, or it has
its own open PR/branch — it is a normal ticket: skip this section and continue to O1.)
mcp__harmony__get_task({ task_id }) (read .harmony-task.json for the id) and
mcp__harmony__get_brief({ task_id }). Show the release-decision-pending brief. On the human's
accept:
mcp__harmony__resolve_brief({ task_id, command: "accept" }) // pending_activity: null → clears the flag, NO state change
The release brief carries pending_activity: null (state-machine §6.1 — Built→Released is
SYSTEM-on-deploy-success, not human-accept). So accept is only the human's "go"; the ticket stays Built
until the deploy actually succeeds (O2). (If the human defers, resolve_brief({ command: "defer" }) parks
it — do not merge.)
Run the manual-mode merge sequence below (pre-flight checks → rebase → force-push → wait for CI → squash merge → cleanup). Only after the deploy actually succeeds:
mcp__harmony__advance_workflow({ task_id, activity: "releasing" }) // Built -> Released (now reality matches)
If CI/deploy goes red, do not advance — the ticket stays Built; fix and retry. This is what keeps
Released meaning "deployed" (state-machine §6.1), so verifying (O3) checks against a real deploy
rather than a state that ran ahead of reality (the B-60 conflation — review F4).
After deploy, file the verification brief so the human can acknowledge real-world behaviour matches the design (state-machine §6.1 — verifying is human-ack by default):
mcp__harmony__compose_brief({
task_id, reason: "verification-ack-pending", pending_activity: "verifying",
doc: { decide: "Does production behaviour match the design?", items: [{ kind: "decision", text: "Acknowledge verified", recommendation: "verify once confirmed" }] }
})
On the human's accept → mcp__harmony__resolve_brief({ task_id, command: "accept" }) advances
Released→Verified (terminal-positive). Report completion.
If post-release the human finds a problem, flag a human-authorised backflow:
mcp__harmony__advance_workflow({ task_id, activity: "revising-building" })(Released → Built) and hand back to/harmony-plugin:start-work.
(everything below is the original finish-work flow — unchanged)
Before doing anything, verify ALL three conditions. If any fail, stop immediately and tell the user what needs to be done — do NOT attempt to fix these yourself.
Working in a worktree? Check that the current directory is inside .worktrees/. If not, error: "You're not in a worktree. Please switch to the worktree for the work you want to finish."
All code committed? Run git status and check for uncommitted changes. If there are any, error: "There are uncommitted changes. Please commit your work before finishing."
PR created? Check if the current branch has an open PR using gh pr view. If not, error: "No PR found for this branch. Please create a PR before finishing."
Acceptance criteria addressed? (soft check — warning, not a blocker)
If the task has acceptance criteria, use list_acceptance_criteria to check whether all items are marked as done. If not, warn the user:
"N of M acceptance criteria are not yet checked. Proceed anyway?"
Similarly check if test cases have been recorded via list_test_cases.
If either is missing, warn but don't block — the user may have valid reasons to skip.
If any of the first three checks fail, stop. Do not proceed. Do not offer to fix it. Just report the issue clearly. For the fourth check, warn but allow the user to override.
Once all checks pass:
git fetch origin main
git rebase origin/main
If there are conflicts, attempt to resolve them. If anything is ambiguous or unclear, stop and consult the user before continuing.
git push --force-with-lease
The force-push triggers a new CI run. Wait for it to complete before merging.
gh pr checks <PR-number> --watch
If CI fails, stop and investigate — do not merge a failing build.
Use gh pr merge <PR-number> --squash. Do NOT pass --delete-branch — the branch deletion will fail from inside the worktree and break the flow.
cd <project-root> # The parent directory outside .worktrees/
git checkout main
git pull origin main
The project root is the repository root (parent of .worktrees/).
Before removing the worktree, kill any long-lived watchers (dev servers, e2e runners, file watchers) that were started during the work. This prevents orphan processes after the directory is deleted.
# Kill watchers by name. Adjust the list to match your stack.
pkill -f "vite preview" 2>/dev/null
pkill -f "vite dev" 2>/dev/null
pkill -f playwright 2>/dev/null
If no matching processes are running the commands return non-zero silently — this step is best-effort.
Don't replace these with lsof +D <worktree> | xargs kill. That scans for every process holding a file open under the worktree, which includes the shell running the cleanup and the Claude Code process itself when its CWD is inside the worktree — the agent self-terminates mid-cleanup and the merge tail (worktree removal, branch deletion, Harmony status move) is left half-done. For new watcher types, add another explicit pkill -f line above instead.
git worktree remove .worktrees/<worktree-name>
git branch -d <branch-name>
git push origin --delete <branch-name>
Read .harmony-task.json from the worktree root (written by start-work). This contains the task UUID, visual ID, and title. If the file doesn't exist, fall back to inferring the task from the branch name, PR title, or conversation context.
mcp__harmony__update_taskmcp__harmony__add_comment(task_id, "Merged to main via PR #<number>")
The task should be a living record of what happened — see the full task lifecycle reference in the start-work skill.
Confirm that main is updated, the worktree is removed, and branches are pruned.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub ycomplex/harmony-plugin --plugin harmony-plugin