Skip to content

Repair stale pnpm GVS package projections#638

Merged
schickling merged 4 commits intomainfrom
schickling/2026-04-28-pnpm-gvs-content-health
Apr 29, 2026
Merged

Repair stale pnpm GVS package projections#638
schickling merged 4 commits intomainfrom
schickling/2026-04-28-pnpm-gvs-content-health

Conversation

@schickling-assistant
Copy link
Copy Markdown
Collaborator

@schickling-assistant schickling-assistant commented Apr 28, 2026

Summary

  • detect missing runtime package export targets in pnpm GVS link projections
  • ignore declaration-only export targets so type metadata gaps do not block valid runtime projections
  • purge stale GVS links and force relink when projection health fails
  • cover missing-runtime-export and declaration-only false-positive cases in the pnpm helper regression test

Rationale

The existing health check caught broken symlinks and missing transitive dependency projections, but not incomplete package contents under pnpm 11 GVS links. A package could keep a valid package.json while an exported runtime file was absent, causing downstream Vitest/build runs to fail later with less actionable module-load errors.

Concrete public repro from side experiments:

  1. Install @testing-library/svelte@5.3.1 in a PNPM 11 workspace with enable-global-virtual-store=true.
  2. Delete only src/vitest.js from the resolved package projection under store/v11/links/@testing-library/svelte/.../node_modules/@testing-library/svelte.
  3. The old health check passes because the workspace symlink and package.json still exist.
  4. The new health check fails with Missing package content: @testing-library/svelte -> ./src/vitest.js.
  5. pnpm install --force does not restore the missing file while the existing v11/links projection remains.
  6. Deleting store/v11/links and reinstalling restores the missing runtime export target.

The repair path already detected GVS hash/config drift and forced a relink, but it only purged workspace node_modules. It now also removes the active v11/links directory before the forced install so pnpm cannot reuse incomplete package projections.

The content check intentionally validates runtime export targets only. During side experiments, vitest@4.0.15 exposed declaration-only types targets that were absent from the GVS projection while the runtime targets were present and loadable. Treating those as package-content failures would make the health check too broad.

Verification

  • Public registry side experiment with @testing-library/svelte@5.3.1:
    • missing src/vitest.js is detected
    • pnpm install --force alone does not restore it
    • deleting store/v11/links plus reinstall restores it
  • PATH=/run/current-system/sw/bin:$PATH bash nix/devenv-modules/tasks/shared/tests/pnpm.test.sh
  • PATH=/run/current-system/sw/bin:$PATH oxfmt --check nix/devenv-modules/tasks/shared/check-node-modules-projection-health.cjs
  • PATH=/run/current-system/sw/bin:$PATH nixfmt --check nix/devenv-modules/tasks/shared/pnpm.nix
  • git diff --check
  • env -u OTEL_STATE_DIR -u OTEL_EXPORTER_OTLP_ENDPOINT -u OTEL_MODE CI=1 devenv tasks run --refresh-task-cache --no-eval-cache genie:check lint:nix:format lint:check:format lint:check:oxlint ts:build --mode before --no-tui

Downstream LiveStore validation with the earlier candidate pinned:

  • env -u OTEL_STATE_DIR -u OTEL_EXPORTER_OTLP_ENDPOINT -u OTEL_MODE -u PNPM_HOME -u PNPM_STORE_DIR -u npm_config_store_dir CI=1 devenv tasks run --refresh-task-cache --no-eval-cache test:unit --mode before --no-tui
  • env -u OTEL_STATE_DIR -u OTEL_EXPORTER_OTLP_ENDPOINT -u OTEL_MODE -u PNPM_HOME -u PNPM_STORE_DIR -u npm_config_store_dir CI=1 devenv tasks run --refresh-task-cache --no-eval-cache ts:build lint:check:format lint:check:oxlint test:unit --mode before --no-tui
Posted on behalf of @schickling
field value
agent_name 🌱 co1-alder
agent_session_id 6c624c62-4e38-435e-b267-475ef99d9340
agent_tool Codex CLI
agent_tool_version codex-cli 0.124.0
agent_runtime Codex CLI codex-cli 0.124.0
agent_model unknown
worktree effect-utils/schickling/2026-04-28-pnpm-gvs-content-health
machine dev3
tooling_profile dotfiles@19cf6f4

@schickling-assistant schickling-assistant force-pushed the schickling/2026-04-28-pnpm-gvs-content-health branch from b2e06e0 to 5ce025d Compare April 28, 2026 21:24
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Storybook Previews

Package Latest URL Last Deploy (Europe/Berlin)
effect-schema-form-aria https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
notion-cli https://notion-cli-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
react-inspector https://react-inspector-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
tui-stories https://tui-stories-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
tui-react https://tui-react-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
genie https://genie-pr-638--overeng-utils.netlify.app 2026-04-29 09:32 CEST
megarepo https://megarepo-pr-638--overeng-utils.netlify.app 2026-04-29 09:33 CEST
effect-react https://effect-react-pr-638--overeng-utils.netlify.app 2026-04-29 09:33 CEST
notion-react https://notion-react-pr-638--overeng-utils.netlify.app 2026-04-29 09:33 CEST
Per-Commit Deploy History

Commit 14fb1dc · 2026-04-29 09:34 CEST

Package URL
effect-schema-form-aria https://69f1b3f12638c02155b9bfa4--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f1b3f89e309623db15e0c2--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f1b3fd988129fdd75c7996--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f1b40558296521465e86c4--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f1b405d027b91edc5b8cba--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f1b40bd107032e6e118557--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f1b450b59ac3189523c412--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f1b456e480ae231c07ec6b--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f1b4568fcba61f4c965bc8--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

Commit 09c871b · 2026-04-29 09:16 CEST

Package URL
effect-schema-form-aria https://69f1aff0d8cf081847d85121--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f1b008a2960d0f601053d0--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f1b01258296514f85e8619--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f1b022b508601254fce72a--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f1b01af24b9cf0f05a3b96--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f1aff92638c01639b9bec2--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f1b0013251a6ef6fb21585--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f1afebd8cf081639d85204--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f1b00dc9329e1769309486--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

Commit 5b418ad · 2026-04-29 08:55 CEST

Package URL
effect-schema-form-aria https://69f1ab2dcee714ff1be3b8d1--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f1ab4a4c9354023cf5caca--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f1ab2d785a1cdd8fbb2c6c--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f1ab3b3b18971086fb5b5e--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f1ab42d027b900405b8d86--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f1ab4ecee714008be3b789--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f1ab29b593ed00772e5972--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f1ab34f24b9ce1f45a38f3--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f1ab4156af800302b147d2--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

Commit be67553 · 2026-04-29 00:27 CEST

Package URL
effect-schema-form-aria https://69f1343468ac989f9329f723--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f1329ac4760cbcae178d18--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f132a1ca49cba7a583e011--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f132b4773431573acc941c--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f132aab1242de4bda27e2c--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f132bc2f8188bf4744e8cb--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f132bc7fa010ae16b4dc14--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f1328a94e6fabdfbf7eb66--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f132bc502b92e492c4d49b--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

Commit fbac966 · 2026-04-29 00:10 CEST

Package URL
effect-schema-form-aria https://69f12f3cf6fe31a09858cb81--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f12f17c75e2b4f236e4cc7--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f12f1dc4760cb258178d98--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f12f3062ad714eb1aa110f--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f12f27a7bb3e9f27ef8da7--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f12f37b1242dd9e6a27ef7--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f13037bae758db713293c6--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f12f357734314b91cc9443--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f12f37bbc94bc74b81c505--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

Commit 5ce025d · 2026-04-28 23:53 CEST

Package URL
effect-schema-form-aria https://69f12ba55213a192cca1449e--overeng-utils.netlify.app
Alias: https://effect-schema-form-aria-pr-638--overeng-utils.netlify.app
notion-cli https://69f12ba5a7bb3e9097ef8e68--overeng-utils.netlify.app
Alias: https://notion-cli-pr-638--overeng-utils.netlify.app
react-inspector https://69f12b8af0e5987f5ce2f47f--overeng-utils.netlify.app
Alias: https://react-inspector-pr-638--overeng-utils.netlify.app
tui-stories https://69f12b9eb1242dcfb5a27ebe--overeng-utils.netlify.app
Alias: https://tui-stories-pr-638--overeng-utils.netlify.app
tui-react https://69f12b947fa01099e8b4dd1d--overeng-utils.netlify.app
Alias: https://tui-react-pr-638--overeng-utils.netlify.app
genie https://69f12b7d94e6faa826f7e953--overeng-utils.netlify.app
Alias: https://genie-pr-638--overeng-utils.netlify.app
megarepo https://69f12b9e68ac98809b29f7de--overeng-utils.netlify.app
Alias: https://megarepo-pr-638--overeng-utils.netlify.app
effect-react https://69f12b75a7bb3e9006ef8ec8--overeng-utils.netlify.app
Alias: https://effect-react-pr-638--overeng-utils.netlify.app
notion-react https://69f12c37b1242dcfa4a27fc0--overeng-utils.netlify.app
Alias: https://notion-react-pr-638--overeng-utils.netlify.app

@schickling-assistant schickling-assistant force-pushed the schickling/2026-04-28-pnpm-gvs-content-health branch from 5ce025d to fbac966 Compare April 28, 2026 22:00
@schickling-assistant schickling-assistant force-pushed the schickling/2026-04-28-pnpm-gvs-content-health branch from fbac966 to be67553 Compare April 28, 2026 22:16
@schickling schickling merged commit 350d1b9 into main Apr 29, 2026
13 checks passed
@schickling schickling deleted the schickling/2026-04-28-pnpm-gvs-content-health branch April 29, 2026 07:39
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.

2 participants