One green fresh run of the no-fake two-node bed is the proof: node2's consumers open the store and broker the mesh built and adopted, over the overlay. Fixed by mesh-controller PR 29, mesh-catalog PR 26, gated by mesh-lab PR 34.
45 lines
2.2 KiB
Markdown
45 lines
2.2 KiB
Markdown
---
|
|
status: resolved
|
|
opened: 2026-09-18
|
|
located-in:
|
|
- mesh-controller
|
|
fixed-by: mesh-controller PR 29 (98aea8b); gated by mesh-lab PR 34
|
|
amended-design:
|
|
---
|
|
|
|
# 062 — A failed lookup composes the network without the registry trust
|
|
|
|
## Symptom
|
|
|
|
One machine in three otherwise identical runs joined the mesh with a runtime that never learned to
|
|
pull from the mesh's artifact store. Its runtime daemon file was never written at all — not stale,
|
|
absent — while the same push on the same commits had carried the trust to the same machine in the
|
|
run before. The push reported success both times.
|
|
|
|
Observed on the built-store-cross-node bed (2026-09-18): the first fresh run carried the trust to
|
|
both machines; the next fresh run carried it to the first machine and composed the second
|
|
machine's declaration without it. Nothing recomposes a machine until the next push, so the
|
|
omission was permanent for that mesh, and everything reported success: the push, the apply, the
|
|
network itself.
|
|
|
|
## Why it matters beyond the instance
|
|
|
|
The controller answers "where is the artifact store this network reaches?" while composing the
|
|
networking module (ADR 0082). The answering code collapsed *the lookup failed* into *the mesh has
|
|
no store*: a transient inventory error during one compose produced a valid-looking declaration
|
|
that simply lacked the trust. That collapse converts a retryable fault into silent permanent
|
|
state — the exact class issues 042/048 name, reappearing as a race after their fix.
|
|
|
|
The general rule this instance argues for: **"not found" must be a fact about the mesh, never a
|
|
disguise for "the question went unanswered."** Any compose-time lookup that degrades to omission
|
|
on error has this bug; the compose should refuse instead, loudly, so the push fails and is retried
|
|
rather than delivering a declaration that is quietly less than what the mesh means.
|
|
|
|
## Open questions
|
|
|
|
- Are there other compose-time lookups that treat an error as an empty answer? The pattern is
|
|
easy to write and invisible until a bed asserts the composed fact end to end.
|
|
- Should a bed that waits on pushed state always print the push's own output, so a compose that
|
|
refused is distinguishable from one that composed short? (The bed now does; the question is
|
|
whether the harness should.)
|