Skip to main content

Vurnix — the honest gate for AI-written code

AI coding agents don't just write bugs. Asked to "make the tests pass", they take shortcuts a human reviewer rarely thinks to check for: they delete the failing assert, skip the test, pad the suite with assert True, or import modules that don't exist anywhere. The suite goes green; the code is still broken.

Vurnix is a set of deterministic, zero-dependency checkers that make those shortcuts impossible to hide. No model in the loop, no heuristics you have to trust — every check is plain code you can read, with a hard exit code.

pip install vurnix
vurnix gate ./myproject        # compile + phantom-import + honest test count, one verdict

The design rule everything here follows: a check that cannot run is not a check that passed. Missing toolchain? That's a labelled SKIP, never a silent OK. Any failing check is a BLOCK and a non-zero exit — there is no "mostly green".

The checkers

Command Catches Languages
vurnix integrity tests being weakened to go green (deleted asserts, new skip/xfail, always-true asserts, deleted test functions) py, js, go, java
vurnix coverage padded test counts — only distinct, non-trivial tests count (assert True and copy-paste duplicates don't) py, js, go, java
vurnix mutation weak tests — mutate the implementation; a mutant your tests don't kill is a coverage gap with a file:line name py + C-family
vurnix phantom invented imports — a module referenced in code that exists nowhere (not stdlib, not local, not vendored) py
vurnix compile code that doesn't even build, per file, before anyone claims "tests pass" py, js, go, java
vurnix gate composite: compile + phantom + coverage floor, one honest verdict

vurnix integrity — the anti-weakening guard

Snapshot the test file before handing it to an agent; compare after:

vurnix integrity snapshot tests/test_api.py > before.json
# ... agent "fixes" the failing tests ...
vurnix integrity compare before.json tests/test_api.py
# WEAKENED: asserts dropped 17 -> 3
# integrity: test file WEAKENED — do NOT count this round as fixed.  (exit 1)

Delta-based: pre-existing skips are fine; only new weakening flags. Strengthening (adding tests) always passes. When a test function disappears, it is named:

WEAKENED: test function(s) deleted/missing: test_redirect_302 (6 -> 5)

vurnix coverage — the honest test-count floor

Prints one integer: the number of distinct, non-trivial test functions. A test counts only if it makes a real assertion (or expects a raise), and identical bodies collapse to one — so "write N easy copies" and "write N assert True" both count as what they are.

vurnix mutation — test strength, measured

vurnix mutation run ./app --max 24 --strict --threshold 0.34 -- python -m pytest -q
# mutation: 9/13 killed — score 69%

A suite that only checks status == 200 scores ~15% on a real CRUD app; a suite that checks behaviour scores ~70%. Survivors are listed by file and mutation so the fix is actionable. Stdlib AST for Python; conservative masked-regex operators for JS/Go/Java (mutants that break syntax simply fail the run — the safe direction).

vurnix phantom — imports that exist nowhere

Real example from our benchmarks: a 12B local model wrote from models import UrlRequest and from db import Database — no models.py, no db.py, no such packages. Syntax checks pass (it is valid syntax); the failure surfaces later as a cryptic install error. This prints the file and the invented module, before anything runs. Host site-packages are deliberately excluded from resolution, so "works on my machine" doesn't mask a missing dependency.

Why we built this

These checkers are extracted from the gate of a local-first autonomous coding pipeline we run against small (12B-class) local models — an environment where every failure mode of agentic coding shows up early and often. All of them earned their place by catching real incidents, including:

  • a cloud model, brought in to rescue a failing build, rewriting a 17-assertion test file down to 3 assertions to go green — blocked by integrity;
  • theatre suites (assert-the-status-code-and-nothing-else) passing every gate until the mutation score exposed them (15% vs 69% on the same app);
  • build-tool resolution failures being mistaken for "tests passed" — which is why SKIP is a first-class, labelled result and never an OK.

The orchestration pipeline itself is not part of this package; these are its trust primitives, usable with any agent, harness, or CI.

Install

pip install vurnix        # Python >= 3.10, zero runtime dependencies
vurnix gate --help

js/go/java checks use your existing node/go/mvn+javac toolchains when present, and report labelled SKIPs when not.

An npm i -g @vurnix/cli stub is also published under the project's npm scope; the Python package is primary.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vurnix-0.2.0.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vurnix-0.2.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file vurnix-0.2.0.tar.gz.

File metadata

  • Download URL: vurnix-0.2.0.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vurnix-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fc289518e2eb221ecc85d45d637aeb0401f57a9a935deb71ff67ad6443ceda09
MD5 f39545177f79af8730c2c11bc55a782a
BLAKE2b-256 1f39eead6670a2cf0429c6ebee46126485cdd3aa86f2f2357f7271717deee3bc

See more details on using hashes here.

File details

Details for the file vurnix-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: vurnix-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vurnix-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 409e3c68820c06448a392efd75719cf068482b747e91e3396b747bcff2b01e2e
MD5 e6be8e7cdcd50f85bc255dd7cf3ce45a
BLAKE2b-256 6f1b4c691fe4630c7f331500ff5c95fdbd9d9d01632a7ab9f144b317a6590a7c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page