Sdlc/Structural/FeatureEnvy: carve out core-type receivers; remove the config Exclude list #1354

Open
opened 2026-10-25 21:22:56 +00:00 by jared · 0 comments
Owner

Problem

The cop Sdlc/Structural/FeatureEnvy flags a def whose one lvar receives three or more distinct messages.
Its fix ("Belongs on ; move it there or extract", feature_envy.rb:14) is impossible when the receiver is a core type.
The cop also relies on a config Exclude list of 14 cop files (plugins/os-sdlc/.rubocop.yml:342-357), which is itself a standard failure.

Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md).

Observed

Counterexamples, receivers that cannot take the method:

  • value is nil or String: plugins/cc-architect/scripts/plugin_config/operations/validate.rb:49
  • name is a String: plugins/os-backlog/lib/backlog/labels.rb:11
  • stack is an Array: plugins/os-aidd-lint/lib/aidd_lint/fence_mask.rb:30
    The cop has 55 hits; most are primitive or core-type params.

Reproduce

n/a: matcher is plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/site.rb; run the cop on the files above.

Approach

Carve-outs go in the cop matcher, never in a config Exclude list or a test-path exclusion.
Skip when the envied lvar receives core-type messages only (nil?, is_a?, to_s, strip, empty?, push, pop, last, include?), or when it is reassigned from .to_s or Array().
Delete the 14-file Exclude at plugins/os-sdlc/.rubocop.yml:342-357, and fix or carve out those files by shape.

Required work:

  1. Add the core-type carve-out to the matcher — check: present strip in plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/*.rb
  2. Delete the FeatureEnvy Exclude list — check: absent Sdlc/Structural/FeatureEnvy in plugins/os-sdlc/.rubocop.yml

Acceptance criteria

  1. Given an lvar that receives only strip, empty?, and to_s, when the cop runs, then it reports no offense.
  2. Given the repo config, when the cop runs, then no Exclude list names the cop.
  3. Given a def whose lvar receives three domain messages of a project class, when the cop runs, then it reports an offense.

Origin

  • Trigger: #1325 zero-false-positive audit of the Sdlc cops
  • Improvised this session: none
  • Chain: false positive and config Exclude ← matcher ignores receiver type ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/feature_envy.rb)
  • Root candidate: #226 (Burn down FeatureEnvy Exclude list; covers only the Exclude list, not the core-type receiver fault)
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/site.rb
  • Session: eb98cdcd-6783-46a0-b7df-cf18a8fe2a56
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-1325/eb98cdcd-6783-46a0-b7df-cf18a8fe2a56.jsonl
    VERDICT: CREATE
## Problem The cop `Sdlc/Structural/FeatureEnvy` flags a def whose one lvar receives three or more distinct messages. Its fix ("Belongs on <Camelized lvar>; move it there or extract", `feature_envy.rb:14`) is impossible when the receiver is a core type. The cop also relies on a config Exclude list of 14 cop files (`plugins/os-sdlc/.rubocop.yml:342-357`), which is itself a standard failure. Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md). ## Observed Counterexamples, receivers that cannot take the method: - `value` is nil or String: `plugins/cc-architect/scripts/plugin_config/operations/validate.rb:49` - `name` is a String: `plugins/os-backlog/lib/backlog/labels.rb:11` - `stack` is an Array: `plugins/os-aidd-lint/lib/aidd_lint/fence_mask.rb:30` The cop has 55 hits; most are primitive or core-type params. ## Reproduce n/a: matcher is `plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/site.rb`; run the cop on the files above. ## Approach Carve-outs go in the cop matcher, never in a config Exclude list or a test-path exclusion. Skip when the envied lvar receives core-type messages only (`nil?`, `is_a?`, `to_s`, `strip`, `empty?`, `push`, `pop`, `last`, `include?`), or when it is reassigned from `.to_s` or `Array()`. Delete the 14-file Exclude at `plugins/os-sdlc/.rubocop.yml:342-357`, and fix or carve out those files by shape. Required work: 1. Add the core-type carve-out to the matcher — check: present `strip` in `plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/*.rb` 2. Delete the FeatureEnvy Exclude list — check: absent `Sdlc/Structural/FeatureEnvy` in `plugins/os-sdlc/.rubocop.yml` ## Acceptance criteria 1. Given an lvar that receives only `strip`, `empty?`, and `to_s`, when the cop runs, then it reports no offense. 2. Given the repo config, when the cop runs, then no Exclude list names the cop. 3. Given a def whose lvar receives three domain messages of a project class, when the cop runs, then it reports an offense. ## Origin - Trigger: #1325 zero-false-positive audit of the Sdlc cops - Improvised this session: none - Chain: false positive and config Exclude ← matcher ignores receiver type ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/feature_envy.rb) - Root candidate: #226 (Burn down FeatureEnvy Exclude list; covers only the Exclude list, not the core-type receiver fault) - Where: plugins/os-sdlc/lib/os_sdlc/cops/feature_envy/site.rb - Session: eb98cdcd-6783-46a0-b7df-cf18a8fe2a56 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-1325/eb98cdcd-6783-46a0-b7df-cf18a8fe2a56.jsonl VERDICT: CREATE
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1354
No description provided.