Skip to main content

1. Generate the workflow

Requires: Docker, and nothing else. Run this inside the repository you want audited:
--pull=always matters: v1 is a moving tag, and docker run reuses whatever it already has on disk rather than checking whether the tag now points somewhere else. Without it you keep running the version you first pulled.
It reads the repository and writes .github/workflows/contract-audit.yml. Commit that file and you are done. Every value in that file was worked out by reading your repository, and each one has a comment next to it saying where it came from, so you can check the working: The middleware row is the one that saves you reading an unfamiliar codebase. Most projects register two APIs in the same place: the one outside developers hold a key for, and the one a dashboard talks to with a session token. Their paths look alike, so what separates them is which guard they sit behind.
init refuses to overwrite a workflow that already exists. Pass --force to replace it, --stdout to print it instead, or --json to see what was detected without writing anything.

Without Docker

Coming soon. Anyone with the codebase checked out already has one of these installed, so it will be the shortest way in: Until then the image above needs only Docker.

2. What runs on GitHub

Once the workflow is committed, every pull request into one of your shared branches is audited, and so is the merged result on those branches. One pull request can add a route while another edits the spec, so each one is audited against its own merge preview, not against whatever they both eventually land on. Each run leaves:
  • A comment on the pull request, edited in place on each run so you get one comment and not a thread. It gives counts by severity and by what disagrees. It does not list the endpoint paths: a route that is registered but undocumented is usually undocumented on purpose, and listing them would publish an inventory to everyone who can see the pull request.
  • A fix brief, uploaded as an artifact and linked from that comment. It has every finding, the evidence, and the test that proved it, written so you can paste it straight into Cursor, Codex or Claude Code.
Every input the action takes is already in the generated file, pointing at secrets that may not exist yet. Each is skipped silently when its secret is unset, so the workflow runs exactly as generated. Adding a secret under Settings → Secrets and variables → Actions turns a feature on without editing any YAML: If that file ever needs editing, it should only be to delete lines you do not want. Where each credential comes from, and setting it → Full input reference and troubleshooting →

3. Running it locally

Only needed to work on the auditor itself, or to audit a repository without putting anything in CI. No pip install, no Docker, no database.

Audit a repository directly

A real repository has no known list of correct answers to score against, so what you get is a ranked report.

Reproduce the evaluation

1

Build the 16 evaluation cases

12 injected drifts and 4 decoys. Each is compiled before it counts as a case.
2

Test the deterministic tools

No API key, no cost.
3

Confirm the scorer is sound

Expect precision 1.0, recall 1.0, decoys 4/4. Anything else means the scorer is broken, not the agent.
4

Score the no-model layer

How much of the problem needs no AI at all.
5

Add a key and run the full auditor

Any OpenAI-compatible endpoint works. Set OPENROUTER_BASE_URL to redirect.
Reset with make clean. Reset with make clean.