01 — Architecture
Decision
Use a Swift native filesystem engine, Next.js/TypeScript management UI, and SQLite local catalog.
Why Swift
Burrow™ is macOS-specific. The engine will eventually need first-class access to:
- mounted volume metadata;
- file resource values and extended attributes;
- macOS permissions and sandbox/security-scoped resources;
- iCloud file metadata;
- file coordination;
- Trash operations;
- filesystem events;
- removable media lifecycle;
- native notifications/background behavior.
Rust remains a good option for portable high-performance hashing libraries, but a separate Rust service is unnecessary complexity initially. Native or packaged BLAKE3 support can be introduced behind a hashing interface.
Logical Architecture
┌───────────────────────────────────────────────┐
│ Next.js Management UI │
│ Dashboard / Storage / Files / Backup / etc. │
└──────────────────────┬────────────────────────┘
│ typed local API / IPC
┌──────────────────────▼────────────────────────┐
│ Burrow Engine │
│ │
│ Volume Discovery Scanner Cloud Classifier │
│ Hashing Rules Backup/Archive(*) │
│ Safety Gate Activity/Audit │
└──────────────┬───────────────────┬────────────┘
│ │
┌──────▼──────┐ ┌──────▼──────────┐
│ SQLite │ │ macOS Filesystem │
│ Local State │ │ iCloud/OneDrive │
└─────────────┘ │ External Volumes │
└───────────────────┘
(*) Disabled in v0.1
Process Boundary
The UI must never be granted unrestricted filesystem primitives. It requests domain operations such as:
listVolumesstartScangetScanStatusqueryFilesgetDuplicateGroups
Future mutation operations must pass through a centralized Safety Gate.
Engine Modules
VolumeDiscovery
Detects mounted volumes and stable identities.
ScanCoordinator
Creates scan runs, manages cancellation/progress, delegates traversal.
FileScanner
Enumerates selected roots and captures metadata.
StorageClassifier
Classifies records as local, iCloud, OneDrive, removable, etc.
HashService
Provides staged hashing and hash caching.
DuplicateAnalyzer
Creates exact/probable duplicate groups.
RecommendationEngine
Produces explainable, non-destructive recommendations.
SafetyGate
Central authorization point for all future filesystem mutations.
BackupEngine / ArchiveEngine
Designed now, implemented after v0.2.
ActivityService
Records scans, analysis, errors, and eventually all mutations.
UI/Engine Communication
The v0.1 transport is HTTP on IPv4 loopback:
- bind
127.0.0.1only (never a wildcard interface); - default port
8741, or0for an ephemeral port; - every
/healthand/identityrequest requires headerX-Burrow-Secret(legacyX-PlatypusVault-Secretis still accepted); - the secret is random per process unless
BURROW_ENGINE_SECRET, legacyPLATYPUSVAULT_ENGINE_SECRET, or--secretis set; - typed JSON contracts live in
/contracts; - no arbitrary path, SQL, or shell endpoints.
The Next.js client calls http://127.0.0.1 only. Hosted HTTPS deployments (burrow.jasonkoch.io / burrow-dev.jasonkoch.io) cannot reach the engine and must display disconnected. Mixed-content rules block https pages from calling loopback HTTP.
A native wrapper/IPC approach may replace HTTP later without changing domain contracts. See contracts/README.md.
SQLite
SQLite is authoritative for application state but never authoritative for whether a file currently exists. Filesystem reality wins and is reconciled through scans.
Enable foreign keys and WAL mode where appropriate.
The 0.1 catalog file lives under Application Support (Burrow/catalog.sqlite) or a temporary directory in tests. A legacy PlatypusVault/catalog.sqlite is reused when the Burrow™ catalog is missing. It must never be created in Documents, iCloud Drive, or OneDrive. Ordered migrations create volume, provider, storage_root, scan, scan_root, and file_item. Catalog writes are metadata-only; they do not copy, move, or delete user files. Hash and duplicate tables wait for 0.2.
Concurrency
Scanning should be cancellable and bounded. Do not open/hash an unbounded number of files concurrently.
Metadata enumeration and hashing should use separate concurrency controls because hashing is I/O intensive.
Incremental Scanning
The catalog should allow unchanged files to reuse metadata/hash results. Future filesystem-event monitoring may mark roots dirty, but full correctness must never depend solely on events.
Error Philosophy
A permission error or unavailable cloud placeholder must not fail an entire scan. Record the issue, continue where safe, and expose incomplete coverage in the UI.
Packaging Direction
The end product should feel like a Mac utility, even though the management UI is Next.js. Packaging options should be evaluated after v0.1 proves the engine/UI boundary.
Architectural Non-Goals
- cross-platform support in the first release;
- remote web access to the management UI or engine;
- multi-user server architecture;
- uploading inventory to a SaaS backend;
- embedding arbitrary shell execution in the UI.
Public documentation and the management UI are the Next.js site at burrow.jasonkoch.io. That hosted console is not remote access to the engine. See docs/hosting.md.