3.0 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design |
|---|---|---|---|---|
| open | 2026-10-04 |
234 — A later declaration left out four assigned modules, and a machine applied it
What was observed
2026-10-04, on a workstation. Four modules (the package manager's, sudo, localization and the
container runtime's) had been assigned and pushed, and the host was applying them in one long apply,
about eleven minutes on a loaded machine. Seven more declarations arrived while it worked. When the
apply ended, the host logged six times set aside a declaration: a newer one arrived with it and
applied the one it kept.
The host chooses by the sequence a declaration carries (issue 107), so the one it kept was the latest the controller had sent. That declaration did not name the four modules. Over the next eight minutes the host undeclared all of them:
removed sudo.operator (…)
removed pacman.config (…)
forgotten pacman.package (pacman)
removed localization.locale (…)
removed docker.prune-service (…)
Throughout, the controller's assignments named the four modules on that machine, and they still do:
plan for the machine lists them. Nobody had unassigned them.
What happened around it:
- A catalogue asked the controller to catch up twice in the same minutes, and every builder rebuilt the same catalogue commit.
- The controller daemon restarted three minutes after the stale declaration was applied.
- Another session was working on the mesh and pushing at the same time.
The controller logs no send. Which process sent the stale declaration, and from what view, cannot be read back from anything the mesh keeps.
Why it matters beyond this instance
A declaration is the mesh's word on what a machine should be, and the host applies it in full, including removing what it does not name. A stale one is not harmless: here it removed four modules, and on a host older than the fix for written-over files it deleted four system files outright (issue 233).
Issue 204 was this family once before and is marked resolved. Ordering by sequence (issue 107) protects against an old declaration arriving late. It does not protect against a declaration that is new in sequence but composed from an old view.
Open questions
- Where can a declaration be composed with fewer modules than the assignments hold? Candidates:
- a send from a process with an out-of-date view;
- composition while a module's build is being replaced;
- a plan sending what it composed when it was made.
- Should every send be recorded with its sequence and its sender, so
statuscan show what a machine was last told and by whom? - Should a declaration that removes something carry a check the host can verify? For example, the assignment generation it was composed from, so a host refuses one older than the generation it has already applied.