Route every os-sdlc rubocop call through one lint entry point #1319
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#1319
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
Eight sites in os-sdlc start rubocop (a ninth, gate/unchanged_check/measurement.rb, is listed under Observed). Each site chooses its own config. Four sites use the layered config (os-sdlc .rubocop.yml first, then the target config). Four sites do not.
The implement gate does not use the os-sdlc config. So the implement gate on os-backlog uses only the os-backlog .rubocop.yml (DisabledByDefault, no Sdlc cops). The gate on os, os-adr, os-aidd-lint, and os-me uses the cc-os root .rubocop.yml (stock cops, no Sdlc cops). All five are targets in .sdlc/project.yaml.
ADR-0298 (commit
09da348a) says os-sdlc layers its rubocop config at run time and installs nothing into target repos. The code does not yet do this at every site.Observed
Sites that use the layered config: plugins/os-sdlc/lib/os_sdlc/lint.rb:11, lint/worklist/rubocop_run.rb:19, lint/sweeping.rb:29, fast_gate/cop_check.rb:28.
Sites that do not: gate/commands.rb:85 (implement gate lint and test-lint), fast_gate/new_offense_check.rb via fast_gate/rubocop.rb, lint/autocorrection/rubocop_run.rb:16 (
rubocop -a). detector/cop_sites.rb runs in-process with its own config.A ninth site that does not use the layered config: gate/unchanged_check/measurement.rb:31 (
os-sdlc-unchanged-checkcounts offenses with only the targetlint.config).fast_gate/cop_check.rb:28 and fast_gate/new_offense_check.rb both start rubocop through one runner, fast_gate/rubocop.rb:14. cop_check passes the layered
--config; new_offense_check passes none. lint.rb:11 is the command constant; the run is at lint.rb:30.lint/worklist/listing.rb:34 prints a
rubocop -a --only ...hint for the human. It starts no process and is not a call site.What the sites need from the entry point: a file list; the target root; lint_config; extra config layers (sweeping.rb and cop_check.rb add
.rubocop-sweep.yml); an--onlycop list (sweeping, cop_check); JSON or clang output (lint.rb and sweeping.rb print clang);--stdinsource for base-commit offenses (new_offense_check); autocorrect-a(autocorrect prepass); the procman rubocop server (implement gate).The gate command at gate/commands.rb:85:
Evidence: the layered config run on the pre-fix os-backlog file (
git show 7c228093:plugins/os-backlog/lib/backlog/cli_command_wiring.rb, 279 lines) fires Sdlc/Structural/ModuleOwnsInstanceState and ParameterThreadedThroughPrivateMethods. The gate did not report them.plugins/os-backlog/.rubocop.yml has a comment that says Sdlc
require:paths crash rubocop there. That is true only for a plain rubocop run. It is not true for the layered config.Reproduce
n/a: design gap. Read gate/commands.rb:85 and compare it with lint.rb:11.
Approach
Build one lint entry point. One object (for example OsSdlc::Lint::Run) and one CLI (for example os-sdlc-lint) own config resolution, rubocop invocation, and result parsing. All eight sites call it, except detector/cop_sites.rb (see Non-goals), and gate/unchanged_check/measurement.rb also. Use the existing chain builder
OsSdlc::Lint::WorklistRubocopConfig(lib/os_sdlc/lint/worklist_rubocop_config.rb) for config resolution; it already raises HarnessError for a missing lint_config.Keep these constraints. ADR-0219: gate rubocop runs through the procman-owned rubocop server. ADR-0179: a nil lint_config means the target .rubocop.yml, and a configured path that is missing raises HarnessError. ADR-0082: one pass, and a missing gem fails loudly and names the gem.
Layering order: os-sdlc plugin .rubocop.yml first, then the target .rubocop.yml or lint_config. Target settings win.
The implement gate must fail only on new offenses against the base commit, as the fast gate new-offense check does. Old offenses in newly covered plugins then do not block unrelated work.
Required work:
class Runinplugins/os-sdlc/lib/os_sdlc/lint/run.rbOsSdlc::Lint::Runinplugins/os-sdlc/bin/os-sdlc-lintcrashinplugins/os-backlog/.rubocop.ymlrubocop #{config_flag}inplugins/os-sdlc/lib/os_sdlc/gate/unchanged_check/measurement.rbAcceptance criteria
rubocop) or runs an in-processRuboCop::Cop::Commissioner, then none exists outside the entry point and detector/cop_sites.rb.Owner sketch
Callers after the change: Gate::Commands#rubocop_command_for, FastGate::Rubocop#offenses, Lint::Autocorrection::RubocopRun#call, Lint#call, Lint::Worklist::RubocopRun.fetch, Lint::Sweeping#report, Gate::UnchangedCheck::Measurement#offense_count. Config chain: Lint::WorklistRubocopConfig#write. New CLI: plugins/os-sdlc/bin/os-sdlc-lint.
Notes
OsSdlc::Lint#callhas no library sender today (only tests/lint_test.rb constructs it); change it as listed in item 4 regardless.Non-goals
Fixing the offenses that the layered config finds in newly covered plugins.
Routing detector/cop_sites.rb through the entry point. It is an in-process measurement: it runs selected cops with config that the code supplies and reads each cop's
findings, which rubocop JSON output does not carry.Follow-up after ship (human, not required work): run lint-sweep per plugin and post the counts on #1317.
Origin
VERDICT: CREATE
Work started on branch ticket-1319 (os-sdlc implement, AFK run approved 2026-10-25).
Resolution
Done: Every os-sdlc rubocop call now goes through OsSdlc::Lint::Run with the ADR-0298 run-time layered config: fast gate, sweep, worklist, autocorrect prepass, unchanged-check measurement, Lint#call. bin/os-sdlc-lint runs FastGate::NewOffenseReport, so the implement gate fails only on offenses new against the base branch. os-backlog target names its own .rubocop.yml. detector/cop_sites.rb out of scope per Non-goals.
Evidence: main
94d682c0(969c4c45,0d37643f). os-sdlc suite 2550 runs, 0 failures; os-backlog suite 327 runs, 0 failures; rubocop 30 files no offenses; eager load ok. All ACs and required-work checks pass. Implementation 161 escalated twice (73: unchecked R2, ticket fixed and rerouted; 74: bound exhausted, AC 6 a search check vs pinned tests); hand-finished with one design audit, its two must-fix findings applied.Follow-ups: #1339 (pipeline routing gaps, skeptic CREATE); #1340 (unchecked required work reached pipeline, skeptic CREATE); #1341 (suite wall time over budget, skeptic CREATE); occurrence on #1096 (worktree guard false positive, skeptic OCCURRENCE). Dropped: configurable base branch (no target needs it yet); Lint#call has no library caller (CRC pass will rule).