Skip to content

.github/workflows/auto-merge.yml

Everything you have forged now joins: the turning wheel, the warden's gate, the oath-bound golems, the sealed evidence, the mana ledger, the honest fixer. One arc remains โ€” the most dangerous one. For the serpent to close its circle, the loop must merge its own repairs. The realm grants that power only behind two final wards: a merge job that waits for every check except its own reflection, and a customs gate that inspects each pull request's cargo before the seal falls. Then you turn the whole wheel, hands off, and watch a defect you planted get witnessed, repaired, gated, merged, and certified โ€” by nothing but the machine you built.

The real-world skills: composing multi-lane automation into one architecture, the self-referential deadlock class (a checker that waits on itself), diff classification as a merge precondition, and reading a fully autonomous run end-to-end.

๐Ÿงญ Campaign note: Level 1110 is Architecture & Design Patterns โ€” precisely what this chapter is: the pattern language of the whole campaign, assembled.

๐Ÿ“– The Legend Behind This Quest

The engine's merge warden carried one flaw so quiet it survived every review: told to "wait until every check on the pull request finishes," it waited โ€” on all of them โ€” including its own. And its own check could never finish while it stood there watching. Thirty minutes of a warden staring at his own reflection, then a timeout, then a red mark, every single time. Four dependency scrolls piled up unmerged before anyone read the water. The cure was one idea: when you are one of the checks, excuse yourself from the list you are waiting on. The morning after that fix merged, the whole circle closed for the first time: six slices walked, one repair gated and kept, and the merge warden โ€” no longer hypnotized โ€” sealed it into the chronicle unaided.

๐ŸŽฏ Quest Objectives

By the end of this quest you will:

  • Draw the full architecture โ€” every lane, gate, and artifact of your loop on one map
  • Build the merge warden โ€” auto-merge that polls checks excluding its own run and merges only on all-green
  • Install the smuggle guard โ€” classify the fix PR's diff; only pure content merges itself
  • Close the circle โ€” one full turn: plant a defect โ†’ walk witnesses โ†’ fixer repairs โ†’ gates pass โ†’ auto-merge seals โ†’ ledger certifies
  • Write the runbook โ€” the one page a human needs the morning something is red

๐Ÿ—บ๏ธ Quest Prerequisites

  • ๐Ÿ“‹ Chapters Iโ€“VI complete and green
  • ๐Ÿ“‹ AUTOMERGE_ENABLED left unset until the final battle โ€” you'll arm it last, like a professional

๐Ÿง™โ€โ™‚๏ธ Chapter 1: The Map of the Whole

Before the last weld, draw what you have built. This is your potion book's architecture โ€” and, scaled up, the realm's quest-perfection engine:

graph TD
    CRON[โฐ Daily schedule] --> GATE[๐Ÿšฆ Gate: LOOP_ENABLED + auth]
    GATE -->|go| PLAN[๐Ÿ“… Plan: budget.yml window,\npinned date]
    PLAN --> CHECK[๐Ÿงช Mint evidence:\ndeterministic checker]
    CHECK --> SEAL[๐Ÿ” Seal to RUNNER_TEMP]
    SEAL --> WALK[๐Ÿค– Scribe golem:\nreads evidence, writes report]
    WALK --> RESTORE[๐Ÿ” Restore sealed copy]
    RESTORE --> LEDGER[๐Ÿงพ Ledger: coverage,\nperfect computed in code]
    LEDGER --> DIGEST[๐Ÿ”ญ Watchtower digest]
    LEDGER -->|witnessed failure| FIXGATE[๐Ÿšฆ Gate: FIX_ENABLED]
    FIXGATE -->|go| FIXER[โš–๏ธ Fixer golem:\nsmallest witnessed repair]
    FIXER --> KRGATE{Keep/revert gate:\nchecker + linter}
    KRGATE -->|kept| PR[๐Ÿ”€ Workflow opens fix PR]
    KRGATE -->|reverted| DIGEST
    PR --> SMUGGLE{๐Ÿ›ƒ Smuggle guard:\ncontent-only diff?}
    SMUGGLE -->|yes| MERGE[๐Ÿ”€ Merge warden:\nall checks green except self]
    SMUGGLE -->|no| HUMAN[๐Ÿ™‹ needs-human]
    MERGE --> CRON

