Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rankloop

The anti-slop pSEO engine.

rankloop is a stateful, self-feeding loop built around one SQLite keyword backlog: real search data flows in, grounded writer briefs flow out, and a wall of publish laws blocks filler before it ships. It was extracted from a production engine that ran three sites, and it encodes the one thing that engine proved: nine-tenths of the value of programmatic SEO is the machinery around the writing, not the writing.

rankloop never writes a word of content and never calls an LLM. It makes whatever writes your content — an LLM CLI, a script, a person — grounded, honest, and measurable.

   seeds ──► discover / suggest / harvest ──► score ──► SERP-ground ──► pick
                                                                          │
   GSC unserved-query harvest ◄── measure traffic ◄──┐                    ▼
        (refills the backlog)                        │        brief ──► YOUR WRITER
                     ▲                               │                    │
                     └─────────── deploy ◄── wire ◄──┴── check (the laws)

Every arrow reads or writes a single SQLite file that lives next to your config (safe to commit — state travels with the repo). The loop closes at the bottom-left: queries Google already shows your site for, that have no page and no backlog row yet, get harvested straight back into the queue on every Search Console sync. That is the flywheel.

  • Stdlib-only core. No required dependencies. Python 3.11+.
  • Niche-agnostic. All niche knowledge (seeds, relevance regexes, taxonomy, banned phrases) lives in one commented rankloop.toml; all machinery lives in code. Swap the config and the same engine runs any site.
  • Writer-agnostic. rankloop brief emits a grounded markdown brief on stdout. Pipe it into anything.

Zero-to-configured: point an agent at your site

The fastest path. From your site's repo:

pipx install rankloop
rankloop setup | claude -p        # or any agent CLI with file access

setup prints a complete onboarding prompt. The agent studies your site -- its niche, voice, information architecture, even the CSS -- and writes your entire configuration: rankloop.toml (relevance regexes, taxonomy, laws calibrated so your existing posts pass), seeds.txt (50-100 clustered seed phrases), writer-prompt.md (your voice + verified facts), a post template matched to your design, and an OG-card palette derived from your real brand colors. It finishes by printing the cron lines that automate the whole loop.

Then automation is three cron lines -- each routine prints its full operating playbook, so the agent that runs it needs zero prior context:

30 9 * * *      cd /your/site && rankloop routine daily  | claude -p
0  9 * * 1      cd /your/site && rankloop routine weekly | claude -p
0 8,14,20 * * * cd /your/site && rankloop routine news   | claude -p

The daily routine has catch-up quota semantics: a missed day is owed, not skipped (rankloop quota computes it from the calendar and the content tree itself, capped so an outage never floods the site). Your laptop can sleep; the plan doesn't drift.

Quickstart (manual)

pipx install rankloop            # stdlib-only core, zero dependencies

cd your-site/
rankloop init                    # writes a commented rankloop.toml + seeds.txt
$EDITOR rankloop.toml            # your niche lives here: regexes, taxonomy, laws
$EDITOR seeds.txt                # 50-100 seed phrases in commented clusters

# fill the backlog — free path first
rankloop suggest                 # Google/Bing/DDG autocomplete long-tails ($0)
rankloop harvest                 # StackExchange + Reddit literal questions ($0)

# optional paid metrics (DataForSEO account required)
rankloop discover --dry-run      # cost projection only — spends nothing
rankloop discover                # volume + difficulty + SERP briefs, budget-capped

# write one post
rankloop pick                    # top-scored keywords + one fresh-question slot
rankloop brief "your keyword" | your-writer > website/blog/your-keyword/index.html
#                               ^ claude -p, a script, a human with a text editor

# gate + ship
rankloop check                   # the publish laws; any failure exits 1
rankloop wire                    # regenerate sitemap.xml, rss.xml, llms.txt
rankloop indexnow                # ping Bing/DuckDuckGo/Yandex directly
git add -A && git commit -m "post" && git push    # deploy however you deploy

# close the loop (weekly)
rankloop gsc setup               # one-time Search Console OAuth (loopback, stdlib)
rankloop gsc sync --days 28      # pull real queries; unserved ones refill the backlog
rankloop status                  # backlog by status/source, spend, 28-day GSC summary

rankloop check is designed as a CI gate: it exits non-zero on any law failure, so one sloppy post can never silently ship with the good ones.

The laws

Every post passes these before it ships. Thresholds are config ([laws] in rankloop.toml); defaults were calibrated on a real corpus.

