Skip to content

fix(scanner): stop dead-code flagging public API; deepen detection (Codex #10)#18

Merged
telivity-otaip merged 1 commit into
mainfrom
fix/dead-code-precision
Jun 18, 2026
Merged

fix(scanner): stop dead-code flagging public API; deepen detection (Codex #10)#18
telivity-otaip merged 1 commit into
mainfrom
fix/dead-code-precision

Conversation

@telivity-otaip

Copy link
Copy Markdown
Collaborator

Summary

Codex review finding #10 — dead-code analysis too shallow. The scanner flagged any export with no in-repo references as dead. But a package's public API lives in its entry point (index.* / __init__.py) and is consumed by code outside the repo, where the usage grep is blind — so the entire public API surface was reported as removable. Acting on those findings would break downstream consumers.

Changes

  • Entry-point exemption — symbols declared in barrel / package-root files are never flagged. New optional DeadCodeProfile.isEntryPoint(path); when a profile omits it, the scanner applies a convention default (index.ts|tsx|js|mjs|cjs|… and __init__.py) via the exported isEntryPointFile() helper.
  • Honest uncertainty — dead-code task descriptions now state the finding is grep-based reachability (not type-aware) and to confirm the symbol isn't reflectively used or part of an external API before removing. The category stays severity: low.
  • Recall fix — the TS export regex now also matches enum, abstract class, and async function declarations (previously silently missed).

Why not full type-graph analysis

True reachability needs a TS type graph (ts-morph / tsc --noUnusedLocals semantics) — a heavy dependency and slow per-scan. This keeps the detector deterministic and fast while removing its single biggest false-positive class (public API) and making the residual uncertainty explicit to whoever acts on the task.

Test plan

New scanner.test.ts cases:

  • exports in a public index.ts with no in-repo uses are not flagged
  • an unused export in a non-entry file is still flagged, and carries the heuristic caveat
  • isEntryPointFile table (index.* and __init__.py true; indexer.ts, my_init.py, plain source false)

Local validation: asil-improvement-loop 191 tests, build + typecheck clean.

…odex #10)

The dead-code scanner flagged any export with no in-repo references as dead.
But a package's public API lives in its entry point (index.* / __init__.py)
and is consumed by code OUTSIDE the repo, where the usage grep is blind — so
the whole API surface was reported as removable. That's the "shallow
analysis" weakness Codex #10 called out.

- Skip symbols declared in entry-point / barrel files. New optional
  `DeadCodeProfile.isEntryPoint(path)`; when a profile omits it the scanner
  applies a convention default (`index.ts|tsx|mjs|…` and `__init__.py`) via
  the exported `isEntryPointFile()` helper.
- Make the uncertainty explicit: dead-code task descriptions now state the
  finding is grep-based reachability (not type-aware) and to confirm the
  symbol isn't reflectively used or part of an external API before removing.
- Recall fix: the TS export regex now also matches `enum`, `abstract class`,
  and `async function` declarations (previously missed → silent gaps).

Adds tests: entry-point exports are never flagged, non-entry unused exports
are still flagged (now with the heuristic caveat), and an `isEntryPointFile`
classification table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@telivity-otaip telivity-otaip merged commit 26f9711 into main Jun 18, 2026
2 checks passed
@telivity-otaip telivity-otaip deleted the fix/dead-code-precision branch June 18, 2026 05:51
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.

1 participant