// Row 195 (#1693): scripts/case1-accept.sh, root's acceptance run on the Case 1 host. Design r7 section 5
// (agents/darkwing/work/queue-195/DESIGN.md); deviations in agents/darkwing/work/queue-195/BUILD.md.
// Every case runs the script with --root on a scratch host tree: /etc, /proc, /srv/mosaic, /opt and the
// host check live under it. Fake systemctl, curl, ss, sudo and stat on PATH record their argv; the fake
// sudo runs the stack's user's commands from the tree. Nothing here reads or writes the real /etc,
// /proc or /srv, and the stand-in credential is not a credential.
import { test } from "node:test";
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { tmp } from "./helpers.mjs";
import { CASE_SUDO_SESSION, recordedLivePids, killRecordedPids, fixtureGuard, cleanupFixture, pollFixtureGone, blockingQuerySource } from "./case-sudo-fixture.mjs";

const REPO = fileURLToPath(new URL("../../../", import.meta.url));
const SCRIPT = join(REPO, "scripts", "case1-accept.sh");
const COPY = "0123456789abcdef0123456789abcdef01234567";
const NODE_PIN = "v24.1.0", CLAUDE_PIN = "2.1.0";
const NODE = `/opt/mosaic-stack/node-${NODE_PIN}/bin/node`;
const CLAUDE = `/opt/mosaic-stack/claude-${CLAUDE_PIN}/node_modules/@anthropic-ai/claude-code/bin/claude.exe`;
const HOME = "/srv/mosaic";
const CLI = `${HOME}/.local/share/mosaic-stack/copies/${COPY}/scripts/mosaic`;
const PRECHECK = `${HOME}/.local/share/mosaic-stack/copies/${COPY}/scripts/case2-precheck.sh`;
const CRED = `${HOME}/.config/mosaic-dev/secrets/claude-session.env`;
const CRED_VALUE = "stand-in-not-a-credential-7f3e2a";
const AS_MOSAIC = `-u mosaic -H env PATH=/opt/mosaic-stack/node-${NODE_PIN}/bin:/usr/local/bin:/usr/bin:/bin`;
const ARGS = ["--profile", "factory", "--user", "mosaic", "--home", HOME, "--business", "mosaic-stack", "--copy", COPY,
  "--node", NODE, "--claude", CLAUDE, "--pm", "--", "--port", "732", "--business", "mosaic-stack", "--tester-socket"];
const OUTER = "bwrap (enforce)", CHILD = "bwrap//&unpriv_bwrap (enforce)";
const MARKS = ["pass", "FAIL", "closed", "accepted Q182+Q183", "accepted Q183", "accepted mos-1096", "unnamed"];
const P_PASS = { P1: "closed", P2: "closed", P3: "accepted Q183", P4: "accepted Q182+Q183", P5: "closed", P6: "closed",
  P7: "closed", P8: "closed", P9: "accepted mos-1096", P10: "unnamed", P11: "closed" };
const PASSWD = "root:x:0:0:root:/root:/bin/bash\nmosaic:x:997:997::/srv/mosaic:/usr/sbin/nologin\nlocaladmin:x:1000:1000::/home/localadmin:/bin/bash\njarvis:x:1001:1001::/home/jarvis:/bin/bash\n";
const GROUP = "root:x:0:\nsudo:x:27:localadmin\nmosaic:x:997:\nlxd:x:998:\ndocker:x:999:\nlocaladmin:x:1000:\njarvis:x:1001:\n";
const SS = "LISTEN 0 511 127.0.0.1:732 0.0.0.0:* users:((\"node\",pid=200,fd=21))\n"
  + "LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:((\"sshd\",pid=900,fd=3))\n";
const HOSTCHECK_OK = [1, 2, 3, 4, 5, 6, 7].map((n) => `ok ${n} item ${n} holds`).join("\n") + "\nnote bubblewrap 0.9.0 is the install pin\n";

function put(file, text, mode) {
  mkdirSync(dirname(file), { recursive: true });
  writeFileSync(file, text);
  if (mode) chmodSync(file, mode);
}
const edit = (file, f) => writeFileSync(file, f(readFileSync(file, "utf8")));
const log = (name) => `printf '%s' ${JSON.stringify(name)} >> "$HC/calls.log"; printf ' %s' "$@" >> "$HC/calls.log"; echo >> "$HC/calls.log"`;

// Fakes on PATH. Each records its argv and answers from a file in the state directory.
const FAKES = {
  systemctl: `case "$1" in
  show) [ -f "$HC/show-$2" ] && cat "$HC/show-$2" ;;
  is-enabled) cat "$HC/enabled-$2" 2>/dev/null || { echo disabled; exit 1; } ;;
esac`,
  curl: `exit "$(cat "$HC/curl-rc")"`,
  ss: `cat "$HC/ss"`,
  od: `if [ "$1" = -An ] && [ "$2" = -tx1 ] && [ "$3" = -N4 ]; then
  [ -f "$HC/elf" ] && cat "$HC/elf" || echo 7f454c46
else exec /usr/bin/od "$@"; fi`,
  // The credential and the settings file answer from the state directory, as root would see them, and
  // only those calls are recorded; everything else is the real stat, which reads the args file.
  stat: `case "\${@: -1}" in
  *claude-session.env) ${log("stat")}; cat "$HC/stat-cred" ;;
  *console/tester.sock) cat "$HC/stat-socket" ;;
  *console) [ "$2" = '%u %a %F %d %i' ] && cat "$HC/stat-parent" || echo "997 700" ;;
  *managed-settings.json) ${log("stat")}; cat "$HC/stat-settings" ;;
  *) exec /usr/bin/stat "$@" ;;
esac`,
  // -l -U USER prints the state file; -u jarvis is the bwrap probe; -u mosaic -H env PATH=... CMD runs
  // CMD from the tree, with the PATH entries and each absolute argument that exists there moved under it.
  sudo: `${CASE_SUDO_SESSION}
case "$1" in
  -l) [ -f "$HC/sudo-l-$3" ] && cat "$HC/sudo-l-$3"; exit 0 ;;
  -u) ;;
  *) exit 97 ;;
esac
user="$2"; shift 2
if [ "$user" = jarvis ]; then cat "$HC/jarvis-bwrap" >&2; exit "$(cat "$HC/jarvis-bwrap-rc")"; fi
[ "$user" = mosaic ] && [ "$1" = -H ] && [ "$2" = env ] || exit 98
shift 2
if [ "$1" = -i ]; then
 [ "$2" = HOME=/srv/mosaic ] || exit 98
 shift 2
fi
[[ "$1" == PATH=* ]] || exit 98
p="\${1#PATH=}"; shift
np=""; IFS=: read -ra parts <<< "$p"; for x in "\${parts[@]}"; do np+="$ROOT_DIR$x:"; done
cmd="$1"; shift
args=(); for a in "$@"; do if [[ "$a" == /* ]] && [ -e "$ROOT_DIR$a" ]; then args+=("$ROOT_DIR$a"); else args+=("$a"); fi; done
export HOME="$ROOT_DIR/srv/mosaic" PATH="$np$PATH"
[ ! -e "$ROOT_DIR$cmd" ] || cmd="$ROOT_DIR$cmd"
case_sudo_run "$HC" "$cmd" "\${args[@]}"`,
};

