#!/usr/bin/env bash
# Contract tests for the remote seat launcher. Local only — no buildbox, no engine, no network
# beyond a DNS miss. Proves the WRAPPER-CONTRACT exit codes survive the remoting layer.
set -uo pipefail

# Every launcher run here must execute EXACTLY as typed. The ~/.claude/bin node shim re-routes a
# node invocation through the local-gate onto a buildbox, where the fixture's BUILD_REMOTE_CONFIG
# and temp repo do not exist — the contract codes then measure the offload, not the launcher.
PATH="$(printf '%s' "$PATH" | tr ':' '\n' | grep -vx "$HOME/.claude/bin" | paste -sd:)"

# Seat/agent runtimes inject HARNESS_SEAT_CONTAINER=1. Contract tests must exercise the
# workstation shim path, not the in-container re-entry short-circuit.
unset HARNESS_SEAT_CONTAINER

SEAT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LAUNCHER="$SEAT_DIR/remote-seat.mjs"
PASS=0 FAIL=0
ok()   { PASS=$((PASS+1)); echo "PASS $1"; }
bad()  { FAIL=$((FAIL+1)); echo "FAIL $1"; }
check(){ [[ "$2" == "$3" ]] && ok "$1 ($2)" || bad "$1: expected $3, got $2"; }
reason(){ [[ "$2" == *"$3"* ]] && ok "$1" || bad "$1: expected reason '$3', got: $2"; }

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

# Without a runnable spine CLI the launcher dies on its top-level backstop before reaching the
# transport, and every rc-3 assertion below passes for the wrong reason.
TRANSPORT="$SEAT_DIR/../../workstation/claude/lib/remote-build.mjs"
printf '{"enabled":false,"port":22,"ssh_user":"user","remote_root":"/home/user/builds"}\n' \
  > "$TMP/spine-preflight.json"
if ! PREFLIGHT="$(BUILD_REMOTE_CONFIG="$TMP/spine-preflight.json" node --input-type=module -e "
import { SPINE_CLI, loadRemoteConfig } from '$TRANSPORT';
process.stderr.write('spine cli: ' + SPINE_CLI + '\n');
loadRemoteConfig();
" 2>&1)"; then
  echo "ABORT seat-contract: the spine CLI cannot execute — the seat contract cannot be measured."
  echo "$PREFLIGHT"
  echo "fix: install the repo spine deps (bun install in spine/) or repair the deploy clone spine."
  exit 1
fi

# --- usage errors stay local and exit 2 (no ssh round trip) ---
node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$TMP" --task-slug s >/dev/null 2>&1
check "missing --trust is a usage error" "$?" 2
node "$LAUNCHER" --bogus x >/dev/null 2>&1
check "unknown flag is a usage error" "$?" 2

# --- adapter gating: blocked adapters and the kill switch never dispatch ---
for adapter in north pi grok canary; do
  node "$LAUNCHER" --check "$adapter" >/dev/null 2>&1
  check "adapter $adapter is not remoted" "$?" 1
done
node "$LAUNCHER" --check codex >/dev/null 2>&1
check "adapter codex is remoted" "$?" 0
node "$LAUNCHER" --check claude >/dev/null 2>&1
check "adapter claude is remoted" "$?" 0
HARNESS_SEAT_REMOTE=0 node "$LAUNCHER" --check codex >/dev/null 2>&1
check "HARNESS_SEAT_REMOTE=0 no longer forces local" "$?" 0
HARNESS_SEAT_CONTAINER=1 node "$LAUNCHER" --check codex >/dev/null 2>&1
check "in-container re-entry forces local (no infinite remoting)" "$?" 1

# --- transport failure is exit 3: engine down, nothing dispatched ---
REPO="$TMP/repo"
mkdir -p "$REPO"
git -C "$REPO" init -q
printf '/seat-prompt-*.txt\n.harness-seat/\n' > "$REPO/.gitignore"
git -C "$REPO" add -A
git -C "$REPO" -c user.name=t -c user.email=t@t commit -q -m base
cat > "$TMP/build-remote.json" <<JSON
{"enabled":true,"port":2222,"ssh_user":"user",
 "remote_root":"/home/user/builds","identity_file":"~/.ssh/id_ed25519_buildbox",
 "local_fallback":false,"local_only":[],"max_remote_jobs":1}
