MGS3010: redundant gate deferred under load
A ci gate was not started. An identical-or-equivalent gate already passed for this branch on this machine, and starting another would queue it behind work the machine is already running - so magus refuses fast instead. A deferral is never a success: the command exits 75, and the refusal prints every input to its decision, so a reader can reconstruct and dispute it from the message alone:
[MGS3010] not running the ci gate for branch polish: it is redundant and this
machine's build pool is saturated.
green gate: run inv0193ab, branch polish, commit 2d15f62c, recorded
2026-09-03T18:04:11Z (14m ago), fingerprint 4c1f22ab9e01
delta since that gate, every file:
docs/guides/setup.md: prose (matches "**/*.md" (built-in default))
gen/knowledge-graph.json: generated (a declared output glob claims it)
run.go: comment-only (only comments differ from the green gate's revision)
machine pool: saturated: 8 of 8 slots held, 2 runs queued
override: pass --no-redundancy-check to run it here anyway
alternative: push; the pull request runs the identical check
This fires only when all three facts hold at once:
- A green gate is on record for this branch. Every completed
magus run ciandmagus affected cirecords its branch, commit, input fingerprint and verdict in the per-repository session store, which every worktree shares. The first gate on a branch always runs; so does any gate after a recorded failure - in both cases this feature says nothing at all. - The gate would re-verify what that one verified. Either the input fingerprint
is identical (derived from the same per-step cache keys a real run mints - sources,
tool versions, charms), or everything changed since the green gate's commit is
low-risk: generated output magus owns (structural: declared output globs),
prose (globs: markdown by default, configurable - see below), or comment-only
edits (Go and Buzz through the lexers magus owns; other spelled languages
through a declared comment/string syntax, string-aware and nesting-aware, with
directive comments like
//go:buildor# type:always counting as code; a language with no declaration is always code, never comment-only). A merge commit in the range is never low-risk, however clean - a merge combines two verified histories into a tree neither gate saw, so it always re-gates. - The machine admission pool is saturated. The daemon that arbitrates the machine budget reports work queued or every slot held. On an idle machine the identical finding prints as an advisory - informative, never behavior-changing - and the gate runs anyway; with no daemon reachable there is no load signal and the check fails open the same way. The daemon is an accelerant, never a capability gate.
Exit 75 is EX_TEMPFAIL, the same convention as MGS3009: the
refusal is about this machine's moment, not about the build. The refusal is also
recorded in the session store as a deferred gate record pointing at the green gate
it deferred to, so the decision stays interrogable after the fact.
Configuring the prose class
magus.project's gate_low_risk key declares the prose globs, following the same
project-relative shape as review_required. magus ships **/*.md and
**/*.markdown; any declaration replaces the defaults workspace-wide, and []
turns the prose class off. The per-path lines name the matching glob and whether it
came from the defaults or a declaration, so each verdict reads straight back to the
key that produced it. See workspace. The other
two classes are deliberately not glob-configurable: generated stays structural and
comment-only stays a mechanism, because a glob cannot assert either honestly.
Why
Parallel worktrees duplicate gates. Several agents iterating on one branch each run
magus affected ci out of discipline, and on a loaded machine the duplicates queue
behind each other verifying the same inputs - wall clock spent proving what the
session store already proves. The record is per-repository and machine-wide precisely
so one worktree's green gate is visible to its siblings.
Refusing only under load keeps the check honest: an idle machine loses nothing by re-verifying, so it merely says what it found and runs. And the named alternative is not "skip verification" but "verify where it is not redundant": the push triggers the pull request pipeline, which runs the identical check on shared runners.
Resolution
-
Push. The pull request runs the same gate; that is the alternative the refusal exists to point at.
-
Force the run. Pass
--no-redundancy-checktomagus run ciormagus affected cito skip the check for this invocation. -
Let the machine drain.
magus statusnames who holds the budget. Once the pool has room, the same command prints the finding as an advisory and runs. -
Dispute a classification. Every path line names the glob or mechanism that classified it. A glob doing the wrong work is yours to change:
gate_low_riskin the declaring magusfile. -
Change something real. Any non-low-risk change in the delta makes the next gate run silently; the check never argues with a tree that differs meaningfully from the one it verified.
See also
- MGS3009: the machine budget this check reads, and the exit-75 convention.
- workspace: the
gate_low_riskdeclaration. - Concurrency: the scopes magus coordinates on one machine.
- Daemon and concurrency: the process that owns the budget, and why losing it fails open.