Parallel Close Skill
A user invocation (/parallel-close <parallel-slug>) forks the parallel-orchestrator agent with
this procedure in context. The parallel slug of the run to terminate is:
$ARGUMENTS
This skill implements the mutation-protocol close operation (spec FR3). It terminates an
open-mode run, which has no other termination signal: the mode-dependent completion semantics in
the ## Mutation Protocol (F6) section of .claude/skills/parallel-orchestrate/SKILL.md state that
an open-mode run never auto-completes. Read that section before applying anything here.
Prerequisites
- A parallel run is in progress and
artifacts/orchestration/parallel-orchestrator-state.jsontracks theparallel_slugnamed in$ARGUMENTS. - The run's
modeisopen. Aclosed-mode run completes through its completion predicate — every non-withdrawn itemmergedorworktree_removed— and needs no close. Report that and stop rather than closing aclosed-mode run to force completion.
Re-Derive Durable State Before Applying Anything
The checkpoint is a CACHE of durable state, not the source of truth
(.claude/rules/parallel-orchestration.md, Cache Doctrine). Before deciding the close, re-derive
the run's true per-item state and rewrite the checkpoint from it when they disagree:
git worktree list --porcelain— worktree existence and path per item.git branch— branch existence and name per item.gh pr view <pr> --json state,mergedAt,headRefOid— pull-request state and merge outcome per item.
The close gate turns entirely on whether any item is in flight, so a stale in-flight set decides the gate wrongly. Closing while an item is genuinely running would abandon that work implicitly, which is exactly what the gate exists to prevent. The re-derivation is mandatory.
Procedure
Re-derive durable state as above and resolve the run's
items[].Gate the close on no item being in flight. Call
decide_close(items)fromscripts/dev_tools/parallel_mutation_protocol.py. It raises the dedicated rejection exception carrying EVERY in-flight key, so the rejection names all the work that must finish first rather than one item at a time. On rejection: report the blocking keys and stop. A rejected close appends NOmutations[]entry and makes NO state change — do not record the attempt.Append exactly one run-scoped
mutations[]entry for a successful close, built bybuild_close_entryfromscripts/dev_tools/parallel_mutation_protocol.py:Case opitem_keyprior_statenew_statedispositionrecolor_generationClose closenull (run-scoped) null null null g(unchanged)The entry is run-scoped, so
item_keyis null: the close acts on the run, not on an item. Theattimestamp comes from the engine's injected clock seam.Do not recompute. Run termination changes no cohort assignment, so
recolor_generationis UNCHANGED andcohorts[]is not rewritten. Do not callrecolor_unstartedas part of a close.Stop admitting. After the close is recorded, the run accepts no further
/parallel-add. The close record is the run's final mutation; nothing may be appended tomutations[]after it.Validate the checkpoint before treating the close as applied. Run the
validate_orchestration_artifactsMCP tool withartifact_type: "parallel-orchestrator-state". A non-empty error list means the close was applied incorrectly; correct the checkpoint rather than proceeding.
Constraints
- One close per run, one
mutations[]entry per successful close. - No field and no enum member is added to
mutations[]or to any state or merge-status enum. The nine parallel enums are owned by.claude/rules/parallel-orchestration.mdand are consumed, never extended. - The close performs no destructive side effect: it closes no pull request and removes no worktree.
An item whose work should be destroyed must be removed first through
/parallel-removewith--disposition abandon, which is also what makes the close gate passable. - The close does not change any item's state. Items that never started remain in their recorded states; the close records that the run stopped admitting, not that those items were withdrawn.
Completion Requirements
- Report the
parallel_slug, the gate outcome, and the single appendedmutations[]entry — or, for a rejected close, the full list of in-flight keys and the explicit confirmation that nothing was appended and no state changed. - Report the unchanged
recolor_generation. - Report the checkpoint validation result.