GGateTest

Architecture, end to end

How GateTest works

122 deterministic modules. A model is called only to generate a fix, and only when a replayed recipe does not already solve the shape.

Most QA scanners are either purely pattern-matched (cheap, noisy) or purely LLM-driven (expensive, unpredictable). GateTest is neither. The default scan is a static engine with no AI in the loop — predictable, reproducible, no surprise API spend. AI is reserved for fix generation, and even there a proven recipe replays first — the AI layer is only called for a shape it has not solved before.

The pipeline

Customer push hits one of two ingress points, lands in a single Postgres queue, runs the gate, and ships a PR. The same path serves every tier — depth comes from what we layer on top, not from a different pipeline.

Customer pushgit push / mergeGitHub App webhook OR Gluecron Signal BusHMAC-verified, fail-closedscan_queue (Postgres)idempotent via delivery idWorker fetches job → Gate runs 122 modulesdeterministic, no AI by defaultFindings clustered, ranked, capped per tierroot causes first, info-severity droppedFix engine · Recipe → AI → Gatespatch must clear syntax + re-scan gatesTest gen + syntax gate + scanner re-validationbroken fixes never reach the PRPair review + architecture annotation · Tier 2+a second AI reviewer critiques every fixCorrelation + AI diagnosis + executive summary · Forensicattack chains across findings, per-finding diagnosis, CISO report (mutation + chaos run via GitHub Action)PR composed and openedbefore/after table, advisory, regression tests

The diagram is hand-rolled SVG. Mermaid would have required adding a dependency, and the rule on unapproved dependencies is hard.

The 122 modules

Each module is self-contained, runs in parallel, and emits structured findings. Click a card to see a representative finding. Grouped by category for browsability — the actual suite assignment lives in src/core/config.js.

122 modules total. Every Full scan ($99) runs the developer suite. URL scans run the live-site subset. Quick scan runs the highest-signal four.

Source & quality13 modules

The foundation. Catches the bugs every linter and compiler should have caught but didn't.

syntax

Validates JS, TS, JSON, YAML, CSS, HTML.

Example finding
Unclosed bracket at src/api/handler.ts:148
lint

ESLint, Stylelint, language-aware style rules.

Example finding
Unexpected console statement at src/db.ts:42
codeQuality

console.log, debugger, TODO/FIXME, eval, innerHTML, complexity.

Example finding
innerHTML assignment found at components/Comment.tsx:88
deadCode

Unused exports across JS/TS/Python, orphaned files, rotting commented-out blocks.

Example finding
Export 'parseLegacyToken' in src/auth.ts has no importers
typescriptStrictness

tsconfig regressions, @ts-ignore abuse, any-leak detection on exported signatures.

Example finding
strict: false in tsconfig.json — implicit-any leaks across 47 files
documentation

README, CHANGELOG, LICENSE, JSDoc coverage, env documentation.

Example finding
Missing README section: Installation
duplicateCode

Copy-pasted blocks that should be extracted into utilities.

Example finding
16-line block duplicated 4x across src/handlers/
importCycle

Circular dependencies that cause runtime TDZ / undefined-import bugs.

Example finding
Cycle: src/user.ts → src/post.ts → src/user.ts
spineHealth

Structural analysis of the dependency graph — what the codebase costs to change. Load-bearing files that are untested, god files, layering violations, and the direction coupling is trending.

Example finding
fragile-spine: src/core/registry.js — 230 files depend on it, no direct test
asyncIteration

Async callbacks handed to .reduce/.filter/.some/.every/.forEach/.map where Promise semantics silently break.

Example finding
.filter(async x => await isValid(x)) — predicate is a Promise, always truthy
datetimeBug

Naive datetimes, JS 0-vs-1 month, moment-legacy.

Example finding
datetime.now() without tz= at jobs/scheduler.py:31
moneyFloat

IEEE-754 precision loss on currency-named variables.

Example finding
parseFloat(amount) on trust-account money in TrustActions.tsx
homoglyph

Trojan Source bidi overrides, Cyrillic/Greek letters in Latin identifiers, zero-width chars.

Example finding
Cyrillic 'а' (U+0430) inside identifier `data` at src/parser.ts:212

Security15 modules

