os-backlog: add its own .rubocop.yml — plugin lints under repo-root config today #339

Closed
opened 2026-08-10 21:47:39 +00:00 by jared · 3 comments
Owner

os-backlog has no .rubocop.yml, so bare rubocop runs there fall through to the cc-os root config (941 offenses, 890 autocorrectable, mostly tests/ and bin/os-backlog under default cops), while /os-sdlc:fix-lints judges it under os-sdlc's tuned config + Sdlc custom cops (38 offenses as of 2026-08-10). Two rulebooks, two answers. Fix: give os-backlog its own .rubocop.yml (model it on plugins/os-sdlc/.rubocop.yml) declaring which rulebook governs it. Discovered 2026-08-10 during the #337 grilling session.

Decomposition (2026-08-12)

Investigation findings (dry run: os-sdlc's .rubocop.yml cop selection, minus the Sdlc/* custom cops — those live in plugins/os-sdlc/lib/os_sdlc/cops/ and don't exist in os-backlog — applied to os-backlog's 36 target files, candidate config kept in scratchpad, not committed):

  • os-sdlc's config is DisabledByDefault: true + an explicit allowlist: Metrics/* (MethodLength 5, PerceivedComplexity 4, AbcSize 15, ClassLength 100, ParameterLists 4), Style/ClassVars, the full rubocop-minitest assertion-idiom family, plus 27 Sdlc/* custom cops requiring os-sdlc-local cop source files.
  • The Sdlc/* custom cops do not transfer — they require: file paths under plugins/os-sdlc/lib/, which don't exist in os-backlog. Only the Metrics/*, Style/ClassVars, and rubocop-minitest sections are portable as-is.
  • TargetRubyVersion: 3.4 transfers (repo-wide Ruby target; os-backlog has no reason to diverge).
  • os-backlog's layout is bin/ (3 extensionless scripts, ruby-shebang), lib/backlog/ (14 files + lib/backlog.rb), tests/ (14 files, not test/) — directly parallel to os-sdlc's bin/+lib/os_sdlc/+tests/ shape. RuboCop's default target-file discovery picks up extensionless shebang scripts under both configs, so no extra Include: is needed for bin/.
  • Dry-run offense count for os-backlog under the portable subset (Metrics + Style/ClassVars + rubocop-minitest, no Sdlc cops): 12 offenses in 3 fileslib/backlog/issues.rb (1: ClassLength), tests/checkout_test.rb (7: ClassLength, ParameterLists, 5x MethodLength), tests/close_protocol_test.rb (4: ClassLength, 3x MethodLength). All Metrics/* — no Style/ClassVars or Minitest-family hits.
  • This is far short of both existing numbers (941 root-config, 38 os-sdlc-tuned+Sdlc-cops) because those Sdlc structural/dry/minitest cops (module-owns-instance-state, feature-envy, etc.) are the ones catching the bulk of os-sdlc's 38 — os-backlog's real offense count under a config that includes equivalent custom cops isn't measurable without porting or reimplementing those cops, which is out of scope here (see below).

In scope

  1. Create plugins/os-backlog/.rubocop.yml carrying the portable subset of os-sdlc's config: DisabledByDefault: true, TargetRubyVersion: 3.4, NewCops: disable, the Metrics/* block (same thresholds, or re-tuned if os-backlog's judgment differs — see AC3), Style/ClassVars, and the rubocop-minitest plugin + its enabled cop list.
  2. Do not carry the Sdlc/* custom-cop require: lines — they point at nonexistent paths in os-backlog and would break rubocop outright.
  3. Decide and document (in the new file or its PR) whether os-backlog should later grow its own custom-cop set analogous to Sdlc/*, or continue relying on /os-sdlc:fix-lints' judgment layer for structural concerns — this ticket only needs the decision recorded, not the cops built.
  4. Verify bin/, lib/backlog/, and tests/ are all still scanned by the new config (no Include/Exclude regressions) — confirm via rubocop --list-target-files from plugins/os-backlog/.
  5. Run bare rubocop from plugins/os-backlog/ and record the resulting offense count/breakdown as the new baseline in this ticket or a follow-up.

Out of scope

  • Actually fixing the offenses the new config surfaces (whether 12, or more once/if Sdlc-equivalent cops are added). Recommend deferring to /os-sdlc:fix-lints or a dedicated follow-up ticket — this ticket is about giving os-backlog a config that produces one consistent, intentional answer, not about reaching zero offenses. Bundling the fix-out would block the config landing on an unrelated, larger effort (12+ offenses minimum, unknown-but-likely-larger once structural cops are considered).
  • Porting or writing os-backlog-specific custom cops (Backlog/* equivalents of Sdlc/*). Flagged as a design question in-scope item 3 above but not built here.
  • Changing the root cc-os/.rubocop.yml or any other plugin's config.
  • Any change to /os-sdlc:fix-lints itself.

Acceptance criteria

  1. plugins/os-backlog/.rubocop.yml exists, is DisabledByDefault: true, declares TargetRubyVersion: 3.4, and does not require: any nonexistent file path (bare rubocop from plugins/os-backlog/ must not crash on cop load).
  2. rubocop --list-target-files from plugins/os-backlog/ still includes all of bin/decision-sweep, bin/os-backlog, bin/wakeup-poll, every lib/backlog/*.rb, and every tests/*.rb (no accidental narrowing vs. today's 36-file scan).
  3. Bare rubocop from plugins/os-backlog/ no longer falls through to the cc-os root config — confirmed by offense count diverging from the root-config run (941) and matching a locally-explainable number under the new config, expected in the 12–40 range absent new custom cops, not 941.
  4. The ticket or its follow-up records the in-scope decision (item 3 above) on whether os-backlog gets its own Backlog/* custom cops or continues deferring structural judgment to /os-sdlc:fix-lints.
  5. No existing os-sdlc .rubocop.yml behavior changes (verified via git diff touching only files under plugins/os-backlog/).

Ordered subtasks

  1. Draft plugins/os-backlog/.rubocop.yml from the portable subset identified above.
  2. Run rubocop --list-target-files and bare rubocop from plugins/os-backlog/; confirm AC2 and record the AC3 baseline count in the PR/ticket.
  3. Record the custom-cop decision (AC4) — a one- or two-line note is sufficient, doesn't require an ADR unless the decision reverses something already recorded.
  4. Open a follow-up ticket for the offense burn-down (explicitly out of scope here) if any offenses remain.
os-backlog has no .rubocop.yml, so bare `rubocop` runs there fall through to the cc-os root config (941 offenses, 890 autocorrectable, mostly tests/ and bin/os-backlog under default cops), while /os-sdlc:fix-lints judges it under os-sdlc's tuned config + Sdlc custom cops (38 offenses as of 2026-08-10). Two rulebooks, two answers. Fix: give os-backlog its own .rubocop.yml (model it on plugins/os-sdlc/.rubocop.yml) declaring which rulebook governs it. Discovered 2026-08-10 during the #337 grilling session. ## Decomposition (2026-08-12) **Investigation findings** (dry run: os-sdlc's `.rubocop.yml` cop selection, minus the `Sdlc/*` custom cops — those live in `plugins/os-sdlc/lib/os_sdlc/cops/` and don't exist in os-backlog — applied to os-backlog's 36 target files, candidate config kept in scratchpad, not committed): - os-sdlc's config is `DisabledByDefault: true` + an explicit allowlist: `Metrics/*` (MethodLength 5, PerceivedComplexity 4, AbcSize 15, ClassLength 100, ParameterLists 4), `Style/ClassVars`, the full `rubocop-minitest` assertion-idiom family, plus 27 `Sdlc/*` custom cops requiring os-sdlc-local cop source files. - The `Sdlc/*` custom cops do **not** transfer — they `require:` file paths under `plugins/os-sdlc/lib/`, which don't exist in os-backlog. Only the `Metrics/*`, `Style/ClassVars`, and `rubocop-minitest` sections are portable as-is. - `TargetRubyVersion: 3.4` transfers (repo-wide Ruby target; os-backlog has no reason to diverge). - os-backlog's layout is `bin/` (3 extensionless scripts, ruby-shebang), `lib/backlog/` (14 files + `lib/backlog.rb`), `tests/` (14 files, not `test/`) — directly parallel to os-sdlc's `bin/`+`lib/os_sdlc/`+`tests/` shape. RuboCop's default target-file discovery picks up extensionless shebang scripts under both configs, so no extra `Include:` is needed for `bin/`. - Dry-run offense count for os-backlog under the portable subset (Metrics + Style/ClassVars + rubocop-minitest, no Sdlc cops): **12 offenses in 3 files** — `lib/backlog/issues.rb` (1: ClassLength), `tests/checkout_test.rb` (7: ClassLength, ParameterLists, 5x MethodLength), `tests/close_protocol_test.rb` (4: ClassLength, 3x MethodLength). All `Metrics/*` — no Style/ClassVars or Minitest-family hits. - This is far short of both existing numbers (941 root-config, 38 os-sdlc-tuned+Sdlc-cops) because those Sdlc structural/dry/minitest cops (module-owns-instance-state, feature-envy, etc.) are the ones catching the bulk of os-sdlc's 38 — os-backlog's real offense count under a config that *includes* equivalent custom cops isn't measurable without porting or reimplementing those cops, which is out of scope here (see below). ### In scope 1. Create `plugins/os-backlog/.rubocop.yml` carrying the portable subset of os-sdlc's config: `DisabledByDefault: true`, `TargetRubyVersion: 3.4`, `NewCops: disable`, the `Metrics/*` block (same thresholds, or re-tuned if os-backlog's judgment differs — see AC3), `Style/ClassVars`, and the `rubocop-minitest` plugin + its enabled cop list. 2. Do **not** carry the `Sdlc/*` custom-cop `require:` lines — they point at nonexistent paths in os-backlog and would break `rubocop` outright. 3. Decide and document (in the new file or its PR) whether os-backlog should later grow its own custom-cop set analogous to `Sdlc/*`, or continue relying on `/os-sdlc:fix-lints`' judgment layer for structural concerns — this ticket only needs the decision recorded, not the cops built. 4. Verify `bin/`, `lib/backlog/`, and `tests/` are all still scanned by the new config (no `Include`/`Exclude` regressions) — confirm via `rubocop --list-target-files` from `plugins/os-backlog/`. 5. Run bare `rubocop` from `plugins/os-backlog/` and record the resulting offense count/breakdown as the new baseline in this ticket or a follow-up. ### Out of scope - **Actually fixing the offenses** the new config surfaces (whether 12, or more once/if Sdlc-equivalent cops are added). Recommend deferring to `/os-sdlc:fix-lints` or a dedicated follow-up ticket — this ticket is about giving os-backlog a config that produces one consistent, intentional answer, not about reaching zero offenses. Bundling the fix-out would block the config landing on an unrelated, larger effort (12+ offenses minimum, unknown-but-likely-larger once structural cops are considered). - Porting or writing os-backlog-specific custom cops (`Backlog/*` equivalents of `Sdlc/*`). Flagged as a design question in-scope item 3 above but not built here. - Changing the root `cc-os/.rubocop.yml` or any other plugin's config. - Any change to `/os-sdlc:fix-lints` itself. ### Acceptance criteria 1. `plugins/os-backlog/.rubocop.yml` exists, is `DisabledByDefault: true`, declares `TargetRubyVersion: 3.4`, and does not `require:` any nonexistent file path (bare `rubocop` from `plugins/os-backlog/` must not crash on cop load). 2. `rubocop --list-target-files` from `plugins/os-backlog/` still includes all of `bin/decision-sweep`, `bin/os-backlog`, `bin/wakeup-poll`, every `lib/backlog/*.rb`, and every `tests/*.rb` (no accidental narrowing vs. today's 36-file scan). 3. Bare `rubocop` from `plugins/os-backlog/` no longer falls through to the cc-os root config — confirmed by offense count diverging from the root-config run (941) and matching a locally-explainable number under the new config, expected in the 12–40 range absent new custom cops, not 941. 4. The ticket or its follow-up records the in-scope decision (item 3 above) on whether os-backlog gets its own `Backlog/*` custom cops or continues deferring structural judgment to `/os-sdlc:fix-lints`. 5. No existing os-sdlc `.rubocop.yml` behavior changes (verified via `git diff` touching only files under `plugins/os-backlog/`). ### Ordered subtasks 1. Draft `plugins/os-backlog/.rubocop.yml` from the portable subset identified above. 2. Run `rubocop --list-target-files` and bare `rubocop` from `plugins/os-backlog/`; confirm AC2 and record the AC3 baseline count in the PR/ticket. 3. Record the custom-cop decision (AC4) — a one- or two-line note is sufficient, doesn't require an ADR unless the decision reverses something already recorded. 4. Open a follow-up ticket for the offense burn-down (explicitly out of scope here) if any offenses remain.
Author
Owner

Work started: creating plugins/os-backlog/.rubocop.yml per the decomposition; burn-down will be captured as a follow-up issue.

Work started: creating plugins/os-backlog/.rubocop.yml per the decomposition; burn-down will be captured as a follow-up issue.
Author
Owner

Done in commit 5dd1a3e: plugins/os-backlog/.rubocop.yml — DisabledByDefault, TargetRubyVersion 3.4, Metrics/* at os-sdlc thresholds, Style/ClassVars, rubocop-minitest set; no Sdlc/* cops carried. AC checks: 36 target files (no narrowing), bare rubocop = 12 offenses in 3 files (all Metrics/), not 941. Custom-cop decision recorded in the file: defer structural judgment to /os-sdlc:fix-lints, no Backlog/ cops. Burn-down captured as #349. Left open for sign-off.

Done in commit 5dd1a3e: plugins/os-backlog/.rubocop.yml — DisabledByDefault, TargetRubyVersion 3.4, Metrics/* at os-sdlc thresholds, Style/ClassVars, rubocop-minitest set; no Sdlc/* cops carried. AC checks: 36 target files (no narrowing), bare rubocop = 12 offenses in 3 files (all Metrics/*), not 941. Custom-cop decision recorded in the file: defer structural judgment to /os-sdlc:fix-lints, no Backlog/* cops. Burn-down captured as #349. Left open for sign-off.
Author
Owner

Resolution

Done: Created plugins/os-backlog/.rubocop.yml with the portable subset of the os-sdlc config (no Sdlc/* cops); custom-cop decision recorded in the file (defer to /os-sdlc:fix-lints).

Evidence: Commit 5dd1a3e on main; verified against 36 target files with no narrowing; 12-offense baseline (all Metrics/*), matching the ticket's dry run.

Follow-ups: Offense burn-down captured as #349.

## Resolution **Done:** Created plugins/os-backlog/.rubocop.yml with the portable subset of the os-sdlc config (no Sdlc/* cops); custom-cop decision recorded in the file (defer to /os-sdlc:fix-lints). **Evidence:** Commit 5dd1a3e on main; verified against 36 target files with no narrowing; 12-offense baseline (all Metrics/*), matching the ticket's dry run. **Follow-ups:** Offense burn-down captured as #349.
jared closed this issue 2026-08-13 17:49:23 +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#339
No description provided.