Ask mesh-delivery for a recheck's group on a bus connection of its own (issue 867, ADR 0382 §1)
mesh/merge-gate head 3fdbea420440 merged into trunk af60d2719c0c — pass: builds mesh-controller → novox; no bus step; every machine composes with the chang…
mesh/repo-check head 3fdbea420440 merged into trunk af60d2719c0c — pass: its merge-check.sh passed
mesh/delivery delivered

`delivery check` runs as a command of its own, where no serving connection exists, so a recheck said its siblings could not be learned ("this controller is not on the bus") and mesh-host#114 was judged without its sibling. groupsAsked now asks through onTheBus, which lends the serving connection or dials one, as the hand-act log does. TestTheRecheckVerbAsksMeshDeliveryOnABusOfItsOwn drives the verb against a real responder.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-10-16 00:27:57 +00:00
co-authored by Claude
parent af60d2719c
commit 3fdbea4204
3 changed files with 62 additions and 13 deletions
+12 -7
View File
@@ -8,6 +8,8 @@ import (
"strings"
"time"
"github.com/nats-io/nats.go"
"github.com/novox/mesh-controller/internal/catalogue"
"github.com/novox/mesh-controller/internal/inventory"
"github.com/novox/mesh-controller/internal/link"
@@ -60,13 +62,16 @@ var groupsAsked = func(ctx context.Context, held bool) ([]groupsLine, error) {
if !held {
return nil, fmt.Errorf("no holder of %s is on record to say it", catalogue.DeliverySeat)
}
serving := servingBus.Load()
if serving == nil {
return nil, errors.New("this controller is not on the bus")
}
asking, cancel := context.WithTimeout(ctx, groupAskWithin)
defer cancel()
raw, err := askDeliveryOwner(asking, serving.Conn(), "groups", map[string]any{})
// On the bus as this process is: the serving controller's own connection, lent, or — in a verb that runs as a command
// of its own, such as a recheck's `delivery check` — one dialled for the moment (onTheBus).
var raw json.RawMessage
err := onTheBus(func(conn *nats.Conn) error {
asking, cancel := context.WithTimeout(ctx, groupAskWithin)
defer cancel()
var err error
raw, err = askDeliveryOwner(asking, conn, "groups", map[string]any{})
return err
})
if err != nil {
if errors.Is(err, link.ErrNothingServes) {
return nil, fmt.Errorf("nothing serves %s.groups", catalogue.DeliverySeat)
+49 -6
View File
@@ -67,6 +67,7 @@ type theIssue867 struct {
js interface{ Conn() *nats.Conn }
judgeCache string
registry string
groups string // what mesh-delivery's groups answers
}
func r867Git(t *testing.T, dir string, args ...string) string {
@@ -172,13 +173,14 @@ func theGroupOfIssue867(t *testing.T) *theIssue867 {
if verb != "groups" {
t.Fatalf("asked the owner %s", verb)
}
return json.RawMessage(`[{"id":"feat/867","members":["` + root + `/mesh-host@` + r.hostHead[:12] + ` (checked)","` +
root + `/mesh-controller@` + r.controllerHead[:12] + ` (checked)"],"member_details":[` +
`{"id":"novox/mesh-host@` + r.hostHead[:12] + `","repository":"novox/mesh-host","state":"checked","number":114,"head":"` +
r.hostHead + `","base":"main","open":true},` +
`{"id":"novox/mesh-controller@` + r.controllerHead[:12] + `","repository":"novox/mesh-controller","state":"checked","number":346,"head":"` +
r.controllerHead + `","base":"main","open":true}]}]`), nil
return json.RawMessage(r.groups), nil
}
r.groups = (`[{"id":"feat/867","members":["` + root + `/mesh-host@` + r.hostHead[:12] + ` (checked)","` +
root + `/mesh-controller@` + r.controllerHead[:12] + ` (checked)"],"member_details":[` +
`{"id":"novox/mesh-host@` + r.hostHead[:12] + `","repository":"novox/mesh-host","state":"checked","number":114,"head":"` +
r.hostHead + `","base":"main","open":true},` +
`{"id":"novox/mesh-controller@` + r.controllerHead[:12] + `","repository":"novox/mesh-controller","state":"checked","number":346,"head":"` +
r.controllerHead + `","base":"main","open":true}]}]`)
r.registry = r867Registry(t)
r867Runtime(t)
return r
@@ -301,3 +303,44 @@ exit 1
t.Setenv("PATH", dir+string(os.PathListSeparator)+os.Getenv("PATH"))
t.Setenv("GOTOOLCHAIN", "local")
}
// A recheck runs as a command of its own (`delivery check` with one member), where the controller is not the serving
// one and holds no connection: it dials the bus for the moment and asks mesh-delivery's `groups` as the daemon does.
// This drives the verb on a test bus with a fake mesh-delivery answering `groups`, with no stub of the seam between.
func TestTheRecheckVerbAsksMeshDeliveryOnABusOfItsOwn(t *testing.T) {
realAsk := askDeliveryOwner
r := theGroupOfIssue867(t)
askDeliveryOwner = realAsk
js, _ := aBuildQueue(t)
if servingBus.Load() != nil {
t.Fatal("this test is of a process that is not the serving controller")
}
asked := 0
wrapped, _ := json.Marshal(map[string]any{"content": []map[string]any{{"type": "text", "text": r.groups}}})
sub, err := js.Conn().Subscribe(link.SeatToolSubject(catalogue.DeliverySeat, "groups"), func(m *nats.Msg) {
asked++
body, _ := json.Marshal(link.Answer{Result: wrapped})
_ = m.Respond(body)
})
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = sub.Unsubscribe() })
member := `[{"id":"novox/mesh-host@` + r.hostHead[:12] + `","repository":"novox/mesh-host","base":"main","head":"` +
r.hostHead + `","number":114,"paths":["validate/more.go"],"module_dirs_said":true}]`
if err := deliveryCommand(t.Context(), []string{"check", "--members", member}); err != nil {
t.Fatal(err)
}
q, err := link.ReadQueue(t.Context(), js, link.TheBuildMachine)
if err != nil || len(q.Asks) == 0 {
t.Fatalf("nothing was asked of the build seat: %v", err)
}
c := q.Asks[len(q.Asks)-1].Request.Check
if c.SiblingsUnknown != "" || len(c.Siblings) != 1 || c.Siblings[0].Repository != "novox/mesh-controller" ||
c.Siblings[0].Number != 346 || c.Siblings[0].Head != r.controllerHead {
t.Fatalf("the recheck learned siblings %+v, unknown %q", c.Siblings, c.SiblingsUnknown)
}
if asked != 1 {
t.Fatalf("mesh-delivery was asked %d times", asked)
}
}