evidence-cli v0.1.7 · contract 0.1
.evidence
Open format · Apache-2.0 · framework-agnostic

One shape for what a test run produced

A browser agent, a Playwright suite, a Jest run, an API check — whatever made it, the .evidence pack is one readable, sealable format. Understandable by a CI dashboard, an auditor, or a human, without knowing the framework that wrote it.

$ npm install -g @testmuai/evidence-cli
kane-cli already emits it · point any of these at the same shape
Playwright · Cypress · Selenium · Jest · Vitest · API suites · Browser & mobile agents

The problem → the pack

Every framework reports differently. Read one shape instead.

A pack is a <name>.evidence/ directory (it zips to a <name>.evidence file), anchored by a top-level run.yaml. At L0 — the minimal profile — only three artifacts are load-bearing.

evidence-cli knows nothing about any framework's definition format. It references and hashes the definition; it never parses it. The format scales by adding optional files and profiles — never by rewriting the core.

run identity lifecycle derived totals hashed definitions
<name>.evidence/
  run.yaml                 # required — manifest anchor
  tests/<id>/
    <definition>           # required, OPAQUE — the framework's own artifact
                            #   (a Markdown spec, *.spec.ts, an API suite, …)
    result.yaml             # required — structured per-step outcomes

Try it yourself

Download a sample pack, drop it in the viewer

Grab the real .evidence pack that kane-cli produced from a browser run — a 27-step, nested-iframe e-commerce checkout — and drop it straight into the viewer at evidence.lambdatest.com to see it rendered.

⬇ Download sample .evidence (2.8 MB) then drag it into the viewer ↓
evidence.lambdatest.com Open in a new tab ↗

The sample is a real pack — 27 steps, 27 screenshots, a 110-request HAR. Drop it into the viewer above, or open the viewer full-screen ↗.

Reference producer

kane-cli already speaks this format

The pack above wasn't made for a demo — kane-cli emits it on every run. It's the worked example: run.yaml, result.yaml, the opaque definition, and the L1 artifacts, with a walkthrough of who writes what.

Point your own framework — Playwright, Jest, an API suite, anything — at the example and emit the same shape. There's no viewer to build: any pack that conforms loads in evidence.lambdatest.com, exactly like this one.

Profiles — a ladder on one 0.1 contract

Start minimal. Add layers, never rewrites.

A profile only adds requirements — it never changes the version. Only a breaking change to an existing meaning bumps evidence (0.1 → 0.2).

L0 the neutral core

Framework-agnostic minimum

The smallest thing that's still complete — three load-bearing artifacts.

  • run.yaml — run identity, lifecycle, derived totals
  • definition — the framework's own opaque artifact, hashed
  • result.yaml — structured per-step outcomes
L1 purely additive

L0 + captured artifacts

Everything in L0, plus the evidence the run actually captured.

  • execution logs — per-test, with metadata
  • step screenshots + a global coverage directory
  • video — optional

Two ways to use it

A library and a CLI, same core

validate checks a pack against a profile; finalize rolls up totals, hashes definitions, and seals the directory into a flat, range-addressable .evidence zip — atomically.

library · TypeScript
import { validate, finalize } from "@testmuai/evidence-cli";

// Validate a directory or a sealed .evidence zip.
const report = await validate("my-run.evidence", { profile: "L1" });
if (!report.valid) {
  for (const d of report.diagnostics)
    console.error(`${d.severity} ${d.location}: ${d.message}`);
}

// Seal a live directory into a sealed .evidence zip.
const { totals, sealedPath } = await finalize("my-run.evidence", {
  endedAt: new Date().toISOString(),
});
CLI · shell
# check a directory OR a sealed .evidence zip
evidence validate my-run.evidence --profile L0

# L1 = L0 + the captured-artifact layer
evidence validate my-run.evidence --profile L1

# roll up totals, hash definitions, seal → .evidence
evidence finalize my-run.evidence/

# machine-readable report
evidence validate my-run.evidence --json

exit codes  0 valid  ·  1 invalid  ·  2 usage error