diff --git a/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/00-report.md b/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/00-report.md index f3ddb4c5..b196a271 100644 --- a/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/00-report.md +++ b/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/00-report.md @@ -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; diff --git a/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/01-diagnosis.md b/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/01-diagnosis.md index 66c3ae05..8fd8ea14 100644 --- a/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/01-diagnosis.md +++ b/04-ISSUES/339-a-verb-can-place-a-directory-at-the-machines-own/01-diagnosis.md @@ -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 `, 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