# What an audit checks, and what the verdicts mean

> What Stableship tests, how long it takes, and what Cleared, Held, Overridden and an audit on hold mean.

## What does an audit check?

A full audit tests your whole app on a fresh private copy, as every kind of user:

- Row level security on every Supabase table, with the policies tested as each kind of user.
- Whether one customer can reach another customer's records: in the app, by address, and directly on the data API.
- Sign-in, Edge Functions that check the JWT, and the service-role key kept out of browser code.
- Signup, checkout and your critical flows, clicked through as every kind of user, with a video of every problem.
- A phone-size pass (390px) and accessibility checks on the critical flows.
- A code review against the rules you confirmed, plus vulnerable dependencies.
- Supabase's own security and performance advisors, run on the copy.
- Protective headers, cookie flags, files that must never be served, and secrets in the browser bundle.
- Your API routes and Edge Functions called as each kind of user, signed out and with no key, including Express, Hono and Fastify routes read from your server code.
- Your repository's own test suite, run on the private copy, and the licenses of the npm packages your app ships.

It never probes or writes to your production app, and it does not read rows in your production database.

## How long does it take?

Setup takes about ten minutes. An audit runs for up to an hour on most apps, and up to 90 minutes on the largest; you can close the tab, and you get an email when it is done. Checks on later pushes take a few minutes for small changes, and up to about half an hour when a push touches sign-in, data or payments.

## What do Cleared, Held and Overridden mean?

- **Cleared**: nothing blocks the release. There may be notes to read.
- **Held**: a check found a problem that blocks the release.
- **Overridden**: a person chose to ship anyway. Their name and reason are in the activity log.
- **Skipped**: nothing needed checking.

## What can block a release?

Only proven problems. A problem found in the browser blocks once it has been replayed twice on a fresh copy, and only when it matters enough to hold a launch: a broken flow blocks when the problem is high severity or worse, or when it stops one of your critical flows from being finished; smaller problems (a missing message, a plain date field, a field without validation) still show and warn. Confirmed security facts block at high severity and above: a secret or service-role key in the browser code, row level security off on a public table, a served `.env` file, or a critical vulnerable dependency. A confirmed break between your app's own parts (an API that still calls a database function a migration renamed) blocks at high severity and above too, because it fails every time. A project can change these bars in Policies. Unconfirmed leads never block; they show as notes.

## When is a problem marked fixed?

Each problem is tracked across runs, however it is worded each time. A problem that a fixed check finds (a vulnerable package, a database advisor, a missing header, an accessibility rule) is **Fixed** once that check runs again and no longer finds it. A problem found by a tester or the code review is **Fixed** once a re-check of that problem passes: every push to your default branch re-checks the open problems on their own, and so does a re-check you ask for. A problem that later checks covered twice without seeing it again shows as **Not seen lately**: it no longer counts or blocks, it is not called fixed, and it opens again if it comes back.

## What do I get when an audit finishes?

A report you can share, a video of every reproduced problem, a fix plan for your coding agent (`STABLESHIP_FIXES.md`), and a re-check once you have fixed things.

## My audit says "on hold"

An audit is put on hold when Stableship cannot build the private copy of your app, for example because the build needs a private package token. It does not count against your plan: the audit it used goes back into your plan. The audit resumes on your next push to the default branch, or when you choose **Run it again** on the release page.

## A run failed on Stableship's side

Runs that fail on our side never count against your plan. Stableship retries once on its own.
