Merge pull request 'Make the login shell's execute optional, so a machine may withhold it (hq ADR 0268)' (#169) from withhold-login-shell-execute into main

This commit was merged in pull request #169.
This commit is contained in:
2026-10-08 22:52:28 +00:00
3 changed files with 77 additions and 6 deletions
@@ -0,0 +1,41 @@
package catalogue
import "testing"
// The login shell's `execute` runs any command as the operator account, which can become root without a
// person, so the operator withheld it on the control-node until a call to it needs a person's approval
// (novox/hq ADR 0268). It is withheld per machine by the holder's own setting, so the seat must let a
// holder hold it without serving the verb there: `execute` is optional (ADR 0246's mark), and stays so in
// a seat row read back from the store, which never keeps the mark.
func TestTheLoginShellsExecuteIsOptionalSoAMachineMayWithholdIt(t *testing.T) {
check := func(t *testing.T) {
t.Helper()
seat, ok := SeatNamed(LoginShellSeat)
if !ok {
t.Fatal("node-login-shell is not defined")
}
if len(seat.Serves) != 1 || seat.Serves[0].Name != "execute" {
t.Fatalf("the login shell promises %+v, not execute alone", seat.Serves)
}
if !seat.Serves[0].Optional {
t.Fatal("execute is required, so a holder that withholds it on one machine could not hold the seat there")
}
withholding := Manifest{Module: "zsh", Version: "1", Claims: []Claim{{Name: LoginShellSeat, Scope: ScopeNode}}}
if err := CanHold(withholding, seat); err != nil {
t.Fatalf("a holder serving no execute is refused: %v", err)
}
serving := withholding
serving.Claims = []Claim{{Name: LoginShellSeat, Scope: ScopeNode, Serves: []string{"execute"}}}
if err := CanHold(serving, seat); err != nil {
t.Fatalf("a holder serving execute is refused: %v", err)
}
}
t.Run("compiled", check)
t.Run("read back from the store", func(t *testing.T) {
before := seats
t.Cleanup(func() { seats = before })
UseSeats([]Seat{{Name: LoginShellSeat, Scope: ScopeNode, Decision: "novox/hq ADR 0204",
Serves: []Verb{{Name: "execute"}}}})
check(t)
})
}
+13 -6
View File
@@ -256,8 +256,9 @@ var defaultSeats = append([]Seat{
{Name: EnvironmentSeat, Scope: ScopeNode, Decision: "novox/hq ADR 0203"},
// The login shell (novox/hq ADR 0204, replacing the module-declared `login-shell` of ADR 0176):
// the mesh's, so a second shell module claims the seat rather than declaring a second one, and
// the seat exists whether or not zsh's definition is registered. `execute` is the contract any
// node may call; the holder places every module's shell code in its slots.
// the seat exists whether or not zsh's definition is registered. `execute` is the contract a caller
// may call where the machine serves it (optional: ADR 0268); the holder places every module's shell
// code in its slots.
{Name: LoginShellSeat, Scope: ScopeNode, Decision: "novox/hq ADR 0204",
Serves: loginShellVerbs()},
// A machine's power (novox/hq ADR 0211): its holder owns logind's power handling, places the
@@ -721,9 +722,6 @@ func uplinkVerbs() []Verb {
}
}
// loginShellVerbs is the contract every holder of node-login-shell serves (novox/hq ADR 0176, ADR
// 0204): one command, run the way the operator's own terminal would run it, bounded below the
// runtime's thirty-second call limit so a hung command answers rather than times the caller out.
// backupVerbs is the node-backup seat's protocol (novox/hq to-be 43): what is kept, take one now,
// and restore beside the live data — never over it.
func backupVerbs() []Verb {
@@ -745,9 +743,18 @@ func backupVerbs() []Verb {
}
}
// loginShellVerbs is the contract of node-login-shell (novox/hq ADR 0176, ADR 0204): one command, run
// the way the operator's own terminal would run it, bounded below the runtime's thirty-second call limit
// so a hung command answers rather than times the caller out.
//
// **`execute` is optional** (novox/hq ADR 0268). It runs any command as the operator account, which can
// become root without a person, so a machine may withhold it: the control-node does, through the
// holder's own `execute` setting, until a call to it needs a person's approval (hq research 039). The mark
// is ADR 0246's: a holder that does not serve the verb on a machine still holds the seat there, and its
// silence on the bus is not judged — a holder withholding it serves nothing on the seat.
func loginShellVerbs() []Verb {
return []Verb{
{Name: "execute", Description: "Run one command on this machine as the operator account, in a " +
{Name: "execute", Optional: true, Description: "Run one command on this machine as the operator account, in a " +
"non-interactive login shell in its home; answers with what it printed and how it exited.",
Input: schema(map[string]string{
"command": "the command line, as you would type it",