Trust Check

How we prove the engine works.

Every number on this page is computed live, in your browser, by running the real rules engine against a corpus of known-broken sample projects. Nothing here is mocked.

Live accuracy
11 / 11
known-broken projects caught correctly
computed on page load · 45 rules
Integrations
5 / 5
100% accuracy
Security
4 / 4
100% accuracy
Env vars
7 / 7
100% accuracy

Every fixture project is open-source under src/engine/fixtures.ts. Add your own and the scoreboard updates immediately.

Try a known bug

Watch the engine catch it live.

Pick a broken sample project. The engine runs the actual rule code against it — you see the expected hits next to what really fired.

Expected vs actual
Fixture

Classic vibe-coder mistake — service-role key imported in a 'use client' file.

Expected rules to fire
  • · supabase.service-in-client
  • · security.client-secret-leak
Engine output

Click "Run engine" to display the actual findings.

Rule library

Every check the engine runs — in plain English.

45 rules across env vars, frameworks, hosting, integrations, and security.

env.missing-prod
Env vars
Must fix
Env var referenced in code but missing in production

A variable is read by your code but not present in the provider's production environment.

env.next-public-mismatch
Env vars
Must fix
Code expects NEXT_PUBLIC_ but only the un-prefixed var is set

Next.js only exposes NEXT_PUBLIC_-prefixed env vars to the browser.

env.vite-prefix
Env vars
Must fix
Vite env var without VITE_ prefix used in browser

Vite only inlines env vars prefixed with VITE_ into the client bundle.

security.client-secret-leak
Security
Must fix
Secret-looking env var referenced from client code

Detects server-only secret names (KEY, SECRET, TOKEN, PASSWORD) used in browser-bound files.

security.public-prefix-secret
Security
Must fix
Server-only secret declared with a public/browser-exposed prefix

Names like VITE_*, NEXT_PUBLIC_*, PUBLIC_*, NUXT_PUBLIC_*, EXPO_PUBLIC_*, REACT_APP_*, GATSBY_* are inlined into the browser bundle. A secret-flavored name (TOKEN, SECRET_KEY, SERVICE_ROLE, API_KEY, DATABASE_URL, AUTH_TOKEN, provider PATs…) under one of those prefixes leaks the secret to every visitor.

env.example-drift
Env vars
Heads up
.env.example missing variables your code uses

Code references env vars that aren't documented in .env.example.

security.env-committed
Security
Must fix
.env file appears to be committed

.env / .env.local files contain real secrets and must never be committed.

env.case-typo
Env vars
Should fix
Likely typo: env var name differs by case or underscore

Env vars are case-sensitive; small typos silently return undefined.

env.db-localhost
Env vars
Must fix
DATABASE_URL still points to localhost

A local DB URL shipped to production will crash on connect.

next.server-only-in-client
Framework
Must fix
Server-only API imported in a 'use client' component

next/headers, next/server, fs, child_process etc. cannot be imported from client components.

remix.server-in-client
Framework
Must fix
Remix server-only module imported from a route component

Remix files ending in .server.ts must not be imported from .tsx route components that render in the browser.

next.edge-node-api
Framework
Must fix
Node API used in an Edge runtime route

When export const runtime = 'edge', Node-only APIs (fs, path, os, net, tls, child_process, crypto.createHmac/createHash/randomBytes, Buffer) are unavailable.

sveltekit.private-in-public
Framework
Must fix
$env/static/private imported in a +page file

SvelteKit treats $env/static/private as server-only.

nuxt.secret-in-public
Framework
Must fix
Secret-looking key in runtimeConfig.public

Anything in runtimeConfig.public is shipped to the browser.

security.dangerous-html
Security
Heads up
dangerouslySetInnerHTML used with non-static value

Potential XSS vector — needs sanitization.

remix.process-env-in-route
Framework
Must fix
Remix browser route reads process.env directly

Remix routes render in the browser; process.env is only populated server-side. Values must be exposed via the loader.

hosting.node-pin
Hosting
Heads up
Node version not pinned in package.json

Without engines.node, your host may upgrade Node mid-deploy and break the build.

railway.port-bind
Hosting
Must fix
Server doesn't bind to process.env.PORT

Railway, Render, Fly all require the app to listen on $PORT.

vercel.build-mismatch
Hosting
Should fix
vercel.json buildCommand disagrees with package.json scripts

Builds run a different command than the one you test locally.

netlify.dual-redirects
Hosting
Should fix
Both netlify.toml [[redirects]] and _redirects file present

Netlify merges both, but conflicts silently win in unexpected order.

docker.expose
Hosting
Heads up
Dockerfile has no EXPOSE

Some providers route traffic based on EXPOSE.

cloudflare.node-compat
Hosting
Must fix
Cloudflare Workers project uses Node API without nodejs_compat

Workers run in V8 — Node built-ins require the nodejs_compat flag.

