SDK-4, SDK-5, SDK-6, SDK-7: the manifest words of series, accepted packages, a renamed config value and the contracts marker (design 32, design 26)

Artifact.Series and SeriesOf (0.1 when absent); Manifest.Packages and AcceptedSeries; a config declaration's
renamed-from, written back in the config form; a package's generated-from. One round-trip case covers the four, in
the config form's existing test; the judge's rules on them are the indexer's (DLV-I13..I16).

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 12:09:19 +01:00
parent c9fec158cb
commit 8a84711792
4 changed files with 70 additions and 1 deletions
+2 -1
View File
@@ -114,6 +114,7 @@ type configDeclaration struct {
Default any `json:"default,omitempty"`
Required bool `json:"required,omitempty"`
Runtime bool `json:"runtime,omitempty"`
RenamedFrom string `json:"renamed-from,omitempty"`
}
// MarshalJSON writes a settings declaration exactly as before, and a config declaration without the settings
@@ -125,7 +126,7 @@ func (d SettingDeclaration) MarshalJSON() ([]byte, error) {
}
return json.Marshal(configDeclaration{Type: d.Type, Description: d.Description, Enum: d.Enum,
Minimum: d.Minimum, Maximum: d.Maximum, Pattern: d.Pattern, Trusted: d.Trusted, Predefined: d.Predefined,
Default: d.Default, Required: d.Required, Runtime: d.Runtime})
Default: d.Default, Required: d.Required, Runtime: d.Runtime, RenamedFrom: d.RenamedFrom})
}
// validationProblems is what is wrong with a declaration's validation, and its default against it.
+26
View File
@@ -132,6 +132,32 @@ func TestAConfigManifestIsWrittenBackInItsOwnForm(t *testing.T) {
if !bytes.Equal(raw, twice) {
t.Fatalf("read again it is written\n%s\nwhere it was\n%s", twice, raw)
}
// The registry milestone's words round-trip the same (design 32): a config value's old name, an artifact's series
// and contracts marker, the series a module accepts of a package; absent, a series is 0.1.
declared := []byte(`{"module":"c","version":"1","config":{"font":{"type":"string","renamed-from":"font-name"}},
"packages":{"mesh-sdk":"0.2"},
"build":{"artifacts":[{"name":"go","kind":"package","language":"go","paths":["go"],"series":"0.2",
"generated-from":"seats"},{"name":"lib","kind":"package","language":"typescript"}]}}`)
m, err = decodeForTest(declared)
if err != nil {
t.Fatal(err)
}
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.Build.Artifacts[0].GeneratedFrom != "seats" || m.Build.Artifacts[1].SeriesOf() != "0.1" {
t.Fatalf("read %+v", m)
}
raw, _ = json.Marshal(m)
for _, said := range []string{`"renamed-from":"font-name"`, `"packages":{"mesh-sdk":"0.2"}`, `"series":"0.2"`,
`"generated-from":"seats"`} {
if !strings.Contains(string(raw), said) {
t.Errorf("written back without %s: %s", said, raw)
}
}
if strings.Count(string(raw), `"series"`) != 1 {
t.Errorf("a series nobody said is written: %s", raw)
}
}
// A module in the settings form is written back byte for byte as before.
+37
View File
@@ -469,6 +469,11 @@ type Manifest struct {
// this is for the rest — `zsh` provides `shell`, `xorg` provides `display-server`.
Provides []Offer `json:"provides,omitempty"`
// Packages are the series of each mesh package this module accepts, by the package's name (novox/hq ADR 0606,
// design 32): its fingerprint takes the newest version of that series, and a publish of another series moves it
// not. A package it uses and does not name is accepted in DefaultSeries (AcceptedSeries).
Packages map[string]string `json:"packages,omitempty"`
// Requires are names that must be provided by something assigned to the same node.
Requires []string `json:"requires,omitempty"`
// OptionalRequires is which of Requires the module can run without (novox/hq ADR 0330): filled
@@ -1224,6 +1229,38 @@ type Artifact struct {
// paths and constants composed with ${dir:…} and ${port:…} exactly as a container's environment
// is, never a secret's content. The node's runtime hands it to this bundle and to no other.
Env map[string]string `json:"env,omitempty"`
// Series is the series this artifact's versions are numbered in, `<major>.<minor>` (novox/hq ADR 0606, design 32):
// the builder numbers `<series>.<n>`, so a change of series is a change a user accepts by its own `packages`.
// Said on a package, an image, a bundle or an archive; the judge refuses it on any other kind. Absent is
// DefaultSeries (SeriesOf).
Series string `json:"series,omitempty"`
// GeneratedFrom marks a package of a contracts module (novox/hq ADR 0608 §5, design 26 *Contracts modules*): the
// directory, relative to the module's, of the seat definitions every file of the package is generated from. A
// module carrying it holds contracts only and claims no seat, which the judge refuses naming the seat; the build
// modules' test step regenerates the package and fails on a file out of step.
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 {
if s := m.Packages[name]; s != "" {
return s
}
return DefaultSeries
}
// DefaultSeries is the series of an artifact or an accepted package that names none (design 32).
const DefaultSeries = "0.1"
// SeriesOf is the series the artifact's versions are numbered in: its own, or DefaultSeries.
func (a Artifact) SeriesOf() string {
if a.Series == "" {
return DefaultSeries
}
return a.Series
}
// Kinds an artifact may be.
+5
View File
@@ -31,6 +31,11 @@ type SettingDeclaration struct {
Required bool `json:"required,omitempty"`
// Runtime is a value the module's code reads at runtime rather than one placed in a file (ADR 0348 §5).
Runtime bool `json:"runtime,omitempty"`
// RenamedFrom is the value's old name, a config value of this module's own (novox/hq ADR 0609 §4, design 32 *A
// config value renamed*): on the merge mesh-config moves the value held under it to this name, and answers both
// names until every node-engine reports a build reading the new one. The config form only: the judge refuses it
// under `settings`, on a secret, and where it changes the value's trust.
RenamedFrom string `json:"renamed-from,omitempty"`
}
// KindPreference is the kind of a setting that may have a default.