zsh: let a machine withhold node-login-shell's execute
mesh/merge-gate pass: builds zsh → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group withhold-login-shell-execute delivered: every member is delivered

execute runs any command as the operator account, which can become root
without a person. The operator withholds it on the control-node until a
call needs a person's approval (hq ADR 0268); the other machines keep it
for now. The setting execute (serve by default) is written into a
root-owned file the tools bundle reads at start, and anything but serve
withholds the verb, so the machine's runtime does not offer it.
This commit is contained in:
jochen
2026-10-09 00:10:28 +02:00
parent 3ee6c2b8ed
commit cfe1dffa45
6 changed files with 162 additions and 6 deletions
+12 -3
View File
@@ -2,11 +2,14 @@
// `zsh_config` (novox/hq ADR 0176, ADR 0204). The node tools runtime launches this bundle as a
// process of its own and serves what it registers (ADR 0188, ADR 0193); it runs as the operator
// account, so the command runs as that account with nothing switched (shell.ts).
//
// `execute` is registered only where this machine's setting serves it (novox/hq ADR 0268): the
// control-node withholds it, so its runtime offers no such verb and a call to it finds nothing.
import { userInfo } from "node:os";
import { join } from "node:path";
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
import { DEFAULT_TIMEOUT_SECONDS, MAX_TIMEOUT_SECONDS, commandEnv, execute, homeOf, timeoutOf, zshFile } from "../shell.js";
import { DEFAULT_TIMEOUT_SECONDS, MAX_TIMEOUT_SECONDS, commandEnv, execute, homeOf, readExecuteSetting, timeoutOf, zshFile } from "../shell.js";
/** The operator account on this machine, as the mesh told the runtime. */
function account(env: NodeJS.ProcessEnv): string {
@@ -14,6 +17,11 @@ function account(env: NodeJS.ProcessEnv): string {
}
function seatVerbs(env: NodeJS.ProcessEnv): ToolDefinition[] {
const setting = readExecuteSetting(env);
if (!setting.served) {
console.error(`[zsh] node-login-shell's execute is not served on this machine: ${setting.why}`);
return [];
}
return [
{
name: "execute",
@@ -47,11 +55,12 @@ function ownTools(env: NodeJS.ProcessEnv): ToolDefinition[] {
return [
{
name: "zsh_config",
description: "The operator account's ~/.zshenv and ~/.zshrc on this machine as they are now: each file's lines, how many are the mesh's block, and the content.",
description: "The operator account's ~/.zshenv and ~/.zshrc on this machine as they are now: each file's lines, how many are the mesh's block, and the content; and whether this machine serves node-login-shell's execute, and why.",
input: { type: "object", properties: {} },
run: async () => {
const home = homeOf(env);
return { account: account(env), zshenv: await zshFile(join(home, ".zshenv")), zshrc: await zshFile(join(home, ".zshrc")) };
const setting = readExecuteSetting(env);
return { account: account(env), execute: { served: setting.served, why: setting.why }, zshenv: await zshFile(join(home, ".zshenv")), zshrc: await zshFile(join(home, ".zshrc")) };
},
},
];