Skip to content

ydah/necropsy

Repository files navigation

Necropsy

Necropsy is a Ruby dead-code detector built around a unified call graph. It collects method definitions with Prism, adds call-edge evidence from static and optional dynamic analyzers, then runs reachability from framework and configured entry points.

Necropsy includes:

  • Prism-based method collection for ordinary, singleton, delegated, aliased, forwarded, and dynamically defined methods
  • static name resolution, CHA, and RTA-style filtering over instantiated classes
  • Prism-backed Rails route parsing plus callback, view, component, migration, plain Ruby, and test-suite entry points
  • unreachable, unused, and test_only_reachable classifications
  • confidence levels, compact JSON/YAML reports, SARIF/GitHub output, CI guardrails, dynamic collectors, and benchmarking

Installation

Add the gem to the development/test group:

gem "necropsy", require: false

Usage

Create a baseline:

bundle exec necropsy baseline --root .

Run a report:

bundle exec necropsy analyze --root . --format human
bundle exec necropsy --version

Fail CI only for new high-confidence findings:

bundle exec necropsy check --root . --fail-on high

Record dynamic evidence from a Ruby script:

bundle exec necropsy record --root . --output tmp/necropsy_trace_point.yml -- script/runner.rb
bundle exec necropsy coverage --root . --output tmp/necropsy_coverage.yml -- script/runner.rb

Record Ruby Coverage while running an external command:

bundle exec necropsy coverage --root . --output tmp/necropsy_coverage.yml -- bundle exec rspec

Child Ruby processes inherit the collector and are merged into the same output for that run.

Evaluate against a gold standard:

bundle exec necropsy bench --root . --gold-standard gold.yml --ablation

JSON and YAML omit the full call graph by default. Add --include-graph when nodes, edges, evidence, and entry points are needed in machine-readable output.

Example configuration:

analyzers:
  static: [name_resolution, cha, rta]
  dynamic:
    coverage:
      source: tmp/necropsy_coverage.yml
      min_observation_days: 30
    coverband:
      source: redis://prod-redis:6379/2?key=coverband
    trace_point:
      source: tmp/necropsy_trace_point.yml
  custom:
    - class: "MyCompany::GraphqlEntryAnalyzer"
      require: "config/necropsy/graphql_entry_analyzer"
cache:
  enabled: true
  path: .necropsy_cache/scan.json
paths:
  include: ["app/**/*.rb", "lib/**/*.rb"]
  exclude: ["app/legacy/**/*.rb"]
entry_points:
  extra:
    - "PublicApi::*"
ci:
  fail_on: high
  baseline: .necropsy_baseline.yml
quarantine:
  days: 30
bench:
  precision_threshold: 0.85
logging:
  verbose: false

The scan cache is invalidated when scanned Ruby files or configuration values change.

Dynamic inputs may provide executed or nodes entries with method IDs, edges with caller_id/callee_id, and an observation hash. SARIF and GitHub Actions annotations are available via --format sarif and --format github.

Coverband file, Redis string, and Redis hash exports are supported. Redis URLs may include an ACL username and password; connect_timeout and read_timeout can be set in the Coverband analyzer configuration. Rails route entry point detection covers common resources, resource, namespace, scope, controller, concerns, draw, mount, root, and verb route forms.

necropsy quarantine --write adds # necropsy:quarantine since=YYYY-MM-DD. When the configured quarantine window expires and no alive evidence appears, the finding is raised to certain.

Development

After checking out the repo, run bin/setup to install dependencies. Then run bundle exec rake for the specs and RuboCop checks. Use bin/console for an interactive prompt.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub.

License

The gem is available as open source under the terms of the MIT License.

About

Hybrid dead-code detection for Ruby projects.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages