Files
hq/04-ISSUES/062-a-failed-lookup-composes-the-network-without-the-registry-trust/00-report.md
T
jschoubben 4279e4914b 042/048/061/062 resolved — the network carries the registry trust
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.
2026-09-18 00:26:50 +02:00

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.)