Move os-sdlc cop files into department folders so cops/ paths match their constants #1397

Closed
opened 2026-10-26 14:51:23 +00:00 by jared · 1 comment
Owner

Problem

plugins/os-sdlc/lib/os_sdlc/cops/ is a flat folder. Its 164 files define constants in five namespaces: RuboCop::Cop::Sdlc::Structural (128), Dry (18), Minitest (7), Sequel (6), and plain RuboCop::Cop::Sdlc (5). The file path does not carry the department. A Zeitwerk loader with namespace RuboCop::Cop::Sdlc cannot map these files, and #1393 needs that loader.

Files whose path does not name their constant:

  • owned_message/match.rb and owned_message/spec.rb reopen Dry::OwnedMessage.
  • reach_through_chain/held.rb reopens Structural::ReachThroughChain.
  • mutable_collection_leak_via_attr_reader/ivar_mutation.rb defines two constants: IvarMutation and IvarCall.
  • lifecycle_ivar_behind_attr_reader/attr_names.rb: constant not confirmed.

Reproduce

n/a: structure change. Count with grep -rhoE 'module (Structural|Dry|Minitest|Sequel)' plugins/os-sdlc/lib/os_sdlc/cops | sort | uniq -c.

Approach

Move each cop file and its helper folder under cops//: structural/, dry/, minitest/, sequel/. The 5 plain-Sdlc cops stay at the cops/ top level. Fold each reopen file into a constant that its path names. Keep one constant per file. Constants and cop names (for example Sdlc/Structural/FeatureEnvy) do not change, so .rubocop.yml cop keys and rubocop:disable comments do not change.

