Skip to content

fix(baseline): key fallow member/component findings by <parent>.<member>#3

Open
robmclarty-minga wants to merge 1 commit into
robmclarty:mainfrom
robmclarty-minga:fix/dead-member-fingerprint-identity
Open

fix(baseline): key fallow member/component findings by <parent>.<member>#3
robmclarty-minga wants to merge 1 commit into
robmclarty:mainfrom
robmclarty-minga:fix/dead-member-fingerprint-identity

Conversation

@robmclarty-minga

Copy link
Copy Markdown

Problem

The dead fingerprint extractor keys a finding on <file>:<symbol>, where the
symbol comes from the first non-empty field in SYMBOL_FIELDS
(export_name, name, member, …). But fallow reports class/enum members
with parent_name + member_name, and component inputs/outputs with
component_name + input_name/output_name — none of which are in that list.
So every unused member of a file falls back to a path-only key and they all
collapse onto one fingerprint.

That collapse breaks gating, not just precision. fallowVerdict only masks a
slot green when findings.size === issueCount (the fullyTracked guard). A
member-heavy report fingerprints to far fewer keys than its issue count, so the
guard treats it as untracked and the baseline can never mask it green.

On a real 7,970-finding repo:

Extractor Unique fingerprints vs total_issues
before 3,148 −4,822
after 7,949 −21

Fix

  • Compose a member identity <container>.<leaf> from
    parent_name.member_name / component_name.input_name /
    component_name.output_name, before falling back to the single-symbol
    fields. Members in a file are now distinct, e.g.
    dead-code:unused_class_members:src/a.ts:Svc.foo.
  • Stop fingerprinting the workspace_diagnostics and next_steps arrays.
    Neither is counted in total_issues, and workspace_diagnostics items carry
    a path, so fingerprinting them pushed findings.size past issueCount
    which the fullyTracked guard also (correctly) rejects, wrongly marking an
    otherwise fully-tracked slot untracked.

Scope / honest limitation

This does not guarantee fullyTracked for every large report. Distinct
findings that share a line-free identity — overloaded members, a symbol
re-exported or imported twice in one file — still legitimately collapse (the
residual −21 above). That's inherent to fingerprints that deliberately exclude
line/column. For grandfathering a large legacy dead slot, fallow's native
per-category regression baseline remains the right tool; this change makes the
fingerprint baseline correct and precise for the common member/component case
and lets member-level fixes ratchet individually.

Verification

  • pnpm exec vitest run — 427 passing, incl. 3 new fallow cases
    (member composition, component composition, workspace_diagnostics skipped).
  • tsc --build clean.
  • Ran the built extractor against the real report above to confirm 3,148 → 7,949.
  • node dist/cli.js (self-gate) green except the pack slot, which fails
    identically on pristine main in my environment (local pnpm version; a direct
    pnpm pack --dry-run exits 0) — unrelated to this change.

fallow reports unused class/enum members and component inputs/outputs with
parent_name/member_name (and component_name/input_name/output_name) rather than
a single symbol field, so the dead-code extractor fell back to the file path and
collapsed every unused member of a file onto one fingerprint key. A member-heavy
report then fingerprinted to far fewer keys than its issue count, which the
fullyTracked guard treats as untracked, so the baseline could never mask the
slot green. Compose the identity as <parent>.<member> so each member is distinct
(on a real 7,970-finding repo the fingerprint count rises from 3,148 to 7,949).

Distinct findings that share a line-free identity (overloaded members, a symbol
re-exported or imported twice in one file) still legitimately collapse, so a
large legacy dead slot can remain untracked; fallow's native regression baseline
stays the tool for grandfathering those.

Also stop fingerprinting the non-counted workspace_diagnostics and next_steps
arrays: neither is in total_issues, and workspace_diagnostics items carry a
path, so fingerprinting them pushed the finding count past the issue count and
could wrongly mark an otherwise fully-tracked slot as untracked.
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