Skip to content

[code-infra] Fix react@^18 CI failing on nanoid trust-downgrade#22923

Merged
LukasTy merged 1 commit into
mui:masterfrom
LukasTy:claude/optimistic-shamir-653f59
Jun 24, 2026
Merged

[code-infra] Fix react@^18 CI failing on nanoid trust-downgrade#22923
LukasTy merged 1 commit into
mui:masterfrom
LukasTy:claude/optimistic-shamir-653f59

Conversation

@LukasTy

@LukasTy LukasTy commented Jun 24, 2026

Copy link
Copy Markdown
Member

Problem

All *_react_18 CI jobs (test_unit_react_18, test_browser_react_18, test_e2e_react_18) started failing in the Install js dependencies step, before any test runs:

[ERR_PNPM_TRUST_DOWNGRADE] High-risk trust downgrade for "[email protected]" (possible package takeover)
This error happened while installing the dependencies of [email protected]

Example: https://app.circleci.com/pipelines/github/mui/mui-x/134351/workflows/af018f65-9aac-4f38-86f8-06b220834647/jobs/868597

Root cause

This is the repo's own trustPolicy: no-downgrade (pnpm supply-chain feature) firing on a false positive:

  • [email protected] was published via a staged/trusted publish; [email protected] (2026-06-20) dropped all trust evidence, so no-downgrade rejects it as a downgrade. It is published by the legitimate maintainer (ai, also postcss's author), not a real takeover.
  • 3.3.14 is the newest version old enough to pass minimumReleaseAge: 4320 (3 days). [email protected] restored SLSA provenance but is still inside the 3-day window, so the resolver can't pick it yet and falls back to the unattested 3.3.14.
  • Why only the react@^18 jobs: they install with package-overrides (react@^18 ...), which re-resolves the dependency graph and pulls in [email protected]. The other jobs install the committed lockfile frozen, pinned to the trusted [email protected], so they never re-resolve. pnpm dedupe hits the same wall whenever it re-resolves nanoid (Dedupe fails with trustPolicy no-downgrade pnpm/pnpm#10329).

Solutions considered

Two one-line fixes unblock CI. Both are self-expiring: they go inert once [email protected] ages past the 3-day minimumReleaseAge window and resolves on its own.

Option A (chosen) -- relax the soak gate for the attested version

minimumReleaseAgeExclude:
  - '[email protected]'

Lets the resolver reach [email protected], which has restored SLSA provenance and passes no-downgrade on its own merit. Only the time-soak gate is waived, for one explicitly-named, attested version; the trust check stays fully enforced.

Option B (rejected) -- whitelist the unattested version in the trust policy

trustPolicyExclude:
  - '[email protected]'

Excludes [email protected] from the trust check, allowing the unattested build through. The soak gate stays, the provenance/trust gate is relaxed.

Comparison

Option A (chosen) Option B
Resolves to [email protected] (SLSA provenance) [email protected] (no attestation)
Gate relaxed time-soak only; trust stays enforced trust/no-downgrade; soak stays
Baked into committed lockfile on re-resolve attested 3.3.15, passes a frozen re-verify unattested 3.3.14, fails frozen re-verify unless the exclude is carried repo-wide
Self-expiry yes, once 3.3.15 ages in the entry is ignored only once a later re-resolution moves off 3.3.14; 3.3.14 never gains provenance

Why Option A

Re-resolution (the react@^18 overrides install, pnpm dedupe, Renovate, a lockfile regen) writes the chosen nanoid version into the committed lockfile, and frozen installs re-verify lockfile entries against the active policies (pnpm 11.1.3+). Committing the unattested 3.3.14 (Option B) is therefore a standing trust-policy exception that every frozen install repo-wide must carry, and 3.3.14 never gains provenance to clear it. Committing the attested 3.3.15 (Option A) passes cleanly, and the soak exemption self-expires within hours. Option A keeps the stronger guarantee (provenance) enforced and only waives the softer time-soak gate.

Honest trade-off: Option A does shave soak time off 3.3.15, and soak time is the one gate that would catch malware shipped with valid provenance (e.g. a maintainer/CI compromise). Low-stakes here -- legitimate maintainer, the version has already soaked ~2.4 days, and the entry self-expires the same day -- but noted.

Verification

Reproduced locally with the repo's trust settings + [email protected]:

  • Baseline (no fix): install and pnpm dedupe both fail with ERR_PNPM_TRUST_DOWNGRADE on 3.3.14.

  • Option A: the re-resolving install and pnpm dedupe both succeed and resolve [email protected].

  • Frozen re-verify: a committed 3.3.14 fails no-downgrade once the exclude is removed; a committed 3.3.15 only trips the (transient) soak gate and passes once aged in.

  • I have followed (at least) the PR section of the contributing guide.

🤖 Generated with Claude Code

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 24, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-22923--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@LukasTy
LukasTy force-pushed the claude/optimistic-shamir-653f59 branch from 6153846 to 4301290 Compare June 24, 2026 08:05
@LukasTy LukasTy added type: bug It doesn't behave as expected. scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). labels Jun 24, 2026
@LukasTy
LukasTy marked this pull request as ready for review June 24, 2026 08:22
@LukasTy
LukasTy requested review from Janpot and brijeshb42 June 24, 2026 08:22
@LukasTy LukasTy changed the title [core] Fix react@^18 CI failing on nanoid trust-downgrade [code-infra] Fix react@^18 CI failing on nanoid trust-downgrade Jun 24, 2026

@Janpot Janpot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very elaborate comment 😄

The react@^18 jobs install with `package-overrides`, which re-resolves the
dependency graph instead of using the committed lockfile. That re-resolution
pulls in [email protected] (a transitive dep of [email protected]), which was published
without provenance after 3.3.13 used a staged/trusted publish. The repo's
`trustPolicy: no-downgrade` then rejects it with ERR_PNPM_TRUST_DOWNGRADE,
failing install before any test runs. `pnpm dedupe` hits the same wall whenever
it re-resolves nanoid (pnpm/pnpm#10329).

[email protected] restored SLSA provenance and passes the trust policy on its own
merit, but is still inside the 3-day minimumReleaseAge soak window, so the
resolver falls back to 3.3.14. Exempt only 3.3.15's soak time via
minimumReleaseAgeExclude so re-resolution lands on the attested 3.3.15 instead
of the unattested 3.3.14 (which a frozen install would re-verify and reject
repo-wide). Self-expiring: once 3.3.15 ages past minimumReleaseAge it resolves
naturally and the entry can be dropped.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@LukasTy
LukasTy force-pushed the claude/optimistic-shamir-653f59 branch from 4301290 to 5f7553d Compare June 24, 2026 10:51
@LukasTy
LukasTy enabled auto-merge (squash) June 24, 2026 10:55
@LukasTy
LukasTy disabled auto-merge June 24, 2026 11:06
@LukasTy
LukasTy merged commit c92c2ff into mui:master Jun 24, 2026
19 of 20 checks passed
@LukasTy
LukasTy deleted the claude/optimistic-shamir-653f59 branch June 24, 2026 11:10
mbrookes pushed a commit to mbrookes/mui-x that referenced this pull request Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants