B2h AS17 (1): a want carries the operator's answer live to a held revert

The seat mesh-wants' want gains `revert`, enum live, beside `backup`; the
wants codec refuses any other answer. The assigner's state form changes, so
its manifest's version moves to 0.2 once (A-245).

Builds: design 47 G §710, §300; A-245

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 09:19:54 +01:00
parent 9e02d6234b
commit c4ba9eb23e
6 changed files with 26 additions and 1 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"module": "mesh-delivery-assigner",
"version": "0.1",
"version": "0.2",
"slug": "assigner",
"runs-as": "mesh-delivery-assigner",
"claims": [
@@ -51,6 +51,10 @@ const (
BackupSkip = seat.WantsByWantNodeModuleValueBackupSkip
)
// RevertLive is the operator's answer to a held revert: the node starts the reverted build on the live data as it is, with
// nothing restored (design 47 G §710).
const RevertLive = seat.WantsByWantNodeModuleValueRevertLive
// NodeWord is the last part of a node's own key.
const NodeWord = "node"
@@ -217,6 +221,9 @@ func checkWant(w Want) error {
default:
return fmt.Errorf("wants: the backup answer %q is not %s or %s", w.Backup, BackupAgain, BackupSkip)
}
if w.Revert != "" && w.Revert != RevertLive {
return fmt.Errorf("wants: the revert answer %q is not %s", w.Revert, RevertLive)
}
if w.Newest == "" && w.Rule == 0 {
return nil
}
@@ -40,6 +40,7 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
"composed": {Want{Fp: a, Composed: c, Words: "w"}, `{"v":1,"fp":"` + a + `","composed":"` + c + `","words":"w"}`},
"held back": {Want{Fp: a, Self: true, Newest: b, Rule: RuleGrant, Backup: BackupAgain, Words: "held"}, `{"v":1,"fp":"` + a + `","newest":"` + b + `","rule":6,"backup":"again","words":"held","self":true}`},
"put": {Want{Fp: a, Self: true, Put: true, Hold: true, Yes: d, Release: "r1"}, `{"v":1,"fp":"` + a + `","put":true,"hold":true,"yes":"` + d + `","release":"r1","self":true}`},
"revert": {Want{Fp: a, Self: true, Revert: RevertLive, Words: "live"}, `{"v":1,"fp":"` + a + `","revert":"live","words":"live","self":true}`},
"removed": {Want{Removed: true, Words: "gone"}, `{"v":1,"removed":true,"words":"gone"}`},
"released": {Want{Fp: a, Composed: c, Version: "0.1.15", Parts: map[string]string{"mesh-sdk:go": d}}, `{"v":1,"fp":"` + a + `","composed":"` + c + `","version":"0.1.15","parts":{"mesh-sdk:go":"` + d + `"}}`},
"kept": {Want{Fp: a, Composed: c, Parts: map[string]string{"x:image": d}, KeptOn: "n1"}, `{"v":1,"fp":"` + a + `","composed":"` + c + `","parts":{"x:image":"` + d + `"},"kept-on":"n1"}`},
@@ -67,6 +68,7 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
"removed names a rule": {Removed: true, Rule: 1},
"release without yes": {Fp: a, Self: true, Release: "r"},
"backup answer unknown": {Fp: a, Self: true, Backup: "later"},
"revert answer unknown": {Fp: a, Self: true, Revert: "hold"},
"newest equals fp": {Fp: a, Self: true, Newest: a, Rule: RuleStep},
"rule 11": {Fp: a, Self: true, Newest: b, Rule: 11},
"newest without a rule": {Fp: a, Self: true, Newest: b},
@@ -921,6 +921,8 @@ type WantsByWantNodeModuleValue struct {
Put bool `json:"put,omitempty"`
Release string `json:"release,omitempty"`
Removed bool `json:"removed,omitempty"`
// live: the operator's answer to a held revert, to start the reverted build on the live data as it is, with nothing restored (design 47 G section 710)
Revert string `json:"revert,omitempty"`
// the rule that holds the node back, 1 to 10
Rule int64 `json:"rule,omitempty"`
Self bool `json:"self,omitempty"`
@@ -937,6 +939,11 @@ const (
WantsByWantNodeModuleValueBackupSkip = "skip"
)
// The values of WantsByWantNodeModuleValue's revert.
const (
WantsByWantNodeModuleValueRevertLive = "live"
)
// WantsByWantNodeNodeValue is one value of the state wants under the key want.<node>.node.
type WantsByWantNodeNodeValue struct {
Composed string `json:"composed"`
@@ -515,6 +515,13 @@
"skip"
]
},
"revert": {
"type": "string",
"description": "live: the operator's answer to a held revert, to start the reverted build on the live data as it is, with nothing restored (design 47 G section 710)",
"enum": [
"live"
]
},
"words": {
"type": "string"
},
@@ -539,6 +539,8 @@ export interface WantsByWantNodeModuleValue {
"put"?: boolean;
"release"?: string;
"removed"?: boolean;
/** live: the operator's answer to a held revert, to start the reverted build on the live data as it is, with nothing restored (design 47 G section 710) */
"revert"?: "live";
/** the rule that holds the node back, 1 to 10 */
"rule"?: number;
"self"?: boolean;