diff --git a/04-ISSUES/050-the-catalogue-knows-nothing-built-before-it/00-report.md b/04-ISSUES/050-the-catalogue-knows-nothing-built-before-it/00-report.md new file mode 100644 index 0000000..c22f42e --- /dev/null +++ b/04-ISSUES/050-the-catalogue-knows-nothing-built-before-it/00-report.md @@ -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 +lavinmq built from +mesh-control built from +``` + +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. |