test-go, test-web and android were separate workflows on the same push as
release.yml, so the image build could not see their verdict: :dev meant
"it built", never "it passed". All lanes now live in release.yml, and
both publishing jobs (image-release and the new release-assets) need
every lane and require `result == 'success'` from each by name, so a
skipped lane blocks the publish just as a failed one does (rule 177).
- New lanes: govulncheck (in golang:1.26-bookworm, the builder's image,
so it checks the stdlib that ships) and `npm audit --omit=dev` in web.
- Attaching the APK to a Release moved out of android-release into
release-assets, behind the gate; the APK still builds in parallel.
- `docker buildx build --pull`, so floating base tags can't serve a
stale Go patch release from the runner's cache.
- Integration wait uses `pg_isready` via docker exec: the old /dev/tcp
probe never connects under dash (rule 81) and burned two minutes a run.
- workflow_dispatch input force_red fails the go lane on purpose, to
watch the gate refuse.
- release_gate_test.go pins the gate: every job must be classified, and
every publisher must need and require success from every lane.
Lanes have no path filters any more; a web-only push runs the Go suite
too, because "not run" must never read as "passed".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>