Provider scoping (items 1/2/6):
- Key visibility maps on (model_id.lower(), upstream_provider_id), matching
refresh_model_maps, so a disable/override row on one provider never leaks
onto another provider's model, and matching is case-insensitive.
Data safety (items 3/5):
- Degraded OpenRouter fetches (network error, 429, non-200, bad payload)
return None (unknown) instead of []; a provider whose path set is unknown
keeps its previously persisted rows instead of being wiped.
- Endpoint payload parsing moved fully inside try, with a list guard, so
endpoints:null or non-list shapes are swallowed as documented.
- refresh with an empty live upstream list is a no-op; the unfiltered
DELETE in the prune path is gone (prune now keys off enabled DB rows).
Hot path (items 4/12/14):
- Persist uses chunked bulk INSERTs (one statement per 500 rows) instead of
per-row ORM adds; redundant ix_model_paths_model_id index dropped.
- Read routes filter in SQL instead of materializing the whole table, and
output ordering is deterministic (public id + path), independent of rowid.
- Visibility no longer rebuilds fully priced Model objects per override row;
it reads id/forwarded_model_id/canonical_slug straight off ModelRow.
Path/id contract (items 7/8/9/11):
- discovery_path_for_subprovider/discovery_base_paths hooks on
BaseUpstreamProvider, overridden by OpenRouterUpstreamProvider, mirror
_apply_provider_field so discovery and response stamping cannot drift
(openrouter:OpenRouter now correctly maps to unknown).
- openrouter_author_slug falls back to a slash-containing forwarded_model_id,
so admin-created alias rows are discoverable.
- public_model_id splits on the first slash, same as get_base_model_id, so
discovery ids can be sent to chat completions verbatim.
Lifecycle (items 10/13):
- ENABLE_MODEL_PATHS_REFRESH kill switch; interval and flag re-read every
loop iteration, and the task idles (not exits) while disabled.
- First 429 latches and aborts the remaining fan-out for the cycle; a
per-cycle cache dedupes fetches across providers sharing a base URL.
- refresh_model_maps prunes paths of disabled/deleted providers so admin
mutations take effect immediately; rows carry updated_at and both
endpoints expose it.
Tests (item 15) rewritten through the public refresh entry point with
transport-level httpx.MockTransport fakes, FK enforcement on, and coverage
for the periodic loop. Migration re-chained onto 9c4d8e2f1a6b.