Keep the builds of the grants step's machine alone, not of every machine its composition resolves (repo-check of #230)
mesh/merge-gate pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without …
mesh/repo-check fail: its merge-check.sh failed: --- FAIL: TestTheGrantsStepSendsTheUserListAndNothingElse (2.14s)
mesh/delivery superseded: a newer head of the same pull request

Composing the bus's machine resolves the others on the same context, and
a machine never recorded as sent refused the whole composition.
This commit is contained in:
2026-10-11 19:30:10 +02:00
parent 0f853e93fa
commit 325575b292
5 changed files with 35 additions and 18 deletions
+18 -13
View File
@@ -63,19 +63,24 @@ func keptExcept(ctx context.Context) (map[string]bool, bool) {
type keepEveryBuildKey struct{}
// keepingEveryBuild is a context whose sends compose every module — recorded or rolling out — at the build
// its machine was last sent (novox/hq issue 490): the grants step, which sends the machine holding the bus
// its new user list and nothing of any module's new code. That code waits there for a gate like any other
// move; the list must not, or the first machine's gate is judged against a bus that refuses what the change
// newly grants.
func keepingEveryBuild(ctx context.Context) context.Context {
return context.WithValue(ctx, keepEveryBuildKey{}, true)
// keepingEveryBuild is a context whose sends compose every module of one machine — recorded or rolling out —
// at the build that machine was last sent (novox/hq issue 490): the grants step, which sends the machine
// holding the bus its new user list and nothing of any module's new code. That code waits there for a gate
// like any other move; the list must not, or the first machine's gate is judged against a bus that refuses
// what the change newly grants.
//
// **That machine alone.** Composing one machine resolves the others too — who is on the private network,
// who answers a requirement — on the same context, and those are no part of the step's send: they are
// composed as any send composes them. Kept for every machine, a machine whose last send is not known
// refused the bus's machine's composition.
func keepingEveryBuild(ctx context.Context, node string) context.Context {
return context.WithValue(ctx, keepEveryBuildKey{}, node)
}
// everyBuildKept is whether this context keeps every module at the build its machine runs.
func everyBuildKept(ctx context.Context) bool {
on, _ := ctx.Value(keepEveryBuildKey{}).(bool)
return on
// everyBuildKept is whether this context keeps every module of this machine at the build it runs.
func everyBuildKept(ctx context.Context, node string) bool {
on, _ := ctx.Value(keepEveryBuildKey{}).(string)
return on != "" && on == node
}
// recordedKept is, for a send under keepingRecorded, every recorded module the machine was last sent a
@@ -87,7 +92,7 @@ func everyBuildKept(ctx context.Context) bool {
// 490), and a machine whose last send is not known refuses the send: there is nothing to keep it at, and
// composing the mesh's builds would be the very move the grants step must not make.
func recordedKept(ctx context.Context, open *stores, node string) (map[string]string, error) {
every := everyBuildKept(ctx)
every := everyBuildKept(ctx, node)
skip, on := keptExcept(ctx)
if !on && !every {
return nil, nil
@@ -150,7 +155,7 @@ func keepRecorded(ctx context.Context, open *stores, node string, shelf map[stri
if err != nil {
return nil, err
}
if !found && everyBuildKept(ctx) {
if !found && everyBuildKept(ctx, node) {
return nil, fmt.Errorf("%s runs %s's build %s, which the build records no longer hold: the bus's user "+
"list cannot be sent there alone with it kept (novox/hq issue 490)", node, m, short(kept[m]))
}