ci/release.sh was a stub that printed a goreleaser/sidecar TODO and
exited 64 — both the sidecar and goreleaser are dissolved (D-56), so it
could never run. Replace it with a finalizer for the single-process app:
read the version from pubspec, assert CHANGELOG has a dated section for it
and the tree is clean, run the full gate (make push-check), then create
the annotated vX.Y.Z tag if missing. Never pushes — prints the
--follow-tags push + build commands. Add a `make release` wrapper so it's
driven through the Makefile like the other gates (CLAUDE.md tooling rule).
This closes the loop that left releases untagged: running `make release`
after the release commit can no longer forget the tag.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>