Page an answer larger than one message of the bus, and keep overviews brief (hq issue 314)
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/314-a-large-answer-is-paged-not-lost delivered: every member is delivered

The client library refuses to send a reply over the bus's max_payload, and the
controller only logged it: conditions and status answered nobody for hours on
2026-10-08 while calls said each was answered in 130 ms, and the operator's
channel read nothing. An answer too large is now held under its call and paged
to the caller that asks, on the same subject; a caller that does not page is
told in words, and calls says it. The overviews no longer carry every finding:
conditions and status list each condition with its newest evidence, doctor at
most twenty findings a probe (probe= gives one whole), and the JSON overviews
are sent once, as data, instead of twice.
This commit is contained in:
jochen
2026-10-08 12:19:16 +02:00
parent 4d337ff897
commit 175b28ee42
12 changed files with 793 additions and 27 deletions
+15 -2
View File
@@ -641,6 +641,9 @@ func (a *verbArguments) commandLine() ([]string, error) {
if which > 1 {
return nil, errors.New("doctor answers one of run, probes or signals at a time")
}
if p := str("probe"); p != "" {
argv = append(argv, "--probe", p)
}
return append(argv, "--json"), nil
case "rotate":
if p := str("provision"); p != "" {
@@ -771,6 +774,11 @@ var jsonVerbs = map[string]bool{"status": true, "seats": true, "plan": true, "co
// The delivery's owner's verbs answer JSON where they read (plan, order, check, walks) — novox/hq ADR 0239.
"delivery": true}
// overviewVerbs are the JSON verbs whose answer is said once, as data, and not again as the text the
// command printed: the overviews, which grow with the mesh (novox/hq issue 314). Every reader of theirs
// reads `answer` first.
var overviewVerbs = map[string]bool{"status": true, "conditions": true, "doctor": true}
// repairingCommand names a command line that repairs by hand, and so says why: a push, a plan stopped
// or closed, a consumer re-made (novox/hq to-be 45 §7). Empty for any other.
func repairingCommand(argv []string) string {
@@ -834,6 +842,11 @@ func runVerb(ctx context.Context, argv []string) (verbAnswer, error) {
var parsed any
if json.Unmarshal(bytes.TrimSpace(stdout.Bytes()), &parsed) == nil {
answer.Answer = parsed
if overviewVerbs[argv[0]] {
// Once, as data: the same document again as text doubled an answer that already
// outgrew one message of the bus (novox/hq issue 314).
answer.Output = stderr.String() + "its answer, as data, is `answer`\n"
}
}
}
var exit *exec.ExitError
@@ -887,10 +900,10 @@ func seatToolHandlers() (map[string]link.ToolHandler, []string, error) {
return nil, err
}
sub := ""
if len(argv) > 2 {
if len(argv) > 2 && !strings.HasPrefix(argv[1], "-") {
sub = argv[1]
}
return doctorAnswer(ctx, sub)
return doctorAnswer(ctx, sub, a.given["probe"])
}
return seatTools(), nil
}