JSON
# The fleet declaration names the build hosts and the registry supplies their state, so an
# unreachable host is spoofed across both, never in the transport config.
cat > "$TMP/fleet.json" <<'JSON'
{"schema_version":1,
 "nodes":{"workstation":{"transport":"local","roles":["control","agent-runtime"],
            "profiles":["shared-agent-tools","workstation"],"execution":"last-resort"},
          "seatfail":{"transport":"ssh","host_ref":"seatfail","roles":["builder","agent-runtime"],
            "profiles":["shared-agent-tools","buildbox"],"execution":"normal"}},
 "fallback":{"enabled":false,"node":"workstation","requires_all_unavailable":["seatfail"],
   "max_concurrent_local_jobs":1,"activation_windows":3,"health_window_sec":60,"lease_ttl_sec":900}}
JSON
cat > "$TMP/buildbox-hosts.json" <<'JSON'
{"schema_version":1,
 "hosts":[{"name":"selfbox","ssh_alias":"selfbox.invalid","state":"reachable",
   "machine_id":"11111111111111111111111111111111","roles":["builder","agent-seat"],
   "access":{"lan":{"host":"selfbox.invalid","port":2222,"user":"user","identity_file":null},
             "tailscale_ip":null,"tailscale_ssh":null},
   "rustdesk":null,"notes":"fixture identity, excluded from build order"},
  {"name":"seatfail","ssh_alias":"seat-transport-failure.invalid","state":"reachable",
   "machine_id":"00000000000000000000000000000000","roles":["builder","agent-seat"],
   "access":{"lan":{"host":"seat-transport-failure.invalid","port":2222,"user":"user","identity_file":null},
             "tailscale_ip":null,"tailscale_ssh":null},
   "rustdesk":null,"notes":"fixture host that never resolves"}],
 "orders":{"build":["seatfail"],"e2e":["seatfail"]}}
JSON
export BUILDBOX_HOSTS_CONFIG="$TMP/buildbox-hosts.json"
export DECKCTL_FLEET_FILE="$TMP/fleet.json"
export OVERDECK_SEAT_HOST=selfbox
ERR="$(BUILD_REMOTE_CONFIG="$TMP/build-remote.json" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$REPO" \
    --trust "noop" --task-slug transportfail --model gpt-5.6-terra-low 2>&1 >/dev/null)"
check "unreachable host is exit 3 (engine down)" "$?" 3
reason "unreachable host exits 3 for a transport refusal" "$ERR" "remote seat not run:"

# --- remoting switched off is rc 70: the wrapper runs locally, it does not fail ---
cat > "$TMP/build-remote-off.json" <<JSON
{"enabled":false,"port":2222,"ssh_user":"user",
 "remote_root":"/home/user/builds","identity_file":"~/.ssh/id_ed25519_buildbox",
 "local_fallback":true,"local_only":[],"max_remote_jobs":1}
JSON
BUILD_REMOTE_CONFIG="$TMP/build-remote-off.json" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$REPO" \
    --trust "noop" --task-slug remoteoff --model gpt-5.6-terra-low >/dev/null 2>&1
BUILD_REMOTE_CONFIG="$TMP/build-remote-off.json" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$REPO" \
    --trust "noop" --task-slug remoteoff --model gpt-5.6-terra-low --permission-mode safe >/dev/null 2>&1
check "permission mode parses and preserves local-only rc" "$?" 70

# --- ignored runtime overlays: any repo must be self-provisioned, not just ours ---
IGNORED="$TMP/ignored"
mkdir -p "$IGNORED"
git -C "$IGNORED" init -q
git -C "$IGNORED" -c user.name=t -c user.email=t@t commit -q --allow-empty -m base
dispatch_ignored() {
  ERR="$(BUILD_REMOTE_CONFIG="$TMP/build-remote.json" \
    node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$1" \
      --trust "noop" --task-slug promptignore --model gpt-5.6-terra-low 2>&1 >/dev/null)"
}
dispatch_ignored "$IGNORED"
git -C "$IGNORED" check-ignore -q .harness-seat/probe
check "a repo with no .gitignore is self-provisioned for runtime overlays" "$?" 0
check "the patterns land in info/exclude, not the tracked .gitignore" "$(ls -A "$IGNORED" | grep -c gitignore)" 0
check "the dispatch never materializes the prompt in the repository" "$(ls "$IGNORED" | grep -c seat-prompt)" 0
dispatch_ignored "$IGNORED"
check "provisioning is idempotent across dispatches" "$(grep -c 'seat-prompt' "$IGNORED/.git/info/exclude")" 1

# a linked worktree shares the common dir: provisioning it once must cover the whole repo
git -C "$IGNORED" worktree add -q -b wtprobe "$TMP/ignored-wt" >/dev/null 2>&1
dispatch_ignored "$TMP/ignored-wt"
git -C "$TMP/ignored-wt" check-ignore -q seat-prompt-probe.txt
check "a linked worktree is covered by the same common-dir exclude" "$?" 0
check "the worktree dispatch did not append a second copy" "$(grep -c 'seat-prompt' "$IGNORED/.git/info/exclude")" 1

# the released launcher must carry its runner into repositories that do not contain harness source
CAPTURE="$TMP/dispatch.json"
cat > "$TMP/fake-transport.mjs" <<'JS'
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
export const loadRemoteConfig = () => ({ enabled: true, ship_ignored: [] });
export const projectRoot = () => process.env.FAKE_ROOT;
export const tryRemoteBuild = (request, options) => {
  const runner = request.argv[0];
  const runtime = dirname(dirname(runner));
  writeFileSync(process.env.FAKE_CAPTURE, JSON.stringify({
    argv: request.argv,
    privateInputMatches: request.privateInput === "noop",
    cleanupRemote: request.cleanupRemote,
    config: options.loadRemoteConfig(),
    runnerExists: existsSync(runner),
    runner: readFileSync(runner, "utf8"),
    wrapperExists: existsSync(join(runtime, "wrappers", "codex.sh")),
    credentialsExist: existsSync(join(runtime, "seat", "credentials.json")),
    reconcilerExists: existsSync(join(runtime, "seat", "seat-reconcile.sh")),
  }));
  return { ran: false, reason: "unreachable-or-full" };
};
JS
HARNESS_SEAT_TRANSPORT="$TMP/fake-transport.mjs" FAKE_ROOT="$IGNORED" FAKE_CAPTURE="$CAPTURE" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$IGNORED" \
    --trust "noop" --task-slug bundled-runner --model gpt-5.6-terra-low >/dev/null 2>&1
check "a target without harness source reaches transport" "$?" 3
node --input-type=module -e "
import { readFileSync } from 'node:fs';
const capture = JSON.parse(readFileSync('$CAPTURE', 'utf8'));
const runnerRel = capture.argv[0].slice('$IGNORED/'.length);
const runtimeRel = runnerRel.replace(/\/seat\/seat-run\.sh$/, '');
if (!capture.runnerExists || capture.runner !== readFileSync('$SEAT_DIR/seat-run.sh', 'utf8')) process.exit(1);
if (!capture.wrapperExists || !capture.credentialsExist || !capture.reconcilerExists) process.exit(2);
if (!capture.config.ship_ignored.includes(runnerRel)) process.exit(3);
if (!runnerRel.match(/^\.harness-seat\/[^/]+\/runtime\/seat\/seat-run\.sh$/)) process.exit(4);
if (!capture.privateInputMatches) process.exit(5);
if (capture.cleanupRemote.length !== 1 || !capture.cleanupRemote.includes(runtimeRel)) process.exit(6);
if (capture.config.ship_ignored.some((path) => path.includes('seat-prompt-'))) process.exit(7);
if (capture.argv.includes('--permission-mode')) process.exit(8);
if (capture.argv[0] === 'bash' || !capture.argv[0].startsWith('/')) process.exit(9);
"
check "the bundled runner rides the ignored overlay" "$?" 0
check "the local runner overlay is cleaned after dispatch" "$(find "$IGNORED/.harness-seat" -name seat-run.sh -print 2>/dev/null | wc -l)" 0

CAPTURE_SAFE="$TMP/dispatch-safe.json"
HARNESS_SEAT_TRANSPORT="$TMP/fake-transport.mjs" FAKE_ROOT="$IGNORED" FAKE_CAPTURE="$CAPTURE_SAFE" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$IGNORED" \
    --trust "noop" --task-slug incident-forward --model gpt-5.6-terra-low \
    --profile profile-a --permission-mode safe >/dev/null 2>&1
check "incident-safe dispatch reaches transport failure without local fallback" "$?" 3
node --input-type=module -e "
import { readFileSync } from 'node:fs';
const argv = JSON.parse(readFileSync('$CAPTURE_SAFE', 'utf8')).argv;
const profile = argv.indexOf('--profile');
const mode = argv.indexOf('--permission-mode');
if (profile < 0 || mode < profile || argv[mode + 1] !== 'safe') process.exit(1);
"
check "profile and safe permission mode reach seat-run in order" "$?" 0

launcher_refuses() {
  local name="$1"; shift
  local capture="$TMP/refuse-launcher-$name.json"
  rm -f "$capture"
  HARNESS_SEAT_TRANSPORT="$TMP/fake-transport.mjs" FAKE_ROOT="$IGNORED" FAKE_CAPTURE="$capture" \
    node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$IGNORED" \
      --trust "noop" --task-slug incident-refuse --model gpt-5.6-terra-low "$@" >/dev/null 2>&1
  check "launcher refuses $name permission mode" "$?" 2
  check "launcher $name refusal dispatches nothing" "$([[ -e "$capture" ]]; printf '%s' "$?")" 1
}
launcher_refuses missing
launcher_refuses empty --permission-mode ""
launcher_refuses unknown --permission-mode nope
launcher_refuses duplicate --permission-mode safe --permission-mode safe

# --- wrapper shim: remote rc is terminal; ordinary callers retain their original argv ---
SHIM="$SEAT_DIR/../wrappers/lib/remote-seat.sh"
mkdir -p "$TMP/fake-bin"
cat > "$TMP/fake-bin/node" <<'SH'
#!/usr/bin/env bash
if [[ "${2:-}" == "--check" ]]; then exit "${FAKE_CHECK_RC:-0}"; fi
printf '%s\0' "$@" > "$FAKE_NODE_CAPTURE"
exit "${FAKE_DISPATCH_RC:-0}"
SH
chmod +x "$TMP/fake-bin/node"
shim_run() {
  local capture="$1"; shift
  PATH="$TMP/fake-bin:$PATH" FAKE_NODE_CAPTURE="$capture" "$@"
}
SHIM_CAPTURE="$TMP/shim-ordinary"
shim_run "$SHIM_CAPTURE" env FAKE_DISPATCH_RC=0 bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt factory-probe model 30 "" "" --thread-id ""' _ "$SHIM"
check "ordinary Factory Codex remote dispatch preserves rc" "$?" 0
node -e "const a=require('fs').readFileSync('$SHIM_CAPTURE').toString().split('\\0');if(a.includes('--permission-mode'))process.exit(1)"
check "ordinary Factory Codex dispatch adds no permission mode" "$?" 0

SHIM_SAFE="$TMP/shim-safe"
shim_run "$SHIM_SAFE" env FAKE_DISPATCH_RC=0 bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt incident-probe model 30 profile-a safe --thread-id tid' _ "$SHIM"
check "incident-safe shim dispatch preserves rc" "$?" 0
node -e "const a=require('fs').readFileSync('$SHIM_SAFE').toString().split('\\0');const p=a.indexOf('--profile'),m=a.indexOf('--permission-mode');if(p<0||m<p||a[m+1]!=='safe')process.exit(1)"
check "shim forwards safe mode after profile" "$?" 0

SHIM_CLAUDE="$TMP/shim-claude"
shim_run "$SHIM_CLAUDE" env FAKE_DISPATCH_RC=0 bash -c \
  'source "$1"; seat_remote_dispatch claude claude.sh /work prompt factory-claude model 30 ignored --resume session-a' _ "$SHIM"
check "ordinary non-Codex seat caller preserves rc" "$?" 0
node -e "const a=require('fs').readFileSync('$SHIM_CLAUDE').toString().split('\\0');const r=a.indexOf('--resume');if(r<0||a[r+1]!=='session-a'||a.includes('--permission-mode'))process.exit(1)"
check "ordinary non-Codex continuation args are unchanged" "$?" 0

SHIM_FAIL="$TMP/shim-fail"
FALLBACK_SENTINEL="$TMP/local-fallback"
shim_run "$SHIM_FAIL" env FAKE_DISPATCH_RC=3 FALLBACK_SENTINEL="$FALLBACK_SENTINEL" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt incident-fail model 30 "" safe --thread-id ""; : > "$FALLBACK_SENTINEL"' _ "$SHIM"
check "remote failure exits with engine-down rc" "$?" 3
check "remote failure performs zero local fallback" "$([[ -e "$FALLBACK_SENTINEL" ]]; printf '%s' "$?")" 1

CHECK_FAIL_CAPTURE="$TMP/shim-check-fail"
CHECK_FAIL_FALLBACK="$TMP/check-fail-local-fallback"
shim_run "$CHECK_FAIL_CAPTURE" env FAKE_CHECK_RC=1 CHECK_FAIL_FALLBACK="$CHECK_FAIL_FALLBACK" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt incident-check-fail model 30 "" safe --thread-id ""; : > "$CHECK_FAIL_FALLBACK"' _ "$SHIM"
check "incident remote preflight failure is terminal engine-down" "$?" 3
check "incident remote preflight failure performs zero local fallback" "$([[ -e "$CHECK_FAIL_FALLBACK" ]]; printf '%s' "$?")" 1
check "incident remote preflight failure dispatches nothing" "$([[ -e "$CHECK_FAIL_CAPTURE" ]]; printf '%s' "$?")" 1

