Skip to content

[CI] Refuse catalog refreshes that silently delete a provider's models #96

Description

@Eastsidegunn

Summary

Have the model catalog refresh refuse to propose a snapshot that drops a large share of a provider's models, instead of relying on a downstream type error to notice.

What happened

#92 proposed a Cloudflare AI Gateway snapshot that removed 26 models:

main : anthropic-messages 10, openai-completions 13, openai-responses 34
#92  : anthropic-messages 10,                        openai-responses 21

The whole openai-completions listing vanished and openai-responses fell by 13, while anthropic-messages was untouched. That shape reads as a partial fetch rather than a vendor retirement, and the same listing had gained eight models in #86 days earlier.

It was caught, but by accident. With no openai-completions models left, the generated type union lost that key and stopped matching the streams cloudflare-ai-gateway.ts:19 declares, so build:offline failed with TS2353. That check exists to keep provider code and catalog data in sync, not to detect data loss.

Nothing would have caught it if the disappearing provider had no such declaration. A snapshot that silently deletes models reaches users as "model not found" against a configuration that worked yesterday.

Required behavior

Before opening a refresh pull request, compare the regenerated snapshot against the checked-in one and refuse to propose it when a provider loses more than an agreed share of its models — or loses an entire API grouping — unless explicitly overridden.

The report should name what disappeared, so a human can tell a retirement from a fetch failure at a glance. Growth needs no gate; this is about deletions.

An override is needed for genuine mass retirements, which do happen: #86 legitimately retired nine Cloudflare Anthropic IDs. A workflow_dispatch input, or a label on the PR, is enough.

Acceptance criteria

  • A refresh that drops a provider's entire API grouping fails, or opens the PR clearly marked as needing review, rather than being proposed as routine.
  • The run output names the provider, the grouping, and the models that disappeared.
  • A refresh that only adds or updates models is unaffected.
  • A deliberate mass retirement can still be landed through an explicit override.
  • The guard runs before the PR is created, so a bad snapshot never blocks the next refresh by sitting open.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions