Sdlc/Structural/UnlayeredConstant: match ledger rows by constant as well as new_constant #1359

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

Problem

Sdlc/Structural/UnlayeredConstant records a file as having no ledger row when the row exists. The ledger indexes a row by new_constant when that field is set (ledger.rb:25-27). A file that has not yet moved still carries its old constant, so the lookup misses it.

Observed

Shape: a RecordingCop. It records a lib/os_sdlc file whose Zeitwerk constant path has no layer role in the LedgerPath ledger (layer_map.rb:46-49). It is registered only in .rubocop-sweep.yml:19. It reports 71 records.

Counterexample: plugins/os-sdlc/lib/os_sdlc/project/changes.rb:3 (Project::Changes) is recorded as "no ledger row". docs/crc/os-sdlc/ledger.tsv:763 has the row, with role query and new_constant WorkingTreeChanges.

Reproduce

bundle exec rubocop -c .rubocop-sweep.yml --only Sdlc/Structural/UnlayeredConstant plugins/os-sdlc/lib/os_sdlc/project/changes.rb

Approach

Fix by shape, in the ledger lookup the cop uses: index a row by both constant and new_constant, or record "pending move" separately. Do not add a config Exclude list or a test-path exclusion.

Required work:

  1. Index ledger rows by the old constant as well as new_constant — check: present new_constant in plugins/os-sdlc/lib/os_sdlc/**/ledger.rb

Acceptance criteria

  1. Given a ledger row with constant Project::Changes and new_constant WorkingTreeChanges, when the cop checks project/changes.rb, then it records no "no ledger row" entry.
  2. Given a file whose constant has no ledger row under either name, when the cop runs, then it still records the file.

Owner sketch

class OsSdlc::Cops::UnlayeredConstant
end

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

VERDICT: CREATE

Origin

  • Trigger: #1325 zero-false-positive audit of every Sdlc cop.
  • Improvised this session: none
  • Chain: wrong "no ledger row" record ← role_by_const keys only on new_constant when set ← DESIGN (ledger.rb:25-27)
  • Root candidate: none found; searched UnlayeredConstant, new_constant, no ledger row, role_by_const, LedgerPath
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/unlayered_constant.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
## Problem `Sdlc/Structural/UnlayeredConstant` records a file as having no ledger row when the row exists. The ledger indexes a row by `new_constant` when that field is set (`ledger.rb:25-27`). A file that has not yet moved still carries its old constant, so the lookup misses it. ## Observed Shape: a RecordingCop. It records a `lib/os_sdlc` file whose Zeitwerk constant path has no layer role in the LedgerPath ledger (`layer_map.rb:46-49`). It is registered only in `.rubocop-sweep.yml:19`. It reports 71 records. Counterexample: `plugins/os-sdlc/lib/os_sdlc/project/changes.rb:3` (`Project::Changes`) is recorded as "no ledger row". `docs/crc/os-sdlc/ledger.tsv:763` has the row, with role `query` and `new_constant` WorkingTreeChanges. ## Reproduce ``` bundle exec rubocop -c .rubocop-sweep.yml --only Sdlc/Structural/UnlayeredConstant plugins/os-sdlc/lib/os_sdlc/project/changes.rb ``` ## Approach Fix by shape, in the ledger lookup the cop uses: index a row by both `constant` and `new_constant`, or record "pending move" separately. Do not add a config Exclude list or a test-path exclusion. Required work: 1. Index ledger rows by the old constant as well as `new_constant` — check: present `new_constant` in `plugins/os-sdlc/lib/os_sdlc/**/ledger.rb` ## Acceptance criteria 1. Given a ledger row with `constant` Project::Changes and `new_constant` WorkingTreeChanges, when the cop checks `project/changes.rb`, then it records no "no ledger row" entry. 2. Given a file whose constant has no ledger row under either name, when the cop runs, then it still records the file. ## Owner sketch ```ruby class OsSdlc::Cops::UnlayeredConstant end ``` Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md). VERDICT: CREATE ## Origin - Trigger: #1325 zero-false-positive audit of every Sdlc cop. - Improvised this session: none - Chain: wrong "no ledger row" record ← `role_by_const` keys only on `new_constant` when set ← DESIGN (`ledger.rb:25-27`) - Root candidate: none found; searched UnlayeredConstant, new_constant, no ledger row, role_by_const, LedgerPath - Where: plugins/os-sdlc/lib/os_sdlc/cops/unlayered_constant.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
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#1359
No description provided.