//! The never-block list (CLAUDE.md section 1.5.4). //! //! These targets are hardcoded, non-negotiable, and cannot be removed by any //! user setting, by any schedule, or by any lock level. Blocking the dialler or //! emergency services would make the device unusable, and section 1.5.4 places //! these guardrails above every other feature in the project. //! //! The list is a `const`, not a setting, and [`is_never_blocked`] is consulted //! inside the engine's target loop *after* schedule evaluation. That ordering is //! deliberate: a schedule that names a protected target still evaluates and //! still blocks its other targets, but the protected one can never enter the //! blocked set. There is no flag that reverses it. /// Android: the dialler and the emergency path. /// /// Section 1.5.4 names phone/dialer, emergency calls and SOS, and emergency /// alerts. Matching is by substring so a variant package name cannot slip past. #[cfg(target_os = "android")] pub const NEVER_BLOCK: &[&str] = &[ "com.android.dialer", "com.android.server.telecom", "com.android.emergency", "com.android.phone", "com.android.server.emergency", "com.android.cellbroadcastreceiver", "com.android.systemui", // holds the emergency call UI ]; /// Desktop: the OS shell and the settings basics needed to keep the machine /// usable. A user who cannot reach their file manager or display settings has /// lost the machine, not been disciplined. #[cfg(any(target_os = "linux", target_os = "windows"))] pub const NEVER_BLOCK: &[&str] = &[ // Session shell / compositor. "plasmashell", "plasmawindowmanager", "kwin_wayland", "kwin_x11", "gnome-shell", "xfce4-session", "explorer.exe", // Settings and the ability to undo things. "systemsettings", "systemsettings5", "systemsettings6", "gnome-control-center", "ksysguard", "plasma-systemmonitor", "dolphin", "org.kde.plasma.systemsettings", // Terminal is deliberately NOT here: it can undo anything. Section 1.5.4 // names the shell and Settings basics, not the terminal. ]; #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "windows")))] pub const NEVER_BLOCK: &[&str] = &[]; /// True when `target` may never be blocked. /// /// Substring matching, case-insensitive, so `com.android.dialer` and /// `com.android.dialer.standalone` are both covered. pub fn is_never_blocked(target: &str) -> bool { let needle = target.to_lowercase(); NEVER_BLOCK.iter().any(|protected| needle.contains(&protected.to_lowercase())) }