Uh oh!
There was an error while loading. Please reload this page.
fix(devx): extend check:test-source-alias past the package boundary into deps it aliases to source - #8392
Merged
Conversation
…nto deps it aliases to source Aliasing a workspace dep to source imports that dep's entire import surface into the consumer's resolution domain. The gate's reachability walk stopped at the package boundary — one hop short of the domain it certifies — so a specifier the consumer's alias list demonstrably mangles was never checked. That gap shipped: #7378 added one runtime import of `@objectstack/spec/shared` inside `packages/core/src`, this gate was green, and CI went red in plugin-hono-server (16 test files) and driver-memory (23) with rule 5's own ENOTDIR signature, for a specifier written in no file of either package. The walk now follows an alias into the dep's source and keeps going, exactly as far as the alias chain reaches. Collected specifiers are judged by rule 5 only; the set-equality-audited KNOWN_UNALIASED_TEST_IMPORTS ledger is deliberately untouched by the crossing. Also strips comments before reading imports. Crossing the boundary made this load-bearing: a JSDoc fence in packages/spec/src/index.ts demonstrating subpath imports was read as code and invented ENOTDIR findings against nine configs. That fix also removes a phantom `@objectstack/core` from service-cache's registry entry, narrowing it to its true measured state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqe56GnYFddggeAyfkZFVz
… walk Crossing the boundary walks the same dependency source once per consuming config (nine alias @objectstack/core). Reading and comment-stripping a file are pure functions of it, so memoize per scan. Full-scan: ~8.5s -> ~5.1s against a ~1.6s baseline. Cleared per scan, not per process: --self-test rewrites fixture files between check() calls to exercise registry drift. Co-Authored-By: Claude Fable 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
|
This was referenced Aug 13, 2026
This was referenced Aug 13, 2026
qq9340100
marked this pull request as ready for review
August 13, 2026 13:21
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#8351
Aliasing a workspace dep to source imports that dep's entire import surface into the consumer's resolution domain. The gate's reachability walk stopped at the package boundary — one hop short of the domain it certifies — so a specifier the consumer's alias list demonstrably mangles was never checked statically.
That gap shipped: #7378 added one runtime import of
@objectstack/spec/sharedinsidepackages/core/src, this gate was green on the diff, and CI then went red inplugin-hono-server(16 test files dead at load) anddriver-memory(23) with rule 5's own ENOTDIR signature — for a specifier written in no file of either package.What changed
KNOWN_UNALIASED_TEST_IMPORTSledger is deliberately untouched by the crossing. Rule 5 is a correctness verdict on the alias list the config already wrote; the ledger is a coverage measurement. Feeding transitive surface into the ledger would silently re-scope and re-measure all 60+ entries as a side effect of a walk change. The header states this boundary and its consequences explicitly, so the unmeasured half is not rediscovered as a bug.packages/spec/src/index.tsdemonstrating subpath import styles was read as code and invented ENOTDIR findings against nine configs for a specifier nobody imports. This also removed a phantom@objectstack/corefromservice-cache's registry entry (a JSDoc usage example), narrowing it to its true measured state — a shrink the both-directions audit demanded, not a widening.@objectstack/core, so the same dependency source was being walked once per consumer.Verification
--self-testgains fixtures reproducing the #8349 miss shape: an aliased-to-src dep whose OWN subpath import is prefix-swallowed, reached through a relative hop inside that dep (the real incident's shape), plus a two-hop chain, a correctly-ordered negative control, an unaliased-dep control, and a JSDoc-only specifier.Per the lane rule, the self-test was mutation-tested — it passed first try, so each new assertion was proven non-empty by breaking the logic eight distinct ways. Every break was caught by its intended named assertion and only that one: crossing removed entirely; crossing limited to one hop; crossing not gated on being aliased-to-source; cross-boundary findings leaked into the ledger; comment stripping removed; provenance dropped from the diagnostic; the through-a-file test skipped; and the cache outliving a scan.
Runtime, full scan, three runs each: ~1.6s before, ~8.5s with the crossing and no cache, ~5.1s with it. The residue is comment stripping (~3.0s), not the crossing (~0.5s).
Not green on its own
The sharpened gate reports seven true findings across six configs missing a
@objectstack/spec/qa(and/api) entry reached through their@objectstack/corealias. Those are latent rather than currently-red — everyQA.use incore/src/qa/is a type position, so esbuild elides the import — but the alias really is missing. Remediation is one line per config and is outside this card's declared file surface (gate script only); it is filed separately as #8391, per this gate's own doctrine that remediation lands as its own card. Blocked by #8391 for a green CI run.Scripts-only, so
skip-changeset.Generated by Claude Code