OWASP-grade scanning that goes beyond CVE lookups into your actual code paths.

security

OWASP patterns, XSS, SQL injection, innerHTML, shell exec, Docker misconfigs.

Example finding
exec(req.body.cmd) at api/run.ts:54 — command injection
secrets

AWS keys, GitHub tokens, Stripe keys, passwords, private keys, DB strings.

Example finding
AKIA[redacted] hardcoded in config/aws.ts
secretRotation

Long-lived credentials in git, .env drift, placeholder/real example mismatch.

Example finding
API_KEY in .env has been unchanged for 412 days
ssrf

User-controlled URLs handed to fetch/axios/got/node-http without validation.

Example finding
fetch(req.query.url) with no allowlist at api/proxy.ts:18
tlsSecurity

rejectUnauthorized:false, verify=False, NODE_TLS_REJECT_UNAUTHORIZED=0.

Example finding
rejectUnauthorized: false in production https.Agent
cookieSecurity

httpOnly:false, weak session secrets, SESSION_COOKIE_* misconfigs.

Example finding
session cookie httpOnly: false — XSS becomes session takeover
redos

Catastrophic-regex detector: nested quantifiers, overlapping alternation, user-controlled patterns.

Example finding
(a+)+ at src/validator.ts:30 — catastrophic backtracking
authBypass

Routes missing authentication.

Example finding
/api/admin/users has no middleware guard
crossFileTaint

Cross-file taint analysis — user input → dangerous sinks across module boundaries.

Example finding
req.body.path → fs.readFile via 3 hops, no validation
webhookPayload

Webhook handlers that use req.body without validation.

Example finding
Stripe webhook handler reads req.body.amount without zod parse
logPii

Credentials, tokens, and request objects logged in plaintext.

Example finding
console.log(user) at auth/login.ts:88 — leaks bcrypt hash
wpExposedFiles

WordPress: sensitive files exposed via public webroot (wp-config.php.bak, debug.log, .git, .env, SQL backups).

Example finding
wp-config.php.bak reachable at /wp-config.php.bak (HTTP 200)
wpXmlrpcExposed

WordPress: /xmlrpc.php exposed (brute-force amplification + DDoS reflector + auth-bypass surface).

Example finding
/xmlrpc.php returns 200 — disable or block at WAF
wpMalwarePatterns

WordPress: rendered HTML/JS scanned for known malware signatures (eval(atob), hidden iframes, base64 payloads).

Example finding
eval(atob(...)) found in footer script — likely compromised
wpAdminProtection

WordPress: /wp-admin and /wp-login.php checked for rate limit / WAF / 2FA / cookie hardening.

Example finding
/wp-login.php has no rate limiting — brute-force open

Reliability11 modules

The bugs that don't break on your machine but break in production at 3am.

errorSwallow

Empty catch, .catch(noop), callback-err ignored, floating promises, global silent handlers.

Example finding
Empty catch block at db/save.ts:114 — error swallowed
nPlusOne

Database calls inside loops across Prisma, Sequelize, TypeORM, Mongoose, Knex, Drizzle.

Example finding
await prisma.post.findUnique inside arr.map at feed.ts:42
retryHygiene

Tight retry loops, no backoff, unbounded retry, retry-on-4xx across fetch/axios/got/node-http.

Example finding
while(true) retry with no jitter at api/upload.ts:88
raceCondition

TOCTOU, get-or-create anti-pattern, lost-update on counters.

Example finding
fs.exists() then fs.unlink() — same path, symlink-race vector
resourceLeak

Unclosed streams, file handles, intervals, sockets across fs/net/ws/events.

Example finding
fs.createReadStream never piped or closed at importer.ts:31
envVars

process.env / os.environ reads cross-referenced with .env.example and CI env blocks.

Example finding
STRIPE_SECRET_KEY read in code but missing from .env.example
cronExpression

Invalid / impossible / too-frequent cron strings (Feb 30, * * * * *, typo aliases).

Example finding
0 0 30 2 * — Feb 30 never fires, silent killer
featureFlag

Stale flags collapsed into constants and dead-branch conditionals.

Example finding
if (true) wrapping 200 lines of code at src/checkout.ts:14
intentVerification

AI checks that the diff matches the commit message / PR description.

