Evidence Link logo: the letter E inside a blue diamond

How Evidence Link works,
shown, not promised.

This page walks the whole system as specified in the Evidence Link implementation brief and as built: the architecture, how it runs today under the Outfielder Accessibility System, the cryptography, the internal API the Outfielder integration connects through, and an honest status line for every phase of the brief.

CURRENT PHASE: OUTFIELDER INTEGRATION & VALIDATION
Evidence Link is being developed and validated through its first production integration with Outfielder. The generic architecture is intact, but external API access is not currently offered, and no outside tenants are being onboarded.

The architecture

Three products, three strict boundaries. Outfielder does the accessibility work. AAccessibility publishes status, references, and a reporting channel, nothing more. Evidence Link preserves and connects the private evidence underneath both.

Outfielderthe work: assessments, fixes, verification, the private Activity Log
↓ events + evidence references
Evidence Link APIapi.evidence.li/v1, tenant-token authenticated
Event ledger+Artifact store + SHA-256 manifests+Signed hash-chain checkpoints + Bitcoin timestamp anchoring
State snapshots + change engine+Evidence graph + attestations+Verify + Case File export
↓ status only, through an allowlist
AAccessibility.comthe public record: status, standards, barrier reporting. Never findings, evidence, or hashes.
Downtime degrades safely. The source system writes its own durable record first. If Evidence Link is unreachable, events queue and seal when it returns; until the seal lands, nothing claims the event was cryptographically secured.

Under the Accessibility System, end to end

This is the live flow on Outfielder today. A small sealer mirrors the Outfielder record into Evidence Link every five minutes, so the client experience never changes while the evidence layer accumulates underneath it.

A business starts an assessment

The request, the email confirmation, and the record page publication are sealed as administrative events, with the submission metadata preserved. Publication is never treated as verification.

The assessment completes

The results are preserved as an artifact with a SHA-256 manifest, attached to the assessment event, together with the test scope, and a state snapshot of what was found.

The web team fixes

Each fix is sealed as a remediation event, linked to the assessment it answers with a corrects relationship, and marked submitted, not verified.

Outfielder verifies

A verification event plus a scoped attestation (who checked, by what method, what scope, what outcome) updates the derived status by deterministic rules, and a new state snapshot makes the before-and-after diff computable.

The public sees status only

The record page at AAccessibility shows the approved status and dates. No findings, no evidence identifiers, no hashes ever cross to the public side.

The evidence downloads in one click

The owner downloads the Case File from their Outfielder dashboard: originals, the full timeline, snapshots and diffs, attestations, the signed checkpoint, and an offline verifier. Every export is audit-logged.

The cryptography, briefly

Method 1

SHA-256 + canonical manifests

Artifacts are stored under their own SHA-256 digest. Each event carries a manifest serialized as canonical JSON, so identical content always hashes identically.

Method 2

Hash chains

Every event hash covers the previous event hash for its subject, with sequence numbers. Gaps, reordering, and edits all break the chain at a findable point.

Method 3

Signed checkpoints

Chain heads are signed with Ed25519 and checkpoint copies are kept outside the database, which is what detects wholesale history replacement. Every checkpoint hash is also submitted to the Bitcoin blockchain through OpenTimestamps, so a public ledger we do not control witnesses when each checkpoint existed.

Method 4

The state engine

For a fixed set of checks, a snapshot is a bitset: found 110101, later 000100. XOR gives 110001, the changed positions; comparing before and after gives the direction. Not-tested and not-applicable are tracked separately, never read as passed.

What cryptography does not prove. Integrity proves the sealed record was not altered after sealing. It does not prove the original observation was accurate, who physically performed an action, or a time beyond the server receipt time, which is why occurred and recorded times are both kept, and why attestations carry method and scope.

Three layers

Evidence Link is built in three independent layers: preservation, structure, and intelligence. In the current phase all three run inside the Outfielder integration only, and the evidence layer never depends on the AI layer.

