<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ali Habibzadeh</title>
    <description>The latest articles on DEV Community by Ali Habibzadeh (@alihabibzadeh).</description>
    <link>https://dev.to/alihabibzadeh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242107%2F8345c8b6-a508-41da-a9a7-664eded34798.jpeg</url>
      <title>DEV Community: Ali Habibzadeh</title>
      <link>https://dev.to/alihabibzadeh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alihabibzadeh"/>
    <language>en</language>
    <item>
      <title>Is GEO only in our heads, or something real?</title>
      <dc:creator>Ali Habibzadeh</dc:creator>
      <pubDate>Wed, 23 Sep 2026 23:43:46 +0000</pubDate>
      <link>https://dev.to/alihabibzadeh/is-geo-only-in-our-heads-or-something-real-4lp1</link>
      <guid>https://dev.to/alihabibzadeh/is-geo-only-in-our-heads-or-something-real-4lp1</guid>
      <description>&lt;p&gt;I was deep in thought about how much of a model hallucination is RLHF-based assumption in the absence of training data or context. Pretraining gives the model the ability to confabulate. Post-training often influences whether it chooses to confabulate rather than say "I don't know."&lt;/p&gt;

&lt;p&gt;A base language model is trained to predict plausible continuations. If the evidence needed to answer is absent from its weights or context, there's no fundamental mechanism in next-token prediction that says &lt;strong&gt;"stop, evidence unavailable."&lt;/strong&gt; It still has a probability distribution over tokens, so it generates the most plausible continuation. Hallucinations therefore exist without RLHF.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aclanthology.org/2022.acl-long.229/" rel="noopener noreferrer"&gt;TruthfulQA&lt;/a&gt; demonstrated this with pre-RLHF base models such as GPT-3, GPT-2 and GPT-Neo/J: they confidently reproduced misconceptions learned from text, and the larger models were &lt;em&gt;less&lt;/em&gt; truthful, not more.&lt;/p&gt;

&lt;p&gt;But this is a slightly narrow point of view for web people like us. For us, when we think of hallucination we think of a model telling an untruth. Which the above is really a subset of.&lt;/p&gt;

&lt;p&gt;Seen in the broader sense, hallucination decomposes like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Wrong information encoded during pretraining.&lt;/strong&gt; The model learned a false claim because the corpus
contained it, or because statistical compression distorted the underlying facts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imperfect retrieval from model weights.&lt;/strong&gt; The correct information is effectively "in there," but
generation retrieves the wrong association: wrong year, wrong person, conflated events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference errors.&lt;/strong&gt; The premises are available, the model reasons incorrectly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confabulation under missing information.&lt;/strong&gt; The model lacks the fact and constructs the most plausible
answer anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-training induced behaviour.&lt;/strong&gt; SFT, RLHF and preference tuning make 1 to 4 &lt;strong&gt;more or less likely to
be verbalised as an assertion&lt;/strong&gt;, depending on whether the learned behaviour rewards answering, agreeing,
sounding decisive, abstaining or checking uncertainty.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I know what you're thinking, this is still narrow. We don't interact with bare models like this. We interact with fully fledged ecosystems with so many moving parts: model, system prompt, memory, retrieval, tools, planners, execution loop, verifiers, reward shaping, UI constraints, external state. What fancy people call harnesses.&lt;/p&gt;

&lt;p&gt;In that environment an untrue response can arrive for a much wider variety of reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The base model invents a fact.&lt;/li&gt;
&lt;li&gt;Retrieval returns the wrong document, stale information, or a semantically similar but incorrect result.&lt;/li&gt;
&lt;li&gt;The model &lt;strong&gt;misreads correct retrieved evidence&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Tool selection is wrong: it searches the web when it should query an MCP server, queries the wrong
database, or fails to use a tool at all.&lt;/li&gt;
&lt;li&gt;The planner makes an unsupported assumption early, and every later step treats it as established fact.&lt;/li&gt;
&lt;li&gt;Memory injects an incorrect prior fact.&lt;/li&gt;
&lt;li&gt;A tool succeeds partially, but the agent interprets partial output as complete.&lt;/li&gt;
&lt;li&gt;The agent loses provenance across steps and can no longer distinguish &lt;strong&gt;observed facts from inferred facts&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A verifier checks linguistic consistency rather than correspondence with reality.&lt;/li&gt;
&lt;li&gt;The system prompt or reward function pressures the agent to "finish the task," so it bridges missing state
with assumptions.&lt;/li&gt;
&lt;li&gt;One agent invents something and another agent treats that output as evidence.&lt;/li&gt;
&lt;li&gt;The final response generator turns an uncertain intermediate state into a declarative statement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why even think about any of this? Well, because if you're to believe GEO is a real discipline, you have to believe you can impact some of these factors in a controlled way &lt;strong&gt;as an outsider&lt;/strong&gt;. Otherwise there'll be nothing to optimise, right?&lt;/p&gt;

&lt;p&gt;The important distinction is &lt;strong&gt;control over the model&lt;/strong&gt; versus &lt;strong&gt;control over the evidence environment the model operates in&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we do then?
&lt;/h2&gt;

&lt;p&gt;Leverage is qualified the same way throughout: where a remediation requires you to operate a machine endpoint, the leverage is conditional on your doing so. Rows 4, 7 and 8 all carry that condition, and an earlier version of this table applied it only to row 4.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Failure&lt;/th&gt;
&lt;th&gt;Business leverage&lt;/th&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;th&gt;What the business can actually do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Base model invents a fact&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong that it happens; weak that businesses can fix weights&lt;/td&gt;
&lt;td&gt;Improve the public factual corpus; correct authoritative third parties; allow training crawlers if you want to. Don't promise that publishing something changes model weights.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Wrong or stale retrieval&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very high&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Crawlability, indexing, canonical URLs, freshness signals, authoritative pages, remove stale duplicates, correct third-party sources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Model misreads correct evidence&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong to moderate&lt;/td&gt;
&lt;td&gt;Make facts explicit, atomic, unambiguous, scoped, easy to extract. Reduce contradictory and verbose pages.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Wrong tool selected&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High, if you expose tools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong and growing&lt;/td&gt;
&lt;td&gt;MCP and API discovery, precise tool descriptions, narrow responsibilities, obvious capability names, good schemas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Planner invents assumption&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Medium-high&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong underlying evidence&lt;/td&gt;
&lt;td&gt;Publish direct answers to likely ambiguous questions, and explicit negative facts, so retrieval resolves rather than infers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Incorrect memory&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Low externally&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mixed&lt;/td&gt;
&lt;td&gt;Make the current authoritative state easy to retrieve so live evidence can override memory. You can't normally edit another provider's memory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Partial tool result treated as complete&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very high, if you expose tools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Engineering evidence stronger than GEO research&lt;/td&gt;
&lt;td&gt;Design API and MCP responses with pagination, completeness, timestamps, status, errors, coverage boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Provenance disappears&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Medium-high, if you return machine-readable facts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong problem evidence&lt;/td&gt;
&lt;td&gt;Attach source URLs, IDs, timestamps and claim provenance to every fact you return&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Bad verifier&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong that verification design matters&lt;/td&gt;
&lt;td&gt;Provide ground-truth endpoints a verifier &lt;em&gt;could&lt;/em&gt; use. You don't control whether third parties use them.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Reward or system prompt encourages guessing&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong phenomenon, outside business control&lt;/td&gt;
&lt;td&gt;Almost nothing externally, except make uncertainty unnecessary by improving evidence availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Agent trusts another agent's fabrication&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Medium&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Growing evidence&lt;/td&gt;
&lt;td&gt;Provide provenance-rich primary evidence so downstream agents can check upstream claims&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Final generator converts uncertainty into fact&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Low-medium&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong phenomenon&lt;/td&gt;
&lt;td&gt;Make evidence decisive and machine-readable; you can't control another system's final-generation policy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2, 3, 4, 5, 7 and 8.&lt;/strong&gt; Those are the genuinely externally addressable hallucination surfaces. And this is much bigger than conventional GEO.&lt;/p&gt;

&lt;p&gt;What follows adds something the argument didn't have when I first wrote it: measurements of how those six surfaces actually look across the web, rather than only arguments that they matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrong or stale retrieval is probably the biggest opportunity
&lt;/h2&gt;

&lt;p&gt;RAG exists precisely because supplying current external information reduces dependence on faulty parametric knowledge. Models frequently update an incorrect parametric belief when given correct external evidence, although strong priors can still cause resistance. Retrieval quality matters enormously: wrong, irrelevant and conflicting documents measurably degrade answer correctness.&lt;/p&gt;

&lt;p&gt;A business can directly work on this. Suppose models incorrectly say &lt;em&gt;"Lumar doesn't support JavaScript rendering."&lt;/em&gt; You want a canonical URL that states the fact plainly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does Lumar crawl JavaScript websites?&lt;/strong&gt;&lt;br&gt;
Yes. Lumar renders pages using Chromium and crawls content generated by client-side JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;rather than expecting the model to derive it from 1,800 words of marketing copy. Then make sure that page is crawlable, internally linked, canonical, indexed, current, server-rendered or otherwise trivially extractable, and not contradicted by three old documentation pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And here's the part I can now measure rather than just assert&lt;/strong&gt; &lt;em&gt;(&lt;a href="https://agentic-readiness.lumar.io/blog/agentic-readiness-of-the-web" rel="noopener noreferrer"&gt;Agentic readiness of the web&lt;/a&gt;, corpus scan)&lt;/em&gt;. The retrieval substrate isn't in good shape. Of the 88,484 publishing hosts, &lt;strong&gt;61,587 publish an XML sitemap and 21,448 of them break the format&lt;/strong&gt;, about 35%. The single most common fault anywhere in the study is a sitemap sitting in a subfolder that lists URLs outside it: &lt;strong&gt;14,176 sites&lt;/strong&gt;, 23% of everyone with a sitemap. Google reads those URLs anyway if you submitted the file through Search Console, which is why so many teams have never seen it break. Hand the same file to anything that isn't Google and the out-of-scope entries are dropped.&lt;/p&gt;

&lt;p&gt;The sitemap protocol was agreed in 2005. If the oldest, most boring piece of retrieval plumbing on the web is broken on a third of sites that bother to publish it, the idea that the evidence environment is already optimised and only model behaviour is left to tune doesn't survive contact with the data.&lt;/p&gt;

