Designs and glossary follow ADR 0634 and ADR 0635: shared code lives with its owner
The registry milestone now moves the Delivery domain out of mesh-sdk, creates a contracts module per domain it moves and the first domain SDK, defines 25 seats whole with their states, reads the seat list from the bus and renames two seats. Design 26's *Where a seat's code goes* is what the review and the developer read to place every new name, so it must say this before develop starts. - design 26: definitions carry states; the 25 seats by contracts module; the seat list from the bus; the two renames; the domain SDK and a module's own package; the transfer in the Delivery domain's SDK; checks per ADR 0634 §10 and ADR 0635 §6 - design 20, playbook 06: the homes of shared code, the first that fits - design 47: the seat mesh-module-assigner - glossary: domain SDK added; seat-set package retired; mesh-module-assigner, mesh-wants, mesh-node-enroller and the-private-network in their domains - preparer and code reviewer definitions: the homes, without the retired word Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -19,9 +19,11 @@ against the records, never limits on what you check: a ruling that contradicts a
|
||||
- it contradicts a decision in force, or does not do what its record's clause says;
|
||||
- a new exported type, field, constant, package or module placed where the designs do not put it: check each
|
||||
one yourself against the design section *Where a seat's code goes* (ask the knowledge base where a seat's code
|
||||
goes): a seat's types in its contract in its domain's contracts module, or in the seat-set package while the seat
|
||||
is not defined whole; logic over a seat in its client package; mesh-sdk only the runtime and seat-neutral parts,
|
||||
never a seat-specific type. Check it whatever the handover says;
|
||||
goes): a seat's types and state layouts in its contract in its domain's contracts module; logic over a seat in its
|
||||
client package; what one module owns in that module's own package; what one domain's modules share in its domain
|
||||
SDK, imported only by that domain's modules and its seats' holders and callers; mesh-sdk only the runtime and what
|
||||
more than one domain uses, never a seat-specific type and never an import of a contracts module. Check it whatever
|
||||
the handover says;
|
||||
- an interaction that is not a mesh path: one module naming another, reading another's internals or being
|
||||
special-cased in another part; a module's name in shared code; state only in memory; a poll or a timer where
|
||||
an event exists; a new state without a tool that reads it or a new behaviour without a tool that steers it;
|
||||
|
||||
@@ -21,9 +21,10 @@ event, which provision (requires and provides), which state on the bus (key-valu
|
||||
and which module owns it, which field of a module's own manifest. A module that names another module, reads
|
||||
another's internals, or is special-cased in another part is not a mesh path: name it as a finding and give the
|
||||
mesh-shaped alternative. Where each new piece of code goes is the design section *Where a seat's code goes* (ask the knowledge base where a
|
||||
seat's code goes): a seat's types in its contract in its domain's contracts module, or in the seat-set package while
|
||||
the seat is not defined whole; logic over a seat in its client package; mesh-sdk only the runtime every module uses
|
||||
and seat-neutral parts, never a seat-specific type and never a module's name. Name, for each new exported type,
|
||||
seat's code goes): a seat's types and state layouts in its contract in its domain's contracts module; logic over a
|
||||
seat in its client package; what one module owns in that module's own package; what one domain's modules share in
|
||||
its domain SDK; mesh-sdk only the runtime every module uses and what more than one domain uses, never a
|
||||
seat-specific type and never a module's name. Name, for each new exported type,
|
||||
field, constant, package or module, the line of that section that places it.
|
||||
|
||||
**Then the work**, as playbook 07's prepare step says: per repository every file and test the change touches,
|
||||
|
||||
+49
-26
@@ -59,8 +59,12 @@ is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
|
||||
A node seat may also name **the paths its holder owns**, such as `/etc/hosts`: a claim whose module does
|
||||
not declare them is refused, and only a claimant declares them (ADR 0287).
|
||||
- **seat definition** — the one language-neutral file (a schema with conformance fixtures) that names a seat's
|
||||
verbs and their messages, its events, its state and the forms of its provisions; its Go and TypeScript types
|
||||
verbs and their messages, its events, its states and the forms of its provisions; its Go and TypeScript types
|
||||
are generated from it. The indexer keeps every trunk's and open pull request's as bus state (ADR 0608 §1, §2).
|
||||
Every seat has one, written by hand in its domain's contracts module, either whole or at the seat list's grain
|
||||
(its name, scope, verbs and provision), and every reader of the list of seats learns it from the bus, never from a
|
||||
compiled package (ADR 0635 §1, §2).
|
||||
*Not:* ~~seat-set package~~ (hq)
|
||||
- **operator** — the person who runs the mesh, and the one the mesh talks to.
|
||||
*Not:* ~~master~~ (hq)
|
||||
- **person** — any human, as against the mesh acting unattended: *a person's word* releases a held
|
||||
@@ -72,7 +76,7 @@ is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
|
||||
**Purpose.** To say what one module is, in the one document every other domain reads.
|
||||
**Recorded in** the catalog, one manifest per module. **Upstream of** every other domain; its words
|
||||
are a published vocabulary, fixed by the manifest's schema. **Decided by** ADR 0040, 0126, 0174, 0188,
|
||||
0207, 0236, 0262.
|
||||
0207, 0236, 0262, 0634, 0635.
|
||||
**Uses:** module, seat, config value (Config), provision (Provisioning), data class (Data), health (Health
|
||||
and repair).
|
||||
|
||||
@@ -99,25 +103,32 @@ and repair).
|
||||
seat's **verb** is the same thing carried by a seat rather than a module.
|
||||
- **mesh-sdk** — the library a module's own code is written against, including the SDK harness that serves a
|
||||
tools bundle to the tool runner. The SDK harness is part of it, not a library of its own. It keeps the runtime
|
||||
every module uses, and the seat-neutral parts two or more seats' clients or holders share; its seat contracts and
|
||||
the logic it held over seats move into the contracts modules, and its seat list into the seat-set package
|
||||
(ADR 0608 §5, ADR 0625 §2, §9, ADR 0627 §2).
|
||||
every module uses, and what modules or seats of more than one domain share; its seat contracts and the logic it
|
||||
held over seats move into the contracts modules, what one domain's modules share into its domain SDK, and what
|
||||
one module owns into that module's own package. It imports no contracts module and reads the seat list from the
|
||||
bus (ADR 0608 §5, ADR 0625 §9, ADR 0634 §1, §4, §5, ADR 0635 §1, §4).
|
||||
*Not:* ~~tools-sdk~~
|
||||
- **contracts module** — a module whose work is to publish the contract packages of seats (their verbs, events,
|
||||
the layouts of their states, their messages), one per seat defined whole and per language, the seat-set package,
|
||||
and the seats' client packages; every file but a client's is generated. `mesh-contracts` for the Core domain's
|
||||
seats and every domain that has none yet, `mesh-<domain>-contracts` for a domain's, named after its heading on
|
||||
this page; a seat defined outside the mesh's own contracts has one of its own. A seat's holder implements the
|
||||
contract; the contracts module holds no seat (ADR 0608 §5, ADR 0625 §1, §5 to §7).
|
||||
the layouts of their states, their messages), one per seat defined whole and per language, with the definitions
|
||||
of its seats at every grain and the seats' client packages; every file but a definition's, a fixture's and a
|
||||
client's is generated. `mesh-contracts` for the Core domain's seats, `mesh-config` and every domain that has none
|
||||
yet, `mesh-<domain>-contracts` for a domain's, named after its heading on this page; a seat defined outside the
|
||||
mesh's own contracts has one of its own. A package-only module found by its manifest, at a repository's root or in
|
||||
a folder. A seat's holder implements the contract; the contracts module holds no seat (ADR 0608 §5, ADR 0625 §1,
|
||||
§5 to §7, ADR 0634 §7, §8, ADR 0635 §2).
|
||||
*Not:* ~~SDK module~~, ~~domain package~~
|
||||
- **client package** — the one hand-written package a seat may carry beside its contract, in the seat's contracts
|
||||
module and never in a holder: the logic two or more callers would otherwise each write over that seat. It uses
|
||||
only its own seat's contract and mesh-sdk's runtime, never another seat's client, and names no holder, no module's
|
||||
tool and no module's subject (ADR 0625 §4, ADR 0627 §1, §3). Bare "client" only where the sense is plain (see
|
||||
module and never in a holder: the logic two or more callers or holders would otherwise each write over that seat.
|
||||
It uses only its own seat's contract, mesh-sdk's runtime and its own domain SDK, never another seat's client, and
|
||||
names no holder, no module's tool and no module's subject (ADR 0625 §4, ADR 0627 §1, §3, ADR 0634 §2). Bare "client" only where the sense is plain (see
|
||||
[Homonyms](#homonyms)).
|
||||
- **seat-set package** — the generated package in `mesh-contracts` holding every seat not yet defined whole at the
|
||||
seat list's grain (its name, scope, verbs and provision); mesh-sdk's `catalogue` is its one importer in mesh-sdk
|
||||
(ADR 0625 §2, §3).
|
||||
- **domain SDK** — a package-only module, `mesh-<domain>-sdk`, named after a domain's heading on this page, holding
|
||||
the logic and forms that one domain's modules and seats share and that no seat carries and no one module owns
|
||||
(`mesh-delivery-sdk` the first). Its importers are its domain's modules and the holders and callers of its domain's
|
||||
seats; it imports only mesh-sdk and contract packages, names no module's tool or subject, and holds no seat's type
|
||||
or state layout and no state layout one module owns. Not a contracts module, and not mesh-sdk, which keeps what
|
||||
more than one domain uses (ADR 0634 §1, §2, §8).
|
||||
*Not:* ~~domain library~~ (hq)
|
||||
- **contracts marker** — the field `generated-from` of a contracts module's package artifact, naming the directory
|
||||
of the seat definitions its files are generated from; the manifest validator refuses a module carrying it that claims a seat,
|
||||
and the build modules' test step regenerates and compares every module carrying it (design 26).
|
||||
@@ -278,22 +289,27 @@ every other domain has something to run on. **Recorded by** the controller and t
|
||||
## Placement — what runs on which node
|
||||
|
||||
**Purpose.** To decide, send and apply what each node runs, and to say why.
|
||||
**Recorded by** the controller's `inventory` database; from ADR 0567, by the seat `mesh-placement`, in its states on
|
||||
**Recorded by** the controller's `inventory` database; from ADR 0567, by the seat `mesh-module-assigner`, in its states on
|
||||
the bus. **Upstream of** Provisioning, Connectivity, Data
|
||||
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261, 0411, 0539, 0549, 0559, 0567, 0571.
|
||||
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261, 0411, 0539, 0549, 0559, 0565, 0567, 0571, 0634.
|
||||
**Uses:** node, machine, module, seat, manifest (Module), config value (Config), proposal (Operator and conversation).
|
||||
|
||||
- **assignment** — a module put on a node. Its config values on that node (module-assignment config,
|
||||
Config) are `mesh-config`'s, never part of what the controller records (ADR 0348 §9).
|
||||
- **placement** — which module runs on which node, with its pins, host ports and bindings, and what a person
|
||||
decided of the node, as one key per node in the state `placement` of the seat `mesh-placement`. It changes only by
|
||||
decided of the node, as one key per node in the state `placement` of the seat `mesh-module-assigner`. It changes only by
|
||||
a placement proposal the operator approves, and no repository holds it or names a node (ADR 0567). Until ADR
|
||||
0547's third milestone the controller's assignments are kept equal to it by the holder.
|
||||
*Not:* ~~placement file~~ (hq)
|
||||
- **mesh-placement** — the seat, held once for the mesh by the assigner, that keeps placement: its states
|
||||
- **mesh-module-assigner** — the seat, held once for the mesh by the assigner, that keeps placement: its states
|
||||
`placement`, `proposals` and `candidates`, and its seven verbs `placement`, `proposals`, `propose`, `withdraw`,
|
||||
`again`, `adopt` and `hand-back`. Only the holder writes its states (ADR 0567).
|
||||
- **seat holders** — the state `seat-holders` of the seat `mesh-placement`, written by its holder, the assigner: one
|
||||
`again`, `adopt` and `hand-back`. Only the holder writes its states (ADR 0567, renamed by ADR 0634 §9). Its
|
||||
contract is in `mesh-placement-contracts` (ADR 0634 §7).
|
||||
*Not:* ~~mesh-placement~~ (hq)
|
||||
- **mesh-wants** — the seat, held once for the mesh by the assigner, that keeps what each node should run, one want
|
||||
per node and module (`want.<node>.<module>`), and a person's upgrade policy, served as its verb `upgrade`
|
||||
(ADR 0565 §7, ADR 0571 §8). Its contract is in `mesh-placement-contracts` (ADR 0634 §6, §7).
|
||||
- **seat holders** — the state `seat-holders` of the seat `mesh-module-assigner`, written by its holder, the assigner: one
|
||||
key per seat naming each holder and its node, composed from placement and the manifests' claims as the indexer
|
||||
holds them, and rewritten only when a key differs. The tool runner and every other reader of who holds a seat
|
||||
read it there, never the controller (ADR 0571 §6, §7).
|
||||
@@ -301,11 +317,11 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
|
||||
of each key they were laid over, the nodes' answers, the verdict and the ask. It takes effect only on the operator's
|
||||
Approve, and is discarded if declined, expired or withdrawn. A kind of *proposal* (Operator and conversation).
|
||||
- **placement candidate** — one node's placement as a placement proposal lays it, kept in the state `candidates`
|
||||
of the seat `mesh-placement` under `<proposal>.<node>` while the proposal is open. The node composes it in
|
||||
of the seat `mesh-module-assigner` under `<proposal>.<node>` while the proposal is open. The node composes it in
|
||||
**shadow** (composed and compared, never applied) and answers in its own have whether what it would run is the
|
||||
same; the verdict fails only on a refusal or a node that has not answered (ADR 0567). Not the indexer's candidates of
|
||||
a group, which are fingerprints (Delivery).
|
||||
- **hand-back** — the operator's verb `hand-back` of the seat `mesh-placement`, answered until the lease write: it
|
||||
- **hand-back** — the operator's verb `hand-back` of the seat `mesh-module-assigner`, answered until the lease write: it
|
||||
deletes every placement key, and every node returns to the compositions the controller sends. A hand act (ADR 0567).
|
||||
- **pending assignment** — an assignment of a module whose build is still running, kept, and made by the
|
||||
controller when that build registers the module, or ended with why when it does not
|
||||
@@ -431,13 +447,17 @@ and vault (Identity and access).
|
||||
**Purpose.** To issue, hold, rotate and check the credentials and grants by which modules, nodes, agents
|
||||
and the operator act. **Recorded by** the controller's `identity` and `licences` databases and the vault.
|
||||
**Upstream of** Provisioning, Delivery, and Operator and conversation.
|
||||
**Decided by** ADR 0085, 0113, 0183, 0225, 0234, 0386, 0387, 0388, 0411, 0413, 0414, 0550, 0571.
|
||||
**Decided by** ADR 0085, 0113, 0183, 0225, 0234, 0386, 0387, 0388, 0411, 0413, 0414, 0550, 0571, 0587, 0634.
|
||||
**Uses:** module, node, seat, tool (Module), operator, consumer and provision (Provisioning), agent and ask (Operator and conversation).
|
||||
|
||||
- **credential** — anything that proves an identity: a password, a key, a token. A **pair credential**
|
||||
is the two ends of one credential, the consumer's and the provider's.
|
||||
- **secret** — a credential or other value the vault keeps sealed and the node-engine unseals into a
|
||||
file at apply (ADR 0085).
|
||||
- **mesh-node-enroller** — the seat, held once for the mesh by the module `mesh-enrolment`, through which a new
|
||||
machine joins: a one-time token issued on the operator's Approve, redeemed once by the machine's node-engine, the
|
||||
node's account minted and signed by the vault (ADR 0587 §1, renamed by ADR 0634 §9). The module keeps its name;
|
||||
only the seat's changed. Its contract is in `mesh-identity-and-access-contracts` (ADR 0634 §7).
|
||||
- **secret family** — a module's own secrets declared as one name ending in `-*`; each member is the prefix
|
||||
and a name (`smb-password-<source>`, one per source the module's config values name), given by its full name
|
||||
and never made by the mesh
|
||||
@@ -845,13 +865,16 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564.
|
||||
|
||||
**Purpose.** To make every node and module reachable by name where it should be, and unreachable where
|
||||
it should not. **Recorded by** the controller. **Upstream of** Provisioning and Health and repair.
|
||||
**Decided by** ADR 0007, 0117, 0138, 0223, 0226, 0247.
|
||||
**Decided by** ADR 0007, 0117, 0138, 0223, 0226, 0247, 0634.
|
||||
**Uses:** node, machine, assignment and endpoint.
|
||||
|
||||
- **private network** — the mesh's own encrypted network between its nodes, on which every node has an
|
||||
address and a mesh name (ADR 0226).
|
||||
The network the machine sits on without it is the **underlay**.
|
||||
*Not:* ~~overlay~~ (hq)
|
||||
- **the-private-network** — the seat of the private network, whose provision is the value a module reads to reach
|
||||
the private network; its contract, holding that value's layout, and its client, holding the private network's own
|
||||
manifest that its callers compose, are in `mesh-connectivity-contracts` (ADR 0634 §4, §6, §7, ADR 0635 §4).
|
||||
- **anchor** and **hub** — the roles a node plays for the private network: the anchor is reachable from
|
||||
outside and every node reaches it; a hub relays for nodes that cannot reach each other directly.
|
||||
- **resolver** — a seat holder that answers the mesh's names; a node lists only the mesh's resolvers
|
||||
|
||||
@@ -83,21 +83,30 @@ Three questions, answered from the machine:
|
||||
thing works: the credential authenticates, a wrong one is refused, the containers reach each
|
||||
other, the data survives a restart.
|
||||
|
||||
## A module that calls or holds a seat
|
||||
## A module that calls or holds a seat, or shares code
|
||||
|
||||
*Added 2026-11-04* (ADR 0625, ADR 0627). Where each piece of a seat's code goes is
|
||||
[design 20](../../03-DESIGN/01-to-be/20-writing-a-module.md) *Where a seat's code goes*; in short:
|
||||
*Added 2026-11-04, widened 2026-11-05* (ADR 0625, ADR 0627, ADR 0634, ADR 0635). Where each piece of shared code goes
|
||||
is [design 20](../../03-DESIGN/01-to-be/20-writing-a-module.md) *Where a seat's code goes*: shared code lives with its
|
||||
owner. In short:
|
||||
|
||||
- **Import the seat's contract and, where it has one, its client package**, from the seat's contracts module
|
||||
(`mesh-contracts` today), never the holder module and never a copy of the seat's types in your own code.
|
||||
- **Import the seat's contract and, where it has one, its client package**, from the seat's domain's contracts module
|
||||
(`mesh-<domain>-contracts`, or `mesh-contracts` for the Core domain and a domain with none), never the holder module
|
||||
and never a copy of the seat's types in your own code. The list of seats your module needs is read from the bus,
|
||||
never compiled in.
|
||||
- **Logic you would write over a seat that another caller would write too** belongs in that seat's client package,
|
||||
through a change of the contracts module; it never goes into mesh-sdk, and never into the holder.
|
||||
- **Logic and state layouts only your module owns**, where it holds no seat for them, are your module's own package;
|
||||
another repository's module imports it only by a published version, so your manifest declares it as a package
|
||||
artifact.
|
||||
- **Logic your domain's modules share, owned by no one module and carried by no seat**, is your domain's SDK's
|
||||
(`mesh-<domain>-sdk`); only what modules of more than one domain use goes into mesh-sdk.
|
||||
- **Holding a seat** means implementing its contract in your module. A seat you define yourself gets a contracts
|
||||
module of its own (it may share your repository); a role no other module could ever take over is your module's
|
||||
own tools and events, not a seat.
|
||||
|
||||
The review of the pull request checks this; the checks design 26 lists refuse a stray file in a contracts module,
|
||||
a seat named in mesh-sdk and a client reaching another seat's client.
|
||||
The review of the pull request checks the home of every new exported name; the checks design 26 lists refuse a stray
|
||||
file in a contracts module, a seat named in mesh-sdk, an import of a contracts module from mesh-sdk, and a client
|
||||
reaching another seat's client.
|
||||
|
||||
## What the first port actually cost
|
||||
|
||||
|
||||
@@ -6,10 +6,15 @@ code:
|
||||
- mesh-controller internal/builder
|
||||
- mesh-sdk src
|
||||
- mesh-contracts
|
||||
updated: 2026-11-04
|
||||
updated: 2026-11-05
|
||||
decisions:
|
||||
- "ADR 0634"
|
||||
- "ADR 0635"
|
||||
- "ADR 0625"
|
||||
- "ADR 0627"
|
||||
- "ADR 0573"
|
||||
- "ADR 0606"
|
||||
- "ADR 0609"
|
||||
- "ADR 0150"
|
||||
- "ADR 0099"
|
||||
- "ADR 0053"
|
||||
@@ -55,30 +60,37 @@ Split the way the protocol is split:
|
||||
- **No storage, no HTTP framework, no logging library.** Use the language's.
|
||||
|
||||
If you find yourself wanting to add something to the SDK, the test is ADR 0039's: **does editing it
|
||||
recompile unrelated modules, and does it change often?** Both, and it does not belong.
|
||||
recompile unrelated modules, and does it change often?** Both, and it does not belong. It goes to
|
||||
its owner instead: a seat's contract or client, the module that owns it, or its domain's SDK (*Where a seat's code
|
||||
goes*, below; ADR 0634 §1).
|
||||
|
||||
## Where a seat's code goes
|
||||
|
||||
*Added 2026-11-04* (ADR 0625, ADR 0627; [design 26](26-the-seats.md) *Where a seat's code goes* is the
|
||||
whole rule). A module that calls or holds a seat meets three places, and each piece of code has one:
|
||||
*Added 2026-11-04, widened 2026-11-05* (ADR 0625, ADR 0627, ADR 0634, ADR 0635; [design 26](26-the-seats.md) *Where
|
||||
a seat's code goes* is the whole rule). Shared code lives with its owner (ADR 0634 §1): a module that calls or holds
|
||||
a seat, or shares code with other modules, meets these places, and each piece of code has one, the first that fits:
|
||||
|
||||
| the code | lives in | written |
|
||||
|---|---|---|
|
||||
| a seat's types, subjects and a typed call per verb or accept | the seat's **contract**: a package of its own per language in the seat's contracts module (`mesh-contracts`, or `mesh-<domain>-contracts` once its domain moves), or the seat-set package while the seat is not yet defined whole | generated from the seat's definition, never by hand |
|
||||
| logic two or more callers would otherwise each write over that seat (an ask and its awaited answer, publishing a file in parts to a registry) | the seat's **client package**, beside its contract, owned by the contracts module | by hand; it uses only its own seat's contract and mesh-sdk's runtime, never another seat's client, and names no holder, no module's tool and no module's subject |
|
||||
| what every module needs whatever the seat (the bus connection, the tools bundle's runtime, state), and a part several seats' clients or holders share that names no seat, verb or seat's type (moving a file in parts) | **mesh-sdk** | by hand; it takes no seat-specific type |
|
||||
| a seat's types, subjects, the layouts of its states and a typed call per verb or accept | the seat's **contract**: a package of its own per language in its domain's contracts module (`mesh-<domain>-contracts`, or `mesh-contracts` for the Core domain and a domain with none), for a seat defined whole; a seat at the seat list's grain has only its definition, which every reader reads from the bus (ADR 0635 §1, §2) | generated from the seat's definition, never by hand |
|
||||
| logic two or more callers or holders would otherwise each write over that seat (an ask and its awaited answer, publishing a file in parts to a registry) | the seat's **client package**, beside its contract, owned by the contracts module | by hand; it uses only its own seat's contract, mesh-sdk's runtime and its own domain's SDK, never another seat's client, and names no holder, no module's tool and no module's subject |
|
||||
| logic and state layouts one module owns, where it holds no seat for them | that module's **own package**, which other modules import from it: by path in the same repository (ADR 0609 §2), by a published version from another (ADR 0573 §1), so its manifest declares it as a package artifact | by hand, in the owner module |
|
||||
| logic and forms no seat carries and no one module owns, used by one domain's modules or seats only (moving a file in parts, the build steps' shared logic) | that domain's **domain SDK**, `mesh-<domain>-sdk`, a package-only module (ADR 0634 §2) | by hand; it imports only mesh-sdk and contract packages, names no module's tool or subject, and holds no seat's type or state layout |
|
||||
| what every module needs whatever the seat (the bus connection, the tools bundle's runtime, state), and a part modules or seats of more than one domain share that names no seat, verb or seat's type | **mesh-sdk** | by hand; it takes no seat-specific type, imports no contracts module, and reads the seat list from the bus |
|
||||
| the seat's implementation | the **holder** module | by hand, against the contract; never the place of the contract or a client |
|
||||
|
||||
**So a module imports the contracts and clients of the seats it uses, and mesh-sdk.** Its users rebuild when a
|
||||
seat they use changes, not when any seat does. A seat you define yourself, outside the mesh's own contracts, gets a
|
||||
**So a module imports the contracts and clients of the seats it uses, the packages of the modules whose state it
|
||||
reads, its domain's SDK where it uses it, and mesh-sdk.** Its users rebuild when something they use changes, not when
|
||||
any seat or any domain does. A seat you define yourself, outside the mesh's own contracts, gets a
|
||||
contracts module of its own, which may share your holder module's repository (ADR 0625 §7): a second holder then
|
||||
imports only the contract, never your holder. And a role no other module could ever take over is no seat at all:
|
||||
it is your module's own tools and events (ADR 0625 §8).
|
||||
imports only the contract, never your holder. A contracts module and a domain SDK are modules like any other, found by
|
||||
their manifests in folders of a repository and delivered to no node (ADR 0634 §8). And a role no other module could
|
||||
ever take over is no seat at all: it is your module's own tools and events (ADR 0625 §8).
|
||||
|
||||
*How it is checked:* by the checks design 26 lists: the generators' tests, mesh-sdk's import and package-list tests,
|
||||
the build modules' regenerate-and-compare step, the catalog check of a client and the manifest validator's refusal of a
|
||||
contracts module that claims a seat; a role made a seat, or a seat left as one module's tools, by the review of the
|
||||
pull request that adds it.
|
||||
contracts module that claims a seat; the home of each new exported name, a domain SDK's importers included, and a role
|
||||
made a seat or a seat left as one module's tools, by the review of the pull request that adds it (ADR 0634 §10).
|
||||
|
||||
## A module with four capabilities, in four languages
|
||||
|
||||
|
||||
@@ -15,9 +15,15 @@ code:
|
||||
- mesh-catalog modules/gitea/module.json
|
||||
- mesh-controller internal/inventory/migrations/0063-a-machines-names-are-one-seats.sql
|
||||
- mesh-controller internal/inventory/migrations/0064-the-resolver-file-is-the-uplinks.sql
|
||||
updated: 2026-11-04
|
||||
updated: 2026-11-05
|
||||
decisions:
|
||||
- "ADR 0634"
|
||||
- "ADR 0635"
|
||||
- "ADR 0625"
|
||||
- "ADR 0573"
|
||||
- "ADR 0606"
|
||||
- "ADR 0609"
|
||||
- "ADR 0595"
|
||||
- "ADR 0627"
|
||||
- "ADR 0608"
|
||||
- "ADR 0613"
|
||||
@@ -178,24 +184,40 @@ merges.
|
||||
## A seat's definition (from 2026-11-03)
|
||||
|
||||
**A seat is defined once, in one language-neutral file, and every part learns it from the bus** (ADR 0608, from
|
||||
research 081). The registry seats (design 51), `mesh-broker` (design 25 § 12.3), the four seats the milestone
|
||||
adds verbs or events to, and `node-engine` are the first ten defined whole this way, in the milestone of ADR 0612
|
||||
(ADR 0613 §1, ADR 0620, ADR 0627 §1).
|
||||
research 081). Every seat has its definition file in its domain's contracts module, written by hand, whether it is
|
||||
defined whole or at the seat list's grain (ADR 0635 §2). In the milestone of ADR 0612, 25 seats are defined whole
|
||||
(ADR 0613 §1, ADR 0620, ADR 0627 §1, ADR 0634 §6, ADR 0635 §5); every other seat is defined at the seat list's grain.
|
||||
|
||||
- **The file** is a schema with conformance fixtures: the seat's verbs and their messages, its events and their
|
||||
bodies, its state and the forms of its provisions. It lives in the contracts module of its domain (*Where a seat's
|
||||
bodies, its states and the forms of its provisions. It lives in the contracts module of its domain (*Where a seat's
|
||||
code goes*, below). Its Go and
|
||||
TypeScript types are generated from it and committed beside it; nobody writes them by hand. The format is JSON, its
|
||||
messages and bodies JSON Schema, as the seat set's verb inputs already are, with the format's own schema checked in;
|
||||
the fixtures are data, never functions.
|
||||
- **What is defined whole now** (ADR 0613; ADR 0620, on the
|
||||
operator's answer of 2026-11-04 to move them all). Every seat this milestone changes is defined whole and its
|
||||
contract moves into `mesh-contracts`: `npm-package-registry`, `go-package-registry`, `container-image-registry`,
|
||||
`oci-artifact-registry` (one common part of their shared verbs, written once, so the four cannot drift) and
|
||||
`mesh-broker`; and the four seats it adds a verb or an event to, each with every verb its holder's manifest on the
|
||||
trunk declares today, plus the new ones. **No event moves subject in this milestone** (ADR 0620): a seat's own events are only those published on its seat subject today,
|
||||
and a holder's own events stay under the holder's own subjects, listed beside the seat they belong with, never moved
|
||||
onto it:
|
||||
- **A definition names its states** (ADR 0608 §1; ADR 0634 §6 leaves the file's format to this design). The field
|
||||
`states` lists each state the seat's holder keeps and others read: its local name, its template of ADR 0595 (state,
|
||||
events, work queue, log, objects or ledger), who writes it (the holder, or each caller its own keys), each form of
|
||||
its keys with the schema of the value under it, and how long it keeps its history. No entry names a holder module,
|
||||
so another module can hold the seat by importing the contract alone (ADR 0625 §7). The generated package carries,
|
||||
per state, its local name, a builder and a parser per key form, and the value types, decoded strictly; the
|
||||
fixtures hold one value per key form. `operator-channel`'s `records` becomes one `states` entry in the same change,
|
||||
so the format has one form for a state. The format's own schema refuses an entry with an unknown template or a
|
||||
key form without a value, naming it.
|
||||
- **What is defined whole.** Ten seats came first (ADR 0613; ADR 0620, on the operator's answer of 2026-11-04 to move
|
||||
them all; ADR 0627 §1): `npm-package-registry`, `go-package-registry`, `container-image-registry` and
|
||||
`oci-artifact-registry` (one common part of their shared verbs, written once, so the four cannot drift),
|
||||
`mesh-broker`, the four seats the milestone adds a verb or an event to, each with every verb its holder's manifest
|
||||
on the trunk declares today, plus the new ones, and `node-engine`. Fifteen more are defined whole in the same
|
||||
milestone because a name leaving mesh-sdk (*Where a seat's code goes*) is their type, state layout or message
|
||||
(ADR 0634 §6, ADR 0635 §5), each with its verbs, events, messages and the layouts of its states:
|
||||
`mesh-module-assigner`, `mesh-wants`, `mesh-node-enroller`, `mesh-catalog`, `node-build-go`, `node-build-image`,
|
||||
`node-build-node`, `mesh-hand-acts`, `mesh-provisioner`, `mesh-conditions`, `mesh-self-check`, `mesh-healers`,
|
||||
`mesh-watchdogs`, `the-private-network` and `mesh-delivery`. Five seats already whole gain the state layouts
|
||||
mesh-sdk held for them: `node-engine`, `mesh-vault`, `mesh-delivery-checker`, `container-image-registry` and
|
||||
`oci-artifact-registry` (ADR 0634 §6). **No event moves subject in this milestone** (ADR 0620), but those of the
|
||||
two renamed seats (*Two seats renamed*, below): a seat's own events are only those published on its seat subject
|
||||
today, and a holder's own events stay under the holder's own subjects, listed beside the seat they belong with,
|
||||
never moved onto it. The four seats the milestone adds to:
|
||||
- `mesh-delivery-checker` (held by the checker): the verbs `try`, `try-read` and `try-end`; no seat event. The
|
||||
holder's own, beside it: its family `checker.asks`, new, with `tag-wanted` (design 51 *Tagged versions*) and
|
||||
`verdict` (*Out of step is learned from events*, below); and its stream `checks`, which already declares
|
||||
@@ -207,35 +229,56 @@ adds verbs or events to, and `node-engine` are the first ten defined whole this
|
||||
`own`, `issue-account`, `sign`, `enrolment-token`, `node-account`, `rotate-node`, `node-account-confirm`,
|
||||
`abandon` and, new, `retire`; no seat event. The holder's own, beside it: `provisioned`, `rotated`,
|
||||
`secret-changed`, `account-hashed`, `own-replaced`, `account-issued`, `signed`, `rotation-begun`,
|
||||
`node-account-ready`, `rotation-done` and, new, `own-retired` (design 32). The seat list mesh-sdk compiles
|
||||
today also names `accept` and `move-asks`, which no holder serves and nothing calls: the same mesh-sdk change
|
||||
drops them from the seat, and its `vault_seat_test.go` with them.
|
||||
`node-account-ready`, `rotation-done` and, new, `own-retired` (design 32). The seat list mesh-sdk compiled
|
||||
also names `accept` and `move-asks`, which no holder serves and nothing calls: the definition drops them.
|
||||
- `operator-channel` (held by the router, the messenger module): the verbs `open`, `history`, `notify`, `tell`
|
||||
and `asks`; the asks it accepts, `ask`, `cancel` and `condition`; its seat event `decided`; `by-caller` for
|
||||
`ask`, `cancel`, `condition` and `decided`; and `records` `asks`, as the holder's seat entry has them. The
|
||||
`ask`, `cancel`, `condition` and `decided`; and its state `asks`, as the holder's seat entry has them. The
|
||||
holder's own, beside it: `refused`, and `offered` and `closed`, new, on its restricted stream (design 55 § 11).
|
||||
mesh-sdk's seat list holds no entry for it today, so its definition is written from the holder's seat entry.
|
||||
- `node-engine` (held by the node-engine on every node): the verb `manifest-reads` and its seat event
|
||||
`manifest-reads-changed`, which the milestone gives it (ADR 0618 §3, §4; design 51), so it is defined whole too
|
||||
(ADR 0627 §1).
|
||||
Its definition is written from the holder's seat entry.
|
||||
|
||||
And `node-engine` (held by the node-engine on every node) has the verb `manifest-reads` and its seat event
|
||||
`manifest-reads-changed`, which the milestone gives it (ADR 0618 §3, §4; design 51). The 25, by the contracts
|
||||
module that holds each (ADR 0634 §7, ADR 0635 §5):
|
||||
|
||||
| contracts module | domain | seats | held by |
|
||||
|---|---|---|---|
|
||||
| `mesh-delivery-contracts` | Delivery | `mesh-catalog`, `mesh-delivery-checker`, `mesh-delivery`, `node-build-go`, `node-build-image`, `node-build-node`, `npm-package-registry`, `go-package-registry`, `container-image-registry`, `oci-artifact-registry` | the indexer, the checker, the gate part, the three build modules, the forge (two), `distribution` (two) |
|
||||
| `mesh-placement-contracts` | Placement | `mesh-module-assigner`, `mesh-wants` | the assigner |
|
||||
| `mesh-health-and-repair-contracts` | Health and repair | `mesh-conditions`, `mesh-self-check`, `mesh-healers`, `mesh-watchdogs`, `mesh-hand-acts` | the condition keeper, mesh-self-check, mesh-healers, the watchman, mesh-hand-acts |
|
||||
| `mesh-provisioning-contracts` | Provisioning | `mesh-provisioner` | mesh-provisioner |
|
||||
| `mesh-identity-and-access-contracts` | Identity and access | `mesh-vault`, `mesh-node-enroller` | the vault, the module `mesh-enrolment` |
|
||||
| `mesh-connectivity-contracts` | Connectivity | `the-private-network` | its holder is named when its definition is written |
|
||||
| `mesh-operator-and-conversation-contracts` | Operator and conversation | `operator-channel` | the router |
|
||||
| `mesh-contracts` | Core, and Config | `node-engine`, `mesh-broker`, `mesh-config` | the node-engine, the bus module, mesh-config |
|
||||
|
||||
**How it is checked**: each of these definitions' conformance fixtures names every event's subject, the seat's and
|
||||
the holder's own, and a case of the holder's whole-module test takes a fixture from the running holder (an event
|
||||
it publishes) and matches it, subject and body, against the definition. The builder and the indexer hold no seat:
|
||||
it publishes) and matches it, subject and body, against the definition; the indexer's generator tests cover each
|
||||
of the 25 (ADR 0634 §10, ADR 0635 §6). The builder and the indexer's own events hold no seat:
|
||||
the builder's `numbered` and `old-form-closed`, the indexer's `manifest-accepted` and its family `indexer.views`
|
||||
are those modules' own, declared in their own manifests, which
|
||||
ADR 0613 does not govern, and no seat definition carries them. Every other seat, the foundation's included, has its definition on the bus in the same milestone, all
|
||||
at once (ADR 0608 §2), holding the seat list's grain: its name, whether it is held once or on every node, its verbs
|
||||
with their inputs and its provision, generated from the seat list mesh-sdk compiles today, so the move changes
|
||||
nothing a reader sees (ADR 0613 §2). Its messages, events and state layouts are added to
|
||||
a seat's definition when its domain's contract next changes, which moves that domain's seats whole into its contracts
|
||||
module in that change (ADR 0613 §3); which domain moves when is tracked by issue 167 (ADR 0613 §4).
|
||||
- **The seat set has one source.** The manifest validator, the node-engine, the tool runner and claude-code each compile a copy of
|
||||
the seat list today; all four import the seat-set package generated in `mesh-contracts` instead, which is where
|
||||
mesh-sdk's seat list moves (ADR 0625 §2), and mesh-sdk's `catalogue` reads the seat set from there. The tool runner's descriptions
|
||||
and claude-code keep that compiled set, equal to the trunk's definition, in this milestone, so neither depends on
|
||||
the indexer at its start; they move to `indexer_seat_definition` and its event when their next change moves them,
|
||||
tracked on issue 1966.
|
||||
with their inputs and its provision. Its file is written by hand in its domain's contracts module, or in
|
||||
`mesh-contracts` where its domain has none; the files the registry branch generated once from mesh-sdk's seat list
|
||||
are their starting text, and nothing generates them again (ADR 0635 §2). Its messages, events and state layouts are
|
||||
added to a seat's definition when its domain's contract next changes, which moves that domain's seats whole into its
|
||||
contracts module in that change (ADR 0613 §3); which domain moves when is tracked by issue 167 (ADR 0613 §4).
|
||||
- **Two seats renamed** (ADR 0634 §9): `mesh-placement` becomes `mesh-module-assigner`, and `mesh-enrolment`
|
||||
becomes `mesh-node-enroller`; the module `mesh-enrolment` keeps its name. Their definitions, the subjects of their
|
||||
verbs and events, every holder's claim, every caller's `invokes` and grant, and the glossary take the new names in
|
||||
the same delivery group, and nothing answers to the old ones. **How it is checked**: the manifest validator refuses a
|
||||
claim of a seat no definition names, so a claim of an old name fails (ADR 0634 §10).
|
||||
- **Every part learns the seat list from the bus** (ADR 0635 §1). The manifest validator, the node-engine, the tool
|
||||
runner, claude-code and every other reader of the list of seats read the definitions the indexer keeps (*On the
|
||||
bus*, below) through mesh-sdk's runtime, at the grain each definition holds, and learn a changed one from the
|
||||
indexer's `seat-definition-changed`. No package carries the seat list, and mesh-sdk imports no contracts module.
|
||||
**A reader that has not heard the indexer** knows the foundation's bootstrapped definitions, says in its health
|
||||
that it waits for the rest, and a check that cannot read the definitions it needs fails, naming them, rather than
|
||||
passing without them (ADR 0635 §3). **How it is checked** (ADR 0635 §6): a test of the readers' start reads the seat
|
||||
list from a bus holding the foundation's definitions only, asserting that the reader says it waits, and then with
|
||||
the indexer's; the indexer's tests read a seat-list-grain definition from a contracts module like a whole one.
|
||||
- **The generator** is each language's build module's: the Go build module's package for Go, the Node and TypeScript
|
||||
build module's for TypeScript (the logic is the module's whose work it is). The generator's version is a build input
|
||||
of every contracts module, so a changed generator rebuilds each contracts module once (ADR 0603 §3). Each build
|
||||
@@ -251,7 +294,7 @@ adds verbs or events to, and `node-engine` are the first ten defined whole this
|
||||
bridge's messages, and keeps them in its own state `seat-definitions`, keyed by seat and source (the trunk, or a
|
||||
pull request's head), as their only writer; a definition is at most 256 KiB. It emits `seat-definition-changed`
|
||||
(seat, source, digest), kept seven days, only when a digest changed. **Only the trunk's entry is the seat's
|
||||
contract**: the readers (the contracts modules' builds, the review, and later the tool runner's descriptions) ask
|
||||
contract**: the readers (every reader of the seat list, the contracts modules' builds and the review) ask
|
||||
`indexer_seat_definition`, which answers the trunk's unless a pull request's head is named, and says which it
|
||||
answered. A pull request's entries are removed on the forge bridge's event that it closed or merged. A definition
|
||||
that does not parse fails its pull request's check; the trunk's stays. The merge is the only approval. The
|
||||
@@ -263,70 +306,104 @@ adds verbs or events to, and `node-engine` are the first ten defined whole this
|
||||
`generated-types-out-of-step`, cleared only by a clean build end of the same contracts module. **Tools** of the indexer: `indexer_seat_definition`
|
||||
(read one), `indexer_seat_definitions_again` (read a trunk's or a pull request's again now) and `indexer_out_of_step`
|
||||
(the generated types out of step).
|
||||
- **Contracts modules.** A seat's contract is published by a contracts module, which holds the seats' contracts and
|
||||
their client packages and no seat (ADR 0625 §4, §5); the seat's holder implements the contract. **The contracts marker**: a contracts
|
||||
- **Contracts modules.** A seat's contract is published by a contracts module, which holds the seats' definitions,
|
||||
their contracts and their client packages and no seat (ADR 0625 §4, §5); the seat's holder implements the contract.
|
||||
**The contracts marker**: a contracts
|
||||
module's package artifact names the directory of its definitions in the field `generated-from`, and the manifest validator
|
||||
refuses a module carrying it that claims a seat, naming the seat. `mesh-contracts` declares its packages in Go and
|
||||
TypeScript, cut per seat as *Where a seat's code goes* says, in package series `0.1`, published through the two
|
||||
package seats (design 51) and taken by its users by version, or inside one delivery group by the group's head. No
|
||||
`mesh-<domain>-contracts` is created in this milestone: a domain's contracts module is created by the change that
|
||||
next moves its domain (ADR 0625 §6). mesh-sdk keeps its name and the shared runtime, and takes no new seat-specific
|
||||
type (ADR 0613 §5): a unit test of mesh-sdk refuses an exported identifier or string constant naming a seat the
|
||||
definitions define. The two checks every change already runs, the
|
||||
refuses a module carrying it that claims a seat, naming the seat. **Each domain whose seats the milestone defines
|
||||
whole has a contracts module of its own, created in the milestone** (ADR 0634 §7, ADR 0635 §5; the table above);
|
||||
`mesh-contracts` keeps the Core domain's seats, `mesh-config`, and the definitions of every seat whose domain has
|
||||
none yet. Each declares its packages in Go and TypeScript, cut per seat as *Where a seat's code goes* says, in
|
||||
package series `0.1`, published through the two package seats (design 51) and taken by its users by version, or
|
||||
inside one delivery group by the group's head.
|
||||
- **A contracts module and a domain SDK are modules like any other, found by their manifests** (ADR 0634 §8).
|
||||
`mesh-delivery-contracts` and the Delivery domain's SDK are folders of the mesh-delivery repository, and the other
|
||||
domains' contracts modules folders of the mesh-contracts repository. Each is a package-only module, as mesh-sdk long
|
||||
is: published from its trunk, rebuilding the modules that use it like any package (ADR 0573 §2, §3), and delivered
|
||||
to no node. A step of the build or the delivery that treats a module in a folder unlike one at a repository's root
|
||||
is a gap of the build and delivery system, fixed in the milestone, never worked around. **How it is checked**: the
|
||||
delivery group's one check builds and publishes every new module from its folder, and the build modules'
|
||||
regenerate-and-compare step runs on every contracts module the milestone creates (ADR 0634 §10).
|
||||
- **mesh-sdk takes no seat-specific type** (ADR 0613 §5): a unit test of mesh-sdk refuses an exported identifier or
|
||||
string constant naming a seat the definitions define. The two checks every change already runs, the
|
||||
build modules' compare step and that test, are where a stray file and a stray type are refused; mesh-catalog's own
|
||||
checks cannot see another repository.
|
||||
- **A contracts cycle holds nothing.** `mesh-contracts` is published through the forge module's package seats and
|
||||
built by the Go and Node build modules, and the forge module, `distribution` and the Go build module import it. A
|
||||
- **A contracts cycle holds nothing.** `mesh-delivery-contracts` is published through the forge module's package seats
|
||||
and built by the Go and Node build modules, and the forge module, `distribution` and the Go build module import it. A
|
||||
package edge and a build module's edge are triggers, never waits, so that cycle starts and is not refused (ADR 0614
|
||||
§6), and a package is numbered per source revision, so the triggers end (design 51 *The versions*).
|
||||
- **Older readers keep working**: a moved contract keeps its subjects, keys and message shapes, and a reader ignores
|
||||
a field it does not know.
|
||||
a field it does not know. The two renamed seats are the exception, and every one of their users moves in the same
|
||||
delivery group (ADR 0634 §9, as it changes ADR 0608 §6).
|
||||
- **A vendor-specific** provision or contribution lives in its module's own extension package, published by version
|
||||
like any package; a later holder of the seat may publish its own the same way. A seat's definition stays
|
||||
vendor-neutral, which the seams review checks.
|
||||
|
||||
### Where a seat's code goes
|
||||
|
||||
*Added 2026-11-04* (ADR 0625, ADR 0627; the operator, 2026-11-04: "many small sdk's instead of 1 large sdk"). A
|
||||
module is rebuilt only for the seats it uses, so a seat's code is cut per seat, in the contracts module of its
|
||||
domain; mesh-sdk keeps what every module shares.
|
||||
*Added 2026-11-04, widened 2026-11-05* (ADR 0625, ADR 0627, ADR 0634, ADR 0635; the operator, 2026-11-04: "many small
|
||||
sdk's instead of 1 large sdk", and shared logic lives with its owner). A module is rebuilt only for what it uses, so
|
||||
shared code lives with its owner: a seat's code is cut per seat, in the contracts module of its domain; what one
|
||||
module owns is that module's own package; what one domain's modules and seats share is that domain's SDK; mesh-sdk
|
||||
keeps only what modules or seats of more than one domain use.
|
||||
|
||||
```
|
||||
contracts module (mesh-contracts, or mesh-<domain>-contracts)
|
||||
├── definitions and fixtures written by hand, the generation's source, outside the published packages
|
||||
├── one package per seat defined whole, per language generated: types, subjects, a typed call per verb
|
||||
│ └── its client package (where callers share logic over the seat) written by hand
|
||||
└── the seat-set package generated: every seat not yet defined whole, at the seat list's grain
|
||||
contracts module of a domain (mesh-<domain>-contracts; mesh-contracts for Core, mesh-config, and a domain with none)
|
||||
├── definitions and fixtures written by hand, every seat's at its grain, the generation's source
|
||||
└── one package per seat defined whole, per language generated: types, subjects, state layouts, a typed call per verb
|
||||
└── its client package (where callers or holders share logic over the seat) written by hand
|
||||
|
||||
mesh-sdk the runtime every module uses, and seat-neutral parts that several seats' clients or holders share
|
||||
imports of a contracts module: only `catalogue`'s, of the seat-set package
|
||||
domain SDK (mesh-<domain>-sdk) written by hand: logic and forms one domain's modules and seats share, owned by no module
|
||||
a module's own package written by hand: logic and state layouts one module owns, where it holds no seat for them
|
||||
mesh-sdk the runtime every module uses, and what modules or seats of more than one domain share;
|
||||
it imports no contracts module and reads the seat list from the bus
|
||||
```
|
||||
|
||||
- **Shared code lives with its owner** (ADR 0634 §1), and the first home that fits is the one: a seat's types, the
|
||||
layouts of its states and the messages of its verbs and events are its contract's, and the logic its callers or
|
||||
holders share is its client's; logic and state layouts one module owns, where that module holds no seat for them,
|
||||
are that module's own package, which other modules import from it; logic and forms no seat carries and no one
|
||||
module owns, the seat-neutral parts seats' clients or holders share included, are their domain SDK's when only one
|
||||
domain's modules or seats use them, and mesh-sdk's when more than one domain's do or every module does.
|
||||
- **Each seat defined whole has a package of its own, per language** (ADR 0625 §1, ADR 0627 §1): its generated
|
||||
contract, and a module imports only the packages of the seats it uses, so a change of that seat rebuilds only its
|
||||
users. Where the fingerprint counts a language's module rather than its package, each such package is a module of
|
||||
its own in the same repository. In the milestone of ADR 0612 these are the ten seats above.
|
||||
- **Every other seat is in one seat-set package** in `mesh-contracts` (ADR 0625 §2), holding each seat's name, scope,
|
||||
verbs and provision at the seat list's grain. A change of any of them rebuilds every importer of that package,
|
||||
mesh-sdk's importers included, until its domain moves and it is defined whole.
|
||||
- **The imports run one way per package** (ADR 0625 §3): a generated package imports nothing of mesh-sdk; mesh-sdk's
|
||||
only import of a contracts module is `catalogue`'s, of the seat-set package; a client imports its own seat's
|
||||
contract and mesh-sdk's runtime. Where a language's module is the unit of import, the clients are a module of
|
||||
their own in the repository, so the two never form a cycle.
|
||||
- **A client package** (ADR 0625 §4) is the one hand-written package a seat may carry beside its contract, owned by
|
||||
the seat's contracts module, never by a holder. It holds the logic two or more callers would otherwise each write
|
||||
over that seat, and only where such logic exists; it uses only its own seat's contract and mesh-sdk's runtime,
|
||||
never another seat's client, and never names a holder, a module's tool or a module's subject. A seat's types and
|
||||
typed calls are its contract's, never its client's.
|
||||
- **Seven clients come in the milestone of ADR 0612** (ADR 0627 §1), for the seats whose shared logic mesh-sdk holds
|
||||
today, each moved out of mesh-sdk with every importer in the same group, mesh-sdk keeping no copy and no alias:
|
||||
`operator-channel` (an ask and its awaited answer, mesh-sdk's `asks` today); `mesh-vault` (the calls its callers
|
||||
share; mesh-sdk's hand-written vault types are replaced by the vault contract's, not moved into the client);
|
||||
`node-engine` (the checks of its compose-candidate ask and answer); and `npm-package-registry`,
|
||||
`go-package-registry`, `container-image-registry` and `oci-artifact-registry` (publishing a file in parts, one
|
||||
client per seat, each binding mesh-sdk's seat-neutral parts transfer to its own seat's verbs and types).
|
||||
- **Moving a file in parts stays seat-neutral in mesh-sdk, on both sides** (ADR 0627 §2): the sending side and the
|
||||
going on from what a holder already holds, and the holder's side (taking the parts into the holder's own objects,
|
||||
its own in the same folder. In the milestone of ADR 0612 these are the 25 seats above.
|
||||
- **A seat at the seat list's grain has its definition and no package** (ADR 0635 §1, §2): its readers learn it
|
||||
from the bus, and a change of it rebuilds nothing.
|
||||
- **The imports run one way per package** (ADR 0625 §3, as ADR 0634 §2 and ADR 0635 §1 change it): a generated
|
||||
package imports nothing of mesh-sdk; mesh-sdk imports no contracts module; a domain SDK imports only mesh-sdk and
|
||||
contract packages; a client imports its own seat's contract, mesh-sdk's runtime and its own domain's SDK. Where a
|
||||
language's module is the unit of import, the clients are a module of their own in the folder, so the two never
|
||||
form a cycle.
|
||||
- **A client package** (ADR 0625 §4, as ADR 0634 §2 changes it) is the one hand-written package a seat may carry
|
||||
beside its contract, owned by the seat's contracts module, never by a holder. It holds the logic two or more
|
||||
callers or holders would otherwise each write over that seat, and only where such logic exists; it uses only its
|
||||
own seat's contract, mesh-sdk's runtime and its own domain's SDK, never another seat's client, and never names a
|
||||
holder, a module's tool or a module's subject. A seat's types and typed calls are its contract's, never its client's.
|
||||
- **A domain SDK** (ADR 0634 §2) is a package-only module, `mesh-<domain>-sdk`, named after the domain's heading in
|
||||
the glossary, which may sit in a repository with that domain's modules. Its importers are its domain's modules and
|
||||
the holders and callers of its domain's seats; it imports only mesh-sdk and contract packages, names no module's
|
||||
tool or subject, and holds no seat's type or state layout and no state layout one module owns. The first is
|
||||
`mesh-delivery-sdk`, in the milestone of ADR 0612: the moving of a file in parts (below), the build steps' and the
|
||||
composer's shared logic, each made seat-neutral over its callers' types (ADR 0635 §4), and the rules the Delivery
|
||||
domain's modules share.
|
||||
- **A module's own package** (ADR 0634 §1) holds what that module owns and no seat carries: its state layouts that
|
||||
other modules read and the logic over them. Another module of the same repository uses it by path, from the same
|
||||
commit (ADR 0609 §2); a module of another repository uses it only by its name and a published version (ADR 0573
|
||||
§1), so the owner's manifest declares it as a package artifact (ADR 0606 §4).
|
||||
- **The clients of the milestone of ADR 0612** (ADR 0627 §1, ADR 0634 §4, ADR 0635 §4), each moved out of mesh-sdk
|
||||
with every importer in the same delivery group, mesh-sdk keeping no copy and no alias: `operator-channel` (an ask
|
||||
and its awaited answer, mesh-sdk's `asks` and `asker`); `mesh-vault` (the calls its callers share; mesh-sdk's
|
||||
hand-written vault types are replaced by the vault contract's, not moved into the client); `node-engine` (the
|
||||
checks of its compose-candidate ask and answer); `npm-package-registry`, `go-package-registry`,
|
||||
`container-image-registry` and `oci-artifact-registry` (publishing a file in parts, one client per seat, each
|
||||
binding the Delivery domain's SDK's transfer to its own seat's verbs and types); `mesh-hand-acts` (recording a
|
||||
hand act); `mesh-provisioner` (mesh-sdk's provider runtime and its harness, which only providers use); and
|
||||
`the-private-network` (the private network's own manifest, which its callers compose).
|
||||
- **Moving a file in parts is seat-neutral, in the Delivery domain's SDK, on both sides** (ADR 0627 §2, as ADR 0634
|
||||
§3 changes it): it serves only the four registry seats, all of the Delivery domain. The sending side and the going
|
||||
on from what a holder already holds, and the holder's side (taking the parts into the holder's own objects,
|
||||
checking their hashes, dropping an upload left idle, saying when its objects fill), name no seat, verb or seat's
|
||||
type and take subjects, shapes and checks from their caller. Each registry seat's client binds the sending side,
|
||||
and each holder (the distribution module, the forge's two package seats) binds the receiving side to the seat it
|
||||
@@ -334,10 +411,10 @@ domain; mesh-sdk keeps what every module shares.
|
||||
- **In a contracts module's published packages every file outside a client is generated** (ADR 0625 §5): the build
|
||||
modules' regenerate-and-compare step fails any other hand-written file there, naming it. The definitions and their
|
||||
fixtures sit outside the published packages and are not judged by that step.
|
||||
- **The contracts modules follow the glossary's domains** (ADR 0625 §6): a domain's seats move into
|
||||
- **The contracts modules follow the glossary's domains** (ADR 0625 §6, ADR 0634 §7): a domain's seats move into
|
||||
`mesh-<domain>-contracts`, named after the domain's heading in the glossary, when that domain's seats move; a seat
|
||||
of the Core domain, or of a domain with no contracts module yet, is in `mesh-contracts`. The order of the domains
|
||||
stays issue 167's (ADR 0613 §4).
|
||||
of the Core domain, or of a domain with no contracts module yet, is in `mesh-contracts`. The seven the milestone of
|
||||
ADR 0612 creates are in *A seat's definition*, above; the order of the other domains stays issue 167's (ADR 0613 §4).
|
||||
- **A seat defined outside the mesh's own contracts has a contracts module of its own** (ADR 0625 §7), which may
|
||||
share a repository with its first holder; its definition, contract and client never live in the holder module, so
|
||||
another module can hold the seat by importing only the contract, and the holder can be retired while the contract
|
||||
@@ -345,33 +422,40 @@ domain; mesh-sdk keeps what every module shares.
|
||||
- **A role only one module could ever play is no seat** (ADR 0625 §8): it is that module's own tools and events,
|
||||
reached by the module's name (ADR 0596 §2). The test is whether another module could take the role over, not how
|
||||
many hold it today, so every seat in force stays a seat, `mesh-broker`, `node-engine` and `route-proxy` included.
|
||||
- **mesh-sdk takes only the runtime every module uses** (ADR 0625 §9, as ADR 0627 §2 widens it): the bus connection,
|
||||
the tools bundle's runtime, state and its helpers, and a seat-neutral part two or more seats' clients or holders
|
||||
share, as long as it names no seat, verb or seat's type. After the milestone it holds no package, type or function
|
||||
over the seven seats above (ADR 0627 §4); the value layouts of seats not defined whole stay in it until their domain
|
||||
moves, as ADR 0613 §3 has it.
|
||||
- **mesh-sdk takes only what modules of more than one domain use** (ADR 0625 §9, as ADR 0627 §2, ADR 0634 §1, §4, §5
|
||||
and ADR 0635 §4 change it): the bus connection, the tools bundle's runtime, state and its helpers, the answer of a
|
||||
module's health tool, the `Membership` type with the names its runtime reads to learn its own membership, the
|
||||
package `views` (which takes its hand-act recorder and its finding writer from its caller), `outward`, the parts of
|
||||
`forgekey` that modules of more than one domain use, and a seat-neutral part seats of more than one domain share,
|
||||
as long as it names no seat, verb or seat's type. In the milestone of ADR 0612 its `go/delivery` is moved whole and
|
||||
deleted, each of its names to the home this section gives it, and every other part naming a seat or a holder's
|
||||
state leaves for its owner, every importer moving in the same delivery group; after it, mesh-sdk holds no package,
|
||||
type or function over a seat defined whole, and no seat list (ADR 0627 §4, ADR 0634 §4, ADR 0635 §1).
|
||||
|
||||
**How it is checked** (ADR 0625 §11, ADR 0627 §3, both built in the milestone of ADR 0612):
|
||||
**How it is checked** (ADR 0625 §11, ADR 0627 §3, ADR 0634 §10 and ADR 0635 §6, all built in the milestone of ADR 0612):
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| One package per seat defined whole, one seat-set package | a unit test of the generator (one program in the Go build module, emitting both languages and run by the Node build module too) emitting one package per seat defined whole and one seat-set package; the generator refuses a seat marked whole in the seat set without its own package; the manifest validator refuses a contracts module whose package holds the generated files of two seats defined whole, naming them |
|
||||
| The imports run one way | a mesh-sdk unit test that no package but `catalogue` imports a contracts module, and `catalogue` only the seat-set package; the generator tests check no generated package imports mesh-sdk |
|
||||
| mesh-sdk holds no logic over the seven seats | mesh-sdk's package-list test refuses by name `asks`, the vault's types and its shared calls, the compose-candidate checks and any seat-named publish code, and refuses the seven seats' names in mesh-sdk outside `catalogue`, so a copy kept without importing a contract fails too |
|
||||
| A client uses only its own seat's contract | the catalog check of a client: its own test refuses a client importing another seat's client and one naming a module's tool or subject, and passes the seven clients |
|
||||
| The parts transfer is seat-neutral | its unit test runs both sides against two different subjects and shapes the caller gives, and the seat-name check holds it seat-neutral; the review refuses a holder that takes parts in without it |
|
||||
| Only a client is written by hand in a published package | each build module's regenerate-and-compare test fails on a hand-written file outside a client package and passes a contracts module holding its definitions and fixtures |
|
||||
| One package per seat defined whole | a unit test of the generator (one program in the Go build module, emitting both languages and run by the Node build module too) emitting one package per seat defined whole, covering each of the 25; the manifest validator refuses a contracts module whose package holds the generated files of two seats defined whole, naming them |
|
||||
| The imports run one way | a mesh-sdk unit test that no package of mesh-sdk imports a contracts module; the generator tests check no generated package imports mesh-sdk; a domain SDK's importers and imports by the review below |
|
||||
| mesh-sdk holds no logic over seats, and no part that left it | mesh-sdk's package-list test refuses by name `go/delivery`, `asks`, `asker`, the vault's types and its shared calls, the compose-candidate checks, the provider runtime, and every other package or part ADR 0634 §4 and ADR 0635 §4 move; its seat-naming test refuses the defined seats' names in mesh-sdk, so a copy kept without importing a contract fails too |
|
||||
| A client uses only its own seat's contract and its domain's SDK | the catalog check of a client: its own test refuses a client importing another seat's client or another domain's SDK, and one naming a module's tool or subject, and passes every client of the milestone |
|
||||
| The parts transfer is seat-neutral | its unit test, in the Delivery domain's SDK, runs both sides against two different subjects and shapes the caller gives, and the seat-name check holds it seat-neutral; the review refuses a holder that takes parts in without it |
|
||||
| Only a client is written by hand in a published package | each build module's regenerate-and-compare test fails on a hand-written file outside a client package and passes a contracts module holding its definitions and fixtures; the step runs on every contracts module |
|
||||
| A module in a folder is built and published as one at a root | the delivery group's one check builds and publishes every new contracts module and the domain SDK from its folder |
|
||||
| A contracts module holds no seat; a role only one module could ever play has none | the manifest validator's refusal of a contracts module that claims a seat; review both ways: a new seat definition's pull request is asked whether another module could take the role over, and a module's pull request is asked the same of each new tool or event family other modules call |
|
||||
| Each new exported name sits where this section puts it | the review of every pull request (playbooks 07 and 08, the code reviewer's definition) asks the home of each new exported type, field, constant, package or module against this section, a domain SDK's importers included |
|
||||
|
||||
Acceptance tests: research 081's 14, 21, 25 and 26; a unit test that the generated seat set equals the seat list
|
||||
mesh-sdk compiled before the move, entry for entry; mesh-sdk's seat-naming test; each build module's compare step
|
||||
Acceptance tests: research 081's 14, 21, 25 and 26; mesh-sdk's seat-naming and import tests; the start test of the
|
||||
seat list's readers (*Every part learns the seat list from the bus*); each build module's compare step
|
||||
failing on a differing, a missing and an unwritten file, naming each; the checker's `verdict` naming out-of-step
|
||||
files; and cases of the indexer's whole-module integration test: a trunk
|
||||
files; the manifest validator refusing a claim of `mesh-placement` and of the seat `mesh-enrolment`; and cases of
|
||||
the indexer's whole-module integration test: a trunk
|
||||
definition that does not parse writes its finding and a fixed one clears it; a trunk build end naming out-of-step types
|
||||
writes the finding, a clean build end of another contracts module leaves it, and a clean one of the same module clears
|
||||
it; `indexer_seat_definition` answers the trunk's entry while a pull request
|
||||
holds another; a pull request's entries go when it closes; a definition over 256 KiB is refused; each of the three
|
||||
tools answers.
|
||||
holds another; a pull request's entries go when it closes; a definition over 256 KiB is refused; a seat-list-grain
|
||||
definition is read from a contracts module like a whole one; each of the three tools answers.
|
||||
|
||||
## The foundation's seats
|
||||
|
||||
@@ -567,5 +651,8 @@ condition keeper (health), a pull request's entries are removed when it closes (
|
||||
The milestone's amendment (ADR 0612, ADR 0613, ADR 0614, ADR 0620: the seats defined whole, the rest at the seat
|
||||
list's grain, the contracts marker, out of step learned from the checker's `verdict` and the builder's build end, the
|
||||
seat set's one source), with the amendment of 2026-11-04 (ADR 0625, ADR 0627: ten seats defined whole, a package per
|
||||
seat, the seat-set package in `mesh-contracts`, the seven clients and the seat-neutral parts transfer, *Where a
|
||||
seat's code goes*), awaits its own review by architectural domain, which rewrites this section.
|
||||
seat, a package for the seats at the seat list's grain in `mesh-contracts`, the seven clients and the seat-neutral parts transfer, *Where a
|
||||
seat's code goes*), and the amendment of 2026-11-05 (ADR 0634, ADR 0635: shared code with its owner, the domain
|
||||
SDK, a module's own package, a contracts module per domain the milestone moves, 25 seats defined whole with their
|
||||
states, the seat list read from the bus, two seats renamed), await their own review by architectural domain, which
|
||||
rewrites this section.
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, hq 00-META/checks]
|
||||
updated: 2026-11-04
|
||||
updated: 2026-11-05
|
||||
decisions:
|
||||
- "ADR 0634"
|
||||
- "ADR 0594"
|
||||
- "ADR 0572"
|
||||
- "ADR 0571"
|
||||
@@ -168,7 +169,7 @@ source revision is derived from the keys: every **want** equals its module's **f
|
||||
node's own want `want.<node>.node`, and never deletes a want (ADR 0408 §4). A move a person must allow is judged
|
||||
by the node agent, which waits; the assigner raises the ask and on a yes writes the want again naming it
|
||||
(ADR 0547 §3). It reads which modules run on which node from its own state `placement`, held as the seat
|
||||
`mesh-placement` (ADR 0567); until ADR 0547's third milestone it also reads the controller's assignments, writes no want for
|
||||
`mesh-module-assigner` (named `mesh-placement` until ADR 0634 §9; ADR 0567); until ADR 0547's third milestone it also reads the controller's assignments, writes no want for
|
||||
a module on a node that the two do not both name, and raises a condition naming the pair while they differ.
|
||||
It also runs the **composition check**: whether the machines a change touches still compose with it, read
|
||||
from the keys the indexer and the builder hold and from the machines, settings and grants it reads, with
|
||||
@@ -225,7 +226,7 @@ there is three milestones, one issuer of each key at every moment (ADR 0547 §11
|
||||
elsewhere but the bus's user list, which the bus node keeps able to follow until the third milestone so `hand-back` has a list to return to.
|
||||
3. **Nothing is left with the controller** (issue 774; what remains of issue 1126, the homes of the controller's
|
||||
other jobs, carries into it by a note on 1126 and is not one of its issues): the vault mints bus accounts, the grants part
|
||||
writes grants, the try is the checker's own verb, placement is read from the seat `mesh-placement` alone (ADR 0567; ADR 0549 §5,
|
||||
writes grants, the try is the checker's own verb, placement is read from the seat `mesh-module-assigner` alone (ADR 0567; ADR 0549 §5,
|
||||
§6), the vault signs with the mesh's signing key (ADR 0550 §2), each node-engine holds the node seat `node-engine`
|
||||
and asks the operator itself for a hand-over or an access act (ADR 0563), and the controller's lease is handed to a
|
||||
holder that is no controller once every other job it keeps has a home by its own decision (research 072): health
|
||||
@@ -268,13 +269,13 @@ The target (ADR 0547):
|
||||
- **The controller** is no part of build and delivery (ADR 0547 §1). The jobs it still keeps outside them
|
||||
(nodes and adoption, identities, secrets and given values, licences, config moves, conditions and facts, ADR
|
||||
0429 §9) each move by a decision of their own under research 072 before it loses its lease. All are decided:
|
||||
placement lives on the bus, held by the seat `mesh-placement` (ADR 0567); the mesh's signing key in the vault
|
||||
placement lives on the bus, held by the seat `mesh-module-assigner` (ADR 0567); the mesh's signing key in the vault
|
||||
(ADR 0550 §2); a hand-over, an access act and the root-free judgement on each node's own seat `node-engine`
|
||||
(ADR 0563); health with the condition keeper, the watchman, the self-check and the healers (ADR 0564); the
|
||||
control records with mesh-config, the node agents, the assigner and the hand-act log's seat `mesh-hand-acts`
|
||||
(ADR 0565); provisioning with the seat `mesh-provisioner` (ADR 0570); and build history with the builder's
|
||||
build log, the artifact sweep with the seat `mesh-artifact-sweep`, disk readings with disk-load, and who holds
|
||||
which seat with the seat `mesh-placement`'s state `seat-holders` (ADR 0571).
|
||||
which seat with the seat `mesh-module-assigner`'s state `seat-holders` (ADR 0571).
|
||||
- **The vault** keeps every secret the mesh keeps (ADR 0550 §1): the mesh's signing key, licence grants and
|
||||
tokens, bus account passwords and module secrets; a holder gets a value only sealed to its own key, or asks the
|
||||
vault to act with it. It makes the mesh's signing key and signs enrolments and node certificates on request, by
|
||||
@@ -696,7 +697,7 @@ backup holder backs up nothing, and the have says so.
|
||||
- **What a node composes from, and who writes it.** One composer, mesh-sdk's, has three callers: the node agent for
|
||||
its own node, the assigner's composition check for every node, and the grants part. Each fills the composition's
|
||||
input from the bus with its own credential and nothing else (ADR 0547 §2, ADR 0549 §3):
|
||||
- **placement**, the state `placement` of the seat `mesh-placement`, one key `placement.<node>`, written by the
|
||||
- **placement**, the state `placement` of the seat `mesh-module-assigner`, one key `placement.<node>`, written by the
|
||||
assigner's credential alone on an approved proposal and said by `placement-changed` (ADR 0567);
|
||||
- **the node records**, each in its node's own have key `<node>.node`, written by that node alone and heard as
|
||||
the key's change (ADR 0555 §3);
|
||||
@@ -710,7 +711,7 @@ backup holder backs up nothing, and the have says so.
|
||||
While both sources stand (ADR 0549 §5), mesh-config resolves values for a module either the placement or the
|
||||
controller's assignments name on a node, and the grants part composes both, holding a seat held once for the mesh
|
||||
where the placement says.
|
||||
- **How placement is changed.** The seat `mesh-placement`, held once for the mesh by the assigner, keeps three
|
||||
- **How placement is changed.** The seat `mesh-module-assigner`, held once for the mesh by the assigner, keeps three
|
||||
states: `placement`, one key `placement.<node>` per node; `proposals`; and `candidates`. Only the holder's
|
||||
credential writes them, and the contract (the states' names among it) is mesh-sdk's. No repository holds
|
||||
placement and none names a node: what differs between nodes is bus state, and a build module's capacity and
|
||||
@@ -777,7 +778,7 @@ backup holder backs up nothing, and the have says so.
|
||||
- **What a node's account reads to compose.** The grants part's composer gives every node's account these reads,
|
||||
each read only, and the controller's frozen copy none of them (ADR 0555):
|
||||
- every node's `<node>.node` of the node-engine's have bucket: the other nodes' records;
|
||||
- every key of the state `placement` of the seat `mesh-placement`: where modules run and what a person decided of each node;
|
||||
- every key of the state `placement` of the seat `mesh-module-assigner`: where modules run and what a person decided of each node;
|
||||
- every key of the indexer's `modules` and `manifests`: the manifests it composes from;
|
||||
- every key of the builder's `builds`: the manifest of a build its want names when that is not the trunk's;
|
||||
- mesh-config's `resolved` values of its own node alone, `<node>.>`.
|
||||
@@ -795,7 +796,7 @@ backup holder backs up nothing, and the have says so.
|
||||
the node composing it keeps what runs until the vault holds it. Likewise a consumer of `model-access` answered by a
|
||||
licence record, placed before the vault serves licences (ADR 0550 §3, issue 569), is refused by the same guard and
|
||||
its node keeps what runs; none is placed today.
|
||||
- **The order a node takes to composing its own.** One delivery group carries every part: the seat `mesh-placement`
|
||||
- **The order a node takes to composing its own.** One delivery group carries every part: the seat `mesh-module-assigner`
|
||||
on the assigner, the controller's verb `placement-export` (as it is) and the controller's pin only, the node-engine
|
||||
(its record and its own composer), the vault's `own`, the grants part's reads, and mesh-config's reading of
|
||||
placement. The grants part's new reads reach the nodes before the node-engine watches the seat's states. Nothing
|
||||
@@ -934,7 +935,7 @@ and `delivered` events.
|
||||
*ADR 0408, ADR 0429 §17, ADR 0539 §4, §12, §13.*
|
||||
|
||||
From release 6, module, source revision, build, want and have are one chain, each link answerable from the next
|
||||
(ADR 0429 §17). Placement is bus state of the seat `mesh-placement`, held by the assigner, and no repository holds it (ADR 0567); the controller's
|
||||
(ADR 0429 §17). Placement is bus state of the seat `mesh-module-assigner`, held by the assigner, and no repository holds it (ADR 0567); the controller's
|
||||
assignments bucket is kept equal to it by the holder until ADR 0547's third milestone and is a source of nothing from then
|
||||
(ADR 0549 §6). The rollouts bucket is kept read-only with its history: no rollout is written after release
|
||||
5's last plan (ADR 0539 §12).
|
||||
@@ -944,7 +945,7 @@ assignments bucket is kept equal to it by the holder until ADR 0547's third mile
|
||||
| build | its module, repository and commit, its reuse key, what it published: an artifact by digest or a package release by name and version | the controller | `mesh-controller_builds` |
|
||||
| want | the fingerprint a node should run of a module, and the digest of the one composition it allows; the node's own want names its node composition | the assigner | `mesh-delivery-assigner_wants` |
|
||||
| have | what the node runs of a module: the fingerprint, the composition's digest, the phase and the health | the node agent | `node-engine_have` |
|
||||
| placement | each node's modules with their pins, host ports and bindings, and what a person decided of the node, as one key per node | the assigner, the holder of the seat `mesh-placement`, on the operator's Approve of a proposal (ADR 0567) | the seat's state `placement` |
|
||||
| placement | each node's modules with their pins, host ports and bindings, and what a person decided of the node, as one key per node | the assigner, the holder of the seat `mesh-module-assigner`, on the operator's Approve of a proposal (ADR 0567) | the seat's state `placement` |
|
||||
| placement proposal | while a change is open: its changes, the revision of each key it was laid over, the nodes' answers, the verdict and the ask, beside the chain and never composed into what runs | the assigner | the seat's state `proposals` |
|
||||
| placement candidate | while a proposal is open: one node's placement as the proposal lays it, which that node composes in shadow and answers | the assigner | the seat's state `candidates` |
|
||||
| assignment | until ADR 0547's third milestone: the module and node, pinned or not, ended or not, written by `assign` and `unassign` after an approved placement change, so that it equals the placement (ADR 0567) | the controller, called by the holder | `mesh-controller_assignments` |
|
||||
@@ -963,7 +964,7 @@ at its first start of release 6 (ADR 0539 §13).
|
||||
controller's store holds builds, rollouts, batches or assignments, so no record mirror,
|
||||
audit or healer exists for them; the nodes, settings, declared-config and predefined-keys mirrors stay as
|
||||
ADR 0289 and ADR 0356 have them. A module reads a bucket by naming it in `reads`. The assigner, the grants part,
|
||||
mesh-config and the node agents read placement from the seat `mesh-placement`'s state, on its watch; from ADR 0547's second
|
||||
mesh-config and the node agents read placement from the seat `mesh-module-assigner`'s state, on its watch; from ADR 0547's second
|
||||
milestone no part but the controller reads the assignments bucket, and the assigner until the third
|
||||
(ADR 0567).
|
||||
- **No key of the chain is removed.** Each bucket keeps up to 64 earlier revisions of each key as its history. A
|
||||
@@ -1106,7 +1107,7 @@ What the build proves before this design is implemented (research 055's directio
|
||||
newer fingerprint once its rules hold, a fingerprint nobody wants any more is never applied, and nothing is
|
||||
released by a person or held in the gate.
|
||||
12. No table in the controller's store holds builds, deliveries or assignments: builds are the builder's keys,
|
||||
wants the assigner's, haves the node agents', and placement the seat `mesh-placement`'s, held by the assigner,
|
||||
wants the assigner's, haves the node agents', and placement the seat `mesh-module-assigner`'s, held by the assigner,
|
||||
with the controller's assignments bucket kept equal to it by the holder until ADR 0547's third milestone
|
||||
(ADR 0567).
|
||||
|
||||
@@ -1200,7 +1201,7 @@ From ADR 0548 and ADR 0551 (issue 568):
|
||||
move carries a verdict by its package digests.
|
||||
- Placement written only by the controller's `assign` and `unassign` (ADR 0539 §12, as ADR 0549 §1 changes it):
|
||||
from ADR 0547's third milestone its tables and verbs are a source of nothing (ADR 0549 §6). The seat
|
||||
`mesh-placement` is the only writer of placement (ADR 0567).
|
||||
`mesh-module-assigner` is the only writer of placement (ADR 0567).
|
||||
- A group's order: `after:` lines, the ranked rules and the order of the repositories' names (ADR 0419, which
|
||||
supersedes ADR 0249).
|
||||
- Delivery member by member, a stop of a member after a failed one, and the own path's separate batch for a
|
||||
@@ -1270,13 +1271,13 @@ release reports the controller's code lines against research 063's baseline (acc
|
||||
| R4g | The last milestone of release 4 and release 5 as one, with one switch-over and no rehearsal (ADR 0524 §1): builds and checks are asks on streams that each build node pulls when it has a free slot, deliveries first, with nothing holding checks and no controller queue (ADR 0525); the assigner is made with its composition check, writes each node's wants compared with what the controller sends and every difference, and the view answers the asks that need no proof of who answered (ADR 0528, ADR 0437 §10); no module's fingerprint takes the builder (ADR 0530); the scripts of the repositories a module is built from, build-agent with its socket and Dockerfile code, the toolchain images and the controller's build code go, and the builder delivers its own module, the build modules and the controller from its keys (ADR 0453 clauses 5, 8, 10; ADR 0524 §5, §7); the ways to deliver without the builder are recorded (ADR 0526); hq's four checks are Go tests (ADR 0527); each repository's script goes (ADR 0529); the word for the composition check's predecessor is struck. Its pull requests are opened only after five readings, the revert path read, not shown on a test merge (ADR 0524 §3) | 4 (from R4g mesh-build-image, rootless, is the only part that builds an image: ADR 0487 §7), 17, 24 (no `merge-check.sh` in a repository a module is built from) | mesh-sdk, mesh-controller (build-agent removed), mesh-delivery, mesh-catalog, mesh-tools, mesh-tools-go, the node-engine (`mesh-host`), mesh-media-catalog, okioki, hq | 1887 (the flow), 1297 (the assigner), 1295 (`merge-check.sh` goes), 979 (closed with the toolchain images), 1296 and 1303 (hq's check, the old word struck), 1299, 1305, 1294, 1318 (the controller's deletions) |
|
||||
| R6 | Each node applies from its wants the compositions its own node agent composes (ADR 0547 §2; as released it applied the controller's signed ones), a new version reaches the module's canary first and the rest once it is healthy there, a move a person must allow is asked before its want, the view says what is moving, settled, stuck and delivered, and the plans are deleted from the code; switched over by release 5's last plan (ADR 0539) | 18, 19, 20 | mesh-sdk, the node-engine (`mesh-host`: the node agent), mesh-controller (plans deleted; as released also compositions and credentials, which ADR 0547 moves to the node agents, the grants part and the vault), mesh-delivery (assigner, watchman, view), mesh-catalog (the gate, the messenger, the issue tracker, the backup holder), hq | 1942 (the planner puts the node-engine and the controller in one tier for the switch; delivered first), the bus's user list granting what release 6 uses (delivered first, under L1's issue), 1943 (mesh-sdk: the composition's layout and signature, the want's digest, `mesh-hand-compose`, the verb tables without the plan verbs), 1944 (the node agent), 1946 (the gate keeps the merge's states; the messenger and the issue tracker hear the view), 1906 (the assigner's seventh rule and its asks, the watchman's pulses for wants, the view's wants and events), 1130 (hq) |
|
||||
| L1 | The controller leaves build and delivery, first milestone: the bus node follows the user list alone, the grants part composes in shadow and the vault holds the bus accounts' hashes, so the operator's take-over can make the grants part's list the one loaded (ADR 0547 §8, §11; ADR 0550 §4) | — | mesh-controller, mesh-delivery, mesh-catalog (the vault, the grants part), the node-engine (`mesh-host`), mesh-sdk | 1945 |
|
||||
| L2 | Nodes compose: each node agent composes its own modules, and no node applies a composition made elsewhere but the bus's user list (ADR 0547 §11); where modules run is bus state held by the seat `mesh-placement` on the assigner, changed by a proposal the nodes answer and the operator approves, and no repository names a node or holds what one installation decides (ADR 0567). Built as release sdk1 (ADR 0593) and delivered to every machine on 2026-11-02, the controller's code emptied (mesh-controller #491) and its repository archived; done once a check has composed a candidate on every machine | — | the node-engine (`mesh-host`), mesh-sdk, mesh-delivery (the assigner as the seat's holder), mesh-catalog, mesh-controller (its pin only) | 1126 |
|
||||
| L3 | Nothing is left with the controller: the vault mints bus accounts and signs, the grants part writes grants, the try is the checker's own verb, placement is read from the seat `mesh-placement` alone, each node-engine holds the node seat `node-engine`, judges `root-free` for its node and asks the operator itself for a hand-over or an access act, acting on the warrant with nothing signed (ADR 0563), and, once L4 to L7 are delivered, the lease write passes the lease to a holder that is no controller, made right after the delivery that drops every listed read of the controller but the three ADR 0571 §13 keeps to the write itself (ADR 0547 §11, ADR 0549 §5, §6, ADR 0550 §2, ADR 0571 §13); the rest of the controller's code lines is the issue of L2. Since the controller left (2026-11-02), nothing writes the bus module's own process accounts while the bus module has no want on the broker node, so its tools that write the bus fail (issue 774) | — | mesh-controller, mesh-sdk, the node-engine (`mesh-host`), mesh-catalog (the vault, the grants part, the messenger), mesh-delivery | 774 |
|
||||
| L2 | Nodes compose: each node agent composes its own modules, and no node applies a composition made elsewhere but the bus's user list (ADR 0547 §11); where modules run is bus state held by the seat `mesh-module-assigner` on the assigner, changed by a proposal the nodes answer and the operator approves, and no repository names a node or holds what one installation decides (ADR 0567). Built as release sdk1 (ADR 0593) and delivered to every machine on 2026-11-02, the controller's code emptied (mesh-controller #491) and its repository archived; done once a check has composed a candidate on every machine | — | the node-engine (`mesh-host`), mesh-sdk, mesh-delivery (the assigner as the seat's holder), mesh-catalog, mesh-controller (its pin only) | 1126 |
|
||||
| L3 | Nothing is left with the controller: the vault mints bus accounts and signs, the grants part writes grants, the try is the checker's own verb, placement is read from the seat `mesh-module-assigner` alone, each node-engine holds the node seat `node-engine`, judges `root-free` for its node and asks the operator itself for a hand-over or an access act, acting on the warrant with nothing signed (ADR 0563), and, once L4 to L7 are delivered, the lease write passes the lease to a holder that is no controller, made right after the delivery that drops every listed read of the controller but the three ADR 0571 §13 keeps to the write itself (ADR 0547 §11, ADR 0549 §5, §6, ADR 0550 §2, ADR 0571 §13); the rest of the controller's code lines is the issue of L2. Since the controller left (2026-11-02), nothing writes the bus module's own process accounts while the bus module has no want on the broker node, so its tools that write the bus fail (issue 774) | — | mesh-controller, mesh-sdk, the node-engine (`mesh-host`), mesh-catalog (the vault, the grants part, the messenger), mesh-delivery | 774 |
|
||||
| M1 | A milestone is a record of the issue tracker: each row of a design's milestone table is a milestone record its issues are linked to by `issue-tracker.link`, an issue to at most one, and pull requests and commits to issues the same way; the knowledge base's `progress` reads the milestones from the tracker, not from this table (ADR 0493 §1 to §4) | — (ADR 0493 §13 in part) | hq, mesh-catalog (mesh-issues, mesh-knowledge) | 1781 |
|
||||
| L4 | Health leaves the controller (ADR 0564): the condition keeper holds the seat `mesh-conditions` and keeps every open condition from the observers' findings, saying today's condition events; the watchman holds `mesh-watchdogs`, its watchdogs pulses, reads each node-engine's node health report, and keeps the dead letters from the lease write; `mesh-self-check` runs the probes, `root-free` among them from L7 (ADR 0571 §11), and says `checked`; of the probes still deferred, D13, D8, D-fill and DA are built and the rest are not, their kinds ending with the controller at the lease write (ADR 0572); `mesh-healers` heals on events and acts only once the lease names no controller; `status` is the view's derivation; built dark, compared, then switched by the operator's take-over; the bus module gains a tool that removes one named consumer, which the lease write uses (ADR 0547 §11) | — | mesh-sdk, mesh-catalog (mesh-conditions, mesh-self-check, mesh-healers, the router, mesh-watcher, nats), mesh-delivery (watchman, view, the grants part) | 1952 |
|
||||
| L5 | Control records leave the controller, and the controller is not changed (ADR 0565): mesh-config keeps each module's declared config in its state `declared` and publishes the predefined keys, which the indexer reads from the forge bridge's messages with each open pull request's config candidate; config switches to that source only on the operator's take-over, refused while `compare` shows a difference; each node agent writes its node's declared packages (the node seat `node-engine`, verb `packages`); the assigner holds the new seat `mesh-wants` with the upgrade policy a person chose and the bus step; the hand-act log (`hand-act`, `hand-acts`, `warranted`) is the stream of the new seat `mesh-hand-acts`, held by a new module in mesh-catalog, which every recorder calls from this delivery with no switch; the checker and the assigner's composition check read the held values of their pull requests from mesh-config's state `kept`; from the lease write a trusted config value is set only on the operator's Approve; `settings`, `move-config` and `move-placement` end with the lease and nothing replaces them. each person's six policy choices are set through `mesh-wants.upgrade` and recorded as hand acts, `upgrade compare` and the assigner's finding `policy-split` show any split, and the lease write waits for `compare` to be empty (ADR 0565 §8). One delivery group, built before the lease write of L3, which waits for the group delivered, the six choices set, mesh-config's `compare` empty and its take-over done, `mesh-wants.upgrade compare` empty, and the readings of ADR 0565 §12 (ADR 0565 §14; ADR 0348 §9, ADR 0502 §2, ADR 0539 §14, §15, ADR 0547 §11) | — | mesh-sdk, mesh-catalog (mesh-config, mesh-hand-acts, pacman, the forge module, claude-code, mesh-knowledge, mesh-conditions, mesh-healers), mesh-delivery (indexer, assigner, checker, grants part, forge bridge), the node-engine (`mesh-host`); mesh-controller is not a member | 1953 |
|
||||
| L6 | Provisioning leaves the controller (ADR 0570): every provision is one key of the seat `mesh-provisioner`, held by mesh-provisioner, holding a reference and never a value, and each placed module's provisioning plan a key of its state `plans`, both composed from placement, the wants and the manifests on change events; each provider acts once all a provision depends on is provided; the assigner moves a want only once its build's provisions are provided; a provision no want needs is retiring, and its account or credential is removed only on the operator's Approve, its data never; the vault mints each provision's secret sealed to the consumer's and the provider's node, and the consumer's node-engine writes it; a wait for a person is a provision's state, which the watchman reads; bus permissions stay with the grants part (ADR 0349, ADR 0230, ADR 0547 §11) | — | mesh-sdk, the node-engine (`mesh-host`), mesh-tools (the tool runner's provisioner client), mesh-catalog (mesh-provisioner, the vault, the provisioner client, postgres, keycloak, gitea, route-adapter), mesh-delivery (assigner, watchman) | 1954 |
|
||||
| L7 | History and records leave the controller (ADR 0571): the builder keeps its build log, one entry at a build's start and one at its end, from which build history and durations are read and the module mesh-catalog asks the builds it missed; the artifact sweep is the seat `mesh-artifact-sweep`, held by artifact-store-tools beside the artifact store, its keep set from the store's own listing, the wants and the build log, sweeping at each build's end from the lease write and recording each deletion in the hand-act log; disk readings are disk-load's own state on every node; who holds which seat is the state `seat-holders` of the seat `mesh-placement`, and tools are found by the tool runners' announcements; what a node runs is its want and its have; the grants part writes `grants.<module>.<fingerprint>` and keeps memberships in its own state; root-free is a probe of the self-check; no manifest but the controller's reads, invokes or consumes `mesh-controller`, but a named list kept to the lease write, so the lease write's check passes (ADR 0189, ADR 0547 §11, ADR 0549 §6) | — | mesh-sdk, mesh-controller (its pin only), mesh-delivery (builder, indexer, assigner, grants part, view), mesh-catalog (artifact-store-tools, disk-load, the backup seat's holder, mounts, nfs-server, minio, mesh-watcher, the messenger, the self-check, the module mesh-catalog, docker), mesh-tools (the tool runner) | 1955 |
|
||||
| L7 | History and records leave the controller (ADR 0571): the builder keeps its build log, one entry at a build's start and one at its end, from which build history and durations are read and the module mesh-catalog asks the builds it missed; the artifact sweep is the seat `mesh-artifact-sweep`, held by artifact-store-tools beside the artifact store, its keep set from the store's own listing, the wants and the build log, sweeping at each build's end from the lease write and recording each deletion in the hand-act log; disk readings are disk-load's own state on every node; who holds which seat is the state `seat-holders` of the seat `mesh-module-assigner`, and tools are found by the tool runners' announcements; what a node runs is its want and its have; the grants part writes `grants.<module>.<fingerprint>` and keeps memberships in its own state; root-free is a probe of the self-check; no manifest but the controller's reads, invokes or consumes `mesh-controller`, but a named list kept to the lease write, so the lease write's check passes (ADR 0189, ADR 0547 §11, ADR 0549 §6) | — | mesh-sdk, mesh-controller (its pin only), mesh-delivery (builder, indexer, assigner, grants part, view), mesh-catalog (artifact-store-tools, disk-load, the backup seat's holder, mounts, nfs-server, minio, mesh-watcher, the messenger, the self-check, the module mesh-catalog, docker), mesh-tools (the tool runner) | 1955 |
|
||||
|
||||
An issue is in one row only (ADR 0493 §2): where a row named an issue another row names too, the last row keeps it and the
|
||||
earlier row says so in words (the operator, 2026-10-26). Milestone M1 makes each row a record of the issue tracker
|
||||
|
||||
Reference in New Issue
Block a user