Skip to content

45 — Release Pipeline — Project Assets, Motion Covers & Configurable Readiness (envisioning)

↳ Superseded-in-part by 46-WORKFLOW-ENGINE.md (2026-06-28). The "configurable readiness" thread here generalized into the broader adaptable workflow engine (doc-46 — ordered Stages → Steps, templates + custom, per studio/project/variant). doc-45 keeps the motion-cover media + project asset space specifics (the assets workflow steps bind to). Read doc-46 for the workflow framing.

Envisioning doc — needs confirmation. POST-MVP. Governed by 00-ROADMAP.md. Created 2026-06-28 (owner-raised, mid-mgmt.ctrl). The seed idea: store / preview / approve animated ("motion") covers the way Apple Music shows them, inside a project "cloud"/asset space that also holds other project/artist/track documents — and the realization that release-readiness has more (and configurable) elements than Title · Cover · Version, varying per project/album and per alternative version (remix / radio-edit / live / instrumental). The unlock is "LEGO" (doc-43) applied to the release pipeline — the workflow hub (mgmt.ctrl doc-42 + Portals doc-26) needs to be prepared for it.

The idea, in three threads

  1. Motion / animated covers (Apple-Music-style) — store · preview · approve. A project (and track) can carry an animated cover asset (a short looping video, the format streaming services accept for motion art), alongside the still cover. The owner wants to preview it in-app the way it will appear before publishing, keep multiple candidate animations, and run them through the approval gate like any other release dimension. Market note (to verify): a dedicated "preview your motion cover as the store will render it" tool may be a genuine gap — worth a scan.Player side → doc-57 §5.2 (2026-07-05): in-app "listening mode" preview + iOS 26 MPMediaItemAnimatedArtwork full-screen lock-screen preview (the literal Apple Music surface, open to third-party apps). Apple's format/placement constraints recorded there — dual 1:1 3840² + 3:4 2048×2732 files, 23.976–30 fps, seamless loop, first frame = still cover, EP/Album/Artist pages only (not singles) → motion artwork is a Project/ArtistSpace asset. This doc keeps store · preview-as-store-renders · approve.
  2. A project "cloud" / asset space. Beyond the cover, a project (and artist / track) accrues documents and assets — contracts, splits, lyrics, art candidates, motion covers, reference files. Today attachments are track-level (folder-structured: Lyrics / Stems / Contracts). The idea lifts this into a per-node asset space ("the project's cloud / folder") at project and artist altitude too.
  3. Configurable, variant-aware release-readiness. "Ready for production" is not a fixed Title-Cover-Version triple. The set of required elements should be configurable per project/album and per variant (a remix may not need new lyrics; a live version needs different sign-offs; an instrumental skips the vocal check). The release checklist itself is data, not code.

What already anchors this (it's largely a synthesis)

Existing docWhat it already givesWhat this doc adds
doc-32 Approval modelApproval as a dimension (audio/cover/lyrics/tracklist/metadata/master) + a Project release-gate rollupMake the dimension set configurable (per project/variant), and add motion-cover as a dimension
doc-28 VariantsvariantType (remix · radio-edit · live · instrumental · clean · explicit) + cross-refsPer-variant readiness profiles — different variants require different elements
doc-43 LEGO attributesPer-workspace configurable catalog (definitions, levels, presets)Apply the same engine to the readiness checklist — a "readiness element" is a definition with an approver + an asset slot
doc-34 Image deliveryCover variants (webp / thumb / medium / original), Sharp pipelineMotion cover = a new media type (video/loop) with its own storage + preview + (later) transcode
Attachments (track)Folder-structured Lyrics / Stems / Contracts on a Track (storage.service.ts, doc CLAUDE)Lift attachments to a per-node asset space at Project + Artist altitude
doc-42 mgmt.ctrlThe workflow hub (Board = release-readiness rollup)The hub renders a configurable checklist + the asset space, not a fixed triple

What's genuinely net-new

  • Motion-cover media — a new File type (video/loop) on Project/Track, with: upload, an in-app preview that mimics the store's rendering, candidate history, and an approval verdict. Distribution- format constraints (codec/length/aspect) to be researched.
  • Per-node asset space — generalizing attachments beyond Track to Project & Artist ("the cloud"), holding documents + media; permission-scoped (doc-44) and surfaced in the node's Portal (doc-26).
  • Configurable readiness profiles — a release-checklist definition (which elements are required, who approves each, which asset each binds to) that varies by project and by variant — the LEGO engine (doc-43) extended from metadata fields to workflow steps.

The asset cloud across the hierarchy (owner-raised 2026-06-30) — design pass

The owner: "I don't know where to locate those files — the cloud/folders/files related to different parts of the hierarchy." Real gap. Grounded findings (verified against the code 2026-06-30):

  • Track attachments already existTrack.attachments is folder-structured ({ Lyrics: [], Stems: [], Contracts: [] } + custom), with endpoints GET /track/:id/attachments, POST /track/:trackId/attachments, POST /track/:trackId/attachments/folder. A file = a File with type: 'attachment'. But there is NO iOS surface — so the user can't find them. (The File Portal, doc-49, is a single audio version's detail — a different thing from the attachments cloud.)
  • Nothing at Project / Artist / Workspace — attachments are Track-only today (resourceType enum even lists project/track/artistSpace, but attachments only live on Track).
  • So the "files at every node" the owner pictures is right (it's this doc's "per-node asset space") but only partially real and entirely unsurfaced.

