Every request is an in-process WHATWG Request

Attack code, not people.
No sockets. Ever.

Crashtest drives a seeded adversarial suite against your real handlers — routing, guards, state, volume — through a fake transport. The output is a hardening ledger your CI fails on new EXPLOITED findings or REFUSED→EXPLOITED regressions. Same commit, same findings, forever.

# 60 seconds — point it at your handlers
npx crashtest init
# edit crashtest.config.js — routes list your handlers, env the fake d1/kv/secrets
npx crashtest run
# → labs/hardening.md · labs/crashledger.json · exit 0 = hold, exit 1 = a finding regressed

🛡 EFF. auth/secret-watermark  🛡 guards/burst-wall      🛡 state/enumeration-oracle
⚡ guards/hygiene-no-store (2xx write with no Cache-Control — real findings look like this)

The pipeline

How a run turns handlers into evidence.

01Declare your surfacename each handler or register a framework adapter — hono, express, fastify, or raw Node dispatch.
02The harness firesevery request is an in-process Request; the fake d1/kv/env mirrors your backend. Nothing leaves the process.
03Scenario modules attackidentity spoofing, secret watermarking, proto pollution, burst walls, storage fill, cost amplification — each returns REFUSED / EXPLOITED / BOUNDED.
04The ledger rememberscrashledger.json is your committed baseline. New exploited finding? Exit 1. Regressed refusal? Exit 1. Attach hardening.md to the PR.

Why it exists

LLMs write programs fast. Programs that route, store, and spend budget need their own fire drill.

§Fail at cause, loudly

No swallowed errors, no phantom 200s — a handler that never ends its response is surfaced as a finding, not papered over.

§Deterministic attacks

Seeded RNG from commit to commit. A scratch-run today reproduces bit-for-bit in CI tomorrow.

§Cost-aware from day one

Every request is accounted in ops — amplification attacks get named per-request and bounded, not vibes.

§Fits CI, not just dev

Zero runtime deps, plain Node, one command. Plus a composite GitHub Action to gate other repos.