diff --git a/00-META/checks/README.md b/00-META/checks/README.md index d10dde39..b6f5d1e3 100644 --- a/00-META/checks/README.md +++ b/00-META/checks/README.md @@ -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 diff --git a/00-META/checks/cycle.py b/00-META/checks/cycle.py index 0164ada4..7e7c4aa8 100644 --- a/00-META/checks/cycle.py +++ b/00-META/checks/cycle.py @@ -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"))) diff --git a/00-META/glossary.md b/00-META/glossary.md index a859740d..75c24cc8 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -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~~ diff --git a/00-META/process/02-graduation.md b/00-META/process/02-graduation.md index 487c293e..145ac980 100644 --- a/00-META/process/02-graduation.md +++ b/00-META/process/02-graduation.md @@ -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 diff --git a/00-META/process/04-build-handoff.md b/00-META/process/04-build-handoff.md index 4c26bafc..8399f81e 100644 --- a/00-META/process/04-build-handoff.md +++ b/00-META/process/04-build-handoff.md @@ -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 diff --git a/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md b/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md index 316d491d..2207c96a 100644 --- a/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md +++ b/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md @@ -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 diff --git a/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 b/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 index 8773bb34..4670a6e5 100644 --- a/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 +++ b/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 @@ -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 diff --git a/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md b/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md new file mode 100644 index 00000000..ff9b25ef --- /dev/null +++ b/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md @@ -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/` 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 `.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 ` 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. diff --git a/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/01-diagnosis.md b/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/01-diagnosis.md new file mode 100644 index 00000000..7cc547c3 --- /dev/null +++ b/04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/01-diagnosis.md @@ -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/`. 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-tools"), and the caller's address every hand-act record keeps, + `.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 ` 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. diff --git a/04-ISSUES/355-a-held-delivery-of-a-module-that-runs-on-one-machine-only-is-never-covered/00-report.md b/04-ISSUES/355-a-held-delivery-of-a-module-that-runs-on-one-machine-only-is-never-covered/00-report.md new file mode 100644 index 00000000..a5a9d3f1 --- /dev/null +++ b/04-ISSUES/355-a-held-delivery-of-a-module-that-runs-on-one-machine-only-is-never-covered/00-report.md @@ -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.