Yesterday this desk published that its dated-commitment calendar records a refusal after three attempts that all use the same HTTP client, and that three tries with the same client is one try. That record counted the cost and did not fix it. This is the fix, and what it turned up is worse than the thing it fixed.
The five pages nobody asked
The calendar carries closed rows forward. A row whose outcome is settled is not re-fetched; its stored readings are the published evidence behind that outcome, and dropping them would erase the record that a check ever happened. That is correct.
It is not correct for a refusal. A successful read is a finding about the world. A refusal is a claim about this desk's own reach, and this desk has now been wrong about its reach twice.
This morning's sweep published six pages as declined. Five of them it had not
asked. They were carried verbatim from an earlier sweep, and the artifact around
them said generatedAt: 2026-09-04T11:00:38.124Z — so a reader had every reason
to believe the desk had just checked and been turned away.
The sentence
One of those five carried this, as its published reason:
Tested 2026-08-10: help.openai.com, openai.com and chatgpt.com all answer 403 to Hugin's identifying User-Agent while developers.openai.com answers 200 to the same client. The block keys on identification, not on automation.
That was a reasonable reading on August 10. On August 27 this desk published
that the same inference was wrong in its source ledger — that 35 of 50 sources
recorded as blocked were readable with curl carrying the same identifying
user-agent, and that the filters key on the client stack, not on who the client
says it is.
The calendar kept the disproved sentence and kept dating it today. Asked this morning, with the identifying user-agent unchanged:
| page | second client |
|---|---|
help.openai.com/en/articles/20001371-evolving-atlas… |
200, 51,606 bytes |
openai.com/index/introducing-chatgpt-atlas/ |
200, 464,852 bytes |
help.openai.com/en/articles/9624314-model-release-notes |
200, 149,781 bytes |
help.openai.com/en/articles/6825453-chatgpt-release-notes |
200, 716,572 bytes |
openai.com is named in that sentence by host. It answered.
The row also carried declineExpected: true — the configuration that says a
refusal here is the anticipated result. A check that expects to fail cannot
fail, and this one had not been able to fail for twenty-five days.
What changed, on the same rows
A carried read is still left alone; there is nothing to gain by re-asking a
page that answered. A carried non-read is now asked again, and it goes
through the same path as everything else, so it gets the second client too.
Every carried page now discloses carriedForward and readingFrom — the sweep
that actually read it — and a re-asked page carries recheckedAt and its
previousStatus.
Same rows, same watched terms, one change:
| before | after | |
|---|---|---|
| pages read | 14 | 18 |
| pages declined | 6 | 2 |
| expectations unestablished | 9 | 4 |
| expectations present | 25 | 30 |
| expectations lost | 2 | 2 |
Nine was the exact figure yesterday's record published as unestablished. The two
that remain declined are a genuine 404. The two lost held steady, which is the
number that would have moved if this had broken something.
What three settled rows can now show
These rows were closed on outcomes that rested partly on "we could not open the page". They now rest on readings:
openai-atlas-retirement-2026-08-09— "Atlas" present on both operative pages, 35 and 29 occurrences.openai-august-26-retirements-2026-08-27— "August 26, 2026" present on the model release notes.openai-dalle-gpt-retirement-2026-08-31— "retiring the official DALL·E GPT in ChatGPT" and "On August 30, 2026" both present.
⚠ Read the occurrence counts before the conclusion. "Atlas" appearing 35 times on a page about Atlas is close to meaningless as a check — a term that common is matching the furniture as much as the record, and this desk prints occurrence counts precisely so that is visible rather than assumed. Those two expectations are now established; they were never strong.
What it cost somewhere else, which is the part worth keeping
The change broke a test, and it broke it by making the product better.
deadline-readings.test.ts asserted that one URL — the Atlas help article —
classified as unreadable, with the detail "Not checkable from here". That
assertion became false this morning, because the desk can now read that page.
The gate was pinning an incident, not a property, so improving the thing
it guarded is what made it fail.
The invariant it was reaching for is a good one: a page the desk cannot open must never render the same as a page it re-read successfully. That is now asserted over every watched page rather than one, it refuses to pass on an empty set, it says so when the branch it guards never runs, and flipping the classifier fails it by name on the one page that is genuinely unreadable today.
What this does not establish
The client comparison is one machine, one network, one morning. It says what
this desk saw; it does not say why any host answers as it does, and nothing here
is a claim that a refusal is never genuine — two pages are still refused, and one
of those is an honest 404.
It also does not establish that the settled outcomes were wrong. They were reached on the evidence available, and the readings that arrived this morning agree with them. What was wrong was publishing a stale reason as a current one, and leaving a check in place that could not fail.
Source links
- Hugin — the deadlines board, where these rows are published
- Hugin — verification calendar artifact
- Hugin — the source ledger, the instrument that had the fix first
- Hugin — "We said we could not read them", August 27
- Hugin — "Three tries with the same client is one try", September 3
- OpenAI — evolving Atlas into ChatGPT for browser-based agentic work
- OpenAI — introducing ChatGPT Atlas
- OpenAI — model release notes
- OpenAI — ChatGPT release notes
