A-316: the assigner's candidate gains added, the version and parts the want it would write carries
The state candidates' value (CandidatesByProposalNodeValue) gains `added`, by module name, each an AddedModule with `version` and `parts` in the want's own forms. It is a copy of the two properties of the seat mesh-wants' state wants, because the seat-definition format cannot reuse another repository's seat's forms (includes take only parts/ of the same repository, and a part holds no state value); a fixture holds both to the want's wire. Regenerated with seatgen. The node names the first round-2 pass left in fixtures lines equal to base lines are role names now, the generated tests with them. Builds: design 47 G A-316 (corrected, hq #594), §626 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -344,6 +344,14 @@ func DecodeSeatHoldersBySeatNodeValue(raw []byte) (SeatHoldersBySeatNodeValue, e
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// AddedModule is what the want a candidate would write for a module carries of its build, in the want's own forms (the seat mesh-wants' state wants: `version` and `parts`; copied here because a seat definition cannot reuse another repository's seat's forms, design 47 G A-316).
|
||||
type AddedModule struct {
|
||||
// the digest of each of the module's parts, by `<module>:<artifact>` (design 47 G section 379)
|
||||
Parts map[string]string `json:"parts,omitempty"`
|
||||
// the module's released version, for people; none for a build of another watched branch (design 47 G section 379)
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// Assignments is one node's assignments assembled.
|
||||
type Assignments struct {
|
||||
Decided NodeDecided `json:"decided"`
|
||||
@@ -687,6 +695,8 @@ type ProposalsByProposalValue = Proposal
|
||||
|
||||
// CandidatesByProposalNodeValue is one value of the state candidates under the key <proposal>.<node>.
|
||||
type CandidatesByProposalNodeValue struct {
|
||||
// by module name, each module the candidate adds to this node without a want there: the `version` and `parts` the want it would write carries (design 47 G A-316); the node-engine builds such a module from this entry
|
||||
Added map[string]AddedModule `json:"added,omitempty"`
|
||||
// the node's assignments with the proposal laid over it; absent when the proposal takes its key away
|
||||
Assignments *Assignments `json:"assignments,omitempty"`
|
||||
Proposal string `json:"proposal"`
|
||||
|
||||
@@ -59,7 +59,7 @@ func TestFixtures(t *testing.T) {
|
||||
err := json.Unmarshal(b, &v)
|
||||
return v, err
|
||||
}, subjectIs: nil},
|
||||
{name: "a candidate", subject: "", given: "{\"proposal\":\"p-20261105t120000-aabbccdd\",\"v\":1}", wire: "{\"proposal\":\"p-20261105t120000-aabbccdd\",\"v\":1}",
|
||||
{name: "a candidate, with the modules it adds and what their wants would carry", subject: "", given: "{\"added\":{\"mesh-build-go\":{\"parts\":{\"mesh-build-go:go-binary\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"version\":\"1.4.0\"}},\"proposal\":\"p-20261105t120000-aabbccdd\",\"v\":1}", wire: "{\"added\":{\"mesh-build-go\":{\"parts\":{\"mesh-build-go:go-binary\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"version\":\"1.4.0\"}},\"proposal\":\"p-20261105t120000-aabbccdd\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) {
|
||||
var v CandidatesByProposalNodeValue
|
||||
err := json.Unmarshal(b, &v)
|
||||
|
||||
@@ -85,7 +85,7 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "the bus module's have carries the user list written (typed from the engine's values)", subject: "", given: "{\"health\":\"ok\",\"phase\":\"running\",\"user-list\":{\"at\":\"2026-11-05T12:00:00Z\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"follows\":\"grants\",\"handed\":{\"at\":\"2026-11-05T12:00:00Z\",\"box\":{\"ct\":\"c\",\"eph\":\"e\",\"iv\":\"i\",\"tag\":\"t\",\"v\":1},\"from\":\"ace\",\"to\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"users\":3},\"key\":\"-----BEGIN PUBLIC KEY-----\",\"revision\":7,\"source\":\"user-list\",\"users\":3,\"wanted\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"v\":1}", wire: "{\"health\":\"ok\",\"phase\":\"running\",\"user-list\":{\"at\":\"2026-11-05T12:00:00Z\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"follows\":\"grants\",\"handed\":{\"at\":\"2026-11-05T12:00:00Z\",\"box\":{\"ct\":\"c\",\"eph\":\"e\",\"iv\":\"i\",\"tag\":\"t\",\"v\":1},\"from\":\"ace\",\"to\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"users\":3},\"key\":\"-----BEGIN PUBLIC KEY-----\",\"revision\":7,\"source\":\"user-list\",\"users\":3,\"wanted\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"},\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a node's own facts with its record and an answer to a candidate (typed from the engine's values)", subject: "", given: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"home-server\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}", wire: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"home-server\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}",
|
||||
{name: "a node's own facts with its record and an answer to a candidate (typed from the engine's values)", subject: "", given: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}", wire: "{\"candidates\":{\"p1\":{\"added\":[{\"module\":\"db\",\"unissued\":[\"db.secret\"]}],\"differs\":[{\"bodies\":[{\"id\":\"api.cfg\",\"paths\":[\"/etc/api.conf\"],\"why\":\"content\"}],\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"api\",\"running\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"why\":\"a file differs\"}],\"proposal\":\"p1\",\"refusals\":[{\"module\":\"mail\",\"today\":\"runs\",\"why\":\"a value is missing\"}],\"removed\":[\"old\"],\"revision\":4,\"same\":[\"web\"],\"verdict\":\"differs\"}},\"composed\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"composes\":\"own\",\"record\":{\"capabilities\":[\"approval-mark/1\",\"docker\"],\"contract\":3,\"networks\":[{\"link\":\"eth0\",\"network\":\"192.0.2.0/24\"}],\"networks-said\":true,\"node\":\"ace\",\"runner-capabilities\":[\"approval-mark/1\"],\"runner-fingerprint\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"tunnel-key\":\"k\",\"v\":1},\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v HaveByNodeNodeValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a module's data items on a node (typed from the engine's values)", subject: "", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"items\":[{\"class\":\"database\",\"covered_by\":\"/var/lib/postgres\",\"item\":\"cluster\",\"measure\":\"dataset\",\"module\":\"postgres\",\"path\":\"/var/lib/postgres\",\"protection\":\"backup\"}],\"module\":\"postgres\",\"node\":\"ace\",\"v\":1}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"items\":[{\"class\":\"database\",\"covered_by\":\"/var/lib/postgres\",\"item\":\"cluster\",\"measure\":\"dataset\",\"module\":\"postgres\",\"path\":\"/var/lib/postgres\",\"protection\":\"backup\"}],\"module\":\"postgres\",\"node\":\"ace\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v DataByNodeModuleValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v ConditionRaisedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-conditions\\.event\\.condition-raised$")},
|
||||
{name: "a condition's owner handed to the operator after two hours (design 47 G 540, A-58)", subject: "mesh.seat.mesh-conditions.event.condition-changed", given: "{\"at\":\"2026-11-11T12:00:00Z\",\"change\":\"owner\",\"event\":\"condition-changed\",\"key\":\"module.mesh-delivery.home-server.pipeline-failed\",\"kind\":\"pipeline-failed\",\"owner\":\"operator-channel\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"runner\",\"subject\":{\"id\":\"mesh-delivery.home-server\",\"machine\":\"home-server\",\"scope\":\"module\"},\"summary\":\"a head failed its pipeline\",\"waiting-on\":\"operator-channel\",\"was\":\"forge:operator\"}", wire: "{\"at\":\"2026-11-11T12:00:00Z\",\"change\":\"owner\",\"event\":\"condition-changed\",\"key\":\"module.mesh-delivery.home-server.pipeline-failed\",\"kind\":\"pipeline-failed\",\"owner\":\"operator-channel\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"runner\",\"subject\":{\"id\":\"mesh-delivery.home-server\",\"machine\":\"home-server\",\"scope\":\"module\"},\"summary\":\"a head failed its pipeline\",\"waiting-on\":\"operator-channel\",\"was\":\"forge:operator\"}",
|
||||
decode: func(b []byte) (any, error) { var v ConditionChangedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-conditions\\.event\\.condition-changed$")},
|
||||
{name: "a condition raised from a finding, as the keeper holds it (captured; empty fields left out)", subject: "", given: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on ace uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `ace/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"key\":\"module.mesh-build-node.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"last-observed\":\"2026-10-26T20:19:41.474823121Z\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.076843727Z\",\"resolved\":\"mesh-build-node's directory on ace is the mesh's\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on ace uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `ace/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}", wire: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on ace uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `ace/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"key\":\"module.mesh-build-node.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"last-observed\":\"2026-10-26T20:19:41.474823121Z\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.076843727Z\",\"resolved\":\"mesh-build-node's directory on ace is the mesh's\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on ace uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `ace/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}",
|
||||
{name: "a condition raised from a finding, as the keeper holds it (captured; empty fields left out)", subject: "", given: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"key\":\"module.mesh-build-node.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"last-observed\":\"2026-10-26T20:19:41.474823121Z\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.076843727Z\",\"resolved\":\"mesh-build-node's directory on ace is the mesh's\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}", wire: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"key\":\"module.mesh-build-node.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"last-observed\":\"2026-10-26T20:19:41.474823121Z\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.076843727Z\",\"resolved\":\"mesh-build-node's directory on ace is the mesh's\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh\"}",
|
||||
decode: func(b []byte) (any, error) { var v ConditionsByKeyValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a condition with an empty evidence trail of headline (captured; empty fields left out)", subject: "", given: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-30T13:03:46.432309782Z\",\"said\":\"The backup of postgres failed on ace\"}],\"explanation\":\"Needs you: answer whether to back up again or go on without a backup. The backup before applying postgres at 978b5db8cb4e on ace failed: node-backup.now could not be asked: not asked: nothing on this machine answers mesh.seat.node-backup.tool.now.ace.\",\"headline\":\"The backup of postgres failed on ace\",\"key\":\"module.ace.postgres.978b5db8cb4ef746ce68d82cc616d1439a53266d335e60f368dc44c4cb25610f.backup\",\"kind\":\"backup\",\"last-observed\":\"2026-10-30T13:03:46.432309782Z\",\"needs\":\"answer whether to back up again or go on without a backup\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.069818178Z\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"assigner.backup\",\"subject\":{\"id\":\"ace.postgres.978b5db8cb4ef746ce68d82cc616d1439a53266d335e60f368dc44c4cb25610f\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"The backup of postgres failed on ace\"}", wire: "{\"count\":1,\"evidence\":[{\"at\":\"2026-10-30T13:03:46.432309782Z\",\"said\":\"The backup of postgres failed on ace\"}],\"explanation\":\"Needs you: answer whether to back up again or go on without a backup. The backup before applying postgres at 978b5db8cb4e on ace failed: node-backup.now could not be asked: not asked: nothing on this machine answers mesh.seat.node-backup.tool.now.ace.\",\"headline\":\"The backup of postgres failed on ace\",\"key\":\"module.ace.postgres.978b5db8cb4ef746ce68d82cc616d1439a53266d335e60f368dc44c4cb25610f.backup\",\"kind\":\"backup\",\"last-observed\":\"2026-10-30T13:03:46.432309782Z\",\"needs\":\"answer whether to back up again or go on without a backup\",\"observations\":1,\"raised\":\"2026-10-31T08:19:57.069818178Z\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"assigner.backup\",\"subject\":{\"id\":\"ace.postgres.978b5db8cb4ef746ce68d82cc616d1439a53266d335e60f368dc44c4cb25610f\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"The backup of postgres failed on ace\"}",
|
||||
decode: func(b []byte) (any, error) { var v ConditionsByKeyValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
@@ -39,7 +39,7 @@ func TestFixtures(t *testing.T) {
|
||||
err := json.Unmarshal(b, &v)
|
||||
return v, err
|
||||
}, subjectIs: nil},
|
||||
{name: "a finding of the module scope with its machine (in the finding layout (design 47 G 660))", subject: "", given: "{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: owned by 10005:10005, mode 700, as found\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator.\",\"headline\":\"mesh-build-node waits for a directory on home-server\",\"id\":\"mesh-build-node.home-server\",\"kind\":\"directory-used-as-found\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"module\",\"severity\":\"warning\",\"since\":\"2026-10-26T20:19:41.474823121Z\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.home-server\",\"machine\":\"home-server\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on home-server uses mesh-build-node.cache as found\"}", wire: "{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on home-server uses mesh-build-node.cache as found: owned by 10005:10005, mode 700, as found\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator.\",\"headline\":\"mesh-build-node waits for a directory on home-server\",\"id\":\"mesh-build-node.home-server\",\"kind\":\"directory-used-as-found\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"module\",\"severity\":\"warning\",\"since\":\"2026-10-26T20:19:41.474823121Z\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.home-server\",\"machine\":\"home-server\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on home-server uses mesh-build-node.cache as found\"}",
|
||||
{name: "a finding of the module scope with its machine (in the finding layout (design 47 G 660))", subject: "", given: "{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on ace uses mesh-build-node.cache as found: owned by 10005:10005, mode 700, as found\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"id\":\"mesh-build-node.home-server\",\"kind\":\"directory-used-as-found\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"module\",\"severity\":\"warning\",\"since\":\"2026-10-26T20:19:41.474823121Z\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on ace uses mesh-build-node.cache as found\"}", wire: "{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"evidence\":[{\"at\":\"2026-10-26T20:19:41.474823121Z\",\"said\":\"mesh-build-node on ace uses mesh-build-node.cache as found: owned by 10005:10005, mode 700, as found\"}],\"explanation\":\"Needs you: hand the directory over from the control-node, as the operator.\",\"headline\":\"mesh-build-node waits for a directory on ace\",\"id\":\"mesh-build-node.home-server\",\"kind\":\"directory-used-as-found\",\"needs\":\"hand the directory over from the control-node, as the operator; the details name it and the line to type.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"module\",\"severity\":\"warning\",\"since\":\"2026-10-26T20:19:41.474823121Z\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-build-node.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"mesh-build-node on ace uses mesh-build-node.cache as found\"}",
|
||||
decode: func(b []byte) (any, error) {
|
||||
var v FindingsByScopeIDKindValue
|
||||
err := json.Unmarshal(b, &v)
|
||||
|
||||
@@ -71,21 +71,21 @@
|
||||
"said": "mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh"
|
||||
}
|
||||
],
|
||||
"explanation": "Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.",
|
||||
"headline": "mesh-build-node waits for a directory on ace",
|
||||
"key": "module.mesh-build-node.ace.directory-used-as-found",
|
||||
"explanation": "Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on home-server, with another owner or mode than mesh-build-node declares.",
|
||||
"headline": "mesh-build-node waits for a directory on home-server",
|
||||
"key": "module.mesh-build-node.home-server.directory-used-as-found",
|
||||
"kind": "directory-used-as-found",
|
||||
"last-observed": "2026-10-26T20:19:41.474823121Z",
|
||||
"needs": "hand the directory over from the control-node, as the operator; the details name it and the line to type.",
|
||||
"observations": 1,
|
||||
"raised": "2026-10-31T08:19:57.076843727Z",
|
||||
"resolved": "mesh-build-node's directory on ace is the mesh's",
|
||||
"resolved": "mesh-build-node's directory on home-server is the mesh's",
|
||||
"resolver": "self",
|
||||
"severity": "warning",
|
||||
"source": "health-report",
|
||||
"subject": {
|
||||
"id": "mesh-build-node.ace",
|
||||
"machine": "ace",
|
||||
"id": "mesh-build-node.home-server",
|
||||
"machine": "home-server",
|
||||
"scope": "module"
|
||||
},
|
||||
"summary": "mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh",
|
||||
@@ -104,21 +104,21 @@
|
||||
"said": "mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh"
|
||||
}
|
||||
],
|
||||
"explanation": "Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on ace, with another owner or mode than mesh-build-node declares.",
|
||||
"headline": "mesh-build-node waits for a directory on ace",
|
||||
"key": "module.mesh-build-node.ace.directory-used-as-found",
|
||||
"explanation": "Needs you: hand the directory over from the control-node, as the operator; the details name it and the line to type. A directory of mesh-build-node was already on home-server, with another owner or mode than mesh-build-node declares.",
|
||||
"headline": "mesh-build-node waits for a directory on home-server",
|
||||
"key": "module.mesh-build-node.home-server.directory-used-as-found",
|
||||
"kind": "directory-used-as-found",
|
||||
"last-observed": "2026-10-26T20:19:41.474823121Z",
|
||||
"needs": "hand the directory over from the control-node, as the operator; the details name it and the line to type.",
|
||||
"observations": 1,
|
||||
"raised": "2026-10-31T08:19:57.076843727Z",
|
||||
"resolved": "mesh-build-node's directory on ace is the mesh's",
|
||||
"resolved": "mesh-build-node's directory on home-server is the mesh's",
|
||||
"resolver": "self",
|
||||
"severity": "warning",
|
||||
"source": "health-report",
|
||||
"subject": {
|
||||
"id": "mesh-build-node.ace",
|
||||
"machine": "ace",
|
||||
"id": "mesh-build-node.home-server",
|
||||
"machine": "home-server",
|
||||
"scope": "module"
|
||||
},
|
||||
"summary": "mesh-build-node on home-server uses mesh-build-node.cache as found: used as found: owned by 10005:10005, mode 700, as found; mesh-build-node, mode 0711 was declared and not given it — `home-server/node-engine.hand-over` with the directory's path, then your yes on your channel, with its path, hands it to the mesh",
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestATokenLifeAndTheRedeemProofAreAsTheHolderMakesThem(t *testing.T) {
|
||||
// TestTheRedeemAnswerIsTheContractsWire: the client's answer reads into the contract's type with no field dropped, and
|
||||
// the contract's reads back as the client's wire.
|
||||
t.Run("TheRedeemAnswerIsTheContractsWire", func(t *testing.T) {
|
||||
mine := RedeemAnswer{Node: "g14", Login: "g14-login", Account: "YQ==", Certificate: "pem", Signer: "dg==", Signature: "cw=="}
|
||||
mine := RedeemAnswer{Node: "laptop", Login: "g14-login", Account: "YQ==", Certificate: "pem", Signer: "dg==", Signature: "cw=="}
|
||||
wire, _ := json.Marshal(mine)
|
||||
var theirs seat.RedeemAnswer
|
||||
d := json.NewDecoder(bytes.NewReader(wire))
|
||||
@@ -43,7 +43,7 @@ func TestATokenLifeAndTheRedeemProofAreAsTheHolderMakesThem(t *testing.T) {
|
||||
if err := d.Decode(&theirs); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if theirs.Node != "g14" || theirs.Signer != "dg==" || theirs.Signature != "cw==" {
|
||||
if theirs.Node != "laptop" || theirs.Signer != "dg==" || theirs.Signature != "cw==" {
|
||||
t.Errorf("the contract reads %+v", theirs)
|
||||
}
|
||||
back, _ := json.Marshal(theirs)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"of": "state:assignments/<node>.<module>",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"placed": {
|
||||
"module": "plex",
|
||||
"branch": "beta",
|
||||
@@ -106,24 +106,32 @@
|
||||
"changes": [
|
||||
{
|
||||
"op": "place",
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"branch": "beta",
|
||||
"build": "src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
}
|
||||
],
|
||||
"base": {
|
||||
"ace": 3
|
||||
"home-server": 3
|
||||
},
|
||||
"state": "answering"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "a candidate",
|
||||
"name": "a candidate, with the modules it adds and what their wants would carry",
|
||||
"of": "state:candidates/<proposal>.<node>",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"proposal": "p-20261105t120000-aabbccdd"
|
||||
"proposal": "p-20261105t120000-aabbccdd",
|
||||
"added": {
|
||||
"mesh-build-go": {
|
||||
"version": "1.4.0",
|
||||
"parts": {
|
||||
"mesh-build-go:go-binary": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -350,6 +350,13 @@
|
||||
"assignments": {
|
||||
"$ref": "#/defs/Assignments",
|
||||
"description": "the node's assignments with the proposal laid over it; absent when the proposal takes its key away"
|
||||
},
|
||||
"added": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/defs/AddedModule"
|
||||
},
|
||||
"description": "by module name, each module the candidate adds to this node without a want there: the `version` and `parts` the want it would write carries (design 47 G A-316); the node-engine builds such a module from this entry"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -1061,6 +1068,23 @@
|
||||
"branch",
|
||||
"nodes"
|
||||
]
|
||||
},
|
||||
"AddedModule": {
|
||||
"type": "object",
|
||||
"description": "what the want a candidate would write for a module carries of its build, in the want's own forms (the seat mesh-wants' state wants: `version` and `parts`; copied here because a seat definition cannot reuse another repository's seat's forms, design 47 G A-316)",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "the module's released version, for people; none for a build of another watched branch (design 47 G section 379)"
|
||||
},
|
||||
"parts": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "the digest of each of the module's parts, by `<module>:<artifact>` (design 47 G section 379)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"subject": "mesh.seat.node-engine.event.composed.home-server",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"fingerprint": "src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"digest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
@@ -85,7 +85,7 @@
|
||||
"subject": "mesh.seat.node-engine.event.running.home-server.nats",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"fingerprint": "src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"manifest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
@@ -98,7 +98,7 @@
|
||||
"subject": "mesh.seat.node-engine.event.running.home-server.nats",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"fingerprint": "src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"manifest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
@@ -112,7 +112,7 @@
|
||||
"subject": "mesh.seat.node-engine.event.running.home-server.nats",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"fingerprint": "src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"manifest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
@@ -126,7 +126,7 @@
|
||||
"subject": "mesh.seat.node-engine.event.running.home-server.nats",
|
||||
"given": {
|
||||
"v": 1,
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"module": "nats",
|
||||
"stopped": true,
|
||||
"at": "2026-11-11T09:00:00Z"
|
||||
@@ -139,7 +139,7 @@
|
||||
"given": {
|
||||
"owner": "node-engine",
|
||||
"step": "kept-build",
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"on": "the kept build of postgres",
|
||||
"bound": "60m",
|
||||
"since": "2026-11-11T10:00:00Z",
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
"name": "process-builds answers each process's build",
|
||||
"of": "verb:process-builds.answer",
|
||||
"given": {
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"processes": [
|
||||
{
|
||||
"module": "nats",
|
||||
@@ -152,7 +152,7 @@
|
||||
"name": "process-builds answers an error",
|
||||
"of": "verb:process-builds.answer",
|
||||
"given": {
|
||||
"node": "ace",
|
||||
"node": "home-server",
|
||||
"processes": [],
|
||||
"error": "the service manager did not answer"
|
||||
}
|
||||
|
||||
+10
@@ -86,6 +86,14 @@ export declare function seatHoldersBySeatNodeKey(seat: string, node: string): st
|
||||
/** The parts of a key of the form "<seat>.<node>", or undefined for a key of another form. */
|
||||
export declare function parseSeatHoldersBySeatNodeKey(_key: string): { seat: string; node: string } | undefined;
|
||||
|
||||
/** what the want a candidate would write for a module carries of its build, in the want's own forms (the seat mesh-wants' state wants: `version` and `parts`; copied here because a seat definition cannot reuse another repository's seat's forms, design 47 G A-316) */
|
||||
export interface AddedModule {
|
||||
/** the digest of each of the module's parts, by `<module>:<artifact>` (design 47 G section 379) */
|
||||
"parts"?: Record<string, string>;
|
||||
/** the module's released version, for people; none for a build of another watched branch (design 47 G section 379) */
|
||||
"version"?: string;
|
||||
}
|
||||
|
||||
/** one node's assignments assembled */
|
||||
export interface Assignments {
|
||||
"decided": NodeDecided;
|
||||
@@ -415,6 +423,8 @@ export type ProposalsByProposalValue = Proposal;
|
||||
|
||||
/** is one value of the state candidates under the key <proposal>.<node>. */
|
||||
export interface CandidatesByProposalNodeValue {
|
||||
/** by module name, each module the candidate adds to this node without a want there: the `version` and `parts` the want it would write carries (design 47 G A-316); the node-engine builds such a module from this entry */
|
||||
"added"?: Record<string, AddedModule>;
|
||||
/** the node's assignments with the proposal laid over it; absent when the proposal takes its key away */
|
||||
"assignments"?: Assignments;
|
||||
"proposal": string;
|
||||
|
||||
Reference in New Issue
Block a user