Add the assigner's eighth rule, every provision the build requires provided, so a want waits on its provisions as ADR 0570 §4 decides (issue 1954 D1)

This commit is contained in:
2026-10-29 22:37:11 +01:00
parent 4a967933b3
commit 56514aa4a2
2 changed files with 12 additions and 6 deletions
+5 -2
View File
@@ -141,11 +141,14 @@ const (
RuleProviders = 5 // every provider the module requires runs healthy on that node, or at its canary
RuleGrant = 6 // the module's credential for F exists (grants.<module>.<fp>)
RuleComposed = 7 // the module's composition for that node at F exists (mesh-controller_composed, ADR 0539 §6)
// RuleProvisions: every provision the module requires on that node is provided (novox/hq ADR 0570 §4): a want's
// words name the key and its state that hold it, as "the database of keycloak on novox is asked of postgres".
RuleProvisions = 8
)
func checkRule(rule int, of string) error {
if rule < RuleBuildDone || rule > RuleComposed {
return fmt.Errorf("delivery: %s names the rule %d, which is not one of the seven (1 to 7)", of, rule)
if rule < RuleBuildDone || rule > RuleProvisions {
return fmt.Errorf("delivery: %s names the rule %d, which is not one of the eight (1 to 8)", of, rule)
}
return nil
}
+7 -4
View File
@@ -10,13 +10,16 @@ func hashOf(c byte) string { return "sha256:" + digestOf(c) }
// 1943/AC3: a want naming its fingerprint and the digest of the composition it allows round-trips, and so does one
// carrying the answer to a failed backup, and from ADR 0547's second milestone one naming the build alone or the yes
// a person gave; a digest not of the sha256
// form, a removed want naming a digest, an unknown backup answer and a rule past the seventh are refused.
// form, a removed want naming a digest, an unknown backup answer and a rule past the eighth are refused.
func TestAWantNamesItsComposition(t *testing.T) {
for _, w := range []Want{
{FP: fp2of('a'), Composed: hashOf('1')},
{FP: fp2of('a'), Composed: hashOf('1'), Backup: BackupAgain},
{FP: fp2of('a'), Composed: hashOf('1'), Backup: BackupSkip, Words: "the operator: go on without a backup"},
{FP: fp2of('a'), Composed: hashOf('1'), Newest: fp2of('b'), Rule: RuleComposed, Words: "no composition of b for ace yet"},
// ADR 0570 §4 (issue 1954 D1): held for a provision its new build requires, its words naming the key.
{FP: fp2of('a'), Composed: hashOf('1'), Newest: fp2of('b'), Rule: RuleProvisions,
Words: "the database of keycloak on novox is asked of postgres (novox.keycloak.postgres-database)"},
{Removed: true},
// ADR 0547 §2, §3 (issue 1126): from the second milestone a want names the build alone, and the yes a person gave.
{FP: fp2of('a'), Self: true},
@@ -44,7 +47,7 @@ func TestAWantNamesItsComposition(t *testing.T) {
{Want{Removed: true, Composed: hashOf('1')}, "removed want names no"},
{Want{FP: fp2of('a'), Composed: hashOf('1'), Backup: "later"}, `backup answer "later"`},
{Want{Removed: true, Backup: BackupAgain}, "removed want names no"},
{Want{FP: fp2of('a'), Composed: hashOf('1'), Newest: fp2of('b'), Rule: 8}, "rule 8"},
{Want{FP: fp2of('a'), Composed: hashOf('1'), Newest: fp2of('b'), Rule: 9}, "rule 9"},
}
for _, r := range refusals {
if _, err := EncodeWant(r.w); err == nil || !strings.Contains(err.Error(), r.why) {
@@ -54,8 +57,8 @@ func TestAWantNamesItsComposition(t *testing.T) {
if _, err := DecodeWant([]byte(`{"v":1,"fp":"` + fp2of('a') + `"}`)); err == nil || !strings.Contains(err.Error(), "names no composition") {
t.Errorf("a want of release 5, naming no composition and not the node's own, was read: %v", err)
}
if RuleComposed != 7 {
t.Errorf("RuleComposed = %d, want the seventh rule", RuleComposed)
if RuleComposed != 7 || RuleProvisions != 8 {
t.Errorf("RuleComposed = %d and RuleProvisions = %d, want the seventh and the eighth", RuleComposed, RuleProvisions)
}
}