Skip to content

chore(husky): add pre-commit guard for pinned @biomejs/biome version#1404

Merged
even-wei merged 2 commits into
mainfrom
chore/biome-pin-guard
May 28, 2026
Merged

chore(husky): add pre-commit guard for pinned @biomejs/biome version#1404
even-wei merged 2 commits into
mainfrom
chore/biome-pin-guard

Conversation

@gcko
Copy link
Copy Markdown
Contributor

@gcko gcko commented May 28, 2026

Summary

The sister recce-cloud-infra repo has been bitten twice by Dependabot consolidations silently re-bumping a deliberate @biomejs/biome pin past a known macOS arm64 stack-overflow bug:

  • DataRecce/recce-cloud-infra#1333 — original pin to 2.4.11 (DRC-3460)
  • DataRecce/recce-cloud-infra#1374 — consolidation re-bumped to 2.4.15 (regression)
  • DataRecce/recce-cloud-infra#1382 — re-pin and add the same guard (sibling PR)

Biome 2.4.12 through 2.4.15 hit a deterministic Rust stack overflow on macOS arm64 when running the TS-aware nursery rules (noFloatingPromises, noMisusedPromises, noUnnecessaryConditions).

Upstream status

What Where Status
Bug report biomejs/biome#10411 CLOSED, S-Bug-confirmed
Fix PR biomejs/biome#10442 Merged 2026-05-24
Released in biome 2.4.16 Shipped 2026-05-27 (Latest)

Important: 2.4.16 was tested on the sister recce-cloud-infra repo and still crashes — the upstream fix is partial. Details in DataRecce/recce-cloud-infra#1382.

The js/biome.json in this repo does not currently enable those rules, so we haven't been bitten here yet — but the same consolidation pattern applies, and silent bumps are easy to miss in lockfile-heavy PRs.

Changes

  • js/.husky/pre-commit — new pinned-dep guard, no functional change otherwise.
  • No biome version change. This repo stays on 2.4.15 because the affected rules aren't enabled here.

The guard

When js/package.json is part of the staged commit, the hook reads its staged content via git show :js/package.json, extracts the @biomejs/biome version, and compares against EXPECTED_BIOME=2.4.15. On mismatch it blocks the commit with a clear error pointing at the upstream issue, the infra-repo PRs, and the 2.4.16 testing finding, plus a 3-step Mac arm64 verification recipe.

Override for intentional bumps:

ALLOW_BIOME_BUMP=1 git commit ...

Then update EXPECTED_BIOME in the hook to the new pinned version in the same commit.

Test plan

  • Staged a fake 2.4.99 version — hook fails with the expected DRC-3460 error message, exit 1
  • Same staged + ALLOW_BIOME_BUMP=1 — hook passes, exit 0
  • No package.json change — guard is silent, existing pnpm lint:staged flow runs normally
  • No biome version change — package.json and lockfile untouched

The sister recce-cloud-infra repo has now been bitten twice (PRs #1333,
#1376, #1382) by Dependabot consolidations silently re-bumping a
deliberate @biomejs/biome pin past a known Mac arm64 stack-overflow bug
in 2.4.12 through 2.4.15. The js/biome.json in this repo does not
currently enable the affected nursery rules (noFloatingPromises,
noMisusedPromises, noUnnecessaryConditions), so the bug has not bitten
here yet, but the same consolidation pattern applies, and silent bumps
are easy to miss in lockfile-heavy PRs.

Add a pre-commit guard that reads the staged content of js/package.json,
checks the @biomejs/biome version against an EXPECTED_BIOME constant
(currently 2.4.15, the version this repo runs on today), and blocks the
commit on a mismatch with a clear remediation message. Override with
ALLOW_BIOME_BUMP=1 after verifying biome runs cleanly on macOS arm64
with the nursery rules enabled.

No biome version change here, only the guard. When biome is deliberately
bumped, update EXPECTED_BIOME in this hook in the same commit.

Signed-off-by: Jared Scott <jared.scott@datarecce.io>
@gcko gcko force-pushed the chore/biome-pin-guard branch from 3a80a1a to e0a000c Compare May 28, 2026 03:09
@gcko gcko requested a review from Copilot May 28, 2026 03:15
@gcko gcko self-assigned this May 28, 2026
@gcko gcko requested a review from even-wei May 28, 2026 03:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a Husky pre-commit safeguard in the js/ workspace to prevent silent Dependabot-driven bumps of the deliberately pinned @biomejs/biome version, reducing the risk of reintroducing the known macOS arm64 stack overflow regression.

Changes:

  • Add a pre-commit guard that inspects the staged js/package.json and blocks commits when @biomejs/biome differs from the expected pinned version (unless explicitly overridden).
  • Provide a documented override mechanism (ALLOW_BIOME_BUMP=1) to allow intentional bumps after verification.

Comment thread js/.husky/pre-commit Outdated
Comment thread js/.husky/pre-commit Outdated
Comment thread js/.husky/pre-commit Outdated
@even-wei
Copy link
Copy Markdown
Contributor

Code Review: PR #1404

SHA e0a000c80 · Verdict NO-GO

Issues

  1. js/.husky/pre-commit:13,52 — Hook references PR #1376 as the sister-repo dependabot-consolidation incident, but PR fix: cancel button gives immediate UI feedback #1376 in recce-cloud-infra is "docs: add Even Wei contributor stats and shared skills to ONBOARDING.md" — unrelated. The actual consolidation re-bump is recce-cloud-infra#1374 (correctly cited in this PR's body table).
    Evidence: gh pr view 1376 --repo DataRecce/recce-cloud-infra returns the ONBOARDING.md docs PR; the PR body table here lists DataRecce/recce-cloud-infra#1374 — consolidation re-bumped to 2.4.15. Line 13 (PR #1333, PR #1376) and line 52 (PRs #1333 and #1376) both need #1374.
    Pass F.

Notes

  1. js/.husky/pre-commit:35-37 — Extraction grep | sed returns multi-line output if @biomejs/biome appears twice (e.g., a future pnpm.overrides entry). The subsequent equality check would then block with a confusing error. Not exploitable today (only one occurrence), but a head -1 would harden against future structure changes.
    Evidence: printf '"@biomejs/biome": "2.4.15",\n"@biomejs/biome": "9.9.9",\n' | grep -E '"@biomejs/biome":' | sed -E 's/.*"([^"]+)".*/\1/' emits two lines.
    Pass F.

  2. js/.husky/pre-commit:18 — Uses --diff-filter=ACMR while the existing JS lint detector on line 69 uses --diff-filter=ACM. Renames of js/package.json are vanishingly unlikely; flag for consistency only.
    Pass F.

Verification performed

  • Confirmed js/package.json pins @biomejs/biome: 2.4.15 (matches EXPECTED_BIOME).
  • Confirmed js/biome.json does NOT enable noFloatingPromises, noMisusedPromises, or noUnnecessaryConditions (only one biome config exists in the repo; no nursery section). Pin-without-bump rationale is sound.
  • Manually staged a fake 2.4.99 version and ran the hook: blocks with exit 1 and the documented error message. With ALLOW_BIOME_BUMP=1 set: passes. With no package.json change: silent, existing pnpm lint:staged path runs.
  • bash -n syntax check: clean. shellcheck on the file emits only pre-existing findings on lines 84/88/90/92; the new guard block (lines 10–66) is shellcheck-clean.
  • Confirmed set -e does NOT abort on a no-match grep inside $(...) (bash behavior; pipefail not set). The [ -n "$STAGED_BIOME" ] guard correctly handles the no-match path.

Copy link
Copy Markdown
Contributor

@even-wei even-wei left a comment

Choose a reason for hiding this comment

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

Code Review: PR #1404

SHA e0a000c80 · Verdict NO-GO

Issues

  1. js/.husky/pre-commit:13,52 — Hook references PR #1376 as the sister-repo dependabot-consolidation incident, but PR #1376 in recce-cloud-infra is "docs: add Even Wei contributor stats and shared skills to ONBOARDING.md" — unrelated. The actual consolidation re-bump is recce-cloud-infra#1374 (correctly cited in this PR's body table).
    Evidence: gh pr view 1376 --repo DataRecce/recce-cloud-infra returns the ONBOARDING.md docs PR; the PR body table here lists DataRecce/recce-cloud-infra#1374 — consolidation re-bumped to 2.4.15. Line 13 (PR #1333, PR #1376) and line 52 (PRs #1333 and #1376) both need #1374.
    Pass F.

Notes

  1. js/.husky/pre-commit:35-37 — Extraction grep | sed returns multi-line output if @biomejs/biome appears twice (e.g., a future pnpm.overrides entry). The subsequent equality check would then block with a confusing error. Not exploitable today (only one occurrence), but a head -1 would harden against future structure changes.
    Evidence: printf '"@biomejs/biome": "2.4.15",\n"@biomejs/biome": "9.9.9",\n' | grep -E '"@biomejs/biome":' | sed -E 's/.*"([^"]+)".*/\1/' emits two lines.
    Pass F.

  2. js/.husky/pre-commit:18 — Uses --diff-filter=ACMR while the existing JS lint detector on line 69 uses --diff-filter=ACM. Renames of js/package.json are vanishingly unlikely; flag for consistency only.
    Pass F.

Verification performed

  • Confirmed js/package.json pins @biomejs/biome: 2.4.15 (matches EXPECTED_BIOME).
  • Confirmed js/biome.json does NOT enable noFloatingPromises, noMisusedPromises, or noUnnecessaryConditions (only one biome config exists in the repo; no nursery section). Pin-without-bump rationale is sound.
  • Manually staged a fake 2.4.99 version and ran the hook: blocks with exit 1 and the documented error message. With ALLOW_BIOME_BUMP=1 set: passes. With no package.json change: silent, existing pnpm lint:staged path runs.
  • bash -n syntax check: clean. shellcheck on the file emits only pre-existing findings on lines 84/88/90/92; the new guard block (lines 10–66) is shellcheck-clean.
  • Confirmed set -e does NOT abort on a no-match grep inside $(...) (bash behavior; pipefail not set). The [ -n "$STAGED_BIOME" ] guard correctly handles the no-match path.

…me extraction

- Correct sister-repo PR references: #1376#1374 on lines 13 and 66.
  (#1376 is an unrelated docs PR; #1374 is the actual Dependabot
  consolidation re-bump.) Spotted by Copilot and @even-wei.
- Harden the staged-version extraction (Copilot, @even-wei Note 1):
  add `head -1` so a future second `"@biomejs/biome":` occurrence
  (e.g., a pnpm.overrides entry) doesn't yield multi-line output, and
  fail-loud when extraction is empty so a package.json reformat or
  intentional dep removal can no longer silently disable the guard.
  `ALLOW_BIOME_BUMP=1` still overrides both the mismatch and the
  empty-extraction paths.
- Align `--diff-filter=ACM` with the existing JS lint detector below
  for consistency (@even-wei Note 2).

Verified locally via index-blob swap on macOS arm64:
  1. 2.4.99 staged, no override → exit 1, updated error cites #1374
  2. 2.4.99 staged + ALLOW_BIOME_BUMP=1 → exit 0
  3. 2.4.15 staged (current) → exit 0
  4. @biomejs/biome key removed → exit 1, "Could not extract" message
  5. @biomejs/biome key removed + ALLOW_BIOME_BUMP=1 → exit 0
`bash -n` clean; `shellcheck -S warning` silent on the guard block.

Signed-off-by: Jared Scott <jared.scott@reccehq.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@datarecce.io>
@gcko
Copy link
Copy Markdown
Contributor Author

gcko commented May 28, 2026

@even-wei All three findings addressed in 967b1e0. Summary table:

Finding File:line (before → after) Action Status
Issue 1: #1376 is unrelated docs PR pre-commit:13,5213,66 Both refs changed to #1374 Fixed
Note 1: grep | sed can return multi-line / silently disable guard pre-commit:35-3738-51 Added head -1; new fail-loud branch when extraction is empty (overrideable with ALLOW_BIOME_BUMP=1) Fixed
Note 2: --diff-filter=ACMR vs ACM below pre-commit:18 Changed to ACM for consistency Fixed

Verification on macOS arm64 (synthetic blob staged via git update-index --cacheinfo, working tree untouched):

Scenario Expected Got
2.4.99 staged, no override exit 1, error cites #1374 exit 1, cites #1374
2.4.99 staged + ALLOW_BIOME_BUMP=1 exit 0 exit 0
2.4.15 staged (current) exit 0 exit 0
@biomejs/biome key removed exit 1, "Could not extract" exit 1, new message
Key removed + ALLOW_BIOME_BUMP=1 exit 0 exit 0

bash -n clean; shellcheck -S warning silent on the new guard block.

Inline replies posted to each of Copilot's three comments. Ready for re-review.

@even-wei
Copy link
Copy Markdown
Contributor

Code Review: PR #1404

SHA 967b1e0 · Verdict GO

Defensive single-file change to js/.husky/pre-commit; adds a pinned-version guard for @biomejs/biome triggered only when js/package.json is part of the staged commit. Reviewed against Passes A (correctness), B (security), D (error handling), F (diff-specific).

Blockers

None.

Issues

None.

Notes

  1. js/.husky/pre-commit:33head -1 selects the first matching line, which is "first occurrence wins" regardless of whether that's devDependencies or a future pnpm.overrides entry. Realistically devDependencies appears first in this file, but if a pnpm.overrides["@biomejs/biome"] is ever added earlier in the JSON than the devDeps block, the guard will compare the override instead of the dep (or vice-versa). Effectively benign — overrides force the resolved version, so checking either is meaningful — but the framing on line 30 ("hardens against a future pnpm.overrides entry adding a second line") slightly misstates the behavior. Pass A.

What was verified

  • Pipeline semantics under set -e (no pipefail): empty grep doesn't abort, empty STAGED_BIOME is caught by the explicit -z check.
  • git show ":js/package.json" reads the index version (i.e. what's about to be committed), not the worktree — correct.
  • Regex captures the full quoted value, so caret/tilde-prefixed versions correctly fail the equality check.
  • Override env var (ALLOW_BIOME_BUMP=1) bypasses both the "could not extract" and "version mismatch" branches, matching the documented escape hatch.
  • Guard is no-op when js/package.json isn't staged; existing pnpm lint:staged flow is unchanged.
  • Pinned version 2.4.15 in EXPECTED_BIOME matches the staged value in js/package.json at this SHA.

Out-of-scope observations

The new block uses 4-space indentation while the surrounding shell uses tabs. Minor, not worth changing.

@even-wei even-wei self-requested a review May 28, 2026 04:07
@even-wei even-wei merged commit d71ad92 into main May 28, 2026
7 checks passed
@even-wei even-wei deleted the chore/biome-pin-guard branch May 28, 2026 04:07
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.

3 participants