Skip to content

seo: resolve the Search Console page-indexing buckets - #108

Merged
JasonColapietro merged 2 commits into
mainfrom
seo/gsc-page-indexing-2026-09
Sep 21, 2026
Merged

JasonColapietro merged 2 commits into
mainfrom
seo/gsc-page-indexing-2026-09

Conversation

@JasonColapietro

@JasonColapietro JasonColapietro commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

What this is

A structural pass over the 2026-09-21 Search Console page-indexing export for suedeai.org (All known pages view: 13 indexed / 22 not indexed).

The export contains counts only, no URLs. Everything below is reconstructed from the repository — the served route surface, the redirect table, the internal link graph, and git history. Where a row is inferred rather than confirmed, it says so. A second agent is pulling the per-reason URL lists from the Search Console UI; those lists should be checked against this table before anyone marks the buckets resolved.

The environment's network policy blocks outbound HTTPS to suedeai.org, so nothing here was verified against the live site. Verification was structural, against the repo.

The URL surface

Static site on Vercel, cleanUrls: true, trailingSlash: true, canonical host https://suedeai.org. 30 HTML routes served, 25 in sitemap.xml, 5 correctly excluded because they carry noindex, follow (the four /thanks/ pages and /welcome-back/). 24 redirect rules in vercel.json. robots.txt disallows only /api/.

Structural checks that came back clean and needed no change: no broken internal links, no sitemap entry that redirects or 404s, no redirect chains, all 72 referenced assets resolve, every page has a unique <title>, meta description and self-referencing canonical, and no page carries noindex that shouldn't.

The 22, mapped

Page with redirect (6) — expected, not a defect

# Likely URL Root cause Fix Confidence
1–4 Legacy WordPress article slugs (/the-hidden-tax…/, /how-record-labels-trap-artists…/, /the-system-was-never-built-for-you/, etc.) The WordPress site was replaced ~May 2026. PR #63 (Aug 23) and #74 (Aug 28) 301'd 13 dead article URLs to their nearest topic page. None — working as intended High
5 /voice/ → /voice/support/ Parent path of the Voice app pages, added in #63 None High
6 /blog/, /feed/, or a /wp-sitemap.xml variant Legacy WP infrastructure URLs, 301'd in #63 None Medium

This bucket tripling 2 → 6 is not a regression — it is the 404 fix landing. #63's own commit message says Search Console had failed page-indexing validation because four old blog posts plus legacy feed and sitemap URLs still returned 404. Those URLs moved out of "Not found (404)" (3 → 1) and into "Page with redirect", which is exactly the intended trade. GSC lists this bucket as informational.

I checked all four defect classes the brief asks about and found none: no sitemap <loc> is a redirect source, no internal link or canonical points at a redirecting URL, there are no A→B→C chains, and there is no host-level (www / .org) redirect rule in the repo. All 6 are expected-and-fine; 0 are defects.

Caveat on dating: git history for this repo starts 2026-08-20, after the May baseline, so the pre-August redirect state could not be read from git. The 2 → 6 attribution rests on #63's and #74's commit messages, which are explicit.

Not found (404) (1) — not fixed, needs the URL

Nothing in the repository points at a dead path. Internal links, sitemap entries, canonicals, JSON-LD and image references were all cross-checked against the served routes — zero misses. So the 404 is a URL Google learned about externally, and I could not identify it structurally.

Two candidate families, neither actionable without the URL:

  1. A legacy WordPress slug not yet in the redirect table. seo: redirect legacy WordPress URLs that still 404 in Google's index #63/fix(seo): redirect retired article URLs #74 covered 13; the old blog may have had more. llms.txt lists TechBullion syndications with no matching redirect (…launches-ios-apps, …avalanche-build-games…, …ip-visibility-audit…, …seo-and-ai-cohort), which suggests the old site carried corresponding posts. I deliberately did not add redirects for guessed slugs — a guarded redirect table (LEGACY_REDIRECTS in verify_site.py) should not accumulate rules for URLs that may never have existed.
  2. An internal file that PR Stop serving tests, scripts, CI workflows and agent config as static assets #93 stopped serving on 2026-09-11. Before .vercelignore landed, every tracked .md, .py, tests/, scripts/ and .github/ file answered 200 (audited 2026-09-11, per the file's own comment). They now 404 — correctly. If the 404 is one of these, the right action is none.

