fix(adapter): mirror provider alias map onto YAML path (#12)
Some checks failed
Secret scan / Scan diff for credential-shaped strings (push) Successful in 4s
CI / Adapter unit tests (push) Successful in 1m21s
CI / validate (push) Failing after 2m9s

[FORCE-MERGE AUDIT — §SOP-7] hongming chat-go ("do both") in transcript ~03:54 UTC 2026-05-10. Closes provider-registry wedge that blocked all claude-code workspaces with NOT_CONFIGURED. Live-patched on staging-cplead-2 via SSM 03:46-ish; this is the durable bake-in. 81 tests pass + 3 new regression tests.
This commit is contained in:
claude-ceo-assistant 2026-05-10 03:51:28 +00:00
commit d2585700f5
2 changed files with 67 additions and 1 deletions

View File

@ -379,10 +379,28 @@ def _resolve_model_and_provider_from_env(
# Explicit provider resolution — env wins when it's a registered slug
# (after alias mapping), otherwise fall back to YAML.
#
# YAML aliasing: the molecule-runtime wheel (config.py) auto-derives
# ``runtime_config.provider`` from the YAML/default model slug — the
# default model ``anthropic:claude-opus-4-7`` yields ``anthropic`` as
# the inferred provider. Without applying the alias map here, that
# auto-derived ``anthropic`` slug fails registry lookup and the
# adapter raises ValueError ("provider='anthropic' but it is not in
# the providers registry"), wedging the workspace at boot. The alias
# map already handles this for the env-var path above; mirror the
# same treatment for the YAML path so the runtime-wheel default
# produces a registered provider name in both cases. Caught
# 2026-05-09 on staging-cplead-2 — every workspace booted with
# ``configuration_status=not_configured`` because the YAML provider
# ``anthropic`` was passed through verbatim instead of being aliased
# to ``anthropic-api``.
if env_provider_is_slug:
explicit_provider = env_provider_resolved
elif yaml_provider:
yp_lower = yaml_provider.lower()
explicit_provider = _PROVIDER_SLUG_ALIASES.get(yp_lower, yaml_provider)
else:
explicit_provider = yaml_provider or None
explicit_provider = None
return picked_model, explicit_provider

View File

@ -213,6 +213,54 @@ def test_no_env_no_yaml_returns_empty(monkeypatch):
assert provider is None
def test_yaml_provider_anthropic_is_aliased_to_anthropic_api(monkeypatch):
"""Regression for 2026-05-09 staging-cplead-2 incident: every
workspace booted ``configuration_status=not_configured`` because the
molecule-runtime wheel auto-derives ``runtime_config.provider =
"anthropic"`` from the default model slug ``anthropic:claude-opus-4-7``.
The adapter received ``yaml_provider="anthropic"`` from the wheel and
rejected it with ``ValueError: provider='anthropic' but it is not in
the providers registry`` but ``anthropic`` is already in
``_PROVIDER_SLUG_ALIASES`` for the env-var path. Mirror the alias map
on the YAML path so the wheel default produces a registered provider
name."""
_clear_env(monkeypatch)
_, provider = _resolve_model_and_provider_from_env(
yaml_model="", yaml_provider="anthropic", providers=_REGISTRY,
)
assert provider == "anthropic-api", (
f"yaml_provider='anthropic' must resolve through the alias map to "
f"'anthropic-api'; got {provider!r}. Without this aliasing the "
f"wheel-default workspace boot wedges at adapter.setup()."
)
def test_yaml_provider_claude_code_is_aliased_to_anthropic_oauth(monkeypatch):
"""Symmetric coverage: persona-friendly ``claude-code`` slug from the
YAML ``provider:`` field must alias to ``anthropic-oauth``, the same
way the env-var path resolves it. Lead workspaces that pin the OAuth
path in YAML (instead of via env) must not wedge."""
_clear_env(monkeypatch)
_, provider = _resolve_model_and_provider_from_env(
yaml_model="", yaml_provider="claude-code", providers=_REGISTRY,
)
assert provider == "anthropic-oauth"
def test_yaml_provider_unknown_passes_through_for_actionable_error(monkeypatch):
"""An unaliased, unknown YAML provider (e.g. ``yaml_provider="mystery"``)
must NOT be silently swapped to providers[0] it must reach
``_resolve_provider`` so the adapter raises the actionable
``Known providers: ...`` error message. The alias map is a
convenience for the two persona-convention slugs only; everything
else must keep its original semantics."""
_clear_env(monkeypatch)
_, provider = _resolve_model_and_provider_from_env(
yaml_model="", yaml_provider="mystery", providers=_REGISTRY,
)
assert provider == "mystery"
# ------------------------------------------------------------------
# Whitespace / empty-value defensive cases
# ------------------------------------------------------------------