When a client asks "what exactly do you test?", this is the answer. Crawl Cove ships 35 deterministic checks across seven categories — HTTP, meta tags, content, links, security & images, an auto-detected WordPress pack, and AI-readiness checks.
Every check has a stable id, a semantic version, a default severity, and most expose tunable thresholds you can adjust per client in the Check Registry. Findings are keyed by (check id, URL), which is what lets the app compare runs and show honest deltas over time.
Note
Findings are deterministic — never guessed. Every row below is produced by a coded check function, not by an AI. The optional LLM layer only explains a finding in plain English; it can never invent, remove, or rescore one. When you put a number in front of a client, it came from a rule you can point to.
Why the version matters: when you improve a check, its semantic version changes, so run-to-run deltas stay honest rather than silently shifting because the rule moved under you. And because findings are keyed by (check id, URL), the same issue on the same page is tracked as one continuous thread across audits — the foundation of proving a fix worked.
Note
Accurate as of Crawl Cove 0.1.1 (26 June 2026). This reference reflects the check set shipping in the current release. Crawl Cove is actively developed, so future updates are likely to add new checks and categories — treat the count above as today's snapshot, not a permanent ceiling. Your installed version's Check Registry is always the authoritative, up-to-date list.
HTTP
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
status-code |
Critical | Pages that failed to fetch or returned 4xx/5xx. | — |
redirect-chain |
Low | Pages reached only after one or more redirects. | min chain length (1) |
Meta tags
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
title |
High | Missing/empty, wrong-length, or duplicated <title>. |
min 30 / max 60 chars |
duplicate-title |
High | Indexable pages sharing a title with others. | — |
meta-description |
Medium | Missing/empty or wrong-length meta description. | min 70 / max 160 chars |
duplicate-meta-description |
Medium | Indexable pages sharing a meta description. | — |
canonical |
Medium | Missing / non-absolute / uncrawled-target canonical. | — |
canonical-to-noindex |
High | Canonical points at a noindex/non-200 page. | — |
canonical-to-redirect |
Medium | Canonical points at a redirect, not the final URL. | — |
insecure-canonical |
Medium | HTTPS page canonicalised to its http:// version. |
— |
robots-noindex |
High | Surfaces pages carrying a noindex directive. |
— |
structured-data-missing |
Low | Substantive pages with no JSON-LD structured data. | min 100 words |
Content
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
heading-structure |
High | Not exactly one H1, or a skipped heading level. | expected H1s (1), max level jump (1) |
thin-content |
Low | Indexable pages below a word-count floor. | min 200 words |
content-depends-on-js |
Medium | Critical content/schema only present after JS runs. | text ratio (2×), delta (500 chars) |
Links
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
broken-internal-link |
High | Internal links to same-site URLs not found in the crawl (scope-aware). | — |
orphan-page |
Medium* | Indexable non-seed pages with zero internal inbound links. | — |
internal-link-to-redirect |
Medium | Internal links pointing at a redirect, not the final URL. | — |
excessive-crawl-depth |
Low | Pages too many clicks from the seed. | max depth (4) |
nofollow-internal-link |
Low | Internal links marked rel="nofollow". |
— |
dead-end-page |
Low | Pages with no outbound internal links. | — |
weakly-linked-page |
Low* | Pages with some but fewer than the recommended inbound links. | min inbound (2) |
internal-link-opportunity |
Info | Suggests contextual internal links to topically related pages. | shared terms (2), relatedness (0.18), max/page (5) |
non-descriptive-anchor-text |
Low | Generic anchors ("click here", "read more"). | — |
excessive-internal-links |
Low | Pages with too many internal links (sprawl). | max links (300) |
*Severity softens on partial/scoped crawls.
Note
The two checks marked with an asterisk — orphan-page and weakly-linked-page —
automatically soften their severity on partial or scoped crawls. Inbound
links may well exist on pages you chose not to crawl, so the app refuses to cry
"orphan" with full confidence when it can't see the whole link graph. Honesty
over false alarms.
Security & images
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
mixed-content |
High | HTTPS pages referencing insecure http:// resources. |
— |
image-alt |
Medium | Images missing alt text. | min images missing (1) |
WordPress (only on auto-detected WordPress sites)
These checks run only when the crawler auto-detects WordPress. A non-WordPress site gets zero WP probes and zero WP findings — see How the crawler behaves.
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
wp-generator-version-exposed |
Low | WordPress version leaked via the generator meta tag. | — |
wp-xmlrpc-reachable |
Medium | /xmlrpc.php publicly reachable (DDoS/brute-force vector). |
— |
wp-default-permalinks |
Low | Default ?p=N permalinks instead of pretty URLs. |
— |
wp-uploads-listing-open |
Medium | /wp-content/uploads/ returns an open directory index. |
— |
wp-missing-image-dimensions |
Low | Images without width/height (causes layout shift). | — |
AI-readiness
| Check id | Default severity | Detects | Tunable |
|---|---|---|---|
ai-bot-access |
Medium | AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended) blocked in robots.txt. | — |
ai-llms-txt |
Low | No /llms.txt content-map file present. |
— |
ai-extractability |
Low | Pages structurally hard for AI engines to quote (names the missing signals). | threshold score (50/100) |
Tuning these to a client
Every threshold above is a per-client default, not a hard-coded law. An e-commerce site with faceted URLs needs different link rules than a blog. In the Check Registry you can enable or disable any check per client, override its severity, and adjust its thresholds — all respected by the audit pipeline on the next crawl. See Tuning checks with the Check Registry.