Needs a human: paste the URL and this is a two-minute fix — a 301 if it is a real retired page, nothing if it is a retired internal file.

Discovered – currently not indexed (10) + Crawled – currently not indexed (5) — fixed

The header nav links 7 internal pages; the footer linked 5. That leaves 12 indexable pages reachable only from body copy — and 12 lines up closely with the 15 in these two buckets. Orphan pages are the standard cause of "Discovered".

Page Words Inbound pages (before) Bucket (inferred) Fix
/about/ 226 2 Discovered footer nav
/voice/privacy/ 1457 2 Discovered footer nav
/voice/terms/ 1058 2 Discovered footer nav
/ai-voice-protection/ 434 3 Discovered footer nav
/ai-likeness-protection/ 463 3 Discovered footer nav
/human-authenticity-layer/ 435 4 Discovered footer nav
/investors/ 658 4 Discovered footer nav
/book-a-call/ 310 4 Discovered footer nav
/sharp-excerpt/ 352 4 Crawled (thin) footer nav
/full-preview/ 253 5 Crawled (thin) footer nav
/agentic-commerce/ 500 7 Discovered footer nav
/creator-ownership/ 438 8 Discovered footer nav
/llms.txt, /llms-full.txt, /docs/accomplishments.md — — Crawled X-Robots-Tag: noindex, follow

Confidence: medium-high on the mechanism (the orphan set is measured, the bucket assignment per URL is inferred), high on the fix being correct regardless of which page sits in which bucket.

