#!/usr/bin/env bash # Health owns the accepted diagnostic snapshot. A newer unreadable response # must degrade diagnostics without discarding the last report that Settings # and future health surfaces will render. set -euo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" source_harness="$repo_dir/config/dot/quickshell/health-harness.qml" service="$repo_dir/config/dot/quickshell/services/Health.qml" shell="$repo_dir/config/dot/quickshell/shell.qml" warning_snapshot='{"schemaVersion":1,"generatedAt":"2026-08-18T00:00:00Z","summary":{"status":"warning","healthy":0,"warnings":2,"errors":0,"unconfigured":0},"context":{"session":"hyprland","versions":[{"id":"quickshell","version":"0.3.0"}]},"checks":[{"id":"integration.calendar","group":"integrations","title":"Calendar","status":"warning","detail":"Calendar probe timed out.","action":{"kind":"open","label":"Open Date & Time","confirm":false,"target":"datetime"}},{"id":"panama.caffeine","group":"panama-tools","title":"Caffeine","status":"warning","detail":"Duplicate inhibitors are active.","action":{"kind":"repair","label":"Release duplicate inhibitors","confirm":false}}]}' confirm_snapshot="$(jq -c ' .summary.status = "error" | .summary.errors = 1 | .checks += [{ id: "desktop.quickshell", group: "desktop-foundation", title: "Quickshell", status: "error", detail: "Panama shell needs to restart.", action: {kind: "repair", label: "Restart Panama", confirm: true} }] ' <<<"$warning_snapshot")" projection_snapshot="$(jq -c ' .fixtureSecret = "fixture-secret" | .summary.fixtureSecret = "fixture-secret" | .context.fixtureSecret = "fixture-secret" | .context.versions[0].fixtureSecret = "fixture-secret" | .checks[0].fixtureSecret = "fixture-secret" ' <<<"$warning_snapshot")" adversarial_snapshot="$(jq -c ' .fixtureSecret = "fixture-secret" | .summary.fixtureSecret = "fixture-secret" | .context.fixtureSecret = "fixture-secret" | .context.versions[0].fixtureSecret = "fixture-secret" | .checks[0].fixtureSecret = "fixture-secret" | .checks[0].action.fixtureSecret = "fixture-secret" ' <<<"$warning_snapshot")" fail() { printf 'health service contract: %s\n' "$1" >&2 exit 1 } [[ -f "$service" ]] || fail 'Health.qml is missing' [[ -f "$source_harness" ]] || fail 'health harness is missing' [[ -f "$shell" ]] || fail 'shell.qml is missing' rg -q 'target: "wallpaper"' "$shell" \ || fail 'wallpaper health target is not exported by the shell' # shell.qml is not started here: it is the active desktop shell. Keep this # contract static while pinning the typed, redacted IPC boundary it exports. python3 - "$shell" <<'PY' || fail 'health IPC contract is missing or exposes unsafe state' import re import sys text = open(sys.argv[1], encoding="utf-8").read() match = re.search(r'IpcHandler \{\s*target: "health"(?P.*?)\n \}', text, re.S) if not match: raise SystemExit(1) body = match.group("body") required = ( 'function refresh(): bool { return Health.refresh(); }', 'function status(): string {', 'summary: Health.summary,', 'busy: Health.busy,', 'generation: Health.generation,', 'acceptedGeneration: Health.acceptedGeneration,', 'checks: Health.checks.map(check => ({ id: check.id, status: check.status }))', 'ShellState.openSettings("services");', 'Health.refresh();', 'function repair(id: string): bool { return Health.repair(id, true); }', ) if any(entry not in body for entry in required): raise SystemExit(1) if 'Health.snapshot' in body or 'Health.diagnostics' in body: raise SystemExit(1) status = re.search(r'function status\(\): string \{\s*return JSON\.stringify\(\{(?P.*?)\n \}\);', body, re.S) if not status: raise SystemExit(1) keys = re.findall(r'^\s*([A-Za-z][A-Za-z0-9]*):', status.group("fields"), re.M) if keys != ["summary", "busy", "generation", "acceptedGeneration", "checks"]: raise SystemExit(1) PY fixture_dir="$(mktemp -d /tmp/panama-health.XXXXXX)" config_path="$fixture_dir/quickshell" cp -a "$repo_dir/config/dot/quickshell" "$config_path" harness="$config_path/health-harness.qml" python3 - "$harness" <<'PY' import sys path = sys.argv[1] source = open(path, encoding="utf-8").read() needle = ' function repair(id: string): bool { return Health.repair(id, false); }\n' replacement = needle + ''' function externalRepair(id: string): bool { return Health.repair(id, true); } function pendingRefreshRace(): string { const before = Health.generation; Health.finishRepair(0, "panama.caffeine", false, JSON.stringify({ schemaVersion: 1, checkId: "panama.caffeine", accepted: true, exitCode: 0, message: "Fixture repair completed." })); const accepted = Health.refresh(); return JSON.stringify({ accepted: accepted, before: before }); } ''' if needle not in source: raise SystemExit("health harness repair seam is missing") open(path, "w", encoding="utf-8").write(source.replace(needle, replacement)) PY helper="$fixture_dir/panama-doctor" copy_bin="$fixture_dir/bin" copy_file="$fixture_dir/copied-report.json" repair_mode_file="$fixture_dir/repair-mode" repair_log="$fixture_dir/repair.log" notification_log="$fixture_dir/notifications.log" repair_started_file="$fixture_dir/repair-started" repair_release_file="$fixture_dir/repair-release" printf 'success\n' >"$repair_mode_file" printf '%s\n' \ '#!/usr/bin/env bash' \ 'printf "%s\n" "$*" >>"$PANAMA_HEALTH_REPAIR_LOG"' \ 'if [[ "$1" == "--json" ]]; then' \ ' sleep 0.2' \ " printf '%s\\n' '$warning_snapshot'" \ ' exit 0' \ 'fi' \ 'if [[ "$1" == "--repair" ]]; then' \ ' repair_start_time="$(awk '\''{ print $22 }'\'' "/proc/$$/stat")"' \ ' printf "%s|%s\n" "$$" "$repair_start_time" >"$PANAMA_HEALTH_REPAIR_STARTED"' \ ' while [[ ! -e "$PANAMA_HEALTH_REPAIR_RELEASE" ]]; do sleep 0.02; done' \ 'fi' \ 'if [[ "$1" == "--repair" && "$2" == "panama.caffeine" && "$3" == "--json" ]]; then' \ ' case "$(cat "$PANAMA_HEALTH_REPAIR_MODE_FILE")" in' \ ' success) printf "{\"schemaVersion\":1,\"checkId\":\"panama.caffeine\",\"accepted\":true,\"exitCode\":0,\"message\":\"Duplicate inhibitors were released.\"}\\n"; exit 0 ;;' \ ' failed) printf "{\"schemaVersion\":1,\"checkId\":\"panama.caffeine\",\"accepted\":true,\"exitCode\":7,\"message\":\"Duplicate inhibitors could not be released.\"}\\n"; exit 7 ;;' \ ' mismatch) printf "{\"schemaVersion\":1,\"checkId\":\"desktop.vicinae\",\"accepted\":true,\"exitCode\":0,\"message\":\"Wrong row.\"}\\n"; exit 0 ;;' \ ' *) printf "not-json\\n"; exit 0 ;;' \ ' esac' \ 'fi' \ 'if [[ "$1" == "--repair" && "$2" == "desktop.quickshell" && "$3" == "--json" ]]; then' \ ' printf "{\"schemaVersion\":1,\"checkId\":\"desktop.quickshell\",\"accepted\":true,\"exitCode\":0,\"message\":\"Panama shell restart was requested.\"}\\n"' \ ' exit 0' \ 'fi' \ 'exit 2' >"$helper" chmod +x "$helper" mkdir -p "$copy_bin" printf '%s\n' \ '#!/usr/bin/env bash' \ '/usr/bin/cat > "$PANAMA_HEALTH_COPY_FILE"' >"$copy_bin/wl-copy" printf '%s\n' \ '#!/usr/bin/env bash' \ 'printf "%s\n" "$*" >>"$PANAMA_HEALTH_NOTIFICATION_LOG"' >"$copy_bin/notify-send" chmod +x "$copy_bin/wl-copy" "$copy_bin/notify-send" run() { PATH="$copy_bin:$PATH" PANAMA_HEALTH_HELPER="$helper" PANAMA_HEALTH_COPY_FILE="$copy_file" \ PANAMA_HEALTH_REPAIR_MODE_FILE="$repair_mode_file" PANAMA_HEALTH_REPAIR_LOG="$repair_log" \ PANAMA_HEALTH_NOTIFICATION_LOG="$notification_log" \ PANAMA_HEALTH_REPAIR_STARTED="$repair_started_file" PANAMA_HEALTH_REPAIR_RELEASE="$repair_release_file" \ qs -p "$harness" "$@" } harness_pid="" harness_start_time="" process_identity_matches() { local pid="$1" expected_start_time="$2" expected_command="${3:-}" current_start_time [[ "$pid" =~ ^[0-9]+$ && "$expected_start_time" =~ ^[0-9]+$ ]] || return 1 [[ -r "/proc/$pid/stat" ]] || return 1 current_start_time="$(awk '{ print $22 }' "/proc/$pid/stat" 2>/dev/null)" || return 1 [[ "$current_start_time" == "$expected_start_time" ]] || return 1 if [[ -n "$expected_command" ]]; then [[ -r "/proc/$pid/cmdline" ]] || return 1 tr '\0' '\n' <"/proc/$pid/cmdline" | grep -Fxq "$expected_command" fi } cleanup() { : >"$repair_release_file" if [[ -f "$repair_started_file" ]]; then IFS='|' read -r repair_pid repair_start_time <"$repair_started_file" || true if process_identity_matches "$repair_pid" "$repair_start_time" "$helper"; then for _ in $(seq 1 40); do ! process_identity_matches "$repair_pid" "$repair_start_time" "$helper" && break sleep 0.05 done if process_identity_matches "$repair_pid" "$repair_start_time" "$helper"; then kill "$repair_pid" >/dev/null 2>&1 || true for _ in $(seq 1 20); do ! process_identity_matches "$repair_pid" "$repair_start_time" "$helper" && break sleep 0.05 done if process_identity_matches "$repair_pid" "$repair_start_time" "$helper"; then kill -KILL "$repair_pid" >/dev/null 2>&1 || true fi fi fi fi if process_identity_matches "$harness_pid" "$harness_start_time"; then kill "$harness_pid" >/dev/null 2>&1 || true for _ in $(seq 1 40); do ! process_identity_matches "$harness_pid" "$harness_start_time" && break sleep 0.05 done if process_identity_matches "$harness_pid" "$harness_start_time"; then kill -KILL "$harness_pid" >/dev/null 2>&1 || true fi fi rm -rf "$fixture_dir" } trap cleanup EXIT PATH="$copy_bin:$PATH" PANAMA_HEALTH_HELPER="$helper" PANAMA_HEALTH_COPY_FILE="$copy_file" \ PANAMA_HEALTH_REPAIR_MODE_FILE="$repair_mode_file" PANAMA_HEALTH_REPAIR_LOG="$repair_log" \ PANAMA_HEALTH_NOTIFICATION_LOG="$notification_log" \ PANAMA_HEALTH_REPAIR_STARTED="$repair_started_file" PANAMA_HEALTH_REPAIR_RELEASE="$repair_release_file" \ qs -p "$harness" --daemonize >/dev/null for _ in $(seq 1 40); do run ipc show 2>/dev/null | rg -q '^target health-test$' && break sleep 0.1 done run ipc show 2>/dev/null | rg -q '^target health-test$' || fail 'test IPC target did not start' harness_pid="$(run list | awk '/Process ID:/ { print $3; exit }')" harness_start_time="$(awk '{ print $22 }' "/proc/$harness_pid/stat" 2>/dev/null || true)" process_identity_matches "$harness_pid" "$harness_start_time" \ || fail 'could not capture a stable health harness process identity' [[ "$(run ipc call health-test accept "$warning_snapshot" 0)" == "true" ]] \ || fail 'valid warning snapshot was rejected' state="$(run ipc call health-test status)" jq -e '.status == "warning" and .acceptedGeneration == 0 and .checks == ["integration.calendar", "panama.caffeine"] and .diagnosticUnavailable == false' \ >/dev/null <<<"$state" || fail "valid warning snapshot was not accepted intact: $state" [[ "$(run ipc call health-test accept "$projection_snapshot" 0)" == "true" ]] \ || fail 'snapshot with unknown non-action fields was rejected instead of safely projected' stored_report="$(run ipc call health-test report)" ! grep -Fq 'fixture-secret' <<<"$stored_report" \ || fail "accepted snapshot retained an unknown secret field: $stored_report" [[ "$(run ipc call health-test copy)" == "true" ]] \ || fail 'copy report was refused' for _ in $(seq 1 40); do [[ -f "$copy_file" ]] && break sleep 0.1 done [[ -f "$copy_file" ]] || fail 'copy report did not reach wl-copy' ! grep -Fq 'fixture-secret' "$copy_file" \ || fail 'copied report retained an unknown secret field' adversarial_result="$(run ipc call health-test accept "$adversarial_snapshot" 1)" [[ "$adversarial_result" == "true" || "$adversarial_result" == "false" ]] \ || fail "adversarial action fixture did not return a Boolean: $adversarial_result" stored_report="$(run ipc call health-test report)" ! grep -Fq 'fixture-secret' <<<"$stored_report" \ || fail "adversarial snapshot leaked an unknown secret field: $stored_report" [[ "$(run ipc call health-test accept "$warning_snapshot" -1)" == "false" ]] \ || fail 'older generation replaced the current snapshot' state="$(run ipc call health-test status)" jq -e '.acceptedGeneration == 0 and .checks == ["integration.calendar", "panama.caffeine"]' \ >/dev/null <<<"$state" || fail "older generation altered accepted state: $state" [[ "$(run ipc call health-test accept '{not json' 1)" == "false" ]] \ || fail 'malformed snapshot was accepted' state="$(run ipc call health-test status)" jq -e '.diagnosticUnavailable == true and .checks == ["integration.calendar", "panama.caffeine"]' \ >/dev/null <<<"$state" || fail "malformed snapshot discarded the last valid checks: $state" before_generation="$(jq -r .generation <<<"$state")" run ipc call health-test queue >/dev/null state="$(run ipc call health-test status)" jq -e '.queuedRefresh == true and .generation == ($before + 1)' --argjson before "$before_generation" \ >/dev/null <<<"$state" || fail "two refreshes did not retain exactly one follow-up: $state" for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 2) and .queuedRefresh == false' --argjson before "$before_generation" \ >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.busy == false and .generation == ($before + 2) and .queuedRefresh == false' --argjson before "$before_generation" \ >/dev/null <<<"$state" || fail "queued refresh did not run exactly once: $state" printf 'success\n' >"$repair_mode_file" rm -f "$repair_started_file" "$repair_release_file" repair_generation="$(jq -r .generation <<<"$state")" [[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \ || fail 'repairable check was refused' for _ in $(seq 1 100); do [[ -s "$repair_started_file" ]] && break sleep 0.05 done [[ -s "$repair_started_file" ]] || fail 'repair helper never reached the started marker' run ipc call health-test queue >/dev/null working_state="$(run ipc call health-test status)" jq -e '.repairingId == "panama.caffeine" and .queuedRefresh == true and (.checkStates[] | select(.id == "panama.caffeine") | .status) == "warning"' \ >/dev/null <<<"$working_state" || fail "repair did not retain the degraded row while working: $working_state" : >"$repair_release_file" for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false' --argjson before "$repair_generation" \ >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false and .lastRepair == {schemaVersion:1, checkId:"panama.caffeine", accepted:true, exitCode:0, message:"Duplicate inhibitors were released."} and (.checkStates[] | select(.id == "panama.caffeine") | .status) == "warning"' \ --argjson before "$repair_generation" >/dev/null <<<"$state" \ || fail "accepted repair was trusted before exactly one observed rescan: $state" # A syntactically valid command failure remains inline for Settings and still # receives exactly one observed rescan. printf 'failed\n' >"$repair_mode_file" failure_generation="$(jq -r .generation <<<"$state")" [[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \ || fail 'second repairable check was refused' for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 1)' --argjson before "$failure_generation" \ >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.lastRepair.checkId == "panama.caffeine" and .lastRepair.accepted == true and .lastRepair.exitCode == 7 and .lastRepair.message == "Duplicate inhibitors could not be released." and .generation == ($before + 1)' --argjson before "$failure_generation" \ >/dev/null <<<"$state" || fail "known repair failure was not retained inline: $state" [[ ! -e "$notification_log" || ! -s "$notification_log" ]] \ || fail 'Settings-originated repair emitted an external notification' # A malformed or mismatched helper response is contained and cannot masquerade # as recovery; it also schedules only one scan. printf 'mismatch\n' >"$repair_mode_file" mismatch_generation="$(jq -r .generation <<<"$state")" [[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \ || fail 'mismatch repair fixture was refused' for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 1)' --argjson before "$mismatch_generation" \ >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.lastRepair.checkId == "panama.caffeine" and .lastRepair.accepted == false and .lastRepair.exitCode == 0 and .generation == ($before + 1)' \ --argjson before "$mismatch_generation" >/dev/null <<<"$state" \ || fail "mismatched repair JSON escaped containment: $state" # A refresh arriving after repair settlement but before the deferred mandatory # scan is coalesced into that scan instead of starting an extra generation. pending_race="$(run ipc call health-test pendingRefreshRace)" jq -e '.accepted == false' >/dev/null <<<"$pending_race" \ || fail "refresh escaped the post-repair pending window: $pending_race" pending_generation="$(jq -r .before <<<"$pending_race")" for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false' \ --argjson before "$pending_generation" >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false' \ --argjson before "$pending_generation" >/dev/null <<<"$state" \ || fail "pending-window refresh created duplicate scans: $state" # External IPC cannot bypass an authored confirmation. The same current row is # still repairable through Settings' external=false path after UI confirmation. confirm_generation="$(jq -r .generation <<<"$state")" [[ "$(run ipc call health-test accept "$confirm_snapshot" "$confirm_generation")" == "true" ]] \ || fail 'confirmation fixture was rejected' before_repair_lines="$(wc -l <"$repair_log")" [[ "$(run ipc call health-test externalRepair desktop.quickshell)" == "false" ]] \ || fail 'external repair bypassed confirmation' [[ "$(wc -l <"$repair_log")" == "$before_repair_lines" ]] \ || fail 'external confirmation rejection started a process' [[ "$(run ipc call health-test repair desktop.quickshell)" == "true" ]] \ || fail 'confirmed Settings repair was refused' for _ in $(seq 1 120); do state="$(run ipc call health-test status)" jq -e '.busy == false and .generation == ($before + 1)' \ --argjson before "$confirm_generation" >/dev/null <<<"$state" && break sleep 0.1 done jq -e '.lastRepair == {schemaVersion:1, checkId:"desktop.quickshell", accepted:true, exitCode:0, message:"Panama shell restart was requested."} and .generation == ($before + 1)' --argjson before "$confirm_generation" \ >/dev/null <<<"$state" || fail "confirmed Settings repair did not complete safely: $state" [[ "$(grep -Fc -- '--repair desktop.quickshell --json' "$repair_log")" == 1 ]] \ || fail 'confirmed Settings repair did not start exactly one repair process' [[ "$(run ipc call health-test repair unknown.check)" == "false" ]] \ || fail 'unknown check started a repair' [[ "$(run ipc call health-test repair integration.calendar)" == "false" ]] \ || fail 'non-repairable check started a repair' state="$(run ipc call health-test status)" jq -e '.repairingId == "" and .generation == ($before + 1)' --argjson before "$confirm_generation" \ >/dev/null <<<"$state" || fail "rejected repair altered process state: $state" python3 - "$service" <<'PY' || fail 'external repair failure notification is not bounded' import sys source = open(sys.argv[1], encoding="utf-8").read() assert 'if (failed && external && !failureNotification.running)' in source assert '"notify-send", "-a", "Panama", "-i", "dialog-error-symbolic"' in source assert '"Panama action failed", "The requested health repair could not be completed."' in source PY trap - EXIT cleanup printf 'health service contract: PASS\n'