Commit Graph
579 Commits
Author SHA1 Message Date
jochen 9ab58e79fb systemd: the service manager as a module — holds node-service-manager and answers for the units in both scopes
The holder of the seat the controller seeds under novox/hq ADR 0177. Eight
verbs under the seat's name — units, status, start, stop, restart, enable,
disable, journal — each taking an optional scope, "system" by default or
"user" for the operator account's own manager, reached as
`systemctl --user --machine=<account>@` when the runtime is not that account.
One tool of its own, systemd_failed, for every failed unit in both scopes.
A package, a claim and a bundle; no container, no process: served by the node
tools runtime (ADR 0175) once it exists. `module check` passes against a
controller that carries the seat; the tools type-check against the SDK.
2026-10-02 16:47:48 +02:00
jochen a263bc36ba zsh: the shell as a module — package, the mesh's ~/.zshrc block, the login-shell seat and execute
The first module of the operator's environment (novox/hq to-be 37 §1, ADR 0173,
0176). A package, the mesh's default configuration as a block inside the
account's ~/.zshrc so the operator's own lines around it survive every push
(ADR 0174 as the host's `into: block` realises it), a `user` shape that makes
zsh the account's login shell, the `login-shell` seat declared with its one
verb, and a tools bundle: `execute` under the seat's name, `zsh_config` under
the module's. No container, no process: the tools are served by the node tools
runtime (ADR 0175), which does not exist yet — the bundle builds and the
manifest registers ahead of it. `module check` passes; the tools type-check
against the SDK.

Two things the manifest cannot yet say, left for the controller: the `user`
shape applies wherever the module is assigned, not only where it holds the
seat; and the runtime learns the account from MESH_OPERATOR_ACCOUNT, which
nothing sets yet.
2026-10-02 16:40:34 +02:00
mesh-admin d5c5415756 Merge pull request 'lab: the image carries python3, file, iproute2 and sudo' (#222) from jschoubben/lab-image-tools into main 2026-10-02 13:24:00 +00:00
jschoubben 6dfd2401c9 lab: the image carries what the builds and the lab call: python3, file, iproute2, sudo 2026-10-02 15:23:52 +02:00
mesh-admin 31923f70e7 Merge pull request 'lab: a run resolves the @novox scope from the forge's package registry' (#221) from jschoubben/lab-npm-scope into main 2026-10-02 13:13:29 +00:00
jschoubben 8cd4f199f1 lab: a run resolves the @novox scope from the forge's package registry 2026-10-02 15:13:22 +02:00
mesh-admin 1b9b298827 Merge pull request 'lab: compile from the module's root, so the runtime finds its tools' (#220) from jschoubben/lab-tools-path into main 2026-10-02 13:08:14 +00:00
jschoubben bce7b3a551 lab: compile from the module's root, so the runtime finds its tools
Both sources sit in tools/, so tsc took tools/ as the root and wrote
dist/index.js, while the runtime loads dist/tools/index.js: the module
started and served nothing.
2026-10-02 15:08:01 +02:00
mesh-admin 17d3d3e63a Merge pull request 'lab: declares the virtualisation capability (hq ADR 0172)' (#218) from jschoubben/the-lab-is-a-module-2 into main 2026-10-02 12:53:43 +00:00
mesh-admin 5c961c446f Merge pull request 'Cite hq ADR 0170, not 0169: the firewall seat's record was renumbered' (#219) from fix/adr-0170-cited into main 2026-10-02 12:53:10 +00:00
jschoubben b77582f6a6 Cite hq ADR 0170, not 0169: the firewall seat's record was renumbered after a collision on hq main 2026-10-02 14:52:26 +02:00
jschoubben b3865d240f lab: declares the virtualisation capability, which grants its daemon's socket 2026-10-02 14:48:10 +02:00
mesh-admin a81b94d4ab Merge pull request 'lab: the lab as a module, running beds when the mesh asks (hq ADR 0172)' (#217) from jschoubben/the-lab-is-a-module into main 2026-10-02 12:17:14 +00:00
jschoubben 67d1a400e8 lab: the lab as a module, running beds when the mesh asks
Five tools on the machine the lab runs on: check, run beds against
branches on the forge, a run's status, its log, and stop. A run checks
out every repository the lab builds, side by side, and runs the suite;
one at a time, answered at once with an id (novox/hq ADR 0172).
2026-10-02 14:15:42 +02:00
mesh-admin 1c201d59c9 Merge pull request 'nftables holds the node-packet-filter seat: rules, reload and remove, from a runtime with NET_ADMIN (hq ADR 0169)' (#216) from feat/the-firewall-seat-serves-its-verbs into main 2026-10-02 11:33:47 +00:00
jschoubben 663e8143d4 nftables holds the node-packet-filter seat: rules, reload and remove, from a runtime with NET_ADMIN (hq ADR 0169)
The seat's three verbs over the machine's own tools: the filter as enforced
(nftables and the legacy filter), the mesh's own table reloaded from its file,
and one rule set the mesh did not write removed by the name the host reports
it under (ADR 0168) — a predecessor's chain loses its jumps and goes, the
runtime's user chain is emptied back to its return, a table of the machine's
own goes whole; the mesh's tables, the runtime's chains, a built-in chain and
an active found firewall's chains are refused. Tested over the shapes two
machines of the first mesh reported live. The module's own tool stays.
2026-10-02 13:28:33 +02:00
mesh-admin 8ce4935132 Merge pull request 'unifi: list networks and set the DNS their DHCP hands out (hq issue 198)' (#215) from jschoubben/unifi-network-dns into main 2026-10-02 09:53:22 +00:00
jschoubben d1f8ab86d1 unifi: list networks and set the DNS their DHCP hands out
Which DNS server the home network's DHCP hands out could be changed only
in the controller's own interface or by hand against its API (novox/hq
issue 198).
2026-10-02 11:53:16 +02:00
mesh-admin 3020cd2312 Merge pull request 'dnsmasq: listen addresses are a setting, and docker's file takes none (hq issue 198)' (#214) from jschoubben/the-lans-dns-is-the-mesh-2 into main 2026-10-02 09:50:09 +00:00
jschoubben b72213261a dnsmasq: listen addresses are a setting, and docker's file takes none
The addresses dnsmasq listens on beside the machine's are a setting, so a
machine that answers its own LAN can say so (novox/hq issue 198). Docker's
daemon.json no longer merges the module's settings: it needs none, and a
setting reaching it is a key dockerd refuses. The host still merges it
into the existing file.
2026-10-02 11:49:57 +02:00
mesh-admin 7e5c98920e Merge pull request 'Revert dnsmasq's listen addresses as a setting (hq issue 198)' (#213) from jschoubben/revert-dnsmasq-listen into main 2026-10-02 09:48:49 +00:00
jschoubben 67f5236b01 Revert dnsmasq's listen addresses as a setting
A module's settings merge into every mergeable file it owns, so the
setting reached docker's daemon.json beside dnsmasq's config, where
dockerd would refuse it (novox/hq issue 198). Back to the fixed
loopback line until settings can be kept out of files they are not for.
2026-10-02 11:48:37 +02:00
mesh-admin e9876858a8 Merge pull request 'dnsmasq: the addresses it listens on beside the machine's are a setting (hq issue 198)' (#212) from jschoubben/the-lans-dns-is-the-mesh into main 2026-10-02 09:46:32 +00:00
jschoubben 56a22847f5 dnsmasq: the addresses it listens on beside the machine's are a setting
Loopback by default, as before. A machine that answers its own LAN adds
its LAN address, and its DNS endpoints' reach opens the filter (novox/hq
issue 198). The mesh-wide default must be set before this lands.
2026-10-02 11:42:41 +02:00
mesh-admin 1271f797e9 Merge pull request 'route-proxy: a bus account, to read its membership (hq ADR 0167, issue 191)' (#211) from jschoubben/an-internal-only-route into main 2026-10-01 23:49:50 +00:00
jschoubben 4f952ce771 route-proxy: a bus account, to read its membership
The proxy reads its routes and the mesh's addresses from its membership
on the bus rather than from a file alone (novox/hq ADR 0167, issue 191).
2026-10-02 01:46:18 +02:00
mesh-admin fec6d76fb3 Merge pull request 'mssql: the query runs as a read-only login, one line, no variables; sqlcmd is installed (hq #193)' (#210) from fix/193-mssql-reads-as-a-reader into main 2026-10-01 22:30:02 +00:00
mesh-admin da7355dce0 Merge pull request 'postgres: the store's query runs as a read-only login, never as the admin (hq #193)' (#209) from fix/193-the-store-reads-as-a-reader into main 2026-10-01 22:29:57 +00:00
jschoubben 400b2f9696 mssql: the query runs as a read-only login, one line, no variables; sqlcmd is installed (hq #193)
Proven on a throwaway server: as the administrator a caller's $(SQLCMDPASSWORD) returned
the sa password, and a line beginning ':!!' ran a program in the tools container. The
statement now runs as mesh_mssql_reader (CONNECT ANY DATABASE, SELECT ALL USER SECURABLES),
with substitution off (-x), after the module's own text on the first line, and a line break
is refused. go-sqlcmd v1.10.0 is installed at a pinned digest: the image never had sqlcmd,
so every mssql tool failed with spawn sqlcmd ENOENT.
2026-10-02 00:25:22 +02:00
jschoubben 160b5ad65a postgres: the store's query runs as a read-only login, never as the admin (hq #193)
The verb wrapped the caller's text in BEGIN READ ONLY ... ROLLBACK as the superuser, so
'COMMIT; ...' left the transaction and, proven on a throwaway server, COPY TO PROGRAM ran a
shell command on the database host. The statement now runs as mesh_store_reader:
pg_read_all_data, no other grant, read-only transactions by role and session, its password
an own-secret the mesh mints. Without that password the call is refused. -q drops the
command tags that came back as rows keyed by BEGIN.
2026-10-02 00:09:09 +02:00
mesh-admin ef44c502db Merge pull request 'route-proxy README: the node that runs a proxy carries public-acme (hq #258)' (#208) from docs/route-proxy-carries-public-acme into main 2026-10-01 15:32:05 +00:00
jschoubben 0651b63926 route-proxy README: the node that runs a proxy carries public-acme (hq #258) 2026-10-01 17:31:58 +02:00
mesh-admin 0c521ffa20 Merge pull request 'The vault's claim, its own event names, and the uplink holders' capabilities return' (#207) from fix/the-vaults-claim-and-events-return into main 2026-10-01 15:19:55 +00:00
jschoubben 01d68bda88 And the uplink holders' capabilities return
The same split lost them the other way round: the merge base held both changes, each branch had reset
the other's files, and the three-way merge kept neither. Both halves of hq ADR 0161 are on main again
with this.
2026-10-01 17:19:41 +02:00
jschoubben 89e0dde9e0 The vault's claim and its own event names return
The uplink branch was split from the vault's with the vault's files reset to a main that did not yet
hold #205; merging it afterwards took the older vault definition along (no claim, the refused event
names), and the vault could not be built. Restored to #205's state.
2026-10-01 17:19:05 +02:00
mesh-admin 5ebc89d89d Merge pull request 'Each uplink holder declares the manager it speaks for (hq ADR 0161)' (#206) from feat/each-uplink-holder-declares-the-manager-it-speaks-for into main 2026-10-01 15:11:31 +00:00
mesh-admin 32fa76fccb Merge pull request 'The vault claims mesh-vault, and each uplink holder declares the manager it speaks for (hq ADR 0161)' (#205) from feat/the-vault-claims-its-seat-and-the-uplinks-say-their-dialect into main 2026-10-01 14:53:15 +00:00
jschoubben 2e96d2f67d This branch carries the uplink capabilities alone (hq ADR 0161 rule 3); merges once every machine running a holder has reported uplink-<manager> 2026-10-01 16:52:47 +02:00
jschoubben 932efb5186 This branch carries the vault's claim alone; the uplink capabilities wait for every machine to report its profile 2026-10-01 16:52:46 +02:00
jschoubben 6ba61a8b4b The provisioner announces the vault's events by their new names 2026-10-01 16:51:13 +02:00
jschoubben 8368697744 The vault's events are its own: provisioned, rotated, deprovisioned
A module publishes under its own name only; secret.provisioned read as another module's event and the
builder refused the vault's definition today, so the seat claim could not be built. The three events lose
the prefix; nothing outside the vault listens for the old names.
2026-10-01 16:50:56 +02:00
jschoubben 966fed1829 The vault claims mesh-vault, and each uplink holder declares the manager it speaks for (hq ADR 0161)
The vault's claim makes a second provider of secret a second claimant, refused by name. The three
uplink definitions declare uplink-networkmanager, uplink-systemd-networkd and uplink-dhcpcd, which the
host reports for the manager it finds active, so the holder for a manager the machine does not run
is refused the way any missing capability is. Merges after the controller holds the seat and the host
reports the capability.
2026-10-01 15:58:05 +02:00
mesh-admin 67c834ac65 Merge pull request 'postgres serves the store seat's verbs, databases and query, and lists its tools (ADR 0159)' (#203) from feat/postgres-serves-the-stores-verbs into main 2026-10-01 13:53:05 +00:00
jschoubben c00dd04494 postgres implements the store seat's verbs under the seat's name, and its claim says so (hq ADR 0160)
The store's databases and query are registered under mesh-store, so the runtime serves them on the
seat's subjects wherever postgres holds the seat and never lists them as postgres's own; the claim
names them, so the mesh can judge the holder without postgres listing the seat's verbs among its
tools. Scoped to what the store enables: creating a database stays postgres's tool.
2026-10-01 15:19:35 +02:00
jschoubben abf5859415 Merge remote-tracking branch 'origin/main' into feat/postgres-serves-the-stores-verbs 2026-10-01 15:19:08 +02:00
mesh-admin fe8d6a25c0 Merge pull request 'The media chain's stale copies leave the catalogue' (#204) from chore/remove-stale-media-duplicates into main 2026-10-01 12:54:00 +00:00
jschoubben 738415710c The media chain's stale copies leave the catalogue
bazarr, bookshelf, lidarr, nzbget, ombi, plex, qbittorrent, radarr,
sonarr and tautulli live in novox/mesh-media-catalog (#195 moved jackett
and left these behind). A build of this repository at a commit today
registered plex and nzbget from these copies, which carry no provides,
and ace's plan stopped resolving. Nothing here depends on the directories:
home-assistant consumes their provisions by name.
2026-10-01 14:53:35 +02:00
jschoubben 4c7e438ea3 postgres serves the store seat's verbs, databases and query, and lists its tools (hq ADR 0159)
Named as the seat names them so the runtime finds them by name; the same calls as its own tools.
Its definition now lists its tools, which is what holding a seat with verbs demands at registration.
Merge before the controller declares the verbs on the mesh-store seat.
2026-10-01 14:02:41 +02:00
mesh-admin fd0fa75cc2 Merge pull request 'searxng says it reads its secret key at start, so the mesh may rotate it (hq 180)' (#202) from feat/searxng-says-how-its-secret-is-taken into main 2026-10-01 10:10:05 +00:00
jschoubben 50c08818d6 searxng says it reads its secret key at start, so the mesh may rotate it (hq 180)
The key signs sessions and nothing else holds it; it lands in the settings file the server
restarts on, so a rotation is a new value and a restart.
2026-10-01 12:09:47 +02:00