// Executables inside the tree, run by the fake sudo or by the script itself. Node marks a run outside
// the fake sudo, which sets HOME to the stack's home, so a test can tell whether root ran it.
const NODE_STUB = `[ "$HOME" = "$ROOT_DIR/srv/mosaic" ] || touch "$HC/node-as-root"
[ "\${1:-}" = --version ] && { cat "$HC/node-version"; exit 0; }
exec "$REAL_NODE" "$@"`;
// The real Python payload runs against a mock socket object, never an OS listener.
const PYTHON_STUB = `[ -f "$HC/peer-output" ] && { cat "$HC/peer-output"; exit "$(cat "$HC/peer-status")"; }
[ -f "$HC/peer-hang" ] && {
 here="$BASHPID"; read -r sid < <(/bin/ps -o sid= -p "$here")
 echo "$here" > "$HC/peer-pid"; printf '%s %s\\n' "$here" "$sid" >> "$HC/query-pids"
 trap '' TERM HUP; exec sleep 60
}
if [ -f "$HC/peer-change" ]; then cat "$HC/peer-change" > "$HC/stat-socket"; fi
if [ -f "$HC/peer-pid-change" ]; then cat "$HC/peer-pid-change" > "$HC/show-mosaic-webui.service"; fi
exec /usr/bin/python3 -I -S -c '
import os,socket,struct,sys
class Fake:
 def __init__(self,*a): assert a==(socket.AF_UNIX,socket.SOCK_STREAM)
 def settimeout(self,n): assert n==1
 def connect(self,p): assert p.endswith("/console/tester.sock")
 def getsockopt(self,*a):
  assert a==(socket.SOL_SOCKET,socket.SO_PEERCRED,12)
  return struct.pack("3i",*[int(x) for x in open(os.environ["HC"]+"/peer").read().split()])
 def close(self): pass
socket.socket=Fake
payload=sys.argv[4]
sys.argv=["probe",sys.argv[5]]
exec(payload)
' "$@"`;
const TREE = {
  "/usr/bin/python3": PYTHON_STUB,
  [NODE]: NODE_STUB,
  [CLAUDE]: `[ "\${1:-}" = --version ] && cat "$HC/claude-version"; exit 0`,
  [CLI]: `${log("mosaic")}
case "$1" in
  talk) case "$(cat "$HC/talk-mode")" in
      reply) echo "sent ab12cd34 to chief"; echo "[chief -> tester] seen" ;;
      noreply) echo "sent ab12cd34 to chief"; echo "no reply from chief within 300 s" >&2; exit 1 ;;
      sentonly) echo "sent ab12cd34 to chief" ;;
    esac ;;
  launches) cat "$HC/launches.json" ;;
  *) exit 2 ;;
esac`,
  [PRECHECK]: `${log("precheck")}
echo "precheck: done"; exit "$(cat "$HC/precheck-rc")"`,
  "/usr/local/lib/mosaic-stack/hostcheck.sh": `${log("hostcheck")}
cat "$HC/hostcheck-out"`,
};

function proc(root, pid, { ppid, uid = 997, exe, argv0 = "x", comm = "x", label }) {
  const d = join(root, "proc", String(pid));
  put(join(d, "status"), `Name:\t${comm}\nState:\tS (sleeping)\nPPid:\t${ppid}\nUid:\t${uid}\t${uid}\t${uid}\t${uid}\n`);
  put(join(d, "cmdline"), `${argv0}\0--x\0`);
  put(join(d, "comm"), `${comm}\n`);
  rmSync(join(d, "exe"), { force: true });
  if (exe) symlinkSync(exe, join(d, "exe"));
  if (label !== undefined) put(join(d, "attr", "current"), label);
}

