HPPR Schemes

Tags: scheme, route, name, attest

© R.A.Sol

This spec defines standard schemes that sit above the HPPR packet, wire, and repository service specs:

These schemes are conventions. They use ordinary HPPR packets and ordinary repo commands.

Route discovery maps public or local route records to upstream repositories and content authorities. Authority-local names define stable identity names under a group. Attestations publish signed statements about verifiers or names.

Terms

Common Conditional Headers

Packets defined in this spec MAY include repeated conditional headers after that packet family’s required semantic headers. A packet is valid only while all of its conditions hold.

Headers:

Rules:

Hierarchical Public Group Route Discovery

Public group routing starts at the unnamed public root under //u/route/group//.

The root delegates top-level labels. Each resolved authority group then delegates its own immediate child labels. API routing stays explicit at the final resolved group.

Canonical roots:

Examples:

Group-name Model

Public group names use dotted suffix hierarchy for discovery only.

Examples:

Each delegation step uses one immediate child label only. Canonical records do not repeat or reverse the full suffix.

Full group-name reconstruction:

Child-label Rules

Each child label:

Provisioning

A route-capable client is provisioned out of band with:

Child-group Records

Canonical coordinate for top-level eu:

//u/route/group//eu/|/seal/<u-route-verifier>

Canonical coordinate for lab.eu under eu:

//eu/route/group//lab/|/seal/<eu-route-verifier>

Canonical coordinate for research.lab.eu under lab.eu:

//lab.eu/route/group//research/|/seal/<lab.eu-route-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <parent-route-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: <parent-group>
API: route/group
Key: <child-label>
TAI: <tai>
Upstream: <via>
Route-Authority-Key: <child-route-verifier>
[Upstream-Verifier: <repo-verifier>]
[Home-API: <api>]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
🖧: B.<hash>.H3
Data-Length: 0

Rules:

API Records

Canonical coordinate for API chat in group u:

//u/route/api//chat/|/seal/<u-route-verifier>

Canonical coordinate for API docs in group lab.eu:

//lab.eu/route/api//docs/|/seal/<lab.eu-route-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <group-route-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: <group>
API: route/api
Key: <api>
TAI: <tai>
[Upstream: <via>]
[Upstream-Verifier: <repo-verifier>]
[Content-Authority: <content-verifier>]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
🖧: B.<hash>.H3
Data-Length: 0

Rules:

After route resolution selects an API record, API content resolution continues through the deploy-pointer convention in [100-CONTENT-ROUTES.md].

Group Landing API Convention

Groups commonly expose one public landing API.

Convention:

Resolution Rules

To resolve direct root API //u/chat//...:

  1. connect to the public-root endpoint
  2. fetch //u/route/api//chat
  3. verify Seal with a trusted root route authority verifier
  4. use the API record’s endpoint and optional pins
  5. continue with the API deploy-pointer resolution defined in [100-CONTENT-ROUTES.md]

To resolve group landing page //lab.eu:

  1. connect to the public-root endpoint
  2. fetch //u/route/group//eu
  3. verify Seal with a trusted root route authority verifier
  4. connect to eu upstream
  5. fetch //eu/route/group//lab
  6. verify Seal with trusted eu Route-Authority-Key
  7. read Home-API when present, else fall back to home
  8. continue as //lab.eu/<home-api>//index.html

To resolve //lab.eu/docs//...:

  1. connect to the public-root endpoint
  2. fetch //u/route/group//eu
  3. verify Seal with a trusted root route authority verifier
  4. read Upstream, Route-Authority-Key, and optional repo pin for group eu
  5. connect to eu upstream
  6. fetch //eu/route/group//lab
  7. verify Seal with trusted eu Route-Authority-Key
  8. read Upstream, Route-Authority-Key, and optional repo pin for group lab.eu
  9. connect to lab.eu upstream
  10. fetch //lab.eu/route/api//docs
  11. verify Seal with trusted lab.eu Route-Authority-Key
  12. apply API-level Upstream or repo pin overrides when present
  13. resolve the API deploy pointer at //lab.eu/admin/deploy//docs/| as defined in [100-CONTENT-ROUTES.md]
  14. fetch content from the selected content root

Generic algorithm for a public group with labels:

Local Route Plane

The route scheme also defines a local effective route plane in the home repo.

Canonical roots:

All local route-plane packets use:

For this section, <local-route-authority-verifier> is the currently trusted verifier for the local route plane.

This spec does not require one canonical storage source for that verifier. Repository-service clients commonly use the Seal-By of //repo/admin/identity//root/|, but other clients or local implementations may provision it independently.

These packets are private client-side policy. They are not public namespace authority records.

Local exact-group records

Canonical coordinate:

Packet form:

