Record a digest of every workspace package's bin declarations in the
repeat-install state so a changed `bin` field relinks the current bins
on the next install, even with --frozen-lockfile and an unchanged
lockfile.
The state used to record each project's name and version but not its
bins, so the frozen-tree gate, the optimistic freshness check, and the
dependency-status check all read a workspace whose only change was a
bin declaration as up to date. The digest covers the whole workspace
and is recorded under the importer id of every project that links
workspace bins (the root and every project with dependencies). A
coarse digest keeps the check independent of the dependency graph; it
changes only when a declaration changes, at the cost of one extra
install for a filtered project whose own bins did not move.
A filtered install vouches only for the projects it installs and
carries the previous records for the others, so a later install that
covers them still relinks. A state without a validation record proves
nothing about any project and defers to the existing timestamp
fallback instead of reading as a mismatch, which would otherwise put
every workspace with bins on the slow path on every run. The
held-projects check returns before hashing the workspace when nothing
is held.
Both CLIs hash the declarations the same way, pinned by paired unit
tests, with e2e coverage for the isolated and hoisted linkers in each.
Removing shims of bins no longer declared is pre-existing behavior on
both CLIs, including with --force, and is tracked in
https://github.com/pnpm/tasks/issues/211.
Closespnpm/pnpm#17324.
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>