Skip to content

✅ fresh

last synced 2026-09-29T21:12:19.681221+00:00 · coverage 100% (gate-coverage)

Validation by Beadloom doc_sync — same source as sync-check.

Gate Coverage (component) ​

The verifications a project's pipeline declares that no step of a gate run performed.

Source: src/beadloom/application/gate_coverage.py


Overview ​

beadloom ci runs reindex, lint, sync-check, docs-audit, docs-quality, doc-spaces, scope-check, config-check and doctor. It does not run the test suite. The division is reasonable and every step it does run is named in the output. What was missing until BDL-UX #247 is the other half: the run never said the suite was not among them, while the text around it promises otherwise — CLAUDE.md calls the pre-push hook "the full beadloom ci" and the coordinator skill calls it "the authoritative blocking backstop" whose red "blocks the push".

Measured twice in one slice, both times by the coordinator that wrote most of BDL-068:

  • at 8befa96 a document change altered the approved node set and reddened two tests, and the Gate returned rc 0 over that tree;
  • the S4 docs wave spilled an inline code span carrying <doc> onto the next line in docs/services/cli.md. beadloom ci returned rc 0 over that tree twice, PR #61 opened and all six test legs went red on one assertion that reproduces locally in 0.07 s — roughly 55 runner-minutes to learn what one local command answers instantly.

Naming what was not run does not change the verdict. It is not a step: it has no status, it adds no finding and it moves no exit code. tests/test_gate_not_run.py fails if that stops being true.

Two sides, both derived ​

SideRead fromGoes stale when
what this run performedthe run's own GateStep names, plus any verification the caller ran beside itnever — a suite step added to the gate removes the line by the same act
what the project verifies.github/workflows/*.yml, through rooms.load_jobsnever — a job added to the pipeline is read on the next run

A hand-written sentence ("this gate does not run pytest") is the defect one level up: beadloom-0mdo.42 measured that trap when a derivation shipped behind a hand-written ^(src|tests)/ filter and the filter, not the derivation, decided the answer. So the claim here is a property of the step list, and nothing in this module names a step of the gate.

On this repository the run reports three:

Not run by this gate:
  the test suite — `uv run pytest --cov=beadloom --cov-report=term-missing --cov-fail-under=80` (.github/workflows/ci.yml: tests)
  the style linter — `uv run ruff check src/ tests/` (.github/workflows/ci.yml: tests)
  the type checker — `uv run mypy src/` (.github/workflows/ci.yml: tests)

The second and third are the ones nobody had filed. The gate's own step is named lint and checks the architecture boundaries, not the source style, so [PASS] lint beside a green verdict reads as ruff to anyone who has not read the step. DUTIES therefore binds the style duty to ruff/style/format and deliberately not to lint.

The vocabulary decides whether anything is said, never what is claimed ​

DUTIES recognises pytest; ruff, flake8, pylint; mypy, pyright. A command is matched by its tool token after any runner prefix, so uv run pytest --cov, python -m pytest and poetry run mypy src are one answer and uv sync --extra dev is none.

A project that verifies under a name this list does not hold is told the population is empty, with the list named — never that nothing is left to run. That is the same distinction this epic has shipped for an empty typed surface (NOTHING TO CHECK), an unowned path (not compared), an unresolvable write target (not_covered) and a guard that cannot evaluate itself (unresolved).

Four statements, one of which every run makes:

SituationWhat the report says
the pipeline runs a verification no step performedeach one, with the command and the workflow job it was read from
every verification read is performed by a stepevery verification this report reads is performed by a step of this run
workflows exist and declare none it readsthe count of files read, the tools it recognises, and that another name is not claimed about
a workflow could not be parsedthe file and the reason, and no claim about what was not run
no workflow existsthis project declares no pipeline

What is deliberately outside it ​

Mutation testing. It is a verification this project holds and no push gate could be mistaken for running it: BDL-068 measured 54 min 55 s over 3 989 mutants with six workers on a 10-core machine, against the ~16-28 runner-minute budget that withdrew tests-windows. Naming it on every gate run would add a line no reader can act on. config-check already reports the mutation scope, which is the part a gate can check in milliseconds.

Since BDL-074 D1 (2026-09-27) mutation runs per change and on a weekly sample, not nightly.mutation.yml has three jobs: mutation-per-change on pull requests, mutation-sample weekly and by hand, and announce. The workflow is disabled until the owner enables it, and neither job is a required status check — the sample reports no check-run on a pull request, and the per-change job has not met its 10-minute budget (≈15 minutes projected on the runner from a local measurement while the whole test pool is the fallback). DUTIES recognises no mutation runner, so neither job is named under Not run by this gate, and nothing this component reports changes.

Outside the gate is not the same as unwatched, as of BDL-072. The retired nightly reached a verdict on 0 of 7 187 mutants for nine consecutive nights and the only place that was visible was the Actions tab. The job announce holds issues: write, opens one issue labelled mutation-weekly when a weekly sample produces no verdict or one under its floor, and titles it by which of the two it is (Mutation weekly sample: no verdict or Mutation weekly sample: under its floor, BDL-074 G1). It comments on that issue each further failed week, retitling it to that week's state, and closes it on the first run whose sample is judged and whose interval reaches its floor, which a score under the floor can still do. It does not cover a scheduled run that never starts, because a run that does not happen runs no job that could speak. Under the nightly's label two of its paths were measured on GitHub (beadloom-e8m4): one killed run opened issue #79 and the next commented on it instead of opening another. That channel reports on the weekly sample and never on a gate run, so nothing this component claims changes: it still names only the verifications a gate run declared and did not perform.

And outside the gate was not the same as scored. The runner killed the whole-scope nightly before it printed a score, and the killer was never identified (beadloom-5isv, closed as superseded when the nightly was retired): eight runs at four mutmut children died after 73-102 minutes, the first at two died after 262.4 minutes with GitHub's annotation "The hosted runner lost communication with the server. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.", and the dispatched verification run (beadloom-kj8t) died at queue position 4 125 of 6 992 after 153.6 minutes. BDL-073 runs two children rather than four, because a mutant was counted killed at four through the live index the children share and survived when run alone, and because fewer children put less load on a 4-vCPU runner. Two still produced false kills, measured over the load_rules mutants. mutmut 3.7.0 already runs each mutant's covering tests cheapest first, and a test pins that, so no ordering patch is carried. The weekly sample exists because the whole scope did not fit the runner; whether it completes on a runner is measured only by its first run there (beadloom-paze). The detail and the numbers are in beadloom mutation. None of it changes what this component reports, which is still only what a gate run declared and did not perform.

Where it surfaces ​

  • beadloom ci --format rich — a block under the verdict, beside the room lines.
  • --format json — not_run: {performed, not_performed, unresolved, inspected}.
  • --format github — one ::notice:: naming the duties and their commands.
  • the MCP complete_bead tool — not_run, on both the PASS and the FAIL payload. That tool runs the suite itself when run_tests=True, and passes performed_elsewhere=("tests",) to the gate so one run cannot report the suite as not run while that run ran it.
  • verdict-room — the same shape one axis over: which rooms a verdict is true of.
  • ci-gate — the run this component qualifies.