humanity.llc

Reference operator

Architecture

Sparse map of what ships today: where keys live, how revoke works, what the resolver stores, and the tradeoffs we locked for v1.

The product is not “a QR that links somewhere.” It is signed public state that any camera can read - with honest limits on what a scan proves.

Live loop (Phase A)

Create

Sign card + QR credential

Resolver

Verify signature, store status

Scan

HTTPS → current state UI

Static site on Cloudflare Pages (site/). API + scan resolver on Cloudflare Workers with D1 for cards, QR credentials, and revocation records. Private keys never leave the owner’s device.

Revoke (how it actually works)

Authorize

Ed25519 in browser tab

Resolver

Check sig → update D1

Next scan

Same URL, new answer

  • Not key rotation on the sticker The printed URL keeps profile_id and qr_id. Revoke changes server-side status, not the ink.
  • Signed authorization Resolver accepts revoke only from the owner key (or recovery key). No password-reset override on the operator.
  • Per-QR scope One wristband or sticker can be revoked while sibling QRs on the same card stay active.

What lives where

  • Browser (owner device) Private Ed25519 key, recovery key display, encrypted backup export. Lost tab = lost signing ability unless backup saved.
  • Resolver (public) Signed card JSON, QR credential rows, status flags, vouches, revocation records. Returns scan HTML + JSON - not a people trail.
  • Physical tag object HTTPS URL only. Camera decodes it; resolver decides current meaning.

Browser custody (on this device)

The resolver stores public state. Signing ability lives in the steward’s browser — not on humanity.llc servers. See Safari keys for iOS-specific limits.

  • Tab session vs saved wallet sessionStorage (hc_created) holds signing keys for this tab. localStorage (hc_wallet) survives tab close after Save ownership on this device — but other tabs must restore keys before signing.
  • Device shell Hub, wallet, status dot, and inbox on /, /wallet/, and /created/. No accounts — everything is local to this browser.
  • PWA vs Safari browser Add to Home Screen shares saved wallet but not tab session. iPhone Camera QR opens Safari, not the Home Screen app — plan for restore or same-tab scan.
  • Hosted steward tier Optional push for live proof when the tab is hidden — partial, production-gated. Keys still never leave the device.

Decisions & tradeoffs

  • Open hc/v1 spec, reference operator first humanity.llc proves the loop; other hosts can implement the same API later (federation is direction, not day-one).
  • HTTPS QR with ids in the URL Any camera works today. Tradeoff: printed ids are permanent; privacy modes live in scan response, not URL shape (v1 lock).
  • Minimal object state, no scan analytics or alerts Store status + expiry, not who scanned. Future interaction signals must stay coarse and log-free: no timestamps, locations, IPs, or per-scan history.
  • Mechanism-revealing scan UI Separate card status, human trust, QR status, and live control. Limits live in one settings row - not buried in marketing copy.
  • Not blockchain, not legal ID Signed social state for communities that refuse surveillance - not KYC, not a global uniqueness oracle.

Security & assurance

Words like signed, revoke, and resolver need backing - threat models, failure modes, tests, and clean boundaries. The repo documents these for reviewers and implementers.

  • Threat model & adversarial review Abuse paths (collusion, replay, stolen stickers), privacy leaks, and required hardening - documented before broad launch.
  • Crypto & replay boundaries Ed25519 + JCS canonicalization; typed payloads with nonces on revoke, vouch, and live-control responses; resolver rejects stale or mismatched signatures.
  • Automated tests (Worker) Vitest covers create, scan, revoke, live control, crypto, CORS, and key backup - run npm run worker:test before deploy.
  • Key recovery boundaries Owner key stays in browser; recovery key or encrypted backup unlocks revoke/live proof later. Operator cannot reset or impersonate - lost keys mean lost signing ability.
  • Failure modes we design for Revoked QR still resolves (not 404 silence); live proof expires in 120s; duplicate webhook/idempotency planned for commerce; federation to avoid single-operator honeypot.

Not in v1

Commerce webhooks, Commons Pass, NFC/mesh carriers, native apps, public directory, scan logging. See research directions for carrier experiments.

Full specs