Commit Graph
935 Commits
Author SHA1 Message Date
mesh-admin 2fa39eac1c Merge pull request 'records: list the decision records by topic when asked (hq ADR 0248)' (#115) from feat/records-decisions into main 2026-10-07 21:44:12 +00:00
mesh-admin 7cd989b6f1 Merge pull request 'systemd: the journal verb reads a window, and failed is the seat's verb' (#105) from feat/journal-window-on-the-seat into main 2026-10-07 21:40:04 +00:00
jochen cb733d1b7c records: list the decision records by topic when asked, since hq stores no list (hq ADR 0248)
mesh/merge-gate pass: builds records → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
2026-10-07 23:38:13 +02:00
mesh-admin f27d3f21bb Merge pull request 'Serve the uplink seat's verbs from both of its holders (hq ADR 0241 rule 8)' (#107) from feat/node-uplink-verbs into main 2026-10-07 21:34:33 +00:00
mesh-admin 30d0b29d6d Merge pull request 'forticlient: hand the client's resolver file to the machine's own resolver (hq ADR 0247)' (#114) from feat/forticlient-split-dns into main 2026-10-07 20:44:13 +00:00
mesh-admin 3da80a4b50 Merge pull request 'systemd-resolved: a machine's own resolver, routing a VPN's domains by link (hq ADR 0247)' (#113) from feat/systemd-resolved-split-dns into main 2026-10-07 20:14:22 +00:00
jochen 51460de958 forticlient: hand the client's resolver file to the machine's own resolver (hq ADR 0247)
mesh/merge-gate pass: builds forticlient, systemd-resolved → g14, shanks; no bus step; 2 wait(s) for a person; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
FortiClient writes /etc/resolv.conf itself on connect and never tells
resolved a link's DNS. The module now requires split-dns and runs an
adapter as root that reads the client's servers and domains from its write,
routes them over the client's tunnel through the resolver's socket on the
machine, takes the write so the resolver's file is back at once, and takes
the route away when the tunnel goes. Nothing of it crosses the bus.
2026-10-07 21:35:50 +02:00
jochen 60641176ab systemd-resolved: say when a route's domains do cross the bus
mesh/merge-gate pass: builds new: modules/systemd-resolved, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 com…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery stopped: covered: its merge 3da80a4b5051 adds a new module sent nowhere (plan moves no module) and is contained in a1406e7d796c which is de…
2026-10-07 21:35:49 +02:00
jochen d53571213c systemd-resolved: a machine's own resolver, routing a VPN's domains by link (hq ADR 0247)
mesh/merge-gate fail: builds new: modules/systemd-resolved, sent nowhere; no bus step; a manifest the change touches fails the module check: modules/system…
mesh/repo-check fail: its merge-check.sh failed: long-running resources without health: 70
mesh/delivery superseded: a newer head of the same pull request
Holds node-resolver and provides split-dns at the machine's reach, for a
machine whose VPN client pushes resolvers of its own. It writes the
resolver file naming the machine's private address, gives resolved the
mesh's resolvers as the default route, and serves routes, route and unroute
on the mesh and, over a root-only socket, on the machine. Its guard keeps an
outside write of the file for the module that handles it and puts the
module's file back: at once when taken, after 90 s otherwise, so a write
nothing declared to handle is still raised by the node-engine.
2026-10-07 21:28:11 +02:00
mesh-admin 942f82f239 Merge pull request 'checks/words: a retired word's plural is the word (hq ADR 0244)' (#112) from fix/words-match-plurals into main 2026-10-07 19:21:35 +00:00
jochen 362974244e Hold a retired word's plural to the word in what the tools say (hq ADR 0244)
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group fix/words-match-plurals delivered: every member is delivered
The pattern ended at the word, so control planes and flavors passed where
control plane and flavor fail. It now takes s or es on the last part; a
test holds it, and merge-check runs that test before the check.
2026-10-07 21:08:33 +02:00
mesh-admin 68aeee2c4e Merge pull request 'claude-code: an "instead of" table and a guard on the agent's shell (hq ADR 0245)' (#110) from feat/claude-code-tools-first into main 2026-10-07 19:04:17 +00:00
mesh-admin 9d4bbbd2bd Merge pull request 'Answer what the mesh's checks said of a pull request: mesh-delivery's checks verb (hq ADR 0239)' (#109) from feat/delivery-checks-verb into main 2026-10-07 19:04:10 +00:00
jochen f72a435487 claude-code: read where it runs from the controller's JSON answer
mesh/merge-gate pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
nodesRunningMe looked for printed lines in what is a JSON list, so every register tool's "also on"
hint and every nodes: "all" named no machine.
2026-10-07 20:28:06 +02:00
jochen 24a3fac2ba claude-code: point the agent at the mesh's tools and guard its shell against ssh to the mesh (hq ADR 0245)
The agent kept running ssh <machine> journalctl while the journal verb existed. The managed
instructions now carry an "instead of" table generated from what each verb says it replaces, and
the plugin carries a PreToolUse guard that refuses ssh to a mesh machine and local work-arounds for a
mesh name, naming the tool or saying one must be created. The operator's override is read from the
session's start environment and recorded.
2026-10-07 20:27:31 +02:00
mesh-admin ba6058abb9 Merge pull request 'Hold what the tools say to the glossary's retired words (hq ADR 0244)' (#111) from feat/tool-descriptions-use-the-glossarys-words into main 2026-10-07 18:24:02 +00:00
mesh-admin 1ab84e69f2 Merge pull request 'mailu records rather than rolls out: people's mail, whose containers are recreated together (hq issue 295, ADR 0242)' (#106) from fix/mail-waits-for-a-person into main 2026-10-07 18:13:21 +00:00
jochen 73bb597c16 Hold what the tools say to the glossary's retired words (hq ADR 0244)
mesh/merge-gate pass: builds docker, gitea, lab, nftables, slack, systemd → ace, g14, novox, shanks; no bus step; 4 wait(s) for a person; every machine com…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
An agent meets the mesh's words most often in tool descriptions, and
nothing compared them with the glossary: several still said "the host"
for the node-engine and the forge's pull request comment was headed
"Change plan", a word retired twice over. retired-words is the copy of
the words the glossary retires for the tools, and checks/words fails the
repository check when any string a module's code can show, or any
manifest description, uses one. Those found are reworded here.
2026-10-07 20:02:09 +02:00
mesh-admin 3ad2235663 Merge pull request 'claude-code: read and remove the person's own home items through the mesh' (#108) from feat/claude-code-home-show-remove into main 2026-10-07 17:48:05 +00:00
jochen a0deb90741 claude-code: undo a home removal through the mesh
mesh/merge-gate pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
A removal kept its copy but nothing could put it back without a shell on
the machine. claude_code_home_restore puts a kept copy back when nothing is
at its path and the copy matches the digests recorded at removal;
claude_code_home_removed lists what is kept.
2026-10-07 19:44:07 +02:00
jochen 03728728c3 claude-code: read and remove the person's own home items through the mesh
mesh/merge-gate pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
Hand-written items in an account's ~/.claude could only be removed over a
shell on the machine. claude_code_home_show reads one in full (memory,
~/.claude/CLAUDE.md, included); claude_code_home_remove removes one on the
person's word, with a required reason, refusing what the mesh placed and
symbolic links, keeping a dated copy in the module's state and logging it.
2026-10-07 19:39:27 +02:00
jochen 13894744a7 Answer what the mesh's checks said of a pull request, as mesh-delivery's checks verb (hq ADR 0239)
mesh/merge-gate pass: builds gitea, mesh-delivery → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
mesh/delivery-group group feat/delivery-checks-verb delivered: every member is delivered
Reading a pull request's mesh/merge-gate and mesh/repo-check meant scraping the controller's journal:
the forge clips each status to 140 characters and nothing returned the verdict whole. mesh-delivery
already keeps the verdict; it now keeps the machine that ran it, the layers' modules and the report,
and its checks verb joins that to the forge's statuses, read through a new gitea_commit_statuses tool
that also says whether the base's protection lets the commit merge.

after: novox/mesh-controller
2026-10-07 19:36:41 +02:00
jochen 8150f38bfd Name the hq issue by its number: 294 was taken on an open branch, this is 295
mesh/merge-gate pass: builds mailu → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
2026-10-07 19:28:54 +02:00
jochen 05278d1aa0 Hold mail's builds for a person: a change to how its containers are declared takes everyone's mail down at once (hq issue 294, ADR 0242)
mesh/merge-gate pass: builds mailu → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
On 2026-10-07 adopting its images' health checks recreated nine of mail's
containers in one send and the operator's phone could not reach the mail.
A module people use directly is moved at a moment a person chooses.
2026-10-07 19:25:16 +02:00
jochen c619a672a3 Serve the uplink seat's verbs from both of its holders (hq ADR 0241)
mesh/merge-gate pass: builds networkmanager, systemd-networkd, sent nowhere; no bus step; 4 wait(s) for a person; every machine composes with the change as…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/node-uplink-verbs delivered: every member is delivered
What a machine resolves through had no tool: the resolver file and who
wrote it, and every link with its default route and the resolvers its
manager knows. Each holder serves the same two node-uplink verbs; the
reading is one text carried by both, held to it by a test, and only
asking the manager for a link's names is each holder's own.
2026-10-07 19:19:52 +02:00
jochen 66106d93ac systemd: the journal verb reads a window, and failed is the seat's verb
mesh/merge-gate pass: builds systemd → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@cb733d1b7cea (merged as 2fa39eac into main, walk plan-17914094762…
mesh/delivery-group group feat/journal-window-on-the-seat delivered: every member is delivered
An incident is read for the minutes it happened in (the operator's direction
2026-10-07): journal takes since, until, priority and a fixed-string match.
Every value is one word of journalctl's argv, held to the forms journalctl
reads, so nothing reaches a shell or is read as an option under sudo. What
the unit printed of a secret is redacted, as docker_logs does, before the
match is applied, so a match cannot find one.

systemd_failed becomes the seat's failed, with an optional scope. Needs the
controller's seat with these verbs (mesh-controller, same branch): an older
controller refuses a claim serving a verb its seat does not promise.
2026-10-07 19:15:20 +02:00
mesh-admin c74f407abd Merge pull request 'Say how the first twenty-three long-running resources are ready (hq ADR 0240, to-be 48 Phase E)' (#104) from feat/health-the-first-declarations into main 2026-10-07 16:54:25 +00:00
jochen f87f4cdfe5 Say how the first twenty-three long-running resources are ready (hq ADR 0240, to-be 48 Phase E)
mesh/merge-gate pass: builds baserow, grafana, mailu, matrix, mongodb, mosquitto, nodered, postgres, redis, step-ca, supabase, website → ace, novox; no bus…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/health-the-first-declarations delivered: every member is delivered
Seven modules' images ship a check the mesh never read. Adopted by name where
it says healthy on the live mesh today: nine of mail's containers (not its
antivirus, whose six-minute start is past the five-minute bound, nor its cache,
whose image ships none), the certificate authority, the spreadsheet app, four
of the database suite's (the studio among them, with the address it binds
fixed), the flow editor and the chat client. And the endpoints four services
already declare, looked at from the machine: tcp on the database, the cache,
the document store and the broker; http on the website and the dashboards.
The count of undeclared falls from 93 to 70.
2026-10-07 18:47:58 +02:00
mesh-admin 79b384ec17 Merge pull request 'Keep the count of long-running resources without health, and let it only go down (hq ADR 0240 rule 8, to-be 48 Phase E)' (#103) from feat/health-the-count into main 2026-10-07 16:32:36 +00:00
jochen c0f9039695 Keep the count of long-running resources without health, and let it only go down (hq ADR 0240 rule 8)
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
A field that is optional for ever is one half the catalogue never gets. The
catalogue's merge check now holds the controller's count of long-running
resources that do not say how they are ready to the number kept in
health-undeclared: a change that raises it fails, one that lowers it must
write the new number. Until the controller the mesh runs counts (Phase B), the
check says it did not count.
2026-10-07 16:17:53 +02:00
mesh-admin f4c6efaadb Merge pull request 'gitea: never set warning on the merge check's statuses; a required one blocks (hq issue 293)' (#102) from fix/no-warning-on-a-required-check into main 2026-10-07 12:05:41 +00:00
jochen 33857626be Never set warning on the merge check's statuses: the forge blocks a required one
mesh/merge-gate pass: builds gitea → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
Branch protection requires mesh/merge-gate (and mesh/repo-check on the core
repositories) with no admin override, and the forge combines warning as a
failure. A note is now a success that says it; a repository without a
merge-check.sh is a success where repo-check is not required and a failure
for a person where it is; the status tool refuses the merge check's contexts.
2026-10-07 13:55:34 +02:00
mesh-admin e61fc6aede Merge pull request 'Ask the check of a delivery that waits for one nobody asked (hq issue 290)' (#101) from fix/a-delivery-waiting-gets-its-check into main 2026-10-07 11:20:18 +00:00
jochen d1de0edd4a Ask the check of a delivery that waits for one nobody asked (hq issue 290)
mesh/merge-gate pass: builds mesh-delivery → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
A pull request's head announced again from the bus's history at
mesh-delivery's first start was proposed with no verdict and nothing
ever asked its check: the controller had taken that announcement long
before, and stalled raised it after an hour for the operator.

A proposed delivery with no verdict and no check asked is now asked
through delivery-check once it has waited past a grace longer than a
check takes; an announcement carrying its head's decided gate status
takes it. The proposed bound runs from the ask, and H2's close may
re-ask once (a table row) before the delivery is the operator's.
2026-10-07 11:44:21 +02:00
mesh-admin 46481baab7 Merge pull request 'Keep secrets off command lines the runtime records (hq issue 282)' (#100) from fix/no-secret-on-a-command-line into main 2026-10-06 23:40:53 +00:00
jochen 13b7562c47 Keep secrets off command lines the runtime records (hq issue 282)
mesh/merge-gate pass: builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person; every machine composes with…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mosquitto passed the broker's admin password to mosquitto_ctrl as -P on
every docker exec, and the container runtime keeps every exec's command
line in its event stream, where docker_events returned it. The admin
credentials now reach mosquitto_ctrl as a 0600 options file fed on
stdin, client passwords at its own prompt, and an argv carrying a secret
is refused before it runs. The admin secret says it is taken at start:
the bootstrap re-runs when the mesh replaces it and re-keys the broker
online from the value it last applied, so it can be rotated.

docker_events redacts what an exec's command line carried, and
docker_secrets_in_events names such secrets by name. keycloak's repair
hands kcadm its passwords through KC_CLI_PASSWORD; minio gives mc its
root alias through MC_HOST_mesh.
2026-10-07 01:37:21 +02:00
mesh-admin 950e52ff64 Merge pull request 'mesh-delivery: the owner of deliveries and delivery groups; the forge's note, view and status tools (hq ADR 0239)' (#99) from feat/mesh-delivery into main 2026-10-06 23:00:36 +00:00
jochen b6f0bc309b Add mesh-delivery, the owner of deliveries and delivery groups (hq ADR 0239)
mesh/merge-gate fail: a manifest the change touches fails the module check: modules/mesh-delivery/module.json: this manifest cannot be used:
mesh/delivery delivered
mesh/delivery-group group feat/mesh-delivery delivered: every member is delivered
One module answers 'did my change go out' for a commit and orders a
cross-repository change: one compiled state table, its state on the bus,
every transition said, noted on the commit and shown on the pull request.
The forge's holder gains the note, view and status tools it asks with, and
says closed pull requests and a merge's head and statuses.
2026-10-06 23:59:54 +02:00
mesh-admin 88135ad0e7 Merge pull request 'gitea: graph-driven announce, both check statuses, the change plan, branch-protection tools (hq ADR 0238)' (#98) from feat/the-graph-decides-what-is-checked into main 2026-10-06 21:00:27 +00:00
jochen 81641a4b22 Test the modules the planner says the change reaches (hq ADR 0238)
mesh/merge-gate pass: the merge check passed
mesh/delivery delivered
mesh/delivery-group group feat/the-graph-decides-what-is-checked delivered: every member is delivered
2026-10-06 22:54:52 +02:00
jochen cc1305a354 gitea: post a pull request's change plan with its verdict (hq ADR 0238)
mesh/merge-gate pass: the merge check passed
mesh/delivery superseded: a newer head of the same pull request
The gate's status says what the change does and how it was judged; a change that builds
something gets its plan as a comment — the tiers, what each machine receives, and what
is not an ordinary send.
2026-10-06 22:50:32 +02:00
jochen dba71a97a8 gitea: tell the controller which files a pull request deletes; say the dependents a merge would build (hq ADR 0238)
The controller asks its planner what a pull request reaches, as if merged: a module whose
manifest the change deletes is one the merge removes, and the plan's dependents are said
on the gate's status beside the modules it moves.
2026-10-06 22:34:53 +02:00
jochen bd7b757dd9 gitea: give the controller what it maps a pull request onto the graph with; set both check statuses; protect a branch by tool (hq ADR 0237)
The controller now decides what a pull request's check runs from the mesh's module
graph, so the announcement carries the changed directories that hold a module at the
head and whether the head has a merge-check.sh. A verdict sets mesh/merge-gate (the
gate, with the modules it judged) and mesh/repo-check (the repository's own tests).
gitea_branch_protection_get/set let the operator's agent make those statuses required.

The catalogue's merge-check.sh leaves the gate to the build seat and keeps its own layer:
every manifest through module check, and the touched Go modules' tests.
2026-10-06 21:56:04 +02:00
mesh-admin b792bf4ba2 Merge pull request 'Phase 5: check every pull request before it merges, and show the verdict on it (hq ADR 0237)' (#97) from feat/merge-gate into main
mesh/delivery delivered
2026-10-06 19:35:57 +00:00
jochen 9951718623 Check every pull request before it merges, and show the verdict on it (hq ADR 0237, to-be 45 §9)
The forge's announcer announces each new head of an open pull request as pull.updated, once,
and marks the head pending; the controller asks the build seat to check it against every
machine of the mesh's facts, and says the verdict as checked, which the forge's holder sets as
the head commit's status mesh/merge-gate - an error never as a success - with the check's own
account as a comment when it is not a pass. merge-check.sh is the catalogue's check: every
manifest through the running controller's module check and merge gate, and the Go tests of each
module the change touches, a module whose dependencies cannot be fetched said as not tested.
2026-10-06 21:16:32 +02:00
mesh-admin 1ba2c0513f Merge pull request 'gitea: say which changed directories hold a module at the merge commit (hq issue 278)' (#96) from fix/a-module-directory-is-never-shared-code into main
mesh/delivery delivered
2026-10-06 18:28:48 +00:00
jochen 1178db279e gitea: say which changed directories hold a module at the merge commit (hq issue 278)
The controller read a changed file as shared code unless its directory was a module it holds or
the merge also changed that directory's manifest. A merge touching modules/showcase/index.ts -
the catalogue's reference module, held by no machine - therefore rebuilt all 103 modules built
from this repository on 2026-10-06, 88 of them byte-identical, with the build agent first only
because everything else is built by it.

Whether a directory is a module is a fact of the repository at the commit, so the announcer now
looks it up: every directory above a changed file (never the root) is asked for its module.json
at the merge commit, and the ones that have one go out as module_dirs, with module_dirs_said.
Not said when the file list is cut, past 300 directories, or when the forge cannot be asked;
the controller then keeps its old rule, which rebuilds too much rather than too little.

modules/showcase stays: TestTheShowcaseModuleIsAValidManifest in mesh-controller parses it and
hq to-be 18 and 20 name it as the reference module.
2026-10-06 19:55:17 +02:00
mesh-admin 9d407248b3 Merge pull request 'Back up the bus by the server's own snapshot of each stream, not its live files (hq ADR 0235)' (#93) from feat/bus-snapshot into main
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
2026-10-06 17:33:13 +00:00
mesh-admin 6e4d12e5a4 Merge pull request 'Say which modules wait for a person's push; announce a merge's deleted files (hq ADR 0236)' (#95) from feat/core-upgrades-that-roll-back into main
mesh/delivery delivered
2026-10-06 17:32:58 +00:00
jochen 1fd2914ae1 Say which modules wait for a person's push, and announce the files a merge deleted (hq ADR 0236)
With a gate on the first machine and a rollback after it, a module's build rolls out by
default. The ones kept back say why: the network path a rollback could not cross, the
providers every consumer on a machine drops with, and the stores holding the photos.
A merge's deleted files are announced, so a module whose manifest went is forgotten
rather than asked to build (the public-acme plan failure).
2026-10-06 18:39:13 +02:00