Issue 354: a decided rename was never scheduled, and a record that defers work names its issue

ADR 0244 left the code renames of the node-engine and the tool runner for later with no issue, owner or
date, and two days on the operator believed them live. Open the issue with the inventory, the risk and a
staged plan; add the rule to playbooks 02 and 04, as a dated insight on ADR 0244, and as a cycle.py check
that found the same gap in ADR 0270 (issue 355).
This commit is contained in:
jochen
2026-10-09 19:27:05 +02:00
parent 1365ec17c8
commit 85da2fb93f
10 changed files with 326 additions and 3 deletions
+8 -1
View File
@@ -61,7 +61,14 @@ number is how a record is cited, and `main` lags every open pull request, so two
allocate the same one). And a core issue — one opened from 2026-10-07 whose `located-in` names a core
repository — resolves only with `replay:` (an id in mesh-lab's replays register) or `replay-none:` saying
why none is possible ([ADR 0237](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md));
it failed on a resolved core issue carrying neither before it passed. `python3 00-META/checks/cycle.py`
it failed on a resolved core issue carrying neither before it passed. And an accepted record that puts work
off — "until renamed", "left for later", "deferred", "a later change" — names the issue that tracks it, in that
paragraph or in a dated progressive insight that says what it tracks
([issue 354](../../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md):
ADR 0244 deferred the code renames with no issue, and two days later the operator believed them done). Held to
it: a record dated from 2026-10-09, and an older one corrected under the rule. Measured from ADR 0244's date
it found deferrals without an issue in ADR 0241, 0244 and 0270; held from 2026-10-09 it failed on 0270, and on
0244 once its insight brought it under the rule, before each named its issue. `python3 00-META/checks/cycle.py`
## words.py
+62
View File
@@ -56,6 +56,41 @@ CORE = re.compile(r"\b(mesh-controller|mesh-host|mesh-tools|mesh-sdk|node-tools|
REPLAYS_FROM = "2026-10-07"
REPLAY_ID = re.compile(r"^R\d+\b")
# A decision that defers work names the issue that tracks it (issue 354). ADR 0244 left the code
# renames of the node-engine and the tool runner "for a later rename", with no issue, owner or date;
# two days later the operator believed them done, and nothing in the record said otherwise. A deferral
# nothing tracks is indistinguishable from work that was done. Held to it: an accepted record dated
# from DEFERRALS_FROM, and an older one corrected under the rule (a progressive insight dated from then
# on): an edit made under the rule is held to it. The phrases are the ones records use to put work off;
# "for later" alone is not one, because records say "never queued for later" and "too narrow for later".
DEFERRALS_FROM = "2026-10-09"
DEFERRAL = re.compile(r"(?i)until (?:it is |they are |the code (?:is )?)?renamed|until the code rename|"
r"\ba later rename|not renamed here|identifier to rename|"
r"left (?:for|to) (?:a )?later(?! record)|"
r"\bdeferred\b|later work|not built here|\ba later change")
ISSUE_REF = re.compile(r"\bissue (\d{3})\b|04-ISSUES/(\d{3})-")
INSIGHT = re.compile(r"\*\*Progressive insights?[ \t]*[—–-][ \t]*(\d{4}-\d{2}-\d{2})")
def paragraphs(path):
"""A record's body as (first line number, text) paragraphs: frontmatter and fenced code left out,
a block quote's markers stripped, so a quoted insight reads as the paragraph it is."""
text = open(path, encoding="utf-8").read()
m = re.match(r"^---\n.*?\n---\n?", text, re.S)
body, first = (text[m.end():], text[: m.end()].count("\n") + 1) if m else (text, 1)
body = re.sub(r"(?ms)^\s*```.*?^\s*```", lambda x: re.sub(r"[^\n]", " ", x.group(0)), body)
out, line = [], first
for chunk in body.split("\n\n"):
stripped = "\n".join(re.sub(r"^\s*>\s?", "", l) for l in chunk.split("\n")).strip()
if stripped:
out.append((line, stripped))
line += chunk.count("\n") + 2
return out
def issue_refs(text, issues):
return {n for a, b in ISSUE_REF.findall(text) for n in (a, b) if n and n in issues}
def rel(path):
return os.path.relpath(path, ROOT)
@@ -233,6 +268,33 @@ def main():
bad(path, "an accepted decision nothing in the cycle cites -- give it a home in a "
"design doc's decisions:, a research became:, an issue, or 00-META")
# ---- deferrals -------------------------------------------------------------------
# A paragraph that puts work off names the issue that tracks it, or the record carries a
# dated progressive insight that names the issue and says what it tracks. An issue that has
# since resolved still counts: the deferred work landed, which is what the pointer was for.
for name, (path, status) in records.items():
front = frontmatter(path) or {}
decided = str(front.get("date") or "")
if status != "accepted":
continue
paras = paragraphs(path)
insights = [(d, text) for line, text in paras for d in INSIGHT.findall(text)]
held = decided >= DEFERRALS_FROM or any(d >= DEFERRALS_FROM for d, _ in insights)
if not held:
continue
covering = set()
for d, text in insights:
if DEFERRAL.search(text):
covering |= issue_refs(text, seen)
for line, text in paras:
m = DEFERRAL.search(text)
if not m or issue_refs(text, seen) or covering:
continue
bad(path, "line %d defers work (%r) and names no issue that tracks it -- a deferral nothing "
"tracks reads as done (issue 354). Name the issue beside it, with its owner, or in a "
"dated progressive insight that says what it tracks"
% (line + text.count("\n", 0, m.start()), m.group(0)))
checked = (
len(glob.glob(os.path.join(ROOT, "03-DESIGN", "0*", "*.md")))
+ len(glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md")))
+4 -2
View File
@@ -135,14 +135,16 @@ every other domain has something to run on. **Recorded by** the controller and t
in the tools' descriptions it is also an SSH server's or a container runtime's own word, so a
description that means the node-engine by it is found by review.
*Not:* ~~host agent~~, ~~the host~~ (hq), ~~node host~~
*Identifier until renamed:* `mesh-host` — the repository, its binary and its service unit
*Identifier until renamed:* `mesh-host` — the repository, its binary and its service unit; the rename is
[issue 354](../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md)
- **tool runner** — the one program on each node that loads every assigned module's tools bundle and
serves every tool and every held seat's verb on the subjects the memberships issue; the node-engine
supervises it as a process beside the services it runs, never a container
([ADR 0175](../02-DECISIONS/0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md),
which called it "node tools"). Its mode on loopback is the mesh MCP server.
*Not:* ~~node tools~~, ~~tool runtime~~ (hq)
*Identifier until renamed:* `node-tools` — the module, its unit and its bus account
*Identifier until renamed:* `node-tools` — the module, its unit and its bus account; the rename is
[issue 354](../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md)
- **foundation** — the store and the bus, raised at genesis before any module system exists. The
foundation is not a third thing beside the store and the bus — it *is* those two, named together.
*Not:* ~~substrate~~
+6
View File
@@ -13,6 +13,12 @@
2. **Record the decision.** Write a record in [`02-DECISIONS/`](../../02-DECISIONS/) taking the next free
number. Format and rules are in [`02-DECISIONS/README.md`](../../02-DECISIONS/README.md). State evidence,
not assertion, and record the options that were rejected — that is the half worth keeping.
**A record that puts work off** — a rename, a check, a case it does not handle — names the issue that
tracks it and the owner who will do it, in the sentence that defers it, or the deferral is not accepted:
a deferral nothing tracks reads as done
([issue 354](../../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md),
ADR 0244's code renames). [`cycle.py`](../checks/cycle.py) holds every accepted record dated from
2026-10-09, and an older one corrected under the rule, to it.
3. **Write the design.** Create the document under `03-DESIGN/01-to-be/` with frontmatter:
```yaml
+4
View File
@@ -24,6 +24,10 @@
## Rules
- Every merge is a human checkpoint, without exception.
- What the handoff leaves for later is an issue with an owner, named in the design or the decision that
leaves it — never a sentence saying "later". The design's `code:` names who owns what is built; the issue
names who owns what is not. [`cycle.py`](../checks/cycle.py) checks the decision record
([issue 354](../../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md)).
- Never open a pull request unprompted. A permissions list saying it is allowed is not a
request.
- Work in an isolated worktree, never a shared checkout. A failed `cd` in a shared checkout
@@ -182,6 +182,16 @@ work:
descriptions call a build request an *ask*;
- the nftables module's tool `firewall_rules`, which serves the packet filter.
> **Progressive insight — 2026-10-09.** This section deferred the code renames and named no issue, owner or
> date for them; two days later the operator believed them done, and nothing in this record said otherwise.
> They are tracked by
> [issue 354](../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md),
> which holds the inventory of what carries the old names, the risk of renaming the paths of a self-updating
> daemon on live nodes, and the staged plan; each stage is owned by the repository it names, and the
> glossary's *Identifier until renamed* lines point at the issue. The decision stands. From this date a
> record that defers work names the issue that tracks it, with an owner, or the deferral is not accepted
> (playbooks 02 and 04; `cycle.py` checks it).
## Options rejected
- **Machine as the one word, node only as an identifier** — the research's proposal, and what the newest
@@ -154,6 +154,11 @@ The table of ADR 0239 decision 2 gains these rows:
held merge of it stays held for a person, as before this record. Reading "every machine running it" from
the first machines when they are all the machines would close it, and is left for a later change.
> **Progressive insight — 2026-10-09.** The one-machine case above was left for a later change with no
> issue, owner or date, which is how ADR 0244's deferred renames went unnoticed (issue 354). It is tracked by
> [issue 355](../04-ISSUES/355-a-held-delivery-of-a-module-that-runs-on-one-machine-only-is-never-covered/00-report.md),
> owned by mesh-delivery in the controller's repository. The decision stands.
> **Progressive insight — 2026-10-09.** *The gap was wider than one machine.* A build the mesh held back for
> a person and sent on the operator's word travels by a backlog walk, whose record gives one step per
> machine and no "every machine running it" or "the rest running it"; and that walk's last record keeps only
@@ -0,0 +1,73 @@
---
status: located
opened: 2026-10-09
located-in: [mesh-host (the node-engine: its repository, module, binary, units, launcher and paths), mesh-tools node-tools (the tool runner: its module, unit and bus account), mesh-controller (the names it keys the core on, and the words it shows), mesh-catalog (the registrations, and the modules that name the two), hq (the designs' code lines, repos.md, the glossary's identifier lines)]
fixed-by:
amended-design:
---
# 354. A decided rename was never scheduled, and the operator believed it live
## Symptom
[ADR 0244](../../02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md)
(2026-10-07) settled the words: the program on every node is the **node-engine**, and the program that serves
every module's tools on a node is the **tool runner**. It left the code renames out on purpose — "`mesh-host`
an identifier until the code rename", "`node-tools` an identifier until renamed", and its §6 *What is not
renamed here*: "code is renamed by the repositories that own it, each with its own change" — and named no
issue, no owner and no date for them.
On 2026-10-09 the operator took the rename as long implemented and live. It is not. As of that day:
- **The repositories**, at their heads (the node-engine's at `b0d03be`, the controller's at `e6b00e2e`, the
catalogue's at `6ae112d`): the node-engine's repository and module are `mesh-host`; its binary is
`nox-mesh-host`; its service units are `nox-mesh-host.service`, `nox-mesh-host-resume.service` and
`nox-mesh-host-roused.service`; its launcher is `/usr/lib/nox-mesh-host/launch`; it is delivered under
`/usr/lib/nox-mesh-host/versions/<version>` and keeps its state under `/var/lib/mesh-host`. The tool
runner is the module `node-tools`, the unit `node-tools.service` and the bus account `node-tools`.
- **The live mesh**, read through the controller's `node` verb for the laptop at 18:05: `mesh-host` and
`node-tools` stand among its assigned modules, and `node-tools.runtime process node-tools.service` among
what it runs.
- **The conditions.** An open condition on the control-node (messenger not healthy) says that
`mesh-host hand-over` at the machine hands a directory to the mesh; every hand-act record of the day
names its caller as `<the laptop>.node-tools`.
- **The record.** `records_search` for "until the code rename" finds ADR 0244's own table row and nothing
else; for "rename mesh-host", nothing. No issue, design or record tracks the rename.
## Why it is an issue
- **A deferral nothing tracks reads as done.** ADR 0244 is accepted; the glossary says node-engine; the
governing documents were reworded the same day. Everything a reader meets says the new name, and the one
sentence that says the code is not renamed says "later" with nobody's name on it. Two days later the
operator believed it done. This is the rule of `AGENTS.md` — an unenforced rule is indistinguishable from
a wrong one — in its deferral form: a record that puts work off without an issue is indistinguishable
from one whose work landed.
- **It is not one record's slip.** The check this issue adds, run over every accepted record from the
date ADR 0244 was accepted, found deferrals without an issue in ADR 0241 ("a later change requires them
once both holders serve them"), ADR 0270 ("left for a later change") and ADR 0244 itself. ADR 0270 is
dated 2026-10-09, is held to the rule, and has
[issue 355](../355-a-held-delivery-of-a-module-that-runs-on-one-machine-only-is-never-covered/00-report.md)
now; ADR 0241 is dated before the rule's start and stands as found.
- **Impact.** The operator plans against a mesh that does not exist: in conversation the mesh says
node-engine, while every file, unit, package and condition on a node says `mesh-host`, so a person at a
machine (`systemctl status nox-mesh-host`, `ls /var/lib/mesh-host`) and a person reading this repository
do not describe the same thing. The glossary's *Identifier until renamed* lines tell an agent the name is
temporary and never say when.
## The fix, in two parts
1. **This rename** is tracked here. The inventory of what carries the old names, the risk of renaming the
paths of a self-updating daemon on live nodes, and a staged plan are in
[`01-diagnosis.md`](01-diagnosis.md). Acceptance: **`mesh-cli node show <node>` and every condition say
node-engine; no file, unit or package on a node is named `mesh-host`; the tool runner likewise.**
2. **The rule**, from 2026-10-09: a decision that defers work names the issue that tracks it, with an
owner, or the deferral is not accepted. Playbooks [02](../../00-META/process/02-graduation.md)
(graduation) and [04](../../00-META/process/04-build-handoff.md) (handoff) say it;
[`cycle.py`](../../00-META/checks/cycle.py) checks it: an accepted record dated from 2026-10-09, or an
older one corrected under the rule, whose text puts work off ("until renamed", "left for later",
"deferred", "a later change") names an issue in that paragraph or in a dated progressive insight that
says what it tracks. ADR 0244 carries the insight that points here.
This resolves when the acceptance sentence holds on every node. It is a core issue
([ADR 0237](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md)):
it resolves with a replay, or with `replay-none:` saying why none is possible.
@@ -0,0 +1,114 @@
# 354. Diagnosis
## 2026-10-09
**The record.** `records_search` for "until the code rename" finds only ADR 0244's table row; for the
old name with "rename", nothing. Issues 142, 194 and 210 carry the old name in their titles and keep it: an issue keeps
its words (ADR 0244 §5).
### What carries the old names
**This repository**, on `main` at `c613cf0`:
| Where | What | How much |
|---|---|---|
| `03-DESIGN/01-to-be/` | `mesh-host` and `node-tools` in prose and in `code:` lines | 24 documents, 97 lines; 19 designs name `mesh-host` in `code:`, which is the repository's name and stays right until the repository is renamed |
| `03-DESIGN/00-as-is/` | `code:` lines | 2 documents |
| `00-META/` | `repos.md` (the table says `mesh-host` exists, tier 0), playbook 07's list of repositories, the glossary's two *Identifier until renamed* lines | 3 documents |
| `02-DECISIONS/`, `01-RESEARCH/`, `04-ISSUES/` | the old names as written | 38, 9 and 135 documents; kept, because a record keeps its words |
**The code**, in the checkouts at the heads the report names:
- **The node-engine's repository, `mesh-host`.** Its manifest: module `mesh-host`, slug `host`, the
artifact's binary `nox-mesh-host`, the resource `launcher` at `/usr/lib/nox-mesh-host/launch`, the
resource `next` (the delivered archive) at `/usr/lib/nox-mesh-host/versions/<version>`. Its packaging:
`nox-mesh-host.service` (whose start command is the launcher), `nox-mesh-host-resume.service`,
`nox-mesh-host-roused.service`, `nox-mesh-host-launch`, `nox-mesh-host-rollback`,
`nox-mesh-host-network.sh` and an OpenRC script. The launcher's environment (`MESH_HOST_STATE_DIR`,
`MESH_HOST_LIBEXEC`, `MESH_HOST_BIN`, and its limits) and its fallback binary `/usr/bin/nox-mesh-host`.
The state directory `/var/lib/mesh-host`: the node's state, the foundation lock, and the launcher's
files (known-good, rolled-back, trial, the start counter). The commands `cmd/mesh-host` (its flag set is
named `mesh-host`) and `cmd/mesh-bootstrap`. The placement guard's `engineModule` (`mesh-host`) and
`engineTrees` (both directories). The words a report says, which conditions quote: `mesh-host hand-over` at
the machine. The Go module path, which the controller's builder check vendors. The
report names a socket under `/run/nox-mesh-host`; I did not find one in the checkout at `b0d03be`, so
the diagnosis in that repository confirms it or strikes it.
- **The tool runner**, in the `mesh-tools` repository under `node-tools/`: the module `node-tools`, the
unit `node-tools.service`, the bus account `node-tools`, the mesh MCP server's description of itself
("reached as <node>.node-tools"), and the caller's address every hand-act record keeps,
`<node>.node-tools`.
- **The controller, `mesh-controller`**: 51 lines naming `mesh-host`, 18 naming `node-tools`. The core
modules the merge gate and the checks key on (`coreModules`: module to repository), the module the probes
key on (`hostModule`), the runtime module (`RuntimeModule`, in the catalogue and the broker packages),
the bus account (`BusNodeTools`), the broker's kind (`KindNodeTools`), the lease witness
(`NodeToolsService`, `ComponentNodeTools`, and a component named `mesh-host`), the seat dependencies, the
reconnects, and the put-back ordering of a send, keyed on the strings `mesh-host` and `mesh-controller`.
The words it shows: `"mesh-host": "the node-engine"` and `"node-tools": "the node tools"` — the second
is a retired word.
- **The catalogue, `mesh-catalog`**: 20 files name one or both — the README, the desktop session code of
five modules, the container runtime's tools and tests, the bus's tools, the service manager's client,
the SSH client's manifest, the lab's tools and the forge's tests. And the registrations: a catalogue row
for `mesh-host` (built from its own repository, ADR 0069) and one for `node-tools` (from `mesh-tools`),
and every node's assignment of both.
The owner of each area is the repository named. For the symptom's words, the whole of the rename, and the
check, this repository.
### The risk
**Renaming the paths of a self-updating daemon on live nodes.** The node-engine delivers itself: its
launcher, placed by the module's own declaration under `/usr/lib/nox-mesh-host`, runs the newest delivered
version under that directory's `versions/` on trial, and goes back to the known-good one recorded under
`/var/lib/mesh-host` when the trial fails
([to-be 45 §8](../../03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md),
[ADR 0227](../../02-DECISIONS/0227-the-core-holds-nine-rules-each-checked-and-is-built-to-them-in-six-phases.md)
rule 8). Its unit is placed when the machine joins, not by the mesh
([to-be 21](../../03-DESIGN/01-to-be/21-the-installation-in-full.md): the installer does not install the
unit). So a build that writes under new paths while the launcher reads the old ones is a build the launcher
cannot find; and a launcher that reads only new paths cannot go back to a known-good version under the old
ones — it halts the node ("this node needs a person"), which on a server is a person at a keyboard. The
module's name is keyed in the controller's core handling (the put-back ordering, the gate's core modules,
the lease witness), so a renamed module is, to a controller that knows one name, a new module beside an old
one. The tool runner has the same shape at a smaller scale: the bus account and the unit are named in the
controller's user list and in every node's assignment.
Hence: **one release in which both names are accepted, on every side, before any release in which the old
one is dropped**, each release walked one node first — the laptop, where a halted node is the operator at a
keyboard — and then the rest. I think no stage should move before the delivery fixes of issues 351 and 352
are live, because a core walk is exactly what those broke; that is a guess from their symptoms, not a
measurement.
### The staged plan
0. **This repository** (this change): the issue; the glossary's identifier lines point here; the rule and
its check.
1. **The words shown**, safe at any time and in any order: the controller's shown words ("the node tools"
becomes the tool runner), the node-engine's report words (the hand-over as the node-engine's command),
the mesh MCP server's description of itself. No path changes.
2. **Both names accepted, for one release.** The controller treats `mesh-host` and the node-engine's new
module name as one core component (core modules, witness, put-back ordering), and `node-tools` and the
tool runner's as another (runtime module, bus account, kind). The node-engine's launcher and upgrade
package read the old and the new library and state directories, and the node-engine moves its state
once, the first time it runs under the new name. Both unit names run the same launcher. The conditions
and the `node` verb say node-engine. The merge gate composes every node green; walked one node first.
3. **The rename proper.** The new module names registered, assigned beside the old on the first node, the
old unassigned there, the acceptance sentence checked on that node, then the rest. The repository
renamed on the forge, with its build source and its Go module path; the packaging renamed. The tool
runner the same: module, unit, bus account — and the caller's address in hand-act records changes with
it, which whoever reads those records must know.
4. **The old names dropped**, one release later: the controller's acceptance of them, the launcher's old
paths, the glossary's two identifier lines (the old names move to *Not:* lines, and `words.py` then
fails on them in prose), the designs' `code:` lines and `repos.md` following the repository.
**Acceptance:** `mesh-cli node show <node>` and every condition say node-engine; no file, unit or package on a
node is named `mesh-host`; the tool runner likewise.
### Open
- **The new identifiers.** The glossary's words are node-engine and tool runner; the `nox-` prefix on the
binary and the units is the packaging's. Whether the binary is `nox-node-engine`, the directories
`/usr/lib/node-engine` and `/var/lib/node-engine`, and the tool runner's module `tool-runner`, is the
operator's call before stage 2 is built.
- **Whether the state directory moves at all.** What is under it is the node's own (the report sequence,
the known-good version): a new name beside a kept path is an option the diagnosis in the node-engine's
repository weighs.
@@ -0,0 +1,40 @@
---
status: open
opened: 2026-10-09
located-in: []
fixed-by:
amended-design:
---
# 355. A held delivery of a module that runs on one machine only is never covered
## Symptom
[ADR 0270](../../02-DECISIONS/0270-a-held-delivery-that-moves-nothing-or-that-a-later-delivered-merge-contains-ends-by-itself-and-a-hold-whose-reason-is-gone-lifts.md)
(2026-10-09) ends a held delivery by itself when a later merge that contains it was delivered to every
machine running its modules — the delivery is *covered*. Its consequences say: "A module that runs on one
machine only is never covered. A walk records 'the rest running it' only after its first machines passed
and the rest were sent. A module on one machine has no rest, so its steps never say it reached every
machine. mesh-delivery itself, on the control node alone, is such a module: a held merge of it stays held
for a person, as before this record. Reading 'every machine running it' from the first machines when they
are all the machines would close it, and is left for a later change."
That later change had no issue, no owner and no date. The check added with
[issue 354](../354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md)
found the sentence on the day the record was accepted. This issue is the pointer the record lacked; the
record carries a dated insight naming it.
## Why it is an issue
A held delivery of mesh-delivery — or of any module placed on one machine — that a later merge covered
stays held for a person, which is the hand-work ADR 0270 set out to remove; and nothing told the operator
this case was excluded except one sentence in the record's consequences. A deferral nothing tracks reads as
done (issue 354).
## Open
- Whether a walk whose first machines are all the machines should record that it reached every machine
(the record's own suggestion), or whether *covered* should read the machines running a module from the
placement rather than from the walk's steps.
- The owner is mesh-delivery, in the controller's repository, as the record says; `located-in:` is filled
when the diagnosis confirms where the walk's record is written.