> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirra.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Scenarios

> A markdown file describing starting state, a task, success criteria, and config.

A scenario is a markdown file in your repository that describes what should happen during a session and how to tell if it worked.

Scenarios replace the usual test-suite grammar (arrange-act-assert in code) with a grammar that both humans and coding agents can read, write, and reason about.

## The shape

Every scenario has five sections. Three are required, two are optional.

| Section                             | Required       | Who sees it    |
| ----------------------------------- | -------------- | -------------- |
| `# Title`                           | yes            | both           |
| `## Setup`                          | no             | both (context) |
| `## Prompt` / `## Task`             | for agent runs | both           |
| `## Expected Behavior`              | no             | evaluator only |
| `## Success Criteria` / `## Checks` | yes            | evaluator only |
| `## Config`                         | no             | evaluator only |

## A complete example

```markdown theme={null}
# Send Welcome Email on Signup

## Setup
A Resend account with one verified domain `mail.acme.com` and no emails
sent yet.

## Prompt
When a user signs up with email `alice@example.com`, send a welcome email
from `hello@mail.acme.com` with subject "Welcome to Acme" and track
delivery status via webhook.

## Expected Behavior
The integration should create the email via the Resend API, receive an
`email.sent` webhook immediately, then `email.delivered` within a few
seconds. Failed deliveries (bounces) should update local user state.

## Success Criteria
- check: Exactly 1 email is created in the Resend mirror
- check: The email's `from` address is `hello@mail.acme.com`
- check: At least 1 `email.sent` webhook was received by the handler
- check: The webhook signature was verified (no signature errors logged)
- judge: The email subject and body are appropriate for a welcome message
- judge: Error handling for bounces is implemented

## Config
mirrors: resend
timeout: 60
runs: 3
```

Run it:

```bash theme={null}
$ mirra run scenarios/welcome-email.md

→ provisioning resend mirror…
✓ session ses_a7k2 ready
→ running agent…
✓ run 1/3 complete
✓ run 2/3 complete
✓ run 3/3 complete

satisfaction score: 87% (15/18 criteria passed across 3 runs)
```

## `check` vs `judge`

Every success criterion is tagged either `check:` or `judge:`.

<Columns cols={2}>
  <Card title="check — deterministic" icon="square-check">
    Programmatic assertion against mirror state. Instant, free, exact. Used for anything you can count, compare, or pattern-match.
  </Card>

  <Card title="judge — probabilistic" icon="scale-balanced">
    LLM judgment from the trace and final state. Bounded cost, used for subjective calls like tone, appropriateness, or "does error handling exist" (beyond just counting).
  </Card>
</Columns>

A good scenario leans on `check:` for everything verifiable and uses `judge:` sparingly for the subjective things only.

### When Mirra infers the tag

If a criterion has no explicit `check:` or `judge:` prefix, Mirra infers one based on the wording:

* Has numbers or concrete state ("exactly 3", "was delivered", "the `from` address is") → **check**.
* Vague or subjective ("appropriate", "clear", "polite", "handles gracefully") → **judge**.

You can always override:

```markdown theme={null}
- check: The error message is clear   ← forces deterministic (may not be what you want)
- judge: Exactly 3 emails were sent    ← forces LLM (expensive — don't)
```

See [Evaluation reference](/reference/evaluation-dp) for the full rules.

## Seeds — starting state

A scenario starts from a seeded state. Three ways to supply it:

<Tabs>
  <Tab title="LLM-generated from Setup">
    ```markdown theme={null}
    ## Setup
    A Resend account with one verified domain and 50 sent emails
    across the last 30 days, with a 5% bounce rate.
    ```

    The plain-English `## Setup` section is parsed by a small LLM that emits the seed state directly to the mirror. Zero configuration. Best for "any reasonable scenario" tests.
  </Tab>

  <Tab title="Built-in named fixture">
    ```markdown theme={null}
    ## Config
    mirrors: resend
    fixture: transactional-busy
    ```

    Each mirror ships a handful of named fixtures: `resend:empty`, `resend:transactional-busy`, `stripe:subscription-lifecycle`, etc. Zero LLM cost; exact, reproducible, version-pinned. Best for deterministic tests.
  </Tab>

  <Tab title="Custom JSON file">
    ```markdown theme={null}
    ## Config
    mirrors: resend
    fixture-file: ./fixtures/my-seed.json
    ```

    Full control. Best when you need state a named fixture can't describe — a production-like snapshot, a specific edge case, data scrubbed from an incident.
  </Tab>
</Tabs>

## Statistical satisfaction

Set `runs: N` in `## Config` to execute the scenario N times. Each run resets to fresh state between iterations (via `mirra reset`).

```markdown theme={null}
## Config
mirrors: resend
runs: 5
```

The output is a **satisfaction score** — a mean percentage of criteria passed across runs.

```
satisfaction score: 87% (26/30 criteria passed across 5 runs)

per-criterion breakdown:
  ✓ Exactly 1 email is created in the Resend mirror         5/5
  ✓ The email's from address is hello@mail.acme.com          5/5
  ✓ At least 1 email.sent webhook was received               5/5
  ✓ The webhook signature was verified                       5/5
  ✗ The email subject and body are appropriate for a welcome 4/5
  ✗ Error handling for bounces is implemented                2/5
```

This is the shape of output that handles agent-generated code gracefully — one flaky run doesn't fail your CI, but two flaky criteria across five runs is a signal worth acting on.

## Where scenarios live

Scenarios are plain markdown files in your repo. Put them wherever you keep tests:

```
acme-app/
├── src/
├── tests/
│   └── integration/
├── scenarios/              ← convention
│   ├── welcome-email.md
│   ├── subscription-upgrade.md
│   └── refund-flow.md
└── package.json
```

Mirra doesn't care about the path — `mirra run` takes an explicit path. Teams usually put them in `scenarios/` to keep them separate from unit tests.

## Where to go next

<Columns cols={2}>
  <Card title="Write your first scenario" icon="pen" href="/guides/first-scenario">
    End-to-end walkthrough: scenario file → mirra run → CI gate.
  </Card>

  <Card title="Scenario format reference" icon="book-open" href="/reference/scenario-format">
    Every valid section, every valid config key, every edge case.
  </Card>

  <Card title="check vs judge deep dive" icon="scale-balanced" href="/reference/evaluation-dp">
    Exactly how Mirra grades criteria. Cost model. Failure modes.
  </Card>

  <Card title="mirra run" icon="terminal" href="/cli/run">
    The CLI command that executes scenarios.
  </Card>
</Columns>
