frameworkseo · v21099:cursor-joseph-os2026-09-02served from databaseAll documents

SEO — get the live host indexed, then rank the helpful page

SEO — get the live host indexed, then rank the helpful page

BLUF. Search is not a trick. Google has to find, read, and trust the live host, then see a page that actually answers what a customer typed. New domains also need links, brand searches, and engagement — on-page work alone underperforms for months. Helpers do the on-site work. Humans submit the sitemap, (for local) fill the Maps listing, and post the off-site listings. Do not ask “Node Dough or Executive Nail Suite?” — resolve the host from the task + R12.

Live: https://projects.jbnx.io/framework/seo Tracking (required on the same host): https://projects.jbnx.io/framework/tracking-doctrine Customer funnel proof: https://projects.jbnx.io/framework/monthly-funnel-proof Voice: https://projects.jbnx.io/framework/human-framework

A ship without a live /insights 200 on that hostname is still not done. SEO does not replace R13.


What you say to any AI (paste this)

Copy once. After that, point at this URL. Do not re-paste the whole page.

SEO — mandatory whenever we ship or fix a public page people should find.
Spec: https://projects.jbnx.io/framework/seo
Tracking (same host): https://projects.jbnx.io/framework/tracking-doctrine

0. Resolve the host yourself. Task text + https://hi.jbnx.io R12 +
   GET /api/1099/deploy-targets. Never ask SaaS vs local as a multiple choice.
   Classify: saas | local | localfave-tenant | marketing.
   Canonical host = the live public origin. Dead aliases (ai.fedm8.com,
   scan.fedm8.com, mock.jbnx.io) must 301 there and must not appear in
   <link rel=canonical>, sitemap <loc>, or JSON-LD url.

1. Technical (AI ships these):
   HTTPS that browsers trust. One indexable host (apex or www 301, not both
   200). robots.txt Allow: / and Sitemap: https://<host>/sitemap.xml.
   sitemap.xml 200, this host only, https locs, no ops paths.
   noindex: /insights /collect /go /api /admin /stack /t/ (path tenants),
   plus thin pages, tag archives, parameter URLs.
   Viewport. Images WebP. Core Web Vitals on the live URL:
   LCP < 2.5s, INP < 200ms, CLS < 0.1 (INP replaced FID in 2024).
   Title ≤60 chars, target phrase near the start. Meta description 120–160.
   Unique title + description per indexable URL. Clean path, no .html junk.
   Visible last-updated on articles. Answer-first opening paragraph.

2. Structure: pillar + 5–10 cluster pages per topic, tightly interlinked.
   Money pages ≤3 clicks from /. Descriptive anchors. No index bloat.

3. People-first + E-E-A-T: write for the customer, then place the phrase
   they type in URL / title / H1 / description. Named author or owner,
   About, contact, privacy, terms. First-hand proof (license, years,
   prices, outcomes). Image filenames + alt. JSON-LD required:
   Organization + SoftwareApplication or LocalBusiness; FAQ, Review,
   BreadcrumbList when that content is visible. NAP = Maps listing.

4. Off-site: new domains need links and brand mentions. SaaS: G2/Capterra/
   Product Hunt/AlternativeTo, partner/integration pages, data-led PR.
   Local: GBP first, plus Apple Maps, Bing Places, Yelp, trade directories.
   Do not buy links or run a link scheme.

5. Human (one batched ask with URLs):
   Search Console URL-prefix + sitemap submit + inspect priority URLs.
   Bing Webmaster (ChatGPT/Copilot read Bing). IndexNow ping is extra.
   Local: Google Business Profile complete; NAP match; reviews + replies.
   Do not add Google Analytics / Clarity as the number we report.

6. Penalties to refuse: scaled content abuse (mass AI pages), link schemes,
   site reputation abuse, expired-domain abuse. Keyword stuffing is still
   a fail; those four are the 2024+ spam policies.

7. Measure: weekly Search Console (impressions before clicks; positions
   20–40 rising is the early signal). /insights for on-site people.
   New domain: 3–6 months before meaningful traffic. On-page without
   links will sit. Done = verify block in /framework/seo on the live host.

