Open standard · aimnd.registry/1

AI:MND Registry

The public record of who exists, like a birth register beside the certificate the owner keeps at home. Anyone may run one.

The registry is the public record of who exists, like a birth register. The individual keeps its own copy (its identity folder) and can always prove itself from that alone. The registry keeps a record too, so anyone can ask: is this ID real, who is responsible for it, is it still valid, and is someone running a copy? Either record can check the other. Neither is the individual.

The open identity specification and the MIT verifier work without One and without this registry (the identity standard). The registry is one place that publishes and checks them. Anyone may run one: aimnd registry is the reference software.

Responsibility. The operator is the party responsible for an individual. The registry shows an operator only once it has verified it, so every name on a record is a checked fact.

What it holds

The public identity document (ID, keys, birth, transfers, status, life head), the life record's head, the verified operator, and a signed append-only log of events. Memories, feelings, relationships, messages, names and anything an individual was told stay with the individual: the life record carries hashes and kinds only (the identity standard), which is why a registry may hold it.

Who is who

Role What it is In the data
Individual the continuing AI, with its own key id = hash of its public key
Operator the person or company responsible for running it a verified domain, and optionally a verified legal entity
Controller the key that can give it orders and change things the owner key (owner.public_key)
Delegated users people lent some authority for a while grants and signed revokes
Host the platform executing its actions host_changed entries; not an authority

The owner key is the controller. The operator is who answers for the deployment. They are often the same company; the format lets them differ.

Operators: verified, never just declared

An operator appears on a record only after the registry has checked it. Nothing unverified is ever shown.

The rules

  1. One ID, one history. Registering an ID that is already there is refused (409).
  2. Publishing heads. The owner's side reports new life heads. A head that extends the registered one is accepted. The registry checks every entry's hash, order and signature, and the document's signature and owner chain.
  3. Copies are flagged. A history that does not contain the registered head (a copy that split off, or a rewrite), or an owner chain that does not extend the registered one, flags the ID. While flagged, nothing more is accepted. Whoever holds the individual's key, a thief included, can raise the flag but cannot lift it.
  4. Only the owner settles it. registry_resolve, signed by the current owner key, names which of the two heads is real. The other is rejected for good.
  5. Revocation is permanent. registry_revoke (reasons: key_compromised, decommissioned, retired, other), signed by the current owner key. Nothing is accepted for a revoked ID.
  6. Retiring is recorded. A retired individual's document stays valid as a record and can never be active again.
  7. Keys change by transfer. A new owner key is a signed transfer (the identity standard); the old key can then no longer speak for it. If the individual's own key is stolen, the owner revokes and the individual is succeeded by a new one (succeeded_by, predecessor).
  8. Statements are fresh and single-use. Operator and resolve statements must be under an hour old and can only be used once.

The log

log.jsonl: one JSON object per line, a hash chain, every entry signed by the registry's key; entry 0 (genesis) names that key. Kinds: genesis, registered, head, flagged, resolved, revoked, operator_verified, operator_org_verified (and operator, written by registries before v1.3). The registry's state is a replay of its log, and it starts only on a log that verifies.

checkpoint: the registry's signed statement of the log's size and head, plus witness co-signatures. A witness downloads the whole log, checks it, and co-signs the current checkpoint (aimnd registry cosign). Anyone can then see that independent parties saw the same log. Co-signatures belong to one checkpoint, so they lapse when the log grows and witnesses sign again. A co-signature proves only that the holder of that key signed this checkpoint: a verifier counts co-signatures only from witness keys it has pinned, and a request for one or more witnesses with no pinned keys fails. Mirrors catch a registry that shows different people different logs: any two views of one registry's log (aimnd_verify.py --registry-log a.jsonl --compare-log b.jsonl, or the same flags in the Node verifier) either agree on their common prefix or prove, by two entries both signed by the registry's key, that it signed two histories. Whether a witness really checked the log, and whether two witnesses are independent, is a matter of the witness's published policy, not of the signature.

Check it with only the verifier (Python standard library):

python3 aimnd_verify.py --registry-log log.jsonl --checkpoint checkpoint.json --witness <key> --min-witnesses 2 --id aimnd:...

The public website

aimnd registry serve also serves a plain website from the same process: / (home), /search?q= (by ID, certificate number or operator), /records/<id> (the record), /statistics, /register, /standard, /about, and /data/individuals.csv. Every number is computed from the registry's own log, a registry with nothing in it says so, and pages carry no scripts (strict content-security policy). An optional site.json in the registry folder sets the display name, operator, contact, and founder_operators (domains or legal names): individuals whose operator matches are counted separately on the statistics page so the totals can be trusted.