Every box is something you built. The two unbuilt ones โ€” the smuggle guard and the merge warden โ€” are today.

๐Ÿ” Knowledge Check

  • Trace a forged-evidence attempt through the map. Where does it die?
  • Trace a mana drought. Which boxes limit the damage, and which record it?

๐Ÿง™โ€โ™‚๏ธ Chapter 2: The Merge Warden and the Mirror

The naive merge warden is one line โ€” gh pr checks "$PR" --watch then merge โ€” and it carries the deadlock: --watch waits for every check, including the warden's own, which stays pending exactly as long as it watches. Build the cured version:

{% raw %}

# .github/workflows/auto-merge.yml
name: Merge Warden
on:
  pull_request_target:
    types: [labeled, opened, synchronize, ready_for_review]

permissions:
  contents: write
  pull-requests: write
  checks: read

jobs:
  merge:
    if: >-
      vars.AUTOMERGE_ENABLED == 'true' &&
      github.event.pull_request.head.repo.full_name == github.repository &&
      contains(github.event.pull_request.labels.*.name, 'auto-fix') &&
      !contains(github.event.pull_request.labels.*.name, 'needs-human')
    runs-on: ubuntu-latest
    timeout-minutes: 30
    env:
      GH_TOKEN: ${{ github.token }}
      PR: ${{ github.event.pull_request.number }}
      RUN_ID: ${{ github.run_id }}
    steps:
      - name: Wait for every check EXCEPT our own reflection, then merge
        run: |
          set -euo pipefail
          deadline=$(( $(date +%s) + 25 * 60 ))
          while :; do
            rows=$(gh pr checks "$PR" --json bucket,link \
                     --jq '.[] | [.bucket, .link] | @tsv' 2>/dev/null || true)
            others=$(printf '%s\n' "$rows" | grep -v "/${RUN_ID}/" || true)
            if [ -z "$others" ]; then    # only our own check exists so far โ€” wait, don't merge unchecked
              [ "$(date +%s)" -ge "$deadline" ] && exit 1
              sleep 30; continue
            fi
            if printf '%s\n' "$others" | awk -F'\t' '$1=="fail"{f=1} END{exit !f}'; then
              gh pr edit "$PR" --add-label needs-human
              echo "a real check failed โ€” standing down."; exit 1
            fi
            if printf '%s\n' "$others" | awk -F'\t' '$1=="pending"{p=1} END{exit !p}'; then
              [ "$(date +%s)" -ge "$deadline" ] && exit 1
              sleep 30; continue
            fi
            break                        # no fails, none pending โ†’ all green
          done
          gh pr merge "$PR" --squash --delete-branch

The four verdict branches, in oath form: a real failure blocks; pending waits; all-green merges; "only my own reflection" waits rather than merging unchecked. That last branch is the humility clause โ€” silence is not proof.

Before the warden may reach for the seal, the smuggle guard inspects the cargo. An auto-fix label is a claim; the diff is the truth:

{% raw %}

      - name: Smuggle guard โ€” the label says content; verify the diff agrees
        run: |
          set -euo pipefail
          files=$(gh pr view "$PR" --json files --jq '.files[].path')
          bad=$(printf '%s\n' "$files" | grep -vE '^potions/' || true)
          if [ -n "$bad" ]; then
            gh pr edit "$PR" --add-label needs-human
            echo "::error::auto-fix PR touches non-content paths:"; echo "$bad"
            exit 1
          fi

Now a golem that somehow smuggled a workflow edit into a "content fix" meets a wall made of grep, not trust. Run this step before the wait-and-merge step.

๐Ÿ” Knowledge Check

  • Why key the exclusion on the run id rather than the check's name?
  • Why does the smuggle guard read the diff itself instead of trusting the label the fix lane applied?

