From d2dce347163982f55a56158a5577c6123df64db0 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 15 Sep 2026 01:26:58 +0200 Subject: [PATCH] The catalogue asks on start, and registers a replay as history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A replayed build is registered exactly as any other and announced to nobody. A module that moved months ago is not something anything should act on now: emitting `upgraded` would have the control plane decide about a rollout, and `rebuild-needed` would ask for builds of things already current. Asked on every start rather than only the first, because a catalogue cannot tell whether it has a gap — and the answer is idempotent, so asking when there is none costs a message. Asked after subscribing, so a build arriving during the replay is not lost between the two. Closes novox/hq 04-ISSUES/050 with mesh-control. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx --- modules/mesh-catalog/index.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/mesh-catalog/index.ts b/modules/mesh-catalog/index.ts index 20c64f0..4181fcb 100644 --- a/modules/mesh-catalog/index.ts +++ b/modules/mesh-catalog/index.ts @@ -36,6 +36,15 @@ interface Built { * produced it. Turning that into an edge between module-versions is this module's job. */ against?: string[]; + /** + * This is history, not news — the mesh re-announcing a build this catalogue was not there for. + * + * Registered exactly as any other, and announced as nothing. A module that moved months ago is + * not something anything should act on now: emitting `upgraded` would have the control plane + * decide about a rollout, and `rebuild-needed` would ask for builds of things that are already + * current. + */ + replay?: boolean; } await on("module.builder.built", async (event) => { @@ -56,6 +65,10 @@ await on("module.builder.built", async (event) => { manifest: body.manifest ?? {}, }, body.made ?? [], body.against ?? []); + // **A replay is registered and announced to nobody.** See `replay` above: the graph gains what + // it was missing, and the mesh is told nothing happened, because nothing did. + if (body.replay) return; + await emit("module.mesh-catalog.registered", { module: body.module, commit: body.commit, upgraded, }); @@ -77,3 +90,15 @@ await on("module.builder.built", async (event) => { }); } }); + +// **And ask for what was built before this catalogue existed** (novox/hq 04-ISSUES/050). +// +// The queue above is durable, so nothing is missed once this is running. What it cannot have is +// what was announced before it first ran — and on a fresh mesh that is never arbitrary: the shared +// base, the store this runs on, and this module itself are each necessarily built BEFORE a +// catalogue exists to hear about them. The graph's foundation is the part it never sees. +// +// Asked on every start, not only the first. A catalogue cannot tell whether it has a gap, and the +// answer is idempotent: registering a build already held changes nothing and announces nothing. +// Asked AFTER subscribing, so a build arriving during the replay is not lost between the two. +await emit("module.mesh-catalog.catching-up", {});