The indexer's judge names, with each verdict, the reader capabilities a manifest's own words, forms and seat names need, in its module value (ADR 0614 §4, issue 774)
Module.Needs is catalogue.ManifestNeeds of the manifest held: written by the merge that takes a changed manifest in, so no reader takes it as needing nothing before the judge's pass, named again by the judge with the verdict, and carried over by a write that leaves the digest, as the verdict is. The module value is the one the assigner and the checker already read. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
|
||||
"mesh-delivery-indexer/internal/fingerprint"
|
||||
@@ -95,6 +96,9 @@ func (ix *Indexer) applyMoving(ctx context.Context, f delivery.Forge, drop bool,
|
||||
}
|
||||
dirOf[name] = dir
|
||||
next := delivery.Module{Repository: f.Repository, Commit: f.Merge, Src: ix.srcOf(f.Repository, f.Merge), Manifest: digests[dir], Path: pathOf(dir)}
|
||||
// The reader capabilities a changed manifest needs are written with it, before the judge's pass names them with its
|
||||
// verdict, so no reader takes a new manifest as needing nothing (ADR 0614 §4).
|
||||
next.Needs, _ = catalogue.ManifestNeeds([]byte(raw))
|
||||
if next.Manifest == "" {
|
||||
next.None2 = "the manifest cannot be read: it cannot be kept as a value"
|
||||
} else {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/process"
|
||||
)
|
||||
@@ -413,6 +414,11 @@ func TestAMergeAddingAModuleDirectoryWritesItsValueWithNoBuildRecordAnywhere(t *
|
||||
if m.FP2 == "" && m.None2 == "" {
|
||||
t.Errorf("module = %+v, want a new-form fingerprint or its reason", m)
|
||||
}
|
||||
// ADR 0614 §4: the merge writes the reader capabilities its manifest needs, so no reader takes it as needing nothing
|
||||
// before the judge's pass.
|
||||
if want, _ := catalogue.ManifestNeeds([]byte(avahi)); len(m.Needs) == 0 || !slices.Equal(m.Needs, want) {
|
||||
t.Errorf("module needs %v, want %v", m.Needs, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAMergeWritesOnlyTheModulesItsManifestsName(t *testing.T) { // I1
|
||||
|
||||
@@ -365,8 +365,9 @@ func (ix *Indexer) writeOverlay(ctx context.Context, overlay, finals map[string]
|
||||
held := found && err == nil
|
||||
if held && cur.Manifest == next.Manifest {
|
||||
// The judge's verdict stands while the digest does (ADR 0578 §3, ADR 0579 §1): a recompute never writes a
|
||||
// refused or outgrown module as accepted; only the judge changes it.
|
||||
// refused or outgrown module as accepted; only the judge changes it. So do the reader capabilities it named.
|
||||
next.Verdict, next.Problems, next.Unknown, next.Warnings = cur.Verdict, cur.Problems, cur.Unknown, cur.Warnings
|
||||
next.Needs = cur.Needs
|
||||
}
|
||||
// The source revision at which FP2 last changed (ADR 0601 §1): this merge's when it moved it (0 until the
|
||||
// source revision naming the merge is heard, which stamps it), else the one held.
|
||||
@@ -401,6 +402,7 @@ func sameButWhere(cur, next delivery.Module) bool {
|
||||
next = withV(next)
|
||||
next.Commit, next.Src, next.FPSrc = cur.Commit, cur.Src, cur.FPSrc
|
||||
next.Verdict, next.Problems, next.Unknown, next.Warnings = cur.Verdict, cur.Problems, cur.Unknown, cur.Warnings
|
||||
next.Needs = cur.Needs
|
||||
return reflect.DeepEqual(cur, next)
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,9 @@ func (ix *Indexer) JudgeAll(ctx context.Context, fresh map[string]bool) (Judged,
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := ix.carryVerdict(ctx, name, digests[name], v); err != nil {
|
||||
// The reader capabilities the manifest's own words, forms and seat names need, named with the verdict (ADR 0614 §4).
|
||||
needs, _ := catalogue.ManifestNeeds(raws[name])
|
||||
if err := ix.carryVerdict(ctx, name, digests[name], v, needs); err != nil {
|
||||
ix.logf("judge: modules.%s does not carry its verdict: %v", name, err)
|
||||
}
|
||||
}
|
||||
@@ -257,9 +259,10 @@ func (ix *Indexer) ownBuildIsNewest(held map[string]delivery.Module) bool {
|
||||
}
|
||||
|
||||
// carryVerdict puts a refusal into the module's value, and takes one out once the manifest is accepted, while the value
|
||||
// still names the digest judged; an accepted module's value carries nothing, so judging writes no value of a module the
|
||||
// still names the digest judged, and the reader capabilities the manifest needs beside it (needs, ADR 0614 §4); an
|
||||
// accepted module's value carries no verdict, so judging writes no value of a module the
|
||||
// judge accepts (a reader takes a value without a verdict as accepted, delivery.TakeManifestVerdict).
|
||||
func (ix *Indexer) carryVerdict(ctx context.Context, name, digest string, v delivery.ManifestVerdict) error {
|
||||
func (ix *Indexer) carryVerdict(ctx context.Context, name, digest string, v delivery.ManifestVerdict, needs []string) error {
|
||||
key, err := delivery.ModulesKey(name)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -280,10 +283,11 @@ func (ix *Indexer) carryVerdict(ctx context.Context, name, digest string, v deli
|
||||
case v.Refused():
|
||||
state = delivery.VerdictRefused
|
||||
}
|
||||
if cur.Verdict == state && slices.Equal(cur.Problems, problems) && slices.Equal(cur.Unknown, v.Unknown) && slices.Equal(cur.Warnings, v.Warnings) {
|
||||
if cur.Verdict == state && slices.Equal(cur.Problems, problems) && slices.Equal(cur.Unknown, v.Unknown) && slices.Equal(cur.Warnings, v.Warnings) &&
|
||||
slices.Equal(cur.Needs, needs) {
|
||||
return nil, false, nil
|
||||
}
|
||||
cur.Verdict, cur.Problems, cur.Unknown, cur.Warnings = state, problems, v.Unknown, v.Warnings
|
||||
cur.Verdict, cur.Problems, cur.Unknown, cur.Warnings, cur.Needs = state, problems, v.Unknown, v.Warnings, needs
|
||||
if state == "" {
|
||||
cur.Problems = nil
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
@@ -113,6 +115,7 @@ func TestTheIndexerJudgesEveryManifestOnce(t *testing.T) {
|
||||
// A merge's write of a module whose digest it leaves as it is carries the verdict over, and nothing is fresh; a changed
|
||||
// digest is fresh, judged in full (review R1, R2).
|
||||
w := &mergeWrite{}
|
||||
oldNeeds := module("old").Needs
|
||||
same := delivery.Module{FP2: "src2:" + strings.Repeat("c", 64), Manifest: changed, Repository: "novox/mesh-catalog", Commit: "c2"}
|
||||
if err := ix.writeOverlay(ctx, map[string]delivery.Module{"old": same}, nil, w); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -120,6 +123,9 @@ func TestTheIndexerJudgesEveryManifestOnce(t *testing.T) {
|
||||
if m := module("old"); m.Verdict != delivery.VerdictRefused || len(m.Problems) == 0 || len(w.fresh) != 0 {
|
||||
t.Fatalf("a merge rewrote a refused module as %+v, fresh %v", m, w.fresh)
|
||||
}
|
||||
if got := module("old").Needs; len(oldNeeds) == 0 || !slices.Equal(got, oldNeeds) {
|
||||
t.Fatalf("a merge leaving the digest dropped the reader capabilities the judge named: %v, held %v", got, oldNeeds)
|
||||
}
|
||||
other := strings.Repeat("d", 64)
|
||||
same.Manifest = other
|
||||
if err := ix.writeOverlay(ctx, map[string]delivery.Module{"old": same}, nil, w); err != nil || !w.fresh[other] {
|
||||
@@ -137,6 +143,15 @@ func TestTheIndexerJudgesEveryManifestOnce(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
// ADR 0614 §4: the judge names, with the verdict, the reader capabilities the manifest's own words need: the bus-state
|
||||
// words, which an engine stating nothing (the baseline) lacks; a manifest of the baseline's words lacks none.
|
||||
if needs := module("moved").Needs; !slices.Contains(needs, "word:bus-state.storage") ||
|
||||
!slices.Contains(catalogue.MissingManifestReads(needs, nil), "word:bus-state") {
|
||||
t.Fatalf("modules.moved needs %v", needs)
|
||||
}
|
||||
if needs := module("good").Needs; !slices.Contains(needs, "word:module") || len(catalogue.MissingManifestReads(needs, nil)) != 0 {
|
||||
t.Fatalf("modules.good needs %v", needs)
|
||||
}
|
||||
if len(accepted) != 1 || accepted[0].Module != "moved" || accepted[0].Digest != moved || accepted[0].Judge != "judge-2" ||
|
||||
len(accepted[0].BusState) != 2 || accepted[0].BusState[0].Name != "cache" || accepted[0].BusState[1].Template != "log" ||
|
||||
string(accepted[0].BusState[0].Options["history"]) != "8" {
|
||||
|
||||
Reference in New Issue
Block a user