GGateTest

Measured

Precision, on code we do not control

A scanner tuned against its own repository looks perfect on its own repository. The only honest test is code its authors did not write and cannot quietly adjust. Each repository below is cloned fresh at a pinned commit and scanned with --suite full — exactly what a paying Full Scan runs. The number is blocking findings; the ceiling is what CI holds the engine to, and it only ever moves down.

Precision — clean code must pass

RepositoryCommitBlockingCeilingWhy it is in the corpus
express023767fe00the most-depended-on Node package there is; the canonical clean control
flaskd318b68322Python — proves the non-JS rules are held to the same bar
fastify15ebc8e233large plugin-oriented server; exercises the auth and route grammars
got687eb7dc00TypeScript HTTP client with a benchmark/ tree — a known scope trap
honoeebdf7be1414every crossFileTaint finding here was false: c.req.query() read as SQL, RegExp.exec() as command exec; 2026-09-05 importCycle type-only elision: the four import cycles it blocked on read every binding inside function bodies — deferred, now a warning — ceiling ratchets down
zod7a00236622monorepo with a docs site and benchmarks; was the worst case at 50, of which 33 were errorSwallow — 23 in benchmark harnesses, 7 the parsing library's coerce-then-check idiom (2026-09-04)
djangob3f4d83a4646Python at scale — the ORM builds SQL by string in django/db, which is the one place that is the job; 74 of 76 "secrets" were test fixtures before the identifier-keyed rules learned about test paths
rails1ec64ce83333Ruby at scale — instance_eval in the routes loader, backtick-quoted words in error messages that a naive shell-interp rule read as commands
spring-petclinic818c413688Java + Thymeleaf templates + a k8s manifest; the reference Spring app
gindcaa429600Go — the ignored-error idiom the go module could not see until 2026-09-04
axum8b30afbf55Rust — first contact 28 blocking: todo!()/unimplemented!() inside #[cfg(test)] modules, dtolnay/rust-toolchain@stable read as a branch pin; what remains is third-party actions on @master and one real unimplemented!()
laravelcdbd17f744PHP — first contact 28 blocking, 23 of them `$redis->eval($lua)` read as PHP eval(); what remains is real eval(var_export()) in the config cache and an unguarded rm -rf in a release script
cleanarchitecture3a06afb944C# + Angular + React — first contact 39 blocking, 26 of them SEO/a11y rules on the two SPA index.html shells; what remains is real: strict:false, a committed .env, unlabeled inputs, log-and-eat catches in a React component
ktorf92fad0477Kotlin — first contact 21 blocking, 14 of them a test.html under test-resources/ scored as a public page, plus a Gradle compile failure in our environment reported as failing tests; what remains is six real TODO() stubs and one third-party workflow on @main
vapor630763c500Swift — first contact 6 blocking: its own reusable workflows on @main and README section gaps; what remains is a *.key file the .gitignore does not cover
nest39fbddae77TypeScript monorepo (npm workspaces) with an integration/ e2e tree and sample apps — first contact 39 blocking: a logger class told it uses console, tsconfig flags as build verdicts, mongodb://localhost fixtures as secrets, `.catch(() => {})` on a stored promise the caller awaits; what remains is six `reduce(async …)` in the e2e app, two npm-audit advisories and one committed PKCS#8 key
trpc66d0544577pnpm monorepo with members under examples/* and www — first contact 33 blocking: build configs and a CLI told they log to console, an OG-image generator scored as a web page, an Algolia search key as a secret, ternary env fallbacks as hardcoded URLs; what remains is four <img> without alt, a real import cycle, a silent connect in a constructor and `${{ github.event.release.tag_name }}` in a shell; 2026-09-05 importCycle type-only elision: its one import cycle ran through two `import { type X }` edges — elided, never a cycle in emitted JS — ceiling ratchets down
apollo-server53ac3c1300npm-workspaces monorepo with a docs site — first contact 4 blocking: a CA bundle read as a private key, a README link the resolver could not follow, a destructured parameter the scope harvester missed; nothing remains
prismadd846dcc1212pnpm monorepo, packages/** nesting, a SQL toolkit that builds SQL by design — first contact 90 blocking: `${STORAGE_TABLE}` constants as injection, seeding loops in test/ as N+1, teardown catches as swallows, tsconfig/ and turbo.json as invalid JSON, `base.sha` as shell injection, an un-runnable test:integration as failing tests; what remains is DDL with a computed database name, three import cycles, telemetry catches and a dev-tool page without a description; 2026-09-05 importCycle type-only elision: the three import cycles it blocked on read their bindings in parameter defaults and method bodies — deferred, now a warning — ceiling ratchets down

Recall — a vulnerable app must keep failing

Precision alone is satisfied by a scanner that reports nothing. So a deliberately vulnerable application is held to a floor: if it ever stops failing, the gate goes red.

RepositoryCommitBlockingFloor
NodeGoatc5cb68a74140

By rule — what a senior developer actually checks

A per-repository table proves the corpus was run; it does not show which rule is trustworthy. This table groups every error-severity finding of the same run by rule: how many fired across the twenty repositories, how many of those landed on a repository held to a zero ceiling — our cleanest controls, so a finding there is the shape of a false positive even when a confidence signal kept it from blocking — and how many tests under tests/ are tagged as that rule’s control pair (Doctrine #3: no rule ships without one). Sort any column by clicking its header.

RuleModule
a11y:input-labelaccessibility5300
a11y:img-altaccessibility1800
quality:eval() usage detectedcodeQuality1710
quality:innerHTML assignment detected — use textContent or sanitizecodeQuality1400
security:innerHTML assignmentsecurity1300
perf:event-cleanupperformance1200
python:sql-concatpython1100
quality:commented-codecodeQuality1100
security:eval()security1110
a11y:html-langaccessibility1000
a11y:landmark-mainaccessibility1000
security:sql-injectionsecurity1000
error-swallow:empty-catcherrorSwallow800
money-float:arithmeticmoneyFloat700
quality:console.log/debug/info foundcodeQuality700
async-iteration:async-reduceasyncIteration600
ci-security:branch-pinciSecurity600
error-swallow:catch-nooperrorSwallow600
kotlin:todo-callkotlin600
perf:render-blockingperformance600
secretssecrets601
visual:viewportvisual600
ruby:evalruby500
security:open redirect risksecurity540
security:secretsecurity510
python:execpython400
retry-hygiene:unbounded-loopretryHygiene400
security:secrets-scansecurity410
a11y:contrast-staticaccessibility300
a11y:invalid-roleaccessibility300
cookie-sec:js-weak-secretcookieSecurity330
links:dead-linkslinks300
perf:lazy-loadingperformance300
python:evalpython300
race-condition:fs-toctouraceCondition300
sql:set-notnullsqlMigrations300
taint:sink:evalcrossFileTaint300
bash-safety:pipe-truebashSafety200
data:migration-dropdataIntegrity200
links:javascript-hreflinks200
n-plus-one:query-in-loopnPlusOne200
php:evalphp200
ruby:system-interpruby200
security:npm-auditsecurity201
sql:drop-tablesqlMigrations200
auth-bypassauthBypass100
auth-bypass:idor-shadowauthBypass100
bash-safety:devnull-swallowbashSafety100
ci-security:shell-injectionciSecurity100
dockerfile:curl-pipe-shdockerfile100
env-vars:missing-from-example:APP_ENVenvVars100
env-vars:missing-from-example:AUTH_GITHUB_IDenvVars100
env-vars:missing-from-example:AUTH_GITHUB_SECRETenvVars100
hardcoded-url:localhosthardcodedUrl100
html:unclosed:bodysyntax110
html:unclosed:htmlsyntax110
k8s:image-tagkubernetes100
log-pii:sensitive-arglogPii110
openapi-drift:undocumented-route:GET:/openapiDrift100
redos:nested-quantifierredos100
redos:user-controlled-regexredos100
rust:unimplementedrust100
secret-rotation:stale:private-keysecretRotation100
secrets:gitignore-.envsecrets100
security:CSRF protection disabledsecurity110
security:NoSQL injection ($where with interpolated input)security100
security:npm-audit:body-parsersecurity100
security:npm-audit:bsonsecurity100
security:npm-audit:expresssecurity100
security:npm-audit:markedsecurity100
security:npm-audit:mongodbsecurity100
security:npm-audit:mongodb-coresecurity100
security:npm-audit:path-to-regexpsecurity100
security:npm-audit:qssecurity100
security:npm-audit:swigsecurity100
security:npm-audit:uglify-jssecurity100
security:npm-audit:underscoresecurity100
security:npm-audit:wssecurity100
security:path-traversalsecurity110
security:sql-injection-scansecurity100
security:template auto-escaping disabled (XSS)security100
seo:descriptionseo100
seo:h1-missingseo100
shell:unsafe-rmshell100
sql:add-notnull-no-defaultsqlMigrations100
sql:drop-columnsqlMigrations100
ssrf:tainted-urlssrf100
syntaxsyntax100
taint:sink:sql-querycrossFileTaint100

Engine v1.62.0 @ 8f2240d8, generated 2026-10-05. This table is regenerated by the nightly corpus run (.github/workflows/dogfood-nightly.yml) whenever the numbers change — not on every merge — and rides the same rolling PR as the repository table above.

Head to head — the same commits, other scanners

The same pinned clones, handed to Semgrep (its default auto ruleset) and, where the repository is JavaScript or TypeScript, to ESLint with eslint-plugin-security’s recommended rules. The counts are not comparable one-to-one: GateTest’s blocking is a gate verdict — error-severity findings at or above the confidence threshold, across code quality, security, infrastructure and documentation — while Semgrep’s error is the label a rule author chose, eslint-plugin-security reports fourteen security rules, and CodeQL’s count comes from its own CLI running the official *-security-extended query suite for the repository’s language (e.g. javascript-security-extended.qls), with a result counted as blocking-equivalent at SARIF level error or a security-severity of 7.0 or above. Read each column as what that tool says about that commit and how long it took to say it. Each tool is time-boxed at 10 minutes per repository. SonarQube has not been run yet; CodeQL runs where its CLI is installed and the repository’s language has a security-extended suite. Either column says so, and why, instead of a number when it was not measured. 18 of 20 corpus repositories measured on 2026-10-05 with GateTest --suite full.

Last measured 17 days ago; the weekly run is scheduled every Monday and this page updates automatically once it lands.

RepositoryLanguageGateTestv1.62.0Semgrepv1.179.0ESLint + eslint-plugin-securityv9.39.5SonarQubeCodeQLv2.27.0
express 023767feJavaScript0 blocking / 132 findings20.9 s0 error / 42 warning / 1 info / 2 other (MEDIUM)5.5 s0 error / 75 warning2.3 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures it1 blocking-equivalent / 5 results85.3 s
django b3f4d83aPython46 blocking / 996 findings27.3 s77 error / 522 warning / 94 info96.0 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database analyze timed out after 650.7 s
rails 1ec64ce8Ruby33 blocking / 446 findings15.9 s45 error / 197 warning / 0 info72.6 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database analyze timed out after 1213.4 s
flask d318b683Python2 blocking / 53 findings2.6 s0 error / 15 warning / 0 info / 1 other (MEDIUM)9.3 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures it8 blocking-equivalent / 8 results41.3 s
fastify 15ebc8e2JavaScript3 blocking / 318 findings28.7 s4 error / 2 warning / 0 info9.2 s0 error / 886 warning6.3 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures it0 blocking-equivalent / 0 results193.7 s
zod 7a002366TypeScript2 blocking / 1403 findings14.1 s1 error / 70 warning / 4 info / 4 other (MEDIUM)26.1 s8 error / 526 warning8.2 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database analyze failed (exit 99): [98/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Security/CWE-912/HttpToFileAccess.qlx. [99/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Security/CWE-020/MissingRegExpAnchor.qlx. [100/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Security/CWE-020/MissingOriginCheck.qlx. [101/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Security/CWE-506/HardcodedDataInterpretedAsCode.qlx. [102/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Diagnostics/ExtractedFiles.qlx. [103/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Diagnostics/ExtractionErrors.qlx. [104/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Summary/LinesOfUserCode.qlx. [105/105] Loaded /home/runner/work/_temp/codeql-home/codeql/qlpacks/codeql/javascript-queries/2.4.5/Summary/LinesOfCode.qlx. Starting evaluation of codeql/javascript-queries/AngularJS/DisablingSce.ql. [1/105 eval 23.3s] Query failed: codeql/javascript-queries/AngularJS/DisablingSce.ql (Query evaluation ran out of Java heap (Java heap (and arrays) maximum: 772 MiB). (eventual cause: OutOfMemoryError "Java heap space")). CodeQL is out of memory. Try running CodeQL on a larger runner (hosted or self-hosted). If you continue to encounter this issue, contact GitHub Support.
gin dcaa4296Go0 blocking / 82 findings71.7 s1 error / 37 warning / 0 info / 2 other (MEDIUM)5.4 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create failed (exit 2): Initializing database at /tmp/gt-h2h-2ce061/gin.codeql-db. A fatal error occurred: Go does not support the none build mode. Please try using one of the following build modes instead: autobuild, manual.
laravel cdbd17f7PHP4 blocking / 73 findings6.8 s5 error / 97 warning / 0 info / 1 other (MEDIUM)25.6 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — CodeQL has no security-extended query suite for PHP
got 687eb7dcTypeScript0 blocking / 348 findings35.7 s0 error / 5 warning / 1 info / 1 other (MEDIUM)10.0 s125 error / 100 warning4.0 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures it18 blocking-equivalent / 18 results130.2 s
hono eebdf7beTypeScript14 blocking / 1684 findings11.1 s64 error / 11 warning / 1 info41.4 s186 error / 488 warning7.5 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures it19 blocking-equivalent / 25 results214.2 s
spring-petclinic 818c4136Java8 blocking / 64 findings141.0 s1 error / 13 warning / 2 info4.7 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database analyze failed (exit 99): Starting evaluation of codeql/java-queries/Diagnostics/ExtractionErrors.ql. [1/124 eval 286ms] Evaluation done; writing results to codeql/java-queries/Diagnostics/ExtractionErrors.bqrs. Starting evaluation of codeql/java-queries/Diagnostics/ExtractionWarnings.ql. Starting evaluation of codeql/java-queries/Diagnostics/SuccessfullyExtractedFiles.ql. [2/124 eval 11ms] Evaluation done; writing results to codeql/java-queries/Diagnostics/ExtractionWarnings.bqrs. Starting evaluation of codeql/java-queries/Likely Bugs/Arithmetic/InformationLoss.ql. [3/124 eval 4s] Evaluation done; writing results to codeql/java-queries/Diagnostics/SuccessfullyExtractedFiles.bqrs. Starting evaluation of codeql/java-queries/Likely Bugs/Concurrency/UnreleasedLock.ql. [4/124 eval 8ms] Evaluation done; writing results to codeql/java-queries/Likely Bugs/Arithmetic/InformationLoss.bqrs. [5/124 eval 18.1s] Query failed: codeql/java-queries/Likely Bugs/Concurrency/UnreleasedLock.ql (Query evaluation ran out of Java heap (Java heap (and arrays) maximum: 772 MiB). (eventual cause: OutOfMemoryError "Java heap space")). CodeQL is out of memory. Try running CodeQL on a larger runner (hosted or self-hosted). If you continue to encounter this issue, contact GitHub Support.
axum 8b30afbfRust5 blocking / 431 findings157.8 s9 error / 37 warning / 0 info / 1 other (MEDIUM)5.1 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — CodeQL has no security-extended query suite for Rust
cleanarchitecture 3a06afb9C#4 blocking / 87 findings5.1 s0 error / 16 warning / 0 info / 3 other (MEDIUM)5.5 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create timed out after 697.9 s
ktor f92fad04Kotlinfailed — no JSON report; blocking read from the summary line89.7 sfailed (exit 2) — no JSON output2.1 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — CodeQL has no security-extended query suite for Kotlin
vapor 630763c5Swift0 blocking / 47 findings2.1 s5 error / 8 warning / 0 info / 2 other (MEDIUM)5.0 snot run — not a JavaScript/TypeScript repositorynot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create failed (exit 2): Initializing database at /tmp/gt-h2h-2ce061/vapor.codeql-db. Running build command: [/home/runner/work/_temp/codeql-home/codeql/swift/tools/autobuild.sh] Running command in /tmp/gt-h2h-2ce061/vapor: [/home/runner/work/_temp/codeql-home/codeql/swift/tools/autobuild.sh] A fatal error occurred: Exit status 1 from command: [/home/runner/work/_temp/codeql-home/codeql/swift/tools/autobuild.sh]
nest 39fbddaeTypeScript9 blocking / 944 findings30.6 s5 error / 43 warning / 0 info / 1 other (MEDIUM)25.5 s17 error / 382 warning11.1 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create failed (exit 2): Initializing database at /tmp/gt-h2h-2ce061/nest.codeql-db. Running build command: [] Running command in /tmp/gt-h2h-2ce061/nest: [/home/runner/work/_temp/codeql-home/codeql/javascript/tools/autobuild.sh] Finalizing database at /tmp/gt-h2h-2ce061/nest.codeql-db. Running TRAP import for CodeQL database at /tmp/gt-h2h-2ce061/nest.codeql-db... Importing TRAP files A fatal error occurred: Could not write relation to /tmp/gt-h2h-2ce061/nest.codeql-db/db-javascript/default/cache/working/hasLocation11350304425550759253.relfrag (eventual cause: IOException "No space left on device") Failed to write diagnostic information.
trpc 66d05445TypeScriptfailed — no JSON report; blocking read from the summary line28.8 s3 error / 68 warning / 8 info / 10 other (MEDIUM)19.6 s102 error / 511 warning8.0 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create failed (exit 2): Initializing database at /tmp/gt-h2h-2ce061/trpc.codeql-db. Running build command: [] Running command in /tmp/gt-h2h-2ce061/trpc: [/home/runner/work/_temp/codeql-home/codeql/javascript/tools/autobuild.sh] A fatal error occurred: Exit status 1 from command: [/home/runner/work/_temp/codeql-home/codeql/javascript/tools/autobuild.sh]
apollo-server 53ac3c13TypeScriptfailed — no JSON report; blocking read from the summary line17.4 sfailed (exit 2) — no JSON output2.1 sfailed (exit 2) — no JSON output5.0 snot measured — needs a running SonarQube server and a scanner token; no server is provisioned for the corpus yet, and no number is written until one measures itnot measured — codeql database create failed (exit 2): OpenJDK 64-Bit Server VM warning: Insufficient space for shared memory file: 23644 Try using the -Djava.io.tmpdir= option to select an alternate temp location. A fatal error occurred: Cannot create logs directory at '/tmp/gt-h2h-2ce061/apollo-server.codeql-db/log'. (eventual cause: FileSystemException "/tmp/gt-h2h-2ce061/apollo-server.codeql-db: No space left on device")

Generated 2026-10-05 by scripts/head-to-head.js on engine v1.62.0. Every tool saw the same bytes; a run that hit the time box is written as timed out with the seconds it used, and a tool the runner could not install is written as unavailable. The script and the manifest are in the repository, so anyone can re-run the table.

Confidence — the block threshold, measured on the same run

Every error finding carries a confidence score: 1.0 unless a signal fires (a test file, a fixture, a comment, a string literal), and only findings at or above the block threshold fail the gate. The threshold used to be a number someone liked. Now each corpus run sweeps the alternatives: how much would block on the clean repositories, and how much the vulnerable one would still catch.

Block at confidence ≥Blocking on clean reposStill caught on NodeGoat
0.5021953
0.6021953
0.6515653
0.70shipped15653
0.7515653
0.8015653
0.8515653
0.9015653
0.9515653
1.0015653

Confidence is not a continuum: this run produced only 6 distinct values (1.00, 0.60, 0.40, 0.24, 0.20, 0.12). The shipped threshold of 0.7 sits between 0.6 and 1, so any value in that gap gives the same gate. The signals kept 159 of 315 error findings off the clean repositories and cost 0 of 53 on the vulnerable one.

What remains on a repository is reported, not hidden. Django’s ORM builds SQL by string inside django/db, which is the one place that is the job; rails runner evaluates its input by contract. A scanner should say so, and the project is right to accept it.

Generated 2026-10-05 by scripts/real-world-precision.js on engine v1.62.0 @ 8f2240d8. The corpus manifest and the runner are in the repository, so anyone can re-run the table. What the 122 modules check → Which rules teams silence →