A nats module that provides mesh-bus and can hold mesh-broker, with an image that reloads its config in place — the accounts file changes every time a node or module is minted a user, and a restart of the bus is not an acceptable price for that. It declares its own ports, TLS and JetStream, and includes the mesh's half of the accounts.
lavinmq becomes an ordinary provider of the same provision rather than part of the foundation, which is what makes the two interchangeable at all.
Issue 127 across the catalogue. Every manifest's events are named locally now, and the subject is derived. Before this, an emitter and a consumer of the same event wrote the name differently and the derived subjects did not meet, so a cross-module subscription listened to something nothing ever published — silently, because a subscription to an unused subject is not an error anywhere.
A build's outcome is addressed to the role rather than to whichever module holds it, which is ADR 0129's half of the same change. The old name is still announced alongside it, so the live catalogue keeps hearing builds through the transition.
84 files, mostly one-line manifest changes. Merged with main, taking the trunk's seat names and this branch's event names.
A `nats` module that provides `mesh-bus` and can hold `mesh-broker`, with an image that reloads its config in place — the accounts file changes every time a node or module is minted a user, and a restart of the bus is not an acceptable price for that. It declares its own ports, TLS and JetStream, and `include`s the mesh's half of the accounts.
`lavinmq` becomes an ordinary provider of the same provision rather than part of the foundation, which is what makes the two interchangeable at all.
**Issue 127 across the catalogue.** Every manifest's events are named locally now, and the subject is derived. Before this, an emitter and a consumer of the same event wrote the name differently and the derived subjects did not meet, so a cross-module subscription listened to something nothing ever published — silently, because a subscription to an unused subject is not an error anywhere.
A build's outcome is addressed to the role rather than to whichever module holds it, which is ADR 0129's half of the same change. The old name is still announced alongside it, so the live catalogue keeps hearing builds through the transition.
84 files, mostly one-line manifest changes. Merged with main, taking the trunk's seat names and this branch's event names.
Step 1.1 and 1.2 of novox/hq ADR 0116. The server is a built artifact rather
than the upstream image directly, because it needs an entrypoint of its own:
the host can only recreate a container, and recreating the bus for every
permission change drops every connection and every in-flight ack. nats-server
reloads on SIGHUP by itself, so the config is mounted as a directory (not
digest-tracked, hq issue 103) and the entrypoint watches the one file.
Verified against the real server, not assumed: a user added to the config
connects, a revoked one is refused, both within one poll interval, with the
container's PID and restart count unchanged and "Reloaded: accounts" in its
log.
Two corrections found by checking rather than reading:
- the seat delivers nothing now (hq ADR 0117), and the controller's parser
refused the manifest until it did — "nats claims mesh-broker, whose holder
answers for amqp, and nats does not provide amqp"
- pinned to the multi-arch index digest; the first pin was the amd64
manifest, which builds here and fails on any other architecture
It claims no seat: mesh-broker is the NATS server's (novox/hq ADR 0119).
The amqp interface stays exactly as it is — a backing service a module may
require, like a database.
Ten manifests claim mesh-* names now. What they PROVIDE is unchanged: gitea
still provides git and npm-package-registry, and a consumer requires the
interface, not the seat.
The split the controller now makes, from this side. The module's own
configuration — ports, TLS, JetStream — is a declared file resource, because those
are properties of this container and change when its image does. `bus-users` names
where the mesh writes every account and permission, in the same directory, and the
module's configuration includes it.
**Both files in one directory because they have to be.** An absolute include path
is resolved relative to the including file's directory: nats-server given
`include /etc/nats/accounts.conf` from /etc/nats-server/nats.conf looks for
/etc/nats-server/etc/nats/accounts.conf and refuses to start. Verified against the
server, and recorded in the configuration itself where somebody moving a file will
read it.
**`verify: true` is gone, and it was refusing every connection in the mesh.** It
makes the server demand a client certificate; a host pins this server's exact
certificate and authenticates with the password the mesh minted, and presents none.
Found by building this image and connecting to it as a host would.
The entrypoint now waits for both files and watches the mesh's half: the module's
own does not change without a new declaration, and that recreates the container
anyway. Verified end to end against this image — the mesh's user 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.
Every module named its events the way the old bus spelled a routing key —
`module.<module>.<verb>`. Design 29 says a module names an event locally and the
mesh works out where it lands, so all 37 were stale against a rule already
decided. On the new bus that derives into a namespace belonging to a module
called "module", so no cross-module subscription in the mesh matched anything:
nothing failed, nothing reacted (novox/hq 04-ISSUES/127).
36 manifests converted, and 43 files of module code with them. The code mattered
as much as the manifests: the runtime builds the subject from what `emit()` is
handed, so a converted manifest with unconverted code would have had the
permission and the subject disagree.
Three things the new check found on the way:
- `photos` emitted an event its manifest never declared, which the new bus refuses
outright. Declared.
- `showcase` waited for an event nothing emits, so its demo could never be
triggered — only `showcase` may publish under its own name. It emits both halves
now.
- `distribution` declared an event named after a different module. It emits
`image.pushed` under its own name. An event about a *role* belongs on the seat,
where the name outlives whoever holds it, but the sdk has no way to publish on a
seat yet, so that stays recorded rather than declared.
The audit logger's "everything" pattern is `**` rather than the old bus's `#`.
ADR 0121. The builder declared `built` as its own event, so every consumer depended
on which module happens to be the build machine today. It is the build-machine
role's event now: the builder declares none of its own, and the catalogue listens
for `mesh-build-machine.built` rather than `builder.built`.
Nothing changes about what reaches the catalogue. What changes is that it survives
the build machine being a different module, which is the whole reason the mesh has a
word for a role.
Two lines of work renamed the same seats differently. The trunk named them for their
scope — node-scoped ones `node-*`, leaving `the-artifact-store`, `npm-package-registry`
and `git` as they were — and this branch had renamed ten of them to `mesh-*`. The trunk's
set is what the live controller loads and what the live seats were actually renamed to, so
a manifest claiming this branch's name is one the running mesh refuses. Three of them
needed reverting by hand: git had auto-merged this branch's names where the trunk had not
touched those lines, which is the quiet kind of merge result.
Event names are this branch's, because the trunk has not converted them and they are what
issue 127 was about.
Verdaccio goes with the trunk's removal of it. The template work on dnsmasq's roster fact
is the trunk's, sitting beside this branch's local event names in the same file — the one
hunk where both changes landed together.
75 manifests, all parsing, no claim outside the trunk's set and no event name left in the
old bus's form.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A
natsmodule that providesmesh-busand can holdmesh-broker, with an image that reloads its config in place — the accounts file changes every time a node or module is minted a user, and a restart of the bus is not an acceptable price for that. It declares its own ports, TLS and JetStream, andincludes the mesh's half of the accounts.lavinmqbecomes an ordinary provider of the same provision rather than part of the foundation, which is what makes the two interchangeable at all.Issue 127 across the catalogue. Every manifest's events are named locally now, and the subject is derived. Before this, an emitter and a consumer of the same event wrote the name differently and the derived subjects did not meet, so a cross-module subscription listened to something nothing ever published — silently, because a subscription to an unused subject is not an error anywhere.
A build's outcome is addressed to the role rather than to whichever module holds it, which is ADR 0129's half of the same change. The old name is still announced alongside it, so the live catalogue keeps hearing builds through the transition.
84 files, mostly one-line manifest changes. Merged with main, taking the trunk's seat names and this branch's event names.