## What `roar diff` is

Two runs that should have matched didn't. A model regressed, a metric moved, an output that used to be byte-identical now isn't. `roar diff` answers **why** — it compares the full upstream lineage of two artifacts (or jobs, or sessions) and reports what actually differs, ranked so the likely root cause is at the top.

It's the CLI counterpart to the **Diff** view on glaas.ai (see [Use Cases](/docs/use-cases)). Same idea, in your terminal, against your local `.roar/roar.db`.

```bash
roar diff ./model.pkl ./model-v2.pkl
```

Because artifacts are identified by content hash and every job records its inputs, code commit, arguments, and environment, `roar` can walk both lineage DAGs and diff them structurally — it isn't guessing from filenames or timestamps.

## What you can compare

Either side of the diff can be any reference that resolves to a point in the lineage:

| Reference | Example |
|---|---|
| File path | `./model.pkl`, `./output/metrics.json` |
| Artifact hash | `b61ba24d…` (resolves locally; can fall back to GLaaS — see below) |
| Step ref | `@5`, `@7` |
| Job UID | `017a0de0` |
| Session | `session:current`, `session:<hash>` |

```bash
roar diff @5 @7                              # two steps in the current session
roar diff ./model.pkl deadbeefcafebabe       # a local file vs. an artifact by hash
roar diff session:current session:<hash>     # a whole pipeline vs. an earlier run
```

A bare artifact hash resolves locally first and can fall back to GLaaS when `glaas.query_nonlocal_ids_on_glaas = true`, so you can diff against a run you never had locally.

## Reading the output

`roar diff` groups differences into categories and leads with a root-cause line. A representative diff after changing an input file:

```
Diff: metrics.json vs metrics.json
  A: 8e4607689a92eaa7...
  B: 60158676b881ab21...

ROOT CAUSE: Step @1: input 'raw.csv' has different content

INPUTS (root artifacts differ)
  A only: raw.csv  14a2d45d722f...
  B only: raw.csv  d2315ecb74d9...

CODE
  Step @1: code changed   A: 8f3eff4a   B: ad5a7476 [0.85]

UNCHANGED
  environment (same packages)
  parameters (same arguments)
```

The categories `roar` divides divergence into:

- **Inputs** — root (unsourced) artifacts whose content hash differs. A different dataset or a hand-edited config lands here.
- **Code** — the git commit recorded for a step differs. Note this is **commit-level**: two runs on different commits are reported as "code changed" even if the specific script for that step was byte-identical between them.
- **Parameters** — the command-line arguments to a step differ.
- **Environment** — the captured interpreter or package set differs.
- **Pipeline** — the DAG shape itself differs (a step added, removed, or rewired).

Each reported difference carries an impact score; `roar` ranks by it so the change most likely to explain the divergence surfaces first as the `ROOT CAUSE`.

## Options

```bash
roar diff @5 @7 --json          # machine-readable output for scripts / CI
roar diff @5 @7 --depth 3       # cap how far up the lineage DAG to walk
```

| Flag | Effect |
|---|---|
| `--json` | Emit the full structured diff instead of the rendered report. |
| `--depth <n>` | Limit lineage traversal depth (useful on deep pipelines). |

## When to reach for it

- **A run regressed.** Diff the bad output against the last good one; the root-cause line usually names the changed input, commit, or argument directly.
- **"It works on my machine."** Diff your session against a teammate's registered session to surface an environment or code drift.
- **Auditing a promotion.** Before shipping `model-v2`, diff it against `model-v1` to confirm *only* the things you intended to change actually changed.
