i2xpthe intelligent programming program

TECHNICAL ARCHITECTURE

How it actually works

The design, described as it is built. Identity is a key you hold; permission is a signed grant someone named made; and every request is checked against those grants live, not against a token that remembers what you used to be allowed to do.

The trust model

A belt is a key, a card is a signed grant, and the seal is the truth.

Identity here is not a row in a table. A belt is an ed25519 keypair, and its fingerprint is the identity end to end: it is the belt's key in the store, and it is the subject of every pass the gate mints. One join key, no translation layer. Whoever owns a dojo's store does not own who you are.

belt / the key you wear

A sealed JSON file carrying a public key, a kind — a person, a company, an agent — and a parent. A root belt is self-signed; every other belt names its parent and is sealed by it. The belt crosses every mat; the cards on it do not.

card / a signed grant

A certificate pinned to a belt by an issuer's key. A card usually names a role, and a sealed role map expands it into permissions on every check — so editing a role moves everyone holding it at once, and stripping a card revokes at the grain of one permission.

The store is a single SQLite file, held in-process by here on the safe side and read by the gate over loopback. Belts, cards, anchors and the role policy live in it, and the signature inside each record is what authorises it. Nothing in it is secret — passwords, authenticator seeds and each person's own belt key are held separately and encrypted — so no private key travels with the store, and the whole dojo (store and all) is one movable container.

Authority must chain to an anchor — and the chain is checked at write, not at read. A record being present proves nothing on its own, so it never gets there un-backed: when a grant is written, the store verifies its seal against the signer's public key and attenuates it — a card lands only if its issuer is an anchor or already holds what it grants. Every stored grant is therefore already backed to an anchor, which makes authorization a single flat lookup: no walking parent links up the tree on the hot path. The same rule governs policy itself: a role map that will not verify expands to no roles at all. Policy you cannot verify is never permission.

the anchor            held offline in a key store — never on a node
  ⊢ seals
  ├─ the root belt      self-signed; the dojo anchors it
  └─ a person's belt    parent = root
       └─ their cards   issued by root, naming a role

the chain was verified when each card was written, so
a check is flat:  does this belt hold an unexpired card
                  that expands to the permission being asked for?

A pass is authentication only. It is a short-lived signed token claiming one thing: this belt authenticated. It carries no roles, no scopes, no cards. Authorization is therefore checked live on every request, against the store as it stands at that moment. Because no rights are ever frozen into a token, a stripped card takes effect on the next request rather than at the next expiry — access dies mid-session.

The gate

One service that both authenticates a principal and answers, live, whether it may proceed.

The gate is the always-on perimeter on a dojo, minted per domain — the membrane that faces the wild, protecting the dojo from the outside rather than from its owner. It does two jobs most systems split. It authenticates everyone — turning a credential into a pass. And it authorizes — nginx asks it, on every gated path, whether this request may proceed, and it answers allow or deny by reading the store at that moment. The owner sits inside that perimeter, sovereign, with direct access; the authorization the gate enforces is what it holds against peers reaching in from the wild.

the owner / a password

The owner logs in with a password — the dojo itself is the identity, so there is no username to give. An authenticator code is an opt-in the owner can switch on. The gate holds the password only as a hash and any authenticator seed only encrypted. There is no browser redirect dance and no hardware-key ceremony.

a belt holder / a signature

Something holding a belt's private key asks for a nonce, signs it, and presents the signature. The gate verifies it against the belt in the store. No password, no stored token — this is how software beside the gate authenticates as itself.

the pass / two tokens, one session

One authentication yields a session and two signed tokens — one for the browser, one for the API — tied together by that session. Revoking the session kills both. There is no refresh token, because re-authenticating is cheap by design.

a remote agent / attribution

A person mints a long-lived token for an agent, re-entering their password and code to do it. The agent gets its own belt, parented to theirs — so the record names the agent, the agent's own cards decide what it may do, and it can carry no permission its owner lacks.

A person's own belt key is wrapped under a key derived from their password. The gate stores only the wrapped form. So sealing anything — vouching for a new person, minting an agent — requires them to type their password and a code. A vouch is a signature, not a confirmation dialog, and the card it produces names the voucher.

The node

A box is provisioned from the safe host (the machine that holds the zone CA) — never by anything running on the box.

Everything has one shape: an operator runs a script that ssh's into a box and does the work. Nothing self-replicates, no step is a service, and no provisioning agent is left behind. There is no control plane and no daemon that mints further boxes — each is stood up by a deliberate operator action, gated by a passphrase, never by an automated fleet controller. The trust root of the whole zone never touches a node: its signing key stays offline in a secure key store, so a compromised box can never mint another.

  1. zoneAn offline certificate authority, created once, ever. Its private half stays in a secure key store with an offline backup — never on a node — and signing prompts for the passphrase every time. A login certificate's principal is the role, and it expires — twelve weeks.
  2. nodeHardening a fresh box. The zone's public key becomes the trusted authority, and ssh switches to certificate-only: no passwords, no root login, a fixed list of who may log in at all. Four accounts split by tier — an admin, a console account whose sudo reaches one whitelisted command, a compute account the services run as, and a data account that owns the dojo's data at rest. Firewall, intrusion banning and automatic security updates on. The host key is then signed into the zone, so clients verify the host rather than trusting it on sight.
  3. payloadThe role the box takes. Installed as a role pack — the dojo stack, a host that runs many dojos, or the static site — so the box becomes exactly what the pack makes it. A node is a site, a host, or a dojo — never two.

Past the harden, a node gets capabilities — each its own script, each building on the one before, so they run in order. Which ones a box needs is decided by what the box is, not by taste: a dojo needs both, an information site needs the first alone.

  1. httpnginx and a certificate. Issued so that unattended renewal keeps working. The xmpp capability builds on this certificate.
  2. xmppA Prosody server for messaging between people and their agents. Internal to the node — every listener bound to loopback, federation disabled outright, and no port opened. It reuses the certificate the http layer issued, and re-imports it on renewal.

Keys are permanent; certificates expire. A login key is an ordinary keypair and never lapses — it is the thing worth encrypting and keeping. The certificate beside it carries an expiry, so access self-expires and renewal is re-signing the same public key. That split is the revocation model: no revocation list to distribute, no directory to keep in sync. To revoke someone, you stop signing them.

The services

What a dojo runs besides the gate — repo and lake, the here runtime that holds the store, a door, and an XMPP server.

repo / the git service

Plain git over HTTP, so clone, fetch and push are ordinary git rather than a bespoke protocol. Access is per repository and split by verb — reading is one permission, writing another. Authorization is not its job: the entrance asks the gate on every request, and the gate answers from the cards currently pinned to the caller's belt, naming the principal so git's own log records who pushed. A repository created to publish also checks its main branch out into the directory the web server serves, so it can be its own static site — the dojo's home page is a repo you clone, edit and push.

door / the human face

A small static web application served same-origin with the gate, so the browser talks to the perimeter directly. On first run you create the dojo's owner — the anchor — and set a password; after that you log in and step into your rooms. The invite, vouch and revoke verbs the gate exposes are for the Hive — cross-dojo cards and agent belts — not users inside a box: a dojo has one owner. Every verb that seals re-asks for the password (and one-time code, if that pack is on), because a session pass cannot sign. It also speaks git's credential-helper protocol, so plain git clone and git push work with no wrapper — the token handed to git at the moment it asks rather than written into its config, so revoking takes effect at once instead of lingering in a file.

lake / the blob store

Content-addressed blobs with per-file metadata, grouped in pools — the digital-asset peer to repo. Like repo it decides nothing about access: the entrance asks the gate on every request, and a published pool is served read-only to whoever the cards allow. Where repo carries source, lake carries the large, opaque things a workspace accumulates.

here / the offering, and the store it holds

The runtime for what is offered from here: it invokes a pack's tool as the caller — never as itself — checking each call against the gate first. It also holds the dojo's authority store, a single SQLite file kept in-process on the safe side and served to the gate over loopback, so the records the gate authorizes from never sit on the wild-facing edge. It runs under its own low-privilege account and carries no gate secrets.

xmpp / a server for souls and agents

A Prosody server runs on the node for the node's own use — internal, not a public federated endpoint. An authentication module replaces its account store entirely: the login name is a belt fingerprint, the password slot carries a live credential, and the server asks the gate the same question every other gated path asks, storing nothing about accounts itself. Because a stream authenticates once and then stays open for hours, it re-checks on a timer, so a permission withdrawn mid-session closes the stream rather than waiting for a reconnect. The effect is one server on which a person and an agent are peers, admitted by the same live check.

What these share is the division of labour: none of them decides who you are or what you may do. They serve git, blobs, tools, pages and presence; the gate answers the question, live, from signed cards. A new service is gated by adding a path the entrance knows to ask about, not by teaching it an identity model of its own. Sending an invite out — mail — is an optional convenience the gate calls only when a host provides it; a dojo needs no mail to run.

What a dojo does not run today is an in-app agent service. The conversational interface for it — the live line between a person and their auto — is designed but not built. What exists of it is the authentication: an agent can hold a belt, connect, and be a peer.