How the Refinery Implements the Merge Queue Strategy in Gas Town

The Refinery employs a sequential rebase-and-fast-forward merge workflow that processes polecat branches one at a time from a Beads-managed queue, ensuring linear history through strict test gating and automated conflict resolution.

The merge queue strategy in the gastownhall/gastown repository centers on the Refinery, an automated processor that eliminates parallel merge conflicts by strictly serializing integration work. Unlike traditional merge queues that attempt concurrent processing, the Refinery guarantees a clean Git history by rebasing each branch onto the current target before applying a fast-forward-only merge. This deterministic approach is codified in internal/templates/roles/refinery.md.tmpl and implemented across the Go source tree.

Core Principles of the Refinery Merge Queue Strategy

Single-Source of Truth via Beads Commands

The Refinery never interrogates raw git branch output to determine pending work. Instead, it relies exclusively on the Beads command gt mq list <rig> as the authoritative source for the ordered merge queue. This command returns polecat branches sequenced by priority, dependencies, and timestamps, ensuring that high-priority changes land first without manual intervention.

Sequential Processing and Fast-Forward Only Merges

Each iteration of the Refinery patrol processes exactly one polecat branch. The workflow in internal/templates/roles/refinery.md.tmpl (lines 124-138) mandates:

  1. Checkout a temporary branch from the polecat branch
  2. Rebase onto the current target branch (git rebase origin/<target>)
  3. Execute the configured test suite
  4. Merge using git merge --ff-only into the target
  5. Push the updated target

After each successful merge, the target branch advances, forcing the next iteration to rebase onto the new baseline. This sequential rebase-and-fast-forward pattern prevents the "old-target" conflicts common in parallel merge strategies.

Automated Conflict Resolution

When git rebase encounters unresolvable conflicts, the Refinery aborts the operation and triggers a failure protocol. According to the template specification (lines 101-110), the system executes git rebase --abort, reopens the source issue via bd update <source-issue> --status=open, notifies the Witness role with a MERGE_FAILED mail, closes the merge request, and deletes the polecat branch.

Test Gating Requirements

Before any fast-forward merge completes, the branch must pass the configured test pipeline defined in Beads. Failures are categorized either as branch-specific issues (triggering the conflict resolution protocol) or as pre-existing infrastructure problems (filed as Beads bugs). This gate prevents broken code from entering the target branch.

Step-by-Step Refinery Patrol Workflow

The concrete implementation follows the patrol molecule (mol-refinery-patrol) defined in the role template. The process begins immediately upon receipt of a MERGE_READY mail sent by the Witness role, implementing a "Hook → Execute" model with no manual approval delays.

The execution flow in internal/protocol/refinery_handlers.go handles these steps:


# 1. Check for MERGE_READY signal

gt mail inbox | grep MERGE_READY && gt mail read <msg-id>

# 2. Obtain ordered queue from Beads (single-source of truth)

gt mq list my-rig

# 3. Process next branch (example: polecat/feat-123)

git checkout -b temp polecat/feat-123
git rebase origin/main

# 4. Run test suite (commands defined in Beads)

./scripts/typecheck && ./scripts/lint && go test ./...

# 5. Fast-forward merge and push

git checkout main
git merge --ff-only temp
git push origin main

# 6. Cleanup

git branch -d temp
git branch -d polecat/feat-123

Handling Merge Conflicts and Failures

When conflicts arise during the rebase phase, the Refinery distinguishes between resolvable and unresolvable states. For resolvable conflicts, manual intervention is not supported—the branch must be updated upstream and resubmitted. For unresolvable conflicts, the automated failure protocol executes:

git checkout -b temp polecat/feat-123
git rebase origin/main

# Conflict appears

git status

# If unresolvable:

git rebase --abort
bd update <source-issue> --status=open
gt mq close <mr-id> --reason="Unresolvable conflicts"
gt mail send my-rig/witness -s "MERGE_FAILED" \
  -m "Branch polecat/feat-123 cannot be merged; source issue reopened."

Integration Branch Processing

Integration branches representing large epics receive special treatment in the merge queue strategy. The Refinery never merges these using raw Git commands. Instead, it processes them exclusively through the dedicated Beads command:

gt mq integration land <epic-id>

This command, referenced in internal/templates/roles/refinery.md.tmpl (lines 142-149), ensures that epic-level integration work undergoes additional validation steps before entering the main line of development.

Key Source Files and Implementation

The merge queue strategy is distributed across these critical source files:

  • internal/templates/roles/refinery.md.tmpl: Human-readable specification defining the patrol molecule, merge logic, and failure handling protocols
  • internal/protocol/refinery_handlers.go: Go implementation of mail-driven handlers processing MERGE_READY and MERGE_FAILED signals
  • internal/cmd/refinery.go: CLI entry point that wires the patrol molecule into the Gas Town daemon
  • internal/config/roles/refinery.toml: Default configuration for target branches, work directories, and notification settings
  • gt-model-eval/tests/refinery‑triage.yaml: Test scenarios validating the patrol workflow

Summary

  • The Refinery implements a sequential rebase-and-fast-forward merge strategy that processes one branch at a time from the Beads-managed queue obtained via gt mq list <rig>.
  • Fast-forward only merges (--ff-only) guarantee linear history; unresolvable conflicts trigger automatic cleanup, issue reopening, and Witness notification.
  • Test gating blocks merges that fail the configured pipeline, attributing failures to either the branch or pre-existing infrastructure problems.
  • Integration branches require the specialized gt mq integration land <epic-id> command rather than standard merge operations.
  • The "Hook → Execute" model ensures immediate processing upon MERGE_READY mail receipt, eliminating manual approval delays.

Frequently Asked Questions

What happens when a fast-forward merge is not possible in Gas Town?

If git merge --ff-only fails because the branch has diverged from the target in a non-linear fashion, the Refinery treats this as an unresolvable condition. According to internal/templates/roles/refinery.md.tmpl, the system aborts the operation, reopens the source issue, sends a MERGE_FAILED mail to the Witness, closes the merge request, and deletes the polecat branch, leaving manual resolution to the developer.

How does the Refinery determine the order of branches in the merge queue?

The Refinery calls gt mq list <rig> to obtain an ordered list from Beads. This command sorts polecat branches by priority markers, dependency chains, and timestamps, ensuring that urgent or foundational changes merge before dependent work. Raw git branch listings are never used as a source of truth.

What is the difference between regular polecat branches and integration branches?

Regular polecat branches follow the standard sequential rebase-and-merge workflow through the Refinery patrol. Integration branches (epics) bypass raw Git merges entirely and must be landed using the specialized command gt mq integration land <epic-id>, which enforces additional validation steps appropriate for large-scale feature integration.

How does the Refinery handle test failures during the merge process?

Test failures abort the merge attempt immediately. The Refinery, as implemented in internal/protocol/refinery_handlers.go, distinguishes between branch-specific failures (which reopen the source issue and notify the Witness) and infrastructure failures (which generate Beads bug reports). In both cases, the polecat branch is cleaned up and removed from the queue until the underlying issue is fixed.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →