Skip to content

Keep OpenAI snapshots that share a bare name apart - #140

Merged
thossullivan merged 3 commits into
mainfrom
fix/openai-snapshot-fold
Oct 25, 2026
Merged

thossullivan merged 3 commits into
mainfrom
fix/openai-snapshot-fold

Conversation

@thossullivan

Copy link
Copy Markdown
Owner

Fixes #135.

Summary

  • Two OpenAI snapshots that share a bare name with different shutdowns stay separate entries, each with its own row's dates.
  • The bare name follows the row with the earliest shutdown. If it is not committed, it becomes that snapshot's alias. If it is its own committed entry (gpt-5, gpt-4o-mini-tts), it takes that row's dates. Before, Date OpenAI undated ids listed beside their dated snapshot #128 stopped the run in that case.
  • A tie on the earliest shutdown, a row that repoints the alias, and a bare-name row that disagrees still stop the run.
  • A general check stops the run when a row would fold in, through an alias, an entry dated earlier in the same run with a different lifecycle. This covers gpt-fam-chat | gpt-fam and month-day snapshots, which folded silently before.

Tests

  • 8 new tests with invented IDs, plus the flipped Date OpenAI undated ids listed beside their dated snapshot #128 test. All 9 fail on main. Every other refresh test is unchanged.
  • A second run on the same page against the merged result changes nothing, in both row orders, for the committed, uncommitted, and alias-move cases.
  • Live --check for all five providers and for the distributors exits 0, with output byte-identical to main.

🤖 Generated with Claude Code

When two OpenAI deprecation rows shared a bare name with different
shutdowns and neither snapshot was committed, mergeFeed folded the
earlier snapshot into the later one as an alias, and the earlier date
was lost. Feeding that result back in then threw.

Maintainer's rule: every dated snapshot keeps its own entry and its own
row's lifecycle, and the shared bare name follows the row with the
single earliest shutdown. An uncommitted bare name is attached to that
snapshot (and moves there if an earlier run put it on another snapshot
of the group); a committed bare entry takes that row's lifecycle, which
replaces the #128 behavior of stopping the run. A tie on the earliest
shutdown, a row that repoints the alias, and a bare-name row that
disagrees still stop the run.

A general check now stops the run when a row would fold in, through an
alias, an entry an earlier row of the same run dated with a different
lifecycle. That catches the same silent fold for non-snapshot rows
(gpt-fam-chat | gpt-fam) and month-day snapshots. Same-lifecycle rows
still merge. Live --check output for every provider and the
distributors is byte-identical to main.

Fixes #135.

Implemented by an Opus subagent; reviewed by Claude.
…ts and Anthropic status rows

Adversarial review of the snapshot split found four gaps.

The repoint rule only ran when the bare name was a committed entry, so
an uncommitted split, or a single uncommitted row such as
"gpt-x | gpt-x-2025-01-01" replaced by gpt-x, produced data. Every
snapshot row that lists its bare name is now checked, before any group
logic: a replacement that is the bare name or one of its dated snapshots
stops the run.

Dated snapshots still folded when their rows shared a lifecycle, and the
result depended on row order (E plus a same-dated gpt-x-2025-06-01 row
became one entry; "gpt-x-chat | gpt-x" made either id canonical). The
maintainer's rule is that every -YYYY-MM-DD OpenAI snapshot is its own
entry. absorb now refuses to fold a dated snapshot into another entry or
another entry into one, and a dated row that resolves to another entry
through a committed alias stops the run (no committed feed has that
shape, so nothing migrates). Same-lifecycle rows sharing a bare name now
form a group too: each snapshot keeps its row's lifecycle, an
uncommitted bare name goes to the newest snapshot by date suffix (moving
there with a notice), and a committed bare entry takes the shared
lifecycle. Different lifecycles keep the earliest-shutdown rule. A
committed split whose snapshots later converge now moves the alias to
the newest snapshot instead of stopping. The "beside its own row" stop
for an uncommitted bare name now covers same-lifecycle groups as well.

An Anthropic status row that reached an entry through an alias skipped
the parser's status-versus-announcement rule and overwrote the
announced dates. A status row and an announcement that reach one entry
now follow the parser's rule as if both named it directly: an Active
status row or different dates stop the run, otherwise the announcement
is used. Two status rows reaching one entry must agree.

Tests cover each item and kill the review's surviving mutations
(grouping without the bare-in-row requirement, the fold check comparing
shutdown only, and the fold check skipping entries dated through an
alias); one test passes currentIds. Live --check for every provider and
the distributors is byte-identical to main.

Implemented by an Opus subagent; reviewed by an Opus adversarial reviewer.
@thossullivan
thossullivan force-pushed the fix/openai-snapshot-fold branch from 159acb1 to 8aa17f9 Compare October 25, 2026 13:16
A late-pass review found that one OpenAI snapshot row beside an
agreeing row for its uncommitted bare name gave different data by row
order: snapshot row first made the bare name an alias of the snapshot,
as the family rule says, while bare row first left it its own entry.
Rows for an uncommitted family alias now merge after the snapshot rows
that list it, so both orders give the alias result. A disagreeing bare
row still stops the run through the existing lifecycle conflict check.

Also adds tests for two surviving mutations: an ID that only contains
a date (gpt-fam-2025-01-01-preview) is not a dated snapshot, and two
Anthropic status rows that differ only in retirement date stop the
run. Live --check for every provider and the distributors is
byte-identical to main.

Implemented by Claude; reviewed by an Opus late-pass review.
@thossullivan
thossullivan merged commit 0993d40 into main Oct 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refresh merge folds two new OpenAI snapshots that share a bare name

1 participant