Merge pull request 'Issues 214–216: a plan losing its own controller, a module pinned silently, a bundle never delivered' (#333) from issues/214-216-found-building-0192-0193 into main

This commit was merged in pull request #333.
This commit is contained in:
2026-10-03 20:15:30 +00:00
3 changed files with 101 additions and 0 deletions
@@ -0,0 +1,36 @@
---
status: open
opened: 2026-10-03
located-in:
- mesh-controller
fixed-by:
amended-design:
---
# 214 — A plan loses track of the controller it rebuilds, and waits on it for ever
## What was observed
2026-10-03, a merge to the controller's repository planned three tiers: the controller itself, then
the build agent, then the route proxy. The controller's build finished and was recorded at 19:24:
```
mesh-controller built 2ebbb799 g14 2026-10-03 19:24
```
Twenty-seven minutes later the plan still read `tier 1 of 3 … mesh-controller asked`, and every later
plan waited behind it. It was stopped by hand; the later tiers were never asked.
## Why it matters beyond this instance
The controller rebuilding itself is the one plan whose first tier replaces the process that runs the
plan. The new controller starts with the plan's state as stored, and the outcome of the build that
produced it arrived to the old one, or between the two. Every merge to the controller's own repository
can end this way, and each one blocks every plan after it until somebody notices.
## Diagnosis
Owner mesh-controller (the planner). **Fix direction:** on start, and whenever a plan waits on a
build, the plan settles an `asked` build against the build records — a build recorded as built from
the plan's commit is that tier's outcome — so a plan resumes after the controller replaced itself.
A test: a plan whose build outcome was recorded while no controller followed it resumes on start.
@@ -0,0 +1,35 @@
---
status: open
opened: 2026-10-03
located-in:
- mesh-controller
fixed-by:
amended-design:
---
# 215 — A module built once at a commit stops following its branch, and merges leave it out
## What was observed
2026-10-03, a catalogue merge changed seven modules. Its plan built six; `unifi` was not in it,
though its change was in the same commit. A second merge the same evening left it out again. Its
build records name a commit where every other module names a branch:
```
unifi built 9c97a8a1 … http://…/mesh-catalog.git at 9c97a8a
```
Built by hand from `main` it was registered again and the change reached its machine.
## Why it matters beyond this instance
A module that was once built at a commit — to pin it during a fix, or by a build asked with a `ref`
— silently stops following its branch: merges plan without it, `status` does not say it is behind its
branch, and nothing says it is pinned. The operator learns it when a change does not arrive.
## Diagnosis
Owner mesh-controller. **Fix direction:** a build asked at a commit does not change the branch a
module follows; or, if pinning is meant, the pin is said — in `module list`, in `status`, and by a
merge's plan naming the module it leaves out and why. A test: building a module at a commit and then
merging a change to it plans it.
@@ -0,0 +1,30 @@
---
status: open
opened: 2026-10-03
located-in:
- mesh-controller
fixed-by:
amended-design:
---
# 216 — A tools bundle nothing says to load is built, recorded, and never delivered
## What was observed
2026-10-03, seven modules moved their tools from a container to a bundle. Each built, each build was
recorded, and the machines that run them reported current — with none of the bundles on them. The
composer delivers a bundle only when the runtime loads something from it, and that is derived from
the module's `tools` list when the artifact names no `loads`; these modules had neither.
## Why it matters beyond this instance
Every step reported success: the build, the registration, the push, the machine's apply. The tools
were simply absent, and the old container was gone. A rule the composer applies silently is a rule
nobody learns until the tools are missing.
## Diagnosis
Owner mesh-controller (the catalogue's registration check). **Fix direction:** a bundle that nothing
loads, runs or unpacks — no `loads`, no `tools` list on its module, no resource naming it — is refused
at registration, naming the field that would deliver it. A test: such a manifest is refused; adding
`loads` admits it.