Building the bus: the decisions the work needed, and what it taught back #150

Merged
jschoubben merged 45 commits from feat/nats-genesis into main 2026-09-27 17:06:40 +00:00
Showing only changes of commit 8c91ba1cfa - Show all commits
+47 -1
View File
@@ -150,9 +150,55 @@ paper is wrong until there is a second mesh to find out.
and names no broker module anywhere in its source. What remains is naming `nats` instead of
the deprecated broker where a genesis module set is declared, which is scenario and installer
configuration — carried with 1.6 rather than before it.
- [ ] 1.7 **the composition, delivered** — the controller gathering its principals, composing the
- [~] 1.7 **the composition, delivered** — the controller gathering its principals, composing the
file, and asserting the streams and consumers on start.
**In**: the user list is derived from the mesh's records and the credentials are kept.
A bus user's bcrypt hash is now recorded, keyed by the username the file needs, and the
plaintext is returned exactly once. That state is new and the reason is worth stating: on the
bus the mesh runs on today an account is a management call — mint, hand over, seal to the
holder, keep nothing — and that works because the broker remembers. Here the users are one
file rewritten whenever any of it changes, so keeping nothing would mean **the first person's
access change silently blanking every module's password**.
**Permissions are not kept, only credentials.** Authority is derived from what each module
declares every time the file is written ([ADR 0043](../../02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md));
a stored permission list would be a second account of a user's authority, able to disagree
with the records it came from while both looked internally consistent.
The derivation refuses two things where they can still be named: two users with one name — the
server reads the file as one of them and which one depends on the order — and a module
assigned but absent from the catalogue, which would compose a user with no authority and fail
on its first publish with an authorisation error that says nothing about a missing manifest.
A user the mesh has minted no password for is *named* rather than dropped or written as a user
anybody is: an ordinary situation with an obvious remedy, and the caller decides whether a
partial file is worth writing. A seat's protocol is gathered across the whole catalogue, not
from one manifest, because a seat is declared by one module and held by another.
**Out, and what each needs.**
*Delivery.* Resolution already prepends `file` resources whose content comes from the
rendering — a certificate does exactly this, and refuses when a module asks for one and none
was issued. The composed configuration is the same shape, and the open question is what the
module *declares* in order to receive it, which is design 29's ground rather than this
document's: a field naming where it wants the file, or nothing at all because the module
holding `mesh-broker` is the one that gets it. The server's own values — ports, TLS paths,
store directory — are constants of the module's own resources today and would have to be read
from one place rather than two.
*Minting, and it is transport-coupled.* A password is minted at enrolment and at assignment,
and an enrolment reply carries exactly one. **A node on the old bus must not be handed a
credential for the new one**, so which bus a node is joining has to be a fact the controller
holds before it can mint for both — the same switch the host's `Transport` is, from the other
end.
*Asserting on start.* The streams, the controller's consumers and every node's are defined
and idempotent; nothing calls them from a start path yet.
**People are not in the list**, deliberately: the account model is built and `operator issue`
is not (4.4), so there is nobody to derive. Left empty rather than guessed at.
> **This corrects a tick, not a decision.** Tasks 1.3 and 1.4 are ticked and they are honest
> about what they built — the composer, the derivation, the permission model, the stream and
> consumer definitions, the asserter, all pure and held by unit tests and a golden