What changed

  1. Every page's footer now links all 12 orphans, taking them from 2–8 inbound pages to 29. The 29 pages on assets/css/site.css get a new .site-footer__explore nav, styled by extending the existing .site-footer__ecosystem rules so it inherits the footer's hairline and rhythm (CSS cache-buster bumped to v=20260921). index.html is the one page on styles.css, and its footer already carried a .site-footer__topics nav with 8 of the 12 — it gains the other 4 there instead, so no links are duplicated and the home page needs no new CSS.
  2. X-Robots-Tag: noindex, follow on /llms.txt, /llms-full.txt, /docs/accomplishments.md, /content/*.json and /LICENSE. These answer 200 but are records, not pages. follow keeps their links crawlable, and noindex does not stop the AI crawlers robots.txt invites from reading them.
  3. Sitemap lastmod refreshed to 2026-09-21. The values had drifted: /about/ still declared 2026-08-27 although the Suede Labs → Suede AI rename rewrote it on 2026-09-15, and every page changes again in this PR. A lastmod that says nothing changed tells Google not to recrawl.
  4. Three regression guards in verify_site.py — the footer's links checked on every page the repo serves (by link, not by markup, so it covers both footer shapes without pinning either to a class name), noindex headers against NOINDEX_ASSET_PATHS, and every sitemap <loc> required to resolve to a served, non-noindexed page that is not a redirect source, with a well-formed lastmod. Each guard was negative-tested.

What I deliberately left alone

  • All 6 redirects. They are the 404 fix working. Removing any would resurrect a 404.
  • The 404. Not guessable from the repo; guessing would put speculative rules into a guarded redirect table.
  • Thin content. /about/ (226 words), /full-preview/ (253) and /book-a-call/ (310) are genuinely thin, but expanding them is content work, not an indexing fix, and the brief scopes out wholesale rewriting. Worth doing separately if linking alone doesn't move them.
  • Near-duplicates. /full-preview/ ~ /sharp-excerpt/ and /ai-voice-protection/ ~ /ai-likeness-protection/ share ~0.35 and ~0.33 Jaccard vocabulary overlap. That is normal for a topic cluster, not duplication. Flagging, not acting.
  • The raw calendar.app.google link added to every footer in ff80830 — an external sitewide link, and it sits outside .site-footer__inner so it renders unstyled. Out of scope here.
  • The home page's #work-with-us header link where every other page would link /investors/. The footer now covers the page, so this is cosmetic rather than an indexing problem.
  • site.webmanifest has no start_url. Minor, unrelated to these four buckets.

Validation

python3 tests/verify_site.py → PASS (18 pages + core assets). node --test tests/*.test.js → 35/35. All 30 pages parse. Internal link graph, asset references and sitemap re-checked after the change: 0 broken links, 0 missing assets, 0 sitemap defects.

Not validated: anything requiring the live site. The network policy blocks outbound HTTPS to suedeai.org, so the redirect behaviour, the new headers and the 301 chain lengths are verified against vercel.json only. The smoke-deployed CI job will exercise the real deployment after merge.

Still needs a human or the GSC URL lists

  1. The 404 URL — paste it and the fix is immediate.
  2. Which of the 15 Discovered/Crawled URLs are the pages above vs. something unaccounted for. If the lists include URLs outside the 30 served routes, there is a discovery source this analysis missed.
  3. The impressions decline (~60/day in Mar–Apr → ~33/day over the last 30 days) is not explained by anything in this repo. It overlaps the WordPress retirement: 13 article URLs that used to rank now 301 to topic pages, and a 301 passes ranking signals but does not preserve the old page's query footprint. That is a plausible cause, not a demonstrated one — confirming it needs the Performance report split by page, which I cannot reach.
  4. If merge slips past 2026-09-21, re-run the lastmod refresh so the declared dates still match git, per the convention seo: give each sitemap URL its real lastmod instead of one shared date #78 and Sitemap: /book last changed 2026-09-04, not 2026-09-05 #92 set.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EBkyDpU9tcCeLydQ85iskj

Search Console's 2026-09-21 page-indexing export for suedeai.org reports 13
indexed against 22 not indexed, with 10 URLs under "Discovered - currently not
indexed" and 5 under "Crawled - currently not indexed".

Twelve indexable pages sit outside both the header nav and the footer, so the
only links pointing at them came from body copy: /about/ had two inbound pages,
/voice/terms/ and /voice/privacy/ two each, /ai-voice-protection/ and
/ai-likeness-protection/ three each. Weak internal linking is the usual reason
Google discovers a URL and never spends crawl budget on it. Add a footer
explore nav carrying all twelve, so every page on the site links to every one
of them.

/llms.txt, /llms-full.txt, /docs/accomplishments.md and the accomplishments
JSON answer 200 but are machine-readable records, not pages. Bare, they get
crawled and then filed under "Crawled - currently not indexed", a critical
bucket. Send X-Robots-Tag: noindex, follow so they are classified as what they
are; follow keeps the links inside them crawlable, and noindex does not stop
the AI crawlers robots.txt invites from reading them.

Sitemap lastmod values had drifted behind the pages: /about/ still declared
2026-08-27 although the Suede Labs to Suede AI rename rewrote it on 2026-09-15,
and every page changed again here. A lastmod that says nothing changed tells
Google not to recrawl, which is the opposite of what these pages need.

Guard all three in verify_site.py: the footer nav is checked on every page the
repository serves rather than the PAGES subset, the noindex headers against
NOINDEX_ASSET_PATHS, and each sitemap <loc> must resolve to a served,
non-noindexed page that is not a redirect source, with a well-formed lastmod.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBkyDpU9tcCeLydQ85iskj
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-21T19:12:59.890683Z fd12503 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd12503f9b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread index.html Outdated
index.html is the one page that loads styles.css rather than
assets/css/site.css, so the .site-footer__explore rules added with the nav
never reached it. There .site-footer is a five-column grid in which
.site-footer__topics and .site-footer__ecosystem each claim grid-column 1 / -1;
an unstyled nav auto-places into a single cell and renders the twelve links
cramped into one column.

The home footer already carries .site-footer__topics with eight of the twelve,
so a second nav would have duplicated them as well as broken the layout. Drop
the explore nav here and add the four links topics was missing: /investors/
(the header links the #work-with-us anchor, not the page), /book-a-call/,
/voice/terms/ and /voice/privacy/. All twelve keep a sitewide inbound link from
all 29 other pages plus this one, and the home page needs no new CSS.

Check the links rather than the markup around them, so the guard covers both
footer shapes and does not pin either page to a class name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBkyDpU9tcCeLydQ85iskj
@JasonColapietro
JasonColapietro merged commit 6a4f9e9 into main Sep 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants