The check's composer composes a module at its build only where that build was made of the change's manifest (issue 1921, milestone 47/G)
mesh/delivery-group group feat/registry-milestone checking: 7 of 7 member(s) ready
mesh/delivery closed: a newer head of the same pull request
mesh/check checking 53addd73c358 on e73aae3686a6 | novox/mesh-host#209 in group feat/registry-milestone

The running indexer could not read 17 of the group's manifests, so the running node-engine composed those modules at
their trunk builds and said nothing; the head composer laid those builds over the change's other manifests and ace
failed on "nothing provides artifact-store, wanted by mesh-build-go" (group check 8a80e8e86858). The input a node
answers a check with now names, per module taken in from its build, the content digest of the manifest that build was
made of (ComposedHow.Manifests); the composer compares it with the case's manifest, and, for an input from a
node-engine before it, compares what the two manifests say beyond what a take-in resolves (the lead's ruling, §17).
Each module lifted either way is composed from the case's manifest, its build awaited, and named in NotJudged with
the comparison that lifted it; one that cannot compose without its build is held as its stub. The digest is taken
over one JSON form because a request through a build module arrives compacted.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-07 07:24:16 +01:00
parent b6c174a324
commit 53addd73c3
5 changed files with 185 additions and 3 deletions
+25
View File
@@ -16,6 +16,9 @@
package compose
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@@ -283,6 +286,28 @@ type ComposedHow struct {
// HeldBefore is each module the node holds composing without the change (the candidate's base), held by the read or
// blamed later for a refusal: the change refuses none of them (issue 774, review round 1).
HeldBefore map[string]string
// Manifests is, by module taken in from its build, the ContentDigest of the manifest that build was made of (its
// build record's manifest), filled in the input a node answers a check with: the check's composer composes a module
// at its build only where the change's manifest is that one (issue 1921). Nil from a node-engine before it.
Manifests map[string]string
}
// ContentDigest is the hex sha256 of a manifest's JSON in one form, its keys sorted and its spacing removed, its numbers
// as written: the same for the bytes its repository holds and for those bytes carried inside a request, which JSON
// encoding compacts on the way (a composition request through a build module), so the two are compared as one manifest.
func ContentDigest(raw []byte) (string, error) {
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
var v any
if err := dec.Decode(&v); err != nil {
return "", fmt.Errorf("compose: the manifest is not JSON: %w", err)
}
canonical, err := json.Marshal(v)
if err != nil {
return "", err
}
sum := sha256.Sum256(canonical)
return hex.EncodeToString(sum[:]), nil
}
// Place is where a node is, as its assignment says (inv.Overlay).