Solomorph
Pricing Build log

build log

What got built, and when.

This log started before there was anything to download, so it is not a release changelog. It is the record of the work, so you can decide for yourself whether anyone is still here.

Now that Solomorph is out, the promise is an entry every month, and it is one you can audit rather than believe: if a month passes with no entry on this page and no explanation, something has gone wrong and you should keep your money.

version today 1.0.0 live on Google Play cut from the 0.9.12 freeze

2026-09-27

public, and what the two weeks were for

Solomorph 1.0.0 is public on Google Play. The first time the listing loaded for a signed-out visitor was the evening of 23 September; a check on 18 September still returned a 404, so the day it actually went public sits somewhere between those two, and this entry does not pretend to know which. It is the same build described in the 8 September entry below — nothing in the app changed while it waited. What changed was paperwork, and all of it is in the repo. The store description moved under version control instead of living in a console text box, and on the way it gained the two things it had left out: merging several servers, and the 30-day trial. The Data safety form declares exactly one thing, the lyrics lookup, and answers “encrypted in transit” with no, on purpose: the app lets you talk plain http to a server on your own LAN, and ticking the other box would have been the easy lie. The listing’s privacy link was corrected from the company’s general policy to solomorph.com/privacy, the page that names every outside destination the app talks to. Google also asked for the foreground service to be explained — it is media playback and nothing else — with a video of it doing that, and its reviewers needed a demo server of ours to sign in to. Two things are still unchecked, and they are written here so they stay unchecked in public: restoring a purchase on a fresh install has not been run on a device, and neither has the end of a trial. The site caught up on 27 September: the Play button is on the front page and Android reads as shipping. The next entry is owed by 27 October.

2026-09-08

many sources at once, restored

Solomorph+ has sold cross-source merge — connect more than one server and browse them as one library, search included — since the pricing entry below. It turns out the merge only ever worked by accident: adding a server kept the old one connected forever, silently unioning whatever had ever been attached that session, which is also why a 49-album demo library once reported itself as 3,069 albums under one server’s own name — the exact sum of the two. Diagnosing that number the wrong way briefly cost the feature itself: for two days browsing was locked to one server at a time, correctly fixing the count and incorrectly deleting something already sold. It is wired to the actual entitlement now — the paid tier merges every connected server, a free or lapsed account reads only the active one — and every server reconnects on its own at launch instead of only the one you happened to open the app into, which is the cold start that never worked before. The “new albums” banner had its own version of the same bug: it compared library size across moments that did not have the same servers attached, so connecting a second server once read as three thousand new albums arriving overnight. It now counts per source, so adding a server you already own is recorded as newly visible, not newly arrived, and only a real addition gets announced. The same pass corrected two Android device filters that had nothing to do with playing music — a microphone and a wifi requirement Android infers from unrelated permissions — which had been quietly blocking installation on an ethernet-only TV box the app already calls a first-class target.

2026-09-06

r8, on, and the number it actually moves

R8 had been off since July, disabled the day it stripped what WorkManager’s Room database reaches reflectively and crashed the first release APK before Flutter even started. The two conditions written down for revisiting it — tested keep rules and a device lap — are both met now: a keep rule for each specific reflective lookup (WorkManager and Room first, then Flutter’s own plugin registration, our exported EQ receiver and widget provider, media3, ML Kit, billing), verified clean on a real phone against both a Solomorph Server and a plain Navidrome — cold start, playback, the media notification, the widget, the EQ receiver, nothing missing and nothing crashed. Worth being honest about what this does not do: it does not move CPU or memory, measured before and after, because everything Solomorph does at runtime is Dart, and R8 only ever touches the Java layer underneath it. What it does move is the Java and Kotlin bytecode the package carries — the DEX, cut from 25.6MB to 8.6MB uncompressed — and it leaves behind a map that finally makes a Java-layer crash report readable instead of a wall of addresses.

2026-09-05

new music says so, and it stays said

The count of albums added since you last opened the app used to live only as a small mark on the Home tab, something you had to go and find. It now says so in words, in the same banner slot already used for offline and for scanning rather than a second banner stacked on top of them — it never competes with either, because two things asking for attention at once is how a quiet app starts to shout. Three bugs in it surfaced and got fixed the same day: the marker used to advance the instant the count was computed rather than when anyone actually saw it, so opening the app, getting distracted, and reopening it could erase the news before it was read; an album already on the phone itself never reached the shelf the banner reads from whenever a server was also connected, so music you already owned locally could arrive unannounced; and the count assumed one single sorted list, which breaks the moment there are two sources, so a local album could sit unseen ahead of the marker and never get counted at all. The fix in each case is the same idea: count how many more albums exist now than the last time you looked, nothing about which ones, because that is the one measure two sources cannot confuse. It can still only be a floor rather than an exact number in some cases, and now says so plainly — “40+” instead of a confident, wrong count. Separately, Solomorph still does not check for updates on its own — Play does that automatically for almost everyone — but Account now carries a row naming the version you are on and opening the store listing, for the person who has that switched off.

2026-09-05

the sleeves were in the files the whole time

A phone-only library had no crates — not a styling gap, the actual rule: nothing artless leans in a bin, and a local album carried no art by construction, so the record-store surface never rendered at all. The art was sitting inside the files the entire time. The scan now pulls each album’s embedded picture out once (a real extraction, cached, not a placeholder) and the crates render properly with no server anywhere in the path. One honest limit remains: an album that stores its art as a separate file next to the tracks, the way a lot of ripped libraries do, still shows no art — reading that needs a broader permission this app doesn’t ask for and isn’t adding quietly just to fill in a sleeve.

2026-09-05

the phone becomes a real source

Solomorph+ and the trial now turn the phone itself into a library — no server required for that half of the app. Fixed the same night it was pointed out: a local-only install used to do nothing at all when you tapped a track. Now: pick which folders hold music (largest first, with counts, so the list explains itself), Android’s own classification keeps ringtones and alarms out without Solomorph ever guessing from filenames, and the phone rides alongside whichever server you also connect rather than replacing it — a record you own in both places is listed once, biased deliberately toward showing a duplicate over ever hiding music you actually own. An album now downloads whole from its own hero, the same circle as play and shuffle, instead of one track at a time from a buried menu — the difference between tapping once and tapping twelve times at an airport gate. And downloads bring their cover art with them, so a flight doesn’t cost you every sleeve in your queue. Also fixed: starting the trial used to look like it had failed.

2026-09-04

1.0.0

Version cut to 1.0.0, the release built from the freeze declared 15 July. Play App Signing — which very nearly would have quietly switched off premium for every paying customer, since Google re-signs whatever you upload with its own key by default and this app only knew about the certificate on its own builds — is now closed correctly: the owner enrolled with Kloudmorph’s own release key instead of accepting Google’s, so Play signs with the same certificate a sideload carries, and the one hash this app checks for covers both. Three checklist items turned out to already be finished and unmarked, which got corrected rather than left to make the remaining work look smaller than it is. What is genuinely still open before this goes public: the Play Data Safety questionnaire, a 1024×500 store graphic, and a lap on real hardware for the premium build specifically. No git tag yet — that is the owner’s call to make, not a side effect of a version number.

2026-09-04

every row gets a face, and the truth about bitrate

The demo library gained 36 more real album covers, closing out what had been a placeholder tide. The library list was quietly showing a bitrate figure that had nothing to do with the actual file — fixed, and checked against files that carry the number it now displays. Podcast subscribe finally confirms it worked instead of returning to a screen that looked unchanged either way. Audiobooks stopped being a greyed-out label in the sidebar: real chapters, a real resume position, and a pause that counts as a save point, wired into the same shelf the music library already uses rather than a second, thinner screen bolted on beside it. Screenshots for the store listing found their own bug in the same push — measuring the glyph contrast instead of eyeballing it turned up two dark-mode frames that were functionally invisible, both pulled before anyone saw them published.

2026-09-04

lyrics, and a privacy policy the app can actually show you

Two owner-directed privacy fixes landed the same afternoon. Lyrics lookups had been leaving the device on every track change regardless of whether captions were ever turned on — the fetch was gated on nothing, only the on-screen display was. It is now gated on the captions switch itself: turn captions off and nothing is requested; turn them on and synced lyrics arrive the way they always did. Where a Solomorph Server is connected, the phone now prefers asking it instead of a stranger on the internet directly — the server does the asking on the phone’s behalf, gated on the same beacon check that already decides the household entitlement. Separately, the About screen finally has real links instead of the empty section that sat there for months rather than ship placeholder legal text: solomorph.com’s privacy policy, terms, refund policy, and a real support address, each opening in your own browser or mail app.

2026-08-28

tier 1+2 hardening

An XDA piece described a local model recovering an app’s entire licensing scheme in half an hour. Solomorph was audited against it and found worse off: a shipped build answered a single grep with the exact preference key to flip and every entitlement flag beside it — no model required, one adb command. Fixed in two tiers: identifiers and preference keys are now stripped from the release binary and checked absent by grep rather than assumed; and the app compares its own signing certificate against the one it actually shipped under, failing open rather than locking out a paying customer on anything less than a definite mismatch. Held on a branch for several days waiting for a phone to come back before merging, because the fix’s whole job is preserving entitlement through an upgrade, and that has to be proven on real hardware rather than reasoned about — which it now has been: the obfuscated build installs over the old one, keeps the purchase, and a re-signed copy of the free build correctly logs itself as tampered. The doc comment says plainly what this does and does not do: it turns a five-second crack into a real reverse-engineering session. It does not prevent one. Actual prevention needs the server-side, phone-home check the pricing model has refused, and that refusal stands until it is revisited on purpose.

2026-08-23

a tour, and somewhere to ask when it isn’t enough

A first-run tour, and a help screen for everything after it. The tour went through its own honesty pass in the days that followed — it started out pointing at things that weren’t built yet, got fixed to point only at what’s actually there, and stopped counting promises it can’t keep. The library started flagging what’s actually new instead of leaving you to guess, and the car integration’s queue and genre display were corrected to tell the truth about what’s playing — casting had been quietly lying about now-playing state, and no longer does.

2026-08-19

the front door, and the proportions nobody asked about

Two days of visual and interaction polish, tight and iterative rather than one big rework: the browser tab earned its own mark, the top-row glyphs lost a halo that only showed up in light theme, the bolt animation was reworked twice, the shuffle tile lost a rectangle it never needed, captions moved off the cover art instead of sitting on top of it, the seek bar learned how long the song actually is, the year rail started reading whole numbers instead of a truncated guess, and the demo library got its real colors and proportions back. The front door — the very first screen anyone sees — was rebuilt to look like it belongs to something people are asked to pay $49 for. None of this traces to a field report: the commits carry no such note, just the owner’s own reaction on the day. It reads as what it is — someone using their own app and fixing what bothered them, not working down a bug list.

2026-08-17

cast, corrected

The 14 July entry above said cast was built and switched off, waiting on a native module of our own. It landed three days later: it drives the Cast framework directly with no stock picker anywhere, and only shows a cast button once a real device answers — never a button standing in for a feature that might not work. Proven the same day, one Solomorph install casting to another. The flagship target, chartered but not yet built, is Solomorph casting to a Solomorph TV app: a mirrored renderer with the EQ following the music into the room. Local files still can’t cast; that limit is real and stays written down rather than dropped quietly.

2026-08-17

one day, twenty-five releases

The single busiest day in the repo: 25 releases between one morning and the next. The audio engine was rebuilt from the ground up — our own processing chain between decode and the speaker, feeding real FFT frames to the meters instead of a simulated bounce, with ReplayGain and a limiter riding the same path. The EQ’s tower-style sliders became fifteen independently graphed points, each one honestly labelled with the frequency it controls. The library layer was rebuilt twice in the same day, picked up real duplicate-detection by consensus instead of one fragile signal, and started surfacing its own errors instead of failing silently.

2026-08-16

the EQ splits in two

The basic equalizer — the device bands, eight core presets, A/B compare, automatic anti-clip headroom — is now free for everyone: an equalizer is table stakes, not a power feature. Solomorph+ buys the advanced layer: the full 37-preset library, the public AutoEq correction database, share codes, and the automation surface. The preset engine became a data table the same day (four presets was an embarrassment and we knew it), and the now-playing screen grew an honest signal-bars glyph that moves only while audio flows through an engaged EQ — activity, never a fake spectrum.

2026-08-15

the Loom · freeze override #2

The EQ rebuilt to its fullest, and recorded in the gate doc as the second deliberate freeze override. Hand-sculpted curves layer over headphone corrections without destroying them; the entire public AutoEq results index — thousands of measured headphones, MIT-licensed, credited in the app — is searchable from the profile sheet, fetched once and cached so a chosen correction works offline forever; anti-clip headroom is computed and applied automatically; curves travel as paste-able share codes; and an opt-in broadcast surface lets Tasker drive all of it, off by default because an exported receiver is an abuse surface. Genre browse landed the same week. Every piece was verified on the device before this entry was written.

2026-08-14

positioning

Competitive read refreshed against the whole field. Two of our own positioning claims turned out to be wrong under scrutiny and were retired rather than shipped: the competitor we most often get compared to does let you theme from artwork, and his licence is genuinely one purchase for unlimited devices. Writing that down here rather than quietly deleting the copy.

2026-07-30

decision

A one-shot 30-day free trial of the paid layer — opt-in, no card, no store round-trip. Deliberately overrides the feature freeze. Nothing you downloaded or configured during a trial is destroyed when it ends; that is written into the code as an invariant, not a preference.

2026-07-15

freeze

Server first boot proved end to end on real hardware: create an account, pick folders, watch 1,941 albums arrive, settled library, no babysitting. Feature freeze declared the same evening — everything built as of 0.9.12 is version one. Everything invented after it goes to a ledger, including the good ideas. It exists because “one more feature” is the specific way products in this category fail to exist at all.

2026-07-14

cast, and why it is switched off

The cast transport, the device picker and the handoff hooks are built and integrated. They are switched off, because the pure-Dart package they were built on does not compile against a current Android toolchain, and the working path is a native module we own. A cast button that fails is worse than no cast button.

2026-07-14

the paid layer

Local files on a media channel we own, offline downloads, graphic EQ with AutoEq output profiles, multi-source merge, OS-keychain credentials, 5-star ratings, sleep timer, and a home-screen widget with artwork.

2026-07-12

positioning

Decided the free tier is the best client to the entire Subsonic ecosystem, not just to Navidrome — which is exactly why we will never resell Navidrome. What we sell is our own engine.

2026-07-09

pricing

The Founders Ladder published: $49 to $79, four rungs, every trigger public, every buyer grandfathered at the price they paid. Written down before a single licence was sold.

2026-07-06

exhibits

Photographed the dev library exactly as the tagging agent will find it — the placeholder tide, one album split into nine partial releases, the [Unknown Artist] page. These are the “before” half. The “after” half does not exist yet, and will not be faked.

2026-07-06

tagging agent v0

Read-only audit, the lyrics pass, a journal that replays backwards, and a veto ledger that remembers every no forever. It ships at the safe end of the ladder on purpose: report first, apply only on your signature.

2026-07-03

named

Named Solomorph, after Timbre (store collision), Klang (laughed out of the room) and Attacca. Kloudmorph ships Solomorph; the brand family names itself.

2026-07-02

started

Started, after reading all 79 clients listed on navidrome.org/apps and concluding that features are not a moat — reliability, distribution and identity are.

What is not on this list is as informative as what is. There is no line that says gapless was tested, because it has not been. Every entry is dated and nothing is backdated. If this page goes quiet, that is information about us, and you should use it.