From fdc482d512c66707f7c31e70e902dc1528fe2604 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 15:47:16 +0100 Subject: [PATCH] IX28: the entry's manifest-digest carries sha256: and the digits, the module's value the bare digits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds: design 47 G §578, §609 (IX28; §500's problems wait on a design question) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../internal/index/catalog_graph.go | 23 +++++++++++++++++-- .../internal/index/catalog_graph_test.go | 12 +++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/modules/mesh-delivery-indexer/internal/index/catalog_graph.go b/modules/mesh-delivery-indexer/internal/index/catalog_graph.go index 85ebbdca..9a47267a 100644 --- a/modules/mesh-delivery-indexer/internal/index/catalog_graph.go +++ b/modules/mesh-delivery-indexer/internal/index/catalog_graph.go @@ -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 diff --git a/modules/mesh-delivery-indexer/internal/index/catalog_graph_test.go b/modules/mesh-delivery-indexer/internal/index/catalog_graph_test.go index 5b8f76e3..fe9e5ae7 100644 --- a/modules/mesh-delivery-indexer/internal/index/catalog_graph_test.go +++ b/modules/mesh-delivery-indexer/internal/index/catalog_graph_test.go @@ -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) } }