Narrow ADR 0287's claimant rule to any seat naming the path, and correct two facts the review found
This commit is contained in:
+1
-1
@@ -91,7 +91,7 @@ it; a module that once wrote a line there asks the mesh's resolver instead.
|
||||
|
||||
> **The mechanism changed — 2026-10-10, by [ADR 0287](0287-a-seat-names-the-paths-its-holder-owns-and-a-claim-without-them-is-refused.md).**
|
||||
> Decision 3 and 4 stand: `/etc/hosts` is the hosts seat's holder's, and no other module writes it. What moved
|
||||
> is where that is stated and checked. The seat's definition now names `/etc/hosts` and `/etc/hostname`, a
|
||||
> is where that is stated and checked. The seat's definition names `/etc/hosts` and `/etc/hostname` (built under issue 412), a
|
||||
> claim without them is refused, and a module that does not claim the seat and declares either is refused at
|
||||
> registration, for every seat that names a path, rather than by this record for one file.
|
||||
|
||||
|
||||
+25
-19
@@ -18,8 +18,7 @@ The operator left the choices to the agent that graduated it ("I trust your judg
|
||||
([ADR 0129](0129-a-seat-carries-the-protocol-of-its-role.md),
|
||||
[ADR 0132](0132-a-seat-carries-the-tools-its-holder-must-serve.md)). Today the protocol is what the holder
|
||||
accepts, emits and serves. A seat's definition in the controller carries a name, a scope, what it delivers,
|
||||
those three, what it receives, whether it is replicated, the seats it needs beside it, and the record that
|
||||
made it a seat. The store's seat table carries a name, a scope, what it delivers and the record. **Neither
|
||||
those three, what it receives, whether it is replicated, and the record that made it a seat. The store's seat table carries a name, a scope, what it delivers and the record. **Neither
|
||||
names a path.**
|
||||
|
||||
**Who owns a machine-wide file has been decided one record at a time:**
|
||||
@@ -47,7 +46,7 @@ on 2026-10-03, *which module owns `/etc/resolv.conf`?*, had no place to be looke
|
||||
|
||||
**What the catalogue declares, measured on 2026-10-10** (mesh-catalog main at `61dcdf0`, 125 manifests):
|
||||
|
||||
- 29 modules claim a node seat.
|
||||
- 29 modules claim one of the mesh's own node seats, and two more claim a node seat they declare themselves.
|
||||
- Three paths that the holders declare are the role's on any machine, whatever program fills the role:
|
||||
`/etc/hosts` and `/etc/hostname` (declared by `hostname`, holder of `node-hostname`), and
|
||||
`/etc/resolv.conf` (rendered for `networkmanager` and `systemd-networkd`, holders of `node-uplink`, and for
|
||||
@@ -56,7 +55,9 @@ on 2026-10-03, *which module owns `/etc/resolv.conf`?*, had no place to be looke
|
||||
tools), which is access, not ownership ([ADR 0051](0051-shared-data-is-the-operators.md)).
|
||||
- Every other path a node seat's holder declares belongs to its program, not to the role:
|
||||
`/etc/fail2ban/jail.local`, `/etc/docker/daemon.json`, `/etc/pacman.conf`, `/etc/lemurs/config.toml`,
|
||||
`/etc/NetworkManager/conf.d/50-mesh.conf`, or a path under the operator's home.
|
||||
`/etc/NetworkManager/conf.d/50-mesh.conf`, or a path under the operator's home. Two are neither: the
|
||||
holder of `node-secret-service` declares `/etc/pam.d/login` and `/etc/pam.d/passwd`, which are shared
|
||||
files of other programs. They are not the role's on any machine either, so no seat names them.
|
||||
|
||||
## Considered Options
|
||||
|
||||
@@ -75,11 +76,11 @@ on 2026-10-03, *which module owns `/etc/resolv.conf`?*, had no place to be looke
|
||||
made and the laptop runs. If `node-uplink` lost `/etc/resolv.conf`, a machine without a resolver of its
|
||||
own would have no owner of the file (against ADR 0223). If `node-resolver` lost it, ADR 0247 would be
|
||||
undone.
|
||||
5. **A seat's paths as a column of the store's seat table.** Rejected. Whether a seat is replicated, what it
|
||||
receives and which seats it needs are compiled with the set and never stored, because each is the mesh's
|
||||
definition of the role and changes what every holder must satisfy
|
||||
([ADR 0220](0220-what-a-machine-asks-needs-its-uplink-held-and-the-retired-resolver-pieces-go.md)). A path
|
||||
is the same kind of fact. A row edited without a release would make claims that were valid refused, with
|
||||
5. **A seat's paths as a column of the store's seat table.** Rejected. Whether a seat is replicated and what
|
||||
it receives are compiled with the set and never stored, as the seats a seat needed were while that field
|
||||
existed ([ADR 0220](0220-what-a-machine-asks-needs-its-uplink-held-and-the-retired-resolver-pieces-go.md)),
|
||||
because each is the mesh's definition of the role and changes what every holder must satisfy. A path is
|
||||
the same kind of fact. A row edited without a release would make claims that were valid refused, with
|
||||
nothing in review.
|
||||
6. **Check it only at the merge gate.** Rejected as the only place. The rule is a judgement over the whole
|
||||
catalogue, which is what registration judges (`CatalogueProblems`). The merge gate already runs
|
||||
@@ -110,20 +111,25 @@ a seat or a seat's need is.
|
||||
**3. A module holds the seat only if it declares every path the seat names.** It declares it as a resource
|
||||
or as a file the mesh renders for it, which is how the uplink and the resolver hold `/etc/resolv.conf`. A
|
||||
claim without them is refused by `CanHold`, the one judgement of whether a module can hold a seat (ADR 0131),
|
||||
at registration and at handover, naming the seat and the missing paths. All four modules that hold one of
|
||||
at registration and at handover, naming the seat and the missing paths. A seat a module declares for itself
|
||||
is held to the same rule by the check that already judges what such a seat's holder serves
|
||||
(`CatalogueProblems`). All four modules that hold one of
|
||||
these seats today declare what the table names, so the rule refuses nothing registered on 2026-10-10.
|
||||
|
||||
**4. Only a claimant declares a seat's path.** A module that does not claim the seat and declares a path the
|
||||
seat names is refused at registration, naming the seat. The same refusal applies at composition to what the
|
||||
**4. Only a claimant declares a seat's path.** A module that claims no seat naming a path, and declares that
|
||||
path, is refused at registration, naming the seats that name it. A module claiming any one of them may declare
|
||||
it, which is how both the uplink and the resolver declare `/etc/resolv.conf`. The same refusal applies at composition to what the
|
||||
controller generates (ADR 0222 §4), so the controller cannot write a seat's path either. Reading a seat's
|
||||
path is access, and stays allowed.
|
||||
|
||||
**5. No two seats name one path, unless one steps back for the other by definition.** A seat may name a path
|
||||
*stepping back for* another node seat: where that other seat is held on the machine, its holder owns the path
|
||||
and this seat's holder does not declare it there. Every path has exactly one seat naming it without stepping
|
||||
back, and the stepping back does not cycle. This makes the existing rule of ADR 0247 part of the definition,
|
||||
in the place `checkResources` applies it today. A module declaring a seat that names a path another seat
|
||||
already names is refused at registration, and the second declaration loses, as for a seat's name.
|
||||
*stepping back for* another node seat: where that other seat is held on the machine, its holder owns the path,
|
||||
and this seat's holder still declares it, but its declaration is not composed on that machine. Every path has
|
||||
exactly one seat naming it without stepping back, and the stepping back does not cycle. This makes the
|
||||
existing rule of ADR 0247 part of the definition, in the place `checkResources` applies it today. Only the
|
||||
mesh's own seats step back, each by a record. A module declaring a seat that names a path another seat
|
||||
already names, stepping back or not, is refused at registration, and the second declaration loses, as for a
|
||||
seat's name.
|
||||
|
||||
**6. The seat listing shows each seat's paths.** *Which module owns `/etc/resolv.conf` on a machine?* is
|
||||
answered by the controller's `seats` verb: the seat that names the path, and that seat's holder on the
|
||||
@@ -158,7 +164,7 @@ All in mesh-controller, built under issue 412:
|
||||
| Only a node seat names paths, absolute and without a placeholder | a unit test over the compiled set; a registration test refusing a module's mesh seat that names a path and a path with `${` |
|
||||
| Every path has one seat naming it without stepping back, and stepping back does not cycle | a unit test over the compiled set; a registration test refusing a module's seat that names `/etc/hosts` |
|
||||
| A claim without the seat's paths is refused, naming them | `CanHold` tests at registration and at handover, with a holder declaring the path as a resource, as a rendered file, and not at all |
|
||||
| Only a claimant declares a seat's path | a registration test refusing a module that declares `/etc/hosts` without claiming `node-hostname`; a composition test refusing a generated resource on a seat's path |
|
||||
| Only a claimant of a seat naming the path declares it | a registration test refusing a module that declares `/etc/hosts` without claiming `node-hostname`, and one accepting the uplink and the resolver both declaring `/etc/resolv.conf`; a composition test refusing a generated resource on a seat's path |
|
||||
| The step-back comes from the seat | the existing composition tests for the uplink and the resolver on one machine pass with the special case removed |
|
||||
| The listing shows the paths | the `seats` command test |
|
||||
| The catalogue as it is passes | `CatalogueProblems` over the catalogue's main gives no new problem; the merge gate runs it on every catalogue pull request |
|
||||
@@ -169,7 +175,7 @@ All in mesh-controller, built under issue 412:
|
||||
effort this graduates.
|
||||
- [26 — The seats](../03-DESIGN/01-to-be/26-the-seats.md), the design amended.
|
||||
- mesh-controller main at `c06a2cd`: `internal/catalogue/seats.go` (`Seat`, `CanHold`),
|
||||
`internal/catalogue/resolve.go` (`checkResources`, `steppedBack`),
|
||||
`internal/catalogue/resolve.go` (`checkResources`), `internal/catalogue/node_resolver.go` (`steppedBack`),
|
||||
`internal/catalogue/seats_declared.go` (`CatalogueProblems`), `cmd/mesh-controller/merge_gate.go`.
|
||||
- mesh-catalog main at `61dcdf0`: the manifests of `hostname`, `networkmanager`, `systemd-networkd` and
|
||||
`systemd-resolved`.
|
||||
|
||||
Reference in New Issue
Block a user