Example finding
PR titled 'fix typo' touches 18 files across 3 directories
regressionPredictor

AI predicts which files this PR is most likely to break.

Example finding
Confidence 87%: this change will break tests in checkout/
rollbackHonesty

Rollback Honesty Checker — verifies advertised rollback path actually rolls back.

Example finding
deploy.sh has no rollback function despite docs claiming one

Web & UX23 modules

Surfacing the user-visible problems static analysis usually pretends don't exist.

accessibility

WCAG 2.2 automated audit (AA + AAA-aligned) — missing alt text, ARIA labels, keyboard traps, heading hierarchy.

Example finding
Heading skip h1 → h3 at /pricing (WCAG 1.3.1)
performance

Dependency count, bundle size analysis, image optimisation checks.

Example finding
Hero image 3.4MB unoptimised — LCP penalty
visual

Visual & UI Regression Testing.

Example finding
Hero CTA shifted 14px between deploys
seo

Meta tags, Open Graph, structured data, robots.txt, canonical URLs.

Example finding
Missing canonical on /compare/snyk
links

Every broken href — dead anchors, placeholder links, 404s.

Example finding
/docs/guide returns 404 from footer link
compatibility

Browser matrix validation. Modern API and CSS features without polyfills.

Example finding
:has() selector at safari < 15.4 — partial support
e2e

End-to-End Test Execution.

Example finding
Checkout flow times out at payment step
liveCrawler

Live site crawl — 404 / 500 / broken-image / redirect-chain on the live URL.

Example finding
/blog/old-post → 3 redirects → 404
explorer

Autonomous Interactive Element Explorer — drives a real browser to click every button + form + dropdown.

Example finding
Submit button on /signup raises uncaught TypeError
runtimeErrors

Live browser runtime errors — uncaught JS, console.error/warn, network 4xx/5xx, CSP violations, hydration mismatches.

Example finding
Hydration mismatch: server rendered 'Dec', client rendered 'Jan'
visualRegression

Full-page screenshot diffing at desktop + mobile widths against a stored baseline — catches redesigns and broken layouts no DOM check can see.

Example finding
18.4% of pixels changed on /pricing (mobile) — exceeds 5% threshold
interactiveElements

Live link + button crawler — HTTP-verifies every internal link, click-tests every button with a destructive-action skip list (delete/cancel/logout never fire) and modal cleanup between clicks.

Example finding
DEAD BUTTON: "Subscribe" on /pricing — clicked but nothing happened
apiHealth

Hits every discovered API endpoint with valid + missing-parameter requests — checks status codes, response time, and JSON vs HTML content-type.

Example finding
POST /graphql returned HTML instead of JSON — middleware or auth redirect intercepting the route
performanceBudget

Live TTFB / LCP / CLS / page-weight budget check against a real URL — median of 3 runs with a cold-start warm-up first.

Example finding
LCP 4120ms > 2500ms budget on /dashboard — unoptimised hero image
mobileRendering

Horizontal-overflow and unreadable-text checks across 5 device widths (390/414/768/1024/1280) — absolute checks, not a diff.

Example finding
63px horizontal overflow at 1024px (laptop) — fixed-width element wider than the viewport
formTesting

Fills and submits every SAFE form (contact, newsletter, search, feedback) and verifies a real success signal. Payment-shaped, auth-shaped, and CAPTCHA-protected forms are detected and skipped — never submitted or bypassed.

Example finding
Contact form on /support accepts input but nothing happens on submit — silent failure
consoleErrors

Site-wide crawl aggregating console errors/warnings across every page visited — fingerprints and dedupes the same error across pages, flags errors that fire on every page as systemic.

Example finding
CSP blocks Google Fonts on every one of 5 crawled pages — persistent, site-wide
designSystemCompliance

Audits live computed styles for near-duplicate colors, off-grid spacing, and type-scale drift — catches design-token erosion no pixel diff or source lint sees.

Example finding
52 distinct colors in use, 20 recommended — palette drifting from shared tokens
crossBrowser

Runs the same page load across Chromium, Firefox, and WebKit and diffs navigation success, runtime errors, and rendering against Chromium as the reference engine.

Example finding
Firefox throws a CSP error Chromium doesn't — engine-specific bug
chaos