๐Ÿง™โ€โ™‚๏ธ Chapter 3: The Full Turn โ€” Hands Off

The final battle is a checklist, not a fight. Arm everything, plant one defect, and touch nothing else:

# Arm all three switches โ€” the loop is now fully autonomous:
gh variable set LOOP_ENABLED --body true
gh variable set FIX_ENABLED --body true
gh variable set AUTOMERGE_ENABLED --body true

# Plant a knowable defect on today's window (typo a command in one potion),
# commit it like an innocent mistake, and step away from the keyboard:
git add -A && git commit -m "content: update elixir recipe" && git push

gh workflow run first-turn.yml     # or wait for the morning cron
gh run watch

Then read the turn like a saga, artifact by artifact: the walk witnesses the failure (sealed evidence, ledger fail, Watchtower digest) โ†’ the fix lane opens a PR whose body quotes the witnessed evidence โ†’ the smuggle guard passes it โ†’ the merge warden waits out every other check and seals it โ†’ the next walk of that window flips the ledger to pass โ†’ coverage completes โ†’ perfect: true. If every arrow fired without your hands, the circle is closed.

  • The circle closed: defect planted โ†’ witnessed โ†’ repaired โ†’ gated โ†’ merged โ†’ certified, zero human interventions

๐Ÿ” Reproduce It

The real closing of the real circle:

  • PR #441 โ€” bamr87/it-journey@d8313a993 (+99/โˆ’35): the self-deadlock cure applied to all three merge lanes at once โ€” read its body for the log excerpt of a warden watching himself time out
  • PR #444 โ€” bamr87/it-journey@4eefc45d7: the consolidated digest of the first fully-autonomous morning (six slices walked, windows and coverage per slice)
  • PR #445 โ€” bamr87/it-journey@08ca5d1cc: the repair from that same morning โ€” opened by the fix lane, merged by the merge warden, no human hands
  • The smuggle guard at scale: scripts/ci/classify_changes.py + its gate in .github/workflows/content-auto-merge.yml

๐ŸŽฎ Mastery Challenge

Objective: prove the wards hold, then write the human's page.

Success Criteria: - [ ] Deadlock demo: temporarily revert the warden to --watch, open a fix PR, and watch it hang on its own reflection; restore the cure and watch the same PR merge - [ ] Smuggle demo: make the fixer's branch also touch scripts/check.sh (edit it from a workflow step for the test) and verify the guard labels it needs-human instead of merging - [ ] The runbook: one page โ€” what each switch disarms, where evidence/ledger/digest live, what needs-human means, and the first three commands to run when the morning digest is red - [ ] The disarm drill: gh variable delete AUTOMERGE_ENABLED and confirm fixes still open PRs that politely wait for a human โ€” autonomy degraded, never wedged

๐ŸŽ Rewards & Progression

  • โ™พ๏ธ Loop Weaver โ€” the serpent turned once, unaided, on a repo you built from an empty directory
  • ๐Ÿ‘‘ Perfection Engineer โ€” campaign complete: return to the hub and claim it
  • โšก Skills unlocked: loop architecture ยท self-merge safety ยท smuggle guards ยท runbook writing
  • ๐Ÿ“Š +200 XP

๐Ÿ—บ๏ธ Quest Network

graph LR
    Prev[โš–๏ธ VI ยท The Fixer's Oath] --> Cur[โ™พ๏ธ VII ยท Weaving the Whole]
    Cur --> Hub[๐Ÿ‘‘ The Ouroboros Loop โ€” complete]
    click Prev "/quests/1101/ouroboros-loop-06-the-fixers-oath/"
    click Hub "/quests/codex/ouroboros-loop/"

๐Ÿ”ฎ Next Adventures

๐Ÿ“š Resource Codex

๐Ÿ•ธ๏ธ Knowledge Graph

Structured wiki-links connect this quest to the IT-Journey knowledge graph.

Campaign hub: [[Epic Quest: The Ouroboros Loop]] Previous: [[The Fixer's Oath]] Level home: [[Level 1110 - Architecture & Design Patterns]]