mesh-delivery-checker: a composer at the node-engine's head that cannot run fails the composition

Review finding 3 (ADR 0593 §9): only a node that does not answer may let a check pass with a warning; a
sandbox composer that cannot be built or run was filed with the silent nodes. It now fails that node's
composition, naming the head.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 19:36:42 +01:00
parent e31da597bb
commit e5ce35cd00
2 changed files with 22 additions and 2 deletions
@@ -91,8 +91,15 @@ func (e EngineCompositions) Compose(ctx context.Context, c *Case) (delivery.Comp
defer cancel()
a, err := e.Asker.ComposeCandidate(at, node, delivery.ComposeCandidateAsk{Candidate: key, Input: sandboxed})
if err == nil && sandboxed && a.Verdict != delivery.ComposeCandidateUnready {
// The composer's build and run are the check's to bound, not the engine's answer bound.
a, err = e.inSandbox(ctx, c, head, node, a)
// The composer's build and run are the check's to bound, not the engine's answer bound. A composer that
// cannot run is no silent node (ADR 0593 §9 lets only that pass): the node's composition fails, naming
// the head.
if composed, serr := e.inSandbox(ctx, c, head, node, a); serr != nil {
a = delivery.ComposeCandidateAnswer{V: a.V, Node: node, Candidate: a.Candidate, Verdict: delivery.ComposeCandidateRefused,
Refused: "the composer at the node-engine's head " + head + " could not compose it: " + serr.Error()}
} else {
a = composed
}
}
mu.Lock()
defer mu.Unlock()
@@ -45,6 +45,7 @@ type fakeSandbox struct {
mu sync.Mutex
jobs []delivery.ComposeJob
v func(node string) composer.Verdict
err error
}
func (f *fakeSandbox) Compose(_ context.Context, job delivery.ComposeJob) (composer.Verdict, error) {
@@ -55,6 +56,9 @@ func (f *fakeSandbox) Compose(_ context.Context, job delivery.ComposeJob) (compo
f.mu.Lock()
f.jobs = append(f.jobs, job)
f.mu.Unlock()
if f.err != nil {
return composer.Verdict{}, f.err
}
return f.v(req.Machines[0]), nil
}
@@ -164,5 +168,14 @@ func TestTheCompositionIsMadeFromTheEnginesAnswers(t *testing.T) {
if v.State != delivery.CompositionFail || v.SDK != head2 || !strings.Contains(v.Words, "the new composer refuses it") {
t.Errorf("verdict = %+v", v)
}
// Review finding 3 (ADR 0593 §9 lets only a node that does not answer pass): a composer at the head that cannot
// run fails the composition, naming the head, never passing as a silent node.
sb.err = errors.New("the build of mesh-compose failed")
v, err = ec.Compose(context.Background(), host)
if err != nil || v.State != delivery.CompositionFail || !strings.Contains(v.Words, head2) ||
!strings.Contains(v.Words, "the build of mesh-compose failed") || len(v.Warnings) != 0 {
t.Errorf("a composer that cannot run: %+v, %v", v, err)
}
})
}