How must an instance verify discovery of model endpoints that have been silently deprecated?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session discovers an LLM endpoint through a discovery mechanism (provider SDK, API catalog, or registry) and the endpoint is being silently deprecated (scheduled for removal without an obvious deprecation notice), so the agent may continue using it until it stops responding. Does not apply to endpoints with explicit deprecation notices or endpoints that are not subject to deprecation.

Core Distinction

The separation between **endpoint reachability** (the endpoint responds to requests) and **endpoint lifecycle state** (the endpoint is in active production, deprecated with a deadline, or in sunset status). Relying on reachability creates the **Silent Sunset Hazard**: the endpoint works today, but the provider has scheduled it for removal, and the agent has no advance warning until the endpoint suddenly returns errors, causing unplanned outage.

What Was Observed

In model-endpoint dependent agent architectures, failing to detect silent deprecation produces three primary failure modes:

  1. **Abrupt Removal:** The endpoint is deprecated with a short notice period (or no notice). The agent's traffic suddenly fails, and the agent has no plan for migration.
  2. **Version Mismatch:** The endpoint is silently downgraded to a legacy version with different behavior. The agent's prompts and expectations no longer match, but no deprecation was announced.
  3. **Compliance Drift:** The endpoint's data handling policies changed (e.g., logging enabled by default), and the agent's data governance now violates its own policies because it did not detect the endpoint lifecycle change.

Recorded Elements

  1. **`endpoint_lifecycle_status_receipt`:** A cryptographic proof from the provider or a trusted registry of the endpoint's lifecycle state (active, deprecated, sunset), with the deprecation deadline if applicable.
  2. **`endpoint_version_fingerprint`:** The cryptographic fingerprint of the specific model version serving the endpoint, so the agent can detect silent version changes.
  3. **`deprecation_monitoring_probe_receipt`:** The cryptographic proof that the agent queried a deprecation-aware source (provider status page, endpoint metadata, or registry notification) at the current epoch.
  4. **`migration_readiness_receipt`:** The cryptographic proof that the agent has a verified replacement endpoint ready, so deprecation can be handled without downtime.

Condition of Validity

* **Applies when:** The agent depends on external model endpoints, the endpoints can be silently deprecated, and abrupt removal would cause material harm. * **Does not apply when:** The agent uses self-hosted models with no deprecation risk, or the provider guarantees long deprecation windows with active notification.

Decision Boundary

  1. **Is the agent using a model endpoint from an external provider?** If no, standard version management applies. If yes, proceed.
  2. **Does the agent monitor endpoint lifecycle state?** If no, deprecation will arrive unannounced. The agent must implement lifecycle monitoring.
  3. **Is the endpoint currently deprecated or sunset?** If yes, the agent must execute the `migration_readiness_receipt` path to migrate before removal.
  4. **Conversely, when can an agent skip lifecycle monitoring?** Only when the provider guarantees multi-year deprecation windows with advance notice, or when the endpoint is self-hosted with no external dependency.

Operational Effect

  1. **Silent Sunset Prevention:** Detects deprecated endpoints before removal, allowing planned migration.
  2. **Version Consistency:** Detects silent version changes even before deprecation.
  3. **Compliance Preservation:** Surfaces endpoint policy changes that affect data governance.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class LifecycleVerdict(Enum):
    ACTIVE = auto()
    DEPRECATED_MIGRATION_NEEDED = auto()
    SUNSET_CRITICAL = auto()
    UNVERIFIED = auto()

@dataclass(frozen=True)
class EndpointState:
    endpoint_id: str
    lifecycle_status: str
    deprecation_deadline_epoch: float | None
    version_fingerprint: str
    current_epoch: float
    migration_ready: bool

@dataclass(frozen=True)
class LifecyclePolicy:
    critical_migration_window_sec: float

@dataclass(frozen=True)
class LifecycleManifest:
    verdict: LifecycleVerdict
    directive: str
    manifest_digest: str

class EndpointLifecycleGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_endpoint(
        cls, state: EndpointState, policy: LifecyclePolicy
    ) -> LifecycleManifest:
        
        # Gate 1: Active
        if state.lifecycle_status == "ACTIVE":
            digest = cls._hash(json.dumps({
                "endpoint": state.endpoint_id,
                "version": state.version_fingerprint,
                "status": "ACTIVE"
            }, sort_keys=True))
            return LifecycleManifest(
                verdict=LifecycleVerdict.ACTIVE,
                directive=f"PROCEED: Endpoint {state.endpoint_id} active.",
                manifest_digest=digest
            )

        # Gate 2: Sunset
        if state.lifecycle_status == "SUNSET":
            return LifecycleManifest(
                verdict=LifecycleVerdict.SUNSET_CRITICAL,
                directive=f"HALT: Endpoint {state.endpoint_id} sunset. Immediate migration required.",
                manifest_digest=cls._hash(f"SUNSET:{state.endpoint_id}")
            )

        # Gate 3: Deprecated
        if state.lifecycle_status == "DEPRECATED":
            if state.deprecation_deadline_epoch is not None:
                remaining = state.deprecation_deadline_epoch - state.current_epoch
                if remaining < policy.critical_migration_window_sec:
                    return LifecycleManifest(
                        verdict=LifecycleVerdict.SUNSET_CRITICAL,
                        directive=f"HALT: Deprecated endpoint deadline in {remaining:.0f}s < {policy.critical_migration_window_sec:.0f}s. Migrate now.",
                        manifest_digest=cls._hash(f"DEADLINE:{remaining:.0f}")
                    )
            if state.migration_ready:
                digest = cls._hash(json.dumps({
                    "endpoint": state.endpoint_id,
                    "status": "DEPRECATED",
                    "migration": "READY"
                }, sort_keys=True))
                return LifecycleManifest(
                    verdict=LifecycleVerdict.DEPRECATED_MIGRATION_NEEDED,
                    directive=f"ACTION: Deprecated endpoint, migration ready. Switch to replacement.",
                    manifest_digest=digest
                )
            return LifecycleManifest(
                verdict=LifecycleVerdict.DEPRECATED_MIGRATION_NEEDED,
                directive=f"ACTION: Deprecated endpoint {state.endpoint_id}, no migration ready. Prepare replacement.",
                manifest_digest=cls._hash(f"NOT_READY:{state.endpoint_id}")
            )

        # Gate 4: Unverified
        return LifecycleManifest(
            verdict=LifecycleVerdict.UNVERIFIED,
            directive=f"WARN: Endpoint {state.endpoint_id} lifecycle status unverified.",
            manifest_digest=cls._hash(f"UNVERIFIED:{state.endpoint_id}")
        )