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.
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.
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.
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 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.
Each fix is sealed as a remediation event, linked to the assessment it answers with a corrects relationship, and marked submitted, not verified.
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 record page at AAccessibility shows the approved status and dates. No findings, no evidence identifiers, no hashes ever cross to the public side.
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.
Artifacts are stored under their own SHA-256 digest. Each event carries a manifest serialized as canonical JSON, so identical content always hashes identically.
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.
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.
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.
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.
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.
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.
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.
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.
| Operation | Purpose |
|---|---|
POST /v1/events | Submit an idempotent event: tenant, subject, type, both timestamps, actor, payload. |
POST /v1/artifacts | Upload evidence bytes; receive the content digest and storage reference. |
POST /v1/states | Submit a schema-versioned state snapshot linked to an event. |
POST /v1/relationships | Connect events: detects, corrects, verifies, supersedes, recurs, pertains_to. |
POST /v1/attestations | Record a scoped human or system verification statement. |
GET /v1/subjects/{id}/history | Retrieve 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/verify | Verify an event chain, manifests, artifacts, and checkpoint signatures; detailed results. |
POST /v1/case-files | Create a scoped, access-controlled, offline-verifiable evidence export. |
POST /v1/checkpoints | Sign 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.
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>" }
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.
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.
A repair event records the flashing replacement, linked to the inspection with a corrects relationship.
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.
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.
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.| Phase | Deliverable | Status |
|---|---|---|
| 1 | Core ledger: ingestion, tenant isolation, idempotency | Live |
| 2 | Integrity: manifests, hash chains, signed checkpoints | Live · checkpoint hashes are anchored to the Bitcoin blockchain through OpenTimestamps, and the proofs ride inside every Case File |
| 3 | Assessment state: versioned checks, unknowns, deterministic diffs | Live |
| 4 | UI integration: dashboard Case File download, house log menu | Live · 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 |
| 5 | AI interpretation with source-linked summaries | Pending · waits on the API key it shares with the assessment engine |
| 6 | Case File: offline-verifiable ZIP, export audit trail | Live · 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 |
| 7 | Generic API: a second, non-accessibility tenant end to end | Live · 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 |