Let a verdict warn of what a stricter judge found in a manifest it accepted before (ADR 0579 §1)
Issue 1585: ManifestVerdict and the modules value carry Warnings; the finding manifest-outgrown names it. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -431,13 +431,19 @@ type Module struct {
|
||||
// that state. Empty in a value written before the indexer judged, which a reader takes as accepted (TakeManifestVerdict).
|
||||
Verdict string `json:"verdict,omitempty"`
|
||||
Problems []string `json:"problems,omitempty"`
|
||||
// Warnings are the problems of an accepted manifest a stricter judge outgrew (novox/hq ADR 0579 §1): Verdict is then
|
||||
// empty (accepted), and the watchman raises delivery.ManifestOutgrown until the manifest is mended.
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
}
|
||||
|
||||
// VerdictOf is the verdict a modules value carries, or nil when it carries none (taken as accepted, TakeManifestVerdict).
|
||||
func (m Module) VerdictOf(module string) *ManifestVerdict {
|
||||
if m.Verdict == "" {
|
||||
if m.Verdict == "" && len(m.Warnings) == 0 {
|
||||
return nil
|
||||
}
|
||||
if m.Verdict == "" {
|
||||
return &ManifestVerdict{Module: module, State: VerdictAccepted, Warnings: m.Warnings}
|
||||
}
|
||||
return &ManifestVerdict{Module: module, State: m.Verdict, Problems: m.Problems}
|
||||
}
|
||||
|
||||
@@ -554,6 +560,8 @@ func (m Module) check() error {
|
||||
return fmt.Errorf("delivery: a module carries a verdict and no manifest digest")
|
||||
case (m.Verdict == VerdictRefused) != (len(m.Problems) > 0):
|
||||
return fmt.Errorf("delivery: a module's problems are named only with a refusal, and a refusal names them")
|
||||
case m.Verdict == VerdictRefused && len(m.Warnings) > 0:
|
||||
return fmt.Errorf("delivery: a refused module warns: a refusal names problems")
|
||||
}
|
||||
return checkNewForm(m.FP2, m.Manifest)
|
||||
}
|
||||
|
||||
+17
-13
@@ -3,6 +3,7 @@ package delivery
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -26,15 +27,23 @@ const (
|
||||
// ManifestRefusedEvent is the indexer's event saying a manifest was refused (ManifestRefused), so the watchman
|
||||
// raises it as a condition beside the indexer's finding.
|
||||
ManifestRefusedEvent = "manifest-refused"
|
||||
|
||||
// ManifestOutgrown is the finding of a manifest the indexer accepted before and a stricter judge finds problems in
|
||||
// (novox/hq ADR 0579 §1): it stays accepted, its problems are the verdict's Warnings, and the watchman raises it as a
|
||||
// warning until the manifest is mended.
|
||||
ManifestOutgrown = "manifest-outgrown"
|
||||
)
|
||||
|
||||
// ManifestVerdict is the value of a verdicts key: the module whose manifest it is, accepted or refused, every problem the judge
|
||||
// found (none when accepted), the judge that made it (the indexer's build fingerprint) and when.
|
||||
type ManifestVerdict struct {
|
||||
V int `json:"v"`
|
||||
Module string `json:"module"`
|
||||
State string `json:"state"`
|
||||
Problems []string `json:"problems,omitempty"`
|
||||
V int `json:"v"`
|
||||
Module string `json:"module"`
|
||||
State string `json:"state"`
|
||||
Problems []string `json:"problems,omitempty"`
|
||||
// Warnings are the problems a stricter judge found in a manifest it accepted before, digest unchanged (novox/hq ADR
|
||||
// 0579 §1): the verdict stays accepted.
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
Judge string `json:"judge"`
|
||||
At time.Time `json:"at"`
|
||||
}
|
||||
@@ -45,15 +54,7 @@ func (v ManifestVerdict) Refused() bool { return v.State == VerdictRefused }
|
||||
// Same is whether v and o say the same of a manifest: the module, the state and the problems, whoever judged and when.
|
||||
// The indexer writes a verdict only when it is not the same as the one it holds.
|
||||
func (v ManifestVerdict) Same(o ManifestVerdict) bool {
|
||||
if v.Module != o.Module || v.State != o.State || len(v.Problems) != len(o.Problems) {
|
||||
return false
|
||||
}
|
||||
for i := range v.Problems {
|
||||
if v.Problems[i] != o.Problems[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return v.Module == o.Module && v.State == o.State && slices.Equal(v.Problems, o.Problems) && slices.Equal(v.Warnings, o.Warnings)
|
||||
}
|
||||
|
||||
func (v ManifestVerdict) check() error {
|
||||
@@ -69,6 +70,9 @@ func (v ManifestVerdict) check() error {
|
||||
if len(v.Problems) == 0 {
|
||||
return fmt.Errorf("delivery: the verdict on %s refuses its manifest and names no problem", v.Module)
|
||||
}
|
||||
if len(v.Warnings) > 0 {
|
||||
return fmt.Errorf("delivery: the verdict on %s refuses its manifest and warns: a refusal names problems", v.Module)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("delivery: the verdict on %s is %q, neither %s nor %s", v.Module, v.State, VerdictAccepted, VerdictRefused)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ func TestAManifestVerdictIsTheContractReadersTake(t *testing.T) {
|
||||
"another state": {Module: "m", State: "maybe", Judge: "j"},
|
||||
"refused, no problem": {Module: "m", State: VerdictRefused, Judge: "j"},
|
||||
"accepted, a problem": {Module: "m", State: VerdictAccepted, Problems: []string{"x"}, Judge: "j"},
|
||||
"refused, a warning": {Module: "m", State: VerdictRefused, Problems: []string{"x"}, Warnings: []string{"y"}, Judge: "j"},
|
||||
} {
|
||||
if _, err := EncodeManifestVerdict(bad); err == nil {
|
||||
t.Errorf("%s: encoded", name)
|
||||
@@ -62,4 +63,13 @@ func TestAManifestVerdictIsTheContractReadersTake(t *testing.T) {
|
||||
if _, err := EncodeModule(m); err == nil {
|
||||
t.Fatal("a module refused naming no problem was encoded")
|
||||
}
|
||||
// ADR 0579 §1: an accepted manifest a stricter judge outgrew carries its warnings and is taken as accepted.
|
||||
outgrown := ManifestVerdict{Module: "x", State: VerdictAccepted, Warnings: []string{"w"}, Judge: "j"}
|
||||
if _, err := EncodeManifestVerdict(outgrown); err != nil || outgrown.Same(ManifestVerdict{Module: "x", State: VerdictAccepted}) {
|
||||
t.Fatalf("an outgrown verdict: %v", err)
|
||||
}
|
||||
m.Verdict, m.Warnings = "", []string{"w"}
|
||||
if r, _ := TakeManifestVerdict(m.VerdictOf("x")); r || len(m.VerdictOf("x").Warnings) != 1 {
|
||||
t.Fatalf("an outgrown module: %+v", m.VerdictOf("x"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user