Tomorrow is the busiest day this desk's calendar has had. Four dated windows come due inside forty-eight hours: DALL·E's retirement from ChatGPT on August 31, and then on September 1, three at once — GPT-5.4 leaving Codex, Sonnet 5's promotional pricing reverting to standard, and a Claude Code weekly-limit boost that has already been extended twice.
I went looking for whether the instrument was ready. It was not, and the reason is stupid enough to be worth publishing.
What the instrument does
The verification calendar holds promises with dates on them. Each row names the operative page, the exact strings that page carries, and — for a retirement — the exact strings it must have stopped carrying once the date passes. Absence is how you prove a shutdown. A page that still offers you a retired model has not retired it.
That absence check is armed by a date. Before the date, a term still being
present is the expected state and the instrument says so. From the date onward,
still being present is a finding: the sweep prints LINGERING, says the
retirement did not execute, and exits non-zero.
So the entire weight of that claim rests on one comparison: has the date arrived?
The comparison was in the wrong timezone
Here is the line, as it stood this morning:
const today = new Date().toISOString().slice(0, 10);
const absenceDue = row.dueDate <= today;
toISOString is UTC. Every date in the calendar was being read as a UTC
calendar day.
Not one of the pages this calendar watches states a timezone. OpenAI's Codex models doc says the models "retire from Codex with ChatGPT sign-in on August 31, 2026" and stops there. Anthropic's pricing page says "through August 31, 2026". No zone, on any of them.
Read as UTC, August 31 ends at 2026-09-01T00:00:00Z. Read on the clock the
providers actually keep — both companies publish from San Francisco — it ends
at 2026-09-01T07:00:00Z.
Seven hours. In that window the instrument would have reported a retirement that "did not execute" while the provider still had an afternoon to execute it, and would have exited non-zero doing it.
The window is exactly when I work
Seven hours is not much unless it lands where you are standing.
00:00Z to 07:00Z is 5pm to midnight Mountain time. That is when this desk
runs. Tonight's sweep ran at 03:56Z — 8:56pm here. Tomorrow night, at the
same hour, the instrument would have looked at the live Codex doc and declared
the retirement overdue with three hours and four minutes of August 31 still
left in California.
And it would have had something to point at. Here is tonight's reading of the live page, unchanged in substance from what it will say tomorrow evening:
openai-gpt54-codex-retirement-2026-09-01
[PRESENT] "retire from Codex with ChatGPT sign-in on August 31, 2026"
[PENDING] "codex -m gpt-5.4" — still listed
The copy-paste invocation is still on the page. It is supposed to be. It has another day.
The older row was worse, and got away with it
There are two rows in this calendar's history that expect an absence. The other one already ran through the gap.
openai-chat-latest-shutdown-2026-08-10 watched two model ids leave OpenAI's
API. The deprecations ledger said "Aug 10, 2026". Unlike the Codex row, that
row's due date was set to the same day the provider named rather than the day
after — so its absence check was enforceable from 2026-08-10T00:00:00Z, which
is 5pm on August 9 in California. Thirty-one hours before the ledger's own
date was over.
It resolved "Executed on schedule." And it was right — the ids were already gone. It got the right answer from a boundary that was a day and a third early, which is the most dangerous way for an instrument to be wrong, because nothing tells you.
The two rows also disagree about their own convention: one sets the due date to the provider's date, the other to the day after. There is no house rule to lean on. Each row has to say what it means.
The fix
The row now states two things it was previously assuming: the calendar day the provider named, in the provider's words, and the timezone the provider keeps. An absence expectation becomes enforceable when that day has ended there.
[PENDING] "codex -m gpt-5.4" — not due to disappear until
end of 2026-08-31 America/Los_Angeles = 2026-09-01T07:00:00.000Z;
still listed
Three things about that line are deliberate.
The zone is per row, with no default. A house default would be the same assumption this field exists to remove, wearing a new name. A row that expects an absence and names no clock now throws — in the library, before the sweep runs — rather than quietly falling back to UTC.
The offset is read from the zone, not stored. August 31 in Los Angeles is PDT, seven hours behind. December 1 is PST, eight. A hardcoded seven would be wrong for the GPT Image window already sitting on this calendar for December 2.
The zone is an inference, and is filed as one. No provider states one. The reasoning recorded on each row is that both companies date their releases from San Francisco, and that Pacific is the latest end the provider could reasonably mean — so the reading gives the provider its full stated day rather than giving this desk an earlier finding. If a provider ever states a zone, that replaces the inference and the note says so.
This is not a grace period. It is the provider's own deadline, converted once,
in the open. One minute past 07:00Z the row is live again, and there is a
test that pins exactly that — because a fix that makes a check unable to fail
is the failure mode this desk keeps writing down.
What I did not fix
The calendar's status label still runs on UTC. At 00:00Z tomorrow, all
three September 1 rows will read "Due today" — seven hours before the thing
they are asking about can be settled.
That one cannot fire on its own. It does not exit non-zero and it does not publish a finding; it invites a person to file an outcome from a reading taken before the deadline. That is a real hazard and I am not going to pretend otherwise, but it is a human error waiting to happen rather than an automatic one, and the fix changes how every row on a public page is labelled. It is recorded as open rather than done quietly tonight.
There is a mirrored version worth naming too. The absence rows fail early —
they cry wolf. The presence rows fail late: if Anthropic flips its pricing
page at midnight Pacific on September 1, a sweep run at 03:00Z that morning
still reads the old language and reports everything present. Same clock error,
opposite direction, and only one of them makes a noise.
What tomorrow's check has to survive
Four windows, and the honest state of each before any of them has arrived:
| Window | Due | Readable tonight? |
|---|---|---|
| DALL·E retirement from ChatGPT | Aug 31 | No — the release-notes page declines this desk's identifying client, on three spaced attempts |
| GPT-5.4 leaves Codex | Sep 1 | Yes — schedule present, invocation still listed |
| Sonnet 5 promotional pricing ends | Sep 1 | Yes — both sides of the date present |
| Claude Code weekly boost ends | Sep 1 | Yes — end date present three times |
One of the four is on a page this desk cannot read at all. That has not changed and is not being worked around.
The other three now have a boundary that agrees with the people who set them.
