# The GeoProof Lifecycle — Reference Standard v1

**Status:** Reference Standard v1 · **Date:** 2026-06 · **Verified against:** `@xyo-network` 7.0.11

> This is the canonical, end-to-end GeoProof story. One thread runs from an
> observation to its independent re-verification — and the whole philosophy proves
> itself along the way. **Every future reference standard is another example of this
> same lifecycle, not a new isolated artifact.** The protocol stays the same; the
> examples change.
>
> Oxyon is the company. GeoProof is the protocol (`../geoproof/SPEC.md`). This is its
> reference implementation.

## The one story

```
Observe + Locate   →  Create a Presence Proof
                   →  Verify it
                   →  Issue a Receipt
                   →  Anchor the Receipt
                   →  Replay it independently
                   →  Reach the same conclusion
```

Three different parties take part — as they would in the real world:

- a **producer** (e.g. GeoPresence) makes the observation,
- an independent **verifier** (e.g. GeoJustice) judges it,
- an **anchoring service** commits the result.

No party has to be trusted. The final step re-derives the conclusion from the
artifacts alone.

## Walkthrough

| Step | What happens | Artifact |
|---|---|---|
| 1 — **Observe + Locate** | A presence event is created and structurally validated. | `oxyon.geoproof.presence.v1` payload |
| 2 — **Verify (authorship)** | It is bound and signed by the producer. | signed bound witness |
| 3 — **Verify + Issue Receipt** | The independent verifier validates the proof and issues a signed receipt that **links to that exact proof by hash**. | `oxyon.geoproof.receipt.v1` |
| 4 — **Anchor** | The proof's and receipt's hashes are committed in a batch destined for XL1. | `oxyon.geoproof.anchor.batch.v1` |
| 5–7 — **Replay independently** | A party trusting *none* of the above re-validates every signature, **recomputes every hash**, and confirms the links and the anchor — then reaches the same verdict, or refuses to. | a conclusion |

## Run it

```bash
npm install        # @xyo-network 7.0.x
npm run lifecycle  # the full story
npm test           # presence + lifecycle, incl. the tamper test
```

## Verified output

```
1. proof signed        : valid
2-3. receipt issued    : verified by c4a248c468…
4. anchored            : 2 hashes on xl1-testnet
5-7. independent replay: verified
     checks            : {"proofSignatureValid":true,"proofIsPresence":true,
                          "receiptSignatureValid":true,"receiptLinksToProof":true,
                          "bothAnchored":true}

✓ Same conclusion reached independently. Observe → Locate → Verify → Connect.
```

## Why this proves the philosophy

The replay is the point. It does not believe the producer, the verifier, or the
anchor. It **recomputes the proof's hash itself** and accepts the verdict only when
every check holds: signatures valid, the receipt linked to *this* proof, both hashes
anchored. That is *Belief Must Be Earned*, *Trust Must Be Explained*, and *Nothing
Comes From Nowhere*, demonstrated in code rather than asserted in prose.

**And tampering is caught.** Present a different proof than the one the receipt and
anchor committed to, and the link breaks — the replay returns `inconclusive`, never
`verified`. *(See the second test in `src/lifecycle.test.ts`.)* Evidence cannot be
silently changed after the fact.

## Verification status

Runtime-verified in-repo on Node 24 with `@xyo-network` 7.0.11:
- `the full lifecycle replays independently to the same conclusion` — **pass**
- `tampering is caught: a different proof breaks the link` — **pass**

## How future standards extend this

Every additional reference is the **same lifecycle with a different event**:

- **Attestation** — swap the presence event for an `oxyon.geoproof.attestation.v1`; the
  receipt/anchor/replay are unchanged.
- **Multi-party** — `BoundWitnessBuilder().signers([...])` for co-authored proofs
  (escrow / atomic exchange).
- **Real anchoring** — submit the `anchor.batch` to XL1 and have the indexer replay it
  from chain (floor block + atomic checkpoints) instead of in memory.

The lifecycle is the standard. The events are the examples.

---

*Code:* [`src/lifecycle.ts`](src/lifecycle.ts) · [`src/lifecycle.example.ts`](src/lifecycle.example.ts) · [`src/lifecycle.test.ts`](src/lifecycle.test.ts).
Single-step detail (Proof of Presence): [`STANDARD.md`](STANDARD.md).