// A scratch Case 1 host where every F check passes and every P check is closed or accepted.
function host(t) {
  const dir = tmp(t, "c1accept-");
  const root = join(dir, "root"), hc = join(dir, "hc"), bin = join(dir, "bin");
  const args = join(root, "etc", "mosaic-stack", "dev.args");
  put(args, ARGS.join("\n") + "\n", 0o644);
  put(join(root, "etc", "passwd"), PASSWD);
  put(join(root, "etc", "group"), GROUP);
  put(join(root, "etc", "sudoers.d", "90-localadmin"), "localadmin ALL=(ALL) NOPASSWD: ALL\n");
  put(join(root, "etc", "claude-code", "managed-settings.json"), JSON.stringify({ env: { DISABLE_AUTOUPDATER: "1" } }));
  put(join(root, CRED), `CLAUDE_CODE_OAUTH_TOKEN=${CRED_VALUE}\n`, 0o600);
  put(join(root, HOME, ".config", "mosaic-dev", "businesses", "mosaic-stack.json"), JSON.stringify({ id: "mosaic-stack", launch: { by: "pm" } }));
  put(join(root, "proc", "sys", "net", "ipv4", "ip_unprivileged_port_start"), "1024\n");
  proc(root, 1, { ppid: 0, uid: 0, exe: "/usr/lib/systemd/systemd", comm: "systemd" });
  proc(root, 100, { ppid: 1, exe: NODE, argv0: NODE, comm: "node" });
  proc(root, 200, { ppid: 1, exe: NODE, argv0: NODE, comm: "node" });
  proc(root, 300, { ppid: 100, exe: "/usr/bin/bwrap", argv0: "/usr/bin/bwrap", comm: "bwrap", label: `${OUTER}\n` });
  proc(root, 301, { ppid: 300, exe: NODE, argv0: NODE, comm: "node", label: `${CHILD}\n` });
  proc(root, 302, { ppid: 301, exe: CLAUDE, argv0: CLAUDE, comm: "claude.exe", label: `${CHILD}\n` });
  // A root bwrap with a mislabelled claude child, which F5 must pass over.
  proc(root, 400, { ppid: 1, uid: 0, exe: "/usr/bin/bwrap", argv0: "/usr/bin/bwrap", comm: "bwrap", label: "unconfined\n" });
  proc(root, 401, { ppid: 400, uid: 0, argv0: "claude", comm: "claude", label: "unconfined\n" });
  const state = {
    "show-mosaic-bus@mosaic-stack.service": "ActiveState=active\nUser=mosaic\nMainPID=100\n",
    "show-mosaic-webui.service": "ActiveState=active\nUser=mosaic\nMainPID=200\n",
    "show-mosaic-hostcheck.service": "Before=mosaic-bus@mosaic-stack.service mosaic-webui.service multi-user.target\n",
    "enabled-mosaic-hostcheck.service": "enabled\n",
    "curl-rc": "0", ss: SS,
    "stat-parent": "997 700 directory 9 10\n", "stat-socket": "997 600 socket 9 11\n", peer: "200 997 997\n",
    "stat-cred": "mosaic 600 regular file\n", "stat-settings": "root:root 644 regular file\n",
    "sudo-l-mosaic": "User mosaic is not allowed to run sudo on dev-53.\n",
    "sudo-l-localadmin": "User localadmin may run the following commands on dev-53:\n    (ALL : ALL) ALL\n    (ALL) NOPASSWD: ALL\n",
    "jarvis-bwrap": "sudo: unable to execute /usr/bin/bwrap: Permission denied\n", "jarvis-bwrap-rc": "1",
    "node-version": `${NODE_PIN}\n`, "claude-version": `${CLAUDE_PIN} (Claude Code)\n`,
    "talk-mode": "reply", "precheck-rc": "0", "hostcheck-out": HOSTCHECK_OK,
    "launches.json": JSON.stringify([
      { instance: "pm", live: true, business: "mosaic-stack", run: "r-0002" },
      { instance: "pm", live: false, business: "mosaic-stack", run: "r-0001" },
      { instance: "dev-1", live: true, business: "mosaic-stack", run: "r-0003" },
    ]),
  };
  for (const [name, text] of Object.entries(state)) put(join(hc, name), text);
  for (const [name, body] of Object.entries(FAKES)) put(join(bin, name), `#!/usr/bin/env bash\n${name === "stat" ? "" : log(name)}\n${body}\n`, 0o755);
  for (const [path, body] of Object.entries(TREE)) put(join(root, path), `#!/usr/bin/env bash\n${body}\n`, 0o755);
  const copyRoot = join(root, HOME, '.local/share/mosaic-stack/copies', COPY);
  put(join(copyRoot, 'packages/cli/src/config.mjs'), `import fs from 'node:fs';export const loadSystem=()=>({dataRoot:fs.readFileSync(${JSON.stringify(join(hc,'data-root'))},'utf8').trim()});`);
  put(join(copyRoot, 'packages/webui/src/cli.mjs'), '// MOSAIC_TESTER_SOCKET_V1\n');
  put(join(hc, 'data-root'), `${HOME}/.mosaic-dev\n`);
  put(join(root, HOME, '.mosaic-dev/console/tester.sock'), 'stand-in socket metadata only');
  chmodSync(join(root, HOME, '.mosaic-dev/console'), 0o700);
  // F9 runs node only when it and each directory above it have no group or other write, whatever the umask.
  for (let d = dirname(NODE); d !== "/"; d = dirname(d)) chmodSync(join(root, d), 0o755);
  chmodSync(root, 0o755);
  return { dir, root, hc, bin, args };
}

function run(h, extra = {}, argv = ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--claude-pin", CLAUDE_PIN, "--node-pin", NODE_PIN, "--root", h.root]) {
  const r = spawnSync(SCRIPT, argv, {
    encoding: "utf8",
    env: { ...process.env, PATH: `${h.bin}:${process.env.PATH}`, HC: h.hc, ROOT_DIR: h.root, REAL_NODE: process.execPath, TMPDIR: h.dir, ...extra },
  });
  const lines = r.stdout.split("\n").filter(Boolean);
  // Each check line as { id, path, mark, evidence }.
  const checks = lines.filter((l) => /^[FP][0-9]+ /.test(l)).map((l) => {
    const [id, path, ...rest] = l.split(" ");
    const tail = rest.join(" ");
    const mark = MARKS.find((m) => tail === m || tail.startsWith(`${m} `));
    return { id, path, mark, evidence: tail.slice(mark?.length ?? 0).trim(), line: l };
  });
  return { status: r.status, out: r.stdout, err: r.stderr, lines, checks };
}
const calls = (h, name) => (existsSync(join(h.hc, "calls.log")) ? readFileSync(join(h.hc, "calls.log"), "utf8") : "")
  .split("\n").filter((l) => l === name || l.startsWith(`${name} `)).map((l) => l.slice(name.length + 1));
const failed = (r) => r.checks.filter((c) => c.mark === "FAIL").map((c) => c.id);
const marksOf = (r, id) => r.checks.filter((c) => c.id === id).map((c) => c.mark);
const mustRun = (h, extra) => { const r = run(h, extra); assert.ok(r.status === 0 || r.status === 1, r.out + r.err); return r; };

test('row253 socket observation uses configured root, metadata and the Console peer without sending bytes', t=>{
  const h=host(t), data='/srv/mosaic/custom-data';
  put(join(h.hc,'data-root'),data+'\n');
  put(join(h.root,data,'console/tester.sock'),'metadata stand-in');
  const r=run(h);
  assert.equal(r.status,0,r.out+r.err);
  assert.match(r.out,/P10 tester-socket-squat unnamed boundary=observed path=\/srv\/mosaic\/custom-data\/console\/tester.sock/);
  assert.match(r.out,/peer_pid=200 peer_uid=997/);
  assert.match(r.out,/hostile same-uid substitution remains/);
  assert.doesNotMatch(r.out,/accepted mos-1101/);
  assert.deepEqual(marksOf(r,'P8'),['closed']);
});

test('row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure',t=>{
  const faults={
    'parent-mode': h=>put(join(h.hc,'stat-parent'),'997 755 directory 9 10\n'),
    'parent-owner': h=>put(join(h.hc,'stat-parent'),'998 700 directory 9 10\n'),
    'socket-mode': h=>put(join(h.hc,'stat-socket'),'997 660 socket 9 11\n'),
    'socket-owner': h=>put(join(h.hc,'stat-socket'),'998 600 socket 9 11\n'),
    'socket-type': h=>put(join(h.hc,'stat-socket'),'997 600 regular file 9 11\n'),
    symlink:h=>{const p=join(h.root,HOME,'.mosaic-dev/console/tester.sock');rmSync(p);symlinkSync('/absent',p);},
    peer:h=>put(join(h.hc,'peer'),'200 998 997\n'),
    'peer-pid':h=>put(join(h.hc,'peer'),'555 997 997\n'),
    'python-mode':h=>chmodSync(join(h.root,'usr/bin/python3'),0o777),
    'python-missing':h=>rmSync(join(h.root,'usr/bin/python3')),
    'python-not-elf':h=>put(join(h.hc,'elf'),'23212f62\n'),
    'peer-malformed':h=>{put(join(h.hc,'peer-output'),'200 997 997 extra\n');put(join(h.hc,'peer-status'),'0');},
    'peer-error':h=>{put(join(h.hc,'peer-output'),'200 997 997\n');put(join(h.hc,'peer-status'),'1');},
    'peer-uid-fields':h=>proc(h.root,200,{ppid:1,uid:998,exe:NODE,comm:'node'}),
    'changed-inode':h=>put(join(h.hc,'peer-change'),'997 600 socket 9 99\n'),
    'changed-pid':h=>put(join(h.hc,'peer-pid-change'),'ActiveState=active\nUser=mosaic\nMainPID=201\n'),
    floor:h=>put(join(h.root,'proc/sys/net/ipv4/ip_unprivileged_port_start'),'700\n'),
  };
  for(const [name,fault] of Object.entries(faults)){
    const h=host(t);fault(h);const r=run(h);
    assert.equal(r.status,name==='peer-uid-fields'?1:0,`${name}: ${r.out}${r.err}`);
    assert.match(r.out,/P10 tester-socket-squat unnamed boundary=failed/,name);
    assert.doesNotMatch(r.out,/boundary=observed/,name);
  }
});

test('row253 acceptance rejects bad config and unsupported copies before talk',t=>{
  const faults={
    outside:h=>put(join(h.hc,'data-root'),'/srv/mosaic2/data\n'),
    dot:h=>put(join(h.hc,'data-root'),'/srv/mosaic/./data\n'),
    absent:h=>rmSync(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/cli/src/config.mjs')),
    unmarked:h=>put(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/webui/src/cli.mjs'),'// old copy'),
    schema:h=>put(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/cli/src/config.mjs'),'console.log(JSON.stringify({dataRoot:"/srv/mosaic/.mosaic-dev",socket:true,extra:1}));process.exit(0);'),
    failed:h=>put(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/cli/src/config.mjs'),'console.log(JSON.stringify({dataRoot:"/srv/mosaic/.mosaic-dev",socket:true}));process.exit(1);'),
  };
  for(const [name,fault] of Object.entries(faults)){
    const h=host(t);fault(h);const r=run(h);
    assert.equal(r.status,2,`${name}: ${r.out}${r.err}`);assert.equal(r.out,'');
    assert.match(r.err,/tester (config query|path refuses)|support/);
    assert.deepEqual(calls(h,'mosaic'),[]);
  }
});

test('row253 stalled peer observation ends within its bound without leaving a reader',async t=>{
  const h=host(t);put(join(h.hc,'peer-hang'),'');
  const r=run(h);assert.equal(r.status,0,r.out+r.err);
  assert.match(r.out,/P10 tester-socket-squat unnamed boundary=failed reason=probe/);
  const pid=Number(readFileSync(join(h.hc,'peer-pid'),'utf8'));
  let state='gone';
  for(let n=0;n<50;n++){
    try{state=readFileSync(`/proc/${pid}/stat`,'utf8').split(') ')[1].split(' ')[0];}catch{state='gone';}
    if(state==='gone'||state==='Z')break;
    await new Promise(resolve=>setTimeout(resolve,10));
  }
  assert.ok(state==='gone'||state==='Z',`peer helper ${pid} still ${state}`);
});

test('row253 P8 refuses both retired TCP and board listeners',t=>{
  for(const port of [7333,7331]){
    const h=host(t);put(join(h.hc,'ss'),SS+`LISTEN 0 511 127.0.0.1:${port} 0.0.0.0:* users:(("node",pid=200,fd=22))\n`);
    assert.deepEqual(marksOf(run(h),'P8'),['unnamed']);
  }
});

test('row253 C4 acceptance query inner reason holds under both sudo models',async t=>{
 for(const mode of ['exec','hop']){
  const h=host(t),files=[join(h.hc,'session-pids'),join(h.hc,'query-pids')];
  put(join(h.hc,'session-mode'),mode);
  put(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/cli/src/config.mjs'),blockingQuerySource(files[1]));
  const capture=cleanupFixture(t,files);const stop=fixtureGuard(t,files);
  const start=performance.now(),r=run(h),seconds=(performance.now()-start)/1000;capture();
  assert.equal(r.status,2,r.out+r.err);assert.equal(r.err,'case1-accept: refusing: tester config query inner-timeout\n');
  assert.ok(seconds<7,`${mode}: ${seconds}s`);assert.equal(r.out,'');assert.deepEqual(calls(h,'mosaic'),[]);
  assert.deepEqual(await pollFixtureGone(files),[]);await stop();
 }
});

test('row253 C4 acceptance query outer reason discards stdout and names residual cleanup',async t=>{
 for(const mode of ['exec','hop']){
  const h=host(t),files=[join(h.hc,'session-pids')];put(join(h.hc,'session-mode'),mode);put(join(h.hc,'stall-config'),'');
  put(join(h.hc,'stall-output'),JSON.stringify({dataRoot:HOME+'/.mosaic-dev',socket:true}));
  const capture=cleanupFixture(t,files);const stop=fixtureGuard(t,files);
  const start=performance.now(),r=run(h),seconds=(performance.now()-start)/1000;capture();
  assert.equal(r.status,2,r.out+r.err);assert.equal(r.err,'case1-accept: refusing: tester config query outer-timeout\n');
  assert.ok(seconds>=7&&seconds<9,`${mode}: ${seconds}s; 2s preflight slack`);
  assert.equal(r.out,'');assert.deepEqual(calls(h,'mosaic'),[]);
  if(mode==='hop')assert.ok(recordedLivePids(files[0]).length>0,'R3 session remains before fixture cleanup');
  killRecordedPids(files[0]);assert.deepEqual(await pollFixtureGone(files),[],'explicit R3 fixture cleanup');await stop();
 }
});

test('row253 C4 acceptance query overflow is output-limit in both models',async t=>{
 for(const mode of ['exec','hop']){
  const h=host(t),files=[join(h.hc,'session-pids')];put(join(h.hc,'session-mode'),mode);const capture=cleanupFixture(t,files);
  put(join(h.root,HOME,'.local/share/mosaic-stack/copies',COPY,'packages/cli/src/config.mjs'),`process.stdout.write('X'.repeat(8192));export const loadSystem=()=>({dataRoot:'${HOME}/.mosaic-dev'});`);
  const r=run(h);capture();assert.equal(r.status,2,r.out+r.err);assert.equal(r.err,'case1-accept: refusing: tester config query output-limit\n');
  assert.equal(r.out,'');assert.deepEqual(calls(h,'mosaic'),[]);assert.deepEqual(await pollFixtureGone(files),[]);
 }
});

for(const fault of ['inner','outer','overflow'])test(`row253 C4 P10 ${fault} reason holds under both sudo models`,async t=>{
 for(const mode of ['exec','hop']){
  const h=host(t),files=[join(h.hc,'session-pids'),join(h.hc,'query-pids')];put(join(h.hc,'session-mode'),mode);
  const capture=cleanupFixture(t,files);const stop=fixtureGuard(t,files,7000);
  if(fault==='inner')put(join(h.hc,'peer-hang'),'');
  if(fault==='outer'){put(join(h.hc,'stall-probe'),'');put(join(h.hc,'stall-output'),'200 997 997\n');}
  if(fault==='overflow'){put(join(h.hc,'peer-output'),'200 997 997\n'+'X'.repeat(256));put(join(h.hc,'peer-status'),'0');}
  const start=performance.now(),r=run(h),seconds=(performance.now()-start)/1000;capture();
  assert.equal(r.status,0,r.out+r.err);
  const reason=fault==='inner'?'inner-timeout':fault==='outer'?'outer-timeout':'output-limit';
  assert.match(r.out,new RegExp('P10 tester-socket-squat unnamed boundary=failed reason=probe-'+reason+' '));
  assert.doesNotMatch(r.out,/boundary=observed/);
  if(fault==='inner')assert.ok(seconds<4,`${mode}: ${seconds}s includes functional checks`);
  if(fault==='outer'){
   assert.ok(seconds>=4&&seconds<6,`${mode}: ${seconds}s; 2s functional-check slack`);
   if(mode==='hop')assert.ok(recordedLivePids(files[0]).length>0,'stalled supervisor is R3 residual');
   for(const file of files)killRecordedPids(file);
  }
  assert.deepEqual(await pollFixtureGone(files),[],fault==='outer'?'explicit R3 cleanup':mode);await stop();
 }
});

// One fault per F check; each makes that check, and only that one, fail.
const F_FAULTS = {
  F1: (h) => proc(h.root, 100, { ppid: 1, uid: 0, exe: NODE, comm: "node" }),
  F2: (h) => put(join(h.hc, "ss"), SS.replace("127.0.0.1:732 ", "0.0.0.0:732 ")),
  F3: (h) => put(join(h.hc, "talk-mode"), "noreply"),
  F4: (h) => put(join(h.hc, "precheck-rc"), "1"),
  F5: (h) => put(join(h.root, "proc", "302", "attr", "current"), "unconfined\n"),
  F6: (h) => put(join(h.hc, "claude-version"), "2.0.9 (Claude Code)\n"),
  F7: (h) => put(join(h.hc, "launches.json"), JSON.stringify([{ instance: "pm", live: false, business: "mosaic-stack", run: "r-1" }])),
  F8: (h) => put(join(h.hc, "stat-cred"), "mosaic 640 regular file\n"),
  F9: (h) => put(join(h.root, "etc", "claude-code", "managed-settings.json"), JSON.stringify({ env: { DISABLE_AUTOUPDATER: "0" } })),
  F10: (h) => put(join(h.hc, "node-version"), "v24.0.0\n"),
  F11: (h) => put(join(h.root, HOME, ".mosaic-dev", "discord", "binding.json"), "{}"),
};

test("row 195 accept: every check passing exits 0, with each P mark and counts that match the lines", (t) => {
  const h = host(t);
  const r = run(h);
  assert.equal(r.status, 0, r.out + r.err);
  assert.deepEqual(r.checks.map((c) => c.id), ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11",
    "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11"]);
  for (const c of r.checks.filter((x) => x.id.startsWith("F"))) assert.equal(c.mark, "pass", c.line);
  for (const [id, mark] of Object.entries(P_PASS)) assert.deepEqual(marksOf(r, id), [mark], id);
  const counts = r.lines.filter((l) => l.startsWith("count ")).map((l) => l.slice(6));
  assert.deepEqual(counts, MARKS.map((m) => `${m} ${r.checks.filter((c) => c.mark === m).length}`));
  assert.match(r.lines.at(-1), /^case1-accept: every F check passes/);
  assert.match(r.out, /^F5 bwrap-label pass bwrap 300 reads 'bwrap \(enforce\)' and its claude descendant 302 reads/m);
  assert.match(r.out, /^F7 pm-live pass one live launch: pm run r-0002$/m);
  assert.ok(!(r.out + r.err).includes(CRED_VALUE));
  assert.ok(existsSync(join(h.hc, "node-as-root")), "F9 runs the pinned, root-only node as root");
});

test("row 195 accept: exits 1 with each F check failing alone, and its line names it", (t) => {
  for (const [id, fault] of Object.entries(F_FAULTS)) {
    const h = host(t);
    fault(h);
    const r = mustRun(h);
    assert.equal(r.status, 1, `${id}: ${r.out}`);
    assert.deepEqual(failed(r), [id], `${id}: ${r.out}`);
    assert.equal(r.lines.at(-1), "case1-accept: an F check failed, so the row fails");
  }
});

test("row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error", (t) => {
  let h = host(t);
  put(join(h.hc, "talk-mode"), "sentonly");
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F3"]);
  assert.match(r.out, /^F3 tester-reply FAIL talk exited 0 with 1 lines on stdout; last: sent ab12cd34 to chief$/m);
  h = host(t);
  put(join(h.hc, "talk-mode"), "noreply");
  r = mustRun(h);
  assert.match(r.out, /^F3 tester-reply FAIL talk exited 1 with 1 lines on stdout; last: no reply from chief within 300 s$/m);
});

test("row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic", (t) => {
  for (const show of ["ActiveState=failed\nUser=mosaic\nMainPID=0\n", "ActiveState=active\nUser=root\nMainPID=100\n"]) {
    const h = host(t);
    put(join(h.hc, "show-mosaic-webui.service"), show);
    const r = mustRun(h);
    assert.equal(r.status, 1);
    assert.ok(failed(r).includes("F1"), r.out);
  }
});

test("row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port", (t) => {
  let h = host(t);
  put(join(h.hc, "curl-rc"), "7");
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F2"]);
  assert.match(r.out, /^F2 console-loopback FAIL curl http:\/\/127\.0\.0\.1:732\/healthz exited 7$/m);
  h = host(t);
  put(join(h.hc, "ss"), SS.replace("pid=200,fd=21", "pid=555,fd=4"));
  r = mustRun(h);
  assert.deepEqual(failed(r), ["F2"]);
});

test("row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space", (t) => {
  for (const label of ["unpriv_bwrap (enforce)\n", "bwrap//&unpriv_bwrap (complain)\n", `${CHILD} \n`]) {
    const h = host(t);
    put(join(h.root, "proc", "302", "attr", "current"), label);
    const r = mustRun(h);
    assert.deepEqual(failed(r), ["F5"], `${JSON.stringify(label)}: ${r.out}`);
  }
  const h = host(t);
  put(join(h.root, "proc", "300", "attr", "current"), `${OUTER} \n`);
  assert.deepEqual(failed(mustRun(h)), ["F5"]);
});

test("row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone", (t) => {
  let h = host(t);
  proc(h.root, 300, { ppid: 100, uid: 1001, exe: "/usr/bin/bwrap", comm: "bwrap", label: `${OUTER}\n` });
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F5"]);
  assert.match(r.out, /^F5 bwrap-label FAIL no \/usr\/bin\/bwrap process of mosaic/m);
  h = host(t);
  proc(h.root, 302, { ppid: 301, argv0: "/proc/self/fd/3", comm: "claude", label: `${CHILD}\n` });
  assert.deepEqual(failed(mustRun(h)), []);
});

test("row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment", (t) => {
  let h = host(t);
  put(join(h.hc, "claude-version"), "");
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F6"]);
  h = host(t);
  const other = CLAUDE.replace(`claude-${CLAUDE_PIN}`, "claude-2.0.9");
  put(h.args, ARGS.map((a) => (a === CLAUDE ? other : a)).join("\n") + "\n", 0o644);
  put(join(h.root, other), `#!/usr/bin/env bash\necho "${CLAUDE_PIN} (Claude Code)"\n`, 0o755);
  r = mustRun(h);
  assert.deepEqual(failed(r), ["F6"]);
  assert.match(r.out, /^F6 claude-pin FAIL --claude \S+claude-2\.0\.9\S+ is not under \/opt\/mosaic-stack\/claude-2\.1\.0\/$/m);
  // Under claude-<pin>/ by prefix, but the binary it names is 2.0.9's, which answers with the pin.
  h = host(t);
  const dotdot = CLAUDE.replace(`claude-${CLAUDE_PIN}/`, `claude-${CLAUDE_PIN}/../claude-2.0.9/`);
  put(h.args, ARGS.map((a) => (a === CLAUDE ? dotdot : a)).join("\n") + "\n", 0o644);
  put(join(h.root, other), `#!/usr/bin/env bash\necho "${CLAUDE_PIN} (Claude Code)"\n`, 0o755);
  r = mustRun(h);
  assert.deepEqual(failed(r), ["F6"], r.out);
  assert.match(r.out, /^F6 claude-pin FAIL --claude \S+\/claude-2\.1\.0\/\.\.\/claude-2\.0\.9\/\S+ has a \.\. segment$/m);
});

test("row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by", (t) => {
  const two = [{ instance: "pm", live: true, business: "mosaic-stack", run: "a" }, { instance: "pm", live: true, business: "mosaic-stack", run: "b" }];
  for (const [file, text] of [["launches.json", JSON.stringify(two)], ["launches.json", JSON.stringify([{ instance: "pm", live: true, business: "other", run: "a" }])]]) {
    const h = host(t);
    put(join(h.hc, file), text);
    assert.deepEqual(failed(mustRun(h)), ["F7"]);
  }
  const h = host(t);
  put(join(h.root, HOME, ".config", "mosaic-dev", "businesses", "mosaic-stack.json"), JSON.stringify({ id: "mosaic-stack" }));
  const r = mustRun(h);
  assert.deepEqual(failed(r), ["F7"]);
  assert.match(r.out, /^F7 pm-live FAIL the business file has no launch\.by$/m);
});

test("row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential", (t) => {
  for (const fault of [
    (h) => put(join(h.hc, "stat-cred"), "mosaic 640 regular file\n"),
    (h) => put(join(h.hc, "stat-cred"), "root 600 regular file\n"),
    (h) => { const f = join(h.root, CRED); rmSync(f); put(`${f}.real`, `X=${CRED_VALUE}\n`, 0o600); symlinkSync(`${f}.real`, f); },
  ]) {
    const h = host(t);
    fault(h);
    const r = mustRun(h);
    assert.deepEqual(failed(r), ["F8"], r.out);
    assert.ok(!(r.out + r.err).includes(CRED_VALUE));
  }
});

test("row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag", (t) => {
  for (const fault of [
    (h) => put(join(h.hc, "stat-settings"), "root:root 664 regular file\n"),
    (h) => put(join(h.hc, "stat-settings"), "mosaic:root 644 regular file\n"),
    (h) => put(join(h.root, "etc", "claude-code", "managed-settings.json"), JSON.stringify({ env: { DISABLE_AUTOUPDATER: 1 } })),
  ]) {
    const h = host(t);
    fault(h);
    assert.deepEqual(failed(mustRun(h)), ["F9"]);
  }
});

test("row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it", (t) => {
  // Another node that works for the stack's user: F9 refuses to run it, and F10 fails on the path.
  let h = host(t);
  const other = NODE.replace(NODE_PIN, "v24.0.9");
  put(h.args, ARGS.map((a) => (a === NODE ? other : a)).join("\n") + "\n", 0o644);
  put(join(h.root, other), `#!/usr/bin/env bash\n${NODE_STUB}\n`, 0o755);
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F9", "F10"], r.out);
  assert.match(r.out, /^F9 autoupdater-off FAIL root won't run --node \/opt\/mosaic-stack\/node-v24\.0\.9\/bin\/node: it is not the --node-pin path$/m);
  assert.ok(!existsSync(join(h.hc, "node-as-root")));
  // The pinned path, under a group-writable directory and then a symlinked node: F9 alone fails, and
  // root doesn't run it.
  for (const [fault, bad] of [
    [(x) => chmodSync(join(x.root, dirname(NODE)), 0o775), "/opt/mosaic-stack/node-v24\\.1\\.0/bin \\(uid \\d+, mode 775\\)"],
    [(x) => { const f = join(x.root, NODE); renameSync(f, `${f}.real`); symlinkSync(`${f}.real`, f); }, "/opt/mosaic-stack/node-v24\\.1\\.0/bin/node \\(uid \\d+, mode 777\\)"],
  ]) {
    h = host(t);
    fault(h);
    r = mustRun(h);
    assert.deepEqual(failed(r), ["F9"], r.out);
    assert.match(r.out, new RegExp(`^F9 autoupdater-off FAIL root won't run --node \\S+: ${bad} is not root's alone$`, "m"));
    assert.ok(!existsSync(join(h.hc, "node-as-root")));
  }
});

test("row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory", (t) => {
  let h = host(t);
  put(join(h.root, HOME, ".mosaic-dev", "discord", "chief.json"), "{}");
  let r = mustRun(h);
  assert.deepEqual(failed(r), ["F11"]);
  assert.match(r.out, /^F11 no-discord FAIL \/srv\/mosaic\/\.mosaic-dev\/discord holds bindings: chief\.json$/m);
  h = host(t);
  mkdirSync(join(h.root, HOME, ".mosaic-dev", "discord"), { recursive: true });
  assert.deepEqual(failed(mustRun(h)), []);
});

// Each P check in its unnamed mark, with the line count each fault makes; none changes the exit.
const P_FAULTS = {
  P1: [1, (h) => put(join(h.hc, "sudo-l-mosaic"), "User mosaic may run the following commands on dev-53:\n")],
  P2: [1, (h) => put(join(h.root, HOME, ".ssh", "authorized_keys"), "ssh-ed25519 AAAA test\n")],
  P5: [1, (h) => edit(join(h.root, "etc", "group"), (s) => s.replace("docker:x:999:", "docker:x:999:jarvis"))],
  P6: [2, (h) => edit(join(h.root, "etc", "group"), (s) => s.replace("sudo:x:27:localadmin", "sudo:x:27:localadmin,bob").replace("lxd:x:998:", "lxd:x:998:carol"))],
  P7: [1, (h) => put(join(h.root, "etc", "sudoers.d", "50-mosaic"), "mosaic ALL=(root) NOPASSWD: /usr/bin/systemctl\n")],
  P8: [1, (h) => put(join(h.hc, "ss"), `${SS}LISTEN 0 511 0.0.0.0:7331 0.0.0.0:* users:(("node",pid=200,fd=23))\n`)],
  P9: [3, (h) => { put(join(h.hc, "hostcheck-out"), HOSTCHECK_OK.replace("ok 2 ", "FAIL 2 ").replace("ok 5 ", "FAIL 5 ")); put(join(h.hc, "jarvis-bwrap-rc"), "0"); }],
  P10: [1, (h) => put(join(h.root, "proc", "sys", "net", "ipv4", "ip_unprivileged_port_start"), "700\n")],
  P11: [1, (h) => put(join(h.hc, "show-mosaic-hostcheck.service"), "Before=mosaic-bus@other.service multi-user.target\n")],
};

test("row 195 accept: each P check reports unnamed on its fault, and the exit stays 0", (t) => {
  for (const [id, [n, fault]] of Object.entries(P_FAULTS)) {
    const h = host(t);
    fault(h);
    const r = run(h);
    assert.equal(r.status, 0, `${id}: ${r.out}`);
    assert.deepEqual(marksOf(r, id), Array(n).fill("unnamed"), `${id}: ${r.out}`);
  }
});

test("row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker", (t) => {
  let h = host(t);
  put(join(h.root, "etc", "group"), GROUP.replace("lxd:x:998:", "lxd:x:998:mosaic"));
  let r = run(h);
  assert.equal(r.status, 0);
  assert.deepEqual(marksOf(r, "P2"), ["unnamed"]);
  assert.match(r.out, /^P2 mosaic-groups-keys unnamed id -G is '997 998'; authorized_keys is absent$/m);
  h = host(t);
  P_FAULTS.P5[1](h);
  r = run(h);
  assert.match(r.out, /^P5 jarvis-reach unnamed jarvis is in docker$/m);
  assert.match(r.out, /^P6 group-docker unnamed jarvis is a member of docker$/m);
});

test("row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys", (t) => {
  const h = host(t);
  put(join(h.root, "etc", "passwd"), PASSWD.replace(/^jarvis:.*\n/m, ""));
  put(join(h.root, HOME, ".ssh", "authorized_keys"), "");
  const r = run(h);
  assert.deepEqual(marksOf(r, "P5"), ["closed"]);
  assert.deepEqual(marksOf(r, "P2"), ["closed"]);
});

test("row 195 accept: P9 is unnamed once for each item missing", (t) => {
  const items = {
    hostcheck: (h) => put(join(h.hc, "hostcheck-out"), HOSTCHECK_OK.replace("ok 3 ", "FAIL 3 ")),
    jarvis: (h) => { put(join(h.hc, "jarvis-bwrap-rc"), "0"); put(join(h.hc, "jarvis-bwrap"), ""); },
    member: (h) => put(join(h.root, "etc", "group"), GROUP.replace("mosaic:x:997:", "mosaic:x:997:jarvis")),
    gid: (h) => put(join(h.root, "etc", "passwd"), `${PASSWD}hermes:x:1002:997::/home/hermes:/bin/bash\n`),
  };
  for (const [name, fault] of Object.entries(items)) {
    const h = host(t);
    fault(h);
    const r = run(h);
    assert.equal(r.status, 0);
    assert.deepEqual(marksOf(r, "P9"), ["unnamed"], `${name}: ${r.out}`);
  }
  const h = host(t);
  put(join(h.hc, "hostcheck-out"), "");
  assert.deepEqual(marksOf(run(h), "P9"), Array(6).fill("unnamed"));
});

test("row253 accept: P10 fails its observation with another peer; P11 with the unit disabled", (t) => {
  let h = host(t);
  put(join(h.hc, "peer"), "555 997 997\n");
  let r = run(h);
  assert.equal(r.status, 0);
  assert.deepEqual(marksOf(r, "P10"), ["unnamed"]);
  assert.match(r.out, /P10 tester-socket-squat unnamed boundary=failed reason=peer/);
  h = host(t);
  put(join(h.hc, "enabled-mosaic-hostcheck.service"), "disabled\n");
  r = run(h);
  assert.deepEqual(marksOf(r, "P11"), ["unnamed"]);
});

test("row 195 accept: every P check unnamed together still exits 0", (t) => {
  const h = host(t);
  for (const [, fault] of Object.values(P_FAULTS)) fault(h);
  const r = run(h);
  assert.equal(r.status, 0, r.out + r.err);
  assert.deepEqual(failed(r), []);
  for (const id of ["P1", "P2", "P5", "P6", "P7", "P8", "P9", "P10", "P11"]) assert.ok(marksOf(r, id).every((m) => m === "unnamed"), id);
  assert.match(r.lines.at(-1), /^case1-accept: every F check passes/);
});

test("row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason", (t) => {
  const bad = {
    "group write": [(h) => chmodSync(h.args, 0o664), /dev\.args must be \S+'s with no group or other write \(it is uid \d+, mode 664\)$/],
    symlink: [(h) => { put(`${h.args}.real`, ARGS.join("\n") + "\n", 0o644); rmSync(h.args); symlinkSync(`${h.args}.real`, h.args); }, /no regular file \/etc\/mosaic-stack\/dev\.args$/],
    "unknown flag": [(h) => put(h.args, ["--send", ...ARGS].join("\n") + "\n", 0o644), /has --send before --, which case2-unit\.sh does not take$/],
    "two copies": [(h) => put(h.args, ["--copy", COPY, ...ARGS].join("\n") + "\n", 0o644), /needs exactly one --copy before --, not 2$/],
    "library profile": [(h) => put(h.args, ARGS.map((a) => (a === "factory" ? "library" : a)).join("\n") + "\n", 0o644), /has --profile 'library', not factory$/],
    "another business": [(h) => put(h.args, ARGS.map((a, i) => (a === "mosaic-stack" && i < 14 ? "acme" : a)).join("\n") + "\n", 0o644), /is for business acme, not mosaic-stack$/],
    "no tester socket": [(h) => put(h.args, ARGS.slice(0, -1).join("\n") + "\n", 0o644), /needs one bare --tester-socket after --$/],
    "retired TCP": [(h) => put(h.args, [...ARGS.slice(0,-1),'--tester-port','7333'].join('\n')+'\n',0o644), /case1-accept.sh retires tester TCP; use --tester-socket$/],
    "socket value": [(h) => put(h.args, [...ARGS,'7333'].join('\n')+'\n',0o644), /unknown serve flag 7333$/],
    "duplicate socket": [(h) => put(h.args, [...ARGS,'--tester-socket'].join('\n')+'\n',0o644), /needs one bare --tester-socket after --$/],
    "short copy": [(h) => put(h.args, ARGS.map((a) => (a === COPY ? "abc123" : a)).join("\n") + "\n", 0o644), /lacks a plain --user, --home, --business, --node, --claude or --copy$/],
    "no file": [(h) => rmSync(h.args), /no regular file \/etc\/mosaic-stack\/dev\.args$/],
  };
  for (const [name, [fault, why]] of Object.entries(bad)) {
    const h = host(t);
    fault(h);
    const r = run(h);
    assert.equal(r.status, 2, `${name}: ${r.out}${r.err}`);
    assert.match(r.err.trimEnd(), /^case1-accept: refusing: /, name);
    assert.match(r.err.trimEnd(), why, name);
    assert.equal(r.out, "", name);
    assert.ok(!existsSync(join(h.hc, "calls.log")), name);
  }
});

test("row 195 accept: usage errors and a run without --root as a user exit 2", (t) => {
  const h = host(t);
  let r = run(h, {}, ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--node-pin", NODE_PIN, "--root", h.root]);
  assert.equal(r.status, 2);
  assert.match(r.err, /^usage: /);
  r = run(h, {}, ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--claude-pin", CLAUDE_PIN, "--node-pin", "24.1.0", "--root", h.root]);
  assert.equal(r.status, 2);
  r = run(h, {}, ["--business", "mosaic-stack", "--args", "/etc/mosaic-stack/dev.args", "--claude-pin", CLAUDE_PIN, "--node-pin", NODE_PIN]);
  assert.equal(r.status, 2);
  assert.equal(r.err, "case1-accept: refusing: run it as root\n");
  assert.ok(!existsSync(join(h.hc, "calls.log")));
});

test("row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...", (t) => {
  const h = host(t);
  const r = run(h);
  assert.equal(r.status, 0, r.out + r.err);
  const sudo = calls(h, "sudo");
  const asMosaic = sudo.filter((a) => a.startsWith("-u mosaic"));
  const isolated = asMosaic.filter(a=>a.startsWith('-u mosaic -H env -i '));
  assert.equal(isolated.length, 2);
  for(const a of isolated) assert.ok(a.startsWith(`-u mosaic -H env -i HOME=${HOME} PATH=/opt/mosaic-stack/node-${NODE_PIN}/bin:/usr/local/bin:/usr/bin:/bin `),a);
  for (const a of asMosaic.filter(a=>!isolated.includes(a))) assert.ok(a.startsWith(`${AS_MOSAIC} /`), a);
  const cmds = asMosaic.filter(a=>!isolated.includes(a)).map((a) => a.slice(AS_MOSAIC.length + 1).split(" ")[0]);
  assert.deepEqual([...new Set(cmds)].sort(), [CLI, PRECHECK, CLAUDE, NODE].sort());
  assert.deepEqual(sudo.filter((a) => !a.startsWith("-u mosaic")).sort(),
    ["-l -U localadmin", "-l -U mosaic", "-u jarvis /usr/bin/bwrap --version"]);
  const talk = calls(h, "mosaic").filter((a) => a.startsWith("talk "));
  assert.equal(talk.length, 1);
  assert.match(talk[0], /^talk chief case1-accept-[0-9a-f]{12}: .* --business mosaic-stack --tester --wait 300$/);
  assert.deepEqual(calls(h, "precheck"), ["--business mosaic-stack --profile factory"]);
});

test("row 195 accept: the host check runs with --check and never --enforce", (t) => {
  const h = host(t);
  run(h);
  assert.deepEqual(calls(h, "hostcheck"), ["--check"]);
});
