# How the Refinery Implements the Merge Queue Strategy in Gas Town

> Discover how the Refinery uses a sequential rebase-and-fast-forward merge queue strategy in Gas Town. Learn about its linear history, test gating, and conflict resolution.

- Repository: [Gas Town Hall/gastown](https://github.com/gastownhall/gastown)
- Tags: deep-dive
- Published: 2026-07-07

---

**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`](https://github.com/gastownhall/gastown/blob/main/internal/protocol/refinery_handlers.go) handles these steps:

```bash

# 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:

```bash
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:

```bash
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`](https://github.com/gastownhall/gastown/blob/main/internal/protocol/refinery_handlers.go)**: Go implementation of mail-driven handlers processing `MERGE_READY` and `MERGE_FAILED` signals
- **[`internal/cmd/refinery.go`](https://github.com/gastownhall/gastown/blob/main/internal/cmd/refinery.go)**: CLI entry point that wires the patrol molecule into the Gas Town daemon
- **[`internal/config/roles/refinery.toml`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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.