Issue sweep: precision fixes, why command, config, rev ranges, tap - #22
Merged
Conversation
class_declaration nodes had no scope_of entry, so refs inside field initializers (e.g. `x = compute();`) fell through to the enclosing current_def instead of the class def -- module-level code (from_def=0) when the class was top-level. Register the class node itself in scope_of; method bodies still resolve correctly since walk_refs re-checks scope_of at every node and method_definition's own (more specific) entry overrides the class-level one for nodes inside it.
build_known_names derived a package qualifier only from the raw import path's last segment, so `import foo "example.com/x/bar"` allow-listed "bar" instead of "foo" -- reads via the actual alias qualifier were silently dropped. collect_imports now also collects each import_spec's alias (its `name` field, when it's a genuine package_identifier rather than a blank/dot import) and threads it into build_known_names. ImportRef itself is left untouched since it's a shared cross-language type.
A deleted source file no longer forces RunAll unconditionally. Deleted files (indexed or not) are now routed through the same raw-import stem scan used for unrecognized changed files: any surviving importer whose raw import text still references the deleted path gets its ModuleInit seeded, since it will fail to resolve/compile. A deleted file with no remaining importer contributes zero seeds.
Unknown-by-short-name widening previously enqueued every Calls{Unknown(n)}
caller repo-wide, exploding selection on dense single-crate repos where a
common method name matches unrelated defs across the whole codebase.
Now an Unknown caller C only widens through to a visited def D when D's
file is in C's forward transitive import closure, or they share a file:
tier-1 resolution scope for a ref in C is C's file plus its direct
imports, so a def outside that reachable set could never have been C's
actual (unresolved) callee under our model.
Exposed two pre-existing indexer gaps the old repo-wide sweep was
papering over: Go same-package cross-file calls (no `import` needed
within a package) were never resolved to `Resolved` edges -- fixed by
extending a Go file's tier-1 scope to its package siblings. The Rust
fixture relying on a bare `crate::`-qualified call with no local `use`
was adjusted to use an explicit `use`, an equally idiomatic style, rather
than extending Rust's import model further.
Add `walk::impacted_tests_with_paths`, which records each def's first-discovery predecessor during the impact BFS so the shortest seed -> test hop path can be reconstructed for any selected test. `impacted_tests` becomes a thin wrapper that discards the paths, so all prior selection semantics and tests are unchanged. Wire this up as `testless why <test-id>`: runs the same analyze+walk pipeline as `select`, forgivingly substring-matches `test_id` against selected tests' `<file> :: <name chain>`, and prints the hop path (human text on a terminal, JSON when piped). Zero matches -> not selected (exit 1); multiple matches -> lists candidates (exit 1); run-all classification mirrors select/changes' exit-2 contract.
Adds an optional repo-root testless.toml escape hatch: `ignore` globs (globset) drop matching files at discovery time so they're never indexed; `always-run` globs are unioned into the selection post-walk, so a smoke test always runs even when the walk itself seeds nothing. A malformed testless.toml (bad TOML, invalid glob, wrong value type) is a hard error (exit 1) in every command that loads it, never a silent run_all degrade. `why` explains an always-run-only selection with a dedicated "selected by always-run glob '<glob>'" line/field instead of the ordinary hop path, since the walk never reached that test at all.
Materializes --to in a temporary git worktree (git worktree add --detach, removed on Drop) and runs the whole analysis pipeline rooted there, so --from/--to can name any two revisions instead of only --from vs. the live worktree. changed_files/show_file still run against the main repo (it has the objects); a bad/unfetched --to rev degrades to the existing run_all/exit-2 fallback, same as a bad --from.
- classify: a deleted Go file now seeds its surviving package siblings' ModuleInit directly and folds the package directory into the importer stem scan, since Go imports name directories, never file stems, and same-package files never reference each other by name (was under- selecting to empty). - analyze: filter `changed` by testless.toml's ignore globset before classify, so an ignored file's change contributes zero seeds instead of hitting classify's "missing from graph" path and forcing run_all. - gitio: TempWorktree dir gets a per-process pid suffix (fixes a real collision between concurrent runs against the same --to rev) and its doc comment's incorrect "collision-safe" claim is corrected. - classify: scan_importers requires a >=3 char stem for its substring match; a deleted+indexed file left with no usable stem escalates to RunAll (under-select forbidden) rather than a non-indexed file's short stem, which just yields no extra seeds (accepted, lower-stakes case).
This was referenced Jul 24, 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.
Summary
Fixes #11 #12 #13 #14 #15 #16 #17 #20.
testless why <test-id>explains selection paths;testless.tomlwith always-run and ignore globs;--to <rev>rev-range analysis via temp worktreesTest plan
176+ workspace tests green (all TDD, RED-verified regressions per issue), clippy/fmt clean, real-repo herdr numbers measured before/after.