#!/bin/bash
# Desktop/media priority sweep (root, 20s timer):
#  - FreeTube renice -5 (media smoothness)
#  - desktop shell + display server: nice -6 + kernel-OOM shield (oom_score_adj)
#  - terminals: modest OOM shield (they host agent CLIs)
#  - clamp negative nice on agent/build cgroup procs (agents must not outrank desktop)
set -uo pipefail

set_ni() { [ "$(ps -o ni= -p "$1" 2>/dev/null | tr -d ' ')" = "$2" ] || renice "$2" -p "$1" >/dev/null 2>&1 || true; }
set_adj() { [ "$(cat /proc/"$1"/oom_score_adj 2>/dev/null)" = "$2" ] || echo "$2" > /proc/"$1"/oom_score_adj 2>/dev/null || true; }

for p in $(pgrep -f '/opt/FreeTube/freetube' 2>/dev/null); do set_ni "$p" -5; done

for p in $(pgrep -x 'Xorg|lightdm' 2>/dev/null); do set_ni "$p" -6; set_adj "$p" -1000; done
for p in $(pgrep -x cinnamon 2>/dev/null); do set_ni "$p" -6; set_adj "$p" -900; done
for p in $(pgrep -f 'cinnamon-session-binary' 2>/dev/null); do set_adj "$p" -900; done
for p in $(pgrep -f 'gnome-terminal-server' 2>/dev/null); do set_adj "$p" -300; done

# Negative-nice + inherited-OOM-shield clamp: agent/build trees only (vte terminal
# scopes, agent/build/ci slices). oom_score_adj is inherited across fork: the -300
# terminal-server shield leaked onto every agent launched from a tab, so the kernel
# killed user sessions instead of a 55G leaker (2026-08-04). Children go back to 200.
while read -r pid ni; do
  adj=$(cat /proc/"$pid"/oom_score_adj 2>/dev/null) || continue
  case "$ni$adj" in *-*) ;; *) continue ;; esac
  cg=$(cat /proc/"$pid"/cgroup 2>/dev/null) || continue
  case "$cg" in
    */vte-spawn-*.scope*|*/agent.slice/*|*/build.slice/*|*/ci.slice/*)
      case "$ni" in -[0-9]*) renice 0 -p "$pid" >/dev/null 2>&1 || true ;; esac
      case "$adj" in -[0-9]*) set_adj "$pid" 200 ;; esac
      ;;
  esac
done < <(ps -eo pid=,ni=)
exit 0
