@pseolint/mcp 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 ouranos-labs
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ouranos-labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > MCP server for pseolint — audit pSEO sites by template from AI coding assistants.
4
4
 
5
- An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that exposes [pseolint](https://www.npmjs.com/package/pseolint) v0.7.0 auditing tools to AI coding assistants like Claude Code, Claude Desktop, Cursor, and Windsurf.
5
+ An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that exposes [pseolint](https://www.npmjs.com/package/pseolint) v0.7.3 auditing tools to AI coding assistants like Claude Code, Claude Desktop, Cursor, and Windsurf.
6
6
 
7
7
  All tools are namespaced with a `pseolint_` prefix (`pseolint_audit_site`, `pseolint_explain_score`, `pseolint_check_page_technical`, `pseolint_orchestrate_audit`) so they don't collide with other MCP servers, and each returns both human-readable text and machine-readable `structuredContent`.
8
8
 
@@ -91,7 +91,8 @@ Run a full pseolint audit on a URL or directory path. Returns the site-level ver
91
91
  - `threshold` — Score threshold for pass/fail (default: 40)
92
92
  - `sampleSize` — Audit a random subset of N pages (0 = all)
93
93
  - `format` — Output format: `console` or `json` (default: console)
94
- - `authorityScore` — 0-100 domain authority hint. ≥80 shifts verdict one tier lenient; ≤30 shifts one tier stricter.
94
+ - `authorityScore` — 0-100 domain authority hint. ≥80 shifts verdict one tier lenient; ≤30 shifts one tier stricter. Raw `risk` number unchanged.
95
+ - `contentEffort` (boolean, default false) — enable the AI content-effort signal: an LLM judges a 0-100 originality/effort score from sampled page text that moderates the verdict ±1 tier. Requires `ANTHROPIC_API_KEY` in the MCP server's environment; no-ops safely without one. Adds a few cents of LLM cost per audit.
95
96
  - `sampleSeed` — Integer seed for deterministic stratified sampling. Same seed = same audit = same verdict.
96
97
 
97
98
  **Returns (v0.6 shape):** `verdict`, `risk`, `categories`, `templates: Template[]`, `findings: RuleResult[]`. AI clients should iterate `templates` first — `topDriver.ruleId + fireRate` is the most actionable per-template signal. Use `findings` for per-URL drill-down.
@@ -105,7 +106,8 @@ Run an audit and get a human-readable explanation of what's driving the SpamBrai
105
106
  **Parameters:**
106
107
  - `source` (required) — URL or directory path to audit
107
108
  - `threshold` — Risk threshold for the pass/fail verdict (default: 40)
108
- - `authorityScore` — 0-100 domain authority hint. ≥80 shifts verdict one tier lenient; ≤30 shifts one tier stricter.
109
+ - `authorityScore` — 0-100 domain authority hint. ≥80 shifts verdict one tier lenient; ≤30 shifts one tier stricter. Raw `risk` number unchanged.
110
+ - `contentEffort` (boolean, default false) — enable the AI content-effort signal: an LLM judges a 0-100 originality/effort score from sampled page text that moderates the verdict ±1 tier. Requires `ANTHROPIC_API_KEY` in the MCP server's environment; no-ops safely without one. Adds a few cents of LLM cost per audit.
109
111
  - `sampleSeed` — Integer seed for deterministic stratified sampling.
110
112
 
111
113
  **Example prompt:** "Explain why my site's SpamBrain score is high"
@@ -119,6 +121,15 @@ Check a single page URL for per-page technical SEO issues (canonical, Open Graph
119
121
 
120
122
  **Example prompt:** "Check https://yoursite.com/templates/california-llc for technical SEO issues"
121
123
 
124
+ ## Resources
125
+
126
+ The server also exposes pseolint's rule knowledge as read-only [MCP resources](https://modelcontextprotocol.io), so an assistant can explain a finding without guessing or fetching the web. The resources are keyed by `ruleId`, the same identifier that appears on every audit finding (e.g. `spam/thin-content`), so they line up 1:1 with tool output.
127
+
128
+ - **`pseolint://rules`** — a JSON index of every documented rule (`ruleId`, `title`, and the per-rule resource URI). Read this first to discover what's available.
129
+ - **`pseolint://rules/<ruleId>`** — one Markdown resource per rule, e.g. `pseolint://rules/spam/thin-content`. Each contains the rule's link, a **What it detects** section, and a **How to fix** checklist.
130
+
131
+ Typical flow: run `pseolint_audit_site`, take a `ruleId` off a finding, then read `pseolint://rules/<ruleId>` to ground the explanation and fix advice in pseolint's own rule documentation.
132
+
122
133
  ## Remote server (hosted, zero-install)
123
134
 
124
135
  Prefer not to install anything? Point your MCP client at the hosted endpoint:
@@ -0,0 +1,12 @@
1
+ export interface RuleKnowledge {
2
+ ruleId: string;
3
+ slug: string;
4
+ category: string;
5
+ title: string;
6
+ oneLiner: string;
7
+ whatItDetects: string;
8
+ howToFix: string[];
9
+ url: string;
10
+ }
11
+ export declare const RULE_KNOWLEDGE: RuleKnowledge[];
12
+ //# sourceMappingURL=okf-knowledge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"okf-knowledge.d.ts","sourceRoot":"","sources":["../src/okf-knowledge.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,cAAc,EAAE,aAAa,EAsgBzC,CAAC"}
@@ -0,0 +1,520 @@
1
+ export const RULE_KNOWLEDGE = [
2
+ {
3
+ "ruleId": "spam/thin-content",
4
+ "slug": "thin-content",
5
+ "category": "spam",
6
+ "title": "Thin Content Detection — How Google Catches Low-Substance Pages",
7
+ "oneLiner": "Google's Helpful Content System (rebuilt August 25, 2022) demoted an estimated 45% of low-effort pages in the March 5, 2024 scaled-content-abuse update — the spam/thin-content rule mirrors that floor by flagging every URL under 300 words of substantive body text (default), after stripping nav and footer chrome via SpamBrain-style readability heuristics.",
8
+ "whatItDetects": "300 words is the default floor pseolint flags pages against — the threshold Google's SpamBrain classifier has been tuned to since the March 5, 2024 scaled-content-abuse update (https://developers.google.com/search/docs/essentials/spam-policies). The rule extracts the page's main content text — after stripping nav, footer, and other chrome — splits on whitespace, and counts non-empty tokens. Any URL whose word count is below the threshold you pass to the rule (defaults differ per pSEO archetype: 200 for product comparators, 350 for guide-style hubs) is added to a `thinContentUrls` set and reported with the exact deficit. That set is then reused by other rules — most notably `spam/doorway-pattern` — so a thin page that also looks templated escalates from a single error (weight 25) to a critical signal stack (weight 40). The check is intentionally cheap and deterministic; it does not try to evaluate quality, only volume of substantive prose.",
9
+ "howToFix": [
10
+ "Audit URL-by-URL, not in aggregate. A 50%-thin domain usually has clusters of completely empty pages; collapsing those is faster than rewriting everything.",
11
+ "If a page has nothing genuinely unique to say, redirect it (301) or noindex it. Pruning is a feature, not a failure.",
12
+ "Replace boilerplate intros and 'why choose us' filler with structured, page-specific facts — dimensions, prices, cohort statistics, change logs. Facts add words and quality at the same time.",
13
+ "Connect a real data source (CSV, JSON, or your DB) so each entity contributes its own attributes. Pages should diverge on the facts, not just the H1.",
14
+ "Raise your `thinMinWords` threshold gradually as you fix pages. Catching the next batch is easier when the floor moves up.",
15
+ "Do not pad with FAQ accordions copied across the site — that triggers `spam/boilerplate-ratio` instead and you end up worse off."
16
+ ],
17
+ "url": "https://pseolint.dev/rules/thin-content"
18
+ },
19
+ {
20
+ "ruleId": "spam/doorway-pattern",
21
+ "slug": "doorway-pattern",
22
+ "category": "spam",
23
+ "title": "Doorway Pages — How Google Detects Templated Funnels",
24
+ "oneLiner": "Google has banned doorway pages since the March 16, 2015 Search Central post — pseolint's spam/doorway-pattern rule mirrors SpamBrain's convergence logic by requiring 3 independent signals to stack (SimHash near-duplicate above 0.85, entity-swap, and structural confirmation) before firing at error severity (weight 25), the highest-confidence spam pattern reported by @pseolint/core v0.4.3.",
25
+ "whatItDetects": "3 independent signals must converge before pseolint fires this rule — mirroring the convergence logic Google's SpamBrain has used to enforce the doorway-pages policy (https://developers.google.com/search/docs/essentials/spam-policies#doorway-pages) since March 16, 2015. The rule does not run a single check. It joins the output of two earlier rules — `spam/near-duplicate` (64-bit SimHash similarity above the 0.85 default threshold) and the entity-swap detector (pages whose only meaningful diff is a swapped noun phrase) — then layers on additional confirmations: identical `structureSignature`, identical `<meta description>`, and whether either URL is already in the thin-content set (300-word default floor). A pair only triggers `spam/doorway-pattern` once at least 3 of these signals agree. The finding fires at error severity (weight 25 in pseolint's scoring, against critical=40, warning=12, info=5) and names both URLs alongside which signals stacked, so you can see at a glance whether you are looking at a near-duplicate problem (fix the content) or a template problem (fix the layout).",
26
+ "howToFix": [
27
+ "Identify which signal you can break most cheaply. Usually it is the meta description — write per-page descriptions before touching content.",
28
+ "Differentiate the structure: introduce conditional sections that only render for pages with certain attributes (e.g., a 'Free tier' callout that only appears for free competitors).",
29
+ "If two pages serve the same intent, merge them. A single 1,500-word /alternatives/ page often outranks ten thin /vs/ pages.",
30
+ "Inspect the entity-swap pairs first; that is the rule's strongest signal and where the worst offenders cluster.",
31
+ "Once you fix a pair, re-run pseolint. Doorway findings drop noisily — fixing one pair often resolves five because of how SimHash buckets cluster.",
32
+ "Do not try to defeat the rule by injecting boilerplate variation (random sentences, swapped synonyms). SpamBrain has the same defenses; you will fail both."
33
+ ],
34
+ "url": "https://pseolint.dev/rules/doorway-pattern"
35
+ },
36
+ {
37
+ "ruleId": "spam/near-duplicate",
38
+ "slug": "near-duplicate",
39
+ "category": "spam",
40
+ "title": "Near-Duplicate Pages — SimHash, SpamBrain, and the Similarity Threshold",
41
+ "oneLiner": "85% SimHash similarity is the pseolint default threshold — every page pair at or above that mirrors the near-duplicate canonicalisation ceiling Google's web indexing team has used since adopting Charikar's 2002 SimHash paper in 2007, and which the March 5, 2024 scaled-content-abuse update reaffirmed as policy via SpamBrain's 60-second triage queue.",
42
+ "whatItDetects": "85% SimHash similarity is the threshold pseolint flags page pairs at, mirroring the near-duplicate canonicalisation ceiling Google's web indexing team has used since adopting Charikar's 2002 SimHash paper in 2007 — and named again in the March 5, 2024 scaled-content-abuse policy (https://developers.google.com/search/docs/essentials/spam-policies). For each page, the rule computes a 64-bit SimHash from the main content text using token-level shingling — chosen over Jaccard (too slow at O(n*m)) and BERT embeddings (too expensive for a 60-second audit budget). It then compares every page against every other page — an O(n²) sweep that is fine for the page counts pSEO sites actually run (the 200-page free-tier audit ceiling completes in under a 1-second wall-clock; the 500-page Pro manual-re-audit ceiling stays within the 30-second per-rule budget).\n\nHamming distance between two hashes is converted to a similarity score in [0,1]. Any pair scoring at or above the configured threshold (default 85%, escalated to 90% for template-heavy sites) is recorded both as a finding and as a `PairMatch` consumed by `spam/doorway-pattern`. The finding fires at warning severity (weight 12) and includes the exact similarity percentage so you can sort the queue worst-first. Implementation lives in @pseolint/core v0.7.0 (current), MIT-licensed at github.com/ouranos-labs/pseolint, and runs in the same pipeline industry crawlers Ahrefs, Sitebulb, and Screaming Frog use for their dedup counters.",
43
+ "howToFix": [
44
+ "Sort findings by similarity percentage descending; fix pairs above 0.95 first — those are almost always copy-paste accidents you can resolve in minutes.",
45
+ "For pairs in the 0.85-0.95 range, decide whether the duplication is intentional (merge into one page with a 301) or accidental (rewrite one to genuinely differentiate).",
46
+ "Add canonicals only as a last resort — they preserve the duplicate URL in the index, which still drags on cluster authority.",
47
+ "Re-run with a stricter threshold (0.80) once you've cleared the worst tier. The tail of medium-similarity pairs often hides templating problems that `spam/boilerplate-ratio` will then surface.",
48
+ "Audit your data source: many near-duplicate clusters trace back to two source rows that should have been one (e.g., 'San Francisco' and 'SF, California' as separate entities)."
49
+ ],
50
+ "url": "https://pseolint.dev/rules/near-duplicate"
51
+ },
52
+ {
53
+ "ruleId": "spam/boilerplate-ratio",
54
+ "slug": "boilerplate-ratio",
55
+ "category": "spam",
56
+ "title": "Boilerplate Ratio — When Shared Template Text Eats Your Pages",
57
+ "oneLiner": "60% is the default boilerplateMaxRatio: pseolint identifies sentence-level blocks appearing on 80%+ of pages, then flags any URL whose word count is dominated by those repeated blocks (warning severity, weight 12).",
58
+ "whatItDetects": "pseolint flags pages whose boilerplate ratio exceeds 60% — the threshold operationalising the 'producing many pages on the same topic to such a degree that individual pages have very little unique value' clause Google added to the helpful-content guidance in the March 5, 2024 scaled-content-abuse update (https://developers.google.com/search/docs/essentials/spam-policies). The rule splits each page's content into sentence-sized blocks (split on `.!?\\n`, lower-cased, blocks shorter than 20 characters discarded). It builds a frequency map across all pages, then defines the 'skeleton' as any block appearing on at least 80% of pages plus one. For each individual page, it sums the words inside skeleton blocks and divides by the page's total word count. Pages above your `boilerplateMaxRatio` (default 0.60) are reported with the exact percentage. Crucially, the skeleton is computed across the actual pages you crawled — so if you sample only 20 pages of a 2,000-page site, the skeleton may be smaller than reality and the ratio is conservatively low.",
59
+ "howToFix": [
60
+ "Find your skeleton blocks first. Run pseolint with `--verbose` and the rule will list which exact sentences it considers boilerplate — that's your edit list.",
61
+ "Move repeated content out of the page body and into the global footer or a separate /about-style URL where it doesn't count against per-page ratio.",
62
+ "Shorten or delete sections that aren't load-bearing. 'Why this works' intros and pre-conclusion summaries are the highest-value cuts because they are uniformly low information.",
63
+ "Grow the variable section. The ratio is a fraction; a smaller numerator is one path, a larger denominator is another. Adding genuine per-page facts is almost always safer than aggressive boilerplate removal.",
64
+ "Treat anything above 50% as a yellow flag even if it passes the rule. The default 60% threshold is permissive; many domains that pass at 0.60 still feel templated to a reader.",
65
+ "Re-run after each round of edits. Removing one skeleton block can shift others' frequencies above the 80% cutoff, so the skeleton recomposes."
66
+ ],
67
+ "url": "https://pseolint.dev/rules/boilerplate-ratio"
68
+ },
69
+ {
70
+ "ruleId": "spam/template-diversity",
71
+ "slug": "template-diversity",
72
+ "category": "spam",
73
+ "title": "Template Diversity — Why HTML Structure Counts as a Spam Signal",
74
+ "oneLiner": "30% is the default minUniqueRatio threshold — pseolint warns when fewer than 30% of pages carry a structurally distinct HTML skeleton, the floor at which SpamBrain (rebuilt August 25, 2022) starts reading a domain as one template rather than N designed pages.",
75
+ "whatItDetects": "30% is the default minUniqueRatio pseolint warns below — the floor at which Google's SpamBrain (rebuilt August 25, 2022 alongside the Helpful Content System launch to score site-level helpfulness alongside per-page signals) starts treating a domain as a single template rather than N designed pages. Each parsed page carries a `structureSignature` — a hash of its HTML structure that ignores text content but preserves the sequence and nesting of element types. The rule counts how many distinct signatures exist across all pages and divides by the page count to produce a unique-ratio in [0,1]. If that ratio falls below `minUniqueRatio` (0.30 default), a single warning-severity finding (weight 12) is emitted at the site level — versus error=25, critical=40, info=5 elsewhere in the engine. This is a holistic signal, not a per-page one: there is no list of 'failing' URLs because the problem is the site's design system, not any individual page. Powered by @pseolint/core v0.7.0, MIT-licensed at github.com/ouranos-labs/pseolint.",
76
+ "howToFix": [
77
+ "Identify which sections in your template should be optional. Anything that doesn't apply to every entity is a candidate: pricing tables, video embeds, timelines, FAQs, comparison widgets.",
78
+ "Wrap optional sections in conditionals that key off the underlying data, not random booleans. 'If the entity has a video URL, render the video block' produces meaningful diversity; 'if Math.random() > 0.5' produces nothing.",
79
+ "Vary the order of secondary sections by entity type. A restaurant page might lead with menu, a hotel page with rooms — same template, different priority.",
80
+ "Add per-entity media variations. Some pages have hero images, some have hero videos, some have galleries. Each renders different HTML.",
81
+ "Don't fix this rule by adding random structural noise. The rule is a holistic warning; if the underlying content is differentiated, the warning is acceptable on a homogeneous content type."
82
+ ],
83
+ "url": "https://pseolint.dev/rules/template-diversity"
84
+ },
85
+ {
86
+ "ruleId": "links/host-section-divergence",
87
+ "slug": "host-section-divergence",
88
+ "category": "links",
89
+ "title": "Site Reputation Abuse — Detecting Parasite Sections on a Trusted Host",
90
+ "oneLiner": "Google's May 7, 2024 site-reputation-abuse policy demotes subfolders that borrow a host's reputation without earning it — links/host-section-divergence flags a URL section (e.g. /coupons/, /deals/) only when it diverges from the rest of the host on at least 2 of 4 independent structural signals, and it deliberately fires on the minority section, never on a balanced multi-topic split.",
91
+ "whatItDetects": "The rule groups every crawled URL by its first path segment (/coupons/, /reviews/, /best/) and tests each section that holds at least 10 pages while leaving at least 10 pages in the rest of the host. It only considers sections that are a strict minority of the corpus (under 50%) — reputation abuse is, by definition, a small parasite section riding a larger host, so a 50/50 split is read as a multi-topic site and skipped.\n\nFor each qualifying section it measures four signals against the rest of the host: (1) inbound-link integration — the fraction of section pages that receive at least one internal link from outside the section, flagged when under 0.20 (the section is an island the host barely references); (2) topic divergence — Jaccard distance between the top-100 TF-IDF terms of the section versus the rest, flagged above 0.75 (under ~25% vocabulary overlap); (3) template isolation — the fraction of section pages whose structureSignature also appears anywhere else on the host, flagged when under 0.10 (the section ships its own template the host never uses); and (4) authorship mismatch — flagged when section and host byline coverage differ by at least 0.40 and one pool is mostly anonymous (≤0.30) while the other is mostly bylined (≥0.70).\n\nA section that trips 2 or more signals emits a warning naming the section, the signal values, and a 20-URL sample; a section that trips 3 or more and holds over 50 pages escalates to error. The rule reasons about structure, not contracts — it cannot read a revenue-share agreement or see a manual action, only the structural fingerprint those arrangements leave behind.",
92
+ "howToFix": [
93
+ "Decide per section whether you actually own it editorially. If a third party produces the content with minimal first-party review, the honest fixes are to integrate it properly or to move it off the host — not to game the four signals.",
94
+ "Integrate, option A: cross-link the section from your primary navigation and from topically-related host pages so it stops reading as an island. Low inbound integration is the cheapest signal to flip and often the most diagnostic.",
95
+ "Integrate, option B: share authorship and schema. Put real, named reviewers on the pages who actually vet them, and align the section's template with the rest of the host so it isn't a structurally foreign body.",
96
+ "Separate, the clean alternative: move the section to a subdomain or a partner-owned domain and 301 the old URLs. It stops borrowing your reputation — which is the point of the enforcement — and stops being a liability.",
97
+ "Do not try to defeat the rule by sprinkling a few host links into the section while leaving it editorially third-party. The policy is about substance, not surface signals; a reviewer applies the same 'would a reasonable user see this as the host's own content' test the rule only approximates."
98
+ ],
99
+ "url": "https://pseolint.dev/rules/host-section-divergence"
100
+ },
101
+ {
102
+ "ruleId": "spam/entity-swap",
103
+ "slug": "entity-swap",
104
+ "category": "spam",
105
+ "title": "Entity-Swap Pages — When Only the Noun Changes Between URLs",
106
+ "oneLiner": "spam/entity-swap masks the variable noun on every page — by default US state names and 5-digit ZIP codes — then computes a 64-bit SimHash of what is left and fires at critical severity when two pages score 95% similarity or higher, the convergence signal Google's SpamBrain has used against entity-swap doorways since the March 5, 2024 scaled-content-abuse update.",
107
+ "whatItDetects": "spam/entity-swap is the rule that catches the single cleanest fingerprint of programmatic generation: a page whose only real difference from its siblings is the entity you swapped in. The rule masks every page's main content with your entity patterns — the defaults cover all 50 US state names and 5-digit ZIP codes, and you add your own dimensions (cities, SKUs, job titles) in pseolint.config.ts — and then computes a 64-bit SimHash over the masked text.\n\nMasking is what separates this rule from spam/near-duplicate. Near-duplicate hashes the raw text and fires at 85%, so two location pages with genuinely different city paragraphs can slip under its bar. Entity-swap removes the entity tokens first, so if the remaining sentence frames are identical the masked similarity rockets toward 100%. The pairwise O(n²) sweep flags any pair scoring 95% or above at critical severity, and records the pair as a PairMatch that spam/doorway-pattern later consumes as one of the three signals it needs to converge.",
108
+ "howToFix": [
109
+ "Bind real per-entity data, not synonyms. Swapping 'top' for 'best' or rewording a sentence leaves the masked SimHash untouched; the rule already ignores the entity token, so only genuinely different facts move the score.",
110
+ "Lead each page with the one thing that entity has and its siblings lack — a local statute, a region-specific fee, a SKU's actual spec — so the opening sentence frame diverges, not just the noun.",
111
+ "Audit your data source for thin records. An entity-swap cluster usually traces back to rows that carry no distinguishing fields; if the data cannot differentiate the page, the page probably should not exist as a separate URL.",
112
+ "Consolidate entities you cannot differentiate. Five states with identical programs are better served by one page that names all five than five pages that pretend to be different.",
113
+ "Re-run after each fix. Because the rule is pairwise, breaking one page out of a cluster can drop several findings at once as the remaining pairs fall below 95%."
114
+ ],
115
+ "url": "https://pseolint.dev/rules/entity-swap"
116
+ },
117
+ {
118
+ "ruleId": "spam/publication-velocity",
119
+ "slug": "publication-velocity",
120
+ "category": "spam",
121
+ "title": "Publication Velocity — When Your Publish Dates Betray Bulk Generation",
122
+ "oneLiner": "spam/publication-velocity groups your pages by publish date and warns when any single day exceeds the greater of 100 pages or 10% of your whole corpus — the date-stacking signal Google's March 27, 2026 core update tightened against programmatically generated sites.",
123
+ "whatItDetects": "spam/publication-velocity reads the publish date off every page — from article:published_time, a datePublished meta, or the first time[datetime] element — truncates it to a calendar day, and groups the corpus by that day. Pages with no detectable date are skipped, so the rule only judges what it can actually see.\n\nThe ceiling is corpus-relative. The effective limit for any day is the greater of two numbers: the absolute floor of 100 pages per day, and 10% of your total page count. A 400-page site is governed by the 100/day floor; a 50,000-page site can legitimately publish up to 5,000 pages on one date before the rule says anything. Any day that exceeds its effective limit emits a single warning naming the date, the count, and which ceiling it breached. The corpus-relative design is what keeps the rule from punishing large, legitimately busy publishers while still catching the small site that stamped 800 generated pages with one timestamp.",
124
+ "howToFix": [
125
+ "Spread real dates, do not fabricate them. If your pages were genuinely created over time, surface that true history in article:published_time instead of stamping every record with the import date.",
126
+ "Drip-publish new batches. Releasing generated pages over days or weeks both lowers the per-day count and matches how Google expects a healthy site to grow.",
127
+ "Raise the corpus, not the spike. The ceiling scales with total page count, so the rule naturally relaxes as a site earns scale — but only if growth is distributed, not stacked.",
128
+ "Check which field you expose. If you have no real publish dates, consider omitting them rather than stamping a placeholder, since the rule skips pages with no detectable date.",
129
+ "Treat a velocity warning as a prompt to audit the same template for thin-content and near-duplicate — date-stacking rarely travels alone."
130
+ ],
131
+ "url": "https://pseolint.dev/rules/publication-velocity"
132
+ },
133
+ {
134
+ "ruleId": "spam/template-coverage",
135
+ "slug": "template-coverage",
136
+ "category": "spam",
137
+ "title": "Template Coverage — How Sparse Keyword Matrices Expose pSEO",
138
+ "oneLiner": "spam/template-coverage groups URLs in the same directory, masks the entity tokens in each filename, and reports how many of the possible dimension combinations a template actually fills — surfacing, at info severity, the sparse high-dimension matrices Google's March 27, 2026 core update down-weighted on programmatic sites.",
139
+ "whatItDetects": "spam/template-coverage is a diagnostic, not an accusation. It groups your URLs into clusters by parent directory, and within each cluster of at least 5 pages it looks only at the filename — the last path segment, extension stripped. It masks the entity tokens in that filename using your entity patterns, then splits the masked name on hyphens into positional tokens.\n\nFor each position where more than one distinct value appears, the rule records a 'dimension'. A cluster like /jobs/[role]-jobs-in-[city] has two dimensions: role and city. The rule multiplies the number of distinct values in each dimension to get the total possible combinations, then divides the pages you actually built by that total to produce a coverage percentage. If a template has 12 services and 50 cities — 600 possible cells — but you shipped 96 pages, coverage is 16% and the rule reports the dimensions, the sample values, and the ratio at info severity. A cluster where every token varies, or none does, produces no finding because there is no matrix to measure.",
140
+ "howToFix": [
141
+ "Narrow the matrix to what you can differentiate. If you cannot write genuinely distinct content for all 600 cells, do not claim the grid — build the cells you can substantiate and drop the dimensions you cannot.",
142
+ "Raise coverage by subtraction, not addition. Pruning empty intent often beats generating the missing cells, because the missing cells are usually the ones with no demand and nothing unique to say.",
143
+ "Check the paired findings first. A coverage finding next to spam/thin-content or spam/near-duplicate in the same cluster is the combination that matters; coverage alone is a diagnostic to note, not an emergency.",
144
+ "Collapse a dimension. If one axis (say, modifier words like cheap/best/top) adds combinations without adding user value, remove it from the URL structure and fold it into a single page.",
145
+ "Treat info severity as guidance. The rule never blocks a verdict on its own — it tells you where a template's ambition outruns its substance so you can decide before Google does."
146
+ ],
147
+ "url": "https://pseolint.dev/rules/template-coverage"
148
+ },
149
+ {
150
+ "ruleId": "content/unique-value",
151
+ "slug": "unique-value",
152
+ "category": "content",
153
+ "title": "Unique Value — Originality as a Density, Not a Word Count",
154
+ "oneLiner": "content/unique-value scores how original each page is as a rarity density — every distinct word weighted by how rare it is across the audit, then averaged — and fires when that density falls below the floor, the page-specific-vocabulary test Google's scaled-content-abuse policy has applied since March 5, 2024 when it asks whether a URL adds anything genuinely new.",
155
+ "whatItDetects": "content/unique-value asks how original a page is relative to its siblings, as a density rather than a raw count. It tokenises each page's main content — lower-cased, split on whitespace, with leading and trailing punctuation stripped so 'word', 'word.' and '(word)' count as one token — and weights every distinct word by how rare it is across the audited set: a word on one page scores 1, a word on every page scores near 0 (normalised inverse document frequency). The page's score is the average of those weights — its unique-content density, between 0 and 1.\n\nA page whose vocabulary mostly repeats across its siblings — boilerplate, shared spec blocks, an entity-swapped template — scores low and fires. Because it is an average, the metric does not punish a page for being short or for living in a large, tightly-themed site, and it does not flip on a one-word margin the way a hard count does. Volume is spam/thin-content's job; exact twins are spam/near-duplicate's; this rule isolates low originality.",
156
+ "howToFix": [
157
+ "Write a page-specific lead. The fastest way to raise density is an opening paragraph true of this entity and nothing else. Boilerplate intros are the first thing to cut.",
158
+ "Move shared blocks to a shared URL. A glossary, a methodology note, or a legal disclaimer that repeats across pages should live on one page the others link to, not embedded everywhere where it dilutes uniqueness.",
159
+ "Stop expecting per-axis data to count. Content repeated across pages on the same axis — a role's regulations across that role's documents — is common vocabulary and barely moves density. Only text specific to this page raises it.",
160
+ "Bind distinct records, not shared ones. If two pages pull the same fields from your data source, they will share vocabulary; differentiate the records or merge the pages.",
161
+ "Read the density and overlap the finding reports. It tells you how distinctive the page is and confirms the problem is overlap, not length."
162
+ ],
163
+ "url": "https://pseolint.dev/rules/unique-value"
164
+ },
165
+ {
166
+ "ruleId": "content/meta-uniqueness",
167
+ "slug": "meta-uniqueness",
168
+ "category": "content",
169
+ "title": "Meta Description Uniqueness — When Snippets Are Templated",
170
+ "oneLiner": "content/meta-uniqueness masks the entity tokens in every page's meta description, lower-cases and trims what remains, and fires an error the moment two or more pages collapse to the same string — the templated-snippet pattern Google has treated as scaled content since the March 5, 2024 spam update.",
171
+ "whatItDetects": "content/meta-uniqueness checks the one piece of copy most teams forget to vary: the meta description. For every page that has one, the rule masks the entity tokens using your entity patterns, then lower-cases and trims the result. Pages whose masked descriptions are byte-for-byte identical are grouped together.\n\nAny group with two or more members fires an error naming the count of pages that share the template. The masking is the important part. A description like 'Compare {tool} against the competition — pricing, features, and migration paths' looks unique on the surface for every tool, but the moment you mask the tool name, all of them collapse to the same sentence. That collapse is the signal: the description was generated from a template, not written for the page. The rule deliberately uses exact-match-after-masking rather than fuzzy similarity, so it only fires when the underlying snippet really is one template wearing different nouns.",
172
+ "howToFix": [
173
+ "Bind a distinct value into every description. A per-page count, price, date, or named attribute pulled from your data source breaks the masked-match because the variable part survives masking.",
174
+ "Do not rely on the entity alone. Swapping only the city or role is exactly what the rule masks away; the description must vary on something the mask does not remove.",
175
+ "Write the description from the page's most specific fact. The best snippets answer 'why this page' in 155 characters — the same discipline that satisfies the rule makes the SERP result more clickable.",
176
+ "Audit templates, not pages. One bad description template generates thousands of duplicates; fix the template's data binding once and the entire cluster clears.",
177
+ "Check for empty descriptions too — pages with no meta description are skipped here, but they surface in tech/og-completeness and lose snippet control for a different reason."
178
+ ],
179
+ "url": "https://pseolint.dev/rules/meta-uniqueness"
180
+ },
181
+ {
182
+ "ruleId": "content/missing-author",
183
+ "slug": "missing-author",
184
+ "category": "content",
185
+ "title": "Missing Author — Why Anonymous pSEO Pages Fail E-E-A-T",
186
+ "oneLiner": "Google added the second E for Experience to its E-A-T trust framework on December 15, 2022, and content/missing-author mirrors that shift by flagging at warning severity, medium confidence, every page that exposes none of four author signals — a meta author tag, a schema author field, a byline element, or a rel=author link.",
187
+ "whatItDetects": "content/missing-author checks one thing per page: is there any machine-readable claim of who wrote it? The rule reads four independent author signals the parser extracts and fires only when all four are absent.\n\nThe signals are precise. (1) Meta author — a non-empty content value on a `<meta name=\"author\">` tag, after whitespace normalisation, so an empty tag does not count. (2) Schema author — any JSON-LD object on the page that carries an `author` key, which covers Article, BlogPosting, and NewsArticle structured data. (3) Byline element — at least one element whose class contains 'author' or 'byline', or which carries `rel='author'`, catching the visible '.byline' or '.author-name' markup most templates ship. (4) Rel=author link — an `<a rel=\"author\">` or `<link rel=\"author\">` anchor pointing at a profile.\n\nA page passes if even one of the four is present, so the bar is deliberately low. Severity is fixed at warning and confidence at medium, because technical docs, product pages, and pricing pages legitimately omit bylines — attribution matters most on blog and news content where authorship is the primary trust signal.",
188
+ "howToFix": [
189
+ "Add a `<meta name=\"author\" content=\"Full Name\">` to every content page's head — it is the single cheapest signal and clears the rule on its own.",
190
+ "Put the author into your JSON-LD: an Article or BlogPosting node with an `author` object carrying a name and, ideally, a sameAs link to a real profile.",
191
+ "Render a visible byline in markup the rule recognises — an element classed 'author' or 'byline', or one carrying rel='author' — so humans and the parser see the same attribution.",
192
+ "Link the byline to a genuine author bio page that documents the writer's relevant experience, not a stub; the link is what turns a name into an E-E-A-T signal.",
193
+ "Decide which page types actually need authors. Technical docs and pricing pages can stay unsigned; blog, news, and 'guide' content should not, since that is where attribution carries the most trust weight.",
194
+ "Audit site-wide before launch: if every page is anonymous on a site deeper than three pages, the rule emits one site-level E-E-A-T warning instead of per-URL findings, so fix the template once rather than page by page."
195
+ ],
196
+ "url": "https://pseolint.dev/rules/missing-author"
197
+ },
198
+ {
199
+ "ruleId": "content/eeat-signals",
200
+ "slug": "eeat-signals",
201
+ "category": "content",
202
+ "title": "E-E-A-T Signals — When a Page Carries No Evidence of Who Wrote It",
203
+ "oneLiner": "content/eeat-signals checks four trust categories on every page — an about-page link, an author byline, a published date, and a sources or references marker — then fires at info severity for any URL carrying fewer than 2 of the 4, the anonymity pattern Google's E-E-A-T framework has weighed against pages since its December 2022 Quality Rater Guidelines update.",
204
+ "whatItDetects": "content/eeat-signals scores each page against four independent trust categories and counts how many it carries. The first is an about-page link: the rule scans the page's resolved hrefs for any URL matching '/about'. The second is an author signal, satisfied if the page exposes a non-empty author meta tag, a schema.org author, a byline element, or a rel=author link. The third is a published date the parser could extract. The fourth is a 'sources' category, matched when the raw HTML contains any of five patterns: 'last updated', 'last modified', 'reviewed by', 'sources:', or 'references:'.\n\nA page passes if it carries 2 or more of those 4 categories. Any page below that floor is flagged. The rule never inspects the quality of the byline or the accuracy of the date — it only asks whether the markers of accountability are present at all. The point is structural: a page that names nobody, dates nothing, links to no about page, and cites no source is anonymous by construction, and anonymity is the baseline condition Google's trust evaluation reads first.",
205
+ "howToFix": [
206
+ "Add a real author byline to every template. A meta author tag, a schema.org author property, a visible byline element, or a rel=author link each satisfies the author category — pick one and bind a genuine name, not a brand placeholder.",
207
+ "Expose a published or updated date. The rule reads the date the parser extracts, so surface a real article:published_time or a visible 'Last updated' line rather than leaving the page undated.",
208
+ "Link to an about page from the template footer or header. Any href matching '/about' resolves the category, and one shared link covers the whole corpus at once.",
209
+ "Cite sources where the topic warrants it. A 'Sources:' or 'References:' block, or a 'Reviewed by' line, matches the rule's patterns and gives readers and raters something to verify against.",
210
+ "Treat a site-wide finding as a template fix, not a per-page chore. When every page is below the floor, the cause is one template missing accountability markers — add them once at the template level and the whole cluster clears.",
211
+ "Prioritise the fix on Your-Money-or-Your-Life pages first, where Google's guidelines weigh visible expertise most heavily before granting trust."
212
+ ],
213
+ "url": "https://pseolint.dev/rules/eeat-signals"
214
+ },
215
+ {
216
+ "ruleId": "content/title-uniqueness",
217
+ "slug": "title-uniqueness",
218
+ "category": "content",
219
+ "title": "Title Uniqueness — Missing, Too-Short, and Duplicate Page Titles",
220
+ "oneLiner": "content/title-uniqueness rolls three checks into one rule — a missing or empty title, a title outside the 10-to-70-character band, and two or more pages sharing the exact same raw title — and it raised this gap to a tier-1 fix in pseolint after the 2026-05-03 blind-spot audit because Google ranks the title above every other on-page element.",
221
+ "whatItDetects": "content/title-uniqueness runs three checks over the title that the existing meta-description rule never touched. First, a missing title: any page whose <head><title> is absent, empty, or whitespace-only fires an error, because the title is the strongest on-page signal Google ranks against. Second, length. A title under 10 characters fires a warning — short titles get rewritten by Google from the H1 or anchor text, so the copy you wrote never shows. A title over 70 characters fires an info finding, because Google truncates the SERP snippet around 60 characters and the tail is lost.\n\nThird, exact duplicates. The rule groups every page by its raw, trimmed title string and fires an error the moment two or more pages share one. It does NOT entity-mask the way the meta rule does — 'Slack to Google Sheets' and 'Slack to Airtable' are different raw strings and stay separate, so the rule never false-positives on a legitimate templated catalog whose titles already carry the per-record entity.",
222
+ "howToFix": [
223
+ "Add a non-empty <head><title> to every page. If a template can render without one, that is the first leak to plug — the title is the field Google reads before any other.",
224
+ "Bind the per-record entity into the title so duplicates cannot form. A raw string carrying the integration name, currency pair, or city is unique by construction and never groups.",
225
+ "Keep titles inside the 10-to-70-character band. Expand anything under 10 characters so Google does not rewrite it from the H1; tighten anything over 70 so the SERP does not truncate the tail.",
226
+ "Front-load the distinguishing words. Google truncates around 60 characters, so the entity and primary keyword belong at the start, not after a long brand suffix.",
227
+ "Never treat an inline SVG <title> as the page title. That logo accessibility label is decorative and crawlers ignore it — add a real <head><title> with the page entity instead.",
228
+ "Re-run the audit after editing a template. Fixing one duplicated title clears the whole group at once, since the rule reports per shared string, not per URL."
229
+ ],
230
+ "url": "https://pseolint.dev/rules/title-uniqueness"
231
+ },
232
+ {
233
+ "ruleId": "content/heading-structure",
234
+ "slug": "heading-structure",
235
+ "category": "content",
236
+ "title": "Heading Structure — Missing, Duplicate, and Unstructured Headings",
237
+ "oneLiner": "content/heading-structure runs three checks on every page Google crawls — a missing H1 fires an error because it is almost always a CMS or template bug, two or more H1 elements raise a warning that the HTML5 outline and accessibility checkers both dislike, and any page past 600 words with no H2 sub-structure emits an info note about Featured Snippet eligibility.",
238
+ "whatItDetects": "content/heading-structure runs three independent checks over every parsed page and emits one finding per problem it sees. First, if a page has zero <h1> elements it fires an error — a page with no top-level heading is almost always a CMS misconfiguration or a template that forgot to render the title, and Google leans on the H1 to disambiguate the page's primary topic when the title tag is weak.\n\nSecond, if a page carries more than one <h1>, the rule raises a warning and reports the count. A single H1 per document is the convention every accessibility checker enforces and several SEO heuristics still expect, so multiple H1s read as an ambiguous primary-topic signal.\n\nThird, the rule measures the page's body word count by splitting the main text on whitespace; once that count reaches 600 words and the page has no <h2> at all, it emits an info finding. A long wall of text with no sub-headings is a readability and Featured Snippet problem, not a correctness bug, which is why this third check sits at the gentlest severity.",
239
+ "howToFix": [
240
+ "Add a single <h1> to every page that lacks one — name the page's primary topic in it, since Google uses the H1 to disambiguate when the title tag is unclear.",
241
+ "Where a page has two or more H1s, keep one and demote the rest to <h2>; the visual size can stay identical via CSS, only the markup level changes.",
242
+ "Check that your hero title is a real <h1> tag and not a styled <div> or <span> — CSS that merely looks like a heading does not count and still trips the missing-H1 error.",
243
+ "Break any page over 600 words into sections with <h2> sub-headings; aim for one H2 per distinct idea so Featured Snippet extractors have clear blocks to pull from.",
244
+ "Fix the template, not the page — a missing or duplicated H1 in a pSEO layout repeats across every generated URL, so one markup change clears the entire cluster at once.",
245
+ "Re-run the audit after editing the template to confirm all three checks (missing, duplicate, and 600-word-no-H2) clear together."
246
+ ],
247
+ "url": "https://pseolint.dev/rules/heading-structure"
248
+ },
249
+ {
250
+ "ruleId": "content/image-alt-text",
251
+ "slug": "image-alt-text",
252
+ "category": "content",
253
+ "title": "Image Alt Text — Catching Content Images That Ship With No Description",
254
+ "oneLiner": "content/image-alt-text scans every <img> tag on a page, skips images you have explicitly marked decorative, and reports each URL where a content-bearing image carries no alt attribute at all — the accessibility gap WCAG 2.1 has required closing under success criterion 1.1.1 since June 5, 2018 and the one that keeps a page out of Google Images.",
255
+ "whatItDetects": "content/image-alt-text reads every <img> tag in a page's HTML and asks one question of each: is this image content-bearing, and if so does it have an alt attribute at all? The rule parses the tag's attributes, then skips any image you have deliberately marked as decorative — role=\"presentation\" or role=\"none\", aria-hidden=\"true\", or an explicit empty alt=\"\". An empty alt is treated as an intentional signal that the image carries no information, so it is accepted, never flagged.\n\nThe rule fires only when the alt attribute is entirely missing from a content-bearing image — not when it is present but short, and not on images you told it to ignore. For each page it counts how many qualifying images lack alt, divides by the total content-bearing images on that page, and emits one summary finding per URL rather than one line per image. A sample of up to three image sources is attached so you can find the offenders fast.\n\nSeverity scales with how widespread the gap is on the page: when at least half of a page's content images are missing alt the finding is a warning; below that ratio it drops to info, on the logic that a single stray image is a smaller signal than a template that never binds the slot.",
256
+ "howToFix": [
257
+ "Add a descriptive alt attribute to every content-bearing <img> that conveys information — describe what the image shows, not the file name, and keep it to a natural phrase a screen reader can speak.",
258
+ "For purely decorative images — dividers, background flourishes, spacer graphics — set alt=\"\" explicitly or add aria-hidden=\"true\" so the rule recognises the omission as intentional rather than forgotten.",
259
+ "In a pSEO template, bind the alt text from the same data source that fills the rest of the page — the product name, the city, the edition size — so each generated image gets its own description instead of a static default.",
260
+ "Never leave a templated alt at a literal placeholder like alt=\"image\" or the entity name alone; a default that repeats across every page is its own duplicate-content tell even though it technically passes this rule.",
261
+ "Re-run the audit after fixing the template binding — because the finding is per page, a single corrected template binding clears the warning across the entire catalog at once.",
262
+ "Spot-check with a screen reader or the browser accessibility tree to confirm the descriptions actually make sense when read aloud, not just that the attribute is present."
263
+ ],
264
+ "url": "https://pseolint.dev/rules/image-alt-text"
265
+ },
266
+ {
267
+ "ruleId": "links/orphan-pages",
268
+ "slug": "orphan-pages",
269
+ "category": "links",
270
+ "title": "Orphan Pages — URLs No Other Page Links To",
271
+ "oneLiner": "links/orphan-pages scans every URL in the crawl, counts the inbound internal links pointing at each one, and fires at error severity on any page with exactly 0 of them — the dead-zone shape that leaves Googlebot unable to reach a URL through your own navigation, a structural gap the March 27, 2026 core update treats as a discoverability failure rather than a content one.",
272
+ "whatItDetects": "links/orphan-pages builds one number for every page in the crawl: how many other pages in the same corpus link to it. It walks each parsed page, reads the inbound-link count the crawler accumulated while following internal hrefs, and flags any URL whose count is exactly 0. The root URL is exempted — your homepage is reached directly, not via an internal link — so the rule never accuses the front door of being unreachable.\n\nThe check is corpus-scoped, which is the detail that makes it honest. It only knows about pages the crawl actually visited and only counts links between those pages. A URL with zero inbound links is one that no page in the set references, meaning a crawler arriving at your homepage has no internal path to it. The page might still be reachable through your XML sitemap or an external backlink, but inside the site's own link graph it is an island.\n\nEvery orphan emits a single error-severity finding naming the URL and recommending you link to it from a relevant hub or index and add it to navigation. The rule reasons purely about reachability — it makes no judgement about whether the page's content is good, only about whether anything points at it.",
273
+ "howToFix": [
274
+ "Link every orphan from a relevant hub or category index so it joins the site's internal link graph and a crawler can actually reach it.",
275
+ "Fix paginated or truncated index templates that list only the first N items — the missing children are usually the orphans, and crawlable pagination restores them all at once.",
276
+ "Add the page to your primary or contextual navigation when it is genuinely important, so it earns inbound links from high-traffic parts of the site.",
277
+ "Cross-link related items to each other, so a product, article, or location references its siblings instead of depending on one fragile index page.",
278
+ "Re-crawl after wiring the links and confirm the inbound count is no longer 0 — a sitemap entry alone does not clear this rule, because the rule measures internal links, not sitemap membership.",
279
+ "For pages that should not exist as standalone URLs, consolidate or noindex them rather than leaving unreachable thin pages stranded in the corpus."
280
+ ],
281
+ "url": "https://pseolint.dev/rules/orphan-pages"
282
+ },
283
+ {
284
+ "ruleId": "links/dead-ends",
285
+ "slug": "dead-ends",
286
+ "category": "links",
287
+ "title": "Dead Ends — Pages With Zero Outbound Links to the Rest of Your Crawl",
288
+ "oneLiner": "links/dead-ends flags every crawled page (the homepage aside) whose outbound links include zero URLs that point to another page in the same crawl, the forward-flow gap that strands Googlebot and traps link equity, a warning a model-railway shop's 1,400 product listings hit when each turnout and locomotive page links only out to a vendor, never deeper into the store.",
289
+ "whatItDetects": "links/dead-ends walks every page in your audited corpus, skips the root URL, and for each remaining page counts how many of its resolved outbound links point to another page that is also in the crawl. The check is strict: a link only counts if its target is in the known-URL set and is not a self-link back to the same page. When that count lands at exactly zero, the page is a dead end and the rule emits a warning naming the URL.\n\nThe test is corpus-scoped, not page-local. A page can carry dozens of links to external vendors, social profiles, or PDFs and still be a dead end, because none of those targets is another crawled page on your own site. Forward flow is the only thing measured: does standing on this page give a crawler, or a reader, any path deeper into the rest of the corpus.\n\nSeverity is fixed at warning. A dead end is not a broken page or a thin page; it renders fine and may read well. It simply terminates the internal link graph at that node, so anything that travels along links, crawl reach and ranking signal alike, stops there instead of moving on to the next page.",
290
+ "howToFix": [
291
+ "Add contextual internal links from every leaf page to a handful of genuinely related crawled pages, so each node offers the crawler a path forward rather than a one-way valve.",
292
+ "Link each product or article up to its parent category or hub page, which alone is usually enough to clear the warning while also restoring a route back into the broader corpus.",
293
+ "Build a related-items or related-reading block into the page template, since dead ends on programmatic sites almost always trace to a template that renders only external links.",
294
+ "Audit your link resolver: relative hrefs, JavaScript-injected menus, or trailing-slash mismatches can make real internal links resolve to URLs outside the known set, so a linked page still reads as a dead end.",
295
+ "Distinguish a dead end from a deliberately terminal page like a checkout or thank-you screen, and exclude only those that should not feed the crawl, never the content pages you want indexed.",
296
+ "Re-crawl after editing the template, because dead ends are usually template-wide: one fix to the shared listing layout clears the warning on hundreds of pages at once."
297
+ ],
298
+ "url": "https://pseolint.dev/rules/dead-ends"
299
+ },
300
+ {
301
+ "ruleId": "links/link-depth",
302
+ "slug": "link-depth",
303
+ "category": "links",
304
+ "title": "Link Depth — How Many Clicks From Home Before Googlebot Gives Up",
305
+ "oneLiner": "links/link-depth runs a breadth-first search from your root URL and measures the shortest click-distance to every page, flagging anything past the default ceiling of 3 clicks as info and anything Googlebot cannot reach from the root at all as a warning, because a page Google crawls last is a page Google ranks last.",
306
+ "whatItDetects": "links/link-depth treats your internal-link graph the way a crawler does. It seeds a breadth-first search at the root URL you audited, walks every internal link, and records for each page the shortest number of clicks it takes to arrive there. The BFS guarantees that distance is the minimum, so a page linked from both the homepage and a deep article is scored by its nearest path, not its farthest.\n\nTwo distinct findings come out of that single traversal. First, any page whose shortest click-distance exceeds maxClicks — default 3 — is reported at info severity with a message naming the page and the depth it sits at. Three clicks is the conventional ceiling because it mirrors how deep a crawler will eagerly follow before a page starts competing for scarce budget.\n\nSecond, any page that has inbound internal links yet never gets visited by the BFS is reported at warning severity as unreachable-from-root. That gap means the page is referenced somewhere, but no chain of links actually connects it back to the root, so a crawler starting at the homepage would never find it.\n\nWhen the audit only sampled a subset of the site, the unreachable check is suppressed, because a missing path may be a sampling artifact rather than a real dead end; the depth measurement keeps running on whatever subgraph was fetched.",
307
+ "howToFix": [
308
+ "Link your deepest money pages directly from a hub or category page so the BFS reaches them in 2 to 3 clicks instead of 5 or 6.",
309
+ "Audit any page reported as unreachable-from-root first — that is a structural island, and adding a single navigational link from a reachable page fixes it.",
310
+ "Flatten deep taxonomies: collapse redundant intermediate index pages that add a click without adding value to a visitor or a crawler.",
311
+ "Add contextual in-content links from popular shallow pages down to important deep ones, so equity has a short path to follow.",
312
+ "Re-run the audit after restructuring, because moving one hub link can lift an entire subtree of pages back inside the 3-click ceiling at once.",
313
+ "Do not rely on an XML sitemap to rescue a buried page — a sitemap aids discovery but does not pass the internal PageRank that depth controls."
314
+ ],
315
+ "url": "https://pseolint.dev/rules/link-depth"
316
+ },
317
+ {
318
+ "ruleId": "links/cluster-connectivity",
319
+ "slug": "cluster-connectivity",
320
+ "category": "links",
321
+ "title": "Cluster Connectivity — When a Directory of Pages Becomes a Topic Silo",
322
+ "oneLiner": "links/cluster-connectivity groups every crawled URL by its parent directory, and for each cluster of 2 or more pages it checks whether a single internal crawl link enters from another cluster or leaves toward one — firing a warning when neither exists, because Google cannot diffuse authority into a directory that no other section of your site references or is referenced by.",
323
+ "whatItDetects": "The rule keys every crawled URL to its parent directory using the same cluster logic the link family shares: /cheese/affinage/ and /cheese/rind/ collapse to the /cheese/ parent, so a cluster is simply the set of pages that live under one folder. It builds that map first, then only looks at clusters that hold 2 or more pages, because a lone page is an orphan question, not a connectivity one.\n\nFor each multi-page cluster it asks two narrow questions against the set of URLs the crawl actually knows about. First, outbound: does any page in the cluster carry a resolved internal href whose target resolves to a different cluster? Second, inbound: does any page outside the cluster link to any URL inside it? A link that stays within the same parent directory does not count for either test — internal-to-cluster links keep the silo sealed.\n\nWhen a cluster of 2 or more pages has neither a cross-cluster outbound link nor a cross-cluster inbound link, it is a sealed silo and the rule emits one warning naming the directory, the page count, and the affected URLs. A cluster with even a single link crossing its boundary in either direction passes.",
324
+ "howToFix": [
325
+ "Add at least one inbound link from a related section. A single contextual link from your catalog, blog, or navigation into the siloed directory is enough for a crawler to find and credit it.",
326
+ "Add at least one outbound link from inside the cluster to another section. Linking out is half the test; a cluster that only receives links still reads as a one-way pocket until its own pages reference the rest of the site.",
327
+ "Link on topical relevance, not in a footer dump. A contextual link from a genuinely related page passes far more authority and reads as editorial rather than as a sitewide boilerplate block.",
328
+ "Audit your navigation for whole sections it omits. Silos usually form when a directory was built after the main nav was frozen and never got wired back into it.",
329
+ "Re-crawl after adding the links. Because the rule only needs one crossing edge in each direction, a small number of well-placed links can clear several siloed clusters at once.",
330
+ "Treat the warning as a discoverability prompt, not a penalty. The pages are not flagged as low quality — they are flagged as unreachable, which is usually a quick fix with outsized traffic upside."
331
+ ],
332
+ "url": "https://pseolint.dev/rules/cluster-connectivity"
333
+ },
334
+ {
335
+ "ruleId": "cannibal/url-pattern",
336
+ "slug": "url-pattern",
337
+ "category": "cannibal",
338
+ "title": "URL Pattern Cannibalization — When Two Slugs Are the Same Words Reordered",
339
+ "oneLiner": "cannibal/url-pattern splits each URL's last slug on hyphens, sorts the tokens, and flags at info severity any two pages in the same directory whose sorted token sets match exactly — the reordered-slug keyword cannibalization Google has resolved by collapsing competing URLs to one canonical result since well before its March 2026 core update.",
340
+ "whatItDetects": "cannibal/url-pattern looks for two URLs that are, word for word, the same page wearing a different word order. For every page it takes the final path segment — the slug after the last slash, trailing slashes removed — splits it on hyphens, drops empty tokens, and sorts what remains alphabetically. Two slugs that differ only in the order of their words produce an identical sorted token list.\n\nThe rule then compares pages pairwise, but only within the same parent directory: the path up to that last slash must match, and it must not be empty. When two distinct URLs in one directory collapse to the same sorted tokens, the rule fires once at info severity, naming both URLs and reporting that they carry the same tokens in a different order. Pages in different directories never compare against each other, and a slug with no tokens is skipped. The match is exact after sorting — not fuzzy — so it fires only when the two slugs really are the same word set reshuffled.",
341
+ "howToFix": [
342
+ "Pick one canonical token order for every slug your builder emits, so the same record can never mint both /moog-analog-oscillator and /oscillator-moog-analog.",
343
+ "Add a 301 redirect from the reordered twin to the canonical URL, collapsing the pair into one address before the link equity finishes splitting.",
344
+ "Set a rel=canonical on any duplicate you cannot redirect, pointing every reordered variant at the single slug you want Google to rank.",
345
+ "Audit the slug-generation code, not the pages — the reorder almost always comes from a builder concatenating attribute tokens in whatever order the data arrives.",
346
+ "Sort or fix the token order at write time in your data pipeline, so new listings are minted in canonical order and the pair never appears again.",
347
+ "Check internal links and your sitemap for both variants, and repoint every reference at the canonical slug so crawlers stop discovering the twin."
348
+ ],
349
+ "url": "https://pseolint.dev/rules/url-pattern"
350
+ },
351
+ {
352
+ "ruleId": "aeo/freshness-signals",
353
+ "slug": "freshness-signals",
354
+ "category": "aeo",
355
+ "title": "Freshness Signals — When a Page Gives AI Engines No Sign It Is Current",
356
+ "oneLiner": "aeo/freshness-signals checks every page for a real modification signal — a JSON-LD dateModified, an article:modified_time meta tag, or a visible 'Last updated' line — warns at medium confidence when none exists, then drops to an info note when the best date it can parse is older than the staleness default of 180 days Google has long associated with how AI Overviews weigh recency.",
357
+ "whatItDetects": "aeo/freshness-signals asks one question of every crawled page: does it carry evidence that it has been touched recently. The rule looks for a true modification signal in three places — a dateModified field anywhere in the page's JSON-LD (found by a recursive walk), a modification meta tag (article:modified_time, last-modified, dc.date.modified, or a <time datetime> element), or visible 'Last updated', 'updated on', 'revised', or 'last modified' text in the rendered content.\n\nA datePublished alone is deliberately not enough. A page born in 2019 and never edited has a publication date but no modification signal, so it falls through to a warning at medium confidence — medium because evergreen pages like an about, pricing, or policy page may legitimately omit a modified date, and re-stamping them would mislead readers.\n\nWhen a modification signal does exist, the rule parses the best date it can find and measures its age. If that age exceeds maxStaleDays — 180 days by default — it emits an info finding at low confidence, because stale by the clock is not always stale by meaning. The two findings sit at different severities on purpose: a missing signal is a warning, an old-but-present date is only an info note.",
358
+ "howToFix": [
359
+ "Add a real dateModified to your JSON-LD schema and bump it whenever the page's underlying data changes, not just when a human edits the prose.",
360
+ "Render a visible 'Last updated: YYYY-MM-DD' line in the page body so both readers and AI engines see the freshness claim without parsing schema.",
361
+ "Wire the modified timestamp to your data source for pSEO templates, so a forecast page that repulls every 6 hours stamps the moment it actually regenerated.",
362
+ "Keep your sitemap <lastmod> accurate and aligned with the on-page date — a contradictory lastmod is worse than none, since it tells the crawler your timestamps cannot be trusted.",
363
+ "Leave genuinely evergreen pages alone — an about, pricing, or policy page that has not changed should not carry a fake recent date that would mislead a reader.",
364
+ "Refresh the body, not just the date, on pages older than the 180 days default whose information has actually moved on, then bump dateModified to reflect the real edit."
365
+ ],
366
+ "url": "https://pseolint.dev/rules/freshness-signals"
367
+ },
368
+ {
369
+ "ruleId": "aeo/llms-txt",
370
+ "slug": "llms-txt",
371
+ "category": "aeo",
372
+ "title": "llms.txt — A Draft Convention for Guiding AI Engines, Checked at Your Origin",
373
+ "oneLiner": "llms.txt is a draft, low-adoption convention proposed in September 2023 and championed by Jeremy Howard at Answer.AI, so pseolint runs this as a low-confidence, informational site-level check that fetches /llms.txt once at your origin and verifies 3 shape rules, treating a missing file as a missed opportunity worth roughly 1 hour of work, never a defect.",
374
+ "whatItDetects": "This is a site-level check, not a per-page one: it runs exactly once against your origin. pseolint takes the source URL, derives its origin, requests `${origin}/llms.txt` with a 10 second timeout, and only proceeds for http and https targets. If the request fails, times out, or returns a non-200 status, the file is treated as absent.\n\nWhen the file is present, pseolint runs three deliberately lenient shape checks drawn from the llmstxt.org proposal. First, the opening non-empty line must be an `# ` H1 title (lines that start with `#` but carry no title text are skipped, not rejected). Second, the file must contain at least one `## ` section heading. Third, it must list at least one markdown link of the form `- [Title](https://...)` somewhere under a section. A file that satisfies all three passes silently.\n\nA missing file and a malformed file both surface the same low-confidence, informational finding — one tells you nothing exists at the origin, the other names which of the three rules failed. The check is intentionally forgiving because the specification is still evolving; it rejects only obvious garbage.",
375
+ "howToFix": [
376
+ "Create a plain-text file at the root of your origin, served as /llms.txt, that opens with a single `# Project Name` H1 title on the first non-empty line.",
377
+ "Add a short blockquote summary under the title, then break your content into `## ` sections such as Getting Started, API Reference, Guides, and Releases.",
378
+ "Under each section, list your most citable pages as markdown links in the form `- [Quickstart](https://...): one-line description` so an engine can read both the link and its purpose.",
379
+ "Point the links at canonical, current pages — your live quickstart, API reference, SDK guides, and changelog — not deep-archived or redirecting URLs.",
380
+ "Keep it in sync with releases: a stale llms.txt that omits a new major version or a renamed code sample misleads engines more than having none at all.",
381
+ "Validate against the format described at llmstxt.org and re-run the audit; a passing file is silent, so no finding means the three shape checks are satisfied."
382
+ ],
383
+ "url": "https://pseolint.dev/rules/llms-txt"
384
+ },
385
+ {
386
+ "ruleId": "aeo/crawler-access",
387
+ "slug": "crawler-access",
388
+ "category": "aeo",
389
+ "title": "Crawler Access — Is Your robots.txt Blocking AI Answer Engines?",
390
+ "oneLiner": "aeo/crawler-access parses your robots.txt user-agent by user-agent and checks 8 named AI crawlers — GPTBot from OpenAI, ClaudeBot from Anthropic, PerplexityBot, Google-Extended, and four more — warning once per fully blocked bot and escalating to an error only when every one is disallowed, so blocking them stays a deliberate choice you make, not a verdict the rule hands down.",
391
+ "whatItDetects": "The rule reads your robots.txt and parses it into a map of user-agent to its Disallow patterns, lowercasing every agent name so the lookup is case-insensitive and stacking consecutive User-agent lines that share one rule block. It then walks a default list of 8 AI crawler user-agents: GPTBot (OpenAI), ChatGPT-User (OpenAI), ClaudeBot (Anthropic), PerplexityBot (Perplexity), Bytespider (ByteDance), Google-Extended (Google), CCBot (Common Crawl), and Applebot-Extended (Apple). You can override this list in pseolint.config.ts to add or remove agents.\n\nFor each crawler the rule asks one question: is this bot fully disallowed? A bot counts as blocked when its own block contains a root Disallow (`Disallow: /` or `Disallow: /*`), or when it has no rule of its own and falls back to a wildcard `User-agent: *` block that is itself fully disallowed. A bot with its own narrower block — say `Disallow: /admin/` — is not counted as blocked, because the rest of the site is still readable.\n\nEvery fully blocked crawler produces one warning naming that bot. If the count of blocked crawlers equals the full configured list — every AI agent disallowed — the warnings collapse into a single error instead, because total blocking is an unambiguous, site-wide decision worth one clear finding rather than 8 scattered ones.",
392
+ "howToFix": [
393
+ "Open robots.txt and find every block with a root `Disallow: /`. For each named AI crawler you want quotable, delete that root rule so the bot can reach your public pages again.",
394
+ "If you only meant to hide private areas, replace `Disallow: /` with the specific paths — for example `Disallow: /drafts/` and `Disallow: /admin/` — so the rest of the site stays crawlable by answer engines.",
395
+ "Decide deliberately which bots you keep out. Blocking a scraper like Bytespider while allowing GPTBot and ClaudeBot is a valid stance; just confirm it is the stance you actually want.",
396
+ "Remember the wildcard fallback: a `User-agent: *` block with `Disallow: /` silently blocks every AI crawler that has no rule of its own. Give bots you want to allow their own narrower block to escape it.",
397
+ "After editing, re-run the audit. The rule downgrades from a site-wide error to per-bot warnings to silence as you reopen access, so you can watch each decision take effect."
398
+ ],
399
+ "url": "https://pseolint.dev/rules/crawler-access"
400
+ },
401
+ {
402
+ "ruleId": "aeo/faq-coverage",
403
+ "slug": "faq-coverage",
404
+ "category": "aeo",
405
+ "title": "FAQ Coverage — Question Content That Ships With No FAQPage Schema",
406
+ "oneLiner": "aeo/faq-coverage flags any page that reads like an FAQ — at least 2 question-phrased H2 headings starting with how, what, or why, or a /faq, /how-to, or /what-is URL path — yet ships no FAQPage or HowTo JSON-LD, the structured-data gap that matters far more for AI extraction since Google narrowed FAQ rich results to government and health sites in August 2023.",
407
+ "whatItDetects": "aeo/faq-coverage looks at each page and asks two questions in sequence. First, does this page look like FAQ or how-to content? It looks that way if 2 or more of its H2 headings are phrased as questions — a heading that ends in a question mark, or one that opens with a question word like how, what, why, when, where, who, can, does, is, are, should, or which — or if the URL path matches a question pattern such as /faq, /how-to-, /what-is-, /guide-, or /questions. The trigger threshold is the faqMinQuestionHeadings option, which defaults to 2.\n\nSecond, if the page looks like FAQ content, does it carry the structured data that declares it? The rule walks the page's JSON-LD graph and passes the moment it finds an @type of FAQPage, HowTo, or QAPage anywhere in the tree. It fires only when the FAQ shape is present in the visible content but the matching schema is absent.\n\nThe finding lands at info severity with medium confidence. Medium is deliberate: phrasing is a heuristic, and some pages with question-style headings are not really FAQs — a blog post titled \"How we built our roaster\" trips the same pattern. So the rule offers the schema as an opportunity, never as a verdict.",
408
+ "howToFix": [
409
+ "Add FAQPage JSON-LD that mirrors the question H2s already on the page — turn each question heading into a Question node and the answer paragraph below it into the acceptedAnswer, so the schema and the visible content stay in lockstep.",
410
+ "Use HowTo schema instead of FAQPage when the page is a sequence of ordered steps rather than independent questions — a dial-in walkthrough that goes grind, dose, tamp, pull is a HowTo, not a loose Q&A list.",
411
+ "For a pSEO template, generate the schema programmatically from the same data source that renders the headings, so every page gets its own correct markup instead of one hand-written block.",
412
+ "Never ship boilerplate Q&A where only the entity name is swapped — identical questions across every page is a templated-content tell that wastes the schema and reads as mass production.",
413
+ "Set realistic expectations: the FAQ rich result is reserved for authoritative government and health sites since August 2023, so treat the schema as an AI-extraction and voice-answer play, not a guaranteed accordion in blue-link search.",
414
+ "Validate the markup in Google's Rich Results Test and re-crawl, since the rule passes the instant a valid FAQPage, HowTo, or QAPage node appears anywhere in the page's JSON-LD graph."
415
+ ],
416
+ "url": "https://pseolint.dev/rules/faq-coverage"
417
+ },
418
+ {
419
+ "ruleId": "aeo/summary-bait",
420
+ "slug": "summary-bait",
421
+ "category": "aeo",
422
+ "title": "Summary Bait — When a Page Front-Loads Every Fact and Leaves the Body Hollow",
423
+ "oneLiner": "aeo/summary-bait fires when 70% or more of a page's citable facts are crammed into its first 150 words and nothing fresh waits below, a low-confidence warning that the page is shaped for an AI Overviews snippet Google can lift whole rather than for a reader who scrolls past the opener.",
424
+ "whatItDetects": "aeo/summary-bait measures one ratio: of all the citable facts on a page, what fraction sits in the first 150 words? The rule extracts facts with the same patterns aeo/citable-facts uses — dollar amounts, percentages, timeframes like '11 days' or '4 weeks', month-day dates, and form numbers — once across the whole page and once across the opener alone, then divides the opener count by the full count.\n\nWhen 70% or more of the page's facts land in that opener, and the page has at least 3 facts to begin with, the rule warns at low confidence. Two gates keep it quiet on healthy pages. First, the opener must already pass aeo/answer-first — a complete, fact-bearing lead — because front-loading a clear answer is good, not a fault. Second, the page must carry no interactive, downloadable, or gated value below the fold: a foraging-calendar widget, a printable spore-print key, or a sign-in-to-continue block all mean there is a real reason to scroll, so the rule stays silent. Only the overlap — strong opener, everything cited up top, nothing new beneath — trips it.",
425
+ "howToFix": [
426
+ "Keep the answer-first opener, but move the supporting numbers below it. The lead should resolve the question; the dated season tables, yield figures, and method steps belong in sections a reader scrolls to reach.",
427
+ "Add value a summary cannot carry. A foraging-calendar widget, a printable spore-print identification key, or a region-specific harvest map gives both the reader and the rule a genuine reason the page exists beyond its opener.",
428
+ "Redistribute citable facts so concentration drops under the 70% threshold. If four of five figures sit in the first 150 words, push two of them into a 'Full season breakdown' section deeper on the page.",
429
+ "Replace padding prose with new information. The body that merely restates the opener in looser words is exactly what flags the page; every section below the fold should add a fact the snippet did not.",
430
+ "Gate or download the genuinely valuable asset. A sign-in-to-save patch log or a downloadable hedgerow checklist counts as below-fold value the rule respects, because an AI Overview cannot reproduce it.",
431
+ "Re-run the audit after rebalancing. The finding clears the moment opener concentration falls below 70% or the page gains real interactive value below the fold."
432
+ ],
433
+ "url": "https://pseolint.dev/rules/summary-bait"
434
+ },
435
+ {
436
+ "ruleId": "content/translation-no-op",
437
+ "slug": "translation-no-op",
438
+ "category": "content",
439
+ "title": "Translation No-Op — Locale Folders That Were Never Actually Translated",
440
+ "oneLiner": "content/translation-no-op groups URLs that differ only by a leading locale segment like /en/ or /fr/, computes a 64-bit SimHash of each extracted body, and fires an error the moment any pair scores at or above 95% similarity — the fake-i18n pattern Google has told site owners to fix with real hreflang pairs, not duplicated English.",
441
+ "whatItDetects": "content/translation-no-op catches a specific failure of programmatic internationalisation: a site ships /en/, /fr/, /de/ folders that look multilingual in the URL but carry the same untranslated body on every locale.\n\nThe rule reads each page's path and matches a leading locale segment with a regular expression covering two-letter codes and region variants — /en/, /fr/, /it/, /fr-ca/. Pages without a locale prefix are skipped. It strips that segment to a base path so /en/openings and /fr/openings both collapse to /openings, then buckets every locale variant under that shared base path. A bucket with fewer than two members is ignored, because one lone locale is not a translation problem.\n\nWithin each bucket it computes a 64-bit SimHash from the extracted main content text, measures Hamming distance between every variant pair, and converts that distance to a similarity score in [0,1]. If any pair scores at or above the 0.95 threshold, the rule emits one error per cluster naming the locale count, the base path, and the exact similarity percentage so you can see how identical the variants really are.",
442
+ "howToFix": [
443
+ "Translate the body for real, not just the title and nav — the SimHash is computed on extracted main content, so a translated heading over an English article still trips the rule at 95%.",
444
+ "If a locale was never meant to ship, delete the untranslated folder and remove its hreflang entry rather than leaving a duplicate live under a foreign tag.",
445
+ "Where you genuinely cannot translate yet, redirect every untranslated locale variant to the canonical URL and keep hreflang only on the canonical until real translations exist.",
446
+ "Audit your i18n pipeline for partial coverage: a template that translated 4 of 12 locales leaves 8 folders of duplicated source language that this rule will flag cluster by cluster.",
447
+ "Re-run after each translation pass — the rule fires once per cluster of near-identical variants, so clearing one base path does not silence the others until their bodies actually diverge."
448
+ ],
449
+ "url": "https://pseolint.dev/rules/translation-no-op"
450
+ },
451
+ {
452
+ "ruleId": "content/regurgitated-content",
453
+ "slug": "regurgitated-content",
454
+ "category": "content",
455
+ "title": "Regurgitated Content — When Your Directory Is Just the Google Places API Reskinned",
456
+ "oneLiner": "content/regurgitated-content is a low-confidence v1 heuristic that fires a warning when a page shows at least 2 of 5 Google-Places-regurgitation tells — Powered by Google attribution, googleusercontent images over 60%, a Static Maps embed, Places API JavaScript, or an aggregator footprint of 5 or more unsigned star-rating blocks.",
457
+ "whatItDetects": "content/regurgitated-content looks for one shape: a page that lifts business names, reviews, addresses, and photos straight from the Google Places API and presents them as a directory with nothing of its own added on top. It reads five independent signals per page and fires only when at least 2 of them are present.\n\nThe signals are specific. (1) Google Places attribution — a 'powered by google' string, or a noopener anchor pointing at google.com/maps. (2) Google images dominate — once a page has 3 or more images, the rule fires this signal when over 60% of them are hosted on googleusercontent.com, the Places photo endpoint, or Street View pixels. (3) Static Maps or Maps embed — a maps.googleapis.com/maps/api/staticmap source, or a google.com/maps/embed iframe. (4) Places API JavaScript — a google.maps.places.PlacesService or AutocompleteService marker in the markup. (5) Aggregator footprint — 5 or more elements carrying a star rating (Unicode stars, a 4.5/5 fraction, or the word 'stars') on a page that shows fewer than 2 of 3 E-E-A-T signals (author, published date, an /about link).\n\nSeverity is fixed at warning and confidence is low. This is a v1 heuristic that reasons about structure, never about a licence: it cannot read a Places API contract or know whether you have permission. It only sees the fingerprint that raw redistribution leaves behind.",
458
+ "howToFix": [
459
+ "Add proprietary substance the API does not hold — original tasting notes, a ranked verdict, a first-person visit log — so the page is more than a redistribution layer.",
460
+ "Shoot and host your own photography. When your own images outnumber googleusercontent.com hero shots, the Google-images-dominate signal stops firing and the page stops looking lifted.",
461
+ "Keep one attributed Google review if you like, but write your own editorial summary alongside it rather than republishing a wall of 5-plus star-rating blocks verbatim.",
462
+ "Attach E-E-A-T: a named byline, a published date, and an /about page describing how you evaluate each venue, which both clears the aggregator-footprint signal and answers the trust question.",
463
+ "Use the embedded map as a convenience, not the content — one Static Maps embed is fine when the words around it are yours and not the API's.",
464
+ "If a page genuinely has nothing to add beyond the Places data, merge it or cut it rather than shipping a thin reskin that competes with Google using Google's own facts."
465
+ ],
466
+ "url": "https://pseolint.dev/rules/regurgitated-content"
467
+ },
468
+ {
469
+ "ruleId": "content/common-phrase-reuse",
470
+ "slug": "common-phrase-reuse",
471
+ "category": "content",
472
+ "title": "Common Phrase Reuse — When pSEO Clichés Pile Up On One Page",
473
+ "oneLiner": "content/common-phrase-reuse scans each page against a bundled list of roughly 42 pSEO marketing clichés grouped into 5 categories — location filler, generic-marketing superlatives, aggregator phrasing, fake-authority claims, and filler hedges — and raises one low-confidence warning the moment 3 or more distinct phrases from that list appear, a speculative density signal Google's helpful-content guidance has weighted since 2024.",
474
+ "whatItDetects": "content/common-phrase-reuse measures how heavily a page leans on stock marketing language. It carries a bundled list of roughly 42 pSEO clichés split across 5 categories: location filler, generic-marketing superlatives, aggregator phrasing, fake-authority claims, and filler hedges. The failing example below shows the kind of phrasing each category covers, so this explainer keeps the quoted samples inside that illustration rather than scattering them through the prose.\n\nFor each page the rule lower-cases the main content text and checks which bundled phrases appear as substrings. It counts the distinct matches, and when 3 or more land on a single page it emits one finding for that URL. The severity is a warning and the confidence is deliberately low: matching a fixed phrase list is a crude proxy, so the rule names the first few matches it found and leaves the judgement to you rather than asserting the page is bad.",
475
+ "howToFix": [
476
+ "Read the finding's listed phrases and delete the ones that are pure filler before swapping anything in.",
477
+ "Replace each cliché with a specific fact: not 'world-class concierge' but 'concierge desk staffed 24 hours, 7 days a week'.",
478
+ "Lead the page with the one detail that is true here and nowhere else, so stock phrases are not carrying the introduction.",
479
+ "Audit the template, not the page — one cliché-laden frame can stamp the same 4 phrases across thousands of generated URLs.",
480
+ "Aim for 2 or fewer stock phrases per page; the rule fires at 3, and staying a margin under it survives small copy edits.",
481
+ "Re-run the audit after editing, since removing 2 of 5 clichés drops a page back under the threshold immediately."
482
+ ],
483
+ "url": "https://pseolint.dev/rules/common-phrase-reuse"
484
+ },
485
+ {
486
+ "ruleId": "content/wikipedia-paraphrase",
487
+ "slug": "wikipedia-paraphrase",
488
+ "category": "content",
489
+ "title": "Wikipedia Paraphrase — When Your Page Is Just the Encyclopedia, Reworded",
490
+ "oneLiner": "content/wikipedia-paraphrase fires a low-confidence warning the moment a page shares 40% or more of its three-word phrases with a bundled Wikipedia reference corpus, the trigram-overlap point at which Google's helpful-content framing reads a URL as reworded encyclopedia rather than the original analysis a March 2024 audit rewards.",
491
+ "whatItDetects": "content/wikipedia-paraphrase asks one narrow question of each page: how much of your prose is just Wikipedia, lightly reworded? The rule tokenises the main content text — lower-cased, punctuation stripped, split on whitespace — and slides a three-word window across it to produce a list of trigrams. Each trigram is checked against a bundled Wikipedia reference corpus stored as a compact bloom filter (65,536 bits, 3 FNV-1a hash functions, roughly a 5% false-positive rate over about 10,000 curated trigrams). The paraphrase rate is the fraction of a page's trigrams that hit the corpus.\n\nWhen that rate reaches the 0.40 threshold, the rule emits one finding per qualifying page at warning severity and low confidence, reporting the exact overlap percentage so you can sort worst-first. Pages with fewer than three tokens score zero and are skipped. The framing is deliberate: paraphrased encyclopedic content adds nothing original to the web, so a page that is 40% recycled Wikipedia phrasing is, for ranking purposes, a page that already exists.\n\nThe heuristic is honest about its limits — it is a low-confidence signal precisely because the corpus is bundled and finite, and a page about a genuinely encyclopedic subject can share common phrasing without copying anything.",
492
+ "howToFix": [
493
+ "Lead with first-hand observation the encyclopedia cannot have — the dig site, the exact sediment layer, the prep tools, the measured dimensions of your actual specimen.",
494
+ "Replace reworded background with two or three linked sentences, then send the reader to Wikipedia for the textbook taxonomy rather than rephrasing it on your page.",
495
+ "Add page-specific facts that exist nowhere else: your matrix-removal technique, the failed prep that cracked a trilobite, the locality coordinates, the date you collected it.",
496
+ "Photograph and describe your own material. A theropod tooth you found, scaled and lit, is content no corpus contains; a reworded description of theropod dentition is not.",
497
+ "Re-run the audit and sort by overlap percentage. Clear pages above 45% first — those are almost entirely reference text and need the most original substance grafted in.",
498
+ "Treat the warning as a prompt, not a verdict. On a legitimately encyclopedic topic the heuristic can over-fire, so confirm the page actually reads as reworded Wikipedia before rewriting it."
499
+ ],
500
+ "url": "https://pseolint.dev/rules/wikipedia-paraphrase"
501
+ },
502
+ {
503
+ "ruleId": "content/value-add",
504
+ "slug": "value-add",
505
+ "category": "content",
506
+ "title": "Value-Add Score — The Composite That Reads Seven Other Rules",
507
+ "oneLiner": "content/value-add is a second-pass composite that reads seven other rules' findings — originality, freshness, citable facts, the four-category E-E-A-T count, translation, cliche reuse, and Wikipedia paraphrase — weights each at one-seventh, averages them into a single 0-to-1 score, and fires an error below 50% or a critical below 30%, the synthesis SpamBrain has rewarded since the March 5, 2024 update.",
508
+ "whatItDetects": "content/value-add does not parse a page. It runs after every other rule has finished and reads their findings, turning seven separate originality checks into one number. Each signal is scored 0, 0.5, or 1 for the page, and the rule takes the plain average — every signal weighted at one-seventh, about 14%.\n\nThe seven signals are: originality (1 unless content/regurgitated-content fired here, then 0), freshness (from aeo/freshness-signals — 1 if silent, 0.5 at warning, 0 otherwise), citable facts (from aeo/citable-facts — 1 if silent, 0.5 at info or warning, 0 otherwise), E-E-A-T (a four-category count — 1 at four signals, 0.5 at two or three, 0 below two), translation (0 if content/translation-no-op named this page, else 1), cliche reuse (0 if content/common-phrase-reuse fired, else 1), and Wikipedia paraphrase (0 if content/wikipedia-paraphrase fired, else 1).\n\nThe average is the value-add score. Below 50% the rule fires one finding per page at error severity; below 30% it escalates that finding to critical. Confidence is fixed at medium.",
509
+ "howToFix": [
510
+ "Lift originality first — rewrite any copy that tripped regurgitated-content into a page-specific tasting note, because that signal is binary and recovering it adds a full one-seventh to the score.",
511
+ "Add a real published or updated date so the freshness signal climbs from 0 toward 1 — an undated page scores zero on a signal that costs one line of markup to fix.",
512
+ "Bind citable facts a buyer can quote — a harvest window, a steeping temperature, an estate elevation — so the citable-facts signal stops scoring zero on a page of pure prose.",
513
+ "Reach four E-E-A-T categories — a byline, an about link, a date, and a sources block — since two or three only earns 0.5 while four earns the full point.",
514
+ "Clear cliche reuse and any translation-no-op flag — both are binary signals, and a page padded with common phrases or a hollow auto-translation each forfeits a full one-seventh.",
515
+ "Re-run the audit after fixing the worst two signals — because the score is an average, recovering two zeros to ones usually moves a 43% page past the 50% floor in one pass."
516
+ ],
517
+ "url": "https://pseolint.dev/rules/value-add"
518
+ }
519
+ ];
520
+ //# sourceMappingURL=okf-knowledge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"okf-knowledge.js","sourceRoot":"","sources":["../src/okf-knowledge.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -3,6 +3,13 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  export declare function registerReadOnlyTools(server: McpServer): void;
4
4
  /** Register the AI-orchestrated audit tool (costs money; gate behind auth when remote). */
5
5
  export declare function registerOrchestrateTool(server: McpServer): void;
6
+ /**
7
+ * Expose pseolint's rule knowledge (Open Knowledge Format bundle, lean subset)
8
+ * as read-only MCP resources, keyed by ruleId so they line up 1:1 with the
9
+ * `ruleId` on audit findings. An agent can audit, then read `pseolint://rules/<id>`
10
+ * for what the rule detects and how to fix it — no web fetch, no extra tool.
11
+ */
12
+ export declare function registerRuleKnowledge(server: McpServer): void;
6
13
  export declare function createServer(): McpServer;
7
14
  export declare function startMcpServer(): Promise<void>;
8
15
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwUpE,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2Q7D;AAED,2FAA2F;AAC3F,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4F/D;AAED,wBAAgB,YAAY,IAAI,SAAS,CAQxC;AAyHD,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAIpD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyUpE,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+Q7D;AAED,2FAA2F;AAC3F,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4F/D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkD7D;AAED,wBAAgB,YAAY,IAAI,SAAS,CASxC;AAyHD,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAIpD"}
package/dist/server.js CHANGED
@@ -3,6 +3,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
3
3
  import { z } from "zod";
4
4
  import { createRequire } from "node:module";
5
5
  import { auditSource, formatConsole, formatJson, orchestrate, SCORED_CATEGORY_KEYS } from "@pseolint/core";
6
+ import { RULE_KNOWLEDGE } from "./okf-knowledge.js";
6
7
  /**
7
8
  * MCP SDK 1.29's `inputSchema`/`outputSchema` are typed as
8
9
  * `ZodRawShapeCompat = Record<string, z3.ZodTypeAny | z4.$ZodType>` via a
@@ -290,6 +291,7 @@ export function registerReadOnlyTools(server) {
290
291
  sampleSize: z.number().int().min(0).max(MAX_SAMPLE_SIZE).optional().default(0).describe(`Audit a random subset of N pages. 0 = all pages up to the MCP cap of ${MCP_SAMPLE_CAP}. Set explicitly to override the cap (up to ${MAX_SAMPLE_SIZE}).`),
291
292
  format: z.enum(["console", "json"]).optional().default("console").describe("Text-content format. Use 'json' for full machine-readable output, 'console' for a human-readable summary. structuredContent is always returned regardless."),
292
293
  authorityScore: z.number().int().min(0).max(100).optional().describe("Bring-your-own domain authority (0-100). >=80 shifts the verdict one tier lenient on established brands; <=30 shifts one tier stricter on newer/lower-authority operators. The raw risk number is never modified."),
294
+ contentEffort: z.boolean().optional().describe("Enable the AI content-effort signal: a 0-100 originality/effort score (judged from page text) that moderates the verdict ±1 tier. Needs ANTHROPIC_API_KEY in the server environment; no-ops safely without one. Default off; adds a few cents of LLM cost per audit."),
293
295
  sampleSeed: z.number().int().optional().describe("Integer seed for deterministic stratified sampling. Same seed + same sampleSize = same audit = same verdict, run after run."),
294
296
  }),
295
297
  outputSchema: zodShape({
@@ -314,7 +316,7 @@ export function registerReadOnlyTools(server) {
314
316
  idempotentHint: true,
315
317
  openWorldHint: true,
316
318
  },
317
- }, async ({ source, threshold, sampleSize, format, authorityScore, sampleSeed }) => {
319
+ }, async ({ source, threshold, sampleSize, format, authorityScore, contentEffort, sampleSeed }) => {
318
320
  try {
319
321
  // MCP audits run on user-supplied URLs inside AI-assistant environments
320
322
  // where the LLM may not vet the target. `safeMode: "saas"` flips on
@@ -324,6 +326,8 @@ export function registerReadOnlyTools(server) {
324
326
  options.sampleSize = sampleSize > 0 ? sampleSize : MCP_SAMPLE_CAP;
325
327
  if (authorityScore !== undefined)
326
328
  options.authorityScore = authorityScore;
329
+ if (contentEffort)
330
+ options.contentEffort = { enabled: true };
327
331
  if (sampleSeed !== undefined)
328
332
  options.sampleSeed = sampleSeed;
329
333
  const summary = await auditSource(source, options);
@@ -395,6 +399,7 @@ export function registerReadOnlyTools(server) {
395
399
  source: z.string().min(1).describe("URL (e.g. http://localhost:3000) or local directory path (e.g. ./out) to audit"),
396
400
  threshold: z.number().int().min(0).max(100).optional().default(40).describe("Risk threshold for the pass/fail verdict (default: 40)"),
397
401
  authorityScore: z.number().int().min(0).max(100).optional().describe("Bring-your-own domain authority (0-100). >=80 shifts the verdict one tier lenient; <=30 shifts one tier stricter. Raw risk unchanged."),
402
+ contentEffort: z.boolean().optional().describe("Enable the AI content-effort signal: a 0-100 originality/effort score (judged from page text) that moderates the verdict ±1 tier. Needs ANTHROPIC_API_KEY in the server environment; no-ops safely without one. Default off; adds a few cents of LLM cost per audit."),
398
403
  sampleSeed: z.number().int().optional().describe("Integer seed for deterministic stratified sampling. Same seed = same audit = same verdict."),
399
404
  }),
400
405
  outputSchema: zodShape({
@@ -415,11 +420,13 @@ export function registerReadOnlyTools(server) {
415
420
  idempotentHint: true,
416
421
  openWorldHint: true,
417
422
  },
418
- }, async ({ source, threshold, authorityScore, sampleSeed }) => {
423
+ }, async ({ source, threshold, authorityScore, contentEffort, sampleSeed }) => {
419
424
  try {
420
425
  const options = { sampleSize: MCP_SAMPLE_CAP, safeMode: "saas" };
421
426
  if (authorityScore !== undefined)
422
427
  options.authorityScore = authorityScore;
428
+ if (contentEffort)
429
+ options.contentEffort = { enabled: true };
423
430
  if (sampleSeed !== undefined)
424
431
  options.sampleSeed = sampleSeed;
425
432
  const summary = await auditSource(source, options);
@@ -610,6 +617,47 @@ export function registerOrchestrateTool(server) {
610
617
  }
611
618
  });
612
619
  }
620
+ /**
621
+ * Expose pseolint's rule knowledge (Open Knowledge Format bundle, lean subset)
622
+ * as read-only MCP resources, keyed by ruleId so they line up 1:1 with the
623
+ * `ruleId` on audit findings. An agent can audit, then read `pseolint://rules/<id>`
624
+ * for what the rule detects and how to fix it — no web fetch, no extra tool.
625
+ */
626
+ export function registerRuleKnowledge(server) {
627
+ const indexUri = "pseolint://rules";
628
+ server.registerResource("pseolint-rules-index", indexUri, {
629
+ title: "pseolint rule knowledge index",
630
+ description: "Index of pSEO audit rules with knowledge resources. Read pseolint://rules/<ruleId> (the same ruleId on audit findings) for detection + fix guidance.",
631
+ mimeType: "application/json",
632
+ }, (uri) => ({
633
+ contents: [
634
+ {
635
+ uri: uri.href,
636
+ mimeType: "application/json",
637
+ text: JSON.stringify(RULE_KNOWLEDGE.map((r) => ({ ruleId: r.ruleId, title: r.title, uri: `pseolint://rules/${r.ruleId}` })), null, 2),
638
+ },
639
+ ],
640
+ }));
641
+ for (const rule of RULE_KNOWLEDGE) {
642
+ const uri = `pseolint://rules/${rule.ruleId}`;
643
+ server.registerResource(`rule-${rule.ruleId}`, uri, {
644
+ title: rule.title,
645
+ description: rule.oneLiner,
646
+ mimeType: "text/markdown",
647
+ }, (u) => ({
648
+ contents: [
649
+ {
650
+ uri: u.href,
651
+ mimeType: "text/markdown",
652
+ text: `# ${rule.title}\n\n` +
653
+ `Rule \`${rule.ruleId}\` — ${rule.url}\n\n` +
654
+ `## What it detects\n${rule.whatItDetects}\n\n` +
655
+ `## How to fix\n${rule.howToFix.map((b) => `- ${b}`).join("\n")}\n`,
656
+ },
657
+ ],
658
+ }));
659
+ }
660
+ }
613
661
  export function createServer() {
614
662
  const server = new McpServer({
615
663
  name: "pseolint",
@@ -617,6 +665,7 @@ export function createServer() {
617
665
  });
618
666
  registerReadOnlyTools(server);
619
667
  registerOrchestrateTool(server);
668
+ registerRuleKnowledge(server);
620
669
  return server;
621
670
  }
622
671
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pseolint/mcp",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "mcpName": "io.github.ouranos-labs/pseolint",
5
5
  "description": "MCP server for pseolint — audit programmatic SEO sites from AI coding assistants. v0.5 adds the AI-orchestrated audit tool that produces a fix manifest with concrete patches.",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@modelcontextprotocol/sdk": "^1.29.0",
48
- "@pseolint/core": "^0.7.1",
48
+ "@pseolint/core": "^0.7.3",
49
49
  "zod": "^4.3.6"
50
50
  }
51
51
  }