From 3ff694e425cfe674f79db90a63da41f5a667a0ba Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 12:35:14 +0100 Subject: [PATCH] =?UTF-8?q?DLV-O4=20sdk:=20manifest-accepted=20and=20manif?= =?UTF-8?q?est-refused=20carry=20the=20indexer's=20revision=20(ADR=200622?= =?UTF-8?q?=20=C2=A72)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- go/delivery/verdicts.go | 6 ++++++ go/delivery/verdicts_test.go | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/go/delivery/verdicts.go b/go/delivery/verdicts.go index 18e9c3d..a6cede6 100644 --- a/go/delivery/verdicts.go +++ b/go/delivery/verdicts.go @@ -205,6 +205,9 @@ type ManifestRefused struct { Digest string `json:"digest"` Judge string `json:"judge"` Problems []string `json:"problems"` + // Revision is the indexer's revision of the verdict it says (novox/hq ADR 0622 §2): a reader following verdicts by + // their events asks its first view again on a gap in it. Zero from an indexer that does not say it. + Revision uint64 `json:"revision,omitempty"` } // RefusedOf is the event body saying v, the verdict on the manifest of digest. @@ -220,6 +223,9 @@ type ManifestAccepted struct { Digest string `json:"digest"` Judge string `json:"judge"` BusState []catalogue.BusStateEntry `json:"bus-state"` + // Revision is the indexer's revision of the verdict it says (novox/hq ADR 0622 §2; the bus module applies a replay + // only if newer, design 25 § 12.2). Zero from an indexer that does not say it. + Revision uint64 `json:"revision,omitempty"` } // AcceptedOf is the event body saying v, the verdict accepting the manifest m of digest. diff --git a/go/delivery/verdicts_test.go b/go/delivery/verdicts_test.go index 0e70049..90af075 100644 --- a/go/delivery/verdicts_test.go +++ b/go/delivery/verdicts_test.go @@ -103,6 +103,16 @@ func TestAManifestVerdictIsTheContractReadersTake(t *testing.T) { if id := heard.EventID(); id != "manifest-accepted-"+digest+"-src2:j" { t.Fatalf("the accepted event's id is %q", id) } + // Both verdict events carry the indexer's revision (ADR 0622 §2), and one without it reads as revision 0. + for _, ev := range []any{ManifestAccepted{Module: "m", Revision: 41}, ManifestRefused{Module: "m", Revision: 41}} { + raw, _ := json.Marshal(ev) + var back struct { + Revision uint64 `json:"revision"` + } + if json.Unmarshal(raw, &back); back.Revision != 41 { + t.Errorf("%T carries no revision: %s", ev, raw) + } + } // A manifest with a field the judge does not know waits (clause 3 of the record on a release's Approve): readers hold it // as a refused one, it round-trips through a modules value, an old value decodes unchanged, and it is not a refusal. waits := ManifestVerdict{Module: "nats", State: VerdictManifestWaits, Unknown: []string{"core-credentials", "tool-runner"}, Judge: "j"}