&lt;p&gt;Basic freshness engineering matters too: Google [explicitly uses trustworthy &lt;code&gt;lastmod&lt;/code&gt; values (&lt;a href="https://developers.google.com/search/blog/2023/06/sitemaps-lastmod-ping" rel="noopener noreferrer"&gt;https://developers.google.com/search/blog/2023/06/sitemaps-lastmod-ping&lt;/a&gt;) as a recrawling signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One correction worth making precisely&lt;/strong&gt;, in an article about precision. For ChatGPT Search, OpenAI &lt;a href="https://developers.openai.com/api/docs/bots" rel="noopener noreferrer"&gt;says&lt;/a&gt; that &lt;em&gt;"sites that are opted out of OAI-SearchBot will not be shown in ChatGPT search answers, though can still appear as navigational links,"&lt;/em&gt; and that they &lt;em&gt;"recommend allowing OAI-SearchBot."&lt;/em&gt; That's narrower than "must be allowed to be eligible": you lose the answers, not the link. They separately state GPTBot &lt;em&gt;"is used to crawl content that may be used in training our generative AI foundation models,"&lt;/em&gt; which is the distinction that matters here.&lt;/p&gt;

&lt;p&gt;It's also a decision very few sites have taken deliberately &lt;em&gt;(corpus scan)&lt;/em&gt;. &lt;strong&gt;33,626 sites name at least one AI crawler in robots.txt, and only 4,289 of them name OAI-SearchBot at all&lt;/strong&gt;, about one in eight. A caveat I won't skip:&lt;br&gt;
naming a crawler isn't blocking it, and a crawl can't see which way a rule points. What the number shows is how few sites have made any explicit decision about the one bot that governs appearing in ChatGPT answers.&lt;/p&gt;

&lt;p&gt;None of this is speculative "LLM SEO." It's improving the evidence retrieval systems have available.&lt;/p&gt;
&lt;h2&gt;
  
  
  Correct evidence that the model misinterprets is also addressable
&lt;/h2&gt;

&lt;p&gt;This is where I'd invest substantially. Models do worse as irrelevant context increases, and evidence placement affects factual verification.&lt;/p&gt;

&lt;p&gt;So stop asking &lt;em&gt;"is this information somewhere on our site?"&lt;/em&gt; and start measuring:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can a machine retrieve the smallest sufficient passage that answers the question without inference?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those are very different standards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our platform empowers modern enterprise teams through an advanced rendering infrastructure designed to help&lt;br&gt;
organizations understand experiences across increasingly dynamic digital environments...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does Lumar crawl JavaScript websites?&lt;/strong&gt;&lt;br&gt;
Yes. Lumar can render pages using Chromium and crawl content generated by client-side JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This matters because you're reducing the amount of &lt;strong&gt;reasoning between evidence and claim&lt;/strong&gt;. I'd call the metric something like &lt;strong&gt;inference distance&lt;/strong&gt;: how many unsupported transformations are required to get from the source material to the desired factual answer. You want that close to zero.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tool selection is increasingly something businesses can influence
&lt;/h2&gt;

&lt;p&gt;This is where the agentic ecosystem gets interesting, and where I have the sharpest numbers.&lt;/p&gt;

&lt;p&gt;MCP and tool-selection research shows measurable differences in models' susceptibility to misleading tool descriptions and overlapping capabilities. A 2026 study ran 8,640 agent runs and found substantial variation in wrong-tool susceptibility depending on tool design and model capability.&lt;/p&gt;

&lt;p&gt;So if you expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Query the system"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;versus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"salesforce_get_account_by_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Authoritative source for Salesforce CRM account records. Returns the current
                  account owner, tier and renewal date for one account ID. Not for opportunities,
                  contacts or historical snapshots."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the latter makes epistemically correct tool selection much easier. You can't force an agent to pick your tool. But you can remove ambiguity from the decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And this is where the numbers get embarrassing&lt;/strong&gt; &lt;em&gt;(corpus scan)&lt;/em&gt;. Across the 88,484 publishing hosts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Sites&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Publish an OpenAPI description&lt;/td&gt;
&lt;td&gt;497&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...with a value whose type is never stated&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;176&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...with an operation that has no &lt;code&gt;operationId&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;112&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...with two operations sharing one &lt;code&gt;operationId&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;66&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publish an MCP server card&lt;/td&gt;
&lt;td&gt;368&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...whose card doesn't say where the server is&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...whose endpoint doesn't speak MCP&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;19&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look at row three again. &lt;strong&gt;112 of 497 machine-readable API descriptions give an agent nothing stable to name a call by&lt;/strong&gt; &lt;em&gt;(corpus scan)&lt;/em&gt;. That's not a theoretical concern about tool ontology. It's the concrete failure this section argues about, already present in 23% of the sites that have gone to the trouble of publishing a contract at all. And 40 server cards advertise an MCP server without saying where it is.&lt;/p&gt;

&lt;p&gt;For businesses this suggests a new optimisation surface:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't merely expose an MCP server. Engineer its ontology so an agent can reliably determine when it is the &amp;gt; authoritative source.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Unsupported planner assumptions are surprisingly addressable
&lt;/h2&gt;

&lt;p&gt;Consider: &lt;em&gt;"Why is Lumar more expensive than Screaming Frog?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If neither company has published meaningful evidence, an agent will generate something plausible. Possibly complete fiction. A company can anticipate those inference gaps and publish the answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How does Lumar's pricing compare with Screaming Frog's?&lt;/strong&gt;&lt;br&gt;
They are priced for different jobs. Screaming Frog licenses a desktop crawler per seat. Lumar is billed on &amp;gt; crawl volume and retained history across a whole estate. A single-site audit is cheaper in Screaming Frog; &amp;gt; continuous monitoring of many domains is what Lumar is priced for.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or, importantly, publish the negative:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does Lumar offer a free tier?&lt;/strong&gt;&lt;br&gt;
No. Lumar does not offer a free or perpetually free plan.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Negative knowledge is particularly useful.&lt;/strong&gt; Companies publish enormous amounts of &lt;em&gt;X does Y&lt;/em&gt; and very little &lt;em&gt;X does **not&lt;/em&gt;* do Y*. False assumptions live precisely in that missing space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provenance may be the biggest long-term opportunity
&lt;/h2&gt;

&lt;p&gt;Generative search research has repeatedly found provenance problems. Liu, Zhang and Liang's &lt;a href="https://aclanthology.org/2023.findings-emnlp.467/" rel="noopener noreferrer"&gt;Evaluating Verifiability in Generative Search Engines&lt;/a&gt;&lt;br&gt;
(Findings of EMNLP 2023) audited four engines by human evaluation and found &lt;strong&gt;only 51.5% of generated sentences fully supported by their citations, and only 74.5% of citations actually supporting the sentence they were attached to&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That study is worth citing carefully rather than waving at. It is from 2023, and it audited Bing Chat, NeevaAI, perplexity.ai and YouChat. NeevaAI no longer exists. It establishes that the problem is real and was severe; it doesn't describe 2026 systems, and I haven't found an equivalently rigorous replication since.&lt;/p&gt;

&lt;p&gt;For a business-controlled machine endpoint, I'd therefore return facts more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"claim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lumar renders JavaScript using Chromium"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.lumar.io/docs/crawler/javascript-rendering/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"asOf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"basis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"supersedes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not because the LLM necessarily needs every property. Because &lt;strong&gt;every downstream agent now has the opportunity to preserve provenance.&lt;/strong&gt; That attacks #8 directly and helps #5, #9, #11 and #12 indirectly.&lt;/p&gt;

&lt;p&gt;And the gap here is close to total &lt;em&gt;(corpus scan)&lt;/em&gt;. &lt;strong&gt;73 sites publish an A2A agent card and 15 of them are valid&lt;/strong&gt;; 58 are missing fields the card is required to carry. Of the 191 sites publishing MCP authorization metadata, 121 are valid. The machinery for machine-readable, attributable answers exists, it's barely deployed, and where it is deployed it's usually wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I'd be much more skeptical
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Base model correction
&lt;/h3&gt;

&lt;p&gt;This is where a lot of GEO marketing is BS. There's no good evidence that adding &lt;code&gt;llms.txt&lt;/code&gt;, rewriting a page a certain way, adding some schema, or mentioning a fact five times reliably causes frontier model parametric knowledge to change.&lt;/p&gt;

&lt;p&gt;A company doesn't control when the next model trains, its corpus, deduplication, weighting, filtering, synthetic-data pipeline or post-training. Allowing GPTBot means content &lt;strong&gt;may&lt;/strong&gt; be used in training. It absolutely does not mean a factual correction will be absorbed.&lt;/p&gt;

&lt;p&gt;Worth noting what the most-adopted intervention actually is &lt;em&gt;(corpus scan)&lt;/em&gt;: &lt;strong&gt;13,730 sites publish &lt;code&gt;llms.txt&lt;/code&gt;&lt;/strong&gt;, making it the most widely adopted agent-facing file on the web after robots.txt and the sitemap. Ahrefs found 97% of the llms.txt files they tracked receive zero AI requests. The most popular lever is the one with the least&lt;br&gt;
demonstrated demand behind it.&lt;/p&gt;

&lt;h3&gt;
  
  
  And current GEO evidence supports that skepticism
&lt;/h3&gt;

&lt;p&gt;There's now quite a lot of GEO research. Controlled studies show altering page structure and content can increase citation visibility. But a review of 45 GEO studies concluded that the strongest evidence concerns what happens &lt;strong&gt;once content is already available to the generative system&lt;/strong&gt;, and found no demonstrated stable, longitudinal, cross-platform causal method for improving organic discoverability.&lt;/p&gt;

&lt;p&gt;That's an enormous distinction. That's how I'd communicate it to customers.&lt;/p&gt;




&lt;h2&gt;
  
  
  So I think there is a much better business category hiding here
&lt;/h2&gt;

&lt;p&gt;Not &lt;em&gt;Generative Engine Optimization&lt;/em&gt;, and not &lt;em&gt;make AI mention your brand more&lt;/em&gt;. Rather:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI factual integrity for organizations.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The product asks models hundreds of questions about the organization. For every claim it identifies, it classifies the failure mode against the twelve above. And crucially it doesn't merely give a brand score. It says &lt;strong&gt;this error is addressable, and here is why&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Three of four models say Lumar cannot crawl JavaScript. The claim is wrong. There is no canonical page &amp;gt; stating it plainly; the fact appears once, in the eleventh paragraph of a product page, alongside two &amp;gt; older documentation pages that contradict it. This is failure mode 2 and 3. Publish a canonical answer &amp;gt; page, retire the contradictions, and re-measure."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;That&lt;/strong&gt; is empirically testable. After the change, rerun the same experiment. Not once, because these systems are stochastic, but enough times to separate a real shift from sampling noise.&lt;/p&gt;

&lt;p&gt;Now you're not selling snake-oil “AI visibility.” You are running something much closer to &lt;strong&gt;observability and remediation for how agents perceive an organization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnose all twelve.&lt;/strong&gt; Sell remediation aggressively for &lt;strong&gt;2, 3, 4, 5, 7 and 8&lt;/strong&gt;, where the organization genuinely has meaningful control. For &lt;strong&gt;1, 6, 9, 10, 11 and 12&lt;/strong&gt;, report the problem and distinguish what can be mitigated from what belongs to the model or agent provider.&lt;/p&gt;

&lt;p&gt;That distinction may be the strongest thing about the product, because it avoids pretending every wrong answer can be fixed with another llms.txt file.&lt;/p&gt;

&lt;p&gt;And it has a precedent in how we already report. In the same corpus scan, the one security-impact check the scanner carries, whether a site has published private key material in its public signing-key directory, fired &lt;strong&gt;zero times across 59 publishers&lt;/strong&gt; &lt;em&gt;(corpus scan)&lt;/em&gt;. The honest way to report that isn't "the web is secure." It is: nobody in this sample did the dangerous thing, the sample is 59, and by the rule of three that's consistent with a true rate anywhere up to about 5%. A product that reports a null result that carefully is a product whose positive findings you can believe.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web</category>
    </item>
    <item>
      <title>I scanned 150,074 sites. The most common mistake is from 2005</title>
      <dc:creator>Ali Habibzadeh</dc:creator>
      <pubDate>Wed, 23 Sep 2026 13:55:34 +0000</pubDate>
      <link>https://dev.to/alihabibzadeh/i-scanned-150074-sites-the-most-common-mistake-is-from-2005-1g11</link>
      <guid>https://dev.to/alihabibzadeh/i-scanned-150074-sites-the-most-common-mistake-is-from-2005-1g11</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/alihabibzadeh/building-an-honest-scanner-for-the-agentic-web-4md2"&gt;Last time&lt;/a&gt; I wrote about building a scanner that refuses to score you for things you have not published. Plenty of people asked the obvious next question: fine, so what does the web actually look like when you measure it that way?&lt;/p&gt;

&lt;p&gt;So I pointed it at the top of the Tranco list and let it run. Between 17 and 19 September it fetched the agent facing files and endpoints of &lt;strong&gt;150,074 domains&lt;/strong&gt;. Not a sample I picked. The list in rank order, until I ran out.&lt;/p&gt;

&lt;p&gt;Here is what came back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules for AI outnumber things for AI, eleven to one
&lt;/h2&gt;

&lt;p&gt;Of the 150,074 hosts, &lt;strong&gt;88,484 published something a machine can read&lt;/strong&gt;. Everything below is counted over those 88,484 and never over the whole list, because a host that never answered is not evidence of anything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;34,160&lt;/strong&gt; have written a rule about AI crawlers, or published a signal about how their content may be used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3,007&lt;/strong&gt; have published an interface an agent can call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to be careful about that first number, because it is easy to read too much into it. It counts sites that named a crawler in robots.txt, or published a content signal, an &lt;code&gt;ai.txt&lt;/code&gt;, or a mining reservation. It does not mean they blocked anything. A group headed by a crawler's name is just as valid with an &lt;code&gt;Allow&lt;/code&gt; in it as with a &lt;code&gt;Disallow&lt;/code&gt;, and from outside I cannot tell which.&lt;/p&gt;

&lt;p&gt;So the honest version is: a third of the web that publishes anything has decided to have a policy about AI. Very few of them have built anything for it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing I did not expect
&lt;/h2&gt;

&lt;p&gt;I built this to measure new protocols. The most common fault it found is twenty one years old.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;61,587&lt;/strong&gt; hosts publish an XML sitemap. &lt;strong&gt;21,448 of them break one of the format's own rules&lt;/strong&gt;, which is about 35%. The sitemap spec was agreed in 2005.&lt;/p&gt;

&lt;p&gt;One fault accounts for roughly half of every problem the scanner found anywhere, across every technology it checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;https://example.com/products/sitemap.xml

&lt;span class="nt"&gt;&amp;lt;url&amp;gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://example.com/about&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
                              ^^^^^^
     the file sits in /products/, so this URL is outside its scope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;14,176 sites&lt;/strong&gt; do this. That is 23% of everyone with a sitemap.&lt;/p&gt;

&lt;p&gt;sitemaps.org says a sitemap may only list URLs at or below its own folder. Google reads those URLs anyway if you submitted the file through Search Console, which is why so many people have never seen it break. Submit the same file any other way, or hand it to anything that is not Google, and the out of scope entries are dropped.&lt;/p&gt;

&lt;p&gt;The rest:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fault&lt;/th&gt;
&lt;th&gt;Sites&lt;/th&gt;
&lt;th&gt;Share of sitemap publishers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lists URLs above its own folder&lt;/td&gt;
&lt;td&gt;14,176&lt;/td&gt;
&lt;td&gt;23%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lists URLs on another domain&lt;/td&gt;
&lt;td&gt;6,106&lt;/td&gt;
&lt;td&gt;9.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing the XML namespace&lt;/td&gt;
&lt;td&gt;2,077&lt;/td&gt;
&lt;td&gt;3.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is not a sitemap at all&lt;/td&gt;
&lt;td&gt;1,562&lt;/td&gt;
&lt;td&gt;2.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses relative URLs&lt;/td&gt;
&lt;td&gt;492&lt;/td&gt;
&lt;td&gt;0.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Worth splitting by how much it costs you. &lt;strong&gt;11,780&lt;/strong&gt; sites break only the folder rule, which Google forgives if you submitted it there. &lt;strong&gt;9,668&lt;/strong&gt; are wrong no matter how you submit them. That is &lt;strong&gt;one in six&lt;/strong&gt; sites with a sitemap.&lt;/p&gt;

&lt;p&gt;If you take one thing from this post: go and look at your sitemap before you think about anything with "agent" in the name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which crawlers people actually name
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;33,626&lt;/strong&gt; sites name at least one crawler in robots.txt. The ones they pick:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Token&lt;/th&gt;
&lt;th&gt;Sites naming it&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GPTBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10,509&lt;/td&gt;
&lt;td&gt;31%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClaudeBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9,038&lt;/td&gt;
&lt;td&gt;27%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CCBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,929&lt;/td&gt;
&lt;td&gt;24%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Google-Extended&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,280&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ChatGPT-User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6,712&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Bytespider&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6,606&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Amazonbot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6,241&lt;/td&gt;
&lt;td&gt;19%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PerplexityBot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5,979&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;CCBot&lt;/code&gt; at 24% is the one that gives the game away. Common Crawl has been around for over a decade and has nothing to do with the current wave. Seeing it that high, in that company, tells you a lot of these rules were pasted from a list someone found rather than decided by the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the three per cent built
&lt;/h2&gt;

&lt;p&gt;The 3,007 sites with something callable, by what they published:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Sites&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UCP profile&lt;/td&gt;
&lt;td&gt;2,202&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAPI description&lt;/td&gt;
&lt;td&gt;497&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP server card&lt;/td&gt;
&lt;td&gt;368&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP authorization metadata&lt;/td&gt;
&lt;td&gt;191&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A2A agent card&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NLWeb endpoint&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Eight NLWeb endpoints, across 88,484 hosts that publish anything at all.&lt;/p&gt;

&lt;p&gt;When these do break, they break in boring ways rather than dramatic ones. &lt;strong&gt;176 of the 497&lt;/strong&gt; OpenAPI descriptions describe a value without saying what type it is. &lt;strong&gt;112&lt;/strong&gt; leave an operation with no &lt;code&gt;operationId&lt;/code&gt;, so an agent picking a call has nothing stable to name it by. Of the 73 A2A agent cards, &lt;strong&gt;54&lt;/strong&gt; are missing fields the spec requires.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is its own story. &lt;strong&gt;13,730&lt;/strong&gt; sites publish one, which makes it the second most adopted thing in the whole study after the sitemap. &lt;strong&gt;1,022&lt;/strong&gt; of those start with text before the title, which the format does not allow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not say
&lt;/h2&gt;

&lt;p&gt;It is not an adoption rate for the web, and I would rather say so myself than have it quoted as one. The list behind it ranks &lt;strong&gt;domain names&lt;/strong&gt; by popularity, not websites. 27,992 of these names never replied, another 14,227 turned me away, and a good chunk of the rest are not sites at all: nameservers, CDN endpoints, API hosts, parked domains.&lt;/p&gt;

&lt;p&gt;Absence is still never counted as a fault, which is the whole argument of the last post. No MCP server card means nothing is reported. An MCP server card whose endpoint does not answer is a defect. Those two stay apart everywhere in this data.&lt;/p&gt;

&lt;p&gt;And one caveat I would rather volunteer than be caught on. Each host was put into exactly one industry by a language model reading its home page. It placed 84,149 of the 88,484. The categories are mine, not a standard taxonomy, and I have not run an accuracy audit on them. So treat anything I say about industries as indicative, not measured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it on your own site
&lt;/h2&gt;

&lt;p&gt;Same checks, same rules, one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx agentic-readiness example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It exits 0 when you have not adopted something and non zero only when something you did publish is broken. That is deliberate, and it means you can put it in CI without it failing your build over a protocol you have never heard of.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agentic readiness of example.com

  OK    Access policies (robots.txt / ai.txt / TDMRep)
  OK    Sitemap

  2 of 14 technologies published, 0 with defects.

  Nothing published here is broken. Absence is never reported.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://agentic-readiness.lumar.io/blog/agentic-readiness-of-the-web" rel="noopener noreferrer"&gt;full study&lt;/a&gt; has the per industry breakdown and every fault counted. The findings are published under CC BY 4.0, so quote them, chart them, build on them, including commercially, as long as you credit us.&lt;/p&gt;

&lt;p&gt;Same offer as last time. Take it, argue with it, or tell me where I have got it wrong.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>web</category>
    </item>
    <item>
      <title>Building an honest scanner for the agentic web</title>
      <dc:creator>Ali Habibzadeh</dc:creator>
      <pubDate>Thu, 27 Aug 2026 23:19:25 +0000</pubDate>
      <link>https://dev.to/alihabibzadeh/building-an-honest-scanner-for-the-agentic-web-4md2</link>
      <guid>https://dev.to/alihabibzadeh/building-an-honest-scanner-for-the-agentic-web-4md2</guid>
      <description>&lt;h2&gt;
  
  
  Why I started
&lt;/h2&gt;

&lt;p&gt;Every few weeks somebody sends me an "AI readiness score" for a website. It is always red. It never explains what the missing items would actually do for that site, and it never distinguishes between two completely different situations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You have not published an emerging protocol.&lt;/li&gt;
&lt;li&gt;You have published one, and it does not work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first is usually an observation. The protocol may not apply to your site, its adoption may be negligible, real agents may not touch it, and waiting may be the correct decision. The second is a genuine defect: an agent card advertising an endpoint that answers nothing, a discovery document that is not discoverable, a required field that is missing.&lt;/p&gt;

&lt;p&gt;Collapsing those two into one number is how you manufacture urgency. A low score creates panic without explaining whether anything is at stake. A high score hides real breakage, because unrelated features compensate for broken ones. Both are dishonest, and both are commercially convenient, which is presumably why they are everywhere.&lt;/p&gt;

&lt;p&gt;There was a second motivation, closer to home. The people who want these technologies are usually SEOs and content teams. The people who can ship them are engineers with a roadmap full of platform work. So a finding sits in a backlog for two quarters, or an agency charges a lot of money for a file that takes ten minutes to write. Telling someone what is broken is only half a product. I wanted the other half.&lt;/p&gt;

&lt;p&gt;So the goal became: &lt;strong&gt;measure honestly, then help implement.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I built in the container
&lt;/h2&gt;

&lt;p&gt;The core is a Lumar custom metric container (&lt;code&gt;inputType: Puppeteer&lt;/code&gt;), organised into six categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technologies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Discoverability&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capabilities&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commerce&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Thirty technologies in total. &lt;strong&gt;23 are scored. 7 are watched and deliberately not scored.&lt;/strong&gt; That split is the product, not an implementation detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  The contract: detect, then validate, then report
&lt;/h3&gt;

&lt;p&gt;Every technology emits the same shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;tech&amp;gt;Present   boolean   the detection gate
&amp;lt;tech&amp;gt;Valid     boolean   present and defect-free
&amp;lt;tech&amp;gt;&amp;lt;Defect&amp;gt;  boolean   one per known defect kind, true only when present-but-wrong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule that falls out of this is the one the whole container rests on: &lt;strong&gt;if a technology is not present, the collector computes nothing and emits nothing.&lt;/strong&gt; Not &lt;code&gt;Present: false&lt;/code&gt;. Nothing at all. There is no point validating, storing, or reporting anything about a technology a page never adopted.&lt;/p&gt;

&lt;p&gt;That produces 309 per-URL metric fields and 185 site-wide fields, backed by &lt;strong&gt;111 catalogued defects&lt;/strong&gt;. Every defect names the clause and the revision it comes from, and whether the authority is a standard or a Lumar recommendation. We do not borrow a specification's authority for our own preferences, and the catalogue makes that distinction machine-readable rather than a matter of tone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two phases, because two kinds of fact
&lt;/h3&gt;

&lt;p&gt;Page-level signals (canonical, JSON-LD, server-side rendering, Markdown twins, WebMCP) vary per URL and are read in the request handler. Site-wide signals (robots.txt, ai.txt, &lt;code&gt;/.well-known/*&lt;/code&gt;, live protocol probes) are one fact per host, so they run once per host in a postCrawl handler and emit a crawl-level item. Nine site-wide signals, one row per host per signal.&lt;/p&gt;

&lt;p&gt;Getting this wrong is expensive. Fetch a well-known file once per URL and a 50,000-page crawl knocks on somebody's server 50,000 times for a file that has not changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Naming evidence states, and never faking one
&lt;/h3&gt;

&lt;p&gt;This is where most of my early false positives came from, so it is now a hard rule.&lt;/p&gt;

&lt;p&gt;A fetch outcome is a discriminated union: &lt;code&gt;complete&lt;/code&gt;, &lt;code&gt;truncated&lt;/code&gt;, &lt;code&gt;absent&lt;/code&gt;, &lt;code&gt;unreachable&lt;/code&gt;. Only &lt;code&gt;complete&lt;/code&gt; carries content, so a body we stopped reading at a byte cap &lt;strong&gt;cannot&lt;/strong&gt; be handed to an analyzer, because the type does not expose it.&lt;/p&gt;

&lt;p&gt;And more importantly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Only an HTTP response proves absence.&lt;/strong&gt; A 4xx or 5xx is the server saying "not here". Everything else, our own timeout, a spent budget, a reset connection, a blocked destination, is &lt;em&gt;us failing to look&lt;/em&gt;, and must map to that signal's "unassessed" state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Collapsing those convicts a site of our own timeout. That is the exact false positive this container exists to avoid, and the type system now refuses to let me write it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two registries that answer different questions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/defect-catalog/&lt;/code&gt; says &lt;strong&gt;what can go wrong&lt;/strong&gt; with a technology and on whose authority. One entry per emitted flag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/tech/&lt;/code&gt; says &lt;strong&gt;what the technology is&lt;/strong&gt;: name, summary, adoption level, named adopters, the documents it is pinned to, the fixtures that demonstrate it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything public is generated from that pair. The scanner, the documentation pages, the survey tables, and the report catalogue all come out of the same two files, so they cannot disagree with the code. When I add a defect, its documentation, its report column, and its public reference page appear because they are derived, not because I remembered to update three places.&lt;/p&gt;




&lt;h2&gt;
  
  
  Keeping up with specs that move weekly
&lt;/h2&gt;

&lt;p&gt;This is the part I did not anticipate, and the part I am most pleased with.&lt;/p&gt;

&lt;p&gt;These are emerging standards. MCP has shipped multiple revisions. Content Signals appeared and gained real adoption inside a year. Proposals turn up with a website, a GitHub repo and an enthusiastic announcement, and some of them die quietly.&lt;/p&gt;

&lt;p&gt;A container pinned to a spec revision goes stale in weeks. Manual re-checking does not survive contact with a roadmap. So I built three Claude Code skills, versioned in the repo alongside the code they maintain. Each one has a bounded remit and writes to a bounded set of files, which is what stops an audit quietly becoming a refactor.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/check-correctness&lt;/code&gt;: is what we score still what the spec says?
&lt;/h3&gt;

&lt;p&gt;Re-reads each technology's authoritative document and compares it against what the container actually validates. It hunts four kinds of drift:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a bumped spec version&lt;/li&gt;
&lt;li&gt;a renamed or restructured field&lt;/li&gt;
&lt;li&gt;a new present-but-wrong surface we should be catching&lt;/li&gt;
&lt;li&gt;a check the spec no longer justifies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is an audit, not a rewrite. It proposes changes and updates only the &lt;code&gt;_Last verified_&lt;/code&gt; stamps. Confirmed drift is implemented separately through &lt;code&gt;/add-metric-checker&lt;/code&gt;, which does the full end-to-end job: interface field, collector, e2e fixtures, &lt;code&gt;SOURCES.md&lt;/code&gt; citation, and the expectations gate.&lt;/p&gt;

&lt;p&gt;Keeping "find the drift" and "fix the drift" as separate skills matters. An audit that can also refactor is an audit you cannot trust the output of.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/scan-emerging-tech&lt;/code&gt;: what should we admit next?
&lt;/h3&gt;

&lt;p&gt;The intake step. It horizon-scans for technologies &lt;strong&gt;not yet in the container&lt;/strong&gt;, and re-tests the "landscape only" and "dropped" rows for anything that has since matured.&lt;/p&gt;

&lt;p&gt;Every candidate goes through an admission rubric:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On-thesis.&lt;/strong&gt; Is it part of a website's public agent-facing surface? Enterprise data-lake architecture is not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crawl-detectable.&lt;/strong&gt; Can we observe it from outside, without credentials?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Present-but-wrong surface.&lt;/strong&gt; Is there a way to adopt it and get it wrong? If not, there is nothing for us to score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distinct.&lt;/strong&gt; Does it overlap something we already check?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec-anchored.&lt;/strong&gt; Is there a document to cite, or only a blog post?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This rubric is why the container scores 23 things and watches 7 rather than scoring everything with a logo. It is also why some things were dropped: ACP and AP2 came out because neither presented a crawl-detectable present-but-wrong surface, and llms.txt came out for lack of adoption. Both decisions are recorded with reasoning, because "we deliberately do not score this" is a claim we should have to defend.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/track-adoption&lt;/code&gt;: who is actually using this?
&lt;/h3&gt;

&lt;p&gt;Maintains an adoption ladder (L0 to L4) for every technology we score or watch, with trajectory, named adopters, depth of implementation, and dated citations. It writes to one document and nothing else.&lt;/p&gt;

&lt;p&gt;Its evidence feeds the scan rubric's adoption gate, which closes the loop: a watched technology maturing shows up here first, then routes to the scan skill, then to the checker skill. And a scored technology whose adoption collapses triggers a drop discussion.&lt;/p&gt;

&lt;p&gt;Today's ladder, straight from the registry, tells a useful story on its own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;L4  established   robots.txt, XML sitemap, canonical, JSON-LD, schema:Action,
                  Product schema, editorial metadata, OpenAPI, Link headers,
                  language and encoding, server-side rendering
L3  widespread    AI-bot rules, Content Signals, UCP profile
L2  adopted       MCP authorization, Markdown twin, TDMRep, Web Bot Auth
L1  emerging      MCP server card, A2A agent card, WebMCP, NLWeb
L0  negligible    ai.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tall bars are two decades of web standards. The short ones are this year. A tool that treats those as equally urgent is not measuring readiness, it is selling anxiety.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running it in the Lumar crawler
&lt;/h2&gt;

&lt;p&gt;Inside a Lumar crawl, the container produces two kinds of output.&lt;/p&gt;

&lt;p&gt;Per-URL metrics land on every page row, so you can segment and filter like any other crawl field. Site-wide items land in the crawl-level table, one row per host per signal, so a robots.txt fault appears once rather than on every one of a million URLs.&lt;/p&gt;

&lt;p&gt;On top of that sit &lt;strong&gt;33 predefined reports&lt;/strong&gt;, and every one of them obeys the same rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A report's filter must AND-in &lt;code&gt;&amp;lt;tech&amp;gt;Present eq true&lt;/code&gt; before any defect predicate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A URL enters a report only when it actually adopted the technology. There is no report anywhere in the product that lists pages for not having something. Each report also shows every one of that technology's defect columns, ordered by severity, so no defect is invisible in the grid. That ordering is derived from the catalogue and asserted in tests, because I had eleven reports inherit the interface's declaration order, which is a parser's order, not a reader's.&lt;/p&gt;




&lt;h2&gt;
  
  
  Turning the checkers into a free scanner
&lt;/h2&gt;

&lt;p&gt;The reports are for customers running crawls. But the argument I wanted to make is a public one, so I built a free scanner: enter a domain or a URL, get an honest answer, no account.&lt;/p&gt;

&lt;p&gt;The important design decision is what it does &lt;strong&gt;not&lt;/strong&gt; do. It does not reimplement the rules. It imports the container's own collectors and analyzers directly. The free tool and the paid audit run the same code, so they cannot drift apart and start disagreeing about what a valid MCP card looks like.&lt;/p&gt;

&lt;p&gt;The output mirrors the container's shape: what you publish, whether each published thing is correct, and, when we could not test something properly, a plain statement that it was only &lt;strong&gt;partly assessed&lt;/strong&gt;. That third state matters. A card declaring gRPC cannot be verified with an HTTPS request, so we say so instead of quietly certifying it.&lt;/p&gt;

&lt;p&gt;There is no total score anywhere in the interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Builders: the other half of the product
&lt;/h2&gt;

&lt;p&gt;Finding a fault and leaving you with it is the behaviour I was complaining about at the start. So every technology the scanner checks ends the same way: with something to do next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Six builders generate a finished file:&lt;/strong&gt; AI-crawler rules, Content Signals, ai.txt, TDMRep, an A2A agent card, an MCP server card. They interview you for what the site cannot tell us, read what you already publish so the form arrives half-complete, and generate the artifact.&lt;/p&gt;

&lt;p&gt;Then the rule that makes it trustworthy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every generated artifact is run through the analyzer this container scores live sites with, and anything that fails is withheld with the reason.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are not going to be the tool that emits the defects it reports. If a card would advertise an endpoint that does not answer, we do not write the address until the endpoint answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seventeen more are tutorials&lt;/strong&gt;, for technologies that cannot be handed over as a file because they need a running server or a template change: canonical tags, JSON-LD, Markdown twins, MCP authorization, NLWeb, WebMCP, server-side rendering. These are assembled from artifacts the repository already tests, the correct and broken fixtures from the e2e suite, and the defect catalogue's clauses. A tutorial cannot drift from what the scanner scores, because it is made of the same material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seven technologies we refuse to build&lt;/strong&gt;, listed by name with the reason. "We track this proposal but do not currently recommend implementing it" is a more useful answer than a missing menu item.&lt;/p&gt;

&lt;p&gt;One thing I got badly wrong and had to redo properly: the robots.txt builders originally emitted a &lt;em&gt;fragment&lt;/em&gt;, while every publishing recipe said "serve this artifact at /robots.txt". Following the Next.js instructions would have replaced a site's entire robots.txt with a single line, deleting the wildcard group, every rule, every named crawler and the sitemap. A fragment also cannot express "change this crawler from Allow to Disallow", so asking to block a crawler the file already allowed returned "nothing to add".&lt;/p&gt;

&lt;p&gt;The fix was a line-level editor that produces the complete file: your current robots.txt with the change applied, every comment and ordering choice preserved, and a list of exactly what changed. It splits a crawler out of a shared group rather than changing its neighbours, and it validates the file before and after so a fault you already had does not get blamed on us.&lt;/p&gt;




&lt;h2&gt;
  
  
  Eating the same food
&lt;/h2&gt;

&lt;p&gt;It would be strange to publish a scanner that grades agent-readiness from a website only humans can use. So the scanner publishes everything it tells you to publish, and its own pages are scored by the container in CI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;MCP endpoint&lt;/strong&gt; with three tools: scan a site, search the documentation, build a file. No account, no key.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;A2A agent card&lt;/strong&gt; and an &lt;strong&gt;OpenAPI contract&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebMCP&lt;/strong&gt; registrations in the page, so a browsing agent can complete a builder wizard while you watch.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Markdown twin of every page&lt;/strong&gt;, served by content negotiation and at its own address.&lt;/li&gt;
&lt;li&gt;Our own robots.txt with named AI-crawler groups, Content Signals, ai.txt, and a TDMRep reservation that matches what the Content Signals line says rather than contradicting it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The three MCP tools compose into the actual job, which is the point of exposing them: find what is broken, read why it matters, generate the fix, check the fix against the same rules the scan uses. An agent can do the whole loop without anyone opening the page.&lt;/p&gt;

&lt;p&gt;This is not decoration. It caught a real defect in code I had written an hour earlier. A new page declared itself a &lt;code&gt;TechArticle&lt;/code&gt; with no author and no &lt;code&gt;datePublished&lt;/code&gt;. &lt;code&gt;TechArticle&lt;/code&gt; is in the Article family, so the container's own editorial checks fired: &lt;code&gt;editorialMissingAuthor&lt;/code&gt; and &lt;code&gt;editorialMissingDatePublished&lt;/code&gt;, two of the defects we report on other people's sites, published on our own page.&lt;/p&gt;

&lt;p&gt;The structural fix was a test that scores every hand-written page through the container and asserts that no defect fires, so the next page cannot ship unscored. That is what dogfooding is for. Not the marketing line, the failing test.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where it stands
&lt;/h2&gt;

&lt;p&gt;The container ships 23 scored technologies and 111 catalogued defects, with 1,426 tests. The scanner adds 607 unit tests and a browser suite. Three maintenance skills keep the specs, the intake and the adoption evidence current, on a cadence rather than on a good intention.&lt;/p&gt;

&lt;p&gt;The position underneath all of it is simple enough to fit in a sentence: &lt;strong&gt;missing is not the same as broken&lt;/strong&gt;, and a tool that cannot tell the difference is not measuring your website, it is measuring your anxiety.&lt;/p&gt;

&lt;p&gt;If any of this is useful to you, take it, argue with it, or tell me where I have got it wrong. The reasoning is all public, including the parts where I changed my mind.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The argument:&lt;/strong&gt; &lt;a href="https://agentic-readiness.lumar.io/mission" rel="noopener noreferrer"&gt;https://agentic-readiness.lumar.io/mission&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The scanner:&lt;/strong&gt; &lt;a href="https://agentic-readiness.lumar.io/" rel="noopener noreferrer"&gt;https://agentic-readiness.lumar.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The reference,&lt;/strong&gt; with every check, its authority, and a correct and broken example of each: &lt;a href="https://agentic-readiness.lumar.io/docs" rel="noopener noreferrer"&gt;https://agentic-readiness.lumar.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>seo</category>
    </item>
  </channel>
</rss>
