dunn.dev/pipeline 4.1.0 Minor: additive plus fixes. No input removed or renamed, no existing default behaviour changed. Consumers pick this up by bumping their component pins. Added - model-id-drift (new, opt-in): fails when a consumer's tracked working tree carries a hardcoded claude-(opus|sonnet|haiku) major below the declared current_ga_major (default "5"). No network access; pure regex over the already-checked-out tree. No repo is auto-enrolled. There is no Renovate datasource for Claude model ids, so a hardcoded id rots invisibly -- confirmed stale on dunn.dev/pi and dunn.dev/skald.md while Opus 5 was GA. - ci-go bakes osv-scanner, ci bakes hadolint (both checksum-verified release binaries). osv-verdict now runs on ci-go, so the gate binary is no longer fetched fresh on every MR across the estate. Changed -- renovate-config preset - go.mod indirect dependencies now propose an MR only when they carry an active OSV/GHSA alert (security:gomodIndirectSecurityUpdates). Surfaced by bairn's kin-openapi indirect dep needing a hand-diagnosed fix. - Internal-artifact MAJORs exempt from minimumReleaseAge; automerge stays false (age delay and human review are separate knobs). Closed two coverage gaps while widening: the bare-catalog depName form was never matched, and the gitlab-releases exemption is now scoped by package name so it no longer silently covered upstream gitlab-org/cli. - mergeConfidence:all-badges, display-only, for the human majors-review queue. - minimumReleaseAge:null for four evidenced timestamp-less packages (envoy via mirror.gcr.io, two immich images, @dunn.dev/reference on GitLab's npm registry) -- a strand fix by exact package name, with explicit automerge:false, not a registry-wide trust exemption. Fixed -- osv-verdict - Go call analysis runs for real now that the job is on ci-go. The gate blocks on called=true or called=unknown; a finding call analysis proves unreachable is still logged and kept in the artifact, just not gate-blocking. - Default-branch pushes diff against CI_COMMIT_BEFORE_SHA instead of full-scanning, closing the green-MR-then-red-main asymmetry. - The MR diff base was a silent no-op: git stash swept up the untracked head-scan outputs and nothing ever popped it, so the verdict was pass regardless of whether a new finding existed. Fail-open under a fail-closed gate, on every diff-mode run. Head scan outputs now survive outside the tree. Fixed -- automerge-gate, osv-verdict - Both jobs now instantiate on a bare branch pipeline with no open MR yet. The prior rules matched only merge_request_event or the default branch; audited across 97 consumer projects, ~25 had zero gate coverage in exactly that gap, where the job never emitted and needs:optional read absent rather than failed. - The clause shipped in a two-rule form and was then consolidated to one (CI_COMMIT_BRANCH && CI_OPEN_MERGE_REQUESTS == null). That is a simplification, not a behaviour change -- both forms render identically. Verified pre-tag: a synthetic consumer POSTed to ci/lint at three refs with components pinned by SHA, carrying probes that prove the rendered variable context. Gate jobs instantiate on a no-MR branch, are correctly suppressed on a branch with an open MR, and main is unchanged. A grandparent control at the commit before the branch clause existed confirms the harness discriminates: the gate jobs are absent there on the same ref and present after. Also: baked tool versions advanced (cosign 3.1.2, syft 1.49.0, just 1.57.0; ci-iac uv 0.11.32, sops 3.13.3), image ARG and template spec-input default moving in lockstep.