Skip to content

fix(samples): de-overfit no_implicit_null_initial (inflector false positive) - #32

Closed
aspala wants to merge 1 commit into
fix/sample-overfitting-false-positivesfrom
fix/inflector-null-initial-false-positive
Closed

fix(samples): de-overfit no_implicit_null_initial (inflector false positive)#32
aspala wants to merge 1 commit into
fix/sample-overfitting-false-positivesfrom
fix/inflector-null-initial-false-positive

Conversation

@aspala

@aspala aspala commented Jun 3, 2026

Copy link
Copy Markdown
Member

Problem

PR #30's action comment flagged lib/codeqa/metrics/file/inflector.ex:32-45 — the detect_casing/1 function, a pure cond-dispatch with regex guards — as a CRITICAL no_implicit_null_initial block. There is no nil-then-assign anywhere in it.

Unlike the file-invariant phantoms fixed in #31 (every block of a file getting the same delta), this was a genuine per-block outlier — the relative-delta floor from #31 correctly let it through because it does stand out. The real cause is upstream.

Root cause

Same overfitting as #31: the no_implicit_null_initial behavior had one good/bad sample pair but a ~105-dimension scalar vector. Learned from a single data point, the vector encodes the quirks of that one file and matches dense cond/case blocks by chance.

Fix

Added 3 good/bad Elixir sample pairs (pricing, session, router), each contrasting:

  • bad: x = nil then if … do x = … end across branches
  • good: direct assignment via case / with / function results

Relearned the scalar vector via sample_report --apply-scalars (457 written, 148 deadzoned). No engine code changed — consistent with the de-overfit approach.

Result

  • inflector.ex no_implicit_null_initial finding: 0
  • Sanity-checked: the behavior still separates cleanly — its bad/loader.ex sample anti-aligns, good/loader.ex does not. No real detections lost (this codebase has no genuine nil-init-then-assign, which is idiomatic-Elixir-untypical).

884 tests, credo --strict clean.

Stacked on #31 (base fix/sample-overfitting-false-positives).

PR #30's action comment flagged inflector.ex detect_casing/1 (a pure
cond-dispatch with no nil-initialization) as a CRITICAL
no_implicit_null_initial block. Unlike the file-invariant phantoms fixed
in #31, this was a genuine per-block outlier — caused by the same
overfitting root cause: the behavior had ONE good/bad sample pair but a
~105-dimension scalar vector, so it matched dense cond/case blocks by
chance.

Added 3 good/bad Elixir sample pairs (pricing, session, router), each
contrasting nil-init-then-branch (bad) against direct assignment via
case/with/function results (good), and relearned the scalar vector via
sample_report --apply-scalars (457 written, 148 deadzoned).

Result: inflector.ex no_implicit_null_initial finding 0; the behavior
still separates its samples cleanly (bad anti-aligns, good does not), so
no real detections were lost.

884 tests, credo --strict clean.
aspala added a commit that referenced this pull request Jun 3, 2026
* fix(health-report): suppress false-positive per-block findings

Combines the work from PRs #31 and #32 (their stacked base branch was
squash-merged into main as #30, which orphaned them).

Two false-positive classes from the action's own PR comment, both fixed:

1. File-invariant per-block phantoms: every block in health_report.ex
   got identical deltas (negated_boolean_name, single_responsibility,
   name_is_abbreviation) regardless of content. Root cause: leave-one-out
   cosine barely moves when a small block is removed from a large file,
   so each block inherited the file-level delta. Fix in TopBlocks:
   subtract the per-behavior file floor (min block delta, only when a
   file has >= 3 blocks) and dedupe exact-duplicate line ranges.

2. Overfit behaviors: negated_boolean_name, name_is_abbreviation,
   single_responsibility and no_implicit_null_initial each had 1-3 sample
   pairs but 70-105 scalar dimensions, matching unrelated code by chance.
   Added good/bad Elixir sample pairs and relearned the vectors via
   sample_report --apply-scalars. Separation ratios improved; behaviors
   still detect their own samples cleanly.

Result on this codebase: health_report.ex critical blocks 10 -> 0,
inflector.ex no_implicit_null_initial -> 0, all four phantom behaviors
0. Remaining block findings are real (line_length).

884 tests, dialyzer clean, credo --strict clean.

* chore(combined-metrics): sync language coverage and scalar vectors [skip ci]

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@aspala

aspala commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

Superseded by #35, which re-lands the #31+#32 content directly on main (the stacked base chore/num42-refactors-scout was squash-merged via #30, orphaning these). All changes are now in main.

@aspala aspala closed this Jun 3, 2026
@aspala
aspala deleted the fix/inflector-null-initial-false-positive branch June 3, 2026 22:15
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