IX28: the entry's manifest-digest carries sha256: and the digits, the module's value the bare digits

Builds: design 47 G §578, §609 (IX28; §500's problems wait on a design question)

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 15:47:16 +01:00
parent a3d4e0d8ad
commit fdc482d512
2 changed files with 30 additions and 5 deletions
@@ -8,6 +8,7 @@ import (
"maps"
"reflect"
"slices"
"strings"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/sdk/graph"
@@ -23,6 +24,24 @@ import (
// CatalogEntryLayout is the layout version an entry and a revision are written in.
const CatalogEntryLayout = 1
// manifestDigestPrefix is how an entry's field manifest-digest begins, as every digest a record names (design 47 G §578).
const manifestDigestPrefix = "sha256:"
// EntryManifestDigest is the entry's field manifest-digest for the module's digest bare, the 64 hex digits the module's
// value and the key of `manifests` hold: `sha256:` and the digits (design 47 G §578). A digest already prefixed stays, and
// none stays none.
func EntryManifestDigest(bare string) string {
if bare == "" || strings.HasPrefix(bare, manifestDigestPrefix) {
return bare
}
return manifestDigestPrefix + bare
}
// BareManifestDigest is the 64 hex digits of an entry's manifest-digest: the module's value and the key of `manifests`
// (design 47 G §578). An entry taken in before G carries the digits alone, which is what its module value held (§609), and
// stays as it is.
func BareManifestDigest(field string) string { return strings.TrimPrefix(field, manifestDigestPrefix) }
// CatalogEntryOf is the catalog graph entry of one module: the module graph's node of it as a recompute computed it
// (its build, provision and verb edges, the verb edges left out on a cycle, ADR 0614), with where the trunk holds it,
// its manifest's digest and verdict, the main package its process runs (MainOf), the package versions it builds against
@@ -30,7 +49,7 @@ const CatalogEntryLayout = 1
// ModuleValueOf gives the module's value back from the entry alone. The acting rules are the revision's to add.
func CatalogEntryOf(module string, cur meshcatalog.ModulesByModuleValue, m catalogue.Manifest, raw string, n graph.Node) meshcatalog.CatalogEntry {
e := meshcatalog.CatalogEntry{V: CatalogEntryLayout, Module: module, Repository: cur.Repository, Path: cur.Path,
Commit: cur.Commit, Manifest: manifestWhole(raw), ManifestDigest: cur.Manifest, Verdict: cur.Verdict, Fp: n.FP, None: n.None, Bases: n.Bases,
Commit: cur.Commit, Manifest: manifestWhole(raw), ManifestDigest: EntryManifestDigest(cur.Manifest), Verdict: cur.Verdict, Fp: n.FP, None: n.None, Bases: n.Bases,
Packages: maps.Clone(cur.Packages), Provides: n.Provides, Requires: n.Requires, Awaits: n.Awaits, Invokes: n.Invokes,
Serves: n.Serves, LeftOut: n.LeftOut, Main: MainOf(m)}
if n.FP == "" && n.None == "" {
@@ -60,7 +79,7 @@ func CatalogEntryOf(module string, cur meshcatalog.ModulesByModuleValue, m catal
// ruling on milestone 47/G finding 1; ADR 0656 §6: one form of the fact). The old line's fields (the old-form
// fingerprint, the reader needs) are not kept.
func ModuleValueOf(e meshcatalog.CatalogEntry) meshcatalog.ModulesByModuleValue {
v := meshcatalog.ModulesByModuleValue{V: keys.Version, Repository: e.Repository, Path: e.Path, Commit: e.Commit, Manifest: e.ManifestDigest,
v := meshcatalog.ModulesByModuleValue{V: keys.Version, Repository: e.Repository, Path: e.Path, Commit: e.Commit, Manifest: BareManifestDigest(e.ManifestDigest),
Verdict: e.Verdict, Fp2: e.Fp, None2: e.None, Packages: maps.Clone(e.Packages)}
if in := e.Inputs; in != nil {
v.Toolchains, v.Paths, v.Problems, v.Warnings, v.Unknown = maps.Clone(in.Toolchains), maps.Clone(in.Paths), in.Problems, in.Warnings, in.Unknown
@@ -16,10 +16,16 @@ func TestAnEntryCarriesItsManifestWholeAndTheDigestOfItsBytes(t *testing.T) {
digest := meshcatalogclient.ManifestDigest([]byte(raw))
cur := meshcatalog.ModulesByModuleValue{Repository: "novox/mesh-catalog", Path: "modules/avahi", Commit: "c", Manifest: digest}
e := CatalogEntryOf("avahi", cur, catalogue.Manifest{}, raw, graph.Node{})
if e.ManifestDigest != digest || e.Manifest["module"] != "avahi" {
t.Fatalf("entry digest %q manifest %v, want the digest %s of the bytes and the manifest whole", e.ManifestDigest, e.Manifest, digest)
if e.ManifestDigest != "sha256:"+digest || e.Manifest["module"] != "avahi" {
t.Fatalf("entry digest %q manifest %v, want sha256: and the digits %s of the bytes (§578) and the manifest whole", e.ManifestDigest, e.Manifest, digest)
}
if back := ModuleValueOf(e); back.Manifest != digest {
t.Errorf("the module's value read back holds %q, want the entry's digest %s", back.Manifest, digest)
t.Errorf("the module's value read back holds %q, want the bare digits %s (§578)", back.Manifest, digest)
}
// §609: an entry taken in before G carries the digits its module value held; reading it back gives the same digits.
before := e
before.ManifestDigest = digest
if back := ModuleValueOf(before); back.Manifest != digest {
t.Errorf("an entry of before G read back holds %q, want %s (§609)", back.Manifest, digest)
}
}