Skip to content

ci(drift): fail fast on a retired drift probe model - #585

Merged
jpr5 merged 3 commits into
mainfrom
ci/drift-model-retirement-preflight
Oct 27, 2026
Merged

jpr5 merged 3 commits into
mainfrom
ci/drift-model-retirement-preflight

Conversation

@jpr5

@jpr5 jpr5 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Why

OpenAI retired o4-mini (shutdown_date 2026-10-23). The K9 drift probe still pinned it, so the nightly Drift Tests failed for three nights (run 40279023362). notify reported each failure as "HTTP API drift detected — providers changed response formats". fix-drift.yml syncs only model-list churn, so nothing caught the retirement. #584 moved the probe to gpt-5.4-mini. This PR catches the next retirement weeks ahead and names it plainly.

What

  • src/__tests__/drift/probe-models.ts: one side-effect-free list of every provider model the live drift probes pin. OPENAI_K9_PROBE_MODEL (from fix(drift): probe K9 exhaustion on gpt-5.4-mini after o4-mini retirement #584) now lives here, and helpers.ts re-exports it. Legs that choose their model from the live listing (resolveLiveModel) heal themselves and are not listed. A unit test checks that each entry is still pinned in the source file it names.
  • scripts/drift-model-preflight.ts: a new step, Preflight — probe model retirement, in the daily drift job, after the key-freshness preflight.
    • Gone, or past its shutdown date: ::error with probe model X retired on DATE — update <constant>, and the step fails before any drift test runs.
    • Shutdown date within 30 days, or deprecated: ::warning, a row in the step summary, and the retirement_alert output.
    • No key, no retirement API, 401/403, 429/5xx or network error: informational skip, never a failure.
  • notify: a retired probe model posts "Drift probe model retired … (not API drift)" instead of "HTTP API drift". A soon-to-retire model posts a warning on an otherwise quiet day, and is added to any other alert. It reuses the existing SLACK_WEBHOOK. No new secrets; no new actions or permissions.
  • gemini.drift.ts: the embeddings canary called text-embedding-004, which answers 404 (the canary logged it and passed). It now calls gemini-embedding-001, which was checked live and returns a 3072-value embedding. Without this change, the new preflight would fail the first nightly run.

Retirement data per provider (each checked with one live request, 2026-10-26)

Provider Field Gone
OpenAI GET /v1/models/{id} shutdown_date (o4-mini → 2026-10-23, gpt-5-mini → 2026-12-11) 404
Anthropic GET /v1/models/{id} lifecycle, deprecated_at, retires_at 404 (claude-3-haiku-20240307)
Gemini GET /v1beta/models/{id} no date field 404 (text-embedding-004)
Cohere GET /v1/models/{id} is_deprecated 404 ("removed on September 15, 2025")
OpenRouter GET /api/v1/models expiration_date missing from the listing
Bedrock GetFoundationModel only modelLifecycle.status (ACTIVE/LEGACY), needs AWS creds: skipped ResourceNotFound
Vertex / Ollama / fal none: skipped —

Local red-green (real provider APIs, real drift keys)

RED. In a scratch copy with OPENAI_K9_PROBE_MODEL = "o4-mini", exit 1:

::error title=probe-model-retired::probe model o4-mini (openai) retired on 2026-10-23 — update OPENAI_K9_PROBE_MODEL in src/__tests__/drift/probe-models.ts
::error::Probe-model preflight failed: a drift probe model is retired. Drift was not run — this is not API drift.

Warning path. In a scratch copy with gpt-5-mini added and DRIFT_PREFLIGHT_WARN_DAYS=60, exit 0. The step output retirement_alert carries the same line:

::warning title=probe-model-retiring::probe model gpt-5-mini (openai) retires on 2026-12-11 (in 46 days) — update the pin in src/__tests__/drift/providers.ts and its entry in src/__tests__/drift/probe-models.ts

GREEN. This branch with the real probe models, exit 0:

preflight: probe model gpt-4o-mini (openai): served (shutdown 2027-01-14)
preflight: probe model text-embedding-3-small (openai): served (no shutdown date)
preflight: probe model whisper-1 (openai): served (shutdown 2027-02-26)
preflight: probe model gpt-realtime-mini (openai): served (shutdown 2027-01-20)
preflight: probe model gpt-4.1-mini (openai): served (shutdown 2027-01-14)
preflight: probe model gpt-5.4-mini (openai): served (no shutdown date)
preflight: probe model claude-haiku-4-5-20251001 (anthropic): served (no shutdown date)
preflight: probe model claude-sonnet-4-5-20250929 (anthropic): served (no shutdown date)
preflight: probe model claude-sonnet-4-5 (anthropic): served (no shutdown date)
preflight: probe model gemini-2.5-flash (gemini): served (Gemini publishes no shutdown date)
preflight: probe model gemini-embedding-001 (gemini): served (Gemini publishes no shutdown date)
preflight: probe model rerank-v3.5 (cohere): served (Cohere publishes no shutdown date)
preflight: probe model qwen/qwen3-32b (openrouter): served (no shutdown date)
preflight: probe model us.anthropic.claude-sonnet-4-5-20250929-v1:0 (bedrock): skipped — no retirement API reachable here (GetFoundationModel gives only ACTIVE/LEGACY and needs AWS credentials)
preflight: probe model gemini-2.5-flash (vertex): skipped — no retirement API reachable here
preflight: probe model qwen2:0.5b (ollama): skipped — local daemon model; nothing to retire upstream
preflight: probe model qwen3:0.6b (ollama): skipped — local daemon model; nothing to retire upstream
preflight: probe model fal-ai/flux/schnell (fal): skipped — fal exposes no model retirement API
preflight: no drift probe model is retired

The date logic has unit tests with fixed dates. A model counts as retired on its shutdown date, and the warning window includes its last day. A mutation from <= 0 to < 0 makes the shutdown-day test fail. The executed notify tests fail against the unmodified workflow (4 of 5; the negative control passes).

Gates (run one at a time, exit codes)

typecheck 0 · lint 0 · format:check 0 · new tests 0 (51) · actionlint on test-drift.yml 0 (the 5 repo-wide info findings are in changelog-radar.yml and test-pytest.yml; main has the same 5) · zizmor --min-severity medium 0 · build 0 · pnpm test 0 (484 files, 19690 passed)

Worth knowing

  • The OpenAI probe models gpt-4o-mini and gpt-4.1-mini shut down on 2027-01-14, and gpt-realtime-mini on 2027-01-20. The preflight starts warning about them in mid-December.
  • On Bedrock, anthropic.claude-sonnet-4-5-20250929-v1:0 already reports LEGACY in us-west-2. This preflight cannot see that, because it holds no AWS credentials.

jpr5 added 3 commits October 26, 2026 16:29
text-embedding-004 answers 404 on the Gemini Developer API, so the canary
logged a 404 every night and checked nothing. gemini-embedding-001 answers
embedContent with a 3072-value embedding (checked live 2026-10-26).
Before the nightly drift run, scripts/drift-model-preflight.ts asks each
provider about every model the live probes pin, listed in one place in
src/__tests__/drift/probe-models.ts. A gone or past-shutdown model fails
the step with "probe model X retired on DATE — update <constant>", and
notify reports it as a retirement, not as API drift. A shutdown date
within 30 days is a warning in the job summary and in Slack. Missing
keys, providers without retirement data, and transient errors skip.

Retirement fields, each checked live: OpenAI shutdown_date, Anthropic
lifecycle/retires_at, OpenRouter expiration_date, Cohere is_deprecated,
and a 404 from Gemini, Anthropic, OpenAI or Cohere when a model is gone.
…be models

The retirement preflight reads probe-models.ts without loading helpers.ts,
which starts servers. helpers.ts re-exports the constant, so the K9 probes
are unchanged.
@pkg-pr-new

pkg-pr-new Bot commented Oct 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@copilotkit/aimock@585

commit: 14cb1ce

@jpr5
jpr5 merged commit 589fd08 into main Oct 27, 2026
37 checks passed
@jpr5
jpr5 deleted the ci/drift-model-retirement-preflight branch October 27, 2026 00:12
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.

1 participant