You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Onboarding: Gate indexer auto-start behind FDA decision
Indexer was running at every launch from `setup()`, recursively scanning `/`. On first launch this triggered macOS native permission popups (iCloud, Photos, etc.) before the in-app FDA modal mounted, stacking three prompts over our explanation modal.
- Add pure `should_auto_start_indexing(indexing_enabled, fda_choice, os_fda_granted)` in `indexing/mod.rs`. Skips auto-start when `fda_choice == NotAskedYet` AND the OS check reports FDA as not granted. 5 unit tests cover the truth table.
- Wire `setup()` in `lib.rs` to call the OS-level FDA check (`permissions::check_full_disk_access` per platform) and pass through to the gate.
- New `start_indexing_after_fda_decision` Tauri command (idempotent via `is_active()`). Frontend `FullDiskAccessPrompt` Deny handler calls it so the user doesn't need to restart for indexing to start in-session. Allow path needs no wiring — next-launch OS check passes the gate.
- Drop `#[allow(dead_code)]` on `Settings::full_disk_access_choice` (now consulted) and re-export `FullDiskAccessChoice` from `settings::mod`.
- Bump `mod.rs` and `lib.rs` entries in `file-length-allowlist.json`.
- Document the gate + `Decision/Why` in `indexing/CLAUDE.md`, `onboarding/CLAUDE.md`, `settings/CLAUDE.md`.
Copy file name to clipboardExpand all lines: apps/desktop/src-tauri/src/indexing/CLAUDE.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -122,6 +122,15 @@ Key test files are alongside each module (test functions within `#[cfg(test)]` b
122
122
123
123
## Key decisions
124
124
125
+
**Defer indexer auto-start until the user decides about Full Disk Access**: At first launch on macOS, recursively
126
+
scanning from `/` opens iCloud Drive, Photos, and other TCC-protected directories, which makes macOS show native
127
+
permission popups stacked on top of the in-app FDA modal. The result is a confusing pile of dialogs before the user has
128
+
seen our prompt. `should_auto_start_indexing(indexing_enabled, fda_choice, os_fda_granted)` (in `mod.rs`) gates the
129
+
launch-time start: it skips when `fda_choice == NotAskedYet` AND `os_fda_granted == false`. Once the user picks Allow
130
+
(restart) or Deny (same session, via `start_indexing_after_fda_decision`), the indexer starts. `os_fda_granted == true`
131
+
overrides `NotAskedYet` so users who granted FDA before our prompt persisted a choice still get auto-start. Pure
132
+
function so the gate logic is unit-tested without touching `setup()`.
133
+
125
134
**`getattrlistbulk` (via jwalk) for scanning, not `enumeratorAtURL` or `searchfs`**: Benchmarked on ~5M files (macOS, Apple Silicon, APFS). `getattrlistbulk` recursive walk: 1m49s with sizes. `enumeratorAtURL` with prefetched keys: 2m05s (+11%), found ~500K fewer entries. `searchfs`: fast for name lookup but can't return sizes. `mdfind`: undercounts (Spotlight excludes `.git/`, `node_modules/`, caches). `getattrlistbulk` is what jwalk uses under the hood on macOS, and adding size collection costs only ~4% overhead (packed in the same bulk buffer, no extra syscalls).
126
135
127
136
**Physical sizes may overcount ~10-20% due to APFS clones**: Per-file `st_blocks * 512` sums to ~905 GB vs ~746 GB true volume usage (`statfs()`). APFS clones (Xcode, simulators, Time Machine, `cp` since Ventura) share underlying blocks but each clone reports full allocation. Volume usage bar always uses `statfs()` for true totals.
0 commit comments