We run your code. So we assume it’s hostile.
Running a team’s tests means executing their code, and code a model drafted. Every run is isolated, short-lived and secret-free by design. The full threat model is public.
The life of one sandbox run
Every proof, re-proof and sandboxed pull request check follows the same path. Nothing survives the last step.
- 1
Fresh machine
A new Firecracker microVM boots from a clean image, or one restored from your own repository’s trusted install snapshot. Nothing from another team or run.
- 2
Shallow clone
One commit is fetched with a one-hour installation token scoped read-only to that repository. The token is scrubbed from the checkout before your code runs.
- 3
Locked network
Package registries are reachable while dependencies install. Then the network is set to deny-all, before any test runs.
- 4
Run and record
The test runs under a time limit. We keep outcomes, the JUnit report and trimmed logs.
- 5
Destroyed
The machine is stopped and deleted, with the clone and anything the test wrote.
The model never decides
A drafted test is admitted only when it fails before the fix and passes after, on real commits. A model cannot mark anything proven or safe.
Least privilege on GitHub
Clone tokens are read-only and per repository. The app writes only to aftershock/* branches, check runs and one comment; tests arrive as pull requests you merge.
No secrets in runs
Your environment variables, deploy keys and cloud credentials are never available to sandboxed code. Tests that need them belong on your own runners.
Untrusted text stays data
Incidents, postmortems, alerts and code reach the model inside random-nonce fences, and its output is parsed and validated before anything uses it.
Every delivery is authenticated
Webhooks are verified by signature or token in constant time, size-capped and replay-checked before anything is stored or run.
Outbound calls can’t reach inside
Notification and model endpoints must be public https addresses; private, loopback and metadata addresses are refused when connecting.
What we keep, and for how long
| Data | Kept | Why |
|---|---|---|
| Source code | Never stored | Exists only inside the sandbox for the run |
| Incidents and notes | Until you delete them | They are what your tests are built from |
| Proven test code | In your repository | It is yours; we keep a copy to run and display |
| Run logs and webhook deliveries | 30 days | For debugging; cleared automatically |
| Verdicts and evidence | Until you delete the repository or workspace | The record of what was proven, and when |
| Model keys, webhook secrets, Slack URLs | Encrypted (AES-256-GCM) until removed | To call the services you connected |
| Workspaces that uninstall the app | 30 days, then purged | So a reinstall can continue where it left off |
Admins can delete an incident, a repository or the workspace, and anyone can delete their own account, from the app. Deletions are recorded in the workspace audit log.
Who processes your data
- VercelHosting, the run sandboxes, durable workflows
- NeonPostgres database
- GitHubSign-in, repositories, checks and pull requests
- The model provider you chooseDrafting tests and triage; Vercel AI Gateway or any OpenAI-compatible endpoint
Report a vulnerability
Use GitHub’s private vulnerability reporting on the repository; you get a reply within 3 working days. Details are in SECURITY.md.
Audit evidence is signed and verifiable. See audit evidence.