Attest

Attest replaces "he said / she said" home-service disputes with a signed, self-verifying evidence record, built on the Ring Partner API — what the devices observed, what the worker and the household each reported, what a coordinator concluded.

Records, not verdicts — the evidence gets a verdict; nobody's story does. Not attendance tracking, not EVV, not surveillance: the record proves it wasn't quietly rewritten — it never claims to know who was at the door.

New York's comptroller found $14.5B paid against 82M personal-care visits with no matching record; Ohio's auditor found 34% of electronic-visit-verification entries manually adjusted — invisibly. Editable records are the problem; Attest makes them tamper-evident — and private home services (cleaners, caregivers, contractors) have no EVV mandate and no shared record at all. That's the gap — and Ring's own throw-away-the-key move makes independent attestation more valuable, not less: when the platform can't see the video either, the signed record is the shared truth everyone can hold.

90 minutes scheduled. The camera observed 65.25. The worker disputes the record: "I dispute this record — I arrived before the first observation shown." The household first wrote: "My mother was home all morning and says the doorbell never rang — nobody came to the door before ten." — then the same account contradicted itself: "I was home that afternoon; I heard the doorbell a little after six and saw someone at the door. I can't say how long she stayed." Every version, verbatim and signed — including a garbled re-send — in one record nobody can quietly rewrite. Read the story the signed bytes tell (every quote in it deep-links to its verification) — or open the live record page.

"He said / she said" disputes stop being memory contests: every observation, statement, and conclusion is a separate signed receipt on a hash-chained ledger — disagreements stay on the record, flagged and verbatim, because the record never adjudicates. And the exported pack carries its own verifier: the same verify.html bundled inside the zip is the page this site hosts — it checks any pack you drop on it, ours or a stranger's email attachment. (How is this different from Ring Event History? — receipts keep verifying even if Attest disappears.)

attest: verified re-run live ↗

Verify the sample packPASS Deep link — the verifier fetches sample-pack.zip and runs the moment this page opens. Drop any exported pack; nothing leaves your browser. Verify the tampered twinFAIL Same pack, but someone inflated the contested visit's observed span — 65.25 to 135.25 minutes, past its 90-minute schedule. Deep link — lands on a red FAILED stamp; then "name what changed" points at the forged field itself. Forge it yourselfFAIL The tamper lab: pick a signed field, type your own number, download the rebuilt zip — the signature refuses your forgery, not ours. Watch the two-minute tour Twelve beats, self-playing — every frame is the real product page, not a screenshot. The fastest possible entry if you'd rather look than click. Run the whole gauntlet9/9 One click, every artifact: clean pack, its older export sibling, the four attack twins, the real-API sweep, the signed fork, the Bitcoin anchor — each verdict scored against the shared oracle, live. The whole demo as a single stream. Compare two packsDIFF "The copy the agency produced" vs "the copy I kept" — each verifies on its own merits, then their signed membership is diffed: the forged field named, and the two log heads proven to reconcile — or caught forking. Two verifying packs that aren't the same records is the whole point. Downloads the comparison as a self-contained page — the same reading attest diff --html writes. Compare across timeGROWTH The pack a family kept vs the export an agency produced weeks later — the signed heads aren't adjacent, so the reconcile walks the newer pack's embedded checkpoint chain hop-by-hop. Append-only growth proven offline; read the report. Verify the real-API sweepPASS The signed verify-live --sign report from the actual api.amazonvision.com run — a lone receipt, auto-verified on load. Verify it on your phone QR code linking to the verifier's one-click sample-pack check Scan — the same one-click check runs entirely in the mobile browser. The pack bytes never leave the phone either. AWS services3 verified live Lambda re-verifies packs with our pinned code, KMS wraps the signing key, S3 holds checkpoints — Bedrock+Strands wired (5 total) with honest fallback.
$ attest demo && attest attack-demo — loading the real transcript…

Real output from this repo's demo runtime, lightly trimmed — including forging a signed resolution's reason code after the fact and swapping media bytes on disk post-signing. Reproduce it yourself: attest demo, then attest attack-demo on the same runtime.

The trust chain — nobody in it is trusted

"The record gets a verdict; nobody's story does."

Every observation and statement becomes a signed receipt; receipts chain by hash into a publicly checkable Merkle tree; independent witnesses cosign the tree head — the shipped sample pack below carries two real counter-signatures from separate deployments, each anchored in the witness's own log. Export a pack and strangers verify it — in a browser, in bare Python, in an AWS Lambda — without asking us, Ring, or the issuer whether the bytes are still honest.

Ring observations worker + household coordinator poll coverage Ed25519-signed receipts — each links the previous by hashan Ed25519 signature proves the bytes haven't changed since the issuer signed — it never proves what a camera saw Merkle transparency log — receipts commit into a checkable treeeach receipt's hash becomes a leaf of a hash tree — anyone can prove a receipt was committed, and prove the tree only ever grew signed tree head + witness cosignthe deployment periodically signs the tree root; an independent witness counter-signs only a head it watched extend — a secret fork would need both parties lying export pack — receipts + proofs + checkpoint + its own verifier independent verifiers → verdictthe pack checks in bare Python, in this browser, or in an AWS Lambda — no Attest service in the loop not present: anyone trusted. Every layer is checkable without us.

"Isn't this just Ring's event history?"

aspect Ring Event History Attest
Who vouches Ring says so the math — anyone re-checks, offline
Voices device events only worker + household + coordinator, kept separate
Edits platform-controlled append-only; tampering breaks the math
After export a screenshot a self-verifying evidence pack

Ring's event history is Ring's word. An Attest receipt verifies without Ring — and without us. Incumbent tracking puts a GPS ankle monitor on the worker's phone, spoofable and resented; Attest anchors observation to the household's own premises, with the household's own cameras. And the trend cuts our way: as Ring moves traffic toward throw-away-the-key encryption (TAKE — Throw Away the Key Encryption, the new default where Ring deletes the content keys within ~24h, so Ring can't produce the footage unilaterally afterward — re-provisioning needs the customer's device), the platform holds less and less producible content — which makes a signed, independently checkable evidence trail more valuable, not less. Encryption decides who can see the bytes; attestation decides whether anyone can quietly change them.

The product behind the proofs

attest demo boots a local Ring emulator and plays an eight-day story (9 visits over 8 days) — a disputed visit, a camera blackout mid-window, a lapsed subscription, a coordinator live view — then serves the whole product on a printed localhost URL (--port 8000 pins it). Or peek at a snapshot first, no install: the coordinator dashboard · the site page (day-by-day coverage strips, the live-view band) · the contested visit (source-divergence callout, signed dispute) · the household view (en español) · the scoped family link (en español) — what the household actually gets texted · the worker's review link (en español) — what the scoped /review/ token sees · the printable brief · the self-audit page (revoked-key suspect windows, annotated — 9 receipts in scope) · its machine-readable JSON — and the raw layer underneath all of it: 447 signed receipts (the demo store's full log) — drawn as the literal hash chain (every edge a prev_hash link — all 447 verify), each one-click verifiable in the same browser page — or all 447 at once (raw JSON). Twenty-eight of them are the deployment auditing itself — attest verify --attest signed the verdicts on the clean pack and the forged twin across regenerations, and attest diff --attest signed the reconciliations, into the same log — and each diff report names the receipt that signed its comparison — the audit trail of the audit is checkable too. New to the math? Anatomy of a signed receipt decomposes one field-by-field — what the signature covers, what the prev_hash edge means, and what a valid signature can never prove.

And because "trust our log" isn't a stopping point either: the demo deployment anchors its journal head to Bitcoin — the signed anchor, one-click verified (journal head + transparency-log root pinned inside it) sits under a real OpenTimestamps submission (pending — public calendars commit to a block on their own schedule; attest stamp --upgrade completes it). "This record existed before that block" — verifiable without trusting us.

The attack gallery — pick one, watch it get caught

One doctored number is the easy case. Each attack below dies to a different check in the same verifier — the links land directly on the red FAILED stamp:

Nineteen more attacks die inside the store — forged rows, erased journal entries, grafted keys, swapped media — the battery's live verdict table renders all 23 verdicts from a real attest attack-demo run against the demo store (22 caught, rolled back — the 23rd is a named detection boundary, marked EXPECTED MISS on purpose).

The seven gates. Every verification runs all of them in order — each attack dies at a different one. Labels deep-link to the check or its public corpus; → marks an annotation, not a failure. open the SVG alone.
Every verify runs every gate — the attack determines which one kills it 1 parse & unpack zip members parse · names bounded · no path tricks malformed-grammar vectors ✗ 2 signed manifest manifest.json verifies · every member committed to · nothing extra smuggled file ✗ deleted record ✗ 3 receipt math Ed25519 over sha256(canonical payload) · envelope agrees with payload doctored field ✗ re-sign under another key ✗ 4 hash chain each prev_hash is the previous receipt's payload hash — order is proof reorder / insert / delete ✗ 5 transparency log RFC 6962 inclusion proofs under a cosigned tree head grafted receipt ✗ missing proof ✗ 2⁴⁰ tree_size ✗ 6 key lifecycle rotation pivots consented · revoked-key windows annotated, not erased orphan pivot ✗ suspect window → 7 tooling & media verifier_manifest pins the checker's own bytes · media digests match or withheld forged verifier ✗ missing tool ✗ …then the verdict — VERIFIED only when every gate passed. 22 of 23 demo-store attacks die at one of these gates — the twenty-third is the named detection boundary.

Mint your own: attest export --tamper-twin twin.zip --attack missing-record — the exporter self-verifies the twin and refuses to ship it if the doctored copy still passes.

Or skip the shipped attacks entirely: the tamper lab lets you commit the forgery yourself — pick a signed field in the sample pack, type your own number, and the verifier rebuilds a real zip around your edit, downloads it for you, and refuses it. Nothing is staged: the doctored pack is a real artifact, and the same signature catches your number, not just ours.

