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.
Intel shows some packages twice (MSR and MMIO), an AMD card's sensors wake it, and a
counter reset after resume read as thousands of watts. The loop's cadence and the bar
script's staleness are now tested, and the sampler running on every machine is said.
The bar left the battery out because it belongs to whoever knows the hardware, and had
no way to take it back in. i3status-rust now renders bar-neutral blocks through its
template; the power module contributes the battery where the machine reports one and
the power draw where something measures it, sampling the root-only energy counter as
root and publishing only a rate. The memory block shows what programs hold, the figure
memory-pressure judges by, instead of counting the cache as used.
mesh/merge-gate pass: builds new: modules/sensors, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
The third review found the asleep match took only one-word modes, so a SAS drive in STANDBY BY TIMER or
LOW POWER was read as a failed answer and lost its reading.
mesh/merge-gate pass: builds new: modules/sensors, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
The second review of #129 found a read stuck in the kernel kept the file fresh and the module healthy,
smartd as a second reader could wake or keep awake the drives the watch spares, and a board chip's
maximum could stop a fan. Read each drive in its own goroutine from a root reader of the module's own,
mark each read in flight, and say a read past its bound or a drive not looked at for twice its cadence;
drop smartd; tell smartctl each drive's kind; take a SAS drive's standby; say a drive asleep since when.
mesh/merge-gate pass: builds dunst, messenger → g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
The build live since 14:38 keeps tokens as token -> index; reading them as grants
failed and skipped the record. A quiet warning known from history was never
reminded, and an answer could silence another condition than its own.
mesh/merge-gate pass: builds dunst, messenger → g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
Review found that any process of the operator's account can choose a dunst action,
so a click could release or stop a delivery in the operator's name; that tokens
lived for ever; that a warning's answers died in ten seconds; and that a restarted
notifier left dead buttons (hq ADR 0258).
mesh/merge-gate pass: builds new: modules/sensors, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
The review of #129 found false alarms and a silent failure: the NVMe temperature bit, old-age
attributes, a fan's minimum or latched alarm, an unrelated hot sensor and a board chip's limits could
raise a condition, while a hung smartctl stopped the fans' looks and an old readings file passed as
healthy. Read spinning drives hourly (smartd too) so a read never keeps one from spinning down, and skip
a drive that cannot say whether it sleeps.
The store's tools counted each platform of an upstream image apart from its index, so a
kept copy read as unrecorded and a let-go index's bytes were never counted as freed. The
copies no record names are now listed for the controller's mirrors verb, and a dry run
says what stays yet names a platform collection would take (hq ADR 0257, issue 321).
mesh/merge-gate pass: builds dunst, messenger → g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
The operator could not tell from a notification whether to act, nor act without
opening a session. Each message now opens with a verdict, a warning that needs
nothing is not sent, and a notification offers answers the messenger performs
through their seat verbs; dunst's send gains actions and says the chosen one
(hq ADR 0253).
A lockfile that could not be read is one of its repository's files that
could not be read (hq ADR 0251 §4): a version only it pins would be deleted
while in use. A real run now refuses on files_not_read as it does on
repositories_unread; a dry run still reports.
mesh/merge-gate pass: builds new: modules/sensors, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compose)
Temperatures against the hardware's own thresholds, fans, each drive's health and the kernel's error
counts, read-only. A root watch reads SMART so the tools need no root and never wake a sleeping drive;
smartd and the watch carry the health that raises a condition when the hardware says it is failing.
Retention read no package-lock.json on the forge: in lockfile v2 and v3 a
packages entry's dependencies is a map of name to range, which the reader
decoded as nested entries, so all 32 files failed whole and the versions
they pin were kept by nothing. Entries are now read one by one, tolerating
unknown fields and skipping workspace links; an entry of an unknown shape
is said, not the whole file.
A dry run measured only the versions it would delete, so every kept
version answered 0 bytes. Every version is now measured, the registry's
total is answered, and a size that cannot be read is said (hq ADR 0251 §4).
The desktop popups were walls of plan ids, commits, keys and verb syntax in UTC.
The messenger now shows the condition's headline, explanation and resolved line,
since when in the operator's time zone, and a clearance in one line (hq ADR 0253).
mesh/merge-gate pass: builds distribution, new: modules/artifact-store-tools → novox; no bus step; every machine composes with the change as it did without…
A module that provides the artifact store cannot build an artifact: building publishes to the store,
so the store would be needed to create itself, and the module check refuses it. The tools become
artifact-store-tools, assigned beside the store, and read manifests from the store's files through its
container as they already read the listing, so they need no address for the store's door. Named for
the artifact store, because "store" alone is the database server (hq glossary).
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@5d7d9020b8c7 (merged as bf542128 into main, walk plan-17914696454…
The daemon refuses to start outside the group, and the fix was a sudo step by hand that nothing
recorded. The module now declares it; the operator logs in again once.
Every publish added a version and nothing removed one. A Go bundle beside the
TypeScript one keeps what a lockfile or a range on the forge names, what a
dist-tag names and the newest five; a dry run unless asked with a why, and
nothing deleted while any repository is unread.
mesh/merge-gate fail: builds distribution → novox; no bus step; a manifest the change touches fails the module check: modules/distribution/module.json: thi…
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.
Images pulled by digest are not dangling, so the weekly prune never takes an old version
and every machine keeps every image it ever ran. docker_prune_images takes them, keeps what
the declaration names (asked of the controller; no answer, nothing removed) and the one before,
and is a dry run unless asked with a why.
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)
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.
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.
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/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…
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.
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/delivery stopped: covered: its merge 3da80a4b5051 adds a new module sent nowhere (plan moves no module) and is contained in a1406e7d796c which is de…
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…
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.
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)
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.
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…
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.
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)
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.
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)
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.
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