Evidence Bundle v1 Contract (2025-11-19)

Scope

Frozen contract for Evidence Bundle v1 covering AdvisoryAI/Concelier/Excititor evidence exports used by air-gap and attestation flows.

Artefact layout

manifest.json fields

{
  "bundle_id": "evidence-bundle-m0",
  "version": "1.0.0",
  "created": "2025-11-19T00:00:00Z",
  "tenant": "demo",
  "scope": "vex",
  "inputs": ["sha256:payload-obs", "sha256:payload-linksets"],
  "aoc": {"guardrails": true, "details": ["schema:frozen:1.0", "limits:chunk:max=2000"]}
}

observations.ndjson (sample record)

{"observationId":"obs-ossl-001","advisoryId":"CVE-2024-1234","component":"pkg:deb/openssl@1.1.1w","source":"nvd","fetchedAt":"2025-11-18T12:00:00Z"}

linksets.ndjson (sample record)

{"linksetId":"lnm-ossl-001","advisoryId":"CVE-2024-1234","components":["pkg:deb/openssl@1.1.1w"],"normalized":true,"createdAt":"2025-11-18T12:05:00Z"}

transparency.json (optional)

{"rekor_uuid": null, "skip_reason": "offline"}

Determinism rules

Example bundle (sample)

Attestation linkage

Append-only persistence (SPRINT_20260501_050)

The on-disk bundle metadata schema gained two fields and lost the Pending/Assembling/Failed persisted statuses:

Persisted status is restricted to Sealed (3) or Archived (5). Pending, Assembling, and Failed exist purely as in-memory states inside EvidenceSnapshotService while the manifest is being built; a failed seal writes nothing to the database.

Retention: expires_at is set at seal time and is immutable. Holds extend retention via the evidence_holds table; effective retention is MAX(bundle.expires_at, MAX(active hold.expires_at)).

Change log