J3 (A2f findings 2, 4): a leaving module's accepted event is named by its module; a user naming no series accepts the first numbered one

ManifestAccepted.EventID names the module when the digest is empty, so the indexer's own id for a module leaving the
trunk can go and the id lives in one place. Manifest.AcceptedSeries takes the series the package has a numbered
version in and answers the lowest, the series of its first numbered version (design 32), DefaultSeries while none is.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 14:25:25 +01:00
parent 5bb0662d19
commit 1a3ef8101f
4 changed files with 41 additions and 5 deletions
+1
View File
@@ -145,6 +145,7 @@ func TestAConfigManifestIsWrittenBackInItsOwnForm(t *testing.T) {
}
if m.Settings["font"].RenamedFrom != "font-name" || m.AcceptedSeries("mesh-sdk") != "0.2" ||
m.AcceptedSeries("mesh-contracts") != DefaultSeries || m.Build.Artifacts[0].SeriesOf() != "0.2" ||
m.AcceptedSeries("mesh-sdk", "0.1") != "0.2" || m.AcceptedSeries("mesh-contracts", "0.10", "x", "0.3", "1.0") != "0.3" ||
m.Build.Artifacts[0].GeneratedFrom != "seats" || m.Build.Artifacts[1].SeriesOf() != "0.1" {
t.Fatalf("read %+v", m)
}
+30 -4
View File
@@ -1243,13 +1243,39 @@ type Artifact struct {
GeneratedFrom string `json:"generated-from,omitempty"`
}
// AcceptedSeries is the series of the package of that name this module accepts: the one Packages names, or
// DefaultSeries.
func (m Manifest) AcceptedSeries(name string) string {
// AcceptedSeries is the series of the package of that name this module accepts: the one Packages names, or else the
// series of the package's first numbered version (design 32), the lowest of numbered, the series the package has a
// numbered version in (the indexer's to say; a series is only ever raised); DefaultSeries while none is numbered.
func (m Manifest) AcceptedSeries(name string, numbered ...string) string {
if s := m.Packages[name]; s != "" {
return s
}
return DefaultSeries
first := ""
for _, s := range numbered {
if seriesOrder(s) != nil && (first == "" || compareSeries(s, first) < 0) {
first = s
}
}
if first == "" {
return DefaultSeries
}
return first
}
// seriesOrder is a series' major and minor, or nil when it is no `<major>.<minor>`.
func seriesOrder(s string) []int {
major, minor, ok := strings.Cut(s, ".")
a, err1 := strconv.Atoi(major)
b, err2 := strconv.Atoi(minor)
if !ok || err1 != nil || err2 != nil || a < 0 || b < 0 {
return nil
}
return []int{a, b}
}
// compareSeries orders two well-formed series by major, then minor.
func compareSeries(a, b string) int {
return slices.Compare(seriesOrder(a), seriesOrder(b))
}
// DefaultSeries is the series of an artifact or an accepted package that names none (design 32).
+5 -1
View File
@@ -234,7 +234,11 @@ func AcceptedOf(digest string, v ManifestVerdict, m catalogue.Manifest) Manifest
}
// EventID is the event's id, one per manifest digest and judge, so the bus takes it once:
// `manifest-accepted-<digest>-<judge>`.
// `manifest-accepted-<digest>-<judge>`. The empty one of a module leaving the trunk carries no digest, so it is named by
// its module: `manifest-accepted-left-<module>-<judge>`.
func (a ManifestAccepted) EventID() string {
if a.Digest == "" {
return ManifestAcceptedEvent + "-left-" + a.Module + "-" + a.Judge
}
return ManifestAcceptedEvent + "-" + a.Digest + "-" + a.Judge
}
+5
View File
@@ -103,6 +103,11 @@ 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)
}
// The empty one of a module leaving the trunk has no digest: its id names the module, so two modules' differ.
if a, b := (ManifestAccepted{Module: "a", Judge: "j"}).EventID(), (ManifestAccepted{Module: "b", Judge: "j"}).EventID(); a == b ||
a != "manifest-accepted-left-a-j" {
t.Fatalf("the ids of two modules leaving are %q and %q", a, b)
}
// 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)