Sally Forth!

The Quest Protocol

Federated proof of presence.

Ed25519-signed JWTs, published and verified through well-known URLs on the issuer’s own domain. No central server, no registry, no gatekeeper.

This protocol is a bet on five claims about the near future:

  1. Knowledge becomes seemingly free and infinite.
  2. Yet unearned knowledge doesn’t satisfy. The psychologist Mihaly Csikszentmihalyi argued that the moments when humans feel most alive, most joyful, and most completely themselves are not when they are relaxing or consuming answers, but when the mind is stretched to its limit to accomplish something difficult. We still have to earn what we know, and the earning happens on the way — which is exactly where we stopped going.
  3. We are the most connected people who have ever lived and among the loneliest. Screens took the hours we used to spend with each other, and the habit of seeking people and meaning in the real world broke with them.
  4. Software is about to get personal. AI and agentic programming put highly customized apps within reach — built around one person’s actual problem, and pointed at their actual life.
  5. None of it measures the doing. Every app and every AI is ready to tell you what your problem is; none of them measure the actual steps you take in the real world to solve it. An open, verifiable receipt for the going is the missing piece. That is the Quest Protocol — the full case is at /why.

The design

An issuer is an HTTPS origin. It attests that a subject was physically present at a location by signing a compact JWT (JWS, EdDSA over Ed25519) and handing it to the subject. It publishes two static JSON files on its own domain — a manifest declaring protocol conformance and a JWKS holding its public keys. That is the entire infrastructure of an issuer.

Verification is federated the way email authentication is. A credential names its issuer in the iss claim; any verifier follows that domain to the published keys and checks the signature — the same move as looking up a DKIM record. Issuers never talk to each other, verifiers never register anywhere, and no company sits in the middle. A credential issued by Sally Forth! verifies in any conforming app, and credentials issued by other conforming apps verify here.

If you can serve two static JSON files and keep a private key, you can issue credentials the whole network can verify.

Anatomy of a credential

This is a real credential issued by Sally Forth! — a visit to Heini’s Cheese Chalet in Berlin, Ohio, the fourth and final waypoint of a quest chain through Amish Country. It is safe to publish, as every credential must be: the subject is a pseudonym, and the location is the quest’s public target.

JWT (JWS Compact Serialization)
eyJhbGciOiJFZERTQSIsImtpZCI6InF1ZXN0LWtleS0yMDI1LTAxIiwidHlwIjoiSldUIn0.eyJxdWVzdCI6eyJ2IjoxLCJpZCI6ImJlcmxpbi1hbWlzaC01MTkxcXYtZG1icDdwIiwibmFtZSI6IkhlaW5pJ3MgQ2hlZXNlIENoYWxldCIsImxhdCI6NDAuNTczODgsImxuZyI6LTgxLjc4MTc1LCJyYWRpdXNfbSI6MjAwLCJ2X2xhdCI6NDAuNTc0MjQyLCJ2X2xuZyI6LTgxLjc4MjI0OSwiYXR0ZXN0IjoiZ3BzIiwiY2hhbGxlbmdlIjoibXVsdGkiLCJjaGFpbiI6ImJlcmxpbi1hbWlzaC01MTkxcXYiLCJzZXEiOjQsIm9mIjo0fSwiaXNzIjoiaHR0cHM6Ly9zYWxseWZvcnRoLnF1ZXN0Iiwic3ViIjoicXBfOWRhOWQ2MjhjMTg0OTA3ZDJhN2ExMzdhZTFlODg1MzgiLCJpYXQiOjE3NzQxMDY2NjIsImp0aSI6InFjXzJkNzUzNjk3LTExMDEtNGJiMi05OTE1LWRmOTI2ZWJmY2IyYSJ9.MeOfHd8U8xI2vjf6PlcWIB6ppt9xzMBv-mMBKPJcMN0U_QNRxBRH06pdzMAzIYSmhdHyFGA1xa-23tHQd-13Cw
Decoded header
{
  "alg": "EdDSA",
  "kid": "quest-key-2025-01",
  "typ": "JWT"
}
Decoded payload
{
  "iss": "https://sallyforth.quest",
  "sub": "qp_9da9d628c184907d2a7a137ae1e88538",
  "iat": 1774106662,
  "jti": "qc_2d753697-1101-4bb2-9915-df926ebfcb2a",
  "quest": {
    "v": 1,
    "id": "berlin-amish-5191qv-dmbp7p",
    "name": "Heini's Cheese Chalet",
    "lat": 40.57388,
    "lng": -81.78175,
    "radius_m": 200,
    "v_lat": 40.574242,
    "v_lng": -81.782249,
    "attest": "gps",
    "challenge": "multi",
    "chain": "berlin-amish-5191qv",
    "seq": 4,
    "of": 4
  }
}
claimmeaning
issThe issuing origin. The root of key discovery — everything verifies back to this domain.
subThe subject, as an issuer-scoped pseudonym: qp_ plus a salted hash. Not a name, not an email, not correlatable across issuers.
iatWhen the credential was issued — the date and time of the visit, as Unix seconds. Here: 1774106662 = March 21, 2026 at 15:24 UTC. Presence is a place and a time; this is the time, and the signature covers it.
jtiUnique credential ID (qc_ + UUID). Makes each credential individually addressable and lets verifiers de-duplicate.
quest.lat / lng / radius_mThe target point and acceptance radius the quest defined.
quest.v_lat / v_lngWhere the subject actually stood at issuance, rounded to 6 decimal places (spec §14). Here: 58 m from the target, inside the 200 m radius.
quest.attestHow presence was checked: gps, device (platform attestation), or nfc (physical tag challenge). Issuers must not claim more than they performed.
quest.challengeWhat kind of presence this credential proves — see challenge methods below.
quest.chain / seq / ofChain claims (spec §18): seq: 4, of: 4 records that this waypoint completed the journey.

The signature covers every byte; change one digit and verification fails. Paste it into any conforming verifier, or validate it here in one tap.

Federated discovery, live

These are not mock-ups — they are this issuer’s real discovery documents, served right now from the well-known URLs any verifier would fetch. The manifest declares conformance; the JWKS publishes the Ed25519 public keys, matched to credentials by the kid header. Key rotation is just publishing a new key and retiring the old kid.

GET https://sallyforth.quest/.well-known/quest-manifest.json
{
  "quest_protocol": 1,
  "issuer": "https://sallyforth.quest",
  "name": "Sally Forth!",
  "description": "Location-based verifiable credentials",
  "jwks_uri": "https://sallyforth.quest/.well-known/quest-jwks.json",
  "attestation_levels": [
    "gps"
  ],
  "url": "https://sallyforth.quest"
}
GET https://sallyforth.quest/.well-known/quest-jwks.json
{
  "keys": [
    {
      "crv": "Ed25519",
      "x": "4Hw8CqMs13eUQamFL391D0ssQNRdJl4yvuyHqfxMweA",
      "kty": "OKP",
      "kid": "quest-key-2025-01",
      "use": "sig"
    }
  ]
}

The verification algorithm

Spec §7. A verifier anywhere can check any credential without an account, an API key, or the issuer’s cooperation:

  1. Decode the JWT and read its iss claim
  2. Fetch {iss}/.well-known/quest-manifest.json and confirm it declares a supported protocol version
  3. Fetch the manifest’s jwks_uri and select the key matching the JWT’s kid
  4. Verify the Ed25519 signature
  5. Confirm the haversine distance from (v_lat, v_lng) to (lat, lng) is within radius_m

After the JWKS is cached, verification is pure math and runs offline. The issuer never learns that one of its credentials was checked, or by whom. What you know afterward is precise: the declared issuer signed this exact payload, and nothing in it has changed since. Whether you trust that issuer’s attestation is your policy call — the spec (§8.3) sketches open, allowlist, and attestation-floor models rather than imposing one.

What a credential deliberately does not carry

A credential is built to be shown to strangers, so the protocol restricts it to what is safe to show anyone: a place, a time, an attestation method, a signature.

This is a boundary, not an accident: the protocol proves the going. Everything else belongs to the person who went.

Challenge methods

The quest.challenge claim says what kind of presence was proven, each with its own claims (spec §11):

challengeproves
singleOne visit to one place.
multiVisits to several places, any order; a completion credential when done.
sequentialVisits in a required order, enforced through chain / seq / of.
durationContinuous presence for duration_m minutes.
dateboundPresence inside a window (window_start / window_end).
recurringoccurrences verified visits at least interval_days apart, with the date of every visit enumerated in dates — the signed pattern itself, not just a count.

recurring is the one with no precedent: showing up again and again has never had a receipt. Every Thursday at a neighbor’s curb, a month of early mornings at the pool, a season of town board meetings — anything whose proof is a pattern rather than an event fits in this claim.

Attestation levels and binding tiers

Two independent axes let the same credential format span a neighborhood walk and an airline gate. Attestation (§9) is how presence was checked: gps alone, device (App Attest / Play Integrity), or nfc (a cryptographic tag at the site). Binding (§10) is who can present the credential afterward:

Credentials outlive apps

Export is mandatory, not a feature (spec §12). Every conforming issuer must let subjects walk away with their credentials as raw JWTs — the .quest file format is a JSON array of them — and every credential remains verifiable as long as the issuer’s public keys stay published, even if the app that issued it is gone. Each one is also addressable at /credentials/{jti}, so a link is a proof.

Build on it

A minimal issuer is an Ed25519 keypair, the two static JSON files above, and one route that checks a haversine distance and signs a JWT. A minimal verifier is two fetches and a signature check — the reference implementation in the spec (§16) is about fifty lines. Everything on this page — chains, group play, recurring windows — is layered on that core, and none of it requires permission from us or anyone.

full specification (markdown) · machine-readable descriptor (JSON) · quest-manifest.json · quest-jwks.json · verifier

Why this exists

The five claims at the top of this page come due here. This is infrastructure for applications that turn a reason into a pattern of going. Imagine an app that notices nobody is counting on you, and answers with a quest — every Thursday, wheel your neighbor’s trash cans to the curb. The credential is the smallest part of that quest, and the only part that needs a protocol: twelve signed Thursdays, the receipt that you kept showing up. A game can use this standard. It is not what the standard is for.

The timing matters too. AI has made every symbolic artifact cheap to counterfeit — text, images, voice, résumés, reviews. What remains provable is a body, in a place, over time. This protocol is the smallest honest receipt for that, private by construction: the proof gets shown to strangers, and the reason for going never does.

And it is a protocol rather than a product because a record of where you went has to outlive whoever kept it. The longer argument — about the going itself — is at /why.