Add cop Sdlc/Structural/ClassInWrongConcept with lesson #1749
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#1749
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The one message of
Sdlc/Structural/ConceptCycledoes not tell an agent the correct fix for a class that is in one concept and that only another concept uses.A separate cop with its own message and lesson gives the correct fix.
Ticket 1 supplies the facts. This ticket is blocked by ticket 1.
The base branch is
ticket-1742. It is not merged. Its worktree is/home/jared/dev/cc-os/.claude/worktrees/ticket-1742. It holds the copSdlc/Structural/ConceptCycleand the classOsSdlc::Lint::ConceptCycleCheck.maindoes not have them.The research source is
docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/onmain(commits5465548a7,9bb6a9845,58ee53c). It holdssimulation/kinds.rb,simulation/facts-os-sdlc.yml,simulation/package/(lessons, message forms,render.rb), andsimulation/round-1/grades/*.yml.A "loop reference" is a reference from one concept to another concept when the two concepts are in a dependency loop. A "concept" is a top-level namespace of the library with its directory. The cop reports 93 loop references in 58 files of os-sdlc.
Work: add the cop
Sdlc/Structural/ClassInWrongConceptand its lesson. The cop reports a class that is in one concept and is used only by another concept.The cop gives one finding for each unit.
The source text is
simulation/package/sdlc-structural-class-in-wrong-concept.yml.Put the cop file under
plugins/os-sdlc/lib/os_sdlc/cops/structural/. Put the lesson underplugins/os-sdlc/lint-lessons/.Write a must-fire fixture and a must-pass fixture.
Constraints:
plugins/os-sdlc/.rubocop.ymlonly (ADR-0298).lib/os_sdlc/cops/structural/agrees with its constant (ADR-0090).Excludelist and no allowlist.Observed
In round 1 (
round-1/grades/known-A.yml), 3 of 3 runs made the correct fix.All three runs named the same gaps in the lesson and message:
The new lesson and message must close these three gaps.
Reproduce
n/a: feature ticket.
Origin
docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/onmain)simulation/package/sdlc-structural-class-in-wrong-concept.yml)ticket-1742)Blocked by #1748: this ticket uses the classification that it builds.
Resolution
Done: Cop Sdlc/Structural/ClassInWrongConcept reports each class that only another concept uses, one time, at its declaration. The message comes from the Facts of Kinds::Report. The lesson is lint-lessons/sdlc-structural-class-in-wrong-concept.yml. ConceptCycle no longer reports a reference of this kind. ConceptCycle::LoopFacts is the shared facts owner for the cops of #1750 and #1751.
Evidence: Branch ticket-1742, commit
73608ed39(11 files, +500/-12). Suite: 5439 runs, 0 failures, 0 errors. Rubocop on the 9 changed Ruby files: no offenses. On os-sdlc lib with .rubocop-sweep.yml: ConceptCycle 91 offenses in 56 files, ClassInWrongConcept 1 offense that stands for 2 loop references; 91 + 2 = 93. Must-fire and must-pass fixtures in test/cops/class_in_wrong_concept_test.rb (13 tests).Follow-ups: Two defects found in Kinds::Report: move_to_path is wrong when the new concept has no file of its own; this is corrected in the build of #1750. When two classes in two concepts use only each other, each is a proven unit; dropped as a ticket, the lesson stop condition covers it and no codebase shows it. The cop is registered in .rubocop-sweep.yml only, the same as ConceptCycle on this branch.