---
title: "MGS3010: redundant gate deferred under load"
description: Fires when a ci gate is not started because an identical-or-equivalent gate already passed for this branch on this machine and the machine admission pool would queue the run, so pushing (where the pull request runs the identical check) beats waiting.
tags: [MGS3010, ci, gate, redundancy, admission, daemon, worktrees, exit 75, no-redundancy-check, gate_low_risk]
---

# 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:

```text
[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 ci` and
  `magus affected ci` records 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:build` or `# 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](MGS3009.md): 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.md](../../../concepts/workspace.md). 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

1. **Push.** The pull request runs the same gate; that is the alternative the
   refusal exists to point at.

2. **Force the run.** Pass `--no-redundancy-check` to `magus run ci` or
   `magus affected ci` to skip the check for this invocation.

3. **Let the machine drain.** `magus status` names who holds the budget. Once the
   pool has room, the same command prints the finding as an advisory and runs.

4. **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_risk`
   in the declaring magusfile.

5. **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](MGS3009.md): the machine budget this check reads, and the exit-75 convention.
- [workspace.md](../../../concepts/workspace.md): the `gate_low_risk` declaration.
- [Concurrency](../../../concepts/concurrency.md): the scopes magus coordinates on one machine.
- [Daemon and concurrency](../../../guides/integrations/daemon.md): the process that owns the budget, and why losing it fails open.
