• JellyTau v0.11.6
    🏗️ Build and Test JellyTau / Run Tests (push) Skipped
    🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
    🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 4m4s
    📱 Test APK / Build test APK (push) Successful in 48m6s
    Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 9m17s
    Traceability Validation / Check Requirement Traces (push) Successful in 20s
    Build & Release / Run Tests (push) Successful in 22m27s
    Build & Release / Build Linux (push) Successful in 31m18s
    Build & Release / Build Windows (push) Successful in 30m1s
    Build & Release / Build Android (push) Successful in 45m53s
    Build & Release / Create Release (push) Successful in 1m15s
    Stable

    dtourolle released this 2026-09-07 20:30:29 +00:00 | 0 commits to master since this release

    Found by an audit of the stack's most fragile seams rather than by hitting them,
    so most of these are faults that had not yet been reported — several could only
    be reached on a bad day, and the worst of them only once.

    🐛 Fixes

    • An interrupted update can no longer stop the app from ever opening again.
      Changes to the local database were applied one statement at a time with no way
      to undo a half-finished one. If an update was interrupted partway — a full
      disk, the phone reclaiming memory, the app being killed mid-launch — the
      earlier statements stuck while nothing recorded that the change had happened.
      On the next launch it started again from the beginning, immediately hit the
      part that was already done, and gave up; and since the app treats a database
      it cannot prepare as fatal, it stopped opening at all, on every launch, with
      the only way out being to clear its data and lose downloads and sign-ins. Each
      change is now all-or-nothing, so an interrupted one leaves no trace and the
      next launch simply tries again. (UR-002 → DR-012)

    • The app no longer vanishes without trace when the player hits trouble.
      The parts of the Android player that report back into the app — position,
      state changes, errors, the end of a track — had no protection around them, and
      a failure inside one killed the whole app instantly: no error, no message, not
      even a crash report worth sending. One such failure was reachable in ordinary
      use, on the position report that fires four times a second: under memory
      pressure the app could fail to build the small worker it needs to send that
      report, and that alone was enough to take everything down. A dropped position
      report is now just a dropped position report. (UR-005 → DR-052)

    • One internal failure no longer disables the whole app until it is restarted.
      Every part of the app that reads or writes local data shares a single gate to
      it. If anything failed while holding that gate, the gate stayed jammed: from
      then on every library page, download, setting and sign-in returned an error for
      the rest of the session, and only quitting and reopening cleared it. The gate
      now recovers instead of jamming. (UR-002 → DR-012)

    • Browsing offline no longer reports a network error over content already on
      the device.
      A read of local data was given a tenth of a second to answer and
      otherwise abandoned and treated as "nothing stored". That is easily exceeded
      on phone storage whenever something else is writing — a sync catching up, a
      batch of artwork being saved — and offline, where there is no server to fall
      back to, the result was a network error shown over a library that was sitting
      on disk. Worse, the abandoned read kept running and kept the storage busy,
      making the next one slower still. A slow read is now waited for rather than
      thrown away, and a fast one still answers immediately as before. (UR-002 →
      DR-013)

    • A download that arrived empty is no longer presented as ready to play. If
      the server answered a download with nothing at all — an error page, a
      conversion that produced no output — the empty file was moved into place and
      the item was marked available offline. Opening it then hung: the app's own
      media server promised one byte of it and sent none, so the player waited
      forever with nothing on screen to say why. An empty download is now treated as
      the failure it is, keeping the partial file so it can resume, and a request for
      an empty file gets an honest refusal instead of a promise. (UR-019, UR-071 →
      DR-168, DR-137)

    • Renaming your computer no longer signs you out. On systems without a
      password manager, sign-in tokens are kept in a file whose key was rebuilt from
      the machine's name and the current username each time the app started. Rename
      the machine, or launch it from somewhere the username is not set, and the key
      came out different, the file could no longer be read, and the app treated that
      as never having been signed in — with nothing shown to explain it. The key is
      now made once, kept, and unaffected by what the machine is called. Existing
      saved sign-ins are carried over automatically. This file has never been a
      substitute for a real password manager, and the app now says so plainly rather
      than implying otherwise. (UR-012 → IR-014)

    • The player's internal locking is now checked rather than merely careful.
      The playback controller coordinates seventeen separate pieces of shared state
      across the audio engine, the lock screen, timers and every screen in the app.
      Nothing stopped two of them being taken in opposite orders by different parts
      of the code, which freezes playback outright with no error anywhere — a fault
      this part of the app has produced before. The correct order is now written down
      and enforced automatically, so a future change cannot quietly reintroduce it.
      No such fault existed; this keeps it that way. (UR-005 → DR-052)

    Downloads

    Platform File
    Linux (portable) *.AppImagechmod +x and run
    Linux (Debian/Ubuntu) *.debsudo dpkg -i
    Linux (Fedora/openSUSE) *.rpmsudo rpm -i
    Windows *-setup.exe (NSIS). Unsigned — SmartScreen may warn on first run.
    Android *.apk sideload, or *.aab for Play Console

    Desktop builds check for updates from here and can install a new
    version in place, verifying its signature first.

    Verifying your download

    sha256sum -c SHA256SUMS
    

    SHA256SUMS covers every file in this release. An SBOM
    (*.cdx.json, frontend-dependencies.txt) lists what went into it.

    Requirements

    • Linux: 64-bit, GLIBC 2.29+
    • Windows: 64-bit Windows 10 or later
    • Android: 8.0 or later, ~50 MB free

    Report a problem: https://gitea.tourolle.paris/dtourolle/jellytau/issues

    Downloads