Found rolling the runtime out to the catalogue: a module's runtime reads its settings-merged config file once at start, but a container is only recreated on a spec change, and file content is not part of the spec. So updating settings re-renders the file and nothing re-reads it — ADR 0051's "on the fly" holds only for config set before first start. Services have restart-on; containers do not. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
3.8 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design |
|---|---|---|---|---|
| open | 2026-09-04 |
Changing a module's settings does not restart its runtime — config is stale until recreated
What was observed
Rolling the module runtime out to the catalogue (the runtime that serves a module's tools and runs its events under the module's own account), each tools+events module receives its configuration the way the design intends: a mergeable config file the module declares, into which the assignment's settings are merged. The runtime container mounts that file and reads it once at start-up, when it builds its API client.
The design for settings says a config file a module owns can be changed without editing it — a person states an intention, the file is regenerated, and the change takes effect. The decision that config is the assignment's, not the manifest's, is explicitly so that configuration can be updated on the fly and managed from a dashboard.
For a runtime delivered as a container, that last part does not hold. When settings change, the control plane re-renders the config file on the node — but the runtime container is only ever recreated when its spec changes, and the spec is image, name, env, ports, volumes and args. The content of a mounted file is not part of it. So the file on disk updates and the process that already read it keeps the value it read at start-up. The new configuration does not take effect until something changes the container's spec, or it is recreated by hand.
A service resource has restart-on, which names the resources whose change forces a
restart — exactly this problem, already solved, for units. A container resource has no
equivalent field, and the apply path for containers never consults the set of resources that
changed this pass. So the one kind of resource that hosts a module's runtime is the kind that
cannot say "restart me when my config changes."
The effect is quiet, which is the worst part: setting a value appears to succeed (the file is correct on disk), and the running tools keep answering with the old configuration, or keep failing to load because the value that would fix them is present but unread.
Why it matters beyond this instance
Every tools+events module converted to the runtime model now takes its URL and credentials this way, so this is not one module's quirk — it is the config path for the whole catalogue. The gap turns the headline promise of the settings design ("change it without editing it, on the fly") into "change it, then recreate the container by hand," which is the manual step the design existed to remove. And because the file is genuinely updated, nothing surfaces the staleness; a dashboard that set the value would report success while the mesh kept doing the old thing.
Config set before the runtime first starts (settings, then assign, then push) does work — the file is right when the process reads it. So the gap is specifically about updates to an already-running runtime, which is precisely the case the "on the fly" promise is about.
Open questions
- Should a
containergainrestart-on, mirroring the service field, so a module can point it at its config resource? - Or should the apply path recreate a container when a file it mounts changed this pass — making mounted-file content behave like part of the spec, without a new field to declare?
- Should the config file's content (or a hash of it) fold into the container spec, so an ordinary spec-diff already catches it? That restarts on every change with no new mechanism, at the cost of a spec that is no longer only the container's own declaration.
- Is a restart even the right primitive for a runtime that could instead watch its config file and rebuild its clients in place — and if so, is that each module's job or the runtime host's?