How to Accept and Merge a Mission
Use this guide to validate mission readiness and merge to the mission's target branch.
Prerequisites
- All WPs are
approvedordone, with review feedback resolved - You are in a checkout where the mission can be resolved (repository root checkout or execution workspace)
Accept the Mission
Run acceptance after the implement-review loop approves every WP and before merge. This is a readiness nudge for humans and LLMs; merge still performs its own gates and remains the mission-close operation.
In your agent:
/spec-kitty.accept
Or in your terminal:
spec-kitty accept
What Accept Checks
- All WPs are
approvedordone - Required metadata and activity logs are present
- No unresolved
[NEEDS CLARIFICATION]markers remain
To run a read-only checklist (in your terminal):
spec-kitty accept --mode checklist
Negative Invariants That Assert the Merged Post-State
The accept gate re-runs each acceptance negative-invariant verification_command
live against the working tree at accept time — it does not trust a stored
result or a hand-set overall_verdict. Two consequences follow:
Hand-editing a verdict does not stick. Setting
overall_verdict(or a negative invariant'sresult) by hand inacceptance-matrix.jsonis overwritten the moment accept runs; the invariant'sverification_commandis the single source of truth, and it must actually pass in the checkout accept runs from.Merged-post-state invariants must be verified after merge. If an invariant asserts a state that only exists once the mission is merged — for example, "
shell: bashis present inci-quality.yml" when that line is added by the merge — it cannot pass while the mission still lives on its lane branch. For such missions, runspec-kitty merge(into localmain) beforespec-kitty accept, so the working tree accept inspects already carries the merged post-state:spec-kitty merge # land into LOCAL main first spec-kitty accept # now the post-state invariants can verify liveThis inverts the usual accept-then-merge order and is only needed for missions whose negative invariants assert the post-merge result. Missions whose invariants describe the lane's own diff verify fine in the normal order.
If you prefer not to re-order, scope the invariant to a path that exists on the lane branch (see
NegativeInvariant.scope) or express it as acustom_commandthat is meaningful pre-merge.
Deferred Invariants and the Post-Consolidation Gate
A scoped grep_absence invariant whose subject does not exist yet — because it
is added only by consolidating the mission's lane branches — cannot be honestly
judged at accept time. Rather than report a false "still present" or a false
"pass", accept records that invariant's result as deferred_to_consolidation
and the mission's overall_verdict as pass_pending_consolidation: acceptance
is not blocked, but the mission cannot reach done while the deferral is
outstanding.
What this means for you as the operator:
- The mission loop does not verify a deferred invariant.
spec-kitty acceptis the acceptance matrix's only pre-consolidation reader, and it is the gate that creates the deferral — it cannot also be the thing that resolves it. Whenspec-kitty acceptassignsdeferred_to_consolidationit discloses this immediately, in the same run, as anegative_invariants_deferredentry under "Skipped checks" — look for it in the console output or the JSON summary. - What verifies it instead is the post-consolidation verification op —
dispatched after
spec-kitty merge(lane consolidation) completes, against the consolidated mission tree. It re-judges everydeferred_to_consolidationinvariant on that tree and records a terminal result (confirmed_absent/still_present/verification_error) stamped with theCONSOLIDATEDsurface. A violation fails that verification op, not the already-completed consolidation — see post-consolidation /CONSOLIDATEDin the terminology glossary for how this surface relates tospec-kitty merge's three overloaded "merge" senses. - What your repository needs: a CI check on the pull request that fails when
any
kitty-specs/*/acceptance-matrix.jsonstill carries an unresolveddeferred_to_consolidationinvariant. This project's own gate isscripts/ci/check_dangling_deferrals.py, wired intoci-quality.yml'sdeferral-consistency-checkjob. A repository without an equivalent check never verifies the deferral — the disclosure above exists precisely so that gap is visible rather than silently assumed away (ADR 2026-07-23-2).
Merge to the target branch
In your agent:
/spec-kitty.merge --push
Or in your terminal:
spec-kitty merge --push
By default, spec-kitty merge lands in the mission's recorded target branch. Use spec-kitty merge --target <branch> only when you intentionally need to override that destination.
For detailed merge options including dry-run, strategies, and cleanup flags, see Merge a Mission.
When Local main Is Not Publishable
Autonomous local runs can leave main ahead of or diverged from origin/main
with planning, status, review, and orchestration commits. If merge refuses with
TARGET_BRANCH_NOT_SYNCHRONIZED, do not reset, rebase, force-push, or push
local main only to satisfy the pre-flight.
Open a focused PR from the mission result instead:
git push -u origin kitty/mission-<mission-slug>
gh pr create --base main --head kitty/mission-<mission-slug> --fill
Or create a dedicated PR branch from the mission branch:
git switch -c kitty/pr/<mission-slug>-to-main kitty/mission-<mission-slug>
git push -u origin kitty/pr/<mission-slug>-to-main
gh pr create --base main --head kitty/pr/<mission-slug>-to-main --fill
Prefer squash-merge when the autonomous run accumulated many orchestration commits. For the full end-to-end path, see Run an Autonomous Mission.
After Merge
Complete the following three steps before declaring the mission done.
1. Mission review — run the post-merge mission review to confirm spec→code fidelity and FR coverage:
# In your agent:
/spec-kitty-mission-review
# Or directly:
spec-kitty agent mission review --mission <handle>
2. Author or verify the retrospective — under default policy the record was already written during merge. Verify with:
cat .kittify/missions/$(jq -r .mission_id kitty-specs/<slug>/meta.json)/retrospective.yaml
If the file is absent (for example, an older mission predating 3.2.0), author it now:
spec-kitty retrospect create --mission <handle>
Reserve the noun "capture" for the event-log fact RetrospectiveCaptured, not for the
operator verb.
3. Surface findings — aggregate across recent missions or inspect proposals for this one:
# Cross-mission view (read-only aggregation)
spec-kitty retrospect summary
# Preview proposals in this mission's retrospective.yaml (dry-run by default)
spec-kitty agent retrospect synthesize --mission <handle>
# Apply a proposal (requires explicit --apply)
spec-kitty agent retrospect synthesize --mission <handle> --apply <proposal-id>
For full details on each command, see How to Use Retrospective Learning.
Merge Strategies
- Default (merge commit):
spec-kitty merge - Squash:
spec-kitty merge --strategy squash
Note: Rebase is not supported for multi-workspace missions. Use merge or squash instead.
Cleanup
By default, merge removes resolved execution worktrees and deletes the mission branch. Use these flags to keep them (in your terminal):
spec-kitty merge --keep-worktree --keep-branch
Abandon a Mission (Manual Cleanup)
If you decide to drop a mission without merging, remove its execution worktrees and branches manually. These steps are safe and reversible until you delete the branch and commit the cleanup.
- List worktrees to find all workspaces for the mission:
git worktree list
- Remove each execution worktree for the mission:
git worktree remove .worktrees/<mission-slug>-lane-a
git worktree remove .worktrees/<mission-slug>-lane-b
If a worktree has uncommitted changes you want to discard, use --force:
git worktree remove --force .worktrees/<mission-slug>-lane-a
- Delete the mission branches:
git branch -D <mission-slug>-lane-a
git branch -D <mission-slug>-lane-b
- Remove the planning artifacts from the repository root checkout (spec/plan/tasks), then commit:
rm -rf kitty-specs/<mission-slug>
git add kitty-specs/
git commit -m "Remove abandoned mission <mission-slug>"
Troubleshooting
- Accept reports blockers: Resolve the listed issues, then rerun
/spec-kitty.accept. - Merge fails: Ensure your current checkout is clean and the mission resolves correctly.
- Merge reports
TARGET_BRANCH_NOT_SYNCHRONIZED: Use the focused-PR path when localmaincontains autonomous-run history that should not be published directly. - Merge is heading to the wrong branch: Inspect the mission's recorded target branch before retrying, and use
spec-kitty merge --target <branch>only if you intend to override it.
For detailed troubleshooting including pre-flight failures, conflict resolution, and merge recovery, see Troubleshoot Merge Issues.
Command Reference
- Slash Commands - All
/spec-kitty.*commands - CLI Commands - Full CLI reference
See Also
- Merge a Mission - Detailed merge workflow
- Run an Autonomous Mission - End-to-end autonomous run and focused-PR fallback
- Keep Main Clean - Choose a target branch without changing planning location
- Troubleshoot Merge Issues - Recovery and conflict resolution
- Review a work package - Required before accept
- Upgrade to 0.11.0 - Breaking changes in v0.11.0
Background
- Execution Lanes - Worktree cleanup
- Git Worktrees - How worktrees work
Getting Started
- Your First Mission - Complete workflow walkthrough