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 dd577e9ebe - Show all commits
+30 -11
View File
@@ -150,7 +150,7 @@ 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
- [x] 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.
@@ -202,14 +202,32 @@ paper is wrong until there is a second mesh to find out.
list rewritten, the module noticing and reloading the server itself with no signal from
outside, and the connection the mesh already had still working afterwards.
*Still out — 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.
**Minting is in, on both halves.** A node at enrolment, a module when its credential is
issued. Three things differ from a management call and each is the point of the move: the
credential is minted into the mesh's records and becomes usable at the next composition, so no
server need be reachable for it; the password travels beside the address rather than inside it,
because a credential embedded in a URL leaks into every log line that prints a connection; and
a module's durable consumer is derived from what it declared rather than named, so it cannot ask
for delivery of something it did not say it consumes. A node reconnecting may be refused until
the composition reaches the machine running the bus — which is what the host's reconnect backoff
is for, where waiting for the push would hold an enrolment open for as long as a declaration
takes to apply.
*Still out — 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.
**Which bus is one fact, and being told about both is refused at start.** Not warned about: a
mesh half on each is one where a declaration goes out on one bus and the report comes back on
the other, and every component logs success while it happens — ADR 0074's failure arriving
through configuration instead of through code. A node that came away holding a credential for
each could be half-moved, and nothing would say which half.
**The objects are asserted on every start**, not created once at genesis: a stream somebody
deleted, a mesh raised from a restored backup, or a bus whose data directory was replaced all
have records and no objects, and a node whose consumer is missing hears nothing while everything
else about it looks correct. Against a real server: every object accepted, asserting twice
changes nothing (a start that failed the second time is a controller that cannot restart), a
machine joining an already-raised bus accepted, each node's consumer bound to its own
declaration subject and no other's, and CONTROL not dead-lettering — because the store window's
bound is the controller's, and a server that gave up first would discard the push the stream
exists to protect.
**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.
@@ -495,9 +513,10 @@ it, and the beds that need a mesh living on NATS can finally run.
held by a `nak`-with-delay cycle still reaches the enrolling node, proving the reply travels
in the payload and not the transport field the consumer's ack has claimed. The server-enforced
permissions were proved at step 1 and are not re-proved here
— **waiting on 1.7, the composition.** Both links speak NATS and every claim above has a unit
test or a check against a running server behind it; what none of them needs is a bus that
composed its own accounts, because each supplies its own. A mesh raising itself does need one
— **nothing is outstanding but the bed itself.** Both links speak NATS, the composition
happens, and every claim above has a unit test or a check against a running server behind it.
What none of them can stand in for is a mesh raising itself, which is what this bed is — so this
is where the code stops and the lab starts
- [ ] 4.2 a build source's change reaches the builder over the bus, and the build that follows is
the one the change asked for — **blocked by
[issue 127](../../04-ISSUES/127-a-module-event-derives-a-subject-nothing-publishes/00-report.md)**