Orchestrata Ultimate › Plans › provider-protocol-reconciliation
Provider-protocol split-brain — reconciliation plan
Source: plans/provider-protocol-reconciliation.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-05 · 64 lines.
Prose pending.
Plan text
Provider-protocol split-brain — reconciliation plan
Task #24. Grounded in the auditor audit (agent a0bf…, 2026-07-05) which ran live
uv run pyright (ground truth, not inference). Execution DEFERRED until coverage
wave 2 + the OpenRouter builder finish (both touch providers//core.protocols — avoid
mid-edit races). Then a single wirer/builder pass, gated by pyright going green.
Canonical decision (evidence-based)
Keep core/protocols/providers.py. core/interfaces/providers.py is frozen pre-SPEC-103.
- SPEC-103 (tool-calling) was implemented only in
core.protocols(Message.tool_calls,ProviderRequest.tools/tool_choice,RawProviderResponse.tool_calls). - AGENTS.md porting table maps
core.interfaces→core.protocols(the destination namespace), and decision #5'sI(X)→XProtocolrule ⇒ProviderProtocol/ProviderManagerProtocolare the intended canonical names (both currently 0 live uses → adopting them is free). - All 25 downstream import sites already use the
core.protocolsfacade data types.
The mechanical fix — 3 files (fixes 4 of the 5 client.py pyright errors)
providers/provider_manager.py: importProviderProtocol, ProviderManagerProtocol(wasIProvider, IProviderManager, line ~26);class ProviderManager(ProviderManagerProtocol)(line 82);register_provider(..., provider: ProviderProtocol)(199);_invoke_provider(..., provider: ProviderProtocol)(353). This also clears theget_metadata/ComponentMetadatamismatch for free (protocols-native base).providers/registry.py:IProvider → ProviderProtocol(line 12; used 31/39/65).core/protocols/__init__.py: drop the now-unnecessaryIProvider, IProviderManagercross-import fromcore.interfaces.providers(line 24) — or keep as explicit deprecated aliasesIProvider = ProviderProtocol(nothing else imports those names;refsconfirms).
Resolved fork A — volk_id vs agent_id (keep volk_id)
The protocol's agent_id (3 sites: providers.py:104,267,292) is a stalled/partial rename that
never propagated; the concrete ProviderManager.get_usage/get_remaining_budget + cost_tracker.py
use volk_id, and "volk" is the 178-file domain vocabulary. AGENTS.md #5 renames class names,
not this data field. → In core/protocols/providers.py: rename the two method kwargs
agent_id→volk_id (267, 292) to match the implementation, and delete the dead
ProviderRequest.agent_id field (104; refs = 1 hit, its own declaration, zero reads).
No implementation change needed — this makes the protocol match reality.
Resolved fork B — ClaudeCLIAdapter needs real code (additive)
Corrects a false premise: ClaudeCLIAdapter (providers/adapters/claude_cli_adapter.py) has
no get_models()/supports_capability(), doesn't inherit BaseAdapter, and is built with
zero args (client.py:133) — so client.py:142 is a REAL missing-methods error, not a type
mismatch. Fix: make it satisfy ProviderProtocol structurally like its 5 siblings —
- add
get_models()returning the Claude model list it supports (from a passedProviderConfig), - add
supports_capability(cap), - pass a
ProviderConfigatclient.py:133(models/pricing for the claude CLI models), mirroring the other_register_*. It shells out to theclaudeCLI (no httpx), so do NOT force fullBaseAdapterinheritance — just implement the two protocol methods + accept the config. Additive; no behavior change tocomplete().
Out of scope — flagged as a SEPARATE, larger ticket
Same interfaces-vs-protocols disease exists core-wide for IComponent/ComponentMetadata
and the core/interfaces/{base,components,decoupling,memory}.py parallel trees — those are NOT
thin shims; ~20 live import sites (kernel, orchestrator, governance, DI container, postman,
plugin) + class X(IComponent) declarations in agents/runtime.py, core/base/service.py,
kernel/volk_registry.py. pyright on provider_manager.py alone shows 8 errors (only 5 are the
provider swap). Deleting core/interfaces/providers.py outright is part of that whole-core
decision — do NOT bundle it into this providers-scoped fix. → new backlog ticket.
Execution gate + verification
Run AFTER wave 2 + OpenRouter builder land. Then: apply the 3-file swap + fork-A kwarg/field edits
- fork-B ClaudeCLIAdapter methods, and verify with:
uv run pyright src/orchestrata_ultimate/llm/client.py src/orchestrata_ultimate/providers/provider_manager.py→ the 5register_providererrors + theget_metadataerror gone. Add/extend atests/providers/test asserting all 6 adapters register + structurally satisfyProviderProtocol. cross-ref [[openrouter-tool-design]] (itsMessage/ProviderConfigimport uses this canonical module).