#!/usr/bin/env bash
# Asserts the containment chain as it is actually configured on this workstation,
# not as the repo describes it. Every check here failed silently at least once:
# a launcher resolved past the shim, a ceiling was shadowed by a same-named user
# drop-in, and oomd held a stale view that left the account unmonitored.
set -uo pipefail

AGENT_CEILING=/etc/systemd/user/agent.slice.d/90-ceiling.conf
BUILD_CEILING=/etc/systemd/user/build.slice.d/90-ceiling.conf

# Skipping on the ceilings themselves would let a machine that lost them report green,
# so the gate is the launcher: wherever agents can start, the ceilings must be present.
if [[ ! -r "$HOME/.claude/bin/_agent-build-scope" ]]; then
  echo "SKIP containment invariants (no agent install: _agent-build-scope absent)"
  exit 0
fi

pass=0
fail=0
skip=0

check() { # $1=name $2=actual $3=expected
  if [[ "$2" == "$3" ]]; then
    pass=$((pass + 1))
    echo "PASS $1"
  else
    fail=$((fail + 1))
    echo "FAIL $1 (want=$3 got=$2)"
  fi
}

BIN="$HOME/.claude/bin"

for name in claude codex cursor-agent; do
  target="$(basename "$(readlink -f "$BIN/$name" 2>/dev/null)" 2>/dev/null)"
  check "entry-point-$name-is-jailed" "$target" "_tmpjail-shim.sh"
done

scope_invariants() { # $1=name-prefix $2=file
  local body
  body="$(<"$2")"
  case "$body" in
    *"confine.sh"*) check "$1-confines" yes yes ;;
    *) check "$1-confines" no yes ;;
  esac
  case "$body" in
    *"exec \"\$@\""*) check "$1-has-no-raw-exec" no yes ;;
    *) check "$1-has-no-raw-exec" yes yes ;;
  esac
}

scope_invariants agent-scope "$BIN/_agent-build-scope"

# The installed copy passing says nothing about the file a land would install next: a branch
# carrying the fail-open variant merges green while the box still holds the good one.
SCOPE_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")/../bin" && pwd)/_agent-build-scope"
if [[ -r "$SCOPE_SRC" ]]; then
  scope_invariants agent-scope-src "$SCOPE_SRC"
else
  check "agent-scope-src-present" no yes
fi

# confine.sh's reentry guard must only skip re-scoping for a descendant whose ancestor
# actually holds a cgroup scope. An ancestor that only reached the rlimit floor (no
# systemd-run reachable at that moment) is NOT capped on TasksMax; trusting a bare class
# marker there is exactly how session-364.scope and a run-p*.scope both ran an agent tree
# with no TasksMax ceiling at all after one transient systemd-run failure.
# Baseline: this test process may itself already run inside an outer confinement (its own
# ulimit -v already clamped by an ancestor), so "untouched by confine.sh" is whatever a bare
# child sees with confine.sh out of the picture entirely -- not a hardcoded "unlimited".
CONFINE_BASELINE_ULIMIT="$(bash -c 'ulimit -v')"

confine_reentry_check() { # $1=name $2=confine.sh path $3=ancestor CONFINE_ACTIVE $4=expect-skip(yes|no)
  local name="$1" src="$2" ancestor="$3" expect_skip="$4" out
  # AGENT_AS_MAX pinned strictly below the ambient baseline: an unambiguous drop proves
  # rlimit_floor actually ran, rather than "happened to already equal the default".
  out="$(CONFINE_ACTIVE="$ancestor" CONFINE_NO_SYSTEMD=1 AGENT_AS_MAX=1G \
    bash "$src" agent bash -c 'ulimit -v' 2>/dev/null)"
  if [[ "$expect_skip" == yes ]]; then
    # A real cgroup ancestor legitimately short-circuits before rlimit_floor ever runs,
    # so the child sees exactly the ambient ulimit -- confine.sh touched nothing.
    check "$name" "$out" "$CONFINE_BASELINE_ULIMIT"
  else
    # Must NOT be a no-op skip: rlimit_floor must have run and clamped to AGENT_AS_MAX.
    check "$name" "$out" 1048576
  fi
}
CONFINE_INSTALLED="$HOME/.claude/lib/confine.sh"
CONFINE_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")/../lib" && pwd)/confine.sh"

confine_reentry_suite() { # $1=label $2=confine.sh path
  confine_reentry_check "confine-reentry-cgroup-ancestor-skips-$1" "$2" "agent:cgroup" yes
  confine_reentry_check "confine-reentry-rlimit-ancestor-rescopes-$1" "$2" "agent:rlimit" no
  confine_reentry_check "confine-reentry-no-ancestor-rescopes-$1" "$2" "" no
}

