The design playbook, run on your real code.
SOLID, the Gang-of-Four patterns, and the package cohesion and coupling principles, measured from your real call graph. Each result names a method or file to move, and where it goes.
Three surfaces. The ra CLI, and CI, print the full report. The editor
shows the in-file moves (feature envy and fat interfaces) as LSP hints with
quick-fixes. Over MCP, an agent requests recommendations across the codebase, or
for a single method or class.
feature_envy
Move a method to where it belongs. A method that sends most of its calls to another object and barely touches its own. It names the object to move it onto, from real call counts.
See more →split_interface
Split a fat interface. A class whose callers each use a different slice of it. It names the role interfaces to split it into, measured from who actually calls what.
See more →relocate_file
Which file should move where. Two files that lean on each other constantly but sit directories apart. The graph names the folder they belong in, weighed by real call traffic and the distance between them.
See more →break_cycle
Cut a dependency cycle. Files or namespaces caught in a runtime dependency cycle, flagged with the single lowest-traffic edge to sever to break the loop.
See more →stabilize_dep
Point dependencies at stability. A stable module, with many callers and few dependencies, reaching into a less stable one. Measured from real call traffic, so you can depend toward stability or put an abstraction between them.
See more →split_package
Split a package used in parts. Consumers that pull in a whole namespace but touch disjoint pieces of it. Split it so nobody takes a dependency on code they never call.
See more →check_diff
Catch it in review. Point it at a branch or PR and it flags only what the change introduced, before it lands: a drifted mock, a fresh dependency cycle, new feature envy.
See more →$ ra refactor --cohesion feature envy · app/models/enrollment.rb Enrollment#eligible_books → 9 calls to Curriculum, 1 to self move it onto Curriculum SRP misplaced file · cohesion app/models/invoice.rb ⇄ app/billing/proration.rb 4,102 calls, no other caller; split across models and billing gather both into app/domains/billing CCP dependency cycle · packaging reporting → enrollment → reporting cut Enrollment#report_row — 1 caller, the only edge closing it ADP
Every line is measured: real call counts, real directions, the actual distance between files. The call graph turns feature envy, misplaced code, cycles, and unstable dependencies each into a concrete move.
It also runs on a diff, not just the whole repo. ra check reports only what a branch
or PR introduced, as a CLI/CI gate or over MCP, so a regression is caught in review instead of
after it ships.