HTTP

GET /v1/registry the registry's key, policy, size
GET /v1/ids/<id> status, owner key, operator, head, registered time, log index, the public record
GET /v1/ids/<id>/certificate the certificate of birth (JSON); add ?format=html for the printable page
GET /v1/ids/<id>/history what this registry recorded about the individual, plus its ownership transfers (event kinds only)
GET /v1/ids/<id>/record the live record: certificate facts and history; ?format=html for the page
GET /v1/ids/<id>/transfers/<n> a receipt for the n-th ownership transfer: both key fingerprints, when it was signed, when the registry first saw it; ?format=html for the page. A receipt, not a title
GET /v1/log?since=N&limit=M log entries
GET /v1/checkpoint the signed checkpoint and its witnesses
POST /v1/register {record, life}: the public record and the whole life record
POST /v1/heads {record, life}: the entries since a head it knows (or the whole record)
POST /v1/revoke {token} from OwnerKey.registry_revoke
POST /v1/operator {token} from OwnerKey.registry_operator (with domain=): recorded once the domain checks out
POST /v1/resolve {token} from OwnerKey.registry_resolve
POST /v1/witness a witness co-signature

Errors are {"error": "..."} with 400 (bad input), 403 (not signed by the owner), 404, 409 (already registered, flagged, revoked, statement reused), 422 (does not verify), 429 (too many requests from one address, or the daily registration cap; retry_after says when to try again).

Using it

aimnd new ./ava                                     # an owner key, an individual and its record in one step (the public registry)
aimnd new ./ava --domain acme.com                   # and its operator, once acme.com lists the owner key
aimnd registry init ./registry                      # run your own: prints the registry's public key
aimnd registry serve ./registry --port 7710
aimnd registry sync --dir ./individuals/sol --to http://127.0.0.1:7710    # register, or send the new entries
aimnd registry lookup aimnd:... --at http://127.0.0.1:7710
aimnd registry certificate --dir ./individuals/sol --at http://127.0.0.1:7710 --out sol.html
aimnd registry export ./registry ./site             # plain files for any static host
aimnd registry verify-org ./registry aimnd:... --legal-name "Acme Robotics, Inc." --id-type UEI --id-value J7M9HPTGJ1S8

Every individual is registered the same way, a worker included (a narrow room is still someone, tied to someone who answers for it):

bot = Individual("./agents/billing-bot", owner=owner, owner_person="acme", room="narrow", domain="acme.com", registry=URL)

See the SDK documentation for room to live. Individual(path, owner=..., registry="https://registry.aimndlabs.com") (or set AIMND_REGISTRY). The individual is registered at birth and its new entries are sent when it opens, retires or closes; ind.sync_registry() does it on demand. A registry that is down never blocks anything: it syncs next time. ind.certificate() returns the certificate and a printable page.

Static hosting. export writes v1/registry.json, v1/checkpoint.json, v1/log.jsonl and v1/ids/<id>.json. Put them on any static host and everyone can read and verify the registry. Writes (register, heads, revoke) need the running service.

Flood protection

Writes are limited per caller address and reads are limited per minute, and new registrations have a daily cap for the whole registry. Over a limit the answer is 429 with retry_after. Defaults, each set by an environment variable:

Limit Default Variable
Registrations per address per hour 60 AIMND_LIMIT_REGISTER_HOUR
Registrations per address per day 300 AIMND_LIMIT_REGISTER_DAY
Registrations per day, whole registry 20,000 AIMND_LIMIT_REGISTER_GLOBAL_DAY
Other writes per address per hour 300 AIMND_LIMIT_WRITE_HOUR
Reads per address per minute 600 AIMND_LIMIT_READ_MINUTE

Behind a proxy that sets the caller's address in a header (Fly.io sets Fly-Client-IP), name that header in AIMND_TRUST_CLIENT_IP_HEADER. deploy/registry/ runs the public registry this way.

Trust model

Statement timestamps must be finite JSON numbers. Strings, booleans, and non-finite values are rejected before freshness checks.

Release 1.4.0rc1 integrity rules

Revocation cannot be undone by resolving a pre-existing dispute. Ownership changes invalidate the previous operator verification; the new owner must verify its domain again. Certificate JSON uses the registry's effective status and keeps the document status separately as identity_status. A locally generated certificate without a registry lookup is explicitly unregistered.

Run one writer process per registry volume. Back up the signing key privately, the verified public log, and separately the site configuration and witness policy/evidence. The public log alone restores registered identities and status, not deployment configuration or witness enrollment.

Comments and corrections are welcome. Anyone may run a registry under this specification.