DISABLED_CAPTURE="$TMP/shim-disabled"
DISABLED_FALLBACK="$TMP/disabled-local-fallback"
shim_run "$DISABLED_CAPTURE" env FAKE_DISPATCH_RC=70 DISABLED_FALLBACK="$DISABLED_FALLBACK" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt incident-disabled model 30 "" safe --thread-id ""; : > "$DISABLED_FALLBACK"' _ "$SHIM"
check "disabled remote config is terminal for incident Codex" "$?" 3
check "disabled remote config performs zero incident local fallback" "$([[ -e "$DISABLED_FALLBACK" ]]; printf '%s' "$?")" 1

DISABLED_ORDINARY_FALLBACK="$TMP/disabled-ordinary-fallback"
shim_run "$TMP/shim-disabled-ordinary" env FAKE_DISPATCH_RC=70 DISABLED_ORDINARY_FALLBACK="$DISABLED_ORDINARY_FALLBACK" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt factory-disabled model 30 "" "" --thread-id "" || : > "$DISABLED_ORDINARY_FALLBACK"' _ "$SHIM"
check "disabled remote config retains ordinary local continuation" "$?" 0
check "disabled remote config can continue ordinary Codex locally" "$([[ -e "$DISABLED_ORDINARY_FALLBACK" ]]; printf '%s' "$?")" 0

CHECK_ORDINARY_FALLBACK="$TMP/check-ordinary-fallback"
shim_run "$TMP/shim-check-ordinary" env FAKE_CHECK_RC=1 CHECK_ORDINARY_FALLBACK="$CHECK_ORDINARY_FALLBACK" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt factory-check-fail model 30 "" "" --thread-id "" || : > "$CHECK_ORDINARY_FALLBACK"' _ "$SHIM"
check "ordinary Codex preflight retains local continuation contract" "$?" 0
check "ordinary Codex preflight can continue locally" "$([[ -e "$CHECK_ORDINARY_FALLBACK" ]]; printf '%s' "$?")" 0

UNSAFE_ORDINARY_FALLBACK="$TMP/unsafe-ordinary-fallback"
shim_run "$TMP/shim-unsafe-ordinary" env FAKE_CHECK_RC=1 UNSAFE_ORDINARY_FALLBACK="$UNSAFE_ORDINARY_FALLBACK" bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt factory-unsafe model 30 "" unsafe --thread-id "" || : > "$UNSAFE_ORDINARY_FALLBACK"' _ "$SHIM"
check "explicit unsafe ordinary Codex preflight retains local continuation contract" "$?" 0
check "explicit unsafe ordinary Codex can continue locally" "$([[ -e "$UNSAFE_ORDINARY_FALLBACK" ]]; printf '%s' "$?")" 0

UNSAFE_INCIDENT_CAPTURE="$TMP/shim-unsafe-incident"
shim_run "$UNSAFE_INCIDENT_CAPTURE" env FAKE_CHECK_RC=1 bash -c \
  'source "$1"; seat_remote_dispatch codex codex.sh /work prompt incident-unsafe model 30 "" unsafe --thread-id ""' _ "$SHIM"
check "explicit unsafe incident Codex remains refused" "$?" 2
check "explicit unsafe incident dispatches nothing" "$([[ -e "$UNSAFE_INCIDENT_CAPTURE" ]]; printf '%s' "$?")" 1

for mode_case in missing unknown; do
  SHIM_REFUSE="$TMP/shim-refuse-$mode_case"
  if [[ "$mode_case" == missing ]]; then mode_args='""'; else mode_args=nope; fi
  shim_run "$SHIM_REFUSE" env FAKE_DISPATCH_RC=0 bash -c \
    "source \"\$1\"; seat_remote_dispatch codex codex.sh /work prompt incident-refuse model 30 \"\" $mode_args --thread-id \"\"" _ "$SHIM"
  check "shim refuses $mode_case incident permission mode" "$?" 2
  check "shim $mode_case refusal dispatches nothing" "$([[ -e "$SHIM_REFUSE" ]]; printf '%s' "$?")" 1
done