Chaos & Resilience Testing — slow network, API failure, offline, missing resources, server timeouts. Runs via the GitHub Action where a headless browser is available; the website-only Forensic scan does not include it.

Example finding
App freezes on 3G simulation — no loading state shown
webHeaders

CSP/HSTS/XFO/CORS misconfig across Next.js, Vercel, Netlify, nginx, Apache, Caddy and server source in any language.

Example finding
CSP missing — defaults to inline-everything
estate

Every host the target owns — list, sitemap, TLS SAN, links — each given an outside-in verdict.

Example finding
api.example.com: gateway-up-app-dead (502)
cacheHeaders

Cache Headers & CDN Configuration.

Example finding
/api/user has Cache-Control: public — PII cacheable at CDN

Infrastructure19 modules

Catches the supply-chain takeovers, container exploits, and CI/CD foot-guns.

dependencies

Supply-chain hygiene across npm, pip, Pipenv, Poetry, go.mod, Cargo, Bundler, Composer, Maven, Gradle.

Example finding
left-pad in package.json pinned to 'latest' — supply-chain risk
dockerfile

Root user, :latest tags, curl|sh, apt hygiene, secrets-in-layers, cache bloat.

Example finding
USER not set — container runs as root
ciSecurity

GitHub Actions hardening — action pinning, pwn-request, shell injection, secrets-in-logs, permissions.

Example finding
actions/checkout@v4 unpinned to SHA — supply-chain risk
ciParamValidator

Validates GitHub Actions with: inputs against action schemas.

Example finding
actions/upload-artifact: invalid input 'retention' (typo of 'retention-days')
shell

Shell script security — curl|sh, unsafe rm, eval injection, hardcoded secrets, set -e, POSIX compliance.

Example finding
rm -rf $VAR with no quoting at scripts/clean.sh:14
bashSafety

Bash / Shell Error-Swallow Detector.

Example finding
Pipeline lacks set -o pipefail — silent failure
sqlMigrations

Drop column/table, non-concurrent indexes, NOT NULL without default, blocking constraints, rolling-deploy renames.

Example finding
ALTER TABLE users ADD COLUMN email NOT NULL — blocks writes
terraform

Public buckets, wildcard ingress, hardcoded secrets, missing encryption, IAM wildcards.

Example finding
aws_s3_bucket.acl = 'public-read' on customer-data bucket
kubernetes

Privileged pods, host namespaces, :latest images, missing limits/probes, dangerous caps.

Example finding
privileged: true in production deployment
systemd

Systemd Unit File Validator.

Example finding
Service has no Restart= policy — won't recover from crash
deployScriptValidator

Health-check URL consistency.

Example finding
deploy.sh checks :3000 but service listens on :8080
serviceConsistency

ExecStart / Procfile / PM2 vs package.json start script.

Example finding
Procfile runs `node dist/server.js`, package.json runs `node server.js`
deployContract

Deploy Contract Validator.

Example finding
Vercel runtime=edge but route uses fs module
deployReadiness

Aggregate 0-100 deployment confidence score.

Example finding
Deploy readiness: 62/100 — 3 critical, 8 high open
nativeBundlerGuard

Native Node addons that cannot be bundled.

Example finding
import sharp — native binary not bundleable on Vercel edge
bundleSize

JS bundles exceeding size budgets.

Example finding
main.js 412 KB gzip — budget is 200 KB
envIntegrity

Env-File Integrity Linter.

Example finding
.env has duplicate STRIPE_KEY entries — last wins silently
promptSafety

Browser-exposed API keys, unbounded max_tokens, prompt-injection surfaces, deprecated models.

Example finding
Client-bundled NEXT_PUBLIC_* credential shipped to every visitor
sbom

Generates a CycloneDX 1.4 Software Bill of Materials from your lockfile — the artifact procurement and compliance teams ask for.

Example finding
SBOM generated: 214 components, 3 GPL-licensed, 1 EOL package flagged

Developer hygiene10 modules

Pulls bad-process bugs out of CI before they cost a 90-minute review.

prSize

Blocks unreviewably-large pull requests (files / lines / sprawl across top-level dirs).

Example finding
PR touches 142 files, 3,400 lines across 6 top-level dirs
prQuality

Weak commit messages, missing tests, mixed deps+code.

Example finding
Commit message 'fix' on a 200-line change
flakyTests

Committed .only/.skip, real clock/network/timers, env leaks, self-admitted flakes. When the engine runs your tests it also records each test per run: one that flips is quarantined as a warning for 14 days, then blocks again unless fixed.

Example finding
describe.only( found in tests/checkout.test.ts
fakeFixDetector

AI-generated symptom patches — skipped tests, swallowed errors, dead code.

Example finding
Test changed from expect(x).toBe(2) to .toBe.any() — patching test, not bug
hardcodedUrl

localhost / 127.0.0.1 / RFC1918 / internal TLDs / non-TLS URLs leaking into production.

Example finding
A dev URL (loop-back, RFC1918, internal TLD) shipped into the production bundle
openapiDrift

Routes defined in code missing from openapi.yaml, and spec paths with no matching handler.

Example finding
GET /api/v2/orders defined in code but absent from spec
trpcContract

tRPC procedure definitions vs frontend call sites.

Example finding
Frontend calls trpc.user.delete — procedure removed in server
monorepoConstraints

Enforces package boundary rules in apps/ packages/ libs/.

Example finding
apps/web imports from apps/admin — boundary violation
zodSchemaPresence

React components without runtime prop validation.

Example finding
<Checkout> exported with no zod parse on prop input
dataIntegrity

Migration safety, SQL injection patterns, PII in logs, database schema validation.

Example finding
Migration drops column 'email' with no backfill

AI & advanced9 modules

Where deterministic scanning stops and reasoning starts. Used sparingly, not by default.

aiReview

AI reads your code and finds real bugs — not patterns, actual understanding.

Example finding
Token refresh races with logout — second auth call uses dead token
agentic

Memory-driven AI investigation — picks hypotheses from past scans, walks the code.

Example finding
Recurring null-deref in user.profile — root cause traced to login flow
memory

Codebase memory — compounding intelligence across scans (issue history + fix patterns).

Example finding
This file had 14 prior findings — focus areas: auth, session
aiHallucination

Fake imports, invented APIs, non-existent methods.

Example finding
An import named { useFoo } from a library that has no such export
claudeCompliance

AI-output rot — mock data in prod, not-implemented stubs, WHAT-not-WHY comment noise, `any` / `@ts-ignore` density.

Example finding
John Doe placeholder in src/users.ts:42 — mock data shipped to prod
undefinedRef

Variables, functions, methods referenced before they're defined.

Example finding
ReferenceError: handleClick is not defined at line 47 — typo'd from handeClick
architectureDrift

AI flags code that violates documented architectural conventions.

Example finding
src/api/orders.ts bypasses repository layer — direct DB access
mutation

Modifies your source code to verify your tests actually catch bugs. Runs via the GitHub Action because it executes your test suite; the website-only Forensic scan does not include it.

Example finding
Mutated return true → return false, 11/11 tests still pass
aiGuardrails

Adversarial LLM testing — 30 scenarios across jailbreak, prompt injection, PII leak, hallucination, tool exfil, cost control. Forensic tier; requires your endpoint URL + auth.

Example finding
Endpoint leaked system prompt under role-play jailbreak scenario 4

Scanning & testing2 modules

The classic suite — unit, integration, end-to-end — wired into the same gate as everything else.

unitTests

Unit Test Execution.

Example finding
tests/cart.test.ts: 14 failed, 218 passed, 0 skipped
integrationTests

Integration Test Execution.

Example finding
Order placement → payment → fulfilment: 1 failure at fulfilment step

Language coverage9 modules

Nine non-JS language backends. Same engine, language-aware patterns.

python

eval/exec, bare-except, SQL injection, pickle.

Example finding
pickle.loads(request.data) at api/users.py:12 — RCE vector
go

Ignored errors, panics, goroutine hygiene.

Example finding
_, err := db.Query(...) — err discarded at db.go:88
rust

unwrap/panic/todo, unsafe block review.

Example finding
.unwrap() on Option in production code at src/auth.rs:24
java

System.out, broad catches, empty catches.

Example finding
catch (Exception e) {} at OrderService.java:301
ruby

eval, shell injection, bare rescue.

Example finding
system("convert #{input}") — shell injection at uploader.rb:18
php

eval, legacy mysql_, XSS, debug output.

Example finding
mysql_query() deprecated API at legacy/db.php:42
csharp

Console.WriteLine, empty catches.

Example finding
Empty catch in OrderController.cs:189 — exception swallowed
kotlin

!!, TODO(), println.

Example finding
user.profile!! at HomeFragment.kt:71 — NPE risk
swift

fatalError, try!, force-unwrap.

Example finding
try! JSONDecoder().decode(...) in production at Network.swift:23

WordPress6 modules

Live-URL probes for the WordPress health check at /wp. Run against any public WordPress site.

wpVersionLeak

Where the site leaks its core version (readme.html, meta generator, RSS feed, CSS/JS ver=).

Example finding
Meta generator: 'WordPress 5.8.1' — readable from view-source
wpPluginCveCheck

Detects installed plugins via fingerprinting and flags any with known CVEs.

Example finding
elementor 3.5.2 detected — CVE-2023-XXXX critical
wpUserEnumerate

Checks if usernames can be enumerated via /?author=1, /wp-json/wp/v2/users, /author/admin/.

Example finding
/?author=1 reveals login 'admin' via redirect
wpPhpVersionEol

Detects the running PHP version and flags it if end-of-life.

Example finding
PHP 7.4 detected — EOL since 2022, no security patches
wpThemeAbandonment

Detects the active theme and flags it if abandoned, deprecated, or carrying known CVEs.

Example finding
Theme 'oldtheme' last updated 2019 — abandoned
wpBackupValidation

Whether a backup plugin is installed AND whether any backup files are publicly exposed.

Example finding
/backup-2024-01.zip reachable (HTTP 200) — full-site dump exposed

Live attack probes5 modulesNot available

Active probes against a running site. Not available — reserved for a future penetration-testing product. No GateTest scan or tier runs these probes today.

liveSqlInjection

Live SQL-injection probe — error-based, boolean, and timing payloads against discovered endpoints.

Example finding
Timing payload on /api/search?q= delayed response 5.1s — injectable
liveXss

Live reflected-XSS probe — reflection detection on discovered endpoints.

Example finding
Payload reflected unencoded in /search results page
livePathTraversal

Live path-traversal probe — /etc/passwd and win.ini read detection.

Example finding
?file=../../etc/passwd returned root:x:0:0 — traversal confirmed
liveAuthBypass

Live auth-bypass probe — tests whether injected headers grant unauthenticated access.

Example finding
X-Forwarded-For: 127.0.0.1 unlocked /admin without a session
liveIdor

Live IDOR probe — tests whether other users' object IDs are reachable without authorization.

Example finding
/api/orders/1001 readable from user B's session — IDOR confirmed

How we keep it quiet

The loudest complaint about every scanner is noise. These are not settings you tune — they are how the engine works by default.

One defect is one finding

When three modules flag the same line — say a tainted eval() seen by the taint tracer, the security scanner and code quality — you read it once, owned by the module with the most detail. Folded duplicates are counted and disclosed, never silently dropped.

Ranked by risk, budgeted to five

The PR comment opens with the five findings that matter most — blocking first, then severity, then confidence, exploitable classes before hygiene, a concrete file:line before an aggregate. Everything else is collapsed under it. Nobody scrolls a wall.

Dependency alerts that can actually hurt you

A CVE blocks only when it sits in a production dependency your source actually imports. Dev-only tooling and installed-but-unused packages are reported with the reason — "pulled in only by devDependencies" — and never turn the check red.

Errors need confidence to block

Every error carries a confidence score from path and source context. Below the threshold it is shown, not enforced, and the report says how many were held back. Rules your team keeps dismissing are softened automatically by the flywheel.

Environment failures are not your defects

If a tool cannot run where the scan runs — no lockfile, no browser, no test runner installed — that is reported as a skip with the reason. It never becomes a red X on your code.

Fragments, fixtures and vendored code are not pages

SEO, accessibility and layout rules run on full documents, not template partials; test fixtures, docs screenshots and compiled vendor CSS are recognised for what they are. Measured on real repositories, with a positive control for every rule so quiet never means muted.

The fix flywheel

When the gate produces a finding that you've paid to have fixed, the pipeline is an AI fix engine working under hard gates. The engine checks the recipe store first — a promoted recipe replays for free. Otherwise the engine proposes a minimal, surgical diff (on the CI path, three competing hypotheses in a single call). Every candidate patch must parse, and the fixed file is re-scanned: the original finding must be gone and nothing new raised. A no-op patch is rejected, and per-tier budget caps mean a fix can never cost more than you paid for it.

1Recipe
$0.00

Deterministic replay of fixes the AI layer has already proven. A recipe is distilled from a small, templatey AI diff and replays only after it has been confirmed enough times to be promoted to stable — an unproven patch never auto-applies.

When it wins

Repeat shapes the AI layer has solved before, once their recipe has earned promotion. Zero cost, zero model call.

Example
// match by ruleKey + file ext
// hit: js-reject-unauthorized
// recipe status: stable
// recipe applied, zero cost
// AI never called
2AI fix
paid

The AI fix engine proposes a minimal, surgical diff for the finding — deeper analysis on the paid fix tiers. On the CI path it generates three competing hypotheses in a single call and the best-ranked candidate wins. Capped per tier so spend never exceeds margin.

When it wins

First-time-seen patterns. Bespoke business-logic bugs. Anything a template can't model.

Example
// novel pattern: ad-hoc auth check
// mixed with feature-flag rollout
// no canonical shape
// AI reasons from your code
// three hypotheses, best wins
// smallest diff that fixes it
3Syntax gate
$0.00

Every candidate patch must parse. A patch that breaks the file's syntax is discarded on the spot, a crash falls through to the next candidate, and a no-op diff is rejected outright.

When it wins

Stops a bad patch before it can touch your branch — nothing that fails to parse ever reaches a PR.

Example
// candidate patch B
// parse → SyntaxError
// discarded, never applied
// candidate A carries on
4Scanner gate
$0.00

The fixed file is re-scanned by the same engine that raised the finding. The fix must make the original finding disappear without raising anything new — on the CI path your own test suite is run as the final judge.

When it wins

Proves the fix is real. A patch that silences the symptom but fails the re-scan or the tests never ships.

Example
// re-scan: finding gone?
// new findings introduced?
// tests still green?
// all three yes → patch lands
// any no → rejected

Cost trend as recipes accumulate

When the AI layer solves something and the diff is small and templatey, theauto-distillstep can record a recipe in your local store. A recipe replays — with no AI call at all — once it has been confirmed enough times to be promoted to stable; an unproven patch never auto-applies. The chart below is the design goal: repeat shapes stop reaching the AI layer, so the paid share falls as promoted recipes accumulate.

0%25%50%75%100%Scan 1 · 100%Scan 25 · 58%Scan 50 · 28%Scan 100+ · 5%Scans completed →% fixes served by AI

Illustrative — actual ratio depends on codebase shape and recipe-hit rate. The architectural goal is that repeat patterns stop reaching the AI layer entirely.

The four tiers

Same engine, same modules, same queue. The tiers differ in what we layer on top of the base scan — and we're honest about what you don't get at each tier. “no” means no.

What you getQuickFullScan + FixForensic
Price$29$99$199$399
Modules run (every module that applies to a repo)4AllAllAll + nuclear suite
Findings clustering by root cause✓✓✓✓
Health score / verdict✓✓✓✓
Detailed report (file, line, advisory)✓✓✓✓
AI code review (reads your code, not patterns)no✓✓✓
Auto-PR with working fixesnono✓✓
Iterative fix loop with retrynono✓✓
Cross-fix syntax + scanner gatenono✓✓
Regression test generated per fixnono✓✓
Pair-review (a second AI reviewer critiques)nono✓✓
Architecture annotationsnono✓✓
Per-finding AI diagnosisnonono✓
Cross-finding attack-chain correlationnonono✓
Mutation testing (via GitHub Action)nononoAction
Chaos / fuzz pass (via GitHub Action)nononoAction
CTO-readable executive summarynonono✓

Action = available via the GitHub Action with mutation: true / chaos: true. These two checks need a CI runner (your test suite for mutation, a headless browser for chaos) so they run wherever your CI runs, not on the website-only scan flow.

Per-scan payment at every tier. One-time charge via Stripe at checkout — one-time for scan tiers (no auto-renew; Continuous and MCP are monthly). If a scan fails to start or crashes mid-way, contact support — we re-run it or issue a credit at our discretion.

The fix workflow in your own CI

Beyond the managed scan, GateTest ships a GitHub Actions workflow that runs in your CI with your own API key. When CI breaks, the workflow pipes the failing log through the same fix engine — promoted recipes replay first, then the engine proposes three competing patches that must survive the syntax and test gates — applies the fix, and opens a follow-up PR. Same engine, same recipe store, your bill with the AI provider rather than ours.

.github/workflows/gatetest-fix.yml
name: GateTest fix workflow
on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]

