diff --git a/contracts/go/seats/meshbuilds/contract.go b/contracts/go/seats/meshbuilds/contract.go index 76437fcc..f95ae661 100644 --- a/contracts/go/seats/meshbuilds/contract.go +++ b/contracts/go/seats/meshbuilds/contract.go @@ -77,11 +77,19 @@ type PackagePublished struct { Version string `json:"version"` } +// ToolchainAgreedDigestsItem is a type of the contract. +type ToolchainAgreedDigestsItem struct { + // the toolchain part's digest + Digest string `json:"digest"` + // the nodes reporting that digest + Nodes []string `json:"nodes"` +} + // ToolchainAgreed is the agreed toolchain of a language changed (design 47 G section 376, ADR 0584 section 1). type ToolchainAgreed struct { At *time.Time `json:"at,omitempty"` - // the toolchain part's digest - Digest string `json:"digest"` + // each digest the nodes reporting the agreed version report, as it stood when the version was agreed, with those nodes (design 47 G section 472, section 495) + Digests []ToolchainAgreedDigestsItem `json:"digests"` // the language whose agreed toolchain changed Language string `json:"language"` V int64 `json:"v"` @@ -91,8 +99,10 @@ type ToolchainAgreed struct { // ReservedInput is what reserved takes. type ReservedInput struct { - // the module - Module string `json:"module"` + // the module; give this or name + Module string `json:"module,omitempty"` + // a package's or an image's name in its ecosystem (the Go module path, the npm name, the image name), in place of module; a name no entry carries, or more than one entry carries, is answered error naming it (design 47 G section 478, section 491) + Name string `json:"name,omitempty"` // the version, when asked for a particular one Version string `json:"version,omitempty"` } diff --git a/contracts/go/seats/meshbuilds/contract_test.go b/contracts/go/seats/meshbuilds/contract_test.go index abbc1cf1..65fb7dfc 100644 --- a/contracts/go/seats/meshbuilds/contract_test.go +++ b/contracts/go/seats/meshbuilds/contract_test.go @@ -19,10 +19,12 @@ func TestFixtures(t *testing.T) { }{ {name: "a package published with the dependencies the build resolved", subject: "mesh.seat.mesh-builds.event.package-published", given: "{\"artifact\":\"mesh-sdk:go\",\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"dependencies\":[{\"artifact\":\"mesh-contracts:go-nodeengine\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":1,\"version\":\"0.1.4\"},{\"artifact\":\"mesh-build-go:toolchain\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":3,\"version\":\"1.26.0\"}],\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"module\":\"mesh-sdk\",\"source\":3589,\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"artifact\":\"mesh-sdk:go\",\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"dependencies\":[{\"artifact\":\"mesh-contracts:go-nodeengine\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":1,\"version\":\"0.1.4\"},{\"artifact\":\"mesh-build-go:toolchain\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":3,\"version\":\"1.26.0\"}],\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"module\":\"mesh-sdk\",\"source\":3589,\"v\":1,\"version\":\"0.1.15\"}", decode: func(b []byte) (any, error) { var v PackagePublishedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.package-published$")}, - {name: "a toolchain agreed", subject: "mesh.seat.mesh-builds.event.toolchain-agreed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", + {name: "a toolchain agreed", subject: "mesh.seat.mesh-builds.event.toolchain-agreed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"ace\",\"g14\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"novox\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"ace\",\"g14\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"novox\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", decode: func(b []byte) (any, error) { var v ToolchainAgreedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.toolchain-agreed$")}, {name: "reserved asks a module", subject: "", given: "{\"module\":\"mesh-sdk\"}", wire: "{\"module\":\"mesh-sdk\"}", decode: func(b []byte) (any, error) { var v ReservedInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "reserved asks a package by its name", subject: "", given: "{\"name\":\"git.novox.be/novox/mesh-sdk/go\",\"version\":\"0.1.15\"}", wire: "{\"name\":\"git.novox.be/novox/mesh-sdk/go\",\"version\":\"0.1.15\"}", + decode: func(b []byte) (any, error) { var v ReservedInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "reserved answers the version and each artifact's digest", subject: "", given: "{\"artifacts\":[{\"artifact\":\"mesh-sdk:go\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"},{\"artifact\":\"mesh-sdk:ts\"}],\"module\":\"mesh-sdk\",\"version\":\"0.1.15\"}", wire: "{\"artifacts\":[{\"artifact\":\"mesh-sdk:go\",\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"},{\"artifact\":\"mesh-sdk:ts\"}],\"module\":\"mesh-sdk\",\"version\":\"0.1.15\"}", decode: func(b []byte) (any, error) { var v ReservedAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, } diff --git a/contracts/seats/mesh-builds/fixtures/events.json b/contracts/seats/mesh-builds/fixtures/events.json index 25c23b77..44192577 100644 --- a/contracts/seats/mesh-builds/fixtures/events.json +++ b/contracts/seats/mesh-builds/fixtures/events.json @@ -36,7 +36,21 @@ "v": 1, "language": "go", "version": "1.26.0", - "digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "digests": [ + { + "digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + "nodes": [ + "ace", + "g14" + ] + }, + { + "digest": "sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", + "nodes": [ + "novox" + ] + } + ], "at": "2026-11-10T10:00:00Z" } } diff --git a/contracts/seats/mesh-builds/fixtures/verbs.json b/contracts/seats/mesh-builds/fixtures/verbs.json index 668a960c..b8c50afb 100644 --- a/contracts/seats/mesh-builds/fixtures/verbs.json +++ b/contracts/seats/mesh-builds/fixtures/verbs.json @@ -6,6 +6,14 @@ "module": "mesh-sdk" } }, + { + "name": "reserved asks a package by its name", + "of": "verb:reserved.input", + "given": { + "name": "git.novox.be/novox/mesh-sdk/go", + "version": "0.1.15" + } + }, { "name": "reserved answers the version and each artifact's digest", "of": "verb:reserved.answer", diff --git a/contracts/seats/mesh-builds/seat.json b/contracts/seats/mesh-builds/seat.json index cfae1a92..29e6a5c3 100644 --- a/contracts/seats/mesh-builds/seat.json +++ b/contracts/seats/mesh-builds/seat.json @@ -16,22 +16,24 @@ "seat:container-image-registry", "seat:oci-artifact-registry" ], - "description": "A module's reserved version with each artifact's digest, for a registry holder deciding whether to publish (design 47 G section 369; design 51, Publishing).", + "description": "A module's reserved version with each artifact's digest, for a registry holder deciding whether to publish; asked by the module or by a package's name in its ecosystem (design 47 G section 369, section 478; design 51, Publishing).", "input": { "type": "object", "properties": { "module": { "type": "string", - "description": "the module" + "description": "the module; give this or name" + }, + "name": { + "type": "string", + "description": "a package's or an image's name in its ecosystem (the Go module path, the npm name, the image name), in place of module; a name no entry carries, or more than one entry carries, is answered error naming it (design 47 G section 478, section 491)" }, "version": { "type": "string", "description": "the version, when asked for a particular one" } }, - "required": [ - "module" - ] + "required": [] }, "answer": { "type": "object", @@ -198,9 +200,29 @@ "type": "string", "description": "the agreed toolchain's version" }, - "digest": { - "type": "string", - "description": "the toolchain part's digest" + "digests": { + "type": "array", + "description": "each digest the nodes reporting the agreed version report, as it stood when the version was agreed, with those nodes (design 47 G section 472, section 495)", + "items": { + "type": "object", + "properties": { + "digest": { + "type": "string", + "description": "the toolchain part's digest" + }, + "nodes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "the nodes reporting that digest" + } + }, + "required": [ + "digest", + "nodes" + ] + } }, "at": { "type": "string", @@ -211,7 +233,7 @@ "v", "language", "version", - "digest" + "digests" ], "description": "the agreed toolchain of a language changed (design 47 G section 376, ADR 0584 section 1)" } diff --git a/contracts/ts/seats/meshbuilds/index.d.ts b/contracts/ts/seats/meshbuilds/index.d.ts index 5c6dfedc..9732e7cd 100644 --- a/contracts/ts/seats/meshbuilds/index.d.ts +++ b/contracts/ts/seats/meshbuilds/index.d.ts @@ -55,11 +55,18 @@ export interface PackagePublished { "version": string; } +export interface ToolchainAgreedDigestsItem { + /** the toolchain part's digest */ + "digest": string; + /** the nodes reporting that digest */ + "nodes": string[]; +} + /** the agreed toolchain of a language changed (design 47 G section 376, ADR 0584 section 1) */ export interface ToolchainAgreed { "at"?: string; - /** the toolchain part's digest */ - "digest": string; + /** each digest the nodes reporting the agreed version report, as it stood when the version was agreed, with those nodes (design 47 G section 472, section 495) */ + "digests": ToolchainAgreedDigestsItem[]; /** the language whose agreed toolchain changed */ "language": string; "v": number; @@ -69,8 +76,10 @@ export interface ToolchainAgreed { /** is what reserved takes. */ export interface ReservedInput { - /** the module */ - "module": string; + /** the module; give this or name */ + "module"?: string; + /** a package's or an image's name in its ecosystem (the Go module path, the npm name, the image name), in place of module; a name no entry carries, or more than one entry carries, is answered error naming it (design 47 G section 478, section 491) */ + "name"?: string; /** the version, when asked for a particular one */ "version"?: string; }