Command: work-complete (iterate → isolate → plan → execute → squash merge → housekeeping → confirm)
Use for: work complete:, work complete (optionally with a ## heading, file/line reference, **Id:** ITER-N, or a pasted block that matches one section in work/ITERATION.md)
Prerequisites: Read ../bootstrap.md and ../rules.md first. This command implements product/repo changes—not "record only."
Source file (only): work/ITERATION.md
Workflow
-
Migrate and bootstrap
work/files as needed. -
Identify the section in
work/ITERATION.mdper../procedures/section-disambiguation.md(scope:work/ITERATION.md, id format:ITER-N).
Then backfill missing entry ids inwork/ITERATION.mdper../id-prefixes.md(Backfill) before editing the section. -
Snapshot the block — Copy the full section text exactly as queued (from the
##line through the content up to but not including the next---or the next##at the same level—same boundary rules as pluck). Keep this copy for the final commit body. Also capture the Source and Source id fields from the iteration entry for provenance. -
Isolate feature work — Before implementation begins, ensure work will happen on a feature branch in a managed worktree.
4a. Detect the base branch using this three-tier fallback (reuse this value for the rest of the run, including step 10):
git config --get git-town.main-branchgit symbolic-ref refs/remotes/origin/HEAD | sed 's|refs/remotes/origin/||'- Fallback to
main
BASE_BRANCH=$(git config --get git-town.main-branch 2>/dev/null || \ git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' || \ echo "main")Follow
../procedures/worktree-setup.mdwith branch-prefixiter/.BASE_BRANCHwas detected in step 4a above. If the procedure's "Decide" step (b) finds the current branch is already a non-base branch, skip to the planning mode gate (step 5).
Planning mode gate (mandatory — do not skip)
-
If the user already declared a mode in the same message, treat it as their choice and go to step 6. Accept plain-language equivalents, for example:
- Native / Plan → Native planning (see below).
- Brainstorm / superpowers →
superpowers:brainstorming.
If there is no such declaration, you must obtain a choice before any implementation work: - Stop after step 4. Do not read the codebase for implementation, do not write or change product code, and do not run tool calls whose purpose is to implement the item.
- Your next message to the user must present only the planning-mode question (optional: one short line naming the section you identified). Prefer a multiple-choice UI when the product supports it (e.g. the product's question UI with exactly two options) so the user must pick before you continue.
- Offer exactly two options (same meaning every time):
- Native planning — Use the product's built-in planning UI so a written plan exists and is visible to the user before coding. If a planning UI is not available, post a short bullet plan in chat and wait for explicit approval (e.g. "proceed," "looks good," or thumbs-up) before writing implementation code.
superpowers:brainstorming— Run thesuperpowers:brainstormingflow first, then implement.
- Wait for the user's reply that selects one option. Do not assume defaults.
-
Hand off to the chosen planner — Read
../templates/work-complete-planner-brief.mdand give the planner explicit instructions that it must:- Follow the squash-merge path and produce two commits on the base branch: one feature delivery commit (step 10) and one housekeeping commit (step 14).
- Do NOT use
superpowers:finishing-a-development-branchfor the merge step — the squash-merge procedure in step 10 replaces it. - Complete all implementation on the feature branch before merging.
-
Execute on the feature branch — All non-
work/changes for the iteration item are made on the feature branch. Follow the selected planning mode: native planning means a visible plan first (Plan mode or chat plan + approval), then implement;superpowers:brainstormingmeans that flow first, then implement.7a. Checkpoint 1 — commit approved spec artifact: When the
superpowers:brainstormingflow completes and the user approves the written spec, check whether the spec file has uncommitted changes before invokingsuperpowers:writing-plans:git status --porcelain -- <spec-path>- If empty: the spec is clean. Continue to
superpowers:writing-plans. - If dirty: stage only the spec file and commit:
wheregit add -- <spec-path> git commit -m "docs: incorporate user revisions to <spec-filename>"<spec-filename>is the basename of the spec path. - If staging or committing fails, stop before
superpowers:writing-plans. Do not continue with an approved-but-uncommitted spec revision. - Do not broaden this commit to other dirty files — checkpoint 1 is scoped to the approved spec artifact only.
By the end of this step the feature branch contains the commits whose messages will later be harvested into the feature delivery commit body. If the implementation produces no meaningful diff relative to the base branch, stop and do not continue to merge.
- If empty: the spec is clean. Continue to
7b. Checkpoint 2 — commit outstanding changes before verification: Before verification runs, ensure the feature branch is fully committed so verification operates on the exact tree that will later be merged.
7b.1 Entry conditions:
- The current branch must be the feature branch, not
BASE_BRANCH. - The working tree must have no unresolved merge conflicts.
If any entry condition fails, stop and report the condition.
7b.2 Dirty detection:
git status --porcelain
- If empty: the feature branch is already clean. Skip checkpoint 2 and continue to step 8.
- If any output: checkpoint 2 must run.
7b.3 Commit behavior:
- Stage all tracked, untracked, and deleted changes:
git add -A - Commit:
git commit -m "chore: commit outstanding changes before squash merge" - Continue to step 8 only after the commit succeeds.
7b.4 Failure handling:
- If
git add -Aor the commit fails, stop before verification. - Do not silently continue with a dirty feature branch.
- Do not filter by file type — preserve the full feature-branch state.
-
Pre-merge verification — Determine the repo's canonical verification command and run it on the feature branch.
- If verification fails, stop on the feature branch. Do not begin squash merge. Fix the issue and rerun verification before proceeding.
- If the repo has no discoverable verification command, stop and ask the user rather than guessing.
-
Squash merge to the base branch — Execute these sub-steps in order:
- Reuse the base branch detected in step 4a (
BASE_BRANCH). Do not re-detect. - Read the current feature branch name:
FEATURE_BRANCH=$(git branch --show-current) - Assert
FEATURE_BRANCH != BASE_BRANCH. If they are equal, stop — the workflow lost its isolation guarantee. - Collect all commit messages on the feature branch that are not on the base branch:
git log ${BASE_BRANCH}..${FEATURE_BRANCH} --format="%B" > /tmp/work-complete-squash-msg-$$.txt - Switch to the base branch and update from upstream when an upstream exists. If no upstream exists, skip the pull step and note that fact in the final summary.
git checkout ${BASE_BRANCH} && git pull - Ensure the base branch checkout is clean before merging. If it is not clean, stop and ask the user to resolve it. Do not auto-stash, auto-reset, or silently mix unrelated changes.
- Run the squash merge:
git merge --squash ${FEATURE_BRANCH} - If the squash merge conflicts, stop. Do not yank the iteration item, do not create the housekeeping commit, and do not delete the feature branch or worktree.
- Stage the merged implementation changes and
CHANGELOG.mdwhen updated. Do not stagework/files. - Commit with this structure:
<concise summary of what shipped> From work/ITERATION.md (ITER-N): <snapshot block from step 3> Original source: <Source field> (<Source id> if present) Commits from <feature-branch>: <collected commit messages>
- Reuse the base branch detected in step 4a (
-
Post-merge verification — Run the same verification command on the base branch after the feature delivery commit.
- If verification passes, continue to cleanup (step 11).
- If verification fails, stop before cleanup and before yanking the iteration item. Preferred recovery: fix the problem on the feature branch and repeat the merge path so the delivered feature remains one reviewable commit.
10a. Ship Proof gate (conditional) — Follow ../procedures/ship-proof-gate.md with:
- item-title: the iteration section title
- item-id:
ITER-N(the iteration entry's id) - source-file: the source filename (from the iteration entry's Source field)
- source-id: the source id (if present)
-
Clean up branch and worktree — Only after step 10 passes:
- Delete the local feature branch:
git branch -D <feature-branch> - If a worktree was used, remove it using the exact path recorded in step 4f:
git worktree remove <recorded-worktree-path> - If the feature branch was pushed, delete the remote branch (best-effort):
git push origin --delete <feature-branch>
Remote branch deletion is best-effort. If it fails, report it but do not roll back a successful local merge.
- Delete the local feature branch:
-
Human verification gate — Follow
../procedures/human-verification-gate.mdwith:- source:
ITERATION.md - source-id: the iteration section's
**Id:** ITER-N
Continue to step 13 whether or not an ACC-N entry was created.
- source:
-
Yank + housekeeping commit — Remove the entire iteration section from
work/ITERATION.md(same boundaries as step 3). If step 12a ran, include the newACCEPTANCE.mdentry in the same commit.Rules:
- Only stage
work/files that changed. - Subject:
xp_work: yank ITER-N from ITERATION - Mention
ACC-Nin the subject or body when acceptance was queued. - Do not include feature code, test changes, or
CHANGELOG.mdin this commit. - Do not change
ITERATION.md's**Last id:**counter when yanking. The counter is monotonic — once an id has been assigned and yanked, the next entry recorded must get the next number, never reuse the yanked one.
- Only stage
-
CHANGELOG — If
CHANGELOG.mdexists and the change is worth recording, update it as part of the feature delivery commit (step 9), not the housekeeping commit. Add one sentence summarizing what shipped or changed, matching the file's existing structure (e.g. Keep a Changelog## [Unreleased]). Do not include the entry id (e.g.ITER-3,IMP-7) in the CHANGELOG line — entry ids are per-file and not unique across time; describe the change in plain language. The snapshot in the commit body preserves the id for traceability. -
Confirm — Return a short summary including:
- Iteration item: ITER-N and section title
- Original source and source id (provenance)
- Planning mode used
- Feature delivery commit hash (from step 9)
- Housekeeping commit hash (from step 13)
- Whether
CHANGELOG.mdwas updated - Whether
ACC-Nwas created (and if so, note thataccept:/xp_work acceptshould be used after the human verifies) - Whether ship-proof ran (spec-driven or ad-hoc fallback), passed, or was skipped — and why (spec row matched, no spec found, not in spec requirements, no UI changes). Include artifact location when it ran:
docs/features_proof/<ITER-N>-<slug>/ - Whether base-branch pull was skipped (no upstream)
- Whether remote branch deletion was skipped or failed
- Whether Workbench workspace archive was triggered or skipped (no Workbench MCP)
-
Workbench workspace archive (conditional) — If the
mcp__workbench__archive_workspacetool is available, the session is running inside a Workbench workspace. Callmcp__workbench__archive_workspaceto archive the workspace. This must be the absolute last action — after the confirm summary has been returned to the user. The tool is irreversible: it stops processes, removes the worktree, and preserves chat history. If the tool is not available, skip this step entirely.
See ../format-guidelines.md for template paths.