dunn.dev/pipeline 4.9.0

`cloudflare-worker` gains an MR-only `validate-worker` job that runs
`wrangler deploy --dry-run`, so a worker bundle that cannot build fails its
merge request instead of main. A **minor**: one template input added
(`cloudflare-worker`'s `mr_dry_run`, default `true`), none removed or
renamed. A `cloudflare-worker` consumer gets the new job on its next merge
request unless it sets `mr_dry_run: false`. `osv-verdict` no longer
fail-closes on a repo that tracks files with Git LFS.

### Added

- **New MR-only `validate-worker` job: `wrangler deploy --dry-run`.**
  Merge requests ran only `build`, which never bundles the worker entry
  script, so a wrangler or worker-dependency bump could pass its MR and
  fail on main at deploy. The job runs the deploy's own config parse and
  bundle (after the same `npm ci` when `needs_npm_install` is set)
  without uploading, and unsets the Cloudflare credentials, so it needs
  none. New input `mr_dry_run` (default `true`); `false` omits the job.

### Changed

- **`renovate-config.json`: dead keys dropped, Go majors guarded.** The
  scan's `RENOVATE_FORCE` already nulls `schedule` and sets
  `prHourlyLimit: 0`, so `lockFileMaintenance.schedule`, the top-level
  `prHourlyLimit` and the default-valued `assignAutomerge` are gone;
  lockfile maintenance behaves as before. A top-level
  `postUpdateOptions` sets `gomodTidy` and `gomodUpdateImportPaths`, so a Go
  `/vN` major rewrites the import paths in source and keeps `go.sum`
  complete (Renovate skips `go mod tidy` on majors without the import-path
  option). It is top-level because a rule scoped to `gomod` is lost on a
  grouped branch whose first dependency is another manager; only the gomod
  manager reads these values.

- **`renovate-config.json`: rule descriptions trimmed, dead rules removed.**
  Each description is now one or two sentences. The
  `dunn.dev/immutable/**` age exemption and the `basef` review rule are
  gone (every project they match is archived, and no live project
  references a `basef` image), and the disabled security-products rule
  drops its dead `pinDigests` key. The internal-catalogs note now states
  that `base-zfs` and `base-zfs-nvidia` automerge at every update type via
  the kmod rule. The resolved config is otherwise unchanged.
- Routine tracking: `golangci-lint` 2.14.0 (`ci-go`), `uv` 0.12.19
  (`ci-iac`), `glab` 1.119.0 (`ci`), rust 1.99 (`ci-rust`), golang 1.27,
  ubi10 and nodejs-22-minimal digests.

### Fixed

- **`osv-verdict`: the merge-base checkout no longer fail-closes on a repo
  that tracks files with Git LFS.** A clone made by the runner helper
  carries LFS hooks in `.git/hooks`; `ci-go` has no `git-lfs`, so the
  post-checkout hook exited non-zero after git had moved HEAD and the job
  reported "base reachable but checkout failed" on every MR pipeline. The
  base and return-to-head checkouts now run with hooks and the LFS filter
  off (the scan reads lockfiles, not LFS blobs), and a genuine checkout
  failure still fail-closes, now printing git's own error.

- **`signal-digest`: red default-branch pipelines are judged per source on
  completed pipelines.** The red-mains signal read only the newest pipeline
  on the default ref, so a running or pending pipeline hid a red one before
  it, and a later green push hid a failed scheduled pipeline. It now takes
  the newest completed pipeline of each source (push, schedule) and flags
  failed or canceled, tagging a schedule finding `[schedule]`. A push
  pipeline canceled by auto-cancel while a newer same-source pipeline
  exists is skipped rather than counted red, a project red on both sources
  counts once, and Renovate's "Detected empty commit" lockfile-maintenance
  no-op is a benign warning.