jobs:
  heal:
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npx -p @gatetest/cli gatetest --suite full --auto-pr
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GITHUB_TOKEN:      ${{ secrets.GITHUB_TOKEN }}
  1. 1CI fails

    Workflow_run trigger fires on conclusion: failure.

  2. 2Logs in

    Heal step downloads the failing job's logs and the diff.

  3. 3Fix engine

    Recipe replay first, then the AI engine's three hypotheses race through syntax and test gates.

  4. 4Fix PR

    Patch lands on a follow-up branch, PR opens against your default.

The stack

We deliberately keep the stack small. Every box below earns its place — no “just in case” services, no orchestration layers we don't need. The serverless rule is hard: no in-memory state between requests, ever.

Frontend

Next.js 16 (App Router) + Tailwind 4. Server Components everywhere except where interactivity demands client.

Runtime

Node on our own managed host. Every request handler is stateless — no in-memory persistence between requests.

Database

Postgres on Neon. Holds scan_queue, audit log, fix-recipe store, customer sessions.

Payments

Stripe upfront-charge. Scan tiers are one-time payments at checkout — no auto-renew. Continuous ($49/mo) and MCP ($29/mo) are monthly subscriptions, cancel anytime.

AI layer

AI-powered fix and review engine — deeper analysis on the paid fix tiers (Scan + Fix, Forensic), a lighter pass on the free and high-volume paths. Our key for managed scans; your key for the fix workflow in your own repo.

