You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filing unassigned, observation-class. Found while implementing #8020 (PR #8107) and deliberately not fixed there — that card's ruling scoped the PR to the template-literal form plus the two registry entries it mis-measured, and this is a latent trap with zero occurrences in the repo today, not a live defect. #8020 remains open until its PR lands.
The fact
PR #8107 taught asPath in scripts/check-test-source-alias.mjs to read the template-literal replacement form. The sibling spelling is still unreadable:
asPath falls through to the last-string-literal rule and answers /$1/index.ts — no srcsegment, so pointsAtSource() says no. That is byte-for-byte the #8020 failure mode: a config that aliases every namespace correctly reads to the gate as aliasing nothing, its package gets an over-stated registry entry, and a dev dispatched to remediate finds the alias already correct with the failure text prescribing the alias they already have.
Semantically the two spellings are indistinguishable — both exist to get the $1 back-reference inside the path, which the anchored one-rule-for-all-namespaces subpath alias requires. Only the JS surface differs.
So this is real but dormant. It becomes live the first time anyone writes a subpath alias with + instead of a template — and the symptom then is a red gate pointing at the wrong thing, which is exactly the round #8020 cost.
Options
A — teach asPath top-level +: split the expression on + outside strings/parens, resolve each operand by the existing rule, concatenate. Same shape as the template fix already merged, roughly the same size, and it closes the spelling axis rather than one point on it.
C — reject the spelling: fail loudly on a + in a replacement, prescribing the template form. Turns a silent over-statement into a loud, actionable message without an expression reader.
No recommendation attached — this is for triage, not graded by me. Worth noting that these two packages (plugin-audit, service-knowledge) have now defeated three separate readers of vitest aliases by three different parsing assumptions, so the "close the axis" argument for A has some evidence behind it.
Filing unassigned, observation-class. Found while implementing #8020 (PR #8107) and deliberately not fixed there — that card's ruling scoped the PR to the template-literal form plus the two registry entries it mis-measured, and this is a latent trap with zero occurrences in the repo today, not a live defect. #8020 remains open until its PR lands.
The fact
PR #8107 taught
asPathinscripts/check-test-source-alias.mjsto read the template-literal replacement form. The sibling spelling is still unreadable:asPathfalls through to the last-string-literal rule and answers/$1/index.ts— nosrcsegment, sopointsAtSource()says no. That is byte-for-byte the #8020 failure mode: a config that aliases every namespace correctly reads to the gate as aliasing nothing, its package gets an over-stated registry entry, and a dev dispatched to remediate finds the alias already correct with the failure text prescribing the alias they already have.Semantically the two spellings are indistinguishable — both exist to get the
$1back-reference inside the path, which the anchored one-rule-for-all-namespaces subpath alias requires. Only the JS surface differs.Why it is not urgent
grep -rn "replacement:" --include='vitest.config.*'overpackages/apps/examplesreturns 12 replacements in 15 alias-bearing configs — 10 plainpath.resolve(…)calls and 2 template literals. Zero+.So this is real but dormant. It becomes live the first time anyone writes a subpath alias with
+instead of a template — and the symptom then is a red gate pointing at the wrong thing, which is exactly the round #8020 cost.Options
asPathtop-level+: split the expression on+outside strings/parens, resolve each operand by the existing rule, concatenate. Same shape as the template fix already merged, roughly the same size, and it closes the spelling axis rather than one point on it.asPathheader under "Spellings that are legal here and still unreadable", so the next reader looks it up instead of rediscovering it. Costs nothing now; pays out only if someone reads the header before writing the config.+in a replacement, prescribing the template form. Turns a silent over-statement into a loud, actionable message without an expression reader.No recommendation attached — this is for triage, not graded by me. Worth noting that these two packages (
plugin-audit,service-knowledge) have now defeated three separate readers of vitest aliases by three different parsing assumptions, so the "close the axis" argument for A has some evidence behind it.Prior art (searched before filing)
vitest.config.tslets a stale@objectstack/coredist decide its verdicts — #7668 fixed one, nothing stops the next #7849 / PR ci(test-alias): gate that a unit test judges source, not a sibling's dist #7966 — the gate and its shrink-only registry. A package with unit tests and novitest.config.tslets a stale@objectstack/coredist decide its verdicts — #7668 fixed one, nothing stops the next #7849 remains open as the tracking anchor.attach-requires-parent-editc3: #4757 multi-delete pin can't execute against the prebuilt@objectstack/core(stale-dist / CI) #7668 / PR test(service-storage): resolve@objectstack/corefrom source so a stale dist can't decide a pin (#7668) #7778 — the anchored-regex constraint that forces the capture-group-inside-path shape in the first place.Generated by Claude Code