# Getting Started with APOPHIS Get from install to your first behavioral bug in 10 minutes. APOPHIS is inspired by [Invariant-Driven Automated Testing](https://arxiv.org/abs/2602.23922) (Malhado Ribeiro, 2021): instead of only validating request and response shape, encode intended behavior as executable contracts and let the tool find violations automatically. ## Prerequisites - Node.js 20.x or 22.x - A Fastify app with `@fastify/swagger` registered ## Step 1: Install ```bash npm install apophis-fastify fastify @fastify/swagger ``` ## Step 2: Scaffold ```bash apophis init --preset safe-ci ``` This creates: - `apophis.config.js` — config with a `quick` profile - `APOPHIS.md` — preset-specific guidance - Package script: `npm run apophis:verify` ## Step 3: Add One Behavioral Contract Pick one important route. Add an `x-ensures` clause that checks behavior across operations: ```javascript import crypto from 'crypto'; app.post('/users', { schema: { 'x-category': 'constructor', 'x-ensures': [ // BEHAVIORAL: Creating a user must make it retrievable 'response_code(GET /users/{response_body(this).id}) == 200' ] } }, async (request, reply) => { const { name } = request.body; const id = `usr-${crypto.createHash('sha256').update(name).digest('hex').slice(0, 8)}`; reply.status(201); return { id, name }; }); ``` > **Warning:** Using `Date.now()` or `Math.random()` in handlers breaks determinism and replay. Use a stable function of the input instead. ## Step 4: Run Verify ```bash apophis verify --profile quick --routes "POST /users" ``` ## Example Failure If your `GET /users/:id` handler has a bug (always returns 404), APOPHIS catches it: ```text Contract violation POST /users Profile: quick Seed: 42 Expected response_code(GET /users/{response_body(this).id}) == 200 Observed GET /users/usr-7d865e returned 404 Why this matters The resource created by POST /users is not retrievable. Replay apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json Next Check the create/read consistency for POST /users and GET /users/{id}. ``` ## Step 5: Replay and Fix Copy the replay command and run it: ```bash apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json ``` Fix the bug in your handler. Re-run verify. The failure should now pass. ## Next Steps - Add more routes to your profile: `apophis verify --profile quick --routes "POST /users,PUT /users/:id"` - Use wildcards to match route patterns: `apophis verify --routes 'POST /api/*'` - Run all routes: `apophis verify --profile quick` - Run only changed routes in CI: `apophis verify --profile ci --changed` - Requires a git repository. - Use machine-readable output in CI: `apophis verify --profile ci --format json-summary` - Add observe mode for runtime drift detection: see [observe.md](observe.md) - Add qualify mode for scenario, stateful, and chaos checks: see [qualify.md](qualify.md) ## Config Reference For the full configuration reference, see [CLI Reference](cli.md). ## Monorepo Workspaces Use `--workspace` to run verify or doctor across all packages: ```bash apophis verify --workspace --profile quick --format json ``` See [CLI Reference](cli.md) for workspace output format and exit codes.