Rules reference
All 300+ audit rules organized by score group and category
squirrelscan includes 300+ rules across 22 categories, plus opt-in cloud gap analysis. Every category rolls up into one of four score groups: SEO, Performance, Security, and Agents. These are the four scores you see on reports and in the dashboard, alongside the overall health score.
Most rules run locally and need no login. A handful of cloud rules use AI analysis, full filter lists, or live search data - they require login and are skipped when you’re not logged in. Cloud rules carry a notice banner on their doc pages.
SEO
Search visibility: crawling, indexing, content, markup, and accessibility. SEO group overview →
Robots.txt, sitemaps, and crawl directives (20 rules)
Essential meta tags and page structure for search engines (14 rules)
Internal and external link health and structure (16 rules)
Text quality, readability, and content structure (24 rules)
Structured data and rich snippet eligibility (25 rules)
Image optimization and accessibility (15 rules)
Open Graph and social sharing metadata (5 rules)
Accessibility for users with disabilities (61 rules)
Mobile-friendliness and responsive design (8 rules)
URL structure, length, and formatting (9 rules)
Language declarations and multi-region support (2 rules)
Experience, expertise, authority, trust signals (15 rules)
Local business schema and NAP consistency (3 rules)
Video content markup and accessibility (3 rules)
Tracking and measurement implementation (2 rules)
Keyword and content gaps backed by live search data (2 rules, opt-in)
Performance
Page speed and loading behavior. Performance group overview →
Page speed and loading performance (30 rules)
Runtime errors, broken resources and failed requests (2 rules)
Security
Transport security, compromise signals, compliance, and blocked content.
Signs of compromise: injected pages, phishing kits, malware, SEO spam (9 rules)
HTTPS, headers, and safe link practices (22 rules)
Privacy policy and legal compliance signals (4 rules)
Content, links, and trackers blocked by ad blockers and privacy filters (3 rules)
Agents
Agent Experience (AX): whether AI agents can read, reach, discover, and act on your site: a first-class score alongside SEO, Performance, and Security, not an afterthought. Covers five pillars: readable (no-JS content, token weight, Markdown), reachable (crawler access, behavioral blocking), discoverable (llms.txt, AGENTS.md, agent manifests), declared (Content-Signal, noai, RSL licensing), and actionable (API/OAuth discovery, pay-per-crawl).
Content inside noscript
A browser with scripting enabled reads <noscript> content as plain text, so nothing in it loads, renders or reaches the accessibility tree. Sites put tracking pixels, Google Tag Manager iframes, lazy-load fallback images and fallback stylesheets there for visitors without JavaScript, so reporting them flags markup that never runs.
The rules that describe what a browser loads or renders skip elements inside <noscript>, so a page with a <noscript> fallback gets the same result as the same page without it:
- Accessibility: aria-required-children, frame-title, image-redundant-alt, meta-refresh
- Images: alt-text, aspect-mismatch, broken-images, dimensions, filename-quality, lazy-loading, modern-format, offscreen-lazy, optimized, picture-element, responsive-size, srcset
- Performance: animated-content, carousel-hidden-eager, cls-hints, critical-request-chains, duplicate-js, font-delivery, font-loading, inp-hints, js-libraries, lazy-above-fold, lcp-fetchpriority, lcp-hints, legacy-js, preconnect, render-blocking, source-maps, total-byte-weight, unminified-css, unminified-js
- Security: csp-blocks-own-resources, mixed-content, sri, third-party-cookies
- Blocking and integrity: blocked-links, template-discontinuity
Same-domain scripts, stylesheets and images that appear only inside <noscript> are not fetched for the file-size and compression rules either. Links inside <noscript> are still collected for crawling, and the remaining rules read the page as before.
Pages kept out of search
A page marked noindex will not show up in search results, so findings about how it would look there are noise. Ten rules leave these pages alone:
- core/meta-title, core/meta-description, core/h1 and content/word-count skip the page. Each records one skipped check, such as
Skipped: page is set to noindex via robots meta tag(orvia X-Robots-Tag header), in place of its usual result. - core/title-unique, content/duplicate-title and content/duplicate-description leave the page out when they group pages by title or description.
- crawl/sitemap-coverage never lists the page as missing from the sitemap, since a noindex page should not be in it.
- content/title-pattern-outlier leaves the page out when it learns the site’s title template, and never reports it as an outlier.
- links/orphan-pages never reports the page as an orphan. Its own links still count toward the pages they point to.
What counts as noindex. The page’s <meta name="robots"> content or its X-Robots-Tag response header contains noindex. This is the same test crawl/indexability uses, so a header scoped to one crawler, such as X-Robots-Tag: googlebot: noindex, counts too. A URL blocked by robots.txt is not a noindex, and crawler-specific meta tags such as <meta name="googlebot"> are not read.
Staging sites and preview deployments. Pages are skipped only when the site itself is being indexed. squirrelscan decides that from the homepage, which is the page at / on the audited host (with or without www., over http or https, with no query string), or, when the homepage was not fetched or answered with an error, from the page the audit started from. If the crawl holds more than one copy of that page, such as both the http and https homepage, any copy marked noindex counts.
| That page is | Result |
|---|---|
| indexable | noindex pages are skipped |
| noindex | nothing is skipped |
| not fetched (neither the homepage nor the start page) | nothing is skipped |
A site-wide noindex usually means the audit is checking a site before launch, which is when title, description and H1 findings matter most. Vercel, Netlify and Cloudflare Pages preview deployments send X-Robots-Tag: noindex on every page by default, so an audit of a preview URL runs every rule.
In reports and scores. A skipped check is not an issue. It does not appear in the issue list in any report format, it is not counted as passed, warning or failed, and the health score leaves it out. A page left out of a site rule’s grouping simply is not in it.
Everything else still runs. Accessibility, security and performance rules, and every link rule other than orphan pages, check noindex pages as usual, and so do core/robots-meta, crawl/indexability and crawl/all-noindex-pages, which report the noindex pages themselves.
Rule time budget
Rules read content the audited site controls, so a page can be built to make a pattern match very slowly. The first line of defence is the rules themselves: their patterns are written to avoid catastrophic backtracking. The time budget is the backstop for whatever still gets through, such as a rule repeating a slow match across thousands of elements or pages.
Every rule runs under it: two seconds per page for a page rule, and two seconds per page of the site for a site rule, capped at 60 seconds. A rule that runs past it is abandoned for that page, and the audit carries on with the next rule. The budget is checked between operations, not in the middle of a single pattern match, so a rule can overrun it by about one runaway match before it is abandoned: in testing, a 200 ms budget abandoned a catastrophic pattern after about 430 ms, roughly twice the budget. It is wall-clock time, so on a heavily loaded machine an ordinary page can run out of time too.
The report records it as a skipped check named after the rule with -error on the end, such as content/hidden-text-error, on every page where it happened, the first one included (or on the whole site, for a site rule). Its skipReason is rule-timed-out and its message is Rule not evaluated: exceeded its 2000 ms time budget and was abandoned (the number is the budget in force). Its details carry timedOut: true, the ruleId, the budgetMs in force, elapsedMs (how long the rule had actually run when it was stopped, which is a little over the budget on an idle machine and far over it when the machine was starved of CPU) and pages, the number of pages it timed out on. elapsedMs is for diagnosing a timeout and is never scored or counted. A timed-out rule is not a finding: the rule did not finish, so nothing was found on that page, and the page is not evaluated for it. It is not counted as a failed check and it does not lower the score: the health score is the same as if that page had been left unchecked for that rule. The audit also gets one info check named after the rule with -timeouts on the end, such as content/hidden-text-timeouts, whose details carry pagesNotChecked, the final count of pages that rule did not check, and maxElapsedMs, the longest the rule ran before it was stopped. The console, text, markdown, HTML, XML and LLM reports also print a yellow Not checked: <rule>. line for each rule that timed out, with a hint to run the audit again or raise time_budget_ms, so a timed-out security rule is never mistaken for a clean one. That rule’s own result for those pages is not in the report.
A timed-out rule did not check those pages. For a security rule, such as security/leaked-secrets, that means no finding on those pages is not a clean result: the pages were not scanned, so treat them as unchecked and look at them yourself. So a security rule that times out is counted by --fail-on as one warning-severity finding (warnings>0 and severity>=warning trip on it, errors and score do not, so a gate that only uses those two passes: add a warning gate or raise time_budget_ms), while the score stays as if the page had been left unchecked. The count appears only in the gate summary, never as a finding in the report. The report and the gate summary name the rule and the number of pages it did not check, so a page built to make a security rule time out cannot leave a quiet pass. Rules in other categories are not counted by the gate.
Ordinary pages never come close on an idle machine: the slowest rule takes a few milliseconds per page. If you see this on a page that looks normal and the machine was not busy, open an issue with the page URL.
Changing the budget
Set time_budget_ms in the [rules] section of squirrel.toml:
[rules]
time_budget_ms = 3000 # three seconds per rule per pageRaise it when rules time out on ordinary pages because the machine is slow or busy, such as a shared CI runner. A value below 1000 is refused. A site rule gets the same amount per page of the site, capped at 60 seconds, or at the budget itself if you set it above that. 0 turns the budget off, which lets one hostile page stall the audit, so leave it on for sites you do not control. The setting applies to audits the CLI runs; cloud audits use the default.
Configuration
Enable/Disable rules
Use glob patterns in squirrel.toml:
[rules]
# Enable specific rules or categories
enable = ["*"] # all rules (default)
# Disable specific rules
disable = [
"ax/*", "ai/*", # disable all Agent Experience rules
"content/word-count", # disable specific rule
]Rule options
Some rules have configurable options:
[rules."core/meta-title"]
min_length = 30
max_length = 75
[rules."content/word-count"]
min_words = 300See individual rule pages for available options.