The landing page, download pages, invite page, assetlinks and installers
existed in two or three places; only site/ and the Forgejo feed are served.
- apps/api-server/wwwroot: delete the stale site build, download/invite
pages, .well-known copy, legacy static admin and 1.0.0 binaries. The API
no longer serves static files (UseStaticFiles/fallbacks and the apk/zip
blocker removed); the Next admin is the only admin UI.
- Delete 19 tracked installers/packages (~568 MiB) under site/public/releases,
apps/web/public/releases and wwwroot/releases; .gitignore blocks them.
- apps/web: delete the download/releases pages, desktop-release.ts, the
download.html and assetlinks copies, and the accept-invite page (invites
are only issued to the site's /accept-invite/). e2e specs call the /app
base path and check the /download redirect instead.
- scripts: delete the retired release/NAS site scripts, drop the web target
from sync-version, and check assetlinks in site/public only.
- Delete the unused Dockerfile.admin (apps/admin/Dockerfile is used).
Policy: docs/REFACTOR_POLICY.md Wave 3, W3-5 and W3-6.
The download contract on both the web console and the landing site still
advertised 1.2.0, so the install button pointed at
D3RO-Voice-Setup-1.2.0-x64.exe, which the feed answers with 404 while 1.3.7
is live. Wire both contract files into version:sync so the installer version
and release date follow the version SSOT, and set them to the published 1.3.7.
💘 Generated with Crush
Assisted-by: Crush:deepseek-v4.1-flash
Desktop clients had two competing update sources: the runtime pointed at a
legacy GitLab registry while the Forgejo packages were filled in by
hardcoded, version-pinned scripts. Operators could not tell which feed was
authoritative, and no release could be reproduced from a tag.
Auto-update now reads a single canonical Forgejo registry feed, updated by
a version-agnostic publisher that runs from the tag on Forgejo, GitLab, and
GitHub CI alike. Channel, minimum supported version, forced install,
full-versus-delta thresholds, staged rollout, and a remote kill switch come
from one policy file the client fetches alongside the feed. Tag creation is
gated on a clean tree, matching version surfaces, and a changelog section.