Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcb5d5ce38 | ||
|
|
bb8075b37b | ||
|
|
40a39c8602 | ||
|
|
e5b98e3b0a | ||
|
|
2f3e6e6641 | ||
|
|
1405dd39e8 | ||
|
|
11294372b7 |
+26
-100
@@ -69,8 +69,7 @@ is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
|
||||
**Recorded in** the catalogue, 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.
|
||||
**Uses:** module, seat, config value (Config), provision (Provisioning), data class (Data), health (Health
|
||||
and repair).
|
||||
**Uses:** module, seat, provision (Provisioning), data class (Data), health (Health and repair).
|
||||
|
||||
- **manifest** — the file a module is defined by (`module.json`): what it is, what it provides and
|
||||
requires, the seats it claims, the resources it declares, its tools, its data and its health. Say
|
||||
@@ -84,9 +83,18 @@ and repair).
|
||||
it guards: the `mesh-controller`, `postgres` and `nats` modules claim the `mesh-controller`,
|
||||
`mesh-store` and `mesh-broker` seats (ADR 0079,
|
||||
ADR 0116).
|
||||
- **setting** — a value a manifest declares and an assignment gives, one of the two ways a node varies
|
||||
a module (ADR 0174).
|
||||
What a "flavor" once varied is a setting or a separate module.
|
||||
*Not:* ~~flavor~~
|
||||
- **preference** — a setting whose manifest gives it a default, because its value is true of the
|
||||
software and only tuned per node: a font size, a width
|
||||
(ADR 0262).
|
||||
A setting with no default is the operator's own value: a domain, an identity.
|
||||
*Not:* ~~tunable~~ (hq)
|
||||
- **kept region** — a marked block in a managed file the mesh writes *into*, where the operator's own
|
||||
lines survive every send and are given back when the module goes (ADR 0174). The other way a node
|
||||
varies a module, besides a config value; a **managed** file's marked block is one (Provisioning).
|
||||
varies a module.
|
||||
- **bundle** — the artifact a module's own code is built into — its tools, a seat's implementation, a
|
||||
daemon — in any language the mesh has a toolchain for; never an image. A **tools bundle** speaks MCP to
|
||||
the tool runner. One module may declare several
|
||||
@@ -103,55 +111,6 @@ and repair).
|
||||
(ADR 0236).
|
||||
The controller's verb `upgrade` shows it.
|
||||
|
||||
## Config — the values someone may change
|
||||
|
||||
**Purpose.** To hold, check and resolve every value a module reads that someone may change, and to say
|
||||
where each resolved value came from. **Recorded by** the `mesh-config` module, in its buckets on the bus,
|
||||
with its store as the history behind them. **Upstream of** Provisioning, which places the values;
|
||||
downstream of Module and Placement. **Decided by** ADR 0262, 0277, 0348.
|
||||
**Uses:** module, node, manifest (Module), assignment (Placement), provision (Provisioning), proposal
|
||||
(Operator and conversation).
|
||||
|
||||
- **config value** — anything a module reads that someone may change: a font size, a domain, an address.
|
||||
A module declares every one it reads under `config` in its manifest, with a type, a description,
|
||||
validation, whether it is trusted, optionally the predefined key it falls back to, and a default or
|
||||
`required`; it lands in a template file as `${config:<key>}` or is read by the module's code at runtime.
|
||||
It resolves from four sources, the most specific winning: the default in the manifest; **mesh config**,
|
||||
the value of the predefined key it falls back to for the whole mesh; **node config**, that key's value
|
||||
on one node; and **module-assignment config**, the module's own value on one node. There is no module
|
||||
value for the whole mesh. *Config* is the concept, the verb (`config`) and the manifest field
|
||||
(ADR 0348). Mesh config is a source level, the value set for the whole mesh; `mesh-config` is the module
|
||||
that keeps every level. The controller holds, mirrors and resolves no config value (ADR 0348 §9).
|
||||
Older records and documents say "setting" for a config value and "settings" for the concept; new writing
|
||||
says config value and config. The word goes on this entry's *Not:* line once the documents in force that
|
||||
still use it in running prose are reworded, which is issue 683; until then it is checked by review. The
|
||||
manifest field and the verb "settings" are kept as aliases until every module has moved (ADR 0348 §1,
|
||||
issue 630), and are named on the line below with the rest once issue 683 is done.
|
||||
*Identifier until renamed:* `takes-settings`, `${setting:}` — manifest forms kept as aliases until every
|
||||
module has moved to their config names (ADR 0348 §1, issue 630).
|
||||
What a "flavor" once varied is a config value or a separate module.
|
||||
*Not:* ~~flavor~~
|
||||
- **predefined key** — a key of the catalogue's `predefined.json`, the fixed list of keys for which mesh
|
||||
config and node config hold values, each with its type, description, validation and whether it is
|
||||
trusted, such as `font-size`. A config value may name the predefined key it falls back to, of its own
|
||||
type; one that names none resolves from its default and the module's own value only. The list is the
|
||||
catalogue build's: a change to it is validated with every manifest naming a key, and removing a key still
|
||||
named or still holding a value is refused (ADR 0348).
|
||||
- **trusted** — said of a config value that decides what runs or who can reach what. At every level it is
|
||||
set only at the controller's terminal or through `config` with propose, on the operator's Approve; a
|
||||
module value that falls back to a trusted predefined key is itself trusted (ADR 0277, ADR 0348 §8). Not
|
||||
the trusted sender of an operator message (see [Homonyms](#homonyms)).
|
||||
- **preference** — a config value whose manifest gives it a default, because its value is true of the
|
||||
software and only tuned per node: a font size, a width
|
||||
(ADR 0262).
|
||||
A config value with no default is `required`: the operator's own value, such as a domain or an
|
||||
identity, and while nothing sets it the module's files are not written (ADR 0348).
|
||||
*Not:* ~~tunable~~ (hq)
|
||||
- **`mesh-config`** — the module that owns every config value, and not the source level mesh config: it
|
||||
holds the seat `mesh-config` once for the mesh, validates, takes a trusted value only from the
|
||||
controller's terminal or the operator's Approve, keeps the history with who set it and why, and resolves
|
||||
the four sources (ADR 0348).
|
||||
|
||||
## Core — the mesh's own machinery
|
||||
|
||||
**Purpose.** To keep the controller, the bus, the store and every node's engine running and agreed, so
|
||||
@@ -219,7 +178,7 @@ every other domain has something to run on. **Recorded by** the controller and t
|
||||
(ADR 0229).
|
||||
|
||||
- **record mirror** — a key-value bucket on the bus that the controller writes from one kind of its
|
||||
records (nodes, assignments, walks, builds), after each change commits in its store and only
|
||||
records (nodes, assignments, walks, builds, settings), after each change commits in its store and only
|
||||
when the value differs, with one event per write. The store stays the record; the self-check compares
|
||||
the two and raises `mirror-drifted` on any difference
|
||||
(ADR 0289). Shortened to *mirror* where the
|
||||
@@ -231,10 +190,9 @@ every other domain has something to run on. **Recorded by** the controller and t
|
||||
**Purpose.** To decide, send and apply what each node runs, and to say why.
|
||||
**Recorded by** the controller's `inventory` database. **Upstream of** Provisioning, Connectivity, Data
|
||||
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261.
|
||||
**Uses:** node, machine, module, seat, manifest (Module), config value (Config).
|
||||
**Uses:** node, machine, module, seat, setting (Module), manifest (Module).
|
||||
|
||||
- **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).
|
||||
- **assignment** — a module put on a node, with the settings that node gives it.
|
||||
- **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
|
||||
(ADR 0261).
|
||||
@@ -269,7 +227,7 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
|
||||
(ADR 0181).
|
||||
Not a name a manifest carries.
|
||||
- **agent account** — the login every coding agent on a node runs as, when the node names one of its own;
|
||||
stated on the node record at the controller's terminal, never by a verb or a config value. Empty means agents
|
||||
stated on the node record at the controller's terminal, never by a verb or a setting. Empty means agents
|
||||
run as the operator account. It cannot become root without a person, and the node-engine judges that on
|
||||
every look (ADR 0266).
|
||||
- **account group** — a group of the machine's group database that a module puts an account in, by
|
||||
@@ -280,21 +238,15 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
|
||||
|
||||
## Provisioning — one module serving another
|
||||
|
||||
**Purpose.** To resolve which module serves a provision for which consumer, to wire the two, and to
|
||||
place every value a module needs into its files on its node. **Recorded by** the controller and
|
||||
`mesh-provisioner`. **Upstream of** Data; downstream of Module, Placement, Config and Identity.
|
||||
**Decided by** ADR 0027, 0084, 0138, 0225, 0230, 0263, 0349.
|
||||
**Uses:** module, seat, node-engine (Core), declaration (Placement), config value (Config), credential
|
||||
and vault (Identity and access).
|
||||
**Purpose.** To resolve which module serves a provision for which consumer, and to wire the two.
|
||||
**Recorded by** the controller. **Upstream of** Data; downstream of Module, Placement and Identity.
|
||||
**Decided by** ADR 0027, 0084, 0138, 0225, 0230, 0263.
|
||||
**Uses:** module, seat, credential (Identity and access).
|
||||
|
||||
- **provision** — a service one module `provides` and others `require`; the mesh resolves a provider
|
||||
and wires the two with an endpoint and a credential. A provision is a service you offer, a seat is a
|
||||
role you occupy, and the two meet where a seat delivers a provision: occupying the seat is what makes
|
||||
a module *the* provider of it.
|
||||
Every value a module needs is a provision from the domain that owns it: placement from the controller,
|
||||
config values from `mesh-config`, shared secrets from the vault, a consumer's values from the module
|
||||
providing it, an item of a collection from its contributor. A module says only what it needs and where
|
||||
it lands (ADR 0349).
|
||||
- **provider** and **consumer** — the module that provides a provision, and the module that requires
|
||||
it. Which of several providers serves a consumer is resolved
|
||||
(ADR 0084).
|
||||
@@ -312,28 +264,6 @@ and vault (Identity and access).
|
||||
node seat `node-mounts`, as a mount unit and an automount unit, mounted on access (ADR 0263).
|
||||
- **occasional source** — a share on a device that is not a node and comes and goes, such as a USB disk;
|
||||
its absence is a state, *not present*, never a fault (ADR 0263).
|
||||
- **mesh-provisioner** — the module that places provisions on the nodes: it holds the seat
|
||||
`mesh-provisioner` once for the mesh, keeping which domain answers which kind of placeholder, what each
|
||||
module on each node needs, what is applied where and the items of every collection, and the seat
|
||||
`node-provisioner` on every node, which its provisioner client serves (ADR 0349).
|
||||
- **provisioner client** — mesh-provisioner's part on one node. For each module there it reads the
|
||||
placeholders of its template files, records the needs, watches each owner's values for the node, fills a
|
||||
template only once every value is there, has the node-engine write the file through a narrow local verb,
|
||||
makes the program take the change as the file declares (`restart-on`, `reload-on`, `read-on-use`), and
|
||||
reports `prov.applied`. It runs as a service with a bus account of its own, never in the tool runner
|
||||
(ADR 0349).
|
||||
- **collection** — a provision with many providers. The **collector**, a module that takes additions from
|
||||
others (a shell's snippets, a bar's blocks), requires it; each **contributor** ships its **item** as a
|
||||
template in its own repository and provides it. The provisioner client fills the collector's template
|
||||
from the items of the contributors placed on its node, and an item goes when its contributor leaves the
|
||||
node (ADR 0349).
|
||||
- **owned** — a placed file that is the mesh's whole: the provisioner writes it back whenever it differs.
|
||||
It is one of three answers a manifest gives for each file it places (`owner-at-runtime`): **owned**,
|
||||
**seed** or **managed**. Whichever it is, the file has one writer: the node-engine writes it only on the
|
||||
provisioner client's word (ADR 0349).
|
||||
- **seed** — a placed file the provisioner writes once; from then on it is the program's.
|
||||
- **managed** — a placed file of which only its named keys or a marked block (a kept region, Module) are
|
||||
the mesh's; the program keeps the rest.
|
||||
|
||||
## Identity and access — who may do what
|
||||
|
||||
@@ -348,7 +278,7 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
|
||||
- **secret** — a credential or other value the vault keeps sealed and the node-engine unseals into a
|
||||
file at apply (ADR 0085).
|
||||
- **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 a name (`smb-password-<source>`, one per source the module's settings name), given by its full name
|
||||
and never made by the mesh
|
||||
(ADR 0283).
|
||||
- **vault** — the module that owns every secret (`mesh-vault`,
|
||||
@@ -492,7 +422,7 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283.
|
||||
running session, started before, does not have that group yet. Said by the node-engine as the module's
|
||||
resource of kind `account`; it clears at the first look after a new login (ADR 0252).
|
||||
- **waiting** — a resource's health when its module's tool check says it waits for the operator: a named own
|
||||
secret or config value of the module, not given yet, without which a part cannot work. Not a fault: the
|
||||
secret or setting of the module, not given yet, without which a part cannot work. Not a fault: the
|
||||
controller checks it and says it as the condition `needs-operator`, naming the act, and the first-node gate
|
||||
reads it as *waits for a person*
|
||||
(ADR 0283).
|
||||
@@ -616,7 +546,7 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272.
|
||||
published for that asker alone. The only thing an asker acts on (ADR 0259).
|
||||
- **proposal** — a change an agent, or anyone the bus admits, puts forward through a verb and that takes
|
||||
effect only on the operator's warrant, bound to the exact thing shown: a shared instruction section (ADR
|
||||
0274), a trusted config value (ADR 0277, ADR 0348).
|
||||
0274), a trusted setting's layer (ADR 0277).
|
||||
A proposal changes nothing by itself; declined, expired or refused, it is discarded.
|
||||
- **approval mark** — a tool's or verb's declaration in its manifest (`needs-approval`) that each call to it runs
|
||||
only on the operator's warrant for that one call, with its exact arguments; the tool runner that serves it, or
|
||||
@@ -633,7 +563,7 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272.
|
||||
build seat's holder, whose seat name `node-build-agent` is an identifier to rename.
|
||||
- **instruction section** — one named section of the managed instruction file, which every agent session on the
|
||||
nodes it is for reads first, as the mesh's word: set at the controller's terminal in the agent module's
|
||||
config, or **proposed** by an agent and made active on each node only by the operator's warrant, which that node
|
||||
settings, or **proposed** by an agent and made active on each node only by the operator's warrant, which that node
|
||||
proves itself (ADR 0274). A hand-over between sessions is one.
|
||||
- **personal rule** — one short text in the operator's own words about how the operator wants their agent
|
||||
to work with them, registered for the operator (the **operator scope** of the agent module) and rendered
|
||||
@@ -648,10 +578,10 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272.
|
||||
## Media — what a person watches, listens to and reads
|
||||
|
||||
**Purpose.** To find, fetch and file copies of the works a person watches, listens to and reads, each in
|
||||
the library its kind names. **Recorded by** the `media-importer` module's config values and its memory of what
|
||||
the library its kind names. **Recorded by** the `media-importer` module's settings and its memory of what
|
||||
it was told, and the servarr apps' own libraries. **Upstream of** nothing. **Decided by** ADR 0295, 0296,
|
||||
0302.
|
||||
**Uses:** module, seat, config value (Config).
|
||||
**Uses:** module, seat, setting (Module).
|
||||
|
||||
- **content** — a work a person watches, listens to or reads: a film, an album and its tracks, an
|
||||
episode, a book, a session of a sport event. It is known by an identity from a catalogue outside the
|
||||
@@ -662,7 +592,7 @@ it was told, and the servarr apps' own libraries. **Upstream of** nothing. **Dec
|
||||
- **media release** — one copy of a work an engine can fetch, such as an NZB or a video. Downloaded, it
|
||||
sits in the downloads folder, not yet filed. ADR 0302 says *release*.
|
||||
- **library** — one folder of one kind, filed by one importer: the media-importer's, named in its
|
||||
config, or a servarr app's. Several libraries may hold one kind, as TV Shows and Anime both hold
|
||||
settings, or a servarr app's. Several libraries may hold one kind, as TV Shows and Anime both hold
|
||||
series.
|
||||
- **media file** — a file on disk together with its metadata: its kind, the fields that identify the
|
||||
work, and what part of the work the file is. It is what the media-importer takes.
|
||||
@@ -782,10 +712,6 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
|
||||
| | a question someone must answer | **issue** | The record |
|
||||
| deploy | the per-node part of a delivery plan | **deploy plan** | Change and delivery |
|
||||
| | a wrapped program's own deploy | its own word | — |
|
||||
| managed | a placed file of which only named keys or a marked block are the mesh's | **managed** (`owner-at-runtime`) | Provisioning |
|
||||
| | a file the mesh writes, such as the agent's instruction file or `managed_settings` | the file's own name, or *a file the mesh places* | — |
|
||||
| trusted | a config value that decides what runs or who can reach what | **trusted** config value | Config |
|
||||
| | a sender on the operator's own list | **trusted** sender, its message an **operator message** | Operator and conversation |
|
||||
|
||||
## How this page is kept
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-sdk, mesh-lab]
|
||||
updated: 2026-10-12
|
||||
updated: 2026-10-14
|
||||
decisions:
|
||||
- "ADR 0357"
|
||||
- "ADR 0325"
|
||||
- "ADR 0323"
|
||||
- "ADR 0318"
|
||||
@@ -259,7 +260,7 @@ signal and asserts its condition. `doctor signals` shows, for every row, the age
|
||||
| S6 | a build asked → its outcome | build seat | each ask | max(20 min, 3 × the p90 of measured builds), 1 h while nothing is measured, *provisional* (the build seat declares no timeout) | `ask-lost` | warning | — |
|
||||
| S7 | a call running → finished | controller | each call | the verb's bound: push, rotate and command 30 min; assign and unassign 15 min; `doctor` 3 min; others 10 min | `call-hung` | warning | — |
|
||||
| S8 | a provider's failing word repeated | provider | every 15 min while failing (ADR 0224) | 30 min | `provider-silent` | warning | — |
|
||||
| S9 | bus advisories: slow consumer, maximum deliveries, permission violation, consumer deleted | bus server's system subjects | any | any occurrence; a message given up on for as long as `DEAD_LETTERS` holds it (ADR 0264) | `slow-consumer`, `max-deliveries`, `refused`, `consumer-lost` — each naming the call, consumer or module in the mesh's words | warning | H3 for `consumer-lost` |
|
||||
| S9 | bus advisories: slow consumer, maximum deliveries, permission violation, consumer deleted; every user's connection the server closed as a slow consumer or for breaking the bus's rules (ADR 0357) | bus server's advisory subjects; the controller's connection; the bus module's watch of its server (`bus.slow-consumer`, `bus.connection-closed`) | any | any occurrence; a message given up on for as long as `DEAD_LETTERS` holds it (ADR 0264) | `slow-consumer`, `connection-closed` (one per bus user), `max-deliveries`, `refused`, `consumer-lost` — each naming the call, consumer or module in the mesh's words | warning | H3 for `consumer-lost` |
|
||||
| S10 | the self-check's heartbeat | controller's `doctor` | every run | 2 × its interval, watched **from the second machine** (§5) | `self-check-silent` | urgent | — |
|
||||
| S11 | tool runner heartbeat | tool runner | its interval | 3 × interval, *provisional* | `tools-silent` | warning | — |
|
||||
| S12 | the controller lease renewed | controller | every 5 s | 15 s; a holder that lost the lease or was found expired, and a lease bucket found raised again from nothing, said for an hour; a controller serving without the lease, while it does | `lease-lost` | urgent | — |
|
||||
@@ -274,10 +275,24 @@ signal and asserts its condition. `doctor signals` shows, for every row, the age
|
||||
The bus advisories (S9) cost one read-only subscription: the server already publishes them. The
|
||||
controller translates each into a condition naming the thing in the mesh's words, as the refused reply
|
||||
of issue 265 is translated today. An advisory clears after an hour without another; a deleted consumer
|
||||
is said only for one the mesh names and expects, and clears when it exists again. Until the bus has a
|
||||
system account the controller hears a slow consumer and a refused subject for its own connection only
|
||||
([issue 270](../../04-ISSUES/270-phase-1-watches-signals-that-come-later-and-hears-only-the-controllers-faults/00-report.md),
|
||||
open question 2).
|
||||
is said only for one the mesh names and expects, and clears when it exists again.
|
||||
|
||||
**Every user's slow consumer, from the bus module (ADR 0357).** The server closes every client it judges
|
||||
a slow consumer and keeps its user and reason in its record of closed connections; it publishes neither
|
||||
in the mesh's account. So the `nats` module's tool bundle reads that record on its own machine every 30
|
||||
seconds and publishes `bus.slow-consumer` for each connection closed as a slow consumer, and
|
||||
`bus.connection-closed` for each the server closed for something its client did against the bus's
|
||||
rules or limits — naming the bus user, the connection and the reason, never a credential. A closure by
|
||||
the client, by the network or by the server's own shutdown is not said: D15 says a user dropped in a
|
||||
loop. A closure — its user, connection id and opening time — is said at least once: again when publishing
|
||||
it failed, and again for the last hour when the bundle starts. The controller's watchdogs read the last
|
||||
hour of both events back from the events stream on every tick, count each closure once, and raise one
|
||||
condition per bus user and kind, naming the module and its machine; it clears an hour after the newest
|
||||
closure. A closure is a condition at most about a minute after the server closed it.
|
||||
|
||||
**A refused subject is still heard for the controller's own connection only.** The server tells the
|
||||
client and writes its log, and says it nowhere else — not in its monitoring endpoint and not to a system
|
||||
account (issue 702, open).
|
||||
|
||||
## 4. The self-check: `doctor` (rule 6)
|
||||
|
||||
@@ -787,10 +802,10 @@ has a week of entries; the durations are recorded for every machine.
|
||||
|
||||
| Repository | Delivers |
|
||||
|---|---|
|
||||
| mesh-controller | the condition store, its verbs, history and events (§2); ADR 0224's standing moved into it; watchdogs for S1–S11 and S13 with bounds set from Phase 0's durations (S12 is Phase 2's, S14 Phase 5's); the bus advisories subscribed and translated (S9); `doctor` with D1–D4, D6–D10, DW and its heartbeat (§4; D5 is Phase 2's); `status` led by open conditions; the test generated from the signals table |
|
||||
| mesh-controller | the condition store, its verbs, history and events (§2); ADR 0224's standing moved into it; watchdogs for S1–S11 and S13 with bounds set from Phase 0's durations (S12 is Phase 2's, S14 Phase 5's); the bus advisories subscribed and translated (S9), and every user's slow consumer and closed connection read back from the bus module's events (ADR 0357); `doctor` with D1–D4, D6–D10, DW and its heartbeat (§4; D5 is Phase 2's); `status` led by open conditions; the test generated from the signals table |
|
||||
| `mesh-host` | the heartbeat carries its interval; D1's validator published as a package the controller imports |
|
||||
| mesh-tools | the tool runner's heartbeat (S11) |
|
||||
| mesh-catalog | the `operator-channel` seat and its holder; the Telegram channel and the desktop notifier contributing to it; `mesh-watcher` on a machine other than the control node (§5) |
|
||||
| mesh-catalog | the `operator-channel` seat and its holder; the Telegram channel and the desktop notifier contributing to it; `mesh-watcher` on a machine other than the control node (§5); the `nats` module's watch of its server's closed connections, publishing `bus.slow-consumer` and `bus.connection-closed` (S9, ADR 0357) |
|
||||
| mesh-lab | R9: each signal suppressed in turn |
|
||||
|
||||
**Done when:** on a lab mesh, suppressing each signal raises its condition within its bound and sends a
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
code: [mesh-controller, mesh-host, mesh-sdk, mesh-catalog]
|
||||
updated: 2026-10-14
|
||||
decisions:
|
||||
- "ADR 0348"
|
||||
- "ADR 0349"
|
||||
- "ADR 0201"
|
||||
- "ADR 0113"
|
||||
- "ADR 0158"
|
||||
---
|
||||
|
||||
# 57. Building config and provisioning
|
||||
|
||||
**The work of ADR 0348 (config is a domain of its own) and ADR 0349 (provisioning), broken into
|
||||
packages small enough that each ends at something that can be seen to work, in the order their
|
||||
dependencies allow.** The two decision records are the authority on *what* is built; this document holds
|
||||
only the packages, their order, their sizes and their proofs, and is wrong the moment it disagrees with
|
||||
them. It is the shape [design 38](38-building-the-operators-machine.md) gave the operator's machine.
|
||||
|
||||
## How this is built
|
||||
|
||||
**Each package is one issue in the issue tracker, and one pull request per repository it touches.** The
|
||||
issue carries the package's number here in its title, links the packages it waits for with `depends-on`,
|
||||
and links ADR 0348 or ADR 0349. At most five packages are worked at once, each by its own agent in its
|
||||
own worktree; a package starts once every package it depends on is merged. Every pull request is
|
||||
reviewed independently at its head and merged only with its checks green.
|
||||
|
||||
**It ships as one release.** The operator's decision of 2026-10-14: one delivery, not one per package.
|
||||
Each of mesh-controller, `mesh-host`, mesh-sdk, mesh-catalog and hq has the branch
|
||||
`feat/57-config-and-provisioning`, and every package's pull request merges into that branch, never into
|
||||
main. When the last package is merged, the whole is rehearsed in the lab: the walk, the moves of data in
|
||||
their order, and every proof that is run live. Then each repository's branch reaches main in one pull
|
||||
request, and the five, sharing their branch's name, are one delivery group (ADR 0239 §2), judged as one
|
||||
future state. The five are merged within one merge window, so they are one batch and one walk (ADR 0276
|
||||
§1, §2), in an order declared with `after:` lines in each pull request (ADR 0239 §11): mesh-sdk, then
|
||||
`mesh-host`, then mesh-controller, then mesh-catalog, then hq. The release holds every package but T6, R1 and R2:
|
||||
the media catalogue and the applications live in repositories of their own and move after it, and only
|
||||
then can the old forms be refused (R1) and the record say what runs (R2).
|
||||
|
||||
**The moves of data run after the delivery, in this order, each a verb that says what it did:**
|
||||
placement out of the settings layers (F2), the settings layers into mesh-config (K5), the secrets into
|
||||
the vault, nothing rotated (V3), then the providers one by one (B2, B3). Each is rehearsed in the lab
|
||||
first, and each is checked by reading back through the module that owns the data before anything
|
||||
points at it.
|
||||
|
||||
**What a release costs.** A proof that is run live (dunst on a workstation, a secret reaching its file, a
|
||||
database consumer connecting) is first seen in the lab rehearsal, and a fault found then holds the
|
||||
release, not one package. A walk that fails fails every commit it carries (ADR 0276 §3), so a fault on
|
||||
the release's first node holds all five; when mesh-delivery or a person stops a member, the others are walked
|
||||
again without it, leaving out every merge that shares its modules (ADR 0299 §1, §2), which in this
|
||||
release is most of them; the fix is a new merge into the release's branch, and the group is walked again.
|
||||
|
||||
**Nothing breaks on the way.** ADR 0349 clause 17: each file is filled the old way or the new way, never
|
||||
both, by the form of its manifest, and the old forms stay accepted until the last module has moved.
|
||||
Inside the release this still holds: the media catalogue and the applications kept in their own
|
||||
repositories move after it, so the old forms stay accepted until they have (R1).
|
||||
|
||||
## What exists already, measured
|
||||
|
||||
Counted 2026-10-14 at mesh-controller `1601cb1`, the node-engine (`mesh-host`) `1a26778`, mesh-sdk `a2d2af0`, mesh-catalog
|
||||
`ebf7f37`.
|
||||
|
||||
| Piece | Today | Becomes |
|
||||
|---|---|---|
|
||||
| the controller's composer | `catalogue.Resolution.compose` fills every namespace but `${secret:}` in one loop (`declaration.go` ~1000–1085); the namespaces and their fields are tabled in `fillers` | fills placement only, for a module that has moved |
|
||||
| settings | tables `settings`, `settings_history`; the `settings` verb (`modules.go` 407–760); proposals and asks (`proposals.go`, 975 lines); trusted files; `takes-settings` merging; about 4 100 lines and 2 500 of tests | the `mesh-config` module and its buckets; the verb `config` |
|
||||
| placement kept as settings | `places`, `accesses` and the kept networks are read from settings layers | facts of an assignment, the controller's own |
|
||||
| secrets | the controller mints, seals and accepts every secret (`internal/secrets`, `inventory/secrets.go` 1 125 lines; tables `secret`, `module_secret`, `secret_ask`, `operator_key`); the vault (`mesh-vault`, TypeScript) is read-only and never asked | the vault, in Go, holding and minting; handing out on request and reply |
|
||||
| bindings | grant files and binding files composed by the controller (`declaration.go` 750–818); `${bound:}` 117 uses | each provider answers its consumers; the vault mints the pair's credential |
|
||||
| contributions | `${contribution:}` (4 collectors), `${shell:}` (3), `${environment:}` (1); 22 contributors | collections, filled by the provisioner client |
|
||||
| file text | 225 file resources in 88 modules, all inline (about 193 KB); 12 modules keep a second copy in 34 files with a test that the two agree (ADR 0349's context counted eleven; the twelfth is lemurs) | template files under `files/`, packed by the module's build |
|
||||
| packing a directory | the builder's `archive` artifact packs a tree and publishes it by digest; the node-engine fetches and unpacks it | the same mechanism carries a module's templates |
|
||||
| the node-engine's file writing | `applyFile`, `applyBlock`, `applyInto`, create-once, drift written back, `Keep` backups, restart-on and reload-on, container reads | the same code, reached also through a narrow local write verb |
|
||||
| the node-engine's local verbs | one socket (`cli.sock`), peer-checked by uid, forwarding to the controller; no local write | a second, narrow socket for the provisioner client |
|
||||
| bus identities | one principal per node for the tool runner, one per module with a process of its own | the provisioner client gets one of its own |
|
||||
| the SDK | KV, watches, asks, caller proof; no sealing helper; the TypeScript `provisioner` is a database-provider harness | a seal box, provider helpers, and readers for config, bound values and secrets |
|
||||
|
||||
**Two measurements decide the order.** The builder can already pack a module's directory, and the
|
||||
controller already fills every placeholder at registration time from text; so template files can ship
|
||||
first, the controller reading the text back from the packed `files/`, and nothing on a node changes. And
|
||||
the node-engine's writing code needs no change in kind, only a second way in; so the provisioner client
|
||||
reuses it rather than writing as root itself.
|
||||
|
||||
## The order the work allows
|
||||
|
||||
```
|
||||
package waits for package waits for
|
||||
F1 — P1 —
|
||||
F2 — P2 P1
|
||||
F3 — P3 F3
|
||||
F4 — P4 P3
|
||||
T1 — P5 P2, P4, T1, K3
|
||||
T2 T1 P6 P5
|
||||
T3 T4 T5 T2 P7 P6
|
||||
T6 T1 V1 F1
|
||||
K1 T1 (same file) V2 V1
|
||||
K2 K1 V3 V2
|
||||
K3 F3, K2 V4 V3, P5
|
||||
K4 K3 V5 V3, V4
|
||||
K5 F2, K4 B1 P5, V5
|
||||
K6 K1 B2 B1
|
||||
K7 K5, P6 B3 B2
|
||||
L1 P6 L2 L1
|
||||
S1 P6 R1 T5, T6, K6, K7, P7, V4, B3, L2, S1
|
||||
R2 R1
|
||||
```
|
||||
The issue tracker carries these as `depends-on` links (thirteen issues also link what they wait for
|
||||
through another package), so the packages ready to start are those whose linked packages are all merged
|
||||
into the release's branches. An issue's "Waits for: … delivered" means merged into the release's
|
||||
branches: nothing is delivered before the release. The first wave touches different repositories and different files:
|
||||
**T1, F1, F3, P1 and F4**. K1 waits for T1 because both change `internal/catalogue/manifest.go`; P3
|
||||
waits for F3 because both change `internal/broker`; F2 joins as soon as a slot is free.
|
||||
|
||||
## 0 — Foundations
|
||||
|
||||
**F1 (issue 650) — A seal box in the SDK.** *mesh-sdk. Half a day.* The ADR 0206 box (X25519, HKDF-SHA256,
|
||||
AES-256-GCM) moves from the licence manager into `mesh-sdk/go/seal`, with a TypeScript twin, and the
|
||||
licence manager uses it. **Proof:** a byte-for-byte test against the licence manager's existing sealed
|
||||
values; the licence manager's tests pass unchanged.
|
||||
|
||||
**F2 (issue 651) — Placement leaves the settings layers.** *mesh-controller. Two days.* `places`, `accesses` and the
|
||||
kept networks become facts of an assignment, held by the controller beside the assignment, with a
|
||||
migration moving each existing layer's keys; `Settle` stops letting a setting replace a provider's
|
||||
served keys. **Proof:** composition of every node before and after the migration is byte-identical;
|
||||
the settings layers hold no placement key afterwards.
|
||||
|
||||
**F3 (issue 652) — The assignments and the modules' config declarations on the bus.** *mesh-controller. Two days.*
|
||||
The controller keeps the bucket of assignments design 54 decides (which module on which node), and a
|
||||
bucket of each registered module's declared config values, written when they change, with one event per
|
||||
write. mesh-config needs both to resolve. **Proof:** a test against a real bus: an assignment and a
|
||||
registration each change exactly one key and raise one event.
|
||||
|
||||
**F4 (issue 653) — The words.** *hq. Half a day.* The glossary gains *config value*, *predefined key*, *provision*
|
||||
and *provisioner client*, *collection*, and the ownership words *owned*, *seed* and *managed*. The word "setting" goes on *config
|
||||
value*'s *Not:* line only in R2, once the 67 documents still using it are reworded; until then the
|
||||
glossary says it is the older word. **Proof:** `words.py` passes.
|
||||
|
||||
## 1 — Template files (ADR 0349 clause 2)
|
||||
|
||||
**T1 (issue 654) — A file resource may name a template.** *mesh-controller. Three days; the largest package of the
|
||||
stage.* A file resource takes `"template": "files/<name>"` in place of `content`; the module's build packs
|
||||
`files/` into an archive artifact of its own (the existing `archive` packing); registration and `Resolve`
|
||||
read each template's text back from the packed tree into `content`, so composition and the node-engine
|
||||
are unchanged; `module check` and the merge gate read templates from the repository tree beside the
|
||||
manifest; a file naming both `template` and `content` is refused. **Proof:** composition tests: a module
|
||||
with its text in `files/` composes byte-identically to the same module with it inline; the merge gate
|
||||
judges a change to a template alone.
|
||||
|
||||
**T2 (issue 655) — The twelve modules with copies.** *mesh-catalog. A day.* adwaita, clipmenu, dunst, feh,
|
||||
gnome-keyring, i3, i3status-rust, lemurs, picom, rofi, screen-lock and xdg move to their templates; the
|
||||
34 inline copies and the `sameAsSource` tests go. **Proof:** each module's composed declaration on its
|
||||
nodes is unchanged (the merge gate's plan says no file changes).
|
||||
|
||||
**T3 (issue 656) — The desktop modules.** *mesh-catalog. A day.* Every remaining module assigned only to
|
||||
workstations. **Proof:** as T2.
|
||||
|
||||
**T4 (issue 657) — The servers' modules.** *mesh-catalog. Two days.* Every remaining module with a build. **Proof:**
|
||||
as T2.
|
||||
|
||||
**T5 (issue 658) — The ten modules without a build.** *mesh-catalog. A day.* ca-trust, de-spiegel, invoicing,
|
||||
local-model-consumer, matrix, node-env, only-office, sshd, step-ca and supabase gain an archive build for
|
||||
their templates. **Proof:** as T2; afterwards no manifest in the catalogue carries file text.
|
||||
|
||||
**T6 (issue 659) — The media catalogue and the applications.** *mesh-media-catalog and each application's
|
||||
repository. Two days.* **Proof:** as T2, per repository.
|
||||
|
||||
## 2 — Config (ADR 0348)
|
||||
|
||||
**K1 (issue 660) — A module declares its config.** *mesh-controller. Two days.* The manifest takes `config` (type,
|
||||
description, validation, trusted, `predefined`, `default` or `required`), `takes-config` and
|
||||
`${config:<key>}`, with `settings`, `takes-settings` and `${setting:}` read as aliases; registration
|
||||
refuses everything ADR 0348's "How it is checked" lists for registration: a value without type or
|
||||
description; a value with neither a default nor `required`; a default failing its validation; an
|
||||
object or list not trusted; a predefined key not on the list or of another type (with K2); an untrusted
|
||||
value falling back to a trusted key; a value neither in a template nor read at runtime; a placeholder
|
||||
naming an undeclared value; a `reload-on` or `restart-on` naming an undeclared file; a moved module's
|
||||
mergeable file not naming its keys; a mesh word or `puid`/`pgid` in `takes-config`. **Proof:** the registration refusal tests, one per
|
||||
rule; every manifest in the catalogue still registers.
|
||||
|
||||
**K2 (issue 661) — The list of predefined keys.** *mesh-controller and mesh-catalog. A day.* `predefined.json` at the
|
||||
catalogue's root, with `font-size` and `agent-managed-settings` first; the build validates it and every
|
||||
manifest naming a key; the merge check refuses removing a key still named or holding a value; the newest
|
||||
trunk build's list is published. **Proof:** the merge check refuses a planted removal; an older build's
|
||||
list does not replace a newer one.
|
||||
|
||||
**K3 (issue 662) — The mesh-config module.** *mesh-catalog. Four days.* A Go module holding the seat `mesh-config`:
|
||||
the buckets `mesh-config_values`, `_resolved`, `_predefined`, `_proposals`; the four sources resolved from
|
||||
F3's assignments and declarations; the verb `config` (set, clear, list, history, narrowed by module and
|
||||
node); validation; the hand-act log; `config-changed`; only its account writes its buckets. Terminal-only
|
||||
for trusted values until K4. **Proof:** its tests resolve each source in turn; a test against a real bus
|
||||
refuses a put from another account.
|
||||
|
||||
**K4 (issue 663) — Trusted values are proposed and approved.** *mesh-catalog. Two days.* mesh-config asks under its
|
||||
own name, with its own grant and cap of open asks, binds each option to the level, key and value, records
|
||||
the approver beside the value, and checks the proposal on Approve (ADR 0277's rules, ADR 0348 clause 8).
|
||||
**Proof:** a proposal test end to end with a stand-in channel; an Approve against a changed value is
|
||||
refused.
|
||||
|
||||
**K5 (issue 664) — The values move, and `settings` forwards.** *mesh-controller and mesh-catalog. Two days.* Each
|
||||
existing layer moves into mesh-config (a node layer to `module.<node>.<module>`; a whole-mesh layer to
|
||||
mesh config, a manifest default or each node, as ADR 0348's consequences say; claude-code's managed
|
||||
settings to `agent-managed-settings`), recorded with why; for a module not yet handed to the provisioner
|
||||
the controller reads `mesh-config_resolved` where it read its layers (ADR 0349 clause 17's old way,
|
||||
an exception to ADR 0348 §9 that R1 removes), and `settings` answers by forwarding to `config`. **Proof:** composition of
|
||||
every node before and after is byte-identical; `settings` and `config` list the same values.
|
||||
|
||||
**K6 (issue 665) — The catalogue says config.** *mesh-catalog. A day.* The 15 modules using `${setting:}`, the 9
|
||||
declaring settings and the 4 with `takes-settings` move to the new names and the full declaration.
|
||||
**Proof:** the catalogue's check finds no old name in a moved module.
|
||||
|
||||
**K7 (issue 666) — The operator's acceptance on dunst.** *live. An hour.* With every level cleared the first
|
||||
workstation's dunstrc says 10; a mesh font size, then that node's font size, then dunst's own value on
|
||||
that node each appear in its dunstrc within the call's answer, and the history shows each change with who and why. Needs P6.
|
||||
|
||||
## 3 — The provisioner (ADR 0349 clauses 3–5, 11, 13)
|
||||
|
||||
**P1 (issue 667) — The node-engine knows who owns a placed file.** *`mesh-host`. A day.* `declaration.File` gains
|
||||
`owner-at-runtime` (`owned`, `seed`, `managed`), mapped onto today's paths (drift written back,
|
||||
create-once, `into`), and the declaration gains the list of files the provisioner fills. **Proof:** the
|
||||
apply tests: each ownership behaves as its old form did.
|
||||
|
||||
**P2 (issue 668) — The narrow local write verb.** *`mesh-host`. Two days.* A second unix socket accepts a write only from
|
||||
the provisioner client's account (`SO_PEERCRED`) and only for a path the declaration names as filled,
|
||||
writes through `applyFile`, `applyBlock` or `applyInto` with `Keep`, and fires restart-on, reload-on and
|
||||
container reads as an apply does. **Proof:** tests: an undeclared path and another uid are refused; a
|
||||
write under `reload-on` reloads its program once.
|
||||
|
||||
**P3 (issue 669) — The provisioner client's own bus account.** *mesh-controller. A day.* A principal of its own per
|
||||
node for `node-provisioner`, granted to read its node's keys in each domain's bucket, publish
|
||||
`prov.applied.<node>.>` and ask the vault; nothing else. **Proof:** the grants test, and a test against a
|
||||
real bus refusing a read of another node's keys.
|
||||
|
||||
**P4 (issue 670) — The provisioner's server.** *mesh-catalog. Two days; after P3.* A Go module holding `mesh-provisioner` once:
|
||||
the registry of which domain answers which kind, the buckets `_registry`, `_needs`, `_applied` and
|
||||
`_collect`. **Proof:** its tests; the buckets listed live.
|
||||
|
||||
**P5 (issue 671) — The provisioner's client.** *mesh-catalog. Four days.* A Go service on every node, outside the tool
|
||||
runner: fetches a module's templates by digest, records needs, watches each owner's keys for its node,
|
||||
fills only when every value is there, writes through P2, reports `prov.applied`, writes an `owned` file
|
||||
back on drift, removes a module's files and needs when it leaves, fills from current values when its node
|
||||
comes back. Its first owners are placement (from the declaration) and config (from
|
||||
`mesh-config_resolved`). **Proof:** the client's test list in ADR 0349, against a real bus.
|
||||
|
||||
**P6 (issue 672) — The controller hands a module to the provisioner, and the gate waits for it.** *mesh-controller.
|
||||
Two days.* For a module marked moved, the declaration carries placement, the templates' digest and the
|
||||
filled-files list, and the controller runs no other filling pass for it; the first-node gate counts the
|
||||
module healthy only after its node's `prov.applied` for the new build (`gateFacts`). dunst moves first.
|
||||
**Proof:** composition and gate tests; dunst on the first workstation filled by the client, live.
|
||||
|
||||
**P7 (issue 673) — The node-engine stops writing placed files from the declaration.** *`mesh-host`. A day.* For a moved
|
||||
module the engine writes its filled files only through P2, and removes as an orphan only what the verb
|
||||
placed. **Proof:** the apply tests; no placed file written twice in a day's journal on the
|
||||
first workstation.
|
||||
|
||||
## 4 — Secrets (ADR 0349 clauses 6–11, 16; issue 647)
|
||||
|
||||
**V1 (issue 674) — The vault in Go, holding secrets.** *mesh-catalog. Four days.* `mesh-vault` is rewritten in Go:
|
||||
its own store, a copy of each secret sealed to the operator key, `get` on request and reply sealed to the
|
||||
asker's key (F1's box; the node-engine's key format is settled here and written down), `secret-changed`
|
||||
without a value, no secret in any bucket. **Proof:** the vault's test list in ADR 0349.
|
||||
|
||||
**V2 (issue 675) — The vault's verbs.** *mesh-catalog and mesh-controller. Three days.* `secret accept`, `secret-ask`
|
||||
(with ADR 0277 §24–§27's record and bounds in the vault's store), `issued` (ADR 0305, the provider's tool
|
||||
answering the vault alone) and `rotate` become the vault's; the controller's verbs forward. **Proof:** the
|
||||
`secret-ask` and issuing provider tests in ADR 0349.
|
||||
|
||||
**V3 (issue 676) — The secrets move to the vault.** *mesh-controller and mesh-catalog. Two days.* Every row of
|
||||
`secret`, `module_secret`, `secret_ask` and the operator key's public half are copied into the vault as they are,
|
||||
nothing rotated, and read back through the vault before anything points at it. **Proof:** for every
|
||||
secret, the vault's sealed answer opens to the same value the controller's does.
|
||||
|
||||
**V4 (issue 647) — A node's secrets come from the vault.** *mesh-catalog, mesh-controller, `mesh-host`.
|
||||
Three days.* The client fills `${secret:}` from the vault's `get`; for a moved module the controller seals
|
||||
nothing; the core's credentials travel sealed by the vault to their node and the node-engine opens them.
|
||||
**Proof:** a secret rotated in the vault reaches its file without a new declaration, live.
|
||||
|
||||
**V5 (issue 677) — The vault mints pair credentials.** *mesh-catalog. Two days.* One value per provider assignment and
|
||||
provision, remade for all holders when the vault sees a consumer's need recorded or deleted (ADR 0158
|
||||
§4–§6). A need recorded for a bind the vault already holds from V3 adopts that value and remakes
|
||||
nothing, so the move itself rotates no credential. **Proof:** the provider test in ADR 0349, with a stand-in provider.
|
||||
|
||||
## 5 — Bindings (ADR 0349 clause 12)
|
||||
|
||||
**B1 (issue 678) — A provider's helper in the SDK.** *mesh-sdk. Two days.* Go: watch the needs for a kind, write one
|
||||
entry per consumer, refuse a derived value for a multi-holder consumer, answer from the vault's pair
|
||||
credential. The TypeScript `provisioner` harness is renamed so the word means one thing. **Proof:** its
|
||||
tests with a stand-in bus.
|
||||
|
||||
**B2 (issue 679) — PostgreSQL answers its consumers.** *mesh-catalog and mesh-controller. Three days.* The first
|
||||
provider moves; its grant files and binding files are retired. **Proof:** every database consumer on
|
||||
every node connects after the move with the credential it had, adopted by the vault as V5 says, live.
|
||||
|
||||
**B3 (issue 680) — The other providers.** *mesh-catalog. A week, one pull request per provider.* **Proof:** as B2, per
|
||||
provider; afterwards the controller composes no grant file.
|
||||
|
||||
## 6 — Collections (ADR 0349 clause 13)
|
||||
|
||||
**L1 (issue 684) — A collection is declared and filled by the client.** *mesh-controller and mesh-catalog. Three days.*
|
||||
A collector requires a collection; a contributor provides an item from a template; the client fills the
|
||||
collector's template from `_collect`. `${contribution:}`, `${shell:}` and `${environment:}` read as
|
||||
collections. **Proof:** zsh's file holds every placed contributor's item and loses one whose contributor
|
||||
leaves.
|
||||
|
||||
**L2 (issue 681) — The collectors and contributors move.** *mesh-catalog. Two days.* zsh first, then the bar, the
|
||||
display session, the hotkeys, xorg, power and node-env, with their 22 contributors. **Proof:** each
|
||||
collector's composed file is unchanged at the move.
|
||||
|
||||
## 7 — A module's code asks at runtime (ADR 0349 clause 14)
|
||||
|
||||
**S1 (issue 685) — The SDK's readers.** *mesh-sdk and mesh-catalog. Two days.* `config`, `bound` and their watches,
|
||||
answered by the node's client for what the manifest declares. `secrets` refuses until the module runs
|
||||
under a bus account of its own, which waits on issue 569 and its decision. **Proof:** the SDK's test in
|
||||
ADR 0349; claude-code reads its managed settings through it.
|
||||
|
||||
## 8 — The old forms go (ADR 0349 clause 17)
|
||||
|
||||
**R1 (issue 682) — Refused and removed.** *mesh-controller, `mesh-host`, mesh-catalog. Three days.* Once every module of
|
||||
every catalogue has moved: the catalogue's check refuses inline text, `settings`, `${setting:}` and the
|
||||
old contribution forms; the controller's filling passes but placement, its settings, secret and binding
|
||||
code and tables (a new migration) go; the node-engine keeps opening sealed values for the core's files
|
||||
only; the controller stops reading `mesh-config_resolved`. **Proof:** the controller's test that its
|
||||
code opens no secret outside genesis and reads no config value; the absence of the
|
||||
removed code.
|
||||
|
||||
**R2 (issue 683) — The record says what runs.** *hq. Two days.* The as-is designs are written, designs 27 and 32 are
|
||||
amended, the 67 documents that still say "setting" in running prose are reworded so the glossary can
|
||||
retire the word (F4 left it off the *Not:* line for them), design 49 lists the Config domain, ADR 0348's and 0349's built status is said, and this document's status becomes `implemented`.
|
||||
|
||||
## What is deliberately not here
|
||||
|
||||
- **Secrets in a module's own code** wait on issue 569 (a module's tools run as the tool runner's
|
||||
account) and its decision; S1 ships without them.
|
||||
- **Release separated from delivery** stays issue 644's, and **the bus's replicas** issue 645's.
|
||||
- **Renaming "walk"** is issue 646's.
|
||||
|
||||
## How this list is kept true
|
||||
|
||||
Each package's proof that runs in its tests is run when it is merged into the release's branch, and its
|
||||
line here gains the date and the commit; a proof that runs live is run in the lab rehearsal and again
|
||||
after the release's delivery. A package whose proof fails is not reworded; the failure is recorded under it and the package
|
||||
stays open. The issue tracker says which packages are worked now; this document says only the order.
|
||||
@@ -56,6 +56,7 @@ document is written and this one's status becomes `implemented`.
|
||||
| [`54-the-controllers-records-on-the-bus.md`](54-the-controllers-records-on-the-bus.md) | **Designed.** The controller keeps five record mirrors on the bus (nodes, assignments, walks, builds, settings): each a bucket written from its store only when the record changed, with one event per write, and audited against the store every self-check run, a difference raised as `mirror-drifted` before the healer H6 repairs it | ADR 0289 |
|
||||
| [`55-the-knowledge-base.md`](55-the-knowledge-base.md) | **Designed.** The mesh keeps its decision records and research efforts whole in one module, `mesh-knowledge`, on the control-node: number, status, topic, typed links both ways, each decision's clauses with their own status, and the reasoning, with every version; a record is proposed, checked at the write, reviewed by the knowledge base's own judgement and accepted there, with the operator's Approve when it needs it; agents ask what holds in one bounded call | ADR 0290 |
|
||||
| [`56-the-mail-client-set-up-by-the-mesh.md`](56-the-mail-client-set-up-by-the-mesh.md) | **Designed.** On every node with a display server, the `betterbird` module installs Betterbird from a pinned upstream release mirrored into the artifact store, ships the Owl add-on pinned and installed by Betterbird's enterprise policy, and declares the operator's mail accounts in a trusted setting without credentials; each account signs in once at a person's first use, and one the profile already holds is adopted by its address | ADR 0316, ADR 0317 |
|
||||
| [`57-building-config-and-provisioning.md`](57-building-config-and-provisioning.md) | **Designed.** The work of ADR 0348 and ADR 0349 as 37 packages, each an issue with its proof: foundations, template files, config in its own module, the provisioner and its client, secrets in the vault, bindings from providers, collections, a module's runtime readers, and removing the old forms; at most five worked at once | ADR 0348, ADR 0349 |
|
||||
|
||||
## Not yet written
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# Release 57: config and provisioning
|
||||
|
||||
This branch carries the work of design 57 (ADR 0348, ADR 0349) in this repository. Each package
|
||||
merges here through its own reviewed pull request; the branch reaches main as one pull request, in one
|
||||
delivery group with the branch of the same name in mesh-controller, mesh-host, mesh-sdk, mesh-catalog
|
||||
and hq, after a rehearsal in the lab. This file is deleted by the last commit before that pull request.
|
||||
Reference in New Issue
Block a user