diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md
index c28fd77..af3069d 100644
--- a/SECURITY_AUDIT.md
+++ b/SECURITY_AUDIT.md
@@ -1,370 +1,169 @@
-# Mole Security Audit Report
+# Mole Security Reference
-
+Version 1.23.2 | 2026-01-26
-**Status:** PASSED | **Risk Level:** LOW | **Version:** 1.23.2 (2026-01-26)
+## Recent Fixes
-
+**Uninstall audit, Jan 2026:**
----
+- `stop_launch_services()` now checks bundle_id is valid reverse-DNS before using it in find patterns. This stops glob injection.
+- `find_app_files()` skips LaunchAgents named after common words like Music or Notes.
+- Added comments explaining why `remove_file_list()` bypasses TOCTOU checks for symlinks.
+- `brew_uninstall_cask()` treats exit code 124 as timeout failure, returns immediately.
-## Audit Overview
+Other changes:
-| Attribute | Details |
-|-----------|---------|
-| Audit Date | January 26, 2026 |
-| Audit Conclusion | **PASSED** |
-| Mole Version | V1.23.2 |
-| Audited Branch | `main` (HEAD) |
-| Scope | Shell scripts, Go binaries, Configuration |
-| Methodology | Static analysis, Threat modeling, Code review |
-| Review Cycle | Every 6 months or after major feature additions |
-| Next Review | July 2026 |
+- Symlink cleanup in `bin/clean.sh` goes through `safe_remove` now
+- Orphaned helper cleanup in `lib/clean/apps.sh` switched to `safe_sudo_remove`
+- ByHost pref cleanup checks bundle ID format first
-**Key Findings:**
+## Path Validation
-- Multi-layer validation effectively blocks risky system modifications.
-- Conservative cleaning logic ensures safety (e.g., 60-day dormancy rule).
-- Comprehensive protection for VPNs, AI tools, and core system components.
-- Operations logging improves traceability while remaining optional (MO_NO_OPLOG=1).
-- Atomic operations prevent state corruption during crashes.
-- Dry-run and whitelist features give users full control.
-- Installer cleanup scans safely and requires user confirmation.
+Every deletion goes through `lib/core/file_ops.sh`. The `validate_path_for_deletion()` function rejects empty paths, paths with `/../` in them, and anything containing control characters like newlines or null bytes.
-**Recent Remediations:**
+**Blocked paths**, even with sudo:
-- **Uninstall Audit (Jan 2026)**: Enhanced security in uninstall logic per comprehensive security review.
- - `stop_launch_services()` now validates bundle_id format (reverse-DNS) before use in find patterns to prevent glob injection attacks.
- - `find_app_files()` LaunchAgents search now excludes common words (Music, Notes, etc.) to prevent false positive matches.
- - `remove_file_list()` symlink handling documented with detailed security comments explaining the TOCTOU protection bypass rationale.
- - `brew_uninstall_cask()` timeout handling improved: exit code 124 (timeout) now returns failure immediately without verification.
-- Symlink cleanup in `bin/clean.sh` now routes through `safe_remove` for target validation.
-- Orphaned helper cleanup in `lib/clean/apps.sh` now uses `safe_sudo_remove`.
-- ByHost preference cleanup in `lib/uninstall/batch.sh` validates bundle IDs and deletes via `safe_remove`.
-
----
-
-## Security Philosophy
-
-**Core Principle: "Do No Harm"**
-
-We built Mole on a **Zero Trust** architecture for filesystem operations. Every modification request is treated as dangerous until it passes strict validation.
-
-**Guiding Priorities:**
-
-1. **System Stability First** - We'd rather leave 1GB of junk than delete 1KB of your data.
-2. **Conservative by Default** - High-risk operations always require explicit confirmation.
-3. **Fail Safe** - When in doubt, we abort immediately.
-4. **Transparency** - Every operation is logged and allows a preview via dry-run mode.
-
----
-
-## Threat Model
-
-### Attack Vectors & Mitigations
-
-| Threat | Risk Level | Mitigation | Status |
-|--------|------------|------------|--------|
-| Accidental System File Deletion | Critical | Multi-layer path validation, system directory blocklist | Mitigated |
-| Path Traversal Attack | High | Absolute path enforcement, relative path rejection | Mitigated |
-| Symlink Exploitation | High | Symlink detection in privileged mode | Mitigated |
-| Command Injection | High | Control character filtering, strict validation | Mitigated |
-| Empty Variable Deletion | High | Empty path validation, defensive checks | Mitigated |
-| Race Conditions | Medium | Atomic operations, process isolation | Mitigated |
-| Network Mount Hangs | Medium | Timeout protection, volume type detection | Mitigated |
-| Privilege Escalation | Medium | Restricted sudo scope, user home validation | Mitigated |
-| False Positive Deletion | Medium | 3-char minimum, fuzzy matching disabled | Mitigated |
-| VPN Configuration Loss | Medium | Comprehensive VPN/proxy whitelist | Mitigated |
-
----
-
-## Defense Architecture
-
-### Multi-Layered Validation System
-
-All automated operations pass through hardened middleware (`lib/core/file_ops.sh`) with 4 layers of validation:
-
-#### Layer 1: Input Sanitization
-
-| Control | Protection Against |
-|---------|---------------------|
-| Absolute Path Enforcement | Path traversal attacks (`../etc`) |
-| Control Character Filtering | Command injection (`\n`, `\r`, `\0`) |
-| Empty Variable Protection | Accidental `rm -rf /` |
-| Secure Temp Workspaces | Data leakage, race conditions |
-
-**Code:** `lib/core/file_ops.sh:validate_path_for_deletion()`
-
-#### Layer 2: System Path Protection ("Iron Dome")
-
-Even with `sudo`, these paths are **unconditionally blocked**:
-
-```bash
-/ # Root filesystem
-/System # macOS system files
-/bin, /sbin, /usr # Core binaries
-/etc, /var # System configuration
-/Library/Extensions # Kernel extensions
-/private # System-private directories
+```text
+/ # root
+/System # macOS system
+/bin, /sbin, /usr # binaries
+/etc, /var # config
+/Library/Extensions # kexts
+/private # system private
```
-**Exceptions:**
+Some system caches are OK to delete:
-- `/System/Library/Caches/com.apple.coresymbolicationd/data` (safe, rebuildable cache)
+- `/System/Library/Caches/com.apple.coresymbolicationd/data`
- `/private/tmp`, `/private/var/tmp`, `/private/var/log`, `/private/var/folders`
- `/private/var/db/diagnostics`, `/private/var/db/DiagnosticPipeline`, `/private/var/db/powerlog`, `/private/var/db/reportmemoryexception`
-**Code:** `lib/core/file_ops.sh:60-78`
+See `lib/core/file_ops.sh:60-78`.
-#### Layer 3: Symlink Detection
+When running with sudo, `safe_sudo_recursive_delete()` also checks for symlinks. Refuses to follow symlinks pointing to system files.
-For privileged operations, pre-flight checks prevent symlink-based attacks:
+## Cleanup Rules
-- Detects symlinks from cache folders pointing to system files.
-- Refuses recursive deletion of symbolic links in sudo mode.
-- Validates real path vs. symlink target.
+**Orphan detection** at `lib/clean/apps.sh:orphan_detection()`:
-**Code:** `lib/core/file_ops.sh:safe_sudo_recursive_delete()`
+App data is only considered orphaned if the app itself is gone from all three locations: `/Applications`, `~/Applications`, `/System/Applications`. On top of that, the data must be untouched for at least 60 days. Adobe, Microsoft, and Google stuff is whitelisted regardless.
-#### Layer 4: Permission Management
+**Uninstall matching** at `lib/clean/apps.sh:uninstall_app()`:
-When running with `sudo`:
+App names need at least 3 characters. Otherwise "Go" would match "Google" and that's bad. Fuzzy matching is off. Receipt scans only look under `/Applications` and `/Library/Application Support`, not in shared places like `/Library/Frameworks`.
-- Auto-corrects ownership back to user (`chown -R`).
-- Restricts operations to the user's home directory.
-- Enforces multiple validation checkpoints.
+**Dev tools:**
-### Interactive Analyzer (Go)
+Cache dirs like `~/.cargo/registry/cache` or `~/.gradle/caches` get cleaned. But `~/.cargo/bin`, `~/.mix/archives`, `~/.rustup` toolchains, `~/.stack/programs` stay untouched.
-The analyzer (`mo analyze`) uses a distinct security model:
+**LaunchAgent removal:**
-- Runs with standard user permissions only.
-- Respects macOS System Integrity Protection (SIP).
-- **Two-Key Confirmation:** Deletion requires ⌫ (Delete) to enter confirmation mode, then Enter to confirm. Prevents accidental double-press of the same key.
-- **Trash Instead of Delete:** Files are moved to macOS Trash using Finder's native API, allowing easy recovery if needed.
-- OS-level enforcement (cannot delete `/System` due to Read-Only Volume).
+Only removed when uninstalling the app that owns them. All `com.apple.*` items are skipped. Services get stopped via `launchctl` first. Generic names like Music, Notes, Photos are excluded from the search.
-**Code:** `cmd/analyze/*.go`
+See `lib/core/app_protection.sh:find_app_files()`.
----
+## Protected Categories
-## Safety Mechanisms
+| Category | What's protected |
+| -------- | ---------------- |
+| System | Control Center, System Settings, TCC, `/Library/Updates`, Spotlight |
+| VPN/Proxy | Shadowsocks, V2Ray, Tailscale, Clash |
+| AI | Cursor, Claude, ChatGPT, Ollama, LM Studio |
+| Time Machine | Checks if backup is running. If status unclear, skips cleanup. |
+| Startup | `com.apple.*` LaunchAgents/Daemons always skipped |
-### Conservative Cleaning Logic
+See `lib/core/app_protection.sh:is_critical_system_component()`.
-#### The "60-Day Rule" for Orphaned Data
+## Analyzer
-| Step | Verification | Criterion |
-|------|--------------|-----------|
-| 1. App Check | All installation locations | Must be missing from `/Applications`, `~/Applications`, `/System/Applications` |
-| 2. Dormancy | Modification timestamps | Untouched for ≥60 days |
-| 3. Vendor Whitelist | Cross-reference database | Adobe, Microsoft, and Google resources are protected |
+`mo analyze` runs differently:
-**Code:** `lib/clean/apps.sh:orphan_detection()`
+- Standard user permissions, no sudo
+- Respects SIP
+- Two keys to delete: press ⌫ first, then Enter. Hard to delete by accident.
+- Files go to Trash via Finder API, not rm
-#### Developer Tool Ecosystems (Consolidated)
+Code at `cmd/analyze/*.go`.
-Support for 20+ languages (Rust, Go, Node, Python, JVM, Mobile, Elixir, Haskell, OCaml, etc.) with strict safety checks:
+## Timeouts
-- **Global Optimization:** The core `safe_clean` function now intelligently checks parent directories before attempting wildcard cleanups, eliminating overhead for missing tools across the entire system.
-- **Safe Targets:** Only volatile caches are cleaned (e.g., `~/.cargo/registry/cache`, `~/.gradle/caches`).
-- **Protected Paths:** Critical directories like `~/.cargo/bin`, `~/.mix/archives`, `~/.rustup` toolchains, and `~/.stack/programs` are explicitly **excluded**.
+| Operation | Timeout | Why |
+| --------- | ------- | --- |
+| Network volume check | 5s | NFS/SMB/AFP can hang forever |
+| App bundle search | 10s | mdfind sometimes stalls |
+| SQLite vacuum | 20s | Skip if Mail/Safari/Messages is open |
+| dyld cache rebuild | 180s | Skip if done in last 24h |
-#### Active Uninstallation Heuristics
+See `lib/core/base.sh:run_with_timeout()`.
-For user-selected app removal:
+## User Config
-- **Sanitized Name Matching:** "Visual Studio Code" → `VisualStudioCode`, `.vscode`
-- **Safety Limit:** 3-char minimum (prevents "Go" matching "Google")
-- **Disabled:** Fuzzy matching and wildcard expansion for short names.
-- **User Confirmation:** Required before deletion.
-- **Receipt Scans:** BOM-derived files are restricted to app-specific prefixes (e.g., `/Applications`, `/Library/Application Support`). Shared directories like `/Library/Frameworks` are **excluded** to prevent collateral damage.
-
-**Code:** `lib/clean/apps.sh:uninstall_app()`
-
-#### System Protection Policies
-
-| Protected Category | Scope | Reason |
-|--------------------|-------|--------|
-| System Integrity Protection | `/Library/Updates`, `/System/*` | Respects macOS Read-Only Volume |
-| Spotlight & System UI | `~/Library/Metadata/CoreSpotlight` | Prevents UI corruption |
-| System Components | Control Center, System Settings, TCC | Centralized detection via `is_critical_system_component()` |
-| Time Machine | Local snapshots, backups | Runtime activity detection (backup running, snapshots mounted), fails safe if status indeterminate |
-| VPN & Proxy | Shadowsocks, V2Ray, Tailscale, Clash | Protects network configs |
-| AI & LLM Tools | Cursor, Claude, ChatGPT, Ollama, LM Studio | Protects models, tokens, and sessions |
-| Startup Items | `com.apple.*` LaunchAgents/Daemons | System items unconditionally skipped |
-
-**LaunchAgent/LaunchDaemon Cleanup During Uninstallation:**
-
-When users uninstall applications via `mo uninstall`, Mole automatically removes associated LaunchAgent and LaunchDaemon plists:
-
-- Scans `~/Library/LaunchAgents`, `~/Library/LaunchDaemons`, `/Library/LaunchAgents`, `/Library/LaunchDaemons`
-- Matches both exact bundle ID (`com.example.app.plist`) and app name patterns (`*AppName*.plist`)
-- Skips all `com.apple.*` system items via `should_protect_path()` validation
-- Unloads services via `launchctl` before deletion (via `stop_launch_services()`)
-- **Safer than orphan detection:** Only removes plists when the associated app is explicitly being uninstalled
-- Prevents accumulation of orphaned startup items that persist after app removal
-- **Common word exclusion:** LaunchAgent name searches exclude generic terms (Music, Notes, Photos, etc.) to prevent false positives
-- **Bundle ID validation:** `stop_launch_services()` validates reverse-DNS format before find patterns
-
-**Code:** `lib/core/app_protection.sh:find_app_files()`, `lib/uninstall/batch.sh:stop_launch_services()`
-
-### Crash Safety & Atomic Operations
-
-| Operation | Safety Mechanism | Recovery Behavior |
-|-----------|------------------|-------------------|
-| Network Interface Reset | Atomic execution blocks | Wi-Fi/AirDrop restored to pre-operation state |
-| Swap Clearing | Daemon restart | `dynamic_pager` handles recovery safely |
-| Volume Scanning | Timeout + filesystem check | Auto-skip unresponsive NFS/SMB/AFP mounts |
-| Homebrew Cache | Pre-flight size check | Skip if <50MB (avoids long delays) |
-| Network Volume Check | `diskutil info` with timeout | Prevents hangs on slow/dead mounts |
-| SQLite Vacuum | App-running check + 20s timeout | Skips if Mail/Safari/Messages active |
-| dyld Cache Update | 24-hour freshness check + 180s timeout | Skips if recently updated |
-| App Bundle Search | 10s timeout on mdfind | Fallback to standard paths |
-
-**Timeout Example:**
+Put paths in `~/.config/mole/whitelist`, one per line:
```bash
-run_with_timeout 5 diskutil info "$mount_point" || skip_volume
+# exact matches only
+/Users/me/important-cache
+~/Library/Application Support/MyApp
```
-**Code:** `lib/core/base.sh:run_with_timeout()`, `lib/optimize/*.sh`
+These paths are protected from all operations.
----
+Run `mo clean --dry-run` or `mo optimize --dry-run` to preview what would happen without actually doing it.
-## User Controls
+## Testing
-### Dry-Run Mode
+| Area | Coverage |
+| ---- | -------- |
+| File ops | 95% |
+| Cleaning | 87% |
+| Optimize | 82% |
+| System | 90% |
+| Security | 100% |
-**Command:** `mo clean --dry-run` | `mo optimize --dry-run`
-
-**Behavior:**
-
-- Simulates the entire operation without modifying a single file.
-- Lists every file/directory that **would** be deleted.
-- Calculates total space that **would** be freed.
-- **Zero risk** - no actual deletion commands are executed.
-
-### Custom Whitelists
-
-**File:** `~/.config/mole/whitelist`
-
-**Format:**
+180+ test cases total, about 88% coverage.
```bash
-# One path per line - exact matches only
-/Users/username/important-cache
-~/Library/Application Support/CriticalApp
+bats tests/ # run all
+bats tests/security.bats # security only
```
-- Paths are **unconditionally protected**.
-- Applies to all operations (clean, optimize, uninstall).
-- Supports absolute paths and `~` expansion.
-
-**Code:** `lib/core/file_ops.sh:is_whitelisted()`
-
-### Interactive Confirmations
-
-We mandate confirmation for:
-
-- Uninstalling system-scope applications.
-- Removing large data directories (>1GB).
-- Deleting items from shared vendor folders.
-
----
-
-## Testing & Compliance
-
-### Test Coverage
-
-Mole uses **BATS (Bash Automated Testing System)** for automated testing.
-
-| Test Category | Coverage | Key Tests |
-|---------------|----------|-----------|
-| Core File Operations | 95% | Path validation, symlink detection, permissions |
-| Cleaning Logic | 87% | Orphan detection, 60-day rule, vendor whitelist |
-| Optimization | 82% | Cache cleanup, timeouts |
-| System Maintenance | 90% | Time Machine, network volumes, crash recovery |
-| Security Controls | 100% | Path traversal, command injection, symlinks |
-
-**Total:** 180+ tests | **Overall Coverage:** ~88%
-
-**Test Execution:**
-
-```bash
-bats tests/ # Run all tests
-bats tests/security.bats # Run specific suite
-```
-
-### Standards Compliance
-
-| Standard | Implementation |
-|----------|----------------|
-| OWASP Secure Coding | Input validation, least privilege, defense-in-depth |
-| CWE-22 (Path Traversal) | Enhanced detection: rejects `/../` components, safely handles `..` in directory names |
-| CWE-78 (Command Injection) | Control character filtering |
-| CWE-59 (Link Following) | Symlink detection before privileged operations |
-| Apple File System Guidelines | Respects SIP, Read-Only Volumes, TCC |
-
-### Security Development Lifecycle
-
-- **Static Analysis:** `shellcheck` runs on all shell scripts.
-- **Code Review:** All changes are manually reviewed by maintainers.
-- **Dependency Scanning:** Minimal external dependencies, all carefully vetted.
-
-### Known Limitations
-
-| Limitation | Impact | Mitigation |
-|------------|--------|------------|
-| Requires `sudo` for system caches | Initial friction | Clear documentation explaining why |
-| 60-day rule may delay cleanup | Some orphans remain longer | Manual `mo uninstall` is always available |
-| No undo functionality | Deleted files are unrecoverable | Dry-run mode and warnings are clear |
-| English-only name matching | May miss non-English apps | Fallback to Bundle ID matching |
-
-**Intentionally Out of Scope (Safety):**
-
-- Automatic deletion of user documents/media.
-- Encryption key stores or password managers.
-- System configuration files (`/etc/*`).
-- Browser history or cookies.
-- Git repository cleanup.
-
----
+CI runs shellcheck and go vet on every push.
## Dependencies
-### System Binaries
+System binaries used, all SIP protected:
-Mole relies on standard, SIP-protected macOS system binaries:
+| Binary | For |
+| ------ | --- |
+| `plutil` | plist validation |
+| `tmutil` | Time Machine |
+| `dscacheutil` | cache rebuild |
+| `diskutil` | volume info |
-| Binary | Purpose | Fallback |
-|--------|---------|----------|
-| `plutil` | Validate `.plist` integrity | Skip invalid plists |
-| `tmutil` | Time Machine interaction | Skip TM cleanup |
-| `dscacheutil` | System cache rebuilding | Optional optimization |
-| `diskutil` | Volume information | Skip network volumes |
+Go libs in analyze-go:
-### Go Dependencies (Interactive Tools)
+| Lib | Version | License |
+| --- | ------- | ------- |
+| `bubbletea` | v0.23+ | MIT |
+| `lipgloss` | v0.6+ | MIT |
+| `gopsutil` | v3.22+ | BSD-3 |
+| `xxhash` | v2.2+ | BSD-2 |
-The compiled Go binary (`analyze-go`) includes:
+Versions are pinned. No CVEs. Binaries built via GitHub Actions.
-| Library | Version | Purpose | License |
-|---------|---------|---------|---------|
-| `bubbletea` | v0.23+ | TUI framework | MIT |
-| `lipgloss` | v0.6+ | Terminal styling | MIT |
-| `gopsutil` | v3.22+ | System metrics | BSD-3 |
-| `xxhash` | v2.2+ | Fast hashing | BSD-2 |
+## Limitations
-**Supply Chain Security:**
+| What | Impact | Workaround |
+| ---- | ------ | ---------- |
+| Needs sudo for system caches | Annoying first time | Docs explain why |
+| 60-day wait for orphans | Some junk stays longer | Use `mo uninstall` manually |
+| No undo | Gone is gone | Use dry-run first |
+| English names only | Might miss localized apps | Falls back to bundle ID |
-- All dependencies are pinned to specific versions.
-- Regular security audits.
-- No transitive dependencies with known CVEs.
-- **Automated Releases**: Binaries are compiled and signed via GitHub Actions.
-- **Source Only**: The repository contains no pre-compiled binaries.
+**Won't touch:**
----
-
-**Our Commitment:** This document certifies that Mole implements industry-standard defensive programming practices and strictly adheres to macOS security guidelines. We prioritize system stability and data integrity above all else.
-
-*For security concerns or vulnerability reports, please open an issue or contact the maintainers directly.*
+- Your documents or media
+- Password managers or keychains
+- Files under `/etc`
+- Browser history/cookies
+- Git repos