A want that may replace the bus server carries its warrant's mark (ADR 0594 §6)

This commit is contained in:
2026-11-03 08:51:15 +01:00
parent 7c015b652d
commit 5bc8d829ff
2 changed files with 31 additions and 2 deletions
+24 -2
View File
@@ -196,15 +196,37 @@ type Want struct {
// Self says the node composes this module itself (ADR 0547 §2): the want names the build alone, and no composition.
// A want that is not Self names the one composition it allows (ADR 0539 clause 1), as before.
Self bool `json:"self,omitempty"`
// Warrant is the mark of a want that may replace the bus server (novox/hq ADR 0594 §6): WarrantPut on a want a put
// writes on the operator's warrant after the streams' snapshot, WarrantOperator on one the operator's credential
// writes by hand at the terminal. The node agent reads this mark and nothing else to decide whether the bus server
// may be replaced (§2); a want without it never replaces the server. Empty on every other want.
Warrant string `json:"warrant,omitempty"`
}
// The warrants a want may carry (Want.Warrant, novox/hq ADR 0594 §6).
const (
// WarrantPut marks a want the assigner's put wrote on the operator's warrant, after the streams' snapshot.
WarrantPut = "put"
// WarrantOperator marks a want the operator's credential wrote by hand at the terminal.
WarrantOperator = "operator"
)
func (w Want) check() error {
if w.Removed {
if w.FP != "" || w.Composed != "" || w.Newest != "" || w.Rule != 0 || w.Backup != "" || w.Put || w.Hold || w.Self || w.Yes != "" {
return fmt.Errorf("delivery: a removed want names no fingerprint, composition, rule, backup answer or put")
if w.FP != "" || w.Composed != "" || w.Newest != "" || w.Rule != 0 || w.Backup != "" || w.Put || w.Hold || w.Self || w.Yes != "" || w.Warrant != "" {
return fmt.Errorf("delivery: a removed want names no fingerprint, composition, rule, backup answer, put or warrant")
}
return nil
}
switch w.Warrant {
case "", WarrantOperator:
case WarrantPut:
if !w.Put {
return fmt.Errorf("delivery: only a put's want carries the put's warrant")
}
default:
return fmt.Errorf("delivery: the warrant %q is not %s or %s", w.Warrant, WarrantPut, WarrantOperator)
}
if w.Hold && !w.Put {
return fmt.Errorf("delivery: only a put holds a want")
}
+7
View File
@@ -79,6 +79,9 @@ func TestAssignerValuesRoundTrip(t *testing.T) {
{FP: fp2of('a'), Composed: hashOf('1'), Newest: fp2of('b'), Rule: RuleCanary, Words: "the canary ace does not run it healthy yet"},
{Removed: true, Words: "the module left g14"},
{FP: fp2of('a'), Composed: hashOf('1'), Put: true, Hold: true, Words: "put by the operator: the bus's user list"},
// 774/S1: a want that may replace the bus server says its warrant (ADR 0594 §6).
{FP: fp2of('a'), Composed: hashOf('1'), Put: true, Warrant: WarrantPut},
{FP: fp2of('a'), Self: true, Warrant: WarrantOperator},
}
for _, w := range wants {
data, err := EncodeWant(w)
@@ -151,6 +154,10 @@ func TestAssignerValuesRefused(t *testing.T) {
{FP: fp2of('a'), Composed: hashOf('1'), Hold: true},
{FP: fp2of('a'), Composed: hashOf('1'), Put: true, Newest: fp2of('b'), Rule: 3},
{Removed: true, Put: true},
// 774/S1: a removed want carries no warrant, a warrant is put or operator, and put only on a put's want.
{Removed: true, Warrant: WarrantOperator},
{FP: fp2of('a'), Self: true, Warrant: "yes"},
{FP: fp2of('a'), Self: true, Warrant: WarrantPut},
} {
if _, err := EncodeWant(w); err == nil {
t.Errorf("EncodeWant(%+v) accepted", w)