Auto-Merge
When the Flywheel orchestrator is trusted to ship work without a human clicking MERGE, you can flip a single toggle and Overdeck will schedule eligible PRs for merge with a short cooldown window. During the cooldown an audible announcement fires, a cancellable banner appears in the dashboard, and the merge runs through the exact same code path as the MERGE button when the cooldown expires.Enabling
Auto-merge is gated by one persisted toggle in the dashboard’sapp_settings store:
true (auto-merge OFF — operator UAT required before merge).
When the toggle is false, the Flywheel orchestrator may schedule auto-merge
for any issue that satisfies the eligibility predicate.
Per-project default
Every registered project’s HOME tab includes a Project settings panel, even when the project has no in-flight pipeline issues. Its auto-merge control offers ⚡ Auto, 🔒 Hold for UAT, and Global default, and the collapsed row shows the current auto-merge and swarming values at a glance. The project default applies only to issues without an explicit per-issue auto-merge setting. Changes are saved throughPOST /api/projects/:key/auto-merge-default and stored
in ~/.overdeck/projects.yaml.
Auto-merge vs. UAT batch trains. This toggle controls per-issue scheduled
auto-merge — Overdeck merging one eligible PR at a time without a human click.
The separate
flywheel.merge_train_enabled flag enables UAT batch
trains, where ready features are assembled into one
tested batch you promote together. They are independent flags: auto-merge ships
individual PRs on a cooldown; batch trains assemble-and-promote a tested bundle.
Leave require_uat_before_merge at its default (true, auto-merge OFF) when you
want a human to UAT each batch before promoting it.Eligibility
A PR is eligible for auto-merge only when all of these are true:readyForMergeistrue(review, test, and ship roles all passed)- The PR is open (not closed, not draft, not already merged)
- GitHub reports all CI checks as completed and passing
(no
checksFailedand nochecksPending) - GitHub reports the PR as
mergeable(no merge conflicts, branch protection satisfied) - None of the blocker labels are present on the issue:
needs-designneeds-discussiondo-not-merge
do-not-merge label
while the timer was running) gets surfaced as a blocked entry instead of
merged.
Cooldown
Cooldown is fixed at 5 minutes of wall-clock time from when the orchestrator schedules the merge to when the executor fires. The countdown is persisted in SQLite, so it survives dashboard restarts — if the dashboard sleeps through the deadline, the executor still picks the entry up on the next tick and re-validates eligibility before firing. The cooldown is not configurable today; it’s a deliberate single-knob value that gives the operator a predictable cancel window.Cancelling
Three ways to cancel an in-flight auto-merge during its cooldown:- The dashboard’s pending-auto-merges banner has a Cancel button.
-
DELETE /api/flywheel/auto-merge/:idagainst the dashboard. -
The CLI:
This calls the DELETE endpoint, removes the entry from the pending list, and emits an
auto-merge cancelled for PAN-123TTS announcement so the operator knows the abort took effect.
merging. Once the executor has started running
the merge there is nothing to cancel — at that point it’s the same code path
as clicking MERGE.
Queue interaction
The dashboard runs at most one merge at a time per project. If two auto-merges become due at the same instant, the second is requeued with a short backoff (scheduledMergeAt bumped by 60 seconds, status reverted to
pending) so the next executor tick re-evaluates eligibility and tries
again. Stale merging rows are prevented by this requeue path; the executor
never leaves a row stuck mid-flight when triggerMerge() returns a
non-terminal status.
Inspecting state
Failure handling
When the executor fires and the merge fails (e.g. surface-level rebase conflict raised at merge time), the row is moved tofailed with the failure
reason captured, a TTS announcement plays, and the orchestrator surfaces the
entry as an investigate suggestion in its next tick snapshot. The operator
can then either fix the underlying problem and reschedule, or cancel the
failed entry to clear it.
Related
pan flywheel config— read/write the two flywheel autonomy togglespan merge cancel <id>— cancel a pending auto-mergeroles/flywheel.md— the orchestrator’s contract; references the toggle when deciding whether to call the scheduler vs. emitting amergesuggestion for human action.