Issue 050 — the catalogue knows nothing built before it started

A mesh raised from bare metal built six modules and its catalogue reported three:
exactly those built after it began running. Missing were the shared base, the
store, and the catalogue itself.

The hole is never random. On a fresh mesh the modules built before the catalogue
are by necessity the ones it needed in order to exist, so the foundation is
always what is absent, on every mesh, at the moment the graph is first populated.

It breaks the question the catalogue is for: build edges hang off the base, so a
catalogue with no record of it answers 'what must be rebuilt' confidently and
wrongly. And nothing reports the gap, because a catalogue cannot know what it was
never told — this was found by comparing its answer against what the mesh had
just been watched doing.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-14 22:16:23 +02:00
parent 0aa8f62e0c
commit 5d13f9c83d
@@ -0,0 +1,66 @@
---
status: open
opened: 2026-09-14
located-in: []
fixed-by:
amended-design:
---
# 050 — The catalogue knows nothing that was built before it
## Symptom
A mesh raised from bare metal built six modules in order: the shared base, a store, the catalogue,
the control plane, a module, and a broker. Asked afterwards what it holds, the catalogue answered
with three — exactly the three built *after* it started running:
```
amqp-ping built from <the catalogue repository>
lavinmq built from <the catalogue repository>
mesh-control built from <the control plane repository>
```
Missing: the shared base, the store, and the catalogue itself.
The catalogue learns what exists by consuming the builder's announcement over the broker. Anything
built before it was running was announced to nobody, and nothing goes back for it.
## Why this matters
**The modules it cannot see are the ones a mesh is made of.** On a fresh mesh the things built
before the catalogue are, necessarily, the things the catalogue needed in order to exist: the base
it was compiled against and the store it keeps its records in. So the hole is not random — it is
always the foundation, on every mesh, at exactly the moment the graph is first populated.
**It breaks the question the catalogue exists to answer.** Build edges are derived facts between
versions, and the base is the node nearly every other module hangs off. A catalogue with no record
of the base cannot know that moving it makes everything standing on it stale, so `catalog_stale`
answers confidently and wrongly — the worst shape for a question about what to rebuild.
**Nothing reports the gap.** The catalogue does not know what it was not told, so it does not say
"three of six" — it says three, and a reader with no independent count believes it. This was found
by asking it a question and comparing the answer against what the mesh had just been watched doing.
**The record is not lost, only the catalogue's copy.** The control plane holds every build it
ordered, with commit, repository, path and resolved artifacts. So this is a gap between two stores
that should agree, rather than information nobody has.
## Open questions
- **Should the catalogue backfill on start** — ask the control plane for the builds it already
recorded and take them in? That fixes the fresh-mesh case and every case where the catalogue was
down while something was built, which is the same fault with a different cause.
- **Or should announcements be durable**, so a build announced while nothing was listening is
delivered when something is? That treats the catalogue as one consumer among several, which it
already is.
- **Or should the control plane be the record and the catalogue a projection of it?** Two stores
that must agree, kept in step by events, is the arrangement that produced this.
- **How would anyone notice next time?** The catalogue cannot compare itself to a source of truth
it does not have. Whatever is chosen, something has to be able to say "these disagree".
## How this would be checked
| Rule | Checked by |
|---|---|
| The catalogue holds every module the mesh built | A mesh is raised from bare metal and the catalogue is asked; its list is compared against the control plane's build records, and a module in one and not the other is a failure. |
| A change to the base makes what stands on it stale | The base is rebuilt on a fresh mesh and the catalogue names the modules that must follow — which requires it to know the base exists. |