lint-worklist: lint a target with the gate's config chain #1417

Closed
opened 2026-10-27 16:12:56 +00:00 by jared · 2 comments
Owner

Problem

bin/lint-worklist lints a target with a different config chain than the gate. Lint::Worklist::RubocopRun.fetch calls Run.new with no lint_config, so the chain becomes plugin config then <root>/.rubocop.yml. The gate passes target.lint.resolved_config(root) (gate/commands.rb), so a target with its own lint_config (os-backlog: plugins/os-backlog/.rubocop.yml) gets plugin config then its own file. fix-lints uses lint-worklist, so on os-backlog it fixes against the wrong cop settings, and the gate can still fail after a "clean" fix-lints run.

Reproduce

plugins/os-sdlc/bin/lint-worklist --target os-backlog

The offense list differs from a full-tree Lint::Run.new(lint_config: target.lint.resolved_config(root)) over plugins/os-backlog (investigation 2026-10-27: os-backlog 312 offenses on the gate chain).

Approach

class Lint::Worklist::RubocopRun
  def self.fetch(project_root, scan_paths, lint_config:)
    Run.new(lint_config: lint_config).call(files: Array(scan_paths), root: project_root)
  end
end

# Lint::Remediation.build_listing
report = Worklist::RubocopRun.fetch(root, target.lint_path(root), lint_config: target.lint.resolved_config(root))

Required work:

  1. Pass the target's resolved lint config to the worklist rubocop run — check: present resolved_config in plugins/os-sdlc/lib/os_sdlc/lint/remediation.rb

Rejected: a separate chain builder for lint-worklist — ADR-0298 and ADR-0179 make target.lint.resolved_config the one resolver; the gate already uses it.

Acceptance criteria

  1. Given a target whose lint_config names its own .rubocop.yml, when lint-worklist lists offenses for that target, then the list is the same as the gate's lint of the same files (plugin config first, then the target's own file).
  2. Given a target with no lint_config, when lint-worklist lists offenses, then the chain is plugin config then the root .rubocop.yml, as today.

Owner sketch

class OsSdlc::Lint::Worklist::RubocopRun
  def self.fetch(project_root, scan_paths, lint_config:)
end

class OsSdlc::Lint::Remediation
  def self.build_listing(project, target)
end

Origin

  • Trigger: lint-cops track increment 3 investigation, 2026-10-27 (full-tree counts per target on the gate chain).
  • Improvised this session: none
  • Chain: fix-lints can leave gate offenses on os-backlog ← lint-worklist ignores the target lint_config ← RubocopRun.fetch calls Run.new with no lint_config (plugins/os-sdlc/lib/os_sdlc/lint/worklist/rubocop_run.rb:9) ← DESIGN (lint/worklist/rubocop_run.rb)
  • Root candidate: none found; searched lint-worklist, worklist, RubocopRun, lint_config, resolved_config
  • Where: plugins/os-sdlc/lib/os_sdlc/lint/worklist/rubocop_run.rb, plugins/os-sdlc/lib/os_sdlc/lint/remediation.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 `bin/lint-worklist` lints a target with a different config chain than the gate. `Lint::Worklist::RubocopRun.fetch` calls `Run.new` with no `lint_config`, so the chain becomes plugin config then `<root>/.rubocop.yml`. The gate passes `target.lint.resolved_config(root)` (`gate/commands.rb`), so a target with its own `lint_config` (os-backlog: `plugins/os-backlog/.rubocop.yml`) gets plugin config then its own file. fix-lints uses `lint-worklist`, so on os-backlog it fixes against the wrong cop settings, and the gate can still fail after a "clean" fix-lints run. ## Reproduce ``` plugins/os-sdlc/bin/lint-worklist --target os-backlog ``` The offense list differs from a full-tree `Lint::Run.new(lint_config: target.lint.resolved_config(root))` over `plugins/os-backlog` (investigation 2026-10-27: os-backlog 312 offenses on the gate chain). ## Approach ```ruby class Lint::Worklist::RubocopRun def self.fetch(project_root, scan_paths, lint_config:) Run.new(lint_config: lint_config).call(files: Array(scan_paths), root: project_root) end end # Lint::Remediation.build_listing report = Worklist::RubocopRun.fetch(root, target.lint_path(root), lint_config: target.lint.resolved_config(root)) ``` Required work: 1. Pass the target's resolved lint config to the worklist rubocop run — check: present `resolved_config` in `plugins/os-sdlc/lib/os_sdlc/lint/remediation.rb` Rejected: a separate chain builder for lint-worklist — ADR-0298 and ADR-0179 make `target.lint.resolved_config` the one resolver; the gate already uses it. ## Acceptance criteria 1. Given a target whose `lint_config` names its own `.rubocop.yml`, when `lint-worklist` lists offenses for that target, then the list is the same as the gate's lint of the same files (plugin config first, then the target's own file). 2. Given a target with no `lint_config`, when `lint-worklist` lists offenses, then the chain is plugin config then the root `.rubocop.yml`, as today. ## Owner sketch ```ruby class OsSdlc::Lint::Worklist::RubocopRun def self.fetch(project_root, scan_paths, lint_config:) end class OsSdlc::Lint::Remediation def self.build_listing(project, target) end ``` ## Origin - Trigger: lint-cops track increment 3 investigation, 2026-10-27 (full-tree counts per target on the gate chain). - Improvised this session: none - Chain: fix-lints can leave gate offenses on os-backlog ← lint-worklist ignores the target `lint_config` ← `RubocopRun.fetch` calls `Run.new` with no `lint_config` (`plugins/os-sdlc/lib/os_sdlc/lint/worklist/rubocop_run.rb:9`) ← DESIGN (`lint/worklist/rubocop_run.rb`) - Root candidate: none found; searched lint-worklist, worklist, RubocopRun, lint_config, resolved_config - Where: `plugins/os-sdlc/lib/os_sdlc/lint/worklist/rubocop_run.rb`, `plugins/os-sdlc/lib/os_sdlc/lint/remediation.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-1417 through /os-sdlc:implement (poodr-ticket-implementation).

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

Resolution

Done: lint-worklist passes the target's resolved lint_config to its rubocop run, so fix-lints lints each target with the same chain as the gate (plugin config first, then the target's own file).

Evidence: Implementation 187 complete (10 dispatches, 0 retries, 9 min 3 s); merged to main; os-sdlc suite on main 2769 runs, 0 failures.

Follow-ups: none

## Resolution **Done:** lint-worklist passes the target's resolved lint_config to its rubocop run, so fix-lints lints each target with the same chain as the gate (plugin config first, then the target's own file). **Evidence:** Implementation 187 complete (10 dispatches, 0 retries, 9 min 3 s); merged to main; os-sdlc suite on main 2769 runs, 0 failures. **Follow-ups:** none
jared closed this issue 2026-10-27 16:49: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#1417
No description provided.