Glossary names no seat's holder: who holds a seat is read from the mesh #527

Merged
mesh-tools merged 1 commits from docs/glossary-no-holders into main 2026-11-08 23:21:14 +00:00
3 changed files with 120 additions and 34 deletions
+3 -1
View File
@@ -9,7 +9,8 @@ in memory. The Python files and `merge-check.sh` are gone (issue 1296).
records_test.go structure: links, no record written here, citations in the form "ADR NNNN"
index_test.go the reading order's topics are written, and no list of records is stored
cycle_test.go the development cycle: a design's layer, status, decisions and code; an issue report's frontmatter
words_test.go the glossary's retired words are not used, no daemon's line is written, and no word is defined twice
words_test.go the glossary's retired words are not used, no daemon's line is written, no word is defined twice,
and the glossary names no seat's holder
```
A failing test fails `go test`, so it can be a gate rather than a report. With `MESH_CATALOG_DIR` set, the words
@@ -31,6 +32,7 @@ indistinguishable from one that cannot.
| `decisions-form` | every entry of a design's `decisions:` is "ADR NNNN", four digits | written with issue 426; it failed on an entry `ADR 290` before it passed |
| `mention-form` | every "ADR N" in the text has four digits, and every "research N" three; a code span is an example and is not read | written with issue 426; it failed on `ADR 12` and `research 45` before it passed |
| *(index test)* | the reading order's six topics are written in `02-DECISIONS/README.md`, none twice, and the README stores no list of records (ADR 0248). The knowledge base reads these lines and refuses a record whose topic is not one of them | a stored list made every two open decisions conflict ([issue 297](../../04-ISSUES/297-two-open-decisions-always-conflict/00-report.md)); it failed on the README of `main` before the list was removed |
| `holders` | the glossary names no module as a seat's holder: no seat "held by" or "claimed by" a named module, no named module "holder of" a seat, no module that "holds the seat"; the holder is read from the mesh's assignments (the operator, 2026-11-09) | **twenty statements** in the glossary, from the registry seats' "held today by the forge module" to the knowledge base's holder |
| `status-vs-code` | a to-be document naming specific code is not still `designed` | **ten documents**, several with a *What was built* section, describing lab-proven code |
## Where the rules on records went
+76
View File
@@ -35,6 +35,9 @@ import (
// struck-through text, link targets, HTML comments and frontmatter are taken out. A word's plural is the word.
// unique no head word heads two entries, and none is also struck through on a *Not:* line.
// lines no daemon's line in a checked document (ADR 0272, its insight of 2026-10-09): the operator types `nox`.
// holders the glossary says no seat's holder: no seat "held by" or "claimed by" a named module, no named module
// "holder of" a seat, no module that "holds the seat" (the operator, 2026-11-09). Who holds a seat is read
// from the mesh's assignments, and the glossary's head says where.
// copy with MESH_CATALOG_DIR set to a checkout of the catalog, its copies of the retired words and the
// daemons' lines equal this glossary's and this list (skipped, with its reason, when unset).
//
@@ -754,3 +757,76 @@ func mapOf(files map[string]string) fs.FS {
}
return m
}
// holders: the glossary defines a word and never says which module holds or claims a seat. Who holds a seat is a fact
// of the mesh's assignments, read with one call (the operator, 2026-11-09: "it shouldn't be in the glossary"), and a
// copy here drifts. Refused, across line breaks: a seat "held by" or "claimed by" anything but a generic holder or a
// seat ("held once for the mesh by `x`", "held today by the forge module"); a named module "holder of" a seat ("the
// module `x`, holder of"); a module that "holds the seat" ("it holds the seat", "the `x` module holds it"); and "its
// holder, the x". A word for the role ("the module that holds the seat `x`") names no module and passes.
var (
heldByRx = regexp.MustCompile("(?i)\\b(held|claimed)(\\s+once)?(\\s+for\\s+the\\s+mesh)?(\\s+today)?\\s+by\\s+")
// What may follow "held by": a holder in general, a seat, or the knowledge base (a seat's word) holding a record.
heldByGenericRx = regexp.MustCompile("^(a\\s+module\\b|some\\s+module\\b|its\\s+holder\\b|the\\s+holder\\b|the\\s+identity\\s+seat\\b|the\\s+knowledge\\s+base\\b|one\\s+author\\b|the\\s+`[^`]+`\\s+seat\\b|the\\s+(node\\s+)?seat\\s+`)")
holderNamedRx = []*regexp.Regexp{
regexp.MustCompile("(?i)(\\bmodule\\s+`?[a-z][a-z0-9-]*`?|`[a-z][a-z0-9-]*`)\\s*,\\s+(the\\s+)?holder\\s+of\\b"),
regexp.MustCompile("(?i)\\b(it|which)\\s+holds\\s+(the\\s+)?(node\\s+)?seats?\\b"),
regexp.MustCompile("(?i)\\bmodule\\s+holds\\s+(it|the\\s+(node\\s+)?seat)\\b"),
regexp.MustCompile("(?i)\\bholder\\s*,\\s+the\\s+[a-z`]"),
}
)
func checkHolders(text string) []string {
var out []string
say := func(i int, m string) {
out = append(out, fmt.Sprintf("%s:%d: %q names a seat's holder; the glossary says where it is read instead", glossaryFile, lineOf(text, i), strings.Join(strings.Fields(m), " ")))
}
for _, loc := range heldByRx.FindAllStringIndex(text, -1) {
rest := text[loc[1]:]
if heldByGenericRx.MatchString(rest) {
continue
}
end := loc[1] + min(len(rest), 30)
say(loc[0], text[loc[0]:end])
}
for _, rx := range holderNamedRx {
for _, loc := range rx.FindAllStringIndex(text, -1) {
say(loc[0], text[loc[0]:loc[1]])
}
}
return out
}
func TestWordsGlossaryNamesNoSeatHolder(t *testing.T) {
expectNone(t, checkHolders(readFile(rootFS(), glossaryFile)))
}
func TestHoldersRefusesANamedHolderAndPassesARole(t *testing.T) {
for _, bad := range []string{
"- **x** — the seat `x`, held once for the mesh by the module `mesh-x`.",
"- **x** — the seat `x`, held\n by `mesh-x`.",
"- **x** — `go-package-registry` (held today by the forge module).",
"- **x** — the seat `x`, claimed by mesh-x.",
"- **x** — the module mesh-x, holder of the seat `x`.",
"- **x** — the module `mesh-x`, holder of `x`.",
"- **mesh-x** — the module that does x: it holds the seat `mesh-x` once.",
"- **bus** — The `nats` module holds it.",
"- **x** — written by its holder, the assigner.",
} {
if len(checkHolders(bad)) == 0 {
t.Errorf("not refused: %q", bad)
}
}
for _, good := range []string{
"- **seat** — a named role, held by a module assignment.",
"- **router** — the module that holds the `operator-channel` seat.",
"- **bus** — Held by the `mesh-broker` seat.",
"- **x** — the seat `x`; its holder is read with `mesh-module-assigner.assignments`.",
"- **depends on a seat** — a seat held on its node by some module.",
} {
if got := checkHolders(good); len(got) != 0 {
t.Errorf("refused a role: %v", got)
}
}
}
+41 -33
View File
@@ -22,6 +22,13 @@ Two fixed lines follow an entry where they apply, and the words test in `00-META
- *Identifier until renamed:* followed by a name in a code span — code that still carries an old name.
It may stand in a code span and nowhere else until the code is renamed, and then the line goes.
**No entry says which module holds a seat.** Which module holds or claims a seat, and on which node, is a fact of
the mesh's assignments, read with one call: `mesh-module-assigner.assignments` with `seats: true` (and `node` for
one machine), which today answers the seats held once for the mesh (the operator, 2026-11-09: "it shouldn't be in
the glossary"). An entry defines the seat; a word for a module defines the module and says no seat it holds. The
words test refuses a seat "held by" or "claimed by" a named module, a named module "holder of" a seat, and a module
that "holds the seat".
Nothing else on this page is struck through. A word that means different things in different domains
is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
@@ -52,8 +59,8 @@ is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
- **seat** — a named role at a scope (node / site / mesh), held by a module assignment, from a **closed
set** the mesh defines: a claim naming a seat outside the set is refused. A seat may **deliver a
provision**, and its holder is then the mesh's answer for it when several modules provide it
(ADR 0126). The set, with who holds each
seat, is the overview of what a mesh has ([26 — The seats](../03-DESIGN/01-to-be/26-the-seats.md)).
(ADR 0126). The set is the overview of what a mesh has ([26 — The seats](../03-DESIGN/01-to-be/26-the-seats.md));
who holds each seat is read from the mesh, as this page's head says.
A seat carries **verbs** — the tools every holder must serve. A verb added to a held seat is first
promised as optional, then served, then required (ADR 0246).
A node seat may also name **the paths its holder owns**, such as `/etc/hosts`: a claim whose module does
@@ -150,8 +157,8 @@ and repair).
- **upgrade policy** — how a module's new builds reach its nodes: `roll` (one node first, judged, then
the rest), `together`, or `record` (register the build, send it nowhere)
(ADR 0236).
The controller's verb `upgrade` shows it until the lease write; from L5's delivery the seat `mesh-wants`,
held once by the assigner, answers it too, as `mesh-wants.upgrade`; a person's choice is kept by the assigner, and the bus is never rolled (ADR 0565 §7).
The controller's verb `upgrade` shows it until the lease write; from L5's delivery the seat `mesh-wants`
answers it too, as `mesh-wants.upgrade`; a person's choice is kept in that seat's state, and the bus is never rolled (ADR 0565 §7).
## Config — the values someone may change
@@ -211,7 +218,7 @@ downstream of Module and Placement. **Decided by** ADR 0262, 0277, 0348.
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
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).
@@ -266,8 +273,7 @@ every other domain has something to run on. **Recorded by** the controller and t
control, declarations, builds, events, tool calls (ADR 0106).
A module reaches it by requiring `mesh-bus` (ADR 0128);
one that does not require it has no account on it. Held by the `mesh-broker` seat, which is named
after the role rather than the server, so the server can change without the seat doing so. The `nats`
module holds it. The **bus module** is the module holding `mesh-broker`; it also provides bus state (Data,
after the role rather than the server, so the server can change without the seat doing so. The **bus module** is the module holding `mesh-broker`; it also provides bus state (Data,
ADR 0595).
- **the deprecated broker** — the lavinmq module. It was the mesh's bus and is not any more. It keeps
running as an **ordinary provider** of the `amqp` provision, for modules that need a message broker
@@ -314,18 +320,19 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
a placement proposal the operator approves, and no repository holds it or names a node (ADR 0567). Until ADR
0547's third milestone the controller's assignments are kept equal to it by the holder.
*Not:* ~~placement file~~ (hq)
- **mesh-module-assigner** — the seat, held once for the mesh by the assigner, that keeps placement: its states
- **mesh-module-assigner** — the seat, held once for the mesh, that keeps placement: its states
`placement`, `proposals` and `candidates`, and its seven verbs `placement`, `proposals`, `propose`, `withdraw`,
`again`, `adopt` and `hand-back`. Only the holder writes its states (ADR 0567, renamed by ADR 0634 §9). Its
contract is in `mesh-placement-contracts` (ADR 0634 §7).
*Not:* ~~mesh-placement~~
- **mesh-wants** — the seat, held once for the mesh by the assigner, that keeps what each node should run, one want
- **mesh-wants** — the seat, held once for the mesh, that keeps what each node should run, one want
per node and module (`want.<node>.<module>`), and a person's upgrade policy, served as its verb `upgrade`
(ADR 0565 §7, ADR 0571 §8). Its contract is in `mesh-placement-contracts` (ADR 0634 §6, §7).
- **seat holders** — the state `seat-holders` of the seat `mesh-module-assigner`, written by its holder, the assigner: one
- **seat holders** — the state `seat-holders` of the seat `mesh-module-assigner`, written by its holder: one
key per seat naming each holder and its node, composed from placement and the manifests' claims as the indexer
holds them, and rewritten only when a key differs. The tool runner and every other reader of who holds a seat
read it there, never the controller (ADR 0571 §6, §7).
read it there, never the controller (ADR 0571 §6, §7); a person or a session reads it with
`mesh-module-assigner.assignments` and `seats: true`.
- **placement proposal** — a change to placement put forward through the verb `propose`: the changes, the revision
of each key they were laid over, the nodes' answers, the verdict and the ask. It takes effect only on the operator's
Approve, and is discarded if declined, expired or withdrawn. A kind of *proposal* (Operator and conversation).
@@ -432,10 +439,10 @@ 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).
- **mesh-provisioner** — the module that places provisions on the nodes, 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;
its part on each node is its provisioner client (ADR 0349). The role's seats are `mesh-provisioner`, held once for
the mesh, and the node seat `node-provisioner`; who holds them is read as this page's head says.
- **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,
@@ -469,10 +476,10 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
file at apply (ADR 0085).
- **secret service** — a node's store of a person's secrets that the programs of a desktop session ask, the node seat
`node-secret-service`, of this domain.
- **mesh-node-enroller** — the seat, held once for the mesh by the module `mesh-enrolment`, through which a new
- **mesh-node-enroller** — the seat, held once for the mesh, through which a new
machine joins: a one-time token issued on the operator's Approve, redeemed once by the machine's node-engine, the
node's account minted and signed by the vault (ADR 0587 §1, renamed by ADR 0634 §9). The module keeps its name;
only the seat's changed. Its contract is in `mesh-identity-and-access-contracts` (ADR 0634 §7).
node's account minted and signed by the vault (ADR 0587 §1, renamed by ADR 0634 §9). Only the seat's name
changed; no module was renamed with it. Its contract is in `mesh-identity-and-access-contracts` (ADR 0634 §7).
- **secret family** — a module's own secrets declared as one name ending in `-*`; each member is the prefix
and a name (`smb-password-<source>`, one per source the module's config values name), given by its full name
and never made by the mesh
@@ -609,7 +616,8 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
- **build capacity** — how many build requests a node's build modules hold at once: a setting of the node that the
build modules read, and 0 pulls nothing (ADR 0525 §5). Not a seat's capacity (**capacity**, Module).
- **build module** — the module of one language that does the build steps for it on a node (fetch, build, digest,
test), claiming that language's build seat: `mesh-build-go`, `mesh-build-node` and `mesh-build-image`. It pulls the
test), claiming that language's build seat; which build modules claim which build seat, on which node, is read from the
mesh's assignments (this page's head). It pulls the
build requests of its language and writes each step's end on its own key (ADR 0525 §3, §6). Not the **builder**.
- **build log** — the builder's own module log `build-log`, in ADR 0297's form, kept 30 days and keyed per
module: one entry when a build of a fingerprint starts and one when it ends (the module, the fingerprint, the
@@ -623,8 +631,8 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
asks a registry seat to store one.
- **registry seat** — a seat held once for the mesh whose holder stores what build modules publish, under the
version the builder gave, and serves its toolchain's read side: `npm-package-registry` and
`go-package-registry` (the **package-registry**, held today by the forge module), `container-image-registry`
and `oci-artifact-registry` (held today by the `distribution` module). One contract: `publish`, `versions`, a
`go-package-registry` (together the **package-registry**), `container-image-registry`
and `oci-artifact-registry`; who holds each is read as this page's head says. One contract: `publish`, `versions`, a
verb removing a tagged version, the events `published` and `removed` (ADR 0605 §1, §2). Not the forge.
*Not:* ~~docker-package-registry~~
- **next version** — the version the builder gives a trunk build of a published thing: its package series and one
@@ -643,7 +651,7 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
An image is one kind of artifact, and a module is not an image. A package and an artifact are two
protocols, not one store being weak (ADR 0075).
- **artifact sweep** — letting go of the artifacts no one needs any more, the seat `mesh-artifact-sweep`, held
once for the mesh by artifact-store-tools beside the artifact store (ADR 0571 clause 2, as its progressive
once for the mesh (ADR 0571 clause 2, as its progressive
insight of 2026-10-29 has it; clauses 3 and 4). Its keep set comes from the store's own listing, the wants and
the build log: a digest a want names is kept however old, and so are each module's five newest builds
(ADR 0526 §1). From the lease write it sweeps at each build's end and records each deletion in the hand-act
@@ -799,7 +807,7 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
judged (a witness, ADR 0236).
- **the lab**, **scenario**, **replay** — a real mesh raised to run a change against before it reaches
nodes; what a lab run declares; and a recorded failure run again to prove a fix (ADR 0016, ADR 0237).
- **git seat** — the seat `git`, held once for the mesh by the forge, delivering the provision `git`: the
- **git seat** — the seat `git`, held once for the mesh, delivering the provision `git`: the
repositories a build comes from ([26 — The seats](../03-DESIGN/01-to-be/26-the-seats.md) *The git seat*). A seat of
this domain.
@@ -828,7 +836,7 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564.
and the watchman reads (ADR 0564, as its progressive insight of 2026-10-29 has it); its layout is mesh-sdk's.
- **observer** — a part that writes findings for the condition keeper: the watchman, the self-check and the
healers (ADR 0564 §2). An observer never writes a condition.
- **condition keeper** — the module mesh-conditions, holder of the seat `mesh-conditions`: the one writer of the
- **condition keeper** — the holder of the seat `mesh-conditions`: the one writer of the
open conditions, raising each from an observer's finding and clearing it when the finding goes, and saying
`condition-raised`, `condition-changed` and `condition-cleared` (ADR 0564 §2, §3). The controller keeps them
until the take-over.
@@ -851,7 +859,7 @@ becomes a message). **Decided by** ADR 0227, 0231, 0240, 0252, 0283, 0564.
operator's decision (ADR 0259).
Not a drill: nothing is broken.
- **hand-act** — a repair a person made by hand, recorded so the mesh knows it happened. The **hand-act log**
is the module's log in ADR 0297's form, the stream `acts` of the seat `mesh-hand-acts`, held once by the module mesh-hand-acts, which also records
is the module's log in ADR 0297's form, the stream `acts` of the seat `mesh-hand-acts`, held once for the mesh, whose holder also records
who chose an ask (`warranted`); every recorder calls it, and the controller's own log is read beside it
until the lease write (ADR 0565 §10, §11).
- **take-over** — the operator's approved switch of a job from the controller to the part that replaces it, with a
@@ -924,7 +932,7 @@ it should not. **Recorded by** the controller. **Upstream of** Provisioning and
address and a mesh name (ADR 0226).
The network the machine sits on without it is the **underlay**.
*Not:* ~~overlay~~ (hq)
- **the-private-network** — the node seat of the private network, held by the module `mesh-wireguard`, whose
- **the-private-network** — the node seat of the private network, whose
provision is the value a module reads to reach the private network. Its contract, holding that value's layout and
no key material, is in `mesh-connectivity-contracts`, a folder module of the mesh-networking repository beside its
holder; it has a client only where its callers share logic, and the private network's manifest and peer generator
@@ -1067,8 +1075,8 @@ it was told, and the servarr apps' own libraries. **Upstream of** nothing. **Dec
- **download client** — a module that fetches a media release into the downloads folder and emits
`download.added` and `download.completed` naming the download's id, its category and the path of its
files: `nzbget`, `qbittorrent`, `youtube`.
- **engine** — a module that searches for media releases: the holder of `usenet-search` (`nzbgeek`,
ADR 0295) or of `youtube-search` (`youtube`, ADR 0296).
- **engine** — a module that searches for media releases: the holder of `usenet-search` (ADR 0295)
or of `youtube-search` (ADR 0296).
- **grab** — an engine handing one media release to a download client. It names the work it is for, so
the media-importer knows where the copy belongs.
@@ -1093,13 +1101,13 @@ and no session (ADR 0278), in its plain sense.
- **mail send** — a mail the mesh sends, which goes out only on the operator's warrant for that one mail (ADR 0361
§2), with the states `mail_send_status` answers (ADR 0440 §7). Any caller `mesh-mail`'s `grants` names for that
account may ask for one (ADR 0472).
- **mail web client** — the module `mesh-mail-web`, holder of `mail-webclient`: the operator's mail in a browser on
- **mail web client** — the module `mesh-mail-web`: the operator's mail in a browser on
the private network (ADR 0440 §1). The page it serves is the mail page.
- **mail notice** — `mesh-mail-notifier`'s desktop pop-up for a new inbox mail (ADR 0378 §7, §9). It retires when
`mesh-mail-notifier` is unassigned everywhere (ADR 0461 §7) and then moves to *mail signal*'s *Not:* line
(issue 1418).
- **mail reading** — the model's reading of each new mail as it arrives, in batches, into its mail group and mail
entry; the seat `mail-reading`, held by `mesh-mail-reader` (ADR 0459). Not *triage* (the issue tracker's
entry; the seat `mail-reading` (ADR 0459). Not *triage* (the issue tracker's
judgement), and not `mail_read`, `mail-store`'s tool that fetches one mail's text.
- **mail entry** — what mail reading keeps about one mail: its mail group, a one-line summary, its mark and why, a
due date; never the body (ADR 0459 §4). Not *catalog entry*: the catalog is Delivery's.
@@ -1164,7 +1172,7 @@ Not a domain of the mesh but of the way it is built, listed because its words me
- **knowledge base** — what holds the decision records and research efforts whole (number, status, topic,
typed links, clauses and reasoning, with every version), and, once they are moved, the designs and the glossary
entries too (ADR 0423); takes them as proposals, has them reviewed and accepted,
and answers what holds: the seat `knowledge-base`, held by the module `mesh-knowledge`
and answers what holds: the seat `knowledge-base`
([55 — The knowledge base](../03-DESIGN/01-to-be/55-the-knowledge-base.md)). Not **the record**, the literal reader
of this repository. It keeps them on the bus: each record's head in its state, its versions on a stream, its
sections' bodies once each in an object bucket by digest (ADR 0592).
@@ -1210,8 +1218,8 @@ Not a domain of the mesh but of the way it is built, listed because its words me
holds it whole: its report, diagnosis and resolution included (ADR 0291);
the folders in `04-ISSUES/` are imported there and removed.
An **incident** is a past event that taught a rule.
- **issue tracker** — what holds the mesh's issues and hands out their numbers: the seat `issue-tracker`,
held by the module `mesh-issues` ([53 — The issue tracker](../03-DESIGN/01-to-be/53-the-issue-tracker.md)).
- **issue tracker** — what holds the mesh's issues and hands out their numbers: the seat `issue-tracker`
([53 — The issue tracker](../03-DESIGN/01-to-be/53-the-issue-tracker.md)).
Not hits's *item*; bare *ticket* is a homonym (see [Homonyms](#homonyms)).
*Not:* ~~ticketing system~~ (hq), ~~ticket system~~ (hq)
- **duplicate check** — the issue tracker's judgement, when an issue is opened, of whether it asks a question an