# The installed leg is deploy-drift coverage: it is only meaningful where the installed path
# resolves to THIS repo's deploy artifact. A host that runs the suite without deploying
# overdeck (an offloaded build box) carries an unrelated confine.sh copy that no land can
# update, so asserting against it reds every branch that introduces a confine.sh change.
installed_deploy_artifact() {
  local real root
  real="$(readlink -f "$CONFINE_INSTALLED" 2>/dev/null)"
  [[ -n "$real" && -r "$real" ]] || return 1
  root="$(git -C "${real%/*}" rev-parse --show-toplevel 2>/dev/null)" || return 1
  [[ -n "$root" && "$real" == "$root/modules/workstation/claude/lib/confine.sh" ]]
}

if installed_deploy_artifact; then
  confine_reentry_suite installed "$CONFINE_INSTALLED"
else
  skip=$((skip + 1))
  echo "SKIP confine-reentry-installed ($CONFINE_INSTALLED is not this repo's deploy artifact)"
fi

if [[ -r "$CONFINE_SRC" ]]; then
  confine_reentry_suite src "$CONFINE_SRC"
else
  check "confine-present-src" no yes
fi

# A scope or service placed in agent.slice/build.slice without its own MemoryMax is
# capped only by the slice, so one runaway consumes the whole slice before the kernel
# picks a victim. Every OOM kill on 2026-08-04 came from such a scope.
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
if command -v git >/dev/null 2>&1 && [[ -d "$REPO_ROOT/.git" || -f "$REPO_ROOT/.git" ]]; then
  unceiled=""
  while IFS= read -r f; do
    [[ "$f" == *"/tests/"* || "$f" == *.test.sh ]] && continue
    case "$f" in *.sh|*.py|*.js|*.ts|*.service|*.conf) ;; *) continue ;; esac
    grep -q -E '^[^#]*(MemoryMax|confine\.sh)' "$REPO_ROOT/$f" || unceiled="$unceiled $f"
  done < <(git -C "$REPO_ROOT" grep -lE -- '(--slice=|^Slice=)(agent|build)\.slice' 2>/dev/null)
  check "in-repo-slice-placements-carry-a-ceiling" "${unceiled:-none}" none
else
  echo "SKIP in-repo slice placements (not a git checkout)"
fi

[[ -r "$AGENT_CEILING" ]] && check "agent-ceiling-installed" yes yes || check "agent-ceiling-installed" no yes
[[ -r "$BUILD_CEILING" ]] && check "build-ceiling-installed" yes yes || check "build-ceiling-installed" no yes

MEM_TOTAL_BYTES=$(awk '/^MemTotal:/ {print $2 * 1024}' /proc/meminfo)

declared() { # $1=drop-in $2=key — bytes, or pct:<n> for a host-relative ceiling
  local raw
  raw="$(grep -E "^$2=" "$1" 2>/dev/null | tail -1)"
  raw="${raw#*=}"
  [[ -n "$raw" ]] || { printf 'unset'; return; }
  case "$raw" in
    infinity|0) printf '%s' "$raw" ;;
    *%) printf 'pct:%s' "${raw%\%}" ;;
    *) numfmt --from=iec "$raw" 2>/dev/null || printf 'unparsed:%s' "$raw" ;;
  esac
}

check_ceiling() { # $1=name $2=effective $3=declared — percentages match within 2%
  local want=$3 target
  if [[ "$want" == pct:* ]]; then
    target=$(( MEM_TOTAL_BYTES * ${want#pct:} / 100 ))
    if [[ "$2" =~ ^[0-9]+$ ]] && (( $2 * 100 >= target * 98 && $2 * 100 <= target * 102 )); then
      pass=$((pass + 1)); echo "PASS $1"
    else
      fail=$((fail + 1)); echo "FAIL $1 (want~=$target got=$2)"
    fi
    return
  fi
  check "$1" "$2" "$want"
}

if systemctl --user show-environment >/dev/null 2>&1; then
  effective() { systemctl --user show "$1" -p "$2" --value 2>/dev/null; }
  # The drop-in is the intended ceiling and systemctl reports the effective one:
  # a shadowing user drop-in or a skipped daemon-reload shows up as a mismatch.
  for key in MemoryHigh MemoryMax MemorySwapMax; do
    check_ceiling "agent-slice-${key,,}" "$(effective agent.slice "$key")" "$(declared "$AGENT_CEILING" "$key")"
    check_ceiling "build-slice-${key,,}" "$(effective build.slice "$key")" "$(declared "$BUILD_CEILING" "$key")"
  done
else
  echo "SKIP slice ceilings (no user manager)"
fi

if command -v oomctl >/dev/null 2>&1 && systemctl is-active systemd-oomd >/dev/null 2>&1; then
  # Registration has to survive `systemctl --user daemon-reload`: the user manager
  # re-pushes its own ManagedOOM cgroups to oomd on reload and that push drops any
  # cgroup only the system manager reported, which is how this silently disarmed.
  # A slice with nothing running in it is not loaded, so no manager reports it and the
  # absence proves nothing. Park a short-lived unit in each so the check is about
  # registration rather than about whether the box happens to be busy.
  for slice in agent.slice build.slice; do
    systemd-run --user --quiet --collect --slice="$slice" \
      --unit="oomd-invariant-${slice%%.*}.service" sleep 20 2>/dev/null || true
  done
  systemctl --user daemon-reload 2>/dev/null && sleep 2
  watched="$(oomctl 2>/dev/null || true)"
  for slice in agent.slice build.slice; do
    case "$watched" in
      *"/$slice"*) check "oomd-watches-$slice" yes yes ;;
      *) check "oomd-watches-$slice" no yes ;;
    esac
  done
else
  echo "SKIP oomd (not active)"
fi

echo "passed=$pass failed=$fail skipped=$skip"
(( fail == 0 ))
