D8: a trunk's held manifest judged by its digest is said as manifest-accepted or manifest-refused, as the full pass says it (issue 1966, ADR 0668 §4; review round 1, finding 3)

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
This commit is contained in:
2026-11-10 04:13:02 +01:00
parent cddaf14cd0
commit 8f50f22622
2 changed files with 26 additions and 1 deletions
@@ -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 {
@@ -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()