From 3644f9be3e5181e058107c6214b52e479f0949e1 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Sat, 29 Aug 2026 18:20:37 -0700 Subject: [PATCH] docs: how to set up a git worktree, and why inheritance hides the gaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A worktree gets a fresh checkout but no npm install. Node walks up for node_modules, so a worktree inside this repo silently inherits the main checkout's ~1300 packages and mostly works — which is why the gaps surface as unrelated-looking failures deep into a task instead of up front. Documents `npm ci` as the one-time setup step, with the four failure signatures hit while working in a worktree this week. They look unrelated and have four distinct causes: - postinstall-generated + gitignored (licensing key) — in no fresh checkout - un-hoisted workspace dep (posthog-node, only in apps/website/node_modules) — the walk up from WORKTREE/apps/website never passes through MAIN's - literal path reference (katex css, resolved from workspace root) — no module resolution, so nothing to inherit through - turbopack resolving its own workspace root (cockpit build) Also records the two things not to do: hand-copying packages from the main checkout (a partial copy pulls a package without its transitive deps, and a mistargeted cp can overwrite node_modules itself), and `npm install` on macOS (rewrites the lockfile and drops the Linux @next/swc-* bindings). Verified rather than assumed — ran `npm ci` in this worktree: exit 0, package-lock.json byte-identical afterwards, all four gaps closed, and `nx build cockpit` went from failing on pristine main to exit 0. Co-Authored-By: Claude Opus 5 --- CONTRIBUTING.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac4e0532f..5ccdbe38e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,43 @@ Threadplane is MIT-licensed and developed in the open. Contributions are welcome 4. **Security issues:** do not open a public issue — see [SECURITY.md](SECURITY.md) for the private vulnerability-reporting process. +## Working in a git worktree + +A `git worktree` gets a fresh checkout but **not** a fresh `npm install`. Node +resolves modules by walking *up* the directory tree, so a worktree created inside +this repository silently inherits the main checkout's `node_modules` and mostly +works — which is why the gaps surface as unrelated-looking failures well into a +task rather than up front. + +Run install once per worktree before building anything: + +```bash +npm ci +``` + +`npm ci` installs strictly from `package-lock.json` and never rewrites it, so it +is safe on any platform (regenerating the lockfile is not — see the note below). +It also runs `postinstall`, which generates files that are gitignored and +therefore absent from every fresh checkout. + +Four failure signatures come from skipping it. They look unrelated but share one +cause, and each is fixed by the install above: + +| Symptom | Why inheritance doesn't cover it | +| --- | --- | +| `Failed to resolve import "./license-public-key.generated.js"` | Generated by `postinstall` and gitignored, so it exists in no fresh checkout. | +| `Cannot find module 'posthog-node'` when building `website` | Installed only into `apps/website/node_modules`, never hoisted. The walk up from the worktree's `apps/website/` never passes through the main checkout's. | +| `Could not resolve "node_modules/katex/dist/katex.min.css"` | Referenced by literal path from the workspace root, not by module resolution — so there is no upward walk to inherit through. | +| `Next.js inferred your workspace root, but it may not be correct` when building `cockpit` | Turbopack resolves its own workspace root and will not compile outside it. | + +Do not fix these by copying individual packages from the main checkout. The list +keeps growing, a partial copy pulls in a package without its transitive +dependencies, and a mistargeted `cp` can overwrite `node_modules` itself. + +Do not run `npm install` in a worktree on macOS either: it rewrites +`package-lock.json` and drops the Linux `@next/swc-*` bindings, which breaks CI. +`npm ci` is the safe command. + ## Testing New functionality and bug fixes must include automated tests. Run a project's