Catalogue: the store's seats deliver nothing, and a seat's reach is the reader capability form:seat-reach (ADR 0632 §1, §2; issue 1966)
CanHold asks the store's holder no provision once the seats stop delivering
artifact-store; a manifest naming ${seat:<seat>:reach} needs an engine that
fills it from the seat holder's listen, so the delivery holds it from one
that does not.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -17,7 +17,11 @@ func TestRenamingASeatDidNotRenameTheInterfaceItDelivers(t *testing.T) {
|
||||
for _, pair := range []struct{ seat, delivers string }{
|
||||
{"git", "git"},
|
||||
{"npm-package-registry", "npm-package-registry"},
|
||||
{"mesh-artifact-store", "artifact-store"},
|
||||
// The store's seats deliver nothing since the provision artifact-store retired (novox/hq ADR 0632 §2): the
|
||||
// store's address is its holder's listen, read through the seat.
|
||||
{"mesh-artifact-store", ""},
|
||||
{"container-image-registry", ""},
|
||||
{"oci-artifact-registry", ""},
|
||||
{"mesh-store", "postgres-database"},
|
||||
{"mesh-broker", "mesh-bus"},
|
||||
} {
|
||||
|
||||
@@ -1331,12 +1331,10 @@ const (
|
||||
ArtifactPackage = "package"
|
||||
)
|
||||
|
||||
// ArtifactStoreProvision is the name a module offers when it is the mesh's store for what modules
|
||||
// ship — images, and archives, which are directories from a repository packed as blobs.
|
||||
//
|
||||
// Named here because a rule depends on it: what provides this cannot be delivered through it
|
||||
// (novox/hq 04-ISSUES/029). A string compared in one place is a convention; a string a rule turns
|
||||
// on is a fact, and it should be written once.
|
||||
// ArtifactStoreProvision is the name the mesh's store for what modules ship (images, and archives,
|
||||
// which are directories from a repository packed as blobs) was offered under until the provision
|
||||
// retired (novox/hq ADR 0632 §2): no seat delivers it and no module provides it. It stays as the
|
||||
// scheme of the older reference form, artifact-store://, which done keys keep (ArtifactStoreScheme).
|
||||
const ArtifactStoreProvision = "artifact-store"
|
||||
|
||||
// Listening is one endpoint a module serves: a port it accepts connections on, and what may be said
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -47,6 +48,16 @@ const ReferenceFormSeat = "seat-reference"
|
||||
// artifactReferenceForms are the reference forms of a build's artifacts this contract reads beyond the baseline's.
|
||||
var artifactReferenceForms = []string{ReferenceFormSeat}
|
||||
|
||||
// ReferenceFormSeatReach names how a node-engine built with this contract fills `${seat:<seat>:reach}`, as the reader
|
||||
// capability `form:seat-reach` (novox/hq ADR 0632 §1): from the seat holder placement names and the listen its manifest
|
||||
// opens to the mesh, the store's three seats among them, never from a module serving the retired provision
|
||||
// artifact-store. An engine before it filled the store's reach only from that provision, so a manifest naming a seat's
|
||||
// reach needs it and is held from a node whose engine does not state it (ManifestNeeds).
|
||||
const ReferenceFormSeatReach = "seat-reach"
|
||||
|
||||
// ofSeatReach is a manifest's value naming a seat's reach, `${seat:<seat>:reach}`.
|
||||
var ofSeatReach = regexp.MustCompile(`\$\{seat:[a-z0-9][a-z0-9-]*:reach\}`)
|
||||
|
||||
// manifestTopWords are the top-level keys Manifest.UnmarshalJSON reads apart from the fields of manifestFields: each
|
||||
// read whole, its inside a map of the module's own names (requirements, local names) and values, no words of the
|
||||
// contract's beneath it. `requires` and `config` are read as their fields are (manifestNeeds).
|
||||
@@ -73,6 +84,7 @@ func ManifestReads() []string {
|
||||
for _, f := range artifactReferenceForms {
|
||||
set[ReadForm+f] = true
|
||||
}
|
||||
set[ReadForm+ReferenceFormSeatReach] = true
|
||||
for _, s := range DefaultSeats() {
|
||||
set[ReadSeat+s.Name] = true
|
||||
}
|
||||
@@ -139,6 +151,9 @@ func ManifestNeeds(raw []byte) ([]string, error) {
|
||||
used[ReadForm+f] = true
|
||||
}
|
||||
}
|
||||
if ofSeatReach.Match(raw) {
|
||||
used[ReadForm+ReferenceFormSeatReach] = true
|
||||
}
|
||||
if _, has := top[ConfigField]; has || takesConfigKey.Match(raw) {
|
||||
used[ReadForm+"config"] = true
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestOwnManifestUsesNoWordTheRunningControllerRefuses(t *testing.T) {
|
||||
}
|
||||
for _, want := range []string{"word:tool-runner", "word:core-credentials", "word:bus-state", "word:bus-state.storage",
|
||||
// The reference form a registry seat answers (ADR 0605 §9), and the seats the registry milestone adds.
|
||||
ReadForm + ReferenceFormSeat, "seat:go-package-registry", "seat:container-image-registry", "seat:oci-artifact-registry"} {
|
||||
ReadForm + ReferenceFormSeat, ReadForm + ReferenceFormSeatReach, "seat:go-package-registry", "seat:container-image-registry", "seat:oci-artifact-registry"} {
|
||||
if !slices.Contains(added, want) {
|
||||
t.Errorf("%s is in the baseline, or not read: added since it are %v", want, added)
|
||||
}
|
||||
@@ -79,6 +79,9 @@ func TestOwnManifestUsesNoWordTheRunningControllerRefuses(t *testing.T) {
|
||||
"word:provides.identity.max", "word:resources"}, nil},
|
||||
{"a bus-state entry of requires", `{"module":"b","version":"1","requires":["mesh-bus",{"name":"jobs","storage":"kv"}]}`,
|
||||
[]string{"word:requires", "word:bus-state.storage"}, []string{"word:bus-state", "word:bus-state.name", "word:bus-state.storage"}},
|
||||
// A seat's reach, filled from the seat holder's listen (ADR 0632 §1): an engine before it lacks the reading.
|
||||
{"a seat's reach", `{"module":"s","version":"1","resources":[{"id":"f","type":"file","content":"${seat:container-image-registry:reach}"}]}`,
|
||||
[]string{"form:seat", "form:seat-reach"}, []string{"form:seat-reach"}},
|
||||
{"a word this contract does not know", `{"module":"u","version":"1","newer-word":{"inside":1}}`, []string{"word:module"}, nil},
|
||||
} {
|
||||
needs, err := ManifestNeeds([]byte(row.raw))
|
||||
|
||||
@@ -61,6 +61,8 @@ func TestUseSeatsReplacesTheSetButNeverEmptiesIt(t *testing.T) {
|
||||
// A verb whose input the whole definition corrected: compose-candidate's input is the boolean the engine and the
|
||||
// checker read, where the compiled list said a word (engine_compose_candidate_test.go reads it).
|
||||
retyped := map[string]bool{"node-engine.compose-candidate": true}
|
||||
// A seat whose provision retired delivers nothing since: the store's, artifact-store (ADR 0632 §2).
|
||||
retired := map[string]bool{"mesh-artifact-store": true}
|
||||
norm := func(v any) any {
|
||||
b, _ := json.Marshal(v)
|
||||
var out any
|
||||
@@ -75,6 +77,9 @@ func TestUseSeatsReplacesTheSetButNeverEmptiesIt(t *testing.T) {
|
||||
t.Errorf("%s left the generated set", want.Name)
|
||||
continue
|
||||
}
|
||||
if retired[want.Name] {
|
||||
want.Delivers = ""
|
||||
}
|
||||
g := golden{Seat: got}
|
||||
for _, v := range got.Serves {
|
||||
if v.Optional {
|
||||
|
||||
Reference in New Issue
Block a user