OpenProgram · Provider reliability

Provider metadata loading diagnostics

Distinguish expected absence from corrupt local configuration when the provider list becomes empty or an endpoint is missing. This change adds local warnings only; it does not change fallbacks, return values or provider selection.

Boundaries

Input stateReturn behaviorLogging behavior
provider.json missingKeep the existing missing-entry/alias fallbackNo log; some providers have no directory of their own
provider.json unreadable, invalid JSON, or a non-object top-level valueReturn an empty endpoint; the caller continues its existing fallbackWarning: source, path, error_type; do not log file contents
models_dev.json missingReturn an empty cacheNo log; this is expected on first run or before any successful fetch
models_dev.json unreadable, invalid JSON, or a non-object top-level valueReturn an empty cache and retain the short failure TTLWarning: source, path, error_type; do not log file contents
models.dev network request failureContinue by trying the disk cacheAdd no network warning in this task, avoiding duplicate logs for expected offline operation

Implementation locations

openprogram/providers/metadata.py shared provider.json reader validates structure and emits warnings; _endpoints() and shipped_provider_ids() reuse it to avoid inconsistent diagnostics between catch branches. openprogram/providers/sources/models_dev.py::_read_disk_cache() handles cache diagnostics.

warning("provider metadata load failed", extra={
  "source": "provider_json" | "models_dev_cache",
  "path": str(path) | "<unresolved>",
  "error_type": type(error).__name__,
})
Use the stable value <unresolved> only when computing the cache path itself fails. Logs must contain no traceback, JSON contents, provider credentials, HTTP response bodies or exception messages. Corrupt files remain at their original paths for inspection; this task does not delete, rewrite or quarantine them.

Acceptance