Git host

Dual-host: GitHub App webhook and Gluecron Signal Bus. HostBridge abstraction means new hosts plug in without rewiring.

Browser

A real headless Chromium, driven by the engine for the chaos, explorer, and runtime-error modules; Firefox and WebKit join for cross-browser diffs.

All scan state lives in Postgres or in Stripe's payment-intent metadata. We never write a Map or module-level variable that's expected to survive across requests — the function instance that picked up your second-page poll is not the one that ran your scan.

What GateTest doesn't do (yet)

Every QA vendor promises the moon. Here's what we don't deliver today. If any of these are blockers for you, the honest answer is “not yet.”

  • 01

    Doesn't replace a senior engineer's code review. We catch the bugs that have a recognisable shape; humans still own architecture and product judgement.

  • 02

    Doesn't catch logic bugs that need domain context. If your invariant is 'don't ever discount over 30%', no scanner can know that without you telling it.

  • 03

    Doesn't fix bugs that span 5+ files without human review. Multi-file refactors are flagged but require an engineer to drive.

  • 04

    Coverage on Rust, Go, and Java is shallower than JS/TS/Python today. We have language-specific modules for nine non-JS backends but the depth is honestly thinner than our JS coverage.

  • 05

    Hosted scans have a file cap. Full, Scan + Fix and Forensic read up to 4,000 source files per scan (prioritised by relevance); the free preview and the Quick tier sample 60. A very large monorepo gets a representative slice, not exhaustive coverage. The CLI and GitHub Action scan everything, with no file cap.

  • 06

    No on-prem deployment yet. Everything runs on our own managed host with a Postgres (Neon) queue today. Air-gapped customers are on the roadmap.

  • 07

    The editor extension is brand new (on the Visual Studio Marketplace and on Open VSX — the registry Cursor, Windsurf and VSCodium read — since 16 September 2026). It runs the same engine in-process and shows findings in the Problems panel, but it has no install base or reviews yet. The proven loop is still push → CI → PR comment.

Run it against your code

Architecture is just words until you see the report. The free URL scan takes well under a minute and returns a real health score against your live site.