Skip to content

Exempt lock file maintenance from the release-age cooldown - #24

Merged
bryanbeverly merged 1 commit into
mainfrom
bryanbeverly/cursor/lockfile-maintenance-cooldown-exemption
Aug 3, 2026
Merged

bryanbeverly merged 1 commit into
mainfrom
bryanbeverly/cursor/lockfile-maintenance-cooldown-exemption

Conversation

@bryanbeverly

@bryanbeverly bryanbeverly commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

minimumReleaseAge: "3 days" applies to every update type in this preset, including lockFileMaintenance. A lockfile refresh is carried out by the package manager rather than resolved from one upstream release, so there is no timestamp to age. Under Renovate's timestamp-required default (Renovate 42+), a missing timestamp reads as "not old enough" rather than "fine", so renovate/stability-days pins to pending permanently and never clears on a rebase.

That silently defeats the lockFileMaintenance.automerge: true this preset already sets, because automerge waits on a check that cannot pass. This matters now: the org-wide Renovate bypass (PLAT-97) is about to be enabled, and without this exemption the lockfile half of that rollout would land and do nothing.

This adds a lockFileMaintenance exemption alongside the existing pin/pinDigest/digest one.

Worked example

trufflesecurity/thog#5901 — open since March 23, force-pushed 250+ times, renovate/stability-days stamped pending at branch creation on every head and never revisited. It was finally merged by hand July 30 carrying 446 changed package resolutions, four months of accumulated drift. Along the way the refresh floated @chakra-ui/react from 2.8.x to 2.10.10 and broke the frontend build.

Design notes

Why a separate rule instead of appending to the pin/digest array. The rationales differ, and so does their permanence. Pins and digests lack a reliable timestamp; lock file maintenance has none by design and always will. Renovate splits these for the same reason in security:minimumReleaseAgeNpm. A separate rule also carries its own prBodyNotes, which the combined rule could not.

Why unscoped by datasource. Upstream's equivalent is matchDatasources: ["npm"] because that preset is npm-specific. This preset applies minimumReleaseAge to Go, Actions, Docker and Terraform as well, and none of them carry a lock-file-maintenance timestamp either.

What the exemption gives up: nothing that existed. Renovate never aged these packages regardless — it delegates to the package manager, and neither Yarn nor Go performs a release-age check of its own (pnpm does). The check has been non-functional here, not protective.

The prBodyNotes carry what a reviewer cannot see from the diff: that no release-age validation happened at any layer, and that a loose caret on a direct dependency lets it move a minor version inside a lockfile refresh without ever surfacing as a version upgrade. That second note is the @chakra-ui/react failure above, generalized.

Known gap, deliberately not addressed here

Upstream also exempts replacement (renovate#39400 — release age isn't wired in yet). No repo in the fleet configures replacement rules today, so it is latent rather than active. Worth a follow-up, out of scope for this change.

Test plan

  • renovate-config-validator run against the modified file; the only error reported is the pre-existing GOPRIVATE / allowedEnv complaint, which the baseline v1.0.3 file reproduces identically and which the Mend-hosted bot accepts in production
  • JSON parses
  • Tag v1.0.4 after merge
  • Bump high-risk repos from #v1.0.3 to #v1.0.4
  • Confirm on the next Monday cycle that renovate/stability-days no longer appears pending on a lockfile maintenance PR

Made with Cursor

A lockfile refresh is carried out by the package manager rather than
resolved from one upstream release, so there is no timestamp for
minimumReleaseAge to evaluate. Under Renovate's timestamp-required
default a missing timestamp reads as "not old enough", so
renovate/stability-days pins to pending permanently and never clears on
a rebase.

That silently defeats the lockFileMaintenance automerge this preset
already configures, because automerge waits on a check that cannot pass.
thog #5901 is the worked example: open since March, force-pushed 250+
times, stability-days pending on every head, and by the time it merged
by hand it carried 446 changed package resolutions.

Keep this separate from the pin/pinDigest/digest exemption rather than
appending to it. The rationales differ and so does their permanence:
pins and digests lack a reliable timestamp, whereas lock file
maintenance has none by design and always will. Renovate splits them
for the same reason in security:minimumReleaseAgeNpm.

Unscoped by datasource, unlike that upstream npm-only preset, because
this preset applies minimumReleaseAge to every ecosystem and none of
them carry a lock-file-maintenance timestamp.

The prBodyNotes carry the two things a reviewer cannot see from the
diff: that no release-age validation happened at any layer (neither Yarn
nor Go performs its own), and that a loose caret on a direct dependency
lets it move a minor version inside a lockfile refresh without ever
surfacing as a version upgrade.

[authored by Cursor]

Co-authored-by: Cursor <cursoragent@cursor.com>
@bryanbeverly
bryanbeverly requested a review from a team July 31, 2026 01:01
@bryanbeverly
bryanbeverly merged commit 6c2d357 into main Aug 3, 2026
3 checks passed
@bryanbeverly
bryanbeverly deleted the bryanbeverly/cursor/lockfile-maintenance-cooldown-exemption branch August 3, 2026 19:30
bryanbeverly added a commit to trufflesecurity/helm-charts that referenced this pull request Aug 6, 2026
## Why

This repo pins the shared Renovate preset, so it has been frozen at
`v1.0.3` and does not yet have the `lockFileMaintenance` release-age
exemption from
[trufflesecurity/.github#24](trufflesecurity/.github#24),
now tagged as `v1.0.4`.

Without that exemption the preset's own `lockFileMaintenance.automerge:
true` can never fire. A lockfile refresh is carried out by the package
manager rather than resolved from a single upstream release, so there is
no release timestamp for `minimumReleaseAge` to evaluate — and Renovate
treats a missing timestamp as "not old enough". The result is that
`renovate/stability-days` pins to pending permanently and never clears
on a rebase, so automerge waits forever on a check that cannot pass.

## What changed

One line — the preset pin, `#v1.0.3` to `#v1.0.4`. No behavior change
beyond the exemption described above.

`v1.0.4` also carries two `prBodyNotes` that will now appear on lock
file maintenance PRs in this repo: one noting that release age was not
validated for the packages involved, and one noting that a loose range
can move a direct dependency without it appearing as a version upgrade.

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants