Margyn
Colour theme
Get Watch

Proof, with the commands

Three claims hold this product up. Each one is a real run against a named commit, each one followed by the command that reproduces it. Dated 2026-08-06.

Claim one

It was written from a pull request that went red

nishuzumi/moss PR #157, 2026-08-01. Eight vendored modules lived under a path containing dist/. The root .gitignore excludes dist/ at any depth, so git dropped all eight from the commit while they sat on disk untracked. Locally the suite was 26 tests green. In CI two tests failed, reading files that had never been pushed.

The diff was innocent. The absence was the bug. Nothing in a diff shows you a file that is not there.

margyn /tmp/moss   # reconstructed at c6cbb45, untracked files restored

2 findings, each with a reproduction you can run.

1. packages/protocols/aave/abis-src/dist/AaveV3Monad.mjs is read by
   packages/protocols/aave/README.md but git ignores it
   HIGH  ignored-source     ignore rule: .gitignore:2:dist/
2. packages/protocols/aave/abis-src/dist/abis/IPool.mjs is read by
   packages/protocols/aave/abis-src/VENDOR.json but git ignores it
   HIGH  ignored-source     ignore rule: .gitignore:2:dist/

Both reproductions answer, which is what turns a finding into a fact. Two statements about one path that disagree:

$ git archive HEAD | tar -t | grep -qx '<path>' || echo 'ABSENT from HEAD'
ABSENT from HEAD
$ test -f '<path>' && echo 'PRESENT on disk'
PRESENT on disk

Against the fixed tree at 0c743c2 both high findings are gone and only the two medium advisories remain. A checker that cannot be shown to go quiet is as hollow as the checks it hunts, so that direction is tested too.

Claim two

What it says about five public repositories

Run on 2026-08-06 against a shallow clone of each, at the commit named. Nothing was tuned for these repositories and nothing was left out because the number was inconvenient.

RepositoryCommitFindings
chalk/chalk661317e0
sindresorhus/execa8017b270
sindresorhus/gote3924aa1 unrun gate
expressjs/expressa3714473 unrun gates
fastify/fastify39e87e86 tests with no assertion, 4 unrun gates

Reproduce any row in two commands. A clone is enough, since the static checks need no account:

git clone --depth 1 https://github.com/fastify/fastify.git /tmp/fastify
npx margyn-scan /tmp/fastify

What a clean clone cannot show

ignored-source found nothing on any of the five. It could not have. It reports a file that is on disk and not in the commit, which by construction cannot exist in a fresh clone. That check fires on a working tree, which is where the moss defect lived. Saying so is the difference between a table and a claim.

The four highest findings, named

Each one is a file and a line anyone can open. These are tests whose only failure mode is an exception: they run the code, assert nothing, then report green whatever came back.

fastify/fastify at 39e87e8

test/decorator.test.js:869          plugin required decorators
test/http2/closing.test.js:118      http/2 closes successfully with async await
test/http2/closing.test.js:133      https/2 closes successfully with async await
test/schema-special-usage.test.js:423   side effect on schema let the server crash

Two of those are worth reading before you judge the check: an await close() with no assertion is a deliberate smoke test in a lot of suites. That is why the finding says what it says rather than "cannot fail". It is reported with the line instead of a count for the same reason.

The same run found seven false positives, so they were fixed

The first pass reported 17 on fastify, not 10. Seven of those were in test/trust-proxy.test.js and every one of them was wrong: the tests declare t.plan(11) then assert through a helper that takes the test context. A planned count fails the test when it comes up short, so a body carrying one cannot be hollow.

Both rules are now in the check and both directions are tested. That is the whole reason the number above is 10. A scanner that cries wolf is hollow itself, so a false positive is a defect here rather than a tuning preference.

What fires this check, what does not · The release it landed in

Claim three

What it says about itself

The mutation proof inverts one line, runs the suite, then reports the suite that stayed green anyway. Pointed at our own repository at the default cap of four, all four survived. Raise the cap to twelve and six do.

bin/build-pages.mjs            === -> !==             suite still passed
bin/contrast.mjs               === -> !==             suite still passed
src/checks/ignored-source.mjs  return true -> false   suite still passed
src/checks/mutation.mjs        return true -> false   suite still passed

The last one is the mutation checker. Our own tool inverted a line inside our own mutation checker and 43 tests reported success. We publish the number rather than the cap that flatters it.

The paid gate is on the CLI flag rather than on the code, so a clone reproduces this without a licence:

git clone https://github.com/zkasuran/margyn && cd margyn && npm test
node --input-type=module -e 'import { mutationProof } from "./src/checks/mutation.mjs";
console.log(mutationProof(process.cwd(), { max: 12 }).map(f => f.summary));'

The number this page does not have

An earlier run across five other repositories went from 132, 51, 20, 6 and 12 findings to 0, 2, 2, 2 and 0 after four precision fixes. It is a true story about how the matching rules were built. It is also the weakest number we have ever published, because those five repositories were never written down, so nobody can re-run it. That is why the table above exists and names every commit.

If you want the older number to mean something, the fix is not an argument, it is a list of five repositories and a date. Until then this page carries the run you can repeat.

Run it on your own repository

npx margyn-scan /path/to/repo

Nothing is uploaded and no account is needed. If it finds nothing, you learned that for free.

Pricing · Documentation · Why there is no hosted scan