Data Model
Libraries and storage locations
Section titled “Libraries and storage locations”A library is the top-level entity — a music collection with its own identity (library_id), name, and encryption key. It lives at a library home on disk (~/.bae/libraries/{uuid}/), where the desktop app writes the authoritative database.
A library can optionally have a cloud home — a single cloud location (Google Drive folder, S3 bucket, etc.) that acts as the collaborative hub for multi-device sync and multi-user access. One cloud home per library, configured in config.yaml. See Cloud Home for details.
Release files can live in one or more of these locations:
- Library home (
~/.bae/libraries/{uuid}/storage/) — local copy, available offline - Cloud home (
cloud-home/storage/) — encrypted copy, available for sync - Unmanaged — files stay wherever they are on disk, bae just indexes them
A release can be local only, cloud only, or both. Cloud-only files are not available for offline playback.
Directory layout
Section titled “Directory layout”Library home
Section titled “Library home”~/.bae/libraries/{uuid}/ config.yaml # device-specific settings (not synced) library.db # SQLite -- all metadata images/ab/cd/{id} # library images (covers, artist photos) storage/ab/cd/{file_id} # release files manifest.json # library identity (library_id, name, encryption fingerprint)config.yaml holds device-specific settings. It is not synced. Credentials go in the OS keyring, not here.
Files under images/ and storage/ use a hash-based layout: the first 2 characters of the ID form the prefix directory, the next 2 form a subdirectory. No filenames or extensions on disk — original filenames and content types live in the database. Same layout in both the library home and cloud home.
Cloud home
Section titled “Cloud home”The cloud home mirrors the library’s data and adds sync and access control machinery:
| Path | Purpose |
|---|---|
snapshot.db.enc | Full database snapshot (bootstrap for new devices) |
changes/{device_id}/{seq}.enc | Incremental sync changesets |
heads/{device_id}.json.enc | Per-device sequence numbers |
images/ab/cd/{id} | Library images (encrypted) |
storage/ab/cd/{file_id} | Release files (encrypted) |
membership/{pubkey}/{seq}.enc | Membership chain entries |
keys/{user_pubkey}.enc | Per-user wrapped encryption keys |
Keyring entries
Section titled “Keyring entries”Managed by KeyService, using the OS keyring (on macOS, the protected data store with iCloud Keychain sync). All entries are namespaced by library_id unless noted otherwise.
| Entry | Scope | Purpose |
|---|---|---|
encryption_master_key | per-library | File and metadata encryption |
cloud_home_credentials | per-library | Serialized enum: S3 access+secret, OAuth token, or none (iCloud) |
discogs_api_key | per-library | Discogs API access |
server_password | per-library | Subsonic API authentication |
followed_password:{id} | per-library | Per-followed-library password |
bae_user_signing_key | global | Ed25519 signing key |
bae_user_public_key | global | Ed25519 public key |
Two classes of files
Section titled “Two classes of files”Release files
Section titled “Release files”Whatever files came with a release: audio, images, CUE sheets, logs, etc. These are the user’s data. bae stores them exactly as imported so they can be ejected intact or seeded as torrents.
Metadata images
Section titled “Metadata images”Images that bae creates and manages, separate from release files:
- Release covers — display art for album grids, detail views, playback. One per release. May come from a file in the release or from MusicBrainz/Discogs. bae makes its own copy, so it can crop or resize without affecting the original.
- Artist images — fetched from external sources during import.
First-run flows
Section titled “First-run flows”New library: On first run, the desktop app shows a welcome screen. The user creates a new library, which generates a UUID, creates the directory structure, and launches the app. The storage/ directory starts empty — files appear as the user imports.
Restore from cloud home: The user provides cloud home credentials and the encryption key. bae downloads the snapshot, applies any newer changesets, and downloads images. Local storage/ starts empty — release files stream from the cloud home on demand.
Going from local to cloud: The user signs in with a cloud provider. bae generates an encryption key (if needed), pushes a full snapshot, images, and release files, then switches to incremental sync.