Skip to content

Implement local merge queue (Mac mini, sign-on-green, replace Actions) #230

@obj-p

Description

@obj-p

Track implementing the local merge queue per the plan in docs/local-merge-queue-plan.md (landed in #229).

Goal

Replace GitHub Actions with a Mac mini single-worker merge queue. Only the maintainer can push to a queue remote. A clean-room macOS VM rebases onto origin/main, runs the merge bar (lint + unit + example integration), signs verified commits with a VM-only key, and fast-forwards main through a deploy key that a ruleset names as the sole bypass actor. No CI runs on GitHub.

Phases (each has a single pass/fail check in the plan)

  • Phase 1 — VM pipeline. post-toolchain snapshot + in-VM script that checks out a SHA, rebases, runs the pipeline, signs on green. Verify: known-good SHA returns signed, known-bad rejected, key injected at run (not baked into snapshot).
  • Phase 2 — Key bundle + injection. Encrypted bundle; harness decrypts and injects onto tmpfs. Verify: rebuild snapshot from provisioning only, inject bundle, landing signs under the same identity.
  • Phase 3 — Host harness. Bare queue remote + receive hook, VM restore/push-in/collect, local branch reset. Verify: end-to-end landing on a scratch repo via git push queue.
  • Phase 4 — GitHub cutover. Bootstrap PreviewsMCP: deploy key, ruleset, require-signed-commits, allowed_signers, disable Actions. Verify: account push to main rejected, web merge button blocked, VM landing shows PR merged.
  • Phase 5 — Rehost drill. Move the queue to a second Mac using only the rehost runbook. Verify: a landing succeeds with no manual step carried from the first host.

Key decisions (settled in the plan)

  • Host: Mac mini at a Tailscale IP, single-worker.
  • Keys: external encrypted bundle injected at run (option B), not baked into the snapshot.
  • Layout: separate private merge-queue tool repo (harness + VM kit from research/vm/ + bootstrap); PreviewsMCP holds only .mergequeue.toml + allowed_signers.
  • No GitHub CI; Actions disabled. Fork PRs get no automated signal until run through the queue.

Open questions (from the plan)

  • Warm build caches in the snapshot vs a pristine environment.
  • Per-push advisory tier vs per-merge full pipeline.
  • Batching if landings back up (Bors-style).
  • Secret store for the bundle: age-encrypted file vs macOS keychain vs secrets manager.
  • Snapshot transport on rehost: copy the image vs rebuild from provisioning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions