Run flay and debride in-process in the sweep scripts #851

Closed
opened 2026-09-30 17:23:55 +00:00 by jared · 2 comments
Owner

Problem

bin/dup-sweep and bin/dead-code-sweep start a shell process to run flay and debride. Both are Ruby gems in os-sdlc's own bundle (Gemfile.lock: flay 2.14.4, debride 1.15.2). The shell call depends on the PATH, and it discards the exit status and stderr. If the executable is missing, or the gem fails, the script prints nothing and still exits 0.

plugins/os-sdlc/bin/dup-sweep:24         out, = Open3.capture2("flay", *extra_args, @target)
plugins/os-sdlc/bin/dead-code-sweep:14   out, = Open3.capture2("debride", @target)

Reproduce

PATH=/usr/bin:/bin plugins/os-sdlc/bin/dup-sweep plugins/os-sdlc/lib

Expected today: the == flay ... == headers print, but flay's report does not. The command still exits 0.

Approach

Each script loads the gem and calls the same entry point that the gem's own executable calls. The entry points below are for flay 2.14.4 and debride 1.15.2. The first required-work item confirms them.

Required work:

  1. Confirm the in-process entry points against the installed gems' bin/flay and bin/debride — check: cd plugins/os-sdlc && bundle exec gem contents flay debride | grep bin/

Rejected: keep the shell and check the exit status — that keeps the PATH dependency, and it does not solve the problem.

Acceptance criteria

  1. Given a directory with two structurally identical methods, when bin/dup-sweep runs on it with a PATH that has no flay executable, then the output lists the duplicated code under both mass headers.
  2. Given a directory with a method that no code calls, when bin/dead-code-sweep runs on it with a PATH that has no debride executable, then the output names that method.
  3. Given flay raises an error, when bin/dup-sweep runs, then the script exits non-zero and shows the error.

Owner sketch

class DupSweep
  def report(label, extra_args)
    puts "== flay (#{label}) =="
    Flay.run([*extra_args, @target]).report
  end
end

class DeadCodeSweep
  def run
    Debride.run([@target]).report
  end
end

Non-goals

  • Rubocop shell calls. They lint the invoking project in that project's bundle, so they stay shell calls (#845 audit).

Origin

  • Trigger: #845 shell-call audit, 2026-09-30.
  • Improvised this session: none
  • Chain: sweep output can be empty with exit 0 ← flay and debride run as shell processes with status ignored (bin/dup-sweep, bin/dead-code-sweep) ← DESIGN: ADR-0061
  • Root candidate: this ticket
  • Where: plugins/os-sdlc/bin/dup-sweep, plugins/os-sdlc/bin/dead-code-sweep
  • Session: f090dd39-8ad6-4f4e-8743-7bbedb8f08d4
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/f090dd39-8ad6-4f4e-8743-7bbedb8f08d4.jsonl
## Problem `bin/dup-sweep` and `bin/dead-code-sweep` start a shell process to run flay and debride. Both are Ruby gems in os-sdlc's own bundle (`Gemfile.lock`: flay 2.14.4, debride 1.15.2). The shell call depends on the PATH, and it discards the exit status and stderr. If the executable is missing, or the gem fails, the script prints nothing and still exits 0. ``` plugins/os-sdlc/bin/dup-sweep:24 out, = Open3.capture2("flay", *extra_args, @target) plugins/os-sdlc/bin/dead-code-sweep:14 out, = Open3.capture2("debride", @target) ``` ## Reproduce ``` PATH=/usr/bin:/bin plugins/os-sdlc/bin/dup-sweep plugins/os-sdlc/lib ``` Expected today: the `== flay ... ==` headers print, but flay's report does not. The command still exits 0. ## Approach Each script loads the gem and calls the same entry point that the gem's own executable calls. The entry points below are for flay 2.14.4 and debride 1.15.2. The first required-work item confirms them. Required work: 1. Confirm the in-process entry points against the installed gems' `bin/flay` and `bin/debride` — check: `cd plugins/os-sdlc && bundle exec gem contents flay debride | grep bin/` Rejected: keep the shell and check the exit status — that keeps the PATH dependency, and it does not solve the problem. ## Acceptance criteria 1. Given a directory with two structurally identical methods, when `bin/dup-sweep` runs on it with a PATH that has no `flay` executable, then the output lists the duplicated code under both mass headers. 2. Given a directory with a method that no code calls, when `bin/dead-code-sweep` runs on it with a PATH that has no `debride` executable, then the output names that method. 3. Given flay raises an error, when `bin/dup-sweep` runs, then the script exits non-zero and shows the error. ## Owner sketch ```ruby class DupSweep def report(label, extra_args) puts "== flay (#{label}) ==" Flay.run([*extra_args, @target]).report end end class DeadCodeSweep def run Debride.run([@target]).report end end ``` ## Non-goals - Rubocop shell calls. They lint the invoking project in that project's bundle, so they stay shell calls (#845 audit). ## Origin - Trigger: #845 shell-call audit, 2026-09-30. - Improvised this session: none - Chain: sweep output can be empty with exit 0 ← flay and debride run as shell processes with status ignored (bin/dup-sweep, bin/dead-code-sweep) ← DESIGN: ADR-0061 - Root candidate: this ticket - Where: plugins/os-sdlc/bin/dup-sweep, plugins/os-sdlc/bin/dead-code-sweep - Session: f090dd39-8ad6-4f4e-8743-7bbedb8f08d4 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/f090dd39-8ad6-4f4e-8743-7bbedb8f08d4.jsonl
Author
Owner

Work started on branch ticket-851 (os-sdlc implement pipeline).

Work started on branch ticket-851 (os-sdlc implement pipeline).
Author
Owner

Resolution

Done: bin/dup-sweep and bin/dead-code-sweep now call Flay.run(...).report and Debride.run(...).report in-process; no flay/debride executable on PATH is needed.

Evidence: Commit 4043ed03 on ticket-851 (implementation 15): bin/dup-sweep, bin/dead-code-sweep, new tests/sweep_bins_test.rb. All os-sdlc gates passed: behavior-verifier, full suite, contract-auditor.

Follow-ups: none

## Resolution **Done:** bin/dup-sweep and bin/dead-code-sweep now call Flay.run(...).report and Debride.run(...).report in-process; no flay/debride executable on PATH is needed. **Evidence:** Commit 4043ed03 on ticket-851 (implementation 15): bin/dup-sweep, bin/dead-code-sweep, new tests/sweep_bins_test.rb. All os-sdlc gates passed: behavior-verifier, full suite, contract-auditor. **Follow-ups:** none
jared closed this issue 2026-09-30 17:46:48 +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#851
No description provided.