# --- buildbox runner: exact mode reaches the container entrypoint; refusals precede podman ---
RUN_ROOT="$TMP/run-root"
RUNTIME="$RUN_ROOT/.harness-seat/test/runtime"
mkdir -p "$RUNTIME/seat" "$RUNTIME/wrappers" "$TMP/run-home" "$TMP/run-bin"
cp "$SEAT_DIR/seat-run.sh" "$RUNTIME/seat/seat-run.sh"
printf '#!/usr/bin/env bash\nexit 0\n' > "$RUNTIME/seat/seat-reconcile.sh"
printf '{"items":[]}\n' > "$RUNTIME/seat/credentials.json"
printf '#!/usr/bin/env bash\nexit 0\n' > "$RUNTIME/wrappers/probe.sh"
chmod +x "$RUNTIME/seat/seat-reconcile.sh" "$RUNTIME/wrappers/probe.sh"
git -C "$RUN_ROOT" init -q
printf 'prompt\n' > "$RUN_ROOT/prompt.txt"
cat > "$TMP/run-bin/podman" <<'SH'
#!/usr/bin/env bash
case "${1:-}" in
  image) exit 0;;
  ps) exit 0;;
  create) printf '%s\0' "$@" > "$PODMAN_CAPTURE"; printf 'container-id\n'; exit 0;;
  start) exit 0;;
  rm) exit 0;;
  *) exit 0;;
esac
SH
printf '#!/usr/bin/env bash\nexit 0\n' > "$TMP/run-bin/tmux"
chmod +x "$TMP/run-bin/podman" "$TMP/run-bin/tmux"
run_seat_runner() {
  local capture="$1" slug="$2"; shift 2
  printf 'prompt\n' > "$RUN_ROOT/prompt.txt"
  HOME="$TMP/run-home" PATH="$TMP/run-bin:$PATH" PODMAN_CAPTURE="$capture" \
    bash "$RUNTIME/seat/seat-run.sh" --run-id "run-${slug//[^a-zA-Z0-9]/}" \
      --wrapper probe.sh --repo-root "$RUN_ROOT" --workspace-rel . --prompt-file prompt.txt \
      --log-rel .harness-seat/logs --task-slug "$slug" --image fixture --memory 1g --cpus 1 \
      --pids 64 --tmpfs-size 64m --max-seats 3 "$@" >/dev/null 2>&1
}
RUN_SAFE="$TMP/run-safe"
run_seat_runner "$RUN_SAFE" incident-runner --permission-mode safe
check "seat-run accepts incident-safe mode" "$?" 0
node -e "const a=require('fs').readFileSync('$RUN_SAFE').toString().split('\\0');const m=a.indexOf('--permission-mode');if(m<0||a[m+1]!=='safe')process.exit(1)"
check "seat-run forwards safe mode to entrypoint" "$?" 0
RUN_ORDINARY="$TMP/run-ordinary"
run_seat_runner "$RUN_ORDINARY" factory-runner
check "ordinary seat-run caller remains valid without mode" "$?" 0
node -e "const a=require('fs').readFileSync('$RUN_ORDINARY').toString().split('\\0');if(a.includes('--permission-mode'))process.exit(1)"
check "ordinary seat-run caller adds no mode" "$?" 0
for mode_case in missing empty unknown duplicate; do
  RUN_REFUSE="$TMP/run-refuse-$mode_case"; rm -f "$RUN_REFUSE"
  case "$mode_case" in
    missing) args=();;
    empty) args=(--permission-mode "");;
    unknown) args=(--permission-mode nope);;
    duplicate) args=(--permission-mode safe --permission-mode safe);;
  esac
  run_seat_runner "$RUN_REFUSE" incident-refuse "${args[@]}"
  check "seat-run refuses $mode_case permission mode" "$?" 2
  check "seat-run $mode_case refusal starts no container" "$([[ -e "$RUN_REFUSE" ]]; printf '%s' "$?")" 1
done

# --- container entrypoint: relocate fixed mounts in a private fixture, preserve all dispatch logic ---
ENTRY_ROOT="$TMP/entry-root"
mkdir -p "$ENTRY_ROOT/seed" "$ENTRY_ROOT/home" "$ENTRY_ROOT/work"
printf 'prompt\n' > "$ENTRY_ROOT/seed/prompt.txt"
printf '{"items":[]}\n' > "$ENTRY_ROOT/credentials.json"
cat > "$ENTRY_ROOT/wrapper.sh" <<'SH'
#!/usr/bin/env bash
printf '%s\0' "$@" > "$CAPTURE"
SH
chmod +x "$ENTRY_ROOT/wrapper.sh"
python3 - "$SEAT_DIR/seat-entrypoint.sh" "$ENTRY_ROOT/entrypoint.sh" "$ENTRY_ROOT/seed/prompt.txt" "$ENTRY_ROOT/home" <<'PY' \
  || { echo "ABORT entrypoint fixture relocation failed" >&2; exit 1; }
