macOS Application

Lossless

A native macOS application for downloading Apple Music releases, built around a reproducible embedded runtime and hardened process lifecycle.

Year
2026
Role
Product design / development
Platform
macOS
Status
In development
  • Swift
  • SwiftUI
  • C
  • Shell
  • Git
View repository ↗

Overview

Lossless is a native macOS application that packages an Apple Music download workflow behind a desktop interface. The project combines product design, native application code, embedded command-line tooling, runtime orchestration, signing, and regression testing.

The goal is not simply to launch a downloader from a GUI. The application has to own and coordinate the runtime around that downloader predictably enough that installs, relaunches, active downloads, authentication state, helper processes, and shutdown all behave like parts of one application.

The problem

A desktop wrapper around command-line tools becomes unreliable quickly if process ownership is ambiguous.

A second app instance can contend for the same runtime. A parent process can exit before child processes are finished. A forced termination can leave stale state behind. Helper processes can escape normal teardown. Bundled upstream binaries can also drift if dependency versions are not pinned and verified.

Those are application-lifecycle problems rather than interface problems, so the engineering work has focused heavily on making runtime behavior deterministic.

Architecture

The application is split into explicit layers so native UI state, download execution, process ownership, and the embedded Linux runtime can be reasoned about independently.

SwiftUI macOS application
        ↓
Native download backend
        ↓
Runtime ownership + shutdown coordination
        ↓
Embedded container runtime
        ↓
apple-music-downloader
        ↓
Wrapper service

The native layer owns admission and lifecycle decisions. The embedded runtime provides the Linux environment required by the downloader and wrapper components. Upstream dependencies are pinned so the packaged runtime can be reproduced and verified.

Development chronology

  1. Foundation — native macOS application structure, embedded runtime packaging, pinned assets, development build validation, and code-signing checks.
  2. Runtime ownership — single-owner locking, canonical runtime paths, stale-metadata handling, race coverage, and recovery after abnormal termination.
  3. Deterministic shutdown — owned process groups, bounded termination escalation, helper-process barriers, idempotent shutdown coordination, and failure reconciliation.
  4. Wrapper-lite migration — current work to move from the legacy wrapper runtime to a pinned wrapper-lite architecture and a compatible pinned apple-music-downloader revision.
  5. Lifecycle hardening — remaining work includes actor/state-machine cleanup, login-service crash recovery, fresh-install/relogin regression coverage, and consolidated diagnostics.

Runtime ownership

Lossless uses an explicit ownership model so only one application instance can control the embedded runtime at a time.

The ownership layer is tested for exclusivity, concurrent acquisition, stale metadata, abnormal termination, stable lock behavior, runtime-root enforcement, and recovery after a process is killed.

That turns “only one copy should use this runtime” from an assumption into an invariant that can be exercised automatically.

Deterministic download shutdown

An active download can involve more than one process. Lossless therefore tracks process attempts and coordinates shutdown as a lifecycle operation rather than simply terminating the top-level command.

The shutdown path is designed to:

  • stop accepting new work once shutdown begins;
  • wait for already-admitted startup work to join the shutdown sequence;
  • terminate owned process groups;
  • escalate when graceful termination is ignored;
  • account for helper processes before runtime teardown;
  • remain idempotent when shutdown is requested more than once.

Tests cover fast exits, spawn failures, cancellation, escalation, helper-process behavior, prior-attempt rejection, and recovery when exit cannot be confirmed immediately.

Reproducible runtime packaging

The embedded runtime is treated as a versioned application dependency.

Upstream revisions are pinned rather than followed as floating branches, and generated runtime artifacts are verified before packaging. Development scripts also validate architecture and expected assets before a build proceeds.

This keeps a future upstream change from silently altering the application that gets shipped.

Verification

The project has dedicated lifecycle, ownership, process-group, and shutdown tests in addition to normal development builds and code-signing checks.

That test coverage is part of the product architecture: runtime behavior that would otherwise be difficult to reason about manually is made explicit enough to reproduce and regress.

Current direction

The current development work is migrating the embedded wrapper layer to the newer wrapper-lite architecture while preserving the same reproducibility and lifecycle guarantees.

Interface screenshots are intentionally deferred until the public-facing UI reaches the intended design state.