skip to content

The merge pattern

Default finish-time merge repair: resolve textual conflicts, adjudicate main-side residue, and route red merge gates through the shared troubleshoot pass.

merge — finish-time merge repair

Included by entry patterns that use Gantry's shipped finish-time merge reconciliation policy. The engine owns the git merge bracket and invokes this pattern once for each re-derived merge state.

merge
[header]
pattern_language_compatibility = "3"
entry = "merge"
include = ["troubleshoot.toml"]
on_stop = "write_handover"
description = """
Default finish-time merge repair: resolve textual conflicts, adjudicate main-side residue, and route
red merge gates through the shared troubleshoot pass.
"""

[patterns.merge]

[[patterns.merge.parameters]]
name = "merge_state"
kind = "text"
description = "The engine-derived merge state: `conflicted`, `residue`, or `gate-red`."

[[patterns.merge.parameters]]
name = "merge_attempt_ceiling"
kind = "text"
default = "2"
description = "The per-state attempt ceiling the engine enforces around this pattern."

[[patterns.merge.parameters]]
name = "merge_attempt"
kind = "text"
default = "1"
description = "The one-based attempt count the engine is running for the current merge state."

[[patterns.merge.parameters]]
name = "troubleshoot_prompt"
kind = "prompt-id"
default = "troubleshoot"
description = "The troubleshoot pass's prompt, used for a red declared gate after integrating the home branch."

[[patterns.merge.parameters]]
name = "protected_check"
kind = "path"
default = ".gantry/no-protected-check"
description = "The gate protection parameter the enclosing run freezes."

[[patterns.merge.parameters]]
name = "declared_gate_command"
kind = "path"
default = "bin/gate"
description = "The run-scoped gate command that judges the integrated worktree."

[[patterns.merge.parameters]]
name = "branch"
kind = "text"
default = "the run branch"
description = "The run branch label the merge prompts name."

[[patterns.merge.parameters]]
name = "conflict_context"
kind = "text"
default = "No conflict context was provided."
description = "The engine's conflict path list or marker-free gate-red fact."

[[patterns.merge.parameters]]
name = "files"
kind = "text"
default = "No residue files were provided."
description = "The per-file residue evidence the adjudicator prompt reads."

[[patterns.merge.parameters]]
name = "merge_last_refusal"
kind = "text"
default = "No previous refusal has been recorded for this merge state."
description = "The engine's previous refusal reason for this merge state."

[[patterns.merge.steps]]
name = "read_merge_state"
title = "Read Merge State"
type = "command"
run = '''
mkdir -p "$orchestration/state"
case "$merge_state" in
  conflicted|residue|gate-red) printf "%s\n" "$merge_state" > "$orchestration/state/merge-state.txt" ;;
esac
'''
outputs = [
  { name = "resolved_merge_state", path = "state/merge-state.txt", values = ["conflicted", "residue", "gate-red"] },
]

[[patterns.merge.steps]]
if = "resolved_merge_state"
then = { conflicted = "resolve_conflicted_merge", residue = "adjudicate_merge_residue", gate-red = "repair_merge_gate_red" }
else = "stop_merge_state_absent"

[patterns.resolve_conflicted_merge]

[[patterns.resolve_conflicted_merge.steps]]
name = "resolve_conflicted_merge"
title = "Resolve Merge Conflict"
type = "agent"
stage = "resolve"
prompt = "resolve-merge"
protected = ["PROGRESS.md", ".preamble.sys.md", "bin", "{{protected_check}}"]
confine = true
on_plan_change = "review_plan_change"

[patterns.resolve_conflicted_merge.steps.text]
BRANCH = "{{branch}}"
MERGE_STATE = "an in-progress git merge"
CONFLICT_CONTEXT = """
{{conflict_context}}

Previous refusal:
{{merge_last_refusal}}
"""

[patterns.adjudicate_merge_residue]

[[patterns.adjudicate_merge_residue.steps]]
name = "adjudicate_merge_residue_first"
title = "Adjudicate Merge Residue"
type = "agent"
stage = "resolve"
prompt = "adjudicate-merge"
protected = ["PROGRESS.md", ".preamble.sys.md", "bin", "{{protected_check}}"]
confine = true
on_plan_change = "review_plan_change"

[patterns.adjudicate_merge_residue.steps.text]
BRANCH = "{{branch}}"
FILES = """
{{files}}

Previous refusal:
{{merge_last_refusal}}
"""

[[patterns.adjudicate_merge_residue.steps]]
if = { adjudicate_merge_residue_first = "failed" }
then = "retry_adjudicate_merge_residue"

[patterns.retry_adjudicate_merge_residue]

[[patterns.retry_adjudicate_merge_residue.steps]]
name = "adjudicate_merge_residue_retry"
title = "Retry Adjudicate Merge Residue"
type = "agent"
stage = "resolve"
prompt = "adjudicate-merge"
protected = ["PROGRESS.md", ".preamble.sys.md", "bin", "{{protected_check}}"]
confine = true
on_plan_change = "review_plan_change"

[patterns.retry_adjudicate_merge_residue.steps.text]
BRANCH = "{{branch}}"
FILES = """
{{files}}

Previous refusal:
{{merge_last_refusal}}
"""

[patterns.repair_merge_gate_red]

[[patterns.repair_merge_gate_red.steps]]
name = "merge_gate"
title = "Testing"
type = "gate"
command = "{{declared_gate_command}}"

[[patterns.repair_merge_gate_red.steps]]
if = { merge_gate = "green" }
then = "nothing"
else = "troubleshoot_merge_gate_red"

[patterns.troubleshoot_merge_gate_red]

[[patterns.troubleshoot_merge_gate_red.steps]]
name = "merge_gate_recovery"
type = "call"
pattern = "troubleshoot"

[patterns.troubleshoot_merge_gate_red.steps.parameters]
troubleshoot_prompt = "{{troubleshoot_prompt}}"
declared_gate_command = "{{declared_gate_command}}"
protected_check = "{{protected_check}}"
position = """
The home branch integrated cleanly into the run branch, but the declared run-scoped gate is red in
the integrated worktree. Repair that gate failure or write the handover document. Previous refusal:
{{merge_last_refusal}}
"""

[[patterns.troubleshoot_merge_gate_red.steps]]
if = { troubleshoot_revert = "revert" }
then = "stop_merge_handover"
else = "route_merge_troubleshoot_verdict"

[[patterns.route_merge_troubleshoot_verdict.steps]]
if = "troubleshoot_verdict"
then = { retry = "nothing", handover = "stop_merge_handover" }
else = "nothing"

[patterns.stop_merge_handover]

[[patterns.stop_merge_handover.steps]]
type = "stop"
note = """
The merge pattern reached an authored handover stop. Previous refusal:
{{merge_last_refusal}}
"""

[patterns.stop_merge_state_absent]

[[patterns.stop_merge_state_absent.steps]]
type = "stop"
note = """
The merge invocation did not receive a recognized merge_state value. Previous refusal:
{{merge_last_refusal}}
"""