Judge a have with no composition against the module's slice of the declaration the node last applied: equal is unchanged (issue 1945; ADR 0540 clause 9)

The first want at the switch skips the record hold only where it changes nothing on the node. A slice differing only in
the bus's user list is marked user-list-only, so no yes waits on it at the switch; any other change at the same
fingerprint is judged as any move, against the declaration's digest.
This commit is contained in:
2026-10-24 21:27:07 +02:00
parent d640ef15ec
commit 9372733861
7 changed files with 214 additions and 2 deletions
+40
View File
@@ -44,6 +44,33 @@ func judgeMove(ctx context.Context, at composedPlace, key string, to sdkdelivery
if err != nil {
return out, err
}
// A node whose have names no composition yet (the switch: it runs the declaration it last applied) is judged
// against that module's slice of that declaration (novox/hq ADR 0540 clause 9): equal is unchanged, a want that
// changes nothing on the node; otherwise by ADR 0377 §3's tests, as any move.
if found && have.Composed == "" && have.FP != "" && have.Phase != sdkdelivery.PhaseRemoved && at.lastApplied != nil {
slice, declared, applied, err := at.lastApplied(ctx, to.Module)
if err != nil {
return out, err
}
if applied {
from := sdkdelivery.Composed{Node: at.node, Module: to.Module, FP: have.FP, Data: to.Data, Resources: slice}
if sameResources(from, to) {
out.Judgement, out.Words = sdkdelivery.JudgedUnchanged, "equal to the declaration "+at.node+" last applied"
return out, nil
}
// Against names the declaration, by its digest: the composition the node runs is that declaration's slice.
out.Against = declared
if onlyTheUserList(from, to) {
// Only the bus's user list, as against a composition (ADR 0539 clause 7): no yes waits on it at the switch.
out.Judgement, out.UserListOnly = sdkdelivery.JudgedNeither, true
out.Words = "only the bus's user list changes, against the declaration " + at.node + " last applied"
return out, nil
}
j, words := judged(from, to)
out.Judgement, out.Words = j, words+", against the declaration "+at.node+" last applied"
return out, nil
}
}
if !found || have.Phase == sdkdelivery.PhaseRemoved || (have.Composed == "" && have.FP == "") {
out.Judgement, out.Words = sdkdelivery.JudgedNeither, "the node runs no composition of "+to.Module
return out, nil
@@ -297,3 +324,16 @@ func withinPlaces(p string, places []string) bool {
}
return false
}
// sameResources says two compositions of a module hold the same resources in the same order, each compared canonical.
func sameResources(a, b sdkdelivery.Composed) bool {
if len(a.Resources) != len(b.Resources) {
return false
}
for i := range a.Resources {
if !bytes.Equal(compactComposed(a.Resources[i]), compactComposed(b.Resources[i])) {
return false
}
}
return true
}