Record · Live in the Outfielder integration

Preserve what happened

Evidence capture, SHA-256 hashing, hash chaining, signed checkpoints, Bitcoin timestamp anchoring, and Case File exports. Turn an existing Activity Log into verifiable evidence without changing your application.

Connect · Live in the Outfielder integration

Understand how records relate

Versioned state snapshots with before and after diffs, relationships between events (corrects, verifies, supersedes, recurs), and scoped attestations. Recurring problems become visible as connected history, not scattered entries.

Intelligence · In design

Explain the history

Read-only, citation-bound AI interpretation over the authorized evidence: chronologies, pattern detection, gap analysis. Our OpenAI integration is the default when it ships, and bring-your-own-AI will work through the same permissioned history APIs when the layer ships. Evidence Link stays AI independent by design.

The API: the integration interface

Evidence Link is generic infrastructure, not an Outfielder feature, and this is the interface the Outfielder integration connects through. In the current phase, access is restricted to approved service identities and external access is not offered. The same interface is what a later phase opens up, unchanged.

OperationPurpose
POST /v1/eventsSubmit an idempotent event: tenant, subject, type, both timestamps, actor, payload.
POST /v1/artifactsUpload evidence bytes; receive the content digest and storage reference.
POST /v1/statesSubmit a schema-versioned state snapshot linked to an event.
POST /v1/relationshipsConnect events: detects, corrects, verifies, supersedes, recurs, pertains_to.
POST /v1/attestationsRecord a scoped human or system verification statement.
GET /v1/subjects/{id}/historyRetrieve the permission-filtered timeline and linked evidence. Each event also reports its covering signed checkpoint and that checkpoint’s Bitcoin anchor status (with the block height once confirmed), and the response lists the tenant’s checkpoints with their anchor states.
POST /v1/verifyVerify an event chain, manifests, artifacts, and checkpoint signatures; detailed results.
POST /v1/case-filesCreate a scoped, access-controlled, offline-verifiable evidence export.
POST /v1/checkpointsSign the current chain heads into a checkpoint. Checkpoint hashes are then submitted to OpenTimestamps for Bitcoin anchoring.

How the integration connects, in four steps: 1. The operator provisions a tenant by hand and issues a scoped bearer token. There is no public registration and no self-serve key issuance. 2. Create a subject for the thing you track. 3. Post artifacts and events with idempotency keys, so retries never duplicate. 4. Pull history, run verification, or export a Case File at any time. Tenants are fully isolated from each other.

Connection note. The API is live on its service host today and every operation above is running. The public name api.evidence.li goes live the moment its DNS record is added; until then the curl examples show the production shape against that name. External developers cannot connect in the current phase.
# Record an event (the brief's example, against the live API shape)
curl -X POST https://api.evidence.li/v1/events \
  -H "Authorization: Bearer <tenant-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "subject_id": "site_123",
    "event_type": "accessibility.assessment_completed",
    "occurred_at": "2026-11-02T15:30:00Z",
    "source": "outfielder.catch",
    "schema_version": "1",
    "payload": {"scan_id": "scan_789", "scope": "checkout"},
    "artifact_ids": ["art_456"],
    "idempotency_key": "catch-scan_789-completed"
  }'

# The receipt: digests are computed server-side from the preserved
# bytes and canonical metadata, never generated or invented.
{
  "event_id": "evt_001",
  "status": "recorded",
  "manifest_sha256": "<64 hex characters>",
  "event_sha256": "<64 hex characters>"
}
AI, bounded. An interpretation worker is part of the design: server-side, read-only against authorized evidence, required to cite event and artifact IDs, with invented citations rejected. It can summarize and flag gaps. It can never create facts, rewrite the ledger, or determine integrity or status. That phase ships after the API-key plumbing it shares with the assessment engine.

Proven outside accessibility: the PropertyTrack demo

On November 2, 2026 a second tenant was provisioned in a completely different field, a fictional property inspection company called PropertyTrack, and a full history was run through the same API Outfielder uses. It is an internal portability test, not a customer: no outside tenants are being onboarded in this phase. No accessibility code exists anywhere in it.

Inspection completed, with a photo

Subject Building 104. An inspector records a roof leak and attaches the inspection photograph as an artifact. First state snapshot: leak active and flashing failed, bitset 1010.

Repair documented

A repair event records the flashing replacement, linked to the inspection with a corrects relationship.

Verified on re-inspection

A follow-up inspection passes. Second snapshot: bitset 0000, so the diff shows exactly what changed. An attestation records who verified, by what method, and a verifies relationship closes the loop.

Checkpointed, anchored, exported

A signed checkpoint seals the history; its hash was submitted for Bitcoin anchoring (confirmation pending, as with all current checkpoints). The Case File was exported and its offline verifier passes all 45 checks. Tenant isolation was tested both directions: neither tenant can read the other's subjects.

Try it yourself. Download the demo Case File: case-building-104.zip. Unzip it, run node verify/verify-bundle.mjs . and watch it pass. Then change one byte in the inspection photo under artifacts/ and run it again: verification fails, and it tells you why. Fictional data only; nothing real is in the file.

Build status against the brief

PhaseDeliverableStatus
1Core ledger: ingestion, tenant isolation, idempotencyLive
2Integrity: manifests, hash chains, signed checkpointsLive · checkpoint hashes are anchored to the Bitcoin blockchain through OpenTimestamps, and the proofs ride inside every Case File
3Assessment state: versioned checks, unknowns, deterministic diffsLive
4UI integration: dashboard Case File download, house log menuLive · the Activity Log evidence badges are deployed in the Outfielder dashboard, with the owner’s approval of a preview built from a real record (November 2, 2026). Every log row whose moment has a sealed counterpart carries an Evidence Link Secured line with its sealed date; the details expand to the Evidence ID, the recorded time, a live integrity result from /v1/verify, and the covering checkpoint’s Bitcoin anchor status. Rows with no sealed counterpart stay clean, and no badge detail appears on the public record page
5AI interpretation with source-linked summariesPending · waits on the API key it shares with the assessment engine
6Case File: offline-verifiable ZIP, export audit trailLive · tamper tests pass: altered bytes, forged events, and edited bundles all fail verification. Every bundle now opens with a Coverage block (subject, event count, sequence range, covering checkpoint, what sits outside the export), and the signing key is published independently at evidence.li/keys so the bundle's key can be checked out of band
7Generic API: a second, non-accessibility tenant end to endLive · proven November 2, 2026 by the PropertyTrack demo tenant above: a property inspection history sealed, checkpointed, Bitcoin-anchor submitted, exported, and independently verified, with zero accessibility code. External tenant access is not offered in the current phase
Bitcoin anchoring, as built. The official OpenTimestamps client runs on the Evidence Link server. An hourly worker submits every new signed checkpoint's SHA-256 hash to several public calendars at once, then keeps upgrading each proof until its Bitcoin block lands, recording the confirmation and block height beside the checkpoint. All three checkpoints that exist today (two for the Outfielder tenant, one for the demo tenant) were submitted on November 2, 2026 and are awaiting Bitcoin confirmation, which is the normal state for the first hours. The anchor status is served with the data, not just kept on the server: history responses carry it per event, and the Outfielder dashboard badges read it live. Every Case File now carries its checkpoint's proof file and anchor status automatically; a fresh export was generated after the change and its offline verifier passes all 147 checks. The claim language is disciplined on purpose: records are anchored to the Bitcoin blockchain and independently verifiable against it. They are never described as verified by Bitcoin, because the chain witnesses a hash, it validates no content.
The north star, from the brief. Outfielder performs the accessibility work. The assessment captures observations. Evidence Link preserves and connects evidence. The Activity Log displays that history. AI helps explain it. And the original evidence remains independently inspectable even if the AI, the dashboard, or the primary application is unavailable.