Watching Files

Atlas tracks files by watching directories and individual files you opt into. When a watched file changes, Atlas automatically hashes the new content and updates the entity’s history.

Adding Watch Paths

Directories

Watch a directory to recursively track everything inside it:

atlas watch ~/projects/myapp

Atlas immediately scans the directory, hashes every file, and begins monitoring for changes. Subdirectories are included recursively.

Individual Files

Watch a single file:

atlas watch ~/Documents/notes.md

Useful when you want to track specific files without watching an entire directory.

What Happens on Watch

When you add a new watch path, Atlas:

  1. Scans all files in the path (recursively for directories)
  2. Computes BLAKE3 hashes for each file
  3. Creates new entities for files with unknown hashes
  4. Detects forks — if a file’s hash matches an existing entity, Atlas records it as a copy
  5. Skips files matching ignore patterns
  6. Starts the daemon automatically if it isn’t running

The scan output reports what was found:

Watching ~/projects/myapp
  142 new entities
    3 forks detected
   12 files ignored
    0 already tracked

Removing Watch Paths

atlas unwatch ~/projects/myapp

This stops monitoring the path for changes. All existing history is preserved — unwatch only affects future tracking. The path remains in the database as inactive so you can see which directories Atlas has historical data for.

If no active watched paths remain after unwatching, Atlas automatically stops the daemon.

Re-watching a Path

If you unwatch a path and later re-watch it, Atlas reactivates the existing record rather than creating a new one. The added_at timestamp updates to the current time.

Path Subsumption

When you watch a parent directory that contains directories already being watched individually, Atlas automatically consolidates them:

atlas watch /Volumes/MyDrive
# Consolidated 3 subdirectories now covered by this path:
#   /Volumes/MyDrive/Projects
#   /Volumes/MyDrive/Samples
#   /Volumes/MyDrive/Presets

The child paths are marked inactive (not deleted). No data is lost — the parent path now covers all files that were previously tracked by the children.

Naming Directories (Namespaces)

Watched directories can be given a human-friendly name using namespaces. This provides cleaner display and enables path remapping when migrating drives.

Assign a Name

atlas namespace add my-samples /Volumes/Samsung_T7/Audio/Samples

The directory is automatically watched if it wasn’t already. Each namespace name must be unique, and each path can only have one namespace.

View Named Directories

atlas namespace list
Namespaces:

  my-samples → /Volumes/Samsung_T7/Audio/Samples
  projects   → /Users/daniel/Projects

Named directories also show their namespace in atlas status:

Active watched paths:
  [dir ] /Volumes/Samsung_T7/Audio/Samples  [my-samples]
         added: 2026-03-10  last activity: 2026-03-17
  [dir ] /Volumes/OldDrive/Archive  [archive]  [disconnected]
         added: 2026-03-09  last activity: 2026-03-15
  [dir ] /Users/daniel/Projects  [projects]
         added: 2026-03-08  last activity: 2026-03-17

Remove a Name

atlas namespace remove my-samples

The directory stays watched — only the name is removed.

Remap to a New Path (Drive Migration)

When you move files to a new drive, remap the namespace instead of unwatching and re-watching:

atlas namespace remap my-samples /Volumes/NewDrive/Audio/Samples

Atlas uses the same fast reconnection system as external drive reconnection:

  1. Entities under the old path are marked disconnected
  2. Paths in current_state are rewritten from the old prefix to the new prefix
  3. Each file at the new path is stat-checked: if mtime and size match, it reconnects instantly (no rehash). If they differ, the file is rehashed.

This preserves all entity history and lineage — no data is lost. A 550K-file library remaps in under a minute.

The Daemon

Atlas uses a background daemon to monitor filesystem events. The daemon starts automatically when you atlas watch, but you can manage it directly.

The daemon polls for watch list changes every 2 seconds. This means you can add or remove watched paths while the daemon is running — no restart required. When a new path is detected, the daemon registers it and runs an initial scan automatically.

Start and Stop

atlas start          # Start daemon in background
atlas stop           # Stop daemon
atlas start --foreground  # Run in foreground (blocks terminal)

Status

atlas status

Shows whether the daemon is running (with PID), watched paths, entity counts, and boot persistence status.

GUI and CLI Daemon

The atlas-gui binary is dual-mode: if launched with start --foreground arguments, it skips the GUI entirely and runs as a headless watcher process. This means start_daemon_background() works identically whether called from the CLI (atlas) or the GUI (atlas-gui) — both use current_exe() to spawn a detached daemon process. Closing the GUI window does not stop the daemon.

Boot Persistence (macOS)

On macOS, Atlas can register as a launch agent so it starts automatically on login:

atlas start --boot   # Install launch agent
atlas stop --boot    # Remove launch agent

This creates a launchd plist at ~/Library/LaunchAgents/com.atlas.app.plist. The daemon is set to auto-restart if it crashes.

How File Watching Works

Event Processing

Atlas uses OS-native filesystem notifications (via the notify crate) with a 2-second polling fallback. Events are processed in order:

  • Create — New file detected. Hash computed, entity created or fork recognized.
  • Modify — File content changed. New hash computed and appended to hash history.
  • Rename — File renamed or moved. New name/path recorded in history. Atlas pairs rename events (from/to) to maintain entity continuity.
  • Remove — File deleted from watched space. Entity marked as deleted, history preserved. If an entire watched path disappears (drive ejected, folder removed), entities are marked as disconnected instead — indicating temporary unavailability rather than intentional deletion. For cloud-backed directories, individual file removals are also treated as disconnections when the parent directory still exists (see Cloud Storage).

Debouncing

To avoid processing intermediate states during rapid saves (e.g., an editor writing a temp file then renaming it), Atlas debounces Create and Modify events. The default debounce interval is 1000ms — Atlas waits until a file has been quiet for that long before processing the change.

Rename and Remove events bypass debounce for immediate handling, since they need to be paired correctly.

The debounce interval is configurable in ~/.atlas/config.toml:

debounce_ms = 1000

Move and Rename Detection

On macOS, filesystem events sometimes report a cross-directory move as separate Remove and Create events rather than a single rename. Atlas handles this with two layers of detection:

  1. Remove→Create pairing — Remove events are held in a short buffer. If a Create with the same content hash follows within 500ms, the pair is treated as a move.
  2. Create→Remove correction — If the Create arrives first (goes into the debounce buffer) and a Remove follows, Atlas checks the debounced path against the pending Remove before processing. If this also misses (debounce fires before the Remove arrives), Atlas detects the resulting fork-then-delete pattern and corrects it back to a move.

When multiple files share identical content, Atlas selects the fork parent closest to the new file’s path — so copying a file within a directory tree correctly identifies the nearest sibling as the source, not a distant file that happens to share the same hash.

External Drive Reconnection

When an external drive or removable volume is ejected, Atlas marks all entities under that path as disconnected. When the drive is reconnected, Atlas performs a fast reconnection pass before running a full scan:

  1. Stat comparison — For each disconnected entity, Atlas checks if the file still exists at its last known path and compares the stored mtime and file size against the current on-disk values.
  2. Fast reconnect — If the mtime and size match, the entity is flipped back to live without rehashing the file. This is the common case — the same drive, same files, no changes.
  3. Rehash on change — If the file exists but mtime or size differ (e.g., the file was modified on another computer while the drive was disconnected), Atlas rehashes the file and updates its record.
  4. Still missing — If the file no longer exists on the reconnected drive, it stays disconnected for later reconciliation.

This makes reconnection proportional to the number of stat calls (fast) rather than the number of hash computations (slow). A 550K-file external drive reconnects in under a minute instead of hours.

The GUI’s poller thread independently checks Path::exists() for all active watched paths every 2 seconds. When a path transitions between connected and disconnected (e.g., drive eject or remount), the GUI emits a connectivity_changed event to the frontend, updating the directory status indicator live — no app restart or daemon dependency required.

What About Deleted Entities?

Entities that were marked deleted (not just disconnected) are also checked during reconnection. If the file exists on disk at its last known path, Atlas reconnects it. This handles cases where files were incorrectly marked as deleted during previous unmount cycles.

Cloud Storage

Atlas automatically detects directories under cloud storage services (Dropbox, Google Drive, OneDrive, iCloud). Cloud-backed directories receive special treatment in the deletion pipeline: when files are removed locally — typically because the cloud provider evicted local copies to free disk space — Atlas marks them as disconnected instead of deleted, preserving their metadata for fast reconnection when the files are re-synced.

Auto-Detection

On macOS, any path under ~/Library/CloudStorage/ is automatically flagged as cloud-backed when you atlas watch it. Common Linux mount points (~/Dropbox/, ~/OneDrive/, ~/Google Drive/) are also recognized.

atlas watch ~/Library/CloudStorage/Dropbox/_Projects
# Now watching directory '...' [cloud-backed]

Manual Override

For cloud storage at non-standard paths, or to disable auto-detection:

atlas watch --cloud /mnt/syncthing/projects    # Force cloud-backed
atlas watch --no-cloud ~/Library/CloudStorage/Dropbox/local-only  # Disable

How Cloud Eviction Works

When files disappear from a cloud-backed directory but the parent directory still exists, Atlas treats the deletion as an eviction rather than a permanent removal:

  1. Entity stays disconnected — Status is set to disconnected instead of deleted. The entity’s mtime, file size, and hash are preserved.
  2. Fast reconnection — When the cloud provider re-syncs the files locally, Atlas uses the same stat-based reconnection as external drives: mtime/size match → instant reconnect, no rehash needed.
  3. Bulk eviction notice — When 5 or more files are evicted in a single reconciliation pass, the daemon emits a cloud_eviction event. The CLI prints a summary; the GUI shows an inline notification.

This distinction matters because cloud providers routinely remove local copies of files that haven’t been accessed recently. Without cloud awareness, Atlas would mark thousands of files as permanently deleted — losing their metadata — every time the provider reclaims disk space.

Status Indicators

Cloud-backed directories show a ☁ indicator in atlas status:

Active watched paths:
  [dir ] ~/Library/CloudStorage/Dropbox/_Projects  ☁  [projects]
         added: 2026-03-08  last activity: 2026-03-17

In the GUI, a ☁ icon appears next to the directory path. The watch status dot tooltip differentiates between “Directory unavailable — files may exist in cloud storage” and the standard “Directory unavailable” for disconnected drives.

Checking Status

atlas status

Active watched paths whose directory no longer exists on disk (e.g., ejected external drive) are tagged [disconnected]. This is computed at query time — reconnecting the drive and running atlas status again removes the tag.

By default, shows only actively watched paths. Use flags to filter:

atlas status              # Active paths (default)
atlas status --active     # Same as default
atlas status --inactive   # Paths no longer watched but with retained data
atlas status --all        # Both active and inactive paths

Example output:

Daemon: running (PID 1234)
Starts on boot: yes

Active watched paths:
  [dir ] ~/projects/myapp
         added: 2026-03-10  last activity: 2026-03-14
  [dir ] /Volumes/ExtDrive/Samples [disconnected]
         added: 2026-03-11  last activity: 2026-03-13
  [dir ] ~/Library/CloudStorage/Dropbox/_Projects ☁ [projects]
         added: 2026-03-08  last activity: 2026-03-17
  [file] ~/Documents/README.md
         added: 2026-03-12  last activity: 2026-03-12

Tracked entities: 542 active, 23 deleted, 12 disconnected

With --inactive:

Inactive watched paths (historical data retained):
  [dir ] /Volumes/OldDrive/Samples
         added: 2026-03-08  removed: 2026-03-14  last activity: 2026-03-13