Sdlc/Structural/PrimitiveObsessedIvar: fix the masgn crash, count reads only, drop the config Exclude #1368

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

Problem

The cop Sdlc/Structural/PrimitiveObsessedIvar crashes on multiple assignment, counts assignments as uses, and needs a config Exclude to stay quiet.

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

Observed

Crash: plugins/os-sdlc/lib/os_sdlc/retired_test.rb:6 @path, @method_name = .... An ivasgn inside an mlhs has no value child, so literal_ivasgns.rb:22 calls hash_type? on a Symbol.
False positive: plugins/os/lib/worktree/start_command.rb:12. @linked is reassigned in 2 defs and read in 1; reference_count.rb:19 counts assignments as uses.
False positive: plugins/os-context/eval/bin/self-test:40. TranscriptBuilder already is the object that owns @lines.
A config Exclude hides cases at .rubocop.yml:339-340.

Reproduce

n/a: run the cop on plugins/os-sdlc/lib/os_sdlc/retired_test.rb; the matcher is at plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.rb.

Approach

Carve-outs go in the cop matcher, never in a config Exclude list or a test-path exclusion.
Skip an ivasgn that has no value child in literal_ivasgns.rb.
Count only :ivar reads in reference_count.rb.
Skip a class that is itself the builder or collector of the ivar.
Delete the .rubocop.yml:339-340 Exclude.

Required work:

  1. Delete the Exclude entries for this cop — check: absent PrimitiveObsessedIvar in .rubocop.yml

Acceptance criteria

  1. Given @a, @b = x, y in initialize, when the cop runs, then it does not crash.
  2. Given an ivar reassigned in 2 defs and read in 1, when the cop runs, then it reports no offense.
  3. Given a class that builds and returns its own array ivar, when the cop runs, then it reports no offense.

Origin

  • Trigger: #1325 zero-false-positive audit of the Sdlc cops
  • Improvised this session: none
  • Chain: crash and false positives ← masgn unhandled, assignments counted as uses, no builder carve-out ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.rb)
  • Root candidate: none found; searched PrimitiveObsessedIvar
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.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/PrimitiveObsessedIvar` crashes on multiple assignment, counts assignments as uses, and needs a config Exclude to stay quiet. Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md). ## Observed Crash: `plugins/os-sdlc/lib/os_sdlc/retired_test.rb:6` `@path, @method_name = ...`. An ivasgn inside an mlhs has no value child, so `literal_ivasgns.rb:22` calls `hash_type?` on a Symbol. False positive: `plugins/os/lib/worktree/start_command.rb:12`. `@linked` is reassigned in 2 defs and read in 1; `reference_count.rb:19` counts assignments as uses. False positive: `plugins/os-context/eval/bin/self-test:40`. `TranscriptBuilder` already is the object that owns `@lines`. A config Exclude hides cases at `.rubocop.yml:339-340`. ## Reproduce n/a: run the cop on `plugins/os-sdlc/lib/os_sdlc/retired_test.rb`; the matcher is at `plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.rb`. ## Approach Carve-outs go in the cop matcher, never in a config Exclude list or a test-path exclusion. Skip an ivasgn that has no value child in `literal_ivasgns.rb`. Count only `:ivar` reads in `reference_count.rb`. Skip a class that is itself the builder or collector of the ivar. Delete the `.rubocop.yml:339-340` Exclude. Required work: 1. Delete the Exclude entries for this cop — check: absent `PrimitiveObsessedIvar` in `.rubocop.yml` ## Acceptance criteria 1. Given `@a, @b = x, y` in `initialize`, when the cop runs, then it does not crash. 2. Given an ivar reassigned in 2 defs and read in 1, when the cop runs, then it reports no offense. 3. Given a class that builds and returns its own array ivar, when the cop runs, then it reports no offense. ## Origin - Trigger: #1325 zero-false-positive audit of the Sdlc cops - Improvised this session: none - Chain: crash and false positives ← masgn unhandled, assignments counted as uses, no builder carve-out ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.rb) - Root candidate: none found; searched PrimitiveObsessedIvar - Where: plugins/os-sdlc/lib/os_sdlc/cops/primitive_obsessed_ivar.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#1368
No description provided.