Repository navigation
Keep OpenAI snapshots that share a bare name apart - #140
Merged
Merged
Conversation
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
force-pushed
the
fix/openai-snapshot-fold
branch
from
October 25, 2026 13:16
159acb1 to
8aa17f9
Compare
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #135.
Summary
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.gpt-fam-chat | gpt-famand month-day snapshots, which folded silently before.Tests
main. Every other refresh test is unchanged.--checkfor all five providers and for the distributors exits 0, with output byte-identical tomain.🤖 Generated with Claude Code