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

# Attach evidence

> Upload a screenshot, recording, report, log or JUnit test results as proof that a change works, anchored where a reviewer will look.

An [artifact](/concepts#how-the-work-is-judged) is a file that proves something about a change. It appears on the work item's page and in the pull request's evidence comment.

## Emit an artifact

Capture the state first, then emit it:

```bash theme={"system"}
outerlayer emit artifact ./after.png --caption "The settings page renders the new toggle"
```

Write the caption as one present-tense sentence with no secrets. The file's extension sets its kind; you cannot set it yourself:

| File type | Kind |
| - | - |
| `png`, `jpg`, `jpeg` | screenshot |
| `webm`, `mp4` | video |
| `html`, `htm`, `pdf` | report |
| `txt`, `log` | log |
| `xml` with a `<testsuites>` or `<testsuite>` root | test |
| any other `xml`, and anything else | file |

Keep files small: video is the kind most likely to hit the size cap. The caps and every flag rule are in [`outerlayer emit artifact`](/reference/cli-emit#outerlayer-emit-artifact).

## Where it lands

**Inside a recorded session**, the file is queued, and the next `outerlayer sync` uploads it with the session. A session not launched with `OUTERLAYER_WORK` refuses the emit, because nothing it produces may leave the machine.

**Outside a session**, it uploads at once. It attaches to the first of these that exists:

1. The pull request `--pr` names.
2. In GitHub Actions, the pull request the run is for.
3. The current git checkout.

With nothing to attach to, the command refuses. On other CI systems, pass `--pr`.

## Bind it to a criterion

First record the item's criteria with [`outerlayer emit criteria`](/reference/cli-emit#outerlayer-emit-criteria). Then pass one of their ids to `--for`, and the **Criteria** tab shows the artifact on that row:

```bash theme={"system"}
outerlayer emit artifact ./after.png --caption "…" --for LOGIN-01
```

The artifact's kind must match the proof the criterion declares. A screenshot never satisfies a criterion that asks for a video.

## Prove a criterion with test results

A criterion can declare `"proof": "test"`. Bind JUnit XML results to it with `--for`. Vitest, Jest, pytest, Go (through `gotestsum`), JUnit and RSpec can all write that format.

```bash theme={"system"}
outerlayer emit artifact results.xml --caption "Auth tests pass" --for AC-724-01
```

Every test in the file is bound. To bind only some, name each one with `--test`. Add `=<path>:<line>` to say where a test is written:

```bash theme={"system"}
outerlayer emit artifact results.xml --caption "Expired links are refused" --for AC-724-01 \
  --test "rejects an expired link=src/auth/link.test.ts:42"
```

The rules for `--test`, and for which XML files are accepted, are in [`outerlayer emit artifact`](/reference/cli-emit#outerlayer-emit-artifact).

A test's location comes from the testcase's own `file` and `line` attributes first, then from `--test`. A test with neither shows by name, with no link. Vitest and jest-junit write `file` only with their `addFileAttribute` option. pytest writes it only under `junit_family=xunit1`.

The criterion is proven when every bound test passed, at least one passed, and no test you named with `--test` was skipped. A failed or errored test leaves it unproven. A skipped test you did not name neither proves nor fails it. When you emit again after a fix, retire the old results with `--replaces`, or the old failure still counts.

Results prove a criterion only at the head commit of a pull request linked to the item. In GitHub Actions, the command records the pull request's head commit, not the merge commit the checkout holds. On other CI, check out the pull request's head commit before you run the tests. Results from an earlier commit show as out of date on the Criteria tab and prove nothing until you emit again at the head.

To require that results came from CI, set [`criteria.test_proof: ci`](/policy-and-validators#the-policy-file) in the policy file.

On the Criteria tab, each bound test links to its file and line at the commit that ran it. A failed test is marked as failed.

## Replace an earlier artifact

The command prints an id. Pass it to `--replaces` to correct that artifact:

```bash theme={"system"}
outerlayer emit artifact ./after-v2.png --caption "…" --replaces <id>
```

A retired artifact that had uploaded is hidden as superseded, but keeps its file and link. One still queued never uploads. A failed emit retires nothing. To retire several at once, see [`--replaces`](/reference/cli-emit#outerlayer-emit-artifact).

## Find the artifact afterwards

Once it uploads, the artifact appears on the work item's page:

* on its criterion's row on **Criteria**, when it is bound to one;
* beside the check that names it on **Checks**;
* otherwise under **Other artifacts** on **Checks**.

Its link also appears in the pull request's evidence comment, if there is one. Copy the link from either. The printed id is not part of the link.

## Permissions

The caller needs **Emit evidence**. See [API keys](/api-keys).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.