| 1 |
# Loose-files mode |
| 2 |
|
| 3 |
## Overview |
| 4 |
|
| 5 |
Per-vault opt-in mode where audiofiles references samples at their original disk location instead of copying them into the vault's `samples/` directory. Trades safety for disk space savings. |
| 6 |
|
| 7 |
In normal mode, every import copies the file into `vault/samples/<hash>.<ext>`. In loose-files mode, the database records the original path and no copy is made. The file stays where the user put it. |
| 8 |
|
| 9 |
## Enabling |
| 10 |
|
| 11 |
Loose-files mode is a vault-level setting, toggled in vault settings. Changing it only affects future imports — samples already in the vault are not moved or copied retroactively. |
| 12 |
|
| 13 |
A vault stores its mode as a preference row: |
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
| `loose_files` | `0` or `1` | `0` | |
| 18 |
|
| 19 |
When loose-files mode is on, the vault settings UI shows a persistent warning: |
| 20 |
> **Loose-files mode is on.** Samples are not copied into this vault. Moving, renaming, or deleting originals will break references. |
| 21 |
|
| 22 |
## Import Behavior |
| 23 |
|
| 24 |
### Normal Mode (unchanged) |
| 25 |
|
| 26 |
1. Hash file → copy to `samples/<hash>.<ext>` → insert `samples` row |
| 27 |
2. File is self-contained in the vault forever |
| 28 |
|
| 29 |
### Loose-files mode |
| 30 |
|
| 31 |
1. Hash file → record original absolute path → insert `samples` row |
| 32 |
2. No copy is made |
| 33 |
3. The `samples` row gets an additional `source_path TEXT` populated with the original absolute path |
| 34 |
|
| 35 |
If a sample with the same hash already exists (duplicate detection still works), skip it as usual regardless of mode. |
| 36 |
|
| 37 |
## Schema Change |
| 38 |
|
| 39 |
Add one column to `samples`: |
| 40 |
|
| 41 |
```sql |
| 42 |
ALTER TABLE samples ADD COLUMN source_path TEXT; |
| 43 |
``` |
| 44 |
|
| 45 |
- `NULL` → normal mode sample (blob lives in `samples/`) |
| 46 |
- Non-`NULL` → loose-files mode sample (blob lives at this path) |
| 47 |
|
| 48 |
This is the only way to tell which mode a sample was imported under. A vault in loose-files mode can contain a mix of both kinds if the mode was toggled between imports. |
| 49 |
|
| 50 |
## Playback and Access |
| 51 |
|
| 52 |
When resolving a sample's file path: |
| 53 |
|
| 54 |
1. If `source_path` is `NULL`, use `vault/samples/<hash>.<ext>` (current behavior) |
| 55 |
2. If `source_path` is non-`NULL`, use `source_path` |
| 56 |
|
| 57 |
## Graceful Recovery |
| 58 |
|
| 59 |
Loose-files mode makes a best-effort attempt to handle files that have gone missing. It does not try to be clever. |
| 60 |
|
| 61 |
### On Access (Playback, Preview, Export, Analysis) |
| 62 |
|
| 63 |
If `source_path` points to a file that no longer exists: |
| 64 |
|
| 65 |
1. Check `vault/samples/<hash>.<ext>` as a fallback — the user may have re-imported in normal mode or manually placed the file there |
| 66 |
2. If the fallback also misses, mark the sample as **unavailable** in the UI (grayed out, struck-through name, tooltip: "Original file not found at `<path>`") |
| 67 |
3. Do not delete the metadata row — the sample keeps its tags, VFS position, and analysis data |
| 68 |
|
| 69 |
### Relocate |
| 70 |
|
| 71 |
Provide a **Relocate** action on unavailable samples: |
| 72 |
|
| 73 |
- User picks a new file |
| 74 |
- App verifies the SHA-256 hash matches the sample's `hash` |
| 75 |
- If it matches, update `source_path` to the new location |
| 76 |
- If it doesn't match, reject with: "Hash mismatch — this is a different file" |
| 77 |
|
| 78 |
No batch relocate, no folder scanning, no automatic search. Keep it manual and simple. |
| 79 |
|
| 80 |
### Vault Integrity Check |
| 81 |
|
| 82 |
Add a "Check vault" action (in vault settings, next to the loose-files mode toggle) that scans all `source_path` entries and reports how many are valid vs. missing. Informational only — it does not fix anything, just gives the user a count. |
| 83 |
|
| 84 |
## What This Does NOT Do |
| 85 |
|
| 86 |
- Does not watch the filesystem for changes |
| 87 |
- Does not auto-relocate or search for moved files |
| 88 |
- Does not create symlinks or hardlinks |
| 89 |
- Does not support relative paths — `source_path` is always absolute |
| 90 |
- Does not convert existing samples between modes (no retroactive copy-in or copy-out) |
| 91 |
- Does not sync `source_path` values via SyncKit — paths are device-local and meaningless on other machines |
| 92 |
|