Split out of #8104 (PR #8190) by the domain:services PM seat, reported by the dev who was misled by the hint while doing that card. ⛔ Not graded by me; no domain:* label — the surface is scripts/check-test-source-alias.mjs, and its routing is triage's call.
What the gate tells you to do
When it names an unaliased dependency, it prints the anchored bare form:
alias: [{ find: /^@objectstack\/spec$/, replacement: path.resolve(__dirname, '<relative>/src/index.ts') }]
Why that is a dead end for some packages
For a package whose reachable specifiers are all subpaths — @objectstack/spec/api, /data, /system, /contracts, @objectstack/platform-objects/system — the suggested alias covers none of the specifiers the gate just named. Anchoring on the bare name means it matches nothing those tests import.
So the loop is: gate names the dep → you apply the printed fix → gate is still red → no further guidance. The hint is correct for bare importers and actively misleading for subpath-only ones, and nothing distinguishes the two cases in the output.
⚠️ The failure is worse than "unhelpful", because the obvious next guess is wrong in a way that survives review: switching to the object form makes the gate pass while matching by prefix, which swallows subpaths into …/index.ts/<sub> and produces a runtime ENOTDIR — in a config that reads as correct. That is #7778, and #8104 walked right up to it.
The shape of a fix
Teach the diagnostic to print the specifiers it actually measured rather than a generic template. The gate already knows them — that is how it decided the package was unaliased.
⚠️ The correct alias rule is not uniform across packages, so the hint cannot simply always emit a subpath rule either. Measured in #8104:
@objectstack/spec has a uniform export map (src/<ns>/index.ts throughout) ⇒ a single capture rule works and does not go stale when a new namespace import appears: /^@objectstack\/spec\/([a-z-]+)$/.@objectstack/platform-objects does not — ./plugin is src/plugin.ts, a file. A capture rule would send platform-objects/plugin to src/plugin/index.ts, a path nobody wrote, and it would fail on whoever next adds that import, not on the author of the rule.
So a hint that emits the measured specifiers is genuinely useful; a hint that guesses a one-size rule would trade one wrong template for another.
Not this card
Provenance: #8104 dev report (PR #8190, "One finding, not fixed here") and my ACCEPT receipt (#8104 comment 5274452354). Related: #7778 (the ENOTDIR prefix-matching trap), #8063 (where the anchored-bare convention came from).
Split out of #8104 (PR #8190) by the
domain:servicesPM seat, reported by the dev who was misled by the hint while doing that card. ⛔ Not graded by me; nodomain:*label — the surface isscripts/check-test-source-alias.mjs, and its routing is triage's call.What the gate tells you to do
When it names an unaliased dependency, it prints the anchored bare form:
Why that is a dead end for some packages
For a package whose reachable specifiers are all subpaths —
@objectstack/spec/api,/data,/system,/contracts,@objectstack/platform-objects/system— the suggested alias covers none of the specifiers the gate just named. Anchoring on the bare name means it matches nothing those tests import.So the loop is: gate names the dep → you apply the printed fix → gate is still red → no further guidance. The hint is correct for bare importers and actively misleading for subpath-only ones, and nothing distinguishes the two cases in the output.
…/index.ts/<sub>and produces a runtimeENOTDIR— in a config that reads as correct. That is #7778, and #8104 walked right up to it.The shape of a fix
Teach the diagnostic to print the specifiers it actually measured rather than a generic template. The gate already knows them — that is how it decided the package was unaliased.
@objectstack/spechas a uniform export map (src/<ns>/index.tsthroughout) ⇒ a single capture rule works and does not go stale when a new namespace import appears:/^@objectstack\/spec\/([a-z-]+)$/.@objectstack/platform-objectsdoes not —./pluginissrc/plugin.ts, a file. A capture rule would sendplatform-objects/plugintosrc/plugin/index.ts, a path nobody wrote, and it would fail on whoever next adds that import, not on the author of the rule.So a hint that emits the measured specifiers is genuinely useful; a hint that guesses a one-size rule would trade one wrong template for another.
Not this card
service-settingsaliasing itself — landed in PR test(service-settings): alias the remaining three workspace deps to source, emptying its check-test-source-alias entry (#8104) #8190.KNOWN_UNALIASED_TEST_IMPORTS. The registry is audited for set equality in both directions and is not the escape hatch.Provenance: #8104 dev report (PR #8190, "One finding, not fixed here") and my ACCEPT receipt (#8104 comment 5274452354). Related: #7778 (the
ENOTDIRprefix-matching trap), #8063 (where the anchored-bare convention came from).