seatdef: a definition names its glossary domain, one of the eleven headings (ADR 0636 §5; issue 1966)

This commit is contained in:
2026-11-05 14:30:56 +01:00
parent 8dcdc9b2a4
commit a0480588ce
74 changed files with 103 additions and 17 deletions
+14
View File
@@ -17,6 +17,7 @@ import (
"errors"
"fmt"
"regexp"
"slices"
"sort"
"strings"
)
@@ -41,6 +42,10 @@ const (
ScopeNode = "node"
)
// Domains are the glossary's domains that own a seat, by their headings (hq 00-META/glossary.md, ADR 0244).
var Domains = []string{"Module", "Config", "Core", "Placement", "Provisioning", "Identity and access", "Delivery",
"Health and repair", "Data", "Connectivity", "Operator and conversation"}
// Definition is one seat's contract.
type Definition struct {
Format int `json:"format"`
@@ -49,6 +54,9 @@ type Definition struct {
Grain string `json:"grain"`
// Decision is the record that made it a seat.
Decision string `json:"decision"`
// Domain is the glossary domain the seat belongs to, by its heading (ADR 0636 §5): the indexer takes a seat of the
// mesh's own contracts only from that domain's contracts module.
Domain string `json:"domain"`
// Description says the role in one paragraph, for a person reading the definition.
Description string `json:"description,omitempty"`
// HolderDeclares says the seat is not in the mesh's compiled seat list: its holder's manifest declares it as a
@@ -398,6 +406,12 @@ func (d Definition) check() Problems {
if d.Decision == "" {
ps = append(ps, Problem{"decision", "missing"})
}
switch {
case d.Domain == "":
ps = append(ps, Problem{"domain", "missing"})
case !slices.Contains(Domains, d.Domain):
ps = append(ps, Problem{"domain", fmt.Sprintf("%q is not a domain of the glossary (%s)", d.Domain, strings.Join(Domains, ", "))})
}
whole := d.Grain == Whole
if !whole && (len(d.Includes) > 0 || d.Family != nil || len(d.HolderEvents) > 0 || len(d.States) > 0 ||
len(d.Provisions) > 0 || len(d.Defs) > 0) {
+17 -15
View File
@@ -9,9 +9,9 @@ import (
// TestADefinitionIsReadStrictlyNamingWhatIsWrong is the format's own table (design 26: a valid definition parses;
// each missing required field is refused naming it; one over 256 KiB is refused), with the parts and fixtures beside.
func TestADefinitionIsReadStrictlyNamingWhatIsWrong(t *testing.T) {
const listGrain = `{"format":1,"seat":"node-hostname","scope":"node","grain":"seat-list","decision":"ADR 1",
const listGrain = `{"format":1,"seat":"node-hostname","scope":"node","grain":"seat-list","domain":"Core","decision":"ADR 1",
"verbs":[{"name":"add","input":{"type":"object"}}]}`
const whole = `{"format":1,"seat":"mesh-broker","scope":"mesh","grain":"whole","decision":"ADR 1",
const whole = `{"format":1,"seat":"mesh-broker","scope":"mesh","grain":"whole","domain":"Core","decision":"ADR 1",
"verbs":[{"name":"list","input":{"type":"object"},"answer":{"type":"object"}}],
"events":[{"name":"created","body":{"type":"object"}}],"family":{"name":"broker.events","max-age-days":7}}`
cases := []struct {
@@ -20,14 +20,16 @@ func TestADefinitionIsReadStrictlyNamingWhatIsWrong(t *testing.T) {
}{
{"the seat list's grain parses", listGrain, ""},
{"a whole definition parses", whole, ""},
{"no format", `{"seat":"a-b","scope":"mesh","grain":"seat-list","decision":"x"}`, "format: missing"},
{"a later format", `{"format":2,"seat":"a-b","scope":"mesh","grain":"seat-list","decision":"x"}`, "format 2"},
{"no seat", `{"format":1,"scope":"mesh","grain":"seat-list","decision":"x"}`, "seat: missing"},
{"no scope", `{"format":1,"seat":"a-b","grain":"seat-list","decision":"x"}`, "scope: missing"},
{"another scope", `{"format":1,"seat":"a-b","scope":"room","grain":"seat-list","decision":"x"}`, "scope"},
{"no grain", `{"format":1,"seat":"a-b","scope":"mesh","decision":"x"}`, "grain: missing"},
{"no format", `{"seat":"a-b","scope":"mesh","grain":"seat-list","domain":"Core","decision":"x"}`, "format: missing"},
{"a later format", `{"format":2,"seat":"a-b","scope":"mesh","grain":"seat-list","domain":"Core","decision":"x"}`, "format 2"},
{"no seat", `{"format":1,"scope":"mesh","grain":"seat-list","domain":"Core","decision":"x"}`, "seat: missing"},
{"no scope", `{"format":1,"seat":"a-b","grain":"seat-list","domain":"Core","decision":"x"}`, "scope: missing"},
{"another scope", `{"format":1,"seat":"a-b","scope":"room","grain":"seat-list","domain":"Core","decision":"x"}`, "scope"},
{"no grain", `{"format":1,"seat":"a-b","scope":"mesh","domain":"Core","decision":"x"}`, "grain: missing"},
{"no decision", `{"format":1,"seat":"a-b","scope":"mesh","grain":"seat-list"}`, "decision: missing"},
{"an unknown field", `{"format":1,"seat":"a-b","scope":"mesh","grain":"seat-list","decision":"x","sevres":[]}`,
{"no domain", `{"format":1,"seat":"a-b","scope":"mesh","grain":"seat-list","decision":"x"}`, "domain: missing"},
{"a domain the glossary lacks", `{"format":1,"seat":"a-b","scope":"mesh","grain":"seat-list","domain":"Weather","decision":"x"}`, "domain"},
{"an unknown field", `{"format":1,"seat":"a-b","scope":"mesh","grain":"seat-list","domain":"Core","decision":"x","sevres":[]}`,
"sevres: a field the format does not know"},
{"a whole verb with no answer", strings.Replace(whole, `,"answer":{"type":"object"}`, "", 1),
"verbs[0].answer: missing"},
@@ -50,10 +52,10 @@ func TestADefinitionIsReadStrictlyNamingWhatIsWrong(t *testing.T) {
{"a holder's event on a subject of no module", strings.Replace(whole, `"family":`, `"holder-events":[{"name":"verdict",`+
`"subject":"mesh.event.verdict"}],"family":`, 1), "holder-events[0].subject: not mesh.mod.<holder>.event.verdict"},
{"a verb twice", strings.Replace(listGrain, `]}`, `,{"name":"add"}]}`, 1), `"add" twice`},
{"states at the seat list's grain", strings.Replace(listGrain, `"decision":"ADR 1",`,
`"decision":"ADR 1","states":[{"name":"asks"}],`, 1), "grain: seat-list holds"},
{"the old records field is gone", strings.Replace(whole, `"decision":"ADR 1",`,
`"decision":"ADR 1","records":[{"name":"asks"}],`, 1), "records: a field the format does not know"},
{"states at the seat list's grain", strings.Replace(listGrain, `"domain":"Core","decision":"ADR 1",`,
`"domain":"Core","decision":"ADR 1","states":[{"name":"asks"}],`, 1), "grain: seat-list holds"},
{"the old records field is gone", strings.Replace(whole, `"domain":"Core","decision":"ADR 1",`,
`"domain":"Core","decision":"ADR 1","records":[{"name":"asks"}],`, 1), "records: a field the format does not know"},
{"a state with a key form and a value", withState(whole, `{"name":"asks","template":"state","writer":"caller",
"history":3,"key-forms":[{"key":"<asker>.<id>","value":{"type":"object"}}]}`), ""},
{"a stream state with an age", withState(whole, `{"name":"placement","template":"events","max-age-days":7,
@@ -98,7 +100,7 @@ func TestADefinitionIsReadStrictlyNamingWhatIsWrong(t *testing.T) {
if err != nil {
t.Fatal(err)
}
d, err := Parse([]byte(strings.Replace(whole, `"decision":"ADR 1",`, `"decision":"ADR 1","includes":["registry"],`, 1)))
d, err := Parse([]byte(strings.Replace(whole, `"domain":"Core","decision":"ADR 1",`, `"domain":"Core","decision":"ADR 1","includes":["registry"],`, 1)))
if err != nil {
t.Fatal(err)
}
@@ -145,5 +147,5 @@ func withState(def, state string) string {
if strings.Contains(def, `"states":[`) {
return strings.Replace(def, `"states":[`, `"states":[`+state+`,`, 1)
}
return strings.Replace(def, `"decision":"ADR 1",`, `"decision":"ADR 1","states":[`+state+`],`, 1)
return strings.Replace(def, `"domain":"Core","decision":"ADR 1",`, `"domain":"Core","decision":"ADR 1","states":[`+state+`],`, 1)
}
+1
View File
@@ -3,6 +3,7 @@
"seat": "mesh-broker",
"scope": "mesh",
"grain": "whole",
"domain": "Core",
"decision": "novox/hq ADR 0079",
"delivers": "mesh-bus",
"description": "The mesh's bus, and the bus state modules ask of it in requires (design 25 § 12). create, apply, recreate and drop are granted to the bus module's own credential alone.",
+1
View File
@@ -3,6 +3,7 @@
"seat": "mesh-catalog",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0636",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-conditions",
"scope": "mesh",
"grain": "whole",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564, ADR 0634, ADR 0635",
"description": "What is wrong with the mesh now (ADR 0564): the open conditions raised from the observers' findings and cleared when a finding goes.",
"verbs": [
+1
View File
@@ -3,6 +3,7 @@
"seat": "mesh-config",
"scope": "mesh",
"grain": "whole",
"domain": "Config",
"decision": "novox/hq ADR 0348, ADR 0565",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-delivery-checker",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0547",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-hand-acts",
"scope": "mesh",
"grain": "whole",
"domain": "Health and repair",
"decision": "novox/hq ADR 0565, ADR 0634, ADR 0635",
"description": "Acts done by hand, recorded with who, why and cause (ADR 0565): the log every module records through.",
"verbs": [
@@ -3,6 +3,7 @@
"seat": "mesh-watchdogs",
"scope": "mesh",
"grain": "whole",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564, ADR 0634, ADR 0635",
"description": "The watchman's seat (ADR 0564, ADR 0433): signals that expire unless renewed, what stopped moving, who is present, the dead letters.",
"verbs": [
+1
View File
@@ -3,6 +3,7 @@
"seat": "node-backup",
"scope": "node",
"grain": "seat-list",
"domain": "Data",
"decision": "novox/hq ADR 0214",
"verbs": [
{
+1
View File
@@ -3,6 +3,7 @@
"seat": "node-engine",
"scope": "node",
"grain": "whole",
"domain": "Core",
"decision": "novox/hq ADR 0563",
"description": "The node seat every node's engine holds (novox/hq ADR 0563, ADR 0618 §3, §4): its hand acts on the operator's warrant, its read-only judgements, its compositions and what it reads of a manifest. Each verb is answered on this node's subject, mesh.seat.node-engine.tool.<verb>.<node>, and each event is published on mesh.seat.node-engine.event.<event>.<node>, the node's name its last token.",
"held-by-the-engine": true,
@@ -3,6 +3,7 @@
"seat": "operator-channel",
"scope": "mesh",
"grain": "whole",
"domain": "Operator and conversation",
"decision": "novox/hq ADR 0259",
"holder-declares": true,
"description": "Asking a person and answering on a channel (ADR 0259): held by the router, the messenger module, whose manifest declares the seat; written from that seat entry (design 26).",
+1 -1
View File
@@ -58,7 +58,7 @@ func TestAReaderStartsFromTheBootstrapAndReadsTheSeatOnceItAnswers(t *testing.T)
t.Fatalf("with the seat silent: %+v, may act on node-files: %v", st, r.MayAct("node-files"))
}
table := map[string]string{"node-files": `{"format":1,"seat":"node-files","scope":"node","grain":"seat-list","decision":"ADR 1",` +
table := map[string]string{"node-files": `{"format":1,"seat":"node-files","scope":"node","grain":"seat-list","domain": "Core", "decision": "ADR 1",` +
`"verbs":[{"name":"read","input":{"type":"object"}}]}`}
serve := func(m *nats.Msg) {
var q struct {
+1 -1
View File
@@ -57,7 +57,7 @@ func (f *fakeOwner) say(event, seat, source string) error {
}
func def(seat, scope, verb string) string {
return `{"format":1,"seat":"` + seat + `","scope":"` + scope + `","grain":"seat-list","decision":"ADR 1",` +
return `{"format":1,"seat":"` + seat + `","scope":"` + scope + `","grain":"seat-list","domain": "Core", "decision": "ADR 1",` +
`"verbs":[{"name":"` + verb + `","input":{"type":"object"}}]}`
}
@@ -3,6 +3,7 @@
"seat": "container-image-registry",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0605",
"description": "The mesh's container images, in the one artifact store: the OCI distribution protocol's read side, an image's tags and mirroring an outside image.",
"includes": [
+1
View File
@@ -3,6 +3,7 @@
"seat": "git",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0111",
"delivers": "git"
}
@@ -3,6 +3,7 @@
"seat": "go-package-registry",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0605",
"description": "The mesh's Go modules: Go's module proxy protocol's read side, and publishing over the bus.",
"delivers": "go-package-registry",
@@ -3,5 +3,6 @@
"seat": "mesh-artifact-store",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0075"
}
@@ -3,6 +3,7 @@
"seat": "mesh-artifact-sweep",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0571",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-broker",
"scope": "mesh",
"grain": "whole",
"domain": "Core",
"decision": "novox/hq ADR 0079",
"delivers": "mesh-bus",
"description": "The mesh's bus, and the bus state modules ask of it in requires (design 25 § 12). create, apply, recreate and drop are granted to the bus module's own credential alone.",
@@ -3,6 +3,7 @@
"seat": "mesh-catalog",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0604",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-conditions",
"scope": "mesh",
"grain": "seat-list",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-config",
"scope": "mesh",
"grain": "whole",
"domain": "Config",
"decision": "novox/hq ADR 0348, ADR 0565",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-delivery-checker",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0547",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-delivery",
"scope": "mesh",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0239",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-dns-resolver",
"scope": "mesh",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0194, ADR 0223",
"delivers": "wildcard-resolution",
"replicated": true
@@ -3,6 +3,7 @@
"seat": "mesh-enrolment",
"scope": "mesh",
"grain": "seat-list",
"domain": "Identity and access",
"decision": "novox/hq ADR 0587",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-hand-acts",
"scope": "mesh",
"grain": "seat-list",
"domain": "Health and repair",
"decision": "novox/hq ADR 0565",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-healers",
"scope": "mesh",
"grain": "seat-list",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-placement",
"scope": "mesh",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0567",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-provisioner",
"scope": "mesh",
"grain": "seat-list",
"domain": "Provisioning",
"decision": "novox/hq ADR 0349",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-self-check",
"scope": "mesh",
"grain": "seat-list",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-store",
"scope": "mesh",
"grain": "seat-list",
"domain": "Module",
"decision": "novox/hq ADR 0079",
"delivers": "postgres-database",
"verbs": [
@@ -3,6 +3,7 @@
"seat": "mesh-vault",
"scope": "mesh",
"grain": "whole",
"domain": "Identity and access",
"decision": "novox/hq ADR 0161",
"delivers": "secret",
"verbs": [
@@ -3,6 +3,7 @@
"seat": "mesh-wants",
"scope": "mesh",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0565",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "mesh-watchdogs",
"scope": "mesh",
"grain": "seat-list",
"domain": "Health and repair",
"decision": "novox/hq ADR 0564",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-backup",
"scope": "node",
"grain": "seat-list",
"domain": "Data",
"decision": "novox/hq ADR 0214",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-bar",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"receives": [
{
@@ -3,6 +3,7 @@
"seat": "node-build-go",
"scope": "node",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0525, ADR 0536, ADR 0553",
"pulled-by-kind": true,
"yields": true,
@@ -3,6 +3,7 @@
"seat": "node-build-image",
"scope": "node",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0525, ADR 0536, ADR 0553",
"pulled-by-kind": true,
"yields": true,
@@ -3,6 +3,7 @@
"seat": "node-build-node",
"scope": "node",
"grain": "seat-list",
"domain": "Delivery",
"decision": "novox/hq ADR 0525, ADR 0536, ADR 0553",
"pulled-by-kind": true,
"yields": true,
@@ -3,6 +3,7 @@
"seat": "node-clipboard",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,5 +3,6 @@
"seat": "node-compositor",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208"
}
@@ -3,5 +3,6 @@
"seat": "node-container-runtime",
"scope": "node",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0166, ADR 0207"
}
@@ -3,6 +3,7 @@
"seat": "node-display-server",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-display-session",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-engine",
"scope": "node",
"grain": "whole",
"domain": "Core",
"decision": "novox/hq ADR 0563",
"description": "The node seat every node's engine holds (novox/hq ADR 0563, ADR 0618 §3, §4): its hand acts on the operator's warrant, its read-only judgements, its compositions and what it reads of a manifest. Each verb is answered on this node's subject, mesh.seat.node-engine.tool.<verb>.<node>, and each event is published on mesh.seat.node-engine.event.<event>.<node>, the node's name its last token.",
"held-by-the-engine": true,
@@ -3,5 +3,6 @@
"seat": "node-environment",
"scope": "node",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0203"
}
@@ -3,6 +3,7 @@
"seat": "node-files",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0394",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-hostname",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0199, ADR 0223",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-hotkeys",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0212",
"receives": [
{
@@ -3,6 +3,7 @@
"seat": "node-intrusion-prevention",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0121",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-launcher",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-lock-screen",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-login-manager",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-login-shell",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0204",
"verbs": [
{
@@ -3,5 +3,6 @@
"seat": "node-message-bus",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0215"
}
@@ -3,6 +3,7 @@
"seat": "node-mounts",
"scope": "node",
"grain": "seat-list",
"domain": "Provisioning",
"decision": "novox/hq ADR 0263",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-nfs-server",
"scope": "node",
"grain": "seat-list",
"domain": "Provisioning",
"decision": "novox/hq ADR 0263",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-notifier",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,5 +3,6 @@
"seat": "node-package-manager",
"scope": "node",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0207"
}
@@ -3,6 +3,7 @@
"seat": "node-packet-filter",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0121",
"verbs": [
{
@@ -3,5 +3,6 @@
"seat": "node-power",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0211"
}
@@ -3,5 +3,6 @@
"seat": "node-provisioner",
"scope": "node",
"grain": "seat-list",
"domain": "Provisioning",
"decision": "novox/hq ADR 0349"
}
@@ -3,6 +3,7 @@
"seat": "node-reads",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0310",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-resolver",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0247",
"verbs": [
{
@@ -3,5 +3,6 @@
"seat": "node-secret-service",
"scope": "node",
"grain": "seat-list",
"domain": "Identity and access",
"decision": "novox/hq ADR 0208"
}
@@ -3,6 +3,7 @@
"seat": "node-service-manager",
"scope": "node",
"grain": "seat-list",
"domain": "Placement",
"decision": "novox/hq ADR 0177",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-terminal-emulator",
"scope": "node",
"grain": "seat-list",
"domain": "Core",
"decision": "novox/hq ADR 0208",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "node-uplink",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0117",
"verbs": [
{
@@ -3,6 +3,7 @@
"seat": "npm-package-registry",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0109",
"description": "The mesh's npm packages: the npm registry protocol's read side, and publishing over the bus.",
"delivers": "npm-package-registry",
@@ -3,6 +3,7 @@
"seat": "oci-artifact-registry",
"scope": "mesh",
"grain": "whole",
"domain": "Delivery",
"decision": "novox/hq ADR 0605",
"description": "The mesh's bundles and archives, by digest, in the one artifact store: the OCI distribution protocol's read side.",
"includes": [
@@ -3,6 +3,7 @@
"seat": "operator-channel",
"scope": "mesh",
"grain": "whole",
"domain": "Operator and conversation",
"decision": "novox/hq ADR 0259",
"holder-declares": true,
"description": "Asking a person and answering on a channel (ADR 0259): held by the router, the messenger module, whose manifest declares the seat; written from that seat entry (design 26).",
@@ -3,5 +3,6 @@
"seat": "the-private-network",
"scope": "node",
"grain": "seat-list",
"domain": "Connectivity",
"decision": "novox/hq ADR 0110"
}