Skip to content

Refactor LSDJ's cross-platform application foundation #107

Description

@brxs

Summary

Refactor LSDJ's shared application foundation so the desktop app, audio engine, child services, model/runtime installer, and release pipeline have explicit cross-platform contracts. This is the enabling issue for Linux and Windows support; it should not change the supported macOS user experience.

Why

Several shared paths currently assume macOS or Unix behavior: application-support locations, .venv/bin executable layouts, shell tools, process-group cleanup, CoreAudio-oriented sample handling, and a macOS-only release flow. Building platform features directly on top of those assumptions would duplicate fixes and make lifecycle and update behavior fragile.

Scope

1. Define storage roots and ownership

  • Distinguish configuration, durable user data, caches, downloaded models/runtimes, and temporary/staging data.
  • Use platform-native locations:
    • macOS: preserve the current user-visible behavior unless migration is required.
    • Windows: non-roaming per-user locations under LocalAppData.
    • Linux: XDG config/data/cache locations with documented fallbacks.
  • Pass resolved roots explicitly from the Rust host to Python services; services must not independently guess them.
  • Keep Windows paths shallow enough to work when long-path support is disabled.
  • Define a one-time, restart-safe migration if any existing macOS path changes.

2. Consolidate child-process lifecycle management

  • Put spawn, readiness, shutdown, timeout, log capture, crash reporting, and cleanup behavior behind one shared supervisor.
  • Support process-tree termination, not only the direct child:
    • Unix process groups/signals.
    • Windows Job Objects or an equivalent tree-lifetime mechanism.
  • Add tests with both a child and grandchild process, including abnormal app exit and service startup failure.
  • Preserve enough bounded diagnostic output to explain failures without leaking credentials.

3. Replace shell-dependent runtime installation

  • Remove reliance on bash, curl, tar, chmod, shell activation, and shell-specific command strings.
  • Download over the app's HTTP client, install with native archive/file APIs, and invoke executables directly.
  • Pin every runtime artifact to an immutable version/revision and verify SHA-256 before extraction.
  • Fetch manifests only from authenticated HTTPS; treat the app-bundled or otherwise authenticated manifest as the trust root.
  • Reject archive traversal, links and device entries, excessive file counts, and excessive expanded size.
  • Stage and validate on the same filesystem, then atomically promote the new install. Preserve the previous working install until promotion succeeds.
  • Make interrupted installs and retries idempotent.

4. Centralize executable and argument resolution

  • Resolve platform-specific executable names (python/python.exe) and virtual-environment layouts (bin/Scripts) in one place.
  • Represent command overrides as an executable plus structured argument list; do not require users to write shell syntax.
  • Handle spaces, Unicode, and non-ASCII user-profile paths.

5. Generalize the real-time audio sample path

  • Keep the engine's internal processing format as f32 while supporting the sample formats exposed by cpal hosts on each platform.
  • Add allocation-free callback-boundary conversion, clipping, channel mapping, and resampling as needed.
  • Add unit tests for conversion boundaries, clipping, mono/stereo/multichannel layouts, and non-48 kHz devices.
  • Do not add platform-specific device UX here; Linux and Windows hardware behavior belongs in their release issues.

6. Split platform-specific Tauri configuration

  • Keep shared capabilities/configuration in a common base and add platform-specific bundle, window, filesystem, and permission settings.
  • Ensure development and packaged builds resolve resources consistently.

7. Add cross-platform CI foundations

  • Run Rust, frontend, and platform-independent Python checks on macOS, Ubuntu, and Windows.
  • Add focused tests for paths, executable resolution, process cleanup, archive validation, and sample conversion.
  • Clearly separate emulator/unit coverage from checks that require real audio, MIDI, or NVIDIA hardware.

8. Establish single-publisher release orchestration

  • Replace the macOS-job-owned GitHub release with one publisher job that waits for all required platform artifact producers.
  • Keep macOS as the only required artifact initially; Linux and Windows will join the required set in their release issues.
  • Upload artifacts and checksums from producer jobs to the publisher; prevent partially successful required builds from publishing a release.

Acceptance criteria

  • The existing macOS build still runs both decks and Stable Audio through the refactored contracts.
  • No runtime/model install path depends on a Unix shell or external download/archive tools.
  • A failed or interrupted update leaves the previous runtime usable.
  • Malicious and oversized archive fixtures are rejected before they can escape or exhaust the install root.
  • Child and grandchild processes are cleaned up on normal quit, startup failure, and abnormal termination on all CI operating systems.
  • Windows and Linux path/executable tests cover spaces and Unicode.
  • Audio conversion tests cover the formats and channel layouts needed by the target platforms without callback-time allocation.
  • CI runs the shared suite on macOS, Ubuntu, and Windows.
  • Release orchestration has one publisher and cannot publish when a required producer fails.

Out of scope

  • Shipping Linux or Windows installers.
  • Choosing or implementing model backends beyond the shared contracts.
  • Linux/Windows hardware certification.
  • Windows code-signing procurement.

Follow-up work

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions