feat(lint): '# lint: loaded-by' fragment directive — E003 context from the composer (#460)#463
Merged
Merged
Conversation
…m the composer (#460) A library fragment declares the file that composes it (load_file entry point or concat sibling); E003 collects that file's transitive binding set via the existing e003_load machinery and lints the fragment against it. Composed-in names stop flagging while a genuine typo still fires — the protection allow-file E003 abandons. Fail-open on unresolvable context, like every E003 edge. lint_collect gains a source param so the LSP passes the live document buffer (as-you-type directive edits take effect); the CLI already had source in hand. Verified on the real consumer corpus: DMG fragments 217 E003 -> 0 via 'loaded-by ../dmg.eigs'; EigenMiniSat lib/ 99 -> 0 via the minisat.eigs entry (trees untouched). Six fixtures in test_lint.sh cover fire, suppress, typo-retention, fail-open, and the no-loader concat case. Gates: release 2584/2584, ASan+UBSan detect_leaks=1 2584/2584, test_lsp.py 67/67, test_lsp_asan.sh clean. Closes #460 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 7, 2026
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 free
to 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.
Resolves the ~380 cross-module E003 false positives from the v0.27.0 consumer sweep — the main friction to consumers turning on a
--lintCI gate.The design decision
The issue offered three directions: a fragment declaration, an entry-points-only convention, or blessing mass
allow-fileheaders. The deciding factor:# lint: allow-file E003abandons undefined-name protection for the fragment; a declared composer keeps it. A fragment linted against its composer's binding set stops flagging composed-in names but still fires on a genuine typo — so the directive turns 380 FPs into 0 without giving up the pass's value. (The eigs.json per-file allow-list, #455, stays open as the contributor on-ramp; it's now the blunt fallback rather than the fragment answer.)Semantics
# lint: loaded-by <relpath>(conventionally the file header, repeatable):<relpath>like aload_filetarget from the fragment's directory and collects the named file's transitive binding set — its binders plus everything its literalload_files bind — via the existing, auditede003_loadmachinery (the feature is ~25 lines because of that reuse).--lintand the LSP:lint_collectgains asourceparam and the LSP passes the live document buffer, so the same fragments stop squiggling in editors too, and as-you-type edits to the directive take effect without a save.Verified on the real corpus (repos untouched)
loaded-by ../dmg.eigs)loaded-by ../minisat.eigs)Exactly the sweep's counts. Consumer rollout (adding the one-line headers) rides the next pin bump per repo.
Tests & docs
Gates
detect_leaks=1: 2584/2584Closes #460
🤖 Generated with Claude Code