Refuse a send that puts the controller or node-engine behind its machine's build (issue 201)
mesh/merge-gate out of date: judged against trunk f10aedac5880, the trunk is now f8daec01d3f0; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk f10aedac5880, the trunk is now f8daec01d3f0; judged again on a recheck or when it is merged
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate out of date: judged against trunk f10aedac5880, the trunk is now f8daec01d3f0; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk f10aedac5880, the trunk is now f8daec01d3f0; judged again on a recheck or when it is merged
mesh/delivery superseded: a newer head of the same pull request
On 2026-10-02 a plan sent the control node a controller older than the one running there, whose seat row the newer build had widened; the older binary refused the row and the mesh went quiet for ten minutes. ADR 0185 took the outage out of it, and the race stayed open. Every send but a person's push now refuses a move of mesh-controller or mesh-host to a build asked before the one its machine was last sent (the builds' registration order, issue 219), whatever composed it — gated or not. A gate's own put-back is the one exception, for the modules it puts back, and says so in its send's scope. The refusal is the send's error, which the plan keeps as its note, and a warning condition on the machine, cleared by the next send there that carries no such move.
This commit is contained in:
@@ -51,6 +51,9 @@ type sendScope struct {
|
||||
modules map[string]bool
|
||||
// person is a person's act: it carries what it carries.
|
||||
person bool
|
||||
// puttingBack is a gate's own put-back of its modules: the one send that may carry a core module to a build
|
||||
// older than the one its machine runs (novox/hq issue 201).
|
||||
puttingBack bool
|
||||
}
|
||||
|
||||
type sendScopeKey struct{}
|
||||
@@ -248,9 +251,11 @@ func ungatedIn(ctx context.Context, open *stores, names []string, addedHolder st
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var kept, refused []string
|
||||
var kept, refused, older []string
|
||||
for _, n := range names {
|
||||
moves, err := machineMoves(ctx, open, f, n, false)
|
||||
// Every move, gated or not: a move to a build that passed a gate elsewhere is no gate's concern here, and
|
||||
// may still be a core module's downgrade (novox/hq issue 201).
|
||||
every, err := machineMoves(ctx, open, f, n, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -262,11 +267,33 @@ func ungatedIn(ctx context.Context, open *stores, names []string, addedHolder st
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var waiting []string
|
||||
for _, mv := range moves {
|
||||
var made []inventory.CarriedMove
|
||||
for _, mv := range every {
|
||||
if was, kept := keeps[mv.Module]; kept && sameCommit(was, mv.From) {
|
||||
continue
|
||||
}
|
||||
made = append(made, mv)
|
||||
}
|
||||
// **No send but a gate's own put-back moves the controller or the node-engine to an older build than
|
||||
// the one its machine runs** (novox/hq issue 201).
|
||||
downgrades, err := refuseCoreDowngrades(ctx, open.inventory, scope, n, made)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(downgrades) > 0 {
|
||||
if n == addedHolder {
|
||||
fmt.Printf("%s holds the bus and its user list changed, and it is not sent now: %s\n", n,
|
||||
strings.Join(downgrades, "; "))
|
||||
continue
|
||||
}
|
||||
older = append(older, downgrades...)
|
||||
continue
|
||||
}
|
||||
var waiting []string
|
||||
for _, mv := range made {
|
||||
if f.gated(mv.Module, mv.To) {
|
||||
continue
|
||||
}
|
||||
if !scope.judged[n] && !scope.modules[mv.Module] {
|
||||
waiting = append(waiting, fmt.Sprintf("%s %s → %s", mv.Module, short(mv.From), short(mv.To)))
|
||||
}
|
||||
@@ -281,6 +308,9 @@ func ungatedIn(ctx context.Context, open *stores, names []string, addedHolder st
|
||||
refused = append(refused, fmt.Sprintf("%s (%s)", n, strings.Join(waiting, ", ")))
|
||||
}
|
||||
}
|
||||
if len(older) > 0 {
|
||||
return nil, fmt.Errorf("%w: %s", errCoreDowngrade, strings.Join(older, "; "))
|
||||
}
|
||||
if len(refused) > 0 {
|
||||
return nil, fmt.Errorf("%w: %s — a walk sends them, one machine at a time, each judged (novox/hq ADR "+
|
||||
"0236); `upgrade backlog` lists them", errUngated, strings.Join(refused, "; "))
|
||||
|
||||
Reference in New Issue
Block a user