#!/usr/bin/env bash
# Containment tests for the seat container. Runs ON a buildbox (never on the workstation).
#
#   modules/harness/seat/test/seat-containment.test.sh [debian1]
#
# Reads the KERNEL's view — cgroup files and /proc/self/mountinfo from inside the container —
# not `podman inspect`, which only replays the flags we asked for.
set -uo pipefail

HOST="${1:-debian1}"
SEAT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
IMAGE="$(node -e 'process.stdout.write(require(process.argv[1]).image)' "$SEAT_DIR/seat-remote.json")"
MEM="$(node -e 'process.stdout.write(require(process.argv[1]).limits.memory)' "$SEAT_DIR/seat-remote.json")"
CPUS="$(node -e 'process.stdout.write(String(require(process.argv[1]).limits.cpus))' "$SEAT_DIR/seat-remote.json")"
PIDS="$(node -e 'process.stdout.write(String(require(process.argv[1]).limits.pids))' "$SEAT_DIR/seat-remote.json")"
SSH=(ssh -F /dev/null -i "$HOME/.ssh/id_ed25519_buildbox" -p 2222 "user@$HOST")

REPORT="$("${SSH[@]}" "IMAGE=$IMAGE MEM=$MEM CPUS=$CPUS PIDS=$PIDS bash -s" <<'REMOTE'
set -uo pipefail
export PATH="$HOME/.local/bin:$PATH"
W="$(mktemp -d "$HOME/builds/seat-containment-XXXX")"
SEED="$(mktemp -d)"; printf 'secret\n' > "$SEED/cred"
# production mounts the mirror's git alternate READ-ONLY AT ITS OWN HOST PATH, which makes podman
# materialize the host home path chain inside the container. The fixture must carry one too or it
# tests a container shape that seat-run.sh never builds.
ALT="$(mktemp -d "$HOME/builds/.seat-containment-alt-XXXX")"; printf 'objects\n' > "$ALT/pack"
podman run --rm --name seat-containment-test \
  --memory "$MEM" --memory-swap "$MEM" --cpus "$CPUS" --pids-limit "$PIDS" \
  --read-only --read-only-tmpfs=false \
  --tmpfs "/tmp:rw,exec,mode=1777,size=256m" --tmpfs "/run:rw,mode=0755,size=16m" \
  --tmpfs "/seat-home:rw,exec,mode=0700,size=256m" \
  -v "$W:/w:rw" -v "$SEED/cred:/seed/cred:ro" -v "$ALT:$ALT:ro" \
  --workdir /w --cap-drop=ALL --security-opt no-new-privileges \
  --cgroup-parent agent.slice \
  --env "ALT=$ALT" --env "HOSTHOME=$HOME" \
  --entrypoint /bin/bash "$IMAGE" -c '
    printf "memory.max=%s\n"      "$(cat /sys/fs/cgroup/memory.max)"
    printf "memory.swap.max=%s\n" "$(cat /sys/fs/cgroup/memory.swap.max)"
    printf "pids.max=%s\n"        "$(cat /sys/fs/cgroup/pids.max)"
    printf "cpu.max=%s\n"         "$(cat /sys/fs/cgroup/cpu.max)"
    printf "caps=%s\n"            "$(awk "/^CapEff/{print \$2}" /proc/self/status)"
    printf "nnp=%s\n"             "$(awk "/^NoNewPrivs/{print \$2}" /proc/self/status)"
    # every WRITABLE mount backed by real host storage, ignoring kernel-virtual filesystems
    while read -r _ _ _ _ mp opts rest; do
      fstype=${rest##*- }; fstype=${fstype%% *}
      case ",$opts," in *,ro,*) continue;; esac
      case "$fstype" in tmpfs|proc|sysfs|devtmpfs|devpts|mqueue|cgroup2|overlay|shm) continue;; esac
      printf "writable-host-mount=%s\n" "$mp"
    done < /proc/self/mountinfo
    ( : > /w/probe )            2>/dev/null && printf "write:/w=ok\n"    || printf "write:/w=denied\n"
    ( : > /rootprobe )          2>/dev/null && printf "write:/=ok\n"     || printf "write:/=denied\n"
    ( : > /usr/local/bin/pwn )  2>/dev/null && printf "write:/usr=ok\n"  || printf "write:/usr=denied\n"
    ( : > /seed/pwn )           2>/dev/null && printf "write:/seed=ok\n" || printf "write:/seed=denied\n"
    ( printf x >> /seed/cred )  2>/dev/null && printf "write:cred=ok\n"  || printf "write:cred=denied\n"
    ( : > "$ALT/pwn" )          2>/dev/null && printf "write:alt=ok\n"   || printf "write:alt=denied\n"
    ( : > /seat-home/probe )    2>/dev/null && printf "write:seat-home=ok\n" || printf "write:seat-home=denied\n"
    printf "host-home-entries=%s\n" "$(ls -A "$HOSTHOME" 2>/dev/null | tr "\n" " ")"
    printf "alt-parent-entries=%s\n" "$(ls -A "$(dirname "$ALT")" 2>/dev/null | tr "\n" " ")"
  ' </dev/null
rc=$?
rm -rf "$W" "$SEED" "$ALT"
printf 'podman-rc=%s\n' "$rc"
REMOTE
)"

echo "$REPORT"
PASS=0 FAIL=0
want() {
  if grep -qx -- "$2" <<<"$REPORT"; then PASS=$((PASS+1)); echo "PASS $1"; else FAIL=$((FAIL+1)); echo "FAIL $1 (missing: $2)"; fi
}
bytes() { node -e 'const m=String(process.argv[1]).match(/^(\d+)([kmg])?$/i);process.stdout.write(String(BigInt(m[1])*(({k:1024n,m:1048576n,g:1073741824n})[(m[2]||"").toLowerCase()]||1n)))' "$1"; }

want "memory ceiling is kernel-enforced at $MEM"   "memory.max=$(bytes "$MEM")"
want "swap is denied (memory-swap == memory)"       "memory.swap.max=0"
want "pid ceiling is kernel-enforced at $PIDS"      "pids.max=$PIDS"
want "cpu quota is kernel-enforced at $CPUS cores"  "cpu.max=$((CPUS * 100000)) 100000"
want "every capability dropped"                     "caps=0000000000000000"
want "no_new_privs set"                             "nnp=1"
want "the workspace is writable"                    "write:/w=ok"
want "container root is read-only"                  "write:/=denied"
want "system binaries are read-only"                "write:/usr=denied"
want "the credential seed is read-only"             "write:/seed=denied"
want "seeded credentials cannot be rewritten"       "write:cred=denied"
want "the git alternate is read-only"               "write:alt=denied"
want "the seat HOME tmpfs is writable"              "write:seat-home=ok"
want "the container exited cleanly"                 "podman-rc=0"

MOUNTS="$(grep '^writable-host-mount=' <<<"$REPORT" | sort -u)"
if [[ "$MOUNTS" == "writable-host-mount=/w" ]]; then
  PASS=$((PASS+1)); echo "PASS the workspace is the ONLY writable host mount"
else
  FAIL=$((FAIL+1)); echo "FAIL writable host mounts are not just /w: ${MOUNTS//$'\n'/ }"
fi
# The alternate mount forces podman to materialize the host home PATH inside the container. What
# must not leak is its CONTENT: the chain holds nothing but the empty parent of the mounted mirror.
HOMEENTS="$(grep -m1 '^host-home-entries=' <<<"$REPORT")"; HOMEENTS="${HOMEENTS#*=}"
ALTENTS="$(grep -m1 '^alt-parent-entries=' <<<"$REPORT")"; ALTENTS="${ALTENTS#*=}"
if [[ "$(tr -s ' ' <<<"$HOMEENTS" | xargs echo)" == "builds" ]]; then
  PASS=$((PASS+1)); echo "PASS the buildbox home holds nothing but the mounted mirror's parent"
else
  FAIL=$((FAIL+1)); echo "FAIL the buildbox home leaked into the seat: $HOMEENTS"
fi
if [[ "$(xargs echo <<<"$ALTENTS")" =~ ^\.seat-containment-alt-[A-Za-z0-9]+$ ]]; then
  PASS=$((PASS+1)); echo "PASS only the mounted alternate is visible beside it"
else
  FAIL=$((FAIL+1)); echo "FAIL the mirror root leaked into the seat: $ALTENTS"
fi

# --- seat-run.sh admission gates: both must refuse BEFORE any container starts ---
HARNESS_DIR="$(dirname "$SEAT_DIR")"
RUNTIME_B64="$(tar -C "$HARNESS_DIR" -czf - seat/seat-run.sh seat/seat-reconcile.sh seat/credentials.json seat/systemd wrappers | base64 -w0)"
GATES="$("${SSH[@]}" "IMAGE=$IMAGE RUNTIME_B64=$RUNTIME_B64 bash -s" <<'REMOTE'
set -uo pipefail
export PATH="$HOME/.local/bin:$PATH"
# seat-run.sh itself comes from the working copy under test (unpacked below), but it resolves the
# wrappers and the credential manifest out of the mirror it is pointed at — so the mirror has to be
# one current enough to carry both. Abandoned worktrees leave mirrors that never sync again.
REPO=""
for cand in "$HOME"/builds/*/; do
  [[ -f "$cand/modules/harness/wrappers/codex.sh" && -f "$cand/modules/harness/seat/credentials.json" ]] || continue
  REPO="${cand%/}"; break
done
[[ -n "$REPO" ]] || { echo "gate-skip=no current repo mirror on this host"; exit 0; }
RUNTIME="$REPO/.harness-seat/gate/runtime"
rm -rf "$RUNTIME"; mkdir -p "$RUNTIME"
printf '%s' "$RUNTIME_B64" | base64 -d | tar -C "$RUNTIME" -xzf -
RUN="$RUNTIME/seat/seat-run.sh"
trap 'rm -rf "$REPO/.harness-seat/gate/runtime"' EXIT
common=(--repo-root "$REPO" --prompt-file nope.txt --log-rel .harness-seat/gate/logs --task-slug gate --image "$IMAGE"
        --memory 1g --cpus 1 --pids 64 --tmpfs-size 64m --permission-mode safe)

# concurrency: hold maxConcurrent sleepers, then a seat over the limit must be refused
for i in 1 2; do
  podman run -d --rm --name "harness-seat-gate$i" --entrypoint /bin/bash "$IMAGE" -c 'sleep 30' >/dev/null
done
printf 'prompt\n' > "$REPO/nope.txt"
out="$(bash "$RUN" --run-id gate --wrapper codex.sh "${common[@]}" --max-seats 2 2>&1)"; rc=$?
printf 'concurrency-rc=%s\n' "$rc"
# the box is shared: real seats may be running alongside the two sleepers, so assert the refusal
# shape and the limit, never an exact occupancy count
grep -qE 'already runs [0-9]+/2 seats' <<<"$out" && echo "concurrency-detail=ok" || echo "concurrency-detail=$out"
podman rm -f harness-seat-gate1 harness-seat-gate2 >/dev/null 2>&1

# an undefined codex profile must not reach the engine
printf 'prompt\n' > "$REPO/nope.txt"
out="$(bash "$RUN" --run-id gate --wrapper codex.sh "${common[@]}" --max-seats 4 --profile no-such-profile-xyz 2>&1)"; rc=$?
printf 'profile-rc=%s\n' "$rc"
grep -q 'is not defined in' <<<"$out" && echo "profile-detail=ok" || echo "profile-detail=$out"
# only this gate's own containers count — a real seat dispatched concurrently is not a leftover
podman ps --filter 'name=harness-seat-gate' --format '{{.Names}}' | sed 's/^/leftover=/'
REMOTE
)"
echo "$GATES"
if grep -q '^gate-skip=' <<<"$GATES"; then
  echo "SKIP seat-run admission gates (no seat mirror on $HOST yet)"
else
  REPORT="$GATES"
  want "a host at its seat limit refuses the dispatch (rc 3)"   "concurrency-rc=3"
  want "the refusal names the limit"                            "concurrency-detail=ok"
  want "an undefined codex profile refuses the dispatch (rc 3)" "profile-rc=3"
  want "the refusal names the missing profile"                  "profile-detail=ok"
  grep -q '^leftover=' <<<"$GATES" && { FAIL=$((FAIL+1)); echo "FAIL a refused dispatch left a container running"; } \
                                   || { PASS=$((PASS+1)); echo "PASS a refused dispatch started no container"; }
fi

# --- the create+start pair must hand back the CONTAINER's rc, and must not reap a live sibling ---
PAIR="$("${SSH[@]}" "IMAGE=$IMAGE bash -s" <<'REMOTE'
set -uo pipefail
export PATH="$HOME/.local/bin:$PATH"
for code in 0 75 124 3; do
  podman rm -f "harness-seat-rcprobe$code" >/dev/null 2>&1
  podman create --rm --name "harness-seat-rcprobe$code" --entrypoint /bin/bash "$IMAGE" -c "exit $code" >/dev/null
  podman start --attach "harness-seat-rcprobe$code" >/dev/null 2>&1 </dev/null
  printf 'rc-passthrough-%s=%s\n' "$code" "$?"
  podman rm -f "harness-seat-rcprobe$code" >/dev/null 2>&1
done
# a seat created seconds ago is a sibling mid-dispatch, NOT a phantom: the prune must spare it
podman create --rm --name harness-seat-fresh --entrypoint /bin/bash "$IMAGE" -c 'exit 0' >/dev/null
podman ps -a --filter 'name=harness-seat-' --filter 'status=created' --filter 'status=exited' \
  --filter 'until=5m' -q 2>/dev/null | xargs -r podman rm -f >/dev/null 2>&1
printf 'fresh-survives-prune=%s\n' "$(podman ps -a --filter 'name=harness-seat-fresh' -q | grep -c .)"
# same filter, window shrunk below the container's age = the phantom case: it IS reaped
sleep 2
podman ps -a --filter 'name=harness-seat-fresh' --filter 'status=created' --filter 'status=exited' \
  --filter 'until=1s' -q 2>/dev/null | xargs -r podman rm -f >/dev/null 2>&1
printf 'phantom-is-reaped=%s\n' "$(podman ps -a --filter 'name=harness-seat-fresh' -q | grep -c .)"
podman rm -f harness-seat-fresh >/dev/null 2>&1
# this whole block IS the stdin test: it is piped to `bash -s`, so a seat that proxied our stdin
# would have swallowed the script and nothing below the first start would ever run.
printf 'stdin-preserved=yes\n'
REMOTE
)"
echo "$PAIR"
REPORT="$PAIR"
want "create+start passes back rc 0"                  "rc-passthrough-0=0"
want "create+start passes back rc 75 (rate limited)"  "rc-passthrough-75=75"
want "create+start passes back rc 124 (timeout)"      "rc-passthrough-124=124"
want "create+start passes back rc 3 (engine down)"    "rc-passthrough-3=3"
want "the phantom prune spares a seat mid-dispatch"   "fresh-survives-prune=1"
want "a phantom seat past the window is reaped"       "phantom-is-reaped=0"
want "the seat does not consume the caller's stdin"   "stdin-preserved=yes"

echo "---- seat-containment on $HOST: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]]
