diff --git a/04-ISSUES/131-nothing-tells-the-mesh-a-source-moved/00-report.md b/04-ISSUES/131-nothing-tells-the-mesh-a-source-moved/00-report.md new file mode 100644 index 0000000..abd4182 --- /dev/null +++ b/04-ISSUES/131-nothing-tells-the-mesh-a-source-moved/00-report.md @@ -0,0 +1,66 @@ +--- +status: open +opened: 2026-09-27 +located-in: [] +fixed-by: +amended-design: +--- + +# 131 — Nothing tells the mesh a source moved, and it reports itself current anyway + +## What was observed + +Six changes were merged to the trunk of six repositories in one sitting. The build machine built +nothing. Its last build, minutes before the first merge, was still the one it reported; no build was +requested, refused or failed, because none was ever asked for. + +Asked afterwards what was wrong, the mesh said: + +> 4 machine(s), all doing what they were told, all heard from, running what the mesh would send them, +> and every module current with its source + +Every one of the six had moved. The last clause was false for all of them, and it is the clause a +person reads to decide whether there is anything to do. + +## Why it matters beyond this instance + +**The mesh learns a source moved by being told, and there is no longer anything to tell it.** The +command exists — a person names the module and the commit — and so does the question the overview +answers. What is missing is whatever used to connect the two. One repository still carries a forge +webhook aimed at a port; the rest carry none, and the port belongs to a different service than the +one the arrangement implies. So the state is not "the trigger is broken" but "there is no trigger, +and nothing says so". + +**A wrong answer is worse here than no answer.** "Every module current with its source" is +indistinguishable, to a reader, from a mesh that has genuinely caught up. The overview is built to be +the thing you check instead of checking by hand, so a confident false negative removes the habit that +would otherwise have caught it. Nothing in the mesh is at fault for being out of date — it is at +fault for saying it is not. + +**It is also why "current with its source" cannot be a stored fact.** The mesh compares what it built +against what it was last told the source was, and calls that agreement. Two facts agreeing tells you +nothing when both come from the same place. + +## The intended shape, which is decided and not built + +The forge emits what happened to it — a pull request merged — and the build machine reacts by +building what that commit affects. That keeps the forge ignorant of the build system and the build +machine ignorant of the forge's internals, which is the same argument +[ADR 0126](../../02-DECISIONS/0126-a-module-declares-its-own-seats.md) makes for addressing an event +to its emitter: the merge is a fact about the forge, and what should be rebuilt because of it is not +the forge's business to know. + +The forge's module already declares the event. The build machine declares that it consumes nothing. + +## Open questions + +- Is "the source moved" still a thing a person can assert by hand once the event path exists, or does + the hand-operated form become the thing that made this failure possible? +- Which commit does the build machine act on — the merge, or each commit it brought — and what does + it do when several arrive for one module at once? +- How does the overview stop being able to lie? Comparing what was built against what was recorded + will always agree. Whether the trunk has moved is a question only the forge can answer, so either + the overview asks it, or it stops claiming to know. +- Does this want to be the same mechanism as the build request on the bus + ([ADR 0129](../../02-DECISIONS/0129-a-seat-carries-the-protocol-of-its-role.md)), or does it sit in + front of it?