SDK-9: mesh-sdk takes no new seat-specific name (ADR 0613 §5, design 26 *Contracts modules*)

Every seat constant of mesh-sdk is mesh-contracts' generated name; the four whole seats' (BrokerSeat, CheckerSeat,
asks.Seat, buscompose.VaultSeat) are marked deprecated for their importers. The package walk of mesh-sdk's own check
refuses a string literal naming a defined seat or its subjects, and an exported name given to one, beyond
testdata/seat-names.txt, which lists what stands before the move (module names that equal a seat's among them) and
only shrinks. No new test function.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 12:25:21 +01:00
parent 6bfd14b14b
commit 253bd06970
24 changed files with 207 additions and 43 deletions
+6 -1
View File
@@ -15,13 +15,18 @@ import (
"strconv"
"strings"
"time"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
)
// The seats (novox/hq ADR 0259 §3).
const (
// Seat is held by the router: an ask and its cancel are its accepts, a warrant its event, each named by
// the asker.
Seat = "operator-channel"
//
// Deprecated: the seat is defined whole in mesh-contracts (operatorchannel.Seat, its subjects and message
// types); kept for its importers until their next change takes it from there (testdata/seat-names.txt).
Seat = contractseats.OperatorChannel
// ChannelSeat is the kinded bench a channel holds to show and say: its accepts carry the kind.
ChannelSeat = "channel"
// IntakeSeat is the kinded bench a channel holds to say what was chosen: its events and proofs carry
+5 -1
View File
@@ -1,5 +1,7 @@
package buscompose
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// Declared is one module on one node, as composing its authority needs it.
type Declared struct {
Module string
@@ -102,4 +104,6 @@ type ProcessPrincipal struct {
}
// VaultSeat is the vault's seat: its holder alone asks the desks and the issuing providers in its own name.
const VaultSeat = "mesh-vault"
//
// Deprecated: a whole seat's name is mesh-contracts' (seats.MeshVault); kept until its importers take it from there.
const VaultSeat = contractseats.MeshVault
+3 -1
View File
@@ -1,5 +1,7 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// ArtifactSweepSeat is the seat artifact-store-tools holds. Not the seat mesh-artifact-store, the store itself held by
// distribution, and not the provision artifact-store it delivers.
const ArtifactSweepSeat = "mesh-artifact-sweep"
const ArtifactSweepSeat = contractseats.MeshArtifactSweep
+3 -1
View File
@@ -1,5 +1,7 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
import "encoding/json"
// CatalogSeat is the seat of the catalog: what the mesh holds of every module (novox/hq ADR 0604 §1). Its states are
@@ -8,7 +10,7 @@ import "encoding/json"
// no verb. It names no event. What must be built again is no verb: a module whose fingerprint differs from its newest
// build, which the delivery view derives. The verbs' answers are CatalogModules, CatalogOne, CatalogProvides and
// CatalogDependents, whose field names are those of the catalog module's tools they replace.
const CatalogSeat = "mesh-catalog"
const CatalogSeat = contractseats.MeshCatalog
// CatalogEntry is one module of the catalog: its repository, its directory there ("." for the root), the merge commit it
// was last changed at, and its new-form fingerprint or why it has none.
+6 -1
View File
@@ -1,4 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// CheckerSeat is the seat mesh-delivery-checker holds.
const CheckerSeat = "mesh-delivery-checker"
//
// Deprecated: a whole seat's name is mesh-contracts' (seats.MeshDeliveryChecker); kept for its importers until their
// next change takes it from there (testdata/seat-names.txt).
const CheckerSeat = contractseats.MeshDeliveryChecker
+4 -2
View File
@@ -1,9 +1,11 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// The two seats.
const (
WantsSeat = "mesh-wants"
HandActsSeat = "mesh-hand-acts"
WantsSeat = contractseats.MeshWants
HandActsSeat = contractseats.MeshHandActs
)
// controlRecordsDecision is the record that made the two seats.
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// DeliverySeat is the seat mesh-delivery holds.
const DeliverySeat = "mesh-delivery"
const DeliverySeat = contractseats.MeshDelivery
// RemovedDeliveryVerbs are the delivery seat's verbs release 6 removed (novox/hq ADR 0539 clause 17): with no plan the
// gate keeps the merge's states and derives nothing after the merge. Each stays in deliveryVerbs as an optional row
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// EnrolmentSeat is the seat mesh-enrolment.
const EnrolmentSeat = "mesh-enrolment"
const EnrolmentSeat = contractseats.MeshEnrolment
// The seat's six verbs (ADR 0587 §1, §4-§8).
const (
+5 -3
View File
@@ -1,12 +1,14 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// EnvironmentSeat and LoginShellSeat are the seats whose holders may place what the modules
// contributed: the account's environment, and the login shell's code.
const (
EnvironmentSeat = "node-environment"
LoginShellSeat = "node-login-shell"
EnvironmentSeat = contractseats.NodeEnvironment
LoginShellSeat = contractseats.NodeLoginShell
// PowerSeat is the seat whose holder places code for the power moments (novox/hq ADR 0211).
PowerSeat = "node-power"
PowerSeat = contractseats.NodePower
)
// Where an environment entry on PATH goes: before the account's existing PATH, or after it.
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// FilesSeat is the role that reads and manages a node's files and accounts (novox/hq ADR 0394).
const FilesSeat = "node-files"
const FilesSeat = contractseats.NodeFiles
// FilesOwnedPaths is the word the holder of node-files is given beside the secret places: a JSON object from
// each absolute path a module owns on its node to "module (tool to use)" (novox/hq ADR 0394 §5).
+13 -11
View File
@@ -3,6 +3,8 @@ package catalogue
import (
"fmt"
"strings"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
)
// The graphical session's seats (novox/hq ADR 0208): one module per piece of software, each piece's
@@ -10,17 +12,17 @@ import (
// a role rather than each inventing one — and a machine running two of one role is refused at
// assignment instead of found by two bars on one screen.
const (
LoginManagerSeat = "node-login-manager"
DisplayServerSeat = "node-display-server"
DisplaySessionSeat = "node-display-session"
TerminalEmulatorSeat = "node-terminal-emulator"
LauncherSeat = "node-launcher"
NotifierSeat = "node-notifier"
LockScreenSeat = "node-lock-screen"
ClipboardSeat = "node-clipboard"
BarSeat = "node-bar"
CompositorSeat = "node-compositor"
SecretServiceSeat = "node-secret-service"
LoginManagerSeat = contractseats.NodeLoginManager
DisplayServerSeat = contractseats.NodeDisplayServer
DisplaySessionSeat = contractseats.NodeDisplaySession
TerminalEmulatorSeat = contractseats.NodeTerminalEmulator
LauncherSeat = contractseats.NodeLauncher
NotifierSeat = contractseats.NodeNotifier
LockScreenSeat = contractseats.NodeLockScreen
ClipboardSeat = contractseats.NodeClipboard
BarSeat = contractseats.NodeBar
CompositorSeat = contractseats.NodeCompositor
SecretServiceSeat = contractseats.NodeSecretService
)
// BarKindBlock is the bar's one received kind: a block (novox/hq ADR 0255).
+6 -4
View File
@@ -1,11 +1,13 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// The four health seats.
const (
ConditionsSeat = "mesh-conditions"
WatchdogsSeat = "mesh-watchdogs"
SelfCheckSeat = "mesh-self-check"
HealersSeat = "mesh-healers"
ConditionsSeat = contractseats.MeshConditions
WatchdogsSeat = contractseats.MeshWatchdogs
SelfCheckSeat = contractseats.MeshSelfCheck
HealersSeat = contractseats.MeshHealers
)
// healthDecision is the record that made the four seats.
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// ResolverSeat is the machine's own resolver (novox/hq ADR 0247).
const ResolverSeat = "node-resolver"
const ResolverSeat = contractseats.NodeResolver
// ResolverFile is the machine's resolver file: the uplink holder's, or the node-resolver holder's where
// one is held.
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// PlacementSeat is the seat the assigner holds for placement.
const PlacementSeat = "mesh-placement"
const PlacementSeat = contractseats.MeshPlacement
// The seat's five verbs (ADR 0567 §10).
const (
+3 -1
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// ReadsSeat is the role that reads a node's files and accounts (novox/hq ADR 0310).
const ReadsSeat = "node-reads"
const ReadsSeat = contractseats.NodeReads
// ReadsSecretPlaces is the word the holder of node-reads is given: the places on its node where a secret is
// kept, as a JSON list of absolute paths, each refused by name before any read (novox/hq ADR 0310 §5).
+5 -3
View File
@@ -1,13 +1,15 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// HotkeysSeat is the machine's hotkey daemon (novox/hq ADR 0212 §5).
const HotkeysSeat = "node-hotkeys"
const HotkeysSeat = contractseats.NodeHotkeys
// MessageBusSeat is the machine's D-Bus (novox/hq ADR 0215).
const MessageBusSeat = "node-message-bus"
const MessageBusSeat = contractseats.NodeMessageBus
// BackupSeat is the machine's backups (novox/hq ADR 0214, to-be 43).
const BackupSeat = "node-backup"
const BackupSeat = contractseats.NodeBackup
// SeatContribution is one piece of configuration a module gives a seat's holder to place.
type SeatContribution struct {
+5 -3
View File
@@ -4,14 +4,16 @@ import (
"fmt"
"sort"
"strings"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
)
// The three seats that apply resources (novox/hq ADR 0207 §1). Named once, because the derivation,
// the seed and the messages all turn on these strings.
const (
ServiceManagerSeat = "node-service-manager"
PackageManagerSeat = "node-package-manager"
ContainerRuntimeSeat = "node-container-runtime"
ServiceManagerSeat = contractseats.NodeServiceManager
PackageManagerSeat = contractseats.NodePackageManager
ContainerRuntimeSeat = contractseats.NodeContainerRuntime
)
// appliedThrough is which seat applies a resource of each type. **Only these three**: ADR 0207
+3
View File
@@ -328,4 +328,7 @@ func SeatsWithAProtocol() []Seat {
// BrokerSeat is the mesh's bus. Its holder is the bus, and its account — when it declares one — may
// snapshot the bus's streams and do nothing else (novox/hq ADR 0235).
//
// Deprecated: a whole seat's name is mesh-contracts' (seats.MeshBroker, meshbroker.Seat); kept for its importers
// until their next change takes it from there (testdata/seat-names.txt).
const BrokerSeat = contractseats.MeshBroker
+4 -2
View File
@@ -1,7 +1,9 @@
package catalogue
import contractseats "git.novox.be/novox/mesh-contracts/go/seats"
// NFSServerSeat is the role of the machine that shares directories over NFS (novox/hq ADR 0263).
const NFSServerSeat = "node-nfs-server"
const NFSServerSeat = contractseats.NodeNfsServer
// MountsSeat is the role that mounts a machine's shares and occasional sources (novox/hq ADR 0263).
const MountsSeat = "node-mounts"
const MountsSeat = contractseats.NodeMounts
+3 -1
View File
@@ -10,11 +10,13 @@ import (
"fmt"
"strings"
"time"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
)
// The seat, its holder and what it keeps (ADR 0565 clause 10).
const (
Seat = "mesh-hand-acts"
Seat = contractseats.MeshHandActs
Module = "mesh-hand-acts"
// ActsLog is the log of every act, kept 400 days; WarrantsState one key `<asker>.<ask>` per warrant, made once.
ActsLog = "acts"
+4 -2
View File
@@ -10,6 +10,8 @@ import (
"fmt"
"strings"
"time"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
)
// The modules holding the four health seats, and the states between them, as `<module>_<state>` buckets.
@@ -272,6 +274,6 @@ type Would struct {
// KeeperSeat and the self-check's run as `checked` on SelfCheckSeat: the controller's events and the take-over key that
// chose between the two sources ended with it (novox/hq ADR 0590 clause 3).
const (
KeeperSeat = "mesh-conditions"
SelfCheckSeat = "mesh-self-check"
KeeperSeat = contractseats.MeshConditions
SelfCheckSeat = contractseats.MeshSelfCheck
)
+51
View File
@@ -6,6 +6,7 @@ import (
"go/parser"
"go/token"
"io/fs"
"os"
"path/filepath"
"reflect"
"slices"
@@ -13,6 +14,7 @@ import (
"strings"
"testing"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
"git.novox.be/novox/mesh-sdk/go/buscalls"
)
@@ -40,6 +42,20 @@ var composesNot = []string{"Resolution.Compose", "Resolution.Declaration", "Reso
// computes.
func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) {
var found []string
// **mesh-sdk takes no new seat-specific name** (novox/hq ADR 0613 §5, design 26 *Contracts modules*, SDK-9): a seat's
// name is mesh-contracts' (go/seats), so no string literal here names a defined seat or its subjects, and no exported
// name is given to one, beyond what testdata/seat-names.txt keeps from before the move (each `<file>: <literal or
// name>`), which only shrinks as areas move. A literal naming a module of the same name as a seat counts too.
defined := contractseats.Names()
namesSeat := func(s string) bool {
for _, seat := range defined {
if s == seat || strings.HasPrefix(s, "mesh.seat."+seat+".") {
return true
}
}
return false
}
var seatNames []string
err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
@@ -61,6 +77,26 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) {
if err != nil {
return err
}
where := filepath.ToSlash(path) + ": "
ast.Inspect(file, func(n ast.Node) bool {
switch n := n.(type) {
case *ast.BasicLit:
if v, err := strconv.Unquote(n.Value); err == nil && n.Kind == token.STRING && namesSeat(v) {
seatNames = append(seatNames, where+v)
}
case *ast.ValueSpec:
for i, name := range n.Names {
if i < len(n.Values) && name.IsExported() {
if sel, ok := n.Values[i].(*ast.SelectorExpr); ok {
if x, ok := sel.X.(*ast.Ident); ok && x.Name == "contractseats" {
seatNames = append(seatNames, where+name.Name)
}
}
}
}
}
return true
})
// 1966/AC5: the calls package imports nothing of mesh-sdk but the catalogue's types, so a change here rebuilds
// only its importers (ADR 0595 §9).
if dir == "buscalls" {
@@ -94,6 +130,21 @@ func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) {
if err != nil {
t.Fatal(err)
}
kept, err := os.ReadFile("testdata/seat-names.txt")
if err != nil {
t.Fatal(err)
}
keep := strings.Split(strings.TrimSpace(string(kept)), "\n")
for _, n := range seatNames {
if !slices.Contains(keep, n) {
t.Errorf("%s names a seat the definitions define: a seat's name and its contract are mesh-contracts' (ADR 0613 §5)", n)
}
}
for _, k := range keep {
if !slices.Contains(seatNames, k) {
t.Errorf("testdata/seat-names.txt keeps %q, which is gone: take it off the list", k)
}
}
slices.Sort(found)
for _, dir := range found {
if !slices.Contains(meshSDKPackages, dir) {
+2 -1
View File
@@ -13,12 +13,13 @@ import (
"strings"
"time"
contractseats "git.novox.be/novox/mesh-contracts/go/seats"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// The seat, its holder and its two states, and the names a reader declares in its `reads`.
const (
Seat = "mesh-provisioner"
Seat = contractseats.MeshProvisioner
Module = "mesh-provisioner"
ProvisionsState = "provisions"
PlansState = "plans"
+61
View File
@@ -0,0 +1,61 @@
asks/asks.go: Seat
buscompose/health_grants.go: mesh.seat.mesh-self-check.event.
buscompose/users.go: VaultSeat
catalogue/artifact_sweep_seat.go: ArtifactSweepSeat
catalogue/catalog_seat.go: CatalogSeat
catalogue/checker_seat.go: CheckerSeat
catalogue/control_records_seats.go: HandActsSeat
catalogue/control_records_seats.go: WantsSeat
catalogue/delivery_seat.go: DeliverySeat
catalogue/engine_seat.go: EngineSeat
catalogue/enrolment_seat.go: EnrolmentSeat
catalogue/environment_into.go: EnvironmentSeat
catalogue/environment_into.go: LoginShellSeat
catalogue/environment_into.go: PowerSeat
catalogue/files.go: FilesSeat
catalogue/graphical_session.go: BarSeat
catalogue/graphical_session.go: ClipboardSeat
catalogue/graphical_session.go: CompositorSeat
catalogue/graphical_session.go: DisplayServerSeat
catalogue/graphical_session.go: DisplaySessionSeat
catalogue/graphical_session.go: LauncherSeat
catalogue/graphical_session.go: LockScreenSeat
catalogue/graphical_session.go: LoginManagerSeat
catalogue/graphical_session.go: NotifierSeat
catalogue/graphical_session.go: SecretServiceSeat
catalogue/graphical_session.go: TerminalEmulatorSeat
catalogue/health_seats.go: ConditionsSeat
catalogue/health_seats.go: HealersSeat
catalogue/health_seats.go: SelfCheckSeat
catalogue/health_seats.go: WatchdogsSeat
catalogue/node_resolver.go: ResolverSeat
catalogue/placement_seat.go: PlacementSeat
catalogue/reads.go: ReadsSeat
catalogue/seat_contributions.go: BackupSeat
catalogue/seat_contributions.go: HotkeysSeat
catalogue/seat_contributions.go: MessageBusSeat
catalogue/seat_dependencies.go: ContainerRuntimeSeat
catalogue/seat_dependencies.go: PackageManagerSeat
catalogue/seat_dependencies.go: ServiceManagerSeat
catalogue/seats.go: BrokerSeat
catalogue/shares.go: MountsSeat
catalogue/shares.go: NFSServerSeat
delivery/checker.go: mesh-delivery-checker
delivery/composed.go: mesh-provisioner
delivery/held.go: mesh.seat.mesh-artifact-sweep.event.
delivery/placement.go: mesh-self-check
delivery/provided.go: the-private-network
delivery/signers.go: mesh-vault
delivery/stepasks.go: node-build-node
handacts/handacts.go: mesh-hand-acts
handacts/handacts.go: Seat
health/findings.go: KeeperSeat
health/findings.go: mesh-conditions
health/findings.go: mesh-healers
health/findings.go: mesh-self-check
health/findings.go: SelfCheckSeat
internal/beside/beside.go: mesh-catalog
overlay/overlay.go: the-private-network
provisions/provisions.go: mesh-provisioner
provisions/provisions.go: mesh-vault
provisions/provisions.go: Seat