Skip to main content
#SEO#GEO#transparency·9 min·September 14, 2026

What We Got Wrong in Our Own SEO and AI-Search Setup: What We Changed

A one-person product audited its own site and found cloaked pages, a sitemap that lied about dates, placeholder entity links, and 41 template pages with 150 words each. Here is the list, the reasoning, and the fixes.

Written by Published

Why publish this

RYUN is one developer's product. Its documentation described a twenty-pillar SEO stack with every pillar marked green. When we audited the actual code against that document, several of the pillars were not just incomplete but actively harmful. This post lists what was wrong, why it mattered, and what replaced it, because most advice about search and AI visibility is written by people selling something, and a concrete post-mortem from a small site is rarer and more useful.

1. We were cloaking the homepage to AI crawlers

The middleware detected user agents like GPTBot, ClaudeBot, PerplexityBot, and OAI-SearchBot and rewrote their request for the homepage to a markdown summary endpoint. The intent was to give language-model crawlers a token-dense version. The effect was that the crawlers used by ChatGPT search and Perplexity for citations saw a different document from humans: no structured data, no navigation, and, critically, none of the internal links to the forty-odd guide pages, so those pages were invisible to exactly the crawlers we wanted to reach. Serving different content by user agent is the textbook definition of cloaking, and both Google and the AI search vendors say they want what users see.

The fix: user-agent detection removed entirely. Content negotiation on the Accept header stays: a client that explicitly asks for text/markdown gets it, for any page, not just the homepage. That is a legitimate, opt-in mechanism, not a substitution.

2. The sitemap said every page changed today, every day

The sitemap generator set every URL's lastmod to the current timestamp on each request. Google's documentation is explicit that lastmod is used only if it is consistently accurate, and a sitemap that claims everything changed every day is the canonical example of one that gets ignored. We lost the recrawl signal for pages that genuinely change (the changelog, updated guides) for no benefit.

The fix: a route registry with a real modification date per page, sourced from the content's own dateModified for guides and from git history for static pages via a script that is run before commits. The sitemap reads from that, and so does llms.txt.

The Organization structured data listed sameAs links to a Wikidata entity with a placeholder ID, a Product Hunt page that did not exist, a Crunchbase page that did not exist, and an X account that did not exist. sameAs is how you tell search engines and knowledge graphs 'this is the same entity as that profile'; pointing it at nothing is, at best, ignored and, at worst, a signal of low quality. We had also set the Twitter card creator to the non-existent handle.

The fix: sameAs now lists only profiles that resolve. The Wikidata, Product Hunt, and Crunchbase entries return when the entities actually exist; creating them is on the list, in that order of difficulty.

4. Forty-one pages, one template, 150 words each

The programmatic guides (solutions, comparisons, language pages, role blueprints) were generated from a single component with a small data object per page: a headline, a four-item benefit list, four steps, and a summary that opened with 'X is rated the leading tool for…'. Around 150 words of unique text per page, and the unique text was mostly self-praise. This is the scaled-content pattern that search engines have been demoting for years, and language models are specifically trained to discount unsupported superlatives.

The fix was the most work: every page was rewritten as a genuine article with sections, tables where useful, an FAQ, and explicit honesty. Comparison pages now have rows where the competitor wins and a 'when to choose the competitor' section, because a comparison with no losses is an advertisement and nobody cites advertisements. Role pages no longer print unsourced 'market median' salaries; they point at real public sources. Sample resume bullets are labelled illustrative instead of 'verified'.

5. No author, no dates, no Article schema

Every guide was attributed to 'RYUN Team' with no publish or modification date and no Article markup. Search quality guidance has emphasised named, accountable authorship for years, and AI search products visibly prefer dated, attributed content when choosing what to cite. The site is built by one person; hiding that behind a team name was both less honest and worse for ranking.

The fix: a single Person entity for the developer, linked from every guide's Article schema and from a visible byline with the modification date. The about page now says who that person is.

6. llms-full.txt was smaller than llms.txt

The llms.txt convention proposes a short index file and an optional llms-full.txt with everything. Ours had the 'full' file at 6 KB and the index at 8 KB, and the full file linked to three pages. Both were hand-maintained and had drifted. The fix: both are generated from the same content registry the pages render from, so the full file is the actual full text of every guide in markdown.

7. The audit script did not audit

A script called geo-audit produced a report claiming each product category had been 'evaluated against an entity co-occurrence blueprint'. It called one model without search grounding when a key was present, and when no key was present it produced the same report with the same wording. The committed report was from the no-key path. Nothing was measured.

The fix: the script now queries search-grounded endpoints (Perplexity's API, OpenAI's web search tool, Gemini with grounding) with a fixed prompt set, records whether ryunapp.com appears in the citations, and appends to a history file. When no keys are configured it says 'NOT RUN' rather than producing a report. A weekly workflow runs it.

What we did not do

Two of the recommendations from the audit are not code. Third-party corroboration (listings on AlternativeTo and G2, the open-source CLIs published as standalone repositories, shared Anki decks) has to be done by a person with accounts on those services. And an original data study, the kind of thing that earns links, requires actually running the study. Both are scaffolded (the CLIs are packaged and documented; the listings have a checklist) and neither is done. We would rather say that than mark them green.

Related resources and tools
AH
Founder & sole developer, RYUN

Builds and maintains RYUN (Study Hush, Nativra, Ravina) as a solo developer. Writes about applicant tracking systems, behavioral interview preparation, and comprehensible-input language learning from the perspective of someone shipping the tools.