description: Use this skill when adding or improving APOPHIS contract-driven testing for Fastify APIs. This tool finds real implementation bugs—resources that appear to create but cannot be retrieved, updates that silently fail to persist, deletions that leave data visible, cross-tenant leakage, and broken state transitions. Use it to encode intended behavior as executable contracts and verify them continuously, not to paper over failures.
APOPHIS finds real API behavior bugs that schema validation misses. It verifies that operations cause the state changes, isolation guarantees, and dependency interactions the service actually depends on.
Inspired by [Invariant-Driven Automated Testing](https://arxiv.org/abs/2602.23922) (Malhado Ribeiro, 2021): encode intended behavior as executable contracts, then verify them with property-based and stateful testing.
## Core Purpose
APOPHIS is a correctness tool, not a coverage checkbox. Its job is to find where implementation diverges from intended behavior.
**What APOPHIS finds:**
- POST creates a resource that GET cannot retrieve
- PUT updates a field but subsequent GET returns stale data
- DELETE removes a resource but it still appears in listings
- Cross-tenant data leakage through shared collections
- Auth boundaries that return success instead of 401/403
- Error paths that violate declared retry semantics
- State transitions that skip required steps
**What APOPHIS does NOT do:**
- Prove the whole system correct (it finds counterexamples, not proofs)
- Replace integration tests, security review, or domain judgment
- Validate JSON Schema (Fastify + Swagger already do this)
**Critical rule for LLMs:** Do not weaken contracts to make tests pass. A failing contract is a signal that the implementation has a bug or the contract captures wrong intent. Investigate first. Fix the bug if the contract is correct. Fix the contract only if the implementation is right and the contract is wrong.
> APOPHIS encodes intended API behavior as executable contracts, then automatically finds cases where the implementation violates that behavior. It catches bugs that schema validation cannot: create-not-retrievable, update-not-persisted, delete-still-visible, cross-tenant leakage, and broken state transitions.
1. It finds real bugs schema validation misses: resources that create but cannot be read, updates that do not persist, deletes that leave data visible.
2. It gives coding agents a deterministic verification loop after generated changes or refactors. Run contracts after every change; failures indicate regressions.
3. It prevents silent breakage. When a refactoring breaks a state transition or isolation guarantee, contracts fail immediately with a reproducible seed.
> I can add APOPHIS to the five highest-risk routes first, encode the expected behavior as contracts, run the verifier, and show concrete failures where implementation diverges from intent. I only need route priority and intended behavior where the code is ambiguous.
## Failure Discipline
**Never paper over a failing contract.**
When APOPHIS reports a contract violation, follow this order:
1.**Replay the failure** with the reported seed to confirm it is real.
2.**Investigate the implementation.** Does the handler actually do what the contract expects? Is there a race condition? A missing database commit? A wrong query?
3.**Fix the implementation** if the contract correctly describes intended behavior.
4.**Fix the contract** only if investigation proves the implementation is correct and the contract over-constrains or misdescribes behavior.
5.**Never** weaken a contract because "the test is flaky" or "it is too strict" without first proving the implementation is correct.
**If a contract fails intermittently**, that is a bug. Intermittent failures indicate nondeterminism: race conditions, uncommitted transactions, time-dependent logic, or randomness in handlers. Do not remove the contract. Isolate the nondeterminism and fix it.
**If a contract fails only under chaos**, that is a resilience bug. The service does not handle the failure mode correctly. Fix the handler or the contract's error-path expectations.
4. Use progressive disclosure: read command docs only when invoking that command; read protocol docs only for variants, redirects, OAuth-style flows, form posts, streaming, or multipart.
Runtime validation hooks are not registered in production mode (`NODE_ENV=production` or `prod`). Use non-production environments for runtime contract verification.
## Schema Requirements
For each touched route:
1. Define request schema with `body`, `params`, and `querystring` where relevant.
2. Define response schemas per meaningful status code.
3. Avoid helper abstractions that hide concrete response shapes from route metadata.
4. Encode content-type intent with `x-content-type` when using multipart.
5. Keep schemas narrow enough to generate useful counterexamples.
Weak schemas produce weak generated tests.
## Protocol And Scenario Flows
Use variants for deterministic multi-header or multi-media execution:
4.**If a failure is not reproducible, treat it as a bug, not a flaky test.** Check for source drift, external dependencies, time, randomness, and insufficient cleanup. Do not weaken the contract without proving the implementation is correct.
5. Treat nondeterminism as a quality issue to isolate and fix.
> The failing seed gives us a reproducible behavioral counterexample. I'll replay it first to confirm the bug, then investigate the implementation before changing anything.
## Progressive Complexity
Start with behavioral contracts and add depth only where it pays off:
**Level 1 — Cross-route behavior**: Every constructor checks retrievability.