Skip to content

Make TypeScript extraction see through barrels, aliases, and typed receivers - #27

Merged
Phoenixrr2113 merged 2 commits into
mainfrom
fix/batch-three-ts-extraction
Aug 21, 2026
Merged

Phoenixrr2113 merged 2 commits into
mainfrom
fix/batch-three-ts-extraction

Conversation

@Phoenixrr2113

Copy link
Copy Markdown
Owner

What this fixes

Batch three, wave one of the pre-launch audit: TypeScript extraction fidelity. Three structural blind spots that made the graph miss or misattribute relationships in ordinary code.

TypeRef identity

A type reference was keyed on the file that mentioned it, so every importing file created its own disconnected TypeRef node and cross-file type aggregation was structurally impossible. Identity is now the declaring file plus the declared name: direct imports, renamed imports (import { User as U }), type-only imports, and imports routed through barrels all converge on one node.

Receiver-typed calls

const s = new Service(); s.work() produced no CALLS edge because resolution only understood bare identifiers. A per-file binding table now tracks constructor assignments and typed declarations, and method edges are class-qualified through HAS_METHOD so two classes sharing a method name cannot cross-contaminate. Ambiguous bindings are dropped rather than guessed. This also exposed and fixed a latent ordering bug: all three graph write paths created CALLS edges before the HAS_METHOD edges they need existed.

Barrel files

Re-exports (export * from, export { y } from) were never parsed, so importing through an index.ts barrel silently dropped call edges. The pipeline now follows re-export chains to the origin with alias rewriting at every hop, a local-declaration base case (a barrel's own exported functions resolve to the barrel), correct handling of multiple export-star statements in one file, and per-path cycle guards with a global attempt bound so adversarial barrel graphs terminate instead of hanging. File-to-File IMPORTS edges still point at the barrel, which is the truthful import relationship.

Review process

Three adversarial review rounds ran live-index attacks against ephemeral databases. Round one found five blockers in code that passed CI; round two confirmed them fixed and found a sixth (multi-star barrels only following the first star); round three verified the fix plus stress probes: a diamond-shaped barrel graph and a 47-file star fan-out with the target buried in the last leaf, resolved correctly in 60ms.

Verification

  • pnpm turbo build 21/21, pnpm turbo test 33/33, pnpm release:check passes with packaging smoke.
  • Test counts: core 232 (was 201), plugin-typescript 106 (was 94), graph 77 (was 72).

Known gaps deliberately not in this PR (ledger)

  • Default exports re-exported through barrels are dropped (fails safe, no wrong edge).
  • Namespace-qualified type usage (T.User) does not converge with the origin type node.
  • Methods inherited from a base class are not resolved for subclass-typed receivers (dropped, not misattributed).
  • The pre-existing zombie-node hazard (symbols keyed on line numbers) is unchanged; new cross-file edges raise its blast radius, which strengthens the case for the node-identity batch.
  • Barrel-aware type resolution runs a second extraction pass per file; deliberate cost, noted for a future restructure.
  • Single-file incremental reindex does not resolve barrel chains (no sibling context); documented limitation.

🤖 Generated with Claude Code

…ceivers

TypeRef identity: a type reference now keys on the file where the type
is declared and its declared name, not the referencing file and local
alias. Two files importing the same interface, directly, renamed, or
through a barrel, converge on one TypeRef node, so cross-file
USES_TYPE, HAS_PARAM, and RETURNS aggregation works for the first time.

Receiver-typed calls: a per-file binding table tracks const x = new
Service() and typed declarations, so s.work() produces a CALLS edge to
the right class's method. Edges are class-qualified through HAS_METHOD
in the graph so two classes sharing a method name in one file cannot
cross-contaminate, and ambiguous bindings are dropped, never guessed.
Fixed a latent ordering bug this exposed: all three write paths created
CALLS edges before HAS_METHOD edges existed.

Barrels: export-star and named re-exports are now extracted, and a
pipeline resolution pass follows chains to the origin with alias
rewriting at every hop, a local-declaration base case so mixed barrels
resolve their own exports, and per-path cycle guards with a global
attempt bound. Multi-star barrels try every star in declaration order
instead of only the first. The indexer builds the barrel index in a
pre-pass whose hint regex tolerates comments, and collects local
exports for every TypeScript file since chains can land anywhere.
File-to-File IMPORTS edges still point at the barrel, which is the
truthful import relationship.

Three adversarial review rounds drove eleven defects out of this work
before merge, verified by live-index attacks kept in the review
scripts, including a diamond-shaped barrel graph and a 47-file star
fan-out that terminates in 60ms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
v0-landing-page-build Skipped Skipped Aug 21, 2026 2:43pm

Comment thread packages/core/src/indexer.ts Fixed
Comment thread packages/core/src/indexer.ts Fixed
CodeQL flagged the comment-tolerant hint regex with two high-severity
ReDoS alerts, and they were real: the old pattern hung past a 5-second
kill on 'export' followed by 50k comment markers, and it ran against
the full content of every indexed TypeScript file. The hint is now a
hand-rolled forward-only scanner with identical semantics (whitespace,
line comments, and block comments allowed between export and the star
or brace) and the two attack shapes are pinned as timing tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Phoenixrr2113
Phoenixrr2113 merged commit 27f6b61 into main Aug 21, 2026
12 checks passed
@Phoenixrr2113
Phoenixrr2113 deleted the fix/batch-three-ts-extraction branch August 21, 2026 14:49

This branch was previously deployed

1 inactive deployment
Preview — bcf418eb Deployed Aug 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants