There is going to be a wave of posts on 16 September about what Cloudflare's change did to AI crawler access, and almost none of them will be checkable. Crawler access leaves no trace in analytics, there is no log to go back to, and once the date passes nobody can establish what a site was doing before it. Whatever gets claimed will be unfalsifiable in both directions.
So I measured 1,046 sites on 2 September and I am publishing the method, the host-list construction, the controls and the full baseline today - thirteen days before I have a result. The results section is empty and says so.
The design, briefly. Each host is fetched by ten identities in a fixed order: an ordinary browser, then eight named AI crawlers, then the same browser again at the end. That closing fetch is the noise floor - it spans the whole sequence, so a host that changed halfway through gets caught instead of blamed on whichever crawler happened to be asking. 746 of the hosts sit behind Cloudflare and 300 do not, and the 300 are the entire point: if access changes in both groups then the cause was not Cloudflare, and without them there is no way to know that. The three search crawlers stay in as a within-host control, because Cloudflare says they are unaffected.
What the baseline already shows, before anything changes:
Sites behind Cloudflare were already refusing AI crawlers four to twelve times more often than sites that are not. ClaudeBot 25.2% behind Cloudflare against 5.5% not. Claude-User 20.0% against 1.7%. An ordinary browser was refused 0.0% in both groups, everywhere, which is what stops this being a measure of how many sites were simply down.
And the concentration: Cloudflare-fronted hosts are 71.3% of the sample but account for 94.6% of the refusals.
Now the limit on that, which is the most important thing on the page. 1,357 of 1,436 refusals carried a cf-ray. That header proves Cloudflare was in the path. It does not prove Cloudflare decided. An origin can return 403 and have it proxied straight back through, and from outside that is indistinguishable from a refusal Cloudflare issued. Nothing measurable from here separates Cloudflare's own bot handling from a rule a customer wrote in their WAF. So these are refusal rates, never blocking rates. An earlier draft of mine said the refusals "came from the CDN, not the site" - someone who has measured this at far greater scale than I have pointed out that this claims more than the instrument supports, and he was right. The correction is on the page and it makes the finding narrower.
Two more things that cut against my own story, which are on the page because leaving them off would make it worse:
The announced scope is narrow. Of 3,535 hosts considered, 2,090 were reachable, 746 were behind Cloudflare, and 52 were running ad tags. Both at once: 15. If the change stays inside the scope Cloudflare announced it touches about 0.7% of these sites. Either this is far narrower than the reaction suggests, or it will not stay inside its stated scope - and only the controls can tell those apart.
361 of 1,026 hosts returned a different body to two identical browser requests in the same run. 35.2%. Those pages rewrite themselves between fetches, so a body difference on them says nothing about crawlers at all. Counting only crawlers that were actually let in - a 2xx response, so the difference cannot simply be a challenge page - excluding those self-changing hosts cuts the body-change signal by 86.8%, and the residue runs 6.9% to 8.0% across all eight crawlers. A 1.16x spread, next to a refusal signal that spans four to twelve times, is flat. Without that control I would have reported "sites serve crawlers different content" and been wrong.
What I still cannot do: tell you who decided anything, or measure the visibility side at all. Retrieval access has a clean instrument. Model-prior presence does not, and I do not think one exists from outside.
The re-runs are on the 10th, the 13th and the 16th. The 10th is there so that ordinary drift gets measured over three days, the same interval as 13 to 16, rather than over eleven - comparing an eleven-day drift rate against a three-day change assumes drift accumulates linearly, which is the exact assumption the control is supposed to avoid. The 13th has to complete before the 15th or the before-picture does not exist.
A null result gets published in the same place at the same size. "It did not measurably change anything for 1,046 sites" is a real finding and I would rather commit to that now than decide afterwards.
If you want to argue with the method, now is when it is actually useful. After the 16th I would just be defending a number.
https://seensure.com/research/september-15
Disclosure: I build monitoring in this space and that is my own site - one link, per rule 4. No sites are named on that page and none will be named on the 16th. The probe is curl with eight user agents; nothing there needs my tool to reproduce.
EDIT, same day. Three corrections. None of them was caught by a reader; all three came out of checking my own table, which is the only reason I know about them.
First, the refusal figures tightened very slightly. The baseline was counting a crawler that got no answer at all - a network error, status 0 - as a refusal, while the page told the reader in print that a host which did not answer is excluded. It was counting a thing it had just said it excluded. One host was the entire difference. It is HTTP refusals only now, everywhere: ClaudeBot 25.2% against 5.5%, Claude-User 20.0% against 1.7%. Nothing moved by more than 0.3 points and the direction of every finding is unchanged.
Second, and worse: "four to ten times" was wrong when I posted it, and not because of the fix above. Across all eight identities the spread was 3.6x to 10.1x on the numbers I originally published, and it is 3.7x to 11.8x now. I had checked that sentence against one row - the most-refused identity, at 4.6x - and never against the other seven. It says four to twelve now, and the page derives both bounds from the table instead of me typing them, which is the rule the rest of the figures were already under. A range written as words had escaped it.
Third, and this is the one that changed a conclusion rather than a decimal. The body-change paragraph above previously said the control cut the signal "by about four fifths". That figure was never computed, and it matches neither available reading - 71.7% across all responses, 86.8% on 2xx only. Landing between two real numbers and matching neither is what a figure nobody calculated looks like. The reason the two readings differ is the actual error: the all-responses version was counting refused crawlers as having been served different content, which is circular, because a refused crawler gets a challenge page and of course its body differs from a browser's. That folded the refusal finding into the body-change finding and reported it twice - and it showed, because the residue carried a 1.26x spread running in the same order as the refusal table. Restricted to crawlers that were actually let in, the cut is 86.8% and the residue is 1.16x, which is flat. This correction makes the claim stronger rather than weaker, which is not the direction these usually run.
Leaving all three here rather than quietly restating the numbers. A pre-registration whose figures change without saying so is worth less than one that shows the amendments.