fly.port-mismatch
Hosting
Must fix
Fly internal_port does not match the app/container port

fly.toml [http_service] internal_port must match the port the container/app actually listens on.

docker.node-latest
Hosting
Should fix
Dockerfile uses an unpinned Node base image

FROM node:latest or FROM node (no tag) breaks reproducible builds when Docker Hub bumps the floating tag.

stripe.env-mix
Integrations
Must fix
Stripe live key paired with test webhook (or vice versa)

Live and test Stripe envs never validate each other's signatures.

stripe.raw-body
Integrations
Must fix
Stripe webhook handler likely parses JSON before verifying signature

stripe.webhooks.constructEvent requires the raw request body.

stripe.webhook-localhost
Integrations
Should fix
Stripe webhook URL points to localhost

Local webhook URLs can't receive production Stripe events.

supabase.service-in-client
Integrations
Must fix
SUPABASE_SERVICE_ROLE_KEY used from client code

Service role bypasses Row Level Security — never expose to the browser.

supabase.url-missing
Integrations
Must fix
Supabase code missing either URL or anon key

createClient(url, anon) needs both.

resend.domain
Integrations
Should fix
Resend sender appears to use an unverified domain

Resend rejects sends from unverified domains.

ai.key-client
Integrations
Must fix
OpenAI / Anthropic client instantiated in browser code

new OpenAI({ apiKey }) in client code leaks your AI key.

security.cors-wildcard
Security
Must fix
Access-Control-Allow-Origin: * with credentials

Wildcard CORS with credentialed cookies is a CSRF vector.

auth0.callback-localhost
Integrations
Must fix
Auth0 dashboard URLs still point at localhost

Auth0 Allowed Callback / Logout / Web Origin URLs must use the public production URL, not localhost.

build.module-not-found
Build
Must fix
Build log: Module not found

Parses common 'cannot find module' errors out of the deploy log.

build.env-undefined
Env vars
Must fix
Runtime log: env var undefined

Parses 'environment variable X is not defined' patterns out of the log.

build.lockfile-mismatch
Build
Must fix
npm ci lockfile out of sync with package.json

Detects npm ci failures caused by package-lock.json missing or out of date.

log.localhost-in-prod
Env vars
Must fix
Production config still points at localhost

Detects descriptions of production URLs (webhooks, redirects, site URL) still set to http://localhost.

ai.dangerously-allow-browser
Security
Must fix
OpenAI client uses dangerouslyAllowBrowser

dangerouslyAllowBrowser: true ships your AI API key to every visitor.

supabase.service-role-warning
Integrations
Should fix
SUPABASE_SERVICE_ROLE_KEY referenced anywhere — must stay server-only

Even on server-only routes, the service-role key bypasses RLS and deserves a hardening check.

env.supabase-anon-naming
Env vars
Must fix
Supabase anon key missing NEXT_PUBLIC_ prefix for Next.js

Next.js needs NEXT_PUBLIC_SUPABASE_ANON_KEY (with prefix) to expose the anon key to the browser.

log.missing-prod-env
Env vars
Must fix
Build/runtime log says a Production env var is not configured

Catches 'X is not configured for Production' / 'X is missing' style warnings in pasted text.

security.weak-secret-default
Security
Must fix
Sensitive secret falls back to a weak default value

Detects JWT_SECRET / SESSION_SECRET / etc. set to placeholder values like 'changeme', or `process.env.X || 'changeme'` fallbacks in source.

security.hardcoded-secret-in-source
Security
Must fix
Real-looking secret token hardcoded in source

Detects provider tokens (GitHub ghp_, Stripe sk_live_/sk_test_, OpenAI sk-, Netlify nfp_, Slack xox*, AWS AKIA*) committed inline in source files.

node.listen-hardcoded-port
Hosting
Must fix
Pasted code/log shows app.listen() bound to a hardcoded port

Mirrors railway.port-bind for log-only / mixed-prose inputs where the user pastes the offending snippet instead of uploading server.js.

security.env-example-real-secret
Security
Must fix
.env.example contains real-looking secret values

.env.example is committed; values that match real credential shapes (ghp_, sk_live_, whsec_, nfp_, sk-…) almost certainly leaked.

Showing 45 of 45 rules.

Second opinion

An independent AI cross-checks every diagnosis.

The rules engine finds the issue with hard evidence. An independent model — different vendor, different prompt — then reviews the verdict and either confirms or flags disagreement. You see both side by side.

  • Rules engine and AI must agree before "Auto-apply" is offered.
  • Disagreements surface as "Needs human review" — never silently merged.
  • Confidence under 80% always gates behind your explicit approval.
Example
Rules engine

SUPABASE_SERVICE_ROLE_KEY referenced in a client component (app/admin/page.tsx:3). Confidence 99%.

Second opinion · Claude

Confirmed. The service role key bypasses RLS; shipping it to the browser would expose your entire database to any visitor.

Both agree · safe to auto-apply