C14: the generated Go and TypeScript of every seat follow the definitions
Written by seatgen at c62650e4 (GEN3) with mesh-sdk b19fc7fa (reader release): the seat mesh-grants new, every TypeScript contract as index.js with index.d.ts, events with subject and stream. mesh-watchdogs gains its family, which a definition with events needs. Written with the reader as it is: the field needs-approval (node-login-shell) and the section bodies (mesh-conditions) are unknown to it, so they were laid aside for the run; nothing generated carries either. Builds: design 47 G §339, §341, §261, §389 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Code generated by seatgen from the seat definitions; DO NOT EDIT.
|
||||
|
||||
// Package nodeengine is the contract of the seat "node-engine", defined whole (seats/node-engine/seat.json): 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.
|
||||
// Package nodeengine is the contract of the seat "node-engine", defined whole (seats/node-engine/seat.json): 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, or, for an event whose subject names <node>, there (composed.<node>, running.<node>.<module>): the grants part grants a node's account only its own node's subjects (ADR 0363 §2).
|
||||
package nodeengine
|
||||
|
||||
import (
|
||||
@@ -28,6 +28,7 @@ const (
|
||||
VerbManifestReads = "manifest-reads"
|
||||
VerbSeatList = "seat-list"
|
||||
VerbSeatListAgain = "seat-list-again"
|
||||
VerbProcessBuilds = "process-builds"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -35,16 +36,19 @@ const (
|
||||
EventDone = "done"
|
||||
EventRefused = "refused"
|
||||
EventManifestReadsChanged = "manifest-reads-changed"
|
||||
EventComposed = "composed"
|
||||
EventRunning = "running"
|
||||
EventCapabilitiesChanged = "capabilities-changed"
|
||||
)
|
||||
|
||||
// Verbs is every verb the seat serves, in its definition's order: a new copy each call.
|
||||
func Verbs() []string {
|
||||
return []string{VerbHandOver, VerbAccessAct, VerbJudgeDirectories, VerbSetuidSearch, VerbRootFree, VerbActs, VerbPackages, VerbComposition, VerbCompose, VerbComposeCandidate, VerbManifestReads, VerbSeatList, VerbSeatListAgain}
|
||||
return []string{VerbHandOver, VerbAccessAct, VerbJudgeDirectories, VerbSetuidSearch, VerbRootFree, VerbActs, VerbPackages, VerbComposition, VerbCompose, VerbComposeCandidate, VerbManifestReads, VerbSeatList, VerbSeatListAgain, VerbProcessBuilds}
|
||||
}
|
||||
|
||||
// Events is every event published on the seat's subject: a new copy each call.
|
||||
func Events() []string {
|
||||
return []string{EventAsked, EventDone, EventRefused, EventManifestReadsChanged}
|
||||
return []string{EventAsked, EventDone, EventRefused, EventManifestReadsChanged, EventComposed, EventRunning, EventCapabilitiesChanged}
|
||||
}
|
||||
|
||||
// Family is where the seat's events are kept: the shared events stream, filtered to the seat's subjects.
|
||||
@@ -67,6 +71,31 @@ func SubjectManifestReadsChanged(caller string) string {
|
||||
return "mesh.seat.node-engine.event.manifest-reads-changed." + caller
|
||||
}
|
||||
|
||||
// SubjectComposed is where composed is published, on mesh.seat.node-engine.event.composed.<node>.
|
||||
func SubjectComposed(node string) string { return "mesh.seat.node-engine.event.composed." + node }
|
||||
|
||||
// SubjectComposedAll hears every composed.
|
||||
const SubjectComposedAll = "mesh.seat.node-engine.event.composed.*"
|
||||
|
||||
// StreamRunning is the stream running is kept in.
|
||||
const StreamRunning = "SEAT_node-engine_running"
|
||||
|
||||
// SubjectRunning is where running is published, on mesh.seat.node-engine.event.running.<node>.<module>.
|
||||
func SubjectRunning(node, module string) string {
|
||||
return "mesh.seat.node-engine.event.running." + node + "." + module
|
||||
}
|
||||
|
||||
// SubjectRunningAll hears every running.
|
||||
const SubjectRunningAll = "mesh.seat.node-engine.event.running.*.*"
|
||||
|
||||
// SubjectCapabilitiesChanged is where capabilities-changed is published, on mesh.seat.node-engine.event.capabilities-changed.<node>.
|
||||
func SubjectCapabilitiesChanged(node string) string {
|
||||
return "mesh.seat.node-engine.event.capabilities-changed." + node
|
||||
}
|
||||
|
||||
// SubjectCapabilitiesChangedAll hears every capabilities-changed.
|
||||
const SubjectCapabilitiesChangedAll = "mesh.seat.node-engine.event.capabilities-changed.*"
|
||||
|
||||
const (
|
||||
StateHave = "have"
|
||||
StateComposed = "composed"
|
||||
@@ -523,6 +552,34 @@ type CandidateRefusal struct {
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// CapabilitiesChanged is a node's capabilities changed, which the assigner places by.
|
||||
type CapabilitiesChanged struct {
|
||||
// when, RFC 3339
|
||||
At time.Time `json:"at"`
|
||||
// its capabilities now
|
||||
Capabilities []string `json:"capabilities"`
|
||||
// the node
|
||||
Node string `json:"node"`
|
||||
// the layout's version
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// Composed is an entry composed on a node (design 47 *What each step says*).
|
||||
type Composed struct {
|
||||
// when, RFC 3339
|
||||
At time.Time `json:"at"`
|
||||
// the digest of the composition (design 47 G 404)
|
||||
Digest string `json:"digest"`
|
||||
// the fingerprint of the want composed
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
// the module
|
||||
Module string `json:"module"`
|
||||
// the node
|
||||
Node string `json:"node"`
|
||||
// the layout's version
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// DeclaredGroup is a group.
|
||||
type DeclaredGroup struct {
|
||||
Gid int64 `json:"gid"`
|
||||
@@ -742,6 +799,38 @@ type PlacedDataItem struct {
|
||||
Protection string `json:"protection,omitempty"`
|
||||
}
|
||||
|
||||
// ProcessBuild is the build one process of a module was started with.
|
||||
type ProcessBuild struct {
|
||||
// the fingerprint handed to it in MESH_FINGERPRINT; empty when it was started without one
|
||||
Fingerprint string `json:"fingerprint,omitempty"`
|
||||
// service or container
|
||||
Kind string `json:"kind"`
|
||||
// the module
|
||||
Module string `json:"module"`
|
||||
// the service's unit or the container's name
|
||||
Process string `json:"process"`
|
||||
// when it was started, RFC 3339
|
||||
Started *time.Time `json:"started,omitempty"`
|
||||
// why its build is unknown: started before the node-engine handed MESH_FINGERPRINT, or the value could not be read
|
||||
Unknown string `json:"unknown,omitempty"`
|
||||
}
|
||||
|
||||
// The values of ProcessBuild's kind.
|
||||
const (
|
||||
ProcessBuildKindService = "service"
|
||||
ProcessBuildKindContainer = "container"
|
||||
)
|
||||
|
||||
// ProcessBuilds is what process-builds answers.
|
||||
type ProcessBuilds struct {
|
||||
// why they could not be read
|
||||
Error string `json:"error,omitempty"`
|
||||
// the node
|
||||
Node string `json:"node"`
|
||||
// every process the node-engine started, by module
|
||||
Processes []ProcessBuild `json:"processes"`
|
||||
}
|
||||
|
||||
// PullWait is the pull from a store a failed apply waits on.
|
||||
type PullWait struct {
|
||||
// when the pull began
|
||||
@@ -796,6 +885,24 @@ type RootVerdict struct {
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// Running is a module running healthy on a node at a build: what the node-engines of other nodes and the grants part decide a seat's pass from (ADR 0660 §2), kept last per subject with no age limit.
|
||||
type Running struct {
|
||||
// when it was seen running healthy, RFC 3339
|
||||
At time.Time `json:"at"`
|
||||
// the fingerprint of the build it runs; none with stopped
|
||||
Fingerprint string `json:"fingerprint,omitempty"`
|
||||
// the digest of that build's manifest, the indexer's manifest of it, read by digest from the catalog half
|
||||
Manifest string `json:"manifest,omitempty"`
|
||||
// the module
|
||||
Module string `json:"module"`
|
||||
// the node
|
||||
Node string `json:"node"`
|
||||
// true when the module no longer runs on the node: no fingerprint or manifest then (design 47 G 365, 404); mesh-sdk's SeatsToPassOn counts such a module as not running there
|
||||
Stopped bool `json:"stopped,omitempty"`
|
||||
// the layout's version
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// Said is the answer of a read-only judgement.
|
||||
type Said struct {
|
||||
// the node
|
||||
@@ -1217,6 +1324,15 @@ type SeatListAgainInput struct {
|
||||
// SeatListAgainAnswer is what seat-list-again answers.
|
||||
type SeatListAgainAnswer = SeatList
|
||||
|
||||
// ProcessBuildsInput is what process-builds takes.
|
||||
type ProcessBuildsInput struct {
|
||||
// only this module's processes
|
||||
Module string `json:"module,omitempty"`
|
||||
}
|
||||
|
||||
// ProcessBuildsAnswer is what process-builds answers.
|
||||
type ProcessBuildsAnswer = ProcessBuilds
|
||||
|
||||
// AskedEvent is the body of the event asked.
|
||||
type AskedEvent = ActSaid
|
||||
|
||||
@@ -1229,6 +1345,15 @@ type RefusedEvent = ActSaid
|
||||
// ManifestReadsChangedEvent is the body of the event manifest-reads-changed.
|
||||
type ManifestReadsChangedEvent = ManifestReadsChanged
|
||||
|
||||
// ComposedEvent is the body of the event composed.
|
||||
type ComposedEvent = Composed
|
||||
|
||||
// RunningEvent is the body of the event running.
|
||||
type RunningEvent = Running
|
||||
|
||||
// CapabilitiesChangedEvent is the body of the event capabilities-changed.
|
||||
type CapabilitiesChangedEvent = CapabilitiesChanged
|
||||
|
||||
// HaveByNodeModuleValue is one value of the state have under the key <node>.<module>.
|
||||
type HaveByNodeModuleValue struct {
|
||||
Build string `json:"build,omitempty"`
|
||||
|
||||
@@ -35,6 +35,18 @@ func TestFixtures(t *testing.T) {
|
||||
err := json.Unmarshal(b, &v)
|
||||
return v, err
|
||||
}, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-engine\\.event\\.manifest-reads-changed\\.[A-Za-z0-9_-]+$")},
|
||||
{name: "composed is said", subject: "mesh.seat.node-engine.event.composed.ace", given: "{\"at\":\"2026-11-09T20:00:00Z\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"nats\",\"node\":\"ace\",\"v\":1}", wire: "{\"at\":\"2026-11-09T20:00:00Z\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"module\":\"nats\",\"node\":\"ace\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v ComposedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-engine\\.event\\.composed\\.[^.*> ]+$")},
|
||||
{name: "running is said, its node and module in its subject", subject: "mesh.seat.node-engine.event.running.ace.nats", given: "{\"at\":\"2026-11-09T20:01:00Z\",\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"manifest\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"module\":\"nats\",\"node\":\"ace\",\"v\":1}", wire: "{\"at\":\"2026-11-09T20:01:00Z\",\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"manifest\":\"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"module\":\"nats\",\"node\":\"ace\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v RunningEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-engine\\.event\\.running\\.[^.*> ]+\\.[^.*> ]+$")},
|
||||
{name: "running says a module stopped on the node, with no fingerprint", subject: "mesh.seat.node-engine.event.running.ace.nats", given: "{\"at\":\"2026-11-11T09:00:00Z\",\"module\":\"nats\",\"node\":\"ace\",\"stopped\":true,\"v\":1}", wire: "{\"at\":\"2026-11-11T09:00:00Z\",\"module\":\"nats\",\"node\":\"ace\",\"stopped\":true,\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v RunningEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-engine\\.event\\.running\\.[^.*> ]+\\.[^.*> ]+$")},
|
||||
{name: "capabilities-changed is said", subject: "mesh.seat.node-engine.event.capabilities-changed.ace", given: "{\"at\":\"2026-11-09T20:02:00Z\",\"capabilities\":[\"build-go\",\"docker\"],\"node\":\"ace\",\"v\":1}", wire: "{\"at\":\"2026-11-09T20:02:00Z\",\"capabilities\":[\"build-go\",\"docker\"],\"node\":\"ace\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) {
|
||||
var v CapabilitiesChangedEvent
|
||||
err := json.Unmarshal(b, &v)
|
||||
return v, err
|
||||
}, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-engine\\.event\\.capabilities-changed\\.[^.*> ]+$")},
|
||||
{name: "the finding of a seat list unread, as the engine writes it", subject: "", given: "{\"at\":\"2026-11-05T14:00:00Z\",\"key\":\"machine.ace.seat-list-unread\",\"kind\":\"seat-list-unread\",\"observer\":\"mesh-host\",\"severity\":\"warning\",\"source\":\"node-engine.seat-list\",\"subject\":{\"id\":\"ace\",\"machine\":\"ace\",\"scope\":\"machine\"},\"summary\":\"the seat list has not been read for five minutes\",\"v\":1}", wire: "{\"at\":\"2026-11-05T14:00:00Z\",\"key\":\"machine.ace.seat-list-unread\",\"kind\":\"seat-list-unread\",\"observer\":\"mesh-host\",\"severity\":\"warning\",\"source\":\"node-engine.seat-list\",\"subject\":{\"id\":\"ace\",\"machine\":\"ace\",\"scope\":\"machine\"},\"summary\":\"the seat list has not been read for five minutes\",\"v\":1}",
|
||||
decode: func(b []byte) (any, error) { var v FindingsByKeyValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "a node's packages, present and absent (captured from ace, shortened)", subject: "", given: "{\"node\":\"ace\",\"packages\":[{\"absent\":false,\"modules\":[\"avahi\"],\"package\":\"avahi\"},{\"absent\":false,\"modules\":[\"mesh-build-go\",\"mesh-build-node\"],\"package\":\"bubblewrap\"},{\"absent\":true,\"modules\":[\"time-sync\"],\"package\":\"ntp\"}]}", wire: "{\"node\":\"ace\",\"packages\":[{\"absent\":false,\"modules\":[\"avahi\"],\"package\":\"avahi\"},{\"absent\":false,\"modules\":[\"mesh-build-go\",\"mesh-build-node\"],\"package\":\"bubblewrap\"},{\"absent\":true,\"modules\":[\"time-sync\"],\"package\":\"ntp\"}]}",
|
||||
@@ -91,6 +103,12 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v SeatListAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "seat-list-again answers the error when the read failed", subject: "", given: "{\"error\":\"seatlist: no answer\",\"health\":\"the seat list is held from the bootstrap\",\"status\":{\"heard\":false,\"held\":[{\"seat\":\"node-engine\",\"source\":\"bootstrap\"}],\"waiting\":[\"node-engine\"]}}", wire: "{\"error\":\"seatlist: no answer\",\"health\":\"the seat list is held from the bootstrap\",\"status\":{\"heard\":false,\"held\":[{\"seat\":\"node-engine\",\"source\":\"bootstrap\"}],\"waiting\":[\"node-engine\"]}}",
|
||||
decode: func(b []byte) (any, error) { var v SeatListAgainAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "process-builds asks one module", subject: "", given: "{\"module\":\"nats\"}", wire: "{\"module\":\"nats\"}",
|
||||
decode: func(b []byte) (any, error) { var v ProcessBuildsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "process-builds answers each process's build", subject: "", given: "{\"node\":\"ace\",\"processes\":[{\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"service\",\"module\":\"nats\",\"process\":\"nats.service\",\"started\":\"2026-11-09T19:00:00Z\"},{\"kind\":\"container\",\"module\":\"route-proxy\",\"process\":\"route-proxy\",\"started\":\"2026-11-01T08:00:00Z\",\"unknown\":\"started before the node-engine handed MESH_FINGERPRINT\"}]}", wire: "{\"node\":\"ace\",\"processes\":[{\"fingerprint\":\"src2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"service\",\"module\":\"nats\",\"process\":\"nats.service\",\"started\":\"2026-11-09T19:00:00Z\"},{\"kind\":\"container\",\"module\":\"route-proxy\",\"process\":\"route-proxy\",\"started\":\"2026-11-01T08:00:00Z\",\"unknown\":\"started before the node-engine handed MESH_FINGERPRINT\"}]}",
|
||||
decode: func(b []byte) (any, error) { var v ProcessBuildsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "process-builds answers an error", subject: "", given: "{\"error\":\"the service manager did not answer\",\"node\":\"ace\",\"processes\":[]}", wire: "{\"error\":\"the service manager did not answer\",\"node\":\"ace\",\"processes\":[]}",
|
||||
decode: func(b []byte) (any, error) { var v ProcessBuildsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
Reference in New Issue
Block a user