Why Anelo's Windows installers aren't on our own website
A 380MB release meeting a 360MB daily transfer limit, and the quiet failure mode that would have followed.
Anelo's macOS build is a 1.3MB disk image. It sits on the website next to the HTML, gets downloaded, and nobody thinks about it.
The Windows build is not like that. Each self-contained package is around 190MB, and shipping both x64 and ARM64 means 380MB of installers per release.
The website was on Firebase Hosting's free tier, which allows 360MB of data transfer per day.
The arithmetic doesn't work, and the failure is silent
One person downloading one Windows installer would exhaust the entire day's allowance. The second person to arrive gets nothing.
What makes this worse than a straightforward outage is what the site looks like while it happens. The HTML still loads — it was already cached. The page renders correctly. The download button is right there, styled properly, in the right place. It just doesn't work. There is no error banner, no status page, no alert in an inbox. From the outside it looks like a working site that people happen not to be downloading from.
That is the kind of failure you find out about weeks later, from someone who assumed the problem was on their end and moved on.
Where each artifact actually belongs
So the two platforms are hosted differently, on purpose:
- macOS DMG → the website. At 1.3MB it costs nothing, and keeping it there means the release script can publish the app and update the download link in one step.
- Windows installers → GitHub Releases. Large binaries are exactly what release hosting is designed for, and there is no daily cap to run into.
The useful generalisation isn't "static hosts are bad for downloads". It's that hosting should be chosen per artifact, not per project. A 1.3MB file and a 190MB file have almost nothing in common except that they both live behind a download button, and picking one host for both means one of them is in the wrong place.
The release pipeline that publishes them
Windows releases are triggered by pushing a win-vX.Y.Z tag, in a workflow file
of its own rather than sharing one with the ordinary push-triggered build.
That separation is deliberate. The regular pipeline filters by changed paths, and a tag push has no meaningful notion of "which files changed" — combining the two produces behaviour that is hard to predict and easy to get wrong. Releasing is a low-frequency, high-consequence operation. It should not share a trigger with something that runs on every commit.
The pipeline also refuses to publish a partial release. Each architecture
produces its own SHA256SUMS.txt containing only its own package, and the two
are merged before publishing. If the asset count isn't exactly two, the release
fails rather than shipping one architecture and leaving the other missing.
About those unsigned binaries
Both Windows builds are currently unsigned, and the release notes say so plainly. Two things follow from that:
SmartScreen will show a full-screen warning. And some antivirus products will flag the installer — which is not a false positive in any interesting sense. Anelo installs a global keyboard hook and synthesises keystrokes into other applications. Structurally, that is what a keylogger does. The difference is intent and what happens to the data, and neither of those is visible to a heuristic scanner.
Until there's a signature, the SHA256 checksums published with each release are the only way to verify you got the file that was actually built. That is worth stating out loud rather than hoping nobody notices the warning.