Follow-up with a second sample and source verification. Two additions.
1. Same deadlock via fff_destroy
A 20-minute freeze (17:20 to 17:40 PDT, ended by app relaunch). Main thread was in WorkspaceSearchIndex's idle-TTL release path this time, not a search:
| 1 | main (4276/4276 samples): |
| 2 | uv__run_timers -> JS -> ffi-rs -> fff_destroy |
| 3 | -> parking_lot::RawRwLock::lock_exclusive_slow -> __psynch_cvwait |
| 4 | |
| 5 | "notify-rs debouncer loop" (holds the picker write lock): |
| 6 | handle_debounced_events -> FilePicker::add_new_file |
| 7 | -> FileItem::detect_binary_per_byte -> read() (stuck in read) |
| 8 | |
| 9 | fff-watcher-own: lock_exclusive_slow (waiting) |
| 10 | fff-scan: ScanJob::new_rescan -> lock_shared_slow (waiting) |
So both mixedSearch (first sample) and destroy (this one) block the event loop behind the watcher's per-file read. fff-core/src/types.rs detect_binary_per_byte opens the file and reads it to EOF with no size cap; add_new_file calls it while handle_debounced_events holds shared_picker.write(). Any large or slow file (network-backed cloud placeholder, for example) parks the whole server.
2. The ~/.ignore workaround does not apply to the watcher on 0.9.4
Checked v0.9.4 source. In background_watcher.rs, should_include_file only consults git when the root is a repo; otherwise it uses the compiled-in is_non_code_directory list (node_modules, __pycache__, venv, target/*, Library/Caches, Library/Application Support, Library/Containers, Library/Group Containers). .ignore / .gitignore are honored by the initial WalkBuilder scan only. Current fff main (0.10.x) routes watcher events through the walker's ignore rules, so bumping @ff-labs/fff-node would at least give non-git roots a working exclusion list. It does not fix the unbounded read under the lock, or the synchronous FFI call on the event loop.
Net: on the shipped build, a non-git workspace root has no user-configurable exclusions for the watcher, and one slow file read anywhere under it can freeze the backend for as long as the read takes.