Offer only acknowledgements as answers, keep a refused verdict, and say a change of words
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group fix/notifications-after-review delivered: every member is delivered

Review found that a desk click proves nothing about who chose, that refused words
could turn "Needs you" into "Nothing for you to do", that sound words were refused,
and that a quiet warning whose words came to need the operator was never said
(hq ADR 0258).
This commit is contained in:
jochen
2026-10-08 14:53:36 +02:00
parent 28712eaea1
commit 76cfbac7a1
9 changed files with 225 additions and 72 deletions
+16 -34
View File
@@ -642,43 +642,28 @@ func waitingNeeds(severity conditions.Severity) string {
return ""
}
// waitingActions are the answers to a walk waiting past its urgent bound: the controller's own verb, since
// the module that should have said go is the one not answering.
func waitingActions(w waitFacts, severity conditions.Severity) []conditions.Action {
if severity != conditions.Urgent {
return nil
}
return []conditions.Action{
{Label: "Start", Verb: "mesh-controller.plans", Arguments: map[string]string{"go": w.id, "why": ""}},
{Label: "Stop", Verb: "mesh-controller.plans", Arguments: map[string]string{"stop": w.id, "why": ""}},
}
}
// moduleNeeds is what the operator can do about a module unhealthy on a machine: log in again where its
// account's groups wait for it (ADR 0252), restart a failed service, or nothing where the mesh restarts it.
func moduleNeeds(node string, rs []inventory.ResourceHealth) (string, []conditions.Action) {
var actions []conditions.Action
// No answer is offered for a restart: a desk click performs only an acknowledgement (ADR 0258).
func moduleNeeds(node string, rs []inventory.ResourceHealth) string {
unit := ""
for _, r := range rs {
if strings.Contains(r.Reason, "relogin needed") {
return fmt.Sprintf("log out of every session on %s and log in again.", node), nil
return reloginNeeds(node)
}
if r.Kind == link.KindUnit && len(actions) < 2 {
scope := "system"
if strings.Contains(r.Reason, "account's own") {
scope = "user"
}
label := "Restart"
if len(actions) > 0 {
label = "Restart " + unitPlainWords(r.Target)
}
actions = append(actions, conditions.Action{Label: label, Verb: "node-service-manager.restart",
Machine: node, Arguments: map[string]string{"unit": r.Target, "scope": scope}})
if r.Kind == link.KindUnit && unit == "" {
unit = unitPlainWords(r.Target)
}
}
if len(actions) > 0 {
return "restart it; if it fails again, the details say why.", actions
if unit != "" {
return fmt.Sprintf("restart its service %s on %s; if it fails again, the details say why.", unit, node)
}
return "", nil
return ""
}
// reloginNeeds is what an account waiting for its groups needs (ADR 0252).
func reloginNeeds(node string) string {
return fmt.Sprintf("log out of every session on %s and log in again.", node)
}
// stalledWords are the plain words of a delivery held past its bound, as mesh-delivery says it.
@@ -695,18 +680,15 @@ func stalledWords(l stalledLine, o conditions.Observation) (headline, explanatio
long = "for " + humanDuration(d)
}
if o.Resolver == conditions.ResolverOperator {
// Words only: releasing or stopping a delivery is not an acknowledgement, so no desk click
// performs it (ADR 0258).
switch held {
case "held":
needs = "release it, or stop it."
actions = []conditions.Action{
{Label: "Release", Verb: "mesh-delivery.release", Arguments: map[string]string{"id": l.ID, "why": ""}},
{Label: "Stop", Verb: "mesh-delivery.stop", Arguments: map[string]string{"id": l.ID, "why": ""}},
}
case "ready", "checked":
needs = "merge its pull request, or close it."
default:
needs = "stop it, or read the details to see what it waits for."
actions = []conditions.Action{{Label: "Stop", Verb: "mesh-delivery.stop", Arguments: map[string]string{"id": l.ID, "why": ""}}}
}
}
return fmt.Sprintf("Delivery of %s %s %s", name, held, long),