Issue 056 — an adopted module assigned to a second node raises a second server
"One postgres, one lavinmq" (ADR 0078) holds only by genesis assigning the adopted modules to the control-node alone; nothing enforces it. A second assign raises a divergent second server, silently. Open questions: a mesh-scoped exclusive seat, or explicit adoption the controller refuses to place elsewhere. https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
---
|
||||
status: open
|
||||
opened: 2026-09-17
|
||||
located-in: [mesh-controller, mesh-host]
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 056 — An adopted module assigned to a second node raises a second server
|
||||
|
||||
## Symptom
|
||||
|
||||
The store and broker are adopted in place ([ADR 0078](../../02-DECISIONS/0078-the-store-and-broker-are-modules.md),
|
||||
issue 051): genesis raises `mesh-store`/`mesh-broker` on the control-node, and assigning the
|
||||
`postgres`/`lavinmq` module there makes the module reconcile the already-running container instead
|
||||
of raising a new one. Adoption works *because the container is already running on that node*.
|
||||
|
||||
Nothing stops the same module being assigned to a **second** node. On a node where no
|
||||
`mesh-store` is running, the applier finds no container by that name and raises one — a second
|
||||
postgres, a second broker. The whole point of Phase 3 — "one postgres, one lavinmq" — holds only
|
||||
by the convention that genesis assigns these modules to the control-node alone; it is not enforced.
|
||||
|
||||
## Why it matters
|
||||
|
||||
"There is one store and one broker" is stated as a property of the mesh, and a property enforced by
|
||||
nothing is indistinguishable from a wrong one. A single extra `assign` — the ordinary verb an
|
||||
operator types — silently produces a divergent second server holding none of the first's data, and
|
||||
consumers resolved to it get an empty store. The failure is silent and far from its cause.
|
||||
|
||||
The exclusive foundation modules are the mesh's clearest case of "there is one of me," yet unlike a
|
||||
mesh-scoped seat, an adopted module carries no claim that the resolver would refuse a second holder
|
||||
for.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Should `postgres`/`lavinmq` claim a mesh-scoped exclusive seat (the way `mesh-controller` claims
|
||||
`the-controller`), so the resolver refuses a second assignment by the same mechanism that keeps
|
||||
one controller?
|
||||
- Or should adoption be explicit — a module that adopts a foundation container declares it, and the
|
||||
controller refuses to place it on a node whose foundation did not raise that container?
|
||||
- How is "one postgres, one lavinmq" checked, rather than assumed — in the resolver, in `status`, or
|
||||
in a bed that tries the second assignment and asserts the refusal?
|
||||
Reference in New Issue
Block a user