Evidence Bundle Anatomy
An evidence bundle is a portable package containing all artifacts required for offline verification: the policy artifact, signed receipts, continuity chain state, and a manifest that cryptographically binds them together.
What are the core components of an evidence bundle?
Every evidence bundle contains four essential components that work together to provide complete verification capability without network access.
1. Bundle Manifest
The manifest lists every file in the bundle with its SHA-256 checksum and size. Verification starts here: if any file checksum fails, the bundle is rejected.
2. Policy Artifact
The signed governance object that defined the rules. Contains selection rules, enforcement mapping, validity window, and issuer signature.
3. Receipt Chain
The sequence of signed receipts documenting every governance decision. Each receipt links to the previous via prev_hash, forming a tamper-evident chain.
4. Chain Head
The final state reference containing the last receipt hash, total count, and run_id. Verifiers confirm the chain ends at the declared head.
What is the bundle directory structure?
The bundle uses a deterministic directory layout. Paths are POSIX-style regardless of the originating platform. File ordering in the ZIP is lexicographic.
evidence-bundle.zip/ ├── bundle_manifest.json # File checksums + metadata ├── policy/ │ └── policy_artifact.json # Signed governance rules ├── subject/ │ └── subject_manifest.json # Baseline measurements ├── receipts/ │ ├── 0001.json # First receipt │ ├── 0002.json # Second receipt │ ├── ... │ ├── 00NN.json # Last receipt │ └── chain_head.json # Chain state summary ├── verifier/ │ ├── verify.js # Offline verifier │ └── VERSION.txt # Verifier version └── README.txt # Verification instructions
What does the bundle manifest contain?
The bundle manifest is the root of trust for the package. It binds all components together with cryptographic checksums.
{
"bundle_v": "1",
"created_at": "2024-01-15T10:30:00Z",
"policy_id": "sha256:a1b2c3...",
"run_id": "run_abc123",
"receipt_count": 42,
"chain_head_hash": "sha256:xyz789...",
"files": [
{
"path": "policy/policy_artifact.json",
"sha256": "abc123...",
"size_bytes": 2048
},
{
"path": "receipts/0001.json",
"sha256": "def456...",
"size_bytes": 512
}
// ... all files listed
],
"verifier": {
"name": "attested-verifier",
"version": "1.0.0",
"entrypoint": "verifier/verify.js"
},
"optional": {
"merkle": "SKIPPED",
"anchor": "SKIPPED"
}
}Why is determinism critical for bundles?
Two systems generating a bundle from the same inputs must produce byte-identical output. This ensures any verifier will produce the same verdict for the same bundle, regardless of where or when verification occurs.
- ■Reproducibility: Bundle regeneration produces identical bytes (important for audits)
- ■Comparability: Diff two bundles to identify exact changes between runs
- ■Archival: Store bundles with confidence that verification will work identically in the future
Frequently asked questions
Can I add custom files to a bundle?
The verifier only validates files declared in the manifest. Adding undeclared files won't break verification, but they won't be covered by the integrity guarantees. Some implementations reject bundles with undeclared files.
What if the embedded verifier is malicious?
Use a trusted verifier from a known source, not the embedded one. The embedded verifier is a convenience for quick validation. For high-assurance scenarios, use your own audited verifier binary.
How large can a bundle be?
Bundles scale with receipt count. A typical run with 1000 receipts produces a bundle under 5MB. Very long runs should use checkpoint segmentation to keep bundle size manageable.