Commit Graph
17 Commits
Author SHA1 Message Date
mesh-tools 652b00b25b Say on every directory how it treats files it does not know, and check it (issue 1024, ADR 0422)
mesh/merge-gate checking again: the gate refused `unknown` because the controller judged with a node-engine validator pinned before mesh-host #117; mesh-co…
mesh/repo-check checking again: the gate refused `unknown` because the controller judged with a node-engine validator pinned before mesh-host #117; mesh-co…
mesh/delivery-group group feat/owned-paths checking: 0 of 2 member(s) ready
mesh/delivery superseded: a newer head of the same pull request
Every directory and archive resource carries `unknown`: move-out for a home folder whose program writes nothing there (the node-engine, delivered in mesh-host #117, moves the rest to ~/.local/state/mesh-moved/<module>/ with a list), module for ~/.ssh and ~/.claude, program elsewhere; `knows` keeps what a program or the operator relies on (powerlevel10k's compiled files, i3's scripts and the asus/g14 drop-ins, dunst's slack rule, betterbird's records, node-env's forge credential, issue 1033). Two shared folders are no longer declared. Each module's README says it. checks/owned holds every manifest to it; checks/sshdir stays while main's merge check runs it (issue 1035). Tests that pin a manifest follow the new key only. Reviewed in three rounds.
2026-10-17 16:23:03 +00:00
mesh-tools 05e6b583e2 Keep what ssh reads itself and linked key folders in ~/.ssh, and fail the sweep loudly (issue 1020, ADR 0417)
mesh/merge-gate head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: builds ssh-client → ace, g14, novox, shanks; no bus step; every machine composes w…
mesh/repo-check head 05e6b583e2e3 merged into trunk ce56b491cffd — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
The sweep from issue 1017 moved known_hosts2, rc and environment, which ssh
and sshd read by default, and moved a link to a folder of keys, breaking every
login through it. It could move a file a tool was still writing. When ~/.local
was on another file system, every sweep failed at its first move and left an
empty folder each round, seen only in the journal. Its list was written after
the moves with errors ignored.

Now those files and linked key folders stay; a link whose target, or the folder
it names, cannot be checked is left and named; a copy of authorized_keys is
moved at any depth; a path changed in the last minute, at any depth, waits for
the next sweep; a retired folder on another file system fails the sweep before
anything is made; the list names each move before it is made; and each sweep's
outcome is kept for ssh_client_check, which shows a failed sweep as a problem.
A key's first line is read only so far.

The catalogue's new checks/sshdir refuses any manifest but ssh-client naming a
path under ~/.ssh (ADR 0415 §6). The README cites §7 for config.d.
2026-10-17 13:36:27 +00:00
mesh-tools 0260ae92f6 Feature 57 (config and provisioning): release the catalogue, the reviewed release branch merged with main, on top of main 2026-10-16 09:42:45 +00:00
jochen 6c10288f0b mesh-mail declares the mail seats and claims mail-store (issue 800 part A)
Declares mail-store and mail-webclient (held once for the mesh) and mail-notifier
(held once per machine, needing node-notifier) per ADR 0378 as amended by ADR 0379.
Claims mail-store and serves its four verbs through the same handlers as the
existing mail_* tools. Moves the event shape (EventKey, Changes) into its own
file, mailevent.go, so mesh-mail-notifier (issue 800 part B) can carry a
byte-identical copy. Adds checks/mailstore, refusing any manifest but mesh-mail's
own that claims mail-store (ADR 0378 §3), wired into merge-check.sh.
2026-10-15 17:16:53 +02:00
jochen eb42806379 Make grafana prefer the vault's password, and let the secrets list only shrink (hq issue 342)
mesh/merge-gate head eb4280637906 merged into trunk 53e51864969f — pass: builds baserow, gitea, grafana, home-assistant, icecast, influxdb, letta, mailu, n…
mesh/repo-check head eb4280637906 merged into trunk 53e51864969f — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery delivered
mesh/delivery-group group fix/342-a-secret-is-never-a-setting delivered: every member is delivered
grafana's client logged in with a token setting ahead of the vault's admin password,
and its runtime config let a layer set token. The token setting is now ignored and
said, token is protected, and the vault's password comes first.

checks/secrets/known could gain a line hiding a newly unprotected key. merge-check.sh
now judges it against the trunk's copy at the merge base, and refuses an added line.
2026-10-13 07:43:08 +02:00
jochen fe2040c65e Keep every password, token and API key the vault's, never a setting (hq issue 342)
mesh/merge-gate head fe2040c65ea2 merged into trunk 53e51864969f — pass: builds baserow, gitea, grafana, home-assistant, icecast, influxdb, letta, mailu, n…
mesh/repo-check head fe2040c65ea2 merged into trunk 53e51864969f — pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the ch…
mesh/delivery-group group fix/342-a-secret-is-never-a-setting ready: every member ready, and composed together they pass
mesh/delivery superseded: a newer head of the same pull request
A setting outranked the vault: baserow, grafana, letta and unifi merged a layer's
password over the ${secret:...} in their runtime config, and the gitea,
home-assistant, icecast, influxdb, mailu and nextcloud clients read the settings
file before the vault's file. A secret in a setting cannot be rotated and is read
back by the settings verb.

The four files now keep their password protected, so the controller refuses a
setting of it. The six clients ignore a secret in the settings file and say so
once, by key and never with the value; icecast reads its admin password from the
vault's file. checks/secrets refuses a mergeable file whose secret a layer could
replace; searxng's nested server.secret_key is listed as known until the
controller protects a nested key.
2026-10-13 07:32:19 +02:00
jochen de8a866189 Fail the check when a module's tests could not run, and take a pinned SDK from its clone beside (issue 385)
mesh/delivery delivered
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh, merge-check-typescript.sh): main's version judged it; the change's judges the pull r…
mesh/delivery-group group fix/385-an-untestable-module-fails-the-check delivered: every member is delivered
A module whose dependencies could not be fetched was said NOT TESTED and the
repository check passed, so a merge on it would have landed untested code.
The build seat clones the SDK beside every check already: a forge requirement
the module cache lacks is now taken from that clone through a go.mod of its
own, and a module that still cannot be built fails the check by name and why.
A TypeScript module whose dependencies the toolchain lacks fails the same way.
2026-10-12 12:03:50 +02:00
jochen b240085e0a Close the review's gaps round the agent account (hq ADR 0266)
mesh/merge-gate pass: builds claude-code, claude-licence-manager, restic, sudo → ace, g14, novox, shanks; no bus step; every machine composes with the chan…
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery delivered
The managed settings apply to every account's claude, so a key-helper script under the
agent's home would run as the operator, and through sudo as root: the command is now
carried whole in the root-owned managed settings and reads the key only as the agent.
The helper reads only a regular file, bounded, without blocking, and a request it does
not answer fails in time instead of holding every later one; a directory entry it
answers that is not a name is refused. The guard's record is matched on its binary in
the query, a half-named agent account is not taken as the operator's, the kept API key
stays until the agent's home holds one, restic refuses to restore beside a directory
others may write, and the agent-home check cleans a path before judging it.
2026-10-09 23:48:15 +02:00
jochen b382045721 Merge remote-tracking branch 'origin/main' into feat/the-agent-account-is-declared
mesh/merge-gate pass: builds claude-code, claude-licence-manager, restic, sudo → ace, g14, novox, shanks; no bus step; every machine composes with the chan…
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
2026-10-09 23:37:04 +02:00
jochen dd14526870 Refuse a daemon's line in what a module shows: the operator types nox (hq ADR 0272, issue 356)
mesh/merge-gate pass: builds mesh-vault → 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, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery covered after its failure: a later walk that contains it was delivered: plan-1792148283013560219 (novox/mesh-catalog at 3db85a0d into main,…
A condition told the operator to type the node-engine's binary at the machine, and nothing held the catalogue's texts to ADR 0272. The words check gains retired-lines — the controller's and the node-engine's commands, copied from hq's words.py --list lines, which compares it — and refuses one in any string a module's tools can show or any manifest description. The vault's and the route adapter's texts now say the nox line.
2026-10-09 18:33:49 +02:00
jochen 6d32975ca6 Refuse the agent-home gap reached through a module's own directory or a literal home
A path written as ${dir:<id>} can resolve under the agent's home, and a
literal /home path may be it; both escaped the check (hq ADR 0266).
2026-10-09 10:14:25 +02:00
jochen 87862f3bf5 Refuse an archive or a file written into under the agent's home
The node-engine writes those as root after checking the path, and the agent
account owns its home and could swap a link in between (hq ADR 0266). No
module does it today; this keeps a future one from opening the gap.
2026-10-09 10:14:25 +02:00
jochen 0d54ecc764 Keep the value a watch hands over at once, watch a dead watch again, and let the path lists grow only in the open (hq ADR 0260)
mesh/merge-gate pass: builds asus-zephyrus-g14, i3status-rust, power → ace, g14, novox, shanks; no bus step; every machine composes with the change as it d…
mesh/repo-check fail: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
The SDK hands the current value over before Watch returns, and the follower had no
entry for it yet, so the first value was dropped. A silent watch is now told from an
expired key and watched again rather than polled, each write takes its own temporary
file, drop-in directories are no module's, and an entry added to the path check's lists
is refused unless its line says why.
2026-10-08 16:12:37 +02:00
jochen 4f6cbd2197 Follow bar values so a dead watch speaks, date them by their reading, and widen the path check (hq ADR 0260)
A watch that died left the block silent, a removed block kept its value, and a value
frozen at its source looked fresh because its file was new. The follower now rereads a
silent value and says so, drops removed blocks, and dates each file by the reading's
own time. The path check takes /etc and /usr/local/lib in, ignores what a container sees
inside itself, and lists the five findings standing today, which may only go.
2026-10-08 16:12:37 +02:00
jochen 76b63744e6 Carry the power draw to the bar over the bus, not through a file (hq ADR 0260)
Modules talk over the bus. The power module's bundle puts each fresh reading of its own
sampler in its state draw, keyed by the machine; the bar's block shows that state, which
the bar's bundle watches under the read the mesh grants it. A new catalogue check refuses
a module naming another module's path under /run or /var/lib.
2026-10-08 16:12:37 +02: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
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