<!--
  scaffold: verify-runtime-behaviour.md
  bucket: engineering-discipline (Bucket 5)
  what belongs here: the verify-what-actually-runs discipline.
    - Tests verify code correctness, not feature correctness.
    - Drive the actual flow to confirm behaviour.
    - If you can't test the UI, say so.
-->

# Verify runtime behaviour

## The rule

**Tests verify code correctness, not feature correctness.** A test passing means the code does what the test asserts. It does NOT mean the feature works for the user.

Corollary: don't ship a change on "tests pass". Ship on "I drove the flow and saw it work."

## Driving the flow

Depending on the surface:

- **CLI.** Run the actual command in the actual shell. Verify stdout, stderr, exit code, and side effects.
- **HTTP service.** Fire a real request. Verify status, headers, body, side effects.
- **Web page / UI.** Load the page in a real browser (Playwright or manual). Verify the interaction works end-to-end.
- **Integration.** Trigger the integration end-to-end. Verify the downstream system received what was expected.

## What tests are good for

- **Regression prevention.** After you've verified the flow works, tests catch when someone later breaks it.
- **Boundary conditions.** Testing 50 edge cases in a unit test is cheaper than driving 50 flows manually.
- **Documenting intended behaviour.** A well-named test describes the shape of correctness.

Tests are load-bearing infrastructure — they're just not sufficient on their own.

## When you can't drive the flow

Say so. Explicitly.

- "I can't test the UI in this environment; I've verified the tests pass and the code paths look right."
- "I can't reach the third-party service; I've verified the request would be well-formed."

Don't ship claiming verification you didn't do. The operator can decide whether to accept the risk; you don't get to decide for them.

## The `/verify` skill (Claude Code)

The Claude Code harness ships a `/verify` skill that formalises this. Run it before committing nontrivial changes to product source. It bootstraps a project verify pattern if one doesn't exist.

Don't invoke `/verify` on a diff that only touches tests, docs, or code with no runtime surface to drive — nothing to observe.

## Related

- CLAUDE.md.template Bucket 5 rule 2.
- Claude Code skills — `/verify`.