law default why
em dashes banned on the single most reliable LLM tell; colons and periods instead
word count 850–4500 below = thin page; above = should be two pages
H2 sections ≥ 4 scannable structure; each H2 is a potential snippet
FAQ entries ≥ 3 answer engines extract these verbatim
internal links ≥ 2, must resolve every link is checked against real slugs — no post ships a 404
title length ≤ 70 chars SERP truncation
meta description ≤ 165 chars SERP truncation
keyword in body required you'd be surprised
keyword density ≤ 2.5% above this it reads like it was written for a robot, because it was
banned filler phrases 15 defaults "delve into", "game-changer", "in today's fast-paced world"… any hit fails
first-person present on a human voice, enforced mechanically
canonical URL required (html mode) must equal exactly site.url + blog_path + slug

A second, tool-gated layer runs when the tools are installed and degrades to a WARN + skip when they are not — automation is never blocked by a missing dependency:

  • vale — the same banned-phrase laws as prose lint, plus an AI-slop watchlist and hedge-phrase warnings (styles ship in rankloop/templates/vale/)
  • lychee — offline link checking across the whole content tree
  • extruct — JSON-LD completeness, FAQ schema mirrored in visible text
  • textstat — readability band (FK grade / reading ease)
pip install 'rankloop[lint]'     # extruct + textstat
brew install vale lychee         # or your package manager of choice

What's in the box

command what it does
rankloop init write a commented rankloop.toml + seeds.txt template
rankloop suggest free autocomplete harvest (Google, Bing, DuckDuckGo; 8 question prefixes × a–z fan-out)
rankloop harvest free literal-question harvest (StackExchange tag feeds, Reddit public RSS)
rankloop discover paid keyword metrics via DataForSEO — cost-projected, budget-capped, every call logged to a spend ledger
rankloop news poll trigger feeds, dedupe, print fresh items — news is a trigger for evergreen pages, never a content type
rankloop pick the selector: highest-scored backlog rows + one fresh-question slot
rankloop brief emit a grounded markdown writer brief (cached SERP + real People-Also-Ask + your laws) to stdout
rankloop check enforce the laws; exit 1 on any failure
rankloop linkfix strip dead internal links, keep the anchor text as prose
rankloop wire regenerate sitemap.xml, rss.xml, llms.txt, llms-full.txt from the post manifest — idempotent, never touches your index or theme
rankloop indexnow submit URLs to the IndexNow API (Bing/DuckDuckGo/Yandex)
rankloop gsc setup / gsc sync Search Console OAuth + sync; unserved queries auto-refill the backlog
rankloop status one screen: backlog by status/source, total spend, GSC 28-day summary

The flywheel

The part that makes the engine self-feeding: rankloop gsc sync pulls your real Search Console rows, then harvests unserved queries — search terms Google already shows you for that have no page and no backlog row — straight back into the keyword queue. It also surfaces opportunity pages (earning impressions, CTR under 2%: your title/meta rewrite queue) and page-2 keywords (positions 5–20 with real impressions: the small-push targets). Real traffic data refills the topic queue. No brainstorming meeting required.

Honest FAQ

Does rankloop write content? No. It has no LLM integration and makes no LLM API calls, ever. It produces briefs and enforces laws; the writing is your writer's job.

Does it track rankings? No. There is no rank tracker. What you get is your own Search Console data (impressions, clicks, average position), which is both free and more honest than scraped rank checks.

Does it do outreach or build backlinks? No. Nothing in rankloop contacts anyone, and nothing should. Outreach automation is how link profiles die.

Are the volume and difficulty numbers real? They are vendor estimates, and rankloop treats them that way: free long-tail keywords carry NULL volume and neutral prior scores by design, because "0 volume" from a keyword tool frequently means "real but too small to measure" — exactly the queries a young domain can win.

Will Google penalize this? The scaled-content-abuse policy targets thin mass pages, not automation. The laws exist to keep you on the right side of that line — unique substance, enforced voice, honest claims, a throttle. No tool can guarantee rankings, including this one.

More in docs/faq.md.

Docs

  • docs/playbook.md — the full operating playbook: seed authoring, the relevance gate, source strategy, the flywheel, gotchas
  • docs/config.md — every rankloop.toml key
  • docs/routines.md — cron / launchd / GitHub Actions templates for the daily and weekly cadences
  • docs/faq.md — the honest limits, in full

Sites running it

Running rankloop on a real site? Open a PR and add it here.

License

MIT.

About

The anti-slop pSEO engine: keyword backlog, grounded LLM briefs, publish laws, Search Console flywheel. Stdlib-only, bring your own writer.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages