Skip to content

Pin-assertion guards duplicate a SHA Dependabot updates elsewhere, so every bump breaks themΒ #1216

Description

@devantler

πŸ€– Generated by the Agentic Engineer

Evidence

Two dependency bumps stalled on the same defect within one hour today, each needing a manual
adaptation commit before it could merge:

Problem

These guards exist for a good reason β€” they stop a pinned action being silently replaced by an
unpinned or different one. But each keeps its own copy of a pin that Dependabot updates
somewhere else, and Dependabot only rewrites uses: lines in workflow files. So every bump of a
guarded action breaks its guard by construction, and the failure looks like a red required check
rather than a stale literal.

The cost is per-bump and recurring: a human or agent must diagnose a confusing failure, find every
copy, and push an adaptation commit before an otherwise-mechanical bump can land. It also erodes
trust in the guard, since the "normal" response to seeing it red is to update the literal without
re-checking that the guard still asserts anything.

One copy was also demonstrably missed by CI's own signal: on #1208,
test-world-at-ruin-required-regressions.sh was failing for this reason without being among the
PR's reported failing checks
, so fixing only the red checks would have left it broken.

Hypothesis

If each guard derives the expected pin from the workflow it is guarding β€” rather than duplicating
it β€” then a Dependabot bump updates the single source and the guard keeps its meaning with no
manual step, while still failing when an action is genuinely unpinned or substituted.

Success signal

The next bump of a guarded action (harden-runner, zizmor-action, or checkout) merges with no
agent or human adaptation commit
, and the guards still fail when given an unpinned or substituted
action. Baseline: 2 of 2 such bumps needed adaptation today.

Acceptance criteria

  • No test or workflow step hardcodes a SHA whose sole source of truth is a uses: line elsewhere
    in the repo; the expected value is read from that line.
  • Each affected guard retains a negative control proving it still fails on an unpinned or
    substituted action β€” deriving the value must not make the assertion vacuous.
  • Genuine fixture files (e.g. test-ci-harden-runner-first-blocks.sh, where the SHA is synthetic
    input rather than an assertion) are explicitly out of scope and left alone.

Rough size: small-to-medium; the guards are few and each change is local.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions