# PHEUN — A Decentralised Internet Replacement

**Single-user-per-node post-quantum P2P infrastructure with deterministic routing, byte-frozen ledger semantics, and embedded democracy.**

Specification V1 · Last updated 5 September 2026

Peace and Harmony Earth United Network
contact.pheun@gmail.com · github.com/nateofearth/peace-and-harmony-earth-united-network

> **This specification is a living document and will change.** It describes the
> wire format, constants and behaviour of the implementation as it stands on the
> date above, down to byte offsets and packet codes — so it moves whenever the
> code moves, and a reader implementing against it should work from the newest
> revision rather than a saved copy.
>
> The **[whitepaper](./whitepaper.md) is the stable document.** It states the
> architecture and the reasoning, names no packet codes or version numbers, and
> is not expected to change. Where the two ever disagree, the code is right,
> this document is the one being corrected, and the whitepaper should still hold
> because it deliberately does not depend on anything at this level of detail.

---

## Abstract

A purely peer-to-peer system would let humans publish, communicate, and govern without intermediaries — without companies that can suspend accounts, governments that can compel disclosure, advertisers that can financialise attention, or moderators that can rewrite history. Existing decentralised systems either reduce to a single global chain (sequencing bottleneck, ~10⁴ writes per second ceiling, mining or validator economics that re-create the trusted-third-party they were designed to remove), depend on a privileged signer set (a rebranded admin), or sacrifice security to scale (variable-format payloads, classical cryptography vulnerable to quantum attack, eventual-consistency UX that breaks for governance and money-equivalent operations).

We propose an alternative. The Peace and Harmony Earth United Network — PHEUN — is an *anchor-stream* of immutable 420-byte records distributed across 10,000 payload-addressed Sacred Anchor Index buckets, with consensus reached not through a global ordering but through deterministic byte placement, NIST post-quantum cryptography (ML-DSA-65 for signatures, ML-KEM-1024 for key encapsulation, AES-256-GCM for payload sealing, BLAKE3 for hashing), and a self-verifying propagation check at every anchor's birth (each receiver re-runs the author's own proof). Identity is regenerated at login from nine personal inputs the human alone holds — no key file, no recovery server, no password database. Every citizen runs one node; the node *is* the user; the user *is* the server. There is no token, no fee, no admin, no kill-switch, no global delete operation.

Sybil resistance is provided by the storage curve, not by stake or proof-of-work: every node holds its share of the anchor stream, which grows monotonically; one human approximates one Guide ID under that economic floor. Per-anchor admission is self-verifying: every receiver re-runs the author's signature and matches the carried genesis against the canonical one at SAI(GUIDE), so a forged or impostor anchor dies at every hop. Privacy-sensitive packet classes — direct messages, voice and video calls, store-forward signals, WebRTC setup — are wrapped in a 3-hop ML-KEM-1024 onion. Governance is universal and SIGN-scoped: any document, including the network's own Constitution, uses the same proposal/vote/consensus pipeline at a 75 % threshold. The ledger is the discovery layer; subscribing to a Guide ID, hashtag, document SIGN, link chain, or stream origin yields every future matching anchor in one to one hundred and twenty seconds. Protocol evolution is soft-fork-only by design: the wire format never changes, but new schemas, new packet types, and new algorithm selectors ride additively through a published extension lane.

This paper specifies the byte layout, the consensus protocols at birth and at replication, the storage placement law for payloads up to ten gigabytes, the universal governance pipeline, the soft-fork extension lane, the threat model, and the scalability analysis at billion-user scale. Sections 2–7 define the architectural invariants, the wire format, and the routing dispatcher. Sections 8–14 specify the network fingerprint, the transport, the onion, and the two consensus systems (birth-time Self-Verifying Anchor Propagation and replication-time Dual-Witness Sync), the fragment routing, and the per-user fork detection. Sections 15–20 cover universal governance, subscriptions, the query engine, vault and cache, bandwidth and relays, and the soft-fork lane. Sections 21–23 cover the PHEUN Sites primitive, Sybil resistance, and the explicit absence of a token. Sections 24–26 cover bootstrap, the full threat model, and the scalability analysis. Section 27 concludes.

---

## Contents

1. Introduction
2. The 1:1:1:1 Invariant
3. Identity — Guide ID
4. Two-Layer Anchor Architecture
5. The 420-Byte Anchor
6. Sacred Anchor Indexes and the Dispatcher
7. The Eight Anchor Categories
8. Network Fingerprint
9. HOPE — Hardened Onion Post-quantum Exchange
10. Private Conversation — Direct Messages, Calls, and the Onion
11. Self-Verifying Anchor Propagation — Consensus at Anchor Birth
12. Dual-Witness Sync — Replication-Time Integrity
13. PayloadWeave — XOR-DHT Fragment Routing
14. PAC Chains and Fork Detection
15. Document Governance
16. Subscriptions and Discovery
17. The Global Query Engine
18. Vault, Cache, and Network Storage
19. Bandwidth, Relays, and Resource Sharing
20. The Soft-Fork Lane
21. PHEUN Sites — A Decentralised Web Layer
22. Sybil Resistance via the Storage Curve
23. No Token, No Fee, No Mining
24. Bootstrap and the 5-per-SAI Coverage Invariant
25. Threat Model
26. Scalability Analysis
27. Conclusion and References

---

## 1. Introduction

Centralised platforms now mediate almost all of human communication, publication, payment, and political organisation. The platform decides which posts are visible, which accounts exist, which transactions clear, which speech is illegal, and which words may be typed. The result is a system in which the ground state of public discourse depends on private terms-of-service updates, in which the right to organise depends on a moderator queue, in which the right to publish depends on an algorithm that no citizen has ever read, and in which financial exchange depends on a payment processor who can decide retroactively that a transaction did not occur.

Decentralised alternatives have, by and large, repeated the same architecture under a new logo. A *blockchain* with a sequencing committee is still a sequencing committee. A *fediverse* with admins is still a federation of admins. A *layer two* on top of a layer one with a foundation that controls the fork is still a hierarchy. Even peer-to-peer storage protocols typically presume a separate identity layer, a separate payment layer, a separate moderation layer — and each of those layers re-introduces a privileged actor.

The thesis of this paper is that a different architecture is possible. One in which the protocol contains no privileged actor; one in which the wire format is byte-frozen and never changes between governance cycles; one in which identity is generated locally from inputs the human alone holds; one in which consensus is a *property of deterministic placement* combined with a small Byzantine fault-tolerant gate at the moment each record is born. Combined with NIST-standardised post-quantum primitives in fail-closed cryptographic paths, the result is a network in which:

- One human approximates one Guide ID, enforced by personal-input entropy at first registration plus the disk cost of running a full node over time.
- Every action — a post, a message, a call, a governance vote, an economic offer, a comment, a subscription, a citation — is the same 420-byte record, byte-indexed identically across the network.
- Every anchor lives at a deterministic Sacred Anchor Index computed from its own bytes by a published dispatcher; two nodes never disagree about where any anchor belongs.
- Discovery is the protocol itself: subscribe to a Guide ID, hashtag, document slug, link chain, or stream origin, and every future matching anchor flows back through the mesh in one to one hundred and twenty seconds.
- Governance is anchor-shaped: the network's governed documents are written, amended, and ratified by one 75 % threshold pipeline, scoped by a 1-byte document id drawn from a namespace closed at compile time.
- Protocol evolution is soft-fork-only and additive: new schemas, new packet types, and new algorithm selectors ride alongside the old ones; old anchors stay valid forever under their original primitives.

PHEUN is *not* a payment system, although it can host barter; it is *not* an anonymity network, although it onion-routes its sensitive packets; it is *not* a blockchain, although it is an immutable signed ledger. It is the substrate on which all of those services can be expressed without re-introducing a privileged operator. Where Bitcoin replaced the central bank with proof-of-work and Tor replaced the trusted ISP with onion routing, PHEUN replaces the centralised internet substrate itself — the layer beneath social media, document publishing, identity, voice and video communication, and resource exchange — with a single deterministic mesh.

The remainder of this paper is organised as follows. Sections 2–7 define the architectural invariants and the on-the-wire format that everything else depends on: the 1:1:1:1 single-user-per-node model, the Guide ID identity system, the two-layer anchor-and-payload content model, the 420-byte record specification, the Sacred Anchor Index dispatcher that decides where every anchor is stored, and the eight semantic categories that organise all use cases. Sections 8–14 specify the network fingerprint that walls off forks at handshake time, the HOPE transport that carries packets between nodes, the Triple Sentry onion that protects sensitive packet classes, the two-stage consensus model (SVAP at birth, Dual-Witness Sync at replication), the PayloadWeave fragment routing that distributes payloads across the mesh by content-addressed XOR distance, and the AnchorChain that detects self-forks per Guide ID. Sections 15–20 cover the document governance pipeline, the subscription system that drives discovery, the global query engine that answers any cross-mesh question in fifteen seconds, the three-tier storage architecture (vault, cache, network duty), the bandwidth and relay system, and the soft-fork lane that carries every future protocol change. Sections 21–23 cover the PHEUN Sites primitive that replaces the Web 2 page substrate, Sybil resistance via the storage curve, and the explicit absence of a token. Sections 24–26 give the bootstrap behaviour, the full threat model, and the scalability analysis at billion-user scale. Section 27 concludes.

---

## 2. The 1:1:1:1 Invariant

The architectural soul of PHEUN, and the single non-negotiable invariant that every other design choice in this paper preserves, is the equivalence:

> One human user equals one Guide ID equals one Node ID equals one server equals one profile equals one Guide login equals one device equals one codebase instance.

This is not a relation. It is a hard equality across every clause. Every citizen of Earth who joins the network runs their own full node on their own device, and the node *is* the user. The user *is* the server. There is no scenario in which N users use node X. There is no scenario in which the node serves K simultaneous users. There is no hosting tier, no operator class, no lite-client downgrade path, no shared instance that any citizen would log into. "Concurrent viewers" on a node means the same human with multiple browser tabs open on the same machine running the same node — never two different people. The browser is the node's own UI, never a remote client.

The only multi-user interaction in PHEUN is *node-to-node*: peer Alice's node talking to peer Bob's node. Per-node load equals per-user load. Per-node metrics are per-user metrics. Per-node subscriptions are per-user subscriptions. Per-node bandwidth is per-user bandwidth. This invariant simplifies every other property in the protocol: scaling becomes linear in user count rather than super-linear in tenants-per-server, identity binding has no impersonation surface across users on a single host, key recovery has no shared-tenancy compromise mode, and there is nothing analogous to a hosting reseller, a tenant administrator, or a privileged operator who could be compelled by an external authority to act against any other user.

The 1:1:1:1 invariant has six immediate consequences that recur throughout the rest of this paper:

**Consequence 1 — there is no admin override anywhere in the protocol.** Because no node ever serves a user other than its own owner, no node has a legitimate reason to impersonate, override, or proxy decisions for another citizen. The protocol is constructed so that no admin override could be added without first violating 1:1:1:1.

**Consequence 2 — rate limits, caps, and quotas are per-node, not per-user.** A "per-user query rate cap" on the originator side is meaningless under 1:1:1:1 because the originator IS the only user the node ever serves; such a cap would simply throttle the citizen's own experience without addressing any real abuse vector. Defences against multi-source flooding belong on the receiving side (limit inbound from a single source peer), not on the originator side.

**Consequence 3 — identity recovery is, by design, the citizen's responsibility.** Because no operator class exists, no operator can perform a recovery for a citizen who has lost their Guide ID inputs. The 9-input regeneration model (Section 3) is the entire recovery story.

**Consequence 4 — the protocol cannot have "shadow accounts," "back-up keys," or "support roles."** All of these presume an operator. They do not exist.

**Consequence 5 — every citizen's node holds and serves only its own user's data.** The vault tier (citizen-permanent storage) is physically separated from the network duty tier (the SAI bucket the node is responsible for as part of the mesh) and from the cache tier (LRU read-back from mesh fetches). Section 18 specifies the three-tier architecture.

**Consequence 6 — bootstrap is the only temporary exception, and the operator retires it.** The 21 Genesis Authority Guide IDs (`nateofearth2100z` and `bootstrapnode001` through `bootstrapnode020`) serve all 10,000 Sacred Anchor Indexes during the network's first phase, when community coverage is incomplete. A GA node serves bootstrap for as long as the operator keeps it running: the bootstrap-mode controller is a pure function of Genesis Authority roster membership, with no coverage gate, no timers, and no auto-toggle (auto-toggling on coverage caused mode-flapping and was removed). The operator watches community coverage via the bootstrap-status endpoint and stops the GA node once every SAI holds at least 5 community peers. Even Genesis Authorities are one human per node — the bootstrap exemption is a service role, not a multi-tenant role. Section 24 details bootstrap behaviour.

The 1:1:1:1 invariant is enforced at multiple layers. At the protocol layer, the node-owner lock file (`data/guide-id.lock`) binds the device to exactly one Guide ID at first login; subsequent attempts to log in under a different Guide ID are refused until the file is manually removed by the human physically present at the device. At the database layer, the vault, session, notification, and PAC tables are all keyed by a single Guide ID with no tenant column. At the WebSocket layer, browser tabs share one connection set associated with one Guide ID. At the cryptographic layer, ML-DSA-65 signatures bind every anchor to one signing keypair derivable only from one citizen's nine personal inputs.

A whitepaper that ignored 1:1:1:1 would describe a different protocol. Every section that follows, including the consensus, the storage placement, the governance pipeline, the threat model, and the scalability analysis, derives part of its security or scaling argument from the assumption that the node is the user.

---

## 3. Identity — Guide ID

Identity in PHEUN is regenerated locally from nine personal inputs that the human alone holds. The server stores the public key and a BLAKE3 fingerprint of it (so a restarted node can resume identity verification); the private key never leaves the device; the keypair itself is recreated from the inputs at every login and zeroed from memory immediately after the session is signed.

### 3.1 The Nine Inputs

The nine personal inputs are facts the citizen knows in combination — not in isolation. They are typed at first registration and remembered (or, with explicit acceptance of the recovery risk, recorded) by the human alone. The recommended set covers the following nine categories, each chosen to be unrecoverable from public records without specific personal context:

1. Date of birth.
2. Naming day (the date the citizen was given the name they associate with this identity).
3. Keyword (a short word or phrase the citizen chooses).
4. Phrase 1 (a longer personal phrase).
5. Phrase 2 (another longer personal phrase).
6. Phrase 3 (a third longer personal phrase).
7. Memory word (a word tied to a specific personal memory).
8. Trinity code (a self-chosen identifier, often a short sequence of characters).
9. Guide ID itself (the 16-character public handle the citizen wants to claim).

The combination matters. Any single input may be guessable from public sources or social engineering; the conjunction of all nine is intended to require either the citizen's full participation or a brute-force search large enough to be economically unattractive. The nine-input scheme is *self-sovereign* in the strict sense: the protocol does not store any of these inputs, the network never sees them, and the citizen's recovery path is to re-enter them. There is no email, no SMS one-time code, no recovery question, no key-file. **Loss of all nine inputs is loss of the identity, and PHEUN has no path to recover it.** This is by design (Vision principle 21). The cost is owned explicitly: a citizen who forgets their inputs creates a new Guide ID and accepts that the old chain is sealed but readable forever.

### 3.2 Deterministic Keypair Derivation

The nine inputs feed a deterministic key derivation pipeline. The inputs are concatenated in a canonical order with a domain-separating prefix per field (`GUIDE_ID:`, `DOB:`, `NAMING_DAY:`, and so on) to prevent ambiguity attacks. The concatenation is hashed with BLAKE3 to a 32-byte seed. The seed is the input to ML-DSA-65 KeyGen, which is itself deterministic when called with a fixed seed: the same inputs always produce the same `(publicKey, secretKey)` pair on any device. Client and server derive the seed through the same code path (`deriveQuantumSeed` in `client/src/lib/quantum-sign.ts` and `server/lib/quantum-guide-auth.ts`), because a one-field divergence would produce a different keypair and make every genesis unverifiable.

**The Guide ID is an INPUT to this derivation, not an output of it.** It is input 1 of the 9 — a citizen-chosen 16-character handle, normalised to lowercase `[a-z0-9_]` and required to be exactly 16 characters at profile creation (`guide-setup.tsx`). It is therefore a name that is *claimed*, not a fingerprint that is *computed*, which is why the create-profile flow carries an availability check against the mesh and why Section 3.3's first-claim uniqueness gate at SAI(GUIDE) exists at all — a derived handle could not collide between two different humans, and would need no such gate. The Genesis Authority roster (`nateofearth2100z`, `bootstrapnode001`…) is the visible consequence: those are chosen names, not base32 digests.

The practical properties of a claimed name are covered in Section 23.3: there is no registrar, no renewal, no expiry and no seizure, and — because the handle is one of the nine seed inputs — no way to transfer a name without surrendering the entire identity, so a claimed name has no resale market.

The derivation is intentionally cheap on the citizen's device and intentionally expensive at adversarial scale. ML-DSA-65 KeyGen is sub-millisecond on consumer hardware, so a single login is invisible to the citizen. A brute-force attacker, however, must run the full nine-input concatenation, BLAKE3, and ML-DSA-65 KeyGen for every guess, against a target whose public key fingerprint they may know but whose nine inputs they do not. The combinatorial space of plausible nine-input combinations for any specific human is vast even when individual inputs are partially guessable, and the cost of an exhaustive search compounds across the full conjunction.

### 3.3 The Genesis Profile Anchor

The first anchor any Guide ID ever signs is its Genesis Profile (category byte `0x01`, type byte `0x00`). The Genesis Profile binds the Guide ID to the public key by carrying the public key's BLAKE3 fingerprint in the PROOF field of the 420-byte record (bytes 65–96), with the protocol byte at position 64 selecting ML-DSA-65 as the signature algorithm and the algorithm byte at position 97 selecting BLAKE3 as the hash family. Every subsequent anchor signed by this Guide ID is verified against this single source of truth: the anchor's home holders (Section 11) confirms that the new anchor's signature verifies under the public key whose fingerprint matches the Genesis Profile's PROOF field.

The Genesis Profile is unique per Guide ID, and SVAP enforces that uniqueness at admission time: the home holders at SAI(GUIDE) reject any second genesis CORE for a Guide ID that is already claimed. A Sybil can only claim a Guide ID that is not yet claimed anywhere the home holders can see: once the legitimate genesis has replicated to the community peers of SAI(GUIDE), any second genesis is rejected. The only window is the propagation gap (~120 seconds at billion-user scale; Section 11), and a genesis born in that gap is resolved by earliest-TIME first-claim-wins, then sealed at the rightful owner's next login walk (Section 14).

### 3.4 Login Flow

At every login, the citizen retypes the nine inputs into the local browser. The browser regenerates the seed, the keypair, and signs a *presence attestation* — a signature over the concatenation of the Guide ID, a session expiry timestamp, and a domain-separating tag — with the freshly regenerated private key. The browser then sends the public key, the presence attestation, and the session expiry to the local server (running on the same device, per 1:1:1:1).

The local server performs three checks:

First, it verifies the presence attestation under the supplied public key. This proves the citizen knows the keypair. Second, it computes BLAKE3 of the supplied public key and compares the result, using a constant-time comparison, to the PROOF field of the on-chain Genesis Profile anchor for this Guide ID. This proves that the supplied public key is the same one that minted this Guide ID's identity (rather than any keypair that happens to verify a forged presence attestation). Third, it walks the citizen's AnchorChain (Section 14) for fork detection: if any prior PAC fork has been recorded for this Guide ID in the local `pac_locks` table, the login is refused with HTTP 423 and the citizen is shown the locked-Guide-ID modal.

If all three checks pass, the server issues a session token and the keypair is zeroed from browser memory. **The session lasts the node's process lifetime — there is no timed auto-logout.** A logged-in node is a full mesh participant (its Sacred Anchor Index goes LIVE and it holds and verifies anchors for its Sacred Anchor Index) for as long as its process runs; a session ends only on process restart, on explicit logout (the session row is deleted), or on a PAC fork-lock (Section 14). Process restart forces a fresh login by construction: the ML-DSA-65 private key is held in RAM only and is gone on restart (Vision principle 21), so the citizen must re-enter the nine inputs to sign again. The former seven-day hard logout was removed — kicking a healthy, LIVE, anchor-holding node off the mesh on a clock served almost no security purpose (the private key, not the session timer, gates every trusted operation and fail-closes without it) while it actively harmed reliability. The session token is a randomly-generated 32-byte value used only for HTTP authentication on the citizen's local browser-to-node link; it carries no cryptographic authority and confers no rights beyond proving "this browser tab is the same one that just authenticated under this Guide ID." The token is not pinned to the requesting IP address — a hard IP pin would log the citizen out every time a mobile or CGNAT carrier rotates its public IP — so the token's secrecy over HTTPS and instant revocation on logout are the gates instead. If the token is stolen, the thief still cannot mint anchors without the regenerated private key, which is no longer in memory.

### 3.5 Multi-Device Operation and Self-Forking

The deterministic derivation property — same inputs, same keypair — has a deliberate consequence: the citizen can log in from any device by re-entering the nine inputs. There is no "device pairing" step, no QR-code handoff, no key export. A citizen who buys a new phone simply logs in there.

This creates a self-forking risk. If the citizen logs in concurrently from two devices and posts an anchor from each before the network synchronises, both devices will sign distinct anchors at the same PAC_COUNT (the monotonic per-Guide-ID counter, Section 14), producing two anchors with identical Guide ID and identical PAC_COUNT but different CORE bytes. Such a fork is irrecoverable by Vision principle 31: a forked Guide ID is dead forever. PHEUN ships three layers of defence to make self-forking unlikely in normal operation:

**Layer 1 — login-time educational modal, plus a periodic key-memory reminder.** Every login surfaces a single modal explaining that single-device discipline is required, summarising the citizen's recent AnchorChain sync state, and asking the citizen to acknowledge their responsibility under the Constitution before continuing. Because sessions no longer expire on a clock, the same modal also resurfaces on a thirty-day cadence mid-session as a *non-blocking key-memory reminder*: the nine inputs are irrecoverable (Vision principle 21), so a citizen who runs their node for months without re-entering them is periodically reminded to make sure they still remember all nine. The reminder never logs the node out — key hygiene is a nudge, not a logout.

**Layer 2 — login walk plus self-subscription.** Every successful login walks the citizen's full AnchorChain via the global query engine (Section 17), pulling all anchors under the citizen's Guide ID and checking for two anchors at any PAC_COUNT with different CORE. Any fork detected during the walk writes a `pac_locks` row, refuses the login, and shows the locked-Guide-ID modal. In parallel, the node auto-subscribes to its own Guide ID via the SAI-Peer Subscription system (Section 16), so future anchors minted under this Guide ID anywhere on the mesh are forwarded back to this node within 1 to 120 seconds; cross-device forks are detected the moment the conflicting anchor arrives, the lock is written, and the active session is killed at the next authenticated request via the request-time PAC lock check.

**Layer 3 — local mint hook.** The local-mint path on this node calls into the same ingest function that gossip and sync use, with a `mintedLocally=true` flag, before announcing the new anchor to its home holders. This ensures the local fork detector observes the local mint immediately, before any race with an inbound forwarded anchor from another device of the same citizen.

The lock is local to this node, but consistent across all nodes by construction: every node walking the same AnchorChain arrives at the same fork verdict independently. There is no broadcast and no admin override. A locked Guide ID is dead by design; the citizen creates a new Guide ID, the sealed history of the old one stays readable forever (Vision principles 20 and 31), and the device-binding is released by the human physically present at the device deleting `data/guide-id.lock` and restarting the node. There is intentionally *no network endpoint* to release the device lock remotely; that surface was considered and removed because any remote recovery path is either unauthenticated (unsafe) or duplicates the nine-input flow that citizens do at first registration.

### 3.6 What the Server Stores

In strict accordance with self-sovereign identity, the server's persistent state for any Guide ID consists of:

- The 32-byte BLAKE3 fingerprint of the public key, embedded in the PROOF field of the Genesis Profile anchor on the chain. This is public and replicated across the mesh.
- Any subsequent anchors signed under this Guide ID.
- A `pac_locks` row if the chain has been forked.
- A session row for any active session (random 32-byte token, login IP recorded for audit). The row lasts the node's process lifetime and is cleared on restart, logout, or a PAC fork-lock — there is no timed expiry.

A subtlety in the second item above: a node's database holds *two* distinct things. First, its one-Sacred-Anchor-Index slice of the global AnchorStream — every citizen's anchors that route to the SAI this node is responsible for, which it serves to the mesh. Second, its *own* complete personal chain — every anchor this Guide ID has ever minted, kept locally regardless of which SAI each routed to. That second store is the authority for appending to the chain: when the citizen posts, the mint reads `MAX(pacCount)` for the Guide ID from the local database to stamp the next PAC_COUNT, so the full personal chain must be present locally. This is the other job of the login walk — beyond fork detection it *downloads* the citizen's full chain into the local database, so a citizen can keep extending their chain correctly immediately after wiping their node or moving to a fresh device. The in-memory tip cache (`pacState`) is only a hot-path accelerator over this database and is rebuilt from it on a cold start, so server restarts — which discard the cache — never produce a wrong PAC_COUNT. Because the mint stamps PAC_COUNT and inserts only after the home holders verify and receipt it (seconds later), the pipeline is serialized node-wide so two near-simultaneous posts from the one operator cannot both read tip N and self-fork the chain.

The server stores no password, no nine-input value, no derivation seed, no private key, no recovery email, no recovery phone, no key file, no device fingerprint beyond IP (which is bound to the session for transport security, not to the identity). A compromise of the server discloses only public material that was already on the public ledger. A compromise of the database discloses only what the public mesh already holds. There is nothing to leak.

The result is an identity model in which the citizen is the only party who can lose the identity, and the only party who can recover it. The protocol does not trust any third party with that responsibility, including PHEUN itself.

---

## 4. Two-Layer Anchor Architecture

PHEUN's content model has exactly two layers, and the boundary between them is enforced everywhere — in storage, in routing, in cryptography, and in propagation. Layer 1 is the *anchor*: a public, permanent, signed, 420-byte record that names a piece of content. Layer 2 is the *payload*: the actual content the anchor names, encrypted, fragmented, and distributed across the mesh by content-addressed routing. Anchors are SAI-routed (Section 6); payloads are XOR-DHT-routed (Section 13). The two layers serve different purposes and their separation is load-bearing for several of the system's other properties.

### 4.1 Layer 1 — The Anchor

The anchor is the *atomic ledger record*. Every action a citizen **publishes** — every post, every comment, every governance vote, every economy offer, every document amendment, every subscription change, every share — is born as exactly one 420-byte anchor.

**Private conversation is the deliberate exception, and the sentence above is the reason.** Anchors are public by construction; they *are* the ledger. So direct messages and calls are **not** anchors and never enter the AnchorStream — they are end-to-end encrypted peer-to-peer traffic with store-and-forward delivery, held in each participant's own local message store. Minting an anchor per message would place a permanent, undeletable, publicly-visible record of who spoke to whom and when into a ledger with no delete operation, which would be a metadata disclosure far worse than anything the payload encryption prevents. What a citizen *publishes* is permanent; what they *say privately* is not. The byte layout is frozen (Section 5) and never changes. Each anchor carries the cryptographic identity of its author (the GUIDE field), a hash of itself (the CORE field), a hash of the author's public key (the PROOF field), a signature seed (the SEAL field), and pointers to other anchors that situate this one in a chain (PAC), a parent (LINK), and a stream (ORIGIN). It also carries a Sacred Anchor Index that determines deterministically where it lives on the mesh (Section 6), a category-and-type discriminator that determines what kind of action it represents (Section 7), and a set of metadata fields covering language, geography, content tags, and a small free region for protocol extensions (Section 20).

