Summary
automerge.yml can leave a mergeable PR open forever. Pin PR #148 stranded this way for four days, which silently froze the GitOps deploy chain.
Root cause
automerge.yml fires on check_suite: completed, reads mergeStateStatus, and only calls enqueuePullRequest when the PR is already mergeable. At that instant GitHub has usually not recomputed mergeStateStatus, so the PR reads BLOCKED. The job then logged:
#148: mergeStateStatus=BLOCKED, waiting for a later check_suite event
and exited. If that was the last check_suite: completed event for the PR, nothing ever retried. The PR subsequently went CLEAN and sat open indefinitely.
Confirmed in the run log for #148 (2026-09-02T20:55:12Z), and reproduced live on #150 the same session: checks completed and the PR went CLEAN, no further automerge run fired, and the merge queue stayed empty until it was enqueued by hand.
Why only this repo
Muninn is currently the only Emkraan repo with a repo-level merge-queue ruleset, so it is the only repo where the explicit enqueuePullRequest call is load-bearing. Every other repo takes the native auto-merge path, which GitHub itself retries.
Impact
build-and-deploy.yml classifies mode=webhook only for a chore: pin muninn -> head commit. A stranded pin PR therefore means the Portainer redeploy never fires and the host keeps serving the previous image.
Observed: HQ_Muninn was running sha-35f160e (built 2026-08-26) while sha-4ecdaec (Sep 2) and sha-f1ffed7 (Sep 6) existed. No alert covered it.
Two pre-existing standard violations found alongside
github-actions-monorepo-standard.md Acceptance requires automerge.yml to mint the deploy-bot App token and pass it to the step calling enqueuePullRequest. This repo ran the mutation under the default GITHUB_TOKEN.
- The
UNSTABLE self-check handling (homelab-stacks #406) was missing, so a fast-CI PR could strand on this job's own in-progress automerge check.
Fix
PR #151 rebases automerge.yml onto the homelab-stacks canonical version (fixing both violations above) and adds a 15-minute scheduled sweep that enqueues any open, mergeable, unqueued PR. The sweep is the convergence guarantee: it is independent of event delivery, so a dropped or badly-timed event can no longer strand a PR.
Detection for the deploy-side symptom is added separately in homelab-stacks#449.
Summary
automerge.ymlcan leave a mergeable PR open forever. Pin PR #148 stranded this way for four days, which silently froze the GitOps deploy chain.Root cause
automerge.ymlfires oncheck_suite: completed, readsmergeStateStatus, and only callsenqueuePullRequestwhen the PR is already mergeable. At that instant GitHub has usually not recomputedmergeStateStatus, so the PR readsBLOCKED. The job then logged:and exited. If that was the last
check_suite: completedevent for the PR, nothing ever retried. The PR subsequently wentCLEANand sat open indefinitely.Confirmed in the run log for #148 (2026-09-02T20:55:12Z), and reproduced live on #150 the same session: checks completed and the PR went
CLEAN, no further automerge run fired, and the merge queue stayed empty until it was enqueued by hand.Why only this repo
Muninn is currently the only Emkraan repo with a repo-level
merge-queueruleset, so it is the only repo where the explicitenqueuePullRequestcall is load-bearing. Every other repo takes the native auto-merge path, which GitHub itself retries.Impact
build-and-deploy.ymlclassifiesmode=webhookonly for achore: pin muninn ->head commit. A stranded pin PR therefore means the Portainer redeploy never fires and the host keeps serving the previous image.Observed:
HQ_Muninnwas runningsha-35f160e(built 2026-08-26) whilesha-4ecdaec(Sep 2) andsha-f1ffed7(Sep 6) existed. No alert covered it.Two pre-existing standard violations found alongside
github-actions-monorepo-standard.mdAcceptance requiresautomerge.ymlto mint the deploy-bot App token and pass it to the step callingenqueuePullRequest. This repo ran the mutation under the defaultGITHUB_TOKEN.UNSTABLEself-check handling (homelab-stacks #406) was missing, so a fast-CI PR could strand on this job's own in-progressautomergecheck.Fix
PR #151 rebases
automerge.ymlonto the homelab-stacks canonical version (fixing both violations above) and adds a 15-minute scheduled sweep that enqueues any open, mergeable, unqueued PR. The sweep is the convergence guarantee: it is independent of event delivery, so a dropped or badly-timed event can no longer strand a PR.Detection for the deploy-side symptom is added separately in homelab-stacks#449.