Drupal is a registered trademark of Dries Buytaert
Release: Leaflet 10.4.11 Minor update available for module leaflet (10.4.11). Release: Session Inspector 1.0.8 Minor update available for module session_inspector (1.0.8). Release: Migrate QA 2.0.4 Minor update available for module migrate_qa (2.0.4). Release: CKEditor Description List 3.0.0 Major update available for module ckeditor_descriptionlist (3.0.0). Release: FlowDrop 2.4.0 Minor update available for module flowdrop (2.4.0). Release: JWT Token Refresh 1.0.4 Minor update available for module jwt_token_refresh (1.0.4). Release: ConReg 1.0.0-beta1 First beta version released for module conreg (1.0.0-beta1). Release: AI Image Studio 1.0.0-beta8 New beta version released for module ai_image_studio (1.0.0-beta8). Usage Milestone: Role Theme Switcher Module role_theme_switcher crossed 1,000 active installs. Module Revived: Decoupled Router 2.0.7 Module decoupled_router updated after 11 months of inactivity (2.0.7).

Site Doctor

1 sites No security coverage
View on drupal.org

Site Doctor provides scheduled, read-only diagnostics for your Drupal site to track its health over time. It identifies issues like pending updates, configuration drift, and permission risks, and reports on changes, trends, and historical data through a web interface and CLI commands. The module helps maintain site health by offering insights for proactive management and automation.

Site Doctor helps you answer a simple question that gets harder as a Drupal site ages: "is my site healthy — and is it getting better or worse?"

It runs read-only diagnostic checks (pending updates, configuration drift, permission risks, dormant accounts, unused leftovers) on a schedule and — unlike a one-time audit — remembers what it finds: every finding carries a stable fingerprint, so the built-in report shows what appeared this week, what stopped being found, what got worse, and what has been quietly degrading for months. It is not a database/query monitor (see Site Health) and not a per-request developer profiler (see Webprofiler) — Site Doctor tracks site-level diagnostic findings over time.

Every result is a projection of the same structured schema: a plain-language report page with history and trends; CLI commands on both Drupal core's new dr CLI and Drush, with CI-friendly output and exit codes for your deployment pipeline; and machine-readable output that automation and AI agents can consume. Site Doctor never mutates site configuration or content — it writes only to its own reporting tables, with configurable retention. There is no auto-fix: it diagnoses and reports; fixing remains a deliberate human decision.

Features

The report page and results store (new in 1.0.0-alpha2):

  • Scheduled check-ups via cron (frequency configurable, default daily); CLI runs are stored too, with a per-run opt-out.
  • The report at /admin/reports/site-doctor, in plain language: current problems with an age breakdown, a filterable "what changed" timeline (new / no longer found / got worse / improved, with fix guidance), severity trends charted over time, and an Inventory — facts on file about the site (every permission grant, configuration overrides, the declared workflow) with their own change history, kept apart from problems. Every filtered view is a bookmarkable URL.
  • Honest history: disabling a check is recorded, never silent — frozen findings say why and since when; a category-filtered run declares itself partial and can never fabricate "resolved".
  • Configurable retention with the horizons printed on the views they bound; the store monitors its own purging as a check like any other.

Checks:

  • Pending updates (system) — pending database/post-deployment updates (code deployed ahead of the database, or a deploy script that swallowed a failure) and mismatched entity/field definitions — the chronic class that drush updb does not fix.
  • Maintenance mode (system) — the site was left in maintenance mode.
  • Permission risk audit (security) — permissions flagged "restrict access" granted to the anonymous role (Error) or to authenticated/other non-admin roles (Warning); admin roles are exempt by contract.
  • Permission grants inventory (security, new in alpha2) — the full (role, permission) inventory as memory rather than judgment: the report's Inventory answers "when did this role gain that permission?" with a stored date, for every grant — not only the risky ones. Never gates CI.
  • Dormant privileged accounts (security) — active accounts holding admin or restricted-permission roles with no login past a configurable threshold (default 180 days); never-logged-in accounts included.
  • Configuration drift classifier (config) — compares active configuration against your sync directory and frames each difference by consequence: what the next config:import would delete, revert, or re-create. Severity follows your declared workflow (sync, active, or auto): sync-disciplined sites get CI-gating Warnings; recipe-era and site-builder sites that treat active storage as the source of truth get a never-nagging Info inventory instead. Also aggregates all runtime config overrides (settings.php / modules) site-wide, reporting the overridden key paths — never the values, which is where secrets live.
  • Entropy checks (advisory — never gate CI) — unused image styles, orphaned view modes, roles with no users, unused text formats.
  • Results store health (new in alpha2) — Site Doctor applies its own machinery to itself: a stalled retention purge is a Warning like any other finding.
  • Extensible by design: drop a check plugin in any module — site-specific business rules become first-class findings on every surface, history included. See CONTRIBUTING.md and AGENTS.md in the repository.

Query commands (answers, not checks):

  • site-doctor:who-can PERMISSION — which roles hold a permission and through which path (explicit grant, admin role, user-1 super-user policy), with user counts — the questions ad-hoc reasoning (human or LLM) reliably gets wrong.
  • site-doctor:role-diff ROLE_A ROLE_B — compare the explicit permission sets of two roles.
  • Roadmap: read commands over the stored history ("what changed since last week?" from the CLI), and pluggable queries — define a site-specific lookup as one Query plugin and it derives a CLI command on both dr and Drush and a typed MCP tool, giving AI agents safe, bounded answers about your site instead of improvised database queries.

Checks (roadmap):

  • Cron and queue health (a stuck queue with 40k items is invisible today).
  • Dangling entity reference auditor (references to deleted targets, media pointing at missing files).
  • Extension risk report (release age, security coverage, unused-module signals).
  • Route latency sampler (production-safe p50/p95 per route, week-over-week regressions — zero external infrastructure).
  • Runtime deprecation telemetry (which deprecated code paths actually execute in production, ranked by hit count — prioritize your next major upgrade by real impact).
  • Content model export (Mermaid/JSON description of your bundles, fields, and references — documentation and agent context).

Surfaces:

  • The report page at /admin/reports/site-doctor and a settings form at /admin/config/development/site-doctor, each behind its own restrict-flagged permission.
  • CLI on both Drupal core's dr (11.4+) and Drush 13+ from one implementation: site-doctor:check [category] --format=table|json|junit|llm. Exit codes are a frozen contract: 0 ok/info, 1 warnings, 2 errors, 3 the diagnosis itself failed (a crashed check never aborts the run — the rest still report). Machine envelopes declare their scope: a category-filtered run can never be mistaken for full coverage.
  • --format=llm — self-describing, bounded output for AI agents: embedded severity semantics and exit-code map, truncation markers on long evidence, staleness fields on every result.
  • Status report summary line at /admin/reports/status, including collection staleness.
  • Tool API integration (roadmap): each check and query exposed as a tool so AI agents and MCP clients can query site health instead of guessing.

Use cases:

  • Pre-deployment CI gate ("fail the pipeline on dangerous config drift"), post-deploy verification ("did updates actually run?"), monthly maintenance review with the "what changed" timeline, incident forensics ("when did that role gain that permission?"), upgrade planning, security/permission audits, handover audits of inherited sites, and giving AI agents accurate structured facts about the site.
  • And the part only your own code can supply: site-specific checks encode your business rules ("every product needs a hero image", "this role must never gain that permission") as one small plugin class in your custom module, and it automatically gets every surface: both CLIs, all output formats, CI exit codes that can gate your deployments, and the full trend history. Agencies can ship one internal check pack across every client site.

Post-Installation

Enable the module, then:

  1. Run drush site-doctor:check (or dr site-doctor:check on Drupal 11.4+) for the first check-up, and open /admin/reports/site-doctor. With cron running, check-ups collect on a schedule from here on (default daily).
  2. Visit /admin/config/development/site-doctor to declare your configuration workflow (so drift severity matches your reality), set the check-up frequency and retention, and switch off any checks you don't want — switching off is always recorded, never silent.
  3. For CI: run drush site-doctor:check --format=junit in your pipeline and gate on the exit code.

No content types, fields, or front-end output are created. All checks are read-only toward your site: Site Doctor writes only to its own four reporting tables, and retention keeps them bounded.

Additional Requirements

None beyond Drupal core (Drupal 11, PHP 8.3+). Drush 13+ is optional — core's dr CLI (11.4+) is fully supported. Individual checks degrade gracefully: a check whose subject doesn't exist on your site reports "not applicable", never a false pass.

Site Doctor deliberately does not duplicate established tools — it complements them and links to them from findings where relevant:

  • Upgrade Status — static deprecation analysis (Site Doctor's runtime telemetry will tell you which of those findings matter in production).
  • Security Review — security best-practice checklist (Site Doctor's security category covers what a checklist can't: reverse lookups, grant-path analysis, account dormancy).
  • Linkchecker — external/content link checking (Site Doctor will cover entity-reference integrity only).
  • Site Audit — use it today for one-shot scored audit reports; see also Similar projects below.
  • Tool API / MCP Server — enables the agent-facing tool surface (roadmap).

Similar projects

  • Site Audit — point-in-time static best-practice checks via Drush. Site Doctor differs in its design around recorded history/trends (in development), production runtime telemetry (roadmap), and results exposed to CI and AI agents (available now: severity-mapped exit codes, junit, and an agent-oriented output format).
  • Healthcheck — similar plugin-based concept from the Drupal 8 era, including historical reports. Site Doctor is a Drupal 11-native take with runtime telemetry and an agent/automation surface.
  • Webprofiler — per-request developer profiling: deep, dev-only, heavyweight. Site Doctor's roadmap latency sampler is the inverse instrument: production-safe 1-in-N sampling, p50/p95 per route trended over time. The sampler finds which route regressed; webprofiler dissects why, in dev.
  • Site Health — database query monitoring (slow queries, per-statement statistics). Site Doctor is route- and site-level over time, not a query profiler.
  • Monitoring — sensor integration with external monitoring stacks (Icinga, etc.). Site Doctor is self-contained with no external infrastructure.
  • health_check / health_check_url and similar — uptime ping endpoints for load balancers; a different problem entirely.

Supporting this Module

Issues, reviews, and merge requests are welcome — the check plugin API is
designed so a new check is a small, self-contained contribution: one plugin
class implementing collect(), one kernel test extending the provided
CheckKernelTestBase, and it automatically appears on every surface.

Community Documentation

The README ships with the module: usage on both CLIs, CI integration with
exit-code semantics, configuration guide (including how to choose your
config workflow), and a writing-your-own-check guide. GitHub Actions
examples and a fuller tutorial are planned as the module matures.

AI-assisted development disclosure: this module is developed with AI
coding assistance under human direction and review. All code is
human-reviewed before commit; every check ships with kernel tests that
encode its expected behavior, and CI (phpcs, phpstan, phpunit, cspell,
code coverage) gates every merge request.

Activity

Tracked releases
3
Tracked since
Jul 2026
Latest release
1 month ago
Releases (12 mo)
3 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Release date
1.0.0-alpha2 Pre-release Jul 7, 2026
1.x-dev Dev Jul 5, 2026
1.0.0-alpha1 Pre-release Jul 5, 2026