Correcting an overstatement from the previous commit, where I had written that a node IS a conversation. It is not. A node is a machine inside the mesh, and the session is one of the things running on it -- like the host, like any workload. That also dissolves the conflict I flagged as unresolved rather than needing anyone to decide it. 0001 says a node does not authenticate to a model provider, agents do. Still true: the session authenticates, and the session is not the machine. The node does not think, something on the node does. I had manufactured the contradiction by promoting a feature into an identity. 0001's summary row is corrected the same way, and says explicitly that neither the node's session nor a hired worker makes the node itself a thinking thing -- both run on a machine, which is what leaves that line untouched.
9.8 KiB
topic, status, date, deciders, reconstructed
| topic | status | date | deciders | reconstructed |
|---|---|---|---|---|
| the tiers | accepted | 2026-08-28 | jochen | false |
4. A node, and how it joins
Consolidated 2026-08-28 from four records.
What a node is
A managed machine inside the mesh. Not a device that is merely known about, not an unprivileged something. If the mesh does not manage it, it is not a node — it is a client, a peer, or a thing on the network, and those want their own names rather than a weakened version of this one.
A disconnected node is still a node, in a different situation. Reachability is state, not class. A machine switched off, roaming, or behind a connection that has dropped has not become a lesser kind of thing; it has a last-known state and a pending set of declarations.
The distinction people reach for is real, but it is capability — what this machine can be asked to do — and that belongs in the host's profile rather than in the definition of a node.
This is the rule that does the most work elsewhere. A single control plane is tolerable because its absence is every node in the ordinary disconnected situation at once. An episodic host on a phone is that situation more often. Neither needed a new mechanism.
A node runs one agent session
Written 2026-08-29. It runs on every node today and appeared in no record, which is how something deliberate comes to look accidental.
A node is a machine. The session is a feature of it — one of the things running there, like the host, like any workload. The node does not think; something on the node does. Which is why ADR 0001's a node does not authenticate to a model provider, agents do holds unchanged: the session authenticates, and it is not the machine.
It is permanent, and it remembers. Anything in the mesh can send it a message; it replies; and what it was asked ten minutes ago is still there next week, alongside what everything else asked in between — the same way both sides of any conversation remember it.
Its system prompt is the node's engram — what makes one node's replies recognisably its own rather than generic.
It has its own tools, and fewer than a session a person is driving directly. So a question can be answered by going and looking: what is in our forge, not only what is your battery.
Messages travel the broker like everything else (ADR 0002). There is no second transport and nothing is dialled.
Any node can message any node, and this is the one part of the system that is genuinely a mesh — symmetric, with no centre. A node that is asked something it does not have can ask another, and how it passes the question on is its own business: it may say who wants to know, or simply ask. A person relaying a question makes the same choice, and it follows from the engram rather than from a message format.
There is no authorisation between nodes. Every node is the operator's own, so a message from one is a message from them, and asking a node something is asking a colleague rather than presenting credentials. Stated once so it is not discovered later: the mesh boundary is therefore the security boundary — anything inside can reach what any node can reach, which is what puts the whole perimeter on the token and the overlay (ADR 0007).
It can be switched off, and switched off it still answers. A node whose session is disabled replies saying so, at once, with no model involved — the queue is still read, and the state is the reply. That is deliberate and it is the same rule the host follows about a service that does not exist: absence must never be indistinguishable from a failure to answer. A node with nothing there is a silence somebody has to go and diagnose; a node that says I am switched off is not.
One per node, always, and it cannot be moved to another machine. Two and nothing decides which replies; none and the node is mute; moved, and one machine is answering as another.
It is not an employee (ADR 0003). Nobody hires it, it holds no tasks, it drains nothing and it is never reassigned — that vocabulary was written for workers and does not describe this. It exists because the node does, and it is gone when the node leaves.
How it joins
The host has one behaviour and two sources of declaration. What differs between the first node and the fiftieth is not what the host does but where the declaration comes from — and, as above, that is a situation rather than a class.
| declaration comes from | |
|---|---|
| no mesh reachable | the pinned bundle the host carries |
| mesh reachable | the control plane, over the link |
The first node is not a different kind of node. It is a node whose mesh is not up yet. It applies the bundle it carries, the control plane comes up on top of it, and from that moment it takes declarations like everything else. Its specialness is temporary and self-erasing, which is what the hand-run bootstrap scripts never were.
A joining node does the minimum to be reachable and nothing else — an identity, an address, and one peer to reach. It does not compute the overlay: the whole peer set is derived centrally and pushed down.
That is also why the migration is smaller than it looked. The hard part of the overlay — every node's key, address, site and reachability — is only needed to compute the whole mesh, and a joining node needs one peer.
The link is the security boundary
Everything reaching a node arrives one way, and four properties make that a boundary rather than a pipe.
It is outbound and node-initiated. The node dials the control plane; nothing dials a node. Not only defensive — most nodes sit behind a household connection with no forwarded port, so an inbound control channel would work for one node and not the rest, and the difference would be invisible until it mattered. A node has no listening control surface at all.
A node holds its own identity and nothing else. No shared secret, no credential to anything it does not own. Compromise of a node is compromise of that node — which the current arrangement does not have, because every node permanently holds the same database and object-store credentials, and there is no mechanism that rotates one and informs everything holding it.
Authority is mutual. The node proves it may join, and the control plane proves it is the mesh. One-way is not enough: the host applies whatever the link delivers, so a node that cannot tell the mesh from something impersonating it will apply that something's declarations.
What may be pushed is bounded by form, not by trust. Declarations of known shape, never a command to run. Stated honestly, this bounds form and not impact: a compromised control plane can declare harmful state and the host will apply it faithfully, because that is what it is for. What the property buys is that the blast radius is describable — exactly what the declaration language can express, which can be reviewed. An arbitrary command channel has no such bound.
The enrolment token carries the mesh
Mutual authority needs the node to verify something before it trusts anything, and that is a circle: verifying the mesh needs the mesh's certificate authority, and obtaining one means trusting whoever hands it over. There is a second circle beside it — a node must reach the mesh before the mesh has configured it, so it can resolve no mesh name.
Both are the same shape: a node needs a fact about the mesh before it has any trustworthy way to obtain one. So that fact arrives by a path other than the mesh.
The token carries four things, and it is the only thing a joining node needs:
| where | the broker's address, not a name — there is no resolution yet, and this is why none is needed |
| what it is connecting to | the fingerprint of the broker's certificate |
| who it will believe | the control plane's signing identity |
| the right to join | a one-time secret, useless once used and useless after it expires |
Carried out of band, by the person adopting the machine. That is what breaks both circles: its authenticity comes from the channel it travelled, not from anything the node can check afterwards. Trust on first use, with the first use moved out of band — the difference between a pin and a guess.
The endpoint and the authority are two identities. A node connects to the broker and takes instruction from the control plane behind it. Pinning only the broker would make the control plane's authority transitive, and a compromised broker could then forge declarations — which, since the host applies whatever the link delivers, is the whole machine. So the transport is verified once at connect, and each declaration is verified by its signature, every time.
What this settles: the mesh's certificate authority is not a bootstrap concern — it certifies internal names once a node is a member. Nothing needs name resolution before the link. And nothing is placed on disk beforehand except the token, which is the first moment a node holds only its own identity becomes true rather than aspirational.
Consequences
- Declarations must be signed, and the host must tell this is not from the mesh I joined apart from this is malformed. Rotating the signing identity is a fleet-wide operation with an overlapping rollover, and that is the cost of not trusting the broker.
- The token becomes security-critical, because it carries the pin. Tampering substitutes the mesh — which is strictly better than the alternative, where there is nothing to tamper with and the node trusts the first answer unconditionally.
- A rejoining node is ordinary. There is no long-lived secret to recover, so a node that lost its identity gets a new token.