Language-agnostic reference for the EPI container format, cryptographic protocol, and verification model. Anyone may implement .epi producers and consumers.
Read the full specification as a Markdown file
Formal JSON Schema (draft 2020-12) for all core formats
Conformance vectors from real .epi containers
The EPI format defines a portable, self-contained, cryptographically sealed container for AI agent execution evidence. A .epi file is a polyglot — valid HTML for browser-based forensic inspection AND a binary envelope carrying a ZIP payload — enabling zero-install verification by regulators, auditors, and courts.
Reference Implementation: epi-recorder (Python, MIT). This specification is an open standard. The .epi file format carries no intellectual property restrictions.
A .epi file begins with a 128-byte binary header, followed by an HTML viewer and ZIP payload.
| Offset | Size | Field | Value / Description |
|---|---|---|---|
| 0 | 4 | magic | 0x3C 0x21 0x2D 0x2D (ASCII <!--) |
| 4 | 1 | version | 0x02 |
| 5 | 1 | flags | Reserved. MUST be 0x00 |
| 6 | 2 | reserved | Reserved. MUST be 0x0000 |
| 8 | 8 | payload_length | ZIP payload byte length (little-endian uint64) |
| 16 | 16 | payload_uuid | UUID v4 (16 raw bytes) |
| 32 | 8 | created_at | Unix epoch microseconds (little-endian uint64) |
| 40 | 32 | payload_sha256 | SHA-256 of ZIP payload (32 raw bytes) |
| 72 | 56 | reserved | Reserved. MUST be zero |
<!-- EPI_ZIP_PAYLOAD_START -->
Bytes between header and marker = embedded viewer. Bytes after marker = ZIP payload.
| Container | MIME |
|---|---|
| Envelope v2 | application/vnd.epi |
| Legacy ZIP | application/vnd.epi+zip |
| SCITT payload | application/vnd.epi.manifest+hash |
First 4 bytes: 0x3C 0x21 0x2D 0x2D → envelope-v2. 0x45 0x50 0x49 0x31 → legacy-zip. Otherwise → invalid.
| File | Purpose | Schema |
|---|---|---|
mimetype | First entry, stored uncompressed. Contains application/vnd.epi+zip | Plain text |
manifest.json | Signed manifest — root of trust | JSON Schema |
steps.jsonl | Immutable execution timeline (NDJSON) | JSON Schema |
environment.json | Runtime environment snapshot | JSON Schema |
analysis.json | 9-pass deterministic fault analysis | JSON Schema |
policy.json | Governance rulebook | JSON Schema |
viewer.html | Self-contained browser forensic viewer | N/A |
VERIFY.txt | Offline verification instructions for auditors | Plain text |
| File | Purpose |
|---|---|
review.json | Human review addendum (NOT in file_manifest) |
review_index.json | Multi-reviewer index |
policy_evaluation.json | Policy rule evaluation results |
stdout.log | Captured stdout |
stderr.log | Captured stderr |
artifacts/scitt/statement.cbor | SCITT COSE_Sign1 |
artifacts/scitt/receipt.cbor | SCITT Merkle receipt |
artifacts/sbom/ | CycloneDX SBOM |
artifacts/agt_export.json | AGT export |
Root of trust. Every file's SHA-256 hash is recorded in file_manifest.
| Field | Type | Description |
|---|---|---|
spec_version | string | EPI version (auto-populated from package, e.g. "4.2.0") |
workflow_id | UUID | Unique execution identifier (auto-generated UUID v4) |
created_at | datetime | UTC ISO 8601 (auto-set to current time): YYYY-MM-DDTHH:MM:SSZ |
file_manifest | object | File paths mapped to 64-char hex SHA-256 hashes |
| Field | Type | Description |
|---|---|---|
cli_command | string | CLI invocation |
public_key | string | 64-char hex Ed25519 (32 raw bytes) |
signature | string | ed25519:<key_id>:<sig_hex> |
container_format | string | "legacy-zip" or "envelope-v2" |
analysis_status | string | "complete", "skipped", "error" |
goal | string | Workflow objective |
metrics | object | Key-value metrics |
source | object | {integration, framework, agent} |
total_steps | integer | Total recorded steps |
tags | array | Categorization tags |
governance | object | DID, SCITT, trust score |
trust | object | Cryptographic verification state |
policy | object | Policy evaluation outcome |
signature, governance, trust (manifest); source_type (step)YYYY-MM-DDTHH:MM:SSZ (strip microseconds)sort_keys=True, separators=(",", ":"), ensure_ascii=TrueConformance: Two implementations computing the canonical hash of identical data MUST produce identical hex strings.
SHA-256(hex_public_key)[:16]ed25519:<key_id>:<128-hex-sig>Key ID is cryptographically bound to the public key — prevents key substitution attacks.
: into 3 partsed25519SHA-256(hex_public_key)[:16]Each step in steps.jsonl contains prev_hash:
prev_hash: nullprev_hash = canonical hash of step N-1Append-only, hash-linked timeline. Any insertion, deletion, or reorder breaks the chain.
NDJSON: one JSON object per line.
| Field | Type | Required | Description |
|---|---|---|---|
index | integer | Yes | Monotonically increasing, 0-indexed |
kind | string | Yes | Step type identifier |
timestamp | datetime | Auto | UTC ISO 8601 (auto-populated) |
content | object | Auto | Step-specific payload (defaults to empty object) |
prev_hash | string|null | Auto | SHA-256 of previous step (auto-computed) |
trace_id | string | No | W3C trace identifier |
span_id | string | No | W3C span identifier |
governance | object | No | Step-level governance |
source_type | string | No | "user"|"tool"|"reasoning"|"system" |
7 independent checks, in order:
file_manifest entries match SHA-256; no extra filesprev_hash links intact; indices monotonic; timestamps non-decreasingtotal_steps matches line countmimetype = application/vnd.epi+zip| Level | Integrity | Signature | Identity | Meaning |
|---|---|---|---|---|
| HIGH | Pass | Valid | Known | Signer verified in trust registry |
| MEDIUM | Pass | Valid | Unknown | SCITT-anchored |
| LOW | Pass | Valid | Unknown | Valid sig, unverified identity |
| NONE | Pass | None | — | Unsigned artifact |
| TAMPERED | Fail | Invalid | — | Modified or corrupted |
| Threat | Mitigation |
|---|---|
| Post-seal tampering | SHA-256 file manifest + Ed25519 signature |
| Evidence replay | Unique workflow_id + created_at |
| Secret leakage | HMAC-SHA256 redaction |
| Signature spoofing | Key ID bound to public key |
| Step manipulation | prev_hash chain |
| File injection | Integrity rejects extras |
| Visual deception | viewer.html in file_manifest |
| Key compromise | Revocation files in trust registry |
EPI is a post-execution evidence system. It records what happened — it does not prevent unauthorized access at runtime. For enforcement, use EPI_ENFORCE=1. File-level encryption is not specified; implementers MAY layer on top.
An implementation is conformant if:
.epi files passing the 7-pass verification procedureprev_hash chains| Resource | Location |
|---|---|
| Manifest Schema | manifest.schema.json |
| Step Schema | step.schema.json |
| Environment Schema | environment.schema.json |
| Analysis Schema | analysis.schema.json |
| Policy Schema | policy.schema.json |
| Test Vectors | test-vectors.json |
.epi file format carries no intellectual property restrictions. Anyone may implement producers and consumers conforming to this specification. Contributions via GitHub Issues.