Detect model deprecations before they break production.
Audit pull requests and default-branch merges for code changes. Audit on a schedule for provider changes. A provider can deprecate or retire a model while your application code remains untouched, and that can still break production.
We built this because we needed a repeatable way to audit model lifecycle across our own systems. We are publishing it because many LLM applications have no reliable process for tracking provider deprecations and retirements.
- Lifecycle
- CHECKING
- Action
- —
- Suggested target
- —
- Why
- Resolving with the live engine…
- Evidence
- Not published for this key
- Mutation
- The API does not change repository configuration
- Docs
- Request and response reference →
- Live
- Open this decision ↗
GitHub Actions setup
Scan the repository, send only normalized model keys, and write findings to source annotations and the job summary. Pull requests and default-branch merges cover repository changes; the schedule covers lifecycle changes when the repository is untouched.
Repository and source ↗- Discovery
- Use
paths: .for the first run. Declare runtime-selected models and deployment aliases inmodels.include. - Privacy
- Source code, prompts, credentials, and surrounding configuration stay on the GitHub runner.
- Control
- The Action never changes a model. Expiring waivers keep a known migration constraint visible without suppressing the audit.
1. Advisory rollout
name: Model lifecycle advisory
on:
pull_request:
push:
branches: [main, master]
schedule:
- cron: "17 9 * * 1"
workflow_dispatch:
permissions:
contents: read
jobs:
check-models:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: PredictabilityAtScale/usagetap-model-lifecycle-action@v1
with:
paths: .
fail-on: never
unknown-policy: warn
api-error-policy: warnBoth lifecycle findings and API outages warn, so UsageTap does not become a merge dependency while you validate discovery.
2. Enforced lifecycle gate
name: Model lifecycle gate
on:
pull_request:
push:
branches: [main, master]
schedule:
- cron: "17 9 * * 1"
workflow_dispatch:
permissions:
contents: read
jobs:
check-models:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- id: lifecycle
uses: PredictabilityAtScale/usagetap-model-lifecycle-action@v1
with:
paths: .
fail-on: replace
unknown-policy: warn
api-error-policy: error
- name: Require at least one discovered model
if: always() && steps.lifecycle.outputs.models-found == '0'
run: |
echo "No model keys were checked. Add runtime aliases to models.include."
exit 1This fails on REPLACE, API/degraded responses, and zero coverage. Pin both actions to verified commit SHAs before making the check required.
Decision and enforcement semantics
There is no configurable advance-warning window today. A published deprecation becomes REPLACE as soon as it enters the source-backed catalog; fail-on controls whether that decision blocks the job.
- KEEP
- The exact key has a source-backed ACTIVE lifecycle record.
- Passes.
- REVIEW
- The exact key is unknown or the available evidence is insufficient to call it active.
- Warns by default; configure unknown-policy to error or ignore.
- REPLACE
- The exact key is source-backed as DEPRECATED or RETIRED, even when shutdown is months away.
- Fails by default; configure fail-on or use an expiring waiver.
Example GitHub finding
The provider replacement remains distinct from any computed recommendation.
| Model key | Found at | Decision | Shutdown | Provider replacement | Evidence |
|---|---|---|---|---|---|
| openai/gpt-4-turbo | src/ai/client.ts:18 | REPLACE | Oct 23, 2026 | openai/gpt-5.6-sol | OpenAI deprecations ↗Checked Sep 16, 2026 |