🖧: S.<hash>.H3
Seal-By: <local-route-authority-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: repo
API: route/group
Key: <exact-group>
TAI: <tai>
Upstream: <via>
Route-Authority-Key: <verifier>
[Upstream-Verifier: <repo-verifier>]
[Home-API: <api>]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
🖧: B.<hash>.H3
Data-Length: 0

Rules:

Meaning:

The local plane stores exact groups, not delegation edges.

Local exact-API records

Canonical coordinate:

Packet form:

🖧: S.<hash>.H3
Seal-By: <local-route-authority-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: repo
API: route/api
Key: <group>/<api>
TAI: <tai>
[Upstream: <via>]
[Upstream-Verifier: <repo-verifier>]
[Content-Authority: <content-verifier>]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
🖧: B.<hash>.H3
Data-Length: 0

Rules:

Meaning:

Local auth records

Local route auth attaches an identity choice to routed access. Public route records do not carry auth data.

Canonical coordinates:

Packet form:

🖧: S.<hash>.H3
Seal-By: <local-route-authority-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: repo
API: route/auth
Key: <group>[/<api>]
TAI: <tai>
Auth: <identity-text>
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
🖧: B.<hash>.H3
Data-Length: 0

Rules:

Meaning:

Auth: anyone is valid and can explicitly override a non-anonymous group default for one API.

Any non-anyone Auth text is outside generic HPPR scheme semantics. Repository-service clients commonly use the identity-text forms defined in 045-IDENTITY-TEXT.md.

Effective Route Resolution

Effective resolution uses both the public route plane and the local route plane.

For target //<group>/<api>//..., effective resolution proceeds in this order.

Step 0: explicit endpoint override

If the input includes explicit via or CLI --via, that wins.

This bypasses stored endpoint selection. It does not erase separately stored local auth or content metadata that the caller may still apply.

Step 1: local exact-API candidate

Check:

If present, record it as a local exact-API candidate. Do not merge fields yet.

Step 2: determine the effective root anchor

If //repo/route/group//u/| exists, effective mode uses it as the root anchor. Otherwise effective mode starts from the provisioned public root.

Step 3: walk exact groups from root to target

Split the group into dotted labels and reconstruct exact groups from right to left.

Example for research.ops.lab.eu:

For each exact group in order:

  1. check local exact-group anchor:
    • //repo/route/group//<exact-group>/|
  2. if present:
    • use it as the effective anchor for that exact group
    • it shadows the canonical public answer for that exact group
    • descendant public lookup continues from this local anchor’s Route-Authority-Key
  3. otherwise:
    • fetch the canonical public child-group record under the current parent namespace
    • verify it using the current parent anchor’s Route-Authority-Key
    • use that public record as the effective anchor for the exact group

Step 4: resolve the API record

After the final exact-group anchor is known:

  1. read local exact-API candidate when present
  2. attempt canonical public API record:
    • //<group>/route/api//<api>
    • verified with the final exact-group anchor Route-Authority-Key
  3. for non-u groups, allow canonical Content-Authority fallback from:
    • //u/route/api//<api>

Content-Authority fallback applies only to Content-Authority. It never applies to Upstream.

Step 5: allow terminal local exact-API bootstrap

If no effective exact-group chain exists for the target group, a local exact-API record may still be sufficient.

In that case:

Step 6: effective field merge

API-level values override group-level values. Local values override public values at the same level.

Effective endpoint:

  1. local API Upstream
  2. public API Upstream
  3. local exact-group Upstream
  4. public exact-group Upstream
  5. failure if nothing resolves

Effective upstream repo verifier:

  1. local API Upstream-Verifier
  2. public API Upstream-Verifier
  3. local exact-group Upstream-Verifier
  4. public exact-group Upstream-Verifier

Effective content authority:

  1. local API Content-Authority
  2. public API Content-Authority
  3. for non-u groups only, canonical fallback to //u/route/api//<api>

Effective home API:

  1. local exact-group Home-API
  2. public exact-group Home-API
  3. implementation fallback home

Step 7: local auth attachment

After the effective route target is known, attach local auth in this order:

  1. //repo/route/auth//<group>/<api>/|
  2. //repo/route/auth//<group>/|
  3. implicit default anyone

Step 8: route client construction

The effective route client uses:

Canonical Route Resolution

Canonical resolution ignores all //repo/route/...//... packets.

For public names:

  1. start from the provisioned public root
  2. walk delegated public group edges only
  3. resolve the public API record under the final exact group
  4. apply canonical public Content-Authority fallback from //u/route/api//<api> for non-u groups only

For ~ groups:

Conditions and Canonical Truth

Condition-* evaluation uses canonical resolution, not effective local resolution.

For group u, canonical truth is the current provisioned public-root configuration:

A local //repo/route/group//u/| packet affects only effective local routing. It MUST NOT affect canonical Condition-* truth.

Reason:

Authority-Local Name Tree

Public or private identity naming lives under an authority group.

Canonical root:

//<authority-group>/name//...

Examples:

The same mechanism supports public and private identities. Visibility is controlled by the authority group’s repository policy.

Exact-name Syntax

Text form:

<part>[.<part>...]@<authority-group>

Examples:

The local name parts stay in written order. They are not reversed in storage.

Name-part Rules

Each local name part:

Core Model

The exact identity node is the continuity anchor. Each exact node has:

Top-level nodes are created by the authority group. Child nodes are created by the current holder of the parent node’s Name-Key.

Identity Node Records

Canonical coordinate for ops.alice.phone@lab.eu:

//lab.eu/name//ops/alice/phone/|

Packet form:

🖧: S.<hash>.H3
Seal-By: <authority-or-parent-node-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: <authority-group>
API: name
Key: <part>[/<part>...]
TAI: <tai>
State: active|withdrawn|compromised|rotated
Name-Key: <verifier>
[Current-Key: <verifier>]*
[Node-Type: role|person|device|team]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
[+Link: supersedes <hash>]
🖧: B.<hash>.H3
Data-Length: <len>

<optional note>

Rules:

Authorization rules:

Continuity rules:

Resolution

To resolve ops.alice.phone@lab.eu:

  1. resolve authority group lab.eu through the route scheme
  2. fetch //lab.eu/name//ops/|
  3. read Name-Key and Current-Key for ops@lab.eu
  4. fetch //lab.eu/name//ops/alice/|
  5. read Name-Key and Current-Key for ops.alice@lab.eu
  6. fetch //lab.eu/name//ops/alice/phone/|
  7. read Name-Key and Current-Key for ops.alice.phone@lab.eu

Exact-name resolution is exact. There is no implicit fallback from ops.alice.phone@lab.eu to ops.alice@lab.eu or ops@lab.eu.

Underspecified UX is handled by listing:

Public Attestation Tree

All attestation packets use:

Packet families:

Scope IDs

<scope-id> lets one issuer publish more than one independent statement for the same target and relation.

Typical values:

state/verifier

state/verifier carries attestation state about one signer verifier.

Canonical coordinate:

//u/attest/state/verifier//<subject-verifier>/<scope-id>/<relation>/|/seal/<issuer-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <issuer-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: u
API: attest/state/verifier
Key: <subject-verifier>/<scope-id>/<relation>
TAI: <tai>
State: yes|no|withdrawn
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
[Scope: //<group>/<api>//...]
[Expires: <tai>]
[Meaning: <text-or-urc>]
[+Link: evidence <hash>]*
[+Link: request <hash>]
🖧: B.<hash>.H3
Data-Length: <len>

<free text note>

Rules:

state/name

state/name carries attestation state about one exact identity name. It does not define names. Names are defined by the name scheme in this spec.

Canonical coordinate:

//u/attest/state/name//<scope-id>/<relation>/<authority-group>/<part>[/<part>...]/|/seal/<issuer-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <issuer-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: u
API: attest/state/name
Key: <scope-id>/<relation>/<authority-group>/<part>[/<part>...]
TAI: <tai>
State: yes|no|withdrawn
Target-Name: <part>[.<part>...]@<authority-group>
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
[Scope: //<group>/<api>//...]
[Expires: <tai>]
[+Link: evidence <hash>]*
🖧: B.<hash>.H3
Data-Length: <len>

<free text note>

Rules:

Relation names are ordinary strings. Common examples:

request

request packets are advisory only. They ask another verifier to publish attestation state.

Canonical coordinate:

//u/attest/request//<target-verifier>/<scope-id>/<relation>/<requester-verifier>/|/seal/<requester-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <requester-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: u
API: attest/request
Key: <target-verifier>/<scope-id>/<relation>/<requester-verifier>
TAI: <tai>
[Request-Subject: <subject-verifier>]
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
[Scope: //<group>/<api>//...]
[+Link: comment <hash>]
[+Link: profile <hash>]
🖧: B.<hash>.H3
Data-Length: <len>

<short free text request>

Rules:

meaning

meaning explains one relation name in issuer-local human terms.

Canonical coordinate:

//u/attest/meaning//<relation>/|/seal/<issuer-verifier>

Packet form:

🖧: S.<hash>.H3
Seal-By: <issuer-verifier>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: u
API: attest/meaning
Key: <relation>
TAI: <tai>
Label: <short label>
[Condition-Route-Authority-Key: <group> <verifier>]*
[Condition-Name-Key: <name> <verifier>]*
[Condition-Current-Key: <name> <verifier>]*
[Condition-State: <state> <exact-urc>]*
[Scope: //<group>/<api>//...]
🖧: B.<hash>.H3
Data-Length: <len>

<human-readable explanation>