Merge Orchestrator Skill
Local Git, Not Remote VCS
This skill performs
local of a subagent's worktree branch into the integration branch, recording a rollback SHA so a
can undo the merge on any failure. It does
not call the VCS provider (GitHub / GitLab / Azure DevOps) and does not require a PR id. For remote PR merging during the synthesize phase, see
@skills/synthesis/SKILL.md
(
action).
The mental model and the rationale for why these are two separate concerns are documented in
references/local-git-semantics.md
.
Overview
Closes the loop between
(which spawns subagents into worktrees) and the integration branch that needs their work. After a delegated task completes inside a worktree, this skill:
- Composes preflight guards (ancestry, current-branch protection, main-worktree assertion, working-tree drift).
- Records pre-merge of the integration branch as a rollback anchor.
- Performs a local of the source (subagent) branch into the target (integration) branch.
- On any failure, runs
git reset --hard <rollbackSha>
and surfaces a categorized failure reason.
- Emits dedicated event types so the merge timeline is reconstructable from the event log alone.
Resumable: terminal phases (
/
/
) short-circuit on re-entry without re-emitting events. Idempotent: re-dispatch with the same
collapses via the
idempotency key.
Triggers
Activate this skill when:
- The HSM is parked in (entry guard fires when the most recent carries a worktree association).
- The envelope surfaces a verb with idempotency key
${streamId}:merge_orchestrate:${taskId}
.
- The user runs
exarchos merge-orchestrate ...
(CLI) or invokes mcp__exarchos__exarchos_orchestrate({ action: "merge_orchestrate", ... })
directly.
Do not activate this skill:
- During the synthesize phase to merge a remote PR — that is .
- When the workflow's is already terminal — the resume short-circuit runs but no fresh dispatch is needed.
Process
Schema: discover the action's argument schema with
mcp__exarchos__exarchos_orchestrate({ action: "describe", actions: ["merge_orchestrate"] })
. Strategy is required (no schema-level default) — pick
/
/
deliberately.
Step 1: Pick the merge strategy
| Strategy | Local git operation | When to choose |
|---|
| git merge --no-ff --no-edit <source>
— explicit merge commit | Preserves the subagent's commit history with a visible merge boundary. |
| git merge --squash <source>
then — single squash commit on target | Subagent commit history is noise; one logical change should land as one commit. |
| rebases an ephemeral copy of source onto target then ff-merges target — linear history | No merge commit; integration branch stays linear. The original source ref is preserved (the rebase runs on a temporary branch that is deleted afterward), so an executor rollback only needs to reset target. |
Strategy is required at the schema layer (#1127 collision check, #1109 §2 user-visible parity). There is no implicit default — operator intent is always explicit in the event log.
Step 2: Invoke
Via MCP:
typescript
mcp__exarchos__exarchos_orchestrate({
action: "merge_orchestrate",
featureId: "<id>",
sourceBranch: "<subagent-branch>",
targetBranch: "<integration-branch>",
taskId: "<task-id>", // present when auto-dispatched from next_actions
strategy: "squash", // required
dryRun: false, // optional — preflight only, no executor invocation
resume: false, // optional — short-circuit on terminal phases
})
Via CLI:
bash
exarchos merge-orchestrate \
--feature-id <id> \
--source-branch <subagent-branch> \
--target-branch <integration-branch> \
--task-id <task-id> \
--strategy squash
# add --dry-run for preflight-only, --resume for terminal-phase short-circuit
CLI exit codes: 0 = success, 1 = invalid input, 2 = merge failed (preflight blocked or rollback executed), 3 = uncaught exception.
Step 3: Interpret the result
The handler returns a
whose
discriminates the outcome:
| Meaning | Operator action |
|---|
| Local merge landed; is the new HEAD of target. | None — workflow exits back to (HSM) and continues. |
| Preflight failed; no merge attempted. carries the structured guard sub-results. | Inspect preflight.ancestry / worktree / currentBranchProtection / drift
to identify which guard failed. Resolve the underlying condition (e.g., commit/stash drift, switch off a protected branch) and re-dispatch. |
| Merge was attempted, failed (reason: 'merge-failed' / 'verification-failed' / 'timeout'
), and git reset --hard <rollbackSha>
ran. The integration branch is restored. | Inspect . If is also present, the reset itself failed — the working tree is stranded and requires operator intervention. |
For the full recovery flow per outcome, see
references/recovery-runbook.md
.
Step 4: Confirm event emissions
Three events are emitted directly to the workflow's event stream (stream id =
) —
not wrapped in
:
| Event type | When | Carries |
|---|
| Always (after preflight runs, before any merge attempt) | Full structured guard sub-results + if |
| On successful local merge | , , , source/target branches |
| On post-merge failure followed by reset | , , , source/target branches |
These events are auto-emitted by the handler — do
not manually append them via
mcp__exarchos__exarchos_event
during normal operation. Manual emission is only sanctioned during the documented manual-recovery flow in
when a merge has been completed out-of-band (e.g., conflict resolution) and the event log must be brought back in sync — follow that runbook's event-first sequencing.
Discover the event payload schemas via
mcp__exarchos__exarchos_event({ action: "describe", eventTypes: ["merge.preflight", "merge.executed", "merge.rollback"] })
.
Disambiguation: vs
Two related actions, two distinct concerns:
| Aspect | (this skill) | (synthesis skill) |
|---|
| Layer | Local SDLC handoff | Remote PR primitive |
| Phase affinity | (between delegate and review) | |
| What it merges | A subagent worktree branch into the integration branch | A user-facing PR via the VCS provider API |
| Identifier required | + | |
| Underlying operation | (local) | (remote API) |
| Rollback | git reset --hard <rollbackSha>
(real, undoes the merge) | None — the VCS provider owns merge state |
| Events | / / | |
If you reach for
thinking "I want to merge a PR," you want
instead.
Resume Semantics
When invoked with
, the handler reads existing
state. Terminal phases (
/
/
, members of
) short-circuit and return the recorded result with no new events and no executor call. Non-terminal phases (
/
) fall through to a fresh preflight + executor run, which is safe because the underlying git operations are idempotent on already-merged branches.
When invoked without
, prior state is deliberately ignored — fresh-dispatch semantics.
Dry-Run
runs preflight, emits
, and short-circuits before the executor runs and before any state persistence. Returns
{ dryRun: true, preflight, phase: 'pending' | 'aborted' }
. Useful for CI integrations that check merge readiness before the merge window opens.
Anti-Patterns
| Don't | Do Instead |
|---|
| Use this skill to merge a remote PR | Use in the synthesize phase |
| Manually emit / / in normal flow | Let the handler auto-emit; manual emission causes duplicates (one exception: documented manual-recovery flow in ) |
| Wrap merge events under | Direct stream append with the dedicated event type — these are state transitions, not gate executions |
| Re-dispatch after a outcome without inspecting the reason | Read and ; address the root cause first |
| Omit / field expecting a default | Strategy is required; supply / / explicitly |
| Invoke from a subagent worktree | Preflight refuses (main-worktree assertion); invoke from the main worktree |
Phase Transitions and Guards
For the full transition table, consult
@skills/workflow-state/references/phase-transitions.md
.
Quick reference:
- → requires guard — fires when the most recent carries a worktree association AND is not in .
- → requires guard — fires when enters a terminal value ( / / ).
The HSM exits
back to
regardless of merge outcome —
then re-evaluates whether more worktree-bearing tasks remain and either re-enters
for the next, or transitions on to
when all delegation is complete.
Schema Discovery
For the argument schema, call
mcp__exarchos__exarchos_orchestrate({ action: "describe", actions: ["merge_orchestrate"] })
. The full feature-workflow phase playbook (which includes
) is available via
mcp__exarchos__exarchos_workflow({ action: "describe", playbook: "feature" })
. Event payload shapes come from
mcp__exarchos__exarchos_event({ action: "describe", eventTypes: ["merge.preflight", "merge.executed", "merge.rollback"] })
.
Completion Criteria
If any criterion fails, consult
references/recovery-runbook.md
before re-dispatching.