Required work:

  1. Move the Structural cops and their helper folders under cops/structural/ — check: absent module Structural in plugins/os-sdlc/lib/os_sdlc/cops/*.rb
  2. Move the Dry, Minitest, and Sequel cops and their helper folders under cops/dry/, cops/minitest/, and cops/sequel/.
  3. Fold owned_message/match.rb, owned_message/spec.rb, and reach_through_chain/held.rb into constants that their paths name, and split ivar_mutation.rb to one constant per file.
  4. Update the require_relative paths in cops/, detector/, and tests/cops/, the .rubocop.yml require: paths, and the PLUGIN_FILE path at tests/cops/cop_source_test.rb:7.

Rejected: a glob entry file over the flat layout — it keeps the per-helper require_relative calls and the hidden LoadError rescues (Jared chose the department layout this session).

Acceptance criteria

  1. Given the full os-sdlc suite, when it runs, then it passes.
  2. Given rubocop --show-cops, when the Sdlc/ cops are counted, then the count equals the count before the change.
  3. Given any file under plugins/os-sdlc/lib/os_sdlc/cops/, when its path is read relative to cops/ under namespace RuboCop::Cop::Sdlc, then it names the constant that the file defines.

Blocking edges

Blocks #1393.

Origin

  • Trigger: /os-sdlc:implement 1393; ticket-decompose found the flat cops/ layout.
  • Improvised this session: none
  • Chain: #1393 loader cannot map cop files ← flat cops/ folder with department namespaces ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/)
  • Root candidate: none found; searched cops/ department, folder, flat layout, constant path, Zeitwerk cops, RuboCop::Cop::Sdlc
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/
  • Session: 4453856e-c594-48a3-8871-c95b3f21ff40
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4453856e-c594-48a3-8871-c95b3f21ff40.jsonl

VERDICT: CREATE

## Problem plugins/os-sdlc/lib/os_sdlc/cops/ is a flat folder. Its 164 files define constants in five namespaces: RuboCop::Cop::Sdlc::Structural (128), Dry (18), Minitest (7), Sequel (6), and plain RuboCop::Cop::Sdlc (5). The file path does not carry the department. A Zeitwerk loader with namespace RuboCop::Cop::Sdlc cannot map these files, and #1393 needs that loader. Files whose path does not name their constant: - owned_message/match.rb and owned_message/spec.rb reopen Dry::OwnedMessage. - reach_through_chain/held.rb reopens Structural::ReachThroughChain. - mutable_collection_leak_via_attr_reader/ivar_mutation.rb defines two constants: IvarMutation and IvarCall. - lifecycle_ivar_behind_attr_reader/attr_names.rb: constant not confirmed. ## Reproduce n/a: structure change. Count with grep -rhoE 'module (Structural|Dry|Minitest|Sequel)' plugins/os-sdlc/lib/os_sdlc/cops | sort | uniq -c. ## Approach Move each cop file and its helper folder under cops/<department>/: structural/, dry/, minitest/, sequel/. The 5 plain-Sdlc cops stay at the cops/ top level. Fold each reopen file into a constant that its path names. Keep one constant per file. Constants and cop names (for example Sdlc/Structural/FeatureEnvy) do not change, so .rubocop.yml cop keys and rubocop:disable comments do not change. Required work: 1. Move the Structural cops and their helper folders under cops/structural/ — check: absent `module Structural` in `plugins/os-sdlc/lib/os_sdlc/cops/*.rb` 2. Move the Dry, Minitest, and Sequel cops and their helper folders under cops/dry/, cops/minitest/, and cops/sequel/. 3. Fold owned_message/match.rb, owned_message/spec.rb, and reach_through_chain/held.rb into constants that their paths name, and split ivar_mutation.rb to one constant per file. 4. Update the require_relative paths in cops/, detector/, and tests/cops/, the .rubocop.yml require: paths, and the PLUGIN_FILE path at tests/cops/cop_source_test.rb:7. Rejected: a glob entry file over the flat layout — it keeps the per-helper require_relative calls and the hidden LoadError rescues (Jared chose the department layout this session). ## Acceptance criteria 1. Given the full os-sdlc suite, when it runs, then it passes. 2. Given rubocop --show-cops, when the Sdlc/ cops are counted, then the count equals the count before the change. 3. Given any file under plugins/os-sdlc/lib/os_sdlc/cops/, when its path is read relative to cops/ under namespace RuboCop::Cop::Sdlc, then it names the constant that the file defines. ## Blocking edges Blocks #1393. ## Origin - Trigger: /os-sdlc:implement 1393; ticket-decompose found the flat cops/ layout. - Improvised this session: none - Chain: #1393 loader cannot map cop files ← flat cops/ folder with department namespaces ← DESIGN (plugins/os-sdlc/lib/os_sdlc/cops/) - Root candidate: none found; searched cops/ department, folder, flat layout, constant path, Zeitwerk cops, RuboCop::Cop::Sdlc - Where: plugins/os-sdlc/lib/os_sdlc/cops/ - Session: 4453856e-c594-48a3-8871-c95b3f21ff40 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4453856e-c594-48a3-8871-c95b3f21ff40.jsonl VERDICT: CREATE
Author
Owner

Resolution

Done: fast-batch-16 moved 159 cop files into cops/structural, dry, minitest and sequel; plain Sdlc cops stay at the top. Every require_relative, test path, .rubocop.yml and .rubocop-sweep.yml require/Exclude path, mine-lints cop path convention and ledger path cell follows. Constants and cop names unchanged.

Evidence: main 3ccd7a22 (7d0646b4 move, 958eacc4 Exclude paths), cost rows 4a0fc41d. Full suite 2672 runs 0 failures; rubocop --show-cops Sdlc/ count 40 before and after; Zeitwerk eager_load of cops/ with namespace RuboCop::Cop::Sdlc: 164 files, 48 cops, no error (raised before the move). Stranger reviews: one spec finding fixed, five rulings in docs/crc/os-sdlc/fast-batch-16/rulings.tsv.

Follow-ups: #1393 unblocked (loader; comment there notes 40 vs 48 registered cops). #1398 (92 missing ledger rows, pre-existing). jared/decision-model#10 (copied cop require: list breaks on moves).

## Resolution **Done:** fast-batch-16 moved 159 cop files into cops/structural, dry, minitest and sequel; plain Sdlc cops stay at the top. Every require_relative, test path, .rubocop.yml and .rubocop-sweep.yml require/Exclude path, mine-lints cop path convention and ledger path cell follows. Constants and cop names unchanged. **Evidence:** main 3ccd7a22 (7d0646b4 move, 958eacc4 Exclude paths), cost rows 4a0fc41d. Full suite 2672 runs 0 failures; rubocop --show-cops Sdlc/ count 40 before and after; Zeitwerk eager_load of cops/ with namespace RuboCop::Cop::Sdlc: 164 files, 48 cops, no error (raised before the move). Stranger reviews: one spec finding fixed, five rulings in docs/crc/os-sdlc/fast-batch-16/rulings.tsv. **Follow-ups:** #1393 unblocked (loader; comment there notes 40 vs 48 registered cops). #1398 (92 missing ledger rows, pre-existing). jared/decision-model#10 (copied cop require: list breaks on moves).
jared closed this issue 2026-10-26 15:13:32 +00:00
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#1397
No description provided.