witness.

A drop-in CI gate that proves your tests actually have teeth — and mints a receipt anyone can re-run.

github.com/sjgant80-hub/witness → re-run the landing →

A green test suite tells you the tests ran, not that they'd catch a regression. witness flips one operator per line of your source — >→>=, &&→|| — and reruns your own tests. A mutant that survives is a line your suite can't tell from a bug: test-theatre. The pass is an un-forgeable, re-runnable Proof-of-Play receipt. No LLM, zero dependencies.

Landed on real external code

vercel/ms pinned @ 1c6264b ~250M downloads/week loading receipt…

We pointed witness at a battle-tested library nobody in our org wrote, and ran it against the library's own 49-test suite. The result is whatever the rail honestly found — reproduced on GitHub's runner, anchored by a hash:

Add it to your CI in 60 seconds

  1. Drop a witness.bench.json in your repo — the whole integration is this one file:
    { "files": ["src/index.js"],
      "testCommand": "npm test" }
  2. Add one step to your workflow:
    - name: witness — proof of play
      uses: sjgant80-hub/witness@v1
  3. CI now fails on test-theatre and uploads a Proof-of-Play receipt + a step summary + a badge — every run.

Mutation gate the teeth test

Flip one operator and run your tests. Still green? That line is unguarded — a hole a real regression falls straight through. It even refuses a file with nothing to mutate, or a red baseline: an empty run is not a pass.

Proof-of-Play un-forgeable

The verdict is content-addressed over your code, your tests, and the gate itself. The receipt carries that hash. Re-run on any clean machine and it reproduces — paste a passing hash onto a theatre repo and verification re-derives the real one. Refused.

Why the receipt can't be faked

Authenticity rests on a reproducible hash, not a signer. verify re-runs the benchmark and tells three refusals apart instead of calling everyone a forger: benchmark-changed (the gate moved — an instrument fingerprint is baked into the proof), repository (your code moved — re-prove), and the anchor that doesn't reproduce (the forgery shape). The gate turned on itself: mutation-gated in its own CI, including the proof-of-play adapter.

# mint a receipt (one gate run)
npx witness-bench prove . > receipt.json

# anyone re-verifies — re-runs the gate, checks the anchor
node verify receipt.json .   ✓ AUTHENTIC
# tampered anchor / wrong repo              ✗ REFUSED

The lesson it caught in itself

witness spawns your test runner. The first time it ran under its own node --test suite, every mutant falsely "survived" — the child inherited NODE_TEST_CONTEXT and exited 0 even on failure. A hard kill mid-run once baked a live mutant into a fixture. Both are designed out now: the child env is scrubbed and the gate self-heals from a sidecar after any interrupt. A build gate has to be hardened against the exact bug classes it hunts.