First stable release since v2.10.10 (2026-04-28). Promotes the dev arc — v2.11.0 cathedral restructure, v2.11.1 listener-request groundwork, v2.12.0 station imaging + Super Italian + classic-era sources, v2.12.1–v2.12.3 fixes + Festival Mode + Italian-first default — and adds v2.12.4's runtime provider transparency and edge add-on channel.
See the full CHANGELOG.md for everything between v2.10.10 and v2.12.4. The v2.12.4-specific notes follow.
Added
- Runtime provider transparency —
GET /statusnow includesruntime_statuswith health_state, a providers map (primary/current/fallback for audio source, script provider, and TTS provider), and recent failover events. The admin Engine Room shows a header health dot and a Runtime Status card with live primary/fallback state. Provider switch events are logged asprovider_switch_eventwith structured fields. Fallback detection covers all producer rescue paths: norm-cache bridges, emergency tone, silence fallback, andfallback_*audio sources. - HA Green performance smoke gate —
make perf-smokenow runs a runtime check against a live station, validating/healthz,/readyz,/public-status, and/streamfirst-byte latency with configurable HA Green thresholds. - Edge add-on (development channel) — A second Home Assistant add-on, Mamma Mi Radio (Edge), now ships from the same repository. It tracks the latest
mainbuild: its version is a calendar version bumped automatically by CI on every add-on-changing merge, so Home Assistant shows a normal in-place "Update" each time. The stable Mamma Mi Radio add-on is unchanged and still updates only on deliberate releases. Edge and stable share one image and cannot run simultaneously (both bind port 8000) — install one. Seedocs/runbooks/ha-addon.mdfor switching instructions.
Changed
- Stable add-on images are now published by Git-tag push — A new
addon-release.ymlworkflow, triggered byv*tag push, is now solely responsible for publishing:X.Y.Zand:latestfor the HA add-on.addon-build.yml(main-push) no longer publishes those tags; it publishes only:sha,:0.0.0, and the edge calver. The release workflow validates the tag ref, semver,config.yamlversion, and prebuilt per-arch:shaimages, smokes the source image, promotes that exact artifact to stable tags, updates:latestonly for the newest stable semver, then smokes the published release tag. Release flow: merge version-bump commit → wait for CI →git tag vX.Y.Z && git push origin vX.Y.Z. - Queue fallback starts before the health-failure window. Active listeners now get cache rescue attempts after a 5-second bounded queue-empty wait, before the preserved 30-second silence health-failure threshold triggers.
- Engineering backlog moved to GitHub issues —
docs/todos.mdwas removed. Open engineering work is now tracked as GitHub issues. A new CI guard (scripts/check-no-backlog-files.sh, wired intoquality.yml) fails the build if a catch-allTODO.md/TODOS.md/docs/todos.md/docs/backlog.mdfile is re-added.
Fixed
io.hass.*labels now correctly embedded in every build variant — The add-on Dockerfile now injectsio.hass.version,io.hass.type, andio.hass.archfrom build-args for all three CI build paths (stable, edge seed, edge calver). A missing-labels gate inscripts/validate-addon.shand a scoped test ensure the contract holds. Local Docker builds without--build-argnow emitio.hass.version=unknownrather than an empty string, making the missing-arg case visible instead of silent.- Spoken host segment assembly is stricter. Generated multi-line banter now rejects broken intermediate TTS line files, strict concat duration shortfalls, and implausibly short multi-line exchanges before they can reach the listener queue.
- Cache rescue no longer repeats the first cached song by filename. Empty-queue fallback now avoids the current/recent song when alternatives exist and randomizes the rescue candidate, preventing skip from landing back on the same cached track.
- Admin control touch targets now meet the 44 px WCAG minimum. Mode-control switches and other admin controls expand their tap area to at least 44×44 px without enlarging the visible control.