Files
jschoubben 61f61b5d06 Reconcile the open issues against main
An audit of the six code repositories found eleven open issues fixed on main
with commits and beds to show (025, 027, 033, 036, 037, 040, 045, 047, 050,
052, 053), three partly (007, 026, 035), nine not (020, 031, 041, 046, 049,
054, 064, 065, 066) and one whose fix would live outside those repos (006).
Resolved ones name their evidence; partly ones say what remains; 041 records
that the exposure has widened since it was reported.
2026-09-21 01:52:53 +02:00

58 lines
3.5 KiB
Markdown

---
status: resolved
opened: 2026-09-05
located-in: [mesh-control, mesh-host, mesh-catalog]
fixed-by: ADR 0052 run-once container: mesh-host 19e5dd8, PR #5 24e9ae4; ADR 0053 scheduled twin 9d1f001; proven by mesh-lab assigned-catalogue-mqtt.test.ts
amended-design: 02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md
---
# 037 — A module cannot run its own code at a lifecycle phase
## The symptom, as observed
Found while converting the catalogue (2026-09-05), across several modules at once. A module can
declare *things that exist* — a directory, a file with fixed content, a network, a container — but
it cannot declare *a step that runs* at a defined point in its own lifecycle. Three converted
modules need exactly that and have nowhere to put it:
- **mosquitto.** Its Dynamic Security plugin will not start unless `dynamic-security.json` already
contains an admin client *before the broker's first start* — the broker loads the plugin at
boot. Seeding it is a run-once step that must happen after the file resource exists and before
the container starts. The vocabulary has no "before first start."
- **The database providers (postgres/mongodb/mssql).** First-boot seeding works today only because
the *image* happens to do it from an env var. Anything the mesh itself must run once against the
server — a schema migration, an extension enable, a health gate before the module is announced
ready — has no home.
- The seed-then-mutate family already recorded in [035](../035-reconciling-a-seed-file-wipes-what-grew-in-it/00-report.md)
is the same shape seen from the *content* side; this is it seen from the *timing* side.
## Why it matters beyond the instance
This is not a defect in a module — it is a **capability the module system does not yet offer.** A
real class of modules needs to run their own code at points in the build/install/run lifecycle:
seed-before-start, migrate, post-start health-gate, pre-remove drain. The declarative resource
model deliberately describes *state*, not *steps*, and that is right for what it covers; the gap is
that some modules genuinely have a step.
**Prior art, and its warning.** An earlier mesh had exactly this as a feature: event-driven
**hooks** that ran custom code at phases of the build/publish/deploy pipeline. It was powerful and
it was **complex to set up and flaky** — which is the real content of this record. The need is not
in question; the cost of the obvious answer is. Whatever shape this takes must not reproduce that
fragility, or it will be worse than the gap.
## Open questions
- Is the right unit narrow — a **run-once / init resource** ("run this once, here, in the
lifecycle") — or general — a **per-phase lifecycle hook** on a module, and if so which phases
(build / publish / install / pre-start / post-start / pre-remove)?
- Where does a hook's code run — in the module's own runtime container under its scoped account
(ADR 0043/0047), so it inherits the same isolation as its tools and events? Or is some of it the
host's, before a container exists?
- How is a step made **idempotent and reconcilable** so a re-apply does not re-run it
destructively — the same discipline the resource model gets for free and a step does not?
- What is the smallest version that unblocks the three modules above without rebuilding the old
flaky hook engine? Is "seed-before-first-start" alone enough for now, with the general case
deferred?
- A rule states how it is checked: whatever shape is chosen, what lab scenario proves a hook runs
exactly once, at the right phase, and converges on re-apply?