And the harder corpus, public: 44 conformance vectors — the Wycheproof-style packs every verifier surface must judge identically. The interesting attacks aren't obvious tampers; they're grammar traps — leaf_index: true, "5" as a string, 5.5 fractional, space-padded hex, a tree_size of 240 that breaks JS bitwise ops. Each row is a one-click verify.html deep link landing on the verdict the oracle predicts. Two verifiers silently diverging is exactly how a pack gets ruled valid in one room and invalid in another — this corpus exists so ours can't.

The fork nobody can hide

The transparency log's whole point: even we can't rewrite history. One issuer key, two histories — a witness pins one tree head, a monitor pins the other. Neither side can tell alone; together they prove the fork, and the catch itself is signed as a monitor_observation receipt committed inside a signed tree head. Verify the caught fork in your browser — the evidence doc's checkpoint signature, inclusion proofs, and embedded observation all check out. Reproduce it: attest split-demo fabricates the whole scenario in scratch space and emits the same evidence document.

Ring surfaces called at runtime: signed webhooks · Event History · media & snapshots (regional redirect handled) · devices/capabilities · app-integrations · subscriptions · WHEP live view. Track fit: business systems + caretaking + accessibility + access control + IoT home automation — caretaking carried through the household view and the scoped-link QR the family scans at the door; access control through the hashed, expiring, revocable grant links those scoped pages run on; IoT telemetry through the device-lifecycle coverage journal (why observation stopped, signed).

Five AWS touchpoints — three verified live

$ aws lambda invoke --function-name attest-verify-pack \
    --payload fileb://pack.json out.json
  {"ok": true} — 2 visit records, 43 receipts proven inside the log
  (transcript of the 2026-09-18 run — the current pack carries 9 visit records, 175 receipts proven at checkpoint size 305)
$ # doctor one byte in a signed payload, invoke again
  {"ok": false} — payload hash mismatch (payload was altered)
  the function catches exactly what the local verifiers catch

The fallback path is itself verified against real AWS failure modes — expired aws login creds surface as LoginRefreshRequired, quota as ThrottlingException — which is the designed behavior, not a mock. An honest FAIL on the label beats a fake PASS.

Also entered: ring-sandbox — the Open Source mini-challenge

Ring ships no SDK and no simulator, so we built both: ring-sandbox is a typed Python client + FastAPI emulator of the documented surface (webhooks, Event History, media, subscriptions, WHEP), a YAML scenario DSL, chaos injection, and a pytest plugin — MIT-licensed, on PyPI, CI-tested on Windows/Linux × Python 3.11/3.14, shipping real Playground recordings as fixtures. Attest's whole demo runs on it — and every team after us gets Ring integration without a doorbell.

pip install ring-sandbox — then point the emulator at a scenario YAML and your client talks to a full Ring surface on localhost. ring-sandbox on PyPI

Developer-experience feedback for the bonus: 17 documented friction-log entries (task → expected vs actual → severity → workaround → suggestion) in FRICTIONLOG.md.

What verification proves — and what it doesn't

A green verdict means

  • Every signature is valid under the pinned issuer key.
  • No record was added, dropped, or altered since signing.
  • The receipts are committed in the signed transparency-log head the pack carries.
  • Redacted media was withheld by policy — its signed digests still match the manifest.

It does not mean

  • That the worker physically attended — camera activity is an observation, not attendance.
  • That absence of events means absence — silence isn't absence.
  • That the issuer is honest — a signature proves integrity under a key, not truth. That's why witness cosigning and the live-log cross-check exist.

What's inside the sample pack

The bundled sample-pack.zip is a real export from the simulated Alvarez residence deployment — media withheld by redaction policy, signed SHA-256 digests preserved. It exercises the hard parts, not just the happy path:

The embedded index.html is a record browser, not a file listing: worker, household, and coordinator voices rendered separately from the signed payload (conflicting household accounts are flagged, never merged — and the household's typo-correction appends as a new signed statement, so the chain keeps the garbled original and the fix), per-visit signed anchors and deep links, a plain-language tab that prints clean, viewer-local times with the signed UTC literal on hover, and a six-element Cures Act crosswalk — the federal EVV (electronic visit verification) statute mapped to evidence fields, labeled as corroboration, never as submission.

Pin the issuer out-of-band. The pack's self-declared key says who signed it; a judge who doesn't trust the site shouldn't take its word for the key either. Three ways to pin:

Proof it talks to the real API

live-sweep-receipt.json is the signed verify-live --sign report from a real sweep against api.amazonvision.com (2026-09-30): five probes pass — users/me, devices, device status, Event History, and media download through the regional redirect — and three fail honestly on documented Playground limits (app-integrations 403, subscriptions 422, WHEP 500: no streaming hardware on the account). Every probe signed, so the claim verifies offline the same way a pack does. Verify it in your browser, one click →

Attest is a hackathon prototype — evidence-preserving records for visit disputes, not an attendance-verification or EVV product. Source: github.com/josepha-mayo/attest · emulator: ring-sandbox · judging: JUDGE.md (the ten-minute path + scoring map) · threat model · the CI evidence gate (every pack must pass ∧ its doctored twin must fail) · a drafted Ring Appstore listing.