Date: 2026-03-18 12:14 Model: Claude Opus 4.6 Type: requirements Artifact: ## Draft: Cloud Download for DAW Export ### Problem MixBoard can browse, stream, and add music to p
Partially yes, but the scope is confused. The core problem is clear and real: "I can't export my playlist to a DAW because cloud tracks get silently skipped." That's a legitimate, frustrating user problem. But the requirements document is solving two different problems and pretending they're one:
These have different priorities, different UX expectations, and different architectural implications. Flow B (manual download for offline playback) is a separate feature that's been smuggled into scope. Prior reviews already flagged this as a scope violation for a "Small" appetite. I agree — ship Flow A, defer Flow B.
A user who hits "Export to Audition" and gets a session with missing tracks cares about one thing: "Give me my complete session." They do NOT care about:
DownloadService mirrors UploadService patternstrack.filePath gets mutatedThey DO care about things this spec doesn't address:
"How long will this take?" — The spec says "progress is visible" but doesn't address the elephant in the room: a playlist with 40 cloud tracks could take 10+ minutes to download before export even starts. What's the UX for this? A progress sheet? Can they keep working? This is arguably the most important UX question and it's completely unspecified.
"What if my export is mostly done and one track fails?" — The silent-skip behavior is terrible, but fail-fast is also terrible if you're 35/40 tracks in. Users would want: download everything possible, tell me exactly what failed, let me export what succeeded. The spec punts on this entirely.
"Why is my 2GB export folder now 4GB?" — Downloaded cloud files sitting in a local directory permanently, never cleaned up. The spec has no cleanup strategy. [CHECK THIS]: Prior reviews flagged this as a disk leak risk — it's still unaddressed.
"I exported this yesterday, why is it downloading again?" — No caching strategy is defined. Does a second export re-download everything?
| Assumption | Why It Matters |
|---|---|
| Stream URLs are stable and don't expire | If URLs rotate or have TTLs, downloads during long exports will fail mid-way |
| Files at stream URLs are complete audio files, not chunked/containerized for streaming | [CHECK THIS] — The spec says "not HLS" and "direct HTTP file URL," but is the file at the stream URL identical to the original upload? If Nginx or the backend does any processing, "preserves original format" may not hold |
| Auth is not enforced on file-server routes and won't be | The spec notes this but treats it as permanent. If auth gets added next sprint, every download breaks. Send the Bearer token now anyway. |
| Network is available at export time | No offline-first consideration. What if they're on a plane? |
track.cloudStreamPath is always a valid, complete URL |
What validation exists? |
| Downloaded files have usable filenames | Stream URLs often have UUIDs or hashes as paths. Does /streams/a3f8c2d1-... become a usable filename in a DAW session? DAW users care deeply about track names. |
"Mirrors UploadService pattern" vs the actual need: UploadService is a fire-and-forget background operation. Export-driven download is a blocking, synchronous dependency in a pipeline. These have fundamentally different error handling, cancellation, and lifecycle requirements. Mirroring the pattern will lead you to the wrong architecture. Prior Review 2's recommendation of a pre-export preflight step is correct — this is a preparation phase, not a background service.
track.filePath mutation vs data integrity: Setting track.filePath on a SwiftData @Model after download conflates "I have a cached copy for export" with "this is a local track." What happens when the cached file gets deleted? Now you have a Track that claims to be local but has no file. The isCloud flag and filePath are now out of sync. This is a data corruption bug waiting to happen. Use a separate cache lookup, not model mutation.
"Cancel download is supported" during export: What does cancel mean? Cancel one track's download? Cancel the whole export? Cancel downloads but continue export with partial tracks? This is unspecified and will create confusing UX if not defined.
"{trackName}.{originalExtension}" with sanitization and collision handling (append -1, -2, etc.)Content-Length headers are available from Nginx [OPEN QUESTION from prior review, still unanswered], check available disk space before starting.No outright hallucinations detected, but several specific code entity names are unverifiable.
The core problem is right. The scope is wrong, the architecture is risky, and the hardest UX questions are unanswered.
Ship this as v1:
Defer to v2: manual download, offline playback, persistent caching, library-level download management.