Issue 339: name the merge order against mesh-host #61, record used-as-found as a behaviour change, and the review's follow-ups
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 superseded: a newer head of the same pull request

This commit is contained in:
jochen
2026-10-09 00:28:55 +02:00
parent 0f02ac47d4
commit ab027691e1
2 changed files with 56 additions and 6 deletions
@@ -75,9 +75,9 @@ pushing.
that holds one. A `settings set` or `settings clear` line through `command` is refused. The layer is
unchanged after every refusal. At the terminal the same placement is taken, but the machine's own trees
(`/`, `/etc`, `/usr`, `/var/lib`, `/home`, the node-engine's state and the rest) are refused from
anywhere. A line break, carriage return or NUL in any setting is refused, keys included. PEM blocks
alone may hold lines, because a provider serves its authority's root as a setting. Each of these tests
fails on the commit before the fix.
anywhere. A line break, carriage return, any other line end or NUL in any setting is refused, keys
included. Only step-ca's `root` may hold lines, as certificates that decode and parse (since the review's
follow-up; at first any PEM block was taken). Each of these tests fails on the commit before the fix.
- **In the node-engine's tests, through `Apply`.** These are refused, each as a failed resource with its
reason:
- a directory, access or mount source that is one of the machine's roots or holds one;
@@ -80,10 +80,60 @@ that the mesh did not record making at that path, is **used as found**: its owne
changed, the outcome says so, and it is never removed. That is ADR 0182 applied beyond the home. The record
of every directory on a running machine already names its path, so nothing applied today changes.
### The two pull requests are independent
### The order the pull requests merge in
The controller's tests do not compose with the node-engine, and the engine's guard needs nothing from the
controller. Either can merge first. Each closes the hole on its own side.
*Corrected 2026-10-09, after review.* The first version of this section said either pull request could merge
first. That is true of the two pull requests for this issue: the controller's tests do not compose with
the node-engine, and the engine's guard needs nothing from the controller. It is not true of the node-engine
pull request for ADR 0266's agent account (`mesh-host` #61), which carries a guard of its own over the same
appliers and the same files. The two conflict, so the order is:
1. The node-engine's fix for this issue (`mesh-host` #63) merges first.
2. `mesh-host` #61 is then rebased onto it. It drops its own copy of the guard and adds its rules for below a
home (an archive, or a file written into, below the home of an account that never becomes root) to the
guard #63 placed, `internal/apply/placement_guard.go`.
The controller's fix (`mesh-controller` #168) merged on 2026-10-09. The controller's pull request for ADR 0266
(`mesh-controller` #164) is rebased onto it in the same way.
### A behaviour change: a directory found on a machine is used as found
Before this fix, the node-engine gave every declared directory the declared owner and mode, whether the mesh
had made it or not. Now a directory that was there before the mesh first applied it, at that path, keeps its
owner and mode, and is never removed. That is the safe default. It is also a new way for a module to fail
quietly: a module whose data directory was found with another owner cannot write it. Its container fails,
and nothing says why, except one line in the apply's outcome.
No directory on a running machine is affected today, because each already has a record of the mesh
applying it at its path. The first to be affected would be:
- a module newly assigned to a machine where its directory already exists;
- a placement moved onto a directory that already exists.
Until the node-engine's follow-up (below) lands, the only trace is that one outcome line.
### The review's follow-ups (2026-10-09)
- **`mesh-controller`:**
- The one setting that may hold lines is narrowed to step-ca's `root`, holding certificates that
`encoding/pem` decodes (label CERTIFICATE, no headers) and `x509.ParseCertificate` parses.
- Vertical tab, form feed, NEL and the Unicode line and paragraph separators are refused alongside line
breaks, carriage returns and NUL.
- The spool, `/opt`, the container runtimes' data and any `.ssh` are added to the paths no placement or
access may name.
- **`mesh-host`, a directory used as found is said:**
- a WARNING line in every apply's log;
- its module's resource of kind `directory`, stated unhealthy on every look, with its owner, its mode and
what was declared. The controller raises that as the module's condition, naming the directory.
- `mesh-host hand-over <dir>`, run by a person at the machine, hands it to the mesh. The next apply gives
it the declared owner and mode.
An unhealthy resource holds a walk's gate for its module, so a delivery of a module with a directory
used as found waits until someone hands it over. That is intended: such a module may not be able to
write its data.
- **`mesh-host`, the guard:** the same paths as the controller are added. The container runtime's data root
is read from its configuration. An account's `.ssh` is refused as an access or a mount, and as a
directory anywhere but below its own account's home.
### Step 3: what the live layers hold