Run the QA invariant sweep
Ask the platform to check its own cross-module truths, and read the violations honestly.
Owned by Admin · 8 steps · about 15 minutes
Why this exists
Every module tests itself. The invariant sweep exists for the statements that no single module owns — the ones that are only true if several modules agree. "Every ledger transaction balances." "A listed ticket has a suspended pass." "No payout over the reporting threshold was paid without verified KYC." Those are cross-module truths, and they are exactly the ones that rot quietly.
Fourteen invariants ship, each with a stable id, and they are read-only against any database state. The sweep never repairs anything, and it never writes outside its own two tables. That is deliberate: a checker that fixes things is a checker you stop trusting, because you can no longer tell whether the system was healthy or merely tidied up.
Each invariant is executed independently and its errors are caught individually, so one broken check cannot abort the sweep, and a table that does not exist yet means "nothing to check" rather than a failure. That is what makes the sweep safe to run on a half-built or freshly seeded database.
Read a violation as a question, not a verdict. Some are genuinely legal states in an unusual moment: a reservation looks expired because the clock was moved and nobody ticked the scheduler; a tab is over its limit because a settlement failed and the carryover is expected. The detail and snapshot on each violation are there so you can tell which kind you have.
Before you start
- An admin session — the dashboard and the debug API are both admin-only.
- Debug endpoints enabled, otherwise the run button has nothing to call.
Practise with
| Persona | Password | Note | |
|---|---|---|---|
| admin | admin@club.test | admin123 | the only persona that can see or run the sweep |
Steps 1–8 — Admin
their manual →-
1Open the QA dashboard. Read the latest run first, then the journey evidence chips, then the interface-documentation matrix.Expected result The last sweep with its status and violations, four journey chips, and a row per module showing whether it ships an INTERFACE.md.Watch out for A seeded database always has one run already, recorded by the seed itself, so the dashboard is never empty on a fresh install. Do not mistake that seeded run for a run you just did.
-
2Run the full sweep with the button on the dashboard.Expected result A run id, a status of passed, failed or errored, counts, a duration, and one entry per violation naming the invariant, the table and the offending row.Watch out for failed means an invariant found violations. errored means an invariant itself blew up — those are recorded separately and are a bug in the check, not necessarily in your data.
-
3Read the registry of all fourteen invariant ids and what each one asserts, so a violation id means something to you before you panic.Expected result Ordered ids with descriptions.Watch out for The ids are stable and are meant to be quoted in incident notes. Do not paraphrase them.
-
4Re-run a single invariant by passing its id as the scope, so you can iterate quickly while you fix something.Expected result The same payload shape, scoped to one check.Watch out for An unknown id is 422 unknown_invariant. Copy the id from the registry rather than typing it.
-
5Look at the run history and ask whether this violation is new. A check that has been failing for a week is a different problem from one that started an hour ago.Expected result Recent runs with status and counts, filterable.Watch out for Every persisted run writes rows. If you are looping the sweep during an investigation, expect the history to fill up.
-
6Check the journey evidence probes: did each end-to-end journey's terminal state ever actually happen in this database?Expected result Four journeys with an ok flag each.Watch out for This is evidence, not a test run. A false chip means nobody has completed that journey here yet — on a fresh demo database that is normal, not broken.
-
7Pull the one-shot health blob when you want the whole picture in a single response: latest run, journeys, interface docs, append-only status.Expected result A single JSON summary suitable for pasting into an incident channel.Watch out for The append-only section checks that the protective triggers still exist. If that goes false, stop and treat it as serious — it means the guarantees the rest of this manual relies on are gone.
-
8Triage violations in the data suite grid, where you can filter and sort them by invariant and entity.Expected result One row per violation with its detail and snapshot.Watch out for Deleting violation rows makes the dashboard look better and changes nothing about the data. Fix the cause and re-run — a clean sweep you earned is the only one worth having.