The goal
A CI run that:- Installs the Mirra CLI.
- Runs every
scenarios/*.mdin your repo. - Fails the job if the satisfaction score drops below a threshold you pick.
- Uploads a result artifact for inspection on failure.
Prerequisites
A Mirra personal access token from app.mirra.run/settings/tokens. Scope it to the workspace and project you’re testing. Store it in your CI’s secret store (GitHub secrets, GitLab variables, CircleCI contexts).GitHub Actions
concurrencyblock — kills the previous run on the same PR when a new commit lands. Important because scenario runs burn minutes.--runs=3— executes every scenario three times for statistical satisfaction. Don’t drop below 2; don’t go above 5 unless you’ve got a flake problem to quantify.--fail-below=0.9— PR fails if fewer than 90% of criteria pass across runs. Tune per repo: stricter for infrastructure, looser for rapidly-changing integration code.--jsonoutput — machine-readable, easy to parse in downstream steps, easy to archive.if: always()on artifact upload — uploads the result even on job failure so you can inspect.
GitLab CI
MIRRA_TOKEN goes in Settings → CI/CD → Variables as a protected, masked variable.
CircleCI
MIRRA_TOKEN lives in a CircleCI context named mirra, restricted to the scenarios job.
Patterns that work
Fail-below per scenario, not per-suite
For critical scenarios, split them out and gate stricter:Cache warm sessions across jobs
If a single workflow runs scenarios across many jobs, reuse a session:Post the satisfaction score to the PR
Parse the JSON and comment on the PR:Troubleshooting
Provisioning is slow
Provisioning is slow
Cold start is sub-2s; warm start is ~2s when the session-cache hits. If you’re consistently seeing 5s+ starts, your workflow isn’t hitting the cache — check that
mirrors, seeds, and workspace are stable between runs.PR fails with 'minutes exhausted'
PR fails with 'minutes exhausted'
You’ve hit your plan’s monthly minute cap. Either upgrade or reduce
--runs. Overage billing is enabled by default — see pricing.Scenario randomly fails in CI but passes locally
Scenario randomly fails in CI but passes locally
Almost always a timing issue. Bump
timeout: in the scenario’s ## Config, or add resetBetweenTests: true if you’re running inside Vitest.Need to pin mirror versions for deterministic runs
Need to pin mirror versions for deterministic runs
Add
mirror-version: to each scenario’s ## Config. See Fidelity — versioning.Where to go next
First scenario
Write the scenario CI will run.
mirra run reference
Every flag, every exit code.