mesh/check being carried to 5dc3a8e17f97 on 998d8f737008 | from fabfdf04f78a
The journal of an unpack sat at <target>.unpacked.json, in a directory
the module's account may write: a forged one would make the root engine
remove or adopt any path it named. It now lives under
<statedir>/unpacked/<sha256 of the target>.json, mode 0600, names its
target, and is refused whole when an entry is not filepath.IsLocal or a
parent is not above the target. It goes when the archive is taken off,
whether its state record still said what it unpacked or not.
The launcher's stop grace for a host on trial rises from 20 s to 75 s and
the unit's TimeoutStopSec is 120 s (openrc the same), past the host's own
60 s wait for the apply in flight, so neither cuts a save off again.
Tests folded as rows into existing ones (the repository is over its unit
budget): the journal's rows, a forged entry and parent refused, the
journal gone with a record that lost its Unpacked; the test that passed
on main dropped; the stop test waits on its own line, not a sleep, and no
longer consumes the save it waits for.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
nats on novox, 2026-11-04: the operator answered "Back up again", the
engine restarted, and baseline() took the hold with AnsweredRev = the
want's current revision, so the answer in that very revision was never
acted on and compose refused "held for a failed backup".
Quick fix: answer once more (a new want revision). Thorough fix, chosen:
at baseline, a held module whose want carries again or skip is applied
(again backs it up first, skip goes on without one); a hold with no
answer stays held. The cost said in the code: an answer already acted on
before a stop, whose backup failed again, is tried once more per start.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
On novox the node-engine's state had lost the records of nats's two
archives, which only a temporary save file of 2026-10-24 still held, and
about 260 such files (~80 MB) lay beside it. The cause: an apply runs
detached from the engine's stop (applyContext, WithoutCancel), and
runLink returned, and the process ended, without waiting for it; a save
cut between its write and its rename left its temporary file and the
state before it, and whatever the apply did was never recorded.
Quick fix: remove the leftover files by hand and restore the records.
Thorough fix, chosen: the engine ends between applies whichever way it
ends (a stop, standing aside, a move to another bus): it waits up to 60 s
for the apply in flight, then lets no save start (store.Quiesce). Save is
one writer per process, flushes the directory after its rename, and says
loudly each record the state saved before held that this save drops and
nothing forgot (Forget, Release mark what is dropped on purpose, and no
longer write into an array an earlier copy reads). The engine's start
removes leftover temporary saves under the apply lock and says how many.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/check being carried to 966093d8d067 on fabfdf04f78a | from 4d47ff5ce743, mesh-catalog dd458cb155f5
The vault judged a module handed only when its assignment already carried a handing plan, and the node-engine followed
that word: a module with no plan was composed the old way, refused for a key only the provider's helper answers
(forge-account's ssh_alias), and so never got its plan. resolution.Handing is now the manifest, its build and the
machine alone; the vault's word is read only to say where the two disagree. A refusal of a file or an own secret the
provisioner's client should fill now says "handed module not handed" and why, never only the keys a binding lacks or a
secret to make.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
mesh/check being carried to 8e325830891c on 4d47ff5ce743 | from 6019c6d514a7
The declaration named the account only beside its filled files (node.go), so a node whose every filled-file module
was held this pass named none: on ace from 2026-11-04 01:29 its build modules and ssh-client were held for their
forge binding, and the node-engine refused every write of the files they keep, and of every other module's. The
account is the node's, named whenever the rendering has one. A row holds restic, the provisioned mesh's one
filled-file module, with the client placed: the node's own still names the account; it named none before.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/check being carried to 054754482cf4 on 6019c6d514a7 | from 83e135f10187
The review removed the guard and the suite still passed. The guard is now provisionerHeld, a placed client held as
its stand-in, rather than any placed client, so one placed and not held that composes no account keeps none stale.
Rows in the held client's table: the client taken out of the node's placement while what runs names the account, read
from the running own composition and from the client's running process, names no account; a placed client whose
process names no user names none. With the guard removed the first three fail; with it reduced to "placed", the last.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
Reading ace's node composition gave four resources twice and no way to see that one revision named no provisioner
client's account. The verb now shows, for module node, the revision's provisioner account beside what runs names, its
adoption, how many identities, groups and libraries it names, and each module the composer's last pass held with why.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
Applied, a node's own composition naming no account refuses every filled write and hands no module, which on ace
went unsaid from 01:29 to 01:33 but for the refusals themselves. The pass now says it once, naming the account what
runs names. A placed client keeps its account by the previous commit; this says the case that is left, a client no
longer composed here.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
provisionerAccount reads the user of the client's process from this pass's plan, and a client held as its stub (or
carried as it runs) composes no process: on ace, 2026-11-04 01:29 to 01:33, the node's own composition named no
account, the node-engine refused every filled write, and no module was handed (postgres's consumers, restic, power).
A node now carries the account its client runs as (Node.RunningProvisioner: its own composition's account as it runs,
else the user of the client's running process), and a placed client that composes none this pass keeps it. A row holds
the client in the provisioned mesh, both ways: the account stays and restic keeps its filled files; both were lost
before.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
frombus skipped reading the build of every module in Scope.InOwn, while compose.compositions folds such a module only
at no src2: fingerprint: a want at src2: (nats on novox, its have waiting for a yes) composed it from the indexer's
unresolved manifest and built() refused it, "no build has published" its server artifact. compose.Folds is now the one
rule; frombus takes the build in, or keeps the module at its wanted build, exactly where it says the module is not
folded. A row composes spiegel, in InOwn and wanted at src2:, from its build's upstream image; it read the indexer's
manifest before.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/check checking 30b86ea602a8 on 83e135f10187 | novox/mesh-host#203 in group feat/l3-final
The stub's mark (Manifest.Stubbed) is no field of a manifest's JSON, so an input a node-engine sent the check's
sandbox lost it: node-tools, held by its manifest's verdict, read as a tool runner with no bundle and refused every
module of ace, g14 and shanks for "its build produced 0 bundle(s)". compose.Input now writes its held modules (catalogue
and each node's kept) beside its fields and marks them again on reading; an input from an engine before the mark is
read by its contract, every module Refused names held as its stub. The sandbox composer also says, in the module's
read, why the input's node-engine holds a module the case carries, so the check names the cause, not a rule about the
stub. One subtest round-trips an input holding a refused tool runner, in both shapes; it refused for 0 bundles before.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/check failed (2): unit: mesh-provisioner-client/cmd/mesh-provisioner-client.TestNatsANodeComingBackFil…; and 1 more | 32a99144f65e on 798d73eb11e9
recordOf writes catalogue.ManifestReads in NodeRecord.ManifestReads, once per build, so the assigner moves a want only
to an engine that reads its manifest. A row holds the engine's own manifest to the baseline's words, so its new build is
never held for a word only it reads.
Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
mesh/delivery-group group feat/l3b-bus rejected: composed together: the checker's verdict at the members' heads (a1cb9beeb97a): unit: modules/mesh-provisioner.…
mesh/check failed (4): unit: modules/mesh-provisioner.gofmt: not as gofmt writes them (run gofmt -w): modul…; and 3 more | a24a1d72ad45 on 798d73eb11e9
The second sandbox fault of the same kind on mesh-host #200 (postgres's secret
reader handed, the module not): the engine stripped the whole catalogue from
the input it answers, so the sandbox composed the node's own modules from the
indexer's source manifests while the bus reader composes them taken in from
their builds (artifacts, templates archive texts, what is handed). Both sides
now go through composer.SentInput: the node's own taken-in manifests and kept
builds stay in the input, and the sandbox composes them over the cases'. An
input past what one bus answer carries is refused in words. A conformance row
composes one node through the bus reader and through the sandbox and requires
the same declaration.
Issue 1126.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
mesh/check failed: novox: not composed on novox: postgres: its own secret reader is handed to the provisioner and the m… | 61a3bd996dd4 on 27a956448c0a
A check that composes with a candidate's own composer (any mesh-host change)
gave it the indexer's manifests alone, and the input carries no catalogue, so
mesh-wireguard (shipped with mesh-sdk, no repository) was missing: "nothing
provides mesh-wireguard / mesh-addressing" on novox for mesh-host #200. Each case
now lays the provided module's manifest over its shelf, as the bus reader does.
Issue 1126.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
mesh/check failed: novox: not composed on novox: these assignments cannot be applied: | b8158affa7af on 27a956448c0a
An endpoint's subscription hands its asks over one at a time: two checks asking
one node at once queued, and the second answered at about 100 s, past the
checker's bound and the bus's one-minute reply window. compose-candidate is now
answered in a goroutine of its own, at most four at once, one more refused in
words. The new cases are rows of the existing tests (test budget).
Issue 1126, review round 1.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Off the control-node an ask of compose-candidate ran into its 60 s bound: each of
its two compositions read every manifest in the mesh one key at a time over the
bus, on scratch copies of the shadow that kept nothing, so each ask read them all
twice again (about 35 s per composition on ace, g14 and shanks; 2 s on novox).
The answer at 60 s then came after the bus's one-minute reply window
(allow_responses ttl), so the bus refused it and the checker heard nothing.
Now the manifests are read eight at a time into the shadow before either
composition, a scratch copy keeps what never changes (manifest, archive, done
build) in the shadow too, the candidate is laid over a copy taken after the
composition without it, and the engine answers within 50 s: unready, naming what
it waits on, when not done. Every answer is said in one journal line with its
reads and its longest wait.
Issue 1126.
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL