fix(scanner): resolve four defects found by post-merge audits - #159
Merged
Conversation
runDepsMode passed the raw CLI root (e.g. ".") into the deps scan instead of absRoot. With a relative root and a degraded/absent ast-grep, buildCargoFallbackOutcome resolved each package's absolute manifest_path against that relative root, filepath.Rel errored, and every cargo-metadata package was silently dropped -- losing the recovered Rust edges and causing cargo metadata to run a second, redundant time during graph build. Pass absRoot at the call site, and absolutize root defensively at the top of scanForGraphOutcomeWithFilters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PEUvjGsJemDFSV8nbxvxBo
scanForGraphOutcomeWithFilters fed the Go fallback from ScanFiles, which -- unlike the ast-grep primary -- does not skip dot-prefixed directories or nested git repos (findNestedGitRepos exists precisely for that). With ast-grep unavailable, hidden dirs and nested repos contributed phantom Go analyses, inflating importers/hub flags beyond what the primary would report. buildGoFallbackOutcome now drops files under a dot-prefixed directory component or a nested-repo subtree before parsing them. Relates to #131 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PEUvjGsJemDFSV8nbxvxBo
`use super::{a, b};` inside an inline module (e.g. `#[cfg(test)] mod
tests { ... }`) is relative to that module, not the file, but
expansion treated it as file-relative and could resolve `super::x` to
an unrelated sibling file that happens to share x's name. Split
rust-use-imports into an outside-mod_item rule (unchanged behavior)
and an inside-mod_item variant whose handling drops self/super-rooted
paths instead of resolving them -- a missed edge beats a wrong one.
crate::-rooted paths mean the same thing everywhere and still resolve
inside inline modules.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUvjGsJemDFSV8nbxvxBo
(a) The imports-append exclusion list excluded askama, cargo-rerun,
and embedded-file kinds but not rust-use-imports, so raw brace-tree
text (e.g. crate::{a::one, b::two}) shipped verbatim in the versioned
imports array and fed --diff's basename matching as noise. Rust graph
edges come from References, which are unaffected.
(b) resolveRustBuildScriptInput and resolveRustAskamaTemplate used the
naive `len(idx.byExact[target]) != 1` shape, which drops a legitimate
target whenever a sibling shares its extension-stripped key (e.g.
data.json + data.json.gz). Both now use the exact-count idiom already
used by resolveRustInclude and resolveRustEmbeddedFile, preserving
each function's other guards.
Relates to #130
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PEUvjGsJemDFSV8nbxvxBo
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.
What does this PR do?
Fixes four verified defects found by adversarial post-merge audits of the #123/#124/#127/#141 batch. Each fix landed with a regression test first proven to fail on unmodified main.
main.go,scanner/cargofallback.go). With a relative root —codemap --deps ., the documented invocation — a degraded ast-grep scan silently dropped the entire Cargo recovery (filepath.Rel(".", <abs manifest>)errors reject every package), mislabeled cargo-metadataauthoritative, and rancargo metadatatwice. Relative and absolute roots now produce byte-identical output with honestfallbackprovenance and a single cargo run.scanner/cargofallback.go). The fallback fed itself fromScanFiles, which skips neither dot-directories nor nested git repos, so with ast-grep unavailable it reported phantom importers and flipped hub flags (160→312 files on this repo). The fallback now applies the primary's hidden-dir andfindNestedGitReposexclusions. Relates to scanner: nested git worktrees inside the repo are scanned as project files (5.5x file-count inflation) #131 (this covers the fallback half; the primary-walker aspect remains open).self/superuse-paths inside inline modules (scanner/sg-rules/rust.yml,scanner/astgrep.go,scanner/rustgraph.go).#[cfg(test)] mod tests { use super::{a, b}; }resolvedsuperagainst the file instead of the inline module, emitting false edges on name collisions (a file's ownfn configvs siblingconfig.rs). The rule now splits into outside/inside-mod_itemvariants; self/super-rooted paths inside inline modules resolve to nothing (crate-rooted paths still resolve). The combined rule set was validated against both ast-grep 0.45.1 and the bundled 0.42.1, and the new rule ID is wired through all three dispatch lists.rust-useraw-imports leak and standardize thebyExactuniqueness idiom (scanner/astgrep.go,scanner/rustbuildscript.go,scanner/rustgraph.go). Raw brace text likecrate::{a::one, b::two}no longer ships in the versionedimportsarray, andresolveRustBuildScriptInput/resolveRustAskamaTemplatenow use the exact-count idiom fromresolveRustInclude, so an extension-sibling (data.json.gz,template.html.orig) no longer blocks resolution of the real target. Relates to buildFileIndex: byExact double-indexing causes both phantom keys and unresolvable extension-less files #130 (the extensionless double-indexing itself stays with that issue).The fifth audit finding — cmd.exe quote-stripping breaking Windows shim scans for paths with spaces — is deliberately excluded: it needs Windows validation and its own PR.
Type of change
Checklist
go build && ./codemap .Additional notes
Each commit is one fix with its regression tests; CLI reproductions were verified before/after with built binaries (cargo-call-counting wrapper for fix 1, ast-grep hidden from PATH for fixes 1–2, real ast-grep end-to-end for fix 3).
go vet ./...clean; fullgo test ./...green apart from the three known root-environment permission tests.🤖 Generated with Claude Code
https://claude.ai/code/session_01PEUvjGsJemDFSV8nbxvxBo
Generated by Claude Code