Audit rules

lumen’s audit engine ships 18 built-in rules across meta, content, links, technical, performance, accessibility and social categories. Rules are small, evidence-first, and plugin-shaped — the audit engine accepts additional rules via the plugin registry.

Severity model

Three severities, no vibes:

SeverityWeightMeaning
error10wrong or broken for search
warning3likely costing you something
info0worth knowing, not a failure

failThreshold (in lumen.config.json) picks the lowest severity that fails the run — error by default.

Scoring

Per-page score = 100 minus the weight of that page’s issues, floored at 0. Report score = the mean over audited pages. A site where nothing was actually audited scores 0 — honest, not generous.

The 18 rules

Rule idDefaultCategoriesFires when
title-missingerrormetano <title> or empty after trim
title-lengthwarningmetatitle longer than 65 or shorter than 15 characters
description-missingerrormetano meta description or empty
description-lengthwarningmetadescription longer than 165 or shorter than 50 characters
h1-missingerrorcontentzero <h1> elements
h1-multipleinfocontentmore than one <h1>
canonical-presentinfometano <link rel="canonical"> (multiple canonicals raise to warning)
lang-attrwarningcontent<html lang> missing or not a plausible BCP-47 primary tag
viewport-metawarningtechnicalno <meta name="viewport">
image-alt-coveragewarningcontent, accessibilityany <img> without an alt attribute (alt="" counts as present)
broken-internal-linkerrorlinkssame-host link target fetched during the crawl returned status >= 400
redirect-chainwarninglinks, technicalpage needed two or more redirect hops to resolve
robots-noindexinfometa, technicalnoindex via meta robots or X-Robots-Tag header
status-errorerrortechnicalfetched page status >= 400
insecure-httpwarningtechnicalpage served over plain http:
mixed-contenterrortechnicalhttp: subresources on an https: page
response-latencywarningperformancemeasured response time above the threshold (default 1500 ms)
og-tags-missinginfosocialany of og:title / og:description / og:image absent

Length thresholds (title, description) and the latency threshold are configurable; everything else is fixed behavior. Crawl rules (broken-internal-link, redirect-chain) only fire on evidence gathered during the crawl itself — a link target that was never fetched is reported as unknown, not invented.

Overrides

Per-rule severity overrides live in severityOverrides in lumen.config.json. An unknown rule id is a config error listing the valid ids — see configuration.

Issue + incomplete reports

An Issue looks like this (evidence snippets are escaped):

{
  "ruleId": "title-length",
  "severity": "warning",
  "message": "title is 72 characters (max 65)",
  "evidence": { "selector": "head > title", "snippet": "<title>Acme Garden Tools — hand-forged broadf…</title>" },
  "fixHint": "shorten the title to 65 characters or fewer"
}

Interrupted runs are labeled rather than dressed up as finished:

{
  "id": "example-2026-08-29t10-31-04z",
  "incomplete": true,
  "summary": { "pagesAudited": 37, "pagesSkipped": 3 },
  "stopReason": "time_budget"
}