# Scans and scopes

> What census scans, how to choose a scope, where the saved scan lives, and how queries reuse it.

## Scan the startup drive

`census`, `census scan` and `census scan --scope drive` all do the same thing: scan the whole startup drive and save the result.

```sh
census scan
```

A drive scan covers the System volume, the Data volume that holds your files and apps, and the startup drive's support volumes (Preboot, VM, Update). It stops at every other mount: external drives, network shares and mounted disk images.

A scan never follows symbolic links, never reads what is inside your files, and never changes anything. It records names, sizes and dates.

## Choose a scope

Every command that reads a scan takes a scope. Use the same scope for every step of a job, so `findings`, `clean` and `review` all look at the same scan.

| Scope | What it covers |
| --- | --- |
| `--scope drive` | The whole startup drive. The default. |
| `--scope data` | Only the Data volume (`/System/Volumes/Data`), where your files and apps live. |
| `--path PATH` | One folder. `census scan PATH` does the same. |

```sh
# Scan only your Downloads folder
census scan --path ~/Downloads

# Scan an external drive: give its mount point as the path
census scan --path /Volumes/Backup

# Query that folder's scan, not the drive's
census top --path ~/Downloads
```

The apps commands (`apps`, `app`, `leftovers` and `uninstall`) need a scan that includes `/Applications` and `~/Library`, which the default drive scan does.

## Read the summary

Without `--json`, a scan prints a short summary:

```text title="Example output"
Macintosh HD   225 GB used · 20.0 GB free

  90.4 GB   █████▋          Other users
  49.0 GB   ███             App data
  35.0 GB   ██▏             macOS
  18.7 GB   █▏              Hidden space
  …

Biggest files
  47.3 GB   ~/Library/Containers/…/2B5D7503.img

Safe to clean: 1.3 GB → census findings
```

- **Used and free** match `diskutil` and Disk Utility.
- **The rows add up to the used space.** Every size is space on disk, not the files' nominal length.
- **Hidden space** is used space census can't see as files: snapshots, the Recovery volume, files macOS protects, and folders it couldn't read.

| Row | What it holds |
| --- | --- |
| macOS | `/System`, `/usr`, `/bin`, `/sbin` |
| Applications | `/Applications`, `~/Applications` |
| App data | `~/Library` |
| Documents | The rest of your home folder, and `/Users/Shared` |
| Developer | Homebrew, `~/Library/Developer`, `~/.cargo`, `~/.npm`, project build output |
| AI agents | `~/.claude`, `~/.codex`, and the data of Cursor, Windsurf and other AI apps |
| Caches, Logs, Trash | What their names say |
| Other users | Other people's home folders |
| System Data | Everything else the system uses: `/private`, `/Library`, swap |

`census report` shows the details behind the numbers, and `census scan --verbose` prints the scan's diagnostics before the summary.

### Why Finder shows less used space

Finder counts purgeable space (snapshots, iCloud files it can download again, some caches) as free. census counts it as used until macOS actually frees it. In JSON, `coverage_details.capacity.purgeable_bytes` is that amount, when macOS reports it.

## Saved scans and rescans

Each scan saves its folder tree in `~/Library/Caches/census/`, one file per scope, and keeps a JSON report of it in `~/Library/Application Support/census/history/`, the 20 newest. Set `CENSUS_CACHE_DIR` or `CENSUS_DATA_DIR` to move them. `--no-save` scans without saving either.

The next scan of the same scope is **incremental**: it replays macOS's file system event log since the saved scan, reads again only the folders that changed, and merges them into the saved tree. It falls back to a full scan, and reports why, when:

- there is no saved scan yet, or macOS was updated;
- Full Disk Access or the user changed;
- a volume was replaced, or its event history was reset;
- the event log dropped events or too many folders changed;
- the last full scan is more than 7 days old, or 50 rescans have run since it.

`--full` forces a full scan. In JSON, `scan_mode` is `full` or `incremental`, and `full_scan_reason` says why a full scan ran despite a saved one.

## Query a saved scan

Queries such as `top`, `ls`, `findings` and `duplicates` read the newest saved scan of their scope. They don't walk the disk again, so the answer is as fresh as that scan. Add `--refresh` to rescan the scope first:

```sh
# Answer from the saved scan
census findings

# Rescan first, then answer
census findings --refresh
```

Without a scope, `census ls PATH` and `census top --under PATH` use the newest saved scan that contains `PATH`. `census scans` lists every saved scan:

```sh
census scans --json
```

```json
{
  "schema_version": 5,
  "command": "scans",
  "status": "ok",
  "exit_code": 0,
  "errors": [],
  "warnings": [],
  "scan": null,
  "results": [
    {
      "scope_kind": "path",
      "root": { "display": "/Applications", "lossy": false },
      "scan_id": "…",
      "items": 172266,
      "bytes": 1920503
    }
  ]
}
```

## Full Disk Access

macOS keeps some folders, such as Mail, Messages and Safari, from apps without Full Disk Access. `census` gets it from whatever started it:

- **In the app,** the app starts `census`, so the access you gave Disk Census covers it.
- **In Terminal,** `census` has Terminal's access, not the app's. To include those folders, add Terminal under System Settings › Privacy & Security › Full Disk Access, then reopen Terminal. The same goes for iTerm, an editor's terminal, or the app an AI agent runs in.

Check what the current process has:

```sh
census access --json
```

`results.status` is `granted`, `not_granted` or `unknown`. Without access, the folders a scan couldn't read count as Hidden space, the scan can end as `partial` (exit code 4), and `coverage_details.access_hint` is `full_disk_access_required`.

## Other users' files

Other people's home folders on the Mac are counted in Hidden space. To include them, scan with `sudo`:

```sh
sudo census scan
```

The saved scan and its history belong to you, the user who ran `sudo`, so later queries without `sudo` read them. Commands that delete refuse to run as root (`run_as_root`), so never use `sudo` to clean.