That is the instruction. If they ignore it, the live URL is the argument.


Phase 0 — Resolve the project (do not skip, do not ask)

The source draft asked “Node Dough, Cipherdeck, or Executive Nail Suite?” That is a human question. Helpers already have the map.

InputWhat you do
Chat names a host or brandUse that host. Confirm against R12.
Chat names a slugGET /api/1099/deploy-targets + R12 row → prod URL.
Chat says “this site” in a tenant repoThe Host you are editing (src/lib/tenants.ts on LocalFave).
Still ambiguous after boot + R12One batched question listing the matching hosts, not a category quiz.

Then classify. Extra work hangs off the class; the technical bar is the same.

ClassExamples (R12)Extra
saasnodedough.com, fedm8.com, scytherdeck.com / CipherDeckIndex marketing + docs you want found. noindex app shells, auth, /admin, /quick, config, health. No Maps listing. Comparison / integration / changelog playbook below.
localexecutivenailsuite.com, Tensuite shop pagesLocalBusiness JSON-LD, NAP, GBP (Map Pack > organic), /go/call + /go/map if a public phone/address exists.
localfave-tenantmarcobros / zensoma / vanessa *.localfave.orgNew site = new portal slug + new hostname on this stack. Do not invent a repo, [App Host] service, or [Database]. JSON-LD + per-host sitemap in the Worker / src/app/sitemap.ts. Same local playbook.
marketinglocalfave.org, fedm8.net, tensuite.net, jbnx.ioIndex the pitch. noindex /stack and operator pages.

Canonical host rules (estate traps):

Claim the slug for that host before you edit. One claim per PR. Public-language --done: say “search listing” / “sitemap”, never the vendor stack.


1. Technical foundations

Google cannot rank a page it cannot fetch. Core Web Vitals are ranking inputs; “loads quickly” is not a target.

HTTPS and one host

CheckPass
curl -sSI https://<host>/200 (or 301/302 to the canonical URL, then 200). Certificate trusted.
http://<host>/301 to https://<host>/ (or https canonical).
www vs apexExactly one returns 200. The other 301s.
HSTSPresent on the canonical host once HTTPS is trusted (strict-transport-security).

Do not tell Chrome users to click through an expired cert. That is a rank-zero failure (see the marcobros.com audit).

robots.txt + sitemap.xml

Live shapes that already pass (copy the pattern, do not invent a second):

# https://marcobros.localfave.org/robots.txt
User-agent: *
Allow: /
Disallow: /api/
Disallow: /collect
Disallow: /go/
Disallow: /insights
Sitemap: https://marcobros.localfave.org/sitemap.xml

Tenant extras: Disallow: /admin (Vanessa tracker), Disallow: /t/ (path previews), Disallow: /stack (hub). SaaS extras: /admin, auth, health, config.

Sitemap rules:

LocalFave code: src/app/robots.ts, src/app/sitemap.ts, Worker routes for /robots.txt and /sitemap.xml per host. A Next-only change is not live while the Worker is the origin — edit the Worker assets too.

Indexing hygiene

New sites die from index bloat as often as from missing pages.

DoDo not index
Homepage, money pages, pillar, each cluster pageThin stubs, tag/category archives, faceted/parameter URLs (?utm_ landing copies, sort/filter)
Unique titles on those URLsPaginated duplicates without rel=prev/next or a canonical to the clean URL
noindex,follow on thank-you / account / search-result HTMLA second 200 host (www + apex, http + https, dead alias)

After ship: human URL Inspection → Request indexing on / and each money page (cap: a handful, not the whole sitemap). IndexNow / Bing ping from the Worker is allowed and already exists on LocalFave — keep it. Do not spam the inspect button.

Mobile and Core Web Vitals

Vague “be fast” is replaced by field/lab thresholds. INP replaced FID in March 2024.

MetricPassFail if
LCP< 2.5sHero image uncompressed, no dimensions, late preconnect
INP< 200msHuge JS on first tap, layout thrash on click-to-call
CLS< 0.1Images/fonts without size, injected banners
Viewport<meta name="viewport" on every indexable HTML page800px Dreamweaver cage
Images we ownWebP (or AVIF), width/height, descriptive altInsert Logo Here, hotlinked dying origins
Fontsdisplay=swapDisplay font blocking first paint

Verify (one pass, not a loop):

Ops paths stay out of the index

PathrobotsHTML
/insightsDisallownoindex,nofollow
/collect /go/ /api/Disallownot a document
/admin /stackDisallownoindex
Health, probes, configDisallownoindex or 404

A 200 insights page that is indexable is a leak of operator copy, not a ranking win.


2. Structure for search

Titles, descriptions, URLs

FieldRuleVerify
<title>≤60 characters. Primary phrase + brand. Unique per URL.`curl -sS https://<host><path> \grep -i '<title'`
Meta description120–160 characters. One sentence a human would click. Unique per URL.grep name="description"
Canonical<link rel="canonical" href="https://<canonical-host><path>"> matching the sitemap <loc>.grep canonical
H1One H1, matches the search intent of that URL. Homepage is not allowed to skip it.
PathLowercase, hyphens, no .html, no _Us Dreamweaver names. Keyword in the slug when it is a real service page (/irrigation, not /page2).sitemap <loc>
Last updatedVisible date on articles / service pages we revise (<time datetime>). Helps people and AI snapshots.

Keyword stuffing in the title is a fail. “Irrigation Silver Spring” in the title of an irrigation page is the job.

Open Graph / Twitter cards: same title + description + one real image. They do not replace the HTML title.

Topic clusters (not a keyword list)

Do not plan “one keyword, one isolated page.” Pick a topic the business can own, then ship:

  1. One pillar — the comprehensive URL (/irrigation, /budgeting, /government-vendor-list).
  2. 5–10 cluster pages that answer a narrower question (/irrigation/backflow-testing, /irrigation/winterize). Each links up to the pillar and across to siblings with descriptive anchors.
  3. The pillar links down to every cluster. That graph is topical authority.

Money pages (book, call, signup, pricing) stay ≤3 clicks from / even inside a cluster.

Hub vs tenant: localfave.org ranks for us. marcobros.localfave.org ranks for Marco. Never cross-canonical them.

Internal linking


3. People-first content and E-E-A-T

Google rewards pages that look like a person who does the work wrote them. Load https://projects.jbnx.io/framework/human-framework before drafting public copy.

Experience, Expertise, Authoritativeness, Trust (E-E-A-T) is how that is judged. Anonymous new domains are held back longer. On every indexable site ship:

SignalWhere
Named owner or author with a real roleByline, About, JSON-LD author / founder
Credentials that are trueLicense (MHIC), years, “who answers the phone”
About pageWho, where, what you will not do
ContactPublic phone or a form. Match NAP.
Privacy + termsLinked in the footer. Needed for ads and for trust.

Vanessa has no public phone — that is correct. Do not invent a byline or a license.

Phrase map, then write

For the host, list 3–8 phrases a customer would type. Evidence, not a brainstorm:

Those phrases become the cluster map, not ten near-duplicate pages. Put the primary phrase in: path, title, H1, first paragraph, meta description. Secondary phrases in H2s and internal anchors. If the sentence only exists to hold the keyword, delete it.

Answer-first (people and AI search)

The first paragraph on an indexable page states the answer in plain prose: who, what, where, what it costs or what happens next. Then the proof. This is the block AI Overviews, AI Mode, ChatGPT, and Perplexity quote. Do not open with a brand manifesto.

Proof only this business has

ClassPut on the page
LocalLicense number, years, service area, prices if they are real, who answers the phone.
SaaSWhat the user can do in one sitting, what it will not do, a true empty state.

Do not invent reviews, star ratings, or “over 10 years” that contradicts the founded year. The marcobros.com audit failed on exactly that class of copy.

Visuals

Structured data (required)

Schema.org JSON-LD is not optional. It enables rich results and is how AI engines parse the page. Only mark up what is visible. Fake Review / AggregateRating is a spam policy issue.

