--- topic: what runs on it status: accepted date: 2026-10-02 deciders: jochen reconstructed: false extends: 02-DECISIONS/0132-a-seat-carries-the-tools-its-holder-must-serve.md --- # 176. The login shell is a node seat held by one shell module, and `execute` is its contract ## Context [ADR 0040](0040-what-a-module-is.md) names the shell as its example of a *shared* seat: bash, zsh and fish all join `shell`, and one may be default. The operator's reading is sharper, and it matches [ADR 0126](0126-a-module-declares-its-own-seats.md) better: *installing* a shell is installing software, and several may be installed; *holding* the seat is being the login shell, which a node has exactly one of. A definition says which seats a module can hold; the assignment says which it does. A seat carries the tools its holder must serve ([ADR 0132](0132-a-seat-carries-the-tools-its-holder-must-serve.md)), and [to-be 33](../03-DESIGN/01-to-be/33-the-tools-the-mesh-answers.md) leaves which verbs each seat serves as a decision per seat, taken slowly. This is the first seat of the operator's environment, and the one every node has. ## Considered Options 1. **A shared `shell` seat with a default**, as 0040's example reads. Rejected: *default* is a second concept beside *holder* for the same fact, and the `user` shape already makes the login shell declared state ([to-be 05](../03-DESIGN/01-to-be/05-the-node-host.md)). 2. **No seat; each shell module sets the login shell for itself.** Rejected: two assigned shell modules would fight over `chsh`, and nothing would say which won. 3. **An exclusive node-scoped seat, `login-shell`, declared by the shell modules, held by one per node.** Chosen. ## Decision **1. `login-shell` is a node-scoped seat declared by the shell modules.** zsh, fish and bash each declare that they can hold it; a node's assignment says which does; the controller refuses a second holder by name as for every seat. A shell module that is assigned without holding the seat is installed and nothing more. **2. Holding the seat sets the account's login shell.** The holder's declaration carries the `user` shape with the shell it provides, so the login shell is declared state the host applies and gives back when the holding moves — `chsh` stops being a hook. **3. The seat's contract is `execute`.** One verb, one argument, the command, run on the node the seat is scoped to as the operator account, answering with what it printed and how it exited. Every holder serves it; a holder may serve its own tools beside it ([ADR 0170](0170-the-firewall-seat-serves-its-verbs.md) §2) — show the rendered configuration, list the plugins, set a prompt value. **4. Any node may call it on any node.** The grant is the node tools runtime's ([ADR 0175](0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md) §5): *run `uptime` on every node* is five calls to one verb. ## Consequences - The first environment module is a shell: a package, files under the home owned by the account, a seat declaration and claim, a `user` shape, and one tool. It proves the whole pattern on every node, servers included, before anything graphical is written. - ADR 0040's shell example is read as *installed is not holding*; a dated note in that record says so. Its decision is untouched. - `execute` is a shell on every machine, addressed over the bus. That is the point, and it is the widest verb the mesh serves; it exists because the operator decided every node may call every tool, and this record does not narrow that. ## How it is checked | Rule | Checked by | |---|---| | Two shell modules assigned to one node, one holding: one `user` shape in the declaration, naming the holder's shell | the controller's composition tests | | A second claimant is refused by name | the catalogue's seat tests | | `execute` runs as the account and answers output and exit status | the module's tool tests over a fake runner, and live on every node | | The seat's verb appears with its scope and machine in the node tools listing | the runtime's tests (to-be 33 §4) | ## References - [Research 018](../01-RESEARCH/018-the-operators-machine-as-modules/04-the-seats-of-the-environment.md) - [ADR 0040](0040-what-a-module-is.md), [ADR 0126](0126-a-module-declares-its-own-seats.md), [ADR 0132](0132-a-seat-carries-the-tools-its-holder-must-serve.md), [ADR 0170](0170-the-firewall-seat-serves-its-verbs.md)