Files
apophis-fastify/docs/verify.md
T

3.9 KiB

Verify Mode

Deterministic contract verification for CI and local development.

What Verify Does

apophis verify runs behavioral contracts against your Fastify routes:

  1. Discovers routes from your Fastify app
  2. Filters routes by profile config and CLI flags
  3. Generates test data from JSON Schema
  4. Executes routes and checks x-ensures contracts
  5. Reports pass/fail with deterministic seed and replay command

When to Use It

  • Local development: Quick feedback on behavioral changes
  • CI pipelines: Catch regressions before merge
  • Pre-commit hooks: Fast smoke verification

Profile Examples

Quick (local smoke)

profiles: {
  quick: {
    name: 'quick',
    mode: 'verify',
    preset: 'safe-ci',
    routes: ['POST /users']
  }
}

CI (PR checks)

profiles: {
  ci: {
    name: 'ci',
    mode: 'verify',
    preset: 'safe-ci',
    routes: []
  }
}

Run with: apophis verify --profile ci --changed

Deep (nightly verification)

profiles: {
  deep: {
    name: 'deep',
    mode: 'verify',
    preset: 'safe-ci',
    routes: []
  }
}

Route Filtering

Filter routes with the --routes flag:

# Single route
apophis verify --routes "POST /users"

# Multiple routes (comma-separated)
apophis verify --routes "POST /users,PUT /users/:id"

# Wildcards
apophis verify --routes "POST /users/*"

# All routes (empty or omitted)
apophis verify --profile quick

--changed Flag

Run only routes modified in the current git branch:

apophis verify --profile ci --changed

If no routes changed, exits 0 with a message.

Failure Output Format

When a contract fails, APOPHIS prints:

Contract violation
POST /users
Profile: quick
Seed: 42

Expected
  response_code(GET /users/{response_body(this).id}) == 200

Observed
  GET /users/usr-123 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}.

Replay Workflow

  1. Copy the replay command from failure output
  2. Run it with the recorded route, seed, and artifact data; source or dependency drift can change the outcome
  3. Fix the bug in your handler
  4. Re-run verify to confirm the fix
apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json

Machine Output for CI

Use concise formats to reduce log volume in large verify runs:

  • --format json-summary — single JSON with summary, failures, warnings. Omits per-step traces.
  • --format ndjson-summary — three NDJSON lines: run.started, run.summary, run.completed.

Filtering examples

# Extract only failed routes from full ndjson
apophis verify --profile quick --format ndjson | jq 'select(.type == "route.failed")'

# Write artifact to disk and parse the file instead of stdout
apophis verify --profile quick --format json --artifact-dir reports/apophis

Exit Codes

Code Meaning
0 All contracts passed
1 One or more behavioral contracts failed
2 Config error or no routes matched
3 Internal APOPHIS error
130 Interrupted (SIGINT)

Config Example

// apophis.config.js
export default {
  mode: 'verify',
  profile: 'quick',
  profiles: {
    quick: {
      name: 'quick',
      mode: 'verify',
      preset: 'safe-ci',
      routes: ['POST /users']
    },
    ci: {
      name: 'ci',
      mode: 'verify',
      preset: 'safe-ci',
      routes: []
    }
  },
  presets: {
    'safe-ci': {
      name: 'safe-ci',
      depth: 'quick',
      timeout: 5000,
      parallel: false,
      chaos: false,
      observe: false
    }
  },
  environments: {
    local: {
      name: 'local',
      allowVerify: true,
      allowObserve: true,
      allowQualify: false,
      allowChaos: false,
      allowBlocking: true,
      requireSink: false
    }
  }
};