Commit Graph
946 Commits
Author SHA1 Message Date
jochen 434b52614d distribution: say what the store holds and what the records name, so collection is no longer blind (hq ADR 0251)
The store had no working tools: its TypeScript client was never built, and nothing could count what
the store holds that no record names. A Go bundle lists the store's files through its own container,
reads each manifest through its door, and sets that beside the controller's records. Collection is
asked of the controller, which decides and records; the store's tools never delete. The image.pushed
event was declared and never emitted, and nothing consumes it, so it goes.
2026-10-08 11:59:39 +02:00
mesh-admin f7b1853b8b Merge pull request 'mesh-delivery: retire history instead of holding it; end owed work the forge cannot do (hq issue 313)' (#121) from fix/313-retire-adopted-history into main 2026-10-08 09:36:52 +00:00
jochen 0ce567a736 Retire history instead of holding it, and end owed work the forge cannot do (hq issue 313)
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 stopped: its group fix/313-retire-adopted-history stopped: novox/mesh-controller@d3d7fc6873a4 superseded
mesh/delivery-group group fix/313-retire-adopted-history stopped: a member was stopped
2026-10-08 11:20:46 +02:00
mesh-admin 3d15c71fab Merge pull request 'mesh-delivery: say which order rule won, and how to end a contradiction (hq issue 309)' (#119) from fix/309-a-group-says-which-order-rule-won into main 2026-10-08 09:11:25 +00:00
mesh-admin 8134627e18 Merge pull request 'Add disk-load: a machine's iowait, disk load and who does the I/O (hq issue 312)' (#120) from feat/disk-load into main 2026-10-08 08:55:38 +00:00
jochen 6fdf5293eb Add disk-load: no tool said a machine's iowait, disk load or who does the I/O (hq issue 312)
mesh/merge-gate pass: builds new: modules/disk-load, sent nowhere; 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-08 10:47:41 +02:00
jochen 6ae112d299 Say which order rule won, and how to end a contradiction (hq issue 309)
mesh/delivery delivered
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
A group whose order rules disagreed was refused as "its order contradicts
itself" with only the member ids: nobody could see which rules clashed or
what to write to resolve it. The controller now resolves rules by
precedence (hq ADR 0249) and answers, per pair, the rules it won over, and
per contradiction no precedence resolves, both rules and how to declare
the order. mesh-delivery keeps both, lists them in groups and the plan
note, and refuses a group by those words; a cycle through more members
names the pairs in it. An older controller's answer reads as before.
2026-10-08 10:43:21 +02:00
mesh-admin 95c985f3a8 Merge pull request 'Put the merge check back to pending before a recheck asks it (hq issue 305)' (#118) from fix/recheck-resets-the-merge-check into main 2026-10-08 08:34:21 +00:00
jochen 74f912e1fb Put the merge check back to pending before a recheck asks it (hq issue 305)
mesh/repo-check pass: its merge-check.sh passed
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/delivery delivered
A recheck asks of the head the forge already judged, and the forge keeps
the newest status of each context on it. Nobody reset mesh/merge-gate or
mesh/repo-check, so the old green stood and branch protection would merge
on it while the fresh check ran; rechecked heads did turn red.

mesh-delivery's recheck now asks the forge's holder to set the gate, and
the repository check when the head holds one, to pending ("checking
again: <why>") before it asks the controller; a forge that cannot be told
refuses the recheck whole. The gitea holder takes pending, and only
pending, on the merge check's statuses by hand: no verdict, so issue 293
still holds.
2026-10-08 10:11:26 +02:00
mesh-admin 4c8007c564 Merge pull request 'minio: cite the derived-value record as ADR 0202, not 0201' (#117) from fix/minio-cites-0202 into main 2026-10-07 23:55:48 +00:00
jschoubben 49f5ba377e The derived-value record is ADR 0202 (was 0201)
mesh/merge-gate pass: builds minio, sent nowhere; no bus step; 1 wait(s) for a person; 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 delivered
(cherry picked from commit ed10d96048)
2026-10-08 01:42:16 +02:00
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