One feature across three repositories, one PR each: this one, novox/mesh-controller and novox/mesh-catalog, all on feat/seats-are-a-closed-set.
The decisions
ADR 0110 — a seat is a module assignment from a closed set, and it may deliver a provision.
The mesh defines which seats exist: name, scope, what occupying it delivers, and the record that made it one. A claim outside the set is refused.
A seat is held by a module assignment. What the mesh knows about a holder is what it knows about that assignment, and nothing about holders is stored beside it.
A seat may deliver a provision. Among several providers, resolution takes a pin, then the seat's holder, then the only provider, and otherwise refuses. ADR 0009's "never guessed" still holds: the seat is the choice made once, mesh-wide, instead of a pin per consumer node.
Seats are informational: every seat, what it delivers, and who holds it, including unheld ones.
The first set is every seat already claimed plus npm-package-registry, so nothing in use is refused.
ADR 0111 — a build source is on the mesh's git seat, or it is external.
There is a git seat, and gitea holds it.
build --self <owner>/<repo> records the repository's path and the seat, and composes the clone URL from the holder at build time. Nothing recorded contains an address.
build <url> is unchanged. GitHub and GitLab are the ordinary external cases.
Private-repository credentials are not decided, and the record says so.
Design
New to-be 26 — the seats.
23 gains the seat step in resolution.
18's source entry names the two forms.
The glossary's seat and provision entries say where the two meet.
Also carried
ADR 0109 is carried from decision/0108-package-registry-seat-per-ecosystem, authorship intact, so every link here resolves.
The decision index was regenerated rather than hand-merged.
Corrected while preparing
The hand enumeration behind the first set missed two sources: the controller's own manifest, and a claim composed in the controller's code (the private-network module's the-private-network). 0110 admits it, and it records the miss as part of its evidence, because the miss is itself the argument for an overview.
cycle.py, records.py and index.py all pass.
One feature across three repositories, one PR each: this one, **novox/mesh-controller** and **novox/mesh-catalog**, all on `feat/seats-are-a-closed-set`.
## The decisions
**ADR 0110 — a seat is a module assignment from a closed set, and it may deliver a provision.**
- The mesh defines which seats exist: name, scope, what occupying it delivers, and the record that made it one. A claim outside the set is refused.
- A seat is held by a module assignment. What the mesh knows about a holder is what it knows about that assignment, and nothing about holders is stored beside it.
- A seat may deliver a provision. Among several providers, resolution takes a **pin**, then the **seat's holder**, then the **only** provider, and otherwise refuses. ADR 0009's "never guessed" still holds: the seat is the choice made once, mesh-wide, instead of a pin per consumer node.
- Seats are informational: every seat, what it delivers, and who holds it, including unheld ones.
- The first set is every seat already claimed plus `npm-package-registry`, so nothing in use is refused.
**ADR 0111 — a build source is on the mesh's git seat, or it is external.**
- There is a `git` seat, and gitea holds it.
- `build --self <owner>/<repo>` records the repository's path and the seat, and composes the clone URL from the holder at build time. Nothing recorded contains an address.
- `build <url>` is unchanged. GitHub and GitLab are the ordinary external cases.
- Private-repository credentials are **not decided**, and the record says so.
## Design
- New **to-be 26 — the seats**.
- 23 gains the seat step in resolution.
- 18's *source* entry names the two forms.
- The glossary's *seat* and *provision* entries say where the two meet.
## Also carried
- **ADR 0109** is carried from `decision/0108-package-registry-seat-per-ecosystem`, authorship intact, so every link here resolves.
- The decision index was regenerated rather than hand-merged.
## Corrected while preparing
The hand enumeration behind the first set missed two sources: the controller's own manifest, and a claim composed in the controller's code (the private-network module's `the-private-network`). 0110 admits it, and it records the miss as part of its evidence, because the miss is itself the argument for an overview.
`cycle.py`, `records.py` and `index.py` all pass.
Extends ADR 0075. Surfaced fixing builder's hand-faked package-registry
binding tonight: gitea's manifest declares the provision once with a single
npm-path, conflating what should be independently assignable per ecosystem
(npm/cargo/docker/...) the same way artifact-store and package-registry
were themselves split. Cited in 22-the-work-ahead.md's Phase 2, where the
target state this decision points at was already described a week ago.
Numbered 109, not 108: route-proxy's policy feature (mesh-controller PR
still-unwritten decision record — reserved but never committed. Renumbered
around it rather than colliding.
Seats have been doing two jobs and neither is written down. The mechanism ADR 0009 introduced is
enforced — a second holder is refused — but any well-formed name becomes a seat by being claimed,
and nothing can say which seats a mesh has or who holds them: holdings are assembled while planning
and discarded. The enumeration done while preparing this missed the control plane's own manifest,
because core modules' manifests live in its repository rather than the catalogue.
0110 closes the set. Each seat has a name, a scope, what occupying it delivers, and the record that
made it one; a claim outside the set is refused. A seat is held by a module assignment, and what the
mesh knows about the holder is what it knows about that assignment — nothing is stored beside it. A
seat may deliver a provision, and then its holder answers for it among several providers: pin, then
the holder, then the only provider, then refused. That keeps 0009's "refused, never guessed": the
seat is the choice made once, mesh-wide, instead of a pin per consumer node. The first set is the
eleven seats already claimed plus 0109's npm-package-registry, so nothing in use is refused.
Two concepts — seats for exclusion, a new word for consumable singulars — was rejected: both mean
"this mesh's one X", and the overview a person wants is one list.
0111 gives the mesh a git seat and makes a build source one of two explicit forms: a repository on
the seat's holder, recorded by its path and cloned from wherever the holder runs at build time; or
an external URL, recorded and cloned exactly as given. Recognising self-hosted sources by matching
URLs against the forge's address was rejected — it fails in the one case it exists for, after the
forge moves. Credentials for private repositories are left undecided and said so.
Design: new to-be 26 (the seats); 23 gains the seat step in resolution; 18's source entry names
the two forms; the glossary's seat and provision entries say where they meet. 0109 is carried from
its own branch so every link here resolves.
The enumeration behind the first set read manifests in two repositories and missed a claim made
in the control plane's own code: the private-network module it ships claims the-private-network at
node scope. A closed set without it would refuse the control plane's own module. Thirteen claims in
use, naming twelve seats.
Closing: the ADR texts here are superseded by #113 (now merged), which carries later versions of 0109, 0110 and 0111 — 0110 with a corrected title and its claim count fixed from eleven to thirteen — and keeps them proposed pending review of to-be 27.
Two edits from this branch did not come along, and they should land the day 0110 is accepted.records.py refuses them until then: a document may not rest on a record that is not accepted, and the glossary on main cites only accepted records. Recorded here in full so nothing has to be reconstructed.
00-META/glossary.md — the seat entry becomes:
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 0110). The set, with who holds each seat, is the overview of what a mesh has (26 — The seats). A seat has a capacity: a capacity-1 seat is exclusive (one holder); a higher-capacity seat is a bench (several holders coexist).
03-DESIGN/01-to-be/23-choosing-a-provider.md — adds 02-DECISIONS/0110-… to decisions:, bumps updated:, inserts:
A seat names the mesh's one provider of a kind. Where a seat delivers the provision, its holder answers for it when several providers exist and the consumer named none. That is not picking: the choice was made once, mesh-wide, by assigning the holder, rather than once per consumer by naming it (ADR 0110, 26 — The seats). A named provider still wins over the seat, because a consumer coupled to particular contents has said so.
and amends the ambiguity rule to "If several providers of a kind exist, none is named, none is co-located, and no seat delivers it, the requirement is unsatisfiable and is refused with the candidates shown."
Branch deleted; git object for the tip was be3d2cc's sibling in this repo's reflog if the prose is ever wanted verbatim rather than quoted.
Closing: the ADR texts here are superseded by #113 (now merged), which carries later versions of 0109, 0110 and 0111 — 0110 with a corrected title and its claim count fixed from eleven to thirteen — and keeps them `proposed` pending review of to-be 27.
**Two edits from this branch did not come along, and they should land the day 0110 is accepted.** `records.py` refuses them until then: *a document may not rest on a record that is not accepted*, and the glossary on `main` cites only accepted records. Recorded here in full so nothing has to be reconstructed.
**`00-META/glossary.md`** — the `seat` entry becomes:
> **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 0110). The set, with who holds each seat, is the overview of what a mesh has (26 — The seats). A seat has a **capacity**: a capacity-1 seat is exclusive (one holder); a higher-capacity seat is a **bench** (several holders coexist).
**`03-DESIGN/01-to-be/23-choosing-a-provider.md`** — adds `02-DECISIONS/0110-…` to `decisions:`, bumps `updated:`, inserts:
> **A seat names the mesh's one provider of a kind.** Where a seat delivers the provision, its holder answers for it when several providers exist and the consumer named none. That is not picking: the choice was made once, mesh-wide, by assigning the holder, rather than once per consumer by naming it (ADR 0110, 26 — The seats). A named provider still wins over the seat, because a consumer coupled to particular contents has said so.
and amends the ambiguity rule to *"If several providers of a kind exist, none is named, none is co-located, **and no seat delivers it**, the requirement is unsatisfiable and is refused with the candidates shown."*
Branch deleted; `git` object for the tip was `be3d2cc`'s sibling in this repo's reflog if the prose is ever wanted verbatim rather than quoted.
Correction to the last line: this branch's tip is d94fe8f63869d612cf5bafd2ccfb259f035e7d02. (The commit named there belongs to a different repository.)
Correction to the last line: this branch's tip is `d94fe8f63869d612cf5bafd2ccfb259f035e7d02`. (The commit named there belongs to a different repository.)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
One feature across three repositories, one PR each: this one, novox/mesh-controller and novox/mesh-catalog, all on
feat/seats-are-a-closed-set.The decisions
ADR 0110 — a seat is a module assignment from a closed set, and it may deliver a provision.
npm-package-registry, so nothing in use is refused.ADR 0111 — a build source is on the mesh's git seat, or it is external.
gitseat, and gitea holds it.build --self <owner>/<repo>records the repository's path and the seat, and composes the clone URL from the holder at build time. Nothing recorded contains an address.build <url>is unchanged. GitHub and GitLab are the ordinary external cases.Design
Also carried
decision/0108-package-registry-seat-per-ecosystem, authorship intact, so every link here resolves.Corrected while preparing
The hand enumeration behind the first set missed two sources: the controller's own manifest, and a claim composed in the controller's code (the private-network module's
the-private-network). 0110 admits it, and it records the miss as part of its evidence, because the miss is itself the argument for an overview.cycle.py,records.pyandindex.pyall pass.Closing: the ADR texts here are superseded by #113 (now merged), which carries later versions of 0109, 0110 and 0111 — 0110 with a corrected title and its claim count fixed from eleven to thirteen — and keeps them
proposedpending review of to-be 27.Two edits from this branch did not come along, and they should land the day 0110 is accepted.
records.pyrefuses them until then: a document may not rest on a record that is not accepted, and the glossary onmaincites only accepted records. Recorded here in full so nothing has to be reconstructed.00-META/glossary.md— theseatentry becomes:03-DESIGN/01-to-be/23-choosing-a-provider.md— adds02-DECISIONS/0110-…todecisions:, bumpsupdated:, inserts:and amends the ambiguity rule to "If several providers of a kind exist, none is named, none is co-located, and no seat delivers it, the requirement is unsatisfiable and is refused with the candidates shown."
Branch deleted;
gitobject for the tip wasbe3d2cc's sibling in this repo's reflog if the prose is ever wanted verbatim rather than quoted.Correction to the last line: this branch's tip is
d94fe8f63869d612cf5bafd2ccfb259f035e7d02. (The commit named there belongs to a different repository.)Pull request closed