Skip to content

piyushbhattadforapps/pseo-quality-gate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pseo-quality-gate

Premium-content quality gate for programmatic SEO at scale. Thirteen hard gates that distinguish premium pSEO content from the AI-slop templates that get classified out of Google's index.

License: MIT Node Zero dependencies

The problem

Programmatic SEO operations that ship at scale (>100 pages from a single template) face a specific Google failure mode. The helpful-content classifier waits two to twelve weeks before applying a site-wide quality verdict, and once it triggers, the entire programmatic surface drops out of the index together. Individual page recovery after a site-level demotion takes months and sometimes never happens.

The Detailed.com 2024 audit of 23 large affiliate sites found that 17 had lost 60-95% of organic traffic within 90 days of a major Google update. The surviving 6 had measurably stricter content quality controls in place pre-update.

Writing better content is the standard advice. Enforcing "better" mechanically before pages ship, at the scale where humans cannot review every page individually, is the hard part.

What this package does

Validates a JSON content payload against thirteen hard gates that approximate the helpful-content classifier's filter from the public side. The gates are necessary, not sufficient. Passing every gate does not guarantee ranking; failing any gate is a strong predictor of eventual deindexation.

The validator is content-generator-agnostic. It fires on the output of whatever pipeline you use (human, LLM, hybrid) and tells you whether the page passes the structural and stylistic gates. It does not generate content, score backlinks, or validate schema.org markup; those are separate concerns with their own tools.

Quick start

# Run via npx, no install required
npx pseo-quality-gate ./content/page-001.json

# Validate a directory tree
npx pseo-quality-gate --glob "content/**/*.json"

# Machine-readable output for CI pipelines
npx pseo-quality-gate --json ./content/page-001.json

Or as a library:

import { runAllGates } from "pseo-quality-gate";
import fs from "fs";

const data = JSON.parse(fs.readFileSync("page.json", "utf8"));
const result = runAllGates(data);

if (!result.pass) {
  for (const e of result.errors) console.error(`${e.gate}: ${e.message}`);
  process.exit(1);
}

The thirteen gates

# Gate What it checks
1 title length ≤ 70 chars
2 metaDescription length 130-165 chars
3 h1 present
4 about ≥ 4 paragraphs, ≥ 500 words total
5 faqs ≥ 5 items, each answer ≥ 15 words
6 citations ≥ 1 with valid reference id (when embeddedItems[] is non-empty)
7 relatedLinks ≥ 5 internal links
8 author name and url present
9 lastUpdated YYYY-MM-DD format
10 emDashes zero anywhere in the JSON
11 marketingProse no blocklisted terms in body content
12 marketingHeadlines no blocklisted terms in title/h1/subheading/metaDescription
13 solicitCriticism no fake-humility closers anywhere

Full gate-by-gate reference: docs/13-hard-gates.md.

Schema

The validator works on a generic premium-content shape. Map your domain fields to this shape; the gates do not require any specific vertical.

interface PremiumContentPage {
  title: string;            // <= 70 chars
  metaDescription: string;  // 130-165 chars
  h1: string;
  subheading?: string;
  about: string[];          // >= 4 paragraphs, >= 500 words total
  faqs: { q: string; a: string }[];               // >= 5
  citations?: { id: string; text: string }[];     // required if embeddedItems[]
  embeddedItems?: { id: string; [k: string]: any }[];
  relatedLinks: { url: string; label: string }[]; // >= 5
  author: { name: string; url: string };
  lastUpdated: string;      // YYYY-MM-DD
}

See examples/pass.json for a complete passing payload and examples/fail.json for a deliberately broken one.

Configuring thresholds

import { runAllGates, DEFAULT_THRESHOLDS } from "pseo-quality-gate";

const result = runAllGates(data, {
  thresholds: {
    ...DEFAULT_THRESHOLDS,
    ABOUT_MIN_WORDS: 750,    // stricter than default 500
    FAQ_MIN: 7,              // stricter than default 5
  },
  extraProseTerms: ["unrivaled", "world-renowned"],   // extend the blocklist
});

Using individual gates

import { gateAbout, gateMarketingProse, gateEmDashes } from "pseo-quality-gate/gates";

const errors = [
  gateAbout(data),
  gateEmDashes(data),
  gateMarketingProse(data, { extraProseTerms: ["myextra"] }),
].filter(Boolean);

Origin

This validator was originally written for the day-trip programmatic SEO section of bestroadtrip.com, where it gates eighty city-pair pages built from a corpus of 1,400 creator-recorded short videos. The site's research section publishes the underlying methodology and dataset behind the page generator; the gates here are extracted from that specific operation and generalized for any premium pSEO content type.

Security and privacy

This package is a CLI/library that reads local JSON files and runs deterministic checks. It makes zero outbound network requests. It uses zero npm dependencies. It does not collect telemetry, write to any path outside the working directory it is run in, or contain any embedded credentials, API keys, or proprietary data. The validator can be run fully offline against any content payload.

Contributing

Contributions welcome. New gates that have empirical backing, refinements to the default thresholds, or expansions to the marketing-language blocklist are all in scope. See CONTRIBUTING.md.

License

MIT. See LICENSE.

About

Premium-content quality gate for programmatic SEO at scale. 13 hard gates that distinguish premium pSEO content from AI-slop templates. Zero dependencies.

Topics

Resources

License

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors