Uh oh!
There was an error while loading. Please reload this page.
fix(scripts): print the measured specifiers in check-test-source-alias remediation - #8486
Merged
Merged
Conversation
…s remediation (#8256) The unaliased-dependency diagnostic named the bare dependency and printed one anchored-BARE alias entry for `deps[0]`. That is right for a package imported bare and a dead end for one whose reachable specifiers are all subpaths: `/^@objectstack\/spec$/` matches none of the specifiers the same message had just named, so applying the printed fix leaves the gate red with the message unchanged and no further guidance. The gate already knows the specifiers — that is how it decided the package was unaliased — so they are now carried through the scan and printed, each with where it lands today (no entry matched, or an entry that lands on `dist/`), plus one anchored entry per specifier. The replacement side cannot be a template either: `@objectstack/spec` serves every namespace from a directory while `@objectstack/platform-objects` maps `./plugin` to a file, so a single capture rule is right for one and wrong for the other — and wrong on whoever next writes that import. Each target is therefore measured against the tree, and printed as unmeasured when nothing under the dependency's `src/` answers to it. A subpath importer is also warned off the object form, which passes this gate by prefix-matching and then dies with ENOTDIR at run time. Output only: no input changes which packages the gate accepts or rejects. `--list` is byte-for-byte identical before and after (61 entries), and the full-repo run is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqe56GnYFddggeAyfkZFVz
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
qq9340100
marked this pull request as ready for review
August 13, 2026 16:01
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#8256
check-test-source-aliasnames an unaliased dependency and then tells you how to repair it. What itprinted was the dependency's bare name and one anchored-bare alias entry for
deps[0].That is right for a package imported bare, and a dead end for one whose test-reachable specifiers are
all subpaths. Measured on
origin/main,packages/formulareaches three specifiers —@objectstack/spec,@objectstack/spec/api,@objectstack/spec/data— and the printed rule/^@objectstack\/spec$/covers exactly one of them. Apply it verbatim and the gate is still red,reprinting the same message with no further guidance. The worse half: the obvious next guess is the
object form, which makes this gate pass while matching by PREFIX and then dying with
ENOTDIRatrun time (the trap recorded in #7778).
What it prints now
The gate already knew the specifiers — that is how it decided the package was unaliased — so they are
carried through the scan instead of being reduced to the dependency's bare name. Real output for
packages/formula, from this branch:The object-form warning is emitted only when a subpath specifier was measured — a package imported
bare cannot hit prefix-matching, and warning it anyway is how a diagnostic becomes noise. A bare
importer keeps exactly the anchored-bare entry that was always right for it.
The replacement side cannot be a template either
The card rules out answering with a different one-size rule, and the repo proves why. Both of these
now come out of the same block, measured per specifier against the tree:
That matches the package's real
exportsmap, where./pluginis a file (dist/plugin.js) and./audita directory (dist/audit/index.js). A capture rule deriving the path from the specifiergets one of those two wrong — and fails on whoever next writes that import, not on the author of the
rule. Targets are therefore resolved with the same file-then-
index.*candidate list the walk alreadyuses, and a specifier with no counterpart under the dependency's
src/prints an explicit unmeasuredplaceholder rather than an invented path.
Output only — the verdict is untouched
Nothing here changes which inputs the gate accepts or rejects.
--listis byte-for-byte identical before and after (63 lines, 61 registry entries,diffclean).OK — 72 packages with tests scanned; 61 registered as still resolving a workspace dep through dist/.KNOWN_UNALIASED_TEST_IMPORTSis untouched, and novitest.config.*was read for anything but input.Mutation testing
Five deliberate breaks, each direction predicted in writing before running, each caught by a named
assertion:
deps[0]template)offending.length >= 0)The capture-rule break is the card's counterexample reproduced mechanically: it left the
directory-served subpath assertion green while breaking the file-served one — right for one
package, wrong for the other, exactly as predicted. The last break confirms the verdict path is still
guarded after the internal
anyUnaliasedflag became a list.New fixture
packages/subpath-onlycarries all three remediation shapes in one importer that writesno bare specifier at all: a subpath served by a file, one served by a directory, and one with no
counterpart under
src/.Known tradeoff
The block is now one ledger line and one alias entry per specifier, uncapped. For the worst case in
the repo (
packages/cli, 27 unaliased dependencies) that is 96 lines instead of 8. No cap was addeddeliberately: every line is a specifier the reader has to alias, a cap would hide exactly the data the
card asked to surface, and this branch of the diagnostic only fires for an unregistered package —
never in normal operation.
Verification
node scripts/check-test-source-alias.mjs --self-test— OKnode scripts/check-test-source-alias.mjs(full repo) — OK, verdict unchangedpnpm check:nul-bytes— OK (7642 files, no raw control bytes); plus a targeted control-characterself-scan of the changed file
npx eslint scripts/check-test-source-alias.mjs— cleannode scripts/pm/dispatch-gates.mjs scripts/check-test-source-alias.mjsre-derived against theactual changed path: no path-scoped family, no delta from the dispatch list
Scripts-only, no user-visible surface ⇒
skip-changeset.Generated by Claude Code
Generated by Claude Code