Skip to content

v1.108.315 — A fix for a false positive can install a false negative

Latest

Choose a tag to compare

@jgravelle jgravelle released this 02 Sep 03:37
· 4 commits to main since this release

find_dead_code's confidence: 1.0 is documented as provably unreachable. That is a claim about the tree, and it was computed from the index with nothing in between. Closes #566 and #569.

Runtime-discovered packages (#569)

encoding/schemas/ is enumerated by pkgutil.iter_modules(__path__) at import time — an edge no static import graph can see — so twelve live encoders were published at confidence 1.0. Which three of the fifteen escaped depended only on whether a test happened to import the module directly. search_symbols.py and search_text.py have the same role, the same shape and the same load path, and one was called dead. The signal was test-authoring habit.

A package that enumerates itself now makes its modules live roots. walk_packages extends that to subpackages; iter_modules deliberately does not. Where the enumerated directory cannot be resolved, the loader is reported and caps the confidence instead.

Corpus adequacy (#566)

A stale index and a too_large file that the size cap withheld each published live files as proven dead — the second because the withheld file's imports vanish with it. search_text handled the identical situation correctly on the identical index in the same session: absence_refused: true, complete: false, naming coverage.generation.git_head.

find_dead_code now reads those same disclosures and caps confidence at 0.6, below the 0.8 default, so the default call refuses rather than asserting. signal_warning names the cause; uncapped_confidence and confidence_capped_by ride on every clamped row.

unknown caps; not applicable does not. An index_repo snapshot has no local tree to compare against and is complete by construction, so it keeps its proof.

check_delete_safe, the destructive surface

Its "no refs at all" fallback reaches safe_to_delete regardless of the dead-code confidence it had just consulted, then floors that verdict at 0.85 — so capping the report alone still certified deletes over a corpus that could not support one. It now answers corpus_inadequate: classified, never terminal, with re-indexing named as the gap. Only absence verdicts are replaced; a found importer is positive evidence a thin corpus cannot unfind.

Also

get_dead_code_v2 shares the runtime roots — its signal 1 is the same import graph. Measured on this repo: files reported under src/ went 15 → 2, and those at confidence 1.0 went 12 → 0.


Suite 9135 passed / 13 skipped / 0 failed; ruff check src/ clean; CI-environment reproduce 9129 passed / 19 skipped, same 9148 total.