rails-doctor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +11 -0
  3. data/LICENSE +21 -0
  4. data/README.md +148 -0
  5. data/docs/adapter-architecture.md +21 -0
  6. data/docs/agent-handoff.md +22 -0
  7. data/docs/architecture.md +21 -0
  8. data/docs/cli-reference.md +48 -0
  9. data/docs/config-reference.md +50 -0
  10. data/docs/github-actions.md +36 -0
  11. data/docs/monetization.md +14 -0
  12. data/docs/output-schema.md +57 -0
  13. data/docs/scoring-model.md +23 -0
  14. data/examples/github-actions/rails-doctor.yml +40 -0
  15. data/examples/report.html +704 -0
  16. data/examples/report.json +971 -0
  17. data/examples/report.md +261 -0
  18. data/examples/report.txt +45 -0
  19. data/exe/rails-doctor +8 -0
  20. data/lib/rails_doctor/adapters/base.rb +109 -0
  21. data/lib/rails_doctor/adapters/brakeman.rb +47 -0
  22. data/lib/rails_doctor/adapters/bundler_audit.rb +54 -0
  23. data/lib/rails_doctor/adapters/dependency_freshness.rb +51 -0
  24. data/lib/rails_doctor/adapters/flay.rb +41 -0
  25. data/lib/rails_doctor/adapters/flog.rb +41 -0
  26. data/lib/rails_doctor/adapters/reek.rb +39 -0
  27. data/lib/rails_doctor/adapters/rubocop.rb +40 -0
  28. data/lib/rails_doctor/adapters/strong_migrations.rb +52 -0
  29. data/lib/rails_doctor/adapters/test_coverage.rb +400 -0
  30. data/lib/rails_doctor/adapters/test_runner.rb +79 -0
  31. data/lib/rails_doctor/adapters/zeitwerk.rb +42 -0
  32. data/lib/rails_doctor/agent/handoff.rb +159 -0
  33. data/lib/rails_doctor/checks/rails_checks.rb +371 -0
  34. data/lib/rails_doctor/cli.rb +232 -0
  35. data/lib/rails_doctor/command_runner.rb +55 -0
  36. data/lib/rails_doctor/config.rb +161 -0
  37. data/lib/rails_doctor/init/runner.rb +191 -0
  38. data/lib/rails_doctor/models.rb +280 -0
  39. data/lib/rails_doctor/project.rb +95 -0
  40. data/lib/rails_doctor/reporters/html.rb +400 -0
  41. data/lib/rails_doctor/reporters/json.rb +18 -0
  42. data/lib/rails_doctor/reporters/markdown.rb +132 -0
  43. data/lib/rails_doctor/reporters/terminal.rb +101 -0
  44. data/lib/rails_doctor/scanner.rb +173 -0
  45. data/lib/rails_doctor/scorer.rb +74 -0
  46. data/lib/rails_doctor/version.rb +5 -0
  47. data/lib/rails_doctor.rb +15 -0
  48. data/site/assets/cli-output.png +0 -0
  49. data/site/assets/report-preview.png +0 -0
  50. data/site/index.html +294 -0
  51. metadata +167 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 33475f8da3160d83e02d37cb0854981fee269452d9d6ec18ee40d928e8355c82
