From f2abbb042c2f2bb306ae86679ebfe45b2fdfba27 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 7 Oct 2026 19:37:44 +0200 Subject: [PATCH] Research 034: the mesh in domains The operator asked for one language per domain because the same concept keeps arriving under different words. Inventory the words in use, test a domain split, list the clashes with evidence, and describe how the glossary rule would be checked. --- .../034-the-mesh-in-domains/00-overview.md | 108 +++++++ .../01-the-concepts-in-use.md | 148 +++++++++ .../034-the-mesh-in-domains/02-the-domains.md | 292 +++++++++++++++++ .../034-the-mesh-in-domains/03-the-clashes.md | 306 ++++++++++++++++++ .../04-how-the-glossary-is-checked.md | 140 ++++++++ .../05-a-glossary-by-domain.md | 101 ++++++ 6 files changed, 1095 insertions(+) create mode 100644 01-RESEARCH/034-the-mesh-in-domains/00-overview.md create mode 100644 01-RESEARCH/034-the-mesh-in-domains/01-the-concepts-in-use.md create mode 100644 01-RESEARCH/034-the-mesh-in-domains/02-the-domains.md create mode 100644 01-RESEARCH/034-the-mesh-in-domains/03-the-clashes.md create mode 100644 01-RESEARCH/034-the-mesh-in-domains/04-how-the-glossary-is-checked.md create mode 100644 01-RESEARCH/034-the-mesh-in-domains/05-a-glossary-by-domain.md diff --git a/01-RESEARCH/034-the-mesh-in-domains/00-overview.md b/01-RESEARCH/034-the-mesh-in-domains/00-overview.md new file mode 100644 index 00000000..7509b9dd --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/00-overview.md @@ -0,0 +1,108 @@ +--- +status: active +initiated: 2026-10-07 +touches: + - 00-META/glossary.md + - 00-META/checks/ + - 02-DECISIONS/0006-the-substrate-and-the-control-plane.md + - 02-DECISIONS/0008-a-context-owns-its-store.md + - 03-DESIGN/01-to-be/06-the-controller.md + - the descriptions of every module's tools and every seat's verbs in the catalogue +--- + +# 034 — The mesh in domains + +## What is investigated + +The operator, 2026-10-07: *"I wanted to develop our nox-mesh domain driven. Meaning every concept +should fit into some domain and we try to come up with a common knowledge base/glossary/jargon for our +application. We kind-of do this already I think, yet sometimes, you return different words for existing +concepts."* + +Two terms from domain-driven design are used throughout this effort, so they are explained once here. +A **domain** (in the literature, a *bounded context*) is an area of the system inside which every word +has exactly one meaning, and which owns the concepts that meaning describes. A **ubiquitous language** is +the set of words a domain uses the same way in conversation, in documents and in code. The glossary +([`00-META/glossary.md`](../../00-META/glossary.md)) is this repository's attempt at a ubiquitous +language for the whole mesh, without domains. + +The effort asks five questions: + +1. **Which concepts are in use**, in the glossary, the decision records, the designs and the issue + reports, and in the words the running mesh's tools use to describe themselves? +2. **Into which domains do they fall?** Each domain gets a purpose, the concepts it owns, the one word + for each, and its relation to the others. The operator's starting guess — building and delivering + changes; running modules on machines; health and alerts; data and backups; people, conversation and + approvals; the network — is tested, not assumed. +3. **Where do the words clash?** Two or more words for one concept (a *synonym*), or one word for two + concepts (a *homonym*), each with evidence and a proposed single word. +4. **How is the glossary rule checked?** [`AGENTS.md`](../../AGENTS.md) says *a rule states how it is + checked*, and "one name per thing" is checked by nothing today. +5. **How should the glossary be organised by domain?** Described only; the glossary itself changes when + this effort graduates, not before. + +## Why + +Because the drift is measurable, and it costs. The glossary retired *control plane* on 2026-09-16; three +weeks later 29 occurrences stand in 12 to-be designs — the documents that tell somebody what to do — and +73 files created after the retirement use it. It retired *host agent*, *the host* and `mesh-host` for the +**node-engine** on 2026-10-05; the descriptions of four tools the running mesh serves still say *"the host +will restore"*, and the glossary's own entry for node tools says *"a host-side process the host +supervises"*. The glossary defines **node**, while the decisions and designs of the last week use +*machine* twice as often as *node*, and the console's own tools are called `mesh_machine` and list +"machines". A reader — person or agent — who meets two words assumes two things, and an agent answering +from these documents repeats whichever word it read last. That is the operator's complaint, observed. + +## What it touches + +The glossary and how it is kept; the checks in [`00-META/checks/`](../../00-META/checks/); the seven +contexts of the controller that [ADR 0006](../../02-DECISIONS/0006-the-substrate-and-the-control-plane.md) +named and [ADR 0008](../../02-DECISIONS/0008-a-context-owns-its-store.md) gave each its own store, which +are the nearest thing the mesh already has to domains; and the descriptions of the tools and seat verbs +that the modules in the catalogue serve, which are where an agent meets the mesh's words most often. + +## The documents + +| | | +|---|---| +| [01 — The concepts in use](01-the-concepts-in-use.md) | the inventory: what was read, how it was counted, what the glossary holds and what it lacks, and the words the running tools use | +| [02 — The domains](02-the-domains.md) | the proposed split into ten domains plus the repository's own, each with purpose, concepts, words and relations; the operator's guess tested | +| [03 — The clashes](03-the-clashes.md) | twenty clashes with evidence and a proposed word for each, the five most costly first | +| [04 — How the glossary is checked](04-how-the-glossary-is-checked.md) | a proposed check over hq documents and over the catalogue's tool descriptions; described, not built | +| [05 — A glossary by domain](05-a-glossary-by-domain.md) | how the glossary would be organised; described, not written | + +## Findings so far + +- **The mesh already has domains under another name.** ADR 0006 named seven *contexts* of the controller — + inventory, config, connectivity, provisioning, delivery, observability, identity. Only three of them have + a store today (`inventory`, `identity`, and `licences`, which is not one of the seven), and the words the + mesh has grown since (seat, delivery, condition, ask, data class) are not organised by them. The + proposed split in [02](02-the-domains.md) keeps five of the seven, renames one, and adds four. +- **The operator's guess survives mostly intact.** Five of its six domains hold up. It lacks a domain for + *identity and access* (credentials, grants, licences), one for *provisioning* (provider and consumer), + the *core* the rest runs on (controller, bus, store, lease, genesis), and the *module* itself, whose + manifest is the language every other domain reads. *Health and alerts* is better called *health and + repair*: the mesh says *condition*, not *alert*. +- **The glossary is short of the vocabulary in use, and contradicts itself twice.** It has 33 entries. At + least 40 words used in more than ten decision records each — *module*, *manifest*, *assignment*, + *machine*, *provider*, *condition*, *gate*, *tier*, *operator* among them — have no entry. It defines the + console as a module and, further down, says node tools replaced that name; it says the deprecated broker + holds no seat and, in the entry for *claim*, that it claims `mesh-broker`. +- **Most drift is in two places**: governing designs written before a word was retired and never + revisited, and tool descriptions, which nothing compares with the glossary at all. +- **Homonyms cost more than synonyms**, and a word list cannot catch them. *Plan*, *push*, *release*, + *gate*, *tier*, *ask*, *store* and *record* each mean two to four things today, several of them in the + verbs of the same seat. + +## Questions for graduation + +- **Machine or node.** One concept, two words, both heavily used; [03](03-the-clashes.md) recommends + *machine* in prose and keeps `node` only as an identifier (a scope's value and the `node-` prefix of seat + names). This is the largest rename the effort proposes, and the operator's call. +- **Domain or context.** The repository already says *context* (ADR 0006, ADR 0008) for an owner of + records with its own store. Using *domain* for the vocabulary partition beside it would be the effort's + own synonym. [02](02-the-domains.md) proposes that a domain is the vocabulary and ownership boundary and + a context is one store inside it, and asks for that to be decided rather than left to usage. +- **Which documents the check holds to the list**, and from which date ([04](04-how-the-glossary-is-checked.md)). +- **Where the tool-description check runs**: in the catalogue repository's merge check, or as a probe of the + running mesh, or both. diff --git a/01-RESEARCH/034-the-mesh-in-domains/01-the-concepts-in-use.md b/01-RESEARCH/034-the-mesh-in-domains/01-the-concepts-in-use.md new file mode 100644 index 00000000..400cff3b --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/01-the-concepts-in-use.md @@ -0,0 +1,148 @@ +# 01 — The concepts in use + +What was read, how words were counted, what the glossary holds, what it lacks, and which words the +running mesh's tools use. The domains in [02](02-the-domains.md) and the clashes in +[03](03-the-clashes.md) are drawn from this. + +## What was read + +| Source | Size on 2026-10-07 | How | +|---|---|---| +| the glossary | 33 entries | read whole | +| decision records (`02-DECISIONS/`) | 225 records | counted; the seven-contexts record (0006), its store rule (0008) and the records from 0220 to 0240 read for their words | +| to-be designs (`03-DESIGN/01-to-be/`) | 49 documents | counted; the controller (06), connectivity (08), and 45 to 48 read for their words | +| as-is designs (`03-DESIGN/00-as-is/`) | 17 documents | counted | +| issue reports (`04-ISSUES/`) | 291 issues | counted | +| research (`01-RESEARCH/`) | 33 efforts | counted; research 005 (*which domains the catalogue groups into*) read whole, as prior art | +| the running mesh's tools | 88 modules serving 535 tools, plus the verbs of 15 seats every machine holds and 5 seats held once for the mesh | listed through the console's read tools (overview, machine, search, describe); nothing was called that changes anything | + +**How words were counted.** A case-insensitive, whole-word match per file; the number given is the number +of *files* containing the word, not of occurrences, unless a statement says otherwise. Where a file's age +matters, its age is the date git first records it. The tool descriptions are the first line each tool +gives of itself in the console's listing, which is cut at about 160 characters, so a word that occurs only +late in a long description is undercounted there. + +## What the glossary holds + +Thirty-three entries, in seven sections: the mesh and its machines; what runs the mesh; what the mesh +stores and serves; how modules relate to the mesh; the surfaces; how a change reaches the machines; the +operator's machine. Retired words are marked three ways — struck through (`~~flavor~~`), *"Replaces +**x**"*, and *"Not x"* — so no program can read the list of retired words from it reliably today. + +**It contradicts itself in two places.** + +- **The console.** The surfaces section defines the console as *"the module (`mesh-console`) that puts the + mesh's tools in front of whoever is on a machine"*. The operator's machine section, further down, defines + node tools as the runtime whose *"serving mode on loopback is what was called **the console**"*, and + says node tools *"replaces 'console' as the module's name; console remains the word for the person's end + of it."* Both entries are current. +- **The deprecated broker.** Its entry says it has *"no seat, not foundation"*. The entry for *claim* + says *"the `mesh-controller`, `postgres` and `lavinmq` modules claim the `mesh-controller`, `mesh-store` + and `mesh-broker` seats"*, and the entry for *bus* says the bus is held by the `mesh-broker` seat. + +**It uses a word it retired.** The node tools entry says *"a host-side process the host supervises"*, +eight lines after the node-engine entry retired *the host*. + +## What the glossary lacks + +Words used in more than ten decision records each, with no entry of their own (files containing each, of +225 records): + +| Word | Records | Word | Records | Word | Records | +|---|---|---|---|---|---| +| machine | 177 | operator | 125 | catalogue | 120 | +| declaration | 106 | manifest | 102 | reach | 101 | +| provider | 95 | person | 91 | adopted | 84 | +| tool | 76 | holder | 75 | grant | 65 | +| assignment | 60 | secret | 56 | scope | 55 | +| apply | 54 | resolver | 51 | genesis | 46 | +| verb | 45 | firewall | 43 | route | 42 | +| converged | 40 | private network | 37 | connectivity | 34 | +| the lab | 33 | proxy | 31 | overlay | 30 | +| upgrade | 27 | gate | 25 | condition | 23 | +| endpoint | 23 | reconcile | 22 | vault | 20 | +| hub | 19 | finding | 19 | health | 19 | +| licence | 16 | probe | 15 | tier | 14 | +| membership | 14 | anchor | 14 | backup | 11 | + +*Module* itself — the word the whole mesh is built on — has no entry. Nor do the words of the four +designs written in the last week: *condition*, *healer*, *self-check*, *watchdog*, *hand-act*, *drill*, +*lease*, *epoch* (to-be 45, *a core that cannot fail silently*); *data class*, *restore point* (to-be 43 +and ADR 0233); *converged* and *adopted* as the two states a machine is in (the controller's `nodes` verb +answers with them). + +## The seven contexts, as they stand + +ADR 0006 split the controller into seven **contexts** — areas of record, each owning its own store +(ADR 0008) — and to-be 06 tabulates them: + +| Context | Owns, in ADR 0006's words | A store of its own today? | +|---|---|---| +| inventory | nodes, modules, assignments, versions | yes | +| config | settings, secrets, and deriving them onto nodes | no | +| connectivity | overlay, resolution, exposure, filtering, certificates | no | +| provisioning | resource grants between modules | no | +| delivery | source to artifact to node | no — deliveries are kept by the `mesh-delivery` module since ADR 0239 | +| observability | health, logs, metrics, alerts | no | +| identity | agents, humans, services, authorisation | yes | + +The store has a third database the seven do not name, `licences` (ADR 0183). The seven are the nearest +thing the mesh has to domains, and they were drawn from one question — *does answering this need more than +one node?* — which is a test for what the controller owns, not for where a word belongs. Seat, claim, +bench, delivery group, condition, ask, data class and every word of the operator's conversation arrived +after them, and none of those records says which context its words belong to. + +Research 005 asked a neighbouring question in August — which *modules* group into domains — measured which +modules change together, and found that only the reachability modules do. Its conclusion, recorded in ADR +0009, was that modules are not grouped into packages; it did not touch the vocabulary. This effort groups +*concepts and words*, not modules: a module may serve several domains, and the domains are not folders in +the catalogue. + +## The words the running tools use + +The console's listing gives each tool's first line. Over the 535 module tools (the seat verbs are counted +separately below): + +| Word | Tools | Modules | Note | +|---|---|---|---| +| machine | 39 | 25 | the word most modules use for where they run | +| node | 27 | 5 | 21 of the 27 in the agent's configuration module; the others the vault, the bus server, the packet filter and a flow editor whose own objects are called nodes | +| the host / host's | 6 | 2 | the container module's `start` and `stop` tools, meaning the node-engine; the remaining uses are a network's hosts | +| operator | 28 | 23 | the person; consistent with the glossary | +| user | 30 | 12 | almost all a wrapped program's own accounts (an identity provider's users, the forge's users, a database's users) | +| install | 43 | 16 | a package installed on a machine, never the mesh's assignment | +| condition | 0 | 0 | — while the controller's verb is `conditions` | +| seat | 0 | 0 | the module tools never name a seat; only the console and the controller do | +| deploy, rollout, pipeline, control plane | 1, 0, 0, 0 | — | the one *deploy* is a wrapped program's own (a flow editor's) | + +The seat verbs say: + +- `/node-service-manager.start` and `.stop`: *"the answer says **the host** will restore what its + declaration says at its next apply"*. +- the bus server module's `connections` tool: *"a machine's **host** `node.`, a machine's runtime + `.node-tools`"* — three words (host, node, runtime) for two programs, in one line. +- `mesh-controller.plan`: *"What one machine would run, and why: **the declaration** the mesh would send + it"*; `mesh-controller.plans`: *"What the last merges produced … the tiers"*; + `mesh-controller.delivery-plan`: *"The delivery plan of a diffset"*. Three meanings of *plan* on one + seat. +- `mesh-controller.queue`, `.cancel`, `.clear`: *"Every **ask** in the build queue"* — while the glossary's + *ask* is a request for the operator's input. +- `mesh-delivery.release`: *"A person's word that a held delivery goes on"*; and + `anthropic-licence-manager.release`: *"Unbind a consumer"*. +- `mesh-controller.doctor`: *"The **self-check** …"* — the verb and the concept named differently. +- the nftables module's tool is called `firewall_rules`, and the seat it holds on every machine is + `node-packet-filter`, whose verb is `rules`. +- `mesh-controller.nodes`: *"Every **machine** the mesh knows"*; the verb is named for nodes and answers + in machines. +- `node-build-agent` is the name of a seat every machine holds, while the glossary avoids *agent* + *"because the word already means two other things here, the build agent and the operator's coding + agent"*, and ADR 0237 calls the same role *the build seat*. +- `operator-channel` is a seat of the mesh, held by the conversation's router (ADR 0234); the glossary + names the router and the `channel` bench but not the seat. + +**Vendor words are not drift.** A module that wraps a program speaks that program's language where it +describes the program's own objects: an identity provider has *users* and *realms*, a media manager has +*releases*, a flow editor *deploys*. That is correct and must stay so; a check that flagged it would be +wrong ([04](04-how-the-glossary-is-checked.md) scopes the list to the mesh's own words for that reason). +The drift is where a tool describes **the mesh's** objects — its machines, its engine, its seats — in a +word the glossary retired or never had. diff --git a/01-RESEARCH/034-the-mesh-in-domains/02-the-domains.md b/01-RESEARCH/034-the-mesh-in-domains/02-the-domains.md new file mode 100644 index 00000000..769f9d7a --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/02-the-domains.md @@ -0,0 +1,292 @@ +# 02 — The domains + +A proposed split of the mesh's concepts into domains, tested against the operator's starting guess and +against the seven contexts of ADR 0006. + +## What a domain is here, and how one was drawn + +A **domain** is an area of the mesh that **owns** a set of concepts: inside it each concept has one +word, and the domain decides what that word means. Another domain may use the word — that is what makes +it a shared language — but may not change its meaning. Two relations between domains are named: + +- **upstream / downstream.** Domain A is *upstream* of B when B depends on A's concepts and A does not + depend on B's. A change of meaning upstream ripples down; never the other way. +- **shared word.** A word two domains both use. It is safe when both mean the same thing and one of + them owns it; it is a clash when they mean different things ([03](03-the-clashes.md)). + +Three tests decided where a concept belongs, in this order: + +1. **Who records it.** The context, module or seat that writes the record of it owns it (ADR 0008: *a + context owns its store*). A condition is the controller's record; a delivery is `mesh-delivery`'s. +2. **Whose decision records define it.** The records that introduced the word, and the to-be design that + names those records in its frontmatter. +3. **Which other words it is never used without.** *Walk* never appears without *delivery*, *tier* and + *gate*; *healer* never without *condition* and *budget*. + +**Domain and context.** ADR 0006's *context* is narrower than a domain: it is one owner of records, with +one store, inside the controller. This effort proposes that a domain may hold zero, one or several +contexts, and that the two words are kept apart: **domain** for the area of vocabulary and ownership, +**context** for a store-owning part of the controller. Whether to adopt *domain* at all, or to widen +*context* to mean it, is a question for graduation ([00](00-overview.md)); this document uses *domain*. + +## The split + +Ten domains of the mesh, and one of this repository. They are ordered from the most upstream to the most +downstream; each lists its purpose, the concepts it owns with the proposed word for each, and its +relations. + +### 1. Module — what a module is and declares + +**Purpose.** To say what one module is, in the one document every other domain reads: its manifest. + +**Owns.** *module*; *manifest* (the file a module is defined by — not *module definition*, not +*module.yml* in prose); *resource* (what a manifest declares a machine must have: a file, a service, a +container, a package); *declares* (the verb for what a manifest states); *provides* / *requires* (as +written in a manifest; their meaning is Provisioning's); *claim* (a manifest's request to hold a seat); +*setting* (a value a manifest declares and an assignment gives); *kept region*; *bundle* and *tools +bundle*; *tool* (what a module serves) and *verb* (what a seat carries); *invokes*; *upgrade policy* +(`roll`, `together`, `record`); the declarations of *data* and *health* (their meaning is Data's and +Health's). + +**Relations.** The most upstream domain. Every other domain reads the manifest, which makes its words a +**published language** — a vocabulary fixed in a schema that others conform to. It depends on nothing +but the Core's notion of a scope. + +**Against the seven contexts.** None; the seven describe the controller, and the manifest is not the +controller's. + +### 2. Core — the mesh's own machinery + +**Purpose.** To keep the controller, the bus, the store and every machine's engine running and agreed, +so that every other domain has something to run on. + +**Owns.** *controller*; *control-node*; *node-engine*; *node tools* (the tool runtime on every machine); +*foundation*; *store* (the one database server); *bus*; *broker seat*; *genesis* (raising the foundation +on an empty mesh); *lease* and *epoch* (ADR 0229: which controller may send, and the order of what it +sent); *context* (a part of the controller that owns a store). + +**Relations.** Upstream of every domain but Module. Every other domain is a **conformist** to it — it +uses the bus and the store as they are and has no say in their shape. + +**Against the seven contexts.** Not one of them: ADR 0006 described what the controller owns, and the +Core is the controller itself. + +### 3. Placement — what runs on which machine + +**Purpose.** To decide, send and apply what each machine runs, and to say why. + +**Owns.** *machine* (or *node* — see clash 1); *operator account*; *assignment* (a module put on a +machine); *seat*, *scope* (machine, site, mesh), *capacity*, *bench*, *kind*, *holder*, *holding*; +*depends on a seat*; *declaration* (what the controller sends one machine — see clash 9); *send* (the +controller giving a machine its declaration; `push` is the verb that asks for it — clash 4); *apply* (the +node-engine making a machine match its declaration); *reconcile*; *converged* and *adopted* (a machine's +two states, ADR 0100); *pin* is Provisioning's, not this domain's. + +**Relations.** Downstream of Module and Core. Upstream of Provisioning, Connectivity, Data and Health, +which all need to know what runs where. Shares *setting* with Module (a manifest declares it, an +assignment gives it its value) and *declaration* with Module (clash 9). + +**Against the seven contexts.** ADR 0006's *inventory* (nodes, modules, assignments, versions) and the +derivation half of *config*. + +The operator's guess called this *running modules on machines (seats, benches, claims)*, and it holds. +*Claim* belongs to Module (a manifest claims) and *holding* to Placement (an assignment holds), which is +the distinction the glossary already draws in *installed / holding*. + +### 4. Provisioning — one module serving another + +**Purpose.** To resolve which module serves a provision for which consumer, and to wire the two. + +**Owns.** *provision*; *provider*; *consumer* (the module that requires); *pin* (a person's choice of +provider); *endpoint* (where a consumer reaches its provider); *pair credential* (the two ends of one +credential; the credential itself is Identity's); *retire* (a provider stops serving a consumer the mesh +no longer asks for, ADR 0230). + +**Relations.** Downstream of Module (requires/provides), Placement (what runs where) and Identity (the +credential). Upstream of Data, which watches what a provider keeps for a consumer. Shares *consumer* with +Identity's licences (a licence is bound to a consumer) — the same idea, safely shared. + +**Against the seven contexts.** ADR 0006's *provisioning*, unchanged. + +The operator's guess has no such domain; its words are spread across *running modules* and *data*. They +are a language of their own: 95 decision records say *provider*, and four seat verbs (`pin`, `unpin`, +`retire`, `cleanup`) are about nothing else. + +### 5. Identity and access — who may do what + +**Purpose.** To issue, hold, rotate and check the credentials and grants by which modules, machines, +agents and the operator act. + +**Owns.** *credential* (anything that proves an identity); *secret* (a credential or other value the vault +keeps sealed); *vault*; *grant* (what an identity may call or reach); *bus account* and *membership*; *rotate*; +*licence*, *binding* (a consumer bound to a licence), *adopt* (taking in a licence that existed before); +*proof* (what an authorising answer carries: a verified sender, a one-time code, a key's touch); +*operator identity* (the list the router checks a sender against). + +**Relations.** Downstream of Core (the bus's accounts) and Placement (what is assigned where). Upstream of +Provisioning, Operator and conversation, and Change and delivery (whose builds are signed and whose +merges are approved). + +**Against the seven contexts.** ADR 0006's *identity*, plus the secrets half of *config*, plus the +`licences` store, which is a context the seven did not name. + +The operator's guess has no such domain. It is not small: *credential* is in 78 decision records, *grant* +in 65, *secret* in 56, and two of the three context stores that exist today (`identity`, `licences`) are +its. + +### 6. Change and delivery — a commit on its way to the machines + +**Purpose.** To take one commit from its pull request to every machine that should run it, and to put it +back when it fails. + +**Owns.** *pull request*, *commit*, *trunk*; *merge check* (the two statuses a pull request carries, the +*merge gate* and the *repository check*, ADR 0238); *build*, *build seat*, *build queue* and the entry in +it (clash 7); *package* and *package-registry*; *artifact* and *artifact store*; *catalogue* (what the mesh +holds of every module, at which commit); *delivery*, *delivery group*, *delivery plan* (its *build plan* +and *deploy plan*); *walk*; *tier* in the sense of a step of a walk (clash 8); *first machine* and its +*gate* (clash 6); *rollback*; *the lab*, *scenario*, *replay*. + +**Relations.** Downstream of Module, Core, Health (the gate reads health) and Data (a module holding +irreplaceable data is recorded, not rolled out, ADR 0236). Upstream of Placement in time — a walk asks +the controller to send — and of Operator and conversation, which carries its held deliveries to a person. + +**Against the seven contexts.** ADR 0006's *delivery*, now owned by the `mesh-delivery` module rather than +by a context of the controller (ADR 0239). + +The operator's guess called this *building and delivering changes*; it holds, with *change* kept for a +diff (the glossary already says so) and *delivery* for the thing that travels. + +### 7. Health and repair — what is wrong, and putting it right + +**Purpose.** To notice what is wrong with the mesh, say it once, repair what may be repaired unattended, +and record what was done by hand. + +**Owns.** *health* (a module's or core component's statement of being well, ADR 0240); *probe*; +*signal* and *watchdog*; *self-check* (clash 13); *condition* (one open fact about something wrong, with a +key and a severity); *healer*, its *repair* and *budget*; *drill*; *hand-act*; *observation* (ADR 0231: +only observation raises or clears a condition). + +**Relations.** Downstream of everything it watches. Upstream of Change and delivery (the gate) and of +Operator and conversation (a condition becomes a message). + +**Against the seven contexts.** ADR 0006's *observability* — whose row says *"health, logs, metrics, +alerts"*. The mesh never built *alerts*; it built conditions, and the word *alert* survives only in a +wrapped dashboard program's tool. The domain is renamed accordingly: *observability* names the watching, +and half of what this domain owns is repair. + +The operator's guess called this *health and alerts*. It holds as a domain, under the word the mesh +uses: *condition*, not *alert* (clash 14). + +### 8. Data — what the mesh keeps, and getting it back + +**Purpose.** To know every item of data a module holds, how precious it is, and to keep it recoverable. + +**Owns.** *data* as a module declares it (ADR 0233); *data class* — *irreplaceable*, *rebuildable*, +*cache*; *backup*; *restore point*; *restore* (beside the live data, never over it); the bus's *stream +snapshot* (ADR 0235); *binding* of a consumer to its data moving only by a person (ADR 0232). + +**Relations.** Downstream of Module (the declaration), Placement (where the data is) and Provisioning +(data a provider keeps for a consumer). Upstream of Change and delivery (irreplaceable data holds a +module back from rolling out) and of Health (data is watched). + +**Against the seven contexts.** None. Data was not foreseen in ADR 0006; the self-check measures it today +(`mesh-controller.data`), and every machine's `node-backup` seat keeps it. + +The operator's guess called this *data and backups*, and it holds. + +### 9. Connectivity — how machines and modules reach one another + +**Purpose.** To make every machine and module reachable by name where it should be, and unreachable +where it should not. + +**Owns.** *private network* (clash 15); *resolver*; *uplink*; *hostname*; *zone*; *proxy* and *public +name*; *packet filter* (clash 16); *intrusion prevention* and *ban*; *reach* (how far an +assignment's endpoint may be reached from, ADR 0138); the roles a machine plays for the network (the anchor, a hub). + +**Relations.** Downstream of Placement (what runs where) and Identity (who may reach). Upstream of +Provisioning (an endpoint must be reachable) and of Health (an unreachable machine is a condition). + +**Against the seven contexts.** ADR 0006's *connectivity*, unchanged — and the one domain research 005 +found real in the catalogue's history, where its modules are the only ones that change together. + +The operator's guess called this *the network*, and it holds. + +### 10. Operator and conversation — the person the mesh works for + +**Purpose.** To let the mesh and its operator talk: tell, ask, answer, and act only on an answer it can +trust. + +**Owns.** *operator* (the person who runs the mesh; clash 17); *person* (any human, as against the mesh +acting unattended); *console* (the person's or agent's end of node tools, clash 5); *channel* and *intake* +benches; *router* and the `operator-channel` seat it holds; *responder*; *ask*, *authorising ask*, +*answer*; *operator message* and *untrusted input*; *reference*; *notification* on a desktop. + +**Relations.** Downstream of Health (conditions become messages), Change and delivery (a held delivery +waits for a person's word) and Identity (proofs, the operator's identities). An authorising answer acts in +whichever domain asked, through that domain's own verb; the conversation owns the asking, never the act. + +**Against the seven contexts.** None. ADR 0006 named `api`, *"the one interface every surface speaks +to"*, as an interface rather than a context; the console and the conversation are what it became. + +The operator's guess called this *people, conversation and approvals*. It holds, with one adjustment: +an **approval** is not this domain's concept. The approval of a merge is Change and delivery's (a human +approves the pull request); the release of a held delivery is `mesh-delivery`'s verb; the conversation +carries both as asks. *Approval* is in five decision records; *ask* in 58. + +### 11. The record — how this repository works + +Not a domain of the mesh but of the company's way of building it, and listed because its words collide +with the mesh's. **Owns** *research effort*, *decision record* (and *supersede*, *progressive insight*), +*design* (*as-is*, *to-be*), *issue*, *playbook*, *check* (one of `00-META/checks/`), *graduation*, +*hand-off*. Its *record* and *check* collide with the mesh's (clashes 11 and 12). + +## The operator's guess, scored + +| Guess | Verdict | +|---|---| +| building and delivering changes | **holds** as *Change and delivery* | +| running modules on machines (seats, benches, claims) | **holds** as *Placement*, with *claim* moved to Module | +| health and alerts | **holds, renamed** *Health and repair*: the mesh's word is condition, and half the domain is repair | +| data and backups | **holds** as *Data* | +| people, conversation and approvals | **holds** as *Operator and conversation*, with *approval* owned by the domain whose act is approved | +| the network | **holds** as *Connectivity* (ADR 0006's word) | +| — | **added**: *Module* (the published language), *Core* (what the rest runs on), *Provisioning* (ADR 0006 had it), *Identity and access* (ADR 0006 had it) | + +## A map + +``` + Module (published language) + | + Core + | + +--------------------------+---------------------------+ + | | | + Identity -------------> Placement | + | / | \ | + | / | \ | + v v v v | + Provisioning <------- Connectivity Data | + | | | + +-------------> Health and repair <------------------+ + | | + v v + Change and delivery Operator and conversation + | ^ + +-------------------+ + (a held delivery waits for a person's word) +``` + +Arrows point downstream. Change and delivery appears low because it reads health and data; in time it +runs first, and asks Placement to send. + +## What this split does not decide + +- **Module ownership.** A module may serve several domains (the controller serves five). The domains + are a partition of words and records, not of the catalogue — research 005 already found that grouping + modules into folders records nothing. +- **Whether every domain gets a context with its own store.** ADR 0008's rule applies where a domain's + records live in the controller; *Change and delivery* has moved its records to a module instead, and + that is equally sound. +- **The operator's machine.** The desktop seats (display session, launcher, clipboard, notifier) are + Placement's seats like any other, and their words are each program's own. Research 018 and 026 did not + introduce a vocabulary that needs a domain. diff --git a/01-RESEARCH/034-the-mesh-in-domains/03-the-clashes.md b/01-RESEARCH/034-the-mesh-in-domains/03-the-clashes.md new file mode 100644 index 00000000..e3d8c177 --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/03-the-clashes.md @@ -0,0 +1,306 @@ +# 03 — The clashes + +Twenty places where the mesh's words disagree with each other. A **synonym clash** is two or more words +for one concept; a **homonym clash** is one word for two or more concepts. Each entry gives the evidence +— which documents and which tool descriptions say what — and a proposed single word, with the domain +([02](02-the-domains.md)) that would own it. Counts are files containing the word, as in +[01](01-the-concepts-in-use.md), unless they say *occurrences*. + +The first five are ordered by cost: how often the clash appears where somebody is told what to do (a +to-be design, `00-META`, a tool description), and how likely it is to make a reader act on the wrong +thing. The other fifteen follow by domain. + +A decision record keeps the words it was written with (its immutability rule), so a retired word found in +a decision record is not a fault and is not counted as drift below unless the record was written after +the word was retired. + +## The five that cost most + +### 1. *machine* and *node* — one concept, two words (synonym) + +**Evidence.** + +- The glossary defines **node**: *"a machine in the mesh"*, and has no entry for *machine*. +- In the decisions and designs of the last week (ADRs 0220 to 0240, to-be 45 to 48), *machine* occurs 706 + times and *node* 349 times. Before ADR 0150, 6 record titles say *machine* and 9 say *node*; from ADR 0150 + on, 17 and 17. +- In the tool descriptions, *machine* is in 39 tools of 25 modules; *node* in 27 tools of 5 modules, 21 of + them one module's (the agent's configuration, where *node* is also a scope's value). +- The console's own tools are `mesh_machine` and an overview that lists *"machines"*. The controller's verb + is `nodes` and answers *"Every **machine** the mesh knows"*; `node` answers *"What one machine + reported"*. Every seat a machine holds is named `node-…`. +- The glossary itself switches inside one entry: *control-node* is *"the one node that also holds…"*, and + the next sentence says it *"is not a separate kind of machine"*. + +**Proposed word: _machine_** (Placement). It is what the operator, the tools and the newest records already +say, and it needs no explaining. *Node* survives only as an **identifier**: the value of a scope +(`scope: node`), the `node-` prefix of seat names, and *control-node* until it is renamed. The glossary +would map the identifier to the word, as it does for `mesh-host` today. The alternative — *node* everywhere — +is defensible and cheaper in code, and is what the glossary says; it is listed in +[00](00-overview.md) as the operator's call because either choice renames something heavily used. + +### 2. *node-engine*, *mesh-host*, *the host*, *node host*, *host agent* — one program (synonym) + +**Evidence.** + +- The glossary retired *host agent*, *the host* and `mesh-host` for **node-engine** on 2026-10-05, keeping + `mesh-host` as the name of the repository, binary and service unit until they are renamed. +- Its own node tools entry still says *"a host-side process **the host** supervises"*. +- To-be 05 is titled *the node host*; *the host* is in 34 to-be designs and *node-engine* in 7. +- Of the decision records written since the retirement, ADR 0222 says *the host* six times, ADR 0236 six + times beside *node-engine* nine times, and ADR 0223 three of each. +- Tool descriptions: `/node-service-manager.start` and `.stop`, and the container module's + `start` and `stop`, say *"the answer says **the host** will restore …"*. The bus server's `connections` + tool says *"a machine's **host** `node.`"* — naming the program *host* and its bus account + *node*. +- *Host* also keeps its ordinary meanings: a network host (the ssh client module's tools), *hosting* a + service, and the *host's* network in a container runtime. + +**Proposed word: _node-engine_** (Core), as the glossary already says; *the host* and *host agent* retired +for the program. Because *host* also has ordinary networking meanings, the check in +[04](04-how-the-glossary-is-checked.md) can retire only the phrases *the host* and *host agent* and the +identifier `mesh-host` outside code spans, not the bare word. If clash 1 is decided for *machine*, the +program's name reads more naturally as **machine engine**; this effort does not propose renaming it again. + +### 3. *plan* — four things (homonym), and *change plan* / *release plan* / *delivery plan* (synonyms) + +**Evidence.** On one seat, the controller's: + +- `mesh-controller.plan` — *"What one machine would run, and why: the declaration the mesh would send it"*. + A **machine's declaration**, previewed. +- `mesh-controller.plans` — *"What the last merges produced and where each stands (ADR 0162): the + tiers"*. ADR 0162 calls it *a tiered plan*; ADR 0218 and ADR 0236 call it the **release plan** (seven + times in ADR 0236: *"Every release plan's first machine passes a gate"*). +- `mesh-controller.delivery-plan` — *"The delivery plan of a diffset"*. The glossary: *"ADR 0238 called it the + **change plan**; that word is retired"* — and the walk replaces the release plan: *"the controller's + plan is now the walk of one delivery's trunk commit across machines"*. +- `mesh-controller.bus` — *"The bus as a **planned step**"*. + +*Release plan* appears in seven files created on or after 2026-10-06, the day ADR 0239 replaced it; *change +plan* in four, including the title of ADR 0238. + +**Proposed words** (Change and delivery, except the first): + +| Concept | Word | Retire | +|---|---|---| +| what the controller would send one machine | **declaration** (Placement); the verb `plan` becomes `declaration` or `preview` | *plan* for this | +| what a delivery would do to the mesh | **delivery plan** | *change plan*, *release plan* | +| the controller's sending of one commit's builds across machines | **walk** | *release plan*, *plan* for this | +| a step a person starts | **planned step**, or simply *step* | — | + +Bare *plan* is then never a mesh concept on its own. + +### 4. *push*, *send*, *roll out*, *release*, *deploy*, *upgrade* — moving a change (synonyms and homonyms) + +**Evidence.** + +- **push.** `mesh-controller.push`: *"Send one machine everything it should be. With no machine named it + is a push of the WHOLE mesh"*. ADR 0221's title: *"a push sends no build a policy or a plan holds + back"*. The same word is a git push (which, per the conventions, starts the build) and a phone + notification (*"Matrix once its push is measured"*, to-be 46). *Push* is in 84 decision records and + 152 issues. +- **send.** ADR 0236: *"that machine is sent it, by the ordinary send"*; the gate is judged *"from the + moment it was sent the build"*. The controller's own description of `push` uses *send*. +- **roll out.** ADR 0236's title says *rolls out unattended*; its person-facing verb is `upgrade + roll-out`, and the manifest's policy for the same thing is spelt `roll`. ADR 0218: *"code rolls out one + machine first"*. *Roll out* is in 30 decision records and 36 issues. +- **release.** `mesh-delivery.release` — *"A person's word that a held delivery goes on"*; + `anthropic-licence-manager.release` — *"Unbind a consumer"*; and the retired *release plan* (clash 3). +- **deploy.** The glossary: a delivery is *"not 'deployment' (one stage of it)"*; its *delivery plan* holds + a *deploy plan*. The controller has no verb named deploy, and the only tool that says *deploy* is a + wrapped flow editor's. +- **upgrade.** `mesh-controller.upgrade` — *"How each module's new builds reach its machines … rolled out + one machine first"*: a **policy**, not an act. + +**Proposed words:** + +| Concept | Word | Domain | +|---|---|---| +| the controller giving one machine its declaration | **send** (the verb `push` asks for one) | Placement | +| one commit travelling to every machine | **delivery** | Change and delivery | +| the per-machine part of a delivery plan | **deploy plan** (kept; the only use of *deploy*) | Change and delivery | +| a build going to its first machine, judged, then the rest | **walk** (the act); **roll** (the policy, one spelling in the manifest and in the verb) | Change and delivery | +| a person letting a held delivery go on | **release** — this sense only | Change and delivery | +| unbinding a licence's consumer | **unbind** (rename the licence verb) | Identity | +| how a module's builds reach its machines | **upgrade policy** | Module | + +*Push* is kept for the controller's verb because it names what the operator does, but prose says *send*; +*roll out* becomes the policy's value `roll` and is not a noun. + +### 5. *console*, *node tools*, *mesh-console*, *the MCP server* — the operator's surface (synonym and homonym) + +**Evidence.** + +- The glossary's surfaces section: the console is *"the module (`mesh-console`)"*; not *"the tool bridge", + "the brain" or "the MCP server"*. +- The glossary's operator's machine section: node tools *"replaces 'console' as the module's name; + console remains the word for the person's end of it"*. Both entries are current. +- The live console introduces itself as *"The tools of a Novox mesh, reached as `.node-tools`"*, + under an MCP server named `mesh`; the organisation's instructions to the agent call that server *"the + console"*. +- *Console* is in 28 decision records; `mesh-console` in 1; *node tools* in 10. A wrapped chat program's + tool and the localisation module's tool use *console* in their own senses (a virtual terminal, a web + console). + +**Proposed words:** **node tools** (Core) for the runtime that serves every module's tools and every seat's +verbs on a machine; **console** (Operator and conversation) for the end of it a person or agent uses — the +MCP endpoint and its five tools. `mesh-console` retired. The glossary's surfaces entry is rewritten at +graduation; the contradiction is removed, not annotated. + +## Change and delivery + +### 6. *gate* — three things (homonym) + +ADR 0136 (*a step gates its module, not the machine*): a failing step of a module's apply stops that +module's later steps. ADR 0236: the **gate** on a delivery's first machine — *"healthy three times"*. +ADR 0237 and ADR 0238: the **merge gate**, a status a pull request carries (`mesh/merge-gate`). The +controller's description of `upgrade` says *"judged there at the gate"*; a wrapped forge's tools say +*branch protection*. **Proposed:** *first-machine gate* for ADR 0236's, *merge gate* for the status, and +ADR 0136's becomes *a failed step holds its module* (no noun). Bare *the gate* is not used. + +### 7. *ask* — the operator's question, and an entry in the build queue (homonym) + +The glossary: *"**ask** — a request for the operator's input, of a declared kind"* (ADR 0234). +`mesh-controller.queue`: *"Every **ask** in the build queue: waiting, in flight … and dead"*; +`.cancel`: *"Drop one waiting or dead ask"*; `.clear`: *"Cancel every waiting ask"*. ADR 0234's ask is in +58 decision records' worth of prose shared with the ordinary verb *to ask*. **Proposed:** *ask* stays the +operator's (Operator and conversation); an entry in the build queue is a **build request** (Change and +delivery), and the three verbs' descriptions say so. + +### 8. *tier* — three things (homonym) + +The `topic: the tiers` of 36 decision records, and `repos.md`'s *Tier 0 … 3*: the **layers** of the mesh +(node-engine, foundation, controller, surfaces). ADR 0162 and to-be 47: the **steps of a walk**, a module +and the modules built against it (*"its builds are asked and registered tier by tier"*). To-be 46: the +**levels of authority** of an ask (*"a kind below the tier"*, *"no P2 tier before recovery codes"*). +**Proposed:** *layer* for the first (Core); *tier* for the walk's steps (Change and delivery), which is how +the tools use it; *assurance level* for the third (Identity and access). + +### 9. *declaration* — what a manifest states, and what the controller sends (homonym) + +The glossary: the node-engine *"receives the node's **declaration**"* — the controller's per-machine +document. The glossary again: a module *"**declares** resources"*, and *depends on a seat* is *"derived from +the resources it declares"* — the manifest. `mesh-controller.plan` returns *"the declaration the mesh would +send"*; the container and service-manager tools say *"what its declaration says"*. *Declaration* is in 106 +decision records, in both senses. **Proposed:** a manifest **declares** (Module; the noun is *the +manifest*), and what the controller sends one machine is that machine's **declaration** (Placement). The +verb and the noun then never name the same thing, and *declaration* is not used for a manifest. + +### 10. *control plane* and *controller* (synonym, drift) + +Retired by the glossary on 2026-09-16. Since then: 29 occurrences in 12 to-be designs (`05`, `07`, `08`, +`18`, `19`, `26`, `28`, `29`, `30`, `32`, `33`, `01`) and one as-is design; 73 files created after the +retirement use it — 36 issue reports, 29 decision records, 6 designs — among them issue 156, titled *moving a consumer's delivery subject +stops the control plane*. ADR 0006, the record the word came from, still has it in its +title. **Proposed:** *controller* (Core), as decided; the to-be designs are corrected at graduation, which +is a link-and-word fix the README's rules allow. + +## The record and its checks + +### 11. *record* — four things (homonym) + +A **decision record** (this repository). **The record** of the mesh — the `records` module that agents +search first (*"search the record with the literal text"*), and ADR 0006's *"where the record lives is +deliberately open"*. An **upgrade policy** value: `record` means *register the build, send it nowhere* +(ADR 0236). **On record**: a seat holder the controller has written down (ADR 0223's *"each on record"*). +**Proposed:** *decision record* always qualified in hq; *the record* for the mesh's knowledge base (Operator +and conversation, or a domain of its own if the records module grows one); the policy value renamed +**hold** — which is also what *held* means for a delivery — and *on record* left as ordinary English. + +### 12. *check* — at least six things (homonym) + +The checks in `00-META/checks/`; a pull request's **merge check**, made of the **merge gate** and the +**repository check** (`mesh/repo-check`, ADR 0238); a delivery group's **composed check** +(`mesh-controller.delivery-check`); the state `checked` of a delivery; the **self-check** (clash 13); a +module's tool named `…_check` (the ssh client's). *Check* is in 92 decision records. **Proposed:** never +bare in a governing document; always one of *merge check*, *repository check*, *composed check*, +*self-check*, *hq check*. The word is too ordinary to retire, so this one is a writing rule, not a list +entry ([04](04-how-the-glossary-is-checked.md) says why it cannot be checked mechanically). + +## Health and repair + +### 13. *self-check* and *doctor* (synonym) + +To-be 45 names the concept **self-check** (8 occurrences) and the verb `doctor` (14); the verb's own +description begins *"The self-check (to-be 45 §4)"*. **Proposed:** *self-check* (Health and repair); the +verb renamed `self-check`, or kept as `doctor` with the glossary mapping it — a verb name is an identifier. + +### 14. *condition*, *alert*, *problem*, *incident*, *finding* (synonyms) + +The controller's verb `conditions`: *"What is wrong with the mesh now: every open condition"*; to-be 45 says +*condition* 72 times. ADR 0006's observability context owns *"health, logs, metrics, **alerts**"*. ADR +0224's title: *"a provider that keeps failing a consumer is a **problem** the controller reports"*. The +container module's tool is `docker_problems`. *Incident* is in 14 decision records, mostly as *the incident +that earned a rule*. *Finding* is in 19, as what a check or a probe found. **Proposed:** *condition* +(Health and repair) for an open fact about something wrong; *finding* for what one probe or check returned +before it becomes a condition; *incident* kept for a past event that taught a rule (The record); *alert* and +*problem* retired for the mesh's own notion. A wrapped dashboard's *alerts* are its own. + +## Connectivity + +### 15. *private network* and *overlay* (synonym) + +The operator, quoted in ADR 0226 (2026-10-06): *"we simply have a private network"*; ADR 0226's title and +the `mesh-wireguard` module's role: *the private network*, in 37 decision records. To-be 08 (connectivity) +says *overlay* 24 times; *overlay* is in 30 decision records and 13 to-be designs. No tool says either. +**Proposed:** *private network* (Connectivity), the operator's word. + +### 16. *packet filter* and *firewall* (synonym) + +The seat every machine holds is `node-packet-filter`, with the verb `rules` (*"The packet filter as this +machine enforces it now"*). The nftables module's tool is `firewall_rules`. *Firewall* is in 33 decision +records and 13 to-be designs; *packet filter* in 22 and 12. **Proposed:** *packet filter* (Connectivity), +after the seat; the module's tool renamed `packet_filter_rules` or described in the seat's word. + +## Operator and conversation + +### 17. *operator*, *the user*, *person* (synonym, partly) + +The glossary's *operator account* entry: *"Not 'the user' (ambiguous with a module's own account)"*. *The +user* is in 10 to-be designs, several meaning a bus account (*"the user list"*, the bus server's word), and +in 9 decision records. *Operator* is in 125 decision records and the tools of 23 modules; *person* in 91 +records, meaning a human as against the mesh acting unattended (*"a person's word"*). **Proposed:** +*operator* for the person who runs the mesh; *person* for any human acting where the mesh could have; *the +user* retired in the mesh's own prose; a bus account is a *bus account* (Identity). A wrapped program's +*users* are its own. + +### 18. *agent* — three things (homonym) + +The glossary avoids *agent* for the node-engine because it *"already means two other things here, the build +agent and the operator's coding agent"*. The seat every machine holds is `node-build-agent`, held by the +`build-agent` module; ADR 0237 calls the role *the build seat*, ADR 0236 *the build machine* (14 decision +records). The licence manager's verbs say *"a node's **agent**"* for the coding agent a licence is bound to. +A wrapped memory server has *agents* of its own. **Proposed:** *agent* only for a coding agent (the +operator's, or one the mesh runs); the build role is the **build seat**, its holder on a machine the +**builder** — and the seat renamed when seats are next renamed. *Build machine* retired: any machine may +hold the seat. + +## Core + +### 19. *store* — four things (homonym) + +The glossary: **store** — *"the one postgres server"*. ADR 0189's title, *"The store keeps what the +records name"*, is about the **artifact store**. Research 015 is about the **object store**. ADR 0006: *"a +node reconciles from its own store"* — the machine's local copy of its declaration. **Proposed:** *store* +alone means only the foundation's database server (Core); the others are always *artifact store*, *object +store*, and the machine's *last declaration*. + +### 20. The glossary's own contradictions + +Recorded in [01](01-the-concepts-in-use.md) and listed here because the fix is the same kind: the console +(clash 5); the deprecated broker, which has no seat in its own entry and claims `mesh-broker` in the entry +for *claim*; and node tools described with the retired *the host*. **Proposed:** fixed at graduation, +in the same change that reorganises the glossary ([05](05-a-glossary-by-domain.md)). + +## Checked and found consistent + +Worth saying, so nobody repeats the search: + +- **catalogue / catalog.** Prose says *catalogue* everywhere (no bare *catalog* in any decision, design or + `00-META` file); *catalog* appears only inside identifiers (`mesh-catalog`, `catalog_modules`). That is an + identifier, not a clash. +- **foundation / substrate.** Of the 10 files created since *substrate* was retired that still use it, 9 + are decision records and research (allowed to keep their words); the tenth is the glossary, naming it + as retired. +- **flavor.** Retired; two to-be designs (08, 16) still say it, both predating the retirement. +- **operator** in the tools is used consistently for the person, in 28 tools of 23 modules. diff --git a/01-RESEARCH/034-the-mesh-in-domains/04-how-the-glossary-is-checked.md b/01-RESEARCH/034-the-mesh-in-domains/04-how-the-glossary-is-checked.md new file mode 100644 index 00000000..9da8bbd8 --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/04-how-the-glossary-is-checked.md @@ -0,0 +1,140 @@ +# 04 — How the glossary is checked + +[`AGENTS.md`](../../AGENTS.md): *"If a document states a rule about the mesh, it says how that rule is +verified. An unenforced rule is indistinguishable from a wrong one."* The glossary states two rules — *one +name per thing*, and *"a new name for an existing thing lands here first, in the same change that +introduces it in code"* — and nothing verifies either. [03](03-the-clashes.md) is what that costs. This +document describes a check; it does not build one. Building it follows graduation. + +## What a word list can and cannot catch + +A list of retired words catches **synonyms**: a word the glossary replaced, used again. It cannot catch +**homonyms** — *plan*, *gate*, *tier*, *ask*, *store*, *record*, *check* — because the word is right in one +sense and wrong in another, and telling them apart is reading, not matching. So the proposal has two +parts: a mechanical check for synonyms, and a rule for homonyms that turns each one, once decided, into a +synonym the list can hold (*release plan* → *walk*; *build machine* → *build seat*; `ask` in the build +queue's verbs → *build request*). A homonym left undecided stays a reviewer's job, and the glossary says +so next to the word. + +## Part 1 — the list, kept in the glossary + +The list of retired words lives **in the glossary, in one fixed form**, so there is one source and no +second file to drift from it. Every entry that retires words ends with one line: + +> *Not:* ~~control plane~~, ~~substrate~~ + +and nothing else in the glossary is struck through. Today the glossary marks retired words three ways +(struck through, *"Replaces x"*, *"Not x"*); graduation moves all of them to this line. + +Each struck word may carry a **scope**, in brackets after it, saying where it is retired: + +- *(hq)* — in this repository's governing documents only; +- *(tools)* — in the descriptions of the mesh's tools and seat verbs only; +- no scope — both. + +The scope exists because some words are wrong in one place and right in the other: *the user* is retired +in hq prose, but a wrapped identity provider's tool must say *user*. + +An entry may also carry an **identifier** line naming code that still has the old name, and the issue that +tracks its rename: + +> *Identifier until renamed:* `mesh-host` — the repository, binary and service unit (issue NNN) + +An identifier is allowed inside a code span (`` `mesh-host` ``) and nowhere else; when the issue resolves, +the line goes and so does the allowance. + +## Part 2 — `00-META/checks/words.py`, over this repository + +**Reads** the glossary's *Not:* lines and *Identifier* lines. **Scans** the documents that tell somebody +what to do — the same set `records.py` calls *governing*: `00-META/` (the glossary's own *Not:* lines +excluded), `03-DESIGN/01-to-be/`, `AGENTS.md` and `README.md` — plus `03-DESIGN/00-as-is/`, whose words +should be today's even where its facts are yesterday's. + +**Fails** on a retired word (of scope *hq* or none) in running prose. It **ignores**: + +- code spans and code blocks, which hold identifiers; +- block quotes and text in quotation marks, which quote somebody — the operator, a tool, an older + record — and must quote them faithfully; +- link targets, which are file names, and file names are immutable when they are a decision record's; +- `02-DECISIONS/` entirely, and `01-RESEARCH/` and `04-ISSUES/` written before the check's start date + — records keep their words, and research and issues observe. + +**For research and issues written after the start date** the check applies the same rule. An issue report +quoting a log or a tool keeps the quotation; its own prose uses today's words. This is a choice for +graduation, listed in [00](00-overview.md); the reason to include them is that issue reports are the +largest single source of drift found (36 of the 73 files that say *control plane* since its retirement). + +**The reverse rule.** A to-be design that defines a word in the glossary's form — a bolded word followed by +a dash at the start of a definition — must find that word as a head word in the glossary. This is how +*"a new name lands here first"* gets checked, and it would have caught *condition*, *healer* and +*data class* arriving in to-be 43 and 45 with no entry. + +**The uniqueness rule.** No head word appears in two entries, and no head word is also struck through in +another entry. This would have caught *release*: today a verb of `mesh-delivery`, and the retired *release +plan*. + +**What it would fail on today** — the check is proposed because these are real, and per +[`00-META/checks/README.md`](../../00-META/checks/README.md) a check must fail on something real before +it passes: + +| Retired word | Where, today | +|---|---| +| control plane | 29 occurrences in 12 to-be designs; one as-is design | +| the host (for the node-engine) | 34 to-be designs, and the glossary's own node tools entry | +| release plan, change plan | to-be 45, 47 | +| flavor | to-be 08, 16 | +| the user | 10 to-be designs (several are a bus account) | + +Each is either fixed at graduation or, where it is a quotation, put in quotation marks — which is the +check doing its job, making a quotation look like one. + +## Part 3 — the same list, over the catalogue's tool descriptions + +An agent meets the mesh's words most often in tool descriptions: 535 module tools and the verbs of 20 seats +today. Nothing compares them with the glossary, and four of them say *the host*. + +**Where it runs.** In the catalogue repository's own repository check (`mesh/repo-check`, ADR 0238), which +already reads every changed manifest. A changed manifest's tool descriptions and its seat's verb +descriptions are matched against the *Not:* words of scope *tools* or none. A finding fails the check, as +everything does on the mesh's repositories (a warning blocks a merge the same as a failure there, [issue +293](../../04-ISSUES/293-a-warning-on-a-required-check-blocked-the-merge/00-report.md), so a warning-only mode +is not available and is not proposed). + +**Where the list comes from.** The catalogue cannot read this repository at build time without a new +dependency. Two options, for graduation: + +1. **A copy, checked.** The catalogue keeps a copy of the list, and `words.py` here fails when the copy in + the catalogue's trunk differs from the glossary. Simple; two repositories change for one word, which is + honest about what a retired word costs. +2. **The list as an artifact.** This repository's merge publishes the list to the artifact store, and the + catalogue's check reads the newest. One source; one more thing that must be up for a catalogue merge. + +The first is recommended: it fails loudly in the right place, and adds no runtime dependency. + +**Vendor words.** A module wrapping a program describes that program's objects in its own words — an +identity provider's *users*, a media manager's *releases*, a flow editor's *deploy*. The list holds only +the mesh's own retired words, and a word that is also a common vendor word (*user*, *release*, *deploy*) +is never retired with scope *tools*. That keeps the check from crying wolf, which +`00-META/checks/README.md` names as the way a check gets suppressed. + +**On the running mesh, later.** The descriptions an agent actually sees are the ones served, which may lag +the catalogue's trunk. A probe in the self-check could compare the controller's `tools` verb with the same +list and raise a condition. That is a second place for the same rule and is not proposed until the first +has run. + +## Part 4 — homonyms, by rule + +For a word the glossary marks *homonym* (*plan*, *gate*, *tier*, *store*, *record*, *check*, *ask*, +*agent*), the entry lists each sense with its qualified form and its domain, and the writing rule is: **a +homonym is never bare in a governing document; it is always the qualified form.** This is not +machine-checked — a word list cannot tell *the gate* that means a first-machine gate from one that means +the merge gate — and the glossary says so next to the rule, as AGENTS.md requires: *"checked by review; +the reviewer looks for the bare word in the diff."* Where a homonym is resolved by renaming one sense, the +old sense moves to the *Not:* line and becomes mechanical. + +## What it costs + +- One Python file of the size of `cycle.py`, run by `merge-check.sh`. +- A one-time correction of the governing documents it fails on, made in the graduation change. +- A copy of the list in the catalogue, and a few lines in its repository check. +- One rule for writers: a retired word may be quoted, never used. diff --git a/01-RESEARCH/034-the-mesh-in-domains/05-a-glossary-by-domain.md b/01-RESEARCH/034-the-mesh-in-domains/05-a-glossary-by-domain.md new file mode 100644 index 00000000..3038917e --- /dev/null +++ b/01-RESEARCH/034-the-mesh-in-domains/05-a-glossary-by-domain.md @@ -0,0 +1,101 @@ +# 05 — A glossary by domain + +How [`00-META/glossary.md`](../../00-META/glossary.md) would be organised once the domains in +[02](02-the-domains.md) are decided. Described only: the glossary changes in the graduation change, with +the decision record that adopts the domains, and not before. + +## What is wrong with its shape today + +- **Its sections are a history, not a map.** *The operator's machine* holds node tools, bundle, kept region + and installed / holding because they arrived with research 018, not because they belong together; node + tools is a Core concept and kept region a Module one. +- **It has no home for a new word.** A writer adding *condition* would not know which section it goes in, + and so it went in none. +- **Retired words are marked three ways**, so no program can read them ([04](04-how-the-glossary-is-checked.md)). +- **It is one page for 33 entries**; with the roughly 50 words [01](01-the-concepts-in-use.md) found + missing, it is about 85, and one flat list of 85 is read by nobody. + +## The proposed shape + +One file, as now — it stays the single authority, and a reader searches one page. Its sections are the +domains, in the order of [02](02-the-domains.md) (most upstream first), preceded by two short sections. + +### 1. How to read this page + +What a domain is, in two sentences; that a word is defined once, in the domain that owns it; that other +domains may use it but not change it; and the forms of the *Not:* and *Identifier* lines the check reads. + +### 2. Words every domain uses + +A short **shared kernel** — the handful of words with one meaning everywhere, owned by no single domain +and changed only by a decision record: *mesh*, *machine* (or *node*, clash 1), *module*, *seat*, *operator*, +*person*. Each points to the domain where its detail lives. Kept deliberately short: a word that only one +domain refines belongs to that domain. + +### 3. One section per domain + +Each section opens with a fixed header, then its entries: + +- **Purpose** — one sentence, from [02](02-the-domains.md). +- **Owned by** — the context, module or seat that records its concepts (*the controller's `inventory` + context*; *the `mesh-delivery` module*; *every machine's `node-backup` seat*). +- **Upstream of / downstream of** — the domains, by name. +- **Decided by** — the decision records that define the domain's words, so a reader can go from a word + to why. + +Each **entry** keeps today's prose form and gains at most three fixed lines: + +- the definition, in plain sentences, with its record cited (as now); +- *Not:* ~~retired word~~, ~~another~~ *(scope)* — the words it replaced; +- *Identifier until renamed:* `old-name` — what code still carries the old name, and the issue that + tracks the rename. + +A word a domain uses but does not own is not repeated there; the domain's section may list it under *Uses* +with a link, so a reader of one section sees its whole vocabulary without the definition being copied. + +### 4. Homonyms + +One section at the end for the words that mean different things in different domains — *plan*, *gate*, +*tier*, *store*, *record*, *check*, *ask*, *agent*, *release*. For each, a small table: the sense, its +qualified form, the domain that owns it. This is the page a reader lands on from a search for a bare +word, and it says the rule beside the table: never bare in a governing document; checked by review. + +### 5. How this page is kept + +Today's section, extended: a new word lands here first, in the domain that owns it; a word moves domain +only with a decision record; a retired word goes on a *Not:* line and nowhere else; and `words.py` +checks the three rules it can ([04](04-how-the-glossary-is-checked.md)). + +## Where today's entries would go + +| Today's entry | Domain | +|---|---| +| node, control-node, operator account | shared kernel (machine); Placement (operator account); Core (control-node) | +| controller, mesh-controller, node-engine, foundation, store, bus, the deprecated broker | Core | +| package, artifact | Change and delivery | +| seat, depends on a seat, installed / holding | Placement | +| claim, provision (as declared), invokes, bundle, kept region | Module | +| provision (as resolved) | Provisioning | +| channel / intake, ask, operator message / input, reference, console | Operator and conversation | +| node tools | Core | +| delivery, delivery group, delivery plan, mesh-delivery, walk | Change and delivery | +| ~~master / slave~~, ~~hub / peer~~, ~~flavor~~ | *Not:* lines on *controller* and *setting* | + +And the sections that are empty today and would be filled from the records that already define their +words: **Identity and access** (credential, secret, vault, grant, bus account, licence, binding, proof — +ADRs 0143, 0183, 0225, 0234); **Health and repair** (condition, probe, signal, watchdog, self-check, healer, +drill, hand-act — to-be 45, ADRs 0227, 0231, 0240); **Data** (data class, backup, restore point, stream +snapshot — to-be 43, ADRs 0233, 0235); **Connectivity** (private network, resolver, uplink, packet +filter, reach — ADRs 0117, 0138, 0223, 0226). + +## What derives from it + +- **The decision index.** The records' `topic:` (*the mesh*, *the tiers*, *what runs on it*, *building + it*, *checking it*, *how we work*) predates the domains and partly overlaps them. Whether a record also + names its domain — a new frontmatter field, and so a schema change — is left for graduation. It would let + `words.py` scope a word by domain, and `index.py` print the reading order per domain. +- **The constitution page.** The mesh injects a page derived from `how-we-build.md` into design sessions + (playbook 05). A derived glossary page per domain could be injected the same way, so an agent starts + with the words; that is a separate decision, not proposed here. +- **Tool descriptions.** Once a domain owns a word, a module describing that concept in a tool uses it; the + check in [04](04-how-the-glossary-is-checked.md) holds them to the retired half, and review to the rest.