Sdlc/Dry/OwnedMessage: require typed receivers and treat casgn owners as inside the owner #1347

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

Problem

Sdlc/Dry/OwnedMessage flags a call to a message that a config Owners spec assigns to an owner. A bare spec matches any receiver, and the owner's own definition can count as outside the owner.
Counterexamples:

  1. The bare spec full_name_parts (.rubocop.yml:394) matches any receiver. class Release; def full_name_parts = [owner, name]; def label = full_name_parts.join("/"); end fires, but the owner has no answer for Release.
  2. An owner defined as a constant assignment (ConstantPath = Data.define do ... end) is a casgn, not a class node. The owner's own call fires.

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

Approach

Fix in the cop matcher (plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb and owned_message/), never by config Exclude. Require a receiver type for every spec: drop the bare form or narrow it to a typed receiver. Treat a casgn block named for the owner as inside the owner.

Required work:

  1. Handle casgn owners in the namespace check — check: present casgn in plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb

Acceptance criteria

  1. Given each counterexample under Problem, when the cop runs, then it reports no offense.
  2. Given the true-positive shape the cop targets, when the cop runs, then it still reports an offense.
  3. Given the repo, when rubocop runs, then no Exclude list or test-path exclusion carries the carve-out.

Owner sketch

The carve-out lives in the cop matcher.

Origin

  • Trigger: the #1325 zero-false-positive audit of the Sdlc cops
  • Improvised this session: none
  • Chain: false positive on valid code <- cop matcher too broad <- DESIGN (cop source: plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb)
  • Root candidate: none found; searched OwnedMessage, owned message, Owners, casgn, typed receiver, Dry cops
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/owned_message.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 `Sdlc/Dry/OwnedMessage` flags a call to a message that a config `Owners` spec assigns to an owner. A bare spec matches any receiver, and the owner's own definition can count as outside the owner. Counterexamples: 1. The bare spec `full_name_parts` (.rubocop.yml:394) matches any receiver. `class Release; def full_name_parts = [owner, name]; def label = full_name_parts.join("/"); end` fires, but the owner has no answer for Release. 2. An owner defined as a constant assignment (`ConstantPath = Data.define do ... end`) is a casgn, not a class node. The owner's own call fires. Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md). ## Approach Fix in the cop matcher (plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb and owned_message/), never by config `Exclude`. Require a receiver type for every spec: drop the bare form or narrow it to a typed receiver. Treat a `casgn` block named for the owner as inside the owner. Required work: 1. Handle `casgn` owners in the namespace check — check: present `casgn` in `plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb` ## Acceptance criteria 1. Given each counterexample under Problem, when the cop runs, then it reports no offense. 2. Given the true-positive shape the cop targets, when the cop runs, then it still reports an offense. 3. Given the repo, when rubocop runs, then no `Exclude` list or test-path exclusion carries the carve-out. ## Owner sketch The carve-out lives in the cop matcher. ## Origin - Trigger: the #1325 zero-false-positive audit of the Sdlc cops - Improvised this session: none - Chain: false positive on valid code <- cop matcher too broad <- DESIGN (cop source: plugins/os-sdlc/lib/os_sdlc/cops/owned_message.rb) - Root candidate: none found; searched OwnedMessage, owned message, Owners, casgn, typed receiver, Dry cops - Where: plugins/os-sdlc/lib/os_sdlc/cops/owned_message.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#1347
No description provided.