> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zespan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Lifecycle — provider deprecation radar

> Detects when a model you're actually calling has a provider-announced end-of-life, with real measured call volume, cost, and affected agents — never a fabricated quality or regression comparison.

Model Lifecycle watches the models your project actually calls against a curated catalogue of provider-announced deprecation and retirement dates, and raises a finding when one of your models is heading toward end-of-life. Every number on a finding is measured from your own traffic — nothing here is estimated or simulated.

## What the radar watches

A daily scan (04:00 UTC) sweeps your project's model usage from the last 30 days and matches every model you called — by model id, disambiguated by provider when the same id is published by more than one — against Zespan's bundled catalogue of provider deprecation announcements (`ModelLifecycle`). See [the feed reference](/reference/model-lifecycle-feed) for exactly what's in that catalogue and how it's maintained.

A model only produces a finding when **both** are true:

* It has an announced `retiresAt` date, and that date falls within the detection horizon (90 days by default)
* Your project actually called it at least once in the last 30 days

A model with an announced retirement date that you've never called, or one retiring further out than the horizon, produces nothing — there's no finding to review and no widget to see.

<Note>
  The catalogue is curated and bundled with each release, not scraped from a provider's page at request time. This also means a self-hosted install with no outbound internet access evaluates lifecycle findings normally — there's no live fetch in the critical path.
</Note>

## Where findings appear

| Location                                       | What you see                                                                                                                                                                                                                          |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Overview** (Engineering view)                | A "Model risk" widget showing your single most urgent open finding, plus a count of any others. It renders nothing at all when there are no open findings — it never sits on the dashboard as an empty state.                         |
| **Models page → Lifecycle column**             | Every model with a catalogue entry or an open finding shows a countdown chip (e.g. "Retires in 34 days", "Retired 429 days ago"). Models with no known lifecycle show a plain dash. See [Models](/dashboard/models#lifecycle-column). |
| **Model Lifecycle page** (`/models/lifecycle`) | The full findings list for the project, filterable by **Open**, **Dismissed**, or **All**. This is the page both the overview widget and the Models page banner link to.                                                              |

## What a finding contains

Each finding is one (project, model) pair. Everything below is either read directly from the catalogue or measured from your own ClickHouse trace data over the trailing 30 days — nothing is inferred beyond that.

| Field                        | Source       | Notes                                                                                           |
| ---------------------------- | ------------ | ----------------------------------------------------------------------------------------------- |
| Model / provider             | Your traffic | The exact model id and provider you called                                                      |
| `deprecatedAt` / `retiresAt` | Catalogue    | The provider's own announced dates; `retiresAt` may be in the past for an already-retired model |
| Days remaining               | Computed     | Whole days from now to `retiresAt`, floored on the UTC day. Negative means already retired.     |
| Calls / 30d, Cost / 30d      | ClickHouse   | Real call volume and spend on this model, in this project, over the trailing 30 days            |
| Affected agents              | ClickHouse   | Every agent name that called this model in the window                                           |
| Affected prompts             | ClickHouse   | Every `name@vN` prompt version that called this model in the window                             |
| Successor model              | Catalogue    | The provider's own named replacement, when one was announced                                    |
| Cost comparison              | ClickHouse   | See below                                                                                       |
| Source / last verified       | Catalogue    | `announced`, `inferred`, or `manual`, plus when a human last checked the `sourceUrl`            |

### Cost comparison

When the provider named a successor and you have real traffic on it too, the finding shows the measured difference in average cost per call between the two models over the same 30-day window. This is a comparison of **your own organic traffic on both models** — not a matched, controlled comparison, since the two models may be serving different operations. If you have no traffic on the successor yet, the finding says so plainly instead of showing a blank or a zero.

<Note>
  Zespan does not run your evaluations or regression suite against the successor model, and does not report a quality delta between the two. Nothing in this platform invokes a model on your behalf — everything shown is measured from calls you already made. Compare quality yourself before switching. See [what's not built yet](#whats-not-built-yet) below.
</Note>

## The re-raise ladder and dismissing a finding

A finding's urgency is expressed as a **band**: 90, 30, 7, or 0 days remaining (0 meaning the model has already retired). Zespan notifies the first time a finding is created, and again only when the band *tightens* — the deadline gets meaningfully closer. A daily re-scan that lands in the same band is silent by design: a re-run with nothing new to say would train you to ignore the feature by the time it actually matters.

**Dismissing** a finding (with a required reason) suppresses it at its current band. It stays dismissed through further daily scans as long as the band doesn't tighten. When the retirement date moves into a nearer threshold — 90 → 30 → 7 days, or crosses into retired — the finding automatically reopens exactly once and notifies again, clearing the old dismissal reason. A band that *widens* (a feed correction pushes the retirement date further out) never reopens a dismissed finding.

<Steps>
  <Step title="Open a finding">
    From the Model Lifecycle page, the Models page banner, or the Overview widget.
  </Step>

  <Step title="Review the evidence">
    Call volume, cost, affected agents and prompts, and the cost comparison against the successor if you have traffic on it.
  </Step>

  <Step title="Dismiss with a reason, or leave it open">
    Dismissing requires a short explanation (e.g. "migrating next sprint") so a later reviewer knows why it was suppressed. Leaving it open keeps it visible until you act.
  </Step>
</Steps>

## Getting notified

Findings are always recorded and visible on this page regardless of alert configuration — but by default nobody is notified when a new one appears. A small settings card at the top of this page turns that on:

<Steps>
  <Step title="Toggle notifications on">
    "Notify me about model deprecations", at the top of this page.
  </Step>

  <Step title="Add recipients">
    A comma-separated list of notification emails, and optionally a webhook URL. The webhook is validated against the same SSRF-safety check every other alert webhook in Zespan goes through — a URL that resolves to a private or internal address is rejected.
  </Step>

  <Step title="Save">
    Takes effect on the next daily scan that raises or re-raises a finding — see the re-raise ladder above for when that is.
  </Step>
</Steps>

<Note>
  This is a dedicated, minimal opt-in for this feature only — it does not appear on, and is not part of, the general [Alerts](/dashboard/alerts) page, since a model-lifecycle rule has no metric, condition, or threshold for that page's table to display. See [Alerts → Model lifecycle alerts](/dashboard/alerts#model-lifecycle-alerts) for how this fits into the shared delivery machinery (same email/webhook pipeline every other alert rule uses).
</Note>

## What's not built yet

* **No quality or regression comparison.** Producing "how would the successor model have performed on your traffic" would mean actually invoking that model on your behalf — a capability that doesn't exist anywhere in Zespan today. The cost comparison above is the only automated comparison this feature makes, and it's explicitly labeled as a cost comparison, never a quality one.
* **No drift detection.** Model Lifecycle only watches for provider-announced retirement dates. It does not detect a provider silently changing a pinned model's behavior over time — that's a separate, harder problem tracked for a future release.
* **No automatic migration.** Nothing here writes to a prompt, a config file, or a model string. A finding is information; acting on it is up to you.

## Next steps

* [Models](/dashboard/models#lifecycle-column) — the Lifecycle column and countdown chip on the model registry table
* [Alerts](/dashboard/alerts#model-lifecycle-alerts) — get notified by email or webhook when a new finding is raised
* [Model lifecycle feed reference](/reference/model-lifecycle-feed) — the exact catalogue fields, how it's curated, and how to report a missing or wrong entry