4
+ data.tar.gz: e21a6029b7fb00a519455fbca1a94f6f529e3dafc551c309629f6e017e752f3f
5
+ SHA512:
6
+ metadata.gz: d6b1afe0d88e480f68941c9e375324c67003775c2f3836bb4864f91270a8413074aea3e0f793f66ce758d0ddbb543d12392d3e10bf8f7b6de7bcf04f7a460e38
7
+ data.tar.gz: b6de0130d08f3467d220895d1d7f0d1a136e06a649c543fd396bffbee93d4313341813934e60a5c9b7f7cc25ca72f6e2d46c73d1744a5250e2b9337f0c936d5a
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial Rails Doctor CLI and gem scaffold.
6
+ - Added normalized findings, scores, hotspots, skipped-tool coverage, and profile support.
7
+ - Added adapters for RuboCop, Brakeman, Bundler Audit, Zeitwerk, Reek, Strong Migrations, Flog, Flay, dependency freshness, and test runtime signals.
8
+ - Added Rails-specific checks for index coverage, uniqueness backing, routes/views, artifact size, TODO density, and test counterparts.
9
+ - Added terminal, JSON, Markdown, and static HTML reports.
10
+ - Added conservative init workflow, GitHub Actions template, and explicit agent handoff.
11
+ - Added repository CI, Pages deployment, Dependabot, security policy, release docs, and copy-paste GitHub Actions examples.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rails Doctor Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # Rails Doctor
2
+
3
+ [![CI](https://github.com/joshsaintjacque/rails-doctor/actions/workflows/ci.yml/badge.svg)](https://github.com/joshsaintjacque/rails-doctor/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/rails-doctor.svg)](https://rubygems.org/gems/rails-doctor)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-teal.svg)](LICENSE)
6
+
7
+ Rails Doctor is a Rails health scanner for developers, CI, and AI coding agents.
8
+
9
+ It runs trusted Ruby/Rails tools, adds Rails-specific checks, and turns the results into one normalized report for humans and agents. The goal is simple: keep fast-moving AI-assisted Rails work from quietly accumulating technical debt.
10
+
11
+ ![Rails Doctor HTML report](site/assets/report-preview.png)
12
+
13
+ ![Rails Doctor CLI output](site/assets/cli-output.png)
14
+
15
+ ## Quickstart
16
+
17
+ ```sh
18
+ gem install rails-doctor
19
+ rails-doctor
20
+ ```
21
+
22
+ For a project setup pass:
23
+
24
+ ```sh
25
+ rails-doctor init --dry-run --ci
26
+ rails-doctor init --yes --ci
27
+ ```
28
+
29
+ Generate reports:
30
+
31
+ ```sh
32
+ rails-doctor --format json --output tmp/rails-doctor/report.json
33
+ rails-doctor --format markdown --output tmp/rails-doctor/summary.md
34
+ rails-doctor --format html --output tmp/rails-doctor/report.html
35
+ rails-doctor --profile ci --base origin/main --changed-only
36
+ ```
37
+
38
+ Hand high-severity findings to an agent explicitly:
39
+
40
+ ```sh
41
+ rails-doctor agent codex --severity high
42
+ rails-doctor agent codex --severity high --apply
43
+ ```
44
+
45
+ Normal scans never mutate your repo. Agent execution requires an explicit `agent` command and `--apply`.
46
+
47
+ ## What It Checks
48
+
49
+ Rails Doctor delegates to mature tools where they already do the job well:
50
+
51
+ - RuboCop and RuboCop Rails for lint/style/correctness
52
+ - Brakeman for Rails security
53
+ - Bundler Audit for vulnerable dependencies
54
+ - `rails zeitwerk:check` for autoloading
55
+ - Reek for code smells
56
+ - Flog for complexity
57
+ - Flay for duplication
58
+ - Strong Migrations for migration safety coverage
59
+ - Bullet or Prosopite signals captured through the configured test command
60
+ - SimpleCov result sets for line and branch coverage metrics
61
+
62
+ Rails Doctor-owned checks focus on Rails-specific gaps and synthesis:
63
+
64
+ - missing indexes on foreign keys
65
+ - uniqueness validations without unique DB indexes
66
+ - route/controller/action/view consistency
67
+ - conservative dead route/action/view hints
68
+ - large Rails artifact hotspots
69
+ - TODO/FIXME/HACK density
70
+ - missing test/spec counterparts for changed app files
71
+ - strict test coverage thresholds for aggregate and per-file coverage
72
+ - churn + quality hotspot scoring
73
+ - skipped-tool coverage gaps
74
+
75
+ ## Test Coverage Metrics
76
+
77
+ `ci` and `deep` profiles read `coverage/.resultset.json` after the configured test command runs. Rails Doctor expects SimpleCov to be configured by the app test suite; `rails-doctor init` recommends the `simplecov` gem but does not edit test boot files automatically.
78
+
79
+ Default thresholds are intentionally strict to make untested generated code visible:
80
+
81
+ - aggregate line coverage: `90%`
82
+ - per-file line coverage: `80%`
83
+ - branch coverage: unset by default, enforced when configured
84
+
85
+ Coverage appears in every report format. Low coverage emits normal `test-coverage` findings, so score and `--fail-on medium` gates can catch coverage regressions without a separate coverage gate.
86
+
87
+ ## Output Formats
88
+
89
+ The default terminal report is concise and human-readable.
90
+
91
+ `--format json` is the stable public contract for agents. It includes summary data, coverage metrics, findings, tool runs, scores, skipped tools, hotspots, metadata, fix guidance, and direct `agent_instruction` fields.
92
+
93
+ `--format markdown` is optimized for pull request comments and GitHub Actions summaries.
94
+
95
+ `--format html` produces a static self-contained dashboard with score, confidence, coverage, top fixes, filters, hotspots, agent brief, skipped tools, and raw tool output.
96
+
97
+ ## Profiles
98
+
99
+ - `fast`: static/local only, no tests, no network
100
+ - `recommended`: core static checks and configured local coverage
101
+ - `ci`: static checks, tests, runtime warnings, coverage metrics, and artifacts
102
+ - `deep`: CI plus deep quality, dependency freshness, and hotspot detail
103
+
104
+ ## GitHub Actions
105
+
106
+ `rails-doctor init --ci` can generate a workflow that runs Rails Doctor on pull requests, writes a Markdown job summary, and uploads JSON/Markdown/HTML artifacts. Use `--base origin/main` or the generated workflow's base-ref expression to separate inherited debt from changed-file risk.
107
+
108
+ You can gate PRs:
109
+
110
+ ```sh
111
+ rails-doctor --profile ci --fail-on critical
112
+ rails-doctor --profile ci --min-score 80
113
+ ```
114
+
115
+ ## Supported Versions
116
+
117
+ Rails Doctor targets modern Rails apps:
118
+
119
+ - Ruby `>= 3.2`
120
+ - Rails `>= 7.1`
121
+ - First-class Rails 8 support
122
+
123
+ The project test matrix covers Ruby 3.2, 3.3, and 3.4 against Rails 7.1, 7.2, and 8.x fixture scenarios where practical.
124
+
125
+ The repository CI includes tests, RuboCop linting, Bundler Audit dependency checks, a gem build dry-run, and GitHub Pages deployment for the public site.
126
+
127
+ ## Documentation
128
+
129
+ - [CLI reference](docs/cli-reference.md)
130
+ - [Configuration reference](docs/config-reference.md)
131
+ - [Output schema](docs/output-schema.md)
132
+ - [Scoring model](docs/scoring-model.md)
133
+ - [Adapter architecture](docs/adapter-architecture.md)
134
+ - [Architecture diagram](docs/architecture.md)
135
+ - [GitHub Actions](docs/github-actions.md)
136
+ - [Agent handoff](docs/agent-handoff.md)
137
+ - [Monetization path](docs/monetization.md)
138
+ - [Contributing](CONTRIBUTING.md)
139
+ - [Security policy](SECURITY.md)
140
+ - [Release process](RELEASE.md)
141
+
142
+ ## Static Site
143
+
144
+ The public marketing site lives in [site/index.html](site/index.html). The repository includes a GitHub Pages workflow that deploys the static site from `site/` on pushes to `main`.
145
+
146
+ ## Monetization Posture
147
+
148
+ Rails Doctor CLI is MIT-licensed and fully useful as open source. Future paid value belongs above the CLI: hosted report history, team policy management, GitHub App checks, org-wide trends, and agent remediation queues.
@@ -0,0 +1,21 @@
1
+ # Adapter Architecture
2
+
3
+ Adapters provide one contract:
4
+
5
+ 1. detect availability
6
+ 2. run a command or coverage check
7
+ 3. parse output into normalized findings
8
+ 4. return a `ToolRun` record
9
+
10
+ Rails Doctor delegates to mature tools instead of duplicating their domains:
11
+
12
+ - security: Brakeman
13
+ - lint/correctness: RuboCop and RuboCop Rails
14
+ - vulnerable dependencies: Bundler Audit
15
+ - code smells: Reek
16
+ - complexity: Flog
17
+ - duplication: Flay
18
+ - migration safety: Strong Migrations
19
+ - test coverage: SimpleCov result set reader
20
+
21
+ Rails Doctor-owned checks fill Rails-specific gaps and synthesize cross-tool signals for reports and agents.
@@ -0,0 +1,22 @@
1
+ # Agent Handoff
2
+
3
+ Rails Doctor is agent-ready by design, but normal scans are read-only.
4
+
5
+ ```sh
6
+ rails-doctor agent codex --severity high
7
+ rails-doctor agent codex --severity high --apply
8
+ ```
9
+
10
+ Without `--apply`, Rails Doctor writes a Markdown repair brief under `.rails-doctor/agent-briefs`.
11
+
12
+ Agent briefs include the current coverage summary and low-coverage files when `ci` or `deep` profiles capture SimpleCov metrics. Agents should use that section to add or update behavior tests before expanding low-coverage implementation code.
13
+
14
+ With `--apply`, Rails Doctor:
15
+
16
+ 1. filters findings
17
+ 2. writes the exact repair brief
18
+ 3. checks dirty-worktree policy
19
+ 4. invokes the configured agent command
20
+ 5. writes an audit JSON file under `.rails-doctor/agent-runs`
21
+
22
+ Rails Doctor never commits automatically in v1.
@@ -0,0 +1,21 @@
1
+ # Architecture
2
+
3
+ ```mermaid
4
+ flowchart LR
5
+ A[Rails app] --> B[Tool adapters]
6
+ A --> C[Rails Doctor checks]
7
+ B --> D[Normalized findings]
8
+ C --> D
9
+ B --> M[Coverage metrics]
10
+ M --> D
11
+ D --> E[Scoring]
12
+ D --> F[Hotspots]
13
+ D --> G[Terminal report]
14
+ D --> H[JSON schema]
15
+ D --> I[Markdown summary]
16
+ D --> J[HTML dashboard]
17
+ D --> K[Agent briefs]
18
+ K --> L[Codex / Claude Code / Cursor]
19
+ ```
20
+
21
+ Adapters run mature tools, normalize their output, and read SimpleCov coverage metrics. Rails Doctor-owned checks fill gaps, then every output format renders from the same report model.
@@ -0,0 +1,48 @@
1
+ # CLI Reference
2
+
3
+ ## `rails-doctor [scan]`
4
+
5
+ Runs a scan from the current Rails project root.
6
+
7
+ Options:
8
+
9
+ - `--profile fast|recommended|ci|deep`
10
+ - `--format terminal|json|markdown|html`
11
+ - `--output PATH`
12
+ - `--config PATH`
13
+ - `--changed-only`
14
+ - `--base REF`
15
+ - `--include-raw`
16
+ - `--fail-on info|low|medium|high|critical`
17
+ - `--min-score N`
18
+
19
+ `ci` and `deep` profiles read SimpleCov coverage metrics after the configured test command. Low coverage is reported as `medium` `test-coverage` findings, so existing severity and score gates can enforce it.
20
+
21
+ ## `rails-doctor init`
22
+
23
+ Detects the Rails app, writes `.rails-doctor.yml`, optionally writes GitHub Actions workflow files, and offers to install missing development/test tooling.
24
+
25
+ Options:
26
+
27
+ - `--profile NAME`
28
+ - `--dry-run`
29
+ - `--yes`
30
+ - `--install`
31
+ - `--ci`
32
+ - `--test-command COMMAND`
33
+
34
+ ## `rails-doctor agent AGENT`
35
+
36
+ Generates a repair brief for an AI coding agent. Supported adapter names are configurable; defaults are `codex`, `claude-code`, and `cursor`.
37
+
38
+ Options:
39
+
40
+ - `--profile NAME`
41
+ - `--severity SEVERITY`
42
+ - `--max-findings N`
43
+ - `--changed-only`
44
+ - `--base REF`
45
+ - `--apply`
46
+ - `--allow-dirty`
47
+
48
+ Without `--apply`, no external agent process is invoked.
@@ -0,0 +1,50 @@
1
+ # Configuration Reference
2
+
3
+ Rails Doctor reads `.rails-doctor.yml` from the project root.
4
+
5
+ ```yaml
6
+ profiles:
7
+ recommended:
8
+ adapters:
9
+ - rubocop
10
+ - brakeman
11
+ - bundler_audit
12
+ - zeitwerk
13
+ - reek
14
+ - strong_migrations
15
+ - rails_checks
16
+ commands:
17
+ test: bin/rails test
18
+ reports:
19
+ output_dir: tmp/rails-doctor
20
+ coverage:
21
+ enabled: true
22
+ source: simplecov
23
+ result_path: coverage/.resultset.json
24
+ include:
25
+ - app/**/*.rb
26
+ - lib/**/*.rb
27
+ max_files: 10
28
+ thresholds:
29
+ fail_on:
30
+ min_score:
31
+ coverage:
32
+ line: 90.0
33
+ file_line: 80.0
34
+ branch:
35
+ git:
36
+ churn_window_days: 90
37
+ base_ref:
38
+ agents:
39
+ codex:
40
+ command: codex exec
41
+ apply_requires_clean_worktree: true
42
+ ```
43
+
44
+ Profiles let teams choose fast local scans, CI coverage, or deeper quality analysis. Commands are strings because projects often run tools through Bundler, binstubs, Docker, or custom scripts.
45
+
46
+ Coverage metrics are read from SimpleCov's `.resultset.json` after the configured test command runs. Rails Doctor reports missing coverage as an informational coverage gap and reports low aggregate line coverage, low per-file line coverage, and any configured low branch coverage as normal `test-coverage` findings. `coverage.max_files` limits displayed low-file detail, not threshold evaluation.
47
+
48
+ Dependency freshness checks should only run in profiles where the team accepts network or cache use.
49
+
50
+ Set `git.base_ref` or pass `--base origin/main` in CI to compute changed-file scores against a pull request base instead of only considering uncommitted local changes.
@@ -0,0 +1,36 @@
1
+ # GitHub Actions
2
+
3
+ Rails Doctor supports two GitHub Actions surfaces:
4
+
5
+ 1. the Rails Doctor repository CI, which tests and packages the gem
6
+ 2. the generated Rails app workflow, which runs `rails-doctor` against application pull requests
7
+
8
+ ## Generated Rails App Workflow
9
+
10
+ Run:
11
+
12
+ ```sh
13
+ rails-doctor init --ci
14
+ ```
15
+
16
+ The generated workflow:
17
+
18
+ - runs on pull requests and manual dispatch
19
+ - installs Ruby with Bundler caching
20
+ - generates Markdown, JSON, and HTML reports
21
+ - appends Markdown to the GitHub Actions job summary
22
+ - uploads report artifacts
23
+ - supports optional PR comments through `RAILS_DOCTOR_PR_COMMENT`
24
+ - passes `--base origin/${{ github.base_ref || 'main' }}` for changed-file scoring
25
+ - reads SimpleCov coverage metrics from `coverage/.resultset.json` when the configured test command generates it
26
+
27
+ See [examples/github-actions/rails-doctor.yml](../examples/github-actions/rails-doctor.yml).
28
+
29
+ ## Threshold Gates
30
+
31
+ ```sh
32
+ bundle exec rails-doctor --profile ci --fail-on critical
33
+ bundle exec rails-doctor --profile ci --min-score 80
34
+ ```
35
+
36
+ Prefer `--fail-on critical` at first. Score gates are useful once a team has agreed on a baseline and understands how skipped tools affect confidence. Teams that want strict AI-generated-code guardrails can use `--fail-on medium` after SimpleCov is configured, because coverage regressions are emitted as medium-severity findings.
@@ -0,0 +1,14 @@
1
+ # Monetization Path
2
+
3
+ Rails Doctor's CLI is fully useful as free MIT-licensed software. The commercial path should stay above the local scanner rather than limiting OSS functionality.
4
+
5
+ Good future paid layers:
6
+
7
+ - hosted report history across repositories
8
+ - team policy management and approved scanner profiles
9
+ - GitHub App checks with hosted artifacts and comments
10
+ - org-wide trends for new vs inherited technical debt
11
+ - agent remediation queue with status tracking
12
+ - private benchmarks across repositories in an organization
13
+
14
+ V1 prepares for this by keeping JSON output stable, including repo/report metadata, preserving report artifacts, and avoiding any required login or hosted backend.
@@ -0,0 +1,57 @@
1
+ # Output Schema
2
+
3
+ `rails-doctor --format json` emits schema version `1.1`.
4
+
5
+ Top-level fields:
6
+
7
+ - `schema_version`
8
+ - `generated_at`
9
+ - `project_root`
10
+ - `profile`
11
+ - `metadata`
12
+ - `summary`
13
+ - `coverage`
14
+ - `findings`
15
+ - `hotspots`
16
+ - `tool_runs`
17
+
18
+ `coverage` is `null` for profiles that do not run the `test_coverage` adapter. When present, it contains:
19
+
20
+ - `available`
21
+ - `status`
22
+ - `source`
23
+ - `report_path`
24
+ - `line_percent`
25
+ - `branch_percent`
26
+ - `covered_lines`
27
+ - `missed_lines`
28
+ - `total_lines`
29
+ - `covered_branches`
30
+ - `missed_branches`
31
+ - `total_branches`
32
+ - `thresholds`
33
+ - `top_files`
34
+ - `low_file_count`
35
+ - `changed_files_below_threshold`
36
+ - `metadata`
37
+
38
+ `status` is one of `ok`, `below_threshold`, `missing`, `invalid`, `empty`, or `disabled`. Missing or empty coverage emits an informational `coverage-gap` finding. Invalid coverage emits a `tool-execution` finding. Aggregate line, per-file line, and configured branch thresholds emit normal `test-coverage` findings.
39
+
40
+ Each finding contains:
41
+
42
+ - `id`
43
+ - `severity`
44
+ - `category`
45
+ - `tool`
46
+ - `file`
47
+ - `line`
48
+ - `confidence`
49
+ - `message`
50
+ - `recommendation`
51
+ - `agent_instruction`
52
+ - `suggested_commands`
53
+ - `metadata`
54
+
55
+ Agents should treat `agent_instruction` and `suggested_commands` as guidance, not permission to mutate code. Mutation only occurs through an explicit agent workflow outside JSON report generation.
56
+
57
+ `metadata` includes detected Ruby and Rails versions, current branch, optional base ref, and changed files used for changed-file scoring.
@@ -0,0 +1,23 @@
1
+ # Scoring Model
2
+
3
+ Rails Doctor scores are communication aids. Findings are the source of truth.
4
+
5
+ Severity penalties:
6
+
7
+ - `critical`: 15
8
+ - `high`: 7
9
+ - `medium`: 3
10
+ - `low`: 1
11
+ - `info`: 0
12
+
13
+ Confidence changes penalty weight:
14
+
15
+ - `high`: 100%
16
+ - `medium`: 75%
17
+ - `low`: 40%
18
+
19
+ Skipped tools reduce report confidence rather than directly penalizing the health score. Reports show `overall_score` and `changed_files_score` so teams can separate inherited debt from new PR risk.
20
+
21
+ Coverage below the configured aggregate or per-file thresholds is represented as `medium` `test-coverage` findings. Those findings affect the health score like any other medium-severity issue, which lets existing gates such as `--fail-on medium` enforce coverage expectations.
22
+
23
+ Hotspots combine severity-weighted findings, Git churn, and changed-file status. In CI, pass `--base origin/main` or configure `git.base_ref` so changed-file score and hotspots are computed against the pull request base.
@@ -0,0 +1,40 @@
1
+ name: Rails Doctor
2
+
3
+ on:
4
+ pull_request:
5
+ workflow_dispatch:
6
+
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ rails-doctor:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ ruby: ["3.2", "3.3", "3.4"]
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+ - uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby }}
25
+ bundler-cache: true
26
+ - run: bundle exec rails-doctor --profile ci --base origin/${{ github.base_ref || 'main' }} --format markdown --output tmp/rails-doctor/summary.md
27
+ - run: bundle exec rails-doctor --profile ci --base origin/${{ github.base_ref || 'main' }} --format json --output tmp/rails-doctor/report.json
28
+ - run: bundle exec rails-doctor --profile ci --base origin/${{ github.base_ref || 'main' }} --format html --output tmp/rails-doctor/report.html
29
+ - name: Rails Doctor summary
30
+ run: cat tmp/rails-doctor/summary.md >> "$GITHUB_STEP_SUMMARY"
31
+ - name: Optional PR comment
32
+ if: github.event_name == 'pull_request' && vars.RAILS_DOCTOR_PR_COMMENT == 'true'
33
+ run: gh pr comment "$PR_URL" --body-file tmp/rails-doctor/summary.md
34
+ env:
35
+ GH_TOKEN: ${{ github.token }}
36
+ PR_URL: ${{ github.event.pull_request.html_url }}
37
+ - uses: actions/upload-artifact@v4
38
+ with:
39
+ name: rails-doctor-${{ matrix.ruby }}
40
+ path: tmp/rails-doctor