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.

The mechanical fix — 3 files (fixes 4 of the 5 client.py pyright errors)

  1. providers/provider_manager.py: import ProviderProtocol, ProviderManagerProtocol (was IProvider, IProviderManager, line ~26); class ProviderManager(ProviderManagerProtocol) (line 82); register_provider(..., provider: ProviderProtocol) (199); _invoke_provider(..., provider: ProviderProtocol) (353). This also clears the get_metadata/ComponentMetadata mismatch for free (protocols-native base).
  2. providers/registry.py: IProvider → ProviderProtocol (line 12; used 31/39/65).
  3. core/protocols/__init__.py: drop the now-unnecessary IProvider, IProviderManager cross-import from core.interfaces.providers (line 24) — or keep as explicit deprecated aliases IProvider = ProviderProtocol (nothing else imports those names; refs confirms).

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 —

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