diff --git a/health-and-repair/go/seats/meshconditions/contract.go b/health-and-repair/go/seats/meshconditions/contract.go index 5962e98..f07e37f 100644 --- a/health-and-repair/go/seats/meshconditions/contract.go +++ b/health-and-repair/go/seats/meshconditions/contract.go @@ -232,8 +232,10 @@ type ConditionEvent struct { LooksUnread string `json:"looks-unread,omitempty"` Needs string `json:"needs,omitempty"` Observations int64 `json:"observations,omitempty"` - Raised *time.Time `json:"raised,omitempty"` - Resolved string `json:"resolved,omitempty"` + // who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) + Owner string `json:"owner,omitempty"` + Raised *time.Time `json:"raised,omitempty"` + Resolved string `json:"resolved,omitempty"` // self, operator, agent or healer: Resolver string `json:"resolver,omitempty"` Severity string `json:"severity,omitempty"` @@ -246,8 +248,10 @@ type ConditionEvent struct { // one line Summary string `json:"summary,omitempty"` Tried []ConditionEventTriedItem `json:"tried,omitempty"` - Was string `json:"was,omitempty"` - Why string `json:"why,omitempty"` + // what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) + WaitingOn string `json:"waiting-on,omitempty"` + Was string `json:"was,omitempty"` + Why string `json:"why,omitempty"` } // The values of ConditionEvent's change. @@ -469,8 +473,10 @@ type ConditionsByKeyValue struct { LooksUnread string `json:"looks-unread,omitempty"` Needs string `json:"needs,omitempty"` Observations int64 `json:"observations,omitempty"` - Raised time.Time `json:"raised"` - Resolved string `json:"resolved,omitempty"` + // who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) + Owner string `json:"owner,omitempty"` + Raised time.Time `json:"raised"` + Resolved string `json:"resolved,omitempty"` // self, operator, agent or healer: Resolver string `json:"resolver,omitempty"` Severity string `json:"severity"` @@ -481,6 +487,8 @@ type ConditionsByKeyValue struct { // one line Summary string `json:"summary,omitempty"` Tried []ConditionsByKeyValueTriedItem `json:"tried,omitempty"` + // what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) + WaitingOn string `json:"waiting-on,omitempty"` } // The values of ConditionsByKeyValue's severity. diff --git a/health-and-repair/go/seats/meshconditions/contract_test.go b/health-and-repair/go/seats/meshconditions/contract_test.go index 92f71e5..ea0fedb 100644 --- a/health-and-repair/go/seats/meshconditions/contract_test.go +++ b/health-and-repair/go/seats/meshconditions/contract_test.go @@ -21,10 +21,16 @@ func TestFixtures(t *testing.T) { decode: func(b []byte) (any, error) { var v FindingsAskedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-conditions\\.event\\.findings-asked$")}, {name: "the keeper asks every observer", subject: "mesh.seat.mesh-conditions.event.findings-asked", given: "{\"ask\":\"a-20261111t100100\",\"at\":\"2026-11-11T10:01:00Z\",\"by\":\"mesh-conditions\"}", wire: "{\"ask\":\"a-20261111t100100\",\"at\":\"2026-11-11T10:01:00Z\",\"by\":\"mesh-conditions\"}", decode: func(b []byte) (any, error) { var v FindingsAskedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-conditions\\.event\\.findings-asked$")}, + {name: "a condition raised with its owner and what it waits on (design 47 G 685)", subject: "mesh.seat.mesh-conditions.event.condition-raised", given: "{\"at\":\"2026-11-11T10:00:00Z\",\"change\":\"raised\",\"event\":\"condition-raised\",\"key\":\"module.mesh-host.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"owner\":\"forge:jochen\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-host.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"a directory waits for a hand\",\"waiting-on\":\"node-engine\"}", wire: "{\"at\":\"2026-11-11T10:00:00Z\",\"change\":\"raised\",\"event\":\"condition-raised\",\"key\":\"module.mesh-host.ace.directory-used-as-found\",\"kind\":\"directory-used-as-found\",\"owner\":\"forge:jochen\",\"resolver\":\"self\",\"severity\":\"warning\",\"source\":\"health-report\",\"subject\":{\"id\":\"mesh-host.ace\",\"machine\":\"ace\",\"scope\":\"module\"},\"summary\":\"a directory waits for a hand\",\"waiting-on\":\"node-engine\"}", + 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 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\"}", 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}, + {name: "a condition carrying its finding's owner, a session, and what it waits on, a seat (design 47 G 685)", 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,\"owner\":\"jochen@shanks\",\"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\",\"waiting-on\":\"node-engine\"}", 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,\"owner\":\"jochen@shanks\",\"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\",\"waiting-on\":\"node-engine\"}", + decode: func(b []byte) (any, error) { var v ConditionsByKeyValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "a condition owned by a commit's author, handed to operator-channel when the keeper hands it over (design 47 G 685, 540)", 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,\"owner\":\"operator-channel\",\"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\",\"waiting-on\":\"forge:jochen\"}", 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,\"owner\":\"operator-channel\",\"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\",\"waiting-on\":\"forge:jochen\"}", + decode: func(b []byte) (any, error) { var v ConditionsByKeyValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "a finding of the bus scope with its zero time (in the finding layout (design 47 G 660))", subject: "", given: "{\"at\":\"0001-01-01T00:00:00Z\",\"evidence\":[{\"at\":\"0001-01-01T00:00:00Z\",\"said\":\"1 held for EVENTS.controller (counted again every 5m0s while any is held, so one delivered again or dropped ends this within it)\"}],\"id\":\"EVENTS.controller\",\"kind\":\"max-deliveries\",\"needs\":\"deliver them again or drop them, from the mesh MCP server.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"bus\",\"severity\":\"warning\",\"since\":\"0001-01-01T00:00:00Z\",\"source\":\"S9\",\"subject\":{\"id\":\"EVENTS.controller\",\"scope\":\"bus\"},\"summary\":\"the controller's consumer on EVENTS gave up on a message; it is kept in DEAD_LETTERS until delivered again or dropped, with why\"}", wire: "{\"at\":\"0001-01-01T00:00:00Z\",\"evidence\":[{\"at\":\"0001-01-01T00:00:00Z\",\"said\":\"1 held for EVENTS.controller (counted again every 5m0s while any is held, so one delivered again or dropped ends this within it)\"}],\"id\":\"EVENTS.controller\",\"kind\":\"max-deliveries\",\"needs\":\"deliver them again or drop them, from the mesh MCP server.\",\"observer\":\"mesh-delivery-watchman\",\"scope\":\"bus\",\"severity\":\"warning\",\"since\":\"0001-01-01T00:00:00Z\",\"source\":\"S9\",\"subject\":{\"id\":\"EVENTS.controller\",\"scope\":\"bus\"},\"summary\":\"the controller's consumer on EVENTS gave up on a message; it is kept in DEAD_LETTERS until delivered again or dropped, with why\"}", decode: func(b []byte) (any, error) { var v FindingsByScopeIDKindValue diff --git a/health-and-repair/seats/mesh-conditions/fixtures/events.json b/health-and-repair/seats/mesh-conditions/fixtures/events.json index dde417e..eebbd31 100644 --- a/health-and-repair/seats/mesh-conditions/fixtures/events.json +++ b/health-and-repair/seats/mesh-conditions/fixtures/events.json @@ -19,5 +19,28 @@ "at": "2026-11-11T10:01:00Z", "by": "mesh-conditions" } + }, + { + "name": "a condition raised with its owner and what it waits on (design 47 G 685)", + "of": "event:condition-raised", + "subject": "mesh.seat.mesh-conditions.event.condition-raised", + "given": { + "key": "module.mesh-host.ace.directory-used-as-found", + "kind": "directory-used-as-found", + "subject": { + "scope": "module", + "id": "mesh-host.ace", + "machine": "ace" + }, + "severity": "warning", + "summary": "a directory waits for a hand", + "source": "health-report", + "resolver": "self", + "owner": "forge:jochen", + "waiting-on": "node-engine", + "event": "condition-raised", + "at": "2026-11-11T10:00:00Z", + "change": "raised" + } } ] diff --git a/health-and-repair/seats/mesh-conditions/fixtures/states.json b/health-and-repair/seats/mesh-conditions/fixtures/states.json index 6b421c1..1b66c9e 100644 --- a/health-and-repair/seats/mesh-conditions/fixtures/states.json +++ b/health-and-repair/seats/mesh-conditions/fixtures/states.json @@ -60,6 +60,72 @@ "summary": "The backup of postgres failed on ace" } }, + { + "name": "a condition carrying its finding's owner, a session, and what it waits on, a seat (design 47 G 685)", + "of": "state:conditions/", + "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", + "owner": "jochen@shanks", + "waiting-on": "node-engine" + } + }, + { + "name": "a condition owned by a commit's author, handed to operator-channel when the keeper hands it over (design 47 G 685, 540)", + "of": "state:conditions/", + "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", + "owner": "operator-channel", + "waiting-on": "forge:jochen" + } + }, { "name": "a finding of the bus scope with its zero time (in the finding layout (design 47 G 660))", "of": "state:findings/..", diff --git a/health-and-repair/seats/mesh-conditions/seat.json b/health-and-repair/seats/mesh-conditions/seat.json index 14be042..ceec115 100644 --- a/health-and-repair/seats/mesh-conditions/seat.json +++ b/health-and-repair/seats/mesh-conditions/seat.json @@ -229,6 +229,16 @@ "type": "string", "description": "self, operator, agent or healer:" }, + "owner": { + "type": "string", + "pattern": "^([a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*|[a-z][a-z0-9-]*|forge:[A-Za-z0-9._-]+)$", + "description": "who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678)" + }, + "waiting-on": { + "type": "string", + "pattern": "^([a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*|[a-z][a-z0-9-]*|forge:[A-Za-z0-9._-]+)$", + "description": "what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678)" + }, "raised": { "type": "string", "format": "date-time" @@ -538,6 +548,16 @@ "type": "string", "description": "self, operator, agent or healer:" }, + "owner": { + "type": "string", + "pattern": "^([a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*|[a-z][a-z0-9-]*|forge:[A-Za-z0-9._-]+)$", + "description": "who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678)" + }, + "waiting-on": { + "type": "string", + "pattern": "^([a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*|[a-z][a-z0-9-]*|forge:[A-Za-z0-9._-]+)$", + "description": "what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678)" + }, "raised": { "type": "string", "format": "date-time" diff --git a/health-and-repair/ts/seats/meshconditions/index.d.ts b/health-and-repair/ts/seats/meshconditions/index.d.ts index f6e33fa..22c4ea8 100644 --- a/health-and-repair/ts/seats/meshconditions/index.d.ts +++ b/health-and-repair/ts/seats/meshconditions/index.d.ts @@ -104,6 +104,8 @@ export interface ConditionEvent { "looks-unread"?: string; "needs"?: string; "observations"?: number; + /** who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) */ + "owner"?: string; "raised"?: string; "resolved"?: string; /** self, operator, agent or healer: */ @@ -118,6 +120,8 @@ export interface ConditionEvent { /** one line */ "summary"?: string; "tried"?: ConditionEventTriedItem[]; + /** what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) */ + "waiting-on"?: string; "was"?: string; "why"?: string; } @@ -306,6 +310,8 @@ export interface ConditionsByKeyValue { "looks-unread"?: string; "needs"?: string; "observations"?: number; + /** who the condition is about, taken from the finding or handed to operator-channel by the keeper: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) */ + "owner"?: string; "raised": string; "resolved"?: string; /** self, operator, agent or healer: */ @@ -318,6 +324,8 @@ export interface ConditionsByKeyValue { /** one line */ "summary"?: string; "tried"?: ConditionsByKeyValueTriedItem[]; + /** what it waits on, from the finding: a session who@node (^[a-z0-9][a-z0-9._-]*@[a-z0-9][a-z0-9-]*$), a seat's name (^[a-z][a-z0-9-]*$) or a commit's author forge: (^forge:[A-Za-z0-9._-]+$); another is refused (design 47 G 678) */ + "waiting-on"?: string; } /** is one value of the state findings under the key ... */