Issue 1126 (the controller's removal; ADR 0593 §7, §9), a blocking fault found by the first live run of compose-candidate: mesh-catalog #599's check (2026-11-02 23:00) passed every test and failed its composition on all four machines with "the indexer holds no candidate fix/940-no-retire-on-partial-read.08c0451d10a3", though the indexer holds that candidate. The checker asks with delivery.CompositionKey (., mesh-delivery checker engines.go:68); the indexer stores a candidate under delivery.CandidatesKey(group) with the heads hash in the value (candidates.go:187); the node-engine looked up the ask's key itself (internal/selfcompose/candidate.go:59). Since mesh-delivery #143 every check composes on the machines, so every check fails until this is delivered.
Fix: split the ask with the SDK's delivery.ParseCompositionKey, read CandidatesKey(group); a candidate stored at other heads is answered unready, naming both hashes (the checker files it as a node that did not answer, ADR 0593 §9), never a verdict on the wrong heads. Quick fix (this one reader) chosen over a shared SDK reader, which would need a second repository and a group delivery for one call site.
Tests: both tests had made up their fixtures with the wrong key, agreeing with the mistake; they now store candidates by group, with a slash in the group name, plus a moved-heads case. The unit test failed before the fix with the live words. gofmt, vet with and without the integration tag, and all unit and integration tests of mesh-host pass.
This check's own composition will fail the same way: the machines compose with the node-engine they run, which has the fault. Its tests passing is what judges it; the operator's Approve of the failed-check merge is the path, said in advance.
Issue 1126 (the controller's removal; ADR 0593 §7, §9), a blocking fault found by the first live run of compose-candidate: mesh-catalog #599's check (2026-11-02 23:00) passed every test and failed its composition on all four machines with "the indexer holds no candidate fix/940-no-retire-on-partial-read.08c0451d10a3", though the indexer holds that candidate. The checker asks with delivery.CompositionKey (<group>.<heads>, mesh-delivery checker engines.go:68); the indexer stores a candidate under delivery.CandidatesKey(group) with the heads hash in the value (candidates.go:187); the node-engine looked up the ask's key itself (internal/selfcompose/candidate.go:59). Since mesh-delivery #143 every check composes on the machines, so every check fails until this is delivered.
Fix: split the ask with the SDK's delivery.ParseCompositionKey, read CandidatesKey(group); a candidate stored at other heads is answered unready, naming both hashes (the checker files it as a node that did not answer, ADR 0593 §9), never a verdict on the wrong heads. Quick fix (this one reader) chosen over a shared SDK reader, which would need a second repository and a group delivery for one call site.
Tests: both tests had made up their fixtures with the wrong key, agreeing with the mistake; they now store candidates by group, with a slash in the group name, plus a moved-heads case. The unit test failed before the fix with the live words. gofmt, vet with and without the integration tag, and all unit and integration tests of mesh-host pass.
This check's own composition will fail the same way: the machines compose with the node-engine they run, which has the fault. Its tests passing is what judges it; the operator's Approve of the failed-check merge is the path, said in advance.
Reviewed-by: review-1126@shanks at 0bbdae1d9dfb313ae582549cb6618bfbecfccf84
https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
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
Deliverynovox/mesh-host@0bbdae1d9dfb — merged since 2026-11-02T23:14:59Z
Source — source.main moved to novox/mesh-host@27a956448c. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-11-02 23:06 (new) → proposed (announced): novox/mesh-host#199's head announced
2026-11-02 23:06 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
2026-11-02 23:14 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-host@0bbdae1d9dfb` — **merged** since 2026-11-02T23:14:59Z
**Source** — source.main moved to novox/mesh-host@27a956448c0a. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-11-02 23:06 (new) → proposed (announced): novox/mesh-host#199's head announced
- 2026-11-02 23:06 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
- 2026-11-02 23:14 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Issue 1126 (the controller's removal; ADR 0593 §7, §9), a blocking fault found by the first live run of compose-candidate: mesh-catalog #599's check (2026-11-02 23:00) passed every test and failed its composition on all four machines with "the indexer holds no candidate fix/940-no-retire-on-partial-read.08c0451d10a3", though the indexer holds that candidate. The checker asks with delivery.CompositionKey (., mesh-delivery checker engines.go:68); the indexer stores a candidate under delivery.CandidatesKey(group) with the heads hash in the value (candidates.go:187); the node-engine looked up the ask's key itself (internal/selfcompose/candidate.go:59). Since mesh-delivery #143 every check composes on the machines, so every check fails until this is delivered.
Fix: split the ask with the SDK's delivery.ParseCompositionKey, read CandidatesKey(group); a candidate stored at other heads is answered unready, naming both hashes (the checker files it as a node that did not answer, ADR 0593 §9), never a verdict on the wrong heads. Quick fix (this one reader) chosen over a shared SDK reader, which would need a second repository and a group delivery for one call site.
Tests: both tests had made up their fixtures with the wrong key, agreeing with the mistake; they now store candidates by group, with a slash in the group name, plus a moved-heads case. The unit test failed before the fix with the live words. gofmt, vet with and without the integration tag, and all unit and integration tests of mesh-host pass.
This check's own composition will fail the same way: the machines compose with the node-engine they run, which has the fault. Its tests passing is what judges it; the operator's Approve of the failed-check merge is the path, said in advance.
Reviewed-by: review-1126@shanks at
0bbdae1d9dhttps://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
Delivery
novox/mesh-host@0bbdae1d9dfb— merged since 2026-11-02T23:14:59ZSource — source.main moved to novox/mesh-host@27a956448c. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.