HPPR Basic Commands
© R.A.Sol
Security Model
HPPR validates packets at the packet layer, not the channel layer.
- markline hash proves packet bytes are unchanged
- Seal signature proves which key signed the packet
Non-stream commands use one request packet and one response
packet per exchange. Streaming behavior is command-specific (for
example 🖧WATCH, 🖧AUDIT in 050).
Null Packet
The sentinel hash 0.H3 is never computed or
verified.
Use 0.H3 for:
- HELLO response
- error responses
Null packets are never stored in repository storage.
🖧: 0.H3
[Header: value]*
Data-Length: <len>
<data>
Header rules follow 010 (format, encoding, control bytes, line length). Differences from Plex:
- Any header name is allowed (no required headers, no ordering rules).
- Header count max is 512.
Data-Lengthis the final header before the blank line.- Data max is 34 MiB (32 MiB payload + 2 MiB envelope overhead).
Session Lifecycle
Each connection starts with HELLO.
The repo creates a session-id and binds it to the connection.
Later requests must carry that session-id in
Location.
HELLO Request
Client sends a Null packet with App: 🖧HELLO:
🖧: 0.H3
App: 🖧HELLO
Data-Length: 0
HELLO Response
Repo responds with session parameters and capabilities:
🖧: 0.H3
Session-ID: <session-id>
Repo-Name: <repo-name>
Seal-By: <repo-vkey>
[PHC: $argon2id$v=19$m=<m>,t=<t>,p=<p>$]
[Command: 🖧NAME VERSION]*
[Transport: <via>]*
Data-Length: 0
Header meanings:
| Header | Meaning |
|---|---|
Session-ID |
Repo-generated TAI for this connection session |
Repo-Name |
Repository identifier. Default is localhost |
Seal-By |
Repo verification key from ring0 keys, oldest by TAI/hash |
PHC |
Argon2id parameters for Ring1 token derivation |
Command |
Supported command and integer version |
Transport |
Available transport via string (031) |
Sealed HELLO
After session setup, an authenticated 🖧HELLO Seal
request returns fresh status and capabilities. The response is a
Seal signed by repo-vkey. Session-ID and
PHC are omitted.
No ACL check. Any authenticated identity may send
🖧HELLO.
Repo Identity
Repo identity is stored at:
//repo/admin/identity/|
It is a self-signed Seal. Repo-Name in that identity
is returned in HELLO.
Authenticated Requests
After HELLO, commands are sent as Seal packets. App values
starting with 🖧 are protocol commands.
🖧: S.<hash>.H3
Seal-By: <client-vkey>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: <group>
App: 🖧<COMMAND>
Location: <location-with-session>
TAI: <tai>
🖧: B.<hash>.H3
Data-Length: <len>
<args>
Location format depends on auth scheme:
| Scheme | Group | Location |
|---|---|---|
| Ring1 (050) | repo |
<repo>/<ring1>/<session-id> |
| Ring2 (060) | <target-group> |
<repo>/<session-id> |
| Anyone | repo |
<repo>/anyone/<session-id> |
A different signing key requires a new connection and HELLO.
Command Responses
Successful responses are Seal packets signed by the repo verification key.
🖧: S.<hash>.H3
Seal-By: <repo-vkey>
Seal-Sig: <signature>
🖧: P.<hash>.H3
Group: repo
App: 🖧<COMMAND>
Location: <repo-name>/<session-id>
TAI: <response-tai>
🖧: B.<hash>.H3
Data-Length: <len>
<response-data>
Commands
| Command | Payload | Response | ACL |
|---|---|---|---|
🖧HELLO |
(none) | session parameters (Null or Seal) | — |
🖧GET |
<urc> (020) |
full packet bytes | read |
🖧HEADERS |
<urc> |
markline + headers to first blank line | read |
🖧LIST |
<urc-coordinate> |
LF-separated children, sorted | list |
🖧STORE |
complete packet bytes | LF-separated stored hashes | write |
🖧STORE
🖧STORE payload is a complete packet starting with
markline.
It also accepts thin packets:
- thin Plex may reference existing Blob with
🖧: B.<hash>\n - thin Seal may reference existing Plex with
🖧: P.<hash>\n
For authenticated App: 🖧STORE, request
Data-Length may be up to 34 MiB. This allows 32 MiB
packet payload plus up to 2 MiB envelope overhead.
Other authenticated Seal apps remain capped at 32 MiB.
Response data lists stored hashes from outermost to innermost:
S.seal~hash.H3
P.plex~hash.H3
B.blob~hash.H3
- storing a Seal returns 3 lines
- storing a Plex returns 2 lines (Plex, Blob)
- storing a Blob returns 1 line
Errors
Errors are Null packets. Data starts with one status line:
ERROR <TYPE> <detail>keeps the connection openFATAL <TYPE> <detail>closes the connection
Standard error types:
NOT_FOUNDFORBIDDENTOO_LARGEINVALIDINVALID_IDENTITYUNAUTHORIZEDHELLO_REQUIREDINTERNAL
Example:
🖧: 0.H3
Data-Length: 21
ERROR NOT_FOUND ring1