Skip to content

fix(repo): untrack node_modules symlinks that dodged the dir-only ignore pattern - #869

Open
lilyshen0722 wants to merge 1 commit into
mainfrom
fix/untrack-node-modules-symlinks
Open

fix(repo): untrack node_modules symlinks that dodged the dir-only ignore pattern#869
lilyshen0722 wants to merge 1 commit into
mainfrom
fix/untrack-node-modules-symlinks

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

What

Two committed symlinks are on main, both pointing at absolute paths inside one operator worktree (.claude/worktrees/sprint-2026-05-24-installable-projection/…):

path arrived in merged
backend/node_modules #818 2026-08-04 22:18Z
frontend/node_modules #867 2026-08-06 02:54Z

Why gitignore didn't stop them

.gitignore:7 is node_modules/ — the trailing slash makes it directory-only. A symlink named node_modules is not a directory to the matcher, so git add -A picks it up. (Docker's ignore file is immune to the same trap because it filepath.Cleans patterns, stripping the slash.)

Measured blast radius (each claim executed, not inferred)

  • Docker builds: safe. Context-exclusion test with positive and negative controls: with .dockerignore node_modules/ present the symlink is CTX-EXCLUDED; without it, CTX-PRESENT. Production-scale corroboration: the live backend image (e55f0c21, deployed 01:27Z tonight) was built from a symlink-carrying tree and succeeded — the failure mode (COPY . . clobbering /app/node_modules before npx tsc) is loud and did not fire.
  • CI: safe. npm ci removes the entry before installing; both carrier PRs passed checks.
  • Every other checkout: NOT safe. Reproduced in a scratch repo: git pull exits 0 and silently replaces a real, populated node_modules directory with the dangling symlink (ignored paths are expendable to checkout). Next build/test in that tree fails with missing modules — or, on the one machine where the target resolves, silently runs against a May-24 worktree's dependencies: version skew with no error anywhere.

Fix

  • git rm --cached both symlinks (the author's local links are untouched — only the index entry is removed).
  • .gitignore: drop the trailing slash with a same-file comment naming the defect, so the pattern matches file, dir, and symlink forms and the next git add -A can't re-commit one.

Not done here

  • No .dockerignore changes — verified already safe, and touching them would change a working exclusion.
  • The three intentional symlinks (AGENTS.md, .agents/skills, .claude/skills) are untouched.

🤖 Generated with Claude Code

…ore pattern

backend/node_modules (#818) and frontend/node_modules (#867) are committed
SYMLINKS pointing at an absolute path inside one operator worktree. They got
past .gitignore because 'node_modules/' (trailing slash) matches only
directories — a symlink named node_modules sails through 'git add -A'.

Measured blast radius before this fix:
- docker builds: SAFE. .dockerignore patterns are filepath.Clean'd, so
  'node_modules/' excludes the symlink from the context (verified empirically
  with positive+negative controls; the live backend image at e55f0c2 was
  already built from a symlink-carrying tree and succeeded).
- CI: SAFE. npm ci removes the symlink before installing; PR checks on both
  carrier PRs passed.
- every other checkout: NOT safe. 'git pull' exits 0 and silently replaces a
  real, populated node_modules directory with the dangling symlink (ignored
  files are expendable to checkout — reproduced in a scratch repo). On the
  one machine where the target resolves, everything silently uses a May-24
  worktree's dependencies instead of the tree's own: version skew with no
  error anywhere.

Fix: untrack both symlinks (git rm --cached — the author's local links are
untouched) and drop the trailing slash so the pattern matches the symlink
form too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.

1 participant