from pathlib import Path
import sys
source = Path(sys.argv[1]).read_text()
assert source.count("/seed/prompt.txt") == 3
assert source.count("export HOME=/seat-home") == 1
source = source.replace("/seed/prompt.txt", sys.argv[3])
source = source.replace("export HOME=/seat-home", f"export HOME={sys.argv[4]}")
source = source.replace('"$(command -v git 2>/dev/null || true)" == /usr/local/bin/git', 'true')
source = source.replace('git --deny-gate-selftest', 'true')
Path(sys.argv[2]).write_text(source)
PY
entry_run() {
  local capture="$1" slug="$2"; shift 2
  rm -f "$capture"
  CAPTURE="$capture" HARNESS_SEAT_CREDENTIALS_MANIFEST="$ENTRY_ROOT/credentials.json" \
    bash "$ENTRY_ROOT/entrypoint.sh" --wrapper "$ENTRY_ROOT/wrapper.sh" \
      --workspace "$ENTRY_ROOT/work" --task-slug "$slug" "$@" >/dev/null
}
ENTRY_SAFE="$ENTRY_ROOT/safe"
entry_run "$ENTRY_SAFE" incident-entry --profile profile-a --permission-mode safe
check "entrypoint accepts incident-safe mode" "$?" 0
node -e "const a=require('fs').readFileSync('$ENTRY_SAFE').toString().split('\\0');const p=a.indexOf('--profile'),m=a.indexOf('--permission-mode');if(p<0||m<p||a[m+1]!=='safe')process.exit(1)"
check "entrypoint forwards safe mode after profile" "$?" 0
ENTRY_ORDINARY="$ENTRY_ROOT/ordinary"
entry_run "$ENTRY_ORDINARY" factory-entry
check "ordinary entrypoint caller remains valid without mode" "$?" 0
node -e "const a=require('fs').readFileSync('$ENTRY_ORDINARY').toString().split('\\0');if(a.includes('--permission-mode'))process.exit(1)"
check "ordinary entrypoint caller adds no mode" "$?" 0
for mode_case in missing empty unknown duplicate; do
  ENTRY_REFUSE="$ENTRY_ROOT/refuse-$mode_case"
  case "$mode_case" in
    missing) args=();;
    empty) args=(--permission-mode "");;
    unknown) args=(--permission-mode nope);;
    duplicate) args=(--permission-mode safe --permission-mode safe);;
  esac
  entry_run "$ENTRY_REFUSE" incident-refuse "${args[@]}"
  check "entrypoint refuses $mode_case permission mode" "$?" 2
  check "entrypoint $mode_case refusal invokes no wrapper" "$([[ -e "$ENTRY_REFUSE" ]]; printf '%s' "$?")" 1
done

# a bundle-copy failure must remove the partial runtime without materializing the prompt
STAGING_FAILURE="$TMP/staging-failure"
mkdir -p "$STAGING_FAILURE"
git -C "$STAGING_FAILURE" init -q
git -C "$STAGING_FAILURE" -c user.name=t -c user.email=t@t commit -q --allow-empty -m base
printf 'blocked\n' > "$STAGING_FAILURE/.harness-seat"
ERR="$(BUILD_REMOTE_CONFIG="$TMP/build-remote.json" \
  node "$LAUNCHER" --adapter codex --wrapper codex.sh --workspace "$STAGING_FAILURE" \
    --trust "staging-secret" --task-slug staging-failure --model gpt-5.6-terra-low 2>&1 >/dev/null)"
check "a runtime staging failure exits on the contract backstop (3)" "$?" 3
reason "the staging failure is the blocked runtime path" "$ERR" "/runtime/seat"
check "a runtime staging failure removes its prompt" "$(find "$STAGING_FAILURE" -maxdepth 1 -name 'seat-prompt-*' -print | wc -l)" 0
check "a runtime staging failure leaves no secret material" "$(grep -R -l --exclude-dir=.git 'staging-secret' "$STAGING_FAILURE" 2>/dev/null | wc -l)" 0
check "a runtime staging failure leaves no partial runtime" "$(find "$STAGING_FAILURE" -path '*/runtime/*' -print 2>/dev/null | wc -l)" 0

