Evidence Ledger - Canonical Implementation Specification
Status: Authoritative
Audience: Backend engineering
Scope: Evidence (E) as a first-class primitive of the Execution Ledger
Supersedes:
- Implementation Spec - Evidence Evaluations (E)
- Evidence Ledger Implementation Plan (draft)
This document defines what Evidence is, how it behaves, and how it must be implemented within Evalium's defensibility-first architecture.
1. Evidence Doctrine (Tier-1 Invariant)
Evidence is a substantiating ledger event - not a file, not a question type.
Evidence exists to answer one question under scrutiny:
"Can you prove this, later, to someone hostile?"
To support both SMB workflows and high-rigor enterprise use cases, Evidence is governed by the following non-negotiable principles.
1.1 Core Invariants
- Evidence is a ledger primitive, not a UI feature.
- Evidence is append-only; decisions are recorded as ledger events.
- Evidence rigor is policy-driven, not hard-coded.
- Evidence may enter the system through multiple entry points, but MUST converge into a single Evidence Core model.
- Evidence is context-bound and non-reusable across unrelated executions.
2. Evidence Core Contract (Shared Data Model)
All evidence records, regardless of how they are captured, MUST conform to the same durable contract.
2.1 Evidence Core Components
| Component | Description | Requirement |
|---|---|---|
| Asset Metadata | UUID, storage reference, SHA-256 hash, media type | Mandatory |
| Capture Context | captured_at, actor_id, device_id; optional GPS, network time | Policy-driven |
| Storage Tier | HOT / ARCHIVED / DELETED for lifecycle awareness | Implemented |
| Association Link | Exactly ONE of: submission_id OR submission_item_id | Mandatory |
| Decision Ledger | Append-only review events (approve / reject / void) | Mandatory |
Rule: There must never be an evidence record without a durable association to execution truth.
3. Evidence Entry Points and Usage Patterns
Evidence supports three entry patterns, all mapping to the same core model.
3.1 Standalone Evidence (Primary)
Purpose: Evidence is the task.
Examples:
- Upload incident photos
- Submit compliance documentation
- Provide video proof of work
Characteristics
| Attribute | Behaviour |
|---|---|
| Association | submission_id |
| Items | Zero items allowed |
| Review | Policy-driven |
| Ledger | Evidence metadata + decision events |
| Programme Role | Gate / deliverable / milestone |
This is the fast path for operational and compliance workflows.
3.2 Inline Evidence (Supporting)
Purpose: Evidence supports a specific item.
Examples:
- "Upload a photo of the setup"
- "Attach supporting documentation"
Characteristics
| Attribute | Behaviour |
|---|---|
| Association | submission_item_id |
| Lifecycle | Bound to parent submission |
| Review | Independent ledger events |
| Analytics | Item-level (future) |
Inline evidence is supporting, not the assessment itself.
3.3 Mixed Evidence (Answer + Proof)
Purpose: Combine answer and evidence in one execution step.
Examples:
- "Answer 'Safe' AND upload a photo"
- "Confirm inspection AND attach certificate"
Characteristics
- Same submission
- Same item
- Separate evidence ledger events
4. Evidence Lifecycle and Ledger Events
4.1 Ledger-First State Model
Evidence does not rely on mutable status fields as truth.
All state is derived from append-only ledger events.
4.2 Canonical Evidence Events
| Event | Meaning |
|---|---|
evidence.pending | Evidence registered |
evidence.file.attached | Asset ingested |
evidence.approved | Accepted |
evidence.rejected | Rejected |
evidence.voided | Invalidated |
Event payload MUST include:
- Association link (submission OR item)
- Actor ID
- Occurred timestamp
- Verification context (if present)
5. Review, Approval and Verification
5.1 Review Is a Ledger Action
Approving or rejecting evidence is itself an execution event and MUST be recorded immutably.
5.2 Capability-Based Gating
Verification MUST be enforced via capabilities, not roles.
| Capability | Purpose |
|---|---|
evidence.review | View + comment |
evidence.verify | Approve / reject |
evidence.void | Invalidate |
5.3 Step-Up Identity (Policy-Driven)
- Step-up identity is REQUIRED when policy demands high rigor (L4).
- Step-up proof metadata MUST be recorded in the ledger event.
- L4 is supported everywhere, but enforced nowhere unless policy requires it.
6. Capture and Ingestion Constraints (Non-Functional)
These constraints influence backend design even if enforced in the UI.
6.1 Capture Ergonomics
- Mobile-first capture
- Camera-first flows
- Multi-shot support
- Immediate upload confirmation
6.2 File Handling
| Type | Notes |
|---|---|
| Images | JPG / PNG |
| Video | MP4 |
| Documents | |
| Other | Policy-configurable |
Large assets MUST support resumable uploads.
7. Audit Metadata and Forensic Guarantees
7.1 Mandatory Metadata
Captured at ingestion:
- Server receipt timestamp (authoritative)
- Submitting user ID
- Submission / item ID
- Evaluation snapshot ID
- SHA-256 file hash
Ingestion requirement
- Hash MUST be computed at upload time and recorded before the ledger write is final.
- Evidence without an ingestion-time hash is invalid and MUST be rejected.
7.2 Optional Metadata (Policy-Driven)
- EXIF capture time
- GPS coordinates
- Device / app instance ID
7.3 Originals vs Derivatives
- Original binary is never modified
- Derivatives allowed (thumbnails, previews)
- Hash always refers to original asset
7.4 Storage Lifecycle (Zombie Object Protection)
Evidence metadata must remain synchronized with object storage lifecycle to avoid "missing artefact" ambiguity.
Planned behavior
- Evidence metadata includes a
storage_tierfield withHOT,ARCHIVED, orDELETED. - Default
storage_tierisHOTat ingestion. - If the object is archived or deleted externally, the ledger metadata MUST reflect that state.
- UI should show a retrieval/restore affordance for
ARCHIVEDrather than a broken link.
8. Offline Evidence Capture (Summary)
Evidence supports offline capture by default.
Rules
- Assets stored locally when offline
- Marked
pending_sync - Submission completion blocked until server receipt timestamps assigned
- Server timestamps always authoritative
Full behaviour defined in:
offline-delivery-implementation.md
9. Findings and Follow-Ups (Adjacent System)
Findings are real-world issues surfaced by evidence.
- Findings are not result remediation.
- Findings may:
- Block programme progression
- Require follow-up evidence
- Follow-up creates a new submission
- Original evidence remains immutable
10. Security, Visibility and Compliance
- Evidence assets are tenant-isolated
- Access is submission-scoped
- External stakeholders see approved evidence only
- GDPR workflows apply to asset references, not ledger truth
- Exports MUST include verification links back to ledger (Glass Box principle)
11. Phase Plan
Phase 0 - Integrity and Storage Lifecycle (In Progress)
- P0: ingestion-time hashing (SHA-256) enforced before ledger write. Implemented
- P1: add
storage_tierto evidence metadata (defaultHOT). Implemented - P2: lifecycle worker to update
storage_tierfrom storage events. Planned
Phase 1 - Standalone Evidence (Implemented)
- Zero-item submissions supported
- Evidence metadata + decisions
- Policy-driven verification
- Tests:
TestStandaloneEvidenceMetadataAndDecisionbackend/tests/evidence_standalone.sh
Phase 2 - Inline Evidence (Implemented)
- Evidence linked to
submission_item_id - Item-level visibility
- Tests:
TestInlineEvidenceMetadataAndDecisionbackend/tests/evidence_inline.sh
Phase 3 - Mixed Evidence (Implemented)
- Answer + evidence in same item
- Tests:
TestMixedEvidenceWithAnswerbackend/tests/evidence_mixed.sh
12. Definition of Done (Any Phase)
To ship any Evidence phase:
- Evidence Core respected
- Ledger events recorded
- Policy-driven verification enforced
- Step-up tested (negative + positive)
- Go tests + smoke tests added
- Docs updated:
FOUNDATION.mdarchitectureKOE-model.mdimplementation-status-feature-matrix.md
13. Explicit Non-Goals
This implementation does not include:
- Global asset libraries
- Evidence reuse across contexts
- Collaborative editing
- File version comparison
- Inline annotation
These are intentionally excluded to preserve defensibility.
Final Statement
Evidence is not supporting data. Evidence is execution truth.
Every decision in this document exists to ensure that truth survives time, scrutiny, and error - without blocking legitimate low-risk workflows.