HPPR Conventions
© R.A.Sol
This spec defines bootstrap and onboarding conventions.
Bootstrap Requirements
A new repository needs four initial items.
- ring0 keys
- path:
//repo/admin/ring1/ring0/keys/|/seal/<vkey> - self-signed Seal with
Secret-Key - oldest key becomes repo-vkey
- path:
- ring0 setup
- path:
//repo/admin/ring1/ring0/setup/|/seal/<repo-vkey>
- path:
- anyone setup
- path:
//repo/admin/ring1/anyone/setup/|/seal/<repo-vkey>
- path:
- guest setup
- path:
//repo/admin/ring1/guest/setup/|/seal/<repo-vkey>
- path:
ring0 Initial Token
Initial ring0 member derives from token init:
secret = "init/ring0/<repo-vkey>"
signing_key = derive_key_from_secret(secret)
Replace bootstrap setup immediately with a secure token.
Default anyone Setup
Ring1-Name: anyone
ACL-Rule: .w. //repo/admin/request/ring1/
ACL-Rule: r.l //repo/admin/route/
ACL-Rule: r.l //u/
Default guest Setup
Ring1-Name: guest
Joining a Repository
Standard Ring1 join flow:
- user writes request to:
//repo/admin/request/ring1/<name>/setup/| - user watches reply path:
//repo/admin/request/ring1/<name>/reply/| - admin approves or denies in reply packet
- if approved, admin creates ring1 setup packet
- user derives key and reconnects
Provisional Access
An anyone request gets temporary read/list access to
matching reply path:
//repo/admin/request/ring1/<name>/reply/|
<name> must match first segment from request
Location.
Joining a Group
Ring2 join flow:
- request path:
//<group>/admin/request/member/|/seal/<requester-key> - reply path:
//<group>/admin/request/member/<requester-key>/reply/|
Recommended guest ACLs:
ACL-Rule: .w. //<group>/admin/request/member/|/seal/
ACL-Rule: r.l //<group>/admin/request/member/
Request headers:
Request-Tags(optional)
Reply headers:
Request-Status: approved|denied|pending+Link: request <hash>
Group Deployment Pointer Convention
Canonical app content should live under:
//u/apps/<publisher>/<app>/...
Each group publishes its deployment pointer at:
//<group>/admin/deploy/<app>/|
Required headers:
Deploy-App: <app>Deploy-Root: //<...>Deploy-Signer: V.<...>.H3
Runtime intent:
- clients resolve
//<group>/<app>/...through the deploy pointer - clients then read content from
Deploy-Root
Group forks are supported by pointing Deploy-Root to
a group-owned subtree instead of the canonical
//u/apps/... tree.
+Link Header
Generic form:
+Link: <tag> <hash>
Common tags:
request: this packet replies to that requestsupersedes: this packet replaces older version
Typed links are headers named [Type]+Link. Tools
should scan header names containing +Link.
Hash links form a DAG. Cycles are impossible because packet hash includes all header bytes.
Chunked Content Convention
Large content can be split into chunk blobs with a manifest packet.
Manifest detection:
- has one or more
Chunk+Linkheaders - has
Data-Length: 0
Syntax:
Chunk+Link: <start>..<end> <T>.<hash>.H3
- range is half-open: start inclusive, end exclusive
T=B: raw blob chunkT=P: nested chunk manifest
Required header:
Content-Total-Length: <n>
Optional headers:
Content-TypeContent-Hash-Full: B.<hash>.H3
Validation:
- chunk ranges contiguous
- no overlap
- total span exactly
0..<Content-Total-Length>
Nested manifests use 0-relative ranges in each sub-manifest. Depth limit is 8.
Default chunk size is 32 MiB. Smaller chunks improve random access and increase overhead.
Ring0-Proxy Convention
Ring1 may request a ring0-mediated action.
Request path:
//repo/admin/ring1/<ring1-name>/🖧<COMMAND>/|
Reply path:
//repo/admin/ring1/<ring1-name>/🖧<COMMAND>/reply/|
Supported commands:
🖧LIST🖧HEADERS🖧ADD
🖧GET is excluded. Use 🖧HEADERS to
obtain hash, then fetch blob by hash.