The model (the fractal again): an asset cloud = node-attached folders → files, available at every altitude (Workspace · Artist · Project · Track), surfaced as a "Files" zone in every Portal (doc-49 anatomy — Files becomes a standard zone, like Notes). Two relationships, kept distinct:

  • Attach-at-node — a file/folder belongs to one node (a contract on the Project, stems on the Track). Generalize today's Track.attachments to a File(type:'attachment', resource:{type,id}, folder) attachable to any node — one model, every altitude (mirrors doc-48's define-at/apply-at thinking).
  • Aggregate-view-up — a higher node's Files zone can roll up its descendants' attachments (the Project "cloud" shows its tracks' Stems; the Workspace cloud is the studio drive) — a read lens, not a move. Default folders (Lyrics/Stems/Contracts) are system presets; custom folders per node (doc-43).

Surfacing (consistent with doc-47/49): Configure/Browse = manage the files (upload, foldering, delete, permission-scope per doc-44); Portals = the Files zone at each node (browse + the node's own attachments + a roll-up of descendants). Motion covers (above) are a typed asset inside this same cloud.

Sequencing (smallest-first): (1) surface the existing Track attachments in the Track Portal's Files zone (uses today's endpoints — immediate, no backend); (2) generalize the attachment model to Project/Artist/Workspace (net-new backend: attachments at any resourceType + endpoints); (3) roll-up view at higher nodes; (4) motion covers as a typed asset. (Owner 2026-06-30 chose envision-first — this section — before building; step 1 is the natural first build when greenlit.)

Updated 2026-07-04 (doc-54 greenlight round) — step 1 SHIPPED + two owner rulings: the Track Portal now has the Files zone (iOS: folder-grouped list + add-file upload over today's endpoints; xcodebuild green).

  1. Files ride the node. An attachment belongs to its node, never to a path — "if the element moves to different dimensions of the hierarchy, all the files should move too" (owner). Reads/UI already behave this way (the map lives on the node); the constraint bites at step 2: blob storage keys are node-derived (createFileAttachmentLink), so a future node-move must re-key or indirect the blobs. Stated now so the generalized model designs for it.
  2. Workspace/Roster placement. The owner's instinct ("so root, so tenant — maybe another section") is confirmed: the Workspace cloud lives in the Workspace Portal's Files zone (Configure ▸ Workspace — its existing home, the "studio drive"), not in Browse. Roster stays a lens (doc-48/49): no cloud of its own — a roster's Files view is an aggregate-view-up filter over its artists' clouds. Tenancy implications → 55-TENANCY-PERSONAS.md.

Step 2 BACKEND SHIPPED (2026-07-04, same day; nest build + 13 e2e green): the generalized model — File(type:'attachment') gains folder + resourceType ('track'·'project'·'artistSpace'· 'workspace'); new AttachmentService (file module) + endpoints GET/POST /artist/:id/attachments · /project/:id/attachments · /workspace/attachments (workspace = owner-scoped "studio drive"); blob keys node-derived via createNodeAttachmentLink; reads AND writes gate through PermissionService.can() (doc-44's first route consumers, legacy-fallback safe); track uploads forward-fill the new fields (legacy embedded-map backfill = later pass). Integration test test/attachments.e2e-spec.ts (in-memory Mongo, stubbed storage, default-deny asserted). iOS surfacing SHIPPED (same day; xcodebuild green): shared PortalFilesSection + Files zones on the Artist / Project / Workspace Portals (folder-grouped, foot-"+" "Add file" when empty; Project's foot now composes cover+file; Workspace = the "studio drive" between Defaults and Roster).

Step 3 — AGGREGATE-VIEW-UP SHIPPED (2026-07-04, full stack; e2e 5/5 + xcodebuild green): the "cloud mapped with the hierarchy". ?rollup=1 on the three GET endpoints returns the node's own attachments plus every descendant's (ancestor-ref query — track/project attachments carry the refs, so it's one cheap find, a read lens not a move). iOS rows show a tier chip (Artist/Project/Track/ Studio) for files living below the node; own files stay clean. So the Project cloud shows its tracks' stems, the Artist cloud rolls up its projects+tracks, the Workspace = the whole studio drive. Legacy backfill SHIPPED (2026-07-05): scripts/backfill-attachment-fields.ts (dry-run by default, APPLY=true to write) forward-fills folder + resourceType:'track' onto pre-existing track attachments from the embedded Track.attachments map, so legacy files fold into the roll-up grouped + tier-chipped like new uploads. Idempotent; orphan-ref safe. Owner to run it against the dev/prod DB when ready.

Files are now a configurable-attribute + searchable layer (owner-raised 2026-07-05): FileType / attachment folder / MIME / size / duration + custom File.metadata become LEGO attributes (doc-43 §3), and the asset cloud gains filter/search (doc-40 — "show only Stems across this project"). Envisioned; builds with the doc-43 catalog slice. Remaining: Home "+" "Add file" · Track-zone dedupe onto the shared section · cloud pagination.

The synthesis (the vision)

Release-readiness becomes a configurable, variant-aware checklist over a project asset space. Each checklist element = { key, label, approver-role, asset-slot, applies-to-variants[] } — a LEGO definition (doc-43). The Project release-gate (doc-32) rolls up whichever elements the project's profile declares (not a hardcoded triple); each element points at an asset in the project's space (still cover, motion cover, lyrics doc, master file, contract…). The workflow hub = mgmt.ctrl Board + the node Portals, now rendering the live checklist + preview affordances. Solo artists get a sensible default profile; labels/power users customize it (premium, doc-31).

Open questions / to envision (later pass)

  1. Motion-cover format & preview fidelity — what formats do the target stores accept; how faithfully can we preview "as the store renders" in-app; transcode now or accept-and-store? Format half answered → Apple's spec + the iOS 26 lock-screen preview path now recorded in doc-57 §5.2; transcode/accept-and-store still open.
  2. Asset-space model — extend the existing attachment/folder model upward, or a new Asset/Space entity? Permission + storage-cost implications (doc-21 BYO-bucket, doc-44 grants).
  3. Readiness profile authoring — where do you define a project/variant's required elements (Portal? mgmt.ctrl? Workspace Settings, doc-43)? Default profiles per release type (single/EP/LP)?
  4. Variant ↔ profile binding — does each variantType (doc-28) carry a default readiness profile?
  5. Scope independence — motion covers, the asset space, and configurable readiness are separable slices; which delivers first value? (Likely: motion-cover preview as a self-contained wow; asset space next; configurable readiness rides doc-43.)

Sequencing

Post-MVP. Full configurability depends on doc-43 (the LEGO engine) being built; motion covers and the asset space are separable and could land earlier as self-contained features (motion-cover preview is a strong standalone "wow"). The mgmt.ctrl Board + Portals are the hub that surfaces all of it. Revisit after the MVP loop + doc-43.


Status: envisioning, post-MVP, captured 2026-06-28. A synthesis of doc-32 (approval) + doc-28 (variants) + doc-43 (LEGO) + doc-34 (images) + attachments, plus net-new motion covers + a project asset space. Deepen in a dedicated pass when the MVP loop is validated.

Ctrl-Audio Platform Documentation