Mirror the OpenIPC/firmware nightly redesign (PRs #2111-#2129) to builder. This commit is PR-Bld-A: the build.yml-side changes only. Subsequent PRs add the manifest aggregator + retention sweep (PR-Bld-B) and the build-one.yml commit input (PR-Bld-C). Changes: 1. **Preflight SHA gate**. New `preflight` job reads `sha=` from the rolling `nightly` release body. On schedule events it short- circuits the matrix when HEAD matches the previously-published SHA; PRs and workflow_dispatch always build. Mirrors firmware's #2111. 2. **Three release tags per build**: - `nightly-YYYYMMDD-<short>` (prerelease, content-addressable, the unit of history — 90-day retention via PR-Bld-B's cleanup.yml). - `nightly` (rolling channel pointer; body carries sha/short/ built_at). - `latest` (legacy alias, kept one cycle so existing sysupgrade clients hitting the old hardcoded URL don't break). 3. **`BUILD_ID` / `BUILD_SHA` / `BUILD_PLATFORM` env** exported at the job level from preflight outputs. firmware's rootfs_script.sh (which builder.sh reuses via its clone of firmware) picks BUILD_ID + BUILD_SHA into /etc/os-release automatically. BUILD_PLATFORM is set to the matrix entry (e.g. `gk7205v200_fpv_caddx-fly`) and is forward-compatible with Phase 3 of the mirror plan (the firmware- side rootfs_script.sh update that emits BUILD_PLATFORM as an os-release field). 4. **Retry budget** around `bash builder.sh`. Matches firmware's `30 60 120 300 600 1200` ladder, covering toolchain/CDN flakes (#2115 + #2129 in firmware). 5. **Telegram caption** leads with `Build: <build_id>`; obsolete `Tag: ${TAG_NAME}` line gone; workflow-level `env: TAG_NAME= latest` removed. No on-device firmware changes; builder cameras keep their existing sysupgrade legacy URL until Phase 2 of the mirror (sysupgrade variant routing) lands in OpenIPC/firmware. See ~/.claude/plans/mirror-nightly-redesign-to-builder.md. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>