Catalogue: the store holder's manifest needs form:seat-reach (ADR 0632 §2; issue 1966)
It is read on every node and leaves an engine before the reading without the old way to find the store. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -52,9 +52,26 @@ var artifactReferenceForms = []string{ReferenceFormSeat}
|
|||||||
// capability `form:seat-reach` (novox/hq ADR 0632 §1): from the seat holder placement names and the listen its manifest
|
// 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
|
// 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
|
// 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).
|
// reach, and the store holder's own manifest, need it and are held from a node whose engine does not state it
|
||||||
|
// (ManifestNeeds).
|
||||||
const ReferenceFormSeatReach = "seat-reach"
|
const ReferenceFormSeatReach = "seat-reach"
|
||||||
|
|
||||||
|
// claimsAtMesh says whether a manifest claims seat at the mesh's scope (a claim with no scope is the seat's own). The
|
||||||
|
// store holder's own manifest, a claim of ContainerImageRegistrySeat, needs form:seat-reach this way (ADR 0632 §2): read
|
||||||
|
// on every node, it leaves an engine before the reading without the old way to find the store, so it is held from every
|
||||||
|
// node whose engine does not state it.
|
||||||
|
func claimsAtMesh(top map[string]any, seat string) bool {
|
||||||
|
for _, c := range asList(top["claims"]) {
|
||||||
|
obj, _ := c.(map[string]any)
|
||||||
|
name, _ := obj["name"].(string)
|
||||||
|
scope, _ := obj["scope"].(string)
|
||||||
|
if hs, ok := SeatNamed(name); ok && hs.Name == seat && (scope == "" || scope == ScopeMesh) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ofSeatReach is a manifest's value naming a seat's reach, `${seat:<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\}`)
|
var ofSeatReach = regexp.MustCompile(`\$\{seat:[a-z0-9][a-z0-9-]*:reach\}`)
|
||||||
|
|
||||||
@@ -151,7 +168,7 @@ func ManifestNeeds(raw []byte) ([]string, error) {
|
|||||||
used[ReadForm+f] = true
|
used[ReadForm+f] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ofSeatReach.Match(raw) {
|
if ofSeatReach.Match(raw) || claimsAtMesh(top, ContainerImageRegistrySeat) {
|
||||||
used[ReadForm+ReferenceFormSeatReach] = true
|
used[ReadForm+ReferenceFormSeatReach] = true
|
||||||
}
|
}
|
||||||
if _, has := top[ConfigField]; has || takesConfigKey.Match(raw) {
|
if _, has := top[ConfigField]; has || takesConfigKey.Match(raw) {
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ func TestOwnManifestUsesNoWordTheRunningControllerRefuses(t *testing.T) {
|
|||||||
// 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, 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}"}]}`,
|
{"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"}},
|
[]string{"form:seat", "form:seat-reach"}, []string{"form:seat-reach"}},
|
||||||
|
// The store holder's manifest, distribution's as ADR 0632 leaves it: no reach written, no provision served; an engine
|
||||||
|
// stating only the baseline lacks the reading that finds the store by it (ADR 0632 §2).
|
||||||
|
{"the store's holder", `{"module":"distribution","version":"1","claims":[{"name":"container-image-registry",` +
|
||||||
|
`"scope":"mesh","serves":["list"]}],"listens":[{"name":"registry","port":5000,"from":"mesh"}]}`,
|
||||||
|
[]string{"form:seat-reach", "seat:container-image-registry"}, []string{"form:seat-reach", "seat:container-image-registry"}},
|
||||||
{"a word this contract does not know", `{"module":"u","version":"1","newer-word":{"inside":1}}`, []string{"word:module"}, nil},
|
{"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))
|
needs, err := ManifestNeeds([]byte(row.raw))
|
||||||
|
|||||||
Reference in New Issue
Block a user