From 8f50f22622cc09fdd2831aa66f950320a785ad95 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 10 Nov 2026 04:13:02 +0100 Subject: [PATCH] =?UTF-8?q?D8:=20a=20trunk's=20held=20manifest=20judged=20?= =?UTF-8?q?by=20its=20digest=20is=20said=20as=20manifest-accepted=20or=20m?= =?UTF-8?q?anifest-refused,=20as=20the=20full=20pass=20says=20it=20(issue?= =?UTF-8?q?=201966,=20ADR=200668=20=C2=A74;=20review=20round=201,=20findin?= =?UTF-8?q?g=203)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit indexer_judge with a digest and the start pass's judgeStale wrote the verdict and said nothing, so a part waiting on manifest-accepted never heard it. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../internal/index/verdicts.go | 7 ++++++- .../internal/index/verdicts_test.go | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/modules/mesh-delivery-indexer/internal/index/verdicts.go b/modules/mesh-delivery-indexer/internal/index/verdicts.go index 0746bb07..24ce8159 100644 --- a/modules/mesh-delivery-indexer/internal/index/verdicts.go +++ b/modules/mesh-delivery-indexer/internal/index/verdicts.go @@ -101,10 +101,15 @@ func (ix *Indexer) judgeOverHeld(ctx context.Context, fresh map[string]bool, ove // knowing its delivery group, whose new packages this state does not know yet (the lead's ruling, issue 1966). The // trunk's own manifests are, and a merge's are again in full (namesAtMerge). known := ix.knownPackages(ctx) + // A digest judged over the trunk that is the trunk's own held one is said as the full pass says it (manifest-accepted, + // manifest-refused): indexer_judge with it, or the start pass's judgeStale, is that manifest's only judgement (review + // round 1 of issue 1966; ADR 0668 ยง4). A candidate's verdict is said nowhere. + onTrunk := map[string]bool{} if over != nil { fresh = map[string]bool{} for module, digest := range over { m := held[module] + onTrunk[module] = m.Manifest == digest if m.Manifest != "" && m.Manifest != digest { trunkOf[module] = m.Manifest } @@ -219,7 +224,7 @@ func (ix *Indexer) judgeOverHeld(ctx context.Context, fresh map[string]bool, ove continue } judgedDigests[digests[name]] = true - if wrote && over != nil { + if wrote && over != nil && !onTrunk[name] { out.Written++ ix.logf("judge: %s judged again by %s: %s", digests[name], id, v.State) } else if wrote { diff --git a/modules/mesh-delivery-indexer/internal/index/verdicts_test.go b/modules/mesh-delivery-indexer/internal/index/verdicts_test.go index 204c20b5..09d6cf52 100644 --- a/modules/mesh-delivery-indexer/internal/index/verdicts_test.go +++ b/modules/mesh-delivery-indexer/internal/index/verdicts_test.go @@ -215,6 +215,26 @@ func TestTheIndexerJudgesEveryManifestOnce(t *testing.T) { if last := accepted[len(accepted)-1]; last.Module != "plain" || last.Digest != plain || last.BusState == nil || len(last.BusState) != 0 { t.Fatalf("a manifest asking for no bus state was said as %+v", last) } + // Review round 1 of issue 1966: a trunk's held manifest judged by its digest (indexer_judge, judgeStale) is said as the + // full pass says it, accepted or refused; a candidate's digest judged over the trunk is said nowhere. + byDigest := hold("bydigest", `{"module":"bydigest","version":"1"}`) + refusedBy := hold("refusedby", `{"module":"refusedby","version":"1","requires":["amqp"]}`) + saidBefore := len(said) + for module, digest := range map[string]string{"bydigest": byDigest, "refusedby": refusedBy} { + if _, err := ix.judgeOver(ctx, nil, module, digest); err != nil { + t.Fatal(err) + } + } + if last := accepted[len(accepted)-1]; last.Digest != byDigest || len(said) != saidBefore+1 || said[len(said)-1].Digest != refusedBy { + t.Fatalf("judged by its digest, the trunk's manifest was said as %+v, refusals %d (were %d)", last, len(said), saidBefore) + } + candidate, err := ix.keepManifest(ctx, "bydigest", `{"module":"bydigest","version":"2"}`) + if err != nil { + t.Fatal(err) + } + if _, err := ix.judgeOver(ctx, nil, "bydigest", candidate); err != nil || accepted[len(accepted)-1].Digest != byDigest { + t.Fatalf("a candidate's verdict was said: %v %+v", err, accepted[len(accepted)-1]) + } // DLV-I9b: a failed publish is published again; one failing twice writes the finding naming the module, which the next // judging pass says again and clears. ix.Findings = newMem()