Add cop Sdlc/Structural/StartingCodeInSharedConcept with lesson #1750

Closed
opened 2026-11-13 20:06:48 +00:00 by jared · 3 comments
Owner

Problem

The one message of Sdlc/Structural/ConceptCycle failed in 2 of 4 earlier runs on code that starts the system and is in a concept that other concepts share.
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 cop Sdlc/Structural/ConceptCycle and the class OsSdlc::Lint::ConceptCycleCheck. main does not have them.

The research source is docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/ on main (commits 5465548a7, 9bb6a9845, 58ee53c). It holds simulation/kinds.rb, simulation/facts-os-sdlc.yml, simulation/package/ (lessons, message forms, render.rb), and simulation/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/StartingCodeInSharedConcept and its lesson. The cop reports code that starts the system and is in a concept that other concepts share.
The cop gives one finding for the unit, at the fault site.
Each reported line says "direction correct, do not change this line" and gives the fault site.
The source text is simulation/package/sdlc-structural-starting-code-in-shared-concept.yml.
Put the cop file under plugins/os-sdlc/lib/os_sdlc/cops/structural/. Put the lesson under plugins/os-sdlc/lint-lessons/.
Write a must-fire fixture and a must-pass fixture.

Constraints:

  • Register cops in plugins/os-sdlc/.rubocop.yml only (ADR-0298).
  • Each cop file name under lib/os_sdlc/cops/structural/ agrees with its constant (ADR-0090).
  • Use no Exclude list and no allowlist.
  • Write no repository name in lesson or message-form text.
  • Put pass/fail logic in tested Ruby, not in prompt text.

Observed

In round 1 (round-1/grades/known-B.yml and known-C.yml), 6 of 6 runs made the correct fix.
This is the kind that the present message failed in 2 of 4 earlier runs.
All runs named these gaps:

  • The message lists bin/ files. It does not list test files. It does not name the directory for the nested files.
  • The message does not say that the references to the shared concept that stay (a superclass, helper constants) make no new report.
  • The message does not name generated design files.

The new lesson and message must close these three gaps.

Reproduce

n/a: feature ticket.

Origin

  • Trigger: round 1 of the concept-cycle kinds research (docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/ on main)
  • Improvised this session: none
  • Chain: the agent fails to move starting code ← the one message does not name this kind ← no cop for this kind exists (DESIGN: ticket 1 of this set and simulation/package/sdlc-structural-starting-code-in-shared-concept.yml)
  • Root candidate: none found; searched StartingCode, SharedConcept, starting code
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/structural/ and plugins/os-sdlc/lint-lessons/ (branch ticket-1742)
  • Session: fdf2ac7d-9590-47d4-97e8-ebff9711ce46
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/fdf2ac7d-9590-47d4-97e8-ebff9711ce46.jsonl
  • VERDICT: CREATE - handoff step 5 asks for these cop changes with fixtures; no open ticket covers this mechanism.
## Problem The one message of `Sdlc/Structural/ConceptCycle` failed in 2 of 4 earlier runs on code that starts the system and is in a concept that other concepts share. 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 cop `Sdlc/Structural/ConceptCycle` and the class `OsSdlc::Lint::ConceptCycleCheck`. `main` does not have them. The research source is `docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/` on `main` (commits `5465548a7`, `9bb6a9845`, `58ee53c`). It holds `simulation/kinds.rb`, `simulation/facts-os-sdlc.yml`, `simulation/package/` (lessons, message forms, `render.rb`), and `simulation/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/StartingCodeInSharedConcept` and its lesson. The cop reports code that starts the system and is in a concept that other concepts share. The cop gives one finding for the unit, at the fault site. Each reported line says "direction correct, do not change this line" and gives the fault site. The source text is `simulation/package/sdlc-structural-starting-code-in-shared-concept.yml`. Put the cop file under `plugins/os-sdlc/lib/os_sdlc/cops/structural/`. Put the lesson under `plugins/os-sdlc/lint-lessons/`. Write a must-fire fixture and a must-pass fixture. Constraints: - Register cops in `plugins/os-sdlc/.rubocop.yml` only (ADR-0298). - Each cop file name under `lib/os_sdlc/cops/structural/` agrees with its constant (ADR-0090). - Use no `Exclude` list and no allowlist. - Write no repository name in lesson or message-form text. - Put pass/fail logic in tested Ruby, not in prompt text. ## Observed In round 1 (`round-1/grades/known-B.yml` and `known-C.yml`), 6 of 6 runs made the correct fix. This is the kind that the present message failed in 2 of 4 earlier runs. All runs named these gaps: - The message lists `bin/` files. It does not list test files. It does not name the directory for the nested files. - The message does not say that the references to the shared concept that stay (a superclass, helper constants) make no new report. - The message does not name generated design files. The new lesson and message must close these three gaps. ## Reproduce n/a: feature ticket. ## Origin - Trigger: round 1 of the concept-cycle kinds research (`docs/research/lint-lessons/2026-11-13-concept-cycle-kinds/` on `main`) - Improvised this session: none - Chain: the agent fails to move starting code ← the one message does not name this kind ← no cop for this kind exists (DESIGN: ticket 1 of this set and `simulation/package/sdlc-structural-starting-code-in-shared-concept.yml`) - Root candidate: none found; searched StartingCode, SharedConcept, starting code - Where: plugins/os-sdlc/lib/os_sdlc/cops/structural/ and plugins/os-sdlc/lint-lessons/ (branch `ticket-1742`) - Session: fdf2ac7d-9590-47d4-97e8-ebff9711ce46 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/fdf2ac7d-9590-47d4-97e8-ebff9711ce46.jsonl - VERDICT: CREATE - handoff step 5 asks for these cop changes with fixtures; no open ticket covers this mechanism.
Author
Owner

Blocked by #1748: this ticket uses the classification that it builds.

Blocked by #1748: this ticket uses the classification that it builds.
Author
Owner

Fact for the design, from a trace of the gate reply code on main.
Gate::Reply#lint_output (lib/os_sdlc/gate/reply.rb:34-40) prints each offense line and then one lesson for each cop (lib/os_sdlc/gate/lint_output.rb:30-34, lib/os_sdlc/offense_directive.rb:27-31).
This cop has 18 reported lines for one unit in os-sdlc. If each line carries the full message, the gate reply repeats the long message 18 times.
The package form is: one full finding for the unit, and a short repeat form for each other line of the same unit (simulation/package/render.rb). The cop must produce that itself, because the gate code does not group offense lines by unit.
Also: the gate shortens the lesson of a cop that the dispatch has seen before to its signal line (lib/os_sdlc/lesson/relay.rb:61). Round 1 always gave the full lesson.

Fact for the design, from a trace of the gate reply code on `main`. `Gate::Reply#lint_output` (`lib/os_sdlc/gate/reply.rb:34-40`) prints each offense line and then one lesson for each cop (`lib/os_sdlc/gate/lint_output.rb:30-34`, `lib/os_sdlc/offense_directive.rb:27-31`). This cop has 18 reported lines for one unit in os-sdlc. If each line carries the full message, the gate reply repeats the long message 18 times. The package form is: one full finding for the unit, and a short repeat form for each other line of the same unit (`simulation/package/render.rb`). The cop must produce that itself, because the gate code does not group offense lines by unit. Also: the gate shortens the lesson of a cop that the dispatch has seen before to its signal line (`lib/os_sdlc/lesson/relay.rb:61`). Round 1 always gave the full lesson.
Author
Owner

Resolution

Done: Cop Sdlc/Structural/StartingCodeInSharedConcept gives one full finding at the declaration of the starting code and a short form (direction correct, do not change this line, where the full finding is) at each reported line. The full finding lists the starter lines, the test files, the nested directory, the references that stay, and the effect. The lesson is lint-lessons/sdlc-structural-starting-code-in-shared-concept.yml. Kinds::Report gives the new Facts. The checksum of the three cops includes the tracked Ruby files outside the library. Kinds::Report move_to_path is corrected.

Evidence: Branch ticket-1742, commits f66e7cb1a and 9f23e21c1 (29 files, +923/-66). Suite: 5477 runs, 0 failures, 0 errors. Rubocop on the 27 changed Ruby files: no offenses. On os-sdlc lib with .rubocop-sweep.yml: ConceptCycle 73 in 39 files, ClassInWrongConcept 1 (2 references), StartingCodeInSharedConcept 19 (1 full, 18 short; 18 references); 73 + 2 + 18 = 93. The full finding states that the move removes 43 reports and 50 stay, which agrees with the step 1 simulation. Fixtures in test/cops/starting_code_in_shared_concept_test.rb (20 tests).

Follow-ups: Corrected in the build of #1751: the two checksum tests of #1749 that compare two different directories, and the missing singular forms of counts in messages. Dropped: a new top-level name that is in use gives a name with Start added and no path; the lesson tells the agent to stop and ask, and no codebase shows it.

## Resolution **Done:** Cop Sdlc/Structural/StartingCodeInSharedConcept gives one full finding at the declaration of the starting code and a short form (direction correct, do not change this line, where the full finding is) at each reported line. The full finding lists the starter lines, the test files, the nested directory, the references that stay, and the effect. The lesson is lint-lessons/sdlc-structural-starting-code-in-shared-concept.yml. Kinds::Report gives the new Facts. The checksum of the three cops includes the tracked Ruby files outside the library. Kinds::Report move_to_path is corrected. **Evidence:** Branch ticket-1742, commits f66e7cb1a and 9f23e21c1 (29 files, +923/-66). Suite: 5477 runs, 0 failures, 0 errors. Rubocop on the 27 changed Ruby files: no offenses. On os-sdlc lib with .rubocop-sweep.yml: ConceptCycle 73 in 39 files, ClassInWrongConcept 1 (2 references), StartingCodeInSharedConcept 19 (1 full, 18 short; 18 references); 73 + 2 + 18 = 93. The full finding states that the move removes 43 reports and 50 stay, which agrees with the step 1 simulation. Fixtures in test/cops/starting_code_in_shared_concept_test.rb (20 tests). **Follow-ups:** Corrected in the build of #1751: the two checksum tests of #1749 that compare two different directories, and the missing singular forms of counts in messages. Dropped: a new top-level name that is in use gives a name with Start added and no path; the lesson tells the agent to stop and ask, and no codebase shows it. <!-- os-backlog kind: resolution -->
jared closed this issue 2026-11-13 21:19:45 +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#1750
No description provided.