Explainer

Evidence: what gets captured and why

Nine artifact kinds, hashed, tied to one result and one commit — and identical whether a machine or a person produced the run.

Applies toPlans:FreeProBusinessEnterpriseRoles:OwnerAdminDeveloperQaViewerWhere:Web appExtensionMCP

The nine kinds

KindTypical sourceWhat it answers
SCREENSHOTPlaywright on failure, or one per manual stepWhat was on screen at that moment
VIDEOPlaywright video, device-farm recordingWhat the whole run looked like
TRACEPlaywright trace.zipEvery action, network call and DOM snapshot, replayable in the trace viewer
HARPlaywright or a browser exportFull request and response timing
CONSOLE_LOGRunner stdout, or the extensionWhat the app logged, errors first
NETWORK_LOGRunner or the extensionWhich requests failed and with what status
RRWEBThe extension, the widget, a captureA scrubbable DOM replay of the session
JUNIT_JSONThe reporter's own machine-readable outputThe raw run as the runner saw it
FILEAnything else you attachWhatever the case needs

How an artifact gets stored

  1. The producer asks for an evidence slot for one result and step, naming the artifact and its size.

  2. BugMojo checks the caps and returns a presigned upload URL. Over-cap artifacts are refused here, before a large upload is wasted.

  3. The producer uploads the bytes directly to storage — they never pass through the API.

  4. The producer finalizes the slot with the artifact's SHA-256, which is stored on the evidence row alongside its kind, size, step and provenance.

Because the hash is recorded at finalize time, the evidence row is a claim about specific bytes. A file swapped afterwards stops matching what the result said it attached — which is what makes a signed report's evidence section worth anything.

Provenance: who produced it

Every row records the producer, not just the artifact. That is how a report can say a case was executed by a person and prove it, and how an agent-driven browsing session is distinguishable from a human one. The run itself carries more: the commit SHA, the deployed URL, the environment and the runner kind — local, CI, hosted, extension or mobile.

Caps and what happens at the edges

There is a maximum size per artifact, a maximum total per result and a maximum number of artifacts per result. The extension applies the same constants locally, so it drops an over-cap artifact with a visible warning rather than making a tester wait for an upload the server will reject.

Nothing in this path is fatal. An unmatched test, an over-cap trace or unconfigured storage becomes a warning on the ingest response — never an exception that turns a green test run red.

Reading evidence back

Open a run in Regression and choose a result: the evidence viewer plays the video, opens the trace, renders the console and network logs and scrubs the replay. Artifact URLs handed to agents and reports are presigned and expire, so a link that leaks stops working rather than exposing the artifact forever.

text
record_run_results   ingest a run; returns a result id per test and an
                     evidence slot per artifact
upload_evidence      presigned PUT for one artifact, then finalize with sha256

Common questions

Is evidence stored for manual runs too?

Yes, through the same code path. A screenshot a tester took by hand is the same kind of row as one Playwright took in CI — same hashing, caps and provenance.

How long is evidence kept?

Retention follows your plan: 30 days on Free, 90 on Pro, 365 on Team. Retention is what we meter, because storage is what actually costs money.

What stops an artifact being swapped later?

Each artifact is finalized with its SHA-256. The hash is stored on the evidence row, so a substituted file no longer matches what the result recorded.

Will a huge trace fail my test run?

No. An over-cap artifact is reported as a warning and skipped. Nothing in the evidence path is allowed to turn a passing run red.

Was this helpful?
Updated Sep 19, 2026 · Still stuck? Contact support

Related articles