Skip to content

scan

fialr scan <target> [options]

Traverse a directory, compute BLAKE3 and SHA256 hashes for every file, detect MIME types, classify each file by sensitivity tier and category, and generate a structured manifest. Read-only. No files are modified.

As of v1.0, scan classifies files by default. The standalone fialr classify command remains available as a backward-compatible alias.


ArgumentDescription
targetDirectory to scan (required)
OptionDescription
-o, --output PATHWrite manifest JSON to this path
--no-classifySkip classification (scan only, no sensitivity tiers or categories)
--include-cloudProcess cloud-evicted files (e.g. iCloud files not downloaded locally)
--sensitivity-rules PATHPath to sensitivity.yaml (default: config/sensitivity.yaml)
-v, --verboseShow debug logs
-q, --quietSuppress status output

scan walks the target directory recursively and builds a manifest.json containing:

  • Relative path, absolute path, file size
  • BLAKE3 hash (primary, canonical identifier)
  • SHA256 hash (secondary, cross-tool verification)
  • MIME type (via python-magic)
  • Sensitivity tier and category (unless --no-classify is set)
  • Exclusion records with reasons

By default, scan applies sensitivity rules from sensitivity.yaml to assign each file a tier (RESTRICTED, SENSITIVE, or INTERNAL) and a category suggestion. Classification uses structural signals only — filename patterns, extensions, directory heuristics, and MIME type. File content is never read during classification.

Pass --no-classify to skip classification and produce a manifest with hashes and MIME types only.

Every file is hashed in full. There is no sampling or partial-read mode. The buffer size for hashing is configurable in fialr.toml under [inventory].buffer_size (default: 256 KB).


The scan respects fialr’s four-layer exclusion system:

  1. Hardcoded.git/, node_modules/, .venv/, __pycache__/, .ssh/, .gnupg/, .Trash/, system directories, and project roots (detected by sentinel files like package.json, Cargo.toml, pyproject.toml)
  2. Config directories — explicit paths in fialr.toml under [exclusions].directories
  3. Config patterns — globs in fialr.toml under [exclusions].patterns
  4. XATTR/sentinel opt-outcom.fialr.exclude extended attribute or .fialr-exclude sentinel file

Every excluded file is recorded in the manifest with its exclusion reason and the layer that triggered it. Nothing is silently skipped.


On macOS, fialr detects iCloud Drive sync state via the platform adapter. Files that are evicted (cloud-only, not downloaded locally) are skipped by default — they are recorded in the manifest with their sync state, but no hash is computed.

To materialize evicted files and include them in the full inventory, pass --include-cloud. This triggers iCloud to download each evicted file so it can be hashed and processed like any local file.


To stderr (human-readable):

scan ~/Documents
SCAN 847 files (2.3s)
CLASSIFY 847 files (0.1s)
────────────────────────────────────────────────────────
files 847
excluded 23
tier 1 12 RESTRICTED
tier 2 89 SENSITIVE
tier 3 746 INTERNAL
errors 0
elapsed 2.4s

When --output is specified, the manifest JSON is written to the given path. Without --output, the manifest is held in memory only and used as input to subsequent pipeline stages.


Terminal window
# Scan and classify a directory
fialr scan ~/Documents
# Scan without classification
fialr scan ~/Documents --no-classify
# Write manifest to file
fialr scan ~/Documents -o manifest.json
# Include iCloud-evicted files
fialr scan ~/Documents --include-cloud
# Use custom sensitivity rules
fialr scan ~/Documents --sensitivity-rules ./my-rules.yaml
# Quiet mode -- errors only
fialr scan ~/Documents -q