Skip to content

chore: pin package-lock.json to LF in .gitattributes - #816

Merged
izzywdev merged 4 commits into
masterfrom
claude/normalise-lockfile-eol
Aug 27, 2026
Merged

chore: pin package-lock.json to LF in .gitattributes#816
izzywdev merged 4 commits into
masterfrom
claude/normalise-lockfile-eol

Conversation

@izzywdev

@izzywdev izzywdev commented Aug 26, 2026

Copy link
Copy Markdown
Owner

📋 Description

Pins package-lock.json to LF so a CRLF-stored lockfile can't recur.

This PR shrank. It originally also carried the EOL normalisation of fuzefront-website/backend/package-lock.json (7,124 lines). #814 has since merged and regenerated that same file as LF, so the normalisation is already on master and this PR is now just the durable rule — 8 lines.

🔄 Type of Change

  • 🧹 Chore (no functional change)

🔧 Implementation Details

.gitattributes already pins manifests:

package.json    text eol=lf
**/package.json text eol=lf

Neither glob matches package-lock.json, so lockfiles were never pinned. This adds:

package-lock.json    text eol=lf
**/package-lock.json text eol=lf

Why it matters more for a lockfile than for ordinary source

npm rewrites the whole file on every resolution. A CRLF-stored lockfile regenerated on Linux comes back entirely LF, so a 9-entry dependency change renders as a 7,124-line diff — which hides the real change from review and trips gate-line-endings.

That is not hypothetical. It happened on #814, and then it cost this PR three red CI cycles, described below.

The Trivy failures on this PR were a real mechanism, worth recording

While this PR carried the EOL rewrite, Trivy failed on it repeatedly — finally as "9 new alerts including 3 high severity security vulnerabilities." The content was byte-identical to master modulo line endings (verified by stripping \r from both sides and diffing: zero version changes), so it introduced nothing.

The alerts were lodash, tar-fs, validator, morgan, qs, body-parsermaster's own pre-existing vulnerabilities in that lockfile. Code scanning attributes alerts to changed lines, and rewriting all 7,124 lines put every vulnerable entry "in code changed by this pull request."

Two corrections came out of chasing it:

  1. It was not the missing-configuration race (fix(ci): stop the Trivy check going red on a missing SARIF configuration #818/fix(ci): one configuration per SARIF tool — the Trivy check race, properly #820). Those are a separate mechanism and would not have cleared this.
  2. fix(deps): raise tar to >=7.5.21 and delete the dead backend/package-lock.json (clears both CRITICALs) #813 was not a valid control. Its diff is −9,887 lines and its Trivy passed, which looked like proof that diff size was irrelevant. But fix(deps): raise tar to >=7.5.21 and delete the dead backend/package-lock.json (clears both CRITICALs) #813 deletes lines while this PR rewrote them — deleted lines cannot carry alerts, rewritten ones can. The comparison did not apply.

What actually fixed it was #814, which raises all six package families in that exact file:

package
lodash 4.18.1
tar-fs 2.1.5
validator 13.15.35
morgan 1.11.0
qs 6.15.3
body-parser 1.20.6

With nothing vulnerable left in the file, the rewrite attributes nothing — and now the rewrite is gone from this PR entirely.

🧪 Testing

  • Conflict on fuzefront-website/backend/package-lock.json resolved by taking master's copy; verified byte-identical to master and LF (0 CRLF lines)
  • All six package families confirmed at fixed versions in the resolved file
  • .gitattributes itself verified LF / UTF-8
  • Net diff against master is 8 lines, one file

Scope note

Many other tracked files are still CRLF (backend/src/**, several workflows, FuzeQuality/**). A repo-wide renormalise would be an enormous diff touching code this PR has no business rewriting, and gate-line-endings only checks files a PR changes — so pre-existing CRLF elsewhere stays out of scope. This pins the lockfile class specifically.

Code Quality

  • Self-review of code completed
  • Code follows conventional commit format

fuzefront-website/backend/package-lock.json is the only lockfile in the
repo stored with CRLF. It predates gate-line-endings, so it sat unnoticed
until a PR touched it — same story as the CLAUDE.md / authentikPassword.ts
entries already pinned at the bottom of .gitattributes.

The existing globs do not cover it:

    package.json    text eol=lf
    **/package.json text eol=lf

neither matches package-lock.json, so the lockfile was never pinned.

This matters more for a lockfile than for an ordinary source file. npm
rewrites the whole file on every resolution, so a CRLF-stored lockfile
regenerated on Linux comes back entirely LF: a 9-entry dependency change
renders as a 7,124-line diff. That hides the real change from review and
trips gate-line-endings at the same time.

Content is byte-identical modulo line endings — verified by stripping \r
from both sides and diffing (no difference). Split out of the #747
dependency work so the deps PR keeps a reviewable diff.

Refs #747

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013tMciHkPE8To7V67CsgKKc
@izzywdev izzywdev added the auto-merge Enable squash auto-merge once CI passes label Aug 26, 2026 — with Claude
@github-actions
github-actions Bot enabled auto-merge (squash) August 26, 2026 18:16
izzywdev pushed a commit that referenced this pull request Aug 26, 2026
gate-line-endings rejects CRLF in any file a PR touches, and this lockfile
is the repo's only CRLF one. It was left as CRLF here to keep the
dependency diff readable; the gate is right and that was the wrong call.

#816 pins package-lock.json to LF in .gitattributes so this cannot recur.
Once it lands, rebasing this branch collapses this file's diff back to the
nine dependency entries that actually changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013tMciHkPE8To7V67CsgKKc

Copy link
Copy Markdown
Owner Author

Both failing checks here are pre-existing on master and are not caused by this PR. Fixes are open for each.

Dockerfiles install from the lockfile — the single FFRNT-254 violation in services/selection-list-service/Dockerfile. Red on master already; this PR touches only .gitattributes and a lockfile's line endings. Fixed by #817 (verified: that gate reports success on #817's head).

Trivy — reports "1 configuration present on refs/heads/master was not found: .github/workflows/ci.yml:security-scan", then, with no baseline to diff against, lists pre-existing findings as new. Fixed by #818 (verified: Trivy reports success on #818's head).

The check summary on this PR is itself the proof that those alerts are phantom:

New alerts in code changed by this pull request — 3 high, 5 medium, 1 low

The entire diff of this PR is CRLF → LF in one lockfile, plus two .gitattributes lines. Content is byte-identical modulo line endings (verified by stripping \r from both sides and diffing). A whitespace-only change cannot introduce nine security alerts. They are master's existing findings, surfaced as "new" because the baseline is incomplete — exactly the failure mode #818 fixes.

Not porting those fixes into this PR. #817 and #818 are both green on their own gates with auto-merge armed, and porting would mean four open PRs concurrently editing the same Dockerfile and the same two workflow files — the exact concurrent-edit hazard CLAUDE.md calls out as the highest-risk moment for this class of bug. Once they land I'll update this branch onto the fixed base so CI re-runs against it, rather than leaving stale red checks.

No re-run spent: a re-run cannot clear either failure, since both originate in files this branch does not contain changes to.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Correcting my earlier comment on this PR. I attributed the Trivy failure to #818#818 has since merged and this PR is still red. That attribution was wrong.

Dockerfiles install from the lockfile is fixed: #817 merged and that check is green here now. The Trivy half needed more.

Why #818 wasn't enough

#818 split the ~6-minute container scan onto its own SARIF tool, on the theory that the duration gap caused the race. Measured on this PR right after it merged:

Trivy   04:27:07 → 04:27:09      ← two seconds
"1 configuration present on refs/heads/master was not found:
   .github/workflows/harden-gate.yml: trivy"

GitHub finalises a tool's check as soon as it considers the set complete, without waiting for stragglers. Two configurations under one SARIF tool race whether they finish six minutes or two seconds apart. Every pass so far just moved which configuration went missing. #820 fixes it on the actual invariant: one configuration per tool.

It is working — Trivy Container reports success here as its own check, which is #818's half doing its job.

What I checked and rejected

The check summary hedges "Alerts not introduced by this pull request might have been detected because the code changes were too large", and this PR does rewrite 7,124 lockfile lines. That looked like a plausible second cause, so I nearly restructured this PR to shed the lockfile.

It isn't the cause. #813 is the control: its diff is +49 −9,887 across 4 files — it deletes an entire 9,887-line lockfile — and its Trivy check reports success. A larger diff over the same kind of dependency data passes. So diff size is not what fails this PR; the missing configuration is.

I reverted that restructuring rather than ship a change I'd talked myself into. Worth recording, since "the diff is too big" is the explanation this check's own message invites.

Status

No fix to push here — this PR's content is two .gitattributes lines and an EOL normalisation, neither of which can affect a dependency scan. It goes green when #820 lands. No re-run spent: a re-run cannot clear a missing-configuration warning.


Generated by Claude Code

…ckfile-eol

# Conflicts:
#	fuzefront-website/backend/package-lock.json
@izzywdev izzywdev changed the title chore: pin package-lock.json to LF and normalise the one CRLF lockfile chore: pin package-lock.json to LF in .gitattributes Aug 27, 2026
@izzywdev
izzywdev merged commit a9cb1bb into master Aug 27, 2026
56 checks passed
@izzywdev
izzywdev deleted the claude/normalise-lockfile-eol branch August 27, 2026 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge Enable squash auto-merge once CI passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants