Files
Linux_post_install/tests/t-uninstall-manifest.sh
Your Name d817c37652
gates / consistency-and-conventions (push) Successful in 26s
fix: stabilization pass — fail-closed auth, ai flag validation, lint/config/security hardening, regression tests
17-point code-level audit executed via Explorer->Architect->Builder->Tester->Reviewer;
Reviewer accepted (APPROVE_WITH_NOTES; 3 block-list items resolved):

- security: telegram sender-owner AND-gate + TELEGRAM_OWNER_ID, matrix
  MATRIX_ROOM_ID fail-closed, gpg --passphrase-fd 3 (no argv secret),
  /dev/tcp positional-arg form (checkport/smb-client/share-lib/NET_PROBE),
  eval deny-by-default + --no-command-execution carried by both chat bridges,
  tty-gated --trust; config/{telegram,matrix}.env reference templates
- ai: all ExecStart flags validated against installed llama.cpp
  (requested->error, default->omit+warn, CONFIG_REQUESTED_FLAGS); single-file
  hf download failure rc=1 + no .hf-meta; LLAMACPP_HOST coherent;
  POS_SUBCMDS + metadata gaps closed
- tooling: lint-conventions Bash-native rewrite (~24-30x faster, rules and
  output byte-identical, :num restored); pos system uninstall covers all 12
  libs + scale-tail + flags dir + systemd user units (|| true) + plugin
  markers; anchored .bash_completion/.bashrc removal replaces sed -i '/pos/d'
- config: canonical load_env_file in lib/config-ui.sh (CRLF strip, env-wins,
  XDG, LOADED_ENV_KEYS); 9 tools migrated; entertainment-lib collapsed to
  wrappers; docker-compose deliberately unmigrated (source semantics)
- tests: first committed regression suite — tests/run-tests.sh zero-dep
  runner + make test; 12 files / 179 checks / 0 skip / ~52s; hard skip
  contract; systemd-analyze verify on generated unit PASS

Verified: make gen idempotent; make check green; make lint 0 FAIL, 0 WARN;
make test green; bash -n clean; git diff --check clean. Audit deliverables +
agent reports + AGENT_TODO Done entry included.
2026-09-06 07:25:44 -04:00

88 lines
3.6 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# t-uninstall-manifest.sh — install/uninstall symmetry (D-E):
# - the installed-file manifest (POS_LIBS in pos-system-uninstall) matches
# install.sh's phase-2 lib list EXACTLY (set equality) and every named
# lib exists,
# - scan_tier1() user-unit discovery honors XDG_CONFIG_HOME and only picks
# pos-* units (never unrelated user units) — extracted function run in a
# sandboxed XDG_CONFIG_HOME,
# - plugin removal stays marker-driven (POS_PLUGIN), not hardcoded.
run_test() {
local sandbox
sandbox="$(mksandbox uninstall-manifest)"
local uninstall="$ROOT/bin/pos-system-uninstall"
# ── static manifest equality ──
local install_libs uninstall_libs
install_libs="$(sed -n 's/.*for lf in \(.*\); do.*/\1/p' "$ROOT/install.sh" | head -1)"
if [ -z "$install_libs" ]; then
printf ' FAIL could not extract install.sh lib list\n'
return 0
fi
# POS_LIBS spans one or two lines: "(… \⏎ …)" or "(…)". Strip markers,
# backslash continuations and parens, join to one token string.
uninstall_libs="$(sed -n '/^POS_LIBS=(/,/)$/p' "$uninstall" \
| sed -e '1s/^POS_LIBS=(//' -e 's/[()\\]//g' \
| tr '\n' ' ')"
# normalize whitespace (line-continuation gap collapses to single spaces)
uninstall_libs="$(printf '%s' "$uninstall_libs" | tr -s ' \t\n' ' ' | sed -e 's/^ //' -e 's/ $//')"
local il uil
il="$(printf '%s' "$install_libs" | tr ' ' '\n' | sort | tr '\n' ' ')"
uil="$(printf '%s' "$uninstall_libs" | tr ' ' '\n' | sort | tr '\n' ' ')"
check_eq "install.sh lib list == POS_LIBS (sorted)" "$il" "$uil"
local lib
for lib in $install_libs; do
if [ -f "$ROOT/lib/$lib" ]; then
printf ' PASS lib/%s exists\n' "$lib"
else
printf ' FAIL lib/%s missing\n' "$lib"
fi
done
# ── behavioral: user-unit discovery honors XDG_CONFIG_HOME, pos-* only ──
local fakeroot="$sandbox/fakeroot"
mkdir -p "$fakeroot/systemd/user"
touch "$fakeroot/systemd/user/pos-aria2.service"
touch "$fakeroot/systemd/user/pos-entertainment-weather.timer"
touch "$fakeroot/systemd/user/unrelated.service"
# extract POS_LIBS + installed_plugins + scan_tier1 verbatim
local extract
extract="$(awk '
/^POS_LIBS=\(/ { infn=1 }
/^scan_tier1\(\) \{/ { inscan=1 }
infn { print }
inscan && /^}/ { exit }
' "$uninstall")"
if [ -z "$extract" ]; then
printf ' FAIL could not extract scan_tier1 function body\n'
return 0
fi
local runner="$sandbox/run-scan.sh"
{
printf '#!/usr/bin/env bash\nset -euo pipefail\n'
printf '%s\n' "$extract"
printf '\nscan_tier1\n'
} > "$runner"
test_run env XDG_CONFIG_HOME="$fakeroot" bash "$runner"
check_contains "scan_tier1 finds pos-* unit file" "user-unit: pos-aria2.service" "$TR_OUT"
check_contains "scan_tier1 finds pos-* timer file" "user-unit: pos-entertainment-weather.timer" "$TR_OUT"
check_not_contains "scan_tier1 ignores unrelated user unit" "user-unit: unrelated.service" "$TR_OUT"
# ── plugin removal stays marker-driven ──
if grep -q "POS_PLUGIN" "$uninstall"; then
printf ' PASS plugin removal is POS_PLUGIN-marker driven\n'
else
printf ' FAIL plugin removal is hardcoded (no POS_PLUGIN marker)\n'
fi
if command -v compgen >/dev/null 2>&1; then
printf ' PASS compgen-based discovery available (bash builtin)\n'
else
printf ' FAIL compgen not available\n'
fi
}