class

Hwaro::Services::Doctor

Inherits Reference < Object

Constants

KNOWN_ISSUE_IDS = begin ids = Set(String).new CHECK_GROUPS.each do |group| group.checks.each do |spec| spec.issue_ids.each do |id| ids << id end end end ids end

Every static issue id doctor can emit, derived from CHECK_GROUPS so a new diagnostic can't be validated against a list that forgot it. CHECK_GROUPS is the registry; this is just its index.

MISSING_SECTION_ID_PREFIX = "missing-config-"

missing-config-<section> ids are generated per config section rather than enumerated, so [doctor] ignore validation matches them by prefix.

OPTIONAL_SECTIONS = Set {"pwa", "amp", "image_processing", "image_processing.lqip", "og.auto_image", "build", "deployment", "permalinks", "auto_includes", "links", "assets", "sass", "related", "series", "pagination", "git", "menus", "content.new", "robots", "llms", "serve"}

Sections that are advanced/niche or low-value for most users. These are now treated as opt-in by default (not auto-suggested in normal doctor, and not added by plain --fix unless the user explicitly wants them).

Goal: Reduce config bloat and the "you should add all these things" pressure.

UNKNOWN_TAG_RE = /\Ano tag with name "([^"]+)" registered/

Crinja's FeatureLibrary::UnknownFeatureError message for a tag.

VALID_CHANGEFREQS = Models::SitemapConfig::VALID_CHANGEFREQS
VALID_MATH_ENGINES = ["katex", "mathjax"] of ::String

Mirrors MarkdownConfig#initialize defaults — only katex/mathjax render math at runtime; other strings load nothing.

VALID_SEARCH_FORMATS = ["fuse_json", "fuse_javascript", "elasticlunr_json", "elasticlunr_javascript"] of ::String

Constructors

new(content_dir : String = "content", config_path : String = "config.toml", templates_dir : String = "templates", static_dir : String = "static", env : String | Nil = nil)
Source

Class methods

content_schema_results(content_dir : String, config : Models::Config, ignore : ContentWalk::Ignore = ContentWalk.ignore_rules(content_dir)) : Array(Tuple(String, Content::FrontMatterSchema::Result))

The build's [[content.schema]] check over the regular pages a default build publishes (ContentLister, plus [[content.generate]] pages), with section cascades resolved by the build's own build_cascade_map / merged_cascade_for. {file, result} per checked page, in path order. Shared by doctor and tool validate.

Source
default_titles

The scaffolded placeholder titles. Models::Config falls back to "Hwaro Site" when title is absent, and every site hwaro init creates ships its scaffold's placeholder — so checking only the internal fallback meant the advisory never fired on the sites that actually have a placeholder title, and it shipped into <title>, OG tags and feeds unnoticed.

Sourced from the scaffold registry rather than a hand-kept literal list: hardcoding "My Hwaro Site" silently exempted every --scaffold blog|docs|book site, which ships "My Blog" / "My Docs" / "My Book". A new scaffold now joins the check automatically.

Source
known_issue_id?(id : String) : Bool

True for any id [doctor] ignore can legitimately name.

Source
schema_issue(v : Content::FrontMatterSchema::Violation) : Issue
Source

Instance methods

fix_config(approve_sections : Bool = false, dry_run : Bool = false, apply_value_fixes : Bool = true) : FixSummary

Apply real fixes (Phase 1: value corrections like base_url trailing slash) and optionally approve/add recommended config sections (Phase 2).

  • apply_value_fixes: Phase 1 value corrections. --fix and --full enable this; a bare --approve must NOT edit real values — the documented model is "--fix normalizes, --approve adds sections".
  • approve_sections: When true, doctor will add the recommended/optional config sections as commented documentation (--approve / --full).

This separation makes --fix focused on corrections, while --approve / --full controls bringing in the larger set of recommendations.

Source
missing_config_sections

Returns the list of config section keys missing from the user's config.toml. On I/O or TOML parse failure, returns an empty array — those paths are already reported by check_config as classified issues, so silent-empty here lets the main run loop carry on without double-reporting. Callers that need a clearer signal (e.g. fix_config) should probe the file directly via readable_config_toml / parse_config_toml.

Source
observed_blocking_ids

The blocking ids the last run observed, recorded BEFORE the [doctor] ignore filter. The CLI's skip rule keys off this rather than off the returned issues: content-dir-missing is a warning, so ignore = ["content-dir-missing"] used to hide it AND take the whole content/ group's skip state with it — every check in the group went back to rendering ✓ for a site with no content directory at all, which is the false all-clear this mechanism exists to prevent. Silencing a report is not the same as the scan having run.

Source

Nested types