TypeWhen
OrganizationEvery public host (legal name, url = canonical, logo)
LocalBusiness (or subtype)local / localfave-tenant. telephone E.164 only if public. address + areaServed. Omit phone for Zen Soma / Vanessa.
SoftwareApplicationsaas marketing homepage
WebSite + SearchActionOnly if a public site-search exists
FAQPageFAQs visible on that URL
Review / AggregateRatingReal, named, on-page reviews — never sample stars
BreadcrumbListAny URL with a breadcrumb
ArticleGuides / changelog posts, with dateModified

One graph per page. @id / url are the canonical host. Verify: view-source contains application/ld+json. Optional human: https://search.google.com/test/rich-results


4. Off-site authority

On-page SEO on a new domain without links will underperform for months. Rank needs other sites naming this host.

Helpers prepare the on-site NAP, listing copy, and partner pages. Humans submit the profiles. Do not buy links, swap PBNs, or stuff footer links onto client sites.

What to earn (class-specific)

ClassPrimary listingsLink-earning pages we can ship
saasG2, Capterra, Product Hunt, AlternativeTo, relevant “best of” listsComparison (X vs Y, X alternatives, best [category] tools), integration/partner pages, indexed docs, public changelog, one free tool that other sites cite
local / tenantGoogle Business Profile first (Map Pack). Then Apple Maps, Bing Places, Yelp, chamber / trade boardsOne URL per service; one city page per city you actually serve; photos NAP-identical to GBP
marketingSame as the product it pitchesOriginal data, a number someone else will quote

Digital PR = original data or a true outcome, then a page others can link. Not a “10 best” listicle we wrote about ourselves.

Brand mentions without a link still help when they match the NAP / product name. Keep the name string stable.

Brand demand and engagement

Google uses click and engagement data (Navboost; 2024 API leak and DOJ testimony). Branded search volume (“nodedough”, “marco bros irrigation”) is a trust signal we cannot fake in the title tag.

Build audience off Google, then they search the name:

Measure engagement we own on /insights (real people, R13). Do not install GA or Clarity to “see Navboost.” Search Console CTR is the Google-side read (human, weekly).

A page that ranks and gets skipped will fall. Titles and descriptions earn the click; the answer-first paragraph + speed earn the stay.


5. AI search optimization

Traffic now also comes from Google AI Overviews / AI Mode, ChatGPT, Copilot, and Perplexity. Those systems quote clear answers on crawlable HTML, not a SPA shell with no first paint.

Ship on every indexable URL:

  1. Answer-first paragraph (who / what / where / next step).
  2. Structured data from §3.
  3. Visible last-updated on anything that changes.
  4. Unique copy. Scaled AI page sets are scaled content abuse (below). One good page beats fifty generated ones.

Bing Webmaster is required, not optional. ChatGPT and Copilot use Bing’s index. Same sitemap as Google.

Do not wrap the main content in a client-only render that curl cannot see. If curl -sS https://<host>/ lacks the H1 and first paragraph, neither Google nor Bing nor ChatGPT has them.


6. Current penalty risks (2024+ spam policies)

“Avoid keyword stuffing” is still true and is no longer the main way sites get dropped. Refuse these by name (March 2024 core spam updates and later):

PolicyWhat it looks like hereWhat we do
Scaled content abuseMass AI/generated pages, thin location doorways we do not serve, 200 near-duplicate “city” URLsWrite fewer pages. City pages only for cities on the truck / in areaServed.
Link schemesBought links, PBNs, guest-post networks, “link exchange” footersEarn listings and data-led mentions. No payments for links.
Site reputation abuseThird-party content on our domain to rank for their queries (parasite SEO)Our host publishes our business. No coupon/casino subfolders.
Expired domain abuseRanking a new product on a aged domain’s leftover authorityNew LocalFave tenant = new hostname. Do not revive random aged domains.
Keyword stuffing / hidden textTitles that repeat the city five times; white-on-whiteHuman-framework voice. One primary phrase.

A helper that “generates 40 SEO pages” for a new shop is proposing scaled content abuse. Push back. Use the cluster cap (pillar + 5–10).


7. Human actions (one batched ask)

Only when Phase 1–3 pass on the live host. Every line is a URL. Helpers do not ask for a paste of a verification token in chat.

Search Console (every class)

Bing Webmaster (every class — AI search)

Google Business Profile (local / localfave-tenant only)

Do not ask the human to “do SEO.” Ask them to verify the property and paste nothing back. If DNS verification is required, give the record name + type and the put-URL for [DNS Server] DNS — never the live secret.


8. Measurement and timeline

CadenceWhereWhat “working” looks like
Live, any timehttps://<host>/insightsReal people, this host only. Not bots, not our curls.
WeeklySearch Console PerformanceImpressions move before clicks. Queries at positions 20–40 rising = early win. CTR problems = title/description, not “more pages.”
WeeklySearch Console CWVLCP/INP/CLS in the pass band, or a named fix.
Weekly (local)GBPViews, calls, direction requests. Map Pack matters more than organic #3.
Month 1–2 (new domain)Coverage + sitemapIndexed count ≈ URLs we meant to index. Not 0, not thousands of junk.
Month 3–6 (new domain)PerformanceFirst non-brand clicks. Brand queries appearing is a trust signal.

A new domain with strong on-page and no links should be expected to sit for months. That is not a bug in the title tag. Work the listings and one link-earning page (SaaS free tool, local data, partner page).

Do not compare GA4 “uniques” to /insights. We do not install GA as the reported number.


Verify (one pass, live host)

H=https://<host>   # canonical, no trailing path

curl -sS -o /dev/null -w 'home %{http_code}\n' "$H/"
curl -sS -o /dev/null -w 'insights %{http_code}\n' "$H/insights"   # 200; that GET must not increment page views
curl -sS "$H/robots.txt"
curl -sS -o /dev/null -w 'sitemap %{http_code} %{content_type}\n' "$H/sitemap.xml"

# titles / canonical / description / json-ld / viewport (digest, do not dump HTML)
curl -sS "$H/" | python3 -c "import sys,re; h=sys.stdin.read();
print('title', re.search(r'<title[^>]*>([^<]+)',h,re.I).group(1)[:80] if re.search(r'<title',h,re.I) else None)
print('canon', (re.search(r'rel=[\"\\']canonical[\"\\'][^>]*href=[\"\\']([^\"\\']+)',h,re.I) or re.search(r'href=[\"\\']([^\"\\']+)[\"\\'][^>]*rel=[\"\\']canonical',h,re.I)))
print('desc', bool(re.search(r'name=[\"\\']description[\"\\']',h,re.I)))
print('viewport', 'viewport' in h.lower())
print('jsonld', 'ld+json' in h.lower())
print('noindex-home', bool(re.search(r'noindex', h[:4000], re.I)))
print('h1', bool(re.search(r'<h1', h, re.I)))"

Pass bar:

  1. Home 200 on HTTPS canonical host. curl sees H1 + answer-first paragraph (not an empty shell).
  2. robots.txt 200, allows /, points at this host’s sitemap, disallows ops paths.
  3. sitemap.xml 200 XML, https locs, this host only, every public money + cluster page listed, no thin/param URLs.
  4. Home has unique title, description, canonical self-URL, viewport, JSON-LD (Organization + LocalBusiness or SoftwareApplication).
  5. /insights 200 for this host only (R13). Home is not noindex.
  6. No third-party analytics script required for any of the above.
  7. Local: NAP in JSON-LD equals visible footer; /go/map dest matches that address. Phone wrapper only if the number is public.
  8. About / contact / privacy exist or are in the same PR for a new host.
  9. CWV: lab or field numbers named, or a named blocker (image too heavy, no dimensions). Do not loop PageSpeed.

[PASS/FAIL] seo <host> with those lines. Max one live pass. Do not curl /go/call as proof.


Done means

A host is SEO-ready when:

  1. Technical + hygiene + CWV block above is green on the live origin (Worker or [App Host], whichever answers the hostname today).
  2. Each indexable URL has a unique title, description, canonical, and H1; pillar/cluster internals link; answer-first opening.
  3. Copy is people-first, E-E-A-T pages exist, images have filenames + alt. No scaled AI set.
  4. JSON-LD matches visible NAP / product name. Canonical host is the live one, not a dead alias.
  5. Sitemap lists those URLs. Human has a single ask (or a recorded skip) for Search Console and Bing Webmaster.
  6. Local class: GBP ask sent (primary category, photos, review replies), or a fact that GBP is already claimed. SaaS: GBP explicitly N/A; at least one link-earning surface (comparison, integration, docs, changelog, or free tool) is planned or shipped.
  7. R13 still holds.

Not done: “added keywords.” Not done: sitemap 303. Not done: canonical to ai.fedm8.com. Not done: indexing /insights. Not done: 40 generated city pages. Not done: on-page only with zero listings on a new domain, promised as “we will rank next week.”


Playbook — SaaS

Use for nodedough.com, fedm8.com, CipherDeck / scytherdeck.com. Skip GBP unless there is a walk-in shop.

Index: homepage, pricing (if it exists), comparison, integrations, docs you want found, changelog, the free tool. noindex the signed-in app, /admin, /quick, config, health, ticket inboxes.

Ship, in order:

  1. Technical bar + Organization + SoftwareApplication JSON-LD.
  2. Pillar = the product job (“see what you can spend in two weeks”). Clusters = objections and adjacent jobs, not synonym spam.
  3. Comparison set: X vs Y, X alternatives, best [category] tools — honest, Human-framework voice, no fake “winner” tables.
  4. One integration or partner page per real integration, with a link target the partner can use.
  5. Docs: index the guides; noindex the empty stubs.
  6. Public changelog with dateModified.
  7. One free tool that earns links (calculator, scanner, checker). That is the backlink engine, not a blog of AI posts.
  8. Listings: G2 / Capterra / Product Hunt / AlternativeTo — human submits; we match the name string.
  9. Bing Webmaster + Search Console. Brand searches (“nodedough”) are the trust signal to watch.

Playbook — local business

Use for executivenailsuite.com, Tensuite shops, every *.localfave.org tenant.

Map Pack > organic position. GBP is the priority surface.

  1. Technical bar + Organization + LocalBusiness JSON-LD. NAP identical on page, JSON-LD, /go/map, Insights dest.
  2. GBP: https://business.google.com — correct primary category, service area, hours, photos. Weekly post or photo. Owner replies to every review. Review velocity is a slow, real signal — do not gate fake reviews.
  3. Apple Maps + Bing Places + Yelp + the one trade directory that city actually uses. Same NAP.
  4. One page per service (cluster). One city landing page per city you actually serve. Do not generate 50 suburbs.
  5. /go/call only if the number is public. No public phone (Zen Soma, Vanessa) → form only, no fake tel.
  6. Photos: real job / room / crew. Filename + alt. Same photos can go on GBP.
  7. Search Console + Bing. New *.localfave.org host: expect 3–6 months. Listings and GBP move local faster than blog posts.

New LocalFave site: new portal slug + <slug>.localfave.org on this stack. Copy the Marco/Zen/Vanessa metadata pattern; do not invent a second repo.


Do / don’t

Do

Don’t


Related

DocWhy
https://projects.jbnx.io/framework/tracking-doctrine/insights, /collect, /go/* — same host, real people only
https://projects.jbnx.io/framework/monthly-funnel-proofWhat we show a paying customer
https://projects.jbnx.io/framework/human-frameworkHow the public sentences sound
https://projects.jbnx.io/framework/app-review-frameworkWhen the ask is a ranked audit, not a ship
https://projects.jbnx.io/framework/marcobros-security-seo-2026-08-31Worked example of an SEO fail (expired TLS, no mobile, no descriptions) — not the playbook

v2 — 2026-09-02. v1 converted the on-site ranking blueprint into an AI playbook. v2 adds 2026 search: off-site links, brand/engagement, AI search + Bing, full schema, CWV numbers, topic clusters, E-E-A-T, indexing hygiene, named spam policies, measurement window, SaaS and local playbooks.