compose-candidate reads the indexer's candidate by its group key, not the check's key
mesh/delivery merged: source.main moved to novox/mesh-host@27a956448c0a
mesh/check checking 0bbdae1d9dfb on 27a956448c0a

The checker asks by the composition key, <group>.<heads hash> (ADR 0593 §7), but the
indexer keys a candidate by its group alone (delivery.CandidatesKey). The node-engine
read the ask's key as the bucket key, so every check's composition was refused on
every node with "the indexer holds no candidate" (mesh-catalog #599, 2026-11-02).

It now parses the ask, reads CandidatesKey(group), and answers unready when the
group's candidate has moved to other heads. Both tests' fixtures had captured the
wrong key; they now key by group, with a slash in the group name.

Quick fix: this lookup. Thorough fix (a shared SDK reader that takes a composition
key and returns the candidate at those heads) not taken: one reader, one repository.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-03 00:05:04 +01:00
parent 4c7056de42
commit 0bbdae1d9d
3 changed files with 38 additions and 12 deletions
+6 -3
View File
@@ -575,13 +575,16 @@ func h8candidate(t *testing.T, b *itBed, fp, running string) {
heads, _ := delivery.HeadsHash([]delivery.Head{head})
pulls := []delivery.CandidatePull{{Head: head, Modules: []string{"web"},
Fps: map[string]delivery.CandidateModule{"web": {FP2: fpIt("c"), Manifest: digest}}}}
craw, err := delivery.EncodeCandidate(delivery.Candidate{Group: "novox/web#3", HeadsHash: heads, Pulls: pulls,
// The indexer keys the candidate by its group (a branch name, slash allowed); the checker asks by the composition key.
const group = "fix/3-web"
craw, err := delivery.EncodeCandidate(delivery.Candidate{Group: group, HeadsHash: heads, Pulls: pulls,
FPSet: delivery.FingerprintSet(pulls)})
if err != nil {
t.Fatal(err)
}
key, _ := delivery.CompositionKey("novox/web#3", heads)
if _, err := cands.Put(key, craw); err != nil {
ckey, _ := delivery.CandidatesKey(group)
key, _ := delivery.CompositionKey(group, heads)
if _, err := cands.Put(ckey, craw); err != nil {
t.Fatal(err)
}
before, _ := b.composed.Status()