Lesson catalog: default lesson for every acted-on offense, not only Sdlc cops #1419

Closed
opened 2026-10-27 16:19:15 +00:00 by jared · 3 comments
Owner

Problem

#1414 gives the _no-lesson-yet default only to Sdlc/* keys. Jared ruled on 2026-10-27 that every offense the AI must act on gets a lesson, in any department. The only exception is a formatting cop that rubocop fixes by itself. Today a Metrics/AbcSize, Lint/* or detector offense with no lesson file reaches the agent with no guidance, and the agent guesses what the offense means.

Reproduce

n/a: design gap; Lesson::Catalog#lesson("Metrics/AbcSize") returns nil, so the relay drops the cop.

Approach

The gate lints without -a (plugins/os-sdlc/lib/os_sdlc/lint/run.rb:21-23), so autocorrectable offenses reach the relay. The code cannot rely on an autocorrect pass. The exception is therefore explicit: a Layout/* or Style/* cop whose class supports autocorrect gets no default. Every other key gets the default.

class Lesson::Catalog::CopKey
  def needs_lesson? = !format_only?

  private

  def format_only?
    %w[Layout Style].include?(department) && cop_class&.support_autocorrect?
  end

  def cop_class = RuboCop::Cop::Registry.global.find_by_cop_name(@key)
end

# Catalog#lesson
return nil unless cop.needs_lesson?
  • Sdlc cops always get a lesson, autocorrect or not (Sdlc/Dry/HandRolledFetch autocorrects, and its autocorrect is the #1346 bug).
  • Lint/* autocorrectable cops get a lesson (Lint/UnusedMethodArgument autocorrect only adds _, which can hide the smoke).
  • Detector keys and unknown keys (no cop class) get the default.

Required work:

  1. Replace the Sdlc/ guard with the format-only exception — check: absent start_with?("Sdlc/") in plugins/os-sdlc/lib/os_sdlc/lesson/catalog/cop_key.rb

Rejected: no exception — Jared ruled formatting cops need no lesson context.
Rejected: exempt every autocorrectable cop — catches Sdlc and Lint cops whose autocorrect hides the smoke.

Acceptance criteria

  1. Given Metrics/AbcSize with no lesson file, when the catalog looks it up, then it returns the default lesson naming Metrics/AbcSize.
  2. Given a detector key with no lesson file, when the catalog looks it up, then it returns the default lesson naming that key.
  3. Given Layout/IndentationWidth with no lesson file, when the catalog looks it up, then it returns nil.
  4. Given an autocorrectable Lint/* cop with no lesson file, when the catalog looks it up, then it returns the default lesson.
  5. Given an autocorrectable Sdlc/* cop with no lesson file, when the catalog looks it up, then it returns the default lesson.

Owner sketch

class OsSdlc::Lesson::Catalog::CopKey
  def needs_lesson?
end

Origin

  • Trigger: Jared's ruling 2026-10-27 on #1414 scope (option A: ship #1414, follow up at once).
  • Improvised this session: none
  • Chain: agent gets no guidance for non-Sdlc offenses ← CopKey#sdlc? guard in Catalog#lesson (plugins/os-sdlc/lib/os_sdlc/lesson/catalog.rb) ← DESIGN (#1414 scope cut, overruled)
  • Root candidate: none found; searched default lesson, no lesson, Metrics lesson, Layout lesson, autocorrect lesson, AUTOCORRECT_COPS, CopKey
  • Where: plugins/os-sdlc/lib/os_sdlc/lesson/catalog/cop_key.rb
  • Session: 0b4d7950-df1c-4eba-a561-ccc19b386a9a
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/0b4d7950-df1c-4eba-a561-ccc19b386a9a.jsonl

VERDICT: CREATE

## Problem #1414 gives the `_no-lesson-yet` default only to `Sdlc/*` keys. Jared ruled on 2026-10-27 that every offense the AI must act on gets a lesson, in any department. The only exception is a formatting cop that rubocop fixes by itself. Today a `Metrics/AbcSize`, `Lint/*` or detector offense with no lesson file reaches the agent with no guidance, and the agent guesses what the offense means. ## Reproduce n/a: design gap; `Lesson::Catalog#lesson("Metrics/AbcSize")` returns nil, so the relay drops the cop. ## Approach The gate lints without `-a` (`plugins/os-sdlc/lib/os_sdlc/lint/run.rb:21-23`), so autocorrectable offenses reach the relay. The code cannot rely on an autocorrect pass. The exception is therefore explicit: a `Layout/*` or `Style/*` cop whose class supports autocorrect gets no default. Every other key gets the default. ```ruby class Lesson::Catalog::CopKey def needs_lesson? = !format_only? private def format_only? %w[Layout Style].include?(department) && cop_class&.support_autocorrect? end def cop_class = RuboCop::Cop::Registry.global.find_by_cop_name(@key) end # Catalog#lesson return nil unless cop.needs_lesson? ``` - Sdlc cops always get a lesson, autocorrect or not (`Sdlc/Dry/HandRolledFetch` autocorrects, and its autocorrect is the #1346 bug). - `Lint/*` autocorrectable cops get a lesson (`Lint/UnusedMethodArgument` autocorrect only adds `_`, which can hide the smoke). - Detector keys and unknown keys (no cop class) get the default. Required work: 1. Replace the `Sdlc/` guard with the format-only exception — check: absent `start_with?("Sdlc/")` in `plugins/os-sdlc/lib/os_sdlc/lesson/catalog/cop_key.rb` Rejected: no exception — Jared ruled formatting cops need no lesson context. Rejected: exempt every autocorrectable cop — catches Sdlc and Lint cops whose autocorrect hides the smoke. ## Acceptance criteria 1. Given `Metrics/AbcSize` with no lesson file, when the catalog looks it up, then it returns the default lesson naming `Metrics/AbcSize`. 2. Given a detector key with no lesson file, when the catalog looks it up, then it returns the default lesson naming that key. 3. Given `Layout/IndentationWidth` with no lesson file, when the catalog looks it up, then it returns nil. 4. Given an autocorrectable `Lint/*` cop with no lesson file, when the catalog looks it up, then it returns the default lesson. 5. Given an autocorrectable `Sdlc/*` cop with no lesson file, when the catalog looks it up, then it returns the default lesson. ## Owner sketch ```ruby class OsSdlc::Lesson::Catalog::CopKey def needs_lesson? end ``` ## Origin - Trigger: Jared's ruling 2026-10-27 on #1414 scope (option A: ship #1414, follow up at once). - Improvised this session: none - Chain: agent gets no guidance for non-Sdlc offenses ← `CopKey#sdlc?` guard in `Catalog#lesson` (`plugins/os-sdlc/lib/os_sdlc/lesson/catalog.rb`) ← DESIGN (#1414 scope cut, overruled) - Root candidate: none found; searched default lesson, no lesson, Metrics lesson, Layout lesson, autocorrect lesson, AUTOCORRECT_COPS, CopKey - Where: `plugins/os-sdlc/lib/os_sdlc/lesson/catalog/cop_key.rb` - Session: 0b4d7950-df1c-4eba-a561-ccc19b386a9a - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/0b4d7950-df1c-4eba-a561-ccc19b386a9a.jsonl VERDICT: CREATE
Author
Owner

Work started on branch ticket-1419 through /os-sdlc:implement (poodr-ticket-implementation).

Work started on branch ticket-1419 through /os-sdlc:implement (poodr-ticket-implementation).
Author
Owner

Resolution

Done: CopKey#needs_lesson? replaces the Sdlc-only guard: every key gets the _no-lesson-yet default except Layout/Style cops whose class supports autocorrect.

Evidence: Implementation 185 complete (10 dispatches, 0 retries, 8 min 58 s); commit f86d591f merged to main; os-sdlc suite on main 2766 runs, 0 failures.

Follow-ups: #1424: render the default lesson once per reply, naming every cop without a lesson (Jared's design, 2026-10-27).

## Resolution **Done:** CopKey#needs_lesson? replaces the Sdlc-only guard: every key gets the _no-lesson-yet default except Layout/Style cops whose class supports autocorrect. **Evidence:** Implementation 185 complete (10 dispatches, 0 retries, 8 min 58 s); commit f86d591f merged to main; os-sdlc suite on main 2766 runs, 0 failures. **Follow-ups:** #1424: render the default lesson once per reply, naming every cop without a lesson (Jared's design, 2026-10-27).
jared closed this issue 2026-10-27 16:38:12 +00:00
Author
Owner

Follow-up fix on main aa6f984f (pattern-detection track, session 47f54f99): CopKey#cop_class reads RuboCop::Cop::Registry but the SubagentStart hook process never required rubocop, so every brief with lint-offense history raised NameError and recorded no dispatch (seen twice on implementation 186). Added require "rubocop" at the top of lesson/catalog/cop_key.rb. No behavior change.

Follow-up fix on main aa6f984f (pattern-detection track, session 47f54f99): CopKey#cop_class reads RuboCop::Cop::Registry but the SubagentStart hook process never required rubocop, so every brief with lint-offense history raised NameError and recorded no dispatch (seen twice on implementation 186). Added require "rubocop" at the top of lesson/catalog/cop_key.rb. No behavior change.
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#1419
No description provided.