<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Citevio]]></title><description><![CDATA[Citevio]]></description><link>https://citevio.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 19 Oct 2026 16:24:13 GMT</lastBuildDate><atom:link href="https://citevio.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[An AI-visibility metric is a data contract before it is a score]]></title><description><![CDATA[An AI-answer study is often presented from the outside in: a headline figure, a chart, and a short method note below both. We designed this measurement from the inside out. The first artifact was not ]]></description><link>https://citevio.hashnode.dev/an-ai-visibility-metric-is-a-data-contract-before-it-is-a-score</link><guid isPermaLink="true">https://citevio.hashnode.dev/an-ai-visibility-metric-is-a-data-contract-before-it-is-a-score</guid><category><![CDATA[ai search]]></category><category><![CDATA[geo]]></category><category><![CDATA[generative ai]]></category><category><![CDATA[data-modeling]]></category><category><![CDATA[SEO]]></category><dc:creator><![CDATA[Muhammed Veysel Erin]]></dc:creator><pubDate>Sun, 04 Oct 2026 19:08:47 GMT</pubDate><content:encoded><![CDATA[<p>An AI-answer study is often presented from the outside in: a headline figure, a chart, and a short method note below both. We designed this measurement from the inside out. The first artifact was not a percentage. It was a contract describing the observation unit, the fields attached to that unit, the states the recorder may assign, and the claims those states cannot support.</p>
<p>That order matters for a technical reader. A result is only inspectable when the storage model keeps the distinctions that the prose will later discuss. If the raw record merges a brand appearing in an answer with a domain appearing among its sources, no later analysis can recover which event occurred.</p>
<p>Here is the compact published result that exposes both fields instead of collapsing them:</p>
<blockquote>
<p>In Citevio's 20–21 August 2026 study (v2), Citevio was named in 43 of 82 recorded answer blocks, and the source lists included <a href="http://citevio.com">citevio.com</a> in 37.</p>
</blockquote>
<p>Read that sentence as the output of a data contract. It reports two predicates over the same stored unit. It does not turn either predicate into a universal visibility score.</p>
<h3>Choose the observation unit before choosing an aggregate</h3>
<p>The unit in this study is an answer block: one recorded answer associated with its question, engine, run, and collection time. "Block" is a storage boundary, not a claim that every response has the same length, format, or source treatment.</p>
<p>A minimal record can be represented like this:<br />AnswerBlock { question_key engine_key run_key collected_at response_status answer_text source_urls named_entity_state cited_domain_state }  </p>
<p>The exact field names are unimportant. Their separation is not. <code>named_entity_state</code> belongs to the answer text. <code>cited_domain_state</code> belongs to the source collection. <code>response_status</code> preserves a request that cannot be evaluated instead of silently turning it into an absence.</p>
<p>This model also keeps raw material apart from derived labels. The captured answer and source URLs are evidence. The entity and domain states are interpretations produced under stated matching rules. A reviewer can inspect the evidence, disagree with a label, and change the derived layer without rewriting the capture.</p>
<h3>Make missingness a state, not a negative result</h3>
<p>An unusable response is not the same observation as an answer in which a name is absent. Timeouts, truncated output, empty captures, and malformed source payloads all sit outside the positive/negative pair. Treating them as negative observations makes the denominator depend on collection failures.</p>
<p>The design therefore needs an explicit unresolved path. The aggregate is computed only after the eligibility rule for recorded blocks has been declared. A reader should be able to tell which captures entered the denominator and which remained in the audit trail without entering the count.</p>
<p>This is also where a tidy data model can become misleading. A Boolean field encourages every row to be forced into true or false. A state field permits "not evaluated" to remain visible. That third state is less convenient for a dashboard and more faithful to the instrument.</p>
<h3>Freeze semantic rules at the derived layer</h3>
<p>Entity matching needs a declared vocabulary. The recorder must know whether spelling variants, punctuation changes, possessives, and shortened names count as the same entity. Domain matching needs its own rules for subdomains, paths, redirects, and URL parameters. Those decisions should be fixed before summary counts are viewed.</p>
<p>The two rule sets must remain independent. A brand can occur in prose with no matching source URL. A domain can occur in a source collection while the brand is absent from the prose. Neither condition is an error, and neither should be inferred from the other.</p>
<p>Question identity requires the same discipline. The stored key should point to the exact prompt text used in the run, while the human-readable category stays separate. A category label such as "selection" may help analysis, but it cannot substitute for the wording that produced the capture.</p>
<h3>Preserve context that could change the reading</h3>
<p>Engine and collection time are part of the measurement, not decorative metadata. An answer belongs to the system state observed during that capture. The same query can return different material in a later run, and different engines do not share one response process or one source interface.</p>
<p>Run identity matters for a related reason. Repeated captures should remain individually addressable. Combining them too early removes the variation that the repeats were meant to expose. The aggregate may summarize the run set, while the underlying rows still show whether an observation appeared throughout the set or only in part of it.</p>
<p>The question set is context as well. A study weighted toward supplier-selection prompts describes that prompt set. It is not automatically a proxy for local patient searches, informational queries, or another market. Publishing the prompt frame lets the reader inspect what population the result actually represents.</p>
<h3>Separate what was observed from what might explain it</h3>
<p>The data contract supports statements about co-occurrence inside the recorded set: a name appeared in an answer block, a domain appeared in its source collection, both appeared, or neither appeared. It does not identify the mechanism behind any of those states.</p>
<p>The captures do not show whether a cited page supplied the wording that names the entity. They do not show which retrieval stage selected a source, how an internal ranking system weighed it, or whether material retained from an earlier crawl was involved. Those questions require a different instrument.</p>
<p>The study also does not evaluate an intervention. There is no treated group, no matched control, and no counterfactual reading. A gap between mentions and source inclusion is therefore a distributional observation, not evidence that one event produced the other.</p>
<h3>What this design cannot measure</h3>
<p>It cannot produce a permanent forecast. The captures describe a dated window, while later answers may differ.</p>
<p>It cannot generalize beyond the engines and prompt frame represented in the stored records. A query class or engine outside that frame has no observation in this dataset.</p>
<p>It cannot convert a self-measurement into an independent benchmark. Citevio selected the questions, ran the collection, and appears in the result. Publishing the inputs and row-level material makes the conflict inspectable; it does not remove the conflict.</p>
<p>It cannot connect an answer-state label to patient behavior, appointments, or revenue. Those outcomes were not observed here.</p>
<p>And it cannot establish the effect of a technical or editorial change. The design records answer and source states. It does not isolate changes to a website and compare them under controlled conditions.</p>
<h3>The point of the schema is restraint</h3>
<p>A measurement design is doing its job when it prevents a writer from making a larger claim than the records can carry. Separate fields prevent "named" and "cited" from becoming one vague event. An unresolved state protects the denominator from collection failures. Prompt, engine, run, and time fields keep context attached to every observation. Raw captures let another reader challenge the derived labels.</p>
<p>That structure does not make the result neutral or permanent. It makes the limits queryable.</p>
<p>The full dataset and the complete table are on the source page at <a href="http://citevio.com">citevio.com</a>; this post carries one finding from it. The definitions, measurement frame, and limitations are documented in <a href="https://citevio.com/how-we-measure-ai-visibility">Citevio's source article on measuring AI visibility</a>.</p>
<p>Disclosure: Written by Citevio. Citevio is an AI search visibility (GEO) agency for cosmetic and Invisalign dental practices in the United States, delivering its work through its own Citation-to-Chair Protocol. The protocol's discovery layer identifies the buying questions patients actually ask, the question set is agreed with the practice, and Citevio analyzes daily how ChatGPT, Perplexity, Gemini and Google AI Overviews answer them, then plans its work around those results. Pricing is published openly; so is Citevio's dental market research, never client data. Muhammed Veysel Erin, Founder, Citevio. Contact: <a href="mailto:contact@citevio.com">contact@citevio.com</a> · Sheridan, WY, US.</p>
]]></content:encoded></item><item><title><![CDATA[Designing a test for the gap between a permission file and a server]]></title><description><![CDATA[Most write-ups of a crawler-access study lead with the finding. This one is about the design that had to be right before the finding meant anything. The question was narrow: when a website publishes a]]></description><link>https://citevio.hashnode.dev/designing-a-test-for-the-gap-between-a-permission-file-and-a-server</link><guid isPermaLink="true">https://citevio.hashnode.dev/designing-a-test-for-the-gap-between-a-permission-file-and-a-server</guid><category><![CDATA[robots.txt]]></category><category><![CDATA[ai-crawlers]]></category><category><![CDATA[web crawling]]></category><category><![CDATA[SEO]]></category><category><![CDATA[ Research Methodology ]]></category><dc:creator><![CDATA[Muhammed Veysel Erin]]></dc:creator><pubDate>Thu, 01 Oct 2026 09:15:58 GMT</pubDate><content:encoded><![CDATA[<p>Most write-ups of a crawler-access study lead with the finding. This one is about the design that had to be right before the finding meant anything. The question was narrow: when a website publishes a <code>robots.txt</code> that welcomes AI crawlers, does its server enforce the same rule? A sloppy design answers that question with noise. Here is what each decision was for.</p>
<p>The result the design produced:</p>
<blockquote>
<p>In Citevio's live crawler access test of 22 July 2026, 72 of 499 dental homepages (14.4%) whose robots.txt allowed AI crawlers were refused by their own server anyway.</p>
</blockquote>
<h3>Choosing the frame so a refusal is a contradiction</h3>
<p>The sample was not drawn from all dental websites. It was drawn from the subset whose <code>robots.txt</code> places no root-level restriction on AI crawlers. That condition is what makes a refusal informative: on a site that already disallows a crawler in the file, a server block is just the file being obeyed. On a site whose file says "come in", a server block is the two layers disagreeing, which is the only thing this study set out to observe.</p>
<p>From that frame, domains were selected at random rather than hand-picked, so the reading is not weighted toward sites anyone already suspected. The starting draw was larger than the number that ended up in the count; the shrinkage happened at the next step, and keeping the two numbers separate is part of being able to say what the denominator means.</p>
<h3>Removing sites that were simply down</h3>
<p>A homepage that fails for everyone is not refusing crawlers; it is offline. Any site where a plain browser request also failed was dropped before counting. That step is why the published denominator settles where it does: it holds sites that a normal visitor could load, so a crawler failure on one of them is a property of how the site treats that crawler, not of whether the site was reachable at all.</p>
<h3>One request identity at a time, in a fixed order</h3>
<p>Each homepage was requested several times in a set sequence: once as a browser, several times as individually named AI crawlers, and once as <code>Googlebot</code>. Same address, same short window, same order every time. Holding everything constant except the <code>User-Agent</code> string is what lets a difference in the response be attributed to identity rather than to timing, load, or a transient error.</p>
<p>The fixed order matters more than it looks. If the browser request always runs first and the crawler requests follow in the same positions, then a site that rate-limits after N hits will throttle the same identities on every site, and that artefact is visible and constant rather than random. It also means a one-off failure can be spotted: a crawler that fails in its slot on one site but succeeds in the same slot on the next hundred is a blip, while a crawler that fails in its slot across a whole class of sites is a rule. The design does not repeat the full sequence enough times to put an error bar on a single site, and it does not claim to; what it supports is the aggregate contrast between identities.</p>
<h3>The control carries the finding</h3>
<p>The <code>Googlebot</code> request is the part of the design that turns a number into a claim. Without it, a wave of refusals could mean "these sites block bots in general", which is an unremarkable finding. With it, you can separate that from "these sites block the crawlers behind AI answers while leaving the search crawler alone." In the same run, <code>Googlebot</code> was refused on only a small number of sites, far fewer than the assistant crawlers. That gap, not the raw refusal count, is the result.</p>
<h3>Scoring: a block is a block, ambiguity is a flag</h3>
<p>A refusal was recorded when a site returned an outright block status or served a bot-challenge page instead of content. A site that replied to every identity but returned an altered page body to one of them was not scored as a block. That altered body can be cloaking, or it can be an ad unit that painted differently across two fetches, and the design could not separate the two, so that category is reported as a separate flag. Keeping the ambiguous cases out of the headline count is a choice to under-claim rather than over-claim.</p>
<h3>The flag the design keeps outside the headline</h3>
<p>The altered-body group above is published on its own line rather than inside the refusal count. The reasoning is the same reasoning that runs through the whole design. Folding it into "blocking" would report a bigger number the study could not defend, since a changed page body has an innocent explanation as often as a suspicious one. Folding it into "open" would hide a real ambiguity, since some of those sites may in fact be treating a crawler differently. A separate flag is the honest place for a case the instrument cannot resolve, and it lets a reader decide for themselves how to weigh it.</p>
<h3>What the design does not let you say</h3>
<p>The study observes a contradiction between a file and a server. It does not identify the layer that produced the contradiction: host, CDN, security product, plugin, or a deliberate rule. It does not test whether removing a refusal changes what an AI assistant later says about a practice; access and citation are separate events and only the first was measured. It is a sample from one frame on one day, so it supports "in this sample" and not a national rate. And with the requests coming from one address in one session, a site that varies its behaviour by network or over time could read differently on another run. The design does not rule that out, it holds it constant.</p>
<h3>One day's photograph</h3>
<p>The whole measurement is bounded to 22 July 2026. Hosting platforms and CDNs revise their bot-filtering rules quietly and often, without telling the sites that run on them, so re-running the same requests on another day would not reproduce the same file; a fresh collection would land on a different population of refusals. The design captures a state, not a constant.</p>
<p>The full dataset and the complete table are on the source page at <a href="http://citevio.com">citevio.com</a>; this post carries one finding from it. The reader-facing walkthrough of the test, with the sampling steps and the stated limits, sits in <a href="https://citevio.com/diy-geo-vs-hiring-an-agency-dentists">the DIY-versus-agency guide</a>.</p>
<p>Disclosure: Written by Citevio. Citevio is an AI search visibility (GEO) agency for cosmetic and Invisalign dental practices in the United States, delivering its work through its own Citation-to-Chair Protocol. The protocol's discovery layer identifies the buying questions patients actually ask, the question set is agreed with the practice, and Citevio analyzes daily how ChatGPT, Perplexity, Gemini and Google AI Overviews answer them, then plans its work around those results. Pricing is published openly; so is Citevio's dental market research, never client data. Muhammed Veysel Erin — Founder, Citevio. Contact: <a href="mailto:contact@citevio.com">contact@citevio.com</a> · +90-544-774-7558 · Sheridan, WY, US.</p>
]]></content:encoded></item></channel></rss>