Anchors are public by construction. They are the ledger. There is no anchor encryption. There is no private anchor. Every anchor that any citizen ever signs is, the moment it is admitted to the network, available to every other citizen to read, mirror, query, cite, and subscribe to. This is the price of an open permissionless ledger and PHEUN owns it explicitly: the protocol provides no filter, no takedown, no flag, no allow-list, no admin, no moderator, and no global delete.

### 4.2 Layer 2 — The Payload

The payload is the actual *content* of an action — the body of a post, the audio of a voice memo, the bytes of a movie, the source of a wiki article, the text of a direct message, the photographs of a catalog item. Payloads can be empty (a metadata-only anchor like a vote ballot has no payload), small (a text post is a few kilobytes), or very large (a high-resolution film is several gigabytes). PHEUN supports payloads up to ten gigabytes per anchor, which covers the great majority of human content including full-length films at distribution-quality bitrates.

Payloads are *not* stored inside the anchor. They are AES-256-GCM authenticated-encrypted with a key derived per anchor from BLAKE3 of (CORE ‖ SEAL ‖ PAC), split into fragments whose count follows a geometric-balance √ law (count ∝ √payloadSize, so fragment size grows from a few kilobytes for a short post up to a 4 MB ceiling for large files — Section 13), and distributed across the mesh by PayloadWeave (Section 13), a Kademlia-style XOR-DHT keyed by the anchor's CORE. Every fragment of one anchor lives in the same XOR neighborhood (K_NEIGHBORHOOD = FLOOR × totalFragments closest peers to CORE, author excluded); each peer in the neighborhood holds exactly one fragment, assigned by XOR rank — the *r*-th closest peer holds index `r mod totalFragments`, a coverage-complete rule that guarantees no index is orphaned (Section 13.1). A 1000-fragment film therefore scatters across thousands of unique peer-slots, with mobile-class nodes typically holding zero or one fragment of any specific anchor where they fall in the neighborhood, never the whole film.

Because the payload is stored separately from the anchor, the anchor stays small (always 420 bytes) and routable, while the payload can be arbitrarily large without affecting the cost of querying or replicating the ledger. A node that wants to read an anchor's content fetches the anchor first (one Sacred Anchor Index round-trip), derives the AES key from the anchor's bytes, originates a distributed QUERY_FORWARD that ripples through existing tunnels to discover the fragment holders, pulls one fragment per holder directly from the reach each reply hands back, verifies each fragment's authentication tag at decryption, and reconstructs the plaintext.

### 4.3 What CORE Binds

A subtle but load-bearing property of the two-layer model is that the CORE hash binds *both* layers. CORE is computed as BLAKE3 over the concatenation of (the manifest section bytes ‖ the payload bytes), with the signature slot excluded from the hash range. The manifest section carries the payload's metadata — the count of payloads, their MIME types, their file names, their sizes, the embedded public key — and the fragment manifest. Tampering with any payload byte breaks CORE. Tampering with any manifest field breaks CORE. Tampering with the embedded public key breaks CORE. Any of these tamperings invalidates the anchor's ML-DSA-65 signature, which the anchor's home holders (Section 11) verifies as part of admission.

This property means a reader who has the anchor and the fragments can trust the entire bundle: the bytes, the metadata about the bytes, the author's public key, and the binding between them. A reader cannot be fooled by a swapped fragment, a forged metadata, or an alternative public key. Implementations that hash only the payloads, or only the manifest, are a fail-closed violation of the protocol contract.

### 4.4 Why the Separation Matters

The two-layer separation gives PHEUN three properties that single-layer ledgers cannot have at the same time:

**Routability with arbitrarily large content.** The anchor stream stays small (420 bytes per record), so every node can hold its share of the ledger and every query is cheap to answer. The payload layer absorbs the large content without touching the ledger's routing or storage cost.

**Encrypted-by-default content with public-by-construction metadata.** The anchor is public; it is the ledger; it is what makes the network legible. The payload is encrypted; it is the content; it is what makes the network usable. A peer that holds a fragment can verify its integrity (the AES-GCM tag rejects tampered bytes at decryption) but cannot read its plaintext without the anchor that names it. A peer that holds the anchor can read any fragment they receive, because the anchor itself carries the AES key derivation.

**Right-to-erasure compliance without anchor rewrite.** GDPR-style erasure is satisfied by destroying the AES key the citizen derives from their anchor — for any anchor whose key is gone, the encrypted fragments on the mesh become unreadable forever, even though the ciphertext continues to exist. The anchor itself stays on the chain (Vision principle 20: anchors are permanent), but the payload it points to is no longer recoverable. There is no protocol-level delete of any anchor or any fragment; the right-to-erasure model is *forgetting the key*, not *removing the bytes*.

---

## 5. The 420-Byte Anchor

The atomic unit of the anchor stream is a fixed-size 420-byte record. Every action on PHEUN — across all categories and types — is one of these. The byte layout is byte-frozen for the lifetime of the V1 protocol and never changes between governance cycles. Bytes are byte-indexed; every offset in this section is a byte position in the canonical 420-byte buffer. The wire-form representation is the 840-character lowercase hex encoding of the buffer.

### 5.1 The Eight Blocks

The 420 bytes are organised into eight semantic blocks, each a coherent unit of meaning. The blocks are not delimited on the wire — they are simply a documentation convention — but they are useful for understanding what each region of the record does:

| Block | Range | Bytes | Concept |
|---|---|---|---|
| 1 | 0–124 | 125 | Cryptographic Identity |
| 2 | 125–229 | 105 | Chain and Stream |
| 3 | 230–237 | 8 | Sacred Anchor Index Routing |
| 4 | 238–255 | 18 | Content Classification |
| 5 | 256–266 | 11 | Consensus Governance |
| 6 | 267–276 | 10 | Mesh and Payload |
| 7 | 277–370 | 94 | Social Discovery and Avatar |
| 8 | 371–419 | 49 | Soft-Fork Lane |

### 5.2 Block 1 — Cryptographic Identity (0–124)

| Range | Field | Length | Description |
|---|---|---|---|
| 0–31 | CORE | 32 | BLAKE3(manifest section ‖ payload bytes), excluding the signature slot. The anchor's own identity hash and primary key. |
| 32–63 | SEAL | 32 | **BLAKE3 of the full ML-DSA-65 signature** — the immutable ledger's only binding to that 3,309-byte signature, which is far too large for the anchor and lives in the payload's signature slot instead. `checkSignature` enforces `BLAKE3(sig) == SEAL` ("this signature, and no other") before the payload opens. It is *also* an input to the payload key, `BLAKE3(CORE ‖ SEAL ‖ PAC)` — but that is a use, not an identity: SEAL is a signature fingerprint, **not** a key seed or a nonce, and reasoning about it as one is what previously led to a proposal to delete it. |
| 64 | SEAL_PROTOCOL | 1 | Hash family for the SEAL derivation. V1 = `0x01` (BLAKE3). |
| 65–96 | PROOF | 32 | BLAKE3 of the signer's ML-DSA-65 public key. The genesis-anchor PROOF binds the Guide ID; subsequent anchors are verified against it. |
| 97 | PROOF_PROTOCOL | 1 | Hash family for the PROOF computation. V1 = `0x01` (BLAKE3). |
| 98 | CRYPT | 1 | Payload cipher selector. V1 = `0x01` (AES-256-GCM with BLAKE3-KDF). |
| 99 | GUARD | 1 | Quantum signature algorithm selector. V1 = `0x01` (ML-DSA-65). |
| 100–115 | GUIDE | 16 | Author's Guide ID, UTF-8, null-padded. |
| 116–124 | TIME | 9 | Unix milliseconds at sign time, big-endian. The first byte (116) is reserved as a CLOCK_SOURCE soft-fork slot, currently `0x00`; the low 8 bytes are the Unix-ms timestamp, which provides ample range until approximately the year 292 million. |

The four selector bytes (SEAL_PROTOCOL, PROOF_PROTOCOL, CRYPT, GUARD) are the protocol's primary upgrade lane for cryptographic primitives. They are the soft-fork mechanism for retiring an algorithm. A future ML-DSA-87 deployment, for example, would land at GUARD = `0x02` (with `0x01` continuing to be served by readers for all anchors signed under V1); old anchors stay valid forever under their original primitives. Section 20 covers the soft-fork lane in detail.

### 5.3 Block 2 — Chain and Stream (125–229)

| Range | Field | Length | Description |
|---|---|---|---|
| 125–156 | PAC | 32 | WHO chain. Pointer to the previous anchor in this Guide ID's chain. The only walked chain in PHEUN. Genesis Profile carries 32 zero bytes. |
| 157–160 | PAC_COUNT | 4 | Monotonic per-Guide-ID counter. Genesis = 1; each subsequent anchor under this Guide increments by one. A fork is two anchors from the same Guide with the same PAC_COUNT and different CORE. |
| 161–192 | LINK | 32 | WHERE pointer. The CORE of the anchor this one replies to or builds on (a comment's parent post, a vote's proposal, an amendment's prior version). Stored, not walked. |
| 193–224 | ORIGIN | 32 | WHAT pointer. The CORE of the genesis anchor of the document, thread, or stream this anchor belongs to. Lets a query collapse all anchors of one document with a single index lookup. Stored, not walked. |
| 225–227 | LINE | 3 | Document line counter, 24-bit (up to ~16.7 million lines per document). Used by the SIGN-scoped governance pipeline (Section 15). |
| 228–229 | LINE_VERSION | 2 | Per-line revision counter, 16-bit (up to 65,535 revisions per line). |

PAC is the only chain pointer that is *walked* — that is, the only one the protocol ever follows backwards through a sequence of anchors. LINK and ORIGIN are stored for routing and rendering but never walked at scale. A reader who wants the full thread under a parent post does not walk LINK; it issues a single Sacred Anchor Index query against SAI(parent.CORE) and gets back every anchor whose LINK matches in one round.

### 5.4 Block 3 — Sacred Anchor Index Routing (230–237)

| Range | Field | Length | Description |
|---|---|---|---|
| 230–231 | SAI | 2 | This anchor's home Sacred Anchor Index, computed by the dispatcher (Section 6). |
| 232–233 | PAC_SAI | 2 | The Sacred Anchor Index of the PAC-linked anchor (a routing hint for chain walks). |
| 234–235 | LINK_SAI | 2 | The Sacred Anchor Index of the LINK parent. |
| 236–237 | ORIGIN_SAI | 2 | The Sacred Anchor Index of the ORIGIN genesis. |

The four SAI fields are 16-bit integers in the range 0 to 9,999. Carrying them in the anchor itself eliminates a round trip when a reader needs to fetch a related anchor: the reader already knows which Sacred Anchor Index bucket holds the parent, the genesis, or the previous anchor in this Guide's chain.

### 5.5 Block 4 — Content Classification (238–255)

| Range | Field | Length | Description |
|---|---|---|---|
| 238 | CATEGORY | 1 | Anchor category. The eight categories are enumerated in Section 7. |
| 239 | TYPE | 1 | Type within the category. `0x00` is universally Genesis Sign (the anchor that opens a document). Each category has its own type space. |
| 240 | FLAGS | 1 | `0x00` regular, `0x01` consensus lock, `0x02` tally checkpoint. Used by the dispatcher to split governance writes across SAI buckets. |
| 241 | TONGUE | 1 | ISO language code byte (the language of the payload, where applicable). |
| 242 | MATURITY | 1 | `0x00` All audiences, `0x0D` 13+, `0x12` 18+, `0x15` 21+. Self-declared by the author; clients use it for filtering, the protocol does not enforce. |
| 243–245 | ZONE | 3 | Geographic zone code. One byte for country, two bytes for city or region within the country. |
| 246–255 | TAGS | 10 | Ten one-byte content tag codes from a shared 256-value namespace. Three are mandatory (non-zero); the remaining seven are optional. |

Block 4 is the substrate for cross-cutting discovery. A query for "all anchors in English about Sydney with tag *recipe* and maturity at most 13+" is a structured filter against bytes 238–255 across the entire mesh. The Sacred Anchor Index dispatcher (Section 6) does not look at Block 4 to decide where the anchor lives, but the global query engine (Section 17) does look at Block 4 when filtering pulled anchors per the requester's filter.

### 5.6 Block 5 — Consensus Governance (256–266)

| Range | Field | Length | Description |
|---|---|---|---|
| 256–260 | ACCORD | 5 | Aggregate yes-vote tally as of this anchor's mint. 5-byte big-endian integer (up to ~1.1 trillion). |
| 261–265 | DISSENT | 5 | Aggregate no-vote tally as of this anchor's mint. |
| 266 | RATIO | 1 | Approval ratio mapped to the 0–200 range, where 150 is the 75 % threshold. |

Block 5 carries on-chain governance state. ACCORD and DISSENT are written by tally-snapshot anchors (FLAGS = `0x02`); the dispatcher routes those to SAI(LINK) so they are co-located with the proposal they tally. RATIO is computed at write time from ACCORD / (ACCORD + DISSENT) and quantised so a single byte can represent the threshold check exactly.

### 5.7 Block 6 — Mesh and Payload (267–276)

| Range | Field | Length | Description |
|---|---|---|---|
| 267–268 | FRAGMENT | 2 | Total fragment count for this anchor's payload (up to 65,535 fragments). |
| 269–270 | PAYLOAD_COUNT | 2 | Logical payload count. `0` = metadata-only (a vote ballot), `1` = text plus preview, `2+` = attachments. |
| 271–276 | TALLY | 6 | Running interaction count within a thread or stream (a 48-bit counter, monotonic). Used for thread popularity sort. |

Block 6 carries the anchor's relationship to its payload (Section 4) and to the engagement around it. FRAGMENT × an average sacred-math fragment size gives a worst-case payload size; readers use this to budget the reconstruction time before committing to a download.

### 5.8 Block 7 — Social Discovery and Avatar (277–370)

| Range | Field | Length | Description |
|---|---|---|---|
| 277 | SIGN | 1 | Document id from the closed registry: `0x00` no document, `0x01` Constitution, `0x02` Curriculum, `0x03`–`0xFF` unallocated (Section 15). Not text. |
| 278–293 | TITLE | 16 | Short display label for the anchor. UTF-8, null-padded. |
| 294–309 | HASHTAG | 16 | Discoverability tag (a `#hashtag` or an `@mention`). |
| 310–341 | PREVIEW | 32 | First 32 bytes of the payload's text, used for card-render quotes without fetching the full payload. |
| 342 | SPAN | 1 | Runtime of the payload's timed media in minutes (0 = none, ceiling 255). Range-searchable by length. |
| 343–344 | CLIENT_VERSION | 2 | The build version of the client that minted this anchor. Used for soft-fork dispatch (Section 20). |
| 345–370 | AVATAR | 26 | Required compact-avatar key for this anchor. The client reconstructs the full SVG character or text design directly from these bytes. Every profile and regular mint supplies a key explicitly; keys may be reused, but are never inherited or synthesized. |

Block 7 is what the user interface reads to render a feed without fetching the payload. PREVIEW carries exactly the first 32 bytes of plaintext for a card quote, while AVATAR reconstructs the anchor-specific SVG locally without an image request or stored SVG markup.

The AVATAR field is 26 bytes because the avatar is read at card size in a feed, where a word carries identity and a 24-pixel face does not. Its 208 bits are spent text-first: 20 glyphs at 8 bits each consume 160, and the remaining 48 configure how that text is set — palette, alignment, weight, case, letter-spacing, frame and texture. The 8-bit glyph is what the width bought; at 7 bits the alphabet held 128 slots and could not fit accented Latin, so a citizen writing their own name in most European languages lost their diacritics.

### 5.9 Block 8 — Soft-Fork Lane (371–419)

| Range | Field | Length | Description |
|---|---|---|---|
| 371–372 | FREE_SCHEMA | 2 | Schema selector for the FREE_PAYLOAD that follows. `0x0000` = empty, `0xFFFF` = TLV container, other values = registered schemas. |
| 373–419 | FREE_PAYLOAD | 47 | Schema-defined payload bytes. Up to 47 bytes; layout depends on the FREE_SCHEMA value. |

Block 8 is the protocol's *additive* extension lane. Every anchor reserves 49 bytes for extension data. New features land as new schema IDs in the FREE_SCHEMA registry; readers without a schema implementation see opaque hex and ignore the schema-specific behaviour, but verify CORE and the signature normally. Section 20 specifies the soft-fork model.

### 5.10 Total Size and Wire Form

The eight blocks sum to exactly 125 + 105 + 8 + 18 + 11 + 10 + 103 + 40 = 420 bytes. The canonical wire form is the 840-character lowercase hex encoding of the buffer. When stored in the database, the column is a 420-byte `bytea` (binary) field and readers convert to hex at the boundary by calling `.toString('hex')`. When transmitted over HOPE (Section 9), the buffer is a 420-byte slice of a UDP packet's payload. When passed between two browser tabs over the local WebSocket UI link, the buffer is hex-encoded.

The byte layout is the compile-time single source of truth across the entire codebase. Any reader or writer that encodes a different layout is, by definition, a different protocol on a different network — the network fingerprint (Section 8) walls off that mismatch at handshake time.

---

## 6. Sacred Anchor Indexes and the Dispatcher

The 10,000 Sacred Anchor Index buckets are not a chain. There is no chain zero. There is no genesis block. There is no global ordering. Sacred Anchor Indexes are *payload-addressed storage targets*: each anchor's home SAI is computed deterministically from its own bytes by a published dispatcher table, and two nodes walking the same SAI with the same inputs observe the same byte order.

### 6.1 Computation

The fundamental SAI computation reduces a 32-byte hash to a 16-bit Sacred Anchor Index by taking the first two bytes as a big-endian integer modulo 10,000:

> SAI(h) = uint16_be(h[0:2]) mod 10,000

For a sixteen-byte SIGN field, the SAI is computed by first hashing the SIGN's raw bytes with BLAKE3 to a 32-byte digest and then applying the same reduction:

> SAI(SIGN) = SAI(BLAKE3(SIGN_bytes))

Other dispatcher rules use the CORE, GUIDE (padded), LINK, ORIGIN, or PAC fields directly. Because all of these are 32-byte values and the reduction is a uniform integer modulus, the resulting SAI is uniformly distributed across the 10,000 buckets for any input that is itself uniformly distributed (as BLAKE3 outputs and signed Guide-derived values are).

### 6.2 The Dispatcher Table

The dispatcher decides which Sacred Anchor Index any anchor belongs to based on its category, type, and flags bytes — and which other field's hash to route on. The full table is enumerated in `shared/anchor-value-mappings.ts`; the headline rules are:

| Category | Type | Flags | Routes to | Anchor class |
|---|---|---|---|---|
| any | `0x00` | any | `SAI(SIGN)` | Genesis Sign — opens a document. |
| `0x01` | `0x00` | any | `SAI(GUIDE)` | Genesis Profile — identity binding. |
| `0x04` | `0x01` | any | `SAI(SIGN)` | Governance proposal. |
| `0x06` | `0x02` | any | `SAI(LINK)` | Comment or reply — co-located with parent. |
| `0x04` | `0x02` | `0x00` | `SAI(CORE)` | Vote Yes ballot — scattered to load-balance viral votes. |
| `0x04` | `0x03` | `0x00` | `SAI(CORE)` | Vote No ballot — scattered. |
| `0x04` | `0x02` | `0x01` | `SAI(SIGN)` | Consensus Approved — co-located with document outline. |
| `0x04` | `0x03` | `0x01` | `SAI(SIGN)` | Consensus Denied. |
| `0x04` | `0x02` | `0x02` | `SAI(LINK)` | Tally Yes snapshot — co-located with proposal. |
| `0x04` | `0x03` | `0x02` | `SAI(LINK)` | Tally No snapshot. |
| default | default | default | `SAI(CORE)` | Regular content anchors. |

The split between SIGN-co-located writes (proposal, consensus) and CORE-scattered writes (ballots) is the load-balancing primitive that lets a single proposal absorb a billion ballots without saturating any one bucket. A single-SAI query at SAI(SIGN) returns the document outline (genesis plus every proposal plus every consensus witness) — bounded growth of approximately one anchor per proposal lifecycle event. A single-SAI query at SAI(LINK) for a specific proposal's CORE returns every tally snapshot for that one proposal — bounded growth of approximately 168 tallies per week. The actual ballots, scattered to SAI(CORE), are aggregated on demand by a 10,000-SAI count fanout against the global query engine (Section 17), which takes 2 to 15 seconds and ships approximately 500 KB of census data.

### 6.3 Determinism Is Consensus

The dispatcher is fully deterministic. Two nodes with the same anchor bytes always compute the same SAI for it. This is the foundation of *consensus by placement*: two nodes never disagree about where an anchor belongs, because the placement is a pure function of the anchor's own bytes.

Within a Sacred Anchor Index, sort order is also deterministic. The primary key is the anchor's TIME field; ties on TIME break on PAC; ties on PAC break on the full 840-character hex transaction string (lexicographic). Two nodes walking the same SAI bucket with the same set of stored anchors observe the same byte order, byte for byte. Consensus on order is not negotiated; it is computed.

### 6.4 SIGN-Scoped Governance Co-Location

The dispatcher's most consequential design choice is the SIGN-scoped routing for governance documents. A *document* in PHEUN is an anchor stream identified by a 1-byte document id — the Constitution (`0x01`) and the Curriculum (`0x02`) at V1. The Genesis Sign anchor (type `0x00`) opens the document at SAI(SIGN). All proposals targeting that document also land at SAI(SIGN). Consensus locks (FLAGS = `0x01`) for that document's proposals also land at SAI(SIGN). The result is that a single Sacred Anchor Index query against SAI(BLAKE3(sign)) returns the document's *complete outline* — its genesis, every proposal ever made against it, and every consensus verdict — in one round trip. This is what lets PHEUN render the Constitution without a global index or a search engine. The id is BLAKE3-hashed before the phi-fold: ids are allocated 1, 2, 3…, and folding them directly is order-preserving, which would put the platform's entire governance surface on one narrow run of buckets.

Section 15 specifies the document governance model in detail.

### 6.5 The Requester Never Reads Its Own DB

A subtle but important rule: the requester never reads its own database to answer its own query. Even the Sacred Anchor Index it owns is queried through an outbound announce-and-pull cycle against the peer that covers it, never by reading the local table directly. This is a Vision principle 22 commitment to determinism: a node with one Sacred Anchor Index cannot trust *itself* as a query source, because trust would presume the node had already verified its own data through some other channel — which it has not, except by virtue of having received those anchors from peers via gossip cascade or sync. A query is, in PHEUN, *always* a network operation. Section 17 specifies the query engine.

---

## 7. The Eight Anchor Categories

Every anchor in PHEUN belongs to exactly one of eight semantic categories, encoded in the CATEGORY byte at position 238. Categories partition the action space so that a feed, query, or subscription can scope to the kinds of anchors a citizen cares about. A type byte at position 239, combined with the flags at 240, further partitions within a category — so the *(category, type, flags)* triple distinguishes a Genesis Profile from a profile update, a vote ballot from a vote consensus lock, a comment from a reply from a quote.

### 7.1 The Category Map

| Byte | Category | Primary Use |
|---|---|---|
| `0x01` | Identity | Genesis Profile, profile updates, presence attestations, device-binding anchors. |
| `0x02` | Shelter | Places, properties, community spaces, building info, host pages. |
| `0x03` | Education | Courses, lessons, syllabi, study materials, quizzes, flashcards. |
| `0x04` | Democracy | Proposals, votes (yes/no), consensus locks, tally snapshots. The governance category. |
| `0x05` | Economy | Barter offers (compute, bandwidth, storage, services, physical goods), service listings, exchange ledger entries. |
| `0x06` | Social | Posts, comments, replies, shares, quotes, reactions, friend connections. |
| `0x07` | Media | Films, music, podcasts, photo albums, channels, streams. |
| `0x08` | Knowledge | Wiki articles, encyclopaedia entries, research papers, citations, glossaries. |

PHEUN has **exactly eight platform categories**. There is no reserved 9th slot. The eight cover every use case identified to date — health and wellness logs sit naturally as Identity sub-types or Social posts depending on privacy intent; spirituality, sports, journalism, hobbies, dating, and pets all distribute across the existing eight without a dedicated home of their own. Consensus + tally semantics are FLAGS-byte states on Democracy anchors (FLAGS=0x01 = consensus lock, FLAGS=0x02 = tally snapshot), not a separate category. Future protocol evolution rides on the soft-fork lane (Section 20) by adding new TYPE bytes inside an existing category's range, new FREE_SCHEMA values, or new dispatcher subtypes — never by allocating a 9th category.

The split is *use-case-shaped*, not technology-shaped. A movie landing page that links to its film payload is in Media (`0x07`); a course that uses the same site primitive but for educational content is in Education (`0x03`); a city council's charter is in Democracy (`0x04`) regardless of which city. The category determines the default feed scope, the discovery filters available, and the subset of types and flags that have meaning. Categories do not enforce content rules — there is no protocol-level content moderation — but they organise the substrate for citizen-driven discovery.

### 7.2 Type Spaces Within Categories

Each category has its own type byte space (256 values per category). Type `0x00` is universally the *Genesis Sign* — the anchor that opens a document under the category's namespace. Beyond `0x00`, each category defines its own types. Democracy (`0x04`) uses `0x01` for proposals, `0x02` for yes votes, `0x03` for no votes, with the flags byte distinguishing regular ballots from consensus locks from tally snapshots. Identity (`0x01`) uses `0x00` for the Genesis Profile and `0x01` and above for profile-update anchors. Social (`0x06`) uses `0x01` for top-level posts and `0x02` for comments and replies (which are dispatcher-routed to the parent post via SAI(LINK)). The full type tables are in `shared/anchor-value-mappings.ts`; the principle is that the category byte gives the discovery scope and the type byte gives the action shape within it.

### 7.3 Cross-Category Composition

Some artefacts compose across categories. A *PHEUN Site* (Section 21) is a payload-class artefact that any anchor under any category can carry — a Knowledge article, an Education course, a Democracy proposal advocacy page, an Economy storefront, a Social profile. The category of the anchor that publishes the site sets the discovery scope; the site's content is the same artefact regardless of category. Similarly, comments (cat `0x06` type `0x02`) can target an anchor in any category as their LINK parent, so the social interaction layer attaches uniformly to every other category's anchors.

The category model is intentionally additive at the soft-fork lane level. New categories are not added cheaply (adding a tenth category byte is a wire-format change that requires governance), but new types within an existing category are pure soft-forks — old readers see an unknown type as a regular anchor and route it normally, new readers process the type-specific behaviour. Section 20 specifies the soft-fork extension lane.

---

## 8. Network Fingerprint

The network fingerprint is the single 32-byte digest that walls off forks at handshake time, before any authenticated traffic flows between two peers. Two peers with different fingerprints are different networks; the protocol drops the connection at the handshake boundary. There is no fingerprint negotiation, no version handshake that allows partial compatibility, no graceful degradation. A fingerprint mismatch is a hard reject.

### 8.1 Computation

The fingerprint is the BLAKE3-32 digest of the canonical concatenation of the compile-time constants every node must agree on:

> fingerprint = BLAKE3-32( HOPE_VERSION ‖ SAI_COUNT ‖ ANCHOR_BYTE_LAYOUT ‖ sorted(GENESIS_AUTHORITY_PROOF_HASHES) ‖ approved_crypto_primitives ‖ approved_packet_type_table )

The inputs are encoded in a canonical, length-prefixed form so that two implementations of the same protocol arrive at the same 32-byte digest. The HOPE_VERSION is the protocol version number. The SAI_COUNT is the number of Sacred Anchor Index buckets (10,000 in production). The ANCHOR_BYTE_LAYOUT is the byte-position table specified in Section 5. The GENESIS_AUTHORITY_PROOF_HASHES are the BLAKE3-32 fingerprints of the public keys associated with the twenty-one Genesis Authority Guide IDs (`nateofearth2100z` and `bootstrapnode001` through `bootstrapnode020`); they are sorted before hashing so the order in which they were declared does not affect the digest. The approved_crypto_primitives are the algorithm selectors recognised at handshake time (V1 includes ML-DSA-65, ML-KEM-1024, AES-256-GCM, BLAKE3). The approved_packet_type_table is the canonical list of HOPE packet type bytes that participate in fingerprint-bound protocol behaviour.

### 8.2 Handshake Check

A peer-join handshake exchanges fingerprints in the first packet round. If the fingerprints match, the handshake proceeds to the post-quantum key exchange (ML-KEM-1024 encapsulation, Section 9). If they do not match, the responder drops the connection and emits a single warning log line. No further packets are exchanged. The mismatch may be logged for diagnostic purposes but does not trigger any reachability failure beyond the dropped connection.

This is what makes a fork *fall out of the mesh*. A community that adopts an incompatible byte layout, a different SAI count, or a different cryptographic primitive computes a different fingerprint, and their nodes can connect only to other nodes with that same divergent fingerprint. The two networks coexist as siblings with no shared state. They cannot accidentally federate, they cannot accidentally cross-pollinate ledgers, and they cannot accidentally accept each other's anchors.

### 8.3 Why the Fingerprint Is Not Negotiated

Some protocols negotiate a version on connect — "I support v1 and v2, you support v2 and v3, let's both speak v2." PHEUN deliberately does not. Negotiation creates a downgrade attack surface, requires the protocol to define partial compatibility windows, and makes the byte semantics depend on which version a particular peer happens to be speaking at the moment. Worse, it dilutes the meaning of the byte-frozen wire format: anchors signed under v1 might or might not be accepted by v2 nodes depending on the negotiation outcome.

PHEUN takes the opposite stance. The wire format is byte-frozen for the lifetime of the V1 protocol. *All evolution happens through the soft-fork lane (Section 20)*: new schemas in the FREE region, new algorithm selector bytes (CRYPT, GUARD, SEAL_PROTOCOL, PROOF_PROTOCOL), new packet types, new dispatcher subtypes, all additive, all opaque to old readers, none of which rotate the network fingerprint. A *real* protocol upgrade — one that would change the byte layout, the SAI count, the crypto primitives' approval list, or the Genesis Authority roster — is, by design, a categorical departure that produces a new fingerprint, and PHEUN does not implement any mechanism to coordinate such a departure across the existing network. Section 20 explains why this rule (no hard fork, ever) is a feature.

---

## 9. HOPE — Hardened Onion Post-quantum Exchange

HOPE is the pure-UDP node-to-node transport. The acronym maps to the design intent: **H**ardened (fail-closed cryptography, egress limiter, fingerprint check, Byzantine fault tolerance), **O**nion (Triple Sentry three-hop relay on sensitive packets), **P**ost-quantum (ML-DSA-65, ML-KEM-1024, AES-256-GCM, BLAKE3 throughout), **E**xchange (peer-to-peer mesh). HOPE is not QUIC and shares no wire format with QUIC; the name reflects the design intent of a compact, deterministic UDP-based protocol for post-quantum mesh networking. WebSocket is reserved for the local browser-to-node UI link inside the citizen's own device (per 1:1:1:1) and is never used between nodes.

### 9.1 Why UDP

UDP rather than TCP is a deliberate choice. TCP's in-order, reliable, byte-stream abstraction is the wrong fit for a packet-oriented protocol where most messages are 420-byte anchors, anchor propagations, fragment chunks, gossip cascades, and onion-wrapped sentry packets — all of which are individually meaningful and can be processed out of order. TCP also fails-closed in ways that hurt mesh availability: a single dropped packet on a long-lived TCP connection between two peers stalls every other message until retransmit, while UDP simply delivers what arrives. Where reliability matters (chunked payloads, fragment delivery), HOPE implements its own application-level chunking with per-chunk acknowledgement and explicit reassembly limits (Section 9.6). Where ordering matters (AnchorChains), the chain pointers in the anchor itself enforce order without depending on the transport.

UDP also makes NAT traversal simpler. Hosts behind consumer NATs can hole-punch to relay nodes without the connection-tracking overhead of TCP. The relay system (Section 19) is built on this property.

### 9.2 Per-Node Connection Budget

A community node runs with a fixed per-node connection budget of 66,666 active peer connections. The budget breaks down as:

> 66,666 = 50,000 mesh + 16,666 reserve

The 50,000 mesh slots are the security substrate: 5 community peers per Sacred Anchor Index times 10,000 SAIs equals 50,000 community-peer edges. The 16,666 reserve absorbs multi-coverage peers (peers that cover more than one SAI), bursts during bootstrap or coverage healing, and short-horizon multi-hop discovery. Beyond the 66,666 active peers, the passport cache (Section 9.4) tracks up to 1,000,000 disk-persisted peer records as the discovery substrate.

The 5-per-SAI invariant is the security floor: every Sacred Anchor Index must have at least five live-or-cached community peers before the bootstrap mode controller (Section 24) considers community coverage complete. Five community peers form the home-holder set that verifies and stores each anchor and supplies the corroborating holders Dual-Witness Sync needs; if an SAI drops toward quorum risk, the emergency floor (two peers) fires an immediate LOCATE re-coverage burst. Bootstrap peer counts are tracked separately as a redundancy metric and are *not* summed into the invariant.

### 9.3 Sessions and Forward Secrecy

Pairwise sessions between two peers use ML-KEM-1024 key encapsulation followed by AES-256-GCM payload encryption with a per-session shared key. The handshake is a two-message round: peer A computes a fingerprint check and sends a ML-KEM-1024 ciphertext encapsulating a fresh shared key under peer B's public key (advertised in the passport, Section 9.4); peer B decapsulates, derives the same shared key, and acknowledges. Subsequent packets are AES-256-GCM-sealed under the shared key with a unique 96-bit nonce per packet.

Two dedicated packet types maintain session keys over the life of the connection. SESSION_KEY_EXCHANGE bootstraps a fresh ML-KEM-1024 session post-handshake (used when a session key is lost or rotated outside the normal cadence). SESSION_KEY_ROTATE re-keys an existing session every N packets or M minutes for forward secrecy: a future compromise of the current shared key does not retrospectively decrypt messages that were encrypted under a prior epoch. A decapsulation failure during a key rotation drops the rotation and the old key remains in use until the next sweep — fail-closed behaviour, never silently degrade to a weaker scheme.

### 9.4 The Passport Cache

A *passport* is a signed record carrying a peer's identity (Guide ID, ML-DSA-65 public key fingerprint), network coordinates (IP, UDP port), Sacred Anchor Index assignment, an *availability score* (how reliably the peer stays reachable — each node measures this locally from probe-ack loss and observed uptime, treating the peer's self-reported figure only as a prior until it has its own measurement; it is a soft ranking preference in candidate selection and never excludes a peer), and capability flags (relay-host, query-capable, fragment-holder). Each passport is signed once, at the peer's last identity attestation, and cached locally. Two peers that have exchanged a passport in the past can reconnect without a full handshake by replaying the cached passport and running only the ML-KEM-1024 session bootstrap.

The passport cache is kept on disk at every node, with a target capacity of 1,000,000 entries (~1.5 GB disk budget) and a 24-hour freshness window after which a passport is treated as stale and re-fetched. At billion-user scale the live mesh of 66,666 connections per node is statistically empty for any specific peer or fragment lookup; the passport cache is the actual substrate for discovery, and the live mesh is the launchpad for the cache-miss path. Section 17 details the cache-first scan order for any peer or fragment query.

### 9.5 Anti-Abuse

Three transport-layer mechanisms protect a node from abuse without rate-limiting its own user.

*Per-peer egress limiter.* For each bursty channel — gossip, fragments, queries — a per-peer token bucket caps the outbound send rate. The gossip channel has a capacity of 120 tokens with a 20-per-second refill rate; the fragment channel runs 60 / 10; the query channel (added in the V1 audit Round 2 hardening pass) runs 240 / 60. A peer whose bucket is empty has its outbound packet dropped until the bucket refills. This is "polite sender" defence: it prevents a runaway loop from this node from blasting any single receiving peer.

*Fair queue.* Below the egress limiter, a transport-layer fair queue scheduler enforces per-peer round-robin on outbound UDP. Each tick (1 millisecond) drains up to 64 packets from across all peers, with each peer entitled to a fair share. The per-peer queue is capped at 256 packets; overflow returns false from the send call so the application layer can decide whether to drop or retry.

*Seen-cache dedup.* For gossip and SVAP propagation packets, a seen-cache keyed by message ID prevents loops. A packet whose ID is already in the cache is dropped without further processing. The cache TTL is five minutes.

*UDP socket spoof-cap.* A maximum of 100,000 simultaneous source addresses are tracked per local UDP socket. A spoofed-source flood from beyond that ceiling is absorbed by the kernel's socket buffer rather than by the protocol's own data structures.

### 9.6 Application-Level Chunking

UDP packets are bounded by the network's MTU (typically around 1,300 bytes after subtracting headers). HOPE's application-level chunking layer fragments larger payloads into chunks of at most 1,302 bytes (the MTU minus the HOPE header and the chunk header). Each chunk carries a 20-byte header with the original packet type, a transfer ID, the chunk index, and the total chunk count. The receiver buffers chunks until the transfer is complete, then reassembles and processes the original packet through its normal handler.

Reassembly is bounded by three caps to prevent memory exhaustion: a global session count of at most 2,000 concurrent reassemblies, a per-peer cap of at most 5 concurrent reassemblies from a single source peer, and a global byte cap of 500 megabytes across all in-flight reassemblies. Each reassembly times out after 30 seconds of inactivity; a transfer that stops mid-flight is purged. Each per-transfer chunk count is capped at 50,000, which at the maximum chunk payload sums to approximately 65 megabytes per individual transfer. These caps prevent a malicious peer from holding open large buffers indefinitely; they also bound the worst-case heap budget the receiver commits to chunked reassembly.

### 9.7 Self-Addressing Without a Third Party

A node behind NAT does not know the address the rest of the world sees it at, and it needs that address to advertise a reachable endpoint. Every conventional answer to this problem is a third party: a STUN server, or an HTTP "what is my IP" service. Both hand a single external operator a complete log of which node came online, from which address, and when — the precise metadata the rest of this design exists to avoid. PHEUN contacts neither. There is no external STUN endpoint, no IP-echo service, and no fallback to one anywhere in the tree.

The observation is that peers *already* have the answer. A peer had to observe our post-NAT source address in order to receive our packet at all. It therefore reports it back to us for free, as two additional fields on the `ENDPOINT_PROOF` packet.

That placement is the security control, not a convenience. The proof echoes a nonce encapsulated to that Guide ID's genesis-bound ML-KEM key, so only the rightful owner could have produced it, and the challenge identifier is single-use so a captured proof cannot be replayed. The reporter is therefore cryptographically established rather than merely claimed. Two weaker placements were considered and rejected: on the plaintext handshake response the Guide ID is an unverified claim and the network fingerprint is publicly computable, so one attacker could satisfy the reporter threshold alone with two invented identities; and on the heartbeat, a "tunnel-verified" gate would be dead code, because heartbeats are never tunnel-encrypted.

A reported address is untrusted input, so adoption requires agreement. Two *distinct* peers must report the same address before it is adopted. A tie between two claimed addresses is contested and adopts neither — the same fail-closed rule Dual-Witness Sync uses for a contested window. Each reporter gets one vote, so re-handshaking cannot stuff the ballot, and provisional pre-login identities do not vote at all. Without this, a single lying peer could make a node advertise a black hole (a self-inflicted denial of service, since nobody could reach it) or a third party's address (a traffic-reflection primitive). What it does not defend against is a coordinated majority of a node's peers agreeing on a false address; that is bounded — the node advertises somewhere unreachable and heals once honest reports outvote the liars after the observation window expires.

Cold start needs no mesh at all, but the question is asked **per address family**. A globally-routable address bound on a local interface is proof that nothing is translating us, which is what lets a public server boot straight into relay-host mode instead of deadlocking as a client that drops its own bootstrap peers' handshakes. "Does this node have a global address" is not one question: the ordinary consumer and mobile shape is a global IPv6 sitting beside a carrier-grade-NAT'd IPv4, and taking the first global address of either family would find the IPv6, declare the node publicly reachable, and advertise a relay host that no IPv4-only peer can reach. Eligibility therefore turns on IPv4 — the family every peer can still use — while a genuinely IPv6-only host qualifies on IPv6, because the peers that can reach it are exactly those sharing its family. A dual-stack node with a translated IPv4 leg waits for a peer observation.

The same principle covers voice and video. A browser placing a call needs a server-reflexive ICE candidate, and only a party that receives a packet from the browser's own UDP socket can supply one — that is what a STUN server is. PHEUN nodes already are that party, so each node answers RFC 5389 Binding requests on its existing HOPE port and the browser asks its own mesh. Three independent checks demultiplex STUN from HOPE unambiguously — length, a message type with its top two bits clear, and the magic cookie — so a HOPE packet can never be answered as STUN nor a STUN message parsed as HOPE. The responder is deliberately unauthenticated: a browser asking "what is my address" has no identity yet, and the answer discloses only the requester's own address back to the requester. Peers are offered to the browser only if they demonstrably accept cold inbound traffic from strangers, since a peer that merely looks publicly addressed may be reachable only because our own heartbeat is holding its NAT mapping open.

The result is that a citizen can discover their own address, advertise a reachable endpoint, and place an encrypted call without any packet leaving the mesh. When no publicly-addressable peer is known, the candidate list is simply empty and ICE gathers host candidates only — a cross-NAT call may then fail. That is the honest outcome, and there is deliberately no external fallback to make it quietly succeed.

---

## 10. Private Conversation — Direct Messages, Calls, and the Onion

PHEUN is *pseudonymous-by-default with onion-protected sensitive channels* — not a global anonymity network. The passport system binds Guide ID to IP:port at the pairwise mesh layer, by design, because home-holder selection, fragment placement, anchor propagation, and Dual-Witness corroboration all require wire-layer authenticated identity. Triple Sentry hides the *content* and *destination* of six sensitive packet classes — direct messages, the four call-control types, and WebRTC signalling — from all but the first and last hop in a three-hop onion path.

### 10.1 What Is Onion-Wrapped

Six HOPE packet types are onion-wrapped. The onion router is invoked from exactly two places in the codebase, and a packet type that does not reach one of them is not wrapped, however it may be catalogued elsewhere:

1. Direct messages (`DIRECT_MESSAGE`) — peer-to-peer text messages. Store-and-forward delivery to an offline peer rides this same type; it is not a separate packet class.
2. Call control — `CALL_INITIATE`, `CALL_ACCEPT`, `CALL_DECLINE`, `CALL_END`. Four types covering the lifecycle of a call invitation.
3. WebRTC signalling (`WEBRTC_SIGNAL`) — SDP offers, answers, and ICE candidate exchanges, delivered across the mesh so a call can be set up without a third-party signalling server.

That is the whole list. Three things a reader might expect to find on it are deliberately absent, and each absence is a design consequence rather than an omission:

- **Subscription forward** (`SUBSCRIPTION_FORWARD`) is sent directly to the elected subscription peer. Onion-wrapping it would be incoherent, not merely expensive: that peer must know the subscriber's identity in order to deliver matches back to it, and the send has no intermediate hop, so an onion would conceal the subscriber from the one party that has to know it and from nobody else. Subscription-metadata privacy requires the introduction-point model discussed in Section 22, not this layer.
- **Peer ban announcement** (`PEER_BAN_ANNOUNCE`) has no sender at V1; bans are node-local.
- **Call media** (`CALL_MEDIA`, 0x16) is a reserved packet slot with no sender and no handler anywhere in the tree, because call media does not travel over HOPE at all. See below.

**Call media does not cross the mesh at all.** Once a call is set up, voice and video frames travel browser-to-browser over WebRTC's own DTLS-SRTP transport — they never enter HOPE, and therefore are never onion-wrapped, never rate-limited by the egress limiter, and never counted against a relay slot. What Triple Sentry protects for a call is the *signalling*: who is calling whom, and the negotiation that gets the two browsers connected. The media path's confidentiality comes from SRTP, whose key agreement is classical ECDHE — the one place in the product where a recorded stream is not protected against harvest-now-decrypt-later. Closing it requires per-frame encryption inside the browser (the Encoded Transform API), keyed from the ML-KEM-1024 session the two nodes already share.

Anchors themselves are *not* onion-wrapped. They are public by construction (Vision principle 28). The propagation that carries anchors across the mesh runs through the standard HOPE transport layer with egress limiter and fingerprint checks, but no onion. Wrapping every anchor would defeat the load-balancing properties of the SAI dispatcher and add no privacy benefit (the anchor is on the ledger anyway). Onion-wrapping is reserved for content that has a sender, a recipient, and a privacy expectation — which excludes the public ledger's writes.

### 10.2 Onion Construction

The onion is a three-layer envelope. Each layer is AES-256-GCM-sealed with a distinct ML-KEM-1024-derived session key, and each inner layer carries the address of the next hop relay:

> hop3 = AES-256-GCM(K3, payload) — to the exit relay
> hop2 = AES-256-GCM(K2, hop3 ‖ next=relay3) — to the middle relay
> hop1 = AES-256-GCM(K1, hop2 ‖ next=relay2) — to the entry relay

The originator picks three relays from its passport cache, establishes an ML-KEM-1024 session with the first one, sends the outer envelope, and the relays unwrap layer by layer until the exit relay delivers the inner payload to the recipient. Each relay sees only its predecessor and successor; no relay sees both ends of the path.

Each session key is established through the same ML-KEM-1024 bootstrap as a regular pairwise session. There are no public-input-derived keys anywhere in the production path: the keys come from fresh ML-KEM-1024 encapsulation, never from a hash of public data. A path-expiry cap, an LRU target cap on circuit memory, and a per-circuit packet-count limit prevent long-lived correlation against any one path.

### 10.3 Threat Coverage and Limits

Triple Sentry defends against a *passive mesh observer* who watches the network and tries to correlate sender, recipient, and content of a sensitive packet. The observer sees the entry relay receive an onion from the originator, but the entry relay cannot read past its own layer; the observer sees the exit relay deliver a payload to a recipient, but the exit relay cannot identify the originator beyond "the previous hop in the path"; no relay or external observer can read the original content unless it is the originator or the recipient.

What Triple Sentry does *not* defend against:

- *Sender identity from any one of the three relay hops.* Each relay sees its predecessor and successor by IP:port. A relay that logs its inputs can record "originator's predecessor was X" or "recipient's successor was Y." Mesh is pairwise authenticated; there is no anonymity at the wire layer of any single relay.
- *Coordinated all-three-relay compromise.* If all three relays in a citizen's circuit are controlled by the same adversary, the citizen's traffic is fully exposed. The mitigation is multi-source candidate selection: relays are picked from the passport cache by a combination of manual operator preferences (decentralisation overrides), availability-score-ranked relay-capable peers, and Genesis Authority fallback. An attacker would need to dominate all three pools simultaneously to guarantee a fully-compromised path.
- *Traffic-shape correlation against an adversary with a global view.* A global passive adversary who can observe both the originator's outbound and the recipient's inbound can correlate timing and packet sizes regardless of the onion. PHEUN's threat model does not promise resistance to a global passive adversary; it promises resistance to a *passive mesh observer* (one or more peers in the mesh, but not the underlying network operator).

Anchors (the ledger) are public by Vision principle 28. The onion only protects packet classes whose content is not intended for the ledger. Section 25 specifies the full threat model.

### 10.4 What a Private Conversation Is — and Is Not

Direct messages and calls are the one part of PHEUN that is **deliberately not an anchor**. Everything a citizen publishes becomes a 420-byte record on a permanent public ledger; what they say privately does not, and the exception is load-bearing rather than an omission.

Minting an anchor per message would place an undeletable, publicly visible record of *who spoke to whom and when* into a ledger with no delete operation. That metadata is worse than anything payload encryption could offset: the content would be sealed, but the social graph and its timing would be permanent, public, and queryable by anyone, forever. So a DM is peer-to-peer traffic held in each participant's own local message store, and a call is signalling plus a browser-to-browser media path. Neither leaves a trace on the AnchorStream. `0xA9` ('Direct Message') exists as a reserved TYPE byte with no server-side usage, and there is no anchor mint anywhere in the messaging path.

The practical consequence is worth stating plainly, because it cuts both ways: **private conversation is not backed up by the network.** An anchor survives because ten thousand strangers replicate the bucket it landed in. A DM survives because the two people in it kept it. Store-and-forward holds a message for an offline peer, but that is delivery, not durability.

A call adds one more layer. Call *signalling* — the invitation, the acceptance, the SDP and ICE exchange — travels as onion-wrapped HOPE packets, so no third-party signalling server ever learns who is calling whom. The reflexive address each browser needs is answered by PHEUN peers acting as STUN responders rather than by Google or Twilio. Call *media* then flows browser-to-browser and never enters the mesh at all, which is why `CALL_MEDIA` is a reserved slot with no handler.

### 10.5 The Contact Gate — Permission Before Reachability

![The contact gate — the Guide ID is a permanent public name, the 13-character contact code is a replaceable number, and every inbound DM or call must prove knowledge of the current code before any ICE candidate is gathered](assets/contact-gate.svg)


Triple Sentry protects a conversation once it exists. A separate mechanism decides whether it exists at all, and it answers a problem the onion cannot: a Guide ID appears in every anchor its owner writes, which is correct for authorship and wrong as a contact address. Without a gate, anyone who reads a post can ring that node forever, and the only remedy is a reactive ban list — the shape that makes a public identifier a liability on every other network that has one.

**Two fields, two jobs.** The Guide ID is the citizen's permanent *name*: public, unchanging, and the thing authorship is proved against. The contact code is their *number*: a 64-bit secret rendered as 13 Crockford base32 characters, which the citizen hands out and can replace at will. Separating them is what lets the name stay permanent while reachability stays revocable.

**What crosses the wire is a proof, never the code.** A sender presents `BLAKE3(DOMAIN ‖ code ‖ senderGuide ‖ recipientGuide ‖ epoch)`. Binding the sender, the recipient and the epoch into the digest means an observer who captures a proof cannot replay it, and cannot turn it against a third party — the proof is valid only for the exact pair and window it was computed for. A short PIN is not an option here: six digits is about 2²⁰ and a distributed guesser walks it in minutes, which is why the secret is 64-bit.

**The gate runs before ICE, and that placement is the control.** WebRTC discloses the local public address to whoever it negotiates with, so a check performed when the call rings has already leaked what it was protecting. The gate therefore sits before session work, before the UI event, and before a single candidate is gathered.

**The proof is re-checked on every inbound.** There is no accepted-contact short-circuit. This is the design's central trade and it is deliberate: with a one-time promotion, rotating the code was a no-op for everyone who had already used it, so a citizen who published their code and was then spammed had no remedy except removing peers by hand. Re-checking means changing the code cuts off *everyone* holding the old one — friends included — which is precisely what makes rotation a real remedy rather than a gesture.

The people a citizen keeps are restored through exactly one channel: the citizen's next message to that person carries the new code inside the ML-KEM envelope, under the onion, and the recipient's node updates its record after sender authentication. There is deliberately **no bulk push** of a new code. A citizen with a thousand unwanted threads would hand the new code straight back to every one of them; the broadcast would *be* the leak. Open threads are a recents list, not a mailing list.

**Guessing is bounded twice, and a correct proof is verified first.** Attempts are capped per sender *and* node-wide, because a per-sender cap alone gives an attacker with N throwaway Guide IDs N fresh allowances. The ordering is load-bearing: because there is no short-circuit above it, consulting the budget before verifying would let a stranger spray wrong codes until the node-wide allowance was spent and every real conversation — all of them now re-proving per message — stopped working. Verification costs at most two BLAKE3 hashes and at 2⁶⁴ a guesser never reaches a correct proof, so nothing is lost by letting a valid one through unmetered.

**What the code buys is revocability, not secrecy.** Publishing it is a supported choice — a citizen who wants to be openly reachable puts it in an anchor payload or on their PHEUN Site — but a code placed in a payload is network-readable forever, because payload keys derive from the public anchor. The honest statement is therefore: private by default, public by choice, and reversible either way. The ban list complements this and is never the door.

---

## 11. Self-Verifying Anchor Propagation — Consensus at Anchor Birth

PHEUN admits each anchor at the moment it is born, and it does so without a jury, an attester, or a witness. The mechanism is *Self-Verifying Anchor Propagation* (SVAP): the anchor carries, on every propagation, everything a receiver needs to prove it is genuine, and **every receiver re-runs that proof independently**. There is no trusted third party whose verdict must be believed. The propagation *is* the verification.

This is a deliberate departure from a committee model. A juror's signature authenticates the juror, not the anchor — and at billion-user scale a receiver almost never holds a given juror's public key in its cache, so it cannot check that signature and would have to trust it. The author's proof has no such weakness: the author's public-key fingerprint (`PROOF`) is *inside* the 420-byte anchor, and the full public key and signature travel with it. Any node, anywhere, can verify the author directly. SVAP authenticates the anchor itself, so it scales where a committee cannot.

### 11.1 What Every Propagation Carries

The self-verifying payload is the `ANCHOR_FULL` packet (type `0x3A`), a fixed-layout binary frame of approximately 6.5 kilobytes carrying five things:

- the **new** 420-byte anchor being born;
- its **genesis** 420-byte anchor (the author's Genesis Profile — the identity root);
- its **previous** 420-byte anchor (the chain link);
- the author's full **ML-DSA-65 public key** (1,952 bytes);
- the author's full **ML-DSA-65 signature** (3,309 bytes).

A genesis anchor carries only the new anchor (it is its own root); a second anchor's previous *is* its genesis, sent once. The frame is binary and length-prefixed — no hex-in-JSON — so the bytes on the wire are the bytes that are hashed and verified.

### 11.2 The Two-Part Proof

Each receiver runs the proof in two parts. The first is **offline math** over the carried bytes alone — cheap, and it rejects malformed or forged input before any network round-trip is spent:

- *Signature.* `BLAKE3(public key) == PROOF` (bytes 65–96) and `BLAKE3(signature) == SEAL` (bytes 32–63), so the carried key and signature are exactly the ones the anchor commits to; and the ML-DSA-65 signature verifies over the CORE. This proves the holder of the corresponding private key signed *this exact anchor*.
- *One keypair.* The new anchor, the carried genesis, and the carried previous all carry the *same* PROOF — one keypair signed the whole chain.
- *Chain link.* `new.PAC == previous.CORE` and `new.PAC_COUNT == previous.PAC_COUNT + 1`.
- *Dispatch and time.* The anchor's SAI field equals the SAI the dispatcher computes for its bytes (recomputed, never trusted), and its TIME falls within the sanity window (5 minutes symmetric in V1), catching future-dated anchors and stale replays.

The offline math proves a valid signed chain under *one keypair*. It does **not** prove that keypair is the rightful owner of the Guide ID — because the Guide ID is a user-chosen input, not derived from the public key (Section 3.2). An impostor can generate their own keypair, stamp a victim's Guide ID onto a fabricated anchor, and self-sign it: the signature verifies, because they signed under *their* key. The offline math cannot catch this.

The second part closes that gap. **Mesh corroboration** is the load-bearing check: the carried genesis must match, byte-for-byte, the **canonical** genesis the network already holds at `SAI(GUIDE)` — the Sacred Anchor Index the author's own Genesis Profile dispatches to (Section 6). Ownership of a Guide ID is *first-claim-wins*: the earliest-TIME genesis at `SAI(GUIDE)` is canonical, because the keypair is not third-party-derivable and cannot be raced after the fact. An impostor's fabricated genesis has a different CORE (it commits to a different public key) than the canonical one, so the check fails with `GENESIS_MISMATCH` and the anchor dies at every hop. For a non-genesis anchor, the carried previous is likewise matched against the canonical anchor at that chain position. The canonical genesis for a Guide ID is immutable and is cached per author to keep the check off the hot path.

Together: the signature proves *this keypair signed this anchor*; the genesis corroboration proves *this keypair owns this Guide ID*. Both are required, and both are re-run by every receiver.

### 11.3 The Wire Flow — HAVE / WANT / FULL

The ~6.5 KB `ANCHOR_FULL` moves only to a peer that actually needs it. The author announces the new anchor with `ANCHOR_HAVE` (type `0x38`, 34 bytes: the CORE plus the anchor's home Sacred Anchor Index) to the peers whose passports prove they cover that home SAI. A peer that does not yet hold the CORE replies `ANCHOR_WANT` (type `0x39`, 32 bytes); the holder answers with the `ANCHOR_FULL`. A home holder that verifies and stores the anchor forwards the `ANCHOR_HAVE` onward to the *other* peers covering the same home SAI, deduplicated by CORE so a cycle of holders never loops. Because only peers covering the home SAI store or forward, propagation stays inside that bucket's roughly five holders — it is not a mesh-wide broadcast.

### 11.4 Storage Receipts — Verified Is Not Published

A home holder that verifies and stores an anchor returns an `ANCHOR_STORED` receipt (type `0x50`) to the *author*. The author appends the anchor to its own personal chain and ships the payload fragments only after at least `MIN_HOME_STORERS` (two) distinct home holders have receipted — because Dual-Witness Sync (Section 12) needs two holders to replicate a window onward, and a single holder would leave every other node in that bucket permanently under-witnessed. The author counts itself when it covers the anchor's home bucket (always true for its own genesis, which dispatches to `SAI(GUIDE)`), and the requirement clamps to however many home holders exist, so a two-node network can still publish. Without this receipt an anchor could be signed and verified yet come to rest nowhere — unfindable by any query, its already-scattered payload fragments orphaned with no anchor to address them.

### 11.5 Forgery, Identity Theft, and the Fork Race

Against forgery, SVAP is not probabilistic. There is no committee to corrupt: an anchor is admitted only if its own signature verifies and its carried genesis matches the canonical one, and *every* honest receiver re-runs both checks. A forged anchor (bad signature) or an impostor anchor (valid signature under a foreign keypair, wrong genesis) is dropped at the first honest hop and every hop after. Collecting other citizens' `ANCHOR_FULL` packets yields nothing usable: the private key never leaves its owner's device (it is regenerated from the nine inputs in RAM and is never stored or transmitted), and possession of a public key and old signatures does not let an attacker produce a new valid signature.

The one thing SVAP does not prevent is a *cross-device self-fork*: a citizen signing two different anchors at the same PAC_COUNT from two of their own devices, under the *same* real key, inside the propagation window. Both anchors pass every check and both propagate — this is unpreventable at the protocol level. It is caught at the next login by the AnchorChain walk (Section 14), which locks the forked Guide ID.

### 11.6 Bandwidth and the Naked-Broadcast Ban

The cost is the ~6.5 KB `ANCHOR_FULL`, and it is paid only toward home holders that answer `WANT` — roughly five peers per anchor, most of whom already hold it and never receive the full frame. The 34-byte `HAVE` is what actually fans out. Per-node cost therefore scales with the anchors landing in a node's one Sacred Anchor Index, not with total network throughput: at larger networks each node sees a smaller fraction of the global anchor flow.

Every anchor that enters a node's `anchor_stream` must arrive as an `ANCHOR_FULL` that passed the receive boundary — offline math plus canonical corroboration — or via a Dual-Witness Sync window pull (Section 12). The legacy gossip-wrapped naked-anchor path is rejected. The author originates its own anchor by announcing `HAVE` and answering `WANT`; it self-stores only when it covers the anchor's own home SAI (always for its genesis; always for a Genesis Authority). On a peerless network a Genesis Authority — or a fresh citizen's genesis — commits solo and Dual-Witness Sync replicates it onward as holders appear; this is not a verification bypass (the author fully verified its own bytes) but a durability relaxation, and it tightens the instant a second holder exists. Genesis uniqueness itself is enforced at `SAI(GUIDE)`: the home holders reject a second genesis CORE for a Guide ID that is already claimed, which is what makes handle-squatting first-claim-wins.

### 11.7 The Live Window — Repairing a Dropped Announce

An `ANCHOR_HAVE` is a single *unacknowledged* UDP datagram, and the loss that matters is not an independent per-packet failure rate but a **correlated stall**: a receiver that pauses for a few hundred milliseconds — a garbage-collection cycle, a full socket buffer — drops the *entire* cascade burst at once, so the redundancy of announcing to several holders dies with it. Compounding this, every receiver refuses an anchor whose TIME falls outside the ±5-minute sanity window (Section 11.2). **The live path will therefore never carry that anchor again.** A missed announce is permanent unless something re-offers it, and propagation over an unreliable datagram transport cannot, by itself, guarantee that every holder receives every anchor.

The repair belongs where the loss happened — inside a bounded **live window** of 60 seconds — and rests on three mechanisms.

First, the `ANCHOR_FULL` cache *is* the live window, and it is the only structure on a node that can serve an `ANCHOR_FULL` at all. It cannot be rebuilt from storage: the persisted 420-byte anchor carries `BLAKE3(pubkey)` as PROOF and `BLAKE3(sig)` as SEAL, but never the 1,952-byte public key or the 3,309-byte signature themselves, which travel in the payload. A holder that has evicted the cached frame can no longer answer a `WANT` for that anchor under any circumstances. The cache is therefore sized in *anchors*, derived from the per-bucket arrival rate rather than the global one: a community node holds exactly one Sacred Anchor Index, and at a billion citizens a single bucket receives on the order of twenty anchors per second, so a 60-second window is roughly 1,200 frames.

Second, the **author re-announces**. While its `ANCHOR_STORED` receipts are still outstanding, the author re-sends `ANCHOR_HAVE` to the home holders that have not yet answered, on a backoff that lands entirely within the store-receipt deadline. A retry issued *after* the stall has passed is the only one that can arrive; re-announcing costs a 34-byte packet and is free of side effects, because a holder that already has the CORE drops the duplicate on its seen-cache without replying.

Third, **co-holders top each other up**. Each node periodically re-announces its whole live window to the peers holding the same bucket, which reply `ANCHOR_WANT` for anything they lack. This reuses the HAVE/WANT/FULL exchange exactly — no new packet type, and therefore no change to the network's wire identity (Section 8) — and is paced beneath the receiver's inbound-HAVE meter so that a top-up is never mistaken for a flood and throttled. One constraint is load-bearing: the rotation must re-offer the window to *every* co-holder within a single cache lifetime. A rotation slower than the cache is worse than none at all, because the anchor ages out of the only structure that could have served it before that peer's turn ever comes.

Together these make propagation reliable enough that a LIVE bucket is **never re-swept on a timer**. A dropped announce is repaired inside the live window that dropped it, not by periodically re-reconciling settled history — which would collapse the catch-up layer and the live layer into one and dissolve the distinction the two-layer model rests on.

---

## 12. Dual-Witness Sync — Replication-Time Integrity

SVAP protects the network against forged anchors at *birth*. Once an anchor is born and propagates through the cascade, it is part of the immutable ledger and any further node that wishes to hold a copy must replicate it from peers. *Dual-Witness Sync* — DWS — is the replication-time integrity check that detects a peer serving corrupted, stale, or modified bytes during a Sacred Anchor Index bucket pull, and the convergence engine that brings a node's bucket up to date. It is implemented as **windowed Merkle anti-entropy**, the technique that lets two nodes reconcile arbitrarily large datasets at a cost proportional to their *difference*, not to the dataset's size.

### 12.1 Why a Second Layer

A reader might wonder why both SVAP and DWS exist. The answer is that they protect against fundamentally different threats. SVAP is *birth-time verification*: it admits a new anchor only if its own signature verifies and its carried genesis matches the canonical one at SAI(GUIDE), re-checked independently by every receiver. DWS is *not* a consensus protocol: it is an integrity-and-convergence check on a peer's storage, applied during the routine replication path when one node copies an SAI bucket from another. The threat DWS catches is not a forged anchor — those are closed at birth by SVAP — but a peer who has stored corrupted bytes (perhaps because their disk failed, perhaps because they are byzantine and serving manipulated data on demand), and the everyday case of a node that is simply *behind* and needs to discover exactly which anchors it is missing. This is set reconciliation over an unordered bucket — the same role a Merkle tree plays in a distributed *database* (Cassandra, DynamoDB, Riak) — and is emphatically **not** a blockchain: there are no blocks, no linear chain, no global order, and no mining. The only walked chain in PHEUN remains the per-user PAC.

### 12.2 The Windowed Merkle Tree

Every anchor in a bucket falls into a fixed TIME window of width `WINDOW_MS` (one minute), indexed from a frozen network epoch. Each *window* has a digest: BLAKE3 over the canonically-ordered **full 420-byte anchors** it contains — not their CORE hashes alone, because CORE addresses only the payload and a CORE-only leaf would leave the record's other 388 bytes (PROOF, GUIDE, routing, metadata) uncommitted, letting witnesses "agree" on a window while serving different anchor bytes. This leaf-commitment rule is bound into the network fingerprint, so two builds that disagree on it fail at handshake rather than silently never converging. Windows fold up a fixed 16-ary tree — each internal node's digest is BLAKE3 over its sixteen children's digests — to a single root. Because two honest nodes holding the same anchors in the same window produce byte-identical digests, comparing two nodes' buckets reduces to comparing digests.

The tree's value is that it is *insertion-stable* and *sparse-cheap*. A late-arriving old anchor — common in a permissionless mesh, where a genesis minted before any peer existed can arrive long after newer anchors — lands in its own window and dirties only that one leaf plus its root-to-leaf ancestor path; nothing else recomputes. Empty spans between sparse anchors collapse to a per-level constant, so building a node's tree costs work proportional to the number of *populated* windows, never to wall-clock time. Settled windows (defined below) have immutable digests, computed once and cached, so a caught-up node re-checks its entire history by comparing a single root digest.

### 12.3 Settled and Live Zones

A whole-bucket root digest is useless for comparison, because the *live edge* — anchors minted in the last few minutes — is always different between any two nodes, so the root would perpetually mismatch. DWS therefore splits the bucket at the live edge, `now − LIVE_ZONE_MS`. This boundary is sized as the **maximum-propagation margin** (ten minutes at V1, comfortably larger than the anchor-propagation budget): any window *older* than it has had time to spread the entire mesh, so a settled-root match provably means "I hold every anchor that has had time to propagate." Everything older is the **settled zone**: frozen, identical across honest nodes, and the basis for comparison. Everything newer is the **live zone**: the moving edge, received through the SVAP propagation once a node is LIVE, and excluded from the settled comparison.

Because the live zone is defined by *age*, not by count, the LIVE transition is a **binary predicate on the settled root** — "do I hold every window older than the margin?" — never a percentage of the whole bucket. This distinction is deliberate: a fraction-of-all-anchors threshold would be a perpetually moving target, since anchors are minted continuously and the denominator never settles, so a node in a busy mesh could approach but never reach it. Anchoring the gate to the frozen settled zone gives a fixed, provable finish line that a node in even the busiest mesh always reaches. A node may therefore go LIVE and begin serving while the last few minutes of the live edge are still arriving; being *settled-complete* — not *caught up to the instant* — is the correct and sufficient bar for participation.

Two synced nodes therefore agree on the settled root constantly, and a sync that finds the roots equal completes in a single exchange — `O(tree-depth)` work regardless of whether the bucket holds a hundred anchors or a hundred billion. When the roots differ, the syncing node drills the tree: it asks a peer for the child digests of the root node, compares each child to its own, and recurses only into the children that differ, descending until it has localised the exact divergent *leaf windows*. It then pulls only those windows. Because both sides compute over the *same* settled window-count — the requester supplies its `n`, and the peer answers over that same prefix — clock skew between the two nodes never causes a spurious mismatch.

Inside a window, order is deterministic: TIME ascending, then full-anchor bytes ascending (the 420-byte record is unique by construction, so the order is total). Two nodes with identical window contents emit identical digests; any difference is caught and localised.

### 12.4 Witness Corroboration and the Live Gate

DWS corroborates a divergent window **only among the peers that actually hold it** (window digest count greater than zero). An empty or behind peer casts no vote and never vetoes a real holder. The ingest decision is bounded by a `requiredHolders` threshold, and that threshold is **pinned to identity, never derived from timing**. Every node requires `requiredHolders = 2` — two agreeing holders — with exactly one exception: roster index-1 (`bootstrapnode001`), the designated cold-start bridge, may use `requiredHolders = 1` while it still sees fewer than two other holders. Roster index-0 (`nateofearth2100z`) *solos* the genesis (§12.5); index-2 through 20 and every community node always require two. A divergent window is ingested only when at least `requiredHolders` holders **agree**.

This makes two-witness corroboration the rule for every node, not an option assigned by whoever happens to connect second. If a non-bridge node can reach only one holder, it does **not** pull and does **not** go LIVE: it stays SYNCING (logging `SYNC_UNDERWITNESSED`) and retries when a second holder becomes reachable. It never single-trusts. The single-witness path (`requiredHolders = 1`) is the **one identity-pinned cold-start exception**: the index-1 bridge replicates the solo'd genesis's already-SVAP-verified history and becomes the second holder, so every node that joins after it has two to corroborate against. This is why the protocol is named **Dual**-Witness: two witnesses is the rule for all but one bridge identity, never a routine mode granted by timing.

With **two or more agreeing holders**, a fabricated anchor held by a single malicious peer produces a window digest the honest holder contests, so it is never corroborated, never ingested, and never propagates. The fork/fake defence is therefore mandatory from the third node on and strengthens as the holder set grows (five-plus holders corroborate normally at billion-user scale). This is strictly stronger than asking a malicious node to quarantine itself: honest nodes simply refuse uncorroborated content, regardless of what the source claims. Subtrees on which two-plus holders *disagree* are contested and skipped for that cycle; they resolve on a later cycle once propagation completes. Every pulled anchor is still format- and SAI-checked on insert.

Live propagation and historical catch-up are **two separate paths with two trust models**, and keeping them separate is what makes the transition clean. New anchors reach a node through **SVAP propagation** — self-verified at receive, direct-inserted; this is how two already-LIVE nodes stay byte-aligned, with no DWS involved. DWS replicates only the history a node *missed*. Crucially, a node still SYNCING a bucket does **not** receive the cascade for it (the receiver gates on whether the bucket is LIVE), so a multi-day backfill of a large bucket is never polluted by live tip-inserts arriving out of order.

A node transitions a Sacred Anchor Index to **LIVE** — meaning it will serve and propagate the bucket and begin receiving the cascade — only once it is missing no witness-corroborated settled content. Live-zone anchors are corroborated **byte-for-byte**: the node fetches the moving edge from every holder without inserting, and ingests an anchor only when `requiredHolders` distinct holders served the identical 420 bytes (a tampered variant under an honest CORE is a distinct key and is never corroborated). A node holding content the witnesses lack (its own recent mints still propagating) is *ahead*; this is logged but does not block LIVE. The transition is a smooth handoff, not a stop-the-world: the node reconciles its settled history, goes LIVE, and a bounded **post-LIVE convergence window** (`POST_LIVE_CONVERGENCE_MS`, one live-zone) keeps additively re-reconciling to catch any anchor minted in the gap between finishing the pull and the mesh learning the node now covers the bucket — then releases to pure cascade delivery.

A live-zone anchor that a syncing node **defers** (held by only one witness) or misses entirely is never lost, because the live zone is a *sliding* window: as the wall clock advances, the anchor crosses the maximum-propagation margin into a settled window, at which point the ordinary settled-root compare covers it like any other historical anchor. The live edge is therefore self-healing through three overlapping mechanisms — the SVAP propagation delivers new anchors to a LIVE node, the byte-for-byte pull corroborates them across `requiredHolders` distinct holders, and **aging into the settled zone is the final backstop** that guarantees eventual inclusion with no single-source trust. Nothing on the moving edge is ever accepted from one source (outside the index-1 cold-start bridge), and nothing on it can be permanently stranded.

### 12.5 Cold Start: the Solo Origin and Event-Driven Catch-Up

The reconcile-then-LIVE model raises a bootstrap question: a node goes LIVE by reconciling its settled history against a peer — but the *very first* node has no peer to reconcile against. Declaring a bucket LIVE from local state alone, with zero peers, is the **solo** primitive, and it is a strict last resort, never a default, reserved to roster index-0. The cold-start ladder is pinned to **identity**, not to how many nodes happen to be connected: index-0 (`nateofearth2100z`) solos the genesis; index-1 (`bootstrapnode001`) is the single-trust bridge that pulls index-0's already-validated history and becomes the second holder; index-2 onward and every community node require **two agreeing holders** and wait rather than pulling from one (§12.4).

Solo is gated two ways. First, **only a Genesis Authority may solo.** A community node *never* declares a bucket LIVE unsynced: a GA bootstrap covers every Sacred Anchor Index, so a reachable peer always exists once the network is up, and "no peers" for a community node simply means it has not finished connecting yet. Going LIVE then would make it an authoritative, serving source for a bucket it never reconciled — a self-bucket fork risk. Fail-closed: it stays in the SYNCING state and waits, never serving unreconciled data. Second, a GA solos only after a short **grace** (`SOLO_FALLBACK_GRACE_MS`) elapses from login with no LIVE peer having appeared. Within the grace even a GA waits, so the second and third nodes — which connect during that window — synchronise *from* the first node rather than each independently soloing.

When several Genesis Authorities boot simultaneously (a fleet restart), a naive "wait while any peer is present" rule would deadlock: each sees the others still SYNCING and none would solo. PHEUN instead elects one origin **deterministically** — among the set of itself plus its active GA peers (all necessarily still SYNCING, because a LIVE GA covers every bucket and would already be a usable sync source), the lexicographically smallest Guide ID is the origin and solos; the rest stay SYNCING and synchronise from it the moment it is LIVE. Because the global-minimum Guide ID always elects itself, exactly one origin emerges with no coordination round (Vision §22 — every node computes the same winner from the same inputs). A lone genesis node is the sole member of its own set and so solos after the grace. The result is the intended sequence: the first node solos, the second single-trust-syncs from it, the third dual-witness-syncs from the first two — never "all solo".

Catch-up after the origin exists is **event-driven, not timer-driven.** Once a bucket is LIVE a node receives new anchors through SVAP propagation (Section 11) — it does not re-run a full sync on a clock. Instead, when a peer (re)connects, the node re-reconciles its held buckets against current peers: a caught-up bucket resolves in a single O(tree-depth) settled-root compare and pulls nothing, while a bucket that went solo at boot or fell behind during a disconnect pulls exactly the windows it is missing. On a stable mesh with no churn, no background re-synchronisation runs at all. This is also why a node that has been offline catches up on rejoining — reconnection is the trigger — and why synchronisation is never time-bounded: a node loading years of settled history from cold may take as long as it needs, batch by batch, with only per-request timeouts and no overall deadline.

### 12.6 LIVE Is Not a One-Way Door

LIVE is a claim with two halves: that a bucket is byte-for-byte identical to its co-holders, **and** that it is receiving every new anchor by propagation. A node that has lost *every* co-holder for a bucket is no longer doing the second — no peer can deliver propagation to it, and the live-window top-up (Section 11.7) has nobody to pull from. Whether it still holds thousands of other connections is irrelevant: for *that bucket*, it is offline.

The response depends entirely on duration, and the boundary is the live window. A blackout **shorter** than the window requires nothing: the top-up re-offers every missed anchor the moment a co-holder is reachable again, so a brief disconnect must not be allowed to flap the bucket in and out of service. A blackout **longer** than the window is different in kind. Those anchors have aged out of every holder's `ANCHOR_FULL` cache and can never arrive on the live path again; the bucket is now genuinely incomplete, and the LIVE claim is simply false. The bucket is therefore demoted **LIVE → SYNCING**, and Dual-Witness Sync — the catch-up layer — restores it, promoting it back to LIVE on a settled-root match.

The demotion is what prevents one node's gap from becoming the whole network's. A node that keeps advertising LIVE coverage while missing anchors continues to be elected as a DWS witness, a synchronisation source, a home holder and a storage receipt-issuer for a bucket whose recent history it does not have. A cold-starting node that selects it as a witness then finds its settled digest disagreeing with the honest holders, and the window is marked *contested* (§12.4) — so an isolated node degrades the synchronisation of every newcomer that happens to sample it. Clearing the coverage bit on demotion removes the node from every such election until it has caught up.

It also follows that **total peer count is the wrong signal for liveness.** A node holds one Sacred Anchor Index out of ten thousand, so the handful of peers that share its bucket are a vanishing fraction of its 66,666 connections; it can lose every one of them while its overall peer count barely moves. Coverage of the *held bucket*, not the size of the peer set, is what LIVE actually asserts.

### 12.7 What DWS Does Not Defend, and the Engine

DWS does not validate on-the-wire bytes against any external truth — only against corroborating witnesses. If `WITNESS_COUNT` peers are *all* colluding and serving identical corrupted bytes, the corroboration passes; PHEUN tolerates this because the underlying forgery threat is already closed at birth by SVAP, so DWS is defending storage integrity and convergence, not forgery. It does not auto-delete an attacker's locally-injected anchor — anchors are immutable (Vision §20) — the fake simply stays inert and unpropagated on the attacker's own node. Cross-node peer-reputation gossip remains a future coordinated upgrade; persistent local ban entries survive restarts today.

The engine is `server/services/sai-merkle.ts` (the windowed tree, digest caching, drill-down, and invalidation) driven by the reconcile loop in `server/services/anchor-sync-service.ts`, exchanging `SAI_MERKLE_REQ` / `SAI_MERKLE_RES` packets. The digest tree is pure local derived state — it is never shipped as authoritative data, contributes nothing to the network fingerprint, and its on-disk cache is a rebuildable, crash-safe-validated optimisation. Window width, epoch, fanout, the live-zone width, and the witness count live in `shared/dws-merkle-config.ts`.

---

## 13. PayloadWeave — XOR-DHT Fragment Routing

PayloadWeave is the storage layer for payloads. While anchors live in deterministic Sacred Anchor Index buckets and are routed by SAI dispatch, payloads are content-addressed and routed by Kademlia-style XOR distance in BLAKE3 hash space. Anchors are SAI-routed; *fragments are content-addressed, not SAI-bucketed*. The two systems share no routing logic and their separation is the fundamental scaling property that lets PHEUN store 10-gigabyte payloads across mobile-class nodes without forcing any single node to hold any single payload's full bytes.

### 13.1 Anchor-Scoped Placement

A payload is split into N fragments of sacred-math-determined size (typically a few hundred kilobytes each). All N fragments of one anchor live in a *single* XOR neighborhood — placement is anchor-scoped, not per-fragment. PayloadWeave computes one *routing key* per anchor:

> coreRoutingKey = CORE_bytes(32)

where CORE is the 32-byte CORE field of the anchor — already a uniform-random hash from `BLAKE3(manifest section ‖ payloads)` so it is used directly as the routing key without an additional hash. Each peer in the mesh has a *peer key* defined as BLAKE3 of their Guide ID. The XOR distance between two 32-byte values is the unsigned 256-bit integer interpretation of their bitwise XOR.

The K_NEIGHBORHOOD = FLOOR × totalFragments peers nearest to coreRoutingKey in XOR space form the *holder pool* for the entire anchor, **excluding the author** (PHEUN is a mesh: the author retrieves its own payload through the same mesh fetch as anyone else, and never stores its own fragments). Placement is by **XOR rank**, not by an independent per-peer hash: the eligible peers are sorted by XOR distance to coreRoutingKey (Guide ID as a deterministic tiebreak), and the peer at rank *r* among the closest K_NEIGHBORHOOD peers holds fragment-index `r mod totalFragments`.

This rank rule is *coverage-complete*: whenever at least totalFragments non-author peers exist, the closest totalFragments of them take indices 0…totalFragments−1 one each, so **no index is ever orphaned**, and each index gets ⌈K_NEIGHBORHOOD ÷ totalFragments⌉ = FLOOR redundant holders (ranks i, i+F, i+2F, …). An independent per-peer hash cannot guarantee this — it could assign every available peer the same index and leave another with zero holders (a two-fragment genesis losing index 0) — which is why placement is by rank, not by hash. With FLOOR = 20 and a 1000-fragment film, K_NEIGHBORHOOD = 20,000 peers, mean 20 holders per index. Per-peer storage stays at one fragment (at most the 4 MB fragment-size ceiling) regardless of file size; FLOOR is a launch-phase knob (1 on the smoke testnet, 10 at public launch, 20 at the mature-mesh target).

This is the PayloadWeave property that distinguishes it from per-anchor concentration. If every fragment of one anchor lived on the same FLOOR-peer set, those peers would each hold the full multi-gigabyte payload — untenable on any consumer device. By scattering the K_NEIGHBORHOOD across thousands of distinct peer-slots and placing one fragment per peer, the protocol enforces a single-fragment storage burden that any phone-class device can handle, while keeping all fragments addressable through a single XOR neighborhood that one distributed QUERY_FORWARD ripple discovers.

Because the holder of any index is decided by XOR rank among the *author-excluded* neighborhood — which a receiving peer cannot reconstruct without knowing the author — the receiver does **not** re-derive and enforce the rank on a `FRAGMENT_STORE` push; it range-checks only that the claimed index is within 0…totalFragments−1. Placement integrity is instead closed downstream: the (CORE, N) composite is the primary key (a peer cannot hold two copies of the same index, and a mis-placed fragment is simply an extra copy the swarm tolerates), and the AES-256-GCM authentication tag rejects any tampered or wrong bytes at reconstruction (§13.5) before any plaintext leaks. Discovery, correspondingly, never trusts a *predicted* assignment: it reports the index a peer **actually holds**, bloom-confirmed (§13.2).

### 13.2 Discovery

A reader who wants to reconstruct an anchor's payload starts with the anchor and its single coreRoutingKey, but it does **not** connect to the holders to find them. At a billion nodes the holders of an arbitrary CORE are almost never in the reader's own live mesh, and dialing the thousands of candidates a cold lookup touches would cost megabytes of post-quantum handshakes merely to *ask* — fatal for a kilobyte post. Instead the reader **originates a distributed QUERY_FORWARD**: a roughly 170-byte query carrying the CORE, the still-needed fragment indexes, a hop-count ttl, and the origin's Guide ID is handed to the reader's closest-to-CORE neighbours over tunnels that **already exist**, and the mesh forwards it the rest of the way. The reader only ever talks to its own neighbours; every other node does O(1) work, so the query's cost is distributed across the mesh rather than piled on the fetcher.

The candidate substrate each node forwards toward is the union of its live K-bucket routing table (66,666 peers) and its passport cache (1,000,000 cached records). The routing table's k-buckets are organised in raw-Guide-ID space, which is **uncorrelated** with the BLAKE3 CORE space fragments are keyed in, so the passport cache is the de-facto CORE-space knowledge (Vision principle 25 — the cache is the fanout engine). To make querying a million-entry cache cheap on the hot path, every node maintains a **PeerXorIndex** over its cache — a leaf-compressed binary trie over peer BLAKE3 keys that returns the k peers nearest any CORE in O(k + depth) (microseconds) rather than the O(N) scan a linear search would cost. It indexes *peers* and is queried *by a CORE*; it is the "which peers are near CORE C?" half of discovery.

Each node that receives the query does four things, all O(1). It **dedups** by requestId against a 30-second seen-cache — the same mechanism as the gossip cascade — so a query never loops or is re-processed. It records the predecessor so a matching reply can be **routed back along the reverse path**. It **bloom-checks** which of the needed indexes it actually holds, keyed by `fragmentLookupKey = CORE_bytes ‖ uint16_be(N)` against its phi-progressive RAM bloom (one entry per (CORE, N) row it holds across vault, viewer cache, and network-duty XOR storage), and if it holds any it sends a `QUERY_FORWARD_REPLY` back toward the origin carrying its Guide ID, the indexes it really holds, and its **reach** — IP:port, plus a relay Guide ID when it is NAT'd — so the reader can pull direct. And it **forwards** the still-needed indexes onward to its own closest-to-CORE peers, ttl permitting (the ceiling is 32 hops). Discovery never trusts a *predicted* assignment: a node answers only for fragments it really holds, bloom-confirmed — under rank placement a responder cannot compute another peer's index without the author-excluded neighborhood, so it reports its own actual holdings and nothing more.

The forward fan-out is **adaptive**, and this is what lets one tiny query discover the holder map for a file of any size. While a node is still routing the query *toward* the CORE it fans NARROW — three closest peers, cheap navigation. Once a node is itself **inside the anchor's K-neighborhood** — detected in O(1) via the sibling **CoreBloom**, which carries one entry per anchor the node holds any fragment of — it fans wide, so the query spreads across all F holders, who are XOR-close to one another, covering every index rather than only the ones that node happens to still need. That width is sized to **what is left to find** rather than fixed: `clamp(stillNeeded, NARROW, WIDE)`, ceiling 64. A search with two thousand indexes outstanding fans the full 64; one with three left fans three, instead of recruiting sixty-four more peers to locate three fragments. Measured on a twenty-six-fragment payload at a hundred copies per index, sizing the fan to the remaining work cut total contacts from 34,131 to 12,515 — 2.7× less query traffic — with hop count and delivery unchanged. The origin seeds its own ripple WIDE as well, wanting full coverage from the first hop. Because the recursion re-fans at every in-neighborhood node, a WIDE_FANOUT of 64 suffices where the retired single-fetcher walk needed an additive per-hop ceiling many times larger. Both blooms grow phi-stepped (16 → 26 → 42 → 68 → 110 → 178 megabytes for the fragment bloom; 2 → 24 for the CoreBloom) as stored content grows, promoting on a 6-hour background rebuild when load passes 70% of optimal capacity and clearing stale bits in the same pass.

Holders in a wave reply in parallel, so wall-clock latency tracks the **hop count**, not the number of nodes touched. The at-scale measurement is `npm run bench:sweep`, which executes the *real* `qfOriginate` / `qfOnQuery` / `qfOnReply` against a simulated transport in **rank space** — a node is represented only by its global XOR-distance rank to the CORE, so the network size is exact at a billion rather than scaled down. That distinction matters: in a materialised mesh of a few tens of thousands of nodes, the `FLOOR × F` holders of a large payload are several percent of the entire network, so anything near the CORE is a holder and coverage looks perfect for reasons that vanish at real scale.

**Nearest-first alone is not enough, and that is the whole shape of the problem.** A node's nearest-to-an-arbitrary-CORE sits near global rank *N* ÷ 1,066,560 — about 938 at a billion nodes, but about **nine** at ten million — so every participant in a ripple offers very nearly the same low ranks, the search converges on the innermost sliver of a `FLOOR × F` holder band, and the seen-cache turns the repeats into no-ops until the frontier dies. A band is 25,600 ranks wide for a ten-gigabyte film and rank *r* holds index *r* mod F, so reaching only the inner few hundred ranks yields only a few hundred distinct indexes. Measured on the shipped engine with no complete copy anywhere, such a payload reached **33 % and did not open** at ten million nodes, while a post, a song and a hundred-megabyte clip all reached 100 %; raising the search budget from six rounds to twenty moved it to 35 %, because the ripple had saturated rather than been cut off.

The fix is that a node already **inside** the neighbourhood forwards *additionally* to peers beyond its own XOR distance, so the wavefront sweeps the whole band instead of collapsing into its centre. Two properties make it work and either alone breaks a different payload size: the sweep is **additive** rather than a share of the fan, because taking it out of the fan halves the in-neighbourhood breadth a replica census depends on; and the covering half carries **no floor at all**, because a band *narrower* than one node's reach is swept by that half alone and a pure outward sweep steps straight past its holders with no way back.

With that, the shipped engine locates every payload from a one-kilobyte post to the ten-gigabyte maximum **100 % of the time in a single round**, at ten million, a hundred million and a billion nodes alike, from canonical placement alone — no vaulter, no viewer cache, no source list. About 4,400 nodes are asked for the film at ten million and 83,878 at a billion. The film is *found* in under a second; the download that follows takes minutes, which is the cost of the bytes and not of the lookup. Fragment count barely moves the hop count, because more holders is a *wider* fan and not a *deeper* search, and a followed or popular anchor whose holders are already in the reader's cache resolves in a single hop.

Replication depth is first a **durability** property: at one copy per index a single holder going offline orphans that index permanently, and the payload is then gone rather than merely slower to locate. It also affects *discovery*, because a narrower band of holders is a smaller target for the same search — but that effect must be measured in rank space to mean anything, since in a materialised simulation of a few tens of thousands of nodes the `FLOOR × F` holders of a large payload are a large fraction of the entire network and coverage looks perfect for reasons that vanish at real scale. The measurements quoted here are the rank-space ones; the materialised benches deliberately skip any payload whose holder set exceeds a small share of the simulated mesh rather than report a routing property they did not test. A short read is nonetheless a failure rather than a partial result — the manifest and the ML-DSA signature are split across fragments, so one absent index makes the whole stream unparseable — which is why the origin's deadline scales with the number of indexes sought instead of being a flat timeout, and why a search that comes back short is retried rather than accepted. A cold lookup ripples through a few thousand of these forwards, each node paying about 0.1 kilobyte, and the per-node forwarding load is constant in network size — a phone carries the same load whether the mesh is a million nodes or a billion.

### 13.3 Pull

Discovery and download are not separate connection phases: a `QUERY_FORWARD_REPLY` hands back each holder's reach, so the reader pulls **directly**. It registers a UDP binding from the reach — a public holder answers directly; a NAT'd holder is reached through the relay Guide ID its passport carries — and sends a single `FRAG_PULL` with an **empty index list**, meaning "send me whatever you hold for this CORE." Under the one-fragment-per-peer placement law the holder normally returns exactly one fragment, so discovery and download collapse into one round-trip per holder. Equal-stripe load distribution is therefore **emergent, not planned**: with a deep swarm (N holders ≈ totalFragments) every holder serves a single fragment — the BitTorrent property where per-peer serve load is bounded by one regardless of payload size. The reader dedups returned indexes against what it still needs and stops once covered; any index momentarily unfound (a holder unreachable this instant) is returned partial and healed by census (§13.4) and the next reader's re-fetch. Each fragment arrives as a `FRAG_PULL_REPLY` carrying base64-encoded (IV ‖ AES-GCM-tag ‖ ciphertext).

The reader decrypts each fragment with the AES-256-GCM key derived as BLAKE3(CORE ‖ SEAL ‖ PAC) of the parent anchor. The 96-bit nonce per fragment is BLAKE3(baseIV ‖ uint16_be(fragmentIndex))[:12] where baseIV is the IV embedded in the fragment header. The 128-bit authentication tag is checked at decryption; a tampered fragment fails the GCM tag check at `decipher.final()` and the reconstruction is *abandoned* before any plaintext leaks. There is no "best-effort decrypt"; tag failure is a fail-closed reject.

After all fragments decrypt successfully and the plaintext concatenates to the original payload, the reader writes the reconstructed bytes to a viewer cache row tagged with the anchor's CORE. Subsequent reads of the same anchor are served from cache without a mesh round trip.

### 13.4 Census and Replica Floor

The replication count of a fragment is not a property the writer guarantees; it is a property the *holders* maintain by census. Every holder of a fragment runs a *census probe* against the K_NEIGHBORHOOD candidates closest to the routing key, on a phi-progressive backoff schedule: 1 hour after first store, then phi hours, then phi-squared hours, and so on out to a 1-week stable interval and a 30-day cold interval after that. The probe is a `FRAG_CENSUS_PROBE` packet carrying (CORE, fragmentIndex, totalFragments); each receiver answers from its **actual holdings** — bloom-confirming whether it currently holds this (CORE, fragmentIndex) row — plus whether it would accept the fragment if pushed. (The receiver reports what it really has rather than re-deriving a predicted rank, since the author-excluded rank is not locally recomputable; the same actual-holdings principle discovery uses.)

The replies, summed across the K probes, give the holder a count of how many of the K-closest peer-slots are populated. **The heal condition is `count < HEAL_TARGET`** — the holder picks willing-and-able peers from the census reply, ranked by XOR closeness to the routing key, and pushes the fragment via `FRAGMENT_STORE`, at most `MAX_PUSH_PER_ROUND` (3) per round, with subsequent rounds finding more willing peers while the index is still under target. `HEAL_TARGET` is an explicit profile constant (V1_LAUNCH: FLOOR 10, HEAL_TARGET 32, REPLICATE_TRIGGER 5), not a multiple derived from FLOOR.

**`REPLICATE_TRIGGER` is the urgency line, NOT the heal threshold**, and conflating the two is the expensive misreading: it would mean an index sitting at twenty copies is left alone until it decays to five, spending the entire margin the replication was for. What TRIGGER actually governs is *cadence* — below it `nextInterval` refuses to relax and re-checks at `INITIAL_DELAY_MS`, because a fragment that close to losing its last holders must not be put on a weekly schedule; between TRIGGER and HEAL_TARGET the index is merely still growing and the backoff proceeds normally.

A fragment whose recent fetch count exceeds a fresh-fetch threshold (10 fetches over the last 7 days) skips census entirely. The interpretation is that an actively-fetched fragment is being kept alive by the swarm itself: when readers pull it, holders push it, willing peers store it. No census intervention is needed for content that is in real demand. Census intervenes for content that is held but not currently in motion — old anchors, archived payloads, low-traffic content — to ensure the floor count is maintained even when no reader is actively pulling.

### 13.5 The Cipher Contract

Every payload fragment is sealed with AES-256-GCM. The wire format on disk and across the mesh is `base64( IV(12B) ‖ TAG(16B) ‖ ciphertext )`. The key plus base IV are derived once per anchor via BLAKE3(CORE ‖ SEAL ‖ PAC); each fragment's 96-bit nonce is BLAKE3(baseIV ‖ fragmentIndex)[:12]. Decryption is fail-closed — a tampered tag throws at `decipher.final()` and the reconstruction abandons the anchor before any plaintext leaks. CBC mode, ECB mode, and any unauthenticated cipher are disallowed; the cipher contract is part of the byte-frozen protocol surface.

The CRYPT byte at position 98 selects the cipher family. V1 = `0x01` (AES-256-GCM-with-BLAKE3-KDF). A future post-AES cipher would land at CRYPT = `0x02`, with old anchors continuing to be served under their original `0x01`. There is no "fallback to a weaker cipher": a node that does not implement the requested CRYPT byte simply cannot decrypt that anchor's payloads. Section 20 covers the soft-fork lane in detail.

### 13.6 Effective Redundancy: the Three Storage Tiers

A fragment's durability is the placement FLOOR plus whoever chooses to keep it. Three storage tiers hold fragment copies, and they contribute to durability differently:

- **xor_storage** — the canonical network-duty tier. The FLOOR closest-rank holders per index, maintained forever by census (§13.4). This is the *guaranteed floor*: present for every anchor regardless of demand, healed back up to FLOOR after churn. It is the durability and immortality guarantee — every anchor, cold or hot, survives on its FLOOR.
- **vault** — permanent citizen pins. A citizen who vaults an anchor snapshots **all** of its fragments into local permanent storage at Tier-1 read priority. Each vaulter therefore adds one permanent copy to *every* index.
- **viewer_cache** — the serving tier. A reader who reconstructs a payload writes the fetched fragments to an evictable cache, and an author keeps their own payload here once it is placed on peers. These copies are **transient**: they raise serving capacity, not durability. Viewing never creates a permanent copy — xor_storage is populated solely by placement and census, never by what a citizen happens to read. Eviction ranks by demand, then last use, then age, so the copies that survive longest are the ones actually being served.

The *permanent* per-index redundancy is therefore `R = FLOOR + vaulters`. Payload recoverability under a per-holder availability `a` is

> P = ( 1 − (1 − a)^R )^F

where the exponent F — the fragment count — is a coupon-collector penalty: every one of the F indices must retain at least one live holder, because every fragment is required to reconstruct. This is precisely why file size governs durability and not only discovery. Modelled over the tiers with the fragment counts the √-law actually produces, a one-gigabyte file (F = 363) at FLOOR = 10 recovers about 100% of the time at 80% holder availability, 70% at 50%, and effectively 0% at 20%; a ten-gigabyte film (F = 2,560) at the same floor recovers about 100% / 8% / 0%. The bare floor is ample for a healthy mesh — availability at or above 80% recovers everything, including the largest films — but the coupon-collector tax makes a multi-thousand-fragment film genuinely fragile under heavy churn.

Two knobs close that gap. For content people care about, **vault** is the durability lever: five vaulters lift the ten-gigabyte film from 8% to about 92% recoverability at 50% availability; twenty lift it past 99%; a hundred make it durable (~100%) even at 20% availability. For huge *cold* archival payloads that must survive cataclysmic churn with nobody to pin them, the lever is the **FLOOR profile** itself — the PRODUCTION_20 and PRODUCTION_32 presets raise the guaranteed floor at a linear cost in author upload and network storage. Content that nobody pins and nobody watches sits at exactly the FLOOR, and census keeps it there — which is the whole point: the overwhelming majority of anchors (a vote, a one-shot post) are never re-fetched after they go live, and their immortality rests entirely and sufficiently on the census-healed FLOOR.

The serving tier scales the opposite way, and a scheduler is what makes that true rather than merely hoped for. **A complete copy — a vault pin, or a cache that happens to hold every index — is the best thing to find and the worst thing to drain.** One hit on it answers every index at once, which is exactly what makes discovery cost independent of fragment count. But rank it first for *bytes* and every reader pulls the whole payload from that one node: a ten-gigabyte film served to a thousand citizens is ten terabytes out of a single uplink, worse than the problem the source list was built to solve. A canonical holder is the opposite — it carries one fragment by XOR rank, precisely the load the placement law sized for, and there are FLOOR × F of them.

So the reader schedules the fetch: **canonical holders carry the bulk, complete copies fill only the gap routing could not reach, and several complete copies split that gap between them.** More complete copies therefore mean *less* work each rather than a bigger target, and the per-holder pull load falls toward F / V as V viewers accumulate. Within a request the scarcest indexes go first, so a fragment only one node can serve is taken while that node is in hand. Each request takes roughly its fair share of what is left — without that, the first complete copy the reader reached would claim everything and "more copies means less work each" would quietly become "the first copy does it all". The ceiling on one request is denominated in **bytes, not rows**, because fragment size grows with payload: a fixed row cap bounds two megabytes of a post and a gigabyte of a film. It shapes each ask without ever refusing delivery — a source is simply asked again for the rest, since a payload missing one index does not open at all.

**The decision is made when each request is sent, not once at the start.** An assignment written before the first fragment lands is stale immediately: sources hand back more than they were asked for, and every early arrival makes some later source's share redundant, so a frozen plan re-requests fragments already in hand and pays for them twice. A source whose whole share has already arrived is skipped without a packet.

**Searching and downloading run together.** The reader does not wait for the search to finish before pulling: holders stream back as replies arrive, the schedule absorbs them mid-fetch, and the download keeps spreading across nodes as more are found. Phasing the two costs the entire search window on an idle link — the discovery deadline scales with fragment count, so a large payload whose last holder is slow to surface would otherwise sit for tens of seconds before its first request went out, and nothing about the first holder found requires the last one to be known. When the search ends, the reader finishes with the sources it has.

**Two things spread the load, and the ordinary case is the second.**

First, a holder says how busy it is. A reader balances beautifully across the sources it knows about and cannot see that five hundred other citizens are pulling the same film from the same holder at that moment. Only the holder knows, so each reports a coarse idle / normal / busy bucket with its reply, measured in **bytes served** rather than fragments served — fragment size spans 8 KB to 4 MB, so a count would call half a megabyte of small posts busy and a quarter of a gigabyte of film normal, steering traffic away from nodes doing almost nothing and into nodes with nothing left to give. It is deliberately a property of the **node**, not the content: a holder swamped serving other files is swamped regardless of this payload, and a per-content "last downloaded" would hand anyone a cheap way to learn when a specific anchor is being read, and by roughly how many people. Being self-reported it orders sources and never excludes one — a busy holder is still asked when nothing else can serve a fragment, so claiming to be busy forever buys a node less traffic and never makes its fragments unreachable.

Second, and more important at ordinary traffic: **among equally good holders the choice is random per fetch.** At any normal serving rate every holder reports idle, so ties are the common case rather than the edge. A fixed tiebreak — alphabetical, or by any other shared rule — means every reader on Earth computes the same "best" holder for a fragment and sends all of its traffic there while the other nine sit idle; the load signal only rescues that after the favourite is already saturated, and does nothing at all below its first threshold. Determinism is a property PHEUN needs for *consensus* — two nodes must agree on byte order, on a routing bucket, on a canonical genesis — and choosing whom to download from is not consensus. Here agreement is precisely the failure. The random key is fixed per source for the length of one fetch, so the order is stable while a download runs and differs between fetches and between nodes. Coarse buckets and random tiebreaks work together: the signal only redirects traffic when a holder is a whole bucket quieter than its peers, and inside a bucket the randomness spreads it.

**Requests run in parallel, and the parallelism is what makes fetch time track round trips instead of holder count.** A ten-gigabyte film is about 2,560 fragments on about 2,560 holders; one at a time is one round trip each with the link idle between them — over two minutes at a fifty-millisecond round trip, for a payload whose holders were located in roughly half a second. A bounded number are in flight at once, because every pull can carry megabytes and opening thousands would exceed the congestion window and ask a phone to hold gigabytes. An index is claimed before its request goes out, so two workers never buy the same fragment; and a source that fails releases its indexes back so another takes them *inside the same fetch*, rather than costing a full discovery round to re-learn holders already known.

Popularity therefore buys download *speed*; durability comes from the FLOOR underneath everything plus voluntary vaulting — guaranteed where it must be, earned where someone chooses to keep it.

---

## 14. PAC Chains and Fork Detection

The Personal Anchor Chain — PAC — is the only chain in PHEUN that is cryptographically walked. It is per-Guide-ID, append-only, and pinned by a 32-byte pointer (PAC, bytes 125–156) and a 4-byte monotonic counter (PAC_COUNT, bytes 157–160) in every anchor.

### 14.1 The Append Rule

Every anchor that any Guide ID signs after its Genesis Profile must satisfy:

> anchor_n.PAC = BLAKE3( anchor_{n-1}.bytes )
> anchor_n.PAC_COUNT = anchor_{n-1}.PAC_COUNT + 1

That is, the PAC field of a new anchor is the BLAKE3 hash of the *full* 420 bytes of its predecessor; the PAC_COUNT field is exactly one more than the predecessor's. The Genesis Profile itself starts the chain at PAC_COUNT = 1, with its PAC field containing 32 zero bytes (no predecessor).

The chain is *walkable*: a reader given a Guide ID's tip anchor can recover the predecessor's CORE by querying `anchor-by-core(tip.PAC)`, then recurse to retrieve any anchor in the citizen's history. The walk is bounded: by Vision-imposed hard cap, no Guide ID may exceed 50 years times 144 anchors per day equals approximately 2.6 million anchors total. This bound is large enough for any plausible human use over a single lifetime and small enough to keep the worst-case walk tractable.

### 14.2 Forks

A *fork* in a Guide ID's AnchorChain is the existence of two anchors that satisfy:

> a.GUIDE = b.GUIDE ∧ a.PAC_COUNT = b.PAC_COUNT ∧ a.CORE ≠ b.CORE

That is, two anchors signed by the same Guide ID, with the same PAC counter, but different CORE hashes. Such a fork can only occur if the same Guide ID's keypair signed two distinct anchors at the same chain position. Because Guide ID derivation is deterministic from nine personal inputs, any two devices with those nine inputs can independently mint anchors at the same PAC counter if they are not synchronised on the chain's tip.

Forks are *categorically* irrecoverable. A forked Guide ID is, by Vision principle 31, dead by design. There is no protocol path to "merge" two AnchorChains at the same counter; there is no admin override that picks a winner; there is no recovery flow that lets the citizen re-claim either branch. The citizen creates a new Guide ID and accepts that the old chain is sealed — readable by any reader who finds it on the mesh, but inert for any further use.

### 14.3 Three-Layer Detection

PHEUN's V1 ships three independent fork-detection layers:

**Layer 1 — Login walk.** Every successful Guide ID attestation runs a full PAC walk before the session is issued. The walk pulls every anchor under the citizen's Guide ID via the global query engine (Section 17), filtered by `guide` plus a PAC_COUNT range, indexed by a `guide_pac_idx` database index for cheap retrieval. If two anchors at the same PAC_COUNT with different CORE are found during the walk, the walker writes a `pac_locks` row keyed by the Guide ID, refuses the login with HTTP 423 (Locked), and surfaces the locked-Guide-ID modal to the citizen. The walk runs forward batches in 30-day windows, stopping on either an empty batch (chain caught up), a fork detected (lock written), or a budget exhaustion (50-year cap reached without conflict).

**Layer 2 — Auto-engaged self-subscription.** Every authenticated node SAI-Peer-Subscribes to its own Guide ID via the SPS system (Section 16). This means every future anchor minted under this Guide ID, anywhere on the mesh, is forwarded back to this node within 1 to 120 seconds of its birth via `SUBSCRIPTION_FORWARD`. When that forward arrives, the node ingests the anchor through the same fork-detection ingest path the login walker uses; if the forwarded anchor conflicts with an already-stored anchor at the same PAC_COUNT, the lock is written within seconds of the conflict appearing on the mesh. The currently-authenticated session is killed at the next request via the request-time PAC lock check (the `requireAuth` middleware checks `pac_locks` on every authenticated request), so a citizen mid-session who self-forks on another device sees the lock take effect almost immediately.

**Layer 3 — Local mint hook.** When this node mints a new anchor under its own citizen's Guide ID, the anchor is passed to the same fork-detection ingest function that gossip-cascade and sync-pull use, with a `mintedLocally=true` flag, *before* the anchor is announced to its home holders. This ensures the local fork detector observes the local mint immediately, before any race with an inbound forwarded anchor from another device. It also enables the user-interface to distinguish "you just posted" (mintedLocally=true) from "another device of yours posted" (mintedLocally=false) in the synchronisation indicator.

### 14.4 Detection Is a Property of the Chain

A subtle but critical property is that every node walking the same chain arrives at the same fork verdict *independently*. The lock is local to each node's `pac_locks` table, but the chain itself is replicated across the mesh, so two nodes that have both observed the conflicting anchors will both write the lock without any coordination between them. There is no broadcast of fork events; there is no admin override; there is no recovery path. The chain is the network's truth, and every node walks the same chain.

Once a Guide ID is locked on this node, the request-time `requireAuth` middleware returns HTTP 423 for any authenticated mutation under that Guide ID. The session is killed, the locked-Guide-ID modal is surfaced to the citizen, and the device-binding lock file (`data/guide-id.lock`) remains in place. The citizen's only recovery is to physically delete `data/guide-id.lock` on the device they own and create a new Guide ID. The sealed history of the old Guide ID stays on the mesh forever; new anchors under the new Guide ID start a fresh AnchorChain.

---

## 15. Document Governance

Democracy is the only governance machinery in PHEUN. Both governed documents — the Digital Constitution and the network's Curriculum — use the same proposal, vote, and consensus pipeline, scoped by SIGN. The protocol does not implement separate governance flows for separate document classes; the machinery that ratifies a constitutional clause is the machinery that ratifies a curriculum line.

### 15.1 The Democracy Category

All governance anchors carry category byte `0x04`, and three types do all the work. TYPE is a single global 256-slot namespace whose byte *ranges* encode the category — `0x60`–`0x7F` is Democracy's range — so the type byte alone identifies a governance anchor and the dispatcher matches on (TYPE, FLAGS) without consulting CATEGORY:

- Type `0x60` — Proposal. A new line in the document, or an amendment to an existing line.
- Type `0x61` — Yes vote. A ballot in favour.
- Type `0x62` — No vote. A ballot against.

A fourth type sits outside the Democracy range because it is not Democracy-specific: type `0x00`, Genesis Sign, is the universal document opener, valid in any category.

A flags byte at position 240 distinguishes three lifecycle phases for votes:

- `0x00` — Regular ballot (a yes or no vote during the voting window).
- `0x01` — Consensus lock (a final, post-window verdict that the document's outline records).
- `0x02` — Tally checkpoint (an intermediate snapshot of the running yes/no count).

The dispatcher (Section 6) routes proposals and consensus locks to SAI(SIGN) — co-located with the document outline. Tally checkpoints route to SAI(LINK), which equals SAI(proposal.CORE), so all checkpoints for a single proposal cluster on one Sacred Anchor Index regardless of how many proposals share the same SIGN. Regular ballots route to SAI(CORE), scattered across the 10,000 buckets, so a viral proposal with millions of votes does not cook any single SAI. The split is what lets the protocol absorb a billion-vote proposal without saturating any one bucket.

### 15.2 The Document Namespace Is Closed

Every governed document is identified by a SIGN, the single byte at position 277 of every anchor. It holds an id from a registry compiled into every node — `0x00` no document, `0x01` Constitution, `0x02` Curriculum, `0x03`–`0xFF` unallocated — so a document's identity is a compile-time constant rather than a name a citizen claims.

This is a deliberate narrowing. An earlier design made SIGN a 16-byte UTF-8 name that any citizen could claim first-wins, which could not deliver the property a governed document actually needs: that every citizen is reading, amending and voting on the *same* one. Two citizens who wrote `constitution` and `Constitution` opened two documents. Two who raced the same name from opposite sides of the mesh opened two that both looked canonical, and — anchors being permanent — both persisted. The name also became the prize, its value accruing to whoever minted first, which is the squatting surface the protocol refuses everywhere else.

A closed namespace removes the race entirely. It costs 253 unallocated ids and a code change to spend one; a new institution is thereby a deliberation rather than a form submission. A document's first anchor can be minted only from that document's own page, which is the sole surface that knows which document it is, and the mint refuses any non-governance anchor that carries a non-zero SIGN.

### A Document Is Opened Once, and the Check Fails Closed on Both Sides

A Genesis Sign (any category, type `0x00`) dispatches to SAI(BLAKE3(sign)), so every opener for a document lands in one bucket and a single Sacred Anchor Index query answers "is this document already open?".

That query has three outcomes, not two, and conflating the last two is what makes an open-once rule fail open. An opener came back; no opener came back *and holders answered*; or **nobody answered at all**. Silence is not evidence of absence — a node that treats an unanswered query as "unopened" will happily mint a second opener for a document that already exists. So the read returns the answer *and* whether the answer was proven, and both consumers refuse an unproven absence: the mint rejects with `GENESIS_EXISTS` when it can prove an opener exists and with `GENESIS_UNVERIFIABLE` when it cannot prove one is absent, and a document's page offers "open this document" only on a *proven* absence. The page also stops offering it the instant this citizen's own opener is signed, because an anchor is not queryable until its home holders admit it, and that propagation gap is exactly when a duplicate gets minted.

**The propagation layer does not enforce uniqueness, deliberately.** Self-Verifying Anchor Propagation admits a second opener with no uniqueness rejection, because rejecting one there would be arrival-order dependent: a holder that had already seen the sibling would refuse while a holder that had not would accept, so two honest nodes would reach different verdicts and permanently disagree about the bucket's contents. Uniqueness that diverges the mesh is worse than no uniqueness at all.

**The reader is decisive instead.** Two nodes partitioned from each other can each mint an opener, and anchors are permanent (Section 4), so both persist forever. Every node therefore picks the canonical opener by the same pure rule — earliest TIME, with the CORE compared ascending to break a tie. The tiebreak is load-bearing rather than decorative: TIME is in milliseconds, so genuine ties happen, and without a second key the winner would be whatever order a mesh query happened to merge results in. With it, every node on Earth renders the same document and the loser is inert — a permanent anchor that no reader treats as the opener. This is the same first-claim-wins rule that governs Guide ID ownership.

The result is that a SIGN resolves to one document for every citizen, enforced as a property of the dispatcher plus a deterministic reader rule rather than by a registry an operator maintains. There is no second Constitution and no second Curriculum — not because the protocol can prevent a duplicate anchor from existing, but because it guarantees every node agrees on which one counts.

### 15.3 The Document Line and Version Model

A document is composed of *lines*, each carrying a *version*. The two fields LINE (bytes 225–227, 24-bit) and LINE_VERSION (bytes 228–229, 16-bit) give every document up to 16.7 million lines, with up to 65,535 revisions per line.

The lifecycle is straightforward:

1. *Genesis Sign opens the document.* Its LINE is 0; LINE_VERSION is unused. The Genesis Sign's SIGN field defines the document's identity.

2. *A new-line proposal targets the next available LINE.* When a citizen proposes adding a line to the document, the proposal's LINE is set to the maximum existing LINE plus one; LINE_VERSION is 1. The proposal is a Democracy proposal anchor (cat `0x04` type `0x60` flags `0x00`) routed to SAI(SIGN). A new line may only be opened once the current top line has reached an approved consensus — otherwise a citizen could stack lines 2, 3 and 4 while line 1 is still unratified, filling the document with competing lines that never lock.

3. *An amendment proposal targets an existing LINE.* When a citizen proposes changing line K of the document, the amendment's LINE is K and LINE_VERSION is the maximum existing version for that line plus one. Line 0 is the exception: the genesis is the opener, not content, and is not amendable — to change what a document opens with, propose a new line.

4. *Consensus locks declare a (LINE, LINE_VERSION) canonical.* When a proposal passes its voting window with at least 75% yes, any citizen can finalise it via the Verify Proposal action. The finaliser mints a consensus anchor (cat `0x04` type `0x61` flags `0x01` for approval, type `0x62` flags `0x01` for denial), routed to SAI(SIGN). This consensus anchor declares that the (LINE, LINE_VERSION) pair is now the canonical content of that line.

5. *Subsequent amendments to the same LINE bump LINE_VERSION again.* The document's history grows monotonically: every line carries its full version chain, with the latest consensus-locked version being the canonical one for rendering.

The page that renders a document walks lines 1 through N, showing the latest consensus-locked version per line, with active proposals annotated as "amendment in progress." A single Sacred Anchor Index query against SAI(SIGN) returns the document's complete outline — the genesis, every proposal ever made against it, and every consensus verdict — in one round trip.

### 15.4 The 75 % Threshold and the Participation Quorum

Approval requires 75 % yes of the total ballots cast within the voting window — **and, separately, that enough ballots were cast at all.**

The second requirement is not a refinement of the first; without it the first is not a gate. One yes vote and no opposition is 100 %, so a threshold alone would let a single citizen amend the Constitution unopposed. Every approval must therefore clear two independent tests: how much of the turnout agreed, and whether there was a turnout to speak of.

**The quorum is derived from the document's own history rather than fixed.** A minimum meaningful for a network of fifty is meaningless for fifty million, and any constant chosen at design time is wrong at one end or the other. The bar is the median yes-count of the document's last five approvals, less a 10 % tolerance for the ordinary variation between votes, and never below an absolute floor of five yes votes:

> requiredYes = max( 5, ⌈ median(last 5 approvals' ACCORD) × 0.90 ⌉ )

Three properties of that formula are load-bearing.

*The median, not the maximum.* A maximum falls only when an approval lands. If participation declined after one unusually well-attended vote, nothing could pass — and because nothing passed, the bar could never come down. The document would be permanently frozen, with no path back that did not involve changing the software. A median moves with the body of recent history instead of its high-water mark, so one burst cannot set an unreachable standard and a genuine decline is tracked rather than fought.

The rate at which it is tracked is the tolerance itself. Because the bar is 90 % of the median, each approval enters the history at roughly 90 % of the one before it, and the bar steps down about a tenth per turnover of the window — 90, 81, 73, 66, 60, and so on toward the floor. A shrinking network therefore keeps governing itself, so long as participation does not fall by more than a tenth between approvals; a collapse steeper than that would outrun the glide and stall until turnout recovered. At the scale the protocol is built for, a drop of that severity inside a single seven-day window is not a realistic failure mode, and the tolerance is one constant on the soft-fork lane (Section 20) if it ever becomes one.

*Document-wide, not per-line.* The window spans every recent approval under the document, so a second line must clear the bar the first line set, and so must every subsequent version of a line. Scoping the window per line would let a citizen open a fresh line purely to escape the standard the document had already established.

*The floor closes the bootstrap case.* A document with no approvals has no history to derive from, so without an absolute minimum the first amendment would pass on a single vote and then set the bar near zero for everything after it.

The arithmetic is integer-only and takes the lower middle on even samples, because every node recomputes the bar independently and must reach an identical verdict (Vision principle 22); averaging two middle values would introduce a rounding decision that nodes could make differently.

The quorum gates approval only. A proposal that misses it is simply not approved, while denial remains available so a failed proposal can be closed and its author can amend and try again — gating both would leave an under-attended proposal impossible to resolve in either direction, and the line behind it could never advance.

The threshold itself is computed from the on-chain ACCORD and DISSENT bytes of the latest tally checkpoint. The voting window defaults to 7 days from the proposal's mint time, but is configurable per document via the document's own governance parameters (which are themselves a SIGN-scoped governable). The threshold is computed from the on-chain ACCORD and DISSENT bytes of the latest tally checkpoint:

> ACCORD / (ACCORD + DISSENT) ≥ 0.75

The on-chain tally is updated by tally checkpoint anchors (FLAGS = `0x02`). Any citizen can run the count fanout — a global query against the proposal's CORE that aggregates yes and no ballot anchors across the 10,000 SAIs — and promote the resulting numbers to a tally checkpoint. The checkpoint is signed by the citizen who ran the count and routed to SAI(LINK) so all checkpoints for one proposal cluster on a single SAI for cheap retrieval.

Finalisation requires an explicit Verify Proposal action by any citizen. There is no auto-finalisation: two code paths producing a consensus anchor for the same proposal would be a determinism violation (Vision principle 22). The finaliser's consensus anchor (FLAGS = `0x01`) is rejected if the voting window is not yet closed, if a prior FLAGS = `0x01` anchor exists for the same LINK, if the SIGN does not match the proposal's document, if the on-chain tally does not meet the 75 % threshold, or — for an approval — if the yes-count falls short of the participation quorum.

### 15.5 The Constitution Posture

PHEUN ships without an age check, ID upload, phone binding, email confirmation, or any other pre-participation gate. The Digital Constitution is itself an anchor — the Genesis Sign for the document SIGN `"constitution"`. Rules of conduct can be added, amended, or rescinded by the citizenry at the same 75 % threshold as any other governed document. The protocol enforces nothing technically: there is no kill-switch, no admin override, no global delete, no content filter, no allowlist, no flag, no moderator. Enforcement is social, legal, and constitutional, never coded.

This is the cost of an open permissionless network and PHEUN owns it explicitly: the protocol provides the substrate; humans, courts, and constitutional amendments do the rest. A community that chooses to ratify a rule against a particular kind of content can do so; the protocol records the rule on the chain; enforcement happens off-protocol.

---

## 16. Subscriptions and Discovery

There is no algorithmic feed in PHEUN. There is no recommender, no engagement-optimised ranking, no editor, no human moderator, no content team. Discovery is the protocol itself: a citizen subscribes to the Guide IDs, hashtags, document SIGNs, link chains, and stream origins they care about; every future matching anchor flows back into their feed in 1 to 120 seconds.

### 16.1 The Five Subscription Types

PHEUN exposes five subscription types, each filtering on a different field of the 420-byte anchor:

1. **Guide ID** — every future anchor signed by a specific Guide ID. Subscribing to `nateofearth2100z` yields every post, comment, vote, message wrapper, and economy offer the citizen with that Guide ID ever signs.

2. **SIGN** — every future anchor under a specific document SIGN. Subscribing to SIGN `"constitution"` yields every proposal, vote, consensus lock, and tally checkpoint against the Constitution.

3. **Hashtag** — every future anchor whose HASHTAG field matches. The HASHTAG field is dual-purpose: a `#hashtag` for topic discovery, or an `@mention` for being notified when someone tags you specifically.

4. **Link chain** — every future anchor whose LINK field equals a specific anchor's CORE. A subscription to a parent post's CORE yields every comment and reply on that post.

5. **Origin (stream)** — every future anchor whose ORIGIN field equals a specific genesis CORE. A subscription to a thread's origin yields every message in that thread, even ones whose LINK chain has branched away from the original line of reply.

The five types are uniform across categories. A subscription to a Guide ID returns anchors of *every* category from that citizen, not just one. A subscription to a SIGN returns anchors targeted at that document regardless of who signed them. A subscription to a hashtag spans Social, Knowledge, Education, Economy — anywhere the tag appears.

### 16.2 SPS — SAI-Peer Subscription Election

A naïve subscription system would register each subscription with every peer covering every Sacred Anchor Index, so that any anchor matching the filter on any peer's SAI bucket is forwarded to the subscriber. At billion-user scale, with 10,000 SAIs and an average citizen carrying perhaps 200 active subscriptions, this would require 200 × 10,000 = 2 million registrations per citizen, with proportional bandwidth at handshake time and proportional state at every covering peer.

PHEUN avoids that scaling cost through the *SAI-Peer Subscription* election, abbreviated SPS. Instead of registering with every covering peer, a node elects *one peer per SAI* it needs coverage for, sends that peer its bundled filter set via a `SUBSCRIPTION_FORWARD` register, and re-elects automatically when the elected peer drops. The bundled filter set is a single bloom-filter-backed registration covering all of the citizen's subscriptions of all five types; the elected peer evaluates incoming anchors at its SAI bucket against the bloom and forwards matches back to the subscriber via `SUBSCRIPTION_FORWARD`.

A node that wishes to subscribe to all five subscription types for various values therefore registers, in total, one filter bundle per Sacred Anchor Index — at most 10,000 elected peers. Coverage policy is uniform: every subscription type covers all 10,000 SAIs, because anchors of any category can land at any SAI under the dispatcher's rules. Per-SAI contracts are keyed by SAI rather than by individual subscription, so adding subscription types or values does not multiply contract count — it just enlarges the bundled filter at each elected peer.

### 16.3 Re-Election

The elected peer for any SAI may drop for several reasons: it goes offline, it is evicted from the passport cache, or it loses its session. The SPS system detects the drop in two ways:

- *Sub-second detection via explicit disconnect.* When the HOPE node observes a peer disconnect (an explicit close, a TCP-equivalent FIN at the UDP layer, a passport eviction in the cache), it fires `spsService.onPeerDisconnect` for the lost peer. SPS scans its contracts for any SAI where the lost peer was the elected one, and fires re-election for those SAIs.

- *30-second safety net via verifyContracts.* A periodic 30-second tick runs `verifyContracts` over all SAIs the node is subscribed to. For any SAI whose elected peer is no longer in the live mesh or is no longer fresh in the passport cache, re-election fires. This catches passport-cache eviction between explicit-disconnect events (a peer that silently times out without sending a disconnect packet).

Re-election picks a fresh peer for the SAI from the SAI Manager (the protocol's coverage layer; Section 24), registers the bundled filter with the new peer via SUBSCRIPTION_FORWARD register, and updates the local contract record. The window between an old peer's drop and a new peer's registration is bounded by the safety-net tick (worst case 30 seconds) for silent timeouts and by the sub-second detection path for explicit drops.

A contract gap longer than 30 seconds for any SAI indicates the LOCATE chain has not yet found a covering peer for that SAI — surfaced as an `uncoveredSIs` count on the system metrics endpoint. The SAI Manager (Section 24) is the authority that finds covering peers; SPS is the authority that elects one of them per SAI for subscription forwarding.

### 16.4 Bundled Filter Bloom

The SPS bundled filter is a Bloom filter sized for high subscription counts at low false-positive rate. The current configuration is a 64-kilobyte filter with 4 BLAKE3-derived hash functions, giving approximately 210 million entries at less than 0.1 % false-positive rate. This is more than enough for any plausible single citizen's subscription set — a citizen subscribing to 100,000 Guide IDs plus 10,000 hashtags plus 1000 documents fits comfortably under the 210-million entry budget.

The bloom is rebuilt from the contract list on subscription change and shipped to the elected peer in the registration packet. The elected peer evaluates each anchor that lands in its SAI bucket against the bloom; a hit triggers a `SUBSCRIPTION_FORWARD` of the anchor back to the subscriber. False positives — anchors that match the bloom but not the underlying filter — are rejected at the subscriber's local filter check after the forward arrives, so the bloom does not need to be perfect; it just needs to be cheap and small.

### 16.5 Discovery Without an Index

PHEUN has no central index. There is no search engine that crawls the mesh; there is no operator-maintained directory; there is no cached snapshot that any citizen could be compelled to share. Discovery happens through three vectors:

- *Subscription forwarding.* Future anchors flow through the SPS pipeline described above. A citizen's feed is the union of every SUBSCRIPTION_FORWARD they receive, sorted by TIME with deterministic tie-breaks.

- *Word-of-mouth Guide ID share.* A 16-character Guide ID handed off out-of-band (a business card, a verbal exchange, a search of a person's name on the off-protocol web) unlocks discovery of every anchor that Guide ID has ever signed — past, present, and future.

- *Global query for back-fill.* For old anchors from before a subscription was set up, the citizen issues a global query (Section 17) against the relevant filter and pulls the historical anchors in.

The combined effect is a discovery layer that has the latency of a subscription system (1 to 120 seconds for new anchors) and the back-fill capability of a global search (15 seconds for any historical query against the entire mesh), without ever requiring a central operator to maintain an index or rank results.

---

## 17. The Global Query Engine

Every search, feed back-fill, research lookup, governance count, profile pull, and lineage query in PHEUN flows through a single unified two-phase per-Sacred-Index fanout. The query engine is the network's primary read path: a citizen asks "find me every anchor matching this filter across the whole mesh"; the engine fans out announces, allocates a per-peer pull budget by the golden ratio, pulls the anchors back, and returns the result in approximately 15 seconds.

### 17.1 The Two-Phase Fanout

A query begins with a *filter*: a structured predicate over anchor fields (any combination of Guide ID, SIGN, HASHTAG, LINK, ORIGIN, category, type, flags, language, zone, content tags, time range, or other indexable bytes), narrowing in both directions — see Section 17.3. The filter is hashed (BLAKE3) to produce a stable filter ID used for de-duplication of overlapping queries from the same node.

**Phase 1 — Announce and count.** The engine sends one `QUERY_ANNOUNCE` packet per Sacred Anchor Index, addressed to a peer covering that SAI from the requester's passport cache. Each announce carries the queryId, the SAI, and the filter bytes. The covering peer runs a count-only query against its local SAI bucket using the SQL field extractors that map filter fields to indexed Postgres expressions. The peer replies with a `QUERY_COUNT_REPLY` packet carrying the queryId, the SAI, and the match count.

The announce phase has a per-peer timeout of 2 seconds (`ANNOUNCE_TIMEOUT_MS`). A peer that has not replied within the budget is treated as "unknown count, 0 allocation" for the pull phase. The first node that has all 10,000 announces complete (or has enough timeouts to bound the remaining unknown count) proceeds to phase 2.

**Phase 2 — PHI-allocated pull.** With per-SAI counts in hand, the engine allocates the pull budget across SAIs by the golden ratio. The total budget comes from the read's contract (Section 17.2) rather than from the call site. The allocation is rebalanced so that *when the matched anchors exceed the budget* no single peer ships more than `perPeerPhiCap(budget) = floor(budget / phi)` — at a 10,000 budget, approximately 6,180 anchors, so no peer dominates more than 62 % of a contested result.

That cap applies **only under contention**, which is the distinction that makes it a fairness rule rather than a ceiling. When the census total fits inside the budget there is nothing to ration: every matching anchor is wanted, and capping a peer that happens to hold most of them would discard anchors the query asked for and nobody was competing over. A document whose entire history lives on one Sacred Anchor Index is precisely that case, and a cap applied unconditionally would have silently cut it to 62 %.

For each SAI with a non-zero allocated share, the engine sends a `QUERY_PULL` packet to the same covering peer, asking for the allocated number of matching anchors. The peer pulls the matching rows from its local SAI bucket and replies with one or more `QUERY_PULL_REPLY` packets. Replies that exceed the MTU are chunked via the application-level chunking layer (Section 9.6).

**A pull is continued, not issued once.** `QUERY_PULL` carries an `offset`, and a peer answers at most `PULL_MAX_PER_REQUEST` anchors per request — a bound on the work one request may ask of one peer, not on what a query can retrieve. The requester re-issues the pull from where the previous reply ended until the peer is exhausted. Without that continuation the per-request bound silently becomes the ceiling on an entire document's history.

Timeouts are derived from the work actually requested rather than fixed. A peer answers in pages of `PULL_PAGE_SIZE` separated by `PULL_PAGE_DELAY_MS`, so the inter-page delay alone puts a floor on how long a large answer takes — five thousand pages for a million anchors is over two minutes of pure pacing, against a flat 8-second timeout sized for a feed. The failure that produces is quiet and therefore dangerous: the pull times out, a partial result returns, and a caller renders half a Constitution as though it were whole. `pullDeadlineMsFor` and `queryDeadlineMsFor` scale the deadline with the page count; small queries keep the ordinary fixed constants.

### 17.2 What a Read Promises — Slice or Complete

A read is one of exactly two things, and conflating them is what let six separate layers each pick their own limit without knowing about the others: the budget clamp, the golden-ratio per-peer cap, the pull offset, the deadline, the truncation flag, and the result cache's byte ceiling.

A **slice** is a page of something larger. A feed and a search are slices, and their cap is a decision about the citizen rather than about correctness: ten thousand anchors is more than anyone reads at once, so coming back capped is the ordinary, expected outcome and nothing is wrong when one is short. A comment thread is a slice too — replies dispatch to SAI(LINK), so a widely-read anchor gathers as many children as the world cares to write, and the interface says "showing 50 of N", which is the honest shape of a page.

A **complete** read is the opposite: the subject *is* the answer, and a partial one is not a smaller answer but a wrong one. A governed document and a citizen's Guide chain are complete reads. A Constitution missing its recent amendments does not look truncated to a reader; it looks as though those amendments were never made. A chain with a silent hole does not look like a shorter life; each anchor names its predecessor, so a gap reads as a break in what the citizen signed. Both must retrieve everything they can and then be honest about whatever is missing — never quietly hand back a prefix as though it were the whole, and never cache one.

**What the two do when the repair still falls short differs, and the difference is the reader's stake in it.** A document is refused: a governed text that renders without its latest amendment misinforms every citizen who reads it, and there is no way to display the absence that a reader would reliably notice. A chain is shown, with the missing positions named. Nearly all of a citizen's history is far more use than an error page, and naming the gap costs nothing — the reader can see exactly which positions have not landed and refresh to pull them again, which is a much better bargain than being shown nothing because one anchor of a million was in flight.

Every read surface declares which it is, once, in a single table (`READ_CONTRACTS`), and every call into the engine names its surface rather than reaching for whichever constant is nearest. Adding a surface means adding a row, which forces the question to be answered in the open. A client's requested `limit` narrows a slice, which is exactly right — asking for two hundred search results should cost two hundred — but it may never narrow a complete read, because there it is a second ceiling underneath the contract's, and a chain capped at the client's own number while still reporting itself whole is precisely the failure the contract exists to prevent.

**A complete read repairs itself.** Every cause of a short one is transient: a peer left between the census and the pull, a datagram page dropped, a pull overran its deadline. None of them means the subject is damaged, so the engine re-runs the whole round rather than handing back a short answer with a flag — a flag only moves the retry into every call site, and the sites that forget it render the partial.

**A Guide chain does better than retrying: it proves completeness rather than asking for it.** PAC_COUNT is monotonic from one with no gaps, ever, so the anchors that arrived say for themselves whether any are missing — positions one through the highest held, checked locally, trusting no peer. A census total is a peer's claim and can be wrong in both directions: inflated, it makes a whole chain look short forever; under-reported, it hides a hole. Contiguity cannot be wrong in either. And because the proof names the missing positions exactly, the repair is exact too — the engine re-pulls that span by PAC_COUNT range over the chain's own index rather than fetching a lifetime again, so a hole costs the mesh the hole and not the chain. Anything still missing after the repair is reported alongside the anchors, and a short chain is never cached, because re-opening the page is the citizen's cheapest retry and caching the hole would take it away from them.

### 17.3 Filtering Narrows in Both Directions

A filter composes any of the anchor's indexable bytes, and each family exists in both a positive and a negative form. Exclusions answer "not this": specific Guide IDs, categories, types, tags, languages, maturity ratings, zones, documents, hashtags, or Sacred Anchor Indexes to keep out of the result. Inclusions answer the question a person actually asks: show me *this*.

The positive half is not a convenience. With subtraction alone, narrowing to a single subject means excluding the other 255 tag codes — across ten tag slots per anchor that is 2,550 conditions to express "show me art", and it inverts the shape of the question being asked.

The two compose by conjunction, with exclusion acting as a veto. Asking for art while excluding violence drops an anchor that carries both, which is what a person means by that pair. Within a list the semantics are disjunctive — an anchor qualifies if any of its ten tag slots holds any listed tag — and a separate intersection form requires an anchor to carry *all* of a named set. The difference is the difference between browsing and research: a union of three tags widens as the list grows, while an intersection of three narrows, which is the only way to isolate a small body of work out of a century of anchors. Ten slots per anchor make that meaningful, since three required tags still leave seven free.

### 17.4 The Requester Never Reads Its Own DB

A subtle but architecturally critical rule: even the Sacred Anchor Index this node owns is queried through an outbound announce-and-pull cycle against the peer that covers it, never by reading the local table directly. A node with one Sacred Anchor Index cannot trust *itself* as a query source, because trust would presume the node had already verified its own data through some other channel — which it has not, except by virtue of having received those anchors from peers via gossip cascade or sync.

Every query is a network operation. This is what makes the query engine deterministic across the mesh: any two nodes issuing the same query at the same time, with the same passport-cache view of covering peers, get identical results modulo the per-peer flake allowed by the timeout budget. The deterministic substrate is the SAI dispatcher's placement rule (Section 6) plus the deterministic sort order within a bucket (TIME → PAC → 840-hex string).

### 17.5 Concurrency and Rate

The engine bounds in-flight queries at two layers. Per-user, the in-flight cap is 8 queries: the 9th query from the same origin Guide ID blocks until one of the first 8 drains. Per-node-globally, the in-flight cap is 512: the 513th query from any source blocks. A query that enters as a *rider* on a deduplicated filter (another query is already in-flight with the same filter hash) does not count against either cap.

Per-node *outbound* rate to any single covering peer is bounded by the query egress limiter (Section 9.5), at 240 token capacity with 60-token-per-second refill. This is "polite sender" defence: it stops a runaway query loop from this node from blasting any single covering peer with announces, while leaving honest workloads unaffected. A typical citizen's query fans out 10,000 announces across approximately 10,000 distinct covering peers (one per SAI on average), so each peer sees 1 to 2 announces from this node per query — well under the cap.

### 17.6 Filter Dedup and Riders

Two queries with the same filter hash, issued within a short window, share one network round. The first query's result is cached in the in-flight table; the second query enters as a *rider*, attaching its result-resolver callback to the first query's waiters list. When the first query resolves, every rider's resolver fires with the same result. This is what makes a UI that opens a feed in two browser tabs simultaneously a single network query rather than two. The dedup window is 5 seconds (`FILTER_DEDUP_WINDOW_MS`), long enough to absorb the round-trip plus minor UI flake.

A rider that arrives while its owner query is already past phase 2 still gets a result, because the engine resolves all riders at completion. A rider whose owner query fails or times out gets a null resolution after the rider's own timeout (bounded at QUERY_TTL_MS as a safety against owner cleanup races).

### 17.7 Coverage Reporting

Every query result carries a coverage report: the count of covering peers that replied with a count, the count that timed out, the SAI identifiers that had no covering peer at all. The user interface uses this to render the result with a clear "result is partial" indicator when coverage is incomplete: a query that hit only 9,500 of 10,000 SAIs is not a wrong result, it is a result with 95 % coverage, and the citizen can choose to retry, narrow the filter, or accept the partial.

Partial coverage is a normal operating mode at small mesh sizes (during bootstrap) and an exception at large mesh sizes (where 99 %+ coverage is the typical case). The coverage report makes the partiality explicit rather than silently truncating, which prevents the "where's the rest of my result?" confusion that plagues centralised search.

### 17.8 The Node-RAM Result Cache

A fanout costs seconds of wall time and touches thousands of peers. Issuing one every time a citizen re-sorts a column, navigates back to a page, or relaunches their browser would be indefensible — both for the citizen and for the ten thousand peers who answer. So the result of a query is held in the node's RAM, and re-read from there.

This is the read-path expression of Vision principle 25 (*the cache is the fanout engine*), and it is possible only because of Vision principle 7 (1:1:1:1). In a conventional web architecture the server is shared by strangers, so per-user result sets must be either recomputed or paid for out of a shared memory budget. In PHEUN the server *is* the user: one operator, one node, one long-running process with gigabytes of free RAM, while the browser in front of it is disposable. A module-level store is therefore not merely an optimisation, it is the correct data structure — there is no other citizen's data to isolate it from.

The cache is partitioned into five namespaces — feeds, global searches, Guide chains, documents, and comment threads — and each entry records when its underlying mesh pull actually ran. Nothing in it is durable. A citizen's vault and their notifications are the only state that survives a node restart, because they are the only state that cannot be re-derived. Everything in this cache is a snapshot of a mesh query; losing it on restart costs time, never data, and it re-warms on the next read.

**The eviction order is load-bearing, and the unit is bytes rather than entries.** Entry sizes differ by two orders of magnitude across surfaces: a feed or a search is a slice capped at 10,000 anchors (roughly 15 MB), whereas a Guide chain is a complete read of an entire life and grows monotonically for as long as the citizen posts. A few chains would consume the entire node budget and evict every loaded feed on the way. Counting entries can therefore never bound memory.

Nothing short is ever stored: a document or chain the node could not read whole is refused rather than cached, so the cache can only hold a complete one and a later reader cannot inherit somebody else's failed fanout. Eviction runs in three stages, each least-recently-used: a per-namespace *entry* cap, so no surface crowds out another; a per-namespace *byte* ceiling, so opening an enormous Guide chain displaces older *chains* and not the citizen's loaded feeds; and a node-wide *byte* budget as the hard backstop. The entry just written is never the victim.

Because anchors are immutable (Vision principle 20), a cached result is always a strict *subset* of the truth rather than a contradiction of it — stale, never wrong. This is what makes serving a stale view acceptable at all. It is nonetheless surfaced rather than concealed: every cached surface renders the age of its underlying pull, and a citizen who wants a fresh fanout asks for one explicitly. Documents additionally cache their *raw anchors* rather than the assembled outline, and re-derive the outline against the current clock on every read, so a proposal's voting window opens and closes correctly even while the pull beneath it ages.

**A read that queries the mesh requires an authenticated session.** Anchors are public by construction (Vision principle 28), so reading an anchor carries no permission; but causing a node to fan out across 10,000 Sacred Anchor Indexes is a bandwidth-amplification vector against the citizen who owns that node, which binds a public interface. Every route that originates a mesh query therefore requires a session. The one sanctioned exception is the Guide ID uniqueness check, which necessarily runs before any Guide ID exists to authenticate with.

---

## 18. Vault, Cache, and Network Storage

PHEUN's per-node storage is partitioned into three physically separate tiers, each with a distinct purpose, eviction policy, and read priority. The separation is enforced at the database schema level — the three tiers do not share a table — and the protocol's read path never reads from the wrong tier for any given purpose. The three-tier design preserves the citizen's storage sovereignty while letting the node still carry its share of the network's storage duty.

The word *cache* appears in two unrelated senses in this paper and the distinction matters. This section concerns the on-disk **payload fragment** tiers: encrypted ciphertext chunks of anchors' payloads. Section 17.6's anchor cache is an in-RAM store of query *result sets* — 420-byte anchors, not payloads — and is never persisted. The two never share a code path, a budget, or a lifetime.

### 18.1 The Three Tiers

**Tier 1 — Vault.** The citizen's permanent personal store. Tables: `vault_collections`, `vault_members`, `vault_fragments`. When a citizen vaults an anchor, the full 420 bytes of the anchor are snapshotted into `vault_members.anchor_420b` (a binary column matching the format of the AnchorStream's own column), and every encrypted payload fragment is copied into `vault_fragments` (same base64 IV-tag-ciphertext wire shape as the network duty tier, ref-counted by the parent anchor's CORE). Vault contents are *never evicted* — the citizen controls what stays and what does not. A vault overflow does not silently drop content; the protocol returns HTTP 413 with a pointer to Settings → Storage so the citizen can choose to raise the budget or unvault items.

**Tier 2 — Viewer cache.** The output of mesh-fetch reconstructions, and of the citizen's own posts. When the citizen views a payload this node does not have vaulted, the protocol fetches the fragments from the holders (Section 13), reconstructs the plaintext, and writes the fragment ciphertexts into the viewer cache as `anchor_fragments` rows tagged `fragment_origin = 'viewer_cache'`. Subsequent reads are served from cache with no mesh round trip. An author's own payload lands here too, once placement on peers is confirmed — the one citizen certain to hold a complete copy should not have to fetch their own post back from strangers, and for brand-new content they are the best source the network has while the canonical holders are still filling. It is deliberately the *cache* and not the vault: evictable, budgeted, expiring on disuse, so an author is not silently conscripted into permanently storing everything they ever wrote.

Eviction is by **value, not by age**: least-fetched first, then least recently used, then oldest. The citizen's own reads count as demand alongside peers' pulls, so a film watched every week outlives a clip opened once — and the time-to-live measures *disuse* for the same reason, since a fragment still being read is not stale merely because it has been held a long time. An age-ordered sweep would evict precisely the content most likely to be wanted again, and every wrongly evicted fragment is bytes the mesh must send a second time.

**Tier 3 — Network duty / XOR storage.** Fragments held because this node is K-closest to those fragments' routing keys (Section 13). The node receives `FRAGMENT_STORE` packets from peers when census burst-replication chooses this node as a recipient, and stores the bytes in `anchor_fragments` rows tagged with `fragment_origin = 'xor_storage'`. The bytes are *never read by the citizen's personal viewing path* — they are the citizen's contribution to the network's storage substrate, not the citizen's own data. Tier 3 storage is permanent (the protocol rejects new placements when the budget is full rather than evicting existing rows) and tracked by a separate budget counter so the citizen's network-duty bytes do not impinge on the cache budget.

### 18.2 Read Priority

Reconstruction follows a strict priority order: **Tier 1 vault → any local fragment row → Tier 3 mesh fetch**. The vault is checked first (cheapest, most local, citizen-controlled). If the anchor is not vaulted, any fragment already on this disk is used — including network-duty rows, whose authenticity is settled by the AES-256-GCM auth tag at decryption rather than by which tier they were filed under. Only what is genuinely absent is fetched: a QUERY_FORWARD discovers the holders, the fragments are pulled directly, decrypted, and written back into the cache for the next view.

**Isolation is about ownership, not about reading.** Network-duty bytes are held in trust for the closest set and remain so: they are never evicted by the cache sweep, never counted against the cache budget, never surfaced in a feed or a search as the citizen's own material, and never released by a personal storage decision. But refusing to *read* a fragment already on the disk is not isolation — it is re-downloading something the node is holding, which costs the mesh bandwidth and the citizen time, and buys nothing. The tag decides authenticity; the tier decides ownership.

### 18.3 Storage Profile Auto-Detect

At first boot, the node detects the device's available RAM and free disk and selects a storage profile from four tiers:

- **DESKTOP** (RAM ≥ 16 GB, free disk ≥ 200 GB): cache 50 GB, vault 100 GB, XOR 1 TB.
- **LAPTOP** (RAM ≥ 8 GB, free disk ≥ 50 GB): cache 10 GB, vault 20 GB, XOR 500 GB.
- **MOBILE** (RAM ≥ 4 GB, free disk ≥ 10 GB): cache 2 GB, vault 5 GB, XOR 100 GB.
- **MINI** (everything below): cache 500 MB, vault 1 GB, XOR 100 GB.

These are defaults, not constraints. The citizen overrides any of the three at any time via Settings → Storage. The auto-detect exists so that a new node has a reasonable starting configuration without forcing the citizen to make storage decisions before they understand what each tier does.

### 18.4 The Vault as Permanent Personal Storage

The vault is the storage answer to "what does this node give back to the citizen for running it?" A citizen's vault is the only way to guarantee that a piece of content remains accessible offline forever, regardless of mesh churn, regardless of fragment census decisions, regardless of whether the K-closest holders go offline simultaneously. Vaulting an anchor copies its bytes into local permanent storage; the anchor is now readable on this device even with no network connection at all.

The vault's three-table architecture (`vault_collections` for grouping, `vault_members` for individual anchor pinnings with the 420-byte snapshot, `vault_fragments` for the encrypted payload chunks) is physically separated from the AnchorStream so the citizen's network duty and personal collection do not share rows.

**Vaulting never re-downloads bytes the node already holds.** A citizen who has just watched a film and decides to keep it has every fragment on their disk already — that is what watching it means. The materialiser takes them, and admits each one on its **auth tag** rather than its origin label: `verifyFragmentBytes` runs the same AES-256-GCM check the read path relies on at decryption. That risk was real — a poisoned fragment copied blindly becomes the citizen's *permanent* first-priority source and breaks every future view — but a label was the wrong instrument for it. A label says nothing about contents, so a corrupted cache row passed the same filter that rejected a perfectly sound network-duty row, while the citizen paid for a full mesh re-fetch at the exact moment they asked to keep something. Asking the tag is one local pass, no packets, and strictly stronger. Anything that fails it falls through to the mesh.

**Promotion moves rather than copies.** Once the vault holds every fragment of an anchor, that anchor's viewer-cache rows are released. The vault is read first and is never evicted, so the cache copy could never be read again; keeping it made vaulting a 10 GB film cost 20 GB of disk until a time-to-live up to a week away. Network-duty rows are untouched by this — they are owed to other citizens, and no personal storage decision may shrink what a node contributes to the durability floor.

---

## 19. Bandwidth, Relays, and Resource Sharing

Every node participates in the mesh as either a **CLIENT** (real IP hidden behind one to three relay hosts) or a **HOST** (publicly addressable, accepts slot reservations from clients). The choice is made at first boot and recorded in the node's settings. Client and Host run the same code, the same protocol, the same anchor model, and the same crypto stack. The distinction is purely a routing role — a Host operator chooses to publish an addressable endpoint and accept slot reservations; a Client operator chooses to hide behind relays for privacy and convenience.

### 19.1 The Slot Token

A Client that wishes to be reachable through a Host registers with the Host via a `RELAY_REGISTER` packet. The Host mints an unguessable slot token by hashing a Host-local secret with the Client's Guide ID and a monotonic counter:

> token = BLAKE3( hostSecret ‖ ownerGuideId ‖ counter )

The counter ensures uniqueness even when a Client re-registers under the same Guide ID. The token is returned in `RELAY_REGISTER_REPLY` with a 24-hour TTL. Anyone wishing to reach this Client sends a `RELAY_FORWARD` packet to the Host carrying the slot token; the Host looks up the slot, decrypts the next layer if onion-wrapped, and forwards the inner packet to the registered Client over the kept-open NAT-punched tunnel.

Slot tokens are unguessable to outsiders because the Host's secret is local. A token leak (an external observer who learns one slot token) does not reveal other tokens, because each slot's counter is independent. A Host's secret leak is more serious — every slot the Host has ever issued becomes guessable — and Hosts are expected to rotate their secret periodically.

### 19.2 Per-Slot DDoS Detection

A Host monitors the forward rate per slot over a 5-second sliding window. A slot that exceeds 1,000 packets per second triggers a `RELAY_DROP_SLOT` to the Client (with a 30-second cooldown) and refuses further forwards on that slot until the cooldown expires. The Client rotates to a fresh slot on the same Host or to a different Host entirely. This is "slot-level DDoS rotation": an attacker who learns a slot token and floods it can disable that one slot, but the Client's identity is unaffected — they simply rotate.

A Client typically maintains 1 to 3 active relay registrations, with the higher count chosen for redundancy. Power-user expansion (Section 19.5) allows up to 10 active relays for very high traffic Clients.

### 19.3 The Bandwidth Monitor

Every wire byte sent or received by the node is classified at the UDP boundary into one of twelve flow classes:

1. **DM** — Direct messages (Triple-Sentry-wrapped).
2. **CALL_SETUP** — Voice/video call setup packets.
3. **CALL_MEDIA** — Voice/video call media streams.
4. **FRAG_SMALL** — Small fragment packets (under a chunking threshold).
5. **FRAG_LARGE** — Large fragment packets (chunked).
6. **QUERY** — Global query engine traffic (announces, replies, pulls).
7. **GOSSIP** — subscription and gossip cascade; **PROPAGATION** — SVAP HAVE/WANT/FULL + storage receipts.
8. **PROPAGATION** — SVAP HAVE/WANT/FULL announcements and storage receipts.
9. **SYNC** — Sacred Anchor Index bucket replication traffic.
10. **RELAY_FORWARD** — Bytes forwarded as a Host on behalf of registered Clients.
11. **RELAY_OUTBOUND** — Bytes sent through an upstream relay as a Client.
12. **OVERHEAD** — Handshake, fingerprint check, presence, ping/pong.

Each packet is recorded with its class, direction (inbound or outbound), per-peer attribution (where applicable), and byte count. The hot-path cost is two integer adds and an optional Map.get per packet. The accumulated counters are persisted hourly to `data/bandwidth-history.bin` as a 90-day rolling window.

### 19.4 The Monthly Cap and Graceful Drain

The bandwidth monitor is the source of truth for one budget gate: the operator's monthly RELAY_FORWARD cap. Defaults are device-tier:

- **MINI** — 100 GB per month.
- **LAPTOP** — 500 GB per month.
- **DESKTOP** — 1 TB per month.
- **SERVER** — 5 TB per month.

The citizen overrides the default at any time via the Settings → Bandwidth slider. When the monthly RELAY_FORWARD class crosses 95 % of the resolved cap, the Host's `handleRegister` refuses NEW slot mints; existing slots TTL out naturally over their 24-hour lifetime. **No mid-transfer kills, ever.** A transfer in progress at the moment of the 95 % trigger completes; only new slot reservations are deferred to the following month.

DM, calls, fragments, queries, gossip, propagation, and sync flows are *never* throttled. The cap applies only to the RELAY_FORWARD class — bytes the Host is moving on behalf of someone else. The Host's own first-class network duty is not affected by the cap.

### 19.5 Power-User Auto-Expand

A Client's outbound traffic through its relays (the RELAY_OUTBOUND class) is monitored similarly. A Client whose monthly RELAY_OUTBOUND exceeds 50 GB activates up to 5 active relays (so the load distributes across more Hosts); over 200 GB monthly, up to 10 active relays. This prevents a "whale Client" from monopolising a single Host's RELAY_FORWARD budget; the load spreads naturally as the Client's traffic grows.

The expansion is automatic and bounded: the Client never holds more relays than the auto-expand schedule prescribes for its current traffic tier. The mechanism is best-effort — a Client without enough Host candidates available simply uses what it can find.

---

## 20. The Soft-Fork Lane

PHEUN extends through three orthogonal channels, all additive, none of which touch the network fingerprint. The wire format is byte-frozen for the lifetime of V1; new features ride alongside the old ones rather than replacing them. **PHEUN does not implement a hard-fork mechanism, by design.** Three load-bearing facilities make hard forks categorically unnecessary.

### 20.1 The Three Channels

**Channel A — New HOPE packet types.** New packet type bytes that are not bound in the PayloadWeave wire-identity digest (Section 8) can be added freely. Old peers silently drop unknown opcodes. New peers use them pairwise. A V1.1 packet type, for example, lands as a new byte in the HOPE packet type table; the network fingerprint is unchanged because the fingerprint's bound list of packet types is the V1 set; old nodes that do not understand the new opcode simply ignore packets carrying it. New peer-pair functionality emerges as both peers update.

**Channel B — New FREE_SCHEMA payloads.** The 49-byte FREE region of every anchor (bytes 371–419) is split into a 2-byte schema selector (FREE_SCHEMA) and a 47-byte schema-defined payload (FREE_PAYLOAD). Schema 0x0000 is empty (the V1 baseline default). Schema 0xFFFF is a TLV container for stacking multiple features in one anchor. Other schema values are allocated per feature in `shared/free-schema.ts`. Readers without an implementation for a schema see opaque hex, verify CORE and signature normally, and skip the schema-specific behaviour.

**Channel C — New governance dispatcher subtypes.** The dispatcher table that maps (category, type, flags) to a routing rule (Section 6) accepts new subtype rows. Old nodes' dispatcher falls through to the default `SAI(CORE)` rule for unknown subtypes; new nodes process the subtype with its dedicated rule. A new governance flow specific to a category — say, peer-review for Knowledge articles or taste-vote for Memes — lands as a new (cat, type, flags) row in the dispatcher and a new SQL extractor for any new on-chain field, all additive, all opaque to old readers.

### 20.2 Algorithm Selectors

The four selector bytes — `SEAL_PROTOCOL` at byte 64, `PROOF_PROTOCOL` at byte 97, `CRYPT` at byte 98, `GUARD` at byte 99 — are the cryptographic upgrade lane. V1 sets all four to `0x01` (BLAKE3, BLAKE3, AES-256-GCM-with-BLAKE3-KDF, ML-DSA-65). A future post-quantum signature scheme — say, ML-DSA-87 if it supersedes ML-DSA-65 — lands at `GUARD = 0x02`, with `0x01` continuing to be served by readers for every anchor signed under V1. Old anchors stay valid forever under their original primitives; new anchors carry the new selector. A reader that does not implement a particular selector byte cannot verify or decrypt anchors carrying that byte — there is no fallback to a weaker primitive.

The selector approach means cryptographic agility is built into the protocol from day one. PHEUN can adopt new NIST-standardised primitives as they emerge, without invalidating existing data and without coordinating a network-wide upgrade.

### 20.3 CLIENT_VERSION and Reader Dispatch

`CLIENT_VERSION` at bytes 358–359 is the build label every newly-minted anchor carries. It is *not* a digest input — the network fingerprint does not depend on CLIENT_VERSION — but it *is* a signal: a reader can branch on the version of the client that minted an anchor and apply version-specific parsing rules. A V1 reader handles V1 anchors with V1 logic; a V2 reader handles V1 anchors with V1 logic and V2 anchors with V2 logic. Old anchors stay readable under their original parser forever.

The handshake envelope also carries `clientVersion` and `supportedSchemas` so peers can advertise which features they support during peer-join. The handshake-level signal feeds the activation engine (Section 20.4) without polluting the on-the-wire anchor format.

### 20.4 The 95 % Activation Gate

A new feature does not become live the moment it is added to the codebase. It becomes live when the network's *readiness signal* crosses a 95 % threshold across two independent sources:

1. **Anchor signal.** Of the last 1,024 anchors observed by this node (`FEATURE_ACTIVATION_WINDOW`), the share carrying `client_version ≥ N` (or `free_schema = the feature's schema id`) must be at least 95 % (`FEATURE_ACTIVATION_THRESHOLD`).

2. **Handshake signal.** Of the currently-cached and currently-connected peers (passport cache plus live mesh), the share advertising `clientVersion ≥ N` (or `supportedSchemas` containing the feature's schema id) must be at least 95 %.

Both must clear independently. A single-source spike — a heavy minter pushing many anchors with the new schema — does not flip the gate, because the handshake signal will not yet show 95 % adoption among peers. A widespread peer adoption — many peers advertising the new clientVersion — does not flip the gate either, because the anchor signal will not show 95 % adoption among recent anchors. Both signals must converge, which in practice happens when actual usage of the new feature reaches network-wide adoption.

Activation is a pure local decision: every node walking the same anchor stream and the same passport cache arrives at the same activation verdict deterministically. There is no governance vote required for soft-fork features — the readiness signal *is* the activation. (Vision §17's 75 % threshold governs *constitutional* changes that ride entirely on the existing dispatcher; technical soft-fork rollouts use the readiness signal alone.)

A bootstrap floor protects fresh nodes: activation refuses while the anchor signal window has fewer than `FEATURE_ACTIVATION_MIN_WINDOW_SAMPLES` anchors so a brand-new node cannot accidentally light up features from its own seeded chain.

### 20.5 Why No Hard Fork

The three channels above plus the algorithm selector bytes plus the CLIENT_VERSION dispatch cover every realistic protocol-evolution scenario without rotating the network fingerprint or invalidating stored anchors. Hard forks — operations that change the byte layout, the SAI count, the cryptographic primitives' approval list, or the Genesis Authority roster — are not implemented as a coordinated network operation. A community that adopts an incompatible change computes a different network fingerprint, and their nodes can only connect to other nodes with the same divergent fingerprint. Two networks coexist as siblings; PHEUN-the-protocol stays a single network for everyone who keeps the V1 fingerprint.

This rule is a feature, not a limitation. PHEUN is not a blockchain — it has no consensus rule that needs to change, no block size to bump, no difficulty adjustment, no transaction format that needs retroactive replacement. The 420-byte anchor is the wire identity; changing it is creating a different network, not upgrading PHEUN. The 10,000-SAI dispatcher scales linearly to 100 billion users (Section 26). The Genesis Authority roster auto-retires under the 5-per-SAI invariant (Section 24). Every credible evolution lane has a soft-fork path baked into V1.

If a community ever ideologically forks (decides to run an incompatible build), that is a sibling network running its own fingerprint — not a PHEUN-mediated upgrade. Sibling networks discover their own peers, recompile their own fingerprint, and are simply a different network from that point forward. PHEUN-the-protocol stays one network.

---

## 21. PHEUN Sites — A Decentralised Web Layer

Every anchor on PHEUN can carry a payload, and one specific payload format is the *PHEUN Site* — a static, immutable, cryptographically-signed, mesh-distributed page primitive that replaces the centralised Web 2 page substrate. A site is to a Web 2 page what an anchor is to a Web 2 post: the PHEUN-native equivalent, with a different distribution model, a different trust model, and a different impermanence story.

### 21.1 The Static Single-Page Model

Sites are deliberately constrained. Every site is a single-page scroll. There is no multi-page navigation; there is no live data; there is no in-site media playback (clicking a `pheun://` link to a video anchor opens the standard payload viewer rather than playing inline); there is no user-supplied JavaScript or CSS escape hatch. The constraints are not deficits but design choices: a static, immutable site has a known set of bytes, a known signature, a known author, and a known content for the rest of time. A "live" site that reads the mesh on every load would, by definition, render different content to different viewers depending on when they loaded — defeating the determinism that PHEUN's other layers depend on.

The single-page constraint is also a publishing-cost constraint. Each site is one anchor with one payload. A 50-section curriculum is one site with 50 sections in a single scroll, not 50 sites with cross-links. Multi-section publishing emerges through SIGN-scoped governance (Section 15) and through composition by the citizen — different sites under different SIGNs, linked by `pheun://` references — rather than through a multi-page model embedded in any single site.

### 21.2 The 31 Component Types

A site is composed from a fixed registry of 31 component types (`SectionConfig` in `client/src/features/pheun-sites/types.ts`), each a platform-trusted React renderer that takes structured data and draws UI. The author does not write code; the author writes the data. The components fall into eight families:

- **Visual headers.** Hero (banner + title + avatar + subtitle), Spotlight (single-anchor feature card), Stat Cards (metric grid).
- **Anchor rendering.** Anchor List, Anchor Grid, Anchor Gallery (Netflix-style poster rows), Ranked List.
- **Text and citation.** Text Block (markdown), Quote Block, Citation Block (full bibliographic form for academic work), Inline Image with caption, Table.
- **Education.** Quizzes (multiple-choice with score and report card), Flashcards (front-back review with optional hint).
- **Identity / Social.** Bio Card, Contact Card, Subscribe (one-tap subscription to the site author's Guide ID).
- **Catalogue.** Catalog (generic indexed item grid — works for libraries, museums, parts inventories, plant collections, etc.).
- **Governance.** Pros and Cons block, Position Card (verdict pill plus reasoning plus author).
- **Layout and page furniture.** Table of Contents, Timeline, Event Card, Call to Action, Accordion, Button Row, Feature Grid, Divider, Countdown, Marquee, Footer.

The renderer is platform code. Citizens cannot ship custom JavaScript or custom CSS; they can configure each component through structured data. This eliminates the entire user-supplied-script attack surface that plagues Web 2 sites.

### 21.3 Templates and Themes

Fifteen templates (Profile, Gallery, Library, Article, Document, Showcase, Directory, Event, Manifesto, Landing, Course, Proposal, Link-in-bio, Contact, Help — `SITE_TEMPLATES`) ship as starter section sets. Each template is a curated combination of components for a specific use case — a Course template starts with Hero, Text, Anchor List for chapters, Flashcards for key terms, and Quizzes for self-assessment, for example. Templates are starting points the citizen edits in the visual builder; they are not constraints.

Ten themes (Midnight, Ocean, Forest, Solar, Light, Civic, Tape, Terminal, Aurora, Print) cover the meaningful aesthetic axes — five dark themes, three light, and two specialty (Aurora's animated gradient, Print's sepia book aesthetic). Each theme is a set of CSS variables (primary colour, background, text colour, surface, accent) that the renderer applies to every component. Citizens override individual variables for further customisation.

### 21.4 The Site Payload Format

A site's payload is a `.pheun.zip` archive containing a manifest JSON (`pheun-site.json`) and an `assets/` folder holding the images the site embeds. The manifest carries the schema version, the chosen template and theme, the array of component sections in render order, and an asset inventory. The ZIP is fragmented into AES-256-GCM-sealed fragments at publish time exactly like any other payload, distributed across the mesh by PayloadWeave (Section 13), and reconstructed by readers on demand.

**A site carries no marker byte in the anchor, and needs none.** It is not a destination in the way a domain is — it is one way of *presenting* a payload, no different in kind from markdown inside a text block or the fields of an event card. An author who wants readers to know a site is attached says so where every anchor already says what it is: the TITLE, the 32-byte PREVIEW, the HASHTAG, the AVATAR. Spending an anchor field on "this one is a site" would rank a rendering choice alongside authorship and time in a 420-byte record where every byte is contested — and it would quietly imply one site per citizen, when in fact a citizen keeps as many as they have purposes, each its own payload under its own anchor. Sites are therefore discovered exactly as everything else is: through the feed, subscriptions, and search (Sections 16 and 17).

A site is therefore the same architectural class as every other PHEUN payload: a public anchor (signed, permanent) plus an encrypted payload (fragmented, content-addressed). The site primitive does not carve out a special case in the protocol; it is simply the most-elaborated payload format that the platform's component renderers understand natively.

---

## 22. Sybil Resistance via the Storage Curve

PHEUN does not implement proof-of-work, proof-of-stake, captchas, phone-number binding, ID verification, or any other anti-Sybil mechanism that depends on an external authority. One human approximates one Guide ID, enforced by two compounding floors that emerge from the protocol's own design.

### 22.1 The Two Floors

**Floor 1 — Guide ID entropy.** The 9-input derivation (Section 3) requires personal facts that only the human knows in combination — names, dates, places, identifiers chosen at first registration. Any single input may be guessable from public sources, but the conjunction of nine, with the input order canonicalised before hashing, presents an attacker with a combinatorial space whose effective entropy depends on the citizen's choices. A throwaway bot does not have a personal life from which to draw nine inputs; an adversary attempting to manufacture nine plausibly-personal-looking inputs for each of millions of fake Guide IDs is doing an expensive amount of generation work per identity.

**Floor 2 — Full-node disk cost.** Every citizen runs the same node, holds their share of the AnchorStream, and is responsible for the K-closest fragments in their corner of the XOR-DHT. The AnchorStream grows monotonically: every anchor ever born is on the chain forever, and every node holding its Sacred Anchor Index bucket holds those anchors. Within a few years of launch, the disk requirement makes cheap-VM Sybil farms economically untenable: a hundred thousand throwaway nodes cost a hundred thousand times the disk, plus a hundred thousand times the Tier 3 XOR storage, plus a hundred thousand times the bandwidth budget. An attacker who creates ten million Sybil identities to vote on a proposal must, within a few years, also be running ten million full nodes with proportional disk.

### 22.2 No Punishment, the Curve

The protocol does not punish attackers; *the storage curve does*. There is no slashing, no stake forfeiture, no captcha rate-limiting, no phone-number ban, no IP blacklist. The economic floor that makes Sybil farms expensive is the disk, and the disk is paid for off-protocol — by whoever runs the node. PHEUN does not need to detect Sybils because Sybils that are not paying the disk cost cannot stay on the network; their nodes fall out of mesh coverage, fail to serve as home holders (they do not hold their share of the anchor stream), and are eventually evicted from peer caches.

Per-IP passport caps, the per-peer egress limiter (Section 9.5), and SVAP self-verification (Section 11) cover short-horizon coordinated attacks before the storage curve has time to bite. Persistent peer ban entries in `data/ban-list.json` (24-hour default plus optional permanent bans) survive node restart and provide local reputation memory without requiring cross-node ban gossip. A future cross-node ban-announcement system (the `PEER_BAN_ANNOUNCE` packet type, reserved at V1) would extend ban memory across the mesh; V1 ships node-local-only.

### 22.3 What This Costs

The Sybil-resistance model exchanges the costs of proof-of-work (massive energy waste) and proof-of-stake (financialisation of identity) for a different set of costs. The most visible: a citizen who joins PHEUN today commits, implicitly, to running a node for years to come; a citizen who stops running their node loses the ability to sign new anchors under their Guide ID until they bring the node back online (the keypair regenerates from the nine inputs, but new anchors require active mesh connectivity to reach the home holders that verify and store them). This is a fundamentally different lifecycle from a Web 2 account, and citizens who do not want this commitment do not run nodes.

For citizens who do run nodes, the cost is the disk and the bandwidth — a few hundred gigabytes for a typical citizen at year 1, growing linearly as the network's history accumulates. Section 26 gives the per-node storage trajectory at billion-user scale.

---

## 23. No Token, No Fee, No Mining

PHEUN has no cryptocurrency, no gas fee, no staking, no paid-node incentive, no premium subscription, no advertising plane, no platform-level currency, no marketplace operator, no payment processor. There is nothing on the network to pay for, nothing to mine, nothing to stake, and no fee at any layer for any operation.

### 23.1 The Economy Category

Resource sharing happens through the *Economy* anchor category (Section 7, byte `0x05`). A citizen posts an Economy anchor offering compute, bandwidth, storage, physical goods, or services — a barter listing, framed in whatever terms the citizen chooses. The counterparty arranges fulfilment off-protocol, through Direct Messages, Voice/Video Calls, or any other communication channel. The protocol is the *medium* — it surfaces the offer, lets citizens find each other, and records the existence of the exchange — but the protocol does not mediate the transaction.

The Economy category does not financialise: there is no settlement, no escrow, no reputation oracle, no dispute resolution mechanism. The protocol does not opine on whether the goods or services were delivered as promised. Commerce on PHEUN is purely citizen-to-citizen, with whatever trust mechanism the participants choose to use (existing reputation in their own communities, off-protocol payment rails, in-person handoff). PHEUN provides the substrate; humans handle the transaction.

### 23.2 Public-by-Construction Anchors, Encrypted-by-Default Payloads

The 420-byte anchor is public and permanent by design — it is the ledger. The payload it points to is AES-256-GCM-sealed with a key derived per anchor from BLAKE3(CORE ‖ SEAL ‖ PAC); the mesh stores ciphertext fragments. Citizens agree to the Digital Constitution at every post; the Constitution forbids illegal content as a matter of social contract. There is *no filter, no ban list, no takedown, no content-hash allow-list, no flag, no moderator, no admin, no report button, and no CORE-hash refusal*. If illegal content is uploaded, it stays — because no mechanism exists to remove it and none will ever be built. This is the cost of an open permissionless network and PHEUN owns it fully. Enforcement is social and legal, never technical. GDPR-style erasure is satisfied by key destruction — destroying the AES key derived from the citizen's own anchor renders that anchor's encrypted fragments unreadable forever, even though the ciphertext continues to exist on the mesh — never by anchor rewrite.

This is not a hands-off posture. It is an architectural commitment. A protocol that supports a takedown mechanism has, by definition, an actor with the authority to perform takedowns; that actor becomes the privileged party every other PHEUN principle was designed to remove. The trade-off — citizens must operate under the Digital Constitution as a *social* obligation, with no technical enforcement layer — is the price of removing the privileged actor entirely. PHEUN accepts this trade.

### 23.3 Discoverability Without Advertising

The AnchorStream itself is the discovery layer (Section 16). Subscribe to a Guide ID, hashtag, document SIGN, link chain, or stream origin and every future matching anchor flows into the citizen's feed in 1 to 120 seconds. Word-of-mouth share of a 16-character Guide ID unlocks discovery of every anchor tied to that identity — past, present, future. There is no central index, no search-engine dependency, no advertising auction, and no boosted post.

**A Guide ID is a claimed name, and the handle race is real — what is missing is the market around it.** The handle is input 1 of the nine (Section 3.2), chosen by the citizen and claimed first-come-first-served, with the uniqueness gate at SAI(GUIDE) (Section 3.3) and earliest-TIME resolution inside the propagation window. So a desirable name can be taken before its obvious owner arrives, exactly as in DNS or any social handle namespace, and the protocol does not pretend otherwise. What it removes is every mechanism that makes handle-squatting profitable or reversible by an authority:

- **No registrar.** No party holds the namespace, so there is no fee, no renewal, no expiry, no dispute process, no trademark arbitration, and no entity that can revoke, reassign or seize a name. Nobody can take a name away, including us.
- **No resale, structurally.** Because the handle is one of the nine seed inputs, it is not a separable asset. Selling a name would mean surrendering all nine inputs — the whole identity and every anchor it has ever signed or will sign. A squatter cannot escrow a name, cannot auction it, and cannot prove to a buyer that they have relinquished it, because there is nothing transferable that is not the entire person and no registry to record a transfer.
- **No impersonation of a claimed name.** Producing the keypair that matches a genesis PROOF requires all nine inputs, not the one that is public. A second genesis under a different key is rejected at admission (Section 3.3).

The honest summary: names are first-come, and squatting is possible; squatting has no exit, and no authority can undo it either.

The absence of an advertising plane means there is no economic incentive to optimise anchor content for engagement metrics — there are no engagement metrics that any actor benefits from. The protocol does not track time-on-page, click-through rate, or impression count. Citizens see what they subscribed to, in chronological order, with deterministic tie-breaks. This is, by the standards of Web 2, a deliberately *boring* feed. It is also a feed that nobody can optimise against the citizen's interests, because nobody is being paid to.

---

## 24. Bootstrap and the 5-per-SAI Coverage Invariant

The mesh's first phase, when community node count is too low for the 10,000 Sacred Anchor Indexes to all have community-peer coverage, runs on bootstrap nodes. The bootstrap exemption is temporary and operator-retired.

### 24.1 The Genesis Authority

Twenty-one Guide IDs are the Genesis Authority: `nateofearth2100z` (the network's founding human operator) and `bootstrapnode001` through `bootstrapnode020` (twenty additional bootstrap operators). Their public-key BLAKE3 fingerprints are bound into the network fingerprint (Section 8) — any community node that disagrees on the GA roster computes a different fingerprint and falls out of the mesh. The GA roster is byte-frozen for the lifetime of V1.

Genesis Authority nodes serve all 10,000 Sacred Anchor Indexes during the network's first phase. They cover every SAI, verify and store anchors at any SAI (subject to the SVAP solo-publish path when no other home holder is available), and run sync against every SAI's history. A community node bootstrapping a new corner of the mesh discovers the GA nodes from a hardcoded peer list and uses them as the initial seed for its own SAI bucket pull.

### 24.2 The 5-per-SAI Invariant

Bootstrap mode is a pure function of Genesis Authority roster membership: a GA node serves bootstrap while it runs, a community node never does. The 5-per-SAI coverage invariant is the goal the operator watches, not a gate on that service. The invariant: every Sacred Anchor Index in the 10,000 must have at least 5 live-or-cached community peers.

> bootstrap_active(node) = is_genesis_authority(node.guideId)

When the mesh has at least 5 live-or-cached community peers for *every* SAI, the bootstrap-status endpoint reports `coverageFullySatisfied` and the operator can stop their GA node — the network no longer needs it. Bootstrap mode does *not* auto-toggle on this signal: an earlier design auto-retired on the first 5-per-SAI hit and re-activated on any dip, which produced bootstrap-mode flapping, non-stationary home-holder composition, and a network that never reached a stable post-bootstrap state. V1 makes retirement an operator decision instead — a GA node serves while it runs, the operator watches coverage, and stopping the node (`npm run node:stop`) is the only way it leaves bootstrap service. Coverage is observability, not policy.

The 5 × 10,000 = 50,000 community-peer edges are the security floor (Section 9.2). The 16,666 reserve absorbs multi-coverage peers (peers covering more than one SAI), bursts during coverage healing, and short-horizon multi-hop discovery. Bootstrap peer counts are tracked separately as a redundancy metric and are *not* summed into the invariant decision — Genesis Authority coverage is observability, not policy.

### 24.3 Why Five

Five community peers per SAI is the home-holder floor (Section 11): every SAI holds enough community peers to verify, store, and receipt any anchor born there, and to supply the two agreeing holders Dual-Witness Sync needs to replicate a window. Five-per-SAI consumes 50,000 of the 66,666 per-node budget, leaving 16,666 for multi-coverage peers, heavy peers, and short-horizon bursts. The mesh leans on the emergency floor — `SAI_MIN_COMMUNITY_PEERS = 2` fires an immediate LOCATE re-coverage burst the moment any SAI drops toward coverage risk — plus the bootstrap fallback and the passport cache to heal transient dips.

### 24.4 Operator Retirement

Bootstrap retirement is an operator decision, taken once community coverage healthily fills. There is no "the network is no longer in bootstrap" global event and no automatic toggle: each GA operator watches their own node's `coverageFullySatisfied` signal — a local view of the mesh — and stops the node when every SAI it would serve is covered by 5 community peers. A GA operator in a well-connected geography may stop early; one seeding a less-connected corner keeps serving longer. The network as a whole transitions out of bootstrap as more nodes join, more community peers fill the SAI buckets, and GA operators retire their nodes one by one.

Production code must work in a community-only mesh with zero bootstrap nodes. The bootstrap exemption is training wheels, not architecture. A mesh of, say, ten million community nodes with no Genesis Authority connectivity at all should function identically to a mesh with full Genesis Authority service, except that the solo-publish path (Section 11.6) is unavailable.

---

## 25. Threat Model

This section enumerates what each PHEUN subsystem defends against and, equally importantly, what it does *not* defend against. The honest accounting of non-defenses is part of the model: a protocol that promises everything is a protocol that promises nothing.

### 25.1 Cryptographic Primitives

- **ML-DSA-65 signatures.** Defends: anchor origin authentication; binds the Guide ID to the Genesis Profile via the PROOF field; quantum-secure for the foreseeable future under NIST FIPS 204. Does not defend: a signing-key leak (the citizen's responsibility), an insider Guide-ID-derivation bypass (a Sybil who somehow obtains the citizen's nine inputs).
- **ML-KEM-1024 key encapsulation.** Defends: pairwise session confidentiality and integrity against a quantum-capable network adversary; FIPS 203. Does not defend: a compromised endpoint device or a stolen device-key from a session in flight.
- **AES-256-GCM payload sealing.** Defends: bit-flip detection at the GCM authentication tag; a tampered fragment fails decryption before plaintext leaks; reconstruction abandoned on tag failure. Does not defend: any peer holding the parent anchor (which carries the AES-key derivation material) can decrypt the fragments — this is by design (Vision §28: the anchor is public, so the payload is readable to any reader who has the anchor and the fragments).
- **BLAKE3 hashing.** Defends: collision resistance, second-preimage resistance, length-extension immunity; performance well above SHA-256. Does not defend: nothing meaningful — BLAKE3 is the current best-in-class general-purpose hash and will be replaced in the soft-fork lane (the SEAL_PROTOCOL and PROOF_PROTOCOL bytes) when a successor matures.

### 25.2 Consensus and Storage

- **SVAP self-verifying admission.** Defends: forged anchors (bad signature) and impostor anchors (valid signature under a foreign keypair, wrong canonical genesis) — each dies at the first honest hop, re-checked by every receiver, so admission is not probabilistic. Does not defend: a same-key cross-device self-fork (caught at login, Section 14); the author's own signing-key theft (defers to ML-DSA-65 key confidentiality).
- **Dual-Witness Sync (windowed Merkle anti-entropy).** Defends: storage corruption + a peer serving modified bytes during replication, and convergence of a behind node — a divergent window is ingested only when the witnesses agree on its digest, so a fake on one peer is never corroborated and never propagates. Does not defend: an all-colluding witness set serving identical corrupted bytes (tolerated — forgery is closed at birth by SVAP); cross-session reputation. Trust does not flow from advertised counts; only matching window digests admit content.
- **PayloadWeave fragment routing.** Defends: per-fragment scatter so no peer holds a full payload; auth-tag rejection of tampered fragments at decryption; census-driven replica floor maintenance with phi-burst replication. Does not defend: a fragment whose K-closest set is dominated by a single colluding entity that refuses to serve (the swarm is still bounded by the available community peers in K-closest distance).
- **PAC fork detection.** Defends: detection of any two anchors at the same PAC_COUNT with different CORE for the same Guide ID, via login walk plus auto-engaged self-subscription plus local mint hook; lock written within seconds of the conflict appearing on the mesh. Does not defend: recovery of a forked Guide ID (recovery is creating a new Guide ID, by design).

### 25.3 Transport and Privacy

- **Network fingerprint.** Defends: forked or mismatched peers are dropped at handshake before any authenticated traffic. Does not defend: flood-level denial of service of handshake attempts (the spoof-cap absorbs up to 100,000 simultaneous source addresses, beyond which the kernel buffer drops the excess).
- **Egress limiter.** Defends: bursty or runaway broadcast on gossip, fragment, and query channels; bounds per-peer outbound rate. Does not defend: coordinated many-peer floods (those require persistent peer reputation plus the ban list).
- **Fair queue.** Defends: per-peer round-robin scheduling on outbound UDP; one chatty peer cannot monopolise the send window. Does not defend: a peer's per-queue cap of 256 packets does not extend to memory consumption beyond that cap.
- **Triple Sentry onion.** Defends: packet-type unlinkability and traffic-shape resistance for the 6 onion-wrapped packet classes (DM, the 4 call-control types, WebRTC signalling) against a passive mesh observer. Does not defend: sender identity from any of the three relay hops (mesh is pairwise authenticated); coordinated all-three-relay compromise; a global passive adversary with both endpoint visibility; subscription forwards, which are sent direct; **live call media, which never enters the mesh** — it rides WebRTC DTLS-SRTP browser-to-browser, so only call signalling is onion-wrapped.
- **Passport IP binding.** Defends: pairwise-only Guide-ID-to-IP visibility, required for home-holder selection, fragment placement, and anchor propagation. Does not defend: a direct peer logging the binding for offline correlation; mitigated for sensitive traffic by Triple Sentry, which hides content and destination from all but the first and last hop.

### 25.4 Sybil and Abuse

- **Sybil resistance via storage curve.** Defends: long-horizon Sybil resistance via the disk-cost floor (one human approximates one Guide ID under the AnchorStream growth curve over years). Does not defend: short-horizon coordinated attacks before the storage curve bites; mitigations are per-IP passport caps, egress limiters, and SVAP self-verification (a forged or impostor anchor dies at every hop).
- **Persistent ban list.** Defends: a misbehaving peer outlasting their ban via an operator restart (atomic write-then-rename to `data/ban-list.json` survives crashes). Does not defend: cross-node ban gossip; bans are node-local at V1.
- **UDP socket spoof-cap.** Defends: spoofed-source floods up to 100,000 simultaneous source addresses. Does not defend: coordinated per-connection floods (egress limiter and fair queue handle those).

### 25.5 Identity

- **9-input Guide ID derivation.** Defends: identity is not stored on any server (no password file to leak, no recovery email to phish, no key file to steal); deterministic regeneration on any device. Does not defend: a citizen who loses or forgets their nine inputs (recovery is impossible; this is by design).
- **Genesis Profile binding.** Defends: a Sybil cannot claim an existing Guide ID's handle because the home holders at SAI(GUIDE) reject a second genesis for a Guide ID already claimed (first-claim-wins). Does not defend: a network-partition attack at registration time where the new Genesis Profile is admitted on a mesh segment that hasn't yet seen the legitimate one (mitigated by the propagation budget — at scale, propagation completes within the bounded window before any second registration could occur).

### 25.6 Governance and Content

- **75 % governance threshold.** Defends: a constitutional change requires supermajority approval; a 50/50 contested change does not pass. Does not defend: vote-buying off-protocol (not a protocol concern; a constitutional matter); coordinated voting blocs.
- **No filter, no takedown.** Defends: there is no actor with the authority to remove content, eliminating the entire takedown attack surface. Does not defend: the mesh hosting illegal content; Vision §28 acknowledges this explicitly. Enforcement is social and legal, never technical.

This list is not exhaustive. The canonical threat-model matrix is maintained in `CLAUDE.md` and updated in the same pull request as any new packet type, onion layer, or security primitive.

---

## 26. Scalability Analysis

PHEUN is designed to be linear in user count with O(1) per-anchor work at any node. This section gives the per-node load at billion-user scale.

### 26.1 Per-Node Work at 1 Billion Users

At a billion citizens with a network-wide anchor mint rate of approximately 115,000 anchors per second, a community node holding 1 of 10,000 Sacred Anchor Indexes sees approximately 5 to 20 anchors per second arriving at its bucket. The cost breakdown:

- **Anchors received.** 5–20/sec × 420 bytes = ~2–8 KB/sec of anchor-byte traffic into this node's SAI bucket; ~60–250 GB per year of anchor storage growth on this one SAI.
- **SVAP bandwidth.** ~2.5 Mbps average per node, dominated by the SVAP propagation phase; the per-anchor cost per node decreases as the mesh grows (a single node's contribution is bounded by its own genesis SAI's peer count, not by the network's total anchor count).
- **Passport cache hit rate on lookups.** ~99 % at billion-user scale; only the 1 % cache-miss path falls through to a live mesh query.
- **Live mesh queries on the cache-miss path.** O(log N) hops, where N is the network size — the LOCATE-chain XOR lookup converges in approximately 1 to 5 hops at all tested scales.
- **Fragment self-check on bloom.** O(1) — the in-RAM bloom filter answers "do I have this fragment?" in nanoseconds, with a phi-progressive auto-grow so the FPR stays below 0.1 % even at multi-million-fragment local stores.

Subscriptions are SPS-elected (Section 16): one peer per SAI a citizen needs coverage for, not one per peer per SAI. The registration count is proportional to the citizen's interests, not to the user base. A citizen with 1,000 active subscriptions registers, in total, 10,000 elected-peer contracts (one per SAI) regardless of whether the network has a million users or a billion.

### 26.2 Storage Trajectory

The AnchorStream grows monotonically. At 115,000 anchors per second network-wide times 420 bytes per anchor equals approximately 48 megabytes per second of *total* anchor growth across the mesh. A community node holding 1 SAI bucket holds approximately 1/10,000 of that: 4.8 kilobytes per second of anchor metadata growth on the bucket, or about 150 GB per year per SAI.

Tier 3 XOR storage (the K-closest fragments held as network duty) is more variable, depending on the specific routing keys the node is closest to. At billion-user scale with the FLOOR=20 replication target, an average node holds approximately FLOOR × (totalFragments / activePeers) fragments — a few hundred gigabytes for a typical desktop with 1 TB of XOR budget, scaling to several terabytes for a server-tier operator.

The Storage Trajectory module on every node tracks linear-regression slopes over 7-day and 30-day windows and projects the days-until the free disk hits a 1 GB safety floor. The citizen's response is the storage tier slider in Settings, which lets them downgrade their node's tier (DESKTOP → LAPTOP → MOBILE → MINI) with corresponding budget reductions, or expand their hardware. The protocol does not prescribe the response; it surfaces the trajectory.

### 26.3 Query Load

Every governance, feed, search, and lineage query goes through the unified two-phase per-SAI fanout (Section 17). Per-query cost: one announce per SAI (10,000 small packets, approximately 50 KB total announce traffic per query at the 5-byte announce-payload typical size) plus the PHI-allocated pull (up to 10,000 anchors at 420 bytes each, approximately 4 megabytes per query at maximum saturation). Per-user concurrency is 8, so a single citizen's worst-case sustained query traffic is approximately 32 megabytes outbound and 32 megabytes inbound across all 8 in-flight queries.

The receiver side: each peer covering a hot SAI may receive announces from many simultaneous queriers across the mesh. The query egress limiter (Section 9.5) bounds the *outbound* announce rate per source peer at 60 announces per second steady-state. Aggregate inbound at a hot SAI is therefore approximately *number of queriers per second × 1 announce per query* on that SAI — typically a few hundred announces per second at most, well within the receiver's COUNT(*) capacity on an indexed expression column.

### 26.4 Bandwidth Floor for Participation

A citizen running PHEUN on a consumer connection needs a baseline of approximately 5 to 10 megabits per second of bandwidth: 2.5 Mbps for SVAP propagation, 1–2 Mbps for fragment serve traffic on K-closest fragments, plus the citizen's own inbound subscription forwards and outbound mints. Heavier participation (running as a Host with relay-forward duties) scales the bandwidth budget linearly with the operator's chosen monthly cap. Mobile citizens on cellular connections operate under tighter budgets via the MOBILE storage tier and can opt out of relay-host duty entirely.

### 26.5 Why the Architecture Scales Linearly

Three load-bearing properties give PHEUN linear scaling:

1. **The Sacred Anchor Index dispatcher partitions the anchor stream by 10,000.** Every per-anchor metric is divided by 10,000 at any one node, because each node holds 1/10,000 of the network's anchor flow.

2. **PayloadWeave anchor-scoped placement scatters payloads across the K_NEIGHBORHOOD = FLOOR × totalFragments closest peers to CORE.** Each peer in the neighborhood holds exactly one fragment, assigned by XOR rank (the *r*-th closest holds index `r mod totalFragments`) — coverage-complete, so no index is orphaned. A fragment's load is bounded by its own neighborhood slot, not by the size of the mesh or the parent payload. Discovery over the cache's O(log N) PeerXorIndex, with the outward expansion that lets a ripple sweep the whole holder band rather than converge on its centre, locates every fragment of a 10 GB payload 100% of the time in a single round — at ten million, a hundred million and a billion nodes alike, from canonical placement alone, measured by `npm run bench:discovery` running the real engine in rank space. Replication depth is therefore a durability property rather than a discovery one: at a single copy per index one holder leaving orphans that index permanently.

3. **SPS subscription election turns N×M into N.** Subscription forwarding registers one peer per Sacred Anchor Index per citizen, not one per peer per SAI per citizen.

These properties together mean adding more citizens to the network adds capacity proportionally to the number added: the new citizens take their share of the per-SAI load (1/10,000 of the new network anchor flow each), they hold their share of the K-closest fragment-set space (1/N of the available peer-slots), and they register their share of the subscription forwarding contracts (independent of the existing citizens' contracts). Per-node work at billion-user scale is identical in shape to per-node work at million-user scale, just at a higher absolute number that the per-SAI partition keeps tractable.

---

## 27. Conclusion

This paper has specified PHEUN — a decentralised internet replacement built on a byte-frozen 420-byte ledger, NIST post-quantum cryptography, 1:1:1:1 single-user-per-node identity, deterministic Sacred Anchor Index routing, a self-verifying propagation check at every anchor's birth (each receiver re-runs the author's own proof), a Dual-Witness Sync integrity check at replication, an XOR-DHT for content-addressed payload storage, a three-layer PAC fork-detection model, a universal SIGN-scoped governance pipeline, and a soft-fork-only protocol evolution lane.

The architectural commitments are honest. The protocol contains no privileged actor: no admin, no moderator, no operator class, no kill-switch, no global delete. The wire format is byte-frozen for the lifetime of V1; all evolution rides through the soft-fork lane (new schemas, new packet types, new algorithm selectors, new dispatcher subtypes), not through hard forks. Identity is regenerated locally from inputs the human alone holds; the server stores the public key and a BLAKE3 fingerprint, never the private key or the inputs. Consensus is a property of deterministic placement combined with a small BFT gate at birth, rather than a global vote. There is no token, no fee, no mining, no advertising plane, no payment processor.

The network that emerges from these commitments has properties that no Web 2 substrate offers and no existing decentralised system has combined in one architecture:

- *Permanent identity.* A citizen's Guide ID cannot be suspended, removed, or unilaterally re-assigned. Recovery is the citizen's nine-input regeneration; loss is the citizen's, not the protocol's.
- *Permanent anchors.* Every action ever signed remains on the chain. Right-to-erasure is satisfied by key destruction (the payload becomes unreadable), never by anchor rewrite.
- *One governance pipeline.* The Constitution and the Curriculum use the same proposal-vote-consensus pipeline at a 75 % threshold, scoped by a 1-byte document id from a namespace closed at compile time.
- *Anchor-shaped barter.* Resource exchange happens through Economy anchors and direct messages between citizens, with no platform-mediated payment layer.
- *Quantum-secure delivery.* Every byte of the protocol's signed and encrypted paths uses NIST post-quantum primitives (ML-DSA-65, ML-KEM-1024, AES-256-GCM, BLAKE3).
- *Mesh-redundant storage.* Payloads are encrypted, fragmented, and distributed across K-closest peer-slots in BLAKE3 hash space; no single point of failure exists for any payload.
- *Linear scaling.* Per-node work at one billion users is the same shape as per-node work at one million users, with each node holding 1/10,000 of the anchor stream and a corresponding share of the fragment XOR space.

The costs are owned explicitly. Identity is irrecoverable if all nine Guide ID inputs are forgotten — the protocol has no recovery path because building one would require a privileged actor. Every anchor signed remains permanent — the protocol has no global delete because building one would require a privileged actor. The mesh hosts whatever citizens upload — the protocol has no content filter because building one would require a privileged actor. The disk-cost floor that gives PHEUN its Sybil resistance also commits citizens to running their nodes for years — the protocol has no participation tier below that because the storage curve *is* the resistance.

PHEUN is not a payment system, although it can host barter. It is not an anonymity network, although it onion-routes its sensitive packets. It is not a blockchain, although it is an immutable signed ledger. It is the *substrate* on which all of those services can be expressed without re-introducing a privileged operator. Where Bitcoin replaced the central bank with proof-of-work and Tor replaced the trusted ISP with onion routing, PHEUN replaces the centralised internet substrate itself — the layer beneath social media, document publishing, identity, voice and video communication, and resource exchange — with a single deterministic mesh.

We have attempted, in this paper, to make the byte layout, the consensus protocols, the storage placement law, the universal governance pipeline, the soft-fork extension lane, the threat model, and the scalability analysis precise enough that a reader can verify every claim against the source code. Every constant cited in this paper is verifiable from the law files in `shared/`; every protocol step is implemented in the corresponding modules in `server/lib/`; every threat is covered (or explicitly not covered) in the canonical threat-model matrix in `CLAUDE.md`. The whitepaper, the source, and the running mesh are intended to be a single coherent system.

The protocol is what it does. Read the source.

---

## References and Source

- **Source code:** [github.com/nateofearth/peace-and-harmony-earth-united-network](https://github.com/nateofearth/peace-and-harmony-earth-united-network)
- **Wire-format law:** `shared/anchor-value-mappings.ts` — byte positions, dispatcher table, SQL field extractors.
- **Network constants:** `shared/network-config.ts`, `shared/coverage-config.ts`, `shared/hope-constants.ts`.
- **Anchor propagation (SVAP):** `shared/propagation-config.ts`, `server/lib/hope/anchor-propagation.ts`, `server/lib/hope/anchor-verify.ts`.
- **Fragment law:** `shared/fragment-id.ts` — PayloadWeave constitutional law.
- **Vision principles, threat-model matrix, architecture laws:** `CLAUDE.md`.

**Standards referenced**

- NIST FIPS 203 — Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM).
- NIST FIPS 204 — Module-Lattice-Based Digital Signature (ML-DSA).
- NIST FIPS 197 — Advanced Encryption Standard (AES).
- BLAKE3 — Aumasson, Neves, O'Connor, Wilcox-O'Hearn (2020).

**Prior art the design references**

- Nakamoto, Satoshi. *Bitcoin: A Peer-to-Peer Electronic Cash System.* 2008. — The original signed-ledger thesis; PHEUN replaces global ordering with deterministic placement.
- Maymounkov, Petar; Mazières, David. *Kademlia: A Peer-to-Peer Information System Based on the XOR Metric.* 2002. — The foundation of PayloadWeave's anchor-scoped XOR-DHT routing.
- Dingledine, Roger; Mathewson, Nick; Syverson, Paul. *Tor: The Second-Generation Onion Router.* 2004. — The onion-routing model Triple Sentry adapts for sensitive packet classes.

---

*PHEUN — A Decentralised Internet Replacement. Whitepaper V1. 2026. Open source. Open mesh. Open future.*