# an exclude file the launcher cannot use must still exit on a CONTRACT code, not an uncaught throw
UNWRITABLE="$TMP/unwritable"
mkdir -p "$UNWRITABLE"
git -C "$UNWRITABLE" init -q
git -C "$UNWRITABLE" -c user.name=t -c user.email=t@t commit -q --allow-empty -m base
rm -f "$UNWRITABLE/.git/info/exclude"; mkdir -p "$UNWRITABLE/.git/info/exclude"
dispatch_ignored "$UNWRITABLE"
check "an unusable info/exclude fails on the contract backstop (3)" "$?" 3
reason "the unusable info/exclude names the overlay it cannot ignore" "$ERR" "does not ignore the seat dispatch overlay"

# --- classification: a dispatch of unknown outcome must NOT claim nothing ran ---
node --input-type=module -e "
import { classifyReason } from '$LAUNCHER';
const down = ['unreachable-or-full','push-failed','transport-grace-expired','start-failed'];
const unknown = ['start-ambiguous:RUNNING','unexpected-job-state:X','invalid-job-meta','pull-failed','epoch-mismatch'];
const local = ['disabled','local_only:x'];
const bad = [...down.filter((r) => classifyReason(r) !== 3), ...unknown.filter((r) => classifyReason(r) !== 124), ...local.filter((r) => classifyReason(r) !== 70)];
if (bad.length) { console.error('misclassified: ' + bad.join(',')); process.exit(1); }
"
check "reason->rc mapping (3 = nothing ran, 124 = outcome unknown)" "$?" 0

# --- commit replay: the transport's rb snapshot must not enter the caller's history ---
REPLAY="$TMP/replay"
mkdir -p "$REPLAY"
git -C "$REPLAY" init -q
git -C "$REPLAY" config user.name t; git -C "$REPLAY" config user.email t@t
echo one > "$REPLAY/a"; git -C "$REPLAY" add -A; git -C "$REPLAY" commit -q -m base
BASE="$(git -C "$REPLAY" rev-parse HEAD)"
echo dirty > "$REPLAY/b"; git -C "$REPLAY" add -A
SNAP="$(git -C "$REPLAY" -c user.name=rb -c user.email=rb@local commit-tree "$(git -C "$REPLAY" write-tree)" -p "$BASE" -m 'rb snapshot')"
echo agent > "$REPLAY/c"; git -C "$REPLAY" add -A
AGENT="$(git -C "$REPLAY" -c user.name=Seat -c user.email=seat@box commit-tree "$(git -C "$REPLAY" write-tree)" -p "$SNAP" -m 'seat work')"
git -C "$REPLAY" reset -q --mixed "$BASE"
node --input-type=module -e "
import { replayAgentCommits } from '$LAUNCHER';
replayAgentCommits('$REPLAY', '$BASE', '$AGENT', () => {});
"
SUBJECTS="$(git -C "$REPLAY" log --format=%s "$BASE"..HEAD | tr '\n' ',')"
check "seat commit replayed without the rb snapshot" "$SUBJECTS" "seat work,"
check "replayed commit keeps the seat author" "$(git -C "$REPLAY" log -1 --format=%ae)" "seat@box"

# --- a rebooted buildbox must not report a code the orchestrator can misread ---
node --input-type=module -e "
import { contractRc, classifyReason, SEAT_CONTRACT_RC } from '$LAUNCHER';
const eq = (a, b, what) => { if (a !== b) { console.error(what + ': expected ' + b + ', got ' + a); process.exit(1); } };
// the transport's own codes, none of which are wrapper codes
eq(contractRc({ status: 254, classification: 'remote-job-disappeared' }), 124, 'job vanished with the box');
eq(contractRc({ status: 0, classification: 'remote-job-disappeared' }), 124, 'a vanished job is never a success');
eq(contractRc({ status: 254 }), 124, 'bare 254 is not a contract code');
eq(contractRc({ status: 143 }), 124, 'a signal code is not a contract code');
// a real wrapper result still passes through untouched
for (const rc of SEAT_CONTRACT_RC) eq(contractRc({ status: rc, classification: 'remote-rc' }), rc, 'wrapper rc ' + rc + ' passes through');
// the two grace expiries mean opposite things to a caller deciding whether to re-dispatch
eq(classifyReason('transport-grace-expired'), 3, 'expiry BEFORE dispatch is nothing-ran');
eq(classifyReason('transport-grace-expired-after-start'), 124, 'expiry AFTER dispatch is outcome-unknown');
"
check "a rebooted box reports 124, never a raw transport code" "$?" 0

echo "---- seat-contract: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]]
