Stop leaked rubocop --server processes from os-sdlc lint runs #1453
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#1453
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
Rubocop server processes from os-sdlc runs are never stopped. On 2026-10-28, 456 processes matched
rubocop --server /tmp/os-sdlc-test, some 2.4 days old. Four more servers run for removed worktrees (ticket-1337, ticket-1357, ticket-1370, ticket-1402). Each server holds memory for a dead directory.Observed
OsSdlc::Lint::Run#argumentsadds--serverwhenserver: true.OsSdlc::FastGate::NewOffenseReport.runpassesserver: true. No code path found that callsrubocop --stop-server.Cause, proven by probe on 2026-10-28 (rubocop 1.92.1): the gate runs
procman with rubocop --root R -- os-sdlc-lint .... procman startsrubocop --start-server --no-detachin R with no--config.os-sdlc-lintthen runsrubocop --server --config <generated lint-worklist.rubocop.yml>. rubocop keys a server by a hash of the config content, so the client sees procman's server as incompatible, stops it, and starts a detached daemon (ppid systemd). procman does not own that daemon, so nothing stops it.Second cause, found at implementation 214 escalation 96 (2026-10-28):
exe/rubocopforwards a plain call with no--serverto any server that runs for the project directory (RuboCop::Server.forward_to_server?), and the client restarts that server detached when the config key differs. So removing--serveralone still leaks under procman.--no-serverstops procman's server on each run.RuboCop::CLInever forwards.Reproduce
n/a: the leak shows in the host process table; run the ps command above.
Approach
os-sdlc starts no rubocop server of its own; procman stays the sole owner of server lifetime (ADR-0219). Remove
server: truefromNewOffenseReport, and remove theserver:option that then has no caller fromLint::RunandFastGate::Rubocop.Lint::Run::Invocation#capturestartsruby -rrubocop -e 'exit RuboCop::CLI.new.run(ARGV)', notexe/rubocop, so rubocop runs in-process and leaves procman's server alone. Measured: one in-process rubocop call 0.68 s; a warm gate LINT run 1.04 s, because it pays the server restart on every run today.The
procman with rubocopwrapper ingate/commands.rbstays unchanged; its server is then unused. Whether to drop the wrapper or start procman's server with the generated config is a separate decision (it touches ADR-0219 and the procman gem).Required work:
server: true— check: absentserver: trueinplugins/os-sdlc/lib/os_sdlc/fast_gate/new_offense_report.rb--serverargument from the lint run — check: absent--serverinplugins/os-sdlc/lib/os_sdlc/lint/run.rbserver:inplugins/os-sdlc/lib/os_sdlc/fast_gate/rubocop.rbOrchestrator work: after merge, run
bin/refresh-pluginsand stop the already-leaked/tmp/os-sdlc-test*servers once.Acceptance criteria
os-sdlc-lintruns over a root, when it calls rubocop, then the rubocop arguments contain no--server.procman with rubocop, when the command ends, then no detachedrubocop --serverprocess for that root exists (procman's own server retires when the root is deleted).Owner sketch
Non-goals
procman with rubocopwrapper, or starting procman's server with the generated config.~/.cache/rubocop_cache/server/*os-sdlc-test*directories.Origin
VERDICT: CREATE
Work started on branch ticket-1453 (os-sdlc implement).
Resolution
Done: os-sdlc lint starts no rubocop server. server: option removed from FastGate::NewOffenseReport, FastGate::Rubocop and Lint::Run. Lint::Run::Invocation#capture runs RbConfig.ruby -rrubocop -e 'exit RuboCop::CLI.new.run(ARGV)', because exe/rubocop forwards even a plain call to a running server for the root and restarts it detached on a config mismatch. procman stays the sole server owner (ADR-0219). Test fakes moved to FakeRubocopLibrary on RUBYLIB. 45 leaked /tmp/os-sdlc-test servers stopped once.
Evidence: main
b347878a(commit7246f609). New test tests/gate/lint_command_leaves_no_rubocop_server_test.rb is red on the old code (detached server, ppid 4617) and green on the fix. Suite on merged branch: 2904 runs, 0 failures, 45.2s. rubocop clean on changed files. os-sdlc-required-work-check 214 exit 0. Implementation 214 escalated (96) on a test defect; hand-finished with one design audit, all SHOULD findings fixed or answered; run abandoned.Follow-ups: none. The procman rubocop wrapper's server is now unused by os-sdlc lint; whether to drop the wrapper or start procman's server with the generated config is a ruling for Jared, reported in the session summary.