I measured whether AI writes hollower tests than humans. It doesn't A new open-source tool called voidguard scans code repositories for 'void guards' — checks that are present, plausible, but verify nothing. The tool, which can be installed via pip and run as a GitHub Action, identifies tests that never run, type gates that check nothing, settings silently discarded, and CI conditions that cannot fire. Its creator developed voidguard after finding seven such void guards in a single repository in one week. Does your green actually check anything? voidguard is a static scanner for void guards — checks that are present, plausible, and verify nothing. It asks one question per guard: could this, as configured, ever be observed to fail? — and shows its evidence for every answer. pip install voidguard voidguard scan . name: voidguard on: pull request permissions: contents: read pull-requests: write jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: driivai/voidguard@v0 Report-only by default — it comments findings on the PR and never fails your build unless you opt in with fail-on . Requires Python 3.11+ for the CLI; the Action brings its own. A guard that fails is doing its job. A guard that's absent is at least honest. The dangerous one runs, reports green , and verifies nothing. What it catches 1 · Tests that never run Skips gated on an environment flag that is set nowhere your repo actually runs; markers every CI invocation deselects; go, rust and js best-effort. 2 · Type gates that check nothing A mypy that cannot see your own types and passes vacuously; imports skipped; check targets matching no files; a weak tsconfig behind an advertised typecheck. 3 · Settings silently discarded PYTHON variables handed to python -I / -E , which drop them; workflow env set and never read; a Docker ARG consumed after FROM without re-declaration. 4 · CI conditions that cannot fire An if: requiring an event the workflow's triggers never deliver; schedules with no run on the record; golden-file assertions whose path matches nothing.Every verdict — VOID, WARN, or an honest UNKNOWN — carries its enumerated search set: what was searched, what was found, absent conventional locations named as absent. A tool about unverified claims does not get to make any. What it cannot catch The taxonomy this tool comes from has seven instance-types. voidguard v0 detects the shapes of four . It would not have caught the other three: Semantic voids — a verdict typed nullable so “nothing” can be mistaken for a value, or a field the code carries but nothing ever persists. These need type-flow and data-flow analysis, not file-shape analysis. Process voids — a human approval gate that a merge routed around while every check was green. No scanner catches a decision that nobody waited for. Anything requiring execution — voidguard never runs your code. A guard that runs and is wrong is outside its question; it only asks whether a guard could ever be observed to fail at all. Where static analysis cannot decide, the verdict is UNKNOWN with the reason — because a scanner that overclaims void guards is itself a void guard. Where it comes from In one week, one repository turned up seven guards that were present, plausible, and void — a core integrity test that had silently skipped in CI since inception, a type gate that passed while checking nothing, an approval step a merge walked straight past. Every one of them was green. voidguard is the generalization of the sweep that found them.