From e6e9d4dcc39a9b535c8def8355bf5cd60644186e Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 6 Oct 2026 11:46:27 +0200 Subject: [PATCH] Issue 208: the bus's objects asserted on every send; fix pointer, the module half, Phase 3 note --- .../00-report.md | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/04-ISSUES/208-a-seats-worker-is-made-only-when-the-controller-starts/00-report.md b/04-ISSUES/208-a-seats-worker-is-made-only-when-the-controller-starts/00-report.md index 54da213..a387079 100644 --- a/04-ISSUES/208-a-seats-worker-is-made-only-when-the-controller-starts/00-report.md +++ b/04-ISSUES/208-a-seats-worker-is-made-only-when-the-controller-starts/00-report.md @@ -3,7 +3,7 @@ status: located opened: 2026-10-03 located-in: - mesh-controller -fixed-by: +fixed-by: novox/mesh-controller#81 (b853439) amended-design: --- @@ -40,3 +40,43 @@ Owner mesh-controller: the raise runs once (`RaiseSeats` with the holders of the `assign` run `EnsureConsumer` only for a module's declared consumption. **Fix direction:** when a module claiming a seat with `accepts` is assigned, or on every push that composes a holder for such a seat, ensure the seat's worker as the raise does — the same derivation, the same idempotent assertion. + +## Seen again, 2026-10-06: the module half of the same gap + +A module carried by the runtime, which consumes the controller's condition events, was assigned to a +machine and pushed. It said `binding messenger's consumer …: nats: consumer not found`, and the +self-check's D6 confirmed that the consumer it reads through was not on the bus. The cause was the one +diagnosed above, on the other side. The controller asserted the bus's objects (streams, seat workers, +every module's consumer) only when it started. A push created a module's consumer only when it minted +that module a bus credential, and the runtime carries a module's traffic under its own credential, so +the module was never minted one and its consumer was never created. + +## Fix + +The bus's objects that a declaration implies are now asserted whenever a declaration is sent: on a +push, on the machines the push cascades to, and on a plan's or a rotation's sends. They are not +asserted only at start. The send asserts them through the same derivation the start and the +self-check use, before the memberships. There is no second list of what a send needs. Every part is +idempotent, so asserting the whole set again changes nothing that already holds. + +A failure to assert is said in the send's own output and raised as a condition (`bus.objects.unasserted`). +The next send that asserts everything clears it. The send itself goes on. The objects belong to the +mesh, not to the machines being sent, and holding every machine back for one consumer would turn one +fault into all of them. The start still refuses to serve without its objects. + +Checked by mesh-controller's `busobjects_test.go`. A module carried by the runtime and a seat's holder, +both assigned after the start's assertion, are asserted by the next send. Against a real bus, through +the send's own grant step, both exist after it. That test fails without the change, with the +`consumer not found` seen live. A refused consumer is said in the output and raised as a condition. +The consumers after it are still asked for, and the next good send clears the condition. + +## Healing what no send reaches (to-be 45 Phase 3) + +The fix covers every object a send implies at the moment it is sent. It does not cover an object lost +between sends: a consumer somebody deleted, or a bus whose data directory was replaced. D6 (a module's +consumer) and D3 (a holder without its worker) find these. Until the next send or a controller +restart, nothing makes them again. H3 in to-be 45 is the healer for D3's half ("raise the seat's +objects again"). Its repair is now exactly the assertion a send makes, so it can be the same call for +D6's missing consumer as well: one healer for "an object the mesh defines is not on the bus", braked +per object, rather than two. This is noted for Phase 3 and not built here. +