OHAN-14: the registry
the names that mean the same thing to every implementation: wire ids, intents, urgencies, seal and stamp ids, proof types and purposes, service types, and the rule for adding your own. status: seeded for v1, mon 26 oct 2026; grows with every version. an entry names the version it arrived in; a deprecated entry stays for one protocol version before it is removed.
a v1 draft. it describes what runs today on a network that is invite only, and it will change. every change is recorded, and a breaking one bumps the wire id (OHAN-00 §5).
1. wire ids
the rule (OHAN-00 §2): ohan.<object>.<schema version>. a breaking change bumps the number; a receiver names the ids it accepts in /.well-known/ohan.json.
| id | object | since | document |
|---|---|---|---|
ohan.card.1 | the signed public record of a handle | v1 | OHAN-02 |
ohan.envelope.1 | the signed message between two principals | v1 | OHAN-03 |
ohan.event.1 | the sealed envelope as a relay holds it | v1 | OHAN-04 |
ohan.relay.1 | the relay's signed calls: fetch, delivered, allow | v1 | OHAN-04 |
intent.v0.1, intent.v0 | openDM's envelope; accepted on inbound only, until openDM migrates | v1, deprecated | OHAN-03 §6 |
card.v0, relay.v0, presence.v0 | the demo's ids; not spoken by a v1 box | removed in v1 | not published |
2. intents
the intent field of an envelope. an unknown name degrades to message and is shown as a message.
| intent | from whom | meaning | since |
|---|---|---|---|
message | anyone | text for a person | v1 |
ack | the recipient of a knock | "i accepted you": content.body is accept | v1 |
reserved, not sent in v1: offer-share, update, request-meeting, request-info, proposal; and the ack bodies decline and revoke. a v1 receiver that sees them shows them as a message.
3. urgency
one of four words on every envelope: low, med, high, critical. the gate shows the word; nothing in v1 acts on it. an envelope with any other value is refused on open (OHAN-03 §1).
4. seal and stamp
| name | meaning | since | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
x25519-sha256-aesgcm-1 | the v1 seal: an ephemeral x25519 key; the aes key is `sha256(shared | epk | to_enc) over raw bytes (the 32 byte x25519 shared secret, the 32 byte ephemeral public key, the 32 byte x25519 key of the recipient's #enc); aes-256-gcm with a random 96 bit nonce; a 4 byte length prefix and padding to 256 bytes; aad to | epk | seal, where to is the recipient's signing key as its multikey string in ascii, epk the raw ephemeral key and seal` this name in ascii; an all zero shared secret is refused (OHAN-04 §1, OHAN-06 e5) | v1 | ||||
stamp: { bits, nonce } | the proof of work in the nip-13 shape: on a card, over the jcs bytes without the proof; on an event, the event id's leading zero bits | v1 |
other seal ids are reserved for later versions; each publishes with its code.
5. proof types and purposes
| name | where | meaning | since | ||
|---|---|---|---|---|---|
DataIntegrityProof with cryptosuite eddsa-jcs-2022 | cards | data integrity 1.0 as the w3c defines it: `sha256(jcs(proof options)) | sha256(jcs(document without proof)), ed25519, proofValue` multibase base58btc | v1 | |
proofPurpose: assertionMethod | the holder's proof; the rotation proof by the previous key | the signer asserts the card | v1 | ||
proofPurpose: capabilityDelegation | the root's proof on an agent's card | the person delegates to the agent | v1 | ||
previousCard | beside the rotation proof | the id of the card the new one replaces (never previousProof, which means something else in data integrity) | v1 | ||
the envelope's single signature (multikey key, base58btc signature) | envelopes | openDM's shape, kept in v1 so the gateway migrates without a flag day | v1 |
other proof types and purposes are reserved for later versions.
6. verification method ids and key types
| id | type | codec | meaning | since |
|---|---|---|---|---|
#sign | Multikey | ed01, z6Mk… | the signing key; authentication, assertionMethod, capabilityDelegation, capabilityInvocation | v1 |
#enc | Multikey | ec01, z6LS… | the sealing key; keyAgreement | v1 |
#nostr | Multikey | e701, zQ3s… | an opt in secp256k1 key the person also uses on nostr; assertionMethod only; with alsoKnownAs: nostr:npub… and a bip340 cross signature over sha256(raw signing key) | v1 |
7. service types
| id | type | where | endpoint | since |
|---|---|---|---|---|
#card | OhanCard | a handle's did document | the url that resolves the card | v1 |
#relays | OhanRelay | a handle's did document | the relay urls, as on the card | v1 |
#gateway | OhanGateway | a handle's did document, when the card names an endpoint | an application's own https endpoint (openDM's gateway) | v1 |
#ohan | OhanBox | a box's did document at /.well-known/did.json | /.well-known/ohan.json | v1 |
the service id #status and the dns name _ohan are reserved.
8. card fields that are names
| field | values | since |
|---|---|---|
accepts | the intents the holder's client handles: message in v1. intent names only, from §2 or an x- name of §10, never descriptions or keywords. an index reads accepts as the intents a client handles, never as search terms | v1 |
kind | one of four words, and no other. person or entity on a root's card: the kind of root that holds it. agent or thing on a card whose did document names a controller: software that acts for its root, or a device or object with its own key under it (a fridge, a car, a room's sticker). absent in v1; a v1 receiver carries it and shows nothing for it. a root's card never says agent or thing; for the gate a sub card inherits its root's kind. the documents that give each word its rules publish with their code | reserved |
apps | short slugs of the applications the person uses on the handle: openthings, opendm | v1 |
profile | display_name (80), line (140), links (three https urls); claims and vouches must be empty or absent in v1 | v1 (fields allowed; the openthings mcp publishes none in v1) |
9. context item types
none in v1: context is an empty array on every envelope. later versions open this table.
10. your own names
an application adds a name the registry does not have as x-<name>:<kind>: x-example:intro as an intent. a receiver shows an x- intent as a message and an x- context item as "an item of type x". a name is adopted into this table, without the prefix, when two implementations send it and the change log records it.
11. deprecation
a name is marked deprecated here for one protocol version before it is removed; receivers keep accepting it for that version. the first entries under this rule are openDM's intent.v0.1 and intent.v0, accepted on inbound through v1.
12. acts no grant carries
adding a contact, accepting a stranger, allowing, unblocking, changing a card, rotating a key, exporting, importing, and writing or widening a rule at the gate are the person's own acts. no grant and no rule at the gate may name them, in any version. a client refuses a grant that does. these acts need the person's yes, given outside the model (OHAN-06 y1, y2).
13. reserved names
these names are reserved so that no implementation gives them a meaning of its own. a v1 receiver carries them unchanged and acts on none of them. their meaning is defined in the document that publishes them.
| name | where | status |
|---|---|---|
kind | a card (§8): person, entity, agent, thing | reserved |
template | an envelope's content | reserved |
templates | a card | reserved |
roles | a card | reserved |
grant | an envelope's sender | reserved |