Issue 361: the setuid search shows its progress, and the operator can ask for a fresh one at the terminal
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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jochen
2026-10-10 01:55:52 +02:00
co-authored by Claude
parent c2d98bc61b
commit a8e9a9afd4
2 changed files with 36 additions and 1 deletions
@@ -2,7 +2,7 @@
layer: to-be
status: in-progress
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-sdk, mesh-lab]
updated: 2026-10-09
updated: 2026-10-10
decisions:
- 02-DECISIONS/0271-a-send-held-for-the-buss-planned-step-is-told-to-the-operator-at-once-and-a-change-that-needs-it-says-so-before-it-merges.md
- 02-DECISIONS/0265-a-verb-that-reads-is-answered-on-the-serving-controllers-own-connection-and-every-connection-says-what-it-is.md
@@ -73,6 +73,7 @@ Every kind of state the core keeps, and the one component that writes it. Anyone
|---|---|---|---|
| a machine's declaration | controller (lease holder) | the bus, last per subject | read |
| a hand-over asked of a machine ([issue 356](../../04-ISSUES/356-the-operators-command-ran-a-stale-engine-and-a-hand-over-had-no-channel/00-report.md)) | controller, at its terminal | the machine, beside its state | the engine verifies the mesh's signature and records it, or refuses |
| a fresh setuid search asked of a machine ([issue 361](../../04-ISSUES/361-the-control-nodes-agent-account-is-never-judged/00-report.md)) | controller, at its terminal | the machine, which throws its last search away | the engine verifies the mesh's signature and starts it, or refuses |
| a machine's applied state and its report | the node-engine's apply queue (§6) | the machine; the report on the bus | the reconcile and a delivery *enqueue*, never apply |
| the controller lease | the controller instance holding it | key-value `mesh-controller_lease` | a candidate waits |
| plans and their tiers | controller (lease holder), compare-and-set on the plan's revision | the controller's store | read through `plans` |
@@ -110,3 +110,37 @@ engine agree. What it found, and what was done:
every searched filesystem would report each change of mode or owner as it happens, turning the daily walk into
a true incremental search.
- **Resolution** of this core issue needs a replay in mesh-lab's register, or `replay-none:` with the reason.
## 2026-10-10 — the search shows its progress, and the operator can ask for a fresh one
- **The progress was kept and seen by nobody.** At 01:40 the operator asked how far the first walk on the
control-node had got. The walk kept its progress every minute beside the engine's state, but `root-free` said
only "not judged yet (search running), started 01:27", and no tool read further. The node-engine serves no
tools of its own, so the progress now travels where the verdict already does: the agent account's verdict
carries it as fields, and its reason gains one line that `root-free` repeats. The line holds filesystems done
of the total, the mount point being walked, the entries visited, the setuid- or setgid-root files found so far,
when the progress was last kept, and how long each finished filesystem took. Counts, times and mount points
only: the cursor and every file found are often under an account's home, and stay in the engine's state and
journal. The line moves at each checkpoint (once a minute) and is never part of what makes a verdict
"changed", so the journal does not repeat it every minute; the statement is said every minute anyway while
the account is not healthy. An entry is counted once across a resume, as it is kept with the cursor it
matches. The time a filesystem took counts only the time the engine walked it, not the time it was stopped.
- **A change by hand was not searched for until the next day.** The first complete search on the control-node
ended at about 01:48 and found two setuid-root programs no package owns, copies in the operator's home. When the
operator removes them by hand, no apply says so, and nothing searches again until the daily search. The
operator now asks for one at the controller's terminal: `nox node setuid-search <node>` on the control-node.
The controller signs the ask with the mesh's key, as it signs a hand-over, under a signing context of its own.
The engine throws away the last complete search and any walk under way or kept, and the next look starts a
full search. Until it completes, the verdict is "not judged yet", with its progress.
- **Why at the terminal alone, not a verb.** A search can never make a machine root-free wrongly: it judges only
once complete. But every ask throws a walk away. Asked again and again, it would keep the machine unjudged
for good and its disks busy, and whoever may call a verb includes agents. The operator needs the line only
after a change made by hand.
- **Considered, not built: judge only what the agent account can reach.** A setuid program under another
account's home with mode 0700 cannot be executed by the agent account, because it cannot traverse the
directory. Counting only files whose every parent directory the agent account may traverse would stop the
operator's own copies blocking `root-free`. It is not built, for three reasons. Root or the operator can make
a directory traversable later without any apply, so the verdict would rest on modes that change unseen. ACLs
and group membership have to be read for every parent. A program the agent cannot reach today is still one
no package owns. Deciding it is a change to ADR 0